Confused on how to set up a simple dynamics world

kraythe
Posts: 9
Joined: Mon Aug 06, 2012 8:27 am

Confused on how to set up a simple dynamics world

Post by kraythe »

So I am trying to do something simple to start. Basically I just want a ball rolling on a table with four walls and a floor to constrain it. However, when I get everything set up the ball simply falls one direction and sticks there no matter what I do to gravity, the box its supposed to be in or anything else. What am I doing wrong here? The relevant portions of code are below.

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;
}
And the setup of the ball in the dynamics world.

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);
}
On each update pulse from the OpenGL kit from iOS, it does the following:

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();
         }
      }
   }
}
After this, the data for the ball is extracted, sent through the world transform and set as uniforms in the vertex shaders:

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);
}
Now no matter what I do to gravity, the ball simply falls vertically up the y direction and sticks there with no x or z translation ever.

Suggestions?

Thanks in advance.
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Confused on how to set up a simple dynamics world

Post by xexuxjy »

What happens if you apply a (one-off) horizontal impulse to the ball, does it then move / bounce around as expected?
kraythe
Posts: 9
Joined: Mon Aug 06, 2012 8:27 am

Re: Confused on how to set up a simple dynamics world

Post by kraythe »

xexuxjy wrote:What happens if you apply a (one-off) horizontal impulse to the ball, does it then move / bounce around as expected?
Nope. It moves to a point and freezes there. It shouldn't move at all until gravity changes from being straight down but it does. I am going for an effect where the ball rolls on the table.
zarlox
Posts: 31
Joined: Tue Apr 26, 2011 5:52 pm

Re: Confused on how to set up a simple dynamics world

Post by zarlox »

I see that you have commented out the activation state setting on the ball. Did you try it with disabling deactivation?

Code: Select all

_sphereBody->setActivationState(DISABLE_DEACTIVATION);
Because the sphere freezing might just be the rigid body deactivating
kraythe
Posts: 9
Joined: Mon Aug 06, 2012 8:27 am

Re: Confused on how to set up a simple dynamics world

Post by kraythe »

zarlox wrote:I see that you have commented out the activation state setting on the ball. Did you try it with disabling deactivation?

Code: Select all

_sphereBody->setActivationState(DISABLE_DEACTIVATION);
Because the sphere freezing might just be the rigid body deactivating
Yes I tried it both ways. Strangely I commented out the profiler lines in the update method

Code: Select all

      { // TODO determine if this is some kind of debugging
         static int i = 0;
         if (i < 10) {
            i++;
            CProfileManager::dumpAll();
         }
      }
And now it seems to have had some effect. At least the ball now responds to some changes in G, although not correctly. It doesnt answer the question of why and how to fix it. I think I am not understanding something important about how the dynamics world works.