diff --git a/CMakeLists.txt b/CMakeLists.txt index 2642c31..968569e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,20 +154,20 @@ endif() set(LIB_SOURCE_FILES src/FBX2glTF.h + src/fbx/materials/3dsMaxPhysicalMaterial.cpp + src/fbx/materials/FbxMaterials.cpp + src/fbx/materials/FbxMaterials.hpp + src/fbx/materials/RoughnessMetallicMaterials.hpp + src/fbx/materials/StingrayPBSMaterial.cpp + src/fbx/materials/TraditionalMaterials.cpp + src/fbx/materials/TraditionalMaterials.hpp src/fbx/Fbx2Raw.cpp src/fbx/Fbx2Raw.hpp src/fbx/FbxBlendShapesAccess.cpp src/fbx/FbxBlendShapesAccess.hpp src/fbx/FbxLayerElementAccess.hpp - src/fbx/FbxMaterialInfo.hpp - src/fbx/FbxMaterialsAccess.cpp - src/fbx/FbxMaterialsAccess.hpp - src/fbx/FbxRoughMetMaterialInfo.cpp - src/fbx/FbxRoughMetMaterialInfo.hpp src/fbx/FbxSkinningAccess.cpp src/fbx/FbxSkinningAccess.hpp - src/fbx/FbxTraditionalMaterialInfo.cpp - src/fbx/FbxTraditionalMaterialInfo.hpp src/gltf/Raw2Gltf.cpp src/gltf/Raw2Gltf.hpp src/gltf/GltfModel.cpp diff --git a/src/fbx/Fbx2Raw.cpp b/src/fbx/Fbx2Raw.cpp index 511e423..5695dbc 100644 --- a/src/fbx/Fbx2Raw.cpp +++ b/src/fbx/Fbx2Raw.cpp @@ -29,8 +29,9 @@ #include "FbxBlendShapesAccess.hpp" #include "FbxLayerElementAccess.hpp" -#include "FbxMaterialsAccess.hpp" #include "FbxSkinningAccess.hpp" +#include "materials/RoughnessMetallicMaterials.hpp" +#include "materials/TraditionalMaterials.hpp" float scaleFactor; @@ -236,7 +237,7 @@ static void ReadMesh( FbxRoughMetMaterialInfo* fbxMatInfo = static_cast(fbxMaterial.get()); - maybeAddTexture(fbxMatInfo->texColor, RAW_TEXTURE_USAGE_ALBEDO); + maybeAddTexture(fbxMatInfo->texBaseColor, RAW_TEXTURE_USAGE_ALBEDO); maybeAddTexture(fbxMatInfo->texNormal, RAW_TEXTURE_USAGE_NORMAL); maybeAddTexture(fbxMatInfo->texEmissive, RAW_TEXTURE_USAGE_EMISSIVE); maybeAddTexture(fbxMatInfo->texRoughness, RAW_TEXTURE_USAGE_ROUGHNESS); @@ -244,8 +245,8 @@ static void ReadMesh( maybeAddTexture(fbxMatInfo->texAmbientOcclusion, RAW_TEXTURE_USAGE_OCCLUSION); rawMatProps.reset(new RawMetRoughMatProps( RAW_SHADING_MODEL_PBR_MET_ROUGH, - toVec4f(fbxMatInfo->colBase), - toVec3f(fbxMatInfo->colEmissive), + toVec4f(fbxMatInfo->baseColor), + toVec3f(fbxMatInfo->emissive), fbxMatInfo->emissiveIntensity, fbxMatInfo->metallic, fbxMatInfo->roughness)); diff --git a/src/fbx/FbxMaterialInfo.hpp b/src/fbx/FbxMaterialInfo.hpp deleted file mode 100644 index aa23ece..0000000 --- a/src/fbx/FbxMaterialInfo.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#pragma once - -#include "FBX2glTF.h" - -class FbxMaterialInfo { - public: - FbxMaterialInfo(const FbxString& name, const FbxString& shadingModel) - : name(name), shadingModel(shadingModel) {} - - const FbxString name; - const FbxString shadingModel; -}; diff --git a/src/fbx/FbxMaterialsAccess.cpp b/src/fbx/FbxMaterialsAccess.cpp deleted file mode 100644 index 5063a7b..0000000 --- a/src/fbx/FbxMaterialsAccess.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include "FbxMaterialsAccess.hpp" -#include "Fbx2Raw.hpp" - -FbxMaterialsAccess::FbxMaterialsAccess( - const FbxMesh* pMesh, - const std::map& textureLocations) - : mappingMode(FbxGeometryElement::eNone), mesh(nullptr), indices(nullptr) { - if (pMesh->GetElementMaterialCount() <= 0) { - return; - } - - const FbxGeometryElement::EMappingMode materialMappingMode = - pMesh->GetElementMaterial()->GetMappingMode(); - if (materialMappingMode != FbxGeometryElement::eByPolygon && - materialMappingMode != FbxGeometryElement::eAllSame) { - return; - } - - const FbxGeometryElement::EReferenceMode materialReferenceMode = - pMesh->GetElementMaterial()->GetReferenceMode(); - if (materialReferenceMode != FbxGeometryElement::eIndexToDirect) { - return; - } - - mappingMode = materialMappingMode; - mesh = pMesh; - indices = &pMesh->GetElementMaterial()->GetIndexArray(); - - for (int ii = 0; ii < indices->GetCount(); ii++) { - int materialNum = indices->GetAt(ii); - if (materialNum < 0) { - continue; - } - - FbxSurfaceMaterial* surfaceMaterial = - mesh->GetNode()->GetSrcObject(materialNum); - - if (materialNum >= summaries.size()) { - summaries.resize(materialNum + 1); - } - auto summary = summaries[materialNum]; - if (summary == nullptr) { - summary = summaries[materialNum] = GetMaterialInfo(surfaceMaterial, textureLocations); - } - - if (materialNum >= userProperties.size()) { - userProperties.resize(materialNum + 1); - } - if (userProperties[materialNum].empty()) { - FbxProperty objectProperty = surfaceMaterial->GetFirstProperty(); - while (objectProperty.IsValid()) { - if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) { - userProperties[materialNum].push_back(TranscribeProperty(objectProperty).dump()); - } - objectProperty = surfaceMaterial->GetNextProperty(objectProperty); - } - } - } -} - -const std::shared_ptr FbxMaterialsAccess::GetMaterial( - const int polygonIndex) const { - if (mappingMode != FbxGeometryElement::eNone) { - const int materialNum = - indices->GetAt((mappingMode == FbxGeometryElement::eByPolygon) ? polygonIndex : 0); - if (materialNum < 0) { - return nullptr; - } - return summaries.at((unsigned long)materialNum); - } - return nullptr; -} - -const std::vector FbxMaterialsAccess::GetUserProperties(const int polygonIndex) const { - if (mappingMode != FbxGeometryElement::eNone) { - const int materialNum = - indices->GetAt((mappingMode == FbxGeometryElement::eByPolygon) ? polygonIndex : 0); - if (materialNum < 0) { - return std::vector(); - } - return userProperties.at((unsigned long)materialNum); - } - return std::vector(); -} - -std::unique_ptr FbxMaterialsAccess::GetMaterialInfo( - FbxSurfaceMaterial* material, - const std::map& textureLocations) { - std::unique_ptr res; - res = FbxRoughMetMaterialInfo::From(material, textureLocations); - if (!res) { - res = FbxTraditionalMaterialInfo::From(material, textureLocations); - } - return res; -} diff --git a/src/fbx/FbxMaterialsAccess.hpp b/src/fbx/FbxMaterialsAccess.hpp deleted file mode 100644 index 9e7c8a3..0000000 --- a/src/fbx/FbxMaterialsAccess.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#pragma once - -#include "Fbx2Raw.hpp" -#include "FbxMaterialInfo.hpp" -#include "FbxRoughMetMaterialInfo.hpp" -#include "FbxTraditionalMaterialInfo.hpp" - -class FbxMaterialsAccess { - public: - FbxMaterialsAccess( - const FbxMesh* pMesh, - const std::map& textureLocations); - - const std::shared_ptr GetMaterial(const int polygonIndex) const; - - const std::vector GetUserProperties(const int polygonIndex) const; - - std::unique_ptr GetMaterialInfo( - FbxSurfaceMaterial* material, - const std::map& textureLocations); - - private: - FbxGeometryElement::EMappingMode mappingMode; - std::vector> summaries{}; - std::vector> userProperties; - const FbxMesh* mesh; - const FbxLayerElementArrayTemplate* indices; -}; diff --git a/src/fbx/FbxRoughMetMaterialInfo.cpp b/src/fbx/FbxRoughMetMaterialInfo.cpp deleted file mode 100644 index 10271a6..0000000 --- a/src/fbx/FbxRoughMetMaterialInfo.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include "FbxRoughMetMaterialInfo.hpp" - -std::unique_ptr FbxRoughMetMaterialInfo::From( - FbxSurfaceMaterial* fbxMaterial, - const std::map& textureLocations) { - std::unique_ptr res( - new FbxRoughMetMaterialInfo(fbxMaterial->GetName(), FBX_SHADER_METROUGH)); - - const FbxProperty mayaProp = fbxMaterial->FindProperty("Maya"); - if (mayaProp.GetPropertyDataType() != FbxCompoundDT) { - return nullptr; - } - if (!fbxMaterial->ShadingModel.Get().IsEmpty()) { - ::fmt::printf( - "Warning: Material %s has surprising shading model: %s\n", - fbxMaterial->GetName(), - fbxMaterial->ShadingModel.Get()); - } - - auto getTex = [&](std::string propName) { - const FbxFileTexture* ptr = nullptr; - - const FbxProperty useProp = mayaProp.FindHierarchical(("use_" + propName + "_map").c_str()); - if (useProp.IsValid() && useProp.Get()) { - const FbxProperty texProp = mayaProp.FindHierarchical(("TEX_" + propName + "_map").c_str()); - if (texProp.IsValid()) { - ptr = texProp.GetSrcObject(); - if (ptr != nullptr && textureLocations.find(ptr) == textureLocations.end()) { - ptr = nullptr; - } - } - } else if (verboseOutput && useProp.IsValid()) { - fmt::printf( - "Note: Property '%s' of material '%s' exists, but is flagged as 'do not use'.\n", - propName, - fbxMaterial->GetName()); - } - return ptr; - }; - - auto getVec = [&](std::string propName) -> FbxDouble3 { - const FbxProperty vecProp = mayaProp.FindHierarchical(propName.c_str()); - return vecProp.IsValid() ? vecProp.Get() : FbxDouble3(1, 1, 1); - }; - - auto getVal = [&](std::string propName) -> FbxDouble { - const FbxProperty vecProp = mayaProp.FindHierarchical(propName.c_str()); - return vecProp.IsValid() ? vecProp.Get() : 0; - }; - - res->texNormal = getTex("normal"); - res->texColor = getTex("color"); - res->colBase = getVec("base_color"); - res->texAmbientOcclusion = getTex("ao"); - res->texEmissive = getTex("emissive"); - res->colEmissive = getVec("emissive"); - res->emissiveIntensity = getVal("emissive_intensity"); - res->texMetallic = getTex("metallic"); - res->metallic = getVal("metallic"); - res->texRoughness = getTex("roughness"); - res->roughness = getVal("roughness"); - - return res; -} diff --git a/src/fbx/FbxRoughMetMaterialInfo.hpp b/src/fbx/FbxRoughMetMaterialInfo.hpp deleted file mode 100644 index f954c1d..0000000 --- a/src/fbx/FbxRoughMetMaterialInfo.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "FbxMaterialInfo.hpp" - -struct FbxRoughMetMaterialInfo : FbxMaterialInfo { - static constexpr const char* FBX_SHADER_METROUGH = "MetallicRoughness"; - - static std::unique_ptr From( - FbxSurfaceMaterial* fbxMaterial, - const std::map& textureLocations); - - FbxRoughMetMaterialInfo(const FbxString& name, const FbxString& shadingModel) - : FbxMaterialInfo(name, shadingModel) {} - - const FbxFileTexture* texColor{}; - FbxVector4 colBase{}; - const FbxFileTexture* texNormal{}; - const FbxFileTexture* texMetallic{}; - FbxDouble metallic{}; - const FbxFileTexture* texRoughness{}; - FbxDouble roughness{}; - const FbxFileTexture* texEmissive{}; - FbxVector4 colEmissive{}; - FbxDouble emissiveIntensity{}; - const FbxFileTexture* texAmbientOcclusion{}; -}; diff --git a/src/fbx/FbxTraditionalMaterialInfo.cpp b/src/fbx/FbxTraditionalMaterialInfo.cpp deleted file mode 100644 index 370973d..0000000 --- a/src/fbx/FbxTraditionalMaterialInfo.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include "FbxTraditionalMaterialInfo.hpp" - -std::unique_ptr FbxTraditionalMaterialInfo::From( - FbxSurfaceMaterial* fbxMaterial, - const std::map& textureLocations) { - auto getSurfaceScalar = [&](const char* propName) -> std::tuple { - const FbxProperty prop = fbxMaterial->FindProperty(propName); - - FbxDouble val(0); - FbxFileTexture* tex = prop.GetSrcObject(); - if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) { - tex = nullptr; - } - if (tex == nullptr && prop.IsValid()) { - val = prop.Get(); - } - return std::make_tuple(val, tex); - }; - - auto getSurfaceVector = [&](const char* propName) -> std::tuple { - const FbxProperty prop = fbxMaterial->FindProperty(propName); - - FbxDouble3 val(1, 1, 1); - FbxFileTexture* tex = prop.GetSrcObject(); - if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) { - tex = nullptr; - } - if (tex == nullptr && prop.IsValid()) { - val = prop.Get(); - } - return std::make_tuple(val, tex); - }; - - auto getSurfaceValues = - [&](const char* colName, - const char* facName) -> std::tuple { - const FbxProperty colProp = fbxMaterial->FindProperty(colName); - const FbxProperty facProp = fbxMaterial->FindProperty(facName); - - FbxDouble3 colorVal(1, 1, 1); - FbxDouble factorVal(1); - - FbxFileTexture* colTex = colProp.GetSrcObject(); - if (colTex != nullptr && textureLocations.find(colTex) == textureLocations.end()) { - colTex = nullptr; - } - if (colTex == nullptr && colProp.IsValid()) { - colorVal = colProp.Get(); - } - FbxFileTexture* facTex = facProp.GetSrcObject(); - if (facTex != nullptr && textureLocations.find(facTex) == textureLocations.end()) { - facTex = nullptr; - } - if (facTex == nullptr && facProp.IsValid()) { - factorVal = facProp.Get(); - } - - auto val = FbxVector4( - colorVal[0] * factorVal, colorVal[1] * factorVal, colorVal[2] * factorVal, factorVal); - return std::make_tuple(val, colTex, facTex); - }; - - std::string name = fbxMaterial->GetName(); - std::unique_ptr res( - new FbxTraditionalMaterialInfo(name.c_str(), fbxMaterial->ShadingModel.Get())); - - // four properties are on the same structure and follow the same rules - auto handleBasicProperty = [&](const char* colName, - const char* facName) -> std::tuple { - FbxFileTexture *colTex, *facTex; - FbxVector4 vec; - - std::tie(vec, colTex, facTex) = getSurfaceValues(colName, facName); - if (colTex) { - if (facTex) { - fmt::printf( - "Warning: Mat [%s]: Can't handle both %s and %s textures; discarding %s.\n", - name, - colName, - facName, - facName); - } - return std::make_tuple(vec, colTex); - } - return std::make_tuple(vec, facTex); - }; - - std::tie(res->colAmbient, res->texAmbient) = - handleBasicProperty(FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor); - std::tie(res->colSpecular, res->texSpecular) = - handleBasicProperty(FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor); - std::tie(res->colDiffuse, res->texDiffuse) = - handleBasicProperty(FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor); - std::tie(res->colEmissive, res->texEmissive) = - handleBasicProperty(FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor); - - // the normal map can only ever be a map, ignore everything else - tie(std::ignore, res->texNormal) = getSurfaceVector(FbxSurfaceMaterial::sNormalMap); - - // shininess can be a map or a factor; afaict the map is always 'ShininessExponent' and the - // value is always found in 'Shininess' but only sometimes in 'ShininessExponent'. - tie(std::ignore, res->texShininess) = getSurfaceScalar("ShininessExponent"); - tie(res->shininess, std::ignore) = getSurfaceScalar("Shininess"); - - // for transparency we just want a constant vector value; - FbxVector4 transparency; - // extract any existing textures only so we can warn that we're throwing them away - FbxFileTexture *colTex, *facTex; - std::tie(transparency, colTex, facTex) = getSurfaceValues( - FbxSurfaceMaterial::sTransparentColor, FbxSurfaceMaterial::sTransparencyFactor); - if (colTex) { - fmt::printf( - "Warning: Mat [%s]: Can't handle texture for %s; discarding.\n", - name, - FbxSurfaceMaterial::sTransparentColor); - } - if (facTex) { - fmt::printf( - "Warning: Mat [%s]: Can't handle texture for %s; discarding.\n", - name, - FbxSurfaceMaterial::sTransparencyFactor); - } - // FBX color is RGB, so we calculate the A channel as the average of the FBX transparency color - // vector - res->colDiffuse[3] = 1.0 - (transparency[0] + transparency[1] + transparency[2]) / 3.0; - - return res; -} diff --git a/src/fbx/FbxTraditionalMaterialInfo.hpp b/src/fbx/FbxTraditionalMaterialInfo.hpp deleted file mode 100644 index edb23b6..0000000 --- a/src/fbx/FbxTraditionalMaterialInfo.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "FbxMaterialInfo.hpp" - -struct FbxTraditionalMaterialInfo : FbxMaterialInfo { - static constexpr const char* FBX_SHADER_LAMBERT = "Lambert"; - static constexpr const char* FBX_SHADER_BLINN = "Blinn"; - static constexpr const char* FBX_SHADER_PHONG = "Phong"; - - FbxTraditionalMaterialInfo(const FbxString& name, const FbxString& shadingModel) - : FbxMaterialInfo(name, shadingModel) {} - - FbxFileTexture* texAmbient{}; - FbxVector4 colAmbient{}; - FbxFileTexture* texSpecular{}; - FbxVector4 colSpecular{}; - FbxFileTexture* texDiffuse{}; - FbxVector4 colDiffuse{}; - FbxFileTexture* texEmissive{}; - FbxVector4 colEmissive{}; - FbxFileTexture* texNormal{}; - FbxFileTexture* texShininess{}; - FbxDouble shininess{}; - - static std::unique_ptr From( - FbxSurfaceMaterial* fbxMaterial, - const std::map& textureLocations); -}; diff --git a/src/fbx/materials/3dsMaxPhysicalMaterial.cpp b/src/fbx/materials/3dsMaxPhysicalMaterial.cpp index deb0cc1..86b0913 100644 --- a/src/fbx/materials/3dsMaxPhysicalMaterial.cpp +++ b/src/fbx/materials/3dsMaxPhysicalMaterial.cpp @@ -73,34 +73,34 @@ std::unique_ptr Fbx3dsMaxPhysicalMaterialResolver::reso } // TODO: attempt to bake transparency > 0.0f into the alpha of baseColour? - double transparency = getValue(props, "transparency", 0.0); - const auto* transparencyMap = getTex("transparency"); + // double transparency = getValue(props, "transparency", 0.0); + // const auto* transparencyMap = getTex("transparency"); // SSS: not supported - double scattering = getValue(props, "scattering", 0.0); - const auto* scatteringMap = getTex("scattering"); + // double scattering = getValue(props, "scattering", 0.0); + // const auto* scatteringMap = getTex("scattering"); // reflectivity: not supported - double reflectivityWeight = getValue(props, "reflectivity", 1.); - const auto* reflectivityWeightMap = getTex("reflectivity"); - FbxDouble4 reflectivityColor = getValue(props, "refl_color", FbxDouble4(1, 1, 1, 1)); - const auto* reflectivityColorMap = getTex("refl_color"); + // double reflectivityWeight = getValue(props, "reflectivity", 1.); + // const auto* reflectivityWeightMap = getTex("reflectivity"); + // FbxDouble4 reflectivityColor = getValue(props, "refl_color", FbxDouble4(1, 1, 1, 1)); + // const auto* reflectivityColorMap = getTex("refl_color"); // coatings: not supported - double coating = getValue(props, "coating", 0.0); + // double coating = getValue(props, "coating", 0.0); // diffuse roughness: not supported - double diffuseRoughness = getValue(props, "diff_roughness", 0.); + // double diffuseRoughness = getValue(props, "diff_roughness", 0.); // explicit brdf curve control: not supported - bool isBrdfMode = getValue(props, "brdf_mode", false); + // bool isBrdfMode = getValue(props, "brdf_mode", false); // anisotrophy: not supported - double anisotropy = getValue(props, "anisotropy", 1.0); + // double anisotropy = getValue(props, "anisotropy", 1.0); // TODO: how the heck do we combine these to generate a normal map? const auto* bumpMap = getTex("bump"); - const auto* displacementMap = getTex("displacement"); + // const auto* displacementMap = getTex("displacement"); std::unique_ptr res(new FbxRoughMetMaterialInfo( fbxMaterial->GetName(), diff --git a/src/fbx/materials/FbxMaterials.cpp b/src/fbx/materials/FbxMaterials.cpp index 05237db..f7f5c07 100644 --- a/src/fbx/materials/FbxMaterials.cpp +++ b/src/fbx/materials/FbxMaterials.cpp @@ -7,6 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#include "fbx/Fbx2Raw.hpp" + #include "FbxMaterials.hpp" #include "RoughnessMetallicMaterials.hpp" #include "TraditionalMaterials.hpp" @@ -41,13 +43,29 @@ FbxMaterialsAccess::FbxMaterialsAccess( if (materialNum < 0) { continue; } + + FbxSurfaceMaterial* surfaceMaterial = + mesh->GetNode()->GetSrcObject(materialNum); + if (materialNum >= summaries.size()) { summaries.resize(materialNum + 1); } auto summary = summaries[materialNum]; if (summary == nullptr) { - summary = summaries[materialNum] = GetMaterialInfo( - mesh->GetNode()->GetSrcObject(materialNum), textureLocations); + summary = summaries[materialNum] = GetMaterialInfo(surfaceMaterial, textureLocations); + } + + if (materialNum >= userProperties.size()) { + userProperties.resize(materialNum + 1); + } + if (userProperties[materialNum].empty()) { + FbxProperty objectProperty = surfaceMaterial->GetFirstProperty(); + while (objectProperty.IsValid()) { + if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) { + userProperties[materialNum].push_back(TranscribeProperty(objectProperty).dump()); + } + objectProperty = surfaceMaterial->GetNextProperty(objectProperty); + } } } } @@ -65,6 +83,18 @@ const std::shared_ptr FbxMaterialsAccess::GetMaterial( return nullptr; } +const std::vector FbxMaterialsAccess::GetUserProperties(const int polygonIndex) const { + if (mappingMode != FbxGeometryElement::eNone) { + const int materialNum = + indices->GetAt((mappingMode == FbxGeometryElement::eByPolygon) ? polygonIndex : 0); + if (materialNum < 0) { + return std::vector(); + } + return userProperties.at((unsigned long)materialNum); + } + return std::vector(); +} + std::unique_ptr FbxMaterialsAccess::GetMaterialInfo( FbxSurfaceMaterial* material, const std::map& textureLocations) { diff --git a/src/fbx/materials/FbxMaterials.hpp b/src/fbx/materials/FbxMaterials.hpp index 808d6a1..9141b78 100644 --- a/src/fbx/materials/FbxMaterials.hpp +++ b/src/fbx/materials/FbxMaterials.hpp @@ -45,6 +45,8 @@ class FbxMaterialsAccess { const std::shared_ptr GetMaterial(const int polygonIndex) const; + const std::vector GetUserProperties(const int polygonIndex) const; + std::unique_ptr GetMaterialInfo( FbxSurfaceMaterial* material, const std::map& textureLocations); @@ -52,6 +54,7 @@ class FbxMaterialsAccess { private: FbxGeometryElement::EMappingMode mappingMode; std::vector> summaries{}; + std::vector> userProperties; const FbxMesh* mesh; const FbxLayerElementArrayTemplate* indices; }; diff --git a/src/fbx/materials/RoughnessMetallicMaterials.hpp b/src/fbx/materials/RoughnessMetallicMaterials.hpp index b20a306..f994e3a 100644 --- a/src/fbx/materials/RoughnessMetallicMaterials.hpp +++ b/src/fbx/materials/RoughnessMetallicMaterials.hpp @@ -70,8 +70,8 @@ class Fbx3dsMaxPhysicalMaterialResolver : FbxMaterialResolver - T getValue(const FbxProperty& props, std::string propName, const T& default) const { + T getValue(const FbxProperty& props, std::string propName, const T& def) const { const FbxProperty prop = props.FindHierarchical(propName.c_str()); - return prop.IsValid() ? prop.Get() : default; + return prop.IsValid() ? prop.Get() : def; } };