Цезий: камера в вид от первого лица
Я хотел бы, чтобы моя камера следовала от первого лица движущегося объекта. я не верю этому 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
,