【问题标题】:Getting bullet physics transform matrix for Opengl获取 Opengl 的子弹物理变换矩阵
【发布时间】:2014-02-25 00:23:40
【问题描述】:

到目前为止,我正在使用以下代码从刚体中的子弹中获取变换矩阵并将其应用于我的实例。现在它似乎没有更新我渲染的立方体的变换,我的第一个想法是相信我在创建 glm mat4 时丢失了数据。所以我的问题是我是否正确转换数据以转换我的矩阵?

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);
}

【问题讨论】:

标签: opengl-3 glm-math bulletphysics


【解决方案1】:

如果你想要完整的转换,你应该这样做:

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));

由于您目前只创建一个平移矩阵,因此您会失去方向/旋转,并最终进行缩放。

另请注意,从 Bullet 返回的矩阵位于世界空间中,因此,如果您有一个场景层次结构/图形,其中矩阵存储为节点父节点的相对变换,您可能还希望将矩阵变换到本地空间,如果需要的话。

【讨论】:

    【解决方案2】:

    要从 Bullet Physics 获取模型矩阵到 OpenGL,请声明 btScalar transform[16],然后查询身体运动状态。对于静态对象,请改用 m_rigidBody-&gt;getWorldTransform(),因为静态对象的运动状态不会更新(在 GitHub 上创建的错误报告)。

    通过调用第一个实用方法 btScalar2mat4() 或调用 Bullet Physics 方法 transform.getOpenGLMatrix(btScalar *array) 重新格式化模型矩阵,返回一个指向 16 元素行主数组的指针以传递到第二个实用方法 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;
    }
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
    • @Carpetsmoker 完成,感谢您的有用建议!
    • 很好的答案,非常完整,正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多