360SDN.COM

首页/GIS/列表

Cesium粒子系统详述(Particle System)

来源:  2018-07-11 17:01:19    评论:0点击:

粒子系统是Cesium1.35最新的更新,让我们一起来看看吧

 1. 例子

首先先来一架飞机

var entity = viewer.entities.add({
    model : {
        uri : '../Apps/SampleData/models/CesiumAir/Cesium_Air.gltf',
        minimumPixelSize : 64
    },
    position : Cesium.Cartesian3.fromDegrees(-112.110693, 36.0994841, 1000.0)
});
viewer.trackedEntity = entity;

然后我们需要拿到飞机模型的位置

 // 计算当前时间点飞机模型的位置矩阵
function computeModelMatrix(entity, time) {
    //获取位置
    var position = Cesium.Property.getValueOrUndefined(entity.position, time, new Cesium.Cartesian3());
    if (!Cesium.defined(position)) {
        return undefined;
    }
    //获取方向
    var modelMatrix;
    var 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;
}

接着设置好粒子发射器的位置

 // 计算引擎(粒子发射器)位置矩阵
function computeEmitterModelMatrix() {
    //方向
    hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, new Cesium.HeadingPitchRoll());
    var trs = new Cesium.TranslationRotationScale();

    //以modelMatrix(飞机)中心为原点的坐标系的xyz轴位置偏移
    trs.translation = Cesium.Cartesian3.fromElements(2.5, 3.5, 1.0, new Cesium.Cartesian3());
    trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, new Cesium.Quaternion());
    return Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());
}

最后就可以加载我们的粒子系统看看效果了

 var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    image : '../Apps/SampleData/fire.png',
    startScale : 1.0,
    endScale : 4.0,
    minimumLife : 1.0,
    maximumLife : 1.5,
    speed : 5.0,
    width : 20,
    height : 20,
    lifeTime : 16.0,
    //主模型参数(位置)
    modelMatrix : computeModelMatrix(entity, Cesium.JulianDate.now()),
    // 发射器参数
    emitter : new Cesium.CircleEmitter(0.5),
    rate : 5.0,
    emitterModelMatrix : computeEmitterModelMatrix(),
    //颜色
    startColor: Cesium.Color.RED.withAlpha(0.7),
    endColor: Cesium.Color.YELLOW.withAlpha(0.3),
    forces: [applyGravity]
}));

这里写图片描述

 2. 粒子发射器

Cesium内置了4种发射器,可以看到我这里用的是CircleEmitter,下面一起看看几种发射器发出来的粒子是啥样的

CircleEmitter


emitter : new Cesium.CircleEmitter(0.5)

这种发射器发射的粒子是一个圆形,所以需要一个半径,这样看可能看不出来,我们可以一瞬间把粒子量加大就能看出来了

这里写图片描述

ConeEmitter

emitter : new Cesium.ConeEmitter(Cesium.Math.toRadians(45.0))

这种发出来的稍微有点散,没有CircleEmitter那么聚集,因为它是以一个锥形进行发散的,这样就需要传一个角度了

这里写图片描述

啧啧,很适合做核弹效果,蘑菇云哎

BoxEmitter和SphereEmitter

剩下两种感觉差不多,我就一起说了,顺带对比下

BoxEmitter这种是从一个长方体中将粒子散发出来,需要传一个Cartesian3,存放长宽高

emitter : new Cesium.BoxEmitter(new Cesium.Cartesian3(1.0, 1.0, 1.0))

SphereEmitter是从一个球中将粒子散发出来,需要一个半径

emitter : new Cesium.SphereEmitter(0.5)

来看一下效果,感觉差不多,我们需要从高空才能看出区别

 

BoxEmitter

这里写图片描述

SphereEmitter

 3. bursts

之前我们看见的效果其实都是用bursts做出来的,bursts就是让粒子系统周期性的做出一些额外的爆发效果,用法很简单

var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    ...
    bursts : [
       new Cesium.ParticleBurst({time : 5.0, minimum : 300, maximum : 500}),
       new Cesium.ParticleBurst({time : 10.0, minimum : 50, maximum : 100}),
       new Cesium.ParticleBurst({time : 15.0, minimum : 200, maximum : 300})
    ],
    ...
}));

我们需要传入一个ParticleBurst类型的array,存的就是你想要的效果

 4. 其他的一些属性

粒子系统中很多属性都有min和max以及其本身,比如life就有minimumLife、maximumLife和life三个,但是如果你设置了life属性,那么minimumLife和maximumLife就会失效,其他的属性也是如此

还有一些比较有趣的属性,比如颜色,你可以设置startColor和endColor来设置颜色的渐变

其中rate是粒子的发射速率,也就是每秒发射的粒子数

在默认的情况下粒子的loop是为true的,如果需要的话可以把它关闭,再配合bursts并把粒子的速率rate设为0,可以做出很不错的爆炸效果

除了这些还有很多的属性比如speed、width、height等等,详细的可以见官方API

 5. 重力效果

这可是一个重头戏,官方给我们提供了一个计算方法(原谅我的数学,一脸懵逼)

//你需要的重力倍数,不过这个重力似乎是反过来的,负的才是增大重力
var gravity = 0;
var gravityScratch = new Cesium.Cartesian3();
function applyGravity(p, dt) {
    // Compute a local up vector for each particle in geocentric space.
    var position = p.position;

    Cesium.Cartesian3.normalize(position, gravityScratch);
    Cesium.Cartesian3.multiplyByScalar(gravityScratch, gravity * dt, gravityScratch);

    p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity);
}

你只需要在粒子系统的初始化里面加上一句就可以了


particleSystem: {
    ...
    forces: [applyGravity],
    ...
}

让我们看看100倍重力是什么效果

 

嘿嘿,挺有意思的,让我们来点更有意思的,让飞机飞起来看看效果如何呢

我们不需要改任何代码,还记得之前那个转圈的飞机么(不知道的戳这里),我们只需要把之前那些代码加在后面,并加上一个更新位置的方法就可以了(毕竟在动嘛)

viewer.scene.preRender.addEventListener(function(scene, time) {
    //重新计算位置
    particleSystem.modelMatrix = computeModelMatrix(entity, time);
});

总共加了这些

//计算当前时间点飞机模型的位置矩阵
function computeModelMatrix(entity, time) {
    //获取位置
    var position = Cesium.Property.getValueOrUndefined(entity.position, time, new Cesium.Cartesian3());
    if (!Cesium.defined(position)) {
        return undefined;
    }
    //获取方向
    var orientation = Cesium.Property.getValueOrUndefined(entity.orientation, time, new Cesium.Quaternion());
    if (!Cesium.defined(orientation)) {
        var 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;
}

//计算引擎(粒子发射器)位置矩阵
function computeEmitterModelMatrix() {
    //方向
    hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, new Cesium.HeadingPitchRoll());
    var trs = new Cesium.TranslationRotationScale();
    //以modelMatrix(飞机)中心为原点的坐标系的xyz轴位置偏移
    trs.translation = Cesium.Cartesian3.fromElements(2.5, 3.5, 1.0, new Cesium.Cartesian3());
    trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, new Cesium.Quaternion());
    return Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());
}

//粒子系统参数
var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    image : '../Apps/SampleData/fire.png',
    startScale : 1.0,
    endScale : 4.0,
    minimumLife : 1.0,
    maximumLife : 1.5,
    speed : 5.0,
    width : 20,
    height : 20,
    lifeTime : 16.0,
    bursts: [
        new Cesium.ParticleBurst({time : 5.0, minimum : 300, maximum : 500}),
        new Cesium.ParticleBurst({time : 10.0, minimum : 50, maximum : 100}),
        new Cesium.ParticleBurst({time : 15.0, minimum : 200, maximum : 300})
    ],
    //主模型参数(位置)
    modelMatrix : computeModelMatrix(entity, Cesium.JulianDate.now()),
    // 发射器参数
    emitter : new Cesium.CircleEmitter(0.5),
    rate : 5.0,
    emitterModelMatrix : computeEmitterModelMatrix(),
    //颜色
    startColor: Cesium.Color.RED.withAlpha(0.7),
    endColor: Cesium.Color.YELLOW.withAlpha(0.3),
    forces: [applyGravity]
}));

//重力计算
var gravityScratch = new Cesium.Cartesian3();
function applyGravity(p, dt) {

    var position = p.position;

    Cesium.Cartesian3.normalize(position, gravityScratch);
    Cesium.Cartesian3.multiplyByScalar(gravityScratch, 1 * dt, gravityScratch);

    p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity);
}

//刷新位置
viewer.scene.preRender.addEventListener(function(scene, time) {
    particleSystem.modelMatrix = computeModelMatrix(entity, time);
});

这里写图片描述

效果还是不错的

来源: https://blog.csdn.net/UmGsoil/article/details/76542720

var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    // 粒子外观
    image : '../../SampleData/fire.png',//纹理
    width : 20,
    height : 20,
    startScale : 1.0,
    endScale : 4.0,
    // Particle behavior
    life : 1.0,
    speed : 5.0,
    // 发射器参数
    //有BoxEmitter、CircleEmitter、ConeEmitter、SphereEmitter
    emitter : new Cesium.CircleEmitter(0.5),
    rate : 5.0,//粒子发射速度,可以用bursts控制不同时段的速度
    emitterModelMatrix : computeEmitterModelMatrix(),
    // Particle system parameters
    modelMatrix : computeModelMatrix(),
    lifetime : 16.0//粒子的生命时间
   minimumLife: 5.0,
   maximumLife: 10.0//粒子的生命时间将在最大值和最小值之间
   startColor: Cesium.Color.RED.withAlpha(0.7),
   endColor: Cesium.Color.YELLOW.withAlpha(0.3)//颜色生成粒子
     minimumWidth: 30.0,
   maximumWidth: 60.0,
   minimumHeight: 30.0,
    maximumHeight: 60.0//随机尺寸
      minimumSpeed: 5.0,
    maximumSpeed: 10.0//速度变化
     startScale: 1.0,
    endScale: 4.0//大小变化
}));
为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权