Скелетная анимация: Skeleton и Bone

Скелетная анимация является важным элементом при создании анимаций для персонажей и объектов в 3D графике. В библиотеке Babylon.js для работы с такими анимациями используются два ключевых компонента: Skeleton и Bone. Эти объекты позволяют моделировать структуру персонажа или объекта и анимировать их части с учетом их иерархии.

Скелетная структура: Skeleton

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

Создание Skeleton

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

let skeleton = new BABYLON.Skeleton("mySkeleton", 0, scene);

Здесь "mySkeleton" — это имя скелета, а 0 — идентификатор скелета, который обычно используется для уникальной идентификации в системе. Объект scene передается для привязки скелета к текущей сцене.

Связь с Mesh

Скелет в Babylon.js обычно используется совместно с Mesh. Это означает, что объект, например, 3D модель, будет анимироваться с помощью костей скелета. Связь между мешем и скелетом устанавливается через SkeletonHelper или специальное преобразование для работы с костями.

let mesh = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
mesh.skeleton = skeleton;

Применение анимаций к Skeleton

После того как скелет создан и привязан к объекту, можно начать применять к нему анимации. Анимации для скелета в Babylon.js создаются через объект Animation. Каждая анимация может воздействовать на различные параметры костей, такие как их вращение, позиция и масштаб.

let boneRotationAnimation = new BABYLON.Animation(
  "rotateBone",
  "rotation.x",
  30,
  BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);
boneRotationAnimation.setKeys([
  { frame: 0, value: 0 },
  { frame: 20, value: Math.PI },
  { frame: 40, value: 0 }
]);

skeleton.beginAnimation(boneRotationAnimation);

Здесь создается анимация для вращения кости вокруг оси X. Анимация воспроизводится по циклу, изменяя угол поворота кости.

Кости и их взаимодействие: Bone

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

Создание Bone

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

let bone = new BABYLON.Bone("headBone", skeleton, null, BABYLON.Matrix.Identity());

Здесь "headBone" — это имя кости, skeleton — скелет, к которому она будет привязана, а null указывает, что кость не имеет родительской кости, то есть она будет корневой. Матрица BABYLON.Matrix.Identity() представляет начальное положение кости.

Иерархия костей

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

let upperArmBone = new BABYLON.Bone("upperArm", skeleton, null, BABYLON.Matrix.Identity());
let lowerArmBone = new BABYLON.Bone("lowerArm", skeleton, upperArmBone, BABYLON.Matrix.Translation(0, -1, 0));

Здесь lowerArmBone — это кость, которая является дочерней для кости upperArmBone. Матрица BABYLON.Matrix.Translation(0, -1, 0) задает смещение для нижней части руки.

Применение анимации к костям

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

let handRotationAnimation = new BABYLON.Animation(
  "rotateHand",
  "rotation.z",
  30,
  BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

handRotationAnimation.setKeys([
  { frame: 0, value: 0 },
  { frame: 20, value: Math.PI / 2 },
  { frame: 40, value: 0 }
]);

lowerArmBone.animations.push(handRotationAnimation);

В этом примере создается анимация вращения кисти. Кость руки будет вращаться вокруг своей оси Z. Анимация будет повторяться циклично.

Особенности работы с костями и скелетами в Babylon.js

Контроль над анимацией

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

skeleton.getAnimationByName("rotateHand").pause();

Этот код приостанавливает анимацию, которая была применена к руке. Для ускорения или замедления анимации можно использовать метод speedRatio.

skeleton.getAnimationByName("rotateHand").speedRatio = 2;

Совмещение скелетной анимации с другими эффектами

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

let physicsImpostor = new BABYLON.PhysicsImpostor(mesh, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 1 }, scene);

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

Заключение

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