Sfoglia il codice sorgente

Check if children were visible before marking parent tile as visible

Garrett Johnson 5 anni fa
parent
commit
2011cad9d2
2 ha cambiato i file con 15 aggiunte e 1 eliminazioni
  1. 1 0
      src/base/TilesRendererBase.js
  2. 14 1
      src/base/traverseFunctions.js

+ 1 - 0
src/base/TilesRendererBase.js

@@ -167,6 +167,7 @@ export class TilesRendererBase {
 
 		tile.__wasSetVisible = false;
 		tile.__visible = false;
+		tile.__childrenWereVisible = false;
 
 		tile.__wasSetActive = false;
 		tile.__active = false;

+ 14 - 1
src/base/traverseFunctions.js

@@ -17,6 +17,7 @@ function resetFrameState( tile, frameCount ) {
 		tile.__visible = false;
 		tile.__active = false;
 		tile.__error = 0;
+		tile.__childrenWereVisible = false;
 
 	}
 
@@ -152,13 +153,17 @@ export function markUsedSetLeaves( tile, renderer ) {
 
 	const children = tile.children;
 	let anyChildrenUsed = false;
+	let childrenWereVisible = false;
 	for ( let i = 0, l = children.length; i < l; i ++ ) {
 
 		const c = children[ i ];
 		anyChildrenUsed = anyChildrenUsed || isUsedThisFrame( c, frameCount );
+		childrenWereVisible = childrenWereVisible || c.__wasSetVisible || c.__childrenWereVisible;
 
 	}
 
+	tile.__childrenWereVisible = childrenWereVisible;
+
 	if ( ! anyChildrenUsed ) {
 
 		// TODO: This isn't necessarily right because it's possible that a parent tile is considered in the
@@ -218,6 +223,7 @@ export function skipTraversal( tile, renderer ) {
 	const meetsSSE = tile.__error <= errorRequirement;
 	const hasContent = ! tile.__contentEmpty;
 	const loadedContent = tile.__loadingState === LOADED && ! tile.__contentEmpty;
+	const childrenWereVisible = tile.__childrenWereVisible;
 	const children = tile.children;
 	let allChildrenHaveContent = true;
 	for ( let i = 0, l = children.length; i < l; i ++ ) {
@@ -239,7 +245,14 @@ export function skipTraversal( tile, renderer ) {
 
 	}
 
-	if ( meetsSSE && loadedContent && ! allChildrenHaveContent ) {
+	// Only mark this tile as visible if it meets the screen space error requirements, has loaded content, not
+	// all children have loaded yet, and if no children were visible last frame. We want to keep children visible
+	// that _were_ visible to avoid a pop in level of detail as the camera moves around and parent / sibling tiles
+	// load in.
+
+	// TODO: this condition is skipped over if data hasn't loaded yet meaning that between when this tile is first
+	// used trigger and when it loads the children are iterated over and triggered to load, which is unnecessary
+	if ( meetsSSE && loadedContent && ! allChildrenHaveContent && ! childrenWereVisible ) {
 
 		if ( tile.__inFrustum ) {