Skip to content

Commit 650b129

Browse files
authored
Move "calculateTileViewError" plugin call to core (#1460)
* Move plugin call to core * Move events
1 parent 7bce6c6 commit 650b129

4 files changed

Lines changed: 93 additions & 81 deletions

File tree

src/core/renderer/tiles/TilesRendererBase.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import { throttle } from '../utilities/throttle.js';
88
import { traverseSet } from '../utilities/TraversalUtils.js';
99

1010
const PLUGIN_REGISTERED = Symbol( 'PLUGIN_REGISTERED' );
11+
const regionErrorTarget = {
12+
inView: true,
13+
error: 0,
14+
distance: Infinity,
15+
};
1116

1217
// priority queue sort function that takes two tiles to compare. Returning 1 means
1318
// "tile a" is loaded first.
@@ -599,6 +604,72 @@ export class TilesRendererBase {
599604

600605
}
601606

607+
calculateTileViewErrorWithPlugin( tile, target ) {
608+
609+
// calculate camera view error
610+
this.calculateTileViewError( tile, target );
611+
612+
// TODO: this logic is extremely complex. It may be more simple to have the plugin
613+
// return a "should mask" field that indicates its "false" values should be respected
614+
// rather than the function returning a "no-op" boolean.
615+
// check the plugin visibility - each plugin will mask between themselves
616+
let inRegion = null;
617+
let inRegionError = 0;
618+
let inRegionDistance = Infinity;
619+
this.invokeAllPlugins( plugin => {
620+
621+
if ( plugin !== this && plugin.calculateTileViewError ) {
622+
623+
// if function returns false it means "no operation"
624+
regionErrorTarget.inView = true;
625+
regionErrorTarget.error = 0;
626+
regionErrorTarget.distance = Infinity;
627+
if ( plugin.calculateTileViewError( tile, regionErrorTarget ) ) {
628+
629+
if ( inRegion === null ) {
630+
631+
inRegion = true;
632+
633+
}
634+
635+
// Plugins can set "inView" to false in order to mask the visible tiles
636+
inRegion = inRegion && regionErrorTarget.inView;
637+
if ( regionErrorTarget.inView ) {
638+
639+
inRegionDistance = Math.min( inRegionDistance, regionErrorTarget.distance );
640+
inRegionError = Math.max( inRegionError, regionErrorTarget.error );
641+
642+
}
643+
644+
}
645+
646+
}
647+
648+
} );
649+
650+
if ( target.inView && inRegion !== false ) {
651+
652+
// if the tile is in camera view and we haven't encountered a region (null) or
653+
// the region is in view (true). regionInView === false means the tile is masked out.
654+
target.error = Math.max( target.error, inRegionError );
655+
target.distanceFromCamera = Math.min( target.distanceFromCamera, inRegionDistance );
656+
657+
} else if ( inRegion ) {
658+
659+
// if the tile is in a region then display it
660+
target.inView = true;
661+
target.error = inRegionError;
662+
target.distanceFromCamera = inRegionDistance;
663+
664+
} else {
665+
666+
// otherwise write variables for load priority
667+
target.inView = false;
668+
669+
}
670+
671+
}
672+
602673
dispose() {
603674

604675
// dispose of all the plugins
@@ -680,6 +751,17 @@ export class TilesRendererBase {
680751

681752
}
682753

754+
const { scene } = tile.engineData;
755+
if ( scene ) {
756+
757+
this.dispatchEvent( {
758+
type: 'dispose-model',
759+
scene,
760+
tile,
761+
} );
762+
763+
}
764+
683765
}
684766

685767
preprocessNode( tile, tilesetDir, parentTile = null ) {
@@ -824,6 +906,14 @@ export class TilesRendererBase {
824906

825907
visible ? this.visibleTiles.add( tile ) : this.visibleTiles.delete( tile );
826908

909+
this.dispatchEvent( {
910+
type: 'tile-visibility-change',
911+
scene: tile.engineData.scene,
912+
tile,
913+
visible,
914+
} );
915+
916+
827917
}
828918

829919
calculateTileViewError( tile, target ) {

src/core/renderer/tiles/optimizedTraverseFunctions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function resetFrameState( tile, renderer ) {
5959
tile.traversal.allUsedChildrenProcessed = false;
6060

6161
// update tile frustum and error state
62-
renderer.calculateTileViewError( tile, viewErrorTarget );
62+
renderer.calculateTileViewErrorWithPlugin( tile, viewErrorTarget );
6363
tile.traversal.inFrustum = viewErrorTarget.inView;
6464
tile.traversal.error = viewErrorTarget.error;
6565
tile.traversal.distanceFromCamera = viewErrorTarget.distanceFromCamera;

src/core/renderer/tiles/traverseFunctions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function resetFrameState( tile, renderer ) {
5959
tile.traversal.allChildrenReady = false;
6060

6161
// update tile frustum and error state
62-
renderer.calculateTileViewError( tile, viewErrorTarget );
62+
renderer.calculateTileViewErrorWithPlugin( tile, viewErrorTarget );
6363
tile.traversal.inFrustum = viewErrorTarget.inView;
6464
tile.traversal.error = viewErrorTarget.error;
6565
tile.traversal.distanceFromCamera = viewErrorTarget.distanceFromCamera;

src/three/renderer/tiles/TilesRenderer.js

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ const INITIAL_FRUSTUM_CULLED = Symbol( 'INITIAL_FRUSTUM_CULLED' );
2828
const tempMat = /* @__PURE__ */ new Matrix4();
2929
const tempVector = /* @__PURE__ */ new Vector3();
3030
const tempVector2 = /* @__PURE__ */ new Vector2();
31-
const viewErrorTarget = {
32-
inView: true,
33-
error: 0,
34-
distance: Infinity,
35-
};
3631

3732
const X_AXIS = /* @__PURE__ */ new Vector3( 1, 0, 0 );
3833
const Y_AXIS = /* @__PURE__ */ new Vector3( 0, 1, 0 );
@@ -784,6 +779,7 @@ export class TilesRenderer extends TilesRendererBase {
784779

785780
disposeTile( tile ) {
786781

782+
// TODO: call this "disposeTileModel"?
787783
super.disposeTile( tile );
788784

789785
// This could get called before the tile has finished downloading
@@ -846,12 +842,6 @@ export class TilesRenderer extends TilesRendererBase {
846842

847843
}
848844

849-
this.dispatchEvent( {
850-
type: 'dispose-model',
851-
scene: engineData.scene,
852-
tile,
853-
} );
854-
855845
engineData.scene = null;
856846
engineData.materials = null;
857847
engineData.textures = null;
@@ -888,13 +878,6 @@ export class TilesRenderer extends TilesRendererBase {
888878

889879
super.setTileVisible( tile, visible );
890880

891-
this.dispatchEvent( {
892-
type: 'tile-visibility-change',
893-
scene,
894-
tile,
895-
visible,
896-
} );
897-
898881
}
899882

900883
calculateBytesUsed( tile, scene ) {
@@ -977,67 +960,6 @@ export class TilesRenderer extends TilesRendererBase {
977960

978961
}
979962

980-
//
981-
982-
// TODO: this logic is extremely complex. It may be more simple to have the plugin
983-
// return a "should mask" field that indicates its "false" values should be respected
984-
// rather than the function returning a "no-op" boolean.
985-
// check the plugin visibility - each plugin will mask between themselves
986-
let inRegion = null;
987-
let inRegionError = 0;
988-
let inRegionDistance = Infinity;
989-
this.invokeAllPlugins( plugin => {
990-
991-
if ( plugin !== this && plugin.calculateTileViewError ) {
992-
993-
// if function returns false it means "no operation"
994-
viewErrorTarget.inView = true;
995-
viewErrorTarget.error = 0;
996-
viewErrorTarget.distance = Infinity;
997-
if ( plugin.calculateTileViewError( tile, viewErrorTarget ) ) {
998-
999-
if ( inRegion === null ) {
1000-
1001-
inRegion = true;
1002-
1003-
}
1004-
1005-
// Plugins can set "inView" to false in order to mask the visible tiles
1006-
inRegion = inRegion && viewErrorTarget.inView;
1007-
if ( viewErrorTarget.inView ) {
1008-
1009-
inRegionDistance = Math.min( inRegionDistance, viewErrorTarget.distance );
1010-
inRegionError = Math.max( inRegionError, viewErrorTarget.error );
1011-
1012-
}
1013-
1014-
}
1015-
1016-
}
1017-
1018-
} );
1019-
1020-
if ( target.inView && inRegion !== false ) {
1021-
1022-
// if the tile is in camera view and we haven't encountered a region (null) or
1023-
// the region is in view (true). regionInView === false means the tile is masked out.
1024-
target.error = Math.max( target.error, inRegionError );
1025-
target.distanceFromCamera = Math.min( target.distanceFromCamera, inRegionDistance );
1026-
1027-
} else if ( inRegion ) {
1028-
1029-
// if the tile is in a region then display it
1030-
target.inView = true;
1031-
target.error = inRegionError;
1032-
target.distanceFromCamera = inRegionDistance;
1033-
1034-
} else {
1035-
1036-
// otherwise write variables for load priority
1037-
target.inView = false;
1038-
1039-
}
1040-
1041963
}
1042964

1043965
// adjust the rotation of the group such that Y is altitude, X is North, and Z is East

0 commit comments

Comments
 (0)