Page 1 of 2

Adding an animator makes the whole thing so slow

Posted: Thu May 12, 2011 5:29 am
by pverlaine999
I have created a floor, and cube. I want to add collision detection so that the cube would not fall through the floor. With the following code:

Code: Select all

	    ISceneNode * cube = smgr->addCubeSceneNode();

	    IAnimatedMesh * movingPlane = smgr->addHillPlaneMesh("floor",
	    		core::dimension2df(10, 10),
	    		core::dimension2du(100, 100));
	    IAnimatedMeshSceneNode *myfloor = smgr->addAnimatedMeshSceneNode(movingPlane);
	    myfloor->setMaterialFlag(EMF_LIGHTING, false);
	    myfloor->setMaterialFlag(EMF_WIREFRAME, true);

    	    cube->setMaterialFlag(EMF_LIGHTING, false);

	    camera = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

	    // Create a triangle selector for the floor
	    ITriangleSelector * selector = smgr->createTriangleSelector(myfloor->getMesh(), myfloor);
	    myfloor->setTriangleSelector(selector);

	    const aabbox3d<f32>& box = cube->getBoundingBox();
	    vector3df radius = box.MaxEdge - box.getCenter();
	    ISceneNodeAnimator * anim = smgr->createCollisionResponseAnimator(
	    		selector,
	    		cube,
	    		radius,
	    		vector3df(0.0f, -10.0f, 0.0f)		// gravity
	    		);
	    cube->addAnimator(anim);
	    selector->drop();
	    anim->drop();
But after adding the animator to the cube, the whole thing becomes so slow, and I only get about 1 fps on my Android. Without this line

Code: Select all

	    cube->addAnimator(anim);
the program would run normally, and I get about 56 or 57 fps.

I'd like to know what is going wrong with adding an animator like that?

All the examples I've seen seems to add animator to the camera, but what I'm creating here is a third-person camera, and I want to make the cube roll and bounce on the floor, without falling through it. This is only one cube, and I'd want to have multiple cubes do the same thing too. Is this method of implementing collision detection right?

Thanks for any hint.

Paul

Posted: Thu May 12, 2011 3:22 pm
by hybrid
Well, triangle selectors are definitely no arbitrary collision check method. It's a very special way to check for collisions, and also a quite costly. After all, they gather triangles, so already setting up the lists with triangles and returning those costs quite some time and memory. And checking lots of faces or zones for inclusion does as well. Better do a bbox intersection test, collision sphere checks (squared distance from center) or other simple things instead. Only check triangles if really needed.

Posted: Fri May 13, 2011 8:37 am
by pera
irrlicht program with one cube and terrain should give you about 1500 fps on pc. I know its android, but you need bigger FPS in start. Maybe building 'release' version would speed things up?

Posted: Fri May 20, 2011 11:42 pm
by christianclavet
Hi,

Using a "full" triangle selector can be costly. This would evaluate all the tris in the mesh each time the animator check for collision.

Is the "floor" will remain flat? If yes, then you could use the "createTriangleSelectorFromBoundingBox"

There other way you could try. Convert your mesh to an octree and use this selector "createOctreeTriangleSelector"

Had the same problem (not as pronounced as yours) and here what I decided to do:

I used another approach (thanks to the recommendations from guys on this forum! :) ):

I do the "collision test" manually and don't use the animator for this.

Check example 7 (collision example) and look at the raycollision method. I used conditions to check if the object will be moving, and when it move to a ray test to check if the ray will collide with the land. And get the position height of the collision. (with an ID on the mesh, the test is done exclusively with the ground mesh)

This worked wonder in my current project, because as the character is moving on the ground, I do 3 rays tests:
1 in front, 1 in the middle of the object and 1 in the back then check the height distance between the front and back. Once that is determined, I can choose to set a maximum so the mesh will stop if the distance is too much (giving me a effective way to stop movin if the slope is too steep.)

I use the results to get the position of the collision of the 3 rays, then get the average to position the character. Having a single ray test, is too precise (unless you don't have feets! :) ) and your model could enter some part of the terrain mesh. Averaging make it smoother. Depending of the performance you have, you can decide to add/lower the ray tests.

As I mentionned before, the test are not done at every frame, it's only done when the mesh is moving. You can fake "gravity" by addind a negative Y vector (as position - vector3df(0,-1,0) for example. With a little more work then you could add a "bounce" when a collision is detected with the ray test. (For the bounce, it will change the negative vector to a positive vector and gradually by using timers, would decrease and make it back to it's negative value. And this will stop at the next collision) Going further and adding "velocity" your would compare the distance from the last frame to the current frame. I would not use this to demonstrate the effects of gravity to NASA :), but for a simple demo or little game... Should do the trick.

With this on my PC, I can have a full scene (landscape, tons of trees, props, and about 15 NPC that are all moving) and still get more than 100+ FPS. So I think doing small ray tests at the proper time is saving some FPS, and is quicker than using an collision response animator. But this method is useful only for "walking/running" on a landscape. The collision response still is useful for me as I used it (bounding box tests) for intercollision with NPC's and objects. (I could simply use a distance test to do that If I want to improve performance further). If you need gravity, friction, buyoancy (floating on water), then think about integrating physic engines (there a couple of nice wrappers on the forum that will ease the work)

I really like that IRRlicht have the possibily to do collision tests "out of the box" and I think it's one of it's advantage. Not every projet need a full physic engine.

Also as Pera mentionned, it's alway a little faster (sometimes much) when you create a "release" build of the application.

Posted: Sat May 21, 2011 6:19 am
by pverlaine999
Thanks everyone for replying. I was trying to do collision detection using triangle selector because, well, this is how the Irrlicht examples introduce how collision detection is done. I learn to program with Irrlicht by studying the examples provided, and thought that these are best practice to do things in Irrlicht.

After a while, I thought I might as well study Bullet Physics and learn to use it. But I was having trouble compiling the different libraries for Android, until today, I found someone has a pre-built shared library that I need. You can get it from his web site here.

I downloaded it, and use it to solve my collision detection problem. With that, the program still runs quite smoothly on Android, with over 20 flying cubes that bump into each other. I got about 55 fps.

With the Irrlicht triangle selector, one single cube, sitting on the floor, made the program crawl to 1 fps. So I'm wondering what's the purpose of triangle selector, and where can it be used for, if it is so processor-intensive? Especially when it is introduced in the examples as the main collision detection mechanism, it is quite misleading. At least, it is misleading to me, as I suppose "official" examples are meant to be best practice.

Posted: Sat May 21, 2011 7:33 am
by Radikalizm
You have to remember that irrlicht is a rendering engine, not a physics + rendering engine
The collision algorithms provided are for people who need to do quick and simple demo's of a scene, without the need of any complex situations with a lot of scene elements interacting with eachother
Since irrlicht is so easy to use, it's a great candidate for quick prototyping and simulations, so simple collision detection is always a welcome for people doing those kinds of projects, together with things such as the pre-built FPS or Maya camera's (which strangely enough a lot of people try to use in complex projects)

If you read through the forums you can find that there are a lot of threads like yours, where people attempt to use irrlicht's collision algo's on broader scenes (although your limiting factor is just the fact that you're using a 'weaker' device, not a complex scene), the general advice in all of those threads is to use an actual physics engine since these are completely optimized to run in these kinds of situations

Posted: Sat May 21, 2011 11:55 am
by captainkitteh
Irrlichts built in animators are good for teaching purposes. But for actual game development they are woefully inadequate.

But that does not mean immediately jump ship for a complicated physics engine that takes ages to learn and fine tune. For most of your collision detection and physics need there is a much easier solution. Try Fun Collision. Its a very easy to use physics solution for irrlicht by a fellow forum member. It gives you Quake 3 Arena level physics including pushing objects, stacking crates and so on. It also has varying performance options so you could potentially get smooth performance on mobile devices.

[/url]

Posted: Sat May 21, 2011 12:09 pm
by Radikalizm
I have to say that engines like bullet and havok (the engines I have experience with) are fairly easy to learn, and fine-tuning is just a matter of correctly passing your required data
In my experience it certainly doesn't take ages

But maybe for mobile applications you're right, I never developed for mobile devices so I can't say whether any issues occur using bullet (or any other engine for that matter)

Posted: Sat May 21, 2011 8:04 pm
by captainkitteh
The problem with physics engines is the lack of up-to-date irrlicht integration information. Figuring out the nuts and bolts of passing matrices between irrlicht and say newton on your own is not easy for a beginner.

And while making cubes move or wheels roll is easy later you run into problems like framerate independent movement. Of course there are solutions. But they require considerable time and thinking. In my current project I abandoned Newton because I have an entire game to finish (map making, animation,shaders, level design etc). I cant dedicate a whole week to learning its intricacies. Of course if you have a team you can simply assign one physics programmer, which I hope to do for my next game.

Posted: Mon May 23, 2011 7:06 am
by pverlaine999
Thanks for you guys to reply to my dumb newbie questions.

I'm learning to program with Irrlicht because I just want to have some fun on my Android device, nothing serious. But from the two-month learning experience (in the evening and weekend, that is), I found that learning a real physics engine will definitely pay off, although it makes the learning curve so much steeper.

Irrlicht has been around for a while, I'm wondering how come no one has extended it into a real game engine yet. I tried the commercial engines, their marketing speak claims they are free, but as soon as you download it, you realize it's anything but free. But yeah, they are much easier to learn. I wish it was as easy to learn Irrlicht.

Posted: Mon May 23, 2011 7:50 am
by hybrid
We have a bunch of wrappers for physics engines, it should be enough to get an easy start.

Posted: Mon May 23, 2011 4:13 pm
by pverlaine999
Thanks, that's what I use. I use irrBullet wrapper. Otherwise, it would be a heck of a learning curve :)

Posted: Mon May 30, 2011 8:36 am
by ratamovic
Hi all,


I am also using Irrlicht on Android and have the same problem when I add an animator. However, I don't use any triangle selector because I don't need to manage collisions.

When draw the terrain alone, FPS is quite okay, but when I add an animator, it gets really slow:

Code: Select all

animS = mSceneManager->createRotationAnimator(irr::core::vector3df(0,0.001,0));
terrain->addAnimator(animS);
animS->drop();
Would you know what's happening? Animator works fine on usual meshes.


Edit: I tried to translate my terrain by hand every frame (Here it is just an "identity" translation):
terrain->setPosition(irr::core::vector3df(terrain->getPosition().X, terrain->getPosition().Y, terrain->getPosition().Z));

And that's maybe even worse compared to an animator... Any idea? My only guess is that it recomputes the terrain when you move it.


Edit2: I tried moving the camera instead, which is not exactly what I want but anyway. It works good during the first second and then starts to lag awfully... And then it gets better sometimes before lagging again. Here is a picture of what I am doing:

Image

Terrain is created that way:

Code: Select all

        irr::scene::ITerrainSceneNode* terrain = mSceneManager->addTerrainSceneNode(
                "terrainheightmap.png",
                0,                                      // parent node
                -1,                                     // node id
                irr::core::vector3df(0.f, -1000.f, 0.f),         // position
                irr::core::vector3df(0.f, 0.f, 0.f),         // rotation
                irr::core::vector3df(40.f, 4.4f, 40.f),      // scale
                irr::video::SColor ( 255, 255, 255, 255 ),   // vertexColor
                5,                                      // maxLOD
                irr::scene::ETPS_17,                         // patchSize
                4                                       // smoothFactor
                );
        terrain->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        terrain->setMaterialTexture(0,
                        mDriver->getTexture("terrdirtgrass.jpg"));
        terrain->scaleTexture(10.0f, 10.0f);

Posted: Mon May 30, 2011 3:35 pm
by hybrid
changing the terrain will call the LOD update, which means that your terrain gets pushed to the GPU each frame. Maybe you need some LOD update reduction in the code.

Posted: Mon May 30, 2011 7:58 pm
by ratamovic
Thanks for your answer. Looking at the code, indeed it seems that it is recomputing the terrain each time it moved...

But I can't understand the slowdown when I move the camera instead. It is just moving constantly, flying over the surface looking to the ground... FPS is good at the beginning, good sometimes, and sometimes suddenly very slow...

What do you mean in your second sentence? Are you saying that Terrain module may recompute some "chunks" dynamically instead of precomputing it when loading?

Thanks again