Skip to content

Commit

Permalink
Add fadeRootTiles option and fade control (#437)
Browse files Browse the repository at this point in the history
* Add maximum extra tiles option

* Add fadeRootTiles option

* Remove unused field
  • Loading branch information
gkjohnson authored Dec 31, 2023
1 parent e92aa86 commit 86ae004
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 51 deletions.
5 changes: 4 additions & 1 deletion example/fadingTiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ let groundTiles, skyTiles, tilesParent;
const params = {

reinstantiateTiles,
fadeRootTiles: false,
useFade: true,
errorTarget: 12,
fadeDuration: 0.5,
Expand Down Expand Up @@ -73,6 +74,7 @@ function init() {

const gui = new GUI();
gui.add( params, 'useFade' );
gui.add( params, 'fadeRootTiles' );
gui.add( params, 'errorTarget', 0, 1000 );
gui.add( params, 'fadeDuration', 0, 5 );
gui.add( params, 'renderScale', 0.1, 1.0, 0.05 ).onChange( v => renderer.setPixelRatio( v * window.devicePixelRatio ) );
Expand Down Expand Up @@ -124,11 +126,12 @@ function render() {
camera.updateMatrixWorld();

groundTiles.errorTarget = params.errorTarget;

groundTiles.fadeRootTiles = params.fadeRootTiles;
groundTiles.setCamera( camera );
groundTiles.setResolutionFromRenderer( camera, renderer );
groundTiles.update();

skyTiles.fadeRootTiles = params.fadeRootTiles;
skyTiles.setCamera( camera );
skyTiles.setResolutionFromRenderer( camera, renderer );
skyTiles.update();
Expand Down
110 changes: 61 additions & 49 deletions example/src/FadeTilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ const _scale = new Vector3();

function onTileVisibilityChange( scene, tile, visible ) {

// ensure the tiles are fading to the right target before stopping fade
if ( this.isMovingFast ) {

this._fadeManager.completeFade( scene );

}

// ensure the tiles are marked as visible on visibility toggle since
// it's possible we disable them when adjusting visibility based on frustum
scene.visible = true;
Expand All @@ -28,7 +21,20 @@ function onTileVisibilityChange( scene, tile, visible ) {

} else {

this._fadeManager.fadeIn( scene );
// if this is a root tile and we haven't rendered any child tiles yet then pop in
// the root tiles immediately rather than fading from nothing
const isRootTile = tile.__depthFromRenderedParent === 0;
if ( ! isRootTile ) {

this.initialLayerRendered = true;

}

if ( ! isRootTile || ! this.fadeRootTiles || this.initialLayerRendered ) {

this._fadeManager.fadeIn( scene );

}

}

Expand Down Expand Up @@ -102,6 +108,9 @@ export const FadeTilesRendererMixin = base => class extends base {

super( ...args );

this.maximumFadeOutTiles = 50;
this.fadeRootTiles = false;

const fadeGroup = new Group();
const fadeManager = new FadeManager();
this.group.add( fadeGroup );
Expand All @@ -113,49 +122,20 @@ export const FadeTilesRendererMixin = base => class extends base {
this.onLoadModel = onLoadModel.bind( this );
this.onTileVisibilityChange = onTileVisibilityChange.bind( this );

this.prevCameraTransform = new Map();
this.initialLayerRendered = false;
this.prevCameraTransforms = new Map();
this.disposeSet = new Set();

}

update( ...args ) {

// determine whether all the rendering cameras are moving
// quickly so we can adjust how tiles fade accordingly
let isMovingFast = true;
const prevCameraTransform = this.prevCameraTransform;
const cameras = this.cameras;
cameras.forEach( camera => {

if ( ! prevCameraTransform.has( camera ) ) {

return;

}

const currMatrix = camera.matrixWorld;
const prevMatrix = prevCameraTransform.get( camera );

currMatrix.decompose( _toPos, _toQuat, _scale );
prevMatrix.decompose( _fromPos, _fromQuat, _scale );

const angleTo = _toQuat.angleTo( _fromQuat );
const positionTo = _toPos.distanceTo( _fromPos );

// if rotation is moving > 0.25 radians per frame or position is moving > 0.1 units
// then we are considering the camera to be moving too fast to notice a faster / abrupt fade
isMovingFast = isMovingFast && ( angleTo > 0.25 || positionTo > 0.1 );

} );

// adjust settings to what's needed for specific fade logic. Ie display active tiles so when the camera
// moves we don't notice tiles popping when they enter the view. And perform the fade animation more quickly
// if the camera is moving quickly.
const fadeDuration = this.fadeDuration;
const displayActiveTiles = this.displayActiveTiles;
this.displayActiveTiles = true;
this.fadeDuration = isMovingFast ? fadeDuration * 0.2 : fadeDuration;
this.isMovingFast = isMovingFast;

// update the tiles
super.update( ...args );
Expand All @@ -176,31 +156,63 @@ export const FadeTilesRendererMixin = base => class extends base {

}

// track the camera movement so we can use it for next frame
cameras.forEach( camera => {
const cameras = this.cameras;
const prevCameraTransforms = this.prevCameraTransforms;
if ( this.maximumFadeOutTiles < this._fadeGroup.children.length ) {

if ( ! prevCameraTransform.has( camera ) ) {
// determine whether all the rendering cameras are moving
// quickly so we can adjust how tiles fade accordingly
let isMovingFast = true;
cameras.forEach( camera => {

prevCameraTransform.set( camera, new Matrix4() );
if ( ! prevCameraTransforms.has( camera ) ) {

}
return;

}

prevCameraTransform.get( camera ).copy( camera.matrixWorld );
const currMatrix = camera.matrixWorld;
const prevMatrix = prevCameraTransforms.get( camera );

} );
currMatrix.decompose( _toPos, _toQuat, _scale );
prevMatrix.decompose( _fromPos, _fromQuat, _scale );

const angleTo = _toQuat.angleTo( _fromQuat );
const positionTo = _toPos.distanceTo( _fromPos );

// if rotation is moving > 0.25 radians per frame or position is moving > 0.1 units
// then we are considering the camera to be moving too fast to notice a faster / abrupt fade
isMovingFast = isMovingFast && ( angleTo > 0.25 || positionTo > 0.1 );

} );

if ( isMovingFast ) {

if ( isMovingFast ) {
this._fadeManager.completeAllFades();

this._fadeManager.completeAllFades();
}

}

// track the camera movement so we can use it for next frame
cameras.forEach( camera => {

if ( ! prevCameraTransforms.has( camera ) ) {

prevCameraTransforms.set( camera, new Matrix4() );

}

prevCameraTransforms.get( camera ).copy( camera.matrixWorld );

} );


}

deleteCamera( camera ) {

this.prevCameraTransform.delete( camera );
this.prevCameraTransforms.delete( camera );

}

Expand Down
1 change: 0 additions & 1 deletion src/base/traverseFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ export function markUsedSetLeaves( tile, renderer ) {
tile.__childrenWereVisible = childrenWereVisible;
tile.__allChildrenLoaded = allChildrenLoaded;


}

}
Expand Down

0 comments on commit 86ae004

Please sign in to comment.