Support scene metadata for USD models 10/319710/3
authorRichard Huang <r.huang@samsung.com>
Wed, 30 Oct 2024 15:46:56 +0000 (15:46 +0000)
committerRichard Huang <r.huang@samsung.com>
Wed, 30 Oct 2024 16:18:36 +0000 (16:18 +0000)
Change-Id: I7bf172c8734f2837958b6954695df6768b0627e0

automated-tests/resources/usd/CesiumMan.metadata [new file with mode: 0644]
automated-tests/src/dali-usd-loader/utc-Dali-UsdLoader.cpp
dali-usd-loader/internal/usd-loader-impl.cpp
dali-usd-loader/internal/usd-material-processor.cpp
dali-usd-loader/internal/usd-material-processor.h
dali-usd-loader/internal/usd-texture-converter.cpp
dali-usd-loader/internal/usd-texture-converter.h

diff --git a/automated-tests/resources/usd/CesiumMan.metadata b/automated-tests/resources/usd/CesiumMan.metadata
new file mode 100644 (file)
index 0000000..5a786dc
--- /dev/null
@@ -0,0 +1,11 @@
+ {
+    "images": [
+        {
+            "uri": "CesiumMan_img0.jpg",
+            "minWidth": 512,
+            "minHeight": 512,
+            "samplingMode": "BOX_THEN_LINEAR"
+        }
+    ]
+}
+
index 5f7d309e03129673726a3c6e2fd5e9105a876d55..a8a3ecb75edc213df85071212cf62f07a137fd13 100644 (file)
@@ -193,14 +193,14 @@ int UtcDaliUsdLoaderSuccess1(void)
     DALI_TEST_EQUAL(iTexture->mSemantic, uint32_t(MaterialDefinition::ALBEDO));
     DALI_TEST_EQUAL(iTexture->mTexture.mImageUri, "");
     DALI_TEST_EQUAL(uint32_t(iTexture->mTexture.mSamplerFlags), uint32_t(SamplerFlags::DEFAULT)); // don't interpret it as a character
-    DALI_TEST_EQUAL(iTexture->mTexture.mMinImageDimensions, ImageDimensions());
+    DALI_TEST_EQUAL(iTexture->mTexture.mMinImageDimensions, ImageDimensions(512, 512));
     DALI_TEST_EQUAL(iTexture->mTexture.mSamplingMode, SamplingMode::BOX_THEN_LINEAR);
     DALI_TEST_EQUAL(iTexture->mTexture.mTextureBuffer.size(), 209908u);
 
     auto& ts = materials[0u].second;
     DALI_TEST_EQUAL(ts.GetTextureCount(), 5u);
-    DALI_TEST_EQUAL(ts.GetTexture(0).GetWidth(), 1024);
-    DALI_TEST_EQUAL(ts.GetTexture(0).GetHeight(), 1024);
+    DALI_TEST_EQUAL(ts.GetTexture(0).GetWidth(), 512);
+    DALI_TEST_EQUAL(ts.GetTexture(0).GetHeight(), 512);
     DALI_TEST_EQUAL(ts.GetTexture(1).GetWidth(), 1);
     DALI_TEST_EQUAL(ts.GetTexture(1).GetHeight(), 1);
     DALI_TEST_EQUAL(ts.GetTexture(2).GetWidth(), 256);
index 93c2f2d2ebbf3f9faff56e1e1e28b9ca9701c23a..2035e29e5ef310e4a656ea814e98a0e67e4aa3e2 100644 (file)
@@ -324,7 +324,9 @@ bool UsdLoaderImpl::LoadModel(const std::string& url, Dali::Scene3D::Loader::Loa
 
 void UsdLoaderImpl::Impl::TraverseMaterials(LoadResult& output)
 {
-  UsdMaterialProcessor materialProcessor(mUsdStage, &mMaterialMap);
+  auto& imageMetaData = output.mSceneMetadata.mImageMetadata;
+
+  UsdMaterialProcessor materialProcessor(mUsdStage, &mMaterialMap, imageMetaData);
   materialProcessor.TraverseMaterials(output);
 }
 
index 007e64e552f1c49a192bb7ec7c79619e1175bb18..a925b614094878ca0fcb330f6f9a947809189967 100644 (file)
@@ -51,9 +51,10 @@ std::unordered_map<std::string, MaterialDefinition::Flags> SHADER_INPUT_NAME_TO_
     {"specularColor", MaterialDefinition::Flags::SPECULAR_COLOR}};
 } // namespace
 
-UsdMaterialProcessor::UsdMaterialProcessor(const UsdStageRefPtr& stage, MaterialMap* materialMap)
+UsdMaterialProcessor::UsdMaterialProcessor(const UsdStageRefPtr& stage, MaterialMap* materialMap, const ImageMetadataMap& imageMetaDataMap)
 : mUsdStage(stage),
-  mMaterialMap(materialMap)
+  mMaterialMap(materialMap),
+  mImageMetaDataMap(imageMetaDataMap)
 {
   // Initialize the map of shader input handlers
   mShaderInputHandlers =
@@ -275,7 +276,7 @@ void UsdMaterialProcessor::ProcessDiffuseColor(const UsdShadeInput& input, Mater
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "diffuseColorTexture: ");
-      materialDefinition.mNeedAlbedoTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::ALBEDO);
+      materialDefinition.mNeedAlbedoTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::ALBEDO);
       if(materialDefinition.mNeedAlbedoTexture)
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::ALBEDO, ");
@@ -310,7 +311,7 @@ void UsdMaterialProcessor::ProcessMetallic(const UsdShadeInput& input, MaterialD
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "metallicTexture: ");
-      materialDefinition.mNeedMetallicTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::METALLIC);
+      materialDefinition.mNeedMetallicTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::METALLIC);
       if(materialDefinition.mNeedMetallicTexture)
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::METALLIC, ");
@@ -339,7 +340,7 @@ void UsdMaterialProcessor::ProcessRoughness(const UsdShadeInput& input, Material
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "roughnessTexture: ");
-      materialDefinition.mNeedRoughnessTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::ROUGHNESS);
+      materialDefinition.mNeedRoughnessTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::ROUGHNESS);
       if(materialDefinition.mNeedRoughnessTexture)
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::MaterialDefinition::ROUGHNESS, ");
@@ -368,7 +369,7 @@ void UsdMaterialProcessor::ProcessNormal(const UsdShadeInput& input, MaterialDef
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "normalTexture: ");
-      materialDefinition.mNeedNormalTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::NORMAL);
+      materialDefinition.mNeedNormalTexture = mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::NORMAL);
       if(materialDefinition.mNeedNormalTexture)
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::NORMAL, ");
@@ -394,7 +395,7 @@ void UsdMaterialProcessor::ProcessOcclusion(const UsdShadeInput& input, Material
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "occlusionTexture: ");
-      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::OCCLUSION))
+      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::OCCLUSION))
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::OCCLUSION, ");
       }
@@ -419,7 +420,7 @@ void UsdMaterialProcessor::ProcessEmissiveColor(const UsdShadeInput& input, Mate
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "emissiveColorTexture: ");
-      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::EMISSIVE))
+      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::EMISSIVE))
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::EMISSIVE, ");
         materialDefinition.mEmissiveFactor = Vector3::ONE;
@@ -458,7 +459,7 @@ void UsdMaterialProcessor::ProcessSpecularColor(const UsdShadeInput& input, Mate
     {
       // Convert the texture and associate it with the material
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "specularColorTexture: ");
-      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, MaterialDefinition::SPECULAR_COLOR))
+      if(mUsdTextureConverter.ConvertTexture(material, uvTexture, materialDefinition, mImageMetaDataMap, MaterialDefinition::SPECULAR_COLOR))
       {
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TraverseMaterials: MaterialDefinition::SPECULAR_COLOR, ");
       }
index e0faf85a9ffaa353a1e2592067b2079196d051dd..00c2f5fec711b2cf82a2f467ecbc6720a1f684f4 100644 (file)
@@ -49,8 +49,9 @@ public:
    * @brief Constructor for MaterialProcessor.
    * @param stage The USD stage to traverse and process materials from.
    * @param materialMap The map of prim path and its corresponding material ID
+   * @param imageMetaDataMap The map of image files to their meta data
    */
-  UsdMaterialProcessor(const pxr::UsdStageRefPtr& stage, MaterialMap* materialMap);
+  UsdMaterialProcessor(const pxr::UsdStageRefPtr& stage, MaterialMap* materialMap, const ImageMetadataMap& imageMetaDataMap);
 
   /**
    * @brief Traverses the USD stage and processes all materials.
@@ -151,9 +152,10 @@ private:
   void ProcessSpecularColor(const pxr::UsdShadeInput& input, MaterialDefinition& materialDefinition, const pxr::UsdShadeMaterial& material, const pxr::UsdShadeShader& uvTexture);
 
 private:
-  pxr::UsdStageRefPtr mUsdStage;
-  MaterialMap*        mMaterialMap; ///< Maps prim paths to material IDs.
-  UsdTextureConverter mUsdTextureConverter;
+  pxr::UsdStageRefPtr     mUsdStage;
+  MaterialMap*            mMaterialMap;      ///< Maps prim paths to material IDs.
+  const ImageMetadataMap& mImageMetaDataMap; ///< Maps image files to their meta data
+  UsdTextureConverter     mUsdTextureConverter;
   using ShaderHandlerMap = std::unordered_map<MaterialDefinition::Flags, std::function<void(const pxr::UsdShadeInput&, MaterialDefinition&, const pxr::UsdShadeMaterial&, const pxr::UsdShadeShader&)>>;
   ShaderHandlerMap mShaderInputHandlers;
 };
index c018636bb9e158ee3da8cd9b6679f225b4d50499..6ec9439adb3d99106fcd853c9cfa34538fda1321 100644 (file)
@@ -19,6 +19,9 @@
 // FILE HEADER
 #include <dali-usd-loader/internal/usd-texture-converter.h>
 
+// EXTERNAL INCLUDES
+#include <filesystem>
+
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/loader/material-definition.h>
 #include <dali-usd-loader/internal/utils.h>
@@ -38,7 +41,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_USD
 
 UsdTextureConverter::UsdTextureConverter() = default;
 
-bool UsdTextureConverter::ConvertTexture(const UsdShadeMaterial& usdMaterial, const UsdShadeShader& usdUvTexture, MaterialDefinition& materialDefinition, uint32_t semantic)
+bool UsdTextureConverter::ConvertTexture(const UsdShadeMaterial& usdMaterial, const UsdShadeShader& usdUvTexture, MaterialDefinition& materialDefinition, const ImageMetadataMap& imageMetaDataMap, uint32_t semantic)
 {
   bool    transformOffsetAuthored = false;
   GfVec2f uvTransformOffset(0.0f, 0.0f);
@@ -55,7 +58,7 @@ bool UsdTextureConverter::ConvertTexture(const UsdShadeMaterial& usdMaterial, co
   std::unordered_map<std::string, std::function<void(const UsdShadeShader&)>> shaderProcessors = {
     {"UsdPrimvarReader_float2", [&](const UsdShadeShader& d) { ProcessUvChannel(d); }},
     {"UsdTransform2d", [&](const UsdShadeShader& d) { transformOffsetAuthored = Process2DTransform(d, uvTransformOffset, uvTransformRotation, uvTransformScale); }},
-    {"UsdUVTexture", [&](const UsdShadeShader& d) { textureProcessed = ProcessTextureAttributes(usdUvTexture, d, materialDefinition, semantic); }}};
+    {"UsdUVTexture", [&](const UsdShadeShader& d) { textureProcessed = ProcessTextureAttributes(usdUvTexture, d, materialDefinition, imageMetaDataMap, semantic); }}};
 
   // Iterate over shader dependencies and process the shader IDs
   for(const auto& d : deps)
@@ -139,7 +142,7 @@ void UsdTextureConverter::ProcessTransformRotation(const UsdShadeInput& input, f
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "UV Transform Rotation: %.7f", uvTransformRotation);
 }
 
-bool UsdTextureConverter::ProcessTextureAttributes(const UsdShadeShader& usdUvTexture, const UsdShadeShader& shader, MaterialDefinition& materialDefinition, uint32_t semantic)
+bool UsdTextureConverter::ProcessTextureAttributes(const UsdShadeShader& usdUvTexture, const UsdShadeShader& shader, MaterialDefinition& materialDefinition, const ImageMetadataMap& imageMetaDataMap, uint32_t semantic)
 {
   std::string    imagePath;
   UsdAssetBuffer imageBuffer;
@@ -166,10 +169,10 @@ bool UsdTextureConverter::ProcessTextureAttributes(const UsdShadeShader& usdUvTe
   }
 
   // Process the image buffer or path after extracting the texture attributes
-  return ProcessImageBuffer(materialDefinition, semantic, imagePath, imageBuffer);
+  return ProcessImageBuffer(materialDefinition, semantic, imagePath, imageBuffer, imageMetaDataMap);
 }
 
-void UsdTextureConverter::ProcessTextureFile(const UsdShadeInput& input, std::string& imagePath, std::vector<uint8_t>& imageBuffer)
+void UsdTextureConverter::ProcessTextureFile(const UsdShadeInput& input, std::string& imagePath, UsdAssetBuffer& imageBuffer)
 {
   SdfAssetPath fileInput;
   input.Get<SdfAssetPath>(&fileInput);
@@ -219,12 +222,23 @@ void UsdTextureConverter::ProcessTextureFallback(const UsdShadeInput& input)
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "fallback: %.7f, %.7f, %.7f, %.7f, ", fallback[0], fallback[1], fallback[2], fallback[3]);
 }
 
-bool UsdTextureConverter::ProcessImageBuffer(MaterialDefinition& materialDefinition, uint32_t semantic, const std::string& imagePath, UsdAssetBuffer& imageBuffer)
+bool UsdTextureConverter::ProcessImageBuffer(MaterialDefinition& materialDefinition, uint32_t semantic, const std::string& imagePath, UsdAssetBuffer& imageBuffer, const ImageMetadataMap& imageMetaDataMap)
 {
+  std::string imageFileName = std::filesystem::path(imagePath).filename().string();
+
+  ImageMetadata metaData;
+  if(!imageFileName.empty())
+  {
+    if(auto search = imageMetaDataMap.find(imageFileName); search != imageMetaDataMap.end())
+    {
+      metaData = search->second;
+    }
+  }
+
   if(imageBuffer.size() > 0)
   {
     // If the image buffer is valid, push it to the material definition as a texture stage
-    materialDefinition.mTextureStages.push_back({semantic, TextureDefinition{std::move(imageBuffer)}});
+    materialDefinition.mTextureStages.push_back({semantic, TextureDefinition{std::move(imageBuffer), SamplerFlags::DEFAULT, metaData.mMinSize, metaData.mSamplingMode}});
     materialDefinition.mFlags |= semantic;
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Image Buffer Processed: semantic: %u", semantic);
     return true;
@@ -232,7 +246,7 @@ bool UsdTextureConverter::ProcessImageBuffer(MaterialDefinition& materialDefinit
   else if(!imagePath.empty())
   {
     // If we have a valid image path, push it to the material definition
-    materialDefinition.mTextureStages.push_back({semantic, TextureDefinition{std::move(imagePath)}});
+    materialDefinition.mTextureStages.push_back({semantic, TextureDefinition{std::move(imagePath), SamplerFlags::DEFAULT, metaData.mMinSize, metaData.mSamplingMode}});
     materialDefinition.mFlags |= semantic;
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Image Path Processed: semantic: %u, imagePath: %s", semantic, imagePath.c_str());
     return true;
index 5864318bdd0bf9dfc99ba060caab82ea510758a6..59f22fbd3a100b255b9b0e477cc182dc7676d811 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/load-scene-metadata.h>
 #include <dali-usd-loader/internal/utils.h>
 
 namespace Dali::Scene3D::Loader
 {
 class MaterialDefinition;
 
+using ImageMetadataMap = std::unordered_map<std::string, ImageMetadata>;
+
 /**
  * @class UsdTextureConverter
  * @brief Handles the conversion of textures for materials in USD models.
@@ -58,9 +61,10 @@ public:
    * @param usdUvTexture The USD shader representing the UV texture.
    * @param materialDefinition The material definition to which the texture will be added.
    * @param semantic The semantic value used to identify the type of texture (e.g., albedo, normal map).
+   * @param imageMetaDataMap The map of image files to their meta data
    * @return True if the texture was successfully converted and added to the material definition, false otherwise.
    */
-  bool ConvertTexture(const pxr::UsdShadeMaterial& usdMaterial, const pxr::UsdShadeShader& usdUvTexture, MaterialDefinition& materialDefinition, uint32_t semantic);
+  bool ConvertTexture(const pxr::UsdShadeMaterial& usdMaterial, const pxr::UsdShadeShader& usdUvTexture, MaterialDefinition& materialDefinition, const ImageMetadataMap& imageMetaDataMap, uint32_t semantic);
 
 private:
   /**
@@ -118,9 +122,10 @@ private:
    * @param shader The USD shader representing the texture attributes.
    * @param materialDefinition The material definition to which the texture properties will be applied.
    * @param semantic The semantic value identifying the texture type.
+   * @param imageMetaDataMap The map of image files to their meta data
    * @return True if texture attributes were successfully processed and added to the material definition, false otherwise.
    */
-  bool ProcessTextureAttributes(const pxr::UsdShadeShader& usdUvTexture, const pxr::UsdShadeShader& shader, MaterialDefinition& materialDefinition, uint32_t semantic);
+  bool ProcessTextureAttributes(const pxr::UsdShadeShader& usdUvTexture, const pxr::UsdShadeShader& shader, MaterialDefinition& materialDefinition, const ImageMetadataMap& imageMetaDataMap, uint32_t semantic);
 
   /**
    * @brief Processes the texture file input and retrieves the image path or buffer.
@@ -170,9 +175,10 @@ private:
    * @param semantic The semantic value used to identify the type of texture (e.g., albedo, normal map).
    * @param imagePath The file path of the texture image.
    * @param imageBuffer The image buffer of the texture.
+   * @param imageMetaDataMap The map of image files to their meta data
    * @return True if the texture was successfully processed, false otherwise.
    */
-  bool ProcessImageBuffer(MaterialDefinition& materialDefinition, uint32_t semantic, const std::string& imagePath, UsdAssetBuffer& imageBuffer);
+  bool ProcessImageBuffer(MaterialDefinition& materialDefinition, uint32_t semantic, const std::string& imagePath, UsdAssetBuffer& imageBuffer, const ImageMetadataMap& imageMetaDataMap);
 };
 } // namespace Dali::Scene3D::Loader