Cesium:将相机放在实体的第一人称视角

3
我希望我的相机能够跟随一个运动实体的第一人称视角。我认为这种情况下 `trackedEntity` 不适用,因为我不想看着实体,而是从它的角度出发看外面。我还希望用户可以使用鼠标来旋转相机,以便例如在飞机移动时可以看向左边的窗户。
在传统的游戏引擎中,我会将相机附加到实体上,这样相机就会随着实体移动,但保留自己相对于实体的本地变换,以便自由移动。
目前我能想到的唯一方法是单独跟踪“用户可控”的变换,并在每次时钟滴答时将其乘以实体的变换。是否有更好的方法?
2个回答

1
请查看Cesium的Cardboard sandcastle example。在这里,您可以乘坐热气球,并从那里感知世界。向外滚动后,您可以使用鼠标平移以四处观看。由于计算相当复杂,我无法详细说明其工作原理,但似乎相机视图与实体的移动方向对齐。脚本的关键部分是:
// Set initial camera position and orientation to be when in the model's reference frame.
var camera = viewer.camera;
camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0);
camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0);
camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0);
camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0);

viewer.scene.postUpdate.addEventListener(function (scene, time) {
  var position = entity.position.getValue(time);
  if (!Cesium.defined(position)) {
    return;
  }

  var transform;
  if (!Cesium.defined(entity.orientation)) {
    transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  } else {
    var orientation = entity.orientation.getValue(time);
    if (!Cesium.defined(orientation)) {
      return;
    }

    transform = Cesium.Matrix4.fromRotationTranslation(
      Cesium.Matrix3.fromQuaternion(orientation),
      position
    );
  }

  // Save camera state
  var offset = Cesium.Cartesian3.clone(camera.position);
  var direction = Cesium.Cartesian3.clone(camera.direction);
  var up = Cesium.Cartesian3.clone(camera.up);

  // Set camera to be in model's reference frame.
  camera.lookAtTransform(transform);

  // Reset the camera state to the saved state so it appears fixed in the model's frame.
  Cesium.Cartesian3.clone(offset, camera.position);
  Cesium.Cartesian3.clone(direction, camera.direction);
  Cesium.Cartesian3.clone(up, camera.up);
  Cesium.Cartesian3.cross(direction, up, camera.right);
});

也许您可以尝试修改相机向量或将变换与另一个旋转矩阵相乘,以模拟在初始视角下转动头部(向左/向右/向后看)。例如,您可以尝试将上面的示例与名为Cesium第一人称相机控制器的存储库中的代码结合起来。

0

我也不得不自己摸索出解决方法。

Camera.setView和自定义的实用函数是你的好朋友。 例如,这里是一个天真的旋转实现(当相机的俯仰角度太像“鸟瞰”时效果不佳):

Cesium.Camera.prototype.rotateView = function(rotation) {
    let { heading, pitch, roll } = rotation;
    heading = this.heading + (heading || 0);
    pitch = this.pitch + (pitch || 0);
    roll = this.roll + (roll || 0);
    const destination = this.position;
    this.setView({
        destination,
        orientation: {
            heading,
            pitch,
            roll
    }
  });
};

同样地,您可以通过提供实体的位置来更新位置destination


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接