Роль Shape как коллайдера тела

В Oimo.js основным элементом, отвечающим за определение формы и границ физического объекта в мире, является объект Shape. Shape не является самостоятельным физическим телом: он всегда принадлежит Body и служит для описания его коллизий и взаимодействий с другими объектами. Понимание принципов работы Shape критично для построения корректной физики в сценах.


Создание Shape и типы коллайдеров

Каждый Shape создается с указанием формы (geometry), которая определяет, как тело будет реагировать на столкновения:

  • Box – прямоугольный параллелепипед, задается размерами по осям X, Y, Z.
  • Sphere – сферический коллайдер, задается радиусом.
  • Cylinder – цилиндрическая форма, задается радиусом и высотой.
  • ConvexMesh – выпуклая многоугольная сетка, используется для сложных объектов.
  • Plane – бесконечная плоскость, применяемая для пола или стен.

Пример создания Shape для тела:

let body = world.add({
    type: "dynamic",
    pos: [0, 5, 0],
    rot: [0, 0, 0],
    shapes: [{
        type: "box",
        size: [1, 1, 1],
        friction: 0.3,
        restitution: 0.5
    }]
});

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

  • type – тип геометрии коллайдера (box, sphere, cylinder, plane, convex).
  • size / radius / height – размеры формы.
  • friction – коэффициент трения.
  • restitution – коэффициент упругости (отражение при столкновениях).
  • density – плотность, влияющая на массу тела (масса = density × объем).

Связь Shape и Body

Shape нельзя рассматривать отдельно от Body. Body отвечает за позицию, ориентацию и динамику, а Shape определяет форму и параметры коллизии. Один Body может иметь несколько Shape, что позволяет создавать составные объекты, например:

let body = world.add({
    type: "dynamic",
    pos: [0, 5, 0],
    shapes: [
        { type: "box", size: [1, 1, 1] },
        { type: "sphere", radius: 0.5, pos: [0, 1, 0] }
    ]
});

В этом примере одно тело сочетает коробку и сферу, создавая сложную форму для столкновений.


Параметры взаимодействия

Friction (трение) и restitution (упругость) задаются на уровне Shape, что позволяет различным частям одного Body вести себя по-разному при контакте с другими объектами. Например, верхняя часть тела может быть скользкой, а нижняя – с высоким трением.

Collision Group и Mask управляют, какие объекты могут сталкиваться. Каждое тело или Shape можно отнести к группе и настроить маску взаимодействий:

shape.group = 1;  // принадлежность к группе 1
shape.mask = 2;   // взаимодействует только с группой 2

Это позволяет создавать слои столкновений, например, чтобы персонаж не сталкивался с декоративными объектами.


Геометрические трансформации Shape

Shape наследует позицию и вращение от Body, но можно задавать смещения относительно центра тела через offset и rotation:

shapes: [{
    type: "box",
    size: [1, 1, 1],
    pos: [0, 0.5, 0], // смещение относительно центра Body
    rot: [0, Math.PI/4, 0] // локальное вращение
}]

Это особенно полезно при создании составных тел с несоосными частями.


Оптимизация физики с Shape

  • Для сложных объектов предпочтительно использовать несколько простых Shape вместо одной сложной ConvexMesh. Это ускоряет расчет столкновений.
  • Маленькие или плоские Shape можно объединять, чтобы уменьшить количество контактных точек.
  • Тела с неподвижными Shape (статические объекты) не требуют высокой точности расчета, что экономит ресурсы.

Взаимодействие с миром

Shape участвует во всех коллизиях, генерируя контакты и силы, которые Body передает движку физики. Через Shape можно:

  • Считывать точки контакта.
  • Проверять столкновения.
  • Настраивать отталкивающие или прилипательные эффекты через restitution и friction.

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

world.step();
body.shapes.forEach(shape => {
    shape.contacts.forEach(contact => {
        console.log("Столкновение с телом:", contact.body);
    });
});

Особенности работы с динамическими и статическими Shape

  • Динамические Shape влияют на движение Body, подчиняются силам и импульсам.
  • Статические Shape (plane, static box) остаются неподвижными, но взаимодействуют с другими телами.
  • Kinematic Shape управляются программно, не подвержены силам физики, но могут толкать динамические тела.

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