I’m trying to make a little ball maze game. The problem is that in low fps situations (old netbook), the ball sinks into the floor and thus can bypass the walls. The problem does not occur at > 200 fps. I can simulate low fps on fast machines by adding “sleep(50)” to “simpleRender()” “settings.setFrameRate(20);”.
I’ve checked the other “floor sink” and “fall through” threads, but couldn’t fix it. I find it also strange that the speed of the simulation seems to be fps dependent. Has anyone an idea what I’m doing wrong or how to fix it?
Edit: It seems this is a jbullet problem since it doesn’t occur with native bullet.
Edit2: I experimented a bit with rotating the floor faster and it seems native bullet is also showing this “problem”. Just not so fast. My way to use the physics might be wrong. Normen proposed to turn the camera and alter the gravity vector in another thread. I think I’ll test that.
To summarize my observations:
jbullet:
works when fps is high (> 200) → has problems when fps is low / throttled
when using a PlaneCollisionShape as floor, the mass of the corresponding RigidBodyControl seems to be irrelevant
when using “CollisionShapeFactory.createMeshShape(plane)” as floor, the mass must be zero (exception otherwise)
native bullet:
works in every fps range
when using a PlaneCollisionShape as floor and the mass of the floor is not zero, the ball falls through the floor
when using “CollisionShapeFactory.createMeshShape(plane)” as floor, the mass must be zero (exception otherwise)
Code updated:
mass of kinematic objects set to zero
using “settings.setFrameRate(20);” to throttle fps
The speed of the simulation is not framerate dependent but when a frame is slower than one physics frame the physics space is stepped multiple times to compensate the accuracy. However that only happens down to 15 frames/second, as its stepped a maximum of 4 times per frame (to avoid driving down its own framerate). If the load is not caused by the physics simulation (in which case the app will simply not work on the netbook), you can set the max number of additional steps by using physicsSpace.setMaxSubSteps(8);
“bulletAppState.getPhysicsSpace().setMaxSubSteps(8)” (or 16) did not help. I don’t think the load is caused by the physics. I’m currently on a 2,8 GHz Core2Duo notebook with “Mobile Intel 4 Series Express Chipset” gpu. Using the GL1-Renderer, the demo runs at > 200 fps and no physics problems occur. Using the GL2-Renderer, the demo runs at 15 fps (without “sleep(50)”) and the described physics problems occur. The problem also occurs at 60 fps (slowed down to).
I also have problems of smaller objects falling through terrain. I modelled a coin and gave it a thin cylinder shaped collision shape. I drop the coins from a small height above the terrain ground and some of them fall through, some dont, and others get stuck inside the terrain. This is even when the engine runs at 60 fps. I read something about a CCD option that could be adjusted to improve the collision detection? Atm I am considering also checking if objects that are falling are at any point under the terrain according to the height map and just move them up to the terrain height in these cases so objects dont get lost.
@johncl said:
I also have problems of smaller objects falling through terrain. I read something about a CCD option that could be adjusted to improve the collision detection?
Don't use a box or large mesh for the floor but use e.g. a height map (automatically used for terrain geometry) or a plane collision shape. CCD makes a sweep test when the object moves more in one frame than the set threshold to avoid fast objects "jumping" through an obstacle.
@survivor said:
"bulletAppState.getPhysicsSpace().setMaxSubSteps(8)" (or 16) did not help. I don't think the load is caused by the physics.
Well in theory the physics should be "normally" calculated then. Maybe its due to the low frequency of your input (e.g. when you got low fps your tpf is high and your mouse movement might cause large forces to be applied). To better separate the physics calculations, you can set the BulletAppState to parallel threading mode, this way the physics will be calculated during rendering and not before.
@normen said:
Don't use a box or large mesh for the floor but use e.g. a height map (automatically used for terrain geometry) or a plane collision shape. CCD makes a sweep test when the object moves more in one frame than the set threshold to avoid fast objects "jumping" through an obstacle.
My terrain is created just like the Terrain Collision sample on the wiki:
Hmm I see from the code that it detects TerrainQuad and will return a HeightfieldCollisionShape, so it should be using the right one.
My objects are not moving fast either, just dropped a few units above ground (but high enough to not be stuck in other objects). It might be related to the alignment of the object as it “tries to hit the surface of the terrain”. I spin the object somewhat as I am dropping it (randomly at 0-1 speed in all directions).
Hm, yeah. When you use the terrain as a parameter to the CollisionShapeFactory it should generate a HeightFieldCollisionShape by default. So yeah, if its about the velocity of the objects, try ccd.
Maybe also try using native bullet as a test to see if the issue is with jbullet maybe. Note that native bullet isn’t 100% working yet though and only on windows32 and linux64.
Using “bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);” has the effect that low fps physics runs as fast as high fps physics, but the “sink into the floor”-problem remains. If I use a “PlaneCollisionShape”, the ball sinks into the floor. If I use “CollisionShapeFactory.createMeshShape(plane)” (commented out), the ball falls through the floor.
As you can see in the source code in the initial post, I’m rotating the floor by rotating the nodes that contain the floor (the labyrinth mesh has it’s center in one corner, therefore the nested nodes “inner” and “outer”). The floor is kinematic and has a mass. The labyrinth object doesn’t have a mass because “Dynamic rigidbody can not have mesh collision shape!”.
[java]
CollisionShape plane_coll = new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0));
plane_phy = new RigidBodyControl(plane_coll, 9f); // mass = 9
plane.addControl(plane_phy);
naby_phy = new RigidBodyControl(naby_coll, 0f); // mass = 0 because “Dynamic rigidbody can not have mesh collision shape!”
naby.addControl(naby_phy);
ball_phy = new RigidBodyControl(1.0f); // mass = 1
ball.addControl(ball_phy);
bulletAppState.getPhysicsSpace().add(plane_phy);
bulletAppState.getPhysicsSpace().add(naby_phy);
bulletAppState.getPhysicsSpace().add(ball_phy);
plane_phy.setKinematic(true);
naby_phy.setKinematic(true);
[/java]
Edit: Native bullet is worse. Even at high fps the ball falls through the floor.
Edit2: If the floor has no mass (but of course kinematic), it works correct with native bullet. Using something like “setMaxSubSteps(16)” makes the simulation run the same speed regardless of fps (20-2000).
Edit3: Switching back to jbullet makes the ball sink into the floor again.
But why does native bullet work only if the floor and the walls (labyrinth) have no mass (but are kinematic)? I can zip and mail you the whole project if you’d like to test it for yourself.
Edit: Hmmm, could it be problematic that the ball is inside a node that is rotated?
Testing with the ball just below the root node…
Edit2: No, that doesn’t solve the problem.
Edit3: I think it’s correct that kinematic objects have zero mass. see bullet manual page 22.
works when fps is high (> 200) → has problems when fps is low / throttled
when using a PlaneCollisionShape as floor, the mass of the corresponding RigidBodyControl seems to be irrelevant
when using “CollisionShapeFactory.createMeshShape(plane)” as floor, the mass must be zero (exception otherwise)
native bullet:
works in every fps range
when using a PlaneCollisionShape as floor and the mass of the floor is not zero, the ball falls through the floor
when using “CollisionShapeFactory.createMeshShape(plane)” as floor, the mass must be zero (exception otherwise)
I didn’t look into the source code of (j)bullet, so I just can make assumptions. I think zero mass means infinite mass. These objects are so heavy that the impact of dynamic physics objects can’t influence them. Both, static and kinematic physics objects, are thus not moved in physics space. The difference between them is, that kinematic objects are moved in world space. The static constraint is used for optimization. That’s how I understand it.
I can create a simpler test scene and file a bug report if demanded. Or you can pull the assets from the Applet.
Its nothing I can do anything about (its either the bullet team or jezeks jbullet, though I won’t add any changes from jbullet anymore probably) but interesting that the manual says kinematic objects should have mass zero. After problems with kinematic objects at first I got the hint that kinematic objects should have a mass. Mesh shapes cannot be dynamic by definition and have to have zero mass, thats correct.
I experimented a bit with rotating the floor faster and it seems native bullet is also showing this “problem”. Just not so fast. My way to use the physics might be wrong. You proposed to turn the camera and alter the gravity vector in another thread. I think I’ll test that.