Cannon.js прошёл несколько обновлений и форков, в результате чего современная версия библиотеки претерпела изменения в структуре классов, способах инициализации мира, обработке тел и коллизий, а также в системе материалов и ограничений. Эти изменения направлены на упрощение интеграции с современными движками и повышение производительности.
В оригинальной версии Cannon.js создание физического мира выглядело так:
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
В обновлённой версии API появились следующие изменения:
const world = new CANNON.World({
gravity: new CANNON.Vec3(0, -9.82, 0),
broadphase: new CANNON.SAPBroadphase(),
solverIterations: 10,
});
broadphase рекомендуется использовать
SAPBroadphase для увеличения производительности при
множественных объектах. NaiveBroadphase остаётся для
совместимости, но менее эффективен.
Параметр solver.iterations заменён на
solverIterations при инициализации. Доступ к solver теперь
через world.solver возможен для расширенной
настройки.
Создание тел (Body) и форм (Shape)
претерпело структурные изменения:
const sphereShape = new CANNON.Sphere(1);
const sphereBody = new CANNON.Body({
mass: 5,
position: new CANNON.Vec3(0, 10, 0),
shape: sphereShape,
});
world.addBody(sphereBody);
Ключевые изменения:
Body принимает объект с параметрами
(mass, position, shape,
velocity, angularVelocity), вместо
последовательного задания свойств после создания.position теперь задаётся непосредственно через
объект Vec3.addShape остаются для добавления дополнительных
форм к телу, но инициализация нескольких форм через конструктор теперь
поддерживается через массив shapes.const boxShape = new CANNON.Box(new CANNON.Vec3(1,1,1));
const compoundBody = new CANNON.Body({
mass: 10,
shapes: [sphereShape, boxShape],
positions: [new CANNON.Vec3(0,0,0), new CANNON.Vec3(1,1,1)],
});
Система материалов получила улучшения для работы с трением и упругостью:
const groundMaterial = new CANNON.Material({ friction: 0.5, restitution: 0.7 });
const ballMaterial = new CANNON.Material({ friction: 0.3, restitution: 0.9 });
const contactMaterial = new CANNON.ContactMaterial(
groundMaterial,
ballMaterial,
{ friction: 0.4, restitution: 0.8 }
);
world.addContactMaterial(contactMaterial);
Изменения:
Material теперь принимает объект с
настройками friction и restitution.ContactMaterial создаётся явно для пары материалов, а
параметры трения и упругости задаются через объект.addMaterial остались, но чаще используется
прямое связывание через ContactMaterial.API для ограничений претерпело унификацию:
DistanceConstraint,
PointToPointConstraint, HingeConstraint.const hinge = new CANNON.HingeConstraint(bodyA, bodyB, {
pivotA: new CANNON.Vec3(1,0,0),
axisA: new CANNON.Vec3(0,1,0),
pivotB: new CANNON.Vec3(-1,0,0),
axisB: new CANNON.Vec3(0,1,0),
maxForce: 1e6
});
world.addConstraint(hinge);
Изменения:
maxForce стал обязательным для большинства динамических
соединений.enableMotor и setMotorSpeed
сохранились, но требуют корректного указания pivot и axis через
векторы.События столкновений теперь централизованы через world и
тело (Body):
sphereBody.addEventListener('collide', function(event){
console.log('Collision with', event.body);
});
world.addEventListener('postStep', function(){
console.log('World step completed');
});
Особенности:
collide передаёт объект события с
contact и body, что упрощает доступ к деталям
столкновения.postStep и preStep позволяют вставлять
обработку логики до или после физического шага.beginContact / endContact
более не используется.Метод step изменился:
const fixedTimeStep = 1.0 / 60.0;
const maxSubSteps = 3;
world.step(fixedTimeStep, deltaTime, maxSubSteps);
deltaTime — реальное прошедшее время между кадрами,
maxSubSteps — максимальное количество внутренних шагов для
компенсации проседаний FPS.step(dt) просто принимал единый параметр времени,
теперь рекомендовано использовать три аргумента для стабильной
симуляции.Vec3 и Quaternion получили расширенные
методы copy, clone, normalize,
vmult, что упрощает работу с преобразованиями.v1.vadd(v2) остаются, но часто
заменяются на новые цепочки методов для читаемости кода.const force = new CANNON.Vec3(10,0,0);
body.applyForce(force, body.position.clone());
mass, invMass,
inertia, invInertia теперь доступны сразу
после инициализации тела.updateMassProperties() следует вызывать после
изменения mass или shapes, чтобы пересчитать
инерцию.shapes,
positions).addEventListener для тел
и мира.step теперь принимает три аргумента для
стабильной симуляции.Vec3 и Quaternion,
упрощение операций.Эти изменения делают API более согласованным, предсказуемым и удобным для интеграции в современные JavaScript-проекты с физикой реального времени.