Skip to content

Commit

Permalink
Merge pull request #662 from CesiumGS/globe-anchor-additional-ops
Browse files Browse the repository at this point in the history
Allow globe anchors to be applied to prims with other xform ops
  • Loading branch information
lilleyse authored Feb 1, 2024
2 parents aa49309 + 9ba954a commit 9c44819
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 152 deletions.
234 changes: 118 additions & 116 deletions src/core/src/FabricMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,122 +1518,124 @@ void FabricMaterial::setMaterial(

const auto& properties = _materialDescriptor.getStyleableProperties();

const auto getPropertyPath = [this, &properties](const std::string& propertyId) {
const auto index = CppUtil::indexOfByMember(properties, &FabricPropertyDescriptor::propertyId, propertyId);
assert(index != properties.size());
return _propertyPaths[index];
};

const auto unsupportedCallback = []([[maybe_unused]] const std::string& propertyId,
[[maybe_unused]] const std::string& warning) {};

MetadataUtil::forEachStyleablePropertyAttributeProperty(
*_pContext,
model,
primitive,
[this, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyAttributePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& primvarName = property.attribute;
const auto& propertyPath = getPropertyPath(propertyId);
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyAttributePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
primvarName,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);

MetadataUtil::forEachStyleablePropertyTextureProperty(
*_pContext,
model,
primitive,
[this, &propertyTextures, &texcoordIndexMapping, &propertyTextureIndexMapping, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyTexturePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& textureInfo = property.textureInfo;
const auto textureIndex = property.textureIndex;
const auto& propertyPath = getPropertyPath(propertyId);
const auto texcoordIndex = texcoordIndexMapping.at(textureInfo.setIndex);
const auto propertyTextureIndex = propertyTextureIndexMapping.at(textureIndex);
const auto& textureAssetPath = propertyTextures[propertyTextureIndex]->getAssetPathToken();
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyTexturePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
textureAssetPath,
textureInfo,
texcoordIndex,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);

uint64_t propertyTablePropertyCounter = 0;

MetadataUtil::forEachStyleablePropertyTableProperty(
*_pContext,
model,
primitive,
[this, &propertyTableTextures, &propertyTablePropertyCounter, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyTablePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& propertyPath = getPropertyPath(propertyId);
const auto textureIndex = propertyTablePropertyCounter++;
const auto& textureAssetPath = propertyTableTextures[textureIndex]->getAssetPathToken();
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyTablePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
textureAssetPath,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);
if (!properties.empty()) {
const auto getPropertyPath = [this, &properties](const std::string& propertyId) {
const auto index = CppUtil::indexOfByMember(properties, &FabricPropertyDescriptor::propertyId, propertyId);
assert(index != properties.size());
return _propertyPaths[index];
};

const auto unsupportedCallback = []([[maybe_unused]] const std::string& propertyId,
[[maybe_unused]] const std::string& warning) {};

MetadataUtil::forEachStyleablePropertyAttributeProperty(
*_pContext,
model,
primitive,
[this, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyAttributePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& primvarName = property.attribute;
const auto& propertyPath = getPropertyPath(propertyId);
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyAttributePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
primvarName,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);

MetadataUtil::forEachStyleablePropertyTextureProperty(
*_pContext,
model,
primitive,
[this, &propertyTextures, &texcoordIndexMapping, &propertyTextureIndexMapping, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyTexturePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& textureInfo = property.textureInfo;
const auto textureIndex = property.textureIndex;
const auto& propertyPath = getPropertyPath(propertyId);
const auto texcoordIndex = texcoordIndexMapping.at(textureInfo.setIndex);
const auto propertyTextureIndex = propertyTextureIndexMapping.at(textureIndex);
const auto& textureAssetPath = propertyTextures[propertyTextureIndex]->getAssetPathToken();
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyTexturePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
textureAssetPath,
textureInfo,
texcoordIndex,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);

uint64_t propertyTablePropertyCounter = 0;

MetadataUtil::forEachStyleablePropertyTableProperty(
*_pContext,
model,
primitive,
[this, &propertyTableTextures, &propertyTablePropertyCounter, &getPropertyPath](
const std::string& propertyId,
[[maybe_unused]] const auto& propertyTablePropertyView,
const auto& property) {
constexpr auto type = std::decay_t<decltype(property)>::Type;
constexpr auto mdlType = DataTypeUtil::getMdlInternalPropertyType<type>();
const auto& propertyPath = getPropertyPath(propertyId);
const auto textureIndex = propertyTablePropertyCounter++;
const auto& textureAssetPath = propertyTableTextures[textureIndex]->getAssetPathToken();
const auto& propertyInfo = property.propertyInfo;
const auto hasNoData = propertyInfo.noData.has_value();
const auto offset = getOffset(propertyInfo);
const auto scale = getScale(propertyInfo);
const auto noData = getNoData(propertyInfo);
const auto defaultValue = getDefaultValue(propertyInfo);
constexpr auto maximumValue = getMaximumValue<type>();

setPropertyTablePropertyValues<mdlType>(
_pContext->getFabricStage(),
propertyPath,
textureAssetPath,
offset,
scale,
maximumValue,
hasNoData,
noData,
defaultValue);
},
unsupportedCallback);
}

for (const auto& path : _allPaths) {
auto& fabricStage = _pContext->getFabricStage();
Expand Down
26 changes: 24 additions & 2 deletions src/core/src/OmniGlobeAnchor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ bool OmniGlobeAnchor::isAnchorValid() const {

if (!xformOps) {
_pContext->getLogger()->oneTimeWarning(
"Globe anchor xform op order must [translate, rotate, scale] without additional transforms.",
"Globe anchor xform op order must be [translate, rotate, scale] followed by any additional transforms.",
_path.GetText());
return false;
}
Expand All @@ -225,16 +225,38 @@ void OmniGlobeAnchor::initialize() {
return;
}

// This function has the effect of baking the world transform into the local transform, which is unavoidable
// when using globe anchors.

const auto cesiumGlobeAnchor = UsdUtil::getCesiumGlobeAnchor(_pContext->getUsdStage(), _path);
const auto xformable = pxr::UsdGeomXformable(cesiumGlobeAnchor.GetPrim());

bool resetsXformStack;
const auto originalXformOps = xformable.GetOrderedXformOps(&resetsXformStack);
const auto translateRotateScaleXformOps = {originalXformOps[0], originalXformOps[1], originalXformOps[2]};

// Only use translate, rotate, and scale ops when computing the local to ecef transform.
// Additional transforms like xformOp:rotateX:unitsResolve are not baked into this transform.
xformable.SetXformOpOrder(translateRotateScaleXformOps);

// Compute the local to ecef transform
const auto primLocalToEcefTransform =
UsdUtil::computePrimLocalToEcefTransform(*_pContext, getResolvedGeoreferencePath(), _path);

// Initialize the globe anchor from the prim's local transform
// Now that the transform is computed, switch back to the original ops
xformable.SetXformOpOrder(originalXformOps);

// Disable inheriting parent transforms from now on
xformable.SetResetXformStack(true);

// Initialize the globe anchor
_pAnchor = std::make_unique<CesiumGeospatial::GlobeAnchor>(primLocalToEcefTransform);

// Use the ecef transform (if set) or geographic coordinates (if set) to reposition the globe anchor.
updateByEcefPosition();
updateByGeographicCoordinates();

// Update ecef position, geographic coordinates, and prim local transform from the globe anchor transform
finalize();
}

Expand Down
Loading

0 comments on commit 9c44819

Please sign in to comment.