Skip to content

Commit 59af27e

Browse files
committed
Add InstancedMeshCulled implementation
1 parent e828fd0 commit 59af27e

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/Three.js

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export { Skeleton } from './objects/Skeleton.js';
2121
export { Bone } from './objects/Bone.js';
2222
export { Mesh } from './objects/Mesh.js';
2323
export { InstancedMesh } from './objects/InstancedMesh.js';
24+
export { InstancedMeshCulled } from './objects/InstancedMeshCulled.js';
2425
export { LineSegments } from './objects/LineSegments.js';
2526
export { LineLoop } from './objects/LineLoop.js';
2627
export { Line } from './objects/Line.js';

src/objects/InstancedMeshCulled.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { InstancedMesh } from './InstancedMesh.js';
2+
import { Sphere } from '../math/Sphere.js';
3+
import { Vector3 } from '../math/Vector3.js';
4+
5+
6+
class InstancedMeshCulled extends InstancedMesh {
7+
8+
constructor( geometry, material, count ) {
9+
10+
super( geometry, material, count );
11+
12+
this.frustumCulled = true;
13+
this.boundingSphere = null;
14+
15+
}
16+
17+
computeBoundingSphere() {
18+
19+
if (this.geometry.boundingSphere === null) this.geometry.computeBoundingSphere();
20+
21+
const min = new Vector3( Infinity, Infinity, Infinity );
22+
const max = new Vector3( - Infinity, - Infinity, - Infinity );
23+
const position = new Vector3();
24+
25+
for ( let m = 0; m < this.count; m ++ ) {
26+
27+
let x = this.instanceMatrix[ m * 16 + 12 ];
28+
let y = this.instanceMatrix[ m * 16 + 13 ];
29+
let z = this.instanceMatrix[ m * 16 + 14 ];
30+
position.set( x, y, z );
31+
min.min( position );
32+
max.max( position );
33+
34+
}
35+
36+
let radius = 0;
37+
const center = new Vector3().addVectors( min, max ).multiply( 0.5 );
38+
for ( let m = 0; m < this.count; m ++ ) {
39+
40+
let x = this.instanceMatrix[ m * 16 + 12 ];
41+
let y = this.instanceMatrix[ m * 16 + 13 ];
42+
let z = this.instanceMatrix[ m * 16 + 14 ];
43+
position.set( x, y, z );
44+
const distance = position.distanceTo( center );
45+
// note: we assume no scaling - computing scale from instance matrix is not trivial
46+
const r = distance + this.geometry.boundingSphere.radius;
47+
if ( r > radius ) radius = r;
48+
49+
}
50+
51+
this.boundingSphere = new Sphere( center, radius );
52+
53+
}
54+
55+
intersectsFrustum( frustum ) {
56+
57+
if (this.boundingSphere === null) this.computeBoundingSphere();
58+
frustum.intersectsSphere( this.boundingSphere );
59+
60+
}
61+
62+
}

0 commit comments

Comments
 (0)