AnimationObjectGroup

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

AnimationObjectGroup работает как контейнер для объектов, участвующих в анимации, позволяя уменьшить накладные расходы, связанные с отдельной анимацией каждого объекта через AnimationMixer. Основная идея заключается в том, чтобы группировать объекты и применять к ним общие KeyframeTrack и AnimationClip, что повышает производительность и упрощает синхронизацию.


Создание и инициализация

Объект AnimationObjectGroup создается с помощью конструктора:

import { AnimationObjectGroup } from 'three';

const group = new AnimationObjectGroup();

Можно сразу передать массив объектов:

const group = new AnimationObjectGroup(mesh1, mesh2, mesh3);

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


Добавление и удаление объектов

Добавление объектов в группу выполняется методами:

group.add(mesh4, mesh5);

Удаление объектов:

group.remove(mesh2);

Методы поддерживают передачу нескольких объектов через аргументы. При удалении объекта из группы все связанные с ним KeyframeTrack автоматически перестают применяться.


Связь с AnimationMixer

AnimationObjectGroup тесно интегрирован с AnimationMixer. Вместо создания отдельного миксера для каждого объекта, можно создать один миксер для группы:

import { AnimationMixer } from 'three';

const mixer = new AnimationMixer(group);

В этом случае AnimationMixer будет управлять анимациями всех объектов в группе одновременно. Применение анимационных клипов происходит через clipAction:

import { AnimationClip } from 'three';

const clip = AnimationClip.findByName(clips, 'walk');
const action = mixer.clipAction(clip, group);
action.play();

Особенности KeyframeTrack и синхронизация

AnimationObjectGroup позволяет создавать KeyframeTrack для нескольких объектов сразу. Например, VectorKeyframeTrack может задавать положение или масштаб всех объектов в группе:

import { VectorKeyframeTrack } from 'three';

const positionTrack = new VectorKeyframeTrack(
  '.position', // путь относительно каждого объекта в группе
  [0, 1, 2],  // ключевые моменты времени
  [0,0,0,  1,1,1,  2,2,2] // значения для всех объектов
);

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


Применение с InstancedMesh

Для InstancedMesh AnimationObjectGroup особенно эффективен. Можно анимировать сразу несколько экземпляров одного меша, используя один трек:

import { InstancedMesh } from 'three';

const instancedMesh = new InstancedMesh(geometry, material, 10);
const group = new AnimationObjectGroup(instancedMesh);

const mixer = new AnimationMixer(group);

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


Важные методы и свойства

  • group.nObjects — количество объектов в группе.
  • group.stats — возвращает статистику обновлений анимации.
  • group.setWeight(obj, weight) — устанавливает вес анимации для конкретного объекта в группе.
  • group.uncache(obj) — удаляет объект и освобождает связанные ресурсы треков.

Рекомендации по использованию

  1. Группировать только анимируемые объекты, чтобы не нагружать миксер ненужными объектами.
  2. Использовать один AnimationMixer на группу вместо множества миксеров для каждого объекта.
  3. Синхронизировать ключевые кадры так, чтобы длина массивов значений соответствовала количеству объектов в группе.
  4. При работе с InstancedMesh предпочтительно использовать AnimationObjectGroup для оптимизации производительности.

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