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);
}
Пример #3
0
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);
}