diff options
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 11 | ||||
-rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 26 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.cpp | 13 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.h | 3 | ||||
-rw-r--r-- | indra/llprimitive/lltextureentry.cpp | 1 | ||||
-rw-r--r-- | indra/llprimitive/lltextureentry.h | 2 | ||||
-rw-r--r-- | indra/llprimitive/tests/llgltfmaterial_test.cpp | 78 |
7 files changed, 124 insertions, 10 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 9f817d6a19..23a39593cf 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); } @@ -110,6 +115,18 @@ public: static const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION; static const LLUUID GLTF_OVERRIDE_NULL_UUID; + // *TODO: If/when we implement additional GLTF extensions, they may not be + // compatible with our GLTF terrain implementation. We may want to disallow + // materials with some features from being set on terrain, if their + // implementation on terrain is not compliant with the spec: + // - KHR_materials_transmission: Probably OK? + // - KHR_materials_ior: Probably OK? + // - KHR_materials_volume: Likely incompatible, as our terrain + // heightmaps cannot currently be described as finite enclosed + // volumes. + // See also LLPanelRegionTerrainInfo::validateMaterials +public: + // get a UUID based on a hash of this LLGLTFMaterial LLUUID getHash() const; @@ -209,7 +226,6 @@ public: bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); } virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); virtual void updateTextureTracking(); - protected: static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value); @@ -257,10 +273,10 @@ public: F32 mAlphaCutoff; AlphaMode mAlphaMode; - bool mDoubleSided; + bool mDoubleSided = false; // Override specific flags for state that can't use off-by-epsilon or UUID // hack - bool mOverrideDoubleSided; - bool mOverrideAlphaMode; + bool mOverrideDoubleSided = false; + bool mOverrideAlphaMode = false; }; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 8c9076bd8b..a4f9132ddd 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1934,6 +1934,19 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic) } } + +void LLReflectionProbeParams::setIsMirror(bool is_mirror) +{ + if (is_mirror) + { + mFlags |= FLAG_MIRROR; + } + else + { + mFlags &= ~FLAG_MIRROR; + } +} + //============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 1c04e0b595..2b15adb162 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -186,6 +186,7 @@ public: { FLAG_BOX_VOLUME = 0x01, // use a box influence volume FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe + FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors. }; protected: @@ -209,11 +210,13 @@ public: void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); } void setIsBox(bool is_box); void setIsDynamic(bool is_dynamic); + void setIsMirror(bool is_mirror); F32 getAmbiance() const { return mAmbiance; } F32 getClipDistance() const { return mClipDistance; } bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; } bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; } + bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; } }; //------------------------------------------------- diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 71caff1686..ee2a4c769a 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -685,6 +685,7 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) mMaterialUpdatePending = true; } mMaterial = pMaterialParams; + return TEM_CHANGE_TEXTURE; } diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index f5f2c0172d..0935147688 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -134,7 +134,7 @@ public: S32 setGlow(F32 glow); S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 88b6fae3a7..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), 216); + 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); + } } |