diff options
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 11 | ||||
-rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 13 | ||||
-rw-r--r-- | indra/llprimitive/tests/llgltfmaterial_test.cpp | 78 |
3 files changed, 91 insertions, 11 deletions
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 12af568b7e..94bc5ef74c 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -81,7 +81,7 @@ LLGLTFMaterial::LLGLTFMaterial() #endif } -void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const +void LLGLTFMaterial::TextureTransform::getPacked(Pack& packed) const { packed[0] = mScale.mV[VX]; packed[1] = mScale.mV[VY]; @@ -92,6 +92,15 @@ void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const packed[3] = packed[6] = packed[7] = 0.f; } +void LLGLTFMaterial::TextureTransform::getPackedTight(PackTight& packed) const +{ + packed[0] = mScale.mV[VX]; + packed[1] = mScale.mV[VY]; + packed[2] = mRotation; + packed[3] = mOffset.mV[VX]; + packed[4] = mOffset.mV[VY]; +} + bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const { return mOffset == other.mOffset && mScale == other.mScale && mRotation == other.mRotation; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 90f1ecfa8f..1b0ab19f71 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -68,7 +68,12 @@ public: LLVector2 mScale = { 1.f, 1.f }; F32 mRotation = 0.f; - void getPacked(F32 (&packed)[8]) const; + static const size_t PACK_SIZE = 8; + static const size_t PACK_TIGHT_SIZE = 5; + using Pack = F32[PACK_SIZE]; + using PackTight = F32[PACK_TIGHT_SIZE]; + void getPacked(Pack& packed) const; + void getPackedTight(PackTight& packed) const; bool operator==(const TextureTransform& other) const; bool operator!=(const TextureTransform& other) const { return !(*this == other); } @@ -120,12 +125,6 @@ public: // heightmaps cannot currently be described as finite enclosed // volumes. // See also LLPanelRegionTerrainInfo::validateMaterials - bool mDoubleSided = false; - - - // These fields are local to viewer and are a part of local bitmap support - typedef std::map<LLUUID, LLUUID> local_tex_map_t; - local_tex_map_t mTrackingIdToLocalTexture; public: diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index b56c9ab4f5..585b9da3ad 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -26,6 +26,8 @@ #include "linden_common.h" #include "lltut.h" +#include <set> + #include "../llgltfmaterial.h" #include "lluuid.cpp" @@ -108,9 +110,9 @@ namespace tut material.setAlphaCutoff(test_fraction); // Because this is the default value, it should append to the extras field to mark it as an override - material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE); + material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true); // Because this is the default value, it should append to the extras field to mark it as an override - material.setDoubleSided(false); + material.setDoubleSided(false, true); return material; } @@ -143,7 +145,7 @@ namespace tut #if LL_WINDOWS // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) // This test result will vary between compilers, so only test a single platform - ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 224); + ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 232); #endif #endif ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4); @@ -366,4 +368,74 @@ namespace tut ensure_equals("LLGLTFMaterial: double sided override flag unset", material.mOverrideDoubleSided, false); } } + + template<typename T> + void ensure_material_hash_pre(LLGLTFMaterial& material, T& material_field, const T new_value, const std::string& field_name) + { + ensure("LLGLTFMaterial: Hash: Test field " + field_name + " is part of the test material object", ( + size_t(&material_field) >= size_t(&material) && + (size_t(&material_field) + sizeof(material_field)) <= (size_t(&material) + sizeof(material)) + )); + ensure("LLGLTFMaterial: Hash: " + field_name + " differs and will cause a perturbation worth hashing", material_field != new_value); + } + + template<typename T> + void ensure_material_hash_not_changed(LLGLTFMaterial& material, T& material_field, const T new_value, const std::string& field_name) + { + ensure_material_hash_pre(material, material_field, new_value, field_name); + + const LLGLTFMaterial old_material = material; + material_field = new_value; + // If this test fails, consult LLGLTFMaterial::getHash, and optionally consult http://www.catb.org/esr/structure-packing/ for guidance on optimal memory packing (effectiveness is platform-dependent) + ensure_equals(("LLGLTFMaterial: Hash: Perturbing " + field_name + " to new value does NOT change the hash").c_str(), material.getHash(), old_material.getHash()); + } + + template<typename T> + void ensure_material_hash_changed(LLGLTFMaterial& material, T& material_field, const T new_value, const std::string& field_name) + { + ensure_material_hash_pre(material, material_field, new_value, field_name); + + const LLGLTFMaterial old_material = material; + material_field = new_value; + // If this test fails, consult LLGLTFMaterial::getHash, and optionally consult http://www.catb.org/esr/structure-packing/ for guidance on optimal memory packing (effectiveness is platform-dependent) + ensure_not_equals(("LLGLTFMaterial: Hash: Perturbing " + field_name + " to new value changes the hash").c_str(), material.getHash(), old_material.getHash()); + } + +#define ENSURE_HASH_NOT_CHANGED(HASH_MAT, SOURCE_MAT, FIELD) ensure_material_hash_not_changed(HASH_MAT, HASH_MAT.FIELD, SOURCE_MAT.FIELD, #FIELD) +#define ENSURE_HASH_CHANGED(HASH_MAT, SOURCE_MAT, FIELD) ensure_material_hash_changed(HASH_MAT, HASH_MAT.FIELD, SOURCE_MAT.FIELD, #FIELD) + + // Test LLGLTFMaterial::getHash, which is very sensitive to the ordering of fields + template<> template<> + void llgltfmaterial_object_t::test<12>() + { + // *NOTE: Due to direct manipulation of the fields of materials + // throughout this test, the resulting modified materials may not be + // compliant or properly serializable. + + // Ensure all fields of source_mat are set to values that differ from + // LLGLTFMaterial::sDefault, even if that would result in an invalid + // material object. + LLGLTFMaterial source_mat = create_test_material(); + source_mat.mTrackingIdToLocalTexture[LLUUID::generateNewID()] = LLUUID::generateNewID(); + source_mat.mLocalTexDataDigest = 1; + source_mat.mAlphaMode = LLGLTFMaterial::ALPHA_MODE_MASK; + source_mat.mDoubleSided = true; + + LLGLTFMaterial hash_mat; + + ENSURE_HASH_NOT_CHANGED(hash_mat, source_mat, mTrackingIdToLocalTexture); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mLocalTexDataDigest); + + ENSURE_HASH_CHANGED(hash_mat, source_mat, mTextureId); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mTextureTransform); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mBaseColor); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mEmissiveColor); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mMetallicFactor); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mRoughnessFactor); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mAlphaCutoff); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mAlphaMode); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mDoubleSided); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mOverrideDoubleSided); + ENSURE_HASH_CHANGED(hash_mat, source_mat, mOverrideAlphaMode); + } } |