btBvhTriangleMeshShape: точная сетка для статики

btBvhTriangleMeshShape — это специализированный класс в Ammo.js, предназначенный для создания коллизий на основе статических треугольных сеток. В отличие от простых примитивов, таких как btBoxShape или btSphereShape, данная структура позволяет моделировать сложные геометрии, сохраняя высокую точность для статических объектов сцены. Она не предназначена для динамических тел, так как использование динамических треугольных мешей может привести к падению производительности и нестабильной физике.


Основные характеристики

  • Статика: подходит исключительно для объектов, которые не перемещаются во время симуляции. Для подвижных объектов следует использовать btConvexHullShape или btCompoundShape.
  • Точная коллизия: каждая грань меша учитывается при вычислениях столкновений.
  • BVH-структура: применяет Bounding Volume Hierarchy, что позволяет ускорить поиск столкновений, минимизируя количество проверяемых треугольников.

Примечание: BVH строится один раз при создании меша и не обновляется динамически, что делает эту форму эффективной для сложных сцен с большим количеством статических объектов.


Создание btBvhTriangleMeshShape

Для построения точной коллизии требуется сначала собрать геометрию с помощью btTriangleMesh. Пример последовательности действий:

// Создание контейнера для треугольников
let triangleMesh = new Ammo.btTriangleMesh();

// Добавление треугольников
triangleMesh.addTriangle(
    new Ammo.btVector3(0, 0, 0),
    new Ammo.btVector3(1, 0, 0),
    new Ammo.btVector3(0, 1, 0),
    true
);

// Создание точной сеточной формы
let useQuantizedAabbCompression = true; // оптимизация памяти и скорости
let meshShape = new Ammo.btBvhTriangleMeshShape(triangleMesh, useQuantizedAabbCompression);

Ключевые моменты при создании:

  • addTriangle(v0, v1, v2, removeDuplicateVertices) — добавляет треугольник, параметр removeDuplicateVertices помогает экономить память, объединяя одинаковые вершины.
  • useQuantizedAabbCompression — сжатие AABB ускоряет столкновения и уменьшает расход памяти, рекомендуется включать для больших мешей.

Настройка коллизий

btBvhTriangleMeshShape работает с btRigidBody, но только как статическое тело. Для этого используется btRigidBodyConstructionInfo с нулевой массой:

let mass = 0; // статическое тело
let localInertia = new Ammo.btVector3(0, 0, 0);

let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, new Ammo.btDefaultMotionState(), meshShape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);

physicsWorld.addRigidBody(body);

Особенности:

  • Любое статическое тело с btBvhTriangleMeshShape не требует вычисления инерции.
  • Перемещение или вращение тела возможно через установку трансформации (setWorldTransform), но физический расчет столкновений с динамическими телами будет корректен только для текущей позиции.

Производительность и оптимизация

  1. Использование BVH: обеспечивает логарифмическое время поиска столкновений вместо проверки каждого треугольника.
  2. Разделение больших мешей: если сцена содержит один огромный меш, стоит разделить его на несколько меньших btBvhTriangleMeshShape, чтобы избежать долгого построения BVH и ускорить рендеринг.
  3. Quantized AABB Compression: уменьшает количество вычислений при столкновениях и экономит память.
  4. Отсутствие динамики: попытки использовать эту форму для подвижных объектов могут вызвать артефакты и падение FPS.

Примеры использования

  • Статические уровни и ландшафты в играх.
  • Сложные здания или архитектурные объекты, где точная форма важнее производительности примитивов.
  • Террейны, которые имеют неровные поверхности, скальные образования, трещины и другие детали, критичные для физики.

Работа с трансформацией и столкновениями

Для корректного взаимодействия с динамическими телами необходимо учитывать:

let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(10, 0, -5));
body.setWorldTransform(transform);
  • setIdentity() сбрасывает предыдущую трансформацию.
  • setOrigin() перемещает тело в заданное положение.
  • Ротацию можно задавать через setRotation(quaternion), где quaternionbtQuaternion.

Динамические объекты будут корректно реагировать на столкновения с этим телом без необходимости пересчитывать BVH, так как BVH рассчитан для статичных объектов.


Примечания по совместимости

  • Не поддерживает физику мягких тел или тел с деформацией.
  • Не использовать для частых изменений меша; для динамических изменений подойдет btGImpactMeshShape.
  • Отлично интегрируется с другими формами Ammo.js и может использоваться вместе с btCompoundShape для комбинирования нескольких статических мешей.

btBvhTriangleMeshShape — основной инструмент для создания высокоточных статических коллизий в Ammo.js. Его правильное использование обеспечивает реалистичные взаимодействия динамических тел с статической сценой без потери производительности на больших мешах.