Анимации моделей

CesiumJS поддерживает анимации в первую очередь через формат glTF/GLB, где встроены скелетные и клиповые анимации. При загрузке модели через Cesium.Model.fromGltf или Cesium.Model.fromGltfAsync объект сцены получает доступ к набору анимационных треков, определённых внутри файла.

Основная структура:

  • glTF animation clips — набор предзаписанных анимаций (walk, idle, run)
  • skeleton/bones — система костей для деформации меша
  • keyframes — ключевые кадры трансформаций
const viewer = new Cesium.Viewer("cesiumContainer");

const model = viewer.scene.primitives.add(
  Cesium.Model.fromGltf({
    url: "character.glb",
    scale: 1.0,
  })
);

После загрузки модель становится частью сцены, но анимации не всегда активируются автоматически — управление осуществляется через activeAnimations.


Активные анимации модели

Ключевая точка управления анимацией в CesiumJS — коллекция model.activeAnimations.

Каждая модель содержит список доступных клипов, которые можно запускать, останавливать и комбинировать.

model.readyPromise.then(() => {
  const animations = model.activeAnimations;

  animations.add({
    name: "Run",
    loop: Cesium.ModelAnimationLoop.REPEAT,
    speedup: 1.0,
  });
});

Основные параметры анимации

  • name — имя клипа из glTF
  • loop — режим повторения
  • speedup — коэффициент скорости
  • reverse — проигрывание в обратном направлении
  • startOffset — смещение начала

Режимы цикла

  • Cesium.ModelAnimationLoop.REPEAT — бесконечное повторение
  • Cesium.ModelAnimationLoop.CLAMP — остановка в конце
  • Cesium.ModelAnimationLoop.NONE — одноразовое воспроизведение

Управление несколькими анимациями

CesiumJS позволяет запускать несколько анимаций одновременно. Это используется для смешивания движений: например, бег + поворот головы.

model.activeAnimations.add({
  name: "Run",
  loop: Cesium.ModelAnimationLoop.REPEAT
});

model.activeAnimations.add({
  name: "Wave",
  loop: Cesium.ModelAnimationLoop.CLAMP
});

Каждая анимация влияет на отдельные кости или каналы трансформации. Если в glTF предусмотрено разделение слоёв, происходит естественное смешивание.


Синхронизация с мировым временем

CesiumJS опирается на глобальные часы сцены — Cesium.Clock. Анимации могут быть привязаны к этому времени, что позволяет синхронизировать движение объектов с реальными временными шкалами.

viewer.clock.shouldAnimate = true;
viewer.clock.multiplier = 2.0;

Влияние Clock на анимации

  • ускорение всей сцены влияет на скорость клипов
  • пауза глобального времени останавливает все анимации
  • можно использовать фиксированные интервалы времени

Процедурные анимации и обновление кадров

Помимо встроенных glTF-анимаций, CesiumJS поддерживает процедурные изменения состояния модели через scene.preRender или modelMatrix.

viewer.scene.preRender.addEventListener(function (scene, time) {
  model.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
    position,
    new Cesium.HeadingPitchRoll(time.secondsOfDay * 0.01, 0, 0)
  );
});

Такой подход применяется для:

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

Анимация положения через свойства Entity

При использовании Entity API движение модели чаще задаётся через SampledPositionProperty, которая интерполирует координаты во времени.

const position = new Cesium.SampledPositionProperty();

position.addSample(
  Cesium.JulianDate.now(),
  Cesium.Cartesian3.fromDegrees(30.0, 50.0, 0)
);

position.addSample(
  Cesium.JulianDate.addSeconds(
    Cesium.JulianDate.now(),
    10,
    new Cesium.JulianDate()
  ),
  Cesium.Cartesian3.fromDegrees(31.0, 50.0, 0)
);

Подключение к Entity

viewer.entities.add({
  position: position,
  model: {
    uri: "vehicle.glb"
  }
});

Cesium автоматически интерполирует движение между точками, создавая плавную анимацию.


Интерполяция и типы сглаживания

CesiumJS использует несколько стратегий интерполяции:

  • линейная интерполяция
  • Lagrange Polynomial Approximation
  • Hermite Interpolation (для производных)
position.setInterpolationOptions({
  interpolationDegree: 2,
  interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});

Выбор метода влияет на:

  • плавность траектории
  • точность движения
  • вычислительную нагрузку

Анимация скелетных моделей

glTF-модели часто содержат кости (bones), влияющие на деформацию меша. CesiumJS применяет матрицы трансформации к каждой кости на основе ключевых кадров.

Структура скелетной анимации:

  • joint transforms
  • inverse bind matrices
  • skinning weights

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


Управление скоростью и таймингом

Скорость воспроизведения анимации регулируется несколькими уровнями:

Уровень модели

model.activeAnimations.add({
  name: "Walk",
  speedup: 0.5
});

Уровень сцены

viewer.clock.multiplier = 0.2;

Комбинированный эффект

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


Петли, задержки и переходы

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

Пример логики переключения

const anims = model.activeAnimations;

anims.add({
  name: "Idle",
  loop: Cesium.ModelAnimationLoop.REPEAT
});

setTimeout(() => {
  anims.removeAll();
  anims.add({
    name: "Jump",
    loop: Cesium.ModelAnimationLoop.CLAMP
  });
}, 3000);

Плавность переходов зависит от наличия cross-fade данных в самом glTF.


Привязка анимации к траектории движения

Для объектов, перемещающихся по маршруту, анимация часто комбинируется с направлением движения.

const orientation = new Cesium.VelocityOrientationProperty(position);

viewer.entities.add({
  position: position,
  orientation: orientation,
  model: {
    uri: "aircraft.glb"
  }
});

Такой подход обеспечивает автоматическое вращение модели по вектору скорости.


Производительность анимаций

CesiumJS оптимизирует анимации через GPU, но при большом количестве моделей возникают ограничения.

Критические факторы:

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

Оптимизация достигается через:

  • LOD (Level of Detail)
  • упрощение скелета
  • отключение неиспользуемых клипов
  • батчинг 3D Tiles

Частые архитектурные подходы

1. Статические модели с редкими анимациями

Используется для инфраструктуры, техники, зданий с редкими событиями.

2. Непрерывно движущиеся объекты

Применяется для транспорта, дронов, спутников.

3. Смешанные сцены

Комбинация Entity API и primitive Model для разделения логики и рендера.


Ошибки и особенности поведения

При работе с анимациями часто возникают характерные ограничения:

  • отсутствие анимаций в GLB приводит к пустому activeAnimations
  • пересечение нескольких клипов может давать конфликт каналов
  • резкое изменение modelMatrix может “ломать” скелетную анимацию
  • несоответствие единиц масштаба влияет на скорость визуального движения

Связь с рендер-циклом сцены

Анимации обновляются в каждом кадре через render loop CesiumJS. Внутри цикла происходит:

  • обновление времени Clock
  • вычисление активных ключевых кадров
  • пересчёт матриц костей
  • GPU skinning
  • отрисовка кадра

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