Hm, a snippet from the documentation and an older conversation seem to pinpoint to the solution.
However I think there's a more compact solution based on what I found in past conversations
1st Way
http://www.bulletphysics.org/Bullet/php ... f=9&t=2209
There is still a visual offset between the object and the drawn center-of-mass (3-axis system), but the physical simulation now is as expected.
(NOTE: the sphere is a nice sphere, it appears a bit distorted only because of the virtual camera)
In the following pModel is my own custom class, and the centroid4d_curr, which is the centroid of the vertices, is computed manually.
Code: Select all
for (int trr=0; trr<pModel->totalTriangles; trr++)
{
Eigen::Vector3d v1 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_1 ];
Eigen::Vector3d v2 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_2 ];
Eigen::Vector3d v3 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_3 ];
btVector3 bv1 = btVector3( (float)v1(0), (float)v1(1), (float)v1(2) );
btVector3 bv2 = btVector3( (float)v2(0), (float)v2(1), (float)v2(2) );
btVector3 bv3 = btVector3( (float)v3(0), (float)v3(1), (float)v3(2) );
bool removeDuplicateVertices = true;
pModel->bt_Mesh->addTriangle( bv1, bv2, bv3, removeDuplicateVertices );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
pModel->bt_CompoundShape = new btCompoundShape();
//////////////////////////////////////////////////////////////////////////////////////////////////////
btCollisionShape* bt_CollisionShape = new btConvexTriangleMeshShape( pModel->bt_Mesh, true );
//////////////////////////////////////////////////////////////////////////////////////////////////////
btTransform localTrans;
localTrans.setIdentity();
localTrans.setOrigin( btVector3( -pModel->centroid4D_curr(0),
-pModel->centroid4D_curr(1),
-pModel->centroid4D_curr(2) ) );
pModel->bt_CompoundShape->addChildShape(localTrans,bt_CollisionShape);
//////////////////////////////////////////////////////////////////////////////////////////////////////
btDefaultMotionState *bt_MotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3( +pModel->centroid4D_curr(0),
+pModel->centroid4D_curr(1),
+pModel->centroid4D_curr(2) ) ) );
btScalar bt_Mass;
bt_Mass = 10;
btVector3 bt_Inertia(0,0,0);
pModel->bt_CompoundShape->calculateLocalInertia( bt_Mass, bt_Inertia );
btRigidBody::btRigidBodyConstructionInfo bt_RigidBodyCI( bt_Mass, bt_MotionState, pModel->bt_CompoundShape, bt_Inertia );
pModel->bt_RigidBody = new btRigidBody( bt_RigidBodyCI );
//////////////////////////////////////////////////////////////
2nd Way
However an even simpler way makes things a bit better:
The physical simulation is normal same as above, but also the center-of-mass (3-axis system) appears at the center of the object.
In the beginning all vertices the centroid is subtracted by all vertices (i.e. move the object @ the origin), and then the collision model is transformed with the coordinates of the centroid.
Code: Select all
for (int trr=0; trr<pModel->totalTriangles; trr++)
{
Eigen::Vector3d v1 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_1 ];
Eigen::Vector3d v2 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_2 ];
Eigen::Vector3d v3 = pModel->mesh.verticesWeighted[ pModel->mesh.triangles[trr].vertexID_3 ];
btVector3 bv1 = btVector3( v1(0)-pModel->centroid4D_curr(0), v1(1)-pModel->centroid4D_curr(1), v1(2)-pModel->centroid4D_curr(2) );
btVector3 bv2 = btVector3( v2(0)-pModel->centroid4D_curr(0), v2(1)-pModel->centroid4D_curr(1), v2(2)-pModel->centroid4D_curr(2) );
btVector3 bv3 = btVector3( v3(0)-pModel->centroid4D_curr(0), v3(1)-pModel->centroid4D_curr(1), v3(2)-pModel->centroid4D_curr(2) );
bool removeDuplicateVertices = true;
pModel->bt_Mesh->addTriangle( bv1, bv2, bv3, removeDuplicateVertices );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
pModel->bt_CollisionShape = new btConvexTriangleMeshShape( pModel->bt_Mesh, true );
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
btDefaultMotionState *bt_MotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3( +pModel->centroid4D_curr(0),
/**/ +pModel->centroid4D_curr(1),
/**/ +pModel->centroid4D_curr(2) ) ) );
btScalar bt_Mass = 50;
btVector3 bt_Inertia(0,0,0);
pModel->bt_CollisionShape->calculateLocalInertia( bt_Mass, bt_Inertia );
btRigidBody::btRigidBodyConstructionInfo bt_RigidBodyCI( bt_Mass, bt_MotionState, pModel->bt_CollisionShape, bt_Inertia );
pModel->bt_RigidBody = new btRigidBody( bt_RigidBodyCI );