1

我正在编写一个基本的游戏引擎来帮助我完成关于多智能体学习的博士课题。我使用 PyBullet 作为后端物理引擎,使用 OpenGL 进行视觉显示。我设置了 OpenGL 缓冲区来保存对象信息,例如位置(vec3)和旋转(matrix4x4),旋转是使用四元数完成的,但为方便起见,使用欧拉角存储。

我的问题是,当我在 OpenGL 游戏世界中(围绕任何轴)旋转对象时,pyBullet 旋转(从 pyBullet GUI 中看到)是相反的方向,有时完全关闭。我一定错过了一些安静的基本内容,如果这是一个简单的解决方法,我深表歉意。我还提供了一个视频来显示我遇到的问题 - 链接到错误视频(https://youtu.be/4VpBUx5LBYQ):

当我使用 PyBullet 提取旋转并使用getBasePositionAndOrientation()将四元数转换为欧拉角pybullet.getEulerFromQuaternion()时,结果是正确的 vec3,但在转换为旋转矩阵pybullet.getMatrixFromQuaternion()时,它似乎反转了旋转方向。

请在下面查看我的代码:


'obj = Class BaseSceneObject'
'action = Euler rotation angle in degrees to apply vec3(x, y, z) e.g.(1., 0., 0.) apply +1 degree rotation to x-axis'

'Collect current position and rotation of object and update PyBullet'
# get the rotation - euler angles in degrees vec3(x,y,z)
rot = obj.get_rotation()
# add rotation action (e.g. +1 degree to x = vec3(1., 0., 0.)) and convert to radians
rot = math.radians(rot[0] + action[0]), math.radians(rot[1] + action[1]), math.radians(rot[2] + action[2])
# convert rotation from euler to quaternion
quat = pybullet.getQuaternionFromEuler(rot)
# update position and orientation
pybullet.resetBasePositionAndOrientation(bodyUniqueId=obj.get_rigid_body_id(),
                                         posObj=obj.get_position(),
                                         ornObj=quat)

'Collect PyBullet results and update OpenGL'
# get position and rotation from PyBullet
position, rotation = pybullet.getBasePositionAndOrientation(bodyUniqueId=obj.get_rigid_body_id())
# update object position
obj.set_position(position=position)
# convert rotation quaternion to euler angles
rot_r = pybullet.getEulerFromQuaternion(rotation)
# convert radians to degrees
rot_d = math.degrees(rot_r[0]), math.degrees(rot_r[1]), math.degrees(rot_r[2])
# construct OpenGL object rotation matrix
rot_m_final = numpy.identity(4)
rot_mr = numpy.array(pybullet.getMatrixFromQuaternion(rotation)).reshape(3, 3)
rot_m_final[:3, :3] = rot_mr
# update OpenGL rotation matrix
obj.set_rotation(rotation=rot_d,
                 rotation_matrix=rot_m_final)
4

1 回答 1

1

事实证明,上面的代码是正确的。问题存在于 OpennGL 着色器中,我忘记了矩阵计算是不可交换的,即 numpy.matmul(Mat4(Rotation), Vec4(position)) 与 numpy.matmul(Vec4(position), Mat4(Rotation) 不同))。

从以下位置更新我的着色器代码后: vec4 aRPos = vec4(aRotation * aVertex); 至:vec4 aRPos = vec4(aVertex * aRotation);

它工作得很好。谢谢你。

于 2020-08-09T21:51:54.310 回答