碰撞检测分析
此碰撞检测分析方案适用于室内,小场景下的慢速碰撞检测分析。对以下几种情况的支持存在不足。
1. 高速物体做碰撞检测容易出现穿隧问题。所谓高速物体指一帧中移动的步长大于碰撞检测盒的检测范围。
2. 场景相机无法观察到的位置,容易出现碰撞检测失效问题。原因是Cesium内部为了性能优化做了视锥体剔除操作,对不可见的物体不会渲染。这样就导致不可见的物体也无法获取其深度信息。使用相机做碰撞体时,后退操作容易出现此问题。
3. 对锥型物体的检测容易失效。为了尽可能的减少碰撞检测的分析数据量,在实际分析时只取碰撞盒边框所覆盖到的深度数据做计算,所以对于锥形的物体,当碰撞体从上方落下时,因为碰撞盒的边框无法覆盖到此锥形物体,故也就无法识别出发生了碰撞。为了处理这种情况可使用高精度模式,但这样就牺牲了较大的性能。
此碰撞检测分析方案适用于室内,小场景下的慢速碰撞检测分析。对以下几种情况的支持存在不足。
1. 高速物体做碰撞检测容易出现穿隧问题。所谓高速物体指一帧中移动的步长大于碰撞检测盒的检测范围。
2. 场景相机无法观察到的位置,容易出现碰撞检测失效问题。原因是Cesium内部为了性能优化做了视锥体剔除操作,对不可见的物体不会渲染。这样就导致不可见的物体也无法获取其深度信息。使用相机做碰撞体时,后退操作容易出现此问题。
3. 对锥型物体的检测容易失效。为了尽可能的减少碰撞检测的分析数据量,在实际分析时只取碰撞盒边框所覆盖到的深度数据做计算,所以对于锥形的物体,当碰撞体从上方落下时,因为碰撞盒的边框无法覆盖到此锥形物体,故也就无法识别出发生了碰撞。为了处理这种情况可使用高精度模式,但这样就牺牲了较大的性能。
Name | Type | Description | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
viewer |
Viewer | 场景视图 | ||||||||||||||||||||||||||||||||||||
collider |
Camera | MapGISM3D | Entity | 做碰撞检测的对象 | ||||||||||||||||||||||||||||||||||||
options |
Object |
optional
可选参数
|
Example:
// 1. 默认使用相机做为碰撞检测对象
var collisionDetection;
collisionDetection = new Cesium.CollisionDetectionByRender(viewer, viewer.camera);
// 对目标位置进行碰撞检测
var 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做为碰撞检测对象
var m3d;
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/2.0/wujiangdizhiti/wujiangdizhiti.mcj';
var options = {
maximumScreenSpaceError: 0,
autoReset: false,
loaded: function(layer) {
m3d = layer;
collisionDetection = new Cesium.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);
// 对目标位置进行碰撞检测
var result = collisionDetection.checkCollision(targetPosition, 0);
// 获取M3D模型在笛卡尔空间的变换矩阵
var transform = m3d.computedTransform;
var newTransform = new Cesium.Matrix4();
var invModelMat = new Cesium.Matrix4();
if (result.result !== 'collided') {
// 获取模型变换矩阵
var modelMatrix = m3d.tileset.modelMatrix;
// 求模型变换矩阵的逆
Cesium.Matrix4.inverse(modelMatrix, invModelMat);
// 未碰撞移动到该位置
Cesium.Matrix4.setTranslation(transform, result.computedPosition, newTransform);
// 乘上模型变换矩阵的逆矩阵
Cesium.Matrix4.multiply(invModelMat, newTransform, newTransform);
// 设置新的变换矩阵
m3d.transform = Matrix4.clone(newTransform);
}
// 3. 使用Entity做为碰撞检测对象
var url = '../../SampleData/models/GroundVehicle/GroundVehicle.glb';
var position = Cesium.Cartesian3.fromDegrees(108.9594, 34.2186, 5);
var hpr = new Cesium.HeadingPitchRoll(0, 0, 0);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
minimumPixelSize: 32,
maximumScale: 20000,
},
});
collisionDetection = new Cesium.CollisionDetectionByRender(viewer, entity, {
colliderLength: 2,
colliderWidth: 0.6,
colliderHeight: 0.6,
colliderPositionOffset: new Cesium.Cartesian3(0, 0, 0.6)
});
// 对目标位置进行碰撞检测
var result = collisionDetection.checkCollision(positionWC, 0);
// 未碰撞移动到该位置
if (result.result !== 'collided') {
entity.position = result.computedPosition;
}
// 4. 打开调试模式
collisionDetection = new Cesium.CollisionDetectionByRender(viewer, viewer.camera, {
debugShowCollider: false, // 相机做为碰撞检测对象时不打开碰撞盒检查
debugShowDepthMap: true, // 打开debug模式,深度图检查
});
Members
碰撞检测对象
碰撞盒高
碰撞盒长
colliderPositionOffset : Cartesian3
碰撞盒位置偏移
碰撞盒宽
是否开启高精度模式
![]() 默认模式下只检测碰撞盒的边框部分 |
![]() 高精度模式下对整个碰撞盒做检测 |
最大可通过高度
Methods
检测目标位置是否会碰撞,需要在场景渲染完成后即postRender事件中做检查。
Name | Type | Default | Description | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
targetPosition |
Cartesian3 | 目标位置 | |||||||||||||||||||||||||||||
heading |
Number | undefined |
碰撞体航向
置空时只做俯视图的检查。 |
|||||||||||||||||||||||||||||
options |
Object |
{}
|
optional
可选参数
|
Returns:
碰撞检测结果数据结构说明:
result | computedPosition | |
'collided' | targetPosition | 发生了碰撞,返回传入的位置。 |
'noCollision' | targetPosition | 没有发生碰撞,返回传入的位置。 |
'passable' | 碰撞后抬高的位置 | 发生了碰撞但可以通过,计算新的位置。 |
销毁碰撞检测