Procházet zdrojové kódy

Added UVec4::operator -, -=, Dot and DotV (#1676)

* Fixed missing const
Jorrit Rouwe před 1 měsícem
rodič
revize
e1b4a498b6
5 změnil soubory, kde provedl 84 přidání a 7 odebrání
  1. 2 2
      Jolt/Core/Array.h
  2. 15 3
      Jolt/Math/UVec4.h
  3. 56 1
      Jolt/Math/UVec4.inl
  4. 1 1
      Jolt/Math/Vec4.h
  5. 10 0
      UnitTests/Math/UVec4Tests.cpp

+ 2 - 2
Jolt/Core/Array.h

@@ -69,8 +69,8 @@ public:
 		rev_it &			operator -- ()					{ ++mValue; return *this; }
 		rev_it &			operator -- ()					{ ++mValue; return *this; }
 		rev_it				operator -- (int)				{ return rev_it(mValue++); }
 		rev_it				operator -- (int)				{ return rev_it(mValue++); }
 
 
-		rev_it				operator + (int inValue)		{ return rev_it(mValue - inValue); }
-		rev_it				operator - (int inValue)		{ return rev_it(mValue + inValue); }
+		rev_it				operator + (int inValue) const	{ return rev_it(mValue - inValue); }
+		rev_it				operator - (int inValue) const	{ return rev_it(mValue + inValue); }
 
 
 		rev_it &			operator += (int inValue)		{ mValue -= inValue; return *this; }
 		rev_it &			operator += (int inValue)		{ mValue -= inValue; return *this; }
 		rev_it &			operator -= (int inValue)		{ mValue += inValue; return *this; }
 		rev_it &			operator -= (int inValue)		{ mValue += inValue; return *this; }

+ 15 - 3
Jolt/Math/UVec4.h

@@ -115,15 +115,21 @@ public:
 	JPH_INLINE uint32			operator [] (uint inCoordinate) const				{ JPH_ASSERT(inCoordinate < 4); return mU32[inCoordinate]; }
 	JPH_INLINE uint32			operator [] (uint inCoordinate) const				{ JPH_ASSERT(inCoordinate < 4); return mU32[inCoordinate]; }
 	JPH_INLINE uint32 &			operator [] (uint inCoordinate)						{ JPH_ASSERT(inCoordinate < 4); return mU32[inCoordinate]; }
 	JPH_INLINE uint32 &			operator [] (uint inCoordinate)						{ JPH_ASSERT(inCoordinate < 4); return mU32[inCoordinate]; }
 
 
-	/// Multiplies each of the 4 integer components with an integer (discards any overflow)
+	/// Component wise multiplication of two integer vectors (stores low 32 bits of result only)
 	JPH_INLINE UVec4			operator * (UVec4Arg inV2) const;
 	JPH_INLINE UVec4			operator * (UVec4Arg inV2) const;
 
 
-	/// Adds an integer value to all integer components (discards any overflow)
-	JPH_INLINE UVec4			operator + (UVec4Arg inV2);
+	/// Add two integer vectors (component wise)
+	JPH_INLINE UVec4			operator + (UVec4Arg inV2) const;
 
 
 	/// Add two integer vectors (component wise)
 	/// Add two integer vectors (component wise)
 	JPH_INLINE UVec4 &			operator += (UVec4Arg inV2);
 	JPH_INLINE UVec4 &			operator += (UVec4Arg inV2);
 
 
+	/// Subtract two integer vectors (component wise)
+	JPH_INLINE UVec4			operator - (UVec4Arg inV2) const;
+
+	/// Subtract two integer vectors (component wise)
+	JPH_INLINE UVec4 &			operator -= (UVec4Arg inV2);
+
 	/// Replicate the X component to all components
 	/// Replicate the X component to all components
 	JPH_INLINE UVec4			SplatX() const;
 	JPH_INLINE UVec4			SplatX() const;
 
 
@@ -142,6 +148,12 @@ public:
 	/// Reinterpret UVec4 as a Vec4 (doesn't change the bits)
 	/// Reinterpret UVec4 as a Vec4 (doesn't change the bits)
 	JPH_INLINE Vec4				ReinterpretAsFloat() const;
 	JPH_INLINE Vec4				ReinterpretAsFloat() const;
 
 
+	/// Dot product, returns the dot product in X, Y, Z and W components
+	JPH_INLINE UVec4			DotV(UVec4Arg inV2) const;
+
+	/// Dot product
+	JPH_INLINE uint32			Dot(UVec4Arg inV2) const;
+
 	/// Store 4 ints to memory
 	/// Store 4 ints to memory
 	JPH_INLINE void				StoreInt4(uint32 *outV) const;
 	JPH_INLINE void				StoreInt4(uint32 *outV) const;
 
 

+ 56 - 1
Jolt/Math/UVec4.inl

@@ -255,7 +255,7 @@ UVec4 UVec4::operator * (UVec4Arg inV2) const
 #endif
 #endif
 }
 }
 
 
-UVec4 UVec4::operator + (UVec4Arg inV2)
+UVec4 UVec4::operator + (UVec4Arg inV2) const
 {
 {
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)
 	return _mm_add_epi32(mValue, inV2.mValue);
 	return _mm_add_epi32(mValue, inV2.mValue);
@@ -282,6 +282,33 @@ UVec4 &UVec4::operator += (UVec4Arg inV2)
 	return *this;
 	return *this;
 }
 }
 
 
+UVec4 UVec4::operator - (UVec4Arg inV2) const
+{
+#if defined(JPH_USE_SSE)
+	return _mm_sub_epi32(mValue, inV2.mValue);
+#elif defined(JPH_USE_NEON)
+	return vsubq_u32(mValue, inV2.mValue);
+#else
+	return UVec4(mU32[0] - inV2.mU32[0],
+				 mU32[1] - inV2.mU32[1],
+				 mU32[2] - inV2.mU32[2],
+				 mU32[3] - inV2.mU32[3]);
+#endif
+}
+
+UVec4 &UVec4::operator -= (UVec4Arg inV2)
+{
+#if defined(JPH_USE_SSE)
+	mValue = _mm_sub_epi32(mValue, inV2.mValue);
+#elif defined(JPH_USE_NEON)
+	mValue = vsubq_u32(mValue, inV2.mValue);
+#else
+	for (int i = 0; i < 4; ++i)
+		mU32[i] -= inV2.mU32[i];
+#endif
+	return *this;
+}
+
 UVec4 UVec4::SplatX() const
 UVec4 UVec4::SplatX() const
 {
 {
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)
@@ -348,6 +375,34 @@ Vec4 UVec4::ReinterpretAsFloat() const
 #endif
 #endif
 }
 }
 
 
+UVec4 UVec4::DotV(UVec4Arg inV2) const
+{
+#if defined(JPH_USE_SSE4_1)
+	__m128i mul = _mm_mullo_epi32(mValue, inV2.mValue);
+    __m128i sum = _mm_add_epi32(mul, _mm_shuffle_epi32(mul, _MM_SHUFFLE(2, 3, 0, 1)));
+    return _mm_add_epi32(sum, _mm_shuffle_epi32(sum, _MM_SHUFFLE(1, 0, 3, 2)));
+#elif defined(JPH_USE_NEON)
+	uint32x4_t mul = vmulq_u32(mValue, inV2.mValue);
+	return vdupq_n_u32(vaddvq_u32(mul));
+#else
+	return UVec4::sReplicate(mU32[0] * inV2.mU32[0] + mU32[1] * inV2.mU32[1] + mU32[2] * inV2.mU32[2] + mU32[3] * inV2.mU32[3]);
+#endif
+}
+
+uint32 UVec4::Dot(UVec4Arg inV2) const
+{
+#if defined(JPH_USE_SSE4_1)
+	__m128i mul = _mm_mullo_epi32(mValue, inV2.mValue);
+    __m128i sum = _mm_add_epi32(mul, _mm_shuffle_epi32(mul, _MM_SHUFFLE(2, 3, 0, 1)));
+    return _mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_shuffle_epi32(sum, _MM_SHUFFLE(1, 0, 3, 2))));
+#elif defined(JPH_USE_NEON)
+	uint32x4_t mul = vmulq_u32(mValue, inV2.mValue);
+	return vaddvq_u32(mul);
+#else
+	return mU32[0] * inV2.mU32[0] + mU32[1] * inV2.mU32[1] + mU32[2] * inV2.mU32[2] + mU32[3] * inV2.mU32[3];
+#endif
+}
+
 void UVec4::StoreInt4(uint32 *outV) const
 void UVec4::StoreInt4(uint32 *outV) const
 {
 {
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)

+ 1 - 1
Jolt/Math/Vec4.h

@@ -221,7 +221,7 @@ public:
 	/// Reciprocal vector (1 / value) for each of the components
 	/// Reciprocal vector (1 / value) for each of the components
 	JPH_INLINE Vec4				Reciprocal() const;
 	JPH_INLINE Vec4				Reciprocal() const;
 
 
-	/// Dot product, returns the dot product in X, Y and Z components
+	/// Dot product, returns the dot product in X, Y, Z and W components
 	JPH_INLINE Vec4				DotV(Vec4Arg inV2) const;
 	JPH_INLINE Vec4				DotV(Vec4Arg inV2) const;
 
 
 	/// Dot product
 	/// Dot product

+ 10 - 0
UnitTests/Math/UVec4Tests.cpp

@@ -222,11 +222,15 @@ TEST_SUITE("UVec4Tests")
 	{
 	{
 		CHECK(UVec4(1, 2, 3, 4) + UVec4(5, 6, 7, 8) == UVec4(6, 8, 10, 12));
 		CHECK(UVec4(1, 2, 3, 4) + UVec4(5, 6, 7, 8) == UVec4(6, 8, 10, 12));
 
 
+		CHECK(UVec4(5, 6, 7, 8) - UVec4(4, 3, 2, 1) == UVec4(1, 3, 5, 7));
+
 		CHECK(UVec4(1, 2, 3, 4) * UVec4(5, 6, 7, 8) == UVec4(1 * 5, 2 * 6, 3 * 7, 4 * 8));
 		CHECK(UVec4(1, 2, 3, 4) * UVec4(5, 6, 7, 8) == UVec4(1 * 5, 2 * 6, 3 * 7, 4 * 8));
 
 
 		UVec4 v = UVec4(1, 2, 3, 4);
 		UVec4 v = UVec4(1, 2, 3, 4);
 		v += UVec4(5, 6, 7, 8);
 		v += UVec4(5, 6, 7, 8);
 		CHECK(v == UVec4(6, 8, 10, 12));
 		CHECK(v == UVec4(6, 8, 10, 12));
+		v -= UVec4(4, 3, 2, 1);
+		CHECK(v == UVec4(2, 5, 8, 11));
 	}
 	}
 
 
 	TEST_CASE("TestUVec4Swizzle")
 	TEST_CASE("TestUVec4Swizzle")
@@ -499,6 +503,12 @@ TEST_SUITE("UVec4Tests")
 		CHECK(v.Swizzle<SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W>() == UVec4(4, 4, 4, 4));
 		CHECK(v.Swizzle<SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W>() == UVec4(4, 4, 4, 4));
 	}
 	}
 
 
+	TEST_CASE("TestUVec4Dot")
+	{
+		CHECK(UVec4(1, 2, 3, 4).Dot(UVec4(5, 6, 7, 8)) == 1 * 5 + 2 * 6 + 3 * 7 + 4 * 8);
+		CHECK(UVec4(1, 2, 3, 4).DotV(UVec4(5, 6, 7, 8)) == UVec4::sReplicate(1 * 5 + 2 * 6 + 3 * 7 + 4 * 8));
+	}
+
 	TEST_CASE("TestUVec4Cast")
 	TEST_CASE("TestUVec4Cast")
 	{
 	{
 		CHECK(UVec4(1, 2, 3, 4).ToFloat() == Vec4(1, 2, 3, 4));
 		CHECK(UVec4(1, 2, 3, 4).ToFloat() == Vec4(1, 2, 3, 4));