@@ -622,6 +622,10 @@ postProcessContentInWorkerThread(
622
622
gltfOptions.pSharedAssetSystem = tileLoadInfo.pSharedAssetSystem ;
623
623
}
624
624
625
+ int32_t version = pGltfModifier && pGltfModifier->getCurrentVersion ()
626
+ ? pGltfModifier->getCurrentVersion ().value_or (0 )
627
+ : 0 ;
628
+
625
629
auto asyncSystem = tileLoadInfo.asyncSystem ;
626
630
auto pAssetAccessor = result.pAssetAccessor ;
627
631
return CesiumGltfReader::GltfReader::resolveExternalData (
@@ -634,8 +638,9 @@ postProcessContentInWorkerThread(
634
638
.thenInWorkerThread ([result = std::move (result),
635
639
projections = std::move (projections),
636
640
tileLoadInfo = std::move (tileLoadInfo),
637
- pGltfModifier](CesiumGltfReader::GltfReaderResult&&
638
- gltfResult) mutable {
641
+ pGltfModifier,
642
+ version](CesiumGltfReader::GltfReaderResult&&
643
+ gltfResult) mutable {
639
644
if (!gltfResult.errors .empty ()) {
640
645
if (result.pCompletedRequest ) {
641
646
SPDLOG_LOGGER_ERROR (
@@ -695,17 +700,27 @@ postProcessContentInWorkerThread(
695
700
std::get<CesiumGltf::Model>(result.contentKind );
696
701
return pGltfModifier
697
702
->apply (GltfModifierInput{
703
+ .version = version,
698
704
.asyncSystem = tileLoadInfo.asyncSystem ,
699
705
.pAssetAccessor = tileLoadInfo.pAssetAccessor ,
700
706
.pLogger = tileLoadInfo.pLogger ,
701
707
.previousModel = model,
702
708
.tileTransform = tileLoadInfo.tileTransform })
703
709
.thenInWorkerThread (
704
- [result = std::move (result)](
710
+ [result = std::move (result), version ](
705
711
std::optional<GltfModifierOutput>&& modified) mutable {
706
712
if (modified) {
707
713
result.contentKind = std::move (modified->modifiedModel );
708
714
}
715
+
716
+ CesiumGltf::Model* pModel =
717
+ std::get_if<CesiumGltf::Model>(&result.contentKind );
718
+ if (pModel) {
719
+ GltfModifierVersionExtension::setVersion (
720
+ *pModel,
721
+ version);
722
+ }
723
+
709
724
return result;
710
725
})
711
726
.thenPassThrough (std::move (tileLoadInfo));
@@ -1115,6 +1130,10 @@ void TilesetContentManager::reapplyGltfModifier(
1115
1130
1116
1131
const TilesetExternals& externals = this ->getExternals ();
1117
1132
1133
+ // Get the version here, in the main thread, because it may change while the
1134
+ // worker is running.
1135
+ int32_t version = externals.pGltfModifier ->getCurrentVersion ().value_or (0 );
1136
+
1118
1137
// It is safe to capture the TilesetExternals and Model by reference because
1119
1138
// the TilesetContentManager guarantees both will continue to exist and are
1120
1139
// immutable while modification is in progress.
@@ -1127,77 +1146,99 @@ void TilesetContentManager::reapplyGltfModifier(
1127
1146
// at the end in order to keep the Tile, its content, and the
1128
1147
// TilesetContentManager alive during the entire process.
1129
1148
externals.asyncSystem
1130
- .runInWorkerThread (
1131
- [&externals, &previousModel, tileTransform = tile.getTransform ()] {
1132
- return externals.pGltfModifier ->apply (GltfModifierInput{
1133
- .asyncSystem = externals.asyncSystem ,
1134
- .pAssetAccessor = externals.pAssetAccessor ,
1135
- .pLogger = externals.pLogger ,
1136
- .previousModel = previousModel,
1137
- .tileTransform = tileTransform});
1138
- })
1139
- .thenInWorkerThread ([&externals,
1140
- &previousModel,
1141
- pRenderContent,
1142
- tileTransform = tile.getTransform (),
1143
- tileBoundingVolume = tile.getBoundingVolume (),
1144
- tileContentBoundingVolume =
1145
- tile.getContentBoundingVolume (),
1146
- rendererOptions = tilesetOptions.rendererOptions ](
1147
- std::optional<GltfModifierOutput>&& modified) {
1148
- const CesiumGltf::Model& model =
1149
- modified ? modified->modifiedModel : previousModel;
1150
-
1151
- TileLoadResult tileLoadResult;
1152
- tileLoadResult.state = TileLoadResultState::Success;
1153
- tileLoadResult.pAssetAccessor = externals.pAssetAccessor ;
1154
- tileLoadResult.rasterOverlayDetails =
1155
- pRenderContent->getRasterOverlayDetails ();
1156
- tileLoadResult.initialBoundingVolume = tileBoundingVolume;
1157
- tileLoadResult.initialContentBoundingVolume = tileContentBoundingVolume;
1158
-
1159
- const auto it = model.extras .find (" gltfUpAxis" );
1160
- if (it == model.extras .end ()) {
1161
- CESIUM_ASSERT (false );
1162
- tileLoadResult.glTFUpAxis = CesiumGeometry::Axis::Y;
1163
- } else {
1164
- tileLoadResult.glTFUpAxis = static_cast <CesiumGeometry::Axis>(
1165
- it->second .getSafeNumberOrDefault (1 ));
1166
- }
1167
-
1168
- if (modified) {
1169
- tileLoadResult.contentKind = std::move (modified->modifiedModel );
1170
- } else {
1171
- tileLoadResult.contentKind = previousModel;
1172
- }
1173
-
1174
- return externals.pPrepareRendererResources ->prepareInLoadThread (
1175
- externals.asyncSystem ,
1176
- std::move (tileLoadResult),
1177
- tileTransform,
1178
- rendererOptions);
1149
+ .runInWorkerThread ([&externals,
1150
+ &previousModel,
1151
+ version,
1152
+ tileTransform = tile.getTransform ()] {
1153
+ return externals.pGltfModifier ->apply (GltfModifierInput{
1154
+ .version = version,
1155
+ .asyncSystem = externals.asyncSystem ,
1156
+ .pAssetAccessor = externals.pAssetAccessor ,
1157
+ .pLogger = externals.pLogger ,
1158
+ .previousModel = previousModel,
1159
+ .tileTransform = tileTransform});
1179
1160
})
1161
+ .thenInWorkerThread (
1162
+ [&externals,
1163
+ &previousModel,
1164
+ pRenderContent,
1165
+ tileTransform = tile.getTransform (),
1166
+ tileBoundingVolume = tile.getBoundingVolume (),
1167
+ tileContentBoundingVolume = tile.getContentBoundingVolume (),
1168
+ rendererOptions = tilesetOptions.rendererOptions ,
1169
+ version](std::optional<GltfModifierOutput>&& modified) {
1170
+ TileLoadResult tileLoadResult;
1171
+ tileLoadResult.state = TileLoadResultState::Success;
1172
+ tileLoadResult.pAssetAccessor = externals.pAssetAccessor ;
1173
+ tileLoadResult.rasterOverlayDetails =
1174
+ pRenderContent->getRasterOverlayDetails ();
1175
+ tileLoadResult.initialBoundingVolume = tileBoundingVolume;
1176
+ tileLoadResult.initialContentBoundingVolume =
1177
+ tileContentBoundingVolume;
1178
+
1179
+ const CesiumGltf::Model& model =
1180
+ modified ? modified->modifiedModel : previousModel;
1181
+ const auto it = model.extras .find (" gltfUpAxis" );
1182
+ if (it == model.extras .end ()) {
1183
+ CESIUM_ASSERT (false );
1184
+ tileLoadResult.glTFUpAxis = CesiumGeometry::Axis::Y;
1185
+ } else {
1186
+ tileLoadResult.glTFUpAxis = static_cast <CesiumGeometry::Axis>(
1187
+ it->second .getSafeNumberOrDefault (1 ));
1188
+ }
1189
+
1190
+ if (modified) {
1191
+ tileLoadResult.contentKind = std::move (modified->modifiedModel );
1192
+ } else {
1193
+ tileLoadResult.contentKind = previousModel;
1194
+ }
1195
+
1196
+ // Whether the GltfModifier modified anything or not, the model is
1197
+ // now up-to-date with the version that triggered this run.
1198
+ GltfModifierVersionExtension::setVersion (
1199
+ std::get<CesiumGltf::Model>(tileLoadResult.contentKind ),
1200
+ version);
1201
+
1202
+ return externals.pPrepareRendererResources ->prepareInLoadThread (
1203
+ externals.asyncSystem ,
1204
+ std::move (tileLoadResult),
1205
+ tileTransform,
1206
+ rendererOptions);
1207
+ })
1180
1208
.thenInMainThread ([this , pTile = Tile::Pointer (&tile)](
1181
1209
TileLoadResultAndRenderResources&& pair) {
1182
- pTile->getContent ().getRenderContent ()->setGltfModifierState (
1183
- GltfModifier::State::WorkerDone);
1210
+ TileRenderContent* pRenderContent =
1211
+ pTile->getContent ().getRenderContent ();
1212
+ CESIUM_ASSERT (pRenderContent != nullptr );
1213
+
1214
+ pRenderContent->setGltfModifierState (GltfModifier::State::WorkerDone);
1184
1215
this ->notifyTileDoneLoading (pTile.get ());
1185
- pTile->getContent ()
1186
- .getRenderContent ()
1187
- ->setModifiedModelAndRenderResources (
1188
- std::move (std::get<CesiumGltf::Model>(pair.result .contentKind )),
1189
- pair.pRenderResources );
1216
+ pRenderContent->setModifiedModelAndRenderResources (
1217
+ std::move (std::get<CesiumGltf::Model>(pair.result .contentKind )),
1218
+ pair.pRenderResources );
1219
+
1190
1220
this ->_externals .pGltfModifier ->onWorkerThreadApplyComplete (*pTile);
1191
1221
})
1192
1222
.catchInMainThread (
1193
- [this , pTile = Tile::Pointer (&tile), &externals](std::exception&& e) {
1223
+ [this , pTile = Tile::Pointer (&tile), &externals, version](
1224
+ std::exception&& e) {
1194
1225
pTile->getContent ().getRenderContent ()->setGltfModifierState (
1195
1226
GltfModifier::State::WorkerDone);
1196
1227
this ->notifyTileDoneLoading (pTile.get ());
1197
1228
SPDLOG_LOGGER_ERROR (
1198
1229
externals.pLogger ,
1199
1230
" An unexpected error occurred when reapplying GltfModifier: {}" ,
1200
1231
e.what ());
1232
+
1233
+ // Even though the GltfModifier failed, we mark the model up-to-date
1234
+ // with the version that triggered this run so that we won't try to
1235
+ // run again for this version.
1236
+ TileRenderContent* pRenderContent =
1237
+ pTile->getContent ().getRenderContent ();
1238
+ CESIUM_ASSERT (pRenderContent != nullptr );
1239
+ GltfModifierVersionExtension::setVersion (
1240
+ pRenderContent->getModel (),
1241
+ version);
1201
1242
});
1202
1243
}
1203
1244
@@ -1824,6 +1865,16 @@ void TilesetContentManager::clearChildrenRecursively(Tile* pTile) noexcept {
1824
1865
1825
1866
void TilesetContentManager::registerTileRequester (
1826
1867
TileLoadRequester& requester) {
1868
+ if (requester._pTilesetContentManager .get () == this ) {
1869
+ return ;
1870
+ }
1871
+
1872
+ if (requester._pTilesetContentManager != nullptr ) {
1873
+ requester._pTilesetContentManager ->unregisterTileRequester (requester);
1874
+ }
1875
+
1876
+ requester._pTilesetContentManager = this ;
1877
+
1827
1878
CESIUM_ASSERT (
1828
1879
std::find (
1829
1880
this ->_requesters .begin (),
@@ -1840,6 +1891,8 @@ void TilesetContentManager::unregisterTileRequester(
1840
1891
if (it != this ->_requesters .end ()) {
1841
1892
this ->_requesters .erase (it);
1842
1893
}
1894
+
1895
+ requester._pTilesetContentManager = nullptr ;
1843
1896
}
1844
1897
1845
1898
namespace {
0 commit comments