Цезий: камера в вид от первого лица

Я хотел бы, чтобы моя камера следовала от первого лица движущегося объекта. я не верю этому trackedEntity будет работать для этого варианта использования, потому что я не хочу смотреть на сущность, но я хочу выглянуть из нее. Я также хотел бы, чтобы пользователь мог использовать мышь для поворота камеры относительно движущегося объекта (например, для просмотра левого окна движущейся плоскости).

В традиционном игровом движке я бы сделал это, прикрепив камеру к сущности, чтобы она двигалась вместе с ней, но сохранила свое собственное локальное преобразование по отношению к сущности, чтобы она могла свободно перемещаться по отношению к сущности.

Единственный способ, о котором я могу думать прямо сейчас, - это отдельно отслеживать "управляемое пользователем" преобразование и умножать его на преобразование объекта при каждом такте. Есть ли способ лучше?

2 ответа

Взгляните на пример замка из песка Cesium Cardboard . Вот вы находитесь на борту воздушного шара и воспринимаете мир оттуда. После прокрутки вы можете перемещаться с помощью мыши, чтобы осмотреться. Так как расчеты довольно сложные, я не могу подробно рассказать, как это работает, но кажется, что вид камеры выровнен по направлению движения объекта. Неотъемлемой частью скрипта является:

      // 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 First Person Camera Controller.

Я должен был понять это и сам.

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,

Другие вопросы по тегам