Skip to content

Commit ba252ac

Browse files
committed
Merge remote-tracking branch 'martenf/vectorsimd' into numerics-cleanup
2 parents 94bb125 + 00199d2 commit ba252ac

File tree

3 files changed

+41
-94
lines changed

3 files changed

+41
-94
lines changed

src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs

+4-25
Original file line numberDiff line numberDiff line change
@@ -166,31 +166,10 @@ public Vector3 Translation
166166
public static Impl operator *(in Impl left, in Impl right)
167167
{
168168
Impl result;
169-
170-
// result.X = Transform(left.X, in right);
171-
result.X = right.X * left.X.X;
172-
result.X += right.Y * left.X.Y;
173-
result.X += right.Z * left.X.Z;
174-
result.X += right.W * left.X.W;
175-
176-
// result.Y = Transform(left.Y, in right);
177-
result.Y = right.X * left.Y.X;
178-
result.Y += right.Y * left.Y.Y;
179-
result.Y += right.Z * left.Y.Z;
180-
result.Y += right.W * left.Y.W;
181-
182-
// result.Z = Transform(left.Z, in right);
183-
result.Z = right.X * left.Z.X;
184-
result.Z += right.Y * left.Z.Y;
185-
result.Z += right.Z * left.Z.Z;
186-
result.Z += right.W * left.Z.W;
187-
188-
// result.W = Transform(left.W, in right);
189-
result.W = right.X * left.W.X;
190-
result.W += right.Y * left.W.Y;
191-
result.W += right.Z * left.W.Z;
192-
result.W += right.W * left.W.W;
193-
169+
result.X = Vector4.Transform(left.X, in right);
170+
result.Y = Vector4.Transform(left.Y, in right);
171+
result.Z = Vector4.Transform(left.Z, in right);
172+
result.W = Vector4.Transform(left.W, in right);
194173
return result;
195174
}
196175

src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.cs

+3-64
Original file line numberDiff line numberDiff line change
@@ -103,40 +103,7 @@ public float this[int index]
103103
/// <remarks>The <see cref="op_Division" /> method defines the division operation for <see cref="Quaternion" /> objects.</remarks>
104104
public static Quaternion operator /(Quaternion value1, Quaternion value2)
105105
{
106-
Quaternion ans;
107-
108-
float q1x = value1.X;
109-
float q1y = value1.Y;
110-
float q1z = value1.Z;
111-
float q1w = value1.W;
112-
113-
//-------------------------------------
114-
// Inverse part.
115-
float ls = value2.X * value2.X + value2.Y * value2.Y +
116-
value2.Z * value2.Z + value2.W * value2.W;
117-
float invNorm = 1.0f / ls;
118-
119-
float q2x = -value2.X * invNorm;
120-
float q2y = -value2.Y * invNorm;
121-
float q2z = -value2.Z * invNorm;
122-
float q2w = value2.W * invNorm;
123-
124-
//-------------------------------------
125-
// Multiply part.
126-
127-
// cross(av, bv)
128-
float cx = q1y * q2z - q1z * q2y;
129-
float cy = q1z * q2x - q1x * q2z;
130-
float cz = q1x * q2y - q1y * q2x;
131-
132-
float dot = q1x * q2x + q1y * q2y + q1z * q2z;
133-
134-
ans.X = q1x * q2w + q2x * q1w + cx;
135-
ans.Y = q1y * q2w + q2y * q1w + cy;
136-
ans.Z = q1z * q2w + q2z * q1w + cz;
137-
ans.W = q1w * q2w - dot;
138-
139-
return ans;
106+
return value1 * Inverse(value2);
140107
}
141108

142109
/// <summary>Returns a value that indicates whether two quaternions are equal.</summary>
@@ -169,6 +136,7 @@ public float this[int index]
169136
Vector128<float> right = value2.AsVector128();
170137

171138
Vector128<float> result = right * left.GetElementUnsafe(3);
139+
172140
result += (Vector128.Shuffle(right, Vector128.Create(3, 2, 1, 0)) * left.GetElementUnsafe(0)) * Vector128.Create(+1.0f, -1.0f, +1.0f, -1.0f);
173141
result += (Vector128.Shuffle(right, Vector128.Create(2, 3, 0, 1)) * left.GetElementUnsafe(1)) * Vector128.Create(+1.0f, +1.0f, -1.0f, -1.0f);
174142
result += (Vector128.Shuffle(right, Vector128.Create(1, 0, 3, 2)) * left.GetElementUnsafe(2)) * Vector128.Create(-1.0f, +1.0f, +1.0f, -1.0f);
@@ -241,36 +209,7 @@ public float this[int index]
241209
/// <param name="value1">The first quaternion rotation in the series.</param>
242210
/// <param name="value2">The second quaternion rotation in the series.</param>
243211
/// <returns>A new quaternion representing the concatenation of the <paramref name="value1" /> rotation followed by the <paramref name="value2" /> rotation.</returns>
244-
public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
245-
{
246-
Quaternion ans;
247-
248-
// Concatenate rotation is actually q2 * q1 instead of q1 * q2.
249-
// So that's why value2 goes q1 and value1 goes q2.
250-
float q1x = value2.X;
251-
float q1y = value2.Y;
252-
float q1z = value2.Z;
253-
float q1w = value2.W;
254-
255-
float q2x = value1.X;
256-
float q2y = value1.Y;
257-
float q2z = value1.Z;
258-
float q2w = value1.W;
259-
260-
// cross(av, bv)
261-
float cx = q1y * q2z - q1z * q2y;
262-
float cy = q1z * q2x - q1x * q2z;
263-
float cz = q1x * q2y - q1y * q2x;
264-
265-
float dot = q1x * q2x + q1y * q2y + q1z * q2z;
266-
267-
ans.X = q1x * q2w + q2x * q1w + cx;
268-
ans.Y = q1y * q2w + q2y * q1w + cy;
269-
ans.Z = q1z * q2w + q2z * q1w + cz;
270-
ans.W = q1w * q2w - dot;
271-
272-
return ans;
273-
}
212+
public static Quaternion Concatenate(Quaternion value1, Quaternion value2) => value2 * value1;
274213

275214
/// <summary>Returns the conjugate of a specified quaternion.</summary>
276215
/// <param name="value">The quaternion.</param>

src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs

+34-5
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,23 @@ public static Vector3 Create(ReadOnlySpan<float> values)
296296
[MethodImpl(MethodImplOptions.AggressiveInlining)]
297297
public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
298298
{
299-
return Create(
300-
(vector1.Y * vector2.Z) - (vector1.Z * vector2.Y),
301-
(vector1.Z * vector2.X) - (vector1.X * vector2.Z),
302-
(vector1.X * vector2.Y) - (vector1.Y * vector2.X)
303-
);
299+
if (Vector128.IsHardwareAccelerated)
300+
{
301+
var v1 = vector1.AsVector128();
302+
var v2 = vector2.AsVector128();
303+
return ((Vector128.Shuffle(v1, Vector128.Create(1, 2, 0, 3)) *
304+
Vector128.Shuffle(v2, Vector128.Create(2, 0, 1, 3))) -
305+
(Vector128.Shuffle(v1, Vector128.Create(2, 0, 1, 3)) *
306+
Vector128.Shuffle(v2, Vector128.Create(1, 2, 0, 3)))).AsVector3();
307+
}
308+
else
309+
{
310+
return Create(
311+
(vector1.Y * vector2.Z) - (vector1.Z * vector2.Y),
312+
(vector1.Z * vector2.X) - (vector1.X * vector2.Z),
313+
(vector1.X * vector2.Y) - (vector1.Y * vector2.X)
314+
);
315+
}
304316
}
305317

306318
/// <summary>Computes the Euclidean distance between the two given points.</summary>
@@ -442,6 +454,23 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
442454
[MethodImpl(MethodImplOptions.AggressiveInlining)]
443455
public static Vector3 Transform(Vector3 value, Quaternion rotation)
444456
{
457+
if (Vector128.IsHardwareAccelerated)
458+
{
459+
var vVector = value.AsVector128();
460+
var rVector = Unsafe.BitCast<Quaternion, Vector128<float>>(rotation);
461+
462+
// v + 2 * (q x (q.W * v + q x v)
463+
return (vVector + Vector128.Create(2f) * Cross(rVector, Vector128.Shuffle(rVector, Vector128.Create(3, 3, 3, 3)) * vVector + Cross(rVector, vVector))).AsVector3();
464+
465+
static Vector128<float> Cross(Vector128<float> v1, Vector128<float> v2)
466+
{
467+
return (Vector128.Shuffle(v1, Vector128.Create(1, 2, 0, 3)) *
468+
Vector128.Shuffle(v2, Vector128.Create(2, 0, 1, 3))) -
469+
(Vector128.Shuffle(v1, Vector128.Create(2, 0, 1, 3)) *
470+
Vector128.Shuffle(v2, Vector128.Create(1, 2, 0, 3)));
471+
}
472+
}
473+
445474
float x2 = rotation.X + rotation.X;
446475
float y2 = rotation.Y + rotation.Y;
447476
float z2 = rotation.Z + rotation.Z;

0 commit comments

Comments
 (0)