PageSourceSearch

https://rippey.ai/assets/threejs/jsm/csm/CSMFrustum.js

js rippey.ai collected 2026-10-05 12:33:37 UTC 2,741 bytes, 152 lines download raw bytes

1import { Vector3, Matrix4 } from 'three';
2
3const inverseProjectionMatrix = new Matrix4();
4
5class CSMFrustum {
6
7	constructor( data ) {
8
9		data = data || {};
10
11		this.vertices = {
12			near: [
13				new Vector3(),
14				new Vector3(),
15				new Vector3(),
16				new Vector3()
17			],
18			far: [
19				new Vector3(),
20				new Vector3(),
21				new Vector3(),
22				new Vector3()
23			]
24		};
25
26		if ( data.projectionMatrix !== undefined ) {
27
28			this.setFromProjectionMatrix( data.projectionMatrix, data.maxFar || 10000 );
29
30		}
31
32	}
33
34	setFromProjectionMatrix( projectionMatrix, maxFar ) {
35
36		const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0;
37
38		inverseProjectionMatrix.copy( projectionMatrix ).invert();
39
40		// 3 --- 0  vertices.near/far order
41		// |     |
42		// 2 --- 1
43		// clip space spans from [-1, 1]
44
45		this.vertices.near[ 0 ].set( 1, 1, - 1 );
46		this.vertices.near[ 1 ].set( 1, - 1, - 1 );
47		this.vertices.near[ 2 ].set( - 1, - 1, - 1 );
48		this.vertices.near[ 3 ].set( - 1, 1, - 1 );
49		this.vertices.near.forEach( function ( v ) {
50
51			v.applyMatrix4( inverseProjectionMatrix );
52
53		} );
54
55		this.vertices.far[ 0 ].set( 1, 1, 1 );
56		this.vertices.far[ 1 ].set( 1, - 1, 1 );
57		this.vertices.far[ 2 ].set( - 1, - 1, 1 );
58		this.vertices.far[ 3 ].set( - 1, 1, 1 );
59		this.vertices.far.forEach( function ( v ) {
60
61			v.applyMatrix4( inverseProjectionMatrix );
62
63			const absZ = Math.abs( v.z );
64			if ( isOrthographic ) {
65
66				v.z *= Math.min( maxFar / absZ, 1.0 );
67
68			} else {
69
70				v.multiplyScalar( Math.min( maxFar / absZ, 1.0 ) );
71
72			}
73
74		} );
75
76		return this.vertices;
77
78	}
79
80	split( breaks, target ) {
81
82		while ( breaks.length > target.length ) {
83
84			target.push( new CSMFrustum() );
85
86		}
87
88		target.length = breaks.length;
89
90		for ( let i = 0; i < breaks.length; i ++ ) {
91
92			const cascade = target[ i ];
93
94			if ( i === 0 ) {
95
96				for ( let j = 0; j < 4; j ++ ) {
97
98					cascade.vertices.near[ j ].copy( this.vertices.near[ j ] );
99
100				}
101
102			} else {
103
104				for ( let j = 0; j < 4; j ++ ) {
105
106					cascade.vertices.near[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i - 1 ] );
107
108				}
109
110			}
111
112			if ( i === breaks.length - 1 ) {
113
114				for ( let j = 0; j < 4; j ++ ) {
115
116					cascade.vertices.far[ j ].copy( this.vertices.far[ j ] );
117
118				}
119
120			} else {
121
122				for ( let j = 0; j < 4; j ++ ) {
123
124					cascade.vertices.far[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i ] );
125
126				}
127
128			}
129
130		}
131
132	}
133
134	toSpace( cameraMatrix, target ) {
135
136		for ( let i = 0; i < 4; i ++ ) {
137
138			target.vertices.near[ i ]
139				.copy( this.vertices.near[ i ] )
140				.applyMatrix4( cameraMatrix );
141
142			target.vertices.far[ i ]
143				.copy( this.vertices.far[ i ] )
144				.applyMatrix4( cameraMatrix );
145
146		}
147
148	}
149
150}
151
152export { CSMFrustum };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.