Архитектура btRaycastVehicle

btRaycastVehicle — это высокоуровневый компонент физического движка Bullet, портированный в JavaScript через Ammo.js, предназначенный для моделирования поведения транспортных средств с колесами. В отличие от обычных rigid body объектов, колёсные транспортные средства имеют сложную динамику, включающую вращение колёс, подвеску и контакт с поверхностью. Основная идея btRaycastVehicle заключается в использовании лучевого кастинга (raycasting) для симуляции контакта колеса с поверхностью без необходимости физически создавать колёсные тела, что значительно оптимизирует вычисления.


Основные элементы архитектуры

1. Rigid Body шасси

Центральным объектом автомобиля является rigid body, которое представляет шасси. Это основной физический объект, на который прикрепляются колёса. Шасси управляет:

  • Положением транспортного средства в мире (position)
  • Ориентацией (rotation)
  • Инерционными свойствами (mass, inertiaTensor)

Пример создания rigid body:

let chassisShape = new Ammo.btBoxShape(new Ammo.btVector3(1, 0.5, 2));
let chassisTransform = new Ammo.btTransform();
chassisTransform.setIdentity();
chassisTransform.setOrigin(new Ammo.btVector3(0, 1, 0));
let motionState = new Ammo.btDefaultMotionState(chassisTransform);
let mass = 800;
let localInertia = new Ammo.btVector3(0, 0, 0);
chassisShape.calculateLocalInertia(mass, localInertia);
let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, chassisShape, localInertia);
let chassisBody = new Ammo.btRigidBody(rbInfo);

2. WheelInfo

Каждое колесо представлено объектом WheelInfo, который хранит конфигурацию колеса:

  • Положение относительно шасси (connectionPoint)
  • Направление подвески (wheelDirectionCS0)
  • Ось вращения колеса (wheelAxleCS)
  • Радиус колеса (radius)
  • Сила подвески (suspensionStiffness)
  • Демпферы (dampingCompression, dampingRelaxation)
  • Сила трения с дорогой (frictionSlip)

Каждое колесо добавляется к btRaycastVehicle через метод addWheel:

let wheelDirection = new Ammo.btVector3(0, -1, 0);
let wheelAxle = new Ammo.btVector3(-1, 0, 0);
let suspensionRestLength = 0.6;
vehicle.addWheel(
    new Ammo.btVector3(1, 0, 1),  // connectionPoint
    wheelDirection,
    wheelAxle,
    suspensionRestLength,
    radius,
    tuning,
    isFrontWheel
);

3. Подвеска (Suspension)

Подвеска — ключевой элемент физики автомобиля. Она моделирует реакцию колеса на неровности дороги и амортизацию:

  • suspensionStiffness — жёсткость пружины подвески
  • dampingCompression — демпфирование при сжатии пружины
  • dampingRelaxation — демпфирование при разжатии
  • maxSuspensionTravelCm — максимальный ход подвески

Подвеска влияет на реакцию автомобиля на ускорение, торможение и повороты. Более жёсткая подвеска даёт острое управление, мягкая — более стабильное поведение на неровной поверхности.


4. Контакт с поверхностью через raycast

Основная особенность btRaycastVehicle — использование лучей вместо физических колёсных тел. Для каждого колеса луч проверяет:

  • Расстояние до поверхности
  • Направление нормали поверхности
  • Контактную точку

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


5. Управление движением

btRaycastVehicle предоставляет методы для управления автомобилем:

  • applyEngineForce(force, wheelIndex) — прикладывает силу двигателя к колесу
  • setBrake(brakeForce, wheelIndex) — прикладывает тормозную силу
  • setSteeringValue(steeringAngle, wheelIndex) — задаёт угол поворота колеса

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

vehicle.applyEngineForce(1500, 2);  // заднее правое колесо
vehicle.setBrake(50, 0);            // переднее левое колесо
vehicle.setSteeringValue(0.3, 0);   // переднее левое колесо
vehicle.setSteeringValue(0.3, 1);   // переднее правое колесо

6. Tuning (Настройка автомобиля)

Для тонкой настройки физики транспортного средства используется объект btVehicleTuning, который хранит параметры:

  • m_suspensionStiffness
  • m_suspensionCompression
  • m_suspensionRelaxation
  • m_maxSuspensionTravelCm
  • m_frictionSlip

Эти параметры передаются при добавлении колеса и позволяют моделировать разные типы автомобилей — от спортивных до грузовиков.

let tuning = new Ammo.btVehicleTuning();
tuning.set_m_suspensionStiffness(20);
tuning.set_m_suspensionCompression(4.4);
tuning.set_m_suspensionRelaxation(2.3);
tuning.set_m_frictionSlip(1000);

7. Обновление и интеграция с физическим миром

Каждое обновление физического мира включает в себя:

  1. Симуляцию rigid body шасси (dynamicsWorld.stepSimulation)
  2. Вычисление новых положений колес через updateVehicle
  3. Применение силы двигателя и торможения к колесам
dynamicsWorld.stepSimulation(deltaTime, 10);
vehicle.updateVehicle(deltaTime);

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


8. Взаимодействие с другими объектами

Колеса btRaycastVehicle учитывают столкновения с другими rigid body в мире:

  • Луч проверяет коллизии с поверхностью
  • При контакте вычисляется нормальная сила и сила трения
  • Эти данные корректируют положение и вращение колеса

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


9. Оптимизация и особенности

  • Использование raycast вместо физических колес снижает нагрузку на CPU
  • Возможность настраивать каждое колесо отдельно
  • Поддержка полного дифференциала за счёт независимого управления силой на каждое колесо
  • Стабильная симуляция на больших скоростях благодаря ограничению хода подвески и демпфированию

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