Oimo.js — это высокопроизводительная библиотека физического движка на
JavaScript, ориентированная на симуляцию твёрдых тел и их
взаимодействий. Она работает по принципам динамической физики,
предоставляя объекты World, Body,
Shape и возможности для работы с силами и коллизиями.
Для начала работы создаётся объект мира:
const world = new OIMO.World({
timestep: 1/60,
iterations: 8,
broadphase: 2, // 1: brute force, 2: sweep and prune
gravity: [0, -9.8, 0]
});
Тела добавляются с помощью world.add:
const box = world.add({
type: "box",
size: [2, 2, 2],
pos: [0, 5, 0],
move: true,
density: 1.0
});
box,
sphere, cylinder, capsule).Взрывная волна создаётся путём применения силы к объектам на определённой дистанции от эпицентра. Сила направлена от точки взрыва и убывает с расстоянием.
function applyExplosion(world, epicenter, radius, power) {
world.bodies.forEach(body => {
if (!body.move) return; // игнорируем статические тела
const pos = body.getPosition();
const dir = [
pos.x - epicenter[0],
pos.y - epicenter[1],
pos.z - epicenter[2]
];
const dist = Math.sqrt(dir[0]**2 + dir[1]**2 + dir[2]**2);
if (dist > radius) return;
const forceMagnitude = power * (1 - dist / radius);
const norm = dir.map(v => v / dist);
const force = norm.map(v => v * forceMagnitude);
body.applyForce(force);
});
}
Эффект взрыва можно комбинировать с визуальными эффектами и детонацией, чтобы создать реалистичную игровую механику.
Подъёмная сила применяется к телам в жидкости или газе, моделируя эффект «подъёма» и сопротивления среды. Основной принцип — вычисление силы Архимеда и силы сопротивления.
function applyBuoyancy(body, fluidLevel, fluidDensity = 1.0, drag = 0.1) {
const pos = body.getPosition();
const halfHeight = body.getShape().halfHeight || 1; // пример для коробки
if (pos.y - halfHeight < fluidLevel) {
const submerged = Math.min(fluidLevel - (pos.y - halfHeight), 2 * halfHeight) / (2 * halfHeight);
const buoyancyForce = fluidDensity * submerged * 9.8 * body.getMass();
body.applyForce([0, buoyancyForce, 0]);
const velocity = body.getLinearVelocity();
const dragForce = velocity.map(v => -v * drag * submerged);
body.applyForce(dragForce);
}
}
Подъёмная сила позволяет реализовать плавание объектов, реалистичные эффекты плавучести при столкновениях и создаёт плавные динамические взаимодействия с жидкостями.
Для динамических реакций на игровые события можно объединять взрыв и подъёмную силу:
function handleEvent(world, event) {
if (event.type === 'explosion') {
applyExplosion(world, event.position, event.radius, event.power);
} else if (event.type === 'flood') {
world.bodies.forEach(body => applyBuoyancy(body, event.waterLevel, event.density, event.drag));
}
}
Такой подход позволяет масштабировать физику на уровне мира и синхронизировать с визуальными эффектами, делая поведение объектов правдоподобным и интерактивным.
Oimo.js предоставляет методы для контроля тел:
body.setPosition([x, y, z]) — мгновенная установка
позиции.body.setLinearVelocity([vx, vy, vz]) — прямое
управление скоростью.body.applyImpulse([ix, iy, iz]) — кратковременное
воздействие силы, имитирующее столкновение.body.getRotation() и
body.setRotation([x, y, z, w]) — управление ориентацией
через кватернионы.Использование этих методов позволяет создавать точные симуляции с событиями, требующими высокой точности при динамических взаимодействиях, таких как эффекты взрывов, подъёма объектов или сильного ветра.
Для больших сцен с множеством объектов рекомендуется:
broadphase: 2 для эффективного поиска
столкновений.iterations до необходимого минимума.Эти меры обеспечивают плавное выполнение симуляции даже на сложных сценах с множеством динамических тел.