@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
71 lines (70 loc) • 2.72 kB
JavaScript
;
import { MathUtils } from "three";
import { TypeAssert } from "../../../engine/poly/Assert";
import { PerspectiveCameraAttribute } from "../CoreCamera";
import { CameraFrameMode } from "../CoreCameraFrameMode";
import { BaseCoreCameraFrameMode } from "./_BaseCoreCameraFrameMode";
import { cameraSetViewOffset } from "../CoreCameraViewOffset";
import { coreObjectClassFactory } from "../../geometry/CoreObjectFactory";
export class CoreCameraPerspectiveFrameMode {
static updateCameraAspect(camera, aspect, options) {
camera.aspect = aspect;
const cameraWithAttributes = (options == null ? void 0 : options.cameraWithAttributes) || camera;
const frameMode = BaseCoreCameraFrameMode.frameMode(cameraWithAttributes);
const expectedAspectRatio = BaseCoreCameraFrameMode.expectedAspectRatio(cameraWithAttributes);
const fov = coreObjectClassFactory(cameraWithAttributes).attribValue(
cameraWithAttributes,
PerspectiveCameraAttribute.FOV
);
if (fov != null && expectedAspectRatio != null) {
this._update({
mode: frameMode,
camera,
fov,
expectedAspectRatio
});
}
if (options && options.resolution) {
cameraSetViewOffset(camera, options.resolution);
}
camera.updateProjectionMatrix();
}
static _update(options) {
const mode = options.mode;
switch (mode) {
case CameraFrameMode.DEFAULT: {
return this._adjustFOVFromModeDefault(options);
}
case CameraFrameMode.COVER: {
return this._adjustFOVFromModeCover(options);
}
case CameraFrameMode.CONTAIN: {
return this._adjustFOVFromModeContain(options);
}
}
TypeAssert.unreachable(mode);
}
static _adjustFOVFromModeDefault(options) {
options.camera.fov = options.fov;
}
static _adjustFOVFromModeCover(options) {
if (options.camera.aspect > options.expectedAspectRatio) {
const cameraHeight = Math.tan(MathUtils.degToRad(options.fov / 2));
const ratio = options.camera.aspect / options.expectedAspectRatio;
const newCameraHeight = cameraHeight / ratio;
options.camera.fov = MathUtils.radToDeg(Math.atan(newCameraHeight)) * 2;
} else {
options.camera.fov = options.fov;
}
}
static _adjustFOVFromModeContain(options) {
if (options.camera.aspect > options.expectedAspectRatio) {
options.camera.fov = options.fov;
} else {
const cameraHeight = Math.tan(MathUtils.degToRad(options.fov / 2));
const ratio = options.camera.aspect / options.expectedAspectRatio;
const newCameraHeight = cameraHeight / ratio;
options.camera.fov = MathUtils.radToDeg(Math.atan(newCameraHeight)) * 2;
}
}
}