Browse Source

BatchedMesh: Add support for raycasting (#27146)

* BatchedMeh: add support for frustum culling batched elements

* comments

* Update frustum culling support

* BatchedMesh: add "perObjectFrustumCulled"

* Reduce the number of world matrix transform applications for frustum culling

* Update copy function

* Update toJSON

* Fix serialization

* BatchedMesh: Add raycast support

* Remove empty line

* Add draw range support
Garrett Johnson 1 year ago
parent
commit
d9817318e7
1 changed files with 61 additions and 2 deletions
  1. 61 2
      examples/jsm/objects/BatchedMesh.js

+ 61 - 2
examples/jsm/objects/BatchedMesh.js

@@ -29,6 +29,8 @@ const _frustum = new Frustum();
 const _box = new Box3();
 const _sphere = new Sphere();
 const _vector = new Vector3();
+const _mesh = new Mesh();
+const _batchIntersects = [];
 
 // @TODO: SkinnedMesh support?
 // @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.
@@ -745,9 +747,66 @@ class BatchedMesh extends Mesh {
 
 	}
 
-	raycast() {
+	raycast( raycaster, intersects ) {
 
-		console.warn( 'BatchedMesh: Raycast function not implemented.' );
+		const visible = this._visible;
+		const active = this._active;
+		const drawRanges = this._drawRanges;
+		const geometryCount = this._geometryCount;
+		const matrixWorld = this.matrixWorld;
+		const batchGeometry = this.geometry;
+
+		// iterate over each geometry
+		_mesh.material = this.material;
+		_mesh.geometry.index = batchGeometry.index;
+		_mesh.geometry.attributes = batchGeometry.attributes;
+		if ( _mesh.geometry.boundingBox === null ) {
+
+			_mesh.geometry.boundingBox = new Box3();
+
+		}
+
+		if ( _mesh.geometry.boundingSphere === null ) {
+
+			_mesh.geometry.boundingSphere = new Sphere();
+
+		}
+
+		for ( let i = 0; i < geometryCount; i ++ ) {
+
+			if ( ! visible[ i ] || ! active[ i ] ) {
+
+				continue;
+
+			}
+
+			const drawRange = drawRanges[ i ];
+			_mesh.geometry.setDrawRange( drawRange.start, drawRange.count );
+
+			// ge the intersects
+			this.getMatrixAt( i, _mesh.matrixWorld ).premultiply( matrixWorld );
+			this.getBoundingBoxAt( i, _mesh.geometry.boundingBox );
+			this.getBoundingSphereAt( i, _mesh.geometry.boundingSphere );
+			_mesh.raycast( raycaster, _batchIntersects );
+
+			// add batch id to the intersects
+			for ( let j = 0, l = _batchIntersects.length; j < l; j ++ ) {
+
+				const intersect = _batchIntersects[ j ];
+				intersect.object = this;
+				intersect.batchId = i;
+				intersects.push( intersect );
+
+			}
+
+			_batchIntersects.length = 0;
+
+		}
+
+		_mesh.material = null;
+		_mesh.geometry.index = null;
+		_mesh.geometry.attributes = {};
+		_mesh.geometry.setDrawRange( 0, Infinity );
 
 	}