@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
105 lines • 4.31 kB
JavaScript
import { Camera } from "../../Cameras/camera.js";
import { UniversalCamera } from "../../Cameras/universalCamera.js";
import { Matrix, Vector3 } from "../../Maths/math.vector.js";
import { TargetCamera } from "../targetCamera.js";
import { TransformNode } from "../../Meshes/transformNode.js";
import { Viewport } from "../../Maths/math.viewport.js";
/**
* Camera used to simulate stereoscopic rendering on real screens (based on UniversalCamera)
* @see https://doc.babylonjs.com/features/featuresDeepDive/cameras
*/
export class StereoscopicScreenUniversalCamera extends UniversalCamera {
set distanceBetweenEyes(newValue) {
this._distanceBetweenEyes = newValue;
}
/**
* distance between the eyes
*/
get distanceBetweenEyes() {
return this._distanceBetweenEyes;
}
set distanceToProjectionPlane(newValue) {
this._distanceToProjectionPlane = newValue;
}
/**
* Distance to projection plane (should be the same units the like distance between the eyes)
*/
get distanceToProjectionPlane() {
return this._distanceToProjectionPlane;
}
/**
* Creates a new StereoscopicScreenUniversalCamera
* @param name defines camera name
* @param position defines initial position
* @param scene defines the hosting scene
* @param distanceToProjectionPlane defines distance between each color axis. The rig cameras will receive this as their negative z position!
* @param distanceBetweenEyes defines is stereoscopic is done side by side or over under
*/
constructor(name, position, scene, distanceToProjectionPlane = 1, distanceBetweenEyes = 0.065) {
super(name, position, scene);
this._distanceBetweenEyes = distanceBetweenEyes;
this._distanceToProjectionPlane = distanceToProjectionPlane;
this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL, {
stereoHalfAngle: 0,
});
this._cameraRigParams.stereoHalfAngle = 0;
this._cameraRigParams.interaxialDistance = distanceBetweenEyes;
}
/**
* Gets camera class name
* @returns StereoscopicScreenUniversalCamera
*/
getClassName() {
return "StereoscopicUniversalCamera";
}
/**
* @internal
*/
createRigCamera(name) {
const camera = new TargetCamera(name, Vector3.Zero(), this.getScene());
const transform = new TransformNode("tm_" + name, this.getScene());
camera.parent = transform;
transform.setPivotMatrix(Matrix.Identity(), false);
camera.isRigCamera = true;
camera.rigParent = this;
return camera;
}
/**
* @internal
*/
_updateRigCameras() {
for (let cameraIndex = 0; cameraIndex < this._rigCameras.length; cameraIndex++) {
const cam = this._rigCameras[cameraIndex];
cam.minZ = this.minZ;
cam.maxZ = this.maxZ;
cam.fov = this.fov;
cam.upVector.copyFrom(this.upVector);
if (cam.rotationQuaternion) {
cam.rotationQuaternion.copyFrom(this.rotationQuaternion);
}
else {
cam.rotation.copyFrom(this.rotation);
}
this._updateCamera(this._rigCameras[cameraIndex], cameraIndex);
}
}
_updateCamera(camera, cameraIndex) {
const b = this.distanceBetweenEyes / 2;
const z = b / this.distanceToProjectionPlane;
camera.position.copyFrom(this.position);
camera.position.addInPlaceFromFloats(cameraIndex === 0 ? -b : b, 0, -this._distanceToProjectionPlane);
const transform = camera.parent;
const m = transform.getPivotMatrix();
m.setTranslationFromFloats(cameraIndex === 0 ? b : -b, 0, 0);
m.setRowFromFloats(2, cameraIndex === 0 ? z : -z, 0, 1, 0);
transform.setPivotMatrix(m, false);
}
_setRigMode() {
this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1);
this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
for (let cameraIndex = 0; cameraIndex < this._rigCameras.length; cameraIndex++) {
this._updateCamera(this._rigCameras[cameraIndex], cameraIndex);
}
}
}
//# sourceMappingURL=stereoscopicScreenUniversalCamera.js.map