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

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

上一节学习了Primitive加载帖地(3dtiles)的线。如果需要绘制帖3dtiles的体,在CESIUM例子学习(七)——Classification Types中学习了整栋楼的单体化。但是如果要在倾斜摄影中,只单体化某建筑二楼、三楼,该如何绘制呢?其实cesium还提供了另一个对象Cesium.ClassificationPrimitive。它可以通过绘制一个BoxGeometry、EllipsoidGeometry等来实现这样的单体化。

一、BoxGeometry

1、绘制加载

代码很简单,项目中基本上都要鼠标交互,所以需要注意的是在 attributes属性中设置show属性,也就是设置绘制是否在初始化时就起作用。即: attributes: {
                   ……
                    show: new Cesium.ShowGeometryInstanceAttribute(true),设置初始化后是否显示 } 
               整个 加载的绘制代码如下:

var buildingHighlight1, buildingHighlight2
function addBoxClassificationPrimitive () {
    let length = 39.0, width = 18.0, height = 4.0, baseHeight = -14.5 //楼的长宽高和基地高
    let center = { //楼中心点位置
        x: -2025016.752089428,
        y: 5532291.539549444,
        z: 2436368.8372620787
    },
        modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
    hprRotation = Cesium.Matrix3.fromHeadingPitchRoll(
        new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(-6), 0.0, 0.0)
    );
    hpr = Cesium.Matrix4.fromRotationTranslation(
        hprRotation,
        new Cesium.Cartesian3(0.0, 0.0, baseHeight) //楼层高度上的偏移
    );
    Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix);
    buildingHighlight1 = viewer.scene.primitives.add(
        new Cesium.ClassificationPrimitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: Cesium.BoxGeometry.fromDimensions({
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
                    dimensions: new Cesium.Cartesian3(length, width, height),
                }),
                modelMatrix: modelMatrix,
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                        new Cesium.Color(1.0, 0.0, 0.0, 0.5)设置高亮颜色
                    ),
                    show: new Cesium.ShowGeometryInstanceAttribute(true),设置初始化后是否显示
                },
                id: "BoxClassificationPrimitive1",
            }),
            classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,//只绘制在3dtiles上
        })
    );
    let modelMatrix2 = Cesium.Transforms.eastNorthUpToFixedFrame(center);
    hpr = Cesium.Matrix4.fromRotationTranslation(
        hprRotation,
        new Cesium.Cartesian3(0.0, 0.0, baseHeight + height)
    );
    Cesium.Matrix4.multiply(modelMatrix2, hpr, modelMatrix2);
    buildingHighlight2 = viewer.scene.primitives.add(
        new Cesium.ClassificationPrimitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: Cesium.BoxGeometry.fromDimensions({
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
                    dimensions: new Cesium.Cartesian3(39.0, 18.0, 4.0),
                }),
                modelMatrix: modelMatrix2,
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                        new Cesium.Color(0.0, 1.0, 0.0, 0.5)
                    ),
                    show: new Cesium.ShowGeometryInstanceAttribute(true),设置初始化后是否显示
                },
                id: "BoxClassificationPrimitive2",
            }),
            classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,//只绘制在3dtiles上
        })
    );
}

绘制结果如下图:

图中可以看到最下面一层范围比楼大,是因为这个范围是拖动绘制的。在项目中应该是有其它数据来源。

2、属性获取与设置

属性获取与设置是通过GeometryInstance的id进行的,首先需要通过id获取到attributes对象,即:

 let attributes= buildingHighlight1.getGeometryInstanceAttributes("BoxClassificationPrimitive1")。代码中getGeometryInstanceAttributes方法要在数据加载完成调用update后过可用,否则会报getGeometryInstanceAttributes的undefined错误。

cesium通过scene.invertClassification属性,设置3dtiles的设置颜色是否起作用; 设置scene.invertClassificationColor颜色控制3dtiles颜色。

属性获取与设置的整个代码如下:

function invertClassification (checked) {
    let scene = viewer.scene
    if (checked && !scene.invertClassificationSupported) {
        window.alert("This browser does not support invert classification");
    }

    scene.invertClassification = checked;
    scene.invertClassificationColor = new Cesium.Color(
        0.15,
        0.15,
        0.15,
        1.0,
    );
    let v = Cesium.ShowGeometryInstanceAttribute.toValue(!checked);
    let attr = buildingHighlight1.getGeometryInstanceAttributes("BoxClassificationPrimitive1")
    attr.show = v;交互控制高亮与否
    attr = buildingHighlight2.getGeometryInstanceAttributes("BoxClassificationPrimitive2")
    attr.show = v;交互控制高亮与否

}

3、获取绘制3dtiles的id

在交互中经经常会通过点击之类的操作获取被点击建筑等属性。可以通过在加载高亮盒子时,设置盒子的id,在点击时,通过下面方法获取到点中目标的id。通过这个id获取相应的外部属性。代码如下:

  var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
    handler.setInputAction(function (movement) {
        checked = !checked
        invertClassification(checked)
 var pickedObject = scene.pick(movement.position);
        if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
           modelid=pickedObject.id
            }

结果如下图:

EllipsoidGeometry绘制不再作说明,可以参考前一节中的EllipsoidGeometry设置参数,而 classificationType属性与BoxGeometry设置一样。源码例子绘制的结果如下图:

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
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中。在鼠标释放事件处理程序中,我们重置起始位置和方向。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值