cesium particle.js示例文件代码理解和注释

cesium particle.js示例文件代码理解和注释

1 四元数的概念

cesiumjs里得quaternion.js文件里实现了四元数的计算,关于四元数主要是用来描述三维空间里的旋转缩放变换的,一个四元数描述为q=a+bi+cj+dk,由一个实数和三个负数组成,三维变化有点不好理解,换成二维的就简单多了。
二维旋转变化可以用负数,a = b+ci描述,b描述为缩放比例,c描述为角度,可换成矩阵形式。
关于四元数,具体可以参考下面的链接:
如何形象地理解四元数?

2 下面直接贴代码,主要部分写了注释

var viewer = new Cesium.Viewer("cesiumContainer");

//Set the random number seed for consistent results.
Cesium.Math.setRandomNumberSeed(3);//随机数种子,不清楚啥用

//Set bounds of our simulation time
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));//起始时间
var stop = Cesium.JulianDate.addSeconds(//结束时间
  start,
  120,
  new Cesium.JulianDate()
);

//Make sure viewer is at the desired time.
viewer.clock.startTime = start.clone();//开始
viewer.clock.stopTime = stop.clone();//结束
viewer.clock.currentTime = start.clone();//当前时间为开始时刻
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end 循环结束后重新开始
viewer.clock.multiplier = 1;//倍速
viewer.clock.shouldAnimate = true;//开始播放,false为暂停

//Set timeline to simulation bounds
viewer.timeline.zoomTo(start, stop);//目前场景时间

var viewModel = {//动态数据
  emissionRate: 5.0,
  gravity: 0.0,
  minimumParticleLife: 1.2,
  maximumParticleLife: 1.2,
  minimumSpeed: 1.0,
  maximumSpeed: 4.0,
  startScale: 1.0,
  endScale: 5.0,
  particleSize: 25.0,
};

Cesium.knockout.track(viewModel);//监控数据
var toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);//数据绑定控件

var entityPosition = new Cesium.Cartesian3();
var entityOrientation = new Cesium.Quaternion();//表示三维空间旋转的四维坐标(四元数)
var rotationMatrix = new Cesium.Matrix3();
var modelMatrix = new Cesium.Matrix4();

function computeModelMatrix(entity, time) {//根据时间计算实体的模型矩阵
  return entity.computeModelMatrix(time, new Cesium.Matrix4());
}

var emitterModelMatrix = new Cesium.Matrix4();
var translation = new Cesium.Cartesian3();
var rotation = new Cesium.Quaternion();
var hpr = new Cesium.HeadingPitchRoll();
var trs = new Cesium.TranslationRotationScale();//仿射变化矩阵

function computeEmitterModelMatrix() {
  hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr);//旋转
  trs.translation = Cesium.Cartesian3.fromElements(
    -4.0,
    0.0,
    1.4,
    translation
  );//平移
  trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, rotation);

  return Cesium.Matrix4.fromTranslationRotationScale(
    trs,
    emitterModelMatrix
  );
}

var pos1 = Cesium.Cartesian3.fromDegrees(//起始位置
  -75.15787310614596,
  39.97862668312678
);
var pos2 = Cesium.Cartesian3.fromDegrees(//结束位置
  -75.1633691390455,
  39.95355089912078
);
var position = new Cesium.SampledPositionProperty();

//不确定是不是在点之间进行插值,源代码看不懂
position.addSample(start, pos1);
position.addSample(stop, pos2);

var entity = viewer.entities.add({
  availability: new Cesium.TimeIntervalCollection([//在给定时间内提供数据
    new Cesium.TimeInterval({
      start: start,
      stop: stop,
    }),
  ]),
  model: {//模型URL和尺寸
    uri: "../SampleData/models/CesiumMilkTruck/CesiumMilkTruck.glb",
    minimumPixelSize: 64,
  },
  viewFrom: new Cesium.Cartesian3(-100.0, 0.0, 100.0),//偏移量
  position: position,
  orientation: new Cesium.VelocityOrientationProperty(position),//根据汽车速度计算四元数
});
viewer.trackedEntity = entity;//相机跟踪实体

var scene = viewer.scene;
var particleSystem = scene.primitives.add(//添加粒子系统
  new Cesium.ParticleSystem({
    image: "../SampleData/smoke.png",//粒子图片路径

    startColor: Cesium.Color.LIGHTSEAGREEN.withAlpha(0.7),//粒子起始颜色
    endColor: Cesium.Color.WHITE.withAlpha(0.0),//粒子结束颜色

    startScale: viewModel.startScale,//开始尺寸,倍数
    endScale: viewModel.endScale,//结束尺寸

    minimumParticleLife: viewModel.minimumParticleLife,//粒子存活最短时间,秒
    maximumParticleLife: viewModel.maximumParticleLife,//最长时间

    minimumSpeed: viewModel.minimumSpeed,//速度
    maximumSpeed: viewModel.maximumSpeed,

    imageSize: new Cesium.Cartesian2(//粒子大小,像素
      viewModel.particleSize,
      viewModel.particleSize
    ),

    emissionRate: viewModel.emissionRate,//每秒发射粒子数量,默认5

    bursts: [//给定时间周期性地粒子爆炸,在粒子系统存活时间内
      // these burst will occasionally sync to create a multicolored effect
      new Cesium.ParticleBurst({//在第5、10、15秒会爆炸
        time: 5.0,
        minimum: 10,
        maximum: 100,
      }),
      new Cesium.ParticleBurst({
        time: 10.0,
        minimum: 50,
        maximum: 100,
      }),
      new Cesium.ParticleBurst({
        time: 15.0,
        minimum: 200,
        maximum: 300,
      }),
    ],

    lifetime: 16.0,//粒子系统发射粒子时常,
    
    loop:true,//默认true,若为false,粒子系统会在lifetime时间之后停止
              //注:粒子系统的时间和viewer.clock的时间不绑定,模型运动的循环和粒子的循环不一致
    
    emitter: new Cesium.CircleEmitter(2.0),//发射器大小和样式

    emitterModelMatrix: computeEmitterModelMatrix(),//计算模型与世界的转换矩阵

    updateCallback: applyGravity,//粒子回调函数
  })
);

var gravityScratch = new Cesium.Cartesian3();

function applyGravity(p, dt) {
  //dt 自上次以来的更新时间,秒
  // We need to compute a local up vector for each particle in geocentric space.
  var position = p.position;//粒子世界坐标系的位置

  Cesium.Cartesian3.normalize(position, gravityScratch);//归一化
  //粒子位置中z分量占比越高,粒子速度就越大
  
  Cesium.Cartesian3.multiplyByScalar(
    gravityScratch,
    viewModel.gravity * dt,
    gravityScratch
  );//计算速度
  p.velocity = Cesium.Cartesian3.add(
    p.velocity,
    gravityScratch,
    p.velocity
  );//更新粒子速度
  
}

viewer.scene.preUpdate.addEventListener(function (scene, time) {
  //监听scene更新或渲染
  //汽车位置改变时scence就要重新渲染
  particleSystem.modelMatrix = computeModelMatrix(entity, time);//计算当前模型矩阵

  // Account for any changes to the emitter model matrix.
  particleSystem.emitterModelMatrix = computeEmitterModelMatrix();//计算粒子发射初始位置

  // Spin the emitter if enabled.
  if (viewModel.spin) {//旋转,空间没有spin属性,不执行
    viewModel.heading += 1.0;
    viewModel.pitch += 1.0;
    viewModel.roll += 1.0;
  }
});

//监测更新
Cesium.knockout
  .getObservable(viewModel, "emissionRate")
  .subscribe(function (newValue) {
    particleSystem.emissionRate = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "particleSize")
  .subscribe(function (newValue) {
    var particleSize = parseFloat(newValue);
    particleSystem.minimumImageSize.x = particleSize;
    particleSystem.minimumImageSize.y = particleSize;
    particleSystem.maximumImageSize.x = particleSize;
    particleSystem.maximumImageSize.y = particleSize;
  });

Cesium.knockout
  .getObservable(viewModel, "minimumParticleLife")
  .subscribe(function (newValue) {
    particleSystem.minimumParticleLife = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "maximumParticleLife")
  .subscribe(function (newValue) {
    particleSystem.maximumParticleLife = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "minimumSpeed")
  .subscribe(function (newValue) {
    particleSystem.minimumSpeed = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "maximumSpeed")
  .subscribe(function (newValue) {
    particleSystem.maximumSpeed = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "startScale")
  .subscribe(function (newValue) {
    particleSystem.startScale = parseFloat(newValue);
  });

Cesium.knockout
  .getObservable(viewModel, "endScale")
  .subscribe(function (newValue) {
    particleSystem.endScale = parseFloat(newValue);
  });

var options = [
  {
    text: "Circle Emitter",
    onselect: function () {
      particleSystem.emitter = new Cesium.CircleEmitter(2.0);
    },
  },
  {
    text: "Sphere Emitter",
    onselect: function () {
      particleSystem.emitter = new Cesium.SphereEmitter(2.5);
    },
  },
  {
    text: "Cone Emitter",
    onselect: function () {
      particleSystem.emitter = new Cesium.ConeEmitter(
        Cesium.Math.toRadians(45.0)
      );
    },
  },
  {
    text: "Box Emitter",
    onselect: function () {
      particleSystem.emitter = new Cesium.BoxEmitter(
        new Cesium.Cartesian3(10.0, 10.0, 10.0)
      );
    },
  },
];

Sandcastle.addToolbarMenu(options);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值