@@ -12,6 +12,7 @@ define([
12
12
'../Core/Intersect' ,
13
13
'../Core/isDataUri' ,
14
14
'../Core/joinUrls' ,
15
+ '../Core/JulianDate' ,
15
16
'../Core/loadJson' ,
16
17
'../Core/Math' ,
17
18
'../Core/Request' ,
@@ -20,6 +21,7 @@ define([
20
21
'../ThirdParty/Uri' ,
21
22
'../ThirdParty/when' ,
22
23
'./Cesium3DTile' ,
24
+ './Cesium3DTileContentState' ,
23
25
'./Cesium3DTileRefine' ,
24
26
'./Cesium3DTileStyleEngine' ,
25
27
'./CullingVolume' ,
@@ -37,6 +39,7 @@ define([
37
39
Intersect ,
38
40
isDataUri ,
39
41
joinUrls ,
42
+ JulianDate ,
40
43
loadJson ,
41
44
CesiumMath ,
42
45
Request ,
@@ -45,6 +48,7 @@ define([
45
48
Uri ,
46
49
when ,
47
50
Cesium3DTile ,
51
+ Cesium3DTileContentState ,
48
52
Cesium3DTileRefine ,
49
53
Cesium3DTileStyleEngine ,
50
54
CullingVolume ,
@@ -669,6 +673,11 @@ define([
669
673
// If there is a parentTile, add the root of the currently loading tileset
670
674
// to parentTile's children, and increment its numberOfChildrenWithoutContent
671
675
if ( defined ( parentTile ) ) {
676
+ if ( parentTile . children . length > 0 ) {
677
+ // Unload the old subtree if it exists
678
+ unloadExpiredSubtree ( parentTile ) ;
679
+ }
680
+
672
681
parentTile . children . push ( rootTile ) ;
673
682
++ parentTile . numberOfChildrenWithoutContent ;
674
683
@@ -754,6 +763,13 @@ define([
754
763
}
755
764
}
756
765
766
+ function recheckRefinement ( tile ) {
767
+ var ancestor = getAncestorWithContent ( tile ) ;
768
+ if ( defined ( ancestor ) && ( ancestor . refine === Cesium3DTileRefine . REPLACE ) ) {
769
+ prepareRefiningTiles ( [ ancestor ] ) ;
770
+ }
771
+ }
772
+
757
773
function getScreenSpaceError ( geometricError , tile , frameState ) {
758
774
// TODO: screenSpaceError2D like QuadtreePrimitive.js
759
775
if ( geometricError === 0.0 ) {
@@ -786,6 +802,68 @@ define([
786
802
787
803
///////////////////////////////////////////////////////////////////////////
788
804
805
+ var scratchJulianDate = new JulianDate ( ) ;
806
+
807
+ function updateExpireDate ( tile ) {
808
+ if ( defined ( tile . expireDuration ) ) {
809
+ var expireDurationDate = JulianDate . now ( scratchJulianDate ) ;
810
+ JulianDate . addSeconds ( expireDurationDate , tile . expireDuration , expireDurationDate ) ;
811
+
812
+ if ( defined ( tile . expireDate ) ) {
813
+ if ( JulianDate . lessThan ( expireDurationDate , tile . expireDate ) ) {
814
+ JulianDate . clone ( expireDurationDate , tile . expireDate ) ;
815
+ }
816
+ }
817
+ }
818
+ }
819
+
820
+ function unloadExpiredSubtree ( tile ) {
821
+ var stack = [ ] ;
822
+ stack . push ( tile ) ;
823
+ while ( stack . length > 0 ) {
824
+ tile = stack . pop ( ) ;
825
+ var children = tile . children ;
826
+ var length = children . length ;
827
+ for ( var i = 0 ; i < length ; ++ i ) {
828
+ var child = children [ i ] ;
829
+ child . destroy ( ) ;
830
+ stack . push ( child ) ;
831
+ }
832
+ }
833
+ tile . children = [ ] ;
834
+ tile . unloadContent ( ) ;
835
+ }
836
+
837
+ function unloadExpiredLeafTile ( tile ) {
838
+ tile . destroy ( ) ;
839
+ var parent = tile . parent ;
840
+ if ( defined ( parent ) ) {
841
+ var index = parent . children . indexOf ( tile ) ;
842
+ parent . children . splice ( index , 1 ) ;
843
+ recheckRefinement ( parent ) ;
844
+ }
845
+ }
846
+
847
+ function unloadExpiredTile ( tile ) {
848
+ if ( tile . children . length === 0 ) {
849
+ unloadExpiredLeafTile ( tile ) ;
850
+ return ;
851
+ }
852
+
853
+ if ( tile . hasContent ) {
854
+ // When the tile is expired and the request fails, then there is no longer any content to show.
855
+ // Unload the tile's old content and replace it with Empty3DTileContent.
856
+ tile . unloadContentAndMakeEmpty ( ) ;
857
+ // Now that the tile is empty recheck its parent's refinement
858
+ recheckRefinement ( tile . parent ) ;
859
+ } else if ( tile . hasTilesetContent ) {
860
+ // When the tile is the root of an external tileset, unload the entire subtree
861
+ unloadExpiredSubtree ( tile ) ;
862
+ // Also destroy this tile
863
+ unloadExpiredLeafTile ( tile ) ;
864
+ }
865
+ }
866
+
789
867
function requestContent ( tileset , tile , outOfCore ) {
790
868
if ( ! outOfCore ) {
791
869
return ;
@@ -794,15 +872,30 @@ define([
794
872
return ;
795
873
}
796
874
875
+ var expired = ( tile . content . state === Cesium3DTileContentState . EXPIRED ) ;
876
+
797
877
tile . requestContent ( ) ;
798
878
799
- if ( ! tile . contentUnloaded ) {
879
+ // If the RequestScheduler is full, the content will remain in the UNLOADED or EXPIRED state.
880
+ // Otherwise, it will be in the LOADING state.
881
+ if ( tile . content . state === Cesium3DTileContentState . LOADING ) {
800
882
var stats = tileset . _statistics ;
801
883
++ stats . numberOfPendingRequests ;
802
884
803
885
var removeFunction = removeFromProcessingQueue ( tileset , tile ) ;
804
- when ( tile . content . contentReadyToProcessPromise ) . then ( addToProcessingQueue ( tileset , tile ) ) . otherwise ( removeFunction ) ;
805
- when ( tile . content . readyPromise ) . then ( removeFunction ) . otherwise ( removeFunction ) ;
886
+ when ( tile . content . contentReadyToProcessPromise ) . then ( function ( ) {
887
+ // Content is loaded and ready to process
888
+ addToProcessingQueue ( tileset , tile ) ;
889
+ updateExpireDate ( tile ) ;
890
+ } ) . otherwise ( removeFunction ) ;
891
+
892
+ when ( tile . content . readyPromise ) . then ( removeFunction ) . otherwise ( function ( ) {
893
+ // The request failed
894
+ removeFunction ( ) ;
895
+ if ( expired ) {
896
+ unloadExpiredTile ( tile ) ;
897
+ }
898
+ } ) ;
806
899
}
807
900
}
808
901
@@ -895,6 +988,18 @@ define([
895
988
var sse = getScreenSpaceError ( t . geometricError , t , frameState ) ;
896
989
// PERFORMANCE_IDEA: refine also based on (1) occlusion/VMSSE and/or (2) center of viewport
897
990
991
+ // If the tile is expired, request new content
992
+ if ( defined ( t . expireDate ) ) {
993
+ var now = JulianDate . now ( scratchJulianDate ) ;
994
+ if ( JulianDate . lessThan ( now , t . expireDate ) ) {
995
+ // Request new content
996
+ if ( t . contentReady && ( t . hasContent || t . hasTilesetContent ) ) {
997
+ t . content . state = Cesium3DTileContentState . EXPIRED ;
998
+ requestContent ( tileset , t , outOfCore ) ;
999
+ }
1000
+ }
1001
+ }
1002
+
898
1003
var children = t . children ;
899
1004
var childrenLength = children . length ;
900
1005
var child ;
@@ -1063,12 +1168,10 @@ define([
1063
1168
///////////////////////////////////////////////////////////////////////////
1064
1169
1065
1170
function addToProcessingQueue ( tileset , tile ) {
1066
- return function ( ) {
1067
- tileset . _processingQueue . push ( tile ) ;
1171
+ tileset . _processingQueue . push ( tile ) ;
1068
1172
1069
- -- tileset . _statistics . numberOfPendingRequests ;
1070
- ++ tileset . _statistics . numberProcessing ;
1071
- } ;
1173
+ -- tileset . _statistics . numberOfPendingRequests ;
1174
+ ++ tileset . _statistics . numberProcessing ;
1072
1175
}
1073
1176
1074
1177
function removeFromProcessingQueue ( tileset , tile ) {
0 commit comments