Spriggsy
Spriggsy

Reputation: 306

Bullet physics, textured sphere doesnt roll

I am trying to battle my way through learning Java and bullet physics all in one go. Quite possible a little too much to do all at once but I like a challenge.

So far, I've learned how to import g3db objects, apply bullet physics to them and interact with them on the screen by using the following code:

assets = new AssetManager();
assets.load("globe.g3db", Model.class);
assets.load("crate.g3db", Model.class);
assets.finishLoading();

Model model = assets.get("globe.g3db", Model.class);
ModelInstance inst = new ModelInstance(model);
inst.transform.trn(0, 20, 0);

btRigidBody body;
btSphereShape sh = new btSphereShape(1);
sh.calculateLocalInertia(1, new Vector3(0,0,0));

body = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(3, new btDefaultMotionState(inst.transform), sh));
body.setUserValue(Minstances.size);
body.proceedToTransform(inst.transform);

motionState = new MyMotionState();
motionState.transform = inst.transform;
body.setMotionState(motionState);

dynamicsWorld.addRigidBody(body );
Minstances.add(inst);

This works fine, if I set it above the ground it falls and comes to rest on the ground, however when it moves about it slides rather than rolls. Is there an easy fix?

Upvotes: 2

Views: 858

Answers (2)

Estiny
Estiny

Reputation: 888

To allow rolling of a physical body, you need to calculate its local inertia and provide it to the construction info. In your code you're almost doing it right.

The method

btCollisionShape.calculateLocalInertia(float mass, Vector3 inertia)

indeed calculates local inertia but stores it in its second argument 'Vector3 inertia'. No changes are applied to btCollisionShape itself.

After obtaining the vector of inertia you need to pass it to

btRigidBodyConstructionInfo(float mass, btMotionState motionState, btCollisionShape collisionShape, Vector3 localInertia)

as the last argument.

The correct code should look like this:

btRigidBody body;
btSphereShape sh = new btSphereShape(1);
Vector3 inertia = new Vector3(0,0,0);
sh.calculateLocalInertia(1, inertia);

body = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(3, new btDefaultMotionState(inst.transform), sh, inertia));

Local inertia is not required to perform the simulation, but without it, all forces applied to bodies are treated as central forces and therefore cannot affect angular speed.

Upvotes: 2

IAmNoone
IAmNoone

Reputation: 1011

You need to read out and set the rotation as well, right now you are just reading \ applying the translation.

Create a new quaternion and get the xyzw values and apply them to your object.

something like this (c++ code, but you can easily do the same in java):

btTransform trans;
Quat myquat;
yourBulletDynamicObject->getMotionState()->getWorldTransform(trans);

btQuaternion rot = trans.getRotation();
myquat.w = rot.w();
myquat.x = rot.x();
myquat.y = rot.z();
myquat.z = rot.y();

set myquat back on your object.

Upvotes: 0

Related Questions