Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fadeRootTiles option and fade control #437

Merged
merged 3 commits into from
Dec 31, 2023
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
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
Loading