ContactMaterial: трение и упругость между двумя материалами

Библиотека Cannon.js предоставляет мощный инструмент для симуляции физики в 3D-сценах на JavaScript. Одним из ключевых компонентов при моделировании взаимодействия объектов является ContactMaterial — объект, который определяет, как два различных материала ведут себя при столкновении. Это позволяет управлять коэффициентами трения, упругости и другими свойствами контакта, обеспечивая реалистичное поведение объектов в сцене.


Определение и назначение ContactMaterial

ContactMaterial — это конструкция, связывающая два экземпляра Material и задающая физические параметры их взаимодействия:

  • friction — коэффициент трения. Определяет, насколько объекты «скользят» друг по другу. Значение обычно находится в диапазоне от 0 до 1, где 0 соответствует полному отсутствию трения, а 1 — сильному сопротивлению скольжению.
  • restitution — коэффициент упругости (отскока). Определяет, насколько сильно объекты отскакивают при столкновении. Значение 0 означает полное отсутствие отскока, 1 — идеальный упругий отскок.
  • stiffness и relaxation — параметры для тонкой настройки силы контакта и демпфирования. Используются для предотвращения «проникновения» объектов друг в друга при расчете столкновений.

Создание ContactMaterial выглядит следующим образом:

const materialA = new CANNON.Material('materialA');
const materialB = new CANNON.Material('materialB');

const contactMaterial = new CANNON.ContactMaterial(materialA, materialB, {
    friction: 0.4,
    restitution: 0.8,
    stiffness: 1e7,
    relaxation: 3
});

world.addContactMaterial(contactMaterial);

Здесь world — это экземпляр CANNON.World, в котором происходит симуляция. Метод addContactMaterial добавляет правило взаимодействия между материалами в глобальную систему столкновений.


Трение: типы и влияние на симуляцию

Friction определяет сопротивление скольжению между поверхностями. В Cannon.js используется Coulomb friction model, где сила трения пропорциональна нормальной силе контакта:

  • Высокий коэффициент трения (например, 0.8–1) подходит для моделирования резиновых или шероховатых поверхностей.
  • Низкий коэффициент трения (0–0.2) подходит для гладких или скользких поверхностей, таких как лед или металл.

Важно учитывать, что friction применяется только в момент контакта и зависит от нормальной силы, действующей на точку столкновения. Для динамических объектов с большой массой и скоростью низкий коэффициент трения может привести к значительному скольжению или «проскальзыванию» при столкновении.


Упругость: реалистичные отскоки

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

Примеры применения:

  • restitution: 0 — объекты не отскакивают, создавая эффект полностью поглощаемого удара.
  • restitution: 1 — идеальный упругий отскок, при котором кинетическая энергия сохраняется почти полностью.
  • restitution > 1 — в реальности невозможно, но библиотека допускает для эффектов «сверхотскока».

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


Тонкая настройка: stiffness и relaxation

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

Relaxation задает скорость демпфирования при контакте, снижая резонансные колебания и предотвращая «прыжки» объектов после столкновения.

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


Примеры использования ContactMaterial

  1. Ледяная поверхность и резиновый мяч:
const ice = new CANNON.Material('ice');
const rubber = new CANNON.Material('rubber');

const iceRubberContact = new CANNON.ContactMaterial(ice, rubber, {
    friction: 0.05,
    restitution: 0.9
});

world.addContactMaterial(iceRubberContact);

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

  1. Дерево и бетон:
const wood = new CANNON.Material('wood');
const concrete = new CANNON.Material('concrete');

const woodConcreteContact = new CANNON.ContactMaterial(wood, concrete, {
    friction: 0.6,
    restitution: 0.2
});

world.addContactMaterial(woodConcreteContact);

Здесь объекты будут двигаться медленно из-за высокого трения и минимального отскока при столкновении.


Практические рекомендации

  • Для сложных сцен с множеством материалов рекомендуется заранее создавать ContactMaterial для каждой важной пары материалов, чтобы избежать неожиданных скольжений или чрезмерного отскока.
  • Значения friction и restitution можно подбирать экспериментально, ориентируясь на визуальную правдоподобность.
  • Для стабильной симуляции избегать слишком высоких значений stiffness, особенно при маленьких шагах интеграции (world.step), иначе могут появиться численные ошибки и дрожание объектов.

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