Identify materials by unique ID, not name.

At the end of the various material/mesh transformations we do, we were still using a ridiculously simplistic method of mapping RawMaterial to glTF MaterialData.

This switches to using FBX's GetUniqueID(), which should be the law of the land in general. Other model entities may need further investigation as well.
This commit is contained in:
Par Winzell 2019-02-24 19:32:13 -08:00
parent 4780efdc6f
commit a596073f04
10 changed files with 30 additions and 17 deletions

View File

@ -209,9 +209,11 @@ static void ReadMesh(
std::shared_ptr<RawMatProps> rawMatProps; std::shared_ptr<RawMatProps> rawMatProps;
FbxString materialName; FbxString materialName;
long materialId;
if (fbxMaterial == nullptr) { if (fbxMaterial == nullptr) {
materialName = "DefaultMaterial"; materialName = "DefaultMaterial";
materialId = -1;
rawMatProps.reset(new RawTraditionalMatProps( rawMatProps.reset(new RawTraditionalMatProps(
RAW_SHADING_MODEL_LAMBERT, RAW_SHADING_MODEL_LAMBERT,
Vec3f(0, 0, 0), Vec3f(0, 0, 0),
@ -222,6 +224,7 @@ static void ReadMesh(
} else { } else {
materialName = fbxMaterial->name; materialName = fbxMaterial->name;
materialId = fbxMaterial->id;
const auto maybeAddTexture = [&](const FbxFileTexture* tex, RawTextureUsage usage) { const auto maybeAddTexture = [&](const FbxFileTexture* tex, RawTextureUsage usage) {
if (tex != nullptr) { if (tex != nullptr) {
@ -436,8 +439,8 @@ static void ReadMesh(
const RawMaterialType materialType = const RawMaterialType materialType =
GetMaterialType(raw, textures, vertexTransparency, skinning.IsSkinned()); GetMaterialType(raw, textures, vertexTransparency, skinning.IsSkinned());
const int rawMaterialIndex = const int rawMaterialIndex = raw.AddMaterial(
raw.AddMaterial(materialName, materialType, textures, rawMatProps, userProperties); materialId, materialName, materialType, textures, rawMatProps, userProperties);
raw.AddTriangle( raw.AddTriangle(
rawVertexIndices[0], rawVertexIndices[0],

View File

@ -149,6 +149,7 @@ std::unique_ptr<FbxRoughMetMaterialInfo> Fbx3dsMaxPhysicalMaterialResolver::reso
} }
std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo( std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo(
fbxMaterial->GetUniqueID(),
fbxMaterial->GetName(), fbxMaterial->GetName(),
FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH, FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH,
baseCol, baseCol,

View File

@ -16,9 +16,10 @@
class FbxMaterialInfo { class FbxMaterialInfo {
public: public:
FbxMaterialInfo(const FbxString& name, const FbxString& shadingModel) FbxMaterialInfo(const FbxUInt64 id, const FbxString& name, const FbxString& shadingModel)
: name(name), shadingModel(shadingModel) {} : id(id), name(name), shadingModel(shadingModel) {}
const FbxUInt64 id;
const FbxString name; const FbxString name;
const FbxString shadingModel; const FbxString shadingModel;
}; };

View File

@ -21,12 +21,13 @@ struct FbxRoughMetMaterialInfo : FbxMaterialInfo {
const std::map<const FbxTexture*, FbxString>& textureLocations); const std::map<const FbxTexture*, FbxString>& textureLocations);
FbxRoughMetMaterialInfo( FbxRoughMetMaterialInfo(
const FbxUInt64 id,
const FbxString& name, const FbxString& name,
const FbxString& shadingModel, const FbxString& shadingModel,
FbxDouble4 baseColor, FbxDouble4 baseColor,
FbxDouble metallic, FbxDouble metallic,
FbxDouble roughness) FbxDouble roughness)
: FbxMaterialInfo(name, shadingModel), : FbxMaterialInfo(id, name, shadingModel),
baseColor(baseColor), baseColor(baseColor),
metallic(metallic), metallic(metallic),
roughness(roughness) {} roughness(roughness) {}

View File

@ -54,6 +54,7 @@ std::unique_ptr<FbxRoughMetMaterialInfo> FbxStingrayPBSMaterialResolver::resolve
FbxDouble3 baseColor = getVec("base_color"); FbxDouble3 baseColor = getVec("base_color");
std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo( std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo(
fbxMaterial->GetUniqueID(),
fbxMaterial->GetName(), fbxMaterial->GetName(),
FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH, FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH,
FbxDouble4(baseColor[0], baseColor[1], baseColor[2], 1), FbxDouble4(baseColor[0], baseColor[1], baseColor[2], 1),

View File

@ -68,8 +68,8 @@ std::unique_ptr<FbxTraditionalMaterialInfo> FbxTraditionalMaterialResolver::reso
}; };
std::string name = fbxMaterial->GetName(); std::string name = fbxMaterial->GetName();
std::unique_ptr<FbxTraditionalMaterialInfo> res( std::unique_ptr<FbxTraditionalMaterialInfo> res(new FbxTraditionalMaterialInfo(
new FbxTraditionalMaterialInfo(name.c_str(), fbxMaterial->ShadingModel.Get())); fbxMaterial->GetUniqueID(), name.c_str(), fbxMaterial->ShadingModel.Get()));
// four properties are on the same structure and follow the same rules // four properties are on the same structure and follow the same rules
auto handleBasicProperty = [&](const char* colName, auto handleBasicProperty = [&](const char* colName,

View File

@ -14,8 +14,11 @@ struct FbxTraditionalMaterialInfo : FbxMaterialInfo {
static constexpr const char* FBX_SHADER_BLINN = "Blinn"; static constexpr const char* FBX_SHADER_BLINN = "Blinn";
static constexpr const char* FBX_SHADER_PHONG = "Phong"; static constexpr const char* FBX_SHADER_PHONG = "Phong";
FbxTraditionalMaterialInfo(const FbxString& name, const FbxString& shadingModel) FbxTraditionalMaterialInfo(
: FbxMaterialInfo(name, shadingModel) {} const FbxUInt64 id,
const FbxString& name,
const FbxString& shadingModel)
: FbxMaterialInfo(id, name, shadingModel) {}
FbxFileTexture* texAmbient{}; FbxFileTexture* texAmbient{};
FbxVector4 colAmbient{}; FbxVector4 colAmbient{};

View File

@ -77,11 +77,6 @@ static const std::vector<TriangleIndex> getIndexArray(const RawModel& raw) {
return result; return result;
} }
// TODO: replace with a proper MaterialHasher class
static const std::string materialHash(const RawMaterial& m) {
return m.name + "_" + std::to_string(m.type);
}
ModelData* Raw2Gltf( ModelData* Raw2Gltf(
std::ofstream& gltfOutStream, std::ofstream& gltfOutStream,
const std::string& outputFolder, const std::string& outputFolder,
@ -123,7 +118,7 @@ ModelData* Raw2Gltf(
std::unique_ptr<GltfModel> gltf(new GltfModel(options)); std::unique_ptr<GltfModel> gltf(new GltfModel(options));
std::map<long, std::shared_ptr<NodeData>> nodesById; std::map<long, std::shared_ptr<NodeData>> nodesById;
std::map<std::string, std::shared_ptr<MaterialData>> materialsByName; std::map<long, std::shared_ptr<MaterialData>> materialsById;
std::map<std::string, std::shared_ptr<TextureData>> textureByIndicesKey; std::map<std::string, std::shared_ptr<TextureData>> textureByIndicesKey;
std::map<long, std::shared_ptr<MeshData>> meshBySurfaceId; std::map<long, std::shared_ptr<MeshData>> meshBySurfaceId;
@ -394,7 +389,8 @@ ModelData* Raw2Gltf(
emissiveFactor * emissiveIntensity, emissiveFactor * emissiveIntensity,
khrCmnUnlitMat, khrCmnUnlitMat,
pbrMetRough)); pbrMetRough));
materialsByName[materialHash(material)] = mData; fmt::printf("Stashing material of id %ls, name %s...\n", material.id, material.name.c_str());
materialsById[material.id] = mData;
if (options.enableUserProperties) { if (options.enableUserProperties) {
mData->userProperties = material.userProperties; mData->userProperties = material.userProperties;
@ -408,7 +404,9 @@ ModelData* Raw2Gltf(
const RawMaterial& rawMaterial = const RawMaterial& rawMaterial =
surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex); surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
const MaterialData& mData = require(materialsByName, materialHash(rawMaterial)); fmt::printf(
"Seeking material of id %ls, name %s...\n", rawMaterial.id, rawMaterial.name.c_str());
const MaterialData& mData = require(materialsById, rawMaterial.id);
MeshData* mesh = nullptr; MeshData* mesh = nullptr;
auto meshIter = meshBySurfaceId.find(surfaceId); auto meshIter = meshBySurfaceId.find(surfaceId);

View File

@ -129,6 +129,7 @@ int RawModel::AddTexture(
int RawModel::AddMaterial(const RawMaterial& material) { int RawModel::AddMaterial(const RawMaterial& material) {
return AddMaterial( return AddMaterial(
material.id,
material.name.c_str(), material.name.c_str(),
material.type, material.type,
material.textures, material.textures,
@ -137,6 +138,7 @@ int RawModel::AddMaterial(const RawMaterial& material) {
} }
int RawModel::AddMaterial( int RawModel::AddMaterial(
const long id,
const char* name, const char* name,
const RawMaterialType materialType, const RawMaterialType materialType,
const int textures[RAW_TEXTURE_USAGE_MAX], const int textures[RAW_TEXTURE_USAGE_MAX],
@ -169,6 +171,7 @@ int RawModel::AddMaterial(
} }
RawMaterial material; RawMaterial material;
material.id = id;
material.name = name; material.name = name;
material.type = materialType; material.type = materialType;
material.info = materialInfo; material.info = materialInfo;

View File

@ -262,6 +262,7 @@ struct RawMetRoughMatProps : RawMatProps {
}; };
struct RawMaterial { struct RawMaterial {
long id;
std::string name; std::string name;
RawMaterialType type; RawMaterialType type;
std::shared_ptr<RawMatProps> info; std::shared_ptr<RawMatProps> info;
@ -374,6 +375,7 @@ class RawModel {
RawTextureUsage usage); RawTextureUsage usage);
int AddMaterial(const RawMaterial& material); int AddMaterial(const RawMaterial& material);
int AddMaterial( int AddMaterial(
const long id,
const char* name, const char* name,
const RawMaterialType materialType, const RawMaterialType materialType,
const int textures[RAW_TEXTURE_USAGE_MAX], const int textures[RAW_TEXTURE_USAGE_MAX],