到目前为止,我使用下面的代码从子弹中的刚体获取变换矩阵并将其应用于我的实例。现在它似乎没有更新我渲染的立方体的变换,我的第一个虽然是相信我在创建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);
}
如果您想要完整转换,您应该:
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返回的矩阵在世界空间中,所以如果你有一个场景层次/图形,矩阵存储为相对变换到节点的父节点,你可能还想将矩阵转换为局部空间,如果需要的话。
要从Bullet Physics获取模型矩阵到OpenGL,声明一个btScalar transform[16]
,然后查询身体运动状态。对于静态对象,请使用m_rigidBody->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;
}