btConvexHullShape: выпуклая оболочка по точкам

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

Создание объекта btConvexHullShape

Конструктор принимает массив координат точек в формате Float32Array или обычного массива чисел. Каждая точка задается тройкой координат [x, y, z]. Для добавления точек можно использовать методы addPoint или передавать массив сразу при инициализации:

const points = [
    1, 1, 1,
    -1, 1, 1,
    -1, -1, 1,
    1, -1, 1,
    1, 1, -1,
    -1, 1, -1,
    -1, -1, -1,
    1, -1, -1
];

const hullShape = new Ammo.btConvexHullShape();

for (let i = 0; i < points.length; i += 3) {
    const point = new Ammo.btVector3(points[i], points[i + 1], points[i + 2]);
    hullShape.addPoint(point, true); // true — пересчитывать локальный AABB после добавления
}
  • addPoint(btVector3 point, recalcLocalAabb = true) — добавляет точку к оболочке. Параметр recalcLocalAabb контролирует пересчет локальной оси ограничивающего блока (AABB). Если добавляется много точек, рекомендуется сначала добавить все точки с false, а затем вызвать recalcLocalAabb один раз для оптимизации.

Основные свойства

  • localScaling — масштабирование объекта. Изменение масштаба влияет на все точки оболочки.
  • margin — дополнительная «подушка» вокруг фигуры для стабильности столкновений. Обычно устанавливается по умолчанию в 0.04.
  • numPoints — количество добавленных вершин.
  • localAabbMin / localAabbMax — минимальные и максимальные координаты локального ограничивающего блока.
hullShape.setMargin(0.05);
hullShape.setLocalScaling(new Ammo.btVector3(2, 1, 1));

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

btConvexHullShape автоматически строит выпуклую оболочку, но при большом количестве точек важно оптимизировать процесс:

  1. Отсечение лишних точек: дублирующиеся или коллинеарные точки увеличивают вычислительную нагрузку.
  2. Отключение пересчета AABB при добавлении каждой точки: лучше добавить все точки с recalcLocalAabb=false, а затем вызвать recalcLocalAabb() один раз.
  3. Использование локального масштаба: масштабирование через setLocalScaling дешевле, чем пересоздание оболочки.

Применение в физическом мире

Выпуклые оболочки особенно эффективны для сложных, но все еще выпуклых объектов:

  • Камни, коробки, контейнеры.
  • Стены, препятствия с неровной поверхностью.
  • Прототипирование объектов без необходимости создавать треугольные сетки.
const mass = 1;
const localInertia = new Ammo.btVector3(0, 0, 0);
hullShape.calculateLocalInertia(mass, localInertia);

const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0, 5, 0));

const motionState = new Ammo.btDefaultMotionState(transform);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, hullShape, localInertia);
const body = new Ammo.btRigidBody(rbInfo);

physicsWorld.addRigidBody(body);
  • calculateLocalInertia(mass, inertiaVector) — вычисляет инерцию объекта, необходимую для динамических тел.
  • btRigidBodyConstructionInfo и btRigidBody создают физическое тело, которое можно добавлять в btDiscreteDynamicsWorld.

Особенности работы с точками

  • Порядок добавления точек не имеет значения для формы.
  • Форма всегда будет выпуклой, даже если исходный набор точек образует вогнутую фигуру.
  • Для вогнутых объектов нужно использовать другие типы коллайдеров (например, btBvhTriangleMeshShape), так как btConvexHullShape не поддерживает вогнутости.

Методы полезные для анализа формы

  • getNumPoints() — возвращает количество точек.
  • getPoint(i) — возвращает точку с индексом i в виде btVector3.
  • recalcLocalAabb() — пересчитывает локальный ограничивающий блок после изменения точек.

Советы по интеграции

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

btConvexHullShape является мощным инструментом для физического моделирования сложных объектов с минимальными усилиями по построению геометрии и обеспечивает баланс между точностью и производительностью при использовании в Ammo.js.