起因:最近想做模型的动画,结果上网查资料,看到网上好多对于模型控制的文章都有限制。决定还是自己研究下。欢迎大家一起探讨,评论留言。
火箭
全部代码在最后
模型控制,第一步当然是需要一个合适的模型,去cesium官网实例中找到了一个合适的模型,并且还顺带了一些模型操作方法。

搜索关键字applyArticulations;模型地址;
拿到模型迫不及待的想在自己自己的项目中加载出来
加载方式有两种entity和Primitive, 我个人更喜欢第二种Primitive方式。
对应的参数就不做解释了,文档中都有
let rocketPrimitive: Cesium.Model
let position = Cesium.Cartesian3.fromDegrees(104.200403, 30.396231, 600.0);
const hpRoll = new Cesium.HeadingPitchRoll();
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator("north", "west");
const rocketPrimitive = viewer.scene.primitives.add(Cesium.Model.fromGltf({url: "https://assets.agi.com/models/launchvehicle.glb",modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position,hpRoll,Cesium.Ellipsoid.WGS84,fixedFrameTransform),minimumPixelSize: 128,}));

const articulations = model.sceneGraph._runtimeArticulations;官方的这段代码我用着报错,文档里面没有。也不知道啥问题

发现了nodes,模型里面的关节点,就是模型由哪些部分组成,官网文档中也明确的说了。画红线的那段话翻译出来就是"返回glTF中具有给定名称的节点。这用于修改用户定义动画的节点变换"
rocketPrimitive.setArticulationStage( //对应属性改变参数值'SRBFlames Size',1);rocketPrimitive.applyArticulations(); //使得修改的属性生效

Cesium.Transforms.headingPitchRollToFixedFrame(showPath[activeIndex], //当前坐标点Cesium.Cartesian3hpRoll,//姿态Cesium.Ellipsoid.WGS84,fixedFrameTransform,rocketPrimitive.modelMatrix //模型当前的世界矩阵);
viewer.scene.preUpdate.addEventListener(keepRun)
const keepRun = (scene: Cesium.Scene, time: number) => {if (activeIndex >= maxIndex) returnif (autoDirection && activeIndex > 0 && !showPath[activeIndex - 1].equals(showPath[activeIndex])) { //判断前后两个点是否一样,不一样就调整姿态const heading = Helper.getHeading(showPath[activeIndex - 1],showPath[activeIndex],);if (heading) hpRoll.heading = headingconst pitch = Helper.getPitch(showPath[activeIndex - 1],showPath[activeIndex])if (pitch) hpRoll.pitch = pitch}Cesium.Transforms.headingPitchRollToFixedFrame(showPath[activeIndex],hpRoll,Cesium.Ellipsoid.WGS84,fixedFrameTransform,rocketPrimitive.modelMatrix);activeIndex += 1
}

可以平滑的移动了。
当然火焰的生起也应当平滑,控制模型都需要平滑的操作,直接写个函数控制
function modelAnimationController(controller: typeModelAnimationController) {const { type, initVal, maxVal, fn, step, minVal } = controllerlet num = initVallet stopFrame: numberconst max = maxVal || 1const min = minVal || -99999const duration = step || 0.1const render = () => {num += durationrocketPrimitive.setArticulationStage(type,num);rocketPrimitive.applyArticulations();stopFrame = requestAnimationFrame(render)if (num > max || num <= min) {window.cancelAnimationFrame(stopFrame)fn && fn()}}render()
}
modelAnimationController({type: 'SRBFlames Size', initVal: 0, maxVal: 1, step: 0.05, fn: () => {viewer.scene.preUpdate.addEventListener(keepRun)}
})

>
上一篇:三国演义里鲁肃长的外貌特征,
下一篇:搜索技术——盲目与启发