Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting bullet physics transform matrix for Opengl

As of now I am using the below code to get the transform matrix from my rigid body in bullet and apply it to my instance. Now right now it seems to not be updating my rendered cube's transform, my first though is to believe that I'm losing data when creating a glm mat4. So my question is am I converting the data correctly to transform my matrix?

for (int i = 0; i < WoodenCrateInstances.size(); i++)
{
    btTransform t;
    WoodenCrateInstances.at(i).asset->body->getMotionState()->getWorldTransform(t);
    float mat[16];
    t.getOpenGLMatrix(mat);
    glm::vec3 vec = glm::make_vec3(mat);
    WoodenCrateInstances.at(i).transform = glm::translate(glm::mat4(), vec);
}
like image 298
Arko Avatar asked Jan 12 '23 03:01

Arko


2 Answers

If you want the full transform, you should do:

btTransform t;

// Get the transform from Bullet and into 't'
WoodenCrateInstances.at(i).asset->body->getMotionState()->getWorldTransform(t);

// Convert the btTransform into the GLM matrix using 'glm::value_ptr'
t.getOpenGLMatrix(glm::value_ptr(WoodenCrateInstances.at(i).transform));

As you only create a translation matrix at the moment, you loose orientation/rotation, and eventually scale.

Also note, that the matrices returned from Bullet is in world space, so if you have a scene hierachy/graph with the matrices stored as relative transforms to the node's parent node, you might also want to transform the matrix into local space, if needed.

like image 86
Keemaron Avatar answered Mar 16 '23 15:03

Keemaron


To get the model matrix from Bullet Physics to OpenGL, declare a btScalar transform[16], then query the body motion state. For static objects, use instead m_rigidBody->getWorldTransform() because the motion state is not updated for static objects (bug report created on GitHub).

Reformat the model matrix by calling the first utility method btScalar2mat4() or call the Bullet Physics method transform.getOpenGLMatrix(btScalar *array) returning a pointer to a 16 elements row major array to pass onto the second utility method glm::mat4 array2mat4(const float* array).

void Cube::update(glm::mat4 T) {

    /* btScalar transform[16];

    if (m_motionState)
        m_motionState->getModelMatrix(transform); */

    if (m_rigidBody) {
        btTransform transform = m_rigidBody->getWorldTransform();

        m_modelMatrix = btScalar2glmMat4(transform);
        m_modelMatrix = T * m_modelMatrix;

        // if (VERBOSE) printMat4(m_modelMatrix);
    }
}


glm::mat4 btScalar2mat4(btScalar* matrix) {
    return glm::mat4(
        matrix[0], matrix[1], matrix[2], matrix[3],
        matrix[4], matrix[5], matrix[6], matrix[7],
        matrix[8], matrix[9], matrix[10], matrix[11],
        matrix[12], matrix[13], matrix[14], matrix[15]);
}


glm::mat4 array2mat4(const float* array) {     // OpenGL row major

    glm::mat4 matrix;

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            matrix[i][j] = array[i + j];
        }
    }

    return matrix;
}
like image 28
LastBlow Avatar answered Mar 16 '23 15:03

LastBlow