Материал по умолчанию и defaultContactMaterial

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


Физические материалы (Material)

Material в Cannon.js представляет собой свойства поверхности объекта, влияющие на столкновения. Основные параметры:

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

Создание материала выполняется через конструктор:

const groundMaterial = new CANNON.Material("groundMaterial");
groundMaterial.friction = 0.5;
groundMaterial.restitution = 0.3;

const ballMaterial = new CANNON.Material("ballMaterial");
ballMaterial.friction = 0.2;
ballMaterial.restitution = 0.7;

Каждый объект в мире связывается с материалом через body.material:

const groundBody = new CANNON.Body({
    mass: 0,
    shape: new CANNON.Plane(),
    material: groundMaterial
});

const ballBody = new CANNON.Body({
    mass: 1,
    shape: new CANNON.Sphere(1),
    material: ballMaterial
});

Контактные материалы (ContactMaterial)

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

  • friction – трение между двумя материалами.
  • restitution – упругость при столкновении.
  • stiffness – жёсткость контакта (для constraints, влияющих на силу реакции).
  • relaxation – ослабление силы реакции.

Создание контактного материала:

const contactMaterial = new CANNON.ContactMaterial(
    groundMaterial,
    ballMaterial,
    {
        friction: 0.4,
        restitution: 0.6
    }
);
world.addContactMaterial(contactMaterial);

При этом при каждом контакте Cannon.js ищет соответствующий ContactMaterial. Если он не задан явно, используется материал по умолчанию.


defaultContactMaterial

defaultContactMaterial — это глобальный материал контакта, который применяется, когда для пары материалов не определён отдельный ContactMaterial. Он служит базовой настройкой столкновений для всех объектов мира.

Пример инициализации:

const defaultMaterial = new CANNON.Material("defaultMaterial");

world.defaultContactMaterial = new CANNON.ContactMaterial(
    defaultMaterial,
    defaultMaterial,
    {
        friction: 0.3,
        restitution: 0.5
    }
);

Если ни один объект не имеет специфического ContactMaterial, столкновения будут использовать параметры defaultContactMaterial. Это особенно полезно для быстрого прототипирования и единообразного поведения объектов в мире.


Особенности и рекомендации

  1. Приоритет ContactMaterial: Если существует ContactMaterial для пары материалов, он всегда перекрывает настройки defaultContactMaterial.

  2. Универсальные значения: Для defaultContactMaterial рекомендуется выбирать средние значения трения и упругости, чтобы избежать экстремальных физических эффектов при случайных столкновениях.

  3. Комбинация материалов: Если несколько объектов с разными материалами часто сталкиваются, создание индивидуальных ContactMaterial для каждой пары повышает реализм, особенно при сложных сценах.

  4. Влияние на производительность: Частое создание уникальных ContactMaterial для множества пар может увеличить нагрузку на симуляцию. В этом случае использование defaultContactMaterial для большинства объектов оптимально.

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


Пример комплексной настройки

// Материалы
const woodMaterial = new CANNON.Material("wood");
const metalMaterial = new CANNON.Material("metal");

// Контактные материалы
const woodMetalContact = new CANNON.ContactMaterial(woodMaterial, metalMaterial, {
    friction: 0.4,
    restitution: 0.3
});

const metalMetalContact = new CANNON.ContactMaterial(metalMaterial, metalMaterial, {
    friction: 0.2,
    restitution: 0.7
});

// Добавление в мир
world.addContactMaterial(woodMetalContact);
world.addContactMaterial(metalMetalContact);

// Глобальный defaultContactMaterial
world.defaultContactMaterial = new CANNON.ContactMaterial(
    new CANNON.Material("default"),
    new CANNON.Material("default"),
    { friction: 0.3, restitution: 0.5 }
);

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