Выпуклые оболочки физики пули с кубами

#c# #bulletphysics

#c# #Физика пули

Вопрос:

Я разрабатываю игровой движок на c # и использую BulletSharp для физики. Он работает хорошо, за исключением кубов:

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

(Ограничивающая рамка, выровненная по оси, — прозрачная красная, модель — белая)

В состоянии покоя они стоят на своих ребрах. Поскольку я загружаюсь из моделей Collada, я создаю ConvexHullShape() и добавляю данные в виде векторного облака. Хотя использование BoxShape() было бы более эффективным (и работало бы корректно), я не могу, поскольку не гарантируется, что все модели являются кубами. Я не могу понять, почему они опираются на вершины, а не на плоские ребра. Является ли моя реализация ConvexHullShape неправильной или мне нужно использовать другой тип формы (для правильной работы физики)?

 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;
        }
  

Ответ №1:

ConvexHullShape ожидает, что центр масс (COM) будет равен (0,0,0), но куб смещен от центра, что приводит к его наклону к углу.

Вы можете найти правильный COM с помощью ConvexTriangleMeshShape.Вычислите первичную форму преобразования галактики. Затем вы можете вычесть COM из каждой вершины, чтобы вернуть COM обратно в 0. Однако проще создать CompoundShape с локальным центром для куба.

 // 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);
  

Примечание: ConvexTriangleMeshShape.CalculatePrincipalAxisTransform работает в SVN trunk, но не в BulletSharp 2.82. Скоро будет выпущено исправление.