diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp index 36f121bd5c2..906e6cf1c34 100644 --- a/modules/fbx/data/fbx_material.cpp +++ b/modules/fbx/data/fbx_material.cpp @@ -37,7 +37,7 @@ String FBXMaterial::get_material_name() const { return material_name; } -void FBXMaterial::set_imported_material(const FBXDocParser::Material *p_material) { +void FBXMaterial::set_imported_material(FBXDocParser::Material *p_material) { material = p_material; } @@ -167,6 +167,11 @@ FBXMaterial::MaterialInfo FBXMaterial::extract_material_info(const FBXDocParser: const String file_extension_uppercase = file_extension.to_upper(); + // TODO: one day we can add this + if (file_extension.empty()) { + continue; // skip it + } + // TODO: we don't support EMBED for DDS and TGA. ERR_CONTINUE_MSG( file_extension_uppercase != "PNG" && @@ -178,8 +183,9 @@ FBXMaterial::MaterialInfo FBXMaterial::extract_material_info(const FBXDocParser: "The FBX file contains a texture with an unrecognized extension: " + file_extension_uppercase); const String texture_name = absoulte_fbx_file_path.get_file(); + print_verbose("Getting FBX mapping mode for " + String(fbx_mapping_name.c_str())); const SpatialMaterial::TextureParam mapping_mode = fbx_texture_mapping_desc.at(fbx_mapping_name); - + print_verbose("Set FBX mapping mode to " + get_texture_param_name(mapping_mode)); TextureFileMapping file_mapping; file_mapping.map_mode = mapping_mode; file_mapping.name = texture_name; @@ -261,7 +267,6 @@ Ref FBXMaterial::import_material(ImportState &state) { // Extract other parameters info. for (FBXDocParser::LazyPropertyMap::value_type iter : material->Props()->GetLazyProperties()) { const std::string name = iter.first; - //const Assimp::FBX::ElementPtr element = iter.second; if (name.empty()) { continue; @@ -272,26 +277,31 @@ Ref FBXMaterial::import_material(ImportState &state) { desc = fbx_properties_desc.at(name); } + // check if we can ignore this it will be done at the next phase + if (desc == PROPERTY_DESC_NOT_FOUND || desc == PROPERTY_DESC_IGNORE) { + // count the texture mapping references. Skip this one if it's found and we can't look up a property value. + if (fbx_texture_mapping_desc.count(name) > 0) { + continue; // safe to ignore it's a texture mapping. + } + } + if (desc == PROPERTY_DESC_IGNORE) { - print_verbose("The FBX material parameter: `" + String(name.c_str()) + "` is ignored."); + WARN_PRINT("[Ignored] The FBX material parameter: `" + String(name.c_str()) + "` is ignored."); continue; } else { print_verbose("FBX Material parameter: " + String(name.c_str())); } + // DISABLE when adding support for all weird and wonderful material formats if (desc == PROPERTY_DESC_NOT_FOUND) { continue; } ERR_CONTINUE_MSG(desc == PROPERTY_DESC_NOT_FOUND, "The FBX material parameter: `" + String(name.c_str()) + "` was not recognized. Please open an issue so we can add the support to it."); - FBXDocParser::PropertyPtr prop = material->Props()->Get(name); + const FBXDocParser::PropertyTable *tbl = material->Props(); + FBXDocParser::PropertyPtr prop = tbl->Get(name); - //Assimp::FBX::PropertyPtr prop = prop.second. - - if (prop == nullptr) { - continue; - } ERR_CONTINUE_MSG(prop == nullptr, "This file may be corrupted because is not possible to extract the material parameter: " + String(name.c_str())); if (spatial_material.is_null()) { @@ -299,54 +309,133 @@ Ref FBXMaterial::import_material(ImportState &state) { spatial_material.instance(); } + const FBXDocParser::TypedProperty *real_value = dynamic_cast *>(prop); + const FBXDocParser::TypedProperty *vector_value = dynamic_cast *>(prop); + + if (!real_value && !vector_value) { + WARN_PRINT("unsupported datatype in property: " + String(name.c_str())); + continue; + } + switch (desc) { case PROPERTY_DESC_ALBEDO_COLOR: { - const Vector3 color = extract_from_prop(prop, Vector3(0, 0, 0), name, "Vector3"); - // Make sure to not lost any eventual opacity. - Color c = spatial_material->get_albedo(); - c[0] = color[0]; - c[1] = color[1]; - c[2] = color[2]; - spatial_material->set_albedo(c); + if (vector_value) { + const Vector3 &color = vector_value->Value(); + // Make sure to not lost any eventual opacity. + Color c = spatial_material->get_albedo(); + c[0] = color[0]; + c[1] = color[1]; + c[2] = color[2]; + spatial_material->set_albedo(c); + } else if (real_value) { + print_error("albedo is unsupported format?"); + } } break; case PROPERTY_DESC_TRANSPARENT: { - const real_t opacity = extract_from_prop(prop, 1.0f, name, "float"); - if (opacity < (1.0 - CMP_EPSILON)) { - Color c = spatial_material->get_albedo(); - c[3] = opacity; - spatial_material->set_albedo(c); - material_info.features.push_back(SpatialMaterial::Feature::FEATURE_TRANSPARENT); - spatial_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); + if (real_value) { + const real_t opacity = real_value->Value(); + if (opacity < (1.0 - CMP_EPSILON)) { + Color c = spatial_material->get_albedo(); + c[3] = opacity; + spatial_material->set_albedo(c); + material_info.features.push_back(SpatialMaterial::Feature::FEATURE_TRANSPARENT); + spatial_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); + } + } else if (vector_value) { + print_error("unsupported transparent desc type vector!"); + } + } break; + case PROPERTY_DESC_SPECULAR: { + if (real_value) { + print_verbose("specular real value: " + rtos(real_value->Value())); + spatial_material->set_specular(MIN(1.0, real_value->Value())); + } + + if (vector_value) { + print_error("unsupported specular vector value: " + vector_value->Value()); + } + } break; + case PROPERTY_DESC_SPECULAR_ROUGHNESS: { + if (real_value) { + print_verbose("specular roughness value:" + rtos(real_value->Value())); + spatial_material->set_roughness(MIN(1.0f, real_value->Value())); + } + + if (vector_value) { + print_error("unsupported specular roughness color: " + vector_value->Value()); + } + } break; + case PROPERTY_DESC_SPECULAR_COLOR: { + if (vector_value) { + print_error("unsupported specular color: " + vector_value->Value()); + } + } break; + case PROPERTY_DESC_SHINYNESS: { + if (real_value) { + print_error("unsupported shinyness:" + rtos(real_value->Value())); } } break; case PROPERTY_DESC_METALLIC: { - spatial_material->set_metallic(std::min(1.0f, extract_from_prop(prop, 1.0f, name, "float"))); + if (real_value) { + print_verbose("metallic real value: " + rtos(real_value->Value())); + spatial_material->set_metallic(MIN(1.0f, real_value->Value())); + } else { + print_error("unsupported value type for metallic"); + } } break; case PROPERTY_DESC_ROUGHNESS: { - spatial_material->set_roughness(std::min(1.0f, extract_from_prop(prop, 1.0f, name, "float"))); + if (real_value) { + print_verbose("roughness real value: " + rtos(real_value->Value())); + spatial_material->set_roughness(MIN(1.0f, real_value->Value())); + } else { + print_error("unsupported value type for roughness"); + } } break; case PROPERTY_DESC_COAT: { - spatial_material->set_clearcoat(extract_from_prop(prop, 1.0f, name, "float")); - material_info.features.push_back(SpatialMaterial::Feature::FEATURE_CLEARCOAT); + if (real_value) { + material_info.features.push_back(SpatialMaterial::Feature::FEATURE_CLEARCOAT); + print_verbose("clearcoat real value: " + rtos(real_value->Value())); + spatial_material->set_clearcoat(MIN(1.0f, real_value->Value())); + } else { + print_error("unsupported value type for clearcoat"); + } } break; case PROPERTY_DESC_COAT_ROUGHNESS: { - spatial_material->set_clearcoat_gloss(1.0 - extract_from_prop(prop, 0.5f, name, "float")); - material_info.features.push_back(SpatialMaterial::Feature::FEATURE_CLEARCOAT); + if (real_value) { + print_verbose("clearcoat real value: " + rtos(real_value->Value())); + spatial_material->set_clearcoat_gloss(1.0 - real_value->Value()); + + material_info.features.push_back(SpatialMaterial::Feature::FEATURE_CLEARCOAT); + } else { + print_error("unsupported value type for clearcoat gloss"); + } } break; case PROPERTY_DESC_EMISSIVE: { - const real_t emissive = extract_from_prop(prop, 0.0f, name, "float"); - if (emissive > CMP_EPSILON) { - spatial_material->set_emission_energy(emissive); + if (real_value) { + print_verbose("Emissive real value: " + rtos(real_value->Value())); + spatial_material->set_emission_energy(real_value->Value()); + material_info.features.push_back(SpatialMaterial::Feature::FEATURE_EMISSION); + } else { + const Vector3 &color = vector_value->Value(); + Color c; + c[0] = color[0]; + c[1] = color[1]; + c[2] = color[2]; + spatial_material->set_emission(c); material_info.features.push_back(SpatialMaterial::Feature::FEATURE_EMISSION); } } break; case PROPERTY_DESC_EMISSIVE_COLOR: { - const Vector3 color = extract_from_prop(prop, Vector3(0, 0, 0), name, "Vector3"); - Color c; - c[0] = color[0]; - c[1] = color[1]; - c[2] = color[2]; - spatial_material->set_emission(c); + if (vector_value) { + const Vector3 &color = vector_value->Value(); + Color c; + c[0] = color[0]; + c[1] = color[1]; + c[2] = color[2]; + spatial_material->set_emission(c); + } else { + print_error("unsupported value type for emissive color"); + } } break; case PROPERTY_DESC_NOT_FOUND: case PROPERTY_DESC_IGNORE: @@ -386,7 +475,7 @@ Ref FBXMaterial::import_material(ImportState &state) { state.cached_image_searches.insert(mapping.name, texture); print_verbose("Created texture from loaded image file."); - } else if (mapping.texture != nullptr && mapping.texture->Media() != nullptr) { + } else if (mapping.texture != nullptr && mapping.texture->Media() != nullptr && mapping.texture->Media()->IsEmbedded()) { // This is an embedded texture. Extract it. Ref image; image.instance(); @@ -409,8 +498,8 @@ Ref FBXMaterial::import_material(ImportState &state) { } else if (extension == "TGA") { // The stored file is a TGA. - //image = Image::_tga_mem_loader_func(mapping.texture->Media()->Content(), mapping.texture->Media()->ContentLength()); - //ERR_CONTINUE_MSG(image.is_valid() == false, "FBX Embedded TGA image load fail."); + image = Image::_tga_mem_loader_func(mapping.texture->Media()->Content(), mapping.texture->Media()->ContentLength()); + ERR_CONTINUE_MSG(image.is_valid() == false, "FBX Embedded TGA image load fail."); } else if (extension == "WEBP") { @@ -476,6 +565,8 @@ Ref FBXMaterial::import_material(ImportState &state) { break; } + print_verbose("Texture mapping mode: " + itos(mapping.map_mode) + " name: " + get_texture_param_name(mapping.map_mode)); + spatial_material->set_texture(mapping.map_mode, texture); } diff --git a/modules/fbx/data/fbx_material.h b/modules/fbx/data/fbx_material.h index 93dd83d561d..f6e6b13e755 100644 --- a/modules/fbx/data/fbx_material.h +++ b/modules/fbx/data/fbx_material.h @@ -38,7 +38,7 @@ struct FBXMaterial : public Reference { String material_name = String(); - mutable const FBXDocParser::Material *material = nullptr; + FBXDocParser::Material *material = nullptr; /* Godot materials *** Texture Maps: @@ -69,6 +69,48 @@ struct FBXMaterial : public Reference { ReflectionM, }; + /* Returns the string representation of the TextureParam enum */ + static String get_texture_param_name(SpatialMaterial::TextureParam param) { + switch (param) { + case SpatialMaterial::TEXTURE_ALBEDO: + return "TEXTURE_ALBEDO"; + case SpatialMaterial::TEXTURE_METALLIC: + return "TEXTURE_METALLIC"; + case SpatialMaterial::TEXTURE_ROUGHNESS: + return "TEXTURE_ROUGHNESS"; + case SpatialMaterial::TEXTURE_EMISSION: + return "TEXTURE_EMISSION"; + case SpatialMaterial::TEXTURE_NORMAL: + return "TEXTURE_NORMAL"; + case SpatialMaterial::TEXTURE_RIM: + return "TEXTURE_RIM"; + case SpatialMaterial::TEXTURE_CLEARCOAT: + return "TEXTURE_CLEARCOAT"; + case SpatialMaterial::TEXTURE_FLOWMAP: + return "TEXTURE_FLOWMAP"; + case SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION: + return "TEXTURE_AMBIENT_OCCLUSION"; + case SpatialMaterial::TEXTURE_DEPTH: + return "TEXTURE_DEPTH"; + case SpatialMaterial::TEXTURE_SUBSURFACE_SCATTERING: + return "TEXTURE_SUBSURFACE_SCATTERING"; + case SpatialMaterial::TEXTURE_TRANSMISSION: + return "TEXTURE_TRANSMISSION"; + case SpatialMaterial::TEXTURE_REFRACTION: + return "TEXTURE_REFRACTION"; + case SpatialMaterial::TEXTURE_DETAIL_MASK: + return "TEXTURE_DETAIL_MASK"; + case SpatialMaterial::TEXTURE_DETAIL_ALBEDO: + return "TEXTURE_DETAIL_ALBEDO"; + case SpatialMaterial::TEXTURE_DETAIL_NORMAL: + return "TEXTURE_DETAIL_NORMAL"; + case SpatialMaterial::TEXTURE_MAX: + return "TEXTURE_MAX"; + default: + return "broken horribly"; + } + }; + // TODO make this static? const std::map fbx_feature_mapping_desc = { /* Transparent */ @@ -105,29 +147,33 @@ struct FBXMaterial : public Reference { { "Maya|specularColor", SpatialMaterial::TextureParam::TEXTURE_METALLIC }, { "Maya|SpecularTexture", SpatialMaterial::TextureParam::TEXTURE_METALLIC }, { "Maya|SpecularTexture|file", SpatialMaterial::TextureParam::TEXTURE_METALLIC }, - { "ShininessExponent", SpatialMaterial::TextureParam::TEXTURE_METALLIC }, + /* Roughness */ - { "Maya|diffuseRoughness", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, - { "Maya|diffuseRoughness|file", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, + { "3dsMax|Parameters|roughness_map", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, { "Maya|TEX_roughness_map", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, { "Maya|TEX_roughness_map|file", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, - { "ReflectionFactor", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, - { "Maya|specularRoughness", SpatialMaterial::TextureParam::TEXTURE_ROUGHNESS }, + /* Normal */ { "NormalMap", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, - { "Bump", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, - { "3dsMax|Parameters|bump_map", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, + //{ "Bump", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, + //{ "3dsMax|Parameters|bump_map", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, { "Maya|NormalTexture", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, - { "Maya|normalCamera", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, - { "Maya|normalCamera|file", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, + //{ "Maya|normalCamera", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, + //{ "Maya|normalCamera|file", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, { "Maya|TEX_normal_map", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, { "Maya|TEX_normal_map|file", SpatialMaterial::TextureParam::TEXTURE_NORMAL }, /* AO */ { "Maya|TEX_ao_map", SpatialMaterial::TextureParam::TEXTURE_AMBIENT_OCCLUSION }, { "Maya|TEX_ao_map|file", SpatialMaterial::TextureParam::TEXTURE_AMBIENT_OCCLUSION }, - // {"TransparentColor",SpatialMaterial::TextureParam::TEXTURE_CHANNEL_ALPHA }, - // {"TransparencyFactor",SpatialMaterial::TextureParam::TEXTURE_CHANNEL_ALPHA } + + //{ "Maya|diffuseRoughness", SpatialMaterial::TextureParam::UNSUPPORTED }, + //{ "Maya|diffuseRoughness|file", SpatialMaterial::TextureParam::UNSUPPORTED }, + //{ "Maya|specularRoughness", SpatialMaterial::TextureParam::UNSUPPORTED }, + //{ "ShininessExponent", SpatialMaterial::TextureParam::UNSUPPORTED }, + //{ "ReflectionFactor", SpatialMaterial::TextureParam::UNSUPPORTED }, + //{ "TransparentColor",SpatialMaterial::TextureParam::TEXTURE_CHANNEL_ALPHA }, + //{ "TransparencyFactor",SpatialMaterial::TextureParam::TEXTURE_CHANNEL_ALPHA } }; // TODO make this static? @@ -137,6 +183,10 @@ struct FBXMaterial : public Reference { PROPERTY_DESC_TRANSPARENT, PROPERTY_DESC_METALLIC, PROPERTY_DESC_ROUGHNESS, + PROPERTY_DESC_SPECULAR, + PROPERTY_DESC_SPECULAR_COLOR, + PROPERTY_DESC_SPECULAR_ROUGHNESS, + PROPERTY_DESC_SHINYNESS, PROPERTY_DESC_COAT, PROPERTY_DESC_COAT_ROUGHNESS, PROPERTY_DESC_EMISSIVE, @@ -149,6 +199,13 @@ struct FBXMaterial : public Reference { { "DiffuseColor", PROPERTY_DESC_ALBEDO_COLOR }, { "Maya|baseColor", PROPERTY_DESC_ALBEDO_COLOR }, + /* Specular */ + { "Maya|specular", PROPERTY_DESC_SPECULAR }, + { "Maya|specularColor", PROPERTY_DESC_SPECULAR_COLOR }, + + /* Specular roughness */ + { "Maya|specularRoughness", PROPERTY_DESC_SPECULAR_ROUGHNESS }, + /* Transparent */ { "Opacity", PROPERTY_DESC_TRANSPARENT }, { "TransparencyFactor", PROPERTY_DESC_TRANSPARENT }, @@ -158,9 +215,10 @@ struct FBXMaterial : public Reference { { "Shininess", PROPERTY_DESC_METALLIC }, { "Reflectivity", PROPERTY_DESC_METALLIC }, { "Maya|metalness", PROPERTY_DESC_METALLIC }, + { "Maya|metallic", PROPERTY_DESC_METALLIC }, /* Roughness */ - { "Maya|diffuseRoughness", PROPERTY_DESC_ROUGHNESS }, + { "Maya|roughness", PROPERTY_DESC_ROUGHNESS }, /* Coat */ { "Maya|coat", PROPERTY_DESC_COAT }, @@ -170,14 +228,16 @@ struct FBXMaterial : public Reference { /* Emissive */ { "Maya|emission", PROPERTY_DESC_EMISSIVE }, + { "Maya|emissive", PROPERTY_DESC_EMISSIVE }, /* Emissive color */ { "EmissiveColor", PROPERTY_DESC_EMISSIVE_COLOR }, { "Maya|emissionColor", PROPERTY_DESC_EMISSIVE_COLOR }, /* Ignore */ + { "Maya|diffuseRoughness", PROPERTY_DESC_IGNORE }, { "Maya", PROPERTY_DESC_IGNORE }, - { "Diffuse", PROPERTY_DESC_IGNORE }, + { "Diffuse", PROPERTY_DESC_ALBEDO_COLOR }, { "Maya|TypeId", PROPERTY_DESC_IGNORE }, { "Ambient", PROPERTY_DESC_IGNORE }, { "AmbientColor", PROPERTY_DESC_IGNORE }, @@ -218,7 +278,7 @@ struct FBXMaterial : public Reference { String get_material_name() const; - void set_imported_material(const FBXDocParser::Material *p_material); + void set_imported_material(FBXDocParser::Material *p_material); struct MaterialInfo { Vector textures; diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index 378f9a0d849..c5b45a9accc 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -505,7 +505,7 @@ Spatial *EditorSceneImporterFBX::_generate_scene( for (uint64_t material_id : materials) { FBXDocParser::LazyObject *lazy_material = p_document->GetObject(material_id); - const FBXDocParser::Material *mat = lazy_material->Get(); + FBXDocParser::Material *mat = (FBXDocParser::Material *)lazy_material->Get(); ERR_CONTINUE_MSG(!mat, "Could not convert fbx material by id: " + itos(material_id)); Ref material; diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h index 76a1b36634f..ce37a2e79fd 100644 --- a/modules/fbx/fbx_parser/FBXDocument.h +++ b/modules/fbx/fbx_parser/FBXDocument.h @@ -644,6 +644,10 @@ public: return type; } + bool IsEmbedded() const { + return contentLength > 0; + } + const std::string &FileName() const { return fileName; } diff --git a/modules/fbx/fbx_parser/FBXMaterial.cpp b/modules/fbx/fbx_parser/FBXMaterial.cpp index ccccc75a362..92909a8b9c5 100644 --- a/modules/fbx/fbx_parser/FBXMaterial.cpp +++ b/modules/fbx/fbx_parser/FBXMaterial.cpp @@ -109,9 +109,11 @@ Material::Material(uint64_t id, const ElementPtr element, const Document &doc, c std::string templateName; if (shading == "phong") { - templateName = "Material.FbxSurfacePhong"; + templateName = "Material.Phong"; } else if (shading == "lambert") { - templateName = "Material.FbxSurfaceLambert"; + templateName = "Material.Lambert"; + } else if (shading == "unknown") { + templateName = "Material.StingRay"; } else { DOMWarning("shading mode not recognized: " + shading, element); } diff --git a/modules/fbx/fbx_parser/FBXProperties.cpp b/modules/fbx/fbx_parser/FBXProperties.cpp index 7d62cc7659a..a16d49def95 100644 --- a/modules/fbx/fbx_parser/FBXProperties.cpp +++ b/modules/fbx/fbx_parser/FBXProperties.cpp @@ -124,7 +124,7 @@ PropertyPtr ReadTypedProperty(const ElementPtr element) { ParseTokenAsFloat(tok[4]), ParseTokenAsFloat(tok[5]), ParseTokenAsFloat(tok[6]))); - } else if (!strcmp(cs, "double") || !strcmp(cs, "Number") || !strcmp(cs, "Float") || !strcmp(cs, "FieldOfView") || !strcmp(cs, "UnitScaleFactor")) { + } else if (!strcmp(cs, "double") || !strcmp(cs, "Number") || !strcmp(cs, "Float") || !strcmp(cs, "float") || !strcmp(cs, "FieldOfView") || !strcmp(cs, "UnitScaleFactor")) { return new TypedProperty(ParseTokenAsFloat(tok[4])); } @@ -168,11 +168,19 @@ PropertyTable::PropertyTable(const ElementPtr element, const PropertyTable *temp } LazyPropertyMap::const_iterator it = lazyProps.find(name); + if (it != lazyProps.end()) { DOMWarning("duplicate property name, will hide previous value: " + name, v.second); continue; } + if (it->second == nullptr) { + print_error("skipped invalid element insertion for " + String(name.c_str())); + continue; + } + + //print_verbose("storing lazy property: " + String(name.c_str())); + // since the above checks for duplicates we can be sure to insert the only match here. lazyProps[name] = v.second; } @@ -187,28 +195,26 @@ PropertyTable::~PropertyTable() { // ------------------------------------------------------------------------------------------------ PropertyPtr PropertyTable::Get(const std::string &name) const { - PropertyMap::const_iterator it = props.find(name); - if (it == props.end()) { - // hasn't been parsed yet? - LazyPropertyMap::const_iterator lit = lazyProps.find(name); - if (lit != lazyProps.end()) { - props[name] = ReadTypedProperty(lit->second); - it = props.find(name); - //ai_assert(it != props.end()); - } - - if (it == props.end()) { - // check property template - if (templateProps) { - return templateProps->Get(name); - } - - return nullptr; - } + // check if loaded already - return it. + PropertyMap::const_iterator loaded_property_element = props.find(name); + if (loaded_property_element != props.end()) { + //print_verbose("Returning conversion for lazy property: " + String(loaded_property_element->first.c_str())); + return loaded_property_element->second; } - return (*it).second; + // now load it since we don't have a match + LazyPropertyMap::const_iterator unloadedProperty = lazyProps.find(name); + if (unloadedProperty != lazyProps.end()) { + PropertyPtr loaded_property = ReadTypedProperty(unloadedProperty->second); + ERR_FAIL_COND_V_MSG(!loaded_property, nullptr, "[fbx][serious] unable to load typed property"); + + //print_verbose("loaded property successfully: " + String(name.c_str())); + props.insert(std::make_pair(name, loaded_property)); + return loaded_property; + } + + return nullptr; } DirectPropertyMap PropertyTable::GetUnparsedProperties() const {