粒子系统使用两个转换粒子系统使用两个转换矩阵来定位:
modelMatrix : 把粒子系统从模型坐标系转到世界坐标系。emitterModelMatrix : 在粒子系统的局部坐标系内变换粒子发射器。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link href="./Cesium-1.67/Build/Cesium/Widgets/widgets.css" rel="stylesheet" /> <script src="./Cesium-1.67/Build/Cesium/Cesium.js"></script> <style> html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; } </style> </head> <body> <div id="cesiumContainer"></div> <script> //定义初始化变量 var viewer, scene; //初始地图参数 var tileset; //调整模型所需tileset对象 // 初始化三维地球 viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, //地图默认点击弹窗 selectionIndicator: false, //地图默认点击元素绿色框框 navigation: false, //导航栏 animation: false, baseLayerPicker: false, geocoder: false, timeline: false, //时间线 sceneModePicker: false, //场景模式选择器 navigationHelpButton: false, //导航帮助按钮 fullscreenButton: false, //全屏按钮 homeButton: false, //主页按钮 orderIndependentTranslucency: false, shouldAnimate : true//场景中的动画自动播放 }); //隐藏图标 viewer.bottomContainer.style.display = "none"; //隐藏窗口底部区域的DOM元素 // 获取场景 scene = viewer.scene; var entity = viewer.entities.add({ // 加载飞机模型 model : { uri : './Cesium-1.67/Apps/SampleData/models/CesiumAir/Cesium_Air.glb', //模型url minimumPixelSize : 64,//不管缩放如何,模型的最小最小像素大小。 }, position : Cesium.Cartesian3.fromDegrees(-112.110693, 36.0994841, 1000.0)//添加实体到那个地方 }); viewer.trackedEntity = entity; //追踪实体 var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({ //在场景中new一个粒子系统对象 image : './Cesium-1.67/Apps/SampleData/fire.png',//图片url startScale : 1.0,//在粒子寿命开始时应用于粒子图像的初始比例。 endScale : 4.0,//在粒子寿命结束时应用于粒子图像的最终比例 particleLife : 1.0,//如果设置,则使用此值覆盖minimumParticleLife和maximumParticleLife输入。 //minimumParticleLife:5,//设置以秒为单位的粒子生命的可能持续时间的最小范围,在该时间范围内可以随机选择粒子的实际生命。 //maximumParticleLife:5,//设置粒子寿命的可能持续时间的最大限制(以秒为单位),在该范围内将随机选择粒子的实际寿命。。 // 发射器参数 emitter : new Cesium.CircleEmitter(0.5), //minimumSpeed:1,//设置以米/秒为单位的最小界限,高于该界限时,将随机选择粒子的实际速度。 //maximumSpeed:3,//设置以米/秒为单位的最大范围,在该范围内将随机选择粒子的实际速度。 speed : 5.0,//如果设置,则用该值覆盖minimumSpeed和maximumSpeed输入。 //minimumImageSize: new Cesium.Cartesian2(20, 20),//设置宽度的最小范围,以高度为单位,在该范围之上可以随机缩放粒子图像的尺寸(以像素为单位)。 //maximumImageSize: new Cesium.Cartesian2(20, 20),//设置最大宽度宽度(以高度为单位),在该范围内可以随机缩放粒子图像的尺寸(以像素为单位)。 imageSize : new Cesium.Cartesian2(20, 20),//如果设置,则将覆盖用来缩放粒子图像尺寸(以像素为单位)的minimumImageSize和maximumImageSize输入。 emissionRate : 5.0,//每秒要发射的粒子数。 lifetime : 16.0,//粒子系统发射粒子的时间(以秒为单位)。 modelMatrix : computeModelMatrix(entity, Cesium.JulianDate.now()),//将粒子系统从模型转换为世界坐标的4x4转换矩阵。 emitterModelMatrix : computeEmitterModelMatrix()//在粒子系统局部坐标系内转换粒子系统发射器的4x4转换矩阵。 })); //首先给粒子系统创建一个模型矩阵,这个矩阵和飞机的位置和朝向完全相同。意思就是飞机的模型矩阵也要做为粒子系统的矩阵,这么设置modelMatrix:计算当前时间点飞机模型的位置矩阵 function computeModelMatrix(entity, time) { //new Cesium.Property () 所有属性的界面,代表一个可以随时间变化的值。此类型定义一个接口,不能直接实例化。 //获取位置 var position = Cesium.Property.getValueOrUndefined(entity.position, time, new Cesium.Cartesian3()); if (!Cesium.defined(position)) { //如果定义了对象,则返回true,否则返回false。 return undefined; } //获取方向 var orientation = Cesium.Property.getValueOrUndefined(entity.orientation, time, new Cesium.Quaternion());// Cesium.Quaternion() 一组4维坐标,用于表示3维空间中的旋转。 if (!Cesium.defined(orientation)) { //Transforms 包含用于将位置转换为各种参考系的功能。 //eastNorthUpToFixedFrame 从具有东北向上轴的参考帧计算4x4变换矩阵以提供的原点为中心,以提供的椭球的固定参考系为中心。局部轴定义为:x 轴指向当地的东部方向。y 轴指向局部北方方向。z 轴指向穿过该位置的椭圆表面法线方向。 var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position, undefined, new Cesium.Matrix4()); } else { // Cesium.Matrix4.fromRotationTranslation (rotation, translation , result ) 从Matrix3计算代表旋转的Matrix4实例和代表翻译的Cartesian3。rotation:矩阵的左上角代表旋转。 translation:矩阵的右上角代表旋转。result:存储结果的对象,如果未定义,将创建一个新实例。 modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromQuaternion(orientation, new Cesium.Matrix3()), position, new Cesium.Matrix4()); } //Cesium.Matrix3.fromQuaternion (quaternion, result )根据提供的四元数计算3x3旋转矩阵。 quaternion 使用的四元数(一组4维坐标,用于表示3维空间中的旋转)。result:存储结果的对象,如果未定义,将创建一个新实例。 return modelMatrix; } //现在这个矩阵已经把粒子放到了飞机中心位置。可是我们想让粒子在飞机的一个引擎上产生,所以我们再创建一个在模型坐标系的平移矩阵。 // 计算引擎(粒子发射器)位置矩阵 function computeEmitterModelMatrix() { //方向 // new Cesium.HeadingPitchRoll ( heading , pitch , roll ) 旋转表示为航向,俯仰和横滚。 var hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, new Cesium.HeadingPitchRoll());//从以度为单位的角度返回一个新的HeadingPitchRoll实例。 var trs = new Cesium.TranslationRotationScale();//由平移,旋转和缩放定义的仿射变换。 //以modelMatrix(飞机)中心为原点的坐标系的xyz轴位置偏移 //translation:Cartesian3(3D笛卡尔点) 指定要应用于该节点的(x,y,z)转换。 trs.translation = Cesium.Cartesian3.fromElements(2.5, 4.0, 1.0, new Cesium.Cartesian3());//根据x,y和z坐标创建Cartesian3实例。result将结果存储到的对象。 //rotation 四元数 指定要应用于该节点的(x,y,z,w)旋转。 //new Cesium.Quaternion ( x , y , z , w ) 一组4维坐标,用于表示3维空间中的旋转。 // Cesium.Quaternion.fromHeadingPitchRoll (headingPitchRoll, result ) 根据给定的航向,俯仰和横滚角计算旋转角度。标题是围绕负Z轴。节距是绕负y轴的旋转。滚动是关于正x轴。 trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, new Cesium.Quaternion()); //从 TranslationRotationScale 实例创建Matrix4实例。translationRotationScale :实例。result: 存储结果的对象,如果未定义,将创建一个新实例。 return Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4()); } </script> </body> </html> </script> </body> </html>