
Cesium 中的 glTF 2.0 动画模型 AnimatedTriangle缓冲区布局、四元数旋转关键帧与 ModelAnimation 驱动原理【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium导读AnimatedTriangle 是 Cesium 仓库中内置的最简 glTF 2.0 动画示例模型一个由 3 个顶点构成的灰色三角形通过 glTF 动画系统绕自身旋转 360°。本文以该模型为最小案例逐层拆解 glTF 2.0 的 Buffer/BufferView/Accessor 数据布局、LINEAR 插值下的四元数旋转关键帧以及 Cesium 引擎中ModelAnimation/ModelAnimationCollection对 glTF 动画的驱动与循环机制。读完本文你将能够读懂任何 glTF 模型的几何与动画 JSON 结构并掌握在 Cesium 中播放、循环、调速模型动画的完整实战方法。模型文件一览AnimatedTriangle 模型位于仓库 Specs/Data/Models/glTF-2.0/AnimatedTriangle目录结构如下glTF/AnimatedTriangle.gltf—— glTF 2.0 主 JSON 文件描述场景、网格、动画与数据引用glTF/simpleTriangle.bin—— 44 字节几何数据缓冲顶点位置 索引glTF/animation.bin—— 100 字节动画数据缓冲时间轴 旋转四元数screenshot/screenshot.gif、screenshot/simpleTriangle.png、screenshot/animation.png—— 官方效果动图与数据布局示意图。其官方 README 声明该模型为公有领域Public domainCC0授权可自由用于学习与测试。几何数据布局从 Buffer 到 Accessor 的三级结构glTF 2.0 中几何数据按 Buffer缓冲→ BufferView缓冲视图→ Accessor访问器 三级组织。打开 AnimatedTriangle.gltf 可以看到buffers[0]指向simpleTriangle.bin长度 44 字节被拆成两个 BufferViewBufferViewbufferbyteOffsetbyteLengthtarget用途000634963ELEMENT_ARRAY_BUFFER索引数据1083634962ARRAY_BUFFER顶点位置属性两个 Accessor 将原始字节解释为有语义的数据accessors[0]componentType: 5123GL_UNSIGNED_SHORT、type: SCALAR、count: 3即 3 个无符号短整型索引值为[0, 1, 2]构成三角形的顶点连接顺序accessors[1]componentType: 5126GL_FLOAT、type: VEC3、count: 3即 3 个三维浮点位置min: [0,0,0]、max: [1,1,0]对应坐标(0,0,0)、(1,0,0)、(0,1,0)。可见 Triangle 之名名副其实整个几何体只有 3 个顶点和 3 条索引simpleTriangle.png示意图直观展示了这一布局。nodes[0]挂载该网格并带有初始rotation: [0,0,0,1]单位四元数scenes[0]引用该节点构成完整的 glTF 场景图。动画数据5 个关键帧的旋转通道AnimatedTriangle 的动画核心位于 AnimatedTriangle.gltf 的animations数组其结构如下animations: [ { samplers: [{ input: 2, // 时间轴 accessor interpolation: LINEAR, output: 3 // 旋转四元数 accessor }], channels: [{ sampler: 0, target: { node: 0, path: rotation } }], name: Sample Animation } ]动画数据缓冲animation.bin100 字节通过单个 BufferView 暴露再被两个 Accessor 切片使用accessors[2]SCALAR/FLOAT/count: 5时间轴采样值[0.0, 0.25, 0.5, 0.75, 1.0]对应max: [1.0]、min: [0.0]accessors[3]VEC4/FLOAT/count: 5byteOffset 20即 5 个四元数[x, y, z, w]max: [0,0,1,1]、min: [0,0,0,-0.707]。channel 的target.path: rotation表明该通道驱动节点 0 的旋转。四元数序列描绘了绕 Z 轴的整圈旋转从单位四元数(0,0,0,1)出发经过(0,0,0.307,0.952)、(0,0,1,0)半圈等中间姿态最终回到起点配合interpolation: LINEAR在相邻关键帧间做线性插值形成平滑的 360° 旋转。animation.png示意图清晰标注了 TIME 与 rotation 两组访问器在 100 字节缓冲中的偏移关系0 与 20screenshot.gif则是该动画的实际运行效果。对比例同一仓库的 BoxAnimated 模型同样基于四元数关键帧驱动 node 旋转而 BoxTextured、BoxInterleaved 则展示了顶点属性交织等不同的几何布局变体可用于对比学习。Cesium 中的动画运行时ModelAnimationCollectionglTF 文件中的动画描述的是静态的动画定义而真正驱动它播放的是 Cesium 引擎的运行时类。Cesium 中模型动画的入口是Model#activeAnimations其类型为 ModelAnimationCollection。官方注释明确要求Access a models animations viaModel#activeAnimationsDo not call the constructor directly——即动画集合由模型自动创建用户通过add/addAll/remove/removeAll管理动画实例。每次add都会创建并返回一个 ModelAnimation 实例同一个 glTF 动画可以创建多个不同起始时间的活动实例这正是活动动画是动画的实例这一设计的体现。ModelAnimationCollection还暴露了animationAdded、animationRemoved事件用于 UI 同步以及animateWhilePaused属性——设为true时动画在场景时间暂停时仍可播放但实际取决于动画自身的animationTime函数。add 的核心参数ModelAnimationCollection#add 的参数节选包括name/index按 glTF 动画名或索引标识要播放的动画二者必须给出其一startTime/stopTime场景时间JulianDate维度的起止点缺省时分别表示下一帧开始和播满全时长delay距startTime的延迟秒数仅当loop为NONE时生效removeOnStop停止后自动从集合移除仅当loop为NONE时生效multiplier播放倍速大于 1 加速、小于 1 减速reverse反向播放loop循环模式见下文。循环模式与状态机循环行为由 ModelAnimationLoop 枚举控制NONE (0)只播一次REPEAT (1)播完后立即从头循环MIRRORED_REPEAT (2)先正向、再反向交替循环。运行时状态则记录在 ModelAnimationState 中仅有STOPPED (0)与ANIMATING (1)两态说明 Cesium 对 glTF 动画的状态管理非常轻量——动画是否在播由集合中的实例与时间函数共同决定。事件钩子每个 ModelAnimation 实例提供三个事件start动画开始播放在渲染完一帧后触发可用于联动音效或粒子系统update每帧更新时触发回调携带当前 glTF 动画时间可在动画进行到特定时刻时启动新动画stop动画停止时触发。实战在 Cesium 中播放 AnimatedTriangle方式一直接加载 glTF 模型将模型文件放入可访问的静态目录后通过Model.fromGltf或viewer.entities.add的model图形加载const entity viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), model: { uri: AnimatedTriangle/glTF/AnimatedTriangle.gltf, scale: 100.0, runAnimations: true, // 默认 true }, }); entity.model.readyEvent.addEventListener((model) { // 模型就绪后获取动画集合按名称播放 const animations model.activeAnimations; animations.add({ name: Sample Animation, loop: Cesium.ModelAnimationLoop.REPEAT, multiplier: 1.0 }); });方式二Entity 的 runAnimations 属性Entity 模型默认自动播放 glTF 动画。引擎内部在 ModelVisualizer 中监听model.ready当runAnimations为true时执行model.activeAnimations.addAll({ loop: ModelAnimationLoop.REPEAT })一次性循环播放模型所有动画为false时则removeAll()停止。因此想快速预览 AnimatedTriangle 的旋转加载即可看到效果无需写任何播放代码。事件与参数组合示例entity.model.readyEvent.addEventListener((model) { const animation model.activeAnimations.add({ name: Sample Animation, multiplier: 2.0, // 2 倍速 reverse: true, // 反向旋转 loop: Cesium.ModelAnimationLoop.REPEAT, }); animation.start.addEventListener((m, a) console.log(start: ${a.name})); animation.update.addEventListener((m, a, t) console.log(glTF 时间: ${t})); animation.stop.addEventListener((m, a) console.log(stop: ${a.name})); });注意事项AnimatedTriangle 的动画名称为Sample Animation见 AnimatedTriangle.gltf按名称add时需精确匹配也可改用index: 0按索引引用。delay、removeOnStop仅在loop: NONE时生效需要循环播放时请使用REPEAT或MIRRORED_REPEAT。时间轴采样值[0.0, 1.0]表示动画时长为 1 秒glTF 内部时间实际播放速度同时受multiplier与场景时钟控制。小结从数据角度看AnimatedTriangle 是 glTF 2.0 三级数据布局Buffer/BufferView/Accessor与动画系统sampler channel 四元数关键帧的最小教科书44 字节几何 100 字节动画即可表达一次完整的 360° 旋转。从引擎角度看Cesium 通过ModelAnimationCollection将 glTF 静态动画定义实例化为可播放的活动动画并提供循环模式、倍速、反向、事件钩子等运行时控制能力。理解了这个最小模型你就掌握了阅读任意 glTF 动画与在 Cesium 中驱动模型动画的基础方法论。【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考