Skip to content

Commit

Permalink
TilesRenderer: Add event dispatcher support (#446)
Browse files Browse the repository at this point in the history
* Add event dispatcher for events

* Adjust google tiles renderer

* Update fade manager

* documentation update

* Fixes
  • Loading branch information
gkjohnson authored Jan 12, 2024
1 parent 75a0426 commit 9c86ef7
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 23 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,23 @@ if ( intersects.length ) {

## TilesRenderer

_extends [TilesRendererBase](https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/src/base/TilesRendererBase.js), which can be used to implement a 3d tiles renderer in other engines_
_extends `THREE.EventDispatcher`` & [TilesRendererBase](https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/src/base/TilesRendererBase.js), which can be used to implement a 3d tiles renderer in other engines_

### events

```js
// fired when a new root or child tile set is loaded
{ type: 'load-tile-set', tileSet: Object, url: String }

// fired when a tile model is loaded
{ type: 'load-model', scene: THREE.Group, tile: Object }

// fired when a tile model is disposed
{ type: 'dispose-model', scene: THREE.Group, tile: Object }

// fired when a tiles visibility changes
{ type: 'tile-visibility-change', scene: THREE.Group, tile: Object }
```

### .fetchOptions

Expand Down
57 changes: 53 additions & 4 deletions example/src/FadeManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ export class FadeManager {
constructor() {

this.duration = 250;
this.fadeCount = 0;
this._lastTick = - 1;
this._fadeState = new Map();
this._fadeParams = new WeakMap();
this.onFadeFinish = () => {};
this.onFadeComplete = null;
this.onFadeStart = null;
this.onFadeSetComplete = null;
this.onFadeSetStart = null;

}

Expand Down Expand Up @@ -195,7 +199,20 @@ export class FadeManager {

} );

this.onFadeFinish( object );
// fire events
this.fadeCount --;

if ( this.onFadeComplete ) {

this.onFadeComplete( object );

}

if ( this.fadeCount === 0 && this.onFadeSetComplete ) {

this.onFadeSetComplete();

}

}

Expand All @@ -212,13 +229,30 @@ export class FadeManager {
// Fade the object in
fadeIn( object ) {

this.guaranteeState( object );

const noState = this.guaranteeState( object );
const state = this._fadeState.get( object );
state.fadeInTarget = 1;
state.fadeOutTarget = 0;
state.fadeOut = 0;

// Fire events
if ( noState ) {

this.fadeCount ++;
if ( this.fadeCount === 1 && this.onFadeSetStart ) {

this.onFadeSetStart();

}

if ( this.onFadeStart ) {

this.onFadeStart( object );

}

}

}

// Fade the object out
Expand All @@ -227,11 +261,26 @@ export class FadeManager {
const noState = this.guaranteeState( object );
const state = this._fadeState.get( object );
state.fadeOutTarget = 1;

// Fire events and initialize state
if ( noState ) {

state.fadeInTarget = 1;
state.fadeIn = 1;

this.fadeCount ++;
if ( this.fadeCount === 1 && this.onFadeSetStart ) {

this.onFadeSetStart();

}

if ( this.onFadeStart ) {

this.onFadeStart( object );

}

}

}
Expand Down
22 changes: 17 additions & 5 deletions example/src/FadeTilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function onLoadModel( scene ) {

}

function onFadeFinish( object ) {
function onFadeComplete( object ) {

// when the fade finishes ensure we dispose the tile and remove it from the fade group
if ( object.parent === this._fadeGroup ) {
Expand Down Expand Up @@ -113,14 +113,17 @@ export const FadeTilesRendererMixin = base => class extends base {

const fadeGroup = new Group();
const fadeManager = new FadeManager();
fadeManager.onFadeSetStart = () => this.dispatchEvent( { type: 'fade-start' } );
fadeManager.onFadeSetComplete = () => this.dispatchEvent( { type: 'fade-end' } );

this.group.add( fadeGroup );
fadeManager.onFadeFinish = onFadeFinish.bind( this );
fadeManager.onFadeComplete = onFadeComplete.bind( this );

this._fadeManager = fadeManager;
this._fadeGroup = fadeGroup;

this.onLoadModel = onLoadModel.bind( this );
this.onTileVisibilityChange = onTileVisibilityChange.bind( this );
this.addEventListener( 'load-model', e => onLoadModel.call( this, e.scene ) );
this.addEventListener( 'tile-visibility-change', e => onTileVisibilityChange.call( this, e.scene, e.tile, e.visible ) );

this.initialLayerRendered = false;
this.prevCameraTransforms = new Map();
Expand All @@ -138,9 +141,18 @@ export const FadeTilesRendererMixin = base => class extends base {
this.displayActiveTiles = true;

// update the tiles
const fadingBefore = this._fadeManager.fadeCount;

super.update( ...args );
this._fadeManager.update();

const fadingAfter = this._fadeManager.fadeCount;
if ( fadingBefore !== 0 && fadingAfter !== 0 ) {

this.dispatchEvent( { type: 'fade-change' } );

}

this.displayActiveTiles = displayActiveTiles;
this.fadeDuration = fadeDuration;

Expand Down Expand Up @@ -241,7 +253,7 @@ export const FadeTilesRendererMixin = base => class extends base {

this.disposeSet.forEach( object => {

onFadeFinish.call( this, object );
onFadeComplete.call( this, object );

} );

Expand Down
7 changes: 7 additions & 0 deletions src/three/TilesRenderer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Tileset } from '../base/Tileset';
import { TilesRendererBase } from '../base/TilesRendererBase';
import { TilesGroup } from './TilesGroup';



export class TilesRenderer extends TilesRendererBase {

autoDisableRendererCulling : Boolean;
Expand Down Expand Up @@ -32,4 +34,9 @@ export class TilesRenderer extends TilesRendererBase {
onDisposeModel : ( ( scene : Object3D, tile : Tile ) => void ) | null;
onTileVisibilityChange : ( ( scene : Object3D, tile : Tile, visible : boolean ) => void ) | null;

addEventListener( type: String, cb: ( e : Object ) => void );
hasEventListener( type: String, cb: ( e : Object ) => void );
removeEventListener( type: String, cb: ( e : Object ) => void );
dispatchEvent( e : Object );

}
71 changes: 62 additions & 9 deletions src/three/TilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
Vector3,
Vector2,
Frustum,
LoadingManager
LoadingManager,
EventDispatcher,
} from 'three';
import { raycastTraverse, raycastTraverseFirstHit } from './raycastTraverse.js';
import { readMagicBytes } from '../utilities/readMagicBytes.js';
Expand Down Expand Up @@ -66,8 +67,9 @@ export class TilesRenderer extends TilesRendererBase {
this.cameraInfo = [];
this.activeTiles = new Set();
this.visibleTiles = new Set();
this._autoDisableRendererCulling = true;
this.optimizeRaycast = true;
this._autoDisableRendererCulling = true;
this._eventDispatcher = new EventDispatcher();

this.onLoadTileSet = null;
this.onLoadModel = null;
Expand Down Expand Up @@ -105,6 +107,30 @@ export class TilesRenderer extends TilesRendererBase {

}

addEventListener( ...args ) {

this._eventDispatcher.addEventListener( ...args );

}

hasEventListener( ...args ) {

this._eventDispatcher.hasEventListener( ...args );

}

removeEventListener( ...args ) {

this._eventDispatcher.removeEventListener( ...args );

}

dispatchEvent( ...args ) {

this._eventDispatcher.dispatchEvent( ...args );

}

/* Public API */
getBounds( target ) {

Expand Down Expand Up @@ -293,18 +319,25 @@ export class TilesRenderer extends TilesRendererBase {
const pr = super.fetchTileSet( url, ...rest );
pr.then( json => {

if ( this.onLoadTileSet ) {
// Push this onto the end of the event stack to ensure this runs
// after the base renderer has placed the provided json where it
// needs to be placed and is ready for an update.
Promise.resolve().then( () => {

this.dispatchEvent( {
type: 'load-tile-set',
tileSet: json,
url,
} );

// Push this onto the end of the event stack to ensure this runs
// after the base renderer has placed the provided json where it
// needs to be placed and is ready for an update.
Promise.resolve().then( () => {
if ( this.onLoadTileSet ) {

this.onLoadTileSet( json, url );

} );
}

} );

}

} );
return pr;
Expand Down Expand Up @@ -675,6 +708,12 @@ export class TilesRenderer extends TilesRendererBase {
cached.scene = scene;
cached.metadata = metadata;

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

if ( this.onLoadModel ) {

this.onLoadModel( scene, tile );
Expand Down Expand Up @@ -721,6 +760,13 @@ export class TilesRenderer extends TilesRendererBase {

}


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

if ( this.onDisposeModel ) {

this.onDisposeModel( cached.scene, tile );
Expand Down Expand Up @@ -759,6 +805,13 @@ export class TilesRenderer extends TilesRendererBase {

}

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

if ( this.onTileVisibilityChange ) {

this.onTileVisibilityChange( scene, tile, visible );
Expand Down
11 changes: 7 additions & 4 deletions src/three/renderers/GoogleTilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const GoogleTilesRendererMixin = base => class extends base {
this.lruCache.maxSize = 5000;
this.errorTarget = 40;

this.onLoadTileSet = tileset => {
const onLoadCallback = () => {

// find the session id in the first sub tile set
let session;
Expand Down Expand Up @@ -61,12 +61,15 @@ const GoogleTilesRendererMixin = base => class extends base {
};

// clear the callback once the root is loaded
this.onLoadTileSet = null;
this.removeEventListener( 'load-tile-set', onLoadCallback );

};

this.onTileVisibilityChange = ( scene, tile, visible ) => {
this.addEventListener( 'load-tile-set', onLoadCallback );

this.addEventListener( 'tile-visibility-change', e => {

const { tile, visible } = e;
const copyright = tile.cached.metadata.asset.copyright || '';
if ( visible ) {

Expand All @@ -78,7 +81,7 @@ const GoogleTilesRendererMixin = base => class extends base {

}

};
} );

}

Expand Down

0 comments on commit 9c86ef7

Please sign in to comment.