I have been trying to learn how to use the Horde3D
rendering engine for the past couple of days,
and so far I have managed to learn a decent amount and integrate Bullet Physics
with it as well.
My problem is in my maths for rotating and translating a node in Horde3D
to keep it in sync with Bullet Physics
.
I have a terrain and a sphere, both of which are in the Bullet Physics
dynamics world.
The sphere drops from the sky and hits the terrain and everything works fine and collides/moves around as it is supposed to.
The problem is that I can successfully translate the 3D model in Horde3D
to stay in sync with the position of the sphere shape in Bullet Physics
,
but as soon as I try to introduce rotation things start to go wrong.
It's a bit difficult to describe so I have uploaded a video of the problem to YouTube (below).
Basically, the green wireframe is the Bullet Physics
sphere shape, and the brown sphere is the sphere at the Horde3D
node.
Everything is fine while the sphere is falling, because there is no rotation, but as soon as it hits the terrain and rotation
is supposed to take place the Horde3D
node moves in a completely different direction to the Bullet Physics
wireframe.
You can see what I mean by watching the video here: http://www.youtube.com/watch?v=Yi_DJIWpxOo&feature=youtu.be
I assume this is probably a quaternion/multiplication/matrix/order of multiplication error of some kind, but I can't figure it out myself.
Horde3D
provides two ways that I know of to set a node's position.
They are:
h3dSetNodeTransform (http://www.horde3d.org/docs/html/_api.html#h3dSetNodeTransform)
h3dSetNodeTransMat (http://www.horde3d.org/docs/html/_api.html#h3dSetNodeTransMat)
I could use h3dSetNodeTransform
and set all of the Euler angles, but Bullet Physics
provides a quaternion,
so I would rather try and use translation and rotation matrices instead of converting the quaternion to Euler angles etc.
For calculations I am using GLM
, if that makes any difference, although I don't think it should do.
The code that handles the updating of the Horde3D node is as follows:
btTransform trans;
sphere_body->getMotionState()->getWorldTransform(trans);
// getOrigin() returns the absolute coordinates, so I am keeping
// track of them to make sure I translate the correct amount
glm::vec3 sphere_cur_pos = glm::vec3(
trans.getOrigin().getX(),
trans.getOrigin().getY(),
trans.getOrigin().getZ()
);
glm::mat4 sphere_node_matrix, matrix_t, matrix_r;
const float *matrix_floats;
h3dGetNodeTransMats(sphere_node, 0, &matrix_floats);
sphere_node_matrix = glm::make_mat4(matrix_floats);
matrix_t = glm::translate(
sphere_node_matrix,
sphere_cur_pos - sphere_last_pos
);
// sphere_last_pos is declared earlier in the code
sphere_last_pos = sphere_cur_pos;
btQuaternion quat = trans.getRotation();
matrix_r = glm::rotate(
matrix_t,
quat.getAngle(),
glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ())
);
h3dSetNodeTransMat(sphere_node, glm::value_ptr(matrix_r));
The above code produces the behaviour you can see in the YouTube video.
If I remove the rotation matrix and just use:
h3dSetNodeTransMat(sphere_node, glm::value_ptr(matrix_t));
then everything works fine and the sphere node stays in sync with the Bullet Physics
wireframe, but there is of course then, there is no rotation.
Can somebody point out what I am doing wrong?
If any more information is needed just let me know and I will update the question.