Skip to content

Commit f02dd5f

Browse files
committed
Pass version to GltfModifier, fix load requester.
1 parent 99a0aa6 commit f02dd5f

File tree

4 files changed

+125
-73
lines changed

4 files changed

+125
-73
lines changed

Cesium3DTilesSelection/include/Cesium3DTilesSelection/GltfModifier.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ class TilesetContentManager;
2525
* @brief The input to the {@link GltfModifier::apply} function.
2626
*/
2727
struct GltfModifierInput {
28+
/**
29+
* @brief The {@link GltfModifier}'s version, as returned by
30+
* {@link GltfModifier::getCurrentVersion} at the start of the modification.
31+
*
32+
* This is provided because calling {@link GltfModifier::getCurrentVersion}
33+
* may return a newer version if {@link GltfModifier::trigger} is called
34+
* again while {@link GltfModifier::apply} is running in a worker thread.
35+
*/
36+
int32_t version;
37+
2838
/**
2939
* @brief The async system that can be used to do work in threads.
3040
*/

Cesium3DTilesSelection/include/Cesium3DTilesSelection/TileLoadRequester.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class TileLoadRequester {
148148
CesiumUtility::IntrusivePointer<TilesetContentManager>
149149
_pTilesetContentManager;
150150

151-
friend class Tileset;
151+
friend class TilesetContentManager;
152152
};
153153

154154
} // namespace Cesium3DTilesSelection

Cesium3DTilesSelection/src/Tileset.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,7 @@ void Tileset::loadTiles() {
468468
}
469469

470470
void Tileset::registerLoadRequester(TileLoadRequester& requester) {
471-
if (requester._pTilesetContentManager == this->_pTilesetContentManager) {
472-
return;
473-
}
474-
475-
if (requester._pTilesetContentManager != nullptr) {
476-
requester._pTilesetContentManager->unregisterTileRequester(requester);
477-
}
478-
479-
requester._pTilesetContentManager = this->_pTilesetContentManager;
480-
if (requester._pTilesetContentManager != nullptr) {
481-
requester._pTilesetContentManager->registerTileRequester(requester);
482-
}
471+
this->_pTilesetContentManager->registerTileRequester(requester);
483472
}
484473

485474
int32_t Tileset::getNumberOfTilesLoaded() const {

Cesium3DTilesSelection/src/TilesetContentManager.cpp

Lines changed: 113 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ postProcessContentInWorkerThread(
622622
gltfOptions.pSharedAssetSystem = tileLoadInfo.pSharedAssetSystem;
623623
}
624624

625+
int32_t version = pGltfModifier && pGltfModifier->getCurrentVersion()
626+
? pGltfModifier->getCurrentVersion().value_or(0)
627+
: 0;
628+
625629
auto asyncSystem = tileLoadInfo.asyncSystem;
626630
auto pAssetAccessor = result.pAssetAccessor;
627631
return CesiumGltfReader::GltfReader::resolveExternalData(
@@ -634,8 +638,9 @@ postProcessContentInWorkerThread(
634638
.thenInWorkerThread([result = std::move(result),
635639
projections = std::move(projections),
636640
tileLoadInfo = std::move(tileLoadInfo),
637-
pGltfModifier](CesiumGltfReader::GltfReaderResult&&
638-
gltfResult) mutable {
641+
pGltfModifier,
642+
version](CesiumGltfReader::GltfReaderResult&&
643+
gltfResult) mutable {
639644
if (!gltfResult.errors.empty()) {
640645
if (result.pCompletedRequest) {
641646
SPDLOG_LOGGER_ERROR(
@@ -695,17 +700,27 @@ postProcessContentInWorkerThread(
695700
std::get<CesiumGltf::Model>(result.contentKind);
696701
return pGltfModifier
697702
->apply(GltfModifierInput{
703+
.version = version,
698704
.asyncSystem = tileLoadInfo.asyncSystem,
699705
.pAssetAccessor = tileLoadInfo.pAssetAccessor,
700706
.pLogger = tileLoadInfo.pLogger,
701707
.previousModel = model,
702708
.tileTransform = tileLoadInfo.tileTransform})
703709
.thenInWorkerThread(
704-
[result = std::move(result)](
710+
[result = std::move(result), version](
705711
std::optional<GltfModifierOutput>&& modified) mutable {
706712
if (modified) {
707713
result.contentKind = std::move(modified->modifiedModel);
708714
}
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+
709724
return result;
710725
})
711726
.thenPassThrough(std::move(tileLoadInfo));
@@ -1115,6 +1130,10 @@ void TilesetContentManager::reapplyGltfModifier(
11151130

11161131
const TilesetExternals& externals = this->getExternals();
11171132

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+
11181137
// It is safe to capture the TilesetExternals and Model by reference because
11191138
// the TilesetContentManager guarantees both will continue to exist and are
11201139
// immutable while modification is in progress.
@@ -1127,77 +1146,99 @@ void TilesetContentManager::reapplyGltfModifier(
11271146
// at the end in order to keep the Tile, its content, and the
11281147
// TilesetContentManager alive during the entire process.
11291148
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});
11791160
})
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+
})
11801208
.thenInMainThread([this, pTile = Tile::Pointer(&tile)](
11811209
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);
11841215
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+
11901220
this->_externals.pGltfModifier->onWorkerThreadApplyComplete(*pTile);
11911221
})
11921222
.catchInMainThread(
1193-
[this, pTile = Tile::Pointer(&tile), &externals](std::exception&& e) {
1223+
[this, pTile = Tile::Pointer(&tile), &externals, version](
1224+
std::exception&& e) {
11941225
pTile->getContent().getRenderContent()->setGltfModifierState(
11951226
GltfModifier::State::WorkerDone);
11961227
this->notifyTileDoneLoading(pTile.get());
11971228
SPDLOG_LOGGER_ERROR(
11981229
externals.pLogger,
11991230
"An unexpected error occurred when reapplying GltfModifier: {}",
12001231
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);
12011242
});
12021243
}
12031244

@@ -1824,6 +1865,16 @@ void TilesetContentManager::clearChildrenRecursively(Tile* pTile) noexcept {
18241865

18251866
void TilesetContentManager::registerTileRequester(
18261867
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+
18271878
CESIUM_ASSERT(
18281879
std::find(
18291880
this->_requesters.begin(),
@@ -1840,6 +1891,8 @@ void TilesetContentManager::unregisterTileRequester(
18401891
if (it != this->_requesters.end()) {
18411892
this->_requesters.erase(it);
18421893
}
1894+
1895+
requester._pTilesetContentManager = nullptr;
18431896
}
18441897

18451898
namespace {

0 commit comments

Comments
 (0)