Tokamak + Irrlicht (code release 0.5 !!!)

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Tokamak + Irrlicht (code release 0.5 !!!)

Post by powerpop »

I finally got Tokamak integrated and working. There are two classes: TokamakSimManager and TokamakRigidBody

What makes this different than the tokamak tutorial is that my classes are not derived off the scenenode which makes a call to Tokamak every frame (and kills the framerate). I decoupled the physics updating and put it in a timer loop. This effectively quadrupled my own frame rate.

the files are here:
http://www.ping.net/snapshots/irrtokamak.zip

you can see it in action by downloading my ping binaries:
http://www.ping.net/snapshots/ping7.zip

and here is a short tutorial on how to use the classes:

first - we make a sim manager for tokamak

Code: Select all

    TokamakSimManager* physicsmanager = new TokamakSimManager(1.0f,45.0f,200,1,0.0f,-10.0f,0.0f);
second - for every node you have that you want to be part of the physics you will need to make a tokamakrigidbody - but you dont want to make this until the position and other information have been set - so what i do is i have a game object that contains a scenenode and what i call a pnode (a TokamakRigidBody) - make a method call initPNode in you game object and add these two calls to this method

Code: Select all

pnode = new TokamakRigidBody(node,physicsmanager,50.0f,ETG_BOX);
pnode->updateDataFromNode();
now i have to make a floor - i am crafting an animatedbody class now - but until i post it use this code to make a floor

Code: Select all

			// set up the floor
			floorbody = physicsmanager->sim->CreateAnimatedBody();

			// determine bounding box info
			irr::core::aabbox3d<f32> nodeBox = floornode->getBoundingBox();
			irr::core::vector3df size = nodeBox.MaxEdge - nodeBox.MinEdge;

			// Create and set tokamak objects
			neGeometry* geom = floorbody->AddGeometry();
			geom->SetBoxSize(size.X,100.0,size.Z);

			floorbody->UpdateBoundingInfo();

			neV3 pos;
			pos.Set(0.0f, -562.0f, 0.0f);
			floorbody->SetPos(pos);
main loop - this is where i use a timing loop to call the physics sim update every 17 milliseconds (roughly 1/60 second)

Code: Select all

	int lastFPS = -1;
	bool first = true;

	irr::u32 lasttime = device->getTimer()->getTime();

	while(device->run())
	{

		driver->beginScene(true, true, video::SColor(255,90,90,156));

		smgr->drawAll();
		driver->endScene();

		if (first)
		{
			**call your initPNode on all your objects **
			first = false;
		}
		else
		{
			irr::u32 currtime = device->getTimer()->getTime();
			if ((currtime - lasttime) > 15)
			{
				physicsmanager->updateSimulation();
				**call updatePhysicsNodes() on all pnodes **
				lasttime = currtime;

				int fps = driver->getFPS();
				if (lastFPS != fps)
					{
					wchar_t tmp[1024];
					swprintf(tmp, 1024, L"Ping.net (%s)(fps:%d)",
					driver->getName(), fps);

					device->setWindowCaption(tmp);
					lastFPS = fps;
					}
			}
		}

	}

that's it - the default on all rigidbodies is to use a box for collision - you can set it to be a cylinder or sphere if you wish (just look at the enumerated types in TokamakRigidBody

on my to do list:

- i might make a list of rigidbodies inside the SimManager so you dont have to manage your own list - one call to updateSimulation will take care of everything

- as you can see, i cannot call initPhysics until after the scene has rendered once - this is because the only way to get position info on an scenenode is from the AbsoluteTransform and this does not exist until after a render (this should be changed in irrlicht by the way!)

- add AnimatedBodies, Joints and Breakable objects

- right now i only pass position info into Tokamak - i should also convert and pass the rotation info for each scenenode

enjoy!
[/code]
Guest
Posts: 35
Joined: Mon Feb 02, 2004 7:17 pm
Location: Russia, Saint-Petersburg

Post by Guest »

Very good job, powerpop! And I think very useful.

I think I have created a timer animator from your source code. So I think it will be much more convenient to use simple animator wich implements Tokamak physics. Morover, I'm convinced that ANY movement can be (and should be) implemented through the ISceneNodeAnimator interface - this will simplify using of it.

I don't have FTP archive but I can send to anyone this code (or post it here cause it's just ione file of 200 lines actually :)). So if you're interested - just tell me.

P.S.: Sorry, I have no chance to check my animator cause I don't have time to play with Tokamak but I think it works (at least it looks like all your code is implemented but in a little bit more compact way).
Guest
Posts: 35
Joined: Mon Feb 02, 2004 7:17 pm
Location: Russia, Saint-Petersburg

Post by Guest »

... and I think I've found something strange.

In tokamak there are three helper functions to create InteriaTensor:

Code: Select all

neV3 TOKAMAK_API neBoxInertiaTensor(const neV3 & boxSize, f32 mass);
neV3 TOKAMAK_API neSphereInertiaTensor(f32 diameter, f32 mass);
neV3 TOKAMAK_API neCylinderInertiaTensor(f32 diameter, f32 height, f32 mass);
so i think it will be better to use each of them in appropriate case in geometry switch in your TokamakRigidBody constructor.
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

[duplicate reply deleted]
Last edited by powerpop on Thu Feb 05, 2004 6:50 pm, edited 1 time in total.
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

ah yes, you are right about the InertiaTensors - i will fix that!

---------

i should mention - although the timer loop right now only calls the physics and the fps display there are many other items that will use time to update themselves - network code, input processing, character animation - so while it is tempting to stuff this timer loop into a sceneanimator i did not do it - it will just result in an inability to control game logic performance and frame rate as the game gets more complex - and you will eat your frame rate up quickly

i am working on a separate GameTickManager that will hold timeanimators and manage game logic updating vs frame rate

it is my opinion that scenenodeanimators should only be used for purely rendering adjustments to the scene - they are shaders essentially - because they are called every frame, and only visual updates should be called every frame
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

"scenenodeanimators should only be used for purely rendering adjustments to the scene"

I fully agree with that statement.
a screen cap is worth 0x100000 DWORDS
Guest
Posts: 35
Joined: Mon Feb 02, 2004 7:17 pm
Location: Russia, Saint-Petersburg

Post by Guest »

well, actually THERE IS NO TIMER inside timer animator :))
I've sent you a code in private message. Look at the animateNode method!
It already has timeMs parameter (time when animation is requested). So you DON'T MAKE ANY COMPLICATED things.

try it, please :) it has NOTHING COMMON with network or other stuff... if you gonna combine them you will lose that perfect structure that IrrLicht has.

I mean there is already a mechanism how to move nodes - why do you need anything else?

Guys, timer here is just a matter of performing animatio or not in a particlar time moment - that's all! No timers at all :)))

If you'd like I can post code here...
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

irrlicht's method of moving nodes isnt very good, and its method of collision detection is worse (I should point out that I am currently using it now, however, I plan to use PP's code when it becomes neccesary to have good collision detection).
a screen cap is worth 0x100000 DWORDS
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

Guest: i have looked at your code (thank you) and sent you back some comments - I dont think you understand what I am saying - when you use a SceneNodeAnimator your animateNode routine is being called EVERY frame - you are then checking if the time elapsed forces you to update the physics for this node - now if you have 500 nodes you are doing this 500 times EVERY frame - this is not efficient and will hurt your frame rate

not to mention that your code will not work because you have to have one central simulator in tokamak not one for each node - and you only need to make one copy of the floor

keless: yes, for collision detection i decided to just use tokamak completely - this works for my app simply because i have a completely physical universe - i understand that if you has a bsp tree scene this is not going to be an option for you - you might want to go with Opcode instead - or maybe 0.5 will boost the collision code

yep, and there needs to be a getPos call in irrlicht too!
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

there is an ISceneNode::getPosition() , though it doesnt give the 'absolute' pos

I dont plan on using .BSP in IrrLichtRPG so this shouldnt be a problem for me. I am trying to keep client-server protocol in mind, thogh Im not doing networking currently-- do you think I'd be able to have Tokamek running on the client and server, and occasionally update the client's physics when it gets a world update? (IE: client runs the physics simulation just like the server, hopefully they run the same. occasionally server sends world update, and client goes 'oh, this object should be over here' and updates that object and its physics)
a screen cap is worth 0x100000 DWORDS
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

does this getPosition send back the coords relative to the parent node then? so how would one get the global position, walk the tree up until you hit the rootnode and add all the position values?

this could be a challenge if i attempt to put in ragdoll physics since you would likely make the character as one scenenode with children - so all the subpositions would be relative - but tokamak (and ODE) have no notion of subnodes in the physics model - hmmm
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

im pretty sure its always global coords, however I havent used many child scene nodes, so I am not sure. I bet there is (or could be) a way to easily modify it by its final transform matrix to get its global coords-- though whether that functionality is already in the engine and accessable from the outside is only a guess.. its probably there but only internally.
a screen cap is worth 0x100000 DWORDS
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

code update

Post by powerpop »

1) I added TokomakStaticBody (which maps to a tokomakanimatedbody - but that name was confusing so i named mine Static instead so you understand is doesnt move in the simulation - its for the ground and other immovable objects.

2) I added the different shape InertiaTensors to RigidBody correctly (thanks to Guest above for pointing that out)

3) I stopped using GetAbsolutePosition for now. Instead I use getPosition which gets the local position I believe. So if you use a lot of nested scenenodes with offset positions this code is not going to work for you. The other code would not work either. This is an open issue - how to map objects between a system that uses scene graphs and one that does not!

4) It turns out that Tokomak may have the same origin system for X,Y,Z that irrlicht has (i am awaiting an answer on that forum) - for now i corrected the code that sets position for Rigid and Static objects assuming that the origins are the same - I discovered this when I tried to make my floor work with the new Static object - the Y position was way off

To make the floor in your game you should use code like this:

Code: Select all

* first make your ground scenenode, either terrain or hill or ? *

floorbody = new TokamakStaticBody(floornode, physicsmanager, ETG_BOX);
floorbody->updateDataFromNode();
the new object code is at the same URL above
Guest
Posts: 35
Joined: Mon Feb 02, 2004 7:17 pm
Location: Russia, Saint-Petersburg

Post by Guest »

[duplicated]
Last edited by Guest on Fri Feb 06, 2004 11:53 am, edited 1 time in total.
Guest
Posts: 35
Joined: Mon Feb 02, 2004 7:17 pm
Location: Russia, Saint-Petersburg

Post by Guest »

Well, I think this is my last post in this thread cause you are not listening to me :(

1. poewerpop, you are ABSOLUTELY RIGHT when you say that it's better to use ONE sim manager for all nodes. (Here is a little question about how to change number of animating nodes during animation process but I'm sure it's not an issue).

2. I have a lot of programming experience (starting from ASM) so I can tell you that EVEN IF YOU HAVE 5000(!) animating nodes it means NOTHING!
Simple calculation for one node:
one call for animateNode ~ 10 CPU clocks (2 push, 1 jmp, 2 pop, 1 jne)
add time to get object pointer from list in scenenode ~ 5 CPU clocks
so it's ABOUT 15CPU CLOCKS PER CALL...
so 5000 calls will take about 5000*15= 75000 CPU clocks.
so if you have 1 GHz CPU (it's not a big deal today :)) then you spend about 75000 / 1000000000 ~ 1/10000 sec. Now just imaging that this value is about 1% of your ONE FRAME duration time (when you get 100fps)...

So don't tell me that it can eat you perfomance...

BTW, creation ofe many small SIMULATORS instead of a big one is not a time-consuming process cause it happens just ONCE for every node. And about simalition itself (the only difference in Advance function of the sim) you cannot be so sure that it works much slower when you call it 10 times with one object in a sim VS. one call with 10 objects in a sim cause you don't know implementation of the advance function. If there is just a simple loop then it's almost the same time :)

(This doesn't mean that I'd prefer to create a lot of simulators. As I said above, powerpop is right that there should be one (or a small number) simulator(s))

3. If you are probably interesting I can give you some examples how to use relative and absolute positions and physics animators.

a. You can create a dummy node (IDummySceneNode like IDummyTransformationSceneNode) which doesn't render itself, has no texture, material, etc... but it has size and position/rotation(read boundingbox!). Call this node as your floor and make this node as a parent for all your other nodes that need physics. Set it as a floor for your physics sim and so on...

b. for advanced physics. Note, that it's possible to make different gravity (force and even direction :)) for any node in the world. it's really powerful :) So the best way to implement this is to use that animator that I've sent to powerpop. you can set the parent node as a floor if you need additional complex physics. E.g. you have a platform and two balls on it. The platform is falling down with acceleration 10 (gravity) and your balls want to fall down with acceleration 15. then you can specify THREE animators: first for platform with gravity 10 (the floor is a ground) and two others for ball with acceleration of 5 (FIVE!) with the PLATFORM as a floor! Look at the results - they are really good :)

resume: anyway, you can put all your code, that you don't want to execute each frame, in one fuction (or a class, node, etc) but who says that it's good? I mean when you have serios reasons to do that then do it asap :) but such animators dont eat your time at all...

Sorry, if you find I'm a little rough... I'm not - I'm just a little upset...
Post Reply