CesiumJS поддерживает анимации в первую очередь через формат
glTF/GLB, где встроены скелетные и клиповые анимации. При загрузке
модели через Cesium.Model.fromGltf или
Cesium.Model.fromGltfAsync объект сцены получает доступ к
набору анимационных треков, определённых внутри файла.
Основная структура:
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,
});
});
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;
Помимо встроенных 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 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)
);
viewer.entities.add({
position: position,
model: {
uri: "vehicle.glb"
}
});
Cesium автоматически интерполирует движение между точками, создавая плавную анимацию.
CesiumJS использует несколько стратегий интерполяции:
position.setInterpolationOptions({
interpolationDegree: 2,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});
Выбор метода влияет на:
glTF-модели часто содержат кости (bones), влияющие на деформацию меша. CesiumJS применяет матрицы трансформации к каждой кости на основе ключевых кадров.
Система автоматически вычисляет итоговую деформацию вершин на 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, но при большом количестве моделей возникают ограничения.
Критические факторы:
Оптимизация достигается через:
Используется для инфраструктуры, техники, зданий с редкими событиями.
Применяется для транспорта, дронов, спутников.
Комбинация Entity API и primitive Model для разделения логики и рендера.
При работе с анимациями часто возникают характерные ограничения:
activeAnimationsmodelMatrix может “ломать” скелетную
анимациюАнимации обновляются в каждом кадре через render loop CesiumJS. Внутри цикла происходит:
ClockЭто делает систему чувствительной к нагрузке сцены и позволяет синхронизировать все движущиеся элементы в едином временном континууме.