CESIUM例子学习(九)——Primitive(3)

1 篇文章 0 订阅
1 篇文章 0 订阅

 

 

 

geometry实在是太多了,多也要一个一个地学。学习的过程中不仅仅是用Primitive加载各种geometry。在这个过程中也加深对cesium的印象,至少混过脸熟,然后熟就能生巧。特别是学习这种事,要自己亲手去做去练习才能有更好的体会。

一、Polyline(线)

cesium提供了SimplePolylineGeometry、PolylineGeometry、PolylineVolumeGeometry、PolylineVolumeOutlineGeometry、GroundPolylineGeometry五种创建线的 构造函数。首先看一下SimplePolylineGeometry和PolylineGeometry的API解释:

SimplePolylineGeometry:A description of a polyline modeled as a line strip; the first two positions define a line segment, and each additional position defines a line segment from the previous position.

PolylineGeometry:A description of a polyline modeled as a line strip; the first two positions define a line segment, and each additional position defines a line segment from the previous position. The polyline is capable of displaying with a material.

竟然是一样的!只是PolylineGeometry多了一个The polyline is capable of displaying with a material,整条线可以使用一个材质渲染显示。可是SimplePolylineGeometry也可以啊。只是SimplePolylineGeometry不能设置线宽,估计是历史遗留问题吧,理解为PolylineGeometry是从SimplePolylineGeometry发展来的,但是为了保证老版本也就把SimplePolylineGeometry留下了。

1、PolylineGeometry与SimplePolylineGeometry(简单线)

PolylineGeometry绘制代码如下:

function addPolylineGeometry () {
    let ps = Cesium.Cartesian3.fromDegreesArrayHeights([
        104.041991, 22.117029, 12000,
        104.441991, 21.817029, 12000,
        105.041991, 22.817029, 35000,
        104.541991, 23.817029, 12000,
        104.081991, 22.417029, 13000,
    ])
    let polylineGeometry = new Cesium.PolylineGeometry({
        positions: ps,
        width: 5,
        id: "polylineGeometry"
    })
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: polylineGeometry,
            }),
            // vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT,
            appearance: new Cesium.PolylineColorAppearance({
                aboveGround: false,
                material: outlineMaterial
            })
        })
    );
}

SimplePolylineGeometry绘制代码如下:

function addSimplePolylineGeometry () {
    let ps = Cesium.Cartesian3.fromDegreesArrayHeights([
        104.141991, 22.117029, 12000,
        104.341991, 21.917029, 12000,
        104.831991, 22.817029, 35000,
        104.441991, 23.817029, 12000,
        104.061991, 22.417029, 13000,
    ])
    let polylineGeometry = new Cesium.SimplePolylineGeometry({
        positions: ps,
        width: 5,
        id: "SimplePolylineGeometry"
    })
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: polylineGeometry,
            }),
            appearance: new Cesium.EllipsoidSurfaceAppearance({
                aboveGround: false,
                material: outlineMaterial
            })
        })
    );
}

绘制结果对比如下图:

需要注意代码中SimplePolylineGeometry的appearance参数,用PolylineColorAppearance时需要在GeometryInstance中指定attributes的颜色属性。即:

 attributes: {
                     color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
                }

否则,无论设置什么颜色,绘制的颜色都是黑色!而用EllipsoidSurfaceAppearance则无些要求。

2、PolylineVolumeGeometry(管线)与PolylineVolumeOutlineGeometry

PolylineVolumeGeometry与PolylineVolumeOutlineGeometry的绘制代码如下:

function addPolylineVolumeGeometry (withOutline = true) {
    let ps = Cesium.Cartesian3.fromDegreesArrayHeights([
        104.141991, 22.117029, 42000,
        104.341991, 21.917029, 42000,
        104.831991, 22.817029, 45000,
        104.441991, 23.817029, 42000,
        104.061991, 22.417029, 43000,
    ])
    let shape = computeCircle(700, 12)
    let polylineVolumeGeometry = new Cesium.PolylineVolumeGeometry({
        polylinePositions: ps,
        shapePositions: shape,
        id: "PolylineVolumeGeometry"
    })
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: polylineVolumeGeometry,
            }),
            appearance: new Cesium.EllipsoidSurfaceAppearance({
                aboveGround: false,
                material: material
            })
        })
    );
    if (withOutline) {
        let polylineVolumeOutlineGeometry = new Cesium.PolylineVolumeOutlineGeometry({
            polylinePositions: ps,
            shapePositions: shape,
            id: "PolylineVolumeOutlineGeometry"
        })
        viewer.scene.primitives.add(
            new Cesium.Primitive({
                geometryInstances: new Cesium.GeometryInstance({
                    geometry: polylineVolumeOutlineGeometry,
                }),
                appearance: new Cesium.EllipsoidSurfaceAppearance({
                    aboveGround: false,
                    material: outlineMaterial
                })
            })
        );
    }
}

绘制结果如下图:

3、GroundPolylinePrimitive

GroundPolylinePrimitive,其字面意思地面线的,是可以帖地、帖3dtiles模型的线。代码如下:

function addGroundPolylineGeometry () {
    var instance = new Cesium.GeometryInstance({
        geometry: new Cesium.GroundPolylineGeometry({
            positions: Cesium.Cartesian3.fromDegreesArray([
                107.141991, 26.117029,
                107.341991, 25.917029,
                107.831991, 26.817029,
                107.441991, 27.817029,
                107.061991, 26.417029
            ]),
            width: 4.0
        }),
        id: 'GroundPolylineGeometry',
        attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
        }
    });
    viewer.scene.groundPrimitives.add(new Cesium.GroundPolylinePrimitive({
        geometryInstances: instance,
        classificationType: Cesium.ClassificationType.BOTH,
        appearance: new Cesium.PolylineColorAppearance()
    }));
}

GroundPolylinePrimitive的classificationType参数是设置线与地表(模型)的关系,Cesium.ClassificationType.BOTH:表示线同时绘制在地形和3dtiles瓦片上;Cesium.ClassificationType.CESIUM_3D_TILE:表示线只绘制在3dtiles瓦片上;Cesium.ClassificationType.TERRAIN:表示线只绘制在地形上。默认参数为Cesium.ClassificationType.BOTH。

绘制帖地表的线,结果如下图:

代码中需要注意,使用PolylineColorAppearance渲染线时,需要在GeometryInstance的attributes属性中指定颜色,即:

 attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
        }

否则会提示如下错误:

与SimplePolylineGeometry类似,只是这里更严重,直接无法渲染。

二、WallGeometry(墙)与WallOutlineGeometry

墙没什么好说的,直接上代码:

function addWallGeometry (withOutline = true) {
    let ps = Cesium.Cartesian3.fromDegreesArray([
        107.041991, 22.117029,
        107.441991, 21.817029,
        109.041991, 22.817029,
        107.541991, 23.817029,
        107.081991, 22.417029
    ])
    let shape = computeCircle(700, 12)
    let wallGeometry = new Cesium.WallGeometry({
        positions: ps,
        maximumHeights: [20000, 30000, 40000, 20000, 30000],
        minimumHeights: [0, 0, 0, 0, 0],
        id: "WallGeometry"
    })
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: wallGeometry,
            }),
            appearance: new Cesium.EllipsoidSurfaceAppearance({
                aboveGround: false,
                material: material
            })
        })
    );
    if (withOutline) {
        let wallGeometry = new Cesium.WallOutlineGeometry({
            positions: ps,
            maximumHeights: [20000, 30000, 40000, 20000, 30000],
            minimumHeights: [0, 0, 0, 0, 0],
            id: "WallGeometry"
        })
        viewer.scene.primitives.add(
            new Cesium.Primitive({
                geometryInstances: new Cesium.GeometryInstance({
                    geometry: wallGeometry,
                }),
                appearance: new Cesium.EllipsoidSurfaceAppearance({
                    aboveGround: false,
                    material: outlineMaterial
                })
            })
        );
    }
}

墙的绘制结果如下图:

这墙背面被剔除了!当前不知道怎么解决!!

Cesium中,您可以通过以下步骤使用鼠标控制primitive旋转: 1. 创建一个primitive对象,并将其添加到场景中。 2. 将鼠标事件监听器附加到控件或场景上,以便在鼠标移动时捕获事件。 3. 在鼠标事件处理程序中获取当前鼠标位置,并计算鼠标移动距离。 4. 将鼠标移动距离转换为旋转角度,并将其应用于primitive对象。 以下是一个示例代码片段,演示如何在Cesium中使用鼠标控制primitive旋转: ```javascript var primitive = new Cesium.Primitive(/* ... */); viewer.scene.primitives.add(primitive); var startPosition; var startOrientation; function onMouseDown(event) { startPosition = new Cesium.Cartesian2(event.clientX, event.clientY); startOrientation = primitive.modelMatrix.clone(); } function onMouseMove(event) { if (!startPosition) return; var currentPosition = new Cesium.Cartesian2(event.clientX, event.clientY); var movement = Cesium.Cartesian2.subtract(currentPosition, startPosition, new Cesium.Cartesian2()); var angle = Cesium.Cartesian2.magnitude(movement) / 100.0; var axis = new Cesium.Cartesian3(movement.y, movement.x, 0.0); axis = Cesium.Cartesian3.normalize(axis, new Cesium.Cartesian3()); var rotation = Cesium.Quaternion.fromAxisAngle(axis, angle); primitive.modelMatrix = Cesium.Matrix4.multiplyTransformation(primitive.modelMatrix, Cesium.Matrix4.fromQuaternion(rotation)); } function onMouseUp(event) { startPosition = undefined; startOrientation = undefined; } viewer.container.addEventListener('mousedown', onMouseDown, false); viewer.container.addEventListener('mousemove', onMouseMove, false); viewer.container.addEventListener('mouseup', onMouseUp, false); ``` 在这个例子中,我们附加了三个事件监听器,分别用于鼠标按下、移动和释放事件。在鼠标按下事件处理程序中,我们记录下当前鼠标位置和primitive的初始方向。在鼠标移动事件处理程序中,我们计算鼠标移动距离,并将其转换为旋转角度和旋转轴。最后,我们将这个旋转应用到primitive的modelMatrix中。在鼠标释放事件处理程序中,我们重置起始位置和方向。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值