Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 27 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
16563ef
🎥 : WIP : New PerspectiveCamera helper method - getMarginAt()
Bug-Reaper Jan 12, 2024
2c3d816
🐛 : FIX : Various small fixes
Bug-Reaper Jan 12, 2024
e8a73c0
🎥 : UPGRADE : Account for camera's matrix world
Bug-Reaper Jan 13, 2024
99bf0c7
🎥 : REFACTOR : getMarginsAt() => frustumHeight(), frustumWidth(), fru…
Bug-Reaper Jan 14, 2024
8351897
🎥 : UPGRADE : More refactor experimentation
Bug-Reaper Jan 14, 2024
253fb2a
🎥 : UPGRADE : Refactored methods provided - Closer to final implement…
Bug-Reaper Jan 16, 2024
98886c9
🎥 : UPGRADE : Tmp vars moved to module scope & Proper imports for Vec…
Bug-Reaper Jan 16, 2024
537e1ea
🎥 : UPGRADE : Consolidate module scoped temp vars w/better re-use
Bug-Reaper Jan 16, 2024
7162815
🎥 : UPGRADE : 3x speed improvement to getBounds() via simplified matr…
Bug-Reaper Jan 16, 2024
8376562
🎥 : NEW : Documentation for getBounds()/frustumDimensions()/frustumCo…
Bug-Reaper Jan 16, 2024
8e019c3
🎥 : UPGRADE : MatrixWorld only relevant on frustumCorners()
Bug-Reaper Jan 16, 2024
a8e2add
🎥 : UPGRADE : MrDoob approves style updates
Bug-Reaper Jan 16, 2024
fc2867d
🎥 : UPGRADE : Gonna gamble this is desired /*__PURE__*/
Bug-Reaper Jan 16, 2024
27a49c6
🎥 : UPGRADE : frustumDimensions => getFrustumDimensions & Use target …
Bug-Reaper Jan 17, 2024
ab65b6e
🎥 : REFACTOR : Move getFrustumCorners() from PerspectiveCamera module…
Bug-Reaper Jan 18, 2024
84b0c11
🎥 : REFACTOR : Rename function + Update comment
Bug-Reaper Jan 18, 2024
fcab13f
🎥 : REFACTOR : Fix case-mistake on function name & updated comment
Bug-Reaper Jan 18, 2024
ef8ba73
Update PerspectiveCamera.js
Mugen87 Jan 18, 2024
e81542d
Update PerspectiveCamera.js
Mugen87 Jan 18, 2024
601461c
Update PerspectiveCamera.js
Mugen87 Jan 18, 2024
d66410e
Update PerspectiveCamera.html
Mugen87 Jan 18, 2024
2432011
Update CameraUtils.js
Mugen87 Jan 18, 2024
03bdbe2
Update PerspectiveCamera.js
Mugen87 Jan 19, 2024
7ae93f5
🚛 : DELETE : `getFrustumCorners()` - Utility to be addressed in a lat…
Bug-Reaper Jan 19, 2024
c1024ad
🎥 : UPGRADE : Bump docs description
Bug-Reaper Jan 19, 2024
c9f5641
🧼 : CLEANUP : Removal of leftover method artifacts
Bug-Reaper Jan 19, 2024
45f8fae
Update CameraUtils.js
Mugen87 Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 21 additions & 2 deletions docs/api/en/cameras/PerspectiveCamera.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,26 @@ <h2>Methods</h2>
<h3>[method:undefined clearViewOffset]()</h3>
<p>Removes any offset set by the [page:PerspectiveCamera.setViewOffset .setViewOffset] method.</p>

<h3>[method:Object frustumCorners]( [param:Float distance] )</h3>
<p>
Provides positions of the camera's frustum corners at a given distance from the camera.
Returns an object with topLeft, topRight, bottomRight, and bottomLeft properties where each property is a
[page:Vector3].
</p>

<h3>[method:Vector2 frustumDimensions]( [param:Float distance] )</h3>
<p>
Calculates the height and width of the camera's frustum at a given distance from the camera.
Returns a [page:Vector2] where x is width and y is height.
</p>

<h3>[method:undefined getBounds]( [param:Float distance], [param:Vector2 minTarget], [param:Vector2 maxTarget] )
</h3>
<p>
Calculates the XY of the min/max bounds for the camera's viewable rectangle at a given distance.
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>

Expand Down Expand Up @@ -214,6 +234,5 @@ <h2>Source</h2>
<p>
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
</p>

</body>
</html>
</html>
62 changes: 62 additions & 0 deletions src/cameras/PerspectiveCamera.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { Camera } from './Camera.js';
import * as MathUtils from '../math/MathUtils.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';

// Temp constants used by getBounds(), frustumDimensions(), and frustumCorners()
const _tempV3 = /*@__PURE__*/ new Vector3();
const _minTarget = /*@__PURE__*/ new Vector2();
const _maxTarget = /*@__PURE__*/ new Vector2();
const _dimensions = /*@__PURE__*/ new Vector2();


class PerspectiveCamera extends Camera {

Expand Down Expand Up @@ -99,6 +108,59 @@ class PerspectiveCamera extends Camera {

}

/*
* Provides the topRight and bottomLeft corners of the camera's 2D frustum slice at a given distance.
* Results are copied into minTarget and maxTarget input vars.
*/
getBounds( distance, minTarget, maxTarget ) {
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

_tempV3.set( - 1, - 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
_tempV3.multiplyScalar( distance / Math.abs( _tempV3.z ) );
minTarget.x = _tempV3.x;
minTarget.y = _tempV3.y;

_tempV3.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse );
_tempV3.multiplyScalar( distance / Math.abs( _tempV3.z ) );
maxTarget.x = _tempV3.x;
maxTarget.y = _tempV3.y;

}

/*
* Calculates the height/width of the camera's frustum at a given distance.
* returns a Vector2 where x is width and y is height.
*/
frustumDimensions( distance ) {
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

this.getBounds( distance, _minTarget, _maxTarget );
_dimensions.x = _maxTarget.x - _minTarget.x;
_dimensions.y = _maxTarget.y - _minTarget.y;

return _dimensions.clone();
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

}

/*
* Calculates Vector3s of the frustum's corners at a given distance from the camera.
* Returns an object with topLeft, topRight, bottomRight, and bottomLeft properties. Each property is a Vector3.
*/
frustumCorners( distance ) {
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

this.getBounds( distance, _minTarget, _maxTarget );
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

this.updateMatrixWorld( true, false );

// .set() -> Calculates the corner position
// .applyMatrix4() -> Accounts for camera position/rotation/scale
return {
topLeft: _tempV3.set( _minTarget.x, _maxTarget.y, - distance ).applyMatrix4( this.matrixWorld ).clone(),
topRight: _tempV3.set( _maxTarget.x, _maxTarget.y, - distance ).applyMatrix4( this.matrixWorld ).clone(),
bottomRight: _tempV3.set( _maxTarget.x, _minTarget.y, - distance ).applyMatrix4( this.matrixWorld ).clone(),
bottomLeft: _tempV3.set( _minTarget.x, _minTarget.y, - distance ).applyMatrix4( this.matrixWorld ).clone(),
};

}

/**
* Sets an offset in a larger frustum. This is useful for multi-window or
* multi-monitor/multi-machine setups.
Expand Down