cesium粒子效果——船舰水花效果

效果:


实现思路(最后有完整代码):

与上篇文章思路一样 无非就是更换了模型与粒子图片以及粒子的配置,上一篇文章链接:https://blog.csdn.net/m0_63701303/article/details/135551667?spm=1001.2014.3001.5501

1.用clock组件创建时间线

2.时间轴和船的位置信息绑定

3.添加模型让模型按照绑定的位置飞行

4.创建粒子系统--水花效果

粒子所需图片地址链接:链接:https://pan.baidu.com/s/1-9bi9UAyWp9TruX1HL0Krw 
提取码:1234

5.让粒子实时跟随模型移动

直接上代码 详细步骤看上篇文章

<template>
  <div class="btn"></div>
  <div>
    <Map />
  </div>
</template>

<script setup>
import Map from "@/components/map/Map.vue";
import { nextTick, onUnmounted, reactive } from "vue";
const person = reactive({});
nextTick(() => {
  // 创建时间线
  var start = Cesium.JulianDate.fromDate(new Date()); // 设置时间轴当前时间为开始时间
  var start = Cesium.JulianDate.addHours(start, 8, new Cesium.JulianDate()); // 开始时间加8小时改为北京时间
  var stop = Cesium.JulianDate.addSeconds(start, 400, new Cesium.JulianDate()); // 设置结束时间为开始时间加400秒
  // 设置时钟开始时间
  viewer.clock.startTime = start.clone();
  // 设置时钟当前时间
  viewer.clock.currentTime = start.clone();
  // 设置时钟结束时间
  viewer.clock.stopTime = stop.clone();
  // 时间速率,数字越大时间过的越快,设置1好像是和实际时间一样
  viewer.clock.multiplier = 5;
  // 时间轴绑定到viewer上去
  //   viewer.timeline.zoomTo(start, stop);
  // 循环执行,到达终止时间,重新从起点时间开始
  viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  //   ======================================================
  var data = [
    { long: 121.399999, lat: 32.66277, height: 0, time: 0 },
    { long: 122.507572, lat: 31.570649, height: 0, time: 180 },
    { long: 122.158023, lat: 30.493342, height: 0, time: 400 },
  ];
  let property = computeFlight(data); // 这是通过一个方法把时间轴和船的位置信息绑定了

  //   时间轴和船的位置信息绑定了
  function computeFlight(source) {
    let property = new Cesium.SampledPositionProperty();
    for (let i = 0; i < source.length; i++) {
      let time = Cesium.JulianDate.addSeconds(
        start,
        source[i].time,
        new Cesium.JulianDate()
      );
      let position = Cesium.Cartesian3.fromDegrees(
        source[i].long,
        source[i].lat,
        source[i].height
      );
      // 添加位置,和时间对应
      property.addSample(time, position);
    }
    return property;
  }
  //   添加并移动船
  var entity = viewer.entities.add({
    availability: new Cesium.TimeIntervalCollection([
      new Cesium.TimeInterval({
        start: start,
        stop: stop,
      }),
    ]),
    position: property,
    // 基于位置计算方向角
    orientation: new Cesium.VelocityOrientationProperty(property),
    model: {
      uri: "./model/战舰模型/xyj.gltf", //gltf文件的URL
      scale: 30.05, //放大倍数
      //color: Cesium.Color.fromCssColorString("rgba(0, 253, 239, 0.6)"), // 船模型颜色
      silhouetteColor: Cesium.Color.fromCssColorString("rgba(0, 255, 0, 1)"), // 船模型边框颜色
      silhouetteSize: 1, // 船模型边框宽度
    },
    // path: {
    //   // 船路径
    //   resolution: 1, //
    //   material: new Cesium.PolylineGlowMaterialProperty({
    //     glowPower: 0.1, // 颜色透明度
    //     color: Cesium.Color.fromCssColorString("rgba(0, 253, 239, 0.5)"), // 路线颜色
    //   }),
    //   width: 2, // 路线的显示宽度
    // },
  });
  viewer.trackedEntity = entity; // 视角跟随模型
  // 创建一个例子系统
  let particleSystem = viewer.scene.primitives.add(
    new Cesium.ParticleSystem({
      image: "./imgs/smoke.png", // 波浪图片
      startColor: Cesium.Color.fromCssColorString("rgba(75, 125, 172, 0.6)"), //粒子在其生命初期的颜色
      endColor: Cesium.Color.WHITE.withAlpha(0.0), //粒子在其生命结束的颜色
      startScale: 10.0, //粒子图像的初始比例
      endScale: 150.0, //粒子图像的结束比例
      minimumParticleLife: 1, //粒子生命的可能持续时间的最小范围
      maximumParticleLife: 6, //粒子生命的可能持续时间的最大范围
      speed: 20.0,
      emissionRate: 50.0, //每秒要发射的粒子数
      emitter: new Cesium.CircleEmitter(2), //粒子发射器样式圆形
      //imageSize: new Cesium.Cartesian2(2, 2),//粒子图像尺寸(以像素为单位)的minimumImageSize和maximumImageSize
      minimumImageSize: new Cesium.Cartesian2(0, 0),
      maximumImageSize: new Cesium.Cartesian2(2, 2),
      //主模型参数(位置)
      modelMatrix: computeModelMatrix(entity, Cesium.JulianDate.now()), //从模型转换为世界坐标的4x4转换矩阵
      emitterModelMatrix: computeEmitterModelMatrix(), // 粒子发射器模型矩阵,粒子发射器位置
    })
  );
  // 在粒子系统局部坐标系内转换粒子系统发射器的4x4转换矩阵。
  function computeEmitterModelMatrix() {
    //方向
    let hpr = Cesium.HeadingPitchRoll.fromDegrees(
      80,
      80,
      80,
      new Cesium.HeadingPitchRoll()
    );
    var trs = new Cesium.TranslationRotationScale();
    //以modelMatrix(船)中心为原点的坐标系的xyz轴位置偏移
    trs.translation = Cesium.Cartesian3.fromElements(
      1700,
      0,
      0,
      new Cesium.Cartesian3()
    );
    trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(
      hpr,
      new Cesium.Quaternion()
    );
    return Cesium.Matrix4.fromTranslationRotationScale(
      trs,
      new Cesium.Matrix4()
    );
  }

  // 计算当前时间点船模型的位置矩阵 //从模型转换为世界坐标的4x4转换矩阵
  function computeModelMatrix(entity, time) {
    // //获取位置
    let position = Cesium.Property.getValueOrUndefined(
      entity.position,
      time,
      new Cesium.Cartesian3()
    );
    if (!Cesium.defined(position)) {
      return undefined;
    }
    //获取方向
    let modelMatrix;
    let orientation = Cesium.Property.getValueOrUndefined(
      entity.orientation,
      time,
      new Cesium.Quaternion()
    );
    if (!Cesium.defined(orientation)) {
      modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
        position,
        undefined,
        new Cesium.Matrix4()
      );
    } else {
      modelMatrix = Cesium.Matrix4.fromRotationTranslation(
        Cesium.Matrix3.fromQuaternion(orientation, new Cesium.Matrix3()),
        position,
        new Cesium.Matrix4()
      );
    }
    return modelMatrix;
  }
  // 粒子跟随模型
  viewer.scene.preRender.addEventListener((scene, time) => {
    particleSystem.modelMatrix = computeModelMatrix(entity, time); // 粒子系统和模型绑定,让他跟着模型跑
  });
});

onUnmounted(() => {});
</script>
<style scoped lang='less'>
.btn {
  position: absolute;
  left: 300px;
  top: 30px;
  z-index: 999;
}
</style>


 

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_63701303

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值