Давайте предположим, что у вас есть текущая камера, и вы хотите убедиться, что вся ваша сцена вписывается в ее вид.Переменные, которые вы можете изменить в OrthographicCamera
: left, right, top, bottom, near, far
.Вы обычно хотите убедиться, что left = -right
и top = -bottom
.И вам нужно убедиться, что соотношение равно соотношению сторон окна.Таким образом, все, что вы можете изменить, это, по сути, одно значение масштаба.
Что мы собираемся сделать, чтобы определить следующее: мы берем все точки в нашей сцене и преобразуем их в пространство камеры.Тогда минимальное и максимальное значения x, y и z, соответственно, дают нам минимальные границы для камеры.И тогда нам просто нужно убедиться, что соотношение сторон правильное.
Теперь делать это для всех точек обычно слишком сложно в вычислительном отношении.Вместо этого мы могли бы приблизить нашу сцену с ограничивающей сферой радиуса r
с центром в c
.Вы можете либо рассчитать их один раз в начале вашего приложения, либо сохранить их вместе со сценой.И затем, вместо того, чтобы убедиться, что сцена вписывается в вид, мы проверяем, что вся ограничивающая сфера вписывается в вид.
Сделать это для орфографической камеры на самом деле довольно просто.Нам просто нужно преобразовать центр сферы в координаты камеры:
var cInCameraSpace = new THREE.Vector3(); //do this once at initialization
//transform sphere center to camera space
cInCameraSpace.copy(c);
cInCameraSpace.applyMatrix4(camera.matrixWorldInverse)
И тогда мы сможем найти границы:
var halfWidth = Math.abs(cInCameraSpace.x) + r;
var halfHeight = Math.abs(cInCameraSpace.y) + r;
camera.near = -cInCameraSpace.z - r;
camera.far = -cInCameraSpace.z + r;
Теперь давайте убедимся, что мы сохраним соотношение сторон,Я предполагаю, что мы уже знаем соотношение сторон окна как windowAspect
.
if(halfWidth / halfHeight > windowAspect) {
camera.right = halfWidth;
camera.top = halfWidth / windowAspect;
} else {
camera.top = halfHeight;
camera.right = halfHeight * windowAspect;
}
camera.bottom = -camera.top;
camera.left = -camera.right;