First the setup of the dynamics world:
Code: Select all
- (btDiscreteDynamicsWorld *)dynamicsWorld {
if (_dynamicsWorld == Nil) {
// -- Initialize the Bullet Physics Dynamics World.
btCollisionConfiguration *_collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher *_collisionDispatcher = new btCollisionDispatcher(_collisionConfiguration);
btBroadphaseInterface *_overlappingPairCache = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver *_constraintSolver = new btSequentialImpulseConstraintSolver;
_dynamicsWorld = new btDiscreteDynamicsWorld(_collisionDispatcher, _overlappingPairCache, _constraintSolver, _collisionConfiguration);
_dynamicsWorld->setGravity(btVector3(0.0f, 0.0f, -1.0f)); // set neutral z gravity.
// Set up the collision shape and planes
btBoxShape *worldBoxShape = new btBoxShape(btVector3(btScalar(1.0f), btScalar(1.0f), btScalar(1.0f)));
for (int i = 0; i < 6; i++) {
// need to iterate through each of the planes in our box shape, moving them to the right collision positions.
// Note that the creation of the shape above didnt create anything in the dynamics world. This will do that.
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, 10, 0));
btVector4 planeEq;
worldBoxShape->getPlaneEquation(planeEq, i);
// Now we will create the collision shape for the boxes.
btCollisionShape *groundShape = new btStaticPlaneShape(-planeEq, planeEq.getW());
btScalar mass(0.0f); //rigidbody is dynamic if and only if mass is non zero, otherwise static
btVector3 localInertia(0, 0, 0); // Static elements have 0 inertia.
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState *myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody *sFloorPlaneBody = new btRigidBody(rbInfo);
_dynamicsWorld->addRigidBody(sFloorPlaneBody); //add the body to the dynamics world
}
[self.ball addToDynamicsWorld:_dynamicsWorld];
}
return _dynamicsWorld;
}
Code: Select all
- (void)addToDynamicsWorld:(btDiscreteDynamicsWorld *)dynamicsWorld {
btTransform bodyTransform;
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(0, 0, 0));
btCollisionShape *sphereShape = new btSphereShape(btScalar(1.0f));
btScalar mass(self.mass);//positive mass means dynamic/moving object
btVector3 localInertia(0, 0, 0);
sphereShape->calculateLocalInertia(mass, localInertia);
NSLog(@"localIntertia = %f, %f, %f", localInertia.getX(), localInertia.getY(), localInertia.getZ());
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState *myMotionState = new btDefaultMotionState(bodyTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, sphereShape, localInertia);
_sphereBody = new btRigidBody(rbInfo);
//most applications shouldn't disable deactivation, but for this demo it is better.
//_sphereBody->setActivationState(DISABLE_DEACTIVATION);
//add the body to the dynamics world
dynamicsWorld->addRigidBody(_sphereBody);
}
Code: Select all
- (void)update {
NSTimeInterval deltaTime = self.timeSinceLastUpdate;
float scaling = 20.f;
if (self.dynamicsWorld) {
btQuaternion attitude = [self fetchAttitude];
btVector3 g = quatRotate(attitude, btVector3(0.0f, 0.0f, -1.0f)); // 0.0, 0.0, -9.8 is neutral G.
NSLog(@">>>> g = %f, %f, %f", g.x(), g.y(), g.z());
g = btVector3(0,0,0);
self.dynamicsWorld->setGravity(g);
self.dynamicsWorld->stepSimulation(deltaTime, 2);//deltaTime);
[self.ball updateUsingInterval:deltaTime];
{ // TODO determine if this is some kind of debugging
static int i = 0;
if (i < 10) {
i++;
CProfileManager::dumpAll();
}
}
}
}
Code: Select all
- (void)updateUsingInterval:(NSTimeInterval)interval {
btTransform transform = self.sphereBody->getCenterOfMassTransform();
btVector3 velocity = self.sphereBody->getTurnVelocity();
btVector3 position = transform.getOrigin();
btQuaternion rotation = transform.getRotation();
// Convert quaternion from bullet to GLK for sending to shader.
GLKQuaternion glkRotation = GLKQuaternionMake(rotation.x(), rotation.y(), rotation.z(), rotation.w());
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(position.x(), position.y(), position.z());
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeWithQuaternion(glkRotation));
modelViewMatrix = GLKMatrix4Multiply(self.viewController.baseModelView, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
_modelViewProjection = GLKMatrix4Multiply(self.viewController.projection, modelViewMatrix);
}
Suggestions?
Thanks in advance.