btDefaultMotionState: реализация по умолчанию

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

Основные свойства и конструктор

Конструктор btDefaultMotionState позволяет определить начальное положение и ориентацию объекта через структуру btTransform. Прототип конструктора выглядит так:

let motionState = new Ammo.btDefaultMotionState(startTransform, centerOfMassOffset);
  • startTransform — объект типа btTransform, задающий начальное положение и ориентацию тела.
  • centerOfMassOffset (необязательный) — btTransform, определяющий смещение центра масс относительно геометрии объекта. Позволяет корректно учитывать моменты инерции при вращении.

Если centerOfMassOffset не задан, используется идентичный трансформ, что удобно для простых тел без сложной геометрии.

Методы btDefaultMotionState

getWorldTransform

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

let transform = new Ammo.btTransform();
motionState.getWorldTransform(transform);

Особенности:

  • Этот метод должен быть реализован для корректного синхронизирования с графикой.
  • Внутри btDefaultMotionState он возвращает текущее сохранённое состояние трансформации.
  • Обеспечивает передачу данных между физикой и визуальной сценой без лишних вычислений.

setWorldTransform

Метод setWorldTransform используется движком физики для уведомления о новых координатах тела после расчёта симуляции. Типичный пример:

motionState.setWorldTransform(newTransform);

Особенности:

  • Вызывается автоматически при изменении позиции или вращения тела.
  • В btDefaultMotionState сохраняет новый btTransform внутри объекта, чтобы последующие вызовы getWorldTransform возвращали актуальные значения.
  • Если объект связан с визуальным представлением, сюда удобно вставлять обновление матриц рендера.

Связь с Rigid Body

btDefaultMotionState часто используется совместно с btRigidBody. При создании тела его motion state передается в конструктор btRigidBody:

let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);
  • Motion state отвечает за позицию и ориентацию.
  • Физический объект вычисляет столкновения и динамику, но не занимается визуализацией — это делегируется motion state.
  • Применение btDefaultMotionState избавляет от необходимости вручную отслеживать трансформации в цикле рендеринга.

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

let startTransform = new Ammo.btTransform();
startTransform.setIdentity();
startTransform.setOrigin(new Ammo.btVector3(0, 10, 0));
let motionState = new Ammo.btDefaultMotionState(startTransform);

let shape = new Ammo.btBoxShape(new Ammo.btVector3(1, 1, 1));
let localInertia = new Ammo.btVector3(0, 0, 0);
shape.calculateLocalInertia(1, localInertia);

let rbInfo = new Ammo.btRigidBodyConstructionInfo(1, motionState, shape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);

physicsWorld.addRigidBody(body);

В этом примере:

  • Создана коробка с массой 1.
  • Задано начальное положение через btDefaultMotionState.
  • Физический объект добавлен в мир, где его движение будет автоматически синхронизировано с motion state.

Важные моменты и рекомендации

  1. Идентичность трансформации по умолчанию — при отсутствии смещения центр масс совпадает с геометрическим центром объекта. Для сложных моделей важно указывать centerOfMassOffset.
  2. Производительность — использование btDefaultMotionState минимизирует накладные расходы на обновление позиции и ориентации, так как библиотека хранит внутреннее состояние объекта.
  3. Синхронизация с визуальной сценой — после каждого шага симуляции можно получить текущий трансформ через getWorldTransform и обновить матрицу объекта в WebGL или Three.js.
  4. Безопасность — объекты btTransform и btVector3 управляются через систему памяти Ammo.js, поэтому необходимо правильно освобождать память через Ammo.destroy() после завершения работы с объектами.

btDefaultMotionState обеспечивает простую и надёжную интеграцию физического движка Ammo.js с визуальной частью сцены, оставаясь оптимальным выбором для большинства динамических тел с предсказуемым поведением.