Parcourir la source

Remove raycast for intersected line items

Garrett Johnson il y a 5 ans
Parent
commit
5c5eaccdc5
2 fichiers modifiés avec 74 ajouts et 49 suppressions
  1. 5 0
      src/three/DebugTilesRenderer.js
  2. 69 49
      src/three/TilesRenderer.js

+ 5 - 0
src/three/DebugTilesRenderer.js

@@ -10,6 +10,9 @@ const GEOMETRIC_ERROR = 2;
 const DISTANCE = 3;
 const DEPTH = 4;
 const IS_LEAF = 5;
+
+function emptyRaycast() {}
+
 export class DebugTilesRenderer extends TilesRenderer {
 
 	constructor( ...args ) {
@@ -293,6 +296,7 @@ export class DebugTilesRenderer extends TilesRenderer {
 					boxHelperGroup.matrix.decompose( boxHelperGroup.position, boxHelperGroup.quaternion, boxHelperGroup.scale );
 
 					const boxHelper = new Box3Helper( cachedBox );
+					boxHelper.raycast = emptyRaycast;
 					boxHelperGroup.add( boxHelper );
 
 					cached.boxHelperGroup = boxHelperGroup;
@@ -306,6 +310,7 @@ export class DebugTilesRenderer extends TilesRenderer {
 
 					const cachedSphere = cached.sphere;
 					const sphereHelper = new SphereHelper( cachedSphere );
+					sphereHelper.raycast = emptyRaycast;
 					cached.sphereHelper = sphereHelper;
 
 					if ( this.displaySphereBounds ) {

+ 69 - 49
src/three/TilesRenderer.js

@@ -8,7 +8,6 @@ import {
 	Vector3,
 	Vector2,
 	Math as MathUtils,
-	Quaternion,
 	Frustum,
 	CanvasTexture,
 	LoadingManager,
@@ -18,12 +17,11 @@ import { raycastTraverse, raycastTraverseFirstHit } from './raycastTraverse.js';
 
 const DEG2RAD = MathUtils.DEG2RAD;
 const tempMat = new Matrix4();
-const tempQuaternion = new Quaternion();
+const tempMat2 = new Matrix4();
 const tempVector = new Vector3();
 const vecX = new Vector3();
 const vecY = new Vector3();
 const vecZ = new Vector3();
-const _sphere = new Sphere();
 
 const X_AXIS = new Vector3( 1, 0, 0 );
 const Y_AXIS = new Vector3( 0, 1, 0 );
@@ -52,7 +50,7 @@ export class TilesRenderer extends TilesRendererBase {
 		this.group = new TilesGroup( this );
 		this.cameras = [];
 		this.resolution = new Vector2();
-		this.frustums = [];
+		this.cameraInfo = [];
 		this.activeTiles = new Set();
 		this.visibleTiles = new Set();
 
@@ -116,7 +114,7 @@ export class TilesRenderer extends TilesRendererBase {
 
 		const group = this.group;
 		const cameras = this.cameras;
-		const frustums = this.frustums;
+		const cameraInfo = this.cameraInfo;
 		const resolution = this.resolution;
 
 		if ( cameras.length === 0 ) {
@@ -133,30 +131,63 @@ export class TilesRenderer extends TilesRendererBase {
 
 		}
 
-		// automatically scale the array of frustums to match the cameras
-		while ( frustums.length > cameras.length ) {
+		// automatically scale the array of cameraInfo to match the cameras
+		while ( cameraInfo.length > cameras.length ) {
 
-			frustums.pop();
+			cameraInfo.pop();
 
 		}
 
-		while ( frustums.length < cameras.length ) {
+		while ( cameraInfo.length < cameras.length ) {
 
-			frustums.push( new Frustum() );
+			cameraInfo.push( {
+
+				frustum: new Frustum(),
+				sseDenominator: - 1,
+				position: new Vector3(),
+				invScale: - 1,
+
+			} );
+
+		}
+
+		tempMat2.getInverse( group.matrixWorld );
+
+		let invScale;
+		tempVector.setFromMatrixScale( tempMat2 );
+		invScale = tempVector.x;
+
+		if ( Math.abs( Math.max( tempVector.x - tempVector.y, tempVector.x - tempVector.z ) ) > 1e-6 ) {
+
+			console.warn( 'ThreeTilesRenderer : Non uniform scale used for tile which may cause issues when calculating screen space error.' );
 
 		}
 
-		// store the camera frustums in the 3d tiles root frame
-		for ( let i = 0, l = frustums.length; i < l; i ++ ) {
+		// store the camera cameraInfo in the 3d tiles root frame
+		for ( let i = 0, l = cameraInfo.length; i < l; i ++ ) {
 
 			const camera = cameras[ i ];
-			const frustum = frustums[ i ];
+			const info = cameraInfo[ i ];
+			const frustum = info.frustum;
+			const position = info.position;
+
+			if ( camera.isPerspectiveCamera ) {
+
+				info.sseDenominator = 2 * Math.tan( 0.5 * camera.fov * DEG2RAD ) / resolution.height;
+
+			}
+
+			info.invScale = invScale;
 
 			tempMat.copy( group.matrixWorld );
 			tempMat.premultiply( camera.matrixWorldInverse );
 			tempMat.premultiply( camera.projectionMatrix );
 			frustum.setFromProjectionMatrix( tempMat );
 
+			position.set( 0, 0, 0 );
+			position.applyMatrix4( camera.matrixWorld );
+			position.applyMatrix4( tempMat2 );
+
 		}
 
 		super.update();
@@ -191,11 +222,13 @@ export class TilesRenderer extends TilesRendererBase {
 
 		let box = null;
 		let boxTransform = null;
+		let boxTransformInverse = null;
 		if ( 'box' in tile.boundingVolume ) {
 
 			const data = tile.boundingVolume.box;
 			box = new Box3();
 			boxTransform = new Matrix4();
+			boxTransformInverse = new Matrix4();
 
 			// get the extents of the bounds in each axis
 			vecX.set( data[ 3 ], data[ 4 ], data[ 5 ] );
@@ -218,6 +251,7 @@ export class TilesRenderer extends TilesRendererBase {
 				0, 0, 0, 1
 			);
 			boxTransform.premultiply( transform );
+			boxTransformInverse.getInverse( boxTransform );
 
 			// scale the box by the extents
 			box.min.set( - scaleX, - scaleY, - scaleZ );
@@ -236,9 +270,11 @@ export class TilesRenderer extends TilesRendererBase {
 
 		} else if ( 'box' in tile.boundingVolume ) {
 
+			const data = tile.boundingVolume.box;
 			sphere = new Sphere();
 			box.getBoundingSphere( sphere );
-			sphere.applyMatrix4( boxTransform );
+			sphere.center.set( data[ 0 ], data[ 1 ], data[ 2 ] );
+			sphere.applyMatrix4( transform );
 
 		}
 
@@ -257,6 +293,7 @@ export class TilesRenderer extends TilesRendererBase {
 
 			box,
 			boxTransform,
+			boxTransformInverse,
 			sphere,
 			region,
 
@@ -275,7 +312,6 @@ export class TilesRenderer extends TilesRendererBase {
 		tile._loadIndex ++;
 
 		const loadIndex = tile._loadIndex;
-
 		const manager = new LoadingManager();
 
 		if ( typeof createImageBitmap !== 'undefined' ) {
@@ -455,51 +491,35 @@ export class TilesRenderer extends TilesRendererBase {
 
 		const cached = tile.cached;
 		const cameras = this.cameras;
+		const cameraInfo = this.cameraInfo;
 
 		// TODO: Use the content bounding volume here?
 		const boundingVolume = tile.boundingVolume;
-		const transformMat = cached.transform;
 		const resolution = this.resolution;
 
 		if ( 'box' in boundingVolume ) {
 
-			const group = this.group;
 			const boundingBox = cached.box;
-			const obbMat = cached.boxTransform;
-
-			// TODO: these can likely be cached? Or the world transform mat can be used
-			// transformMat can be rolled into oobMat
-			tempMat.copy( group.matrixWorld );
-			tempMat.multiply( obbMat );
-			tempMat.getInverse( tempMat );
-
-			// NOTE: scale is inverted here.
-			// assume the scales on all axes are uniform.
-			let invScale;
-
-			// account for tile scale.
-			tempVector.setFromMatrixScale( tempMat );
-			invScale = tempVector.x;
-
-			if ( Math.abs( Math.max( tempVector.x - tempVector.y, tempVector.x - tempVector.z ) ) > 1e-6 ) {
-
-				console.warn( 'ThreeTilesRenderer : Non uniform scale used for tile which may cause issues when calculating screen space error.' );
-
-			}
+			const boxTransformInverse = cached.boxTransformInverse;
 
 			let minError = Infinity;
 			for ( let i = 0, l = cameras.length; i < l; i ++ ) {
 
+				// TODO: move this logic (and the distance scale extraction) into the update preprocess step
+
 				// transform camera position into local frame of the tile bounding box
-				const cam = cameras[ i ];
-				tempVector.copy( cam.position );
-				tempVector.applyMatrix4( tempMat );
+				// TODO: this should be the cameras world position
+				const camera = cameras[ i ];
+				const info = cameraInfo[ i ];
+				const invScale = info.invScale;
+				tempVector.copy( info.position );
+				tempVector.applyMatrix4( boxTransformInverse );
 
 				let error;
-				if ( cam.isOrthographicCamera ) {
+				if ( camera.isOrthographicCamera ) {
 
-					const w = cam.right - cam.left;
-					const h = cam.top - cam.bottom;
+					const w = camera.right - camera.left;
+					const h = camera.top - camera.bottom;
 					const pixelSize = Math.max( h / resolution.height, w / resolution.width );
 					error = tile.geometricError / ( pixelSize * invScale );
 
@@ -507,8 +527,8 @@ export class TilesRenderer extends TilesRendererBase {
 
 					const distance = boundingBox.distanceToPoint( tempVector );
 					const scaledDistance = distance * invScale;
-					const sseDenominator = 2 * Math.tan( 0.5 * cam.fov * DEG2RAD );
-					error = ( tile.geometricError * resolution.height ) / ( scaledDistance * sseDenominator );
+					const sseDenominator = info.sseDenominator;
+					error = tile.geometricError / ( scaledDistance * sseDenominator );
 
 					tile.cached.distance = scaledDistance;
 
@@ -546,10 +566,10 @@ export class TilesRenderer extends TilesRendererBase {
 		const sphere = tile.cached.sphere;
 		if ( sphere ) {
 
-			const frustums = this.frustums;
-			for ( let i = 0, l = frustums.length; i < l; i ++ ) {
+			const cameraInfo = this.cameraInfo;
+			for ( let i = 0, l = cameraInfo.length; i < l; i ++ ) {
 
-				const frustum = frustums[ i ];
+				const frustum = cameraInfo[ i ].frustum;
 				if ( frustum.intersectsSphere( sphere ) ) {
 
 					return true;