diff --git a/CMakeLists.txt b/CMakeLists.txt index 8747efe0c..b012a282f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ else() find_package(simdjson CONFIG) if (simdjson_FOUND) message(STATUS "fastgltf: Found simdjson config") - target_link_libraries(fastgltf PRIVATE simdjson::simdjson) + target_link_libraries(fastgltf PUBLIC simdjson::simdjson) else() # Download and configure simdjson set(SIMDJSON_TARGET_VERSION "3.6.3") diff --git a/src/fastgltf.cpp b/src/fastgltf.cpp index 5ecba48f4..54f180e75 100644 --- a/src/fastgltf.cpp +++ b/src/fastgltf.cpp @@ -882,6 +882,34 @@ fg::Error fg::validate(const fastgltf::Asset& asset) { if (material.pbrData.metallicRoughnessTexture.has_value() && isInvalidTexture(material.pbrData.metallicRoughnessTexture->textureIndex)) return Error::InvalidGltf; + + // Validate that for every additional material field from an extension the correct extension is marked as used by the asset. + if (material.anisotropy && !isExtensionUsed(extensions::KHR_materials_anisotropy)) + return Error::InvalidGltf; + if (material.clearcoat && !isExtensionUsed(extensions::KHR_materials_clearcoat)) + return Error::InvalidGltf; + if (material.iridescence && !isExtensionUsed(extensions::KHR_materials_iridescence)) + return Error::InvalidGltf; + if (material.sheen && !isExtensionUsed(extensions::KHR_materials_sheen)) + return Error::InvalidGltf; + if (material.specular && !isExtensionUsed(extensions::KHR_materials_specular)) + return Error::InvalidGltf; +#if FASTGLTF_ENABLE_DEPRECATED_EXT + if (material.specularGlossiness && !isExtensionUsed(extensions::KHR_materials_pbrSpecularGlossiness)) + return Error::InvalidGltf; +#endif + if (material.transmission && !isExtensionUsed(extensions::KHR_materials_transmission)) + return Error::InvalidGltf; + if (material.volume && !isExtensionUsed(extensions::KHR_materials_volume)) + return Error::InvalidGltf; + if (material.emissiveStrength != 1.0f && !isExtensionUsed(extensions::KHR_materials_emissive_strength)) + return Error::InvalidGltf; + if (material.ior != 1.5f && !isExtensionUsed(extensions::KHR_materials_ior)) + return Error::InvalidGltf; + if (material.packedNormalMetallicRoughnessTexture && !isExtensionUsed(extensions::MSFT_packing_normalRoughnessMetallic)) + return Error::InvalidGltf; + if (material.packedOcclusionRoughnessMetallicTextures && !isExtensionUsed(extensions::MSFT_packing_occlusionRoughnessMetallic)) + return Error::InvalidGltf; } for (const auto& mesh : asset.meshes) { diff --git a/tests/optional_tests.cpp b/tests/optional_tests.cpp new file mode 100644 index 000000000..82e7c8b7d --- /dev/null +++ b/tests/optional_tests.cpp @@ -0,0 +1,18 @@ +#include + +#include + +TEST_CASE("Test basic Optional interface", "[optional-tests]") { + // We have no specialization for std::uint32_t, and therefore this is just + // a std::optional with a bool field padded by 3 bytes. + fastgltf::Optional optional; + static_assert(sizeof(optional) > sizeof(std::uint32_t)); +} + +TEST_CASE("Test Optional float specialization", "[optional-tests]") { + fastgltf::Optional doptional; + static_assert((std::numeric_limits::is_iec559 && sizeof(doptional) == sizeof(double)) || !std::numeric_limits::is_iec559); + + fastgltf::Optional foptional; + static_assert((std::numeric_limits::is_iec559 && sizeof(foptional) == sizeof(float)) || !std::numeric_limits::is_iec559); +}