Кинематические тела и анимированные объекты

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

Кинематические тела создаются аналогично динамическим, но их тип тела задается как Body.KINEMATIC. Например:

const body = new CANNON.Body({
    mass: 0, // масса не влияет на движение
    type: CANNON.Body.KINEMATIC,
    shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1))
});

Ключевой особенностью кинематических тел является явное задание позиции и ориентации. Cannon.js не рассчитывает их движение на основе сил и импульсов. Вместо этого положение обновляется напрямую через свойства position и quaternion.

body.position.set(0, 5, 0);
body.quaternion.setFromEuler(0, Math.PI/4, 0);

Управление движением и анимацией

Для анимации кинематических объектов обычно используется функция обновления в цикле рендеринга:

function updateKinematicBody(deltaTime) {
    body.position.x += 2 * deltaTime; // постоянная скорость по оси X
    body.quaternion.setFromEuler(0, performance.now() / 1000, 0); // вращение
}

deltaTime — это время, прошедшее с предыдущего кадра, что позволяет движение оставлять независимым от частоты кадров.

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

Различие кинематических и статических тел

  • Статические тела (Body.STATIC) – неподвижны, взаимодействуют с динамическими объектами, но не двигаются.
  • Кинематические тела (Body.KINEMATIC) – двигаются по заданной траектории, воздействуют на динамические объекты, но не подчиняются физическим силам.
  • Динамические тела (Body.DYNAMIC) – полностью управляются физикой: силами, импульсами и столкновениями.

Коллизии с кинематическими объектами

При взаимодействии с динамическими объектами Cannon.js использует алгоритм импульсов для корректного отталкивания. Важно помнить:

  • Кинематические тела не получают импульс от столкновения.
  • Динамические тела получают корректное отражение в соответствии с законом сохранения импульса.
  • Для сложных взаимодействий рекомендуется использовать контактные события:
body.addEventListener('collide', function(event) {
    const other = event.body;
    console.log('Столкновение с', other.id);
});

Анимация по траектории

Для плавного движения кинематического объекта можно использовать интерполяцию:

const startPos = new CANNON.Vec3(0, 0, 0);
const endPos = new CANNON.Vec3(10, 0, 0);
const duration = 5; // секунд
let elapsed = 0;

function animate(deltaTime) {
    elapsed += deltaTime;
    const t = Math.min(elapsed / duration, 1);
    body.position.lerp(startPos, endPos, t);
}

Метод lerp обеспечивает линейное перемещение между двумя точками, что особенно полезно для платформ или объектов с заранее заданной анимацией.

Вращение кинематических объектов

Для поворота объектов используются кватернионы или преобразования Эйлера. Прямое изменение углов Эйлера:

body.quaternion.setFromEuler(0, Math.PI * Math.sin(performance.now()/1000), 0);

Для сложной анимации можно комбинировать slerp для плавного вращения между кватернионами:

const q1 = new CANNON.Quaternion();
const q2 = new CANNON.Quaternion();
q2.setFromEuler(0, Math.PI/2, 0);
CANNON.Quaternion.slerp(q1, q2, body.quaternion, 0.05);

slerp обеспечивает плавное вращение без резких скачков и сохраняет нормализацию кватерниона.

Интеграция с игровым циклом

В большинстве проектов обновление кинематических тел выполняется в основном цикле симуляции:

world.step(timeStep);
updateKinematicBody(timeStep);
renderer.render(scene, camera);

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

Использование кинематических тел в игровых механиках

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

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

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

  • Не назначать кинематическому телу массу, она не используется.
  • Избегать частых пересозданий тел, лучше обновлять position и quaternion.
  • Использовать sleep или отключение столкновений для объектов, которые временно не участвуют в физике, чтобы снизить нагрузку на расчёт коллизий.

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