diff --git a/common/util/gltf_util.cpp b/common/util/gltf_util.cpp index 22af8f2664a..f9e549d0c53 100644 --- a/common/util/gltf_util.cpp +++ b/common/util/gltf_util.cpp @@ -680,6 +680,28 @@ EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat) { return settings; } +bool material_has_envmap(const tinygltf::Material& mat) { + return mat.extensions.contains("KHR_materials_specular"); +} + +bool envmap_is_valid(const tinygltf::Material& mat, bool die) { + if (material_has_envmap(mat) && mat.pbrMetallicRoughness.metallicRoughnessTexture.index < 0) { + std::string error = fmt::format( + "Material \"{}\" has specular property set, but is missing a metallic roughness texture! " + "Check " + "that the Specular IOR level for the material is at the default of 0.5 if this is " + "unintended.", + mat.name); + if (die) { + lg::die(error); + } else { + lg::error(error); + } + return false; + } + return true; +} + std::optional find_single_skin(const tinygltf::Model& model, const std::vector& all_nodes) { std::optional skin_index; diff --git a/common/util/gltf_util.h b/common/util/gltf_util.h index 627110cb751..01cfbce1245 100644 --- a/common/util/gltf_util.h +++ b/common/util/gltf_util.h @@ -125,6 +125,8 @@ struct EnvmapSettings { }; EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat); +bool material_has_envmap(const tinygltf::Material& mat); +bool envmap_is_valid(const tinygltf::Material& mat, bool die); /*! * Find the index of the skin for this model. Returns nullopt if there is no skin, the index of the diff --git a/decompiler/level_extractor/merc_replacement.cpp b/decompiler/level_extractor/merc_replacement.cpp index 2afed37bd1a..c35647e2e31 100644 --- a/decompiler/level_extractor/merc_replacement.cpp +++ b/decompiler/level_extractor/merc_replacement.cpp @@ -4,10 +4,6 @@ using namespace gltf_util; namespace decompiler { -bool material_has_envmap(const tinygltf::Material& mat) { - return mat.extensions.contains("KHR_materials_specular"); -} - void extract(const std::string& name, MercExtractData& out, const tinygltf::Model& model, @@ -25,7 +21,7 @@ void extract(const std::string& name, int joints = 3; auto skin_idx = find_single_skin(model, all_nodes); if (skin_idx) { - joints = get_joint_count(model, *skin_idx); + joints += get_joint_count(model, *skin_idx); } for (const auto& n : all_nodes) { @@ -134,14 +130,13 @@ void extract(const std::string& name, return; } - int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index; - ASSERT(roughness_tex_idx >= 0); const auto& base_tex = model.textures[base_tex_idx]; ASSERT(base_tex.sampler >= 0); ASSERT(base_tex.source >= 0); gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode); gltf_util::setup_alpha_from_material(mat, &draw.mode); - const auto& roughness_tex = model.textures.at(roughness_tex_idx); + const auto& roughness_tex = + model.textures.at(mat.pbrMetallicRoughness.metallicRoughnessTexture.index); ASSERT(roughness_tex.sampler >= 0); ASSERT(roughness_tex.source >= 0); @@ -169,6 +164,7 @@ void extract(const std::string& name, if (!material_has_envmap(mat)) { process_normal_draw(e, mat_idx, d_); } else { + envmap_is_valid(mat, true); has_envmaps = true; envmap_eff.has_envmap = true; process_envmap_draw(envmap_eff, mat_idx, d_); diff --git a/goalc/build_actor/common/MercExtract.cpp b/goalc/build_actor/common/MercExtract.cpp index fb857b8dc23..db20ea69516 100644 --- a/goalc/build_actor/common/MercExtract.cpp +++ b/goalc/build_actor/common/MercExtract.cpp @@ -5,10 +5,6 @@ #include "goalc/build_level/common/gltf_mesh_extract.h" -bool material_has_envmap(const tinygltf::Material& mat) { - return mat.extensions.contains("KHR_materials_specular"); -} - void extract(const std::string& name, MercExtractData& out, const tinygltf::Model& model, @@ -25,7 +21,7 @@ void extract(const std::string& name, int joints = 3; auto skin_idx = find_single_skin(model, all_nodes); if (skin_idx) { - joints = gltf_util::get_joint_count(model, *skin_idx); + joints += gltf_util::get_joint_count(model, *skin_idx); } for (const auto& n : all_nodes) { @@ -146,14 +142,13 @@ void extract(const std::string& name, return; } - int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index; - ASSERT(roughness_tex_idx >= 0); const auto& base_tex = model.textures[base_tex_idx]; ASSERT(base_tex.sampler >= 0); ASSERT(base_tex.source >= 0); gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode); gltf_util::setup_alpha_from_material(mat, &draw.mode); - const auto& roughness_tex = model.textures.at(roughness_tex_idx); + const auto& roughness_tex = + model.textures.at(mat.pbrMetallicRoughness.metallicRoughnessTexture.index); ASSERT(roughness_tex.sampler >= 0); ASSERT(roughness_tex.source >= 0); @@ -178,9 +173,10 @@ void extract(const std::string& name, for (const auto& [mat_idx, d_] : draw_by_material) { const auto& mat = model.materials[mat_idx]; - if (!material_has_envmap(mat)) { + if (!gltf_util::material_has_envmap(mat)) { process_normal_draw(e, mat_idx, d_); } else { + gltf_util::envmap_is_valid(mat, false); has_envmaps = true; envmap_eff.has_envmap = true; process_envmap_draw(envmap_eff, mat_idx, d_);