AnimationClip и AnimationAction

В Three.js анимации реализованы через модульную систему, основанную на объектах AnimationClip, AnimationMixer и AnimationAction. Такая архитектура позволяет воспроизводить сложные движения моделей, управлять временными шкалами, смешивать анимации и динамически изменять их параметры.

Основная идея заключается в следующем:

  • AnimationClip — контейнер анимационных данных
  • AnimationMixer — механизм воспроизведения
  • AnimationAction — экземпляр воспроизведения клипа с настройками

Анимационные данные могут поступать из различных источников:

  • импортированные 3D-модели (например, glTF)
  • программно созданные keyframe-анимации
  • библиотечные анимации персонажей

AnimationClip

AnimationClip представляет собой набор ключевых кадров, описывающих изменение свойств объектов во времени. Он хранит саму анимацию, но не управляет её воспроизведением.

Основные характеристики

AnimationClip содержит:

  • name — имя клипа
  • duration — длительность анимации
  • tracks — массив треков анимации
  • blendMode — режим смешивания

Треки представляют собой временные последовательности изменений конкретных свойств объекта.

Структура клипа

AnimationClip
 ├─ name
 ├─ duration
 └─ tracks[]
      ├─ VectorKeyframeTrack
      ├─ QuaternionKeyframeTrack
      ├─ NumberKeyframeTrack
      └─ ColorKeyframeTrack

Каждый KeyframeTrack содержит:

  • временные отметки
  • значения параметров
  • интерполяцию

Создание AnimationClip

Клип можно создать программно.

const times = [0, 1, 2];
const values = [0, 5, 0];

const track = new THREE.NumberKeyframeTrack(
    '.position[x]',
    times,
    values
);

const clip = new THREE.AnimationClip(
    'moveX',
    2,
    [track]
);

Здесь:

  • times — временные точки
  • values — значения свойства
  • .position[x] — путь к анимируемому свойству

Типы KeyframeTrack

В Three.js используются несколько типов треков.

NumberKeyframeTrack

Используется для анимации числовых значений.

opacity
intensity
position.x

VectorKeyframeTrack

Для трёхмерных векторов.

position
scale
direction

QuaternionKeyframeTrack

Для вращений.

Использование кватернионов позволяет избежать проблем gimbal lock.

rotation
quaternion

ColorKeyframeTrack

Для изменения цвета.

material.color

Интерполяция

Ключевые кадры соединяются интерполяцией.

Доступны режимы:

  • InterpolateLinear
  • InterpolateDiscrete
  • InterpolateSmooth

Пример:

track.setInterpolation(THREE.InterpolateSmooth);

AnimationMixer

AnimationMixer отвечает за управление воспроизведением анимаций.

Он связан с конкретным объектом сцены.

const mixer = new THREE.AnimationMixer(mesh);

Mixer выполняет:

  • обновление времени
  • воспроизведение клипов
  • смешивание анимаций
  • управление состояниями

Обновление происходит в игровом цикле:

const delta = clock.getDelta();
mixer.update(delta);

AnimationAction

AnimationAction — объект управления воспроизведением AnimationClip.

Каждый Action создаётся через AnimationMixer.

const action = mixer.clipAction(clip);

Action управляет:

  • запуском
  • остановкой
  • скоростью
  • повторением
  • смешиванием

Основные свойства

Свойство Назначение
enabled активность действия
paused пауза
time текущее время
timeScale скорость
weight влияние при смешивании
loop режим цикла

Методы управления

play()

Запуск анимации.

action.play();

stop()

Полная остановка.

action.stop();

reset()

Сброс времени.

action.reset();

fadeIn()

Плавное появление.

action.fadeIn(0.5);

fadeOut()

Плавное исчезновение.

action.fadeOut(0.5);

Режимы повторения

AnimationAction поддерживает несколько режимов циклов.

LoopOnce

Анимация проигрывается один раз.

action.setLoop(THREE.LoopOnce);

LoopRepeat

Повторяется заданное количество раз.

action.setLoop(THREE.LoopRepeat, 3);

LoopPingPong

Анимация воспроизводится вперёд и назад.

action.setLoop(THREE.LoopPingPong, 5);

Скорость воспроизведения

Скорость регулируется параметром timeScale.

action.timeScale = 2;

Возможности:

Значение Эффект
1 нормальная скорость
2 в два раза быстрее
0.5 медленнее
-1 воспроизведение назад

Смешивание анимаций

Система blending позволяет плавно переходить между анимациями.

Пример:

walkAction.fadeOut(0.5);
runAction.fadeIn(0.5).play();

Таким образом создаётся переход:

Walk → Run

Вес анимации

Каждая AnimationAction имеет параметр weight.

0 = нет влияния
1 = полное влияние
action.setEffectiveWeight(0.5);

Это позволяет комбинировать движения.


Кроссфейдинг (Crossfade)

Crossfade — плавная смена анимации.

action1.crossFadeTo(action2, 0.3, false);

Параметры:

targetAction
duration
warp

Работа с несколькими клипами

Часто модели содержат несколько анимаций.

Пример с glTF:

loader.load('character.glb', (gltf) => {

    const model = gltf.scene;
    const mixer = new THREE.AnimationMixer(model);

    const clips = gltf.animations;

    const idle = mixer.clipAction(clips[0]);
    const walk = mixer.clipAction(clips[1]);
    const run = mixer.clipAction(clips[2]);

    idle.play();

});

Управление временем

AnimationAction хранит собственное время.

action.time

Можно вручную задать позицию анимации.

action.time = 1.5;

Ограничение последнего кадра

После завершения анимации можно зафиксировать финальное состояние.

action.clampWhenFinished = true;

И отключить повтор:

action.setLoop(THREE.LoopOnce);

События анимаций

AnimationMixer поддерживает события.

finished

Срабатывает после окончания клипа.

mixer.addEventListener('finished', (event) => {

    console.log('Animation finished');

});

loop

Срабатывает при повторе.

mixer.addEventListener('loop', (event) => {

});

Пример полной системы анимации

const mixer = new THREE.AnimationMixer(model);

const idle = mixer.clipAction(clips[0]);
const walk = mixer.clipAction(clips[1]);

idle.play();

function switchToWalk(){

    idle.fadeOut(0.3);
    walk
        .reset()
        .fadeIn(0.3)
        .play();

}

Оптимизация анимаций

Большие сцены могут содержать десятки анимаций. Для оптимизации используются:

Отключение неиспользуемых Action

action.stop();

Ограничение количества треков

Чем меньше анимируемых свойств, тем быстрее вычисления.


Использование одного AnimationMixer

Для персонажа или сложного объекта используется один mixer.


Программная генерация анимаций

AnimationClip может генерироваться динамически.

Пример вращения:

const times = [0, 2];

const values = [
    0,0,0,1,
    0,1,0,0
];

const track = new THREE.QuaternionKeyframeTrack(
    '.quaternion',
    times,
    values
);

const clip = new THREE.AnimationClip(
    'rotate',
    2,
    [track]
);

Взаимодействие с системой скелетной анимации

В моделях персонажей AnimationClip управляет:

  • костями скелета
  • morph targets
  • трансформациями

Чаще всего такие клипы импортируются из формата glTF.

Каждый трек содержит путь вида:

Bone.position
Bone.quaternion
Bone.scale

Роль AnimationClip и AnimationAction в архитектуре Three.js

Разделение обязанностей делает систему гибкой.

AnimationClip

  • хранит данные
  • не зависит от сцены
  • может переиспользоваться

AnimationAction

  • управляет воспроизведением
  • имеет состояние
  • работает через AnimationMixer

Такой подход позволяет:

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