3
\$\begingroup\$

I am writing an iOS game, using bullet for physics, blender to create models, cocos3d as the game engine.

I have a model like this enter image description here

Basically there is a plane, with a hole, and a UVSphere. Both were created in blender. What I am trying is to create a physics body along the vertices of the plane. So that when the UVSphere goes over the hole, it should fall through.

I am using btBvhTriangleMeshShape to create physics body along the vertices of this plane. code is given below

//GPlane stands for groundPlane :)
CC3MeshNode* gPlaneNode  = (CC3MeshNode*)[self getNodeNamed:@"GPlane"];

/*Get Vertex and indices data out from the .pod*/
float *gVertexData       = (float*)((CC3VertexArrayMesh*)gPlaneNode.mesh)
                                .vertexLocations.vertices;
GLushort* gIndices       = (GLushort*)((CC3VertexArrayMesh*)gPlaneNode.mesh)
                                .vertexIndices.vertices;
int gIndiceCount         = ((CC3VertexArrayMesh*)gPlaneNode.mesh)
                                .vertexIndices.vertexCount;

/*Create triangle mesh*/
btTriangleMesh* gTriangleMesh = new btTriangleMesh();
for (int i = 0; i < gIndiceCount; i+=3)
{
   unsigned int index1 = gIndices[i] * 6;
   unsigned int index2 = gIndices[i+1] * 6;
   unsigned int index3 = gIndices[i+2] * 6;
   gTriangleMesh->addTriangle(
      btVector3(gVertexData[index1] , gVertexData[index1+1], gVertexData[index1+2]),
      btVector3(gVertexData[index2] , gVertexData[index2+1], gVertexData[index2+2] ),
      btVector3(gVertexData[index3] , gVertexData[index3+1], gVertexData[index3+2]));
}

/*Create  a rigid body using this triangle mesh*/
btBvhTriangleMeshShape *gTriMeshShape   =   new
                          btBvhTriangleMeshShape(gTriangleMesh,true);
gTriMeshShape->setMargin(0.1);
btDefaultMotionState *groundMotionState =   
                new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1)
                                           ,btVector3(0,0.0,0)));
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0
                   ,groundMotionState,gTriMeshShape,btVector3(0,0,0.0));
groundRigidBodyCI.m_restitution = 0.3;
btRigidBody *groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);

And I am adding the sphere to the scene like this

sphereNode    =   (CC3MeshNode*)[self getNodeNamed:@"Sphere"];
btCollisionShape *fallShape = new btSphereShape(1);
btDefaultMotionState *fallMotionState = new btDefaultMotionState(btTransform(
           btQuaternion(sphereNode.location.x,sphereNode.location.y
              ,sphereNode.location.z,1), btVector3(0,0,0)));
btScalar mass = 1.0;
btVector3 fallInertia(0,0,0);
fallShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass
                      ,fallMotionState,fallShape,fallInertia);
fallRigidBodyCI.m_restitution = 1.0;
fallRigidBody = new btRigidBody(fallRigidBodyCI);
fallRigidBody->setDamping(0.3,0.8);
dynamicsWorld->addRigidBody(fallRigidBody);

To view the physics body, I use bullet physics debug drawing method and this is how it is drawn

enter image description here

As far as I can tell, physics body looks fine, the hole is there alright.

My problem

It is simple. My ball just slide over the hold instead of falling through it. I expect with a mass and negative Y gravity, the ball to fall through the hole.

Ball is falling of the edge of the plane alright. So gravity is there.

Any idea?

\$\endgroup\$
  • \$\begingroup\$ Try cutting through the hole, making two separate meshes, like this > i.imgur.com/eeqkx7T.jpg \$\endgroup\$ – Gustavo Maciel Jul 9 '13 at 6:48
  • \$\begingroup\$ @GustavoMaciel That didn't help. It was the problem with the way I exported the sphere from blender. See my answer. Anyway thanks \$\endgroup\$ – Krishnabhadra Jul 12 '13 at 8:41
1
\$\begingroup\$

Okay, I got this working. I changed the sphere adding code to this

CC3MeshNode *node =  (CC3MeshNode*)[self getNodeNamed:@"Sphere"];

//This was the magic step.. I don't know how 
//copying helped. But it did
CC3MeshNode *sphereNode = (CC3MeshNode*)[node copyWithName:@"someOtherName"];

sphereNode.location             =   cc3v(0.0, 1.0, 10);
[self addChild:sphereNode];

//Remove the original node, since we no longer need this.
[self removeChild:node];

//Now physics body.
btCollisionShape *fallShape = new btSphereShape(0.5);

//This line also different.. Compare with the code in question
btDefaultMotionState *fallMotionState 
     =  new btDefaultMotionState(btTransform(btQuaternion(
         sphereNode.location.x, sphereNode.location.y, sphereNode.location.z,1)
         ,btVector3(sphereNode.location.x,sphereNode.location.y
         ,sphereNode.location.z)));
btScalar mass  =   1.0;
btVector3 fallInertia(0,0,0);
fallShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(
                 mass,fallMotionState,fallShape,fallInertia);
fallRigidBodyCI.m_restitution   =   1.0;
btRigidBody* fallRigidBody =   new btRigidBody(fallRigidBodyCI);
fallRigidBody->setDamping(0.3,0.8);
dynamicsWorld->addRigidBody(fallRigidBody);
\$\endgroup\$
  • \$\begingroup\$ I'm not familiar with the code side but within blender you can set the block with a whole in it to use mesh for the collision shape and the ball will fall through the hole. \$\endgroup\$ – sambler Aug 16 '13 at 10:08
  • \$\begingroup\$ @sambler My blender model had a hole in it. And physics body along the model got created correctly (you can see the second image in question). The problem was the physics body I created for the ball is got placed in a different location. But adding physics body like the one given in answer corrected the issue \$\endgroup\$ – Krishnabhadra Aug 16 '13 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.