I wanted to cut down on memory overhead and load-times, so I wanted to switch from my working method A (see below) to method B (see below), however, doing this breaks a lot of things. btDebugDraw verifies that the objects seem to be in the right locations and scales, but most of the objects have incorrect rotations. Also, my btCollisionWorld::convexSweepTest -based character controller is messing up when colliding with the sides of all of the objects (but curiously, not when walking on top of them). It seems as if the hit normals that convexSweepTest returns are not correct anymore.
I'm using two things as my metric for "working vs not working":
1) I'm visually inspecting the objects using btDebugDraw and comparing them against wireframe versions of the manually-transformed versions to see if they match
2) btCollisionWorld::convexSweepTest returns vastly different results depending on the method I'm using and this messes up my character controller significantly (the hit normals seem to be entirely off)
This method A works:
So why does this method B not work?Get the translation, rotation, scaling of the mesh instance and construct a matrix out of it.
Run D3DXVec3TransformCoordArray (with the matrix we just made) on my collision vertices for every instance of every mesh.
Create a btBvhTriangleMeshShape using a btTriangleIndexVertexArray consisting of those pretransformed collision verts.
Create a btCollisionObject.
Make a btTransform and set it to the identity (using setIdentity() )
Set that btTransform as the setWorldTransform for the btCollisionObject.
Add that btCollisionObject into the btCollisionWorld.
The three (all of which don't seem to work) methods I've tried to use for setting the btTransform's rotation are:Don't pretransform the collision vertices.
Create a btBvhTriangleMeshShape using a btTriangleIndexVertexArray consisting of the untransformed collision verts.
Set the btBvhTriangleMeshShape 's local scaling to the mesh instance's scaling
Create a btCollisionObject.
Make a btTransform.
Call setOrigin on the btTransform and pass in the translation of the mesh instance.
Run one of three methods to figure out the rotation for the btTransform (they all seem to not work)
Set that btTransform as the setWorldTransform for the btCollisionObject.
Add that btCollisionObject into the btCollisionWorld.
Code: Select all
// Using the btQuaternion's euler XYZ constructor
startTransform.setRotation(btQuaternion(rotY, rotX, rotZ) );
Code: Select all
// Using D3DX to create a rotation quaternion from my mesh instance's transformation matrix (after removing the scale component) and then turning that into a btQuaternion
D3DXMATRIXA16 copymatrix = newphysicsmatrix;
copymatrix._11 /= scale;
copymatrix._22 /= scale;
copymatrix._33 /= scale;
D3DXQUATERNION out;
D3DXQuaternionRotationMatrix(&out, ©matrix);
startTransform.setRotation(btQuaternion(out.x, out.y, out.z, out.w) );
Code: Select all
// Using the setFromOpenGLMatrix function (after removing the scale component from the transformation matrix)
startTransform.setFromOpenGLMatrix( (const float* const)©matrix);