btConvexTriangleMeshShape weird behaviour @ collisions

Post Reply
dim_tz
Posts: 11
Joined: Sun Apr 06, 2014 5:27 pm

btConvexTriangleMeshShape weird behaviour @ collisions

Post by dim_tz »

I just stumbled upon a weird problem.

When I create a simple spherical object and let it fall to the ground, depending on the restitution it might bounce a little bit or not, but then it reaches a stable state in a pretty predictive way.

Code: Select all

btCollisionShape* ballShape = new btSphereShape(10);
However, when I use my custom spherical mesh (960 triangles, 482 vertices) and I create a btConvexTriangleMeshShape based on this, when the ball falls down and touches the ground, then some weird forces make the ball bounce to a weird direction almost parallel to the ground and then it rolls back and forth for quite some time, to reach the stable position only much time later. The whole process is not realistic at all.

Code: Select all

pModel->bt_CollShape = new btConvexTriangleMeshShape( pModel->bt_Mesh, true );
Any hint on how to solve this issue?
dim_tz
Posts: 11
Joined: Sun Apr 06, 2014 5:27 pm

Re: btConvexTriangleMeshShape weird behaviour @ collisions

Post by dim_tz »

New observation: it seems that the mass center (this drawn little 3d axis-system that accompanies the object) for collisions is NOT the centroid of the vertices.
I'm not sure how to correct this, setCenterOfMassTransform doesn't help, since it transforms also the vertices/triangles.
If anybody has a hint it would be nice.
dim_tz
Posts: 11
Joined: Sun Apr 06, 2014 5:27 pm

Re: btConvexTriangleMeshShape weird behaviour @ collisions

Post by dim_tz »

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

Image

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)
Image

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.

Image

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 );
Post Reply