Шарнир с фиксацией: GenericJoint

GenericJoint — один из самых универсальных типов шарниров в библиотеке Oimo.js, предназначенный для точного управления степенями свободы соединяемых тел. Он позволяет комбинировать различные ограничения вращения и перемещения, создавая конструкции от простых дверных петель до сложных механизмов роботов.

Основные концепции

GenericJoint работает между двумя телами (bodyA и bodyB) и задаёт ограничения по шести степеням свободы: три вращательные (Roll, Pitch, Yaw) и три линейные (X, Y, Z). Каждая степень свободы может быть:

  • Свободной (free) — движение не ограничено.
  • Фиксированной (fixed) — движение полностью заблокировано.
  • Ограниченной диапазоном (limited) — движение возможно только в пределах заданного диапазона.

Степени свободы задаются через методы setLinearLimit и setAngularLimit, позволяя комбинировать различные типы ограничений для одной оси.

Создание GenericJoint

Создание шарнира начинается с инициализации через конструктор:

const joint = new OIMO.GenericJoint({
    bodyA: rigidBodyA,
    bodyB: rigidBodyB,
    position: new OIMO.Vec3(0, 1, 0),
    axis1: new OIMO.Vec3(1, 0, 0),
    axis2: new OIMO.Vec3(0, 1, 0)
});
  • bodyA, bodyB — тела, соединяемые шарниром.
  • position — точка соединения в мировых координатах.
  • axis1, axis2 — локальные оси вращения для каждого тела. Их ориентация определяет направления возможного вращения.

Линейные ограничения

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

joint.setLinearLimit(axis, min, max);
  • axis — индекс оси (0 — X, 1 — Y, 2 — Z).
  • min, max — минимальное и максимальное смещение по этой оси.

Пример: блокировка смещения по оси Y и разрешение движения по X и Z в диапазоне:

joint.setLinearLimit(0, -2, 2); // X
joint.setLinearLimit(1, 0, 0);  // Y фиксированная
joint.setLinearLimit(2, -1, 1); // Z

Вращательные ограничения

Angular limits задаются аналогично, но для вращательных осей:

joint.setAngularLimit(axis, min, max);
  • axis — индекс вращательной оси (0 — X, 1 — Y, 2 — Z).
  • min, max — угловые ограничения в радианах.

Пример: вращение вокруг X разрешено только в пределах ±45°, вокруг Y заблокировано, вокруг Z свободно:

joint.setAngularLimit(0, -Math.PI/4, Math.PI/4);
joint.setAngularLimit(1, 0, 0);
joint.setAngularLimit(2, -Infinity, Infinity);

Настройка жесткости и демпфирования

GenericJoint поддерживает настройку жесткости (spring) и демпфирования (damping) для плавного контроля движения. Они задаются для каждой оси отдельно:

joint.setSpring(axis, stiffness, damping);
  • stiffness — коэффициент упругости, чем выше значение, тем сильнее сопротивление отклонению.
  • damping — коэффициент демпфирования, уменьшает колебания после движения.

Пример настройки пружины для оси X:

joint.setSpring(0, 10, 0.5);

Методы управления

  • enableMotor(axis, speed, maxForce) — активирует мотор для вращения или смещения по выбранной оси.
  • disableMotor(axis) — отключает мотор.
  • getPosition() — возвращает текущую позицию шарнира.
  • getRotation() — возвращает текущие углы вращения по осям.

Эти методы позволяют создавать динамические механизмы с автоматическим управлением движением и ограничениями.

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

  1. Дверные петли и ворота — фиксируются только определенные оси вращения, остальные блокируются.
  2. Роботизированные руки — комбинация ограничений вращения и линейных позволяет точно контролировать положение сегментов.
  3. Подвесные системы и транспортные механизмы — можно задать мягкие линейные и угловые ограничения, эмулируя пружины и амортизаторы.

Советы по оптимизации

  • Устанавливать только необходимые ограничения, чтобы избежать лишней нагрузки на физический движок.
  • Использовать ограниченные диапазоны вместо полного блокирования, если требуется естественная подвижность.
  • Регулировать stiffness и damping для предотвращения резких колебаний и «дрожания» соединений.
  • Проверять ориентацию осей axis1 и axis2, чтобы движения соответствовали ожидаемым направлениям.

Особенности реализации в Oimo.js

GenericJoint в Oimo.js отличается точной обработкой шести степеней свободы благодаря внутреннему решателю ограничений. Он автоматически пересчитывает силы и моменты, чтобы соблюсти заданные лимиты, включая взаимодействие с гравитацией и столкновениями. Это делает его ключевым инструментом для сложных физико-динамических симуляций.

Шарнир GenericJoint сочетает гибкость и контроль, позволяя создавать как полностью фиксированные соединения, так и высоко динамичные механизмы с детальной настройкой всех степеней свободы.