void add_rigid_body(OBJMESH * objmesh, float mass) { btCollisionShape *btcollisionshape = new btBoxShape(btVector3(objmesh->dimension.x * 0.5f, objmesh->dimension.y * 0.5f, objmesh->dimension.z * 0.5f)); btTransform bttransform; mat4 mat; vec4 rotx = { 1.0f, 0.0f, 0.0f, objmesh->rotation.x }, roty = { 0.0f, 1.0f, 0.0f, objmesh->rotation.y}, rotz = { 0.0f, 0.0f, 1.0f, objmesh->rotation.z}; mat4_identity(&mat); mat4_translate(&mat, &mat, &objmesh->location); mat4_rotate(&mat, &mat, &rotz); mat4_rotate(&mat, &mat, &roty); mat4_rotate(&mat, &mat, &rotx); bttransform.setFromOpenGLMatrix((float *)&mat); btDefaultMotionState *btdefaultmotionstate = NULL; btdefaultmotionstate = new btDefaultMotionState(bttransform); btVector3 localinertia(0.0f, 0.0f, 0.0f); if (mass) btcollisionshape->calculateLocalInertia(mass, localinertia); objmesh->btrigidbody = new btRigidBody(mass, btdefaultmotionstate, btcollisionshape, localinertia); objmesh->btrigidbody->setUserPointer(objmesh); dynamicsworld->addRigidBody(objmesh->btrigidbody); }
void add_rigid_body(OBJMESH * objmesh, unsigned char bound, float mass, unsigned char dynamic_only) { btCollisionShape *btcollisionshape = NULL; switch (bound) { case BOX: { btcollisionshape = new btBoxShape(btVector3(objmesh->dimension.x * 0.5f, objmesh->dimension.y * 0.5f, objmesh->dimension.z * 0.5f)); break; } case SPHERE: { btcollisionshape = new btSphereShape(objmesh->radius); break; } case CYLINDER: { btcollisionshape = new btCylinderShapeZ(btVector3(objmesh->dimension.x * 0.5f, objmesh->dimension.y * 0.5f, objmesh->dimension.z * 0.5f)); break; } } btTransform bttransform; bttransform.setIdentity(); bttransform.setOrigin(btVector3(objmesh->location.x, objmesh->location.y, objmesh->location.z)); btDefaultMotionState *btdefaultmotionstate = NULL; btdefaultmotionstate = new btDefaultMotionState(bttransform); btVector3 localinertia(0.0f, 0.0f, 0.0f); if (mass > 0.0f) btcollisionshape->calculateLocalInertia(mass, localinertia); objmesh->btrigidbody = new btRigidBody(mass, btdefaultmotionstate, btcollisionshape, localinertia); if (mass > 0.0f) { objmesh->btrigidbody->setLinearFactor(btVector3(1.0f, 0.0f, 1.0f)); if (!dynamic_only) objmesh->btrigidbody->setAngularFactor(btVector3(0.0f, 1.0f, 0.0f)); else objmesh->btrigidbody->setAngularFactor(0.0f); } objmesh->btrigidbody->setUserPointer(objmesh); dynamicsworld->addRigidBody(objmesh->btrigidbody); }
void add_rigid_body(OBJMESH *objmesh, float mass) { /* Create a new Box collision shape for the current mesh. */ /* Use half of the dimension XYZ to represent the extent of the box * relative to its pivot point, which is already centered in the middle of * its bounding box. */ btCollisionShape *btcollisionshape = new btBoxShape(btVector3(objmesh->dimension->x * 0.5f, objmesh->dimension->y * 0.5f, objmesh->dimension->z * 0.5f)); /* Declare a btTransform variable to be able to contain the transformation * matrix of the object in a form that Bullet will understand. */ btTransform bttransform; TStack l; l.loadTranslation(objmesh->location); // Convert angles to radians & divide by 2. float alpha = objmesh->rotation->z*DEG_TO_RAD_DIV_2; float cosAlpha(cosf(alpha)), sinAlpha(sinf(alpha)); float beta = objmesh->rotation->y*DEG_TO_RAD_DIV_2; float cosBeta(cosf(beta)), sinBeta(sinf(beta)); float gamma = objmesh->rotation->x*DEG_TO_RAD_DIV_2; float cosGamma(cosf(gamma)), sinGamma(sinf(gamma)); float cAcB(cosAlpha*cosBeta); float sAsB(sinAlpha*sinBeta); float cAsB(cosAlpha*sinBeta); float sAcB(sinAlpha*cosBeta); l.rotate(quaternion(cAcB*cosGamma+sAsB*sinGamma, cAcB*sinGamma-sAsB*cosGamma, cAsB*cosGamma+sAcB*sinGamma, sAcB*cosGamma-cAsB*sinGamma)); /* Assign the current transformation matrix that you create using the * standard "OpenGL way" and send it over to the Bullet transform variable. */ bttransform.setFromOpenGLMatrix(l.back().m()); /* Create a new motion state in order for Bullet to be able to * maintain and interpolate the object transformation. */ btDefaultMotionState *btdefaultmotionstate = NULL; btdefaultmotionstate = new btDefaultMotionState(bttransform); /* Create a Bullet vector to be able to hold the local inertia of * the object. */ btVector3 localinertia(0.0f, 0.0f, 0.0f); /* If a mass greater than 0 is passed in as a parameter to the function, * use it to calculate the local inertia. If a mass is equal to 0, it means * that the object is static and you do not need to execute this calculation. */ if (mass > 0.0f) btcollisionshape->calculateLocalInertia(mass, localinertia); /* Create a new rigid body and link the information that you have * calculated above. Note that you are using the btRigidBody pointer already * contained in the OBJMESH structure to initialize the class. This way, when * you're drawing, you can easily query the pointer in order to gain access to * its transformation matrix, which is from now on maintained by Bullet * internally. */ objmesh->btrigidbody = new btRigidBody(mass, btdefaultmotionstate, btcollisionshape, localinertia); /* Built into the btRigidBody class is a "void *" variable that * allows you to associate a user-defined pointer with the rigid * body. By associating the current objmesh pointer to this * variable, you will have direct access to the OBJMESH structure * at any time inside any Bullet-driven functions and callbacks. */ objmesh->btrigidbody->setUserPointer(objmesh); /* Only mark the object named "Cube" to receive a contact-added callback. */ if (!strcmp(objmesh->name, "Cube")) { /* Adjust the collision flags for this body by adding * CF_CUSTOM_MATERIAL_CALLBACK to the current flags. */ objmesh->btrigidbody->setCollisionFlags(objmesh->btrigidbody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } /* Add the new rigid body to your physical world. */ dynamicsworld->addRigidBody(objmesh->btrigidbody); }