Parcourir la source

Add debug renderer

Garrett Johnson il y a 5 ans
Parent
commit
845ccaa91a
4 fichiers modifiés avec 205 ajouts et 57 suppressions
  1. 1 1
      example/index.js
  2. 2 0
      src/index.js
  3. 197 0
      src/three/DebugTilesRenderer.js
  4. 5 56
      src/three/TilesRenderer.js

+ 1 - 1
example/index.js

@@ -1,4 +1,4 @@
-import { TilesRenderer } from '../src/index.js';
+import { DebugTilesRenderer as TilesRenderer } from '../src/index.js';
 import {
 	Scene,
 	DirectionalLight,

+ 2 - 0
src/index.js

@@ -1,3 +1,4 @@
+import { DebugTilesRenderer } from './three/DebugTilesRenderer.js';
 import { TilesRenderer } from './three/TilesRenderer.js';
 import { B3DMLoader } from './three/B3DMLoader.js';
 
@@ -8,6 +9,7 @@ import { LRUCache } from './utilities/LRUCache.js';
 import { PriorityQueue } from './utilities/PriorityQueue.js';
 
 export {
+	DebugTilesRenderer,
 	TilesRenderer,
 	B3DMLoader,
 

+ 197 - 0
src/three/DebugTilesRenderer.js

@@ -0,0 +1,197 @@
+import { Box3Helper, Group, MeshBasicMaterial } from 'three';
+import { TilesRenderer } from './TilesRenderer.js';
+
+const ORIGINAL_MATERIAL = Symbol( 'ORIGINAL_MATERIAL' );
+
+const NONE = 0;
+const SCREEN_ERROR = 1;
+const GEOMETRIC_ERROR = 2;
+const DISTANCE = 3;
+const DEPTH = 4;
+export class DebugTilesRenderer extends TilesRenderer {
+
+	constructor( ...args ) {
+
+		super( ...args );
+
+		const tilesGroup = this.group;
+		const boxGroup = new Group();
+		tilesGroup.add( boxGroup );
+
+		this.displayBounds = false;
+		this.colorMode = NONE;
+		this.boxGroup = boxGroup;
+
+	}
+
+	update() {
+
+		super.update();
+
+		this.boxGroup.visible = this.displayBounds;
+
+		let maxDepth = - 1;
+		this.traverse( tile => {
+
+			maxDepth = Math.max( maxDepth, tile.__depth );
+
+		} );
+
+		const errorTarget = this.errorTarget;
+		const colorMode = this.colorMode;
+		const visibleSet = this.visibleSet;
+		this.traverse( tile => {
+
+			const scene = tile.cached.scene;
+			if ( visibleSet.has( scene ) ) {
+
+				scene.traverse( c => {
+
+					const currMaterial = c.material;
+					if ( currMaterial ) {
+
+						const originalMaterial = c[ ORIGINAL_MATERIAL ];
+						if ( colorMode === NONE && currMaterial !== originalMaterial ) {
+
+							c.material.dispose();
+							c.material = c[ ORIGINAL_MATERIAL ];
+
+						} else if ( colorMode !== NONE && currMaterial === originalMaterial ) {
+
+							c.material = new MeshBasicMaterial();
+
+						}
+
+						switch ( colorMode ) {
+
+							case DEPTH: {
+
+								const val = tile.__depth / maxDepth;
+								c.material.color.setRGB( val, val, val );
+								break;
+
+							}
+							case SCREEN_ERROR: {
+
+								// TODO
+								const relativeError = tile.__error - errorTarget;
+								const val = relativeError / 5;
+								if ( val < 0.0 ) {
+
+									c.material.color.setRGB( 1.0, 0.0, 0.0 );
+
+								} else {
+
+									c.material.color.setRGB( val, val, val );
+
+								}
+								break;
+
+							}
+							case GEOMETRIC_ERROR: {
+
+								const val = Math.min( tile.geometricError / 7, 1 );
+								c.material.color.setRGB( val, val, val );
+								break;
+
+							}
+							case DISTANCE: {
+
+								// TODO
+								const val = Math.min( tile.geometricError / 7, 1 );
+								c.material.color.setRGB( val, val, val );
+								break;
+
+							}
+
+
+
+						}
+
+					}
+
+				} );
+
+			}
+
+		} );
+
+	}
+
+	setTileVisible( tile, visible ) {
+
+		super.setTileVisible( tile, visible );
+
+		const boxGroup = this.boxGroup;
+		const cached = tile.cached;
+		const boxHelperGroup = cached.boxHelperGroup;
+
+		if ( ! visible && boxHelperGroup.parent ) {
+
+			boxGroup.remove( boxHelperGroup );
+
+		} else if ( visible && ! boxHelperGroup.parent ) {
+
+			boxGroup.add( boxHelperGroup );
+			boxHelperGroup.updateMatrixWorld( true );
+
+		}
+
+	}
+
+	parseTile( buffer, tile ) {
+
+		return super
+			.parseTile( buffer, tile )
+			.then( () => {
+
+				const cached = tile.cached;
+				const scene = cached.scene;
+				if ( scene ) {
+
+					const cachedBox = cached.box;
+					const cachedBoxMat = cached.boxTransform;
+					const cachedTransform = cached.transform;
+
+					const boxHelperGroup = new Group();
+					boxHelperGroup.matrix.copy( cachedBoxMat );
+					boxHelperGroup.matrix.multiply( cachedTransform );
+					boxHelperGroup.matrix.decompose( boxHelperGroup.position, boxHelperGroup.quaternion, boxHelperGroup.scale );
+
+					const boxHelper = new Box3Helper( cachedBox );
+					boxHelperGroup.add( boxHelper );
+					boxHelperGroup.updateMatrixWorld( true );
+
+					cached.boxHelperGroup = boxHelperGroup;
+
+					if ( this.displayBounds ) {
+
+						this.boxGroup.add( boxHelperGroup );
+
+					}
+
+					scene.traverse( c => {
+
+						const material = c.material;
+						if ( material ) {
+
+							c[ ORIGINAL_MATERIAL ] = material;
+
+						}
+
+					} );
+
+				}
+
+			} );
+
+	}
+
+	disposeTile( tile ) {
+
+		super.disposeTile( tile );
+		delete tile.cached.boxBounds;
+
+	}
+
+}

+ 5 - 56
src/three/TilesRenderer.js

@@ -42,42 +42,6 @@ export class TilesRenderer extends TilesRendererBase {
 
 	}
 
-	get displayBounds() {
-
-		return this._displayBounds;
-
-	}
-
-	set displayBounds( val ) {
-
-		if ( val !== this.displayBounds ) {
-
-			this._displayBounds = val;
-			this.traverse( t => {
-
-				const scene = t.cached.scene;
-				const boxHelper = t.cached.boxHelperGroup;
-				if ( scene ) {
-
-					if ( val ) {
-
-						scene.add( boxHelper );
-						boxHelper.updateMatrixWorld( true );
-
-					} else {
-
-						scene.remove( boxHelper );
-
-					}
-
-				}
-
-			} );
-
-		}
-
-	}
-
 	constructor( ...args ) {
 
 		super( ...args );
@@ -292,8 +256,9 @@ export class TilesRenderer extends TilesRendererBase {
 			sphere,
 			region,
 
-			boxHelper: null,
 			scene: null,
+			geometry: null,
+			material: null,
 
 		};
 
@@ -315,31 +280,15 @@ export class TilesRenderer extends TilesRendererBase {
 			}
 
 			const cached = tile.cached;
-			const cachedBox = cached.box;
-			const cachedBoxMat = cached.boxTransform;
-
-			// add a helper group to represent the obb rotation matrix
-			const boxHelper = new Box3Helper( cachedBox );
-			const boxHelperGroup = new Group();
-			cachedBoxMat.decompose( boxHelperGroup.position, boxHelperGroup.quaternion, boxHelperGroup.scale );
-			boxHelperGroup.add( boxHelper );
-			boxHelperGroup.updateMatrixWorld( true );
+			const cachedTransform = cached.transform;
 
 			const scene = res.scene;
-			cached.transform.decompose( scene.position, scene.quaternion, scene.scale );
+			cachedTransform.decompose( scene.position, scene.quaternion, scene.scale );
 			scene.traverse( c => c.frustumCulled = false );
 
-			cached.boxHelperGroup = boxHelperGroup;
 			cached.scene = scene;
 
-			if ( this.displayBounds ) {
-
-				scene.add( cached.boxHelperGroup );
-
-			}
-
 			// We handle raycasting in a custom way so remove it from here
-			boxHelper.raycast = emptyRaycast;
 			scene.traverse( c => {
 
 				c.raycast = emptyRaycast;
@@ -411,7 +360,6 @@ export class TilesRenderer extends TilesRendererBase {
 			cached.scene = null;
 			cached.materials = null;
 			cached.geometry = null;
-			cached.boxHelperGroup = null;
 
 		}
 
@@ -421,6 +369,7 @@ export class TilesRenderer extends TilesRendererBase {
 
 	setTileVisible( tile, visible ) {
 
+		// TODO: save the whole tile object in the visible set and active set
 		const scene = tile.cached.scene;
 		const visibleSet = this.visibleSet;
 		const group = this.group;