类名 CollisionDetectionByRender

# new CollisionDetectionByRender(viewer, collider, optionsopt)

参数:

名称 类型 默认值 描述
viewer Viewer

场景视图

collider Cesium.Camera | Cesium.MapGISM3D | Cesium.Entity

做碰撞检测的对象

options Object

可选参数

colliderLength Number 0.4

碰撞盒的长(单位米)

colliderWidth Number 0.4

碰撞盒的宽(单位米)

colliderHeight Number 1.7

碰撞盒的高(单位米)

原点高度属性用于通知碰撞检测实例碰撞对象的坐标原点所在的高度,如单体模型的坐标原点有的在其底部,有的在其中间。
默认值设为1.7是因为默认的碰撞对象是相机。

colliderPositionOffset Cesium.Cartesian3 (0,0,0)

碰撞盒的位置偏移(单位米)

maxPassableHeight Number 0.5

最大可通过高度(单位米)

highPrecision Boolean false

是否开启高精度碰撞检测

基于性能考虑默认不开启高精度碰撞检测。非高精度状态下只检测碰撞盒的边框所覆盖的区域,高精度状态下对碰撞盒覆盖的整个区域做检测。

debugShowDepthMap Boolean false

检查深度图(debug模式)

debugShowCollider Boolean false

检查碰撞盒(debug模式)

debug模式生成的碰撞盒所使用的位置是上一帧的碰撞检测结果,所以并不能精确的表示碰撞盒与场景的碰撞关系。
深度图中可查看到较为精确的碰撞关系。
开启碰撞盒检查主要是为了方便调整碰撞盒与模型相匹配。
相机做为碰撞对象时,开启碰撞盒检查,相机会被碰撞盒包在里面。

示例
const { CollisionDetectionByRender } = zondy.cesium
// ES6引入方式
import { CollisionDetectionByRender } from "@mapgis/webclient-cesium-plugin"

// 1. 默认使用相机做为碰撞检测对象
let collisionDetection;
collisionDetection = new CollisionDetectionByRender(viewer, viewer.camera);
// 对目标位置进行碰撞检测
let result = collisionDetection.checkCollision(targetPosition, 0);
// 未碰撞移动到该位置
if (result.result !== 'collided') {
    camera.setView({
        destination: result.computedPosition,
        orientation: {
            heading: camera.heading,
            pitch: camera.pitch,
            roll: 0.0
        }
    });
}

// 2. 使用M3D做为碰撞检测对象
let m3d;
let url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/2.0/wujiangdizhiti/wujiangdizhiti.mcj';
let options = {
    maximumScreenSpaceError: 0,
    autoReset: false,
    loaded: function(layer) {
        m3d = layer;
        collisionDetection = new CollisionDetectionByRender(viewer, layer._root, {
            colliderLength: 0.8, // 设置碰撞盒长
            colliderWidth: 0.6, // 设置碰撞盒宽
            colliderHeight: 1, // 设置碰撞盒高
            colliderPositionOffset: new Cesium.Cartesian3(0, 0, 0.5), // 设置碰撞盒偏移
            debugShowCollider: true, // 打开debug模式,碰撞盒检查
            debugShowDepthMap: true // 打开debug模式,深度图检查
        });
    }
};
viewer.scene.layers.appendM3DLayer(url, options);
// 对目标位置进行碰撞检测
let result = collisionDetection.checkCollision(targetPosition, 0);
// 获取M3D模型在笛卡尔空间的变换矩阵
let transform = m3d.computedTransform;
let newTransform = new Cesium.Matrix4();
let invModelMat = new Cesium.Matrix4();
if (result.result !== 'collided') {
     // 获取模型变换矩阵
     let modelMatrix = m3d.tileset.modelMatrix;
     // 求模型变换矩阵的逆
     Cesium.Matrix4.inverse(modelMatrix, invModelMat);
     // 未碰撞移动到该位置
     Cesium.Matrix4.setTranslation(transform, result.computedPosition, newTransform);
     // 乘上模型变换矩阵的逆矩阵
     Cesium.Matrix4.multiply(invModelMat, newTransform, newTransform);
     // 设置新的变换矩阵
     m3d.transform = Cesium.Matrix4.clone(newTransform);
}

// 3. 使用Entity做为碰撞检测对象
let url = '../../SampleData/models/GroundVehicle/GroundVehicle.glb';
let position = Cesium.Cartesian3.fromDegrees(108.9594, 34.2186, 5);
let hpr = new Cesium.HeadingPitchRoll(0, 0, 0);
let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
let entity = viewer.entities.add({
    name: url,
    position: position,
    orientation: orientation,
    model: {
        uri: url,
        minimumPixelSize: 32,
        maximumScale: 20000,
    },
});
collisionDetection = new CollisionDetectionByRender(viewer, entity, {
    colliderLength: 2,
    colliderWidth: 0.6,
    colliderHeight: 0.6,
    colliderPositionOffset: new Cesium.Cartesian3(0, 0, 0.6)
});
// 对目标位置进行碰撞检测
let result = collisionDetection.checkCollision(positionWC, 0);
// 未碰撞移动到该位置
if (result.result !== 'collided') {
    entity.position = result.computedPosition;
}

// 4. 打开调试模式
collisionDetection = new CollisionDetectionByRender(viewer, viewer.camera, {
    debugShowCollider: false, // 相机做为碰撞检测对象时不打开碰撞盒检查
    debugShowDepthMap: true, // 打开debug模式,深度图检查
});

成员变量

Cesium.Camera | Cesium.MapGISM3D | Cesium.Entity

# readonly collider

碰撞检测对象

Number

# colliderHeight

碰撞盒高

Number

# colliderLength

碰撞盒长

Cesium.Cartesian3

# colliderPositionOffset

碰撞盒位置偏移

Number

# colliderWidth

碰撞盒宽

Boolean

# highPrecision

是否开启高精度模式

defaultPrecision
默认模式下只检测碰撞盒的边框部分
highPrecision
高精度模式下对整个碰撞盒做检测
Number

# maxPassableHeight

最大可通过高度

方法

# checkCollision(targetPosition, heading, optionsopt)

检测目标位置是否会碰撞,需要在场景渲染完成后即postRender事件中做检查。

参数:

名称 类型 默认值 描述
targetPosition Cesium.Cartesian3

目标位置

heading Number | undefined

碰撞体航向

置空时只做俯视图的检查。

options Object {}

可选参数

colliderLength Number

碰撞盒长,默认值取实例的同名属性值

colliderWidth Number

碰撞盒宽,默认值取实例的同名属性值

colliderHeight Number

碰撞盒高,默认值取实例的同名属性值

colliderPositionOffset Cesium.Cartesian3 (0,0,0)

碰撞盒的位置偏移,默认值取实例的同名属性值

maxPassableHeight Number

最大可通过高度,默认值取实例的同名属性值

highPrecision Boolean false

是否开启高精度碰撞检测,默认值取实例的同名属性值

碰撞检测结果数据结构说明:

result computedPosition
'collided' targetPosition 发生了碰撞,返回传入的位置。
'noCollision' targetPosition 没有发生碰撞,返回传入的位置。
'passable' 碰撞后抬高的位置 发生了碰撞但可以通过,计算新的位置。
Object

# destory()

销毁碰撞检测

构造函数
成员变量
方法
事件