Изменение геометрии: удаление и добавление Shape

В Oimo.js объект Shape представляет собой геометрическую форму, привязанную к телу (Body). Shape определяет форму коллизии и физические свойства объекта, такие как масса, трение и упругость. Каждое тело может содержать несколько форм, что позволяет создавать сложные составные объекты.

Создание Shape осуществляется через конструктор, передавая параметры геометрии и физические свойства:

const shape = new OIMO.Shape({
    type: 'box',
    size: [1, 2, 1],
    pos: [0, 1, 0],
    rot: [0, 0, 0],
    density: 1,
    friction: 0.5,
    restitution: 0.2
});
  • type — тип формы: 'box', 'sphere', 'cylinder', 'capsule' и т.д.
  • size — размеры формы. Для 'box' это [width, height, depth].
  • pos и rot — позиция и вращение относительно тела.
  • density, friction, restitution — масса, коэффициент трения и упругости.

После создания форму нужно привязать к телу:

body.addShape(shape);

Добавление Shape к существующему телу

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

const extraShape = new OIMO.Shape({
    type: 'sphere',
    size: [0.5],
    pos: [0, 1.5, 0],
    density: 0.5
});

body.addShape(extraShape);

При добавлении формы важно учитывать:

  • Расположение относительно тела — координаты pos задают локальную позицию формы.
  • Физические свойства — новые формы влияют на общую массу тела и распределение инерции. Oimo.js автоматически пересчитывает эти параметры.
  • Количество форм — слишком большое количество форм на одном теле может ухудшить производительность. Оптимально комбинировать несколько мелких форм в одну сложную.

Удаление Shape из тела

Удаление формы используется для динамического изменения коллизионной геометрии во время работы симуляции. Метод удаления:

body.removeShape(shape);

После удаления формы необходимо учитывать:

  • Перерасчёт массы — Oimo.js пересчитывает массу тела с учётом оставшихся форм.
  • Ссылки на объекты — удалённая форма больше не взаимодействует с коллизиями, но объект Shape остаётся доступным в памяти, если на него есть ссылки.

Для полного уничтожения формы следует освободить все ссылки:

shape = null;

Работа с массивом форм тела

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

body.shapes.forEach((s, index) => {
    if (s.type === 'sphere') {
        body.removeShape(s);
    }
});

Динамическое обновление формы

Oimo.js не поддерживает прямое изменение размера или типа существующей формы. Для модификации требуется:

  1. Удалить старую форму с body.removeShape().
  2. Создать новую форму с нужными параметрами.
  3. Добавить новую форму в тело через body.addShape().

Пример изменения куба на сферу:

const oldShape = body.shapes[0];
body.removeShape(oldShape);

const newShape = new OIMO.Shape({
    type: 'sphere',
    size: [1],
    pos: oldShape.position,
    density: oldShape.density
});

body.addShape(newShape);

Особенности производительности

Добавление и удаление форм во время симуляции:

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

Совместное использование нескольких форм

С помощью нескольких форм можно создавать сложные коллизионные объекты:

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

Пример составного тела:

const body = new OIMO.Body({
    type: 'dynamic',
    pos: [0, 2, 0]
});

body.addShape(new OIMO.Shape({ type: 'box', size: [1, 1, 1] }));
body.addShape(new OIMO.Shape({ type: 'cylinder', size: [0.5, 2], pos: [0, 1, 0] }));

Это позволяет точно контролировать коллизию и поведение физического объекта.


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