2014-06-20 2 views
0

Je développe un moteur de jeu en C# et j'utilise BulletSharp pour la physique. Cela fonctionne bien, sauf avec des cubes:Bullet Physics Coques convexes avec des cubes

http://i.stack.imgur.com/EPfrw.png

(La boîte englobante Axis-Alignés est le rouge transparent, le modèle est le blanc)

Au repos, la position sur leurs bords. Comme je charge des modèles Collada, je crée un ConvexHullShape() et j'ajoute les données sous forme de nuage vectoriel. Tout en utilisant BoxShape() serait plus efficace (et fonctionnerait correctement), je ne peux pas car il n'est pas garanti que tous les modèles sont des cubes. Je ne peux pas comprendre pourquoi ils reposent sur les sommets et non sur les bords plats. Mon implémentation de ConvexHullShape est-elle incorrecte ou dois-je utiliser un autre type de forme (pour que la physique fonctionne correctement)?

public RigidBody AddDynamicGeometry(ColladaGeometry geometry, Matrix4 transform) 
     { 
      List<Vector3> points = new List<Vector3>(); 
      foreach (Triangle tri in geometry.triangles) 
      { 
       points.Add(tri.vertices[0]); 
       points.Add(tri.vertices[1]); 
       points.Add(tri.vertices[2]); 
      } 
      CollisionShape shape = new ConvexHullShape(points); 



      shape.UserObject = geometry; 

      collisionShapes.Add(shape); 

      RigidBody body = CreateRigidBody(geometry.triangles.Count * 10, transform, shape); 

      return body; 
     } 

     public RigidBody CreateRigidBody(float mass, Matrix4 startTransform, CollisionShape shape) 
     { 
      bool isDynamic = (mass != 0.0f); 

      Vector3 localInertia = Vector3.Zero; 
      if (isDynamic) 
       shape.CalculateLocalInertia(mass, out localInertia); 

      DefaultMotionState myMotionState = new DefaultMotionState(startTransform); 

      RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia); 
      RigidBody body = new RigidBody(rbInfo); 

      physics_world.AddRigidBody(body); 

      return body; 
     } 

Répondre

1

ConvexHullShape attend le centre de masse (COM) pour être (0,0,0), mais le cube est décalé par rapport au centre, ce qui en fait basculer vers le coin.

Vous pouvez trouver la bonne COM avec ConvexTriangleMeshShape.CalculatePrincipalAxisTransform. Ensuite, vous pouvez soustraire le COM de chaque sommet pour ramener le COM à 0. Cependant, il est plus facile de créer un CompoundShape avec un centre local pour le cube.

// Create a ConvexTriangleMeshShape from the points 
const int indexStride = 3 * sizeof(int); 
const int vertexStride = 12; 
int vertexCount = points.Count; 
int indexCount = vertexCount/3; 

TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(); 
IndexedMesh mesh = new IndexedMesh(); 
mesh.Allocate(vertexCount, vertexStride, indexCount, indexStride); 
Vector3Array vdata = mesh.Vertices; 
IntArray idata = mesh.TriangleIndices; 
for (int i = 0; i < vertexCount; i++) 
{ 
    vdata[i] = points[i]; 
    idata[i] = i; 
} 
vertexArray.AddIndexedMesh(mesh); 
ConvexTriangleMeshShape shape = new ConvexTriangleMeshShape(vertexArray, true); 

// Calculate center of mass 
Matrix center = Matrix.Identity; 
Vector3 inertia; 
float volume; 
shape.CalculatePrincipalAxisTransform(ref center, out inertia, out volume); 

// Create a CompoundShape with COM offset 
CompoundShape compound = new CompoundShape(); 
compound.AddChildShape(Matrix.Invert(center), shape); 

Note: ConvexTriangleMeshShape.CalculatePrincipalAxisTransform fonctionne dans le coffre SVN, mais pas dans BulletSharp 2,82. Il y aura une version de correction de bug bientôt.

Questions connexes