Using the LibGDX port of bullet physics for Android and Desktop http://libgdx.badlogicgames.com/, I am attempting to write a small game which involves a spaceship travelling over an infinite heightmap, avoiding obstacles. So far this has all gone well. I have managed to compute the heightmap (btHeightfieldTerrainShape) and have the spaceship (btBoxShape) collide with it. The translation of the spaceship appears to work fine - it will slide down hills and stop moving towards the base of mountains. However, the problem is that for some reason no matter what I do the orientation of the spaceship will not change. I.e. the spaceship is always facing horizontally forward.
I have tried calling calculateLocalInertia and even setting rolling friction and anisotropic friction (which I'm unsure has anything to do with the problem anyway), however the issue still remains. At this point I'm beginning to get fairly frustrated!
The spaceship is initialized in the standard way with:
Code: Select all
//
btCollisionShape collisionShape = new btBoxShape(new Vector3(1.1f, 0.7f, 1.5f));
boolean isDynamic = config.getMass() != 0; // mass is 1
if(isDynamic){
collisionShape.calculateLocalInertia(config.getMass(), config.getLocalInertia());
}
...
// collision shape is passed to a ManagedCollisionShape, which keeps track of the number of references
btCollisionShape collisionShape = manCollisionShape.getValue();
motionState = new btDefaultMotionState(transform, config.getCoMOffset()); // center of mass offset is (0, 0, 0)
btRigidBodyConstructionInfo rbInfo = new btRigidBodyConstructionInfo(config.getMass(), motionState, collisionShape, new Vector3(0, 0, 0)); // mass is 1
body = new btRigidBody(rbInfo);
body.setRestitution(config.getRestitution()); // friction is 0.25
body.setFriction(config.getFriction()); // restitution is 0
body.setCollisionFlags(body.getCollisionFlags() | CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
if(config.getDeactivationDisabled()){
body.setActivationState(gdxBullet.DISABLE_DEACTIVATION);
}
body.setCcdMotionThreshold(config.getCcdThreshold());
body.setCcdSweptSphereRadius(0.25f);
body.activate(true);
Code: Select all
m_collisionConfig = new btDefaultCollisionConfiguration();
m_collisionDispatcher = new btCollisionDispatcher(m_collisionConfig);
m_broadphaseInterface = new btDbvtBroadphase();
// the default constraint solver
m_constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_collisionDispatcher, m_broadphaseInterface, m_constraintSolver, m_collisionConfig);
m_dynamicsWorld.getSolverInfo().setM_solverMode(
btSolverMode.SOLVER_USE_2_FRICTION_DIRECTIONS | btSolverMode.SOLVER_RANDMIZE_ORDER);
m_dynamicsWorld.setGravity(new Vector3(0, GRAVITY, 0));
debugDraw.setDebugMode(btIDebugDraw.DebugDrawModes.DBG_DrawWireframe | btIDebugDraw.DebugDrawModes.DBG_DrawAabb);
m_dynamicsWorld.setDebugDrawer(debugDraw);
Code: Select all
btHeightfieldTerrainShape heightfield = new btHeightfieldTerrainShape(gridWidth, gridHeight, data, 1, -1, 1, 1, true);
heightfield.setLocalScaling(new Vector3(scaleX, scaleY, scaleZ));
ManagedCollisionMesh shape = new ManagedCollisionMesh(heightfield, new CollisionShapeConfiguration(0)); // constructor for CollisionShapeConfiguration passes a mass of 0 to the rigid body construction method.
and turned into rigid bodies in the same way as the spaceship.
Note: It's a little difficult for me to post the code exactly as it's written in my project source, as in actuality the code is split between many different classes. However, I've attempted to reconstruct it in a way that is more or less the same and (hopefully) simple to read.