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

View File

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

View File

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

View File

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

View File

@ -54,6 +54,7 @@ std::unique_ptr<FbxRoughMetMaterialInfo> FbxStingrayPBSMaterialResolver::resolve
FbxDouble3 baseColor = getVec("base_color");
std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo(
fbxMaterial->GetUniqueID(),
fbxMaterial->GetName(),
FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH,
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::unique_ptr<FbxTraditionalMaterialInfo> res(
new FbxTraditionalMaterialInfo(name.c_str(), fbxMaterial->ShadingModel.Get()));
std::unique_ptr<FbxTraditionalMaterialInfo> res(new FbxTraditionalMaterialInfo(
fbxMaterial->GetUniqueID(), name.c_str(), fbxMaterial->ShadingModel.Get()));
// four properties are on the same structure and follow the same rules
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_PHONG = "Phong";
FbxTraditionalMaterialInfo(const FbxString& name, const FbxString& shadingModel)
: FbxMaterialInfo(name, shadingModel) {}
FbxTraditionalMaterialInfo(
const FbxUInt64 id,
const FbxString& name,
const FbxString& shadingModel)
: FbxMaterialInfo(id, name, shadingModel) {}
FbxFileTexture* texAmbient{};
FbxVector4 colAmbient{};

View File

@ -77,11 +77,6 @@ static const std::vector<TriangleIndex> getIndexArray(const RawModel& raw) {
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(
std::ofstream& gltfOutStream,
const std::string& outputFolder,
@ -123,7 +118,7 @@ ModelData* Raw2Gltf(
std::unique_ptr<GltfModel> gltf(new GltfModel(options));
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<long, std::shared_ptr<MeshData>> meshBySurfaceId;
@ -394,7 +389,8 @@ ModelData* Raw2Gltf(
emissiveFactor * emissiveIntensity,
khrCmnUnlitMat,
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) {
mData->userProperties = material.userProperties;
@ -408,7 +404,9 @@ ModelData* Raw2Gltf(
const RawMaterial& rawMaterial =
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;
auto meshIter = meshBySurfaceId.find(surfaceId);

View File

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

View File

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