ParticleSystem.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * 粒子效果
  3. * 火粒子、水粒子
  4. */
  5. class ParticleSystem {
  6. /**
  7. * 默认初始化
  8. * @param {Object} viewer 三维场景
  9. */
  10. constructor(viewer) {
  11. if (!viewer) throw new DeveloperError('no viewer object!');
  12. this.viewer = viewer;
  13. }
  14. }
  15. /**
  16. * 通用对外公开函数
  17. */
  18. Object.assign(ParticleSystem.prototype, /** @lends ParticleSystem.prototype */ {
  19. /**
  20. * 创建火焰粒子
  21. * @param {Array} coordinates 粒子位置 [longitude, latitude, height]
  22. */
  23. createParticleFire: function(coordinates) {
  24. this.viewer.clock.shouldAnimate = true; //是否允许动画,看到粒子效果
  25. // 指定喷射地点
  26. var position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2] || 0);
  27. // 使用一个entity来作为粒子载体,比如示例中的小车
  28. var entity = this.viewer.entities.add({
  29. position: position
  30. });
  31. // 计算载体位置
  32. function computeModelMatrix(entity, time) {
  33. var position = Cesium.Property.getValueOrUndefined(entity.position);
  34. var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  35. return modelMatrix;
  36. }
  37. var viewModel = {
  38. startScale: 3,
  39. endScale: 1.5,
  40. minimumParticleLife: 1.5,
  41. maximumParticleLife: 1.8,
  42. minimumSpeed: 7, //粒子发射的最小速度
  43. maximumSpeed: 9, //粒子发射的最大速度
  44. particleSize: 2,
  45. emissionRate: 200
  46. };
  47. var primitive = this.viewer.scene.primitives.add(
  48. new Cesium.ParticleSystem({
  49. image: "jt3dSDK/imgs/particlesystem/fire.png",
  50. imageSize: new Cesium.Cartesian2(viewModel.particleSize, viewModel.particleSize), //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小
  51. startColor: new Cesium.Color(1, 1, 1, 1), //粒子出生时的颜色
  52. endColor: new Cesium.Color(0.5, 0, 0, 0), //当粒子死亡时的颜色
  53. startScale: viewModel.startScale, //粒子出生时的比例,相对于原始大小
  54. endScale: viewModel.endScale, //粒子在死亡时的比例
  55. minimumParticleLife: viewModel.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位),粒子的实际寿命将随机生成
  56. maximumParticleLife: viewModel.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位),粒子的实际寿命将随机生成
  57. minimumSpeed: viewModel.minimumSpeed, //设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
  58. maximumSpeed: viewModel.maximumSpeed, //设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
  59. emissionRate: viewModel.emissionRate, //每秒发射的粒子数。
  60. lifetime: 16.0, //多长时间的粒子系统将以秒为单位发射粒子
  61. //粒子系统是否应该在完成时循环其爆发
  62. loop: true,
  63. //设置粒子的大小是否以米或像素为单位
  64. sizeInMeters: true, //AAAAAAAAAAAA
  65. emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(45.0)), //此系统的粒子发射器 共有 圆形、锥体、球体、长方体 ( BoxEmitter,CircleEmitter,ConeEmitter,SphereEmitter ) 几类
  66. modelMatrix: computeModelMatrix(entity, Cesium.JulianDate.now()), // 4x4转换矩阵,可将粒子系统从模型转换为世界坐标
  67. })
  68. );
  69. entity.remove = function() {
  70. viewer.entities.remove(entity);
  71. viewer.scene.primitives.remove(primitive);
  72. };
  73. return entity;
  74. },
  75. /**
  76. * 创建喷水粒子
  77. * @param {Array} coordinates 粒子位置 [longitude, latitude, height]
  78. */
  79. createParticleWater: function(coordinates) {
  80. let viewer = this.viewer;
  81. this.viewer.clock.shouldAnimate = true; //是否允许动画,看到粒子效果
  82. // 指定喷射地点,并实时计算位置
  83. var position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2] || 0);
  84. // 使用一个entity来作为粒子载体,比如示例中的小车
  85. var entity = this.viewer.entities.add({
  86. position: position
  87. });
  88. //设置该粒子系统的位置
  89. // function computeModelMatrix(entity) {
  90. // var position = Cesium.Property.getValueOrUndefined(entity.position);
  91. // let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  92. // return modelMatrix;
  93. // }
  94. function computeModelMatrix(entity, time) {
  95. return entity.computeModelMatrix(time, new Cesium.Matrix4());
  96. }
  97. // 计算粒子发射器的位置姿态
  98. function computeEmitterModelMatrix() {
  99. let hpr = Cesium.HeadingPitchRoll.fromDegrees(viewModel.heading, viewModel.pitch, viewModel.roll); // 倾斜角度
  100. let trs = new Cesium.TranslationRotationScale();
  101. trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1); // 发射高度
  102. trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
  103. let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
  104. return Matrix4
  105. }
  106. // 更新粒子运动状态
  107. function updateCallback(p, dt) {
  108. var gravityScratch = new Cesium.Cartesian3();
  109. var position = p.position;
  110. Cesium.Cartesian3.normalize(position, gravityScratch);
  111. // Cesium.Cartesian3.fromElements(20 * dt, gravityScratch.y * dt, -30 * dt, gravityScratch);
  112. Cesium.Cartesian3.multiplyByScalar(gravityScratch, viewModel.gravity * dt, gravityScratch);
  113. p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity);
  114. }
  115. // 实时计算位置
  116. function update(scene, time) {
  117. waterParticleSystem.modelMatrix = computeModelMatrix(entity, time);
  118. waterParticleSystem.emitterModelMatrix = computeEmitterModelMatrix();
  119. }
  120. viewer.scene.preUpdate.addEventListener(update);
  121. var viewModel = {
  122. startScale: 1,
  123. endScale: 7,
  124. minimumParticleLife: 6,
  125. maximumParticleLife: 7,
  126. minimumSpeed: 9,
  127. maximumSpeed: 9.5,
  128. particleSize: 1,
  129. emissionRate: 60.0,
  130. gravity: -4, //重力,上下出水方向
  131. // transX: 2.5,
  132. // transY: 4.0,
  133. // transZ: 1.0,
  134. heading: 110.0,
  135. pitch: 30.0,
  136. roll: 0.0,
  137. // fly: true,
  138. // spin: true,
  139. // show: true
  140. };
  141. var waterParticleSystem = new Cesium.ParticleSystem({
  142. //这里需要改为自己的图片路径
  143. image: "jt3dSDK/imgs/particlesystem/water.png",
  144. //设置发射出的图像大小
  145. imageSize: new Cesium.Cartesian2(viewModel.particleSize, viewModel.particleSize),
  146. startColor: new Cesium.Color(1, 1, 1, 0.6), //粒子出生时的颜色
  147. endColor: new Cesium.Color(0.80, 0.86, 1, 0.4), //当粒子死亡时的颜色
  148. // 值越大,初始时粒子图的大小越大
  149. startScale: viewModel.startScale,
  150. endScale: viewModel.endScale,
  151. //值越大,尾巴越长
  152. minimumParticleLife: viewModel.minimumParticleLife,
  153. maximumParticleLife: viewModel.maximumParticleLife,
  154. //值越大,尾巴飘的越高
  155. minimumSpeed: viewModel.minimumSpeed,
  156. maximumSpeed: viewModel.maximumSpeed,
  157. //每秒发射的粒子数。
  158. //数值越大,越浓密
  159. emissionRate: viewModel.emissionRate,
  160. //设置粒子的大小是否以米或像素为单位
  161. sizeInMeters: true, //AAAAAAAAAAAA
  162. emitter: new Cesium.CircleEmitter(0.2),
  163. modelMatrix: computeModelMatrix(entity),
  164. emitterModelMatrix: computeEmitterModelMatrix(),
  165. updateCallback: updateCallback,
  166. });
  167. // 将粒子系统添加到场景中
  168. viewer.scene.primitives.add(waterParticleSystem);
  169. entity.remove = function() {
  170. viewer.entities.remove(entity);
  171. viewer.scene.primitives.remove(waterParticleSystem);
  172. };
  173. return entity;
  174. },
  175. });
  176. export default ParticleSystem;