Закрепление узлов к миру и к твёрдым телам: appendAnchor

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


Принцип работы appendAnchor

Метод appendAnchor создаёт фиксированное соединение между объектом (чаще всего btRigidBody) и целевой точкой. Эта точка может быть:

  • Абсолютной в мире — закрепление к координатам сцены, исключая перемещение.
  • Относительной к другому телу — фиксация объекта на другом движущемся теле.

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


Синтаксис метода

softBody.appendAnchor(nodeIndex, body, disableCollisionBetweenLinkedBodies = true, influence = 1.0);

Параметры:

  • nodeIndex — индекс узла в массиве вершин softBody. Узлы — это точки, на которых строится сетка мягкого тела.
  • body — объект btRigidBody или null. Если null, привязка идёт к фиксированной точке мира.
  • disableCollisionBetweenLinkedBodies — логическое значение. Если true, исключается столкновение между телами, связанными якорем.
  • influence — сила влияния якоря на узел. Значение 1.0 означает полное закрепление, меньшие значения создают эффект “пружины”.

Закрепление к миру

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

  • Подвешивания мягких тел (тканей, верёвок, сетей) на неподвижных точках.
  • Создания фиксированных концов деформируемых объектов.
  • Симуляции креплений, например, карнизов или растяжек.

Пример:

// softBody — btSoftBody, создаваемый из меша
const fixedNodeIndex = 0; // первый узел
softBody.appendAnchor(fixedNodeIndex, null, true, 1.0);

В этом примере первый узел полностью закреплён в пространстве. Он не двигается и не реагирует на столкновения.


Закрепление к твёрдым телам

Привязка к другому объекту btRigidBody создаёт динамическое соединение, которое учитывает движение и вращение тела. Это позволяет моделировать:

  • Подвешенные объекты на движущихся платформах.
  • Динамические соединения мягких тел с роботизированными компонентами.
  • Контакт мягких тел с персонажами или транспортом.

Пример:

const nodeIndex = 5; // узел мягкого тела
const rigidBody = myRigidBody; // btRigidBody, к которому привязываем
softBody.appendAnchor(nodeIndex, rigidBody, true, 0.8);

В этом случае узел мягкого тела следует за телом rigidBody, сохраняя влияние на уровне 0.8, что создаёт эффект упругого соединения, а не жёсткой фиксации.


Особенности поведения якорей

  1. Influence — ключевой параметр. Значения:

    • 1.0 — узел полностью фиксирован.
    • 0.0 — якорь не влияет.
    • 0.1–0.9 — создаёт эффект мягкой фиксации, как пружина.
  2. disableCollisionBetweenLinkedBodies предотвращает самоконфликты. Если мягкое тело и твёрдое тело находятся в одной зоне, без отключения столкновений возможны нежелательные силы реакции.

  3. Множественные якоря — один узел может быть закреплён несколькими якорями к разным телам. Влияние каждого суммируется, создавая сложные динамические эффекты.


Практические рекомендации

  • Для имитации ткани лучше закреплять несколько узлов на краях сетки, оставляя центральные свободными.
  • Для подвесных объектов, например канатов или флагов, стоит использовать комбинированное закрепление к миру и к телам.
  • Если требуется визуальная гибкость, использовать значения influence < 1, чтобы узлы имели некоторую подвижность.
  • Следить за производительностью: большое количество якорей с высокой точностью может замедлить симуляцию.

Примеры типичных сценариев

Подвесной флаг

// закрепляем верхние узлы к миру
for (let i = 0; i < topNodes.length; i++) {
    softBody.appendAnchor(topNodes[i], null, true, 1.0);
}

Мягкая рука робота

// каждый палец прикреплён к твёрдому телу
fingersNodes.forEach((node, idx) => {
    softBody.appendAnchor(node, robotFingers[idx], true, 0.9);
});

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


appendAnchor в Ammo.js является инструментом для точного контроля над поведением узлов мягких тел, позволяя моделировать реальные закрепления и динамические соединения с другими объектами сцены, сохраняя при этом естественную гибкость.