123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- import { Box3Helper, Group, MeshBasicMaterial } from 'three';
- import { TilesRenderer } from './TilesRenderer.js';
- import { SphereHelper } from './SphereHelper.js';
- const ORIGINAL_MATERIAL = Symbol( 'ORIGINAL_MATERIAL' );
- function emptyRaycast() {}
- export const NONE = 0;
- export const SCREEN_ERROR = 1;
- export const GEOMETRIC_ERROR = 2;
- export const DISTANCE = 3;
- export const DEPTH = 4;
- export const RELATIVE_DEPTH = 5;
- export const IS_LEAF = 6;
- export const RANDOM_COLOR = 7;
- export class DebugTilesRenderer extends TilesRenderer {
- constructor( ...args ) {
- super( ...args );
- const tilesGroup = this.group;
- const boxGroup = new Group();
- tilesGroup.add( boxGroup );
- const sphereGroup = new Group();
- tilesGroup.add( sphereGroup );
- this.displayBoxBounds = false;
- this.displaySphereBounds = false;
- this.colorMode = NONE;
- this.boxGroup = boxGroup;
- this.sphereGroup = sphereGroup;
- this.maxDepth = - 1;
- this.maxDistance = - 1;
- this.maxError = - 1;
- this.extremeDepth = - 1;
- this.extremeError = - 1;
- }
- initExtremes() {
- let maxDepth = - 1;
- this.traverse( tile => {
- maxDepth = Math.max( maxDepth, tile.__depth );
- } );
- let maxError = - 1;
- this.traverse( tile => {
- maxError = Math.max( maxError, tile.geometricError );
- } );
- this.extremeDepth = maxDepth;
- this.extremeError = maxError;
- }
- loadTileSet( ...args ) {
- const pr = super.loadTileSet( ...args );
- pr.then( () => this.initExtremes() );
- return pr;
- }
- getTileInformationFromActiveObject( object ) {
- let targetTile = null;
- const activeTiles = this.activeTiles;
- activeTiles.forEach( tile => {
- if ( targetTile ) {
- return true;
- }
- const scene = tile.cached.scene;
- if ( scene ) {
- scene.traverse( c => {
- if ( c === object ) {
- targetTile = tile;
- }
- } );
- }
- } );
- if ( targetTile ) {
- return {
- distanceToCamera: targetTile.cached.distance,
- geometricError: targetTile.geometricError,
- screenSpaceError: targetTile.__error,
- depth: targetTile.__depth,
- isLeaf: targetTile.__isLeaf
- };
- } else {
- return null;
- }
- }
- update() {
- super.update();
- if ( ! this.root ) {
- return;
- }
- this.boxGroup.visible = this.displayBoxBounds;
- this.sphereGroup.visible = this.displaySphereBounds;
- let maxDepth = - 1;
- if ( this.maxDepth === - 1 ) {
- maxDepth = this.extremeDepth;
- } else {
- maxDepth = this.maxDepth;
- }
- let maxError = - 1;
- if ( this.maxError === - 1 ) {
- maxError = this.extremeError;
- } else {
- maxError = this.maxError;
- }
- let maxDistance = - 1;
- if ( this.maxDistance === - 1 ) {
- maxDistance = this.root.cached.sphere.radius;
- } else {
- maxDistance = this.maxDistance;
- }
- // TODO: Support i3dm, pnts, cmpt here
- const errorTarget = this.errorTarget;
- const colorMode = this.colorMode;
- const visibleTiles = this.visibleTiles;
- visibleTiles.forEach( tile => {
- const scene = tile.cached.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();
- }
- if ( colorMode !== RANDOM_COLOR ) {
- delete c.material.__randomColor;
- }
- switch ( colorMode ) {
- case DEPTH: {
- const val = tile.__depth / maxDepth;
- c.material.color.setRGB( val, val, val );
- break;
- }
- case RELATIVE_DEPTH: {
- const val = tile.__depthFromRenderedParent / maxDepth;
- c.material.color.setRGB( val, val, val );
- break;
- }
- case SCREEN_ERROR: {
- const val = tile.__error / errorTarget;
- if ( val > 1.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 / maxError, 1 );
- c.material.color.setRGB( val, val, val );
- break;
- }
- case DISTANCE: {
- // We don't update the distance if the geometric error is 0.0 so
- // it will always be black.
- const val = Math.min( tile.cached.distance / maxDistance, 1 );
- c.material.color.setRGB( val, val, val );
- break;
- }
- case IS_LEAF: {
- if ( ! tile.children || tile.children.length === 0 ) {
- c.material.color.set( 0xffffff );
- } else {
- c.material.color.set( 0 );
- }
- break;
- }
- case RANDOM_COLOR: {
- if ( ! c.material.__randomColor ) {
- const h = Math.random();
- const s = 0.5 + Math.random() * 0.5;
- const l = 0.375 + Math.random() * 0.25;
- c.material.color.setHSL( h, s, l );
- c.material.__randomColor = true;
- }
- break;
- }
- }
- }
- } );
- } );
- }
- setTileVisible( tile, visible ) {
- super.setTileVisible( tile, visible );
- const cached = tile.cached;
- const sphereGroup = this.sphereGroup;
- const boxGroup = this.boxGroup;
- const boxHelperGroup = cached.boxHelperGroup;
- const sphereHelper = cached.sphereHelper;
- if ( ! visible ) {
- boxGroup.remove( boxHelperGroup );
- sphereGroup.remove( sphereHelper );
- } else {
- boxGroup.add( boxHelperGroup );
- boxHelperGroup.updateMatrixWorld( true );
- sphereGroup.add( sphereHelper );
- sphereHelper.updateMatrixWorld( true );
- }
- }
- parseTile( buffer, tile, extension ) {
- return super
- .parseTile( buffer, tile, extension )
- .then( () => {
- const cached = tile.cached;
- const scene = cached.scene;
- if ( scene ) {
- const cachedBox = cached.box;
- const cachedBoxMat = cached.boxTransform;
- const boxHelperGroup = new Group();
- boxHelperGroup.matrix.copy( cachedBoxMat );
- boxHelperGroup.matrix.decompose( boxHelperGroup.position, boxHelperGroup.quaternion, boxHelperGroup.scale );
- const boxHelper = new Box3Helper( cachedBox );
- boxHelper.raycast = emptyRaycast;
- boxHelperGroup.add( boxHelper );
- cached.boxHelperGroup = boxHelperGroup;
- if ( this.visibleTiles.has( tile ) && this.displayBoxBounds ) {
- this.boxGroup.add( boxHelperGroup );
- boxHelperGroup.updateMatrixWorld( true );
- }
- const cachedSphere = cached.sphere;
- const sphereHelper = new SphereHelper( cachedSphere );
- sphereHelper.raycast = emptyRaycast;
- cached.sphereHelper = sphereHelper;
- if ( this.visibleTiles.has( tile ) && this.displaySphereBounds ) {
- this.sphereGroup.add( sphereHelper );
- sphereHelper.updateMatrixWorld( true );
- }
- scene.traverse( c => {
- const material = c.material;
- if ( material ) {
- c[ ORIGINAL_MATERIAL ] = material;
- }
- } );
- }
- } );
- }
- disposeTile( tile ) {
- super.disposeTile( tile );
- const cached = tile.cached;
- if ( cached.boxHelperGroup ) {
- cached.boxHelperGroup.children[ 0 ].geometry.dispose();
- cached.sphereHelper.geometry.dispose();
- delete cached.boxHelperGroup;
- delete cached.sphereHelper;
- }
- }
- }
|