| 2147 | |
| 2148 | COVERAGE(HMM_MulQ, 1) |
| 2149 | static inline HMM_Quat HMM_MulQ(HMM_Quat Left, HMM_Quat Right) |
| 2150 | { |
| 2151 | ASSERT_COVERED(HMM_MulQ); |
| 2152 | |
| 2153 | HMM_Quat Result; |
| 2154 | |
| 2155 | #ifdef HANDMADE_MATH__USE_SSE |
| 2156 | __m128 SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(0, 0, 0, 0)), _mm_setr_ps(0.f, -0.f, 0.f, -0.f)); |
| 2157 | __m128 SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(0, 1, 2, 3)); |
| 2158 | __m128 SSEResultThree = _mm_mul_ps(SSEResultTwo, SSEResultOne); |
| 2159 | |
| 2160 | SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(1, 1, 1, 1)) , _mm_setr_ps(0.f, 0.f, -0.f, -0.f)); |
| 2161 | SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(1, 0, 3, 2)); |
| 2162 | SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); |
| 2163 | |
| 2164 | SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(2, 2, 2, 2)), _mm_setr_ps(-0.f, 0.f, 0.f, -0.f)); |
| 2165 | SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(2, 3, 0, 1)); |
| 2166 | SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); |
| 2167 | |
| 2168 | SSEResultOne = _mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(3, 3, 3, 3)); |
| 2169 | SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(3, 2, 1, 0)); |
| 2170 | Result.SSE = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); |
| 2171 | #else |
| 2172 | Result.X = Right.Elements[3] * +Left.Elements[0]; |
| 2173 | Result.Y = Right.Elements[2] * -Left.Elements[0]; |
| 2174 | Result.Z = Right.Elements[1] * +Left.Elements[0]; |
| 2175 | Result.W = Right.Elements[0] * -Left.Elements[0]; |
| 2176 | |
| 2177 | Result.X += Right.Elements[2] * +Left.Elements[1]; |
| 2178 | Result.Y += Right.Elements[3] * +Left.Elements[1]; |
| 2179 | Result.Z += Right.Elements[0] * -Left.Elements[1]; |
| 2180 | Result.W += Right.Elements[1] * -Left.Elements[1]; |
| 2181 | |
| 2182 | Result.X += Right.Elements[1] * -Left.Elements[2]; |
| 2183 | Result.Y += Right.Elements[0] * +Left.Elements[2]; |
| 2184 | Result.Z += Right.Elements[3] * +Left.Elements[2]; |
| 2185 | Result.W += Right.Elements[2] * -Left.Elements[2]; |
| 2186 | |
| 2187 | Result.X += Right.Elements[0] * +Left.Elements[3]; |
| 2188 | Result.Y += Right.Elements[1] * +Left.Elements[3]; |
| 2189 | Result.Z += Right.Elements[2] * +Left.Elements[3]; |
| 2190 | Result.W += Right.Elements[3] * +Left.Elements[3]; |
| 2191 | #endif |
| 2192 | |
| 2193 | return Result; |
| 2194 | } |
| 2195 | |
| 2196 | COVERAGE(HMM_MulQF, 1) |
| 2197 | static inline HMM_Quat HMM_MulQF(HMM_Quat Left, float Multiplicative) |