No change in rotation for objects dropped onto heightmap

halfmike99
Posts: 3
Joined: Thu Aug 08, 2013 2:00 pm

No change in rotation for objects dropped onto heightmap

Post by halfmike99 »

[SOLVED]

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);
the dynamics world is initialized with:

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);
and the heightmap(s) are created with:

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.
halfmike99
Posts: 3
Joined: Thu Aug 08, 2013 2:00 pm

Re: No change in rotation for objects dropped onto heightmap

Post by halfmike99 »

So, it turns out that the solution was bleedingly obvious and I now feel very stupid (and has done nothing to help ease my growing dislike of C++ practices neither!).

I thought the method "calculateLocalInertia" set some internal variable within the collision shape; whereas in actual fact, the function simply sets the value of the passed Vector3 to the calculated result. To me, it would make much more sense if calculateLocalInertia() actually RETURNED the computed result to make its intentions more obvious (... java background ...), but whatever, eh ;)

Well, all's well that ends well.

:)
halfmike99
Posts: 3
Joined: Thu Aug 08, 2013 2:00 pm

Re: No change in rotation for objects dropped onto heightmap

Post by halfmike99 »

Yes. Well done for copying and pasting that. As I just said, I tried all three of these methods; but I incorrectly assumed that the calculated local inertia was set as in internal variable in btCollisionShape, not output in the Vector3 passed.

I think that's a fairly easy mistake to make really.