Tighten material schema-driven binding path
This commit is contained in:
@@ -620,6 +620,93 @@ bool TryParseFloatListText(const std::string& text,
|
||||
return outCount > 0;
|
||||
}
|
||||
|
||||
Containers::String NormalizeMaterialLookupToken(const Containers::String& value) {
|
||||
std::string normalized;
|
||||
normalized.reserve(value.Length());
|
||||
for (size_t index = 0; index < value.Length(); ++index) {
|
||||
const unsigned char ch = static_cast<unsigned char>(value[index]);
|
||||
if (std::isalnum(ch) != 0) {
|
||||
normalized.push_back(static_cast<char>(std::tolower(ch)));
|
||||
}
|
||||
}
|
||||
|
||||
return Containers::String(normalized.c_str());
|
||||
}
|
||||
|
||||
const ShaderPropertyDesc* FindShaderPropertyBySemantic(
|
||||
const Shader* shader,
|
||||
const Containers::String& semantic) {
|
||||
if (shader == nullptr || semantic.Empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Containers::String normalizedSemantic = NormalizeMaterialLookupToken(semantic);
|
||||
for (const ShaderPropertyDesc& property : shader->GetProperties()) {
|
||||
if (NormalizeMaterialLookupToken(property.semantic) == normalizedSemantic) {
|
||||
return &property;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Containers::String ResolveLegacyMaterialSemanticAlias(
|
||||
const Containers::String& propertyName,
|
||||
JsonRawValueType rawType) {
|
||||
const Containers::String normalizedName = NormalizeMaterialLookupToken(propertyName);
|
||||
|
||||
if (rawType == JsonRawValueType::Array ||
|
||||
rawType == JsonRawValueType::Number) {
|
||||
if (normalizedName == "basecolor" ||
|
||||
normalizedName == "color") {
|
||||
return Containers::String("BaseColor");
|
||||
}
|
||||
}
|
||||
|
||||
if (rawType == JsonRawValueType::String) {
|
||||
if (normalizedName == "basecolortexture" ||
|
||||
normalizedName == "maintex" ||
|
||||
normalizedName == "maintexture" ||
|
||||
normalizedName == "albedotexture" ||
|
||||
normalizedName == "texture") {
|
||||
return Containers::String("BaseColorTexture");
|
||||
}
|
||||
}
|
||||
|
||||
return Containers::String();
|
||||
}
|
||||
|
||||
const ShaderPropertyDesc* ResolveShaderPropertyForMaterialKey(
|
||||
const Shader* shader,
|
||||
const Containers::String& propertyName,
|
||||
JsonRawValueType rawType) {
|
||||
if (shader == nullptr || propertyName.Empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (const ShaderPropertyDesc* property = shader->FindProperty(propertyName)) {
|
||||
return property;
|
||||
}
|
||||
|
||||
const Containers::String normalizedName = NormalizeMaterialLookupToken(propertyName);
|
||||
for (const ShaderPropertyDesc& property : shader->GetProperties()) {
|
||||
if (NormalizeMaterialLookupToken(property.name) == normalizedName) {
|
||||
return &property;
|
||||
}
|
||||
}
|
||||
|
||||
if (const ShaderPropertyDesc* property = FindShaderPropertyBySemantic(shader, propertyName)) {
|
||||
return property;
|
||||
}
|
||||
|
||||
const Containers::String semanticAlias = ResolveLegacyMaterialSemanticAlias(propertyName, rawType);
|
||||
if (!semanticAlias.Empty()) {
|
||||
return FindShaderPropertyBySemantic(shader, semanticAlias);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TryApplySchemaMaterialProperty(Material* material,
|
||||
const ShaderPropertyDesc& shaderProperty,
|
||||
const std::string& rawValue,
|
||||
@@ -767,7 +854,7 @@ bool TryParseMaterialPropertiesObject(const std::string& objectText, Material* m
|
||||
|
||||
const Shader* shader = material->GetShader();
|
||||
const ShaderPropertyDesc* shaderProperty =
|
||||
shader != nullptr ? shader->FindProperty(propertyName) : nullptr;
|
||||
ResolveShaderPropertyForMaterialKey(shader, propertyName, rawType);
|
||||
if (shader != nullptr && shaderProperty == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@@ -943,8 +1030,17 @@ bool TryApplyTexturePath(Material* material,
|
||||
return false;
|
||||
}
|
||||
|
||||
const Shader* shader = material->GetShader();
|
||||
const ShaderPropertyDesc* shaderProperty =
|
||||
ResolveShaderPropertyForMaterialKey(shader, textureName, JsonRawValueType::String);
|
||||
if (shader != nullptr && shaderProperty == nullptr) {
|
||||
return false;
|
||||
}
|
||||
const Containers::String resolvedPropertyName =
|
||||
shaderProperty != nullptr ? shaderProperty->name : textureName;
|
||||
|
||||
material->SetTexturePath(
|
||||
textureName,
|
||||
resolvedPropertyName,
|
||||
ResolveSourceDependencyPath(texturePath, material->GetPath()));
|
||||
return true;
|
||||
}
|
||||
@@ -978,7 +1074,9 @@ bool TryParseMaterialTextureBindings(const std::string& jsonText, Material* mate
|
||||
return false;
|
||||
}
|
||||
|
||||
TryApplyTexturePath(material, Containers::String(key), texturePath);
|
||||
if (!TryApplyTexturePath(material, Containers::String(key), texturePath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasKey(jsonText, "textures")) {
|
||||
@@ -987,13 +1085,19 @@ bool TryParseMaterialTextureBindings(const std::string& jsonText, Material* mate
|
||||
return false;
|
||||
}
|
||||
|
||||
bool appliedAllBindings = true;
|
||||
if (!TryParseStringMapObject(
|
||||
texturesObject,
|
||||
[material](const Containers::String& name, const Containers::String& value) {
|
||||
TryApplyTexturePath(material, name, value);
|
||||
[material, &appliedAllBindings](const Containers::String& name, const Containers::String& value) {
|
||||
if (appliedAllBindings) {
|
||||
appliedAllBindings = TryApplyTexturePath(material, name, value);
|
||||
}
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
if (!appliedAllBindings) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user