Влияние контактного материала на стабильность стека

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

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

Контактный материал создается через объект CANNON.ContactMaterial и привязывается к паре материалов с помощью world.addContactMaterial().

const groundMaterial = new CANNON.Material("ground");
const boxMaterial = new CANNON.Material("box");

const contactMaterial = new CANNON.ContactMaterial(
    groundMaterial,
    boxMaterial,
    {
        friction: 0.4,
        restitution: 0.3,
        stiffness: 1e7,
        relaxation: 3
    }
);

world.addContactMaterial(contactMaterial);

Влияние на стабильность стека объектов

При построении стека объектов (например, колонны из кубов) параметры контактного материала критически влияют на устойчивость:

  1. Трение (friction)

    • Низкое трение (0–0.2) приводит к скольжению верхних объектов и разрушению стека.
    • Оптимальное значение трения для устойчивого стека обычно 0.3–0.6.
    • Слишком высокое трение (>0.8) может вызвать «залипание» объектов и неестественные колебания.
  2. Упругость (restitution)

    • Высокая упругость (>0.7) вызывает сильные отскоки при падении объектов на нижние уровни, что может рассыпать стек.
    • Для стабильного стека часто используется низкая упругость (0–0.2), чтобы объекты аккуратно оседали друг на друга.
  3. Жесткость контакта (stiffness)

    • Низкая жесткость (<1e5) позволяет объектам «проваливаться» друг в друга при столкновении, создавая визуальный артефакт и нестабильность.
    • Слишком высокая жесткость (>1e8) при больших временных шагах интеграции может вызвать дрожание стека и численные расхождения.
    • Баланс: подобрать stiffness так, чтобы объекты не проседали, но симуляция оставалась стабильной.
  4. Демпфирование (relaxation)

    • Позволяет снижать колебания после контакта.
    • Значения от 2 до 5 обеспечивают плавное погашение вибраций в стеке.
    • Слишком высокое демпфирование может «замораживать» объекты, делая движение неестественным.

Применение комбинаций материалов

Для сложных сцен часто используют несколько типов материалов:

  • Основание стека — более жесткий и менее упругий материал.
  • Верхние объекты — немного более упругие и менее жесткие, чтобы сцена выглядела динамичнее.
  • При контакте разных типов материалов создается отдельный контактный материал с индивидуальными параметрами трения и упругости.
const topBoxMaterial = new CANNON.Material("topBox");

const mixedContact = new CANNON.ContactMaterial(
    groundMaterial,
    topBoxMaterial,
    { friction: 0.5, restitution: 0.1, stiffness: 1e7, relaxation: 3 }
);

world.addContactMaterial(mixedContact);

Практические советы для стабильного стека

  • Малый шаг интеграции (timeStep ≤ 1/120) повышает точность расчета контактов.
  • Контактная жесткость должна быть сопоставима с массой объектов: более тяжелые объекты требуют большей stiffness.
  • Использовать небольшое демпфирование для устранения мелких колебаний, особенно при высокой упругости.
  • Избегать слишком высокой упругости для низких объектов, чтобы предотвратить эффект «скачущей башни».

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