btFixedConstraint: жёсткое соединение

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


Основные принципы работы

Жёсткое соединение реализует ограничение всех шести степеней свободы: три трансляционных и три вращательных. На практике это означает:

  • Положение: объекты не могут смещаться друг относительно друга. Любая попытка переместить один объект автоматически передаёт смещение на второй.
  • Вращение: любые вращательные движения одного объекта полностью передаются второму объекту, исключая относительное вращение.
  • Сила и импульс: соединение автоматически вычисляет силы и моменты, необходимые для поддержания фиксации, учитывая массу и инерцию обоих тел.

Жёсткое соединение является строгим, поэтому при неправильной настройке или слишком большом времени шага интеграции могут возникать численные нестабильности. Рекомендуется использовать мелкий шаг симуляции и правильные параметры массы для всех связанных объектов.


Создание btFixedConstraint

В Ammo.js btFixedConstraint создаётся на основе двух объектов (rigid bodies) и двух локальных трансформаций. Основной конструктор выглядит следующим образом:

const fixedConstraint = new Ammo.btFixedConstraint(
    bodyA,                  // Первый rigid body
    bodyB,                  // Второй rigid body
    frameInA,               // btTransform относительно bodyA
    frameInB                // btTransform относительно bodyB
);

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

  • bodyA, bodyB – объекты типа btRigidBody, которые необходимо соединить.
  • frameInA, frameInB – объекты типа btTransform, определяющие локальное положение и ориентацию соединения относительно каждого тела. Эти трансформации задают, где и как тела будут фиксированы относительно друг друга.

Пример создания локального трансформа:

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

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

Настройка жёсткости и ограничений

Хотя btFixedConstraint фиксирует все степени свободы, в Ammo.js существует возможность настройки ограничений с помощью методов setLinearLowerLimit, setLinearUpperLimit, setAngularLowerLimit, setAngularUpperLimit, если требуется смягчение или частичное ограничение движения:

fixedConstraint.setLinearLowerLimit(new Ammo.btVector3(0, 0, 0));
fixedConstraint.setLinearUpperLimit(new Ammo.btVector3(0, 0, 0));
fixedConstraint.setAngularLowerLimit(new Ammo.btVector3(0, 0, 0));
fixedConstraint.setAngularUpperLimit(new Ammo.btVector3(0, 0, 0));

В данном случае все ограничения полностью блокированы, что соответствует типичной конфигурации жёсткого соединения.


Интеграция с миром физики

После создания btFixedConstraint объект нужно добавить в физический мир через addConstraint:

physicsWorld.addConstraint(fixedConstraint, true);

Параметр true указывает на то, что соединение должно быть collision-disabled, то есть тела, соединённые жёстко, не будут сталкиваться друг с другом, что предотвращает артефакты при симуляции.


Применение и особенности

  • Моделирование сложных конструкций: фиксированные соединения подходят для объединения частей механизмов, мебели, зданий или роботов.
  • Оптимизация производительности: жёсткие соединения устраняют необходимость расчёта относительного движения между объектами, снижая нагрузку на симуляцию.
  • Комбинирование с другими constraints: можно сочетать с вращательными или пружинными соединениями для создания гибридных моделей.
  • Влияние массы: при добавлении жёсткого соединения важно, чтобы масса объектов была адекватно сбалансирована. Несбалансированные массы могут вызывать рывки или нестабильность при симуляции.

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

  1. Фиксация деталей мебели: столешница и ножки, которые должны оставаться неподвижными относительно друг друга.
  2. Создание транспортных средств: соединение кабины и шасси, когда относительное движение недопустимо.
  3. Стабилизация объектов сцены: например, лампы, колонны или объекты, которые должны быть статичными, но участвовать в столкновениях.

Советы по производительности и стабильности

  • Использовать шаг симуляции ≤ 1/60 секунды для динамических объектов.
  • Избегать слишком высоких масс у одного из соединённых тел относительно другого.
  • Применять collisionDisabled для предотвращения внутренних столкновений.
  • Проверять начальные трансформации frameInA и frameInB на совпадение с реальной позицией тел.

Жёсткие соединения в Ammo.js обеспечивают надежный способ создания фиксированных связей между объектами с минимальной дополнительной логикой, что делает их идеальным инструментом для статичных и полустатичных конструкций в 3D-сценах на JavaScript.