cesium——源码解读相机飞行

const scratchToHPRDirection = new Cartesian3();
const scratchToHPRUp = new Cartesian3();
const scratchToHPRRight = new Cartesian3();
function directionUpToHeadingPitchRoll(camera, position, orientation, result) {
  const direction = Cartesian3.clone(
    orientation.direction,
    scratchToHPRDirection
  );
  const up = Cartesian3.clone(orientation.up, scratchToHPRUp);

  if (camera._scene.mode === SceneMode.SCENE3D) {
    const ellipsoid = camera._projection.ellipsoid;
    const transform = Transforms.eastNorthUpToFixedFrame(
      position,
      ellipsoid,
      scratchHPRMatrix1
    );
    const invTransform = Matrix4.inverseTransformation(
      transform,
      scratchHPRMatrix2
    );

    Matrix4.multiplyByPointAsVector(invTransform, direction, direction);
    Matrix4.multiplyByPointAsVector(invTransform, up, up);
  }

  const right = Cartesian3.cross(direction, up, scratchToHPRRight);

  result.heading = getHeading(direction, up);
  result.pitch = getPitch(direction);
  result.roll = getRoll(direction, up, right);

  return result;
}
function getHeading(direction, up) {
  let heading;
  if (
    !CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)
  ) {
    heading = Math.atan2(direction.y, direction.x) - CesiumMath.PI_OVER_TWO;
  } else {
    heading = Math.atan2(up.y, up.x) - CesiumMath.PI_OVER_TWO;
  }

  return CesiumMath.TWO_PI - CesiumMath.zeroToTwoPi(heading);
}

function getPitch(direction) {
  return CesiumMath.PI_OVER_TWO - CesiumMath.acosClamped(direction.z);
}

function getRoll(direction, up, right) {
  let roll = 0.0;
  if (
    !CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)
  ) {
    roll = Math.atan2(-right.z, up.z);
    roll = CesiumMath.zeroToTwoPi(roll + CesiumMath.TWO_PI);
  }

  return roll;
}

  1.  roll是围绕x轴旋转
  2.  pitch是围绕Y轴旋转
  3. heding 是为找z手旋转,图中的yaw

这段代码实现的是将摄像机的方向向量和上方向量转换为欧拉角(heading、pitch、roll)。以下是代码的解读:

  1. 首先将摄像机的方向向量和上方向量分别存储到directionup变量中。

  2. 如果当前场景是3D场景,那么需要对directionup进行转换,使它们相对于场景的东北天坐标系(east-north-up)。

    具体做法是:先根据当前摄像机位置和地球椭球体,计算出将东北天坐标系转换为固定坐标系(fixed)的变换矩阵transform;然后再根据transform的逆矩阵invTransform,将directionup从固定坐标系转换回东北天坐标系。这样做的目的是为了确保欧拉角的计算是相对于场景的东北天坐标系的。

  3. 接着计算右方向向量right,这个向量是通过directionup的叉积计算得到的。

  4. 最后调用getHeadinggetPitchgetRoll三个工具方法,分别计算欧拉角的yaw、pitch和roll值。这三个方法的具体实现逻辑不在这段代码中,但它们的功能分别是:

  • getHeading:计算yaw;

计算yaw值(偏航角,也叫航向角)。这个方法需要传入视图中的方向向量direction和上方向向量up。根据方向向量和上方向量的值,计算出绕Z轴旋转的角度,即yaw值。具体做法是:如果方向向量的z分量不等于1,那么yaw值可以通过方向向量在x-y平面上的反正切值来计算;否则yaw值通过上方向量在x-y平面上的反正切值来计算。计算出的yaw值需要进行一系列的角度转换和规范化,以确保它处于0到2π之间。

  • getPitch:计算pitch值,即绕右方向向量旋转的角度;

计算pitch值(俯仰角)。这个方法也需要传入视图中的方向向量direction。根据方向向量的z值,计算出绕右方向向量旋转的角度,即pitch值。具体做法是:先计算出方向向量与Z轴的夹角,然后将这个夹角减去π/2,即为pitch的值。

  • getRoll:计算roll值,即绕方向向量旋转的角度。

    这个方法需要传入视图中的方向向量direction、上方向量up和右方向量right。根据这三个向量的值,计算出绕方向向量旋转的角度,即roll值。具体做法是:如果方向向量的z分量不等于1,那么roll值可以通过右方向量在up向量上的反正切值来计算;否则roll值为0。计算出的roll值需要进行一系列的角度转换和规范化,以确保它处于0到2π之间。

这些工具方法可以用于将视图中的方向向量和上方向向量转换为欧拉角的值,以便于对摄像机进行控制。

最后将计算出的yaw、pitch和roll值存储到result对象中,并返回result对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium 是一个基于 WebGL 的虚拟地球引擎,可以用来创建交互式地球、地图和其他地理空间应用。Cesium 源代码是一个开源项目,可以在 GitHub 上找到。 Cesium源码结构相对清晰,主要分为以下几个部分: 1. Core:包含 Cesium 的核心代码,如 Cesium 对象、Clock 对象、Event 对象等。 2. DataSources:包含 Cesium 的数据源代码,如 GeoJSONDataSource、KMLDataSource 等。 3. Renderer:包含 Cesium 的渲染器代码,如 WebGLRenderer、SceneRenderer、FrustumCommands 等。 4. ThirdParty:包含 Cesium 使用的第三方库代码,如 glsl-optimizer、knockout、moment、protobuf 等。 5. Widgets:包含 Cesium 的小部件代码,如 InfoBox、NavigationHelpButton、PerformanceWatchdog 等。 6. Workers:包含 Cesium 的 Worker 代码,如 buildPickColors、createVerticesFromPickIds 等。 在阅读 Cesium 源代码时,需要注意以下几点: 1. Cesium 使用的是 ECMAScript 6 (ES6) 语法,需要了解 ES6 的语法规范。 2. Cesium 的源代码使用了大量的模块化编程,需要了解模块化编程的概念和使用。 3. Cesium 的源代码中使用了大量的注释,需要认真阅读注释,了解代码的功能和实现原理。 4. Cesium 的源代码结构相对清晰,可以从多个角度入手,如核心代码、数据源代码、渲染器代码等。 总之,阅读 Cesium 源代码需要有一定的 JavaScript 编程经验和基本的地理空间知识,需要认真阅读代码注释,了解代码的功能和实现原理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值