Sfoglia il codice sorgente

Merge pull request #169 from liberostelios/add-raycast-option

Add option to enable/disable override of raycast
Garrett Johnson 4 anni fa
parent
commit
283fc4b6ae
4 ha cambiato i file con 35 aggiunte e 6 eliminazioni
  1. 11 1
      README.md
  2. 3 0
      example/index.js
  3. 5 1
      src/three/TilesGroup.js
  4. 16 4
      src/three/TilesRenderer.js

+ 11 - 1
README.md

@@ -311,6 +311,16 @@ autoDisableRendererCulling = true : Boolean
 
 If true then all tile meshes automatically have their [frustumCulled](https://threejs.org/docs/index.html#api/en/core/Object3D.frustumCulled) field set to false. This is useful particularly when using one camera because the tiles renderer automatically performs it's own frustum culling on visible tiles. If [displayActiveTiles](#displayActiveTiles) is true or multiple cameras are being used then you may consider setting this to false.
 
+### .optimizeRaycast
+
+```js
+optimizeRaycast = true : Boolean
+```
+
+If true then `.group` uses a traversal of the tileset definition to optimize the process. If `raycaster.firstHitOnly = true`, then only the first hit of the terrain is reported in the tileset.
+
+This overrides the default threejs behaviour for all its children. If you intend to use typical threejs code against the tiles (e.g. raycast directly against the meshes) you should set this to false.
+
 ### .onPreprocessURL
 
 ```js
@@ -351,7 +361,7 @@ group : Group
 
 The container group for the 3d tiles. Add this to the three.js scene in order to render it.
 
-When raycasting a higher performance traversal approach is used if `raycaster.firstHitOnly = true`. If true then only the first hit of the terrain is reported in the tileset.
+When raycasting a higher performance traversal approach is used (see [optimizeRaycast](#optimizeRaycast)).
 
 ### .manager
 

+ 3 - 0
example/index.js

@@ -51,6 +51,7 @@ let params = {
 
 	'enableUpdate': true,
 	'raycast': NONE,
+	'optimizeRaycast': true,
 	'enableCacheDisplay': false,
 	'enableRendererStats': false,
 	'orthographic': false,
@@ -273,6 +274,7 @@ function init() {
 
 	} );
 	exampleOptions.add( params, 'raycast', { NONE, ALL_HITS, FIRST_HIT_ONLY } );
+	exampleOptions.add( params, 'optimizeRaycast', );
 	exampleOptions.add( params, 'enableCacheDisplay' );
 	exampleOptions.add( params, 'enableRendererStats' );
 	exampleOptions.open();
@@ -442,6 +444,7 @@ function animate() {
 	tiles.errorTarget = params.errorTarget;
 	tiles.errorThreshold = params.errorThreshold;
 	tiles.loadSiblings = params.loadSiblings;
+	tiles.optimizeRaycast = params.optimizeRaycast;
 	tiles.stopAtEmptyTiles = params.stopAtEmptyTiles;
 	tiles.displayActiveTiles = params.displayActiveTiles;
 	tiles.maxDepth = params.maxDepth;

+ 5 - 1
src/three/TilesGroup.js

@@ -15,7 +15,11 @@ export class TilesGroup extends Group {
 
 	raycast( raycaster, intersects ) {
 
-		this.tilesRenderer.raycast( raycaster, intersects );
+		if ( this.tilesRenderer.optimizeRaycast ) {
+
+			this.tilesRenderer.raycast( raycaster, intersects );
+
+		}
 
 	}
 

+ 16 - 4
src/three/TilesRenderer.js

@@ -12,7 +12,7 @@ import {
 	Vector2,
 	Math as MathUtils,
 	Frustum,
-	LoadingManager,
+	LoadingManager
 } from 'three';
 import { raycastTraverse, raycastTraverseFirstHit } from './raycastTraverse.js';
 
@@ -28,8 +28,6 @@ const vecZ = new Vector3();
 const X_AXIS = new Vector3( 1, 0, 0 );
 const Y_AXIS = new Vector3( 0, 1, 0 );
 
-function emptyRaycast() {}
-
 function updateFrustumCulled( object, toInitialValue ) {
 
 	object.traverse( c => {
@@ -77,6 +75,7 @@ export class TilesRenderer extends TilesRendererBase {
 		this.activeTiles = new Set();
 		this.visibleTiles = new Set();
 		this._autoDisableRendererCulling = true;
+		this.optimizeRaycast = true;
 
 		this.onLoadTileSet = null;
 		this.onLoadModel = null;
@@ -98,6 +97,19 @@ export class TilesRenderer extends TilesRendererBase {
 		} );
 		this.manager = manager;
 
+		// Setting up the override raycasting function to be used by
+		// 3D objects created by this renderer
+		const tilesRenderer = this;
+		this._overridenRaycast = function ( raycaster, intersects ) {
+
+			if ( ! tilesRenderer.optimizeRaycast ) {
+
+				Object.getPrototypeOf( this ).raycast.call( this, raycaster, intersects );
+
+			}
+
+		};
+
 	}
 
 	/* Public API */
@@ -617,7 +629,7 @@ export class TilesRenderer extends TilesRendererBase {
 			// We handle raycasting in a custom way so remove it from here
 			scene.traverse( c => {
 
-				c.raycast = emptyRaycast;
+				c.raycast = this._overridenRaycast;
 
 			} );