Пулинг тел и форм

Библиотека Cannon.js предоставляет мощный физический движок для симуляции трёхмерной механики тел в JavaScript. В основе работы лежит World — пространство, в котором происходят все взаимодействия. Объект CANNON.World создаётся следующим образом:

const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // стандартная гравитация
world.broadphase = new CANNON.NaiveBroadphase(); // упрощённая проверка столкновений
world.solver.iterations = 10; // точность решения контактов

Ключевые моменты:

  • gravity определяет направление и величину силы тяжести.
  • broadphase отвечает за алгоритм определения потенциальных столкновений между телами.
  • solver.iterations влияет на стабильность симуляции при большом числе контактов.

Создание и пулинг тел

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

Пример структуры пулинга:

class BodyPool {
    constructor(shape, mass, size) {
        this.pool = [];
        this.shape = shape;
        this.mass = mass;
        this.size = size || 50;
        for (let i = 0; i < this.size; i++) {
            const body = new CANNON.Body({ mass: this.mass });
            body.addShape(this.shape);
            body.position.set(0, -100, 0); // прячем объект вне видимой сцены
            this.pool.push(body);
        }
    }

    acquire() {
        return this.pool.length ? this.pool.pop() : null;
    }

    release(body) {
        body.velocity.set(0, 0, 0);
        body.angularVelocity.set(0, 0, 0);
        body.position.set(0, -100, 0);
        body.quaternion.set(0, 0, 0, 1);
        this.pool.push(body);
    }
}

Важные детали:

  • Все тела создаются заранее и добавляются в массив.
  • При активации объекта его состояние сбрасывается и позиция устанавливается в сцене.
  • После завершения использования объект возвращается в пул, очищенный от скорости и поворота.

Формы (Shapes) в Cannon.js

Cannon.js использует примитивные формы для расчёта столкновений. Основные типы:

  • Box: прямоугольный параллелепипед

    const boxShape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
  • Sphere: сфера

    const sphereShape = new CANNON.Sphere(0.5);
  • Cylinder: цилиндр

    const cylinderShape = new CANNON.Cylinder(0.5, 0.5, 2, 16);
  • Plane: бесконечная плоскость для пола

    const groundShape = new CANNON.Plane();

Каждое тело (CANNON.Body) может содержать одну или несколько форм, что позволяет создавать сложные составные объекты.


Добавление тел в пул и мир

После создания пулинга тела необходимо добавить в мир для взаимодействия:

const spherePool = new BodyPool(new CANNON.Sphere(0.5), 1, 100);

for (let i = 0; i < 50; i++) {
    const sphere = spherePool.acquire();
    if (sphere) {
        sphere.position.set(Math.random()*5, 10 + i, Math.random()*5);
        world.addBody(sphere);
    }
}

Особенности:

  • Тела из пула активируются постепенно по мере необходимости.
  • Добавление в мир позволяет Cannon.js рассчитывать столкновения и реакции.

Управление телами после использования

Чтобы объекты не накапливались в мире и не замедляли симуляцию, их возвращают в пул:

function update() {
    world.step(1/60);

    world.bodies.forEach(body => {
        if (body.position.y < -10) { // объект упал ниже границы
            world.removeBody(body);
            spherePool.release(body);
        }
    });
}

Ключевые моменты:

  • Проверка условий выхода объекта за пределы сцены.
  • Удаление тела из мира предотвращает лишние расчёты столкновений.
  • Сброс состояния тела гарантирует корректную повторную активацию.

Комплексные примеры использования пулинга

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

Оптимизация производительности

  • Размер пула: должен быть достаточен для всех активных объектов в сцене, чтобы избежать динамического создания тел.
  • Сброс состояния: обнуление скорости и вращения перед возвратом в пул предотвращает непредсказуемое поведение.
  • Удаление из мира: неиспользуемые тела не должны оставаться в world.bodies, чтобы не перегружать расчёт столкновений.
  • Формы и масса: упрощение формы и снижение количества сложных тел ускоряет физические расчёты.

Заключение по теме пулинга тел и форм

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