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:
parent
4780efdc6f
commit
a596073f04
|
@ -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],
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue