cesium相机剖面实现

需求:屏幕上点击两点划线对场景进行剖切(相机作为第三个点),常见场景如切西瓜。

针对glb模型

Cesium Sandcastle

针对tileset

Cesium Sandcastle

 核心思想:

1.viewer.camera.getPickRay函数不受相机位置的影响。

2.剖面是以物体(origin)为原点的物体坐标系形成的。

3.基于上述两点,相机到划线两点的两方向向量需要进行转换,从全局坐标转到物体东北上坐标系。且此时“相机”坐标也需要转换为物体坐标,通过两方向向量确定平面的法向量,再根据平面上的一点来生成对应的平面即可。

4.第3点中的相机坐标打引号了,是因为当viewer.trackedEntity=entity之后,相机坐标此时为东北上的物体坐标系,且带有一定偏移。经测试发现可能和glb模型的建模原点与包围体中心点不一致导致,但经过计算比较也合不上。 所以第3点中的相机坐标来源于第1点提到的函数,该函数可以得到方向向量的起点(即相机实际位置)和方向。

5.坐标转换从全局坐标到物体坐标由eastNorthUpToFixedFrame实现,position为物体(glb)放置的位置

const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
const inverse = new Cesium.Matrix4();
    Cesium.Matrix4.inverse(transform,
      inverse
    );

6.若是3dtiles格式则需要看其transform矩阵,如果没有,则第5点提到的position即为包围球的中心

function getInverseTransform (tileSet) {
  let transform;
  let tmp = tileSet.root.transform;
  let tempPos1=tileSet.boundingSphere.center;
  if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
    transform = Cesium.Transforms.eastNorthUpToFixedFrame(tileSet.boundingSphere.center);
  } else {
    transform = Cesium.Matrix4.fromArray(tileSet.root.transform);
    tempPos1 = new Cesium.Cartesian3(tileset.root.transform[12],tileset.root.transform[13],tileset.root.transform[14]);
  }
    const inverse = new Cesium.Matrix4();
    Cesium.Matrix4.inverse(transform,
      inverse
    );
  return [transform,tempPos1,inverse];
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值