Цилиндр: CylinderGeometry

В библиотеке Oimo.js объекты физики создаются через тела (RigidBody) и формы (Shape). Для работы с цилиндрами используется специальная форма, описывающая геометрию цилиндра, которая позволяет рассчитывать столкновения, массу и инерцию тела.

Цилиндр в Oimo.js определяется двумя основными параметрами: радиусом и высотой. Эти параметры задаются при создании формы цилиндра, а тело получает физические свойства через конфигурацию: массу, тип тела, коэффициенты трения и упругости.

import * as OIMO from "oimo";

// Создание физического мира
let world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2 });

// Создание тела с цилиндром
let cylinderBody = world.add({
    type: "dynamic",
    size: [1, 2, 1], // размеры: радиус, высота, радиус
    pos: [0, 5, 0],
    rot: [0, 0, 0],
    move: true,
    density: 1
});

Здесь size задаёт радиус цилиндра по оси X и Z, а по оси Y — высоту. Тип тела “dynamic” делает объект подвижным и реагирующим на силы.


Параметры цилиндра

Oimo.js поддерживает следующие ключевые параметры для цилиндров:

  • radius — радиус цилиндра по основанию.
  • height — высота цилиндра.
  • density — плотность материала, влияющая на массу.
  • friction — коэффициент трения при контакте с другими телами.
  • restitution — коэффициент упругости (отскок при столкновении).

Все эти параметры задаются либо через объект тела (add), либо через отдельную форму (ShapeConfig), что позволяет создавать сложные композиции из цилиндров.

let shapeConfig = new OIMO.ShapeConfig();
shapeConfig.geometry = new OIMO.CylinderGeometry(1, 2); // радиус 1, высота 2
shapeConfig.friction = 0.5;
shapeConfig.restitution = 0.3;

let cylinderBody2 = new OIMO.RigidBody({
    type: "dynamic",
    pos: [2, 10, 0],
    move: true
});
cylinderBody2.addShape(shapeConfig);
world.addRigidBody(cylinderBody2);

Создание сцены с цилиндрами

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

let ground = world.add({
    type: "static",
    size: [20, 1, 20],
    pos: [0, 0, 0]
});

for (let i = 0; i < 5; i++) {
    world.add({
        type: "dynamic",
        size: [0.5, 2, 0.5],
        pos: [i * 2, 5, 0],
        density: 1
    });
}

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


Ориентация и вращение цилиндра

Цилиндры в Oimo.js по умолчанию ориентированы вдоль оси Y. Для изменения ориентации используется свойство rotation или методы вращения тела.

cylinderBody.setOrientation(new OIMO.Quat().setFromEuler(0, Math.PI / 2, 0));

Поворот на 90 градусов вокруг оси Y меняет направление цилиндра, что важно для моделирования лежащих труб, бревен или катящихся объектов.


Интеграция с визуализацией

Для отображения цилиндров в WebGL или Three.js размеры тела и геометрии должны совпадать. Например:

import * as THREE from "three";

let geometry = new THREE.CylinderGeometry(1, 1, 2, 32);
let material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
let mesh = new THREE.Mesh(geometry, material);

mesh.position.copy(cylinderBody.getPosition());
mesh.quaternion.copy(cylinderBody.getQuaternion());
scene.add(mesh);

Каждое обновление физического мира должно синхронизировать позицию и вращение визуального объекта с телом Oimo.js.


Масса, плотность и инерция

Масса цилиндра вычисляется автоматически по формуле:

[ m = r^2 h]

где ( r ) — радиус, ( h ) — высота, density — плотность материала. Для вращения учитывается момент инерции цилиндра:

[ I_x = I_z = m (3 r^2 + h^2), I_y = m r^2]

Это позволяет корректно моделировать наклонные падения, вращения и крутящие моменты.


Применение силы и столкновения

Цилиндры в Oimo.js реагируют на силы и импульсы через методы applyForce и applyImpulse. Например, толчок в сторону оси X:

cylinderBody.applyImpulse(new OIMO.Vec3(10, 0, 0));

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


Особенности работы с массивами цилиндров

При создании множества цилиндров важно учитывать производительность. Рекомендуется:

  • Использовать статические тела для неподвижных объектов.
  • Минимизировать количество контактных точек.
  • Применять broadphase для оптимизации детектирования столкновений.
let world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2 });

Параметр broadphase ускоряет расчёт столкновений, что критично при больших сценах с десятками цилиндров.


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