btHingeConstraint: петля с ограничением угла

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

Создание btHingeConstraint

Конструктор петли имеет несколько вариантов. Основные из них:

// Вариант 1: петля между двумя телами
let hinge = new Ammo.btHingeConstraint(
    bodyA,            // Первое rigid body
    bodyB,            // Второе rigid body
    pivotInA,         // Локальная точка соединения в bodyA
    pivotInB,         // Локальная точка соединения в bodyB
    axisInA,          // Локальная ось вращения в bodyA
    axisInB,          // Локальная ось вращения в bodyB
    useReferenceFrameA // true или false, для ориентации в системе A или B
);

// Вариант 2: петля одного тела относительно мировых координат
let hingeSingle = new Ammo.btHingeConstraint(
    body,             // rigid body
    pivot,            // Точка в локальных координатах тела
    axis               // Ось вращения в локальных координатах тела
);

Ключевые параметры:

  • pivotInA/pivotInB — векторы типа btVector3, задающие точку крепления в локальных координатах каждого тела.
  • axisInA/axisInB — векторы, определяющие направление оси вращения. Должны быть нормализованы.
  • useReferenceFrameA — булево значение, определяющее, будет ли ограничение считаться относительно тела A.

Ограничение углов

Ограничение углов задается методом setLimit:

hinge.setLimit(low, high, softness, biasFactor, relaxationFactor);
  • low и high — минимальный и максимальный угол в радианах.
  • softness — коэффициент мягкости ограничения (0 — жестко, 1 — полностью мягко).
  • biasFactor — коэффициент коррекции для смещения угла при столкновениях.
  • relaxationFactor — скорость достижения ограничения при динамике.

Пример ограничения вращения двери на ±90°:

hinge.setLimit(-Math.PI/2, Math.PI/2, 0.9, 0.3, 1.0);

Получение текущего угла

Текущий угол вращения можно получить через метод getHingeAngle:

let angle = hinge.getHingeAngle();

Метод возвращает угол в радианах, учитывая ориентацию тел и установленное ограничение.

Управление мотором

btHingeConstraint поддерживает встроенный мотор, позволяющий вращать тело автоматически:

// Включение мотора
hinge.enableMotor(true);
hinge.setMotorTargetVelocity(velocity); // скорость вращения в рад/сек
hinge.setMaxMotorImpulse(maxImpulse);   // максимальная сила, применяемая мотором
  • velocity — целевая скорость вращения.
  • maxImpulse — сила, ограничивающая мотор, чтобы избежать резких движений.

Для более точного контроля можно использовать позиционный мотор:

hinge.enableAngularMotor(true, targetVelocity, maxMotorImpulse);

Позиционный мотор автоматически корректирует положение, чтобы достигнуть заданного угла.

Применение трансформаций

btHingeConstraint корректно работает с btTransform объектов. Для установки нового положения тела:

let trans = new Ammo.btTransform();
trans.setIdentity();
trans.setOrigin(new Ammo.btVector3(x, y, z));
body.setWorldTransform(trans);

Важно поддерживать согласованность локальных осей тела и петель, чтобы избежать непредсказуемой динамики.

Интеграция в физический мир

Для добавления петли в симуляцию используется метод addConstraint объекта btDiscreteDynamicsWorld:

world.addConstraint(hinge, true); // true — включает возможность коллизий между телами

Практические советы

  1. Нормализация осей: любые векторы осей должны быть нормализованы, иначе движение может быть нестабильным.
  2. Мягкие ограничения: значение softness между 0.8 и 1.0 снижает вероятность рывков при быстром столкновении.
  3. Разделение тел: при больших массах рекомендуется использовать отдельные трансформации и учитывать центры масс, чтобы петля работала корректно.
  4. Отладка углов: метод getHingeAngle полезен для визуализации текущей позиции двери или рычага в реальном времени.

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