i have a pretty detailed physical world, in which a robot that i’ve simulated with articulated rigid bodies (wheels, actuators, etc) drives around doing AI stuff. As the world get large, jme3 gets very slow, because everything in my world is a physical object. I realise that this is a no-no as far as game design goes, but since this is for robotics simulation, I need to have physics anywhere that the robot goes.
A solution I’m hoping to implement is to only have objects that are sufficiently near the robot in the physics space, and to detach any objects that are far away to save the broadphase from calculating their collisions. I would really like to use this function in Bullet:
“you can use the new Bullet 2.76 broadphase query with all objects that have AABB overlap. See btBroadphaseInterface::aabbTest.” -bullet forums
But I can’t see that method in the jBullet BroadPhaseInterface.java class. So I guess that means the best way to do it is with a GhostControl to get the list of nearby objects and a PhysicsTickListener to add and remove them from the world?
Objects are already deactivated when theres no other moving objects close to them. A problem could be having one big collision shape for the world, as that would basically prohibit using the broadphase check at all.
Thanks normen. I don’t have one big collision shape for the world, I use the PlaneCollisionShape for the floor, and Boxes for a maze of walls. The problem is these “stepfields” which are meant to simulate rough terrain for the robot to drive over:
There are several of these fields. Each one is a CompoundCollisionShape with many (~100) child BoxCollisionShapes. Do you think broadphase would handle this better if they were all seperate collision shapes? I should point out that they are static collision shapes (Mass = 0).
I just started thinking about this today, and I think I have made the switch. I just removed jme-libraries-physics from the list of libraries in jMP, and added jme-libraries-physics-native. Is that all that’s needed to switch to native?
@adam said:
I just started thinking about this today, and I think I have made the switch. I just removed jme-libraries-physics from the list of libraries in jMP, and added jme-libraries-physics-native. Is that all that's needed to switch to native?
I didn’t notice much difference.
Yep, thats how you switch. Maybe the rendering is your actual problem?
depends on how many you are rendering, and whether they are batched or not. What is the object count in the stats? Keep in mind if you are displaying debug physics objects, that will also slow you down
Normally, no, but it all depends on the number of shapes, whether they’re culled, whether they’re sharing textures or not, whether something in your code causes JME to constantly re-upload textures or other data to the GPU.
Things I can think of to find out whether it’s the physics or the graphics:
Disable the physics update and see what the frame rate does.
Or check whether the framerate changes significantly if the resolution changes. That would be the fastest test.
If you have the physics running in a separate thread, check which threads take how much CPU. (In the unlikely case the SDK doesn’t have that view, you can always fire up JVisualVM, it’s in the JDK’s bin/ folder.)
Profiling the threads using the Netbeans jFluid profiler shows that the physics thread (I think, it’s pool-1-thread-1 right?) is mostly waiting, while the LWJGL renderer thread is running constantly. Does that mean its likely to be a graphics issue?
Although I had another thought, I am simulating a scanning laser range finder by doing a bunch (~1000) ray casts from the robots position every frame, it might be that the number of collisions is going up rapidly with the number of objects in the world, and killing performance.
2000 objects is a lot… especially for only 32k triangles. That’s roughly 16 triangles per object.
Can you tell us more about how your world is structured? You mention textured boxes which makes it sound kind of like a Minecraft clone but the object counts seem to indicate otherwise.
Your ray casts will perform better the more spatially organized your scene is… or the fewer objects you have (depending on the objects). Are you casting rays using the physics engine or using JME’s collideWith() method?
an articulated robot model (box chassis, cylinder wheels, and some jointed actuators), each component of which is a textured box.
a maze of walls, each of which is a textured box model
a bunch of ragdoll humanoids made using the TestPhysicsRagDoll.java demo which used to be around the test packages. this is textured spheres and cylinders.
and several of the ‘stepfields’ which i mentioned earlier (see the image link in my second post), which is a collection of textured boxes.
I think I can avoid doing the ray casts, which improves performance a bit. What determines the object count? Or whether they are batched?
an articulated robot model (box chassis, cylinder wheels, and some jointed actuators), each component of which is a textured box.
a maze of walls, each of which is a textured box model
a bunch of ragdoll humanoids made using the TestPhysicsRagDoll.java demo which used to be around the test packages. this is textured spheres and cylinders.
and several of the ‘stepfields’ which i mentioned earlier (see the image link in my second post), which is a collection of textured boxes.
I think I can avoid doing the ray casts, which improves performance a bit. What determines the object count? Or whether they are batched?
You determine whether they are batched. Objects = Geometry instances. Each one is its own managed thing that gets draw-dispatched to the the GPU every frame. If you batch some of your boxes together (preferably spatially organized) then you can improve things… whether it will help enough or not depends largely on where the time is going.
<cite>@pspeed said:</cite>
If you batch some of your boxes together (preferably spatially organized) then you can improve things...
Pardon my ignorance, but if each box is built like this:
body = new Geometry(name, jBox);
body.setMaterial(mat);
boxNode.attachChild(body);
body.setShadowMode(ShadowMode.CastAndReceive);
physics = new RigidBodyControl(mass);
body.addControl(physics);
boxNode.addControl(physics);
world.getRootNode().attachChild(boxNode);
Another thing that I notice is that if I scale the world up, and make all the objects bigger, then the number of objects in the statistics goes way up and performance drops. I don’t understand why that might be?
@adam said:
Pardon my ignorance, but if each box is built like this:
body = new Geometry(name, jBox);
body.setMaterial(mat);
boxNode.attachChild(body);
body.setShadowMode(ShadowMode.CastAndReceive);
physics = new RigidBodyControl(mass);
body.addControl(physics);
boxNode.addControl(physics);
world.getRootNode().attachChild(boxNode);
Then how do I batch them together?
Your boxes are all mobile or static?
…if all of them are mobile then it does get trickier. Otherwise, you batch them at the jBox stage and make one Geometry.
Awesome. Thanks guys will get on with batching them. Last question. Is it a bad idea to batch all the geometries in a big node? For example all the wall segments (which have the same material) that make up a maze that takes up the entire world? Or is batching always a good thing
If you batch everything then you miss out on frustum culling. That may not matter if you don’t have that many triangles but generally it’s better to batch spatially.