Pivot point и смещение центра вращения

В Babylon.js концепция pivot point (или опорной точки) используется для управления вращением, масштабированием и позиционированием объектов в 3D-пространстве. Это ключевой механизм, который позволяет задавать точку, вокруг которой будет происходить трансформация объекта.

Пивот-точка в Babylon.js

Когда объект 3D-сцены вращается или масштабируется, важно понять, откуда будет происходить изменение. По умолчанию эта точка привязки находится в центре объекта, но в Babylon.js можно настроить её для достижения более сложных и гибких эффектов.

Пивот-точка — это локальная точка объекта, относительно которой вычисляются все трансформации. Изменяя пивот-точку, можно контролировать, как именно объект будет вращаться или изменять размеры.

let mesh = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
mesh.position = new BABYLON.Vector3(0, 0, 0);

В данном примере объект создается с привязкой пивот-точки по умолчанию в центре. Если необходимо, чтобы объект вращался вокруг угла, можно изменить пивот-точку с помощью свойства setPivotPoint().

mesh.setPivotPoint(new BABYLON.Vector3(1, 1, 1));  // Изменение пивот-точки на угол

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

Вращение и смещение центра

При изменении пивот-точки важно учитывать, как это влияет на вращение объекта. Например, если объект расположен в центре сцены, а его пивот-точка сдвинута в другую точку, вращение объекта будет происходить относительно этой новой точки. Смещение центра вращения может быть полезно в таких сценариях, как создание объектов, вращающихся вокруг своей оси, или анимация сложных объектов с несколькими компонентами.

mesh.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0);  // Вращение вокруг X-оси

Смещение пивот-точки также влияет на начальную позицию объекта. Если пивот-точка перемещена за пределы объекта, можно наблюдать, как он изменяет положение на сцене при вращении. Это создаёт эффект смещения объекта, как если бы его центр вращения был смещён в другую точку.

Использование пивот-точки для анимаций

Одним из самых популярных применений пивот-точки является создание анимаций, где объект должен вращаться или масштабироваться вокруг конкретной точки. В Babylon.js для этого можно использовать анимации, контролируя пивот-точку для каждого объекта, чтобы добиться желаемого эффекта.

let animation = new BABYLON.Animation("rotateAnim", "rotation.y", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
let keys = [
    { frame: 0, value: 0 },
    { frame: 100, value: Math.PI * 2 }
];
animation.setKeys(keys);
mesh.animations.push(animation);
scene.beginAnimation(mesh, 0, 100, true);

Этот пример анимирует вращение объекта вокруг оси Y. Для более сложных объектов, таких как машины или персонажи, можно будет использовать пивот-точку для задания более сложных траекторий движения, которые зависят от того, где находится точка вращения.

Применение смещения пивот-точки для иерархий объектов

Babylon.js поддерживает работу с иерархиями объектов, что позволяет комбинировать несколько объектов в один для более сложных сцен. В таких случаях пивот-точка становится особенно важной, так как она определяет, как все дочерние объекты будут вращаться и изменяться.

Когда объект является дочерним элементом другого объекта, его трансформации будут зависеть от пивот-точки родительского объекта. Если родительский объект вращается, все его дочерние объекты вращаются вокруг той же самой точки. Однако если пивот-точка дочернего объекта будет изменена, это приведёт к тому, что дочерний объект начнёт вращаться относительно новой точки, даже если родитель продолжает вращаться вокруг своей точки.

let parent = BABYLON.MeshBuilder.CreateBox("parentBox", { size: 3 }, scene);
let child = BABYLON.MeshBuilder.CreateSphere("childSphere", { diameter: 1 }, scene);

child.parent = parent;
child.setPivotPoint(new BABYLON.Vector3(1.5, 0, 0));  // Смещение пивот-точки относительно родителя

В этом примере объект child будет вращаться вокруг своего сдвинутого пивота, несмотря на то, что родитель будет оставаться неподвижным.

Трансформация с учётом пивот-точки

Когда пивот-точка изменена, важно правильно управлять трансформациями, чтобы учесть её влияние. Смещение пивот-точки приводит к изменению не только точки вращения, но и положения объекта в пространстве. Поэтому важно учитывать как локальные, так и глобальные координаты.

  • Локальная позиция объекта — это положение объекта относительно его пивот-точки.
  • Глобальная позиция — это положение объекта относительно координатной системы всей сцены.

Если пивот-точка изменена, объект может перемещаться по сцене в глобальной системе координат, даже если его локальная позиция остаётся неизменной. Для правильной работы с этими трансформациями можно использовать методы getWorldMatrix() и setPositionWithLocalVector().

let worldMatrix = mesh.getWorldMatrix();
let localPosition = mesh.position.clone().subtract(mesh.getPivotPoint());
mesh.setPositionWithLocalVector(localPosition);

Этот код позволяет корректно перемещать объект с учётом изменений пивот-точки.

Резюме

Пивот-точка и смещение центра вращения — это мощные инструменты для управления 3D-объектами в Babylon.js. Использование этих концепций позволяет создавать динамичные сцены, где объекты могут вращаться, масштабироваться и перемещаться вокруг заданных точек. Смещение пивот-точки помогает в анимации сложных объектов и в работе с иерархиями, где важна точность трансформаций.