浏览代码

PerspectiveCamera: Moved frameCorners() to CameraUtils in examples.

Mr.doob 4 年之前
父节点
当前提交
e87bfebbad

+ 0 - 6
docs/api/en/cameras/PerspectiveCamera.html

@@ -186,12 +186,6 @@ camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 		Updates the camera projection matrix. Must be called after any change of parameters.
 		</p>
 
-		<h3>[method:null frameCorners]( [param:Vector3 bottomLeftCorner], [param:Vector3 bottomRightCorner], [param:Vector3 topLeftCorner], [param:boolean estimateViewFrustum] )</h3>
-		<p>
-		Set this PerspectiveCamera's projectionMatrix and quaternion to exactly frame the corners of an arbitrary rectangle using [link:https://web.archive.org/web/20191110002841/http://csc.lsu.edu/~kooima/articles/genperspective/index.html Kooima's Generalized Perspective Projection formulation].
-		NOTE: This function ignores the standard parameters; do not call updateProjectionMatrix() after this! toJSON will also not capture the off-axis matrix generated by this function.
-		</p>
-
 		<h3>[method:Object toJSON]([param:Object meta])</h3>
 		<p>
 		meta -- object containing metadata such as textures or images in objects' descendants.<br />

+ 29 - 0
docs/examples/en/utils/CameraUtils.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<p class="desc">A class containing useful utility functions for camera manipulation.</p>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null frameCorners]( [param:PerspectiveCamera camera] [param:Vector3 bottomLeftCorner], [param:Vector3 bottomRightCorner], [param:Vector3 topLeftCorner], [param:boolean estimateViewFrustum] )</h3>
+		<p>
+		Set a PerspectiveCamera's projectionMatrix and quaternion to exactly frame the corners of an arbitrary rectangle using [link:https://web.archive.org/web/20191110002841/http://csc.lsu.edu/~kooima/articles/genperspective/index.html Kooima's Generalized Perspective Projection formulation].
+		NOTE: This function ignores the standard parameters; do not call updateProjectionMatrix() after this! toJSON will also not capture the off-axis matrix generated by this function.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/CameraUtils.js examples/jsm/utils/CameraUtils.js]
+		</p>
+	</body>
+</html>

+ 1 - 0
docs/list.json

@@ -418,6 +418,7 @@
 
 			"Utils": {
 				"BufferGeometryUtils": "examples/en/utils/BufferGeometryUtils",
+				"CameraUtils": "examples/en/utils/CameraUtils",
 				"SceneUtils": "examples/en/utils/SceneUtils",
 				"SkeletonUtils": "examples/en/utils/SkeletonUtils"
 			}

+ 1 - 1
examples/files.json

@@ -173,7 +173,6 @@
 		"webgl_math_obb",
 		"webgl_math_orientation_transform",
 		"webgl_mirror",
-		"webgl_portal",
 		"webgl_modifier_curve",
 		"webgl_modifier_curve_instanced",
 		"webgl_modifier_edgesplit",
@@ -198,6 +197,7 @@
 		"webgl_points_dynamic",
 		"webgl_points_sprites",
 		"webgl_points_waves",
+		"webgl_portal",
 		"webgl_raycast_sprite",
 		"webgl_raycast_texture",
 		"webgl_read_float_buffer",

+ 88 - 0
examples/js/utils/CameraUtils.js

@@ -0,0 +1,88 @@
+( function () {
+
+	const _va = /*@__PURE__*/new THREE.Vector3(),
+		// from pe to pa
+		_vb = /*@__PURE__*/new THREE.Vector3(),
+		// from pe to pb
+		_vc = /*@__PURE__*/new THREE.Vector3(),
+		// from pe to pc
+		_vr = /*@__PURE__*/new THREE.Vector3(),
+		// right axis of screen
+		_vu = /*@__PURE__*/new THREE.Vector3(),
+		// up axis of screen
+		_vn = /*@__PURE__*/new THREE.Vector3(),
+		// normal vector of screen
+		_vec = /*@__PURE__*/new THREE.Vector3(),
+		// temporary vector
+		_quat = /*@__PURE__*/new THREE.Quaternion(); // temporary quaternion
+
+
+	class CameraUtils {
+
+		/** Set a PerspectiveCamera's projectionMatrix and quaternion
+   * to exactly frame the corners of an arbitrary rectangle.
+   * NOTE: This function ignores the standard parameters;
+   * do not call updateProjectionMatrix() after this!
+   * @param {Vector3} bottomLeftCorner
+   * @param {Vector3} bottomRightCorner
+   * @param {Vector3} topLeftCorner
+   * @param {boolean} estimateViewFrustum */
+		static frameCorners( camera, bottomLeftCorner, bottomRightCorner, topLeftCorner, estimateViewFrustum = false ) {
+
+			const pa = bottomLeftCorner,
+				pb = bottomRightCorner,
+				pc = topLeftCorner;
+			const pe = camera.position; // eye position
+
+			const n = camera.near; // distance of near clipping plane
+
+			const f = camera.far; //distance of far clipping plane
+
+			_vr.copy( pb ).sub( pa ).normalize();
+
+			_vu.copy( pc ).sub( pa ).normalize();
+
+			_vn.crossVectors( _vr, _vu ).normalize();
+
+			_va.copy( pa ).sub( pe ); // from pe to pa
+
+
+			_vb.copy( pb ).sub( pe ); // from pe to pb
+
+
+			_vc.copy( pc ).sub( pe ); // from pe to pc
+
+
+			const d = - _va.dot( _vn ); // distance from eye to screen
+
+			const l = _vr.dot( _va ) * n / d; // distance to left screen edge
+
+			const r = _vr.dot( _vb ) * n / d; // distance to right screen edge
+
+			const b = _vu.dot( _va ) * n / d; // distance to bottom screen edge
+
+			const t = _vu.dot( _vc ) * n / d; // distance to top screen edge
+			// Set the camera rotation to match the focal plane to the corners' plane
+
+			_quat.setFromUnitVectors( _vec.set( 0, 1, 0 ), _vu );
+
+			camera.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat ); // Set the off-axis projection matrix to match the corners
+
+			camera.projectionMatrix.set( 2.0 * n / ( r - l ), 0.0, ( r + l ) / ( r - l ), 0.0, 0.0, 2.0 * n / ( t - b ), ( t + b ) / ( t - b ), 0.0, 0.0, 0.0, ( f + n ) / ( n - f ), 2.0 * f * n / ( n - f ), 0.0, 0.0, - 1.0, 0.0 );
+			camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert(); // FoV estimation to fix frustum culling
+
+			if ( estimateViewFrustum ) {
+
+				// Set fieldOfView to a conservative estimate
+				// to make frustum tall/wide enough to encompass it
+				camera.fov = THREE.MathUtils.RAD2DEG / Math.min( 1.0, camera.aspect ) * Math.atan( ( _vec.copy( pb ).sub( pa ).length() + _vec.copy( pc ).sub( pa ).length() ) / _va.length() );
+
+			}
+
+		}
+
+	}
+
+	THREE.CameraUtils = CameraUtils;
+
+} )();

+ 76 - 0
examples/jsm/utils/CameraUtils.js

@@ -0,0 +1,76 @@
+import {
+	MathUtils,
+	Quaternion,
+	Vector3
+} from '../../../build/three.module.js';
+
+const _va = /*@__PURE__*/ new Vector3(), // from pe to pa
+	_vb = /*@__PURE__*/ new Vector3(), // from pe to pb
+	_vc = /*@__PURE__*/ new Vector3(), // from pe to pc
+	_vr = /*@__PURE__*/ new Vector3(), // right axis of screen
+	_vu = /*@__PURE__*/ new Vector3(), // up axis of screen
+	_vn = /*@__PURE__*/ new Vector3(), // normal vector of screen
+	_vec = /*@__PURE__*/ new Vector3(), // temporary vector
+	_quat = /*@__PURE__*/ new Quaternion(); // temporary quaternion
+
+class CameraUtils {
+
+	/** Set a PerspectiveCamera's projectionMatrix and quaternion
+	 * to exactly frame the corners of an arbitrary rectangle.
+	 * NOTE: This function ignores the standard parameters;
+	 * do not call updateProjectionMatrix() after this!
+	 * @param {Vector3} bottomLeftCorner
+	 * @param {Vector3} bottomRightCorner
+	 * @param {Vector3} topLeftCorner
+	 * @param {boolean} estimateViewFrustum */
+	static frameCorners( camera, bottomLeftCorner, bottomRightCorner, topLeftCorner, estimateViewFrustum = false ) {
+
+		const pa = bottomLeftCorner, pb = bottomRightCorner, pc = topLeftCorner;
+		const pe = camera.position; // eye position
+		const n = camera.near; // distance of near clipping plane
+		const f = camera.far; //distance of far clipping plane
+
+		_vr.copy( pb ).sub( pa ).normalize();
+		_vu.copy( pc ).sub( pa ).normalize();
+		_vn.crossVectors( _vr, _vu ).normalize();
+
+		_va.copy( pa ).sub( pe ); // from pe to pa
+		_vb.copy( pb ).sub( pe ); // from pe to pb
+		_vc.copy( pc ).sub( pe ); // from pe to pc
+
+		const d = - _va.dot( _vn );	// distance from eye to screen
+		const l = _vr.dot( _va ) * n / d; // distance to left screen edge
+		const r = _vr.dot( _vb ) * n / d; // distance to right screen edge
+		const b = _vu.dot( _va ) * n / d; // distance to bottom screen edge
+		const t = _vu.dot( _vc ) * n / d; // distance to top screen edge
+
+		// Set the camera rotation to match the focal plane to the corners' plane
+		_quat.setFromUnitVectors( _vec.set( 0, 1, 0 ), _vu );
+		camera.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat );
+
+		// Set the off-axis projection matrix to match the corners
+		camera.projectionMatrix.set( 2.0 * n / ( r - l ), 0.0,
+			( r + l ) / ( r - l ), 0.0, 0.0,
+			2.0 * n / ( t - b ),
+			( t + b ) / ( t - b ), 0.0, 0.0, 0.0,
+			( f + n ) / ( n - f ),
+			2.0 * f * n / ( n - f ), 0.0, 0.0, - 1.0, 0.0 );
+		camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert();
+
+		// FoV estimation to fix frustum culling
+		if ( estimateViewFrustum ) {
+
+			// Set fieldOfView to a conservative estimate
+			// to make frustum tall/wide enough to encompass it
+			camera.fov =
+				MathUtils.RAD2DEG / Math.min( 1.0, camera.aspect ) *
+				Math.atan( ( _vec.copy( pb ).sub( pa ).length() +
+						   ( _vec.copy( pc ).sub( pa ).length() ) ) / _va.length() );
+
+		}
+
+	}
+
+}
+
+export { CameraUtils };

+ 1 - 1
examples/tags.json

@@ -49,7 +49,7 @@
 	"webgl_math_obb": [ "intersection", "bounding" ],
 	"webgl_math_orientation_transform": [ "rotation" ],
 	"webgl_mirror": [ "reflection" ],
-	"webgl_portal": [ "portal", "frameCorners", "renderTarget" ],
+	"webgl_portal": [ "frameCorners", "renderTarget" ],
 	"webgl_morphtargets_horse": [ "animation" ],
 	"webgl_multiple_elements": [ "differential equations", "physics" ],
 	"webgl_multiple_elements_text": [ "font" ],

+ 6 - 5
examples/webgl_portal.html

@@ -24,6 +24,7 @@
 
 			import * as THREE from '../build/three.module.js';
 
+			import { CameraUtils } from './jsm/utils/CameraUtils.js';
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
 
 			let camera, scene, renderer;
@@ -33,7 +34,7 @@
 			let smallSphereOne, smallSphereTwo;
 
 			let portalCamera, leftPortal, rightPortal, leftPortalTexture, reflectedPosition,
-				rightPortalTexture, bottomLeftCorner, bottomRightCorner, topLeftCorner, frustumHelper;
+				rightPortalTexture, bottomLeftCorner, bottomRightCorner, topLeftCorner;
 
 			init();
 			animate();
@@ -191,7 +192,7 @@
 				otherPortalMesh.localToWorld( bottomRightCorner.set( - 50.05, - 50.05, 0.0 ) );
 				otherPortalMesh.localToWorld( topLeftCorner.set( 50.05, 50.05, 0.0 ) );
 				// set the projection matrix to encompass the portal's frame
-				portalCamera.frameCorners( bottomLeftCorner, bottomRightCorner, topLeftCorner, false );
+				CameraUtils.frameCorners( portalCamera, bottomLeftCorner, bottomRightCorner, topLeftCorner, false );
 
 				// render the portal
 				thisPortalTexture.texture.encoding = renderer.outputEncoding;
@@ -227,9 +228,9 @@
 				smallSphereTwo.rotation.z = timerTwo * 0.8;
 
 				// save the original camera properties
-				let currentRenderTarget = renderer.getRenderTarget();
-				let currentXrEnabled = renderer.xr.enabled;
-				let currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
+				const currentRenderTarget = renderer.getRenderTarget();
+				const currentXrEnabled = renderer.xr.enabled;
+				const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
 				renderer.xr.enabled = false; // Avoid camera modification
 				renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
 

+ 0 - 65
src/cameras/PerspectiveCamera.js

@@ -206,62 +206,6 @@ class PerspectiveCamera extends Camera {
 
 	}
 
-	/** Set this PerspectiveCamera's projectionMatrix and quaternion
-	 * to exactly frame the corners of an arbitrary rectangle.
-	 * NOTE: This function ignores the standard parameters;
-	 * do not call updateProjectionMatrix() after this!
-	 * @param {Vector3} bottomLeftCorner
-	 * @param {Vector3} bottomRightCorner
-	 * @param {Vector3} topLeftCorner
-	 * @param {boolean} estimateViewFrustum */
-	frameCorners( bottomLeftCorner, bottomRightCorner, topLeftCorner, estimateViewFrustum = false ) {
-
-		const pa = bottomLeftCorner, pb = bottomRightCorner, pc = topLeftCorner;
-		const pe = this.position; // eye position
-		const n = this.near; // distance of near clipping plane
-		const f = this.far; //distance of far clipping plane
-
-		_vr.copy( pb ).sub( pa ).normalize();
-		_vu.copy( pc ).sub( pa ).normalize();
-		_vn.crossVectors( _vr, _vu ).normalize();
-
-		_va.copy( pa ).sub( pe ); // from pe to pa
-		_vb.copy( pb ).sub( pe ); // from pe to pb
-		_vc.copy( pc ).sub( pe ); // from pe to pc
-
-		const d = - _va.dot( _vn );	// distance from eye to screen
-		const l = _vr.dot( _va ) * n / d; // distance to left screen edge
-		const r = _vr.dot( _vb ) * n / d; // distance to right screen edge
-		const b = _vu.dot( _va ) * n / d; // distance to bottom screen edge
-		const t = _vu.dot( _vc ) * n / d; // distance to top screen edge
-
-		// Set the camera rotation to match the focal plane to the corners' plane
-		_quat.setFromUnitVectors( _vec.set( 0, 1, 0 ), _vu );
-		this.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat );
-
-		// Set the off-axis projection matrix to match the corners
-		this.projectionMatrix.set( 2.0 * n / ( r - l ), 0.0,
-			( r + l ) / ( r - l ), 0.0, 0.0,
-			2.0 * n / ( t - b ),
-			( t + b ) / ( t - b ), 0.0, 0.0, 0.0,
-			( f + n ) / ( n - f ),
-			2.0 * f * n / ( n - f ), 0.0, 0.0, - 1.0, 0.0 );
-		this.projectionMatrixInverse.copy( this.projectionMatrix ).invert();
-
-		// FoV estimation to fix frustum culling
-		if ( estimateViewFrustum ) {
-
-			// Set fieldOfView to a conservative estimate
-			// to make frustum tall/wide enough to encompass it
-			this.fov =
-				MathUtils.RAD2DEG / Math.min( 1.0, this.aspect ) *
-				Math.atan( ( _vec.copy( pb ).sub( pa ).length() +
-						   ( _vec.copy( pc ).sub( pa ).length() ) ) / _va.length() );
-
-		}
-
-	}
-
 	toJSON( meta ) {
 
 		const data = super.toJSON( meta );
@@ -288,13 +232,4 @@ class PerspectiveCamera extends Camera {
 
 PerspectiveCamera.prototype.isPerspectiveCamera = true;
 
-const _va = /*@__PURE__*/ new Vector3(), // from pe to pa
-	_vb = /*@__PURE__*/ new Vector3(), // from pe to pb
-	_vc = /*@__PURE__*/ new Vector3(), // from pe to pc
-	_vr = /*@__PURE__*/ new Vector3(), // right axis of screen
-	_vu = /*@__PURE__*/ new Vector3(), // up axis of screen
-	_vn = /*@__PURE__*/ new Vector3(), // normal vector of screen
-	_vec = /*@__PURE__*/ new Vector3(), // temporary vector
-	_quat = /*@__PURE__*/ new Quaternion(); // temporary quaternion
-
 export { PerspectiveCamera };