Преглед изворни кода

🎥 : PerspectiveCamera: New helper methods `getFrustumBounds()`, `getFrustumSize()`. (#27574)

* 🎥 : WIP : New PerspectiveCamera helper method - getMarginAt()

* 🐛 : FIX : Various small fixes

* 🎥 : UPGRADE : Account for camera's matrix world

* 🎥 : REFACTOR : getMarginsAt() => frustumHeight(), frustumWidth(), frustumCorners()

* 🎥 : UPGRADE : More refactor experimentation

* 🎥 : UPGRADE : Refactored methods provided - Closer to final implementation

* 🎥 : UPGRADE : Tmp vars moved to module scope & Proper imports for Vector2/3

* 🎥 : UPGRADE : Consolidate module scoped temp vars w/better re-use

* 🎥 : UPGRADE : 3x speed improvement to getBounds() via simplified matrix calc

* 🎥 : NEW : Documentation for getBounds()/frustumDimensions()/frustumCorners()

* 🎥 : UPGRADE : MatrixWorld only relevant on frustumCorners()

* 🎥 : UPGRADE : MrDoob approves style updates

* 🎥 : UPGRADE : Gonna gamble this is desired /*__PURE__*/

All the other modules were doing it 🤷‍♂️

* 🎥 : UPGRADE : frustumDimensions => getFrustumDimensions & Use target vector input arg

* 🎥 : REFACTOR : Move getFrustumCorners() from PerspectiveCamera module to CameraUtils

* 🎥 : REFACTOR : Rename function + Update comment

* 🎥 : REFACTOR : Fix case-mistake on function name & updated comment

* Update PerspectiveCamera.js

* Update PerspectiveCamera.js

Clean up.

* Update PerspectiveCamera.js

* Update PerspectiveCamera.html

* Update CameraUtils.js

* Update PerspectiveCamera.js

* 🚛 : DELETE : `getFrustumCorners()` - Utility to be addressed in a later PR

* 🎥 : UPGRADE : Bump docs description

* 🧼 : CLEANUP : Removal of leftover method artifacts

* Update CameraUtils.js

---------

Co-authored-by: Michael Herzog <[email protected]>
Bug-Reaper пре 1 година
родитељ
комит
668968e67c
2 измењених фајлова са 47 додато и 1 уклоњено
  1. 13 1
      docs/api/en/cameras/PerspectiveCamera.html
  2. 34 0
      src/cameras/PerspectiveCamera.js

+ 13 - 1
docs/api/en/cameras/PerspectiveCamera.html

@@ -118,6 +118,19 @@
 		<h3>[method:undefined clearViewOffset]()</h3>
 		<p>Removes any offset set by the [page:PerspectiveCamera.setViewOffset .setViewOffset] method.</p>
 
+		<h3>[method:Vector2 getFrustumSize]( [param:Float distance], [param:Vector2 target] )</h3>
+		<p>
+			Computes the height/width of the camera's viewable rectangle at a given distance along the viewing direction.
+			Copies the result into provided target [page:Vector2] where x is width and y is height.
+		</p>
+
+		<h3>[method:undefined getFrustumBounds]( [param:Float distance], [param:Vector2 minTarget], [param:Vector2 maxTarget] )
+		</h3>
+		<p>
+			Calculates the min/max 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction.
+			Results are copied into minTarget and maxTarget input vars. 
+		</p>
+
 		<h3>[method:Float getEffectiveFOV]()</h3>
 		<p>Returns the current vertical field of view angle in degrees considering .zoom.</p>
 
@@ -214,6 +227,5 @@ camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 		<p>
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 		</p>
-
 	</body>
 </html>

+ 34 - 0
src/cameras/PerspectiveCamera.js

@@ -1,5 +1,12 @@
 import { Camera } from './Camera.js';
 import * as MathUtils from '../math/MathUtils.js';
+import { Vector2 } from '../math/Vector2.js';
+import { Vector3 } from '../math/Vector3.js';
+
+const _v3 = /*@__PURE__*/ new Vector3();
+const _minTarget = /*@__PURE__*/ new Vector2();
+const _maxTarget = /*@__PURE__*/ new Vector2();
+
 
 class PerspectiveCamera extends Camera {
 
@@ -99,6 +106,33 @@ class PerspectiveCamera extends Camera {
 
 	}
 
+	/*
+	 * Computes 2D bounds of the camera's frustum at a given distance along the viewing direction.
+	 * Copies max/min height and width of the frustum's rectangle into minTarget and maxTarget.
+	 * Results are in the camera's local coordinate space, independent of its global position/rotation/scale.
+	 */
+	getFrustumBounds( distance, minTarget, maxTarget ) {
+
+		_v3.set( - 1, - 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
+		minTarget.copy( _v3 ).multiplyScalar( - distance / _v3.z );
+
+		_v3.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
+		maxTarget.copy( _v3 ).multiplyScalar( - distance / _v3.z );
+
+	}
+
+	/*
+	 * Computes the height/width of the camera's frustum at a given distance along the viewing direction.
+	 * Copies the result into provided target Vector2 where x is width and y is height.
+ 	 */
+	getFrustumSize( distance, target ) {
+
+		this.getFrustumBounds( distance, _minTarget, _maxTarget );
+
+		return target.subVectors( _maxTarget, _minTarget );
+
+	}
+
 	/**
 	 * Sets an offset in a larger frustum. This is useful for multi-window or
 	 * multi-monitor/multi-machine setups.