From 6d5460a72eed9339e68aab249fcc60c18e447eb2 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Mon, 16 Oct 2023 18:28:42 -0500 Subject: [PATCH] Fixed opening a USD file with saved Globe Anchors --- src/core/include/cesium/omniverse/UsdUtil.h | 2 + src/core/src/Context.cpp | 46 ++++++++++++--------- src/core/src/UsdNotificationHandler.cpp | 2 +- src/core/src/UsdUtil.cpp | 25 +++++++++++ 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/core/include/cesium/omniverse/UsdUtil.h b/src/core/include/cesium/omniverse/UsdUtil.h index dec7942c8..cac86a440 100644 --- a/src/core/include/cesium/omniverse/UsdUtil.h +++ b/src/core/include/cesium/omniverse/UsdUtil.h @@ -125,5 +125,7 @@ void setGeoreferenceForTileset(const pxr::SdfPath& tilesetPath, const pxr::SdfPa void addOrUpdateTransformOpForAnchor(const pxr::SdfPath& path, const glm::dmat4& transform); std::optional getCesiumTransformOpValueForPathIfExists(const pxr::SdfPath& path); +std::optional getAnchorGeoreferencePath(const pxr::SdfPath& path); +std::optional getCartographicOriginForAnchor(const pxr::SdfPath& path); }; // namespace cesium::omniverse::UsdUtil diff --git a/src/core/src/Context.cpp b/src/core/src/Context.cpp index 8ab4fe0a3..4fbd49375 100644 --- a/src/core/src/Context.cpp +++ b/src/core/src/Context.cpp @@ -182,6 +182,14 @@ void Context::reloadStage() { AssetRegistry::getInstance().addTileset(path, UsdUtil::GEOREFERENCE_PATH); } else if (UsdUtil::isCesiumImagery(path)) { AssetRegistry::getInstance().addImagery(path); + } else if (UsdUtil::hasCesiumGlobeAnchor(path)) { + auto origin = UsdUtil::getCartographicOriginForAnchor(path); + + // We probably need to do something else other than crash, but there really isn't more we can do in this case. + assert(origin.has_value()); + + auto anchorToFixed = UsdUtil::computeUsdLocalToEcefTransformForPrim(origin.value(), path); + GlobeAnchorRegistry::getInstance().createAnchor(path, anchorToFixed); } } } @@ -314,20 +322,18 @@ void Context::processCesiumGeoreferenceChanged(const cesium::omniverse::ChangedP for (const auto& globeAnchor : anchors) { auto anchorApi = UsdUtil::getCesiumGlobeAnchor(globeAnchor->getPrimPath()); - pxr::SdfPathVector targets; - if (!anchorApi.GetGeoreferenceBindingRel().GetForwardedTargets(&targets)) { - return; - } - // We only want to update an anchor if we are updating it's related Georeference Prim. - if (path != targets[0]) { + if (path != + UsdUtil::getAnchorGeoreferencePath(globeAnchor->getPrimPath()).value_or(pxr::SdfPath::EmptyPath())) { continue; } - auto georeferenceOrigin = UsdUtil::getCesiumGeoreference(targets[0]); - auto origin = GeospatialUtil::convertGeoreferenceToCartographic(georeferenceOrigin); + auto origin = UsdUtil::getCartographicOriginForAnchor(globeAnchor->getPrimPath()); + if (!origin.has_value()) { + continue; + } - GeospatialUtil::updateAnchorOrigin(origin, anchorApi, globeAnchor); + GeospatialUtil::updateAnchorOrigin(origin.value(), anchorApi, globeAnchor); } } @@ -335,32 +341,31 @@ void Context::processCesiumGlobeAnchorChanged(const cesium::omniverse::ChangedPr const auto& [path, name, primType, changeType] = changedPrim; auto globeAnchor = UsdUtil::getCesiumGlobeAnchor(path); - pxr::SdfPathVector targets; - if (!globeAnchor.GetGeoreferenceBindingRel().GetForwardedTargets(&targets)) { + auto origin = UsdUtil::getCartographicOriginForAnchor(path); + + if (!origin.has_value()) { return; } - auto georeferenceOrigin = UsdUtil::getCesiumGeoreference(targets[0]); - auto cartographicOrigin = GeospatialUtil::convertGeoreferenceToCartographic(georeferenceOrigin); bool detectTransformChanges; globeAnchor.GetDetectTransformChangesAttr().Get(&detectTransformChanges); if (detectTransformChanges && (name == pxr::CesiumTokens->cesiumAnchorDetectTransformChanges || name == pxr::UsdTokens->xformOp_transform_cesium)) { - GeospatialUtil::updateAnchorByUsdTransform(cartographicOrigin, globeAnchor); + GeospatialUtil::updateAnchorByUsdTransform(origin.value(), globeAnchor); return; } if (name == pxr::CesiumTokens->cesiumAnchorGeographicCoordinates) { - GeospatialUtil::updateAnchorByLatLongHeight(cartographicOrigin, globeAnchor); + GeospatialUtil::updateAnchorByLatLongHeight(origin.value(), globeAnchor); return; } if (name == pxr::CesiumTokens->cesiumAnchorPosition || name == pxr::CesiumTokens->cesiumAnchorRotation || name == pxr::CesiumTokens->cesiumAnchorScale) { - GeospatialUtil::updateAnchorByFixedTransform(cartographicOrigin, globeAnchor); + GeospatialUtil::updateAnchorByFixedTransform(origin.value(), globeAnchor); return; } @@ -403,6 +408,11 @@ void Context::processPrimAdded(const ChangedPrim& changedPrim) { const auto tilesetPath = changedPrim.path.GetParentPath(); AssetRegistry::getInstance().addImagery(imageryPath); reloadTileset(tilesetPath); + } else if (changedPrim.primType == ChangedPrimType::CESIUM_GLOBE_ANCHOR) { + auto anchorApi = UsdUtil::getCesiumGlobeAnchor(changedPrim.path); + auto origin = UsdUtil::getCartographicOriginForAnchor(changedPrim.path); + assert(origin.has_value()); + GeospatialUtil::updateAnchorByUsdTransform(origin.value(), anchorApi); } } @@ -845,10 +855,6 @@ void Context::addGlobeAnchorToPrim(const pxr::SdfPath& path) { // Until we support multiple georeference points, we should just use the default georeference object. auto georeferenceOrigin = UsdUtil::getOrCreateCesiumGeoreference(); globeAnchor.GetGeoreferenceBindingRel().AddTarget(georeferenceOrigin.GetPath()); - - const auto cartographicOrigin = GeospatialUtil::convertGeoreferenceToCartographic(georeferenceOrigin); - - GeospatialUtil::updateAnchorByUsdTransform(cartographicOrigin, globeAnchor); } } // namespace cesium::omniverse diff --git a/src/core/src/UsdNotificationHandler.cpp b/src/core/src/UsdNotificationHandler.cpp index b85a19558..fefc298b4 100644 --- a/src/core/src/UsdNotificationHandler.cpp +++ b/src/core/src/UsdNotificationHandler.cpp @@ -126,7 +126,7 @@ void UsdNotificationHandler::onObjectsChanged(const pxr::UsdNotice::ObjectsChang void UsdNotificationHandler::onPrimAdded(const pxr::SdfPath& primPath) { const auto type = getType(primPath); - if (type != ChangedPrimType::OTHER && type != ChangedPrimType::CESIUM_GLOBE_ANCHOR) { + if (type != ChangedPrimType::OTHER) { _changedPrims.emplace_back(ChangedPrim{primPath, pxr::TfToken(), type, ChangeType::PRIM_ADDED}); CESIUM_LOG_INFO("Added prim: {}", primPath.GetText()); } diff --git a/src/core/src/UsdUtil.cpp b/src/core/src/UsdUtil.cpp index fc357c99a..3fc31a28f 100644 --- a/src/core/src/UsdUtil.cpp +++ b/src/core/src/UsdUtil.cpp @@ -559,4 +559,29 @@ std::optional getCesiumTransformOpValueForPathIfExists(const px return std::nullopt; } +std::optional getAnchorGeoreferencePath(const pxr::SdfPath& path) { + if (!hasCesiumGlobeAnchor(path)) { + return std::nullopt; + } + + auto globeAnchor = getCesiumGlobeAnchor(path); + pxr::SdfPathVector targets; + if (!globeAnchor.GetGeoreferenceBindingRel().GetForwardedTargets(&targets)) { + return std::nullopt; + } + + return targets[0]; +} + +std::optional getCartographicOriginForAnchor(const pxr::SdfPath& path) { + auto anchorGeoreferencePath = getAnchorGeoreferencePath(path); + + if (!anchorGeoreferencePath.has_value()) { + return std::nullopt; + } + + auto georeferenceOrigin = UsdUtil::getCesiumGeoreference(anchorGeoreferencePath.value()); + return GeospatialUtil::convertGeoreferenceToCartographic(georeferenceOrigin); +} + } // namespace cesium::omniverse::UsdUtil