Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions src/core/renderer/tiles/TilesRendererBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { throttle } from '../utilities/throttle.js';
import { traverseSet } from '../utilities/TraversalUtils.js';

const PLUGIN_REGISTERED = Symbol( 'PLUGIN_REGISTERED' );
const regionErrorTarget = {
inView: true,
error: 0,
distance: Infinity,
};

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

}

calculateTileViewErrorWithPlugin( tile, target ) {

// calculate camera view error
this.calculateTileViewError( tile, target );

// TODO: this logic is extremely complex. It may be more simple to have the plugin
// return a "should mask" field that indicates its "false" values should be respected
// rather than the function returning a "no-op" boolean.
// check the plugin visibility - each plugin will mask between themselves
let inRegion = null;
let inRegionError = 0;
let inRegionDistance = Infinity;
this.invokeAllPlugins( plugin => {

if ( plugin !== this && plugin.calculateTileViewError ) {

// if function returns false it means "no operation"
regionErrorTarget.inView = true;
regionErrorTarget.error = 0;
regionErrorTarget.distance = Infinity;
if ( plugin.calculateTileViewError( tile, regionErrorTarget ) ) {

if ( inRegion === null ) {

inRegion = true;

}

// Plugins can set "inView" to false in order to mask the visible tiles
inRegion = inRegion && regionErrorTarget.inView;
if ( regionErrorTarget.inView ) {

inRegionDistance = Math.min( inRegionDistance, regionErrorTarget.distance );
inRegionError = Math.max( inRegionError, regionErrorTarget.error );

}

}

}

} );

if ( target.inView && inRegion !== false ) {

// if the tile is in camera view and we haven't encountered a region (null) or
// the region is in view (true). regionInView === false means the tile is masked out.
target.error = Math.max( target.error, inRegionError );
target.distanceFromCamera = Math.min( target.distanceFromCamera, inRegionDistance );

} else if ( inRegion ) {

// if the tile is in a region then display it
target.inView = true;
target.error = inRegionError;
target.distanceFromCamera = inRegionDistance;

} else {

// otherwise write variables for load priority
target.inView = false;

}

}

dispose() {

// dispose of all the plugins
Expand Down Expand Up @@ -680,6 +751,17 @@ export class TilesRendererBase {

}

const { scene } = tile.engineData;
if ( scene ) {

this.dispatchEvent( {
type: 'dispose-model',
scene,
tile,
} );

}

}

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

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

this.dispatchEvent( {
type: 'tile-visibility-change',
scene: tile.engineData.scene,
tile,
visible,
} );


}

calculateTileViewError( tile, target ) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/renderer/tiles/optimizedTraverseFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function resetFrameState( tile, renderer ) {
tile.traversal.allUsedChildrenProcessed = false;

// update tile frustum and error state
renderer.calculateTileViewError( tile, viewErrorTarget );
renderer.calculateTileViewErrorWithPlugin( tile, viewErrorTarget );
tile.traversal.inFrustum = viewErrorTarget.inView;
tile.traversal.error = viewErrorTarget.error;
tile.traversal.distanceFromCamera = viewErrorTarget.distanceFromCamera;
Expand Down
2 changes: 1 addition & 1 deletion src/core/renderer/tiles/traverseFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function resetFrameState( tile, renderer ) {
tile.traversal.allChildrenReady = false;

// update tile frustum and error state
renderer.calculateTileViewError( tile, viewErrorTarget );
renderer.calculateTileViewErrorWithPlugin( tile, viewErrorTarget );
tile.traversal.inFrustum = viewErrorTarget.inView;
tile.traversal.error = viewErrorTarget.error;
tile.traversal.distanceFromCamera = viewErrorTarget.distanceFromCamera;
Expand Down
80 changes: 1 addition & 79 deletions src/three/renderer/tiles/TilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ const INITIAL_FRUSTUM_CULLED = Symbol( 'INITIAL_FRUSTUM_CULLED' );
const tempMat = /* @__PURE__ */ new Matrix4();
const tempVector = /* @__PURE__ */ new Vector3();
const tempVector2 = /* @__PURE__ */ new Vector2();
const viewErrorTarget = {
inView: true,
error: 0,
distance: Infinity,
};

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

disposeTile( tile ) {

// TODO: call this "disposeTileModel"?
super.disposeTile( tile );

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

}

this.dispatchEvent( {
type: 'dispose-model',
scene: engineData.scene,
tile,
} );

engineData.scene = null;
engineData.materials = null;
engineData.textures = null;
Expand Down Expand Up @@ -888,13 +878,6 @@ export class TilesRenderer extends TilesRendererBase {

super.setTileVisible( tile, visible );

this.dispatchEvent( {
type: 'tile-visibility-change',
scene,
tile,
visible,
} );

}

calculateBytesUsed( tile, scene ) {
Expand Down Expand Up @@ -977,67 +960,6 @@ export class TilesRenderer extends TilesRendererBase {

}

//

// TODO: this logic is extremely complex. It may be more simple to have the plugin
// return a "should mask" field that indicates its "false" values should be respected
// rather than the function returning a "no-op" boolean.
// check the plugin visibility - each plugin will mask between themselves
let inRegion = null;
let inRegionError = 0;
let inRegionDistance = Infinity;
this.invokeAllPlugins( plugin => {

if ( plugin !== this && plugin.calculateTileViewError ) {

// if function returns false it means "no operation"
viewErrorTarget.inView = true;
viewErrorTarget.error = 0;
viewErrorTarget.distance = Infinity;
if ( plugin.calculateTileViewError( tile, viewErrorTarget ) ) {

if ( inRegion === null ) {

inRegion = true;

}

// Plugins can set "inView" to false in order to mask the visible tiles
inRegion = inRegion && viewErrorTarget.inView;
if ( viewErrorTarget.inView ) {

inRegionDistance = Math.min( inRegionDistance, viewErrorTarget.distance );
inRegionError = Math.max( inRegionError, viewErrorTarget.error );

}

}

}

} );

if ( target.inView && inRegion !== false ) {

// if the tile is in camera view and we haven't encountered a region (null) or
// the region is in view (true). regionInView === false means the tile is masked out.
target.error = Math.max( target.error, inRegionError );
target.distanceFromCamera = Math.min( target.distanceFromCamera, inRegionDistance );

} else if ( inRegion ) {

// if the tile is in a region then display it
target.inView = true;
target.error = inRegionError;
target.distanceFromCamera = inRegionDistance;

} else {

// otherwise write variables for load priority
target.inView = false;

}

}

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