925fcc9f68b57dbbdac7c5fbb91e03184bffa0f0
[mono.git] / mcs / class / referencesource / System.Numerics / System / Numerics / Vector3_Intrinsics.cs
1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4 using System.Runtime.CompilerServices;
5
6 namespace System.Numerics
7 {
8     // This file contains the definitions for all of the JIT intrinsic methods and properties that are recognized by the current x64 JIT compiler.
9     // The implementation defined here is used in any circumstance where the JIT fails to recognize these members as intrinsic.
10     // The JIT recognizes these methods and properties by name and signature: if either is changed, the JIT will no longer recognize the member.
11     // Some methods declared here are not strictly intrinsic, but delegate to an intrinsic method. For example, only one overload of CopyTo()
12     // is actually recognized by the JIT, but both are here for simplicity.
13
14     public partial struct Vector3
15     {
16         /// <summary>
17         /// The X component of the vector.
18         /// </summary>
19         public Single X;
20         /// <summary>
21         /// The Y component of the vector.
22         /// </summary>
23         public Single Y;
24         /// <summary>
25         /// The Z component of the vector.
26         /// </summary>
27         public Single Z;
28
29         #region Constructors
30         /// <summary>
31         /// Constructs a vector whose elements are all the single specified value.
32         /// </summary>
33         /// <param name="value">The element to fill the vector with.</param>
34         [JitIntrinsic]
35         public Vector3(Single value) : this(value, value, value) { }
36
37         /// <summary>
38         /// Constructs a Vector3 from the given Vector2 and a third value.
39         /// </summary>
40         /// <param name="value">The Vector to extract X and Y components from.</param>
41         /// <param name="z">The Z component.</param>
42         public Vector3(Vector2 value, float z) : this(value.X, value.Y, z) { }
43
44         /// <summary>
45         /// Constructs a vector with the given individual elements.
46         /// </summary>
47         /// <param name="x">The X component.</param>
48         /// <param name="y">The Y component.</param>
49         /// <param name="z">The Z component.</param>
50         [JitIntrinsic]
51         public Vector3(Single x, Single y, Single z)
52         {
53             X = x;
54             Y = y;
55             Z = z;
56         }
57         #endregion Constructors
58
59         #region Public Instance Methods
60         /// <summary>
61         /// Copies the contents of the vector into the given array.
62         /// </summary>
63         [MethodImpl(MethodImplOptions.AggressiveInlining)]
64         public void CopyTo(Single[] array)
65         {
66             CopyTo(array, 0);
67         }
68
69         /// <summary>
70         /// Copies the contents of the vector into the given array, starting from index.
71         /// </summary>
72         /// <exception cref="ArgumentNullException">If array is null.</exception>
73         /// <exception cref="RankException">If array is multidimensional.</exception>
74         /// <exception cref="ArgumentOutOfRangeException">If index is greater than end of the array or index is less than zero.</exception>
75         /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array.</exception>
76         [JitIntrinsic]
77         [MethodImpl(MethodImplOptions.AggressiveInlining)]
78         public void CopyTo(Single[] array, int index)
79         {
80             if (array == null)
81                 throw new ArgumentNullException("values");
82             if (index < 0 || index >= array.Length)
83                 throw new ArgumentOutOfRangeException(SR.GetString("Arg_ArgumentOutOfRangeException", index));
84             if ((array.Length - index) < 3)
85                 throw new ArgumentException(SR.GetString("Arg_ElementsInSourceIsGreaterThanDestination", index));
86             array[index] = X;
87             array[index + 1] = Y;
88             array[index + 2] = Z;
89         }
90
91         /// <summary>
92         /// Returns a boolean indicating whether the given Vector3 is equal to this Vector3 instance.
93         /// </summary>
94         /// <param name="other">The Vector3 to compare this instance to.</param>
95         /// <returns>True if the other Vector3 is equal to this instance; False otherwise.</returns>
96         [JitIntrinsic]
97         public bool Equals(Vector3 other)
98         {
99             return X == other.X &&
100                    Y == other.Y &&
101                    Z == other.Z;
102         }
103         #endregion Public Instance Methods
104
105         #region Public Static Methods
106         /// <summary>
107         /// Returns the dot product of two vectors.
108         /// </summary>
109         /// <param name="vector1">The first vector.</param>
110         /// <param name="vector2">The second vector.</param>
111         /// <returns>The dot product.</returns>
112         [JitIntrinsic]
113         [MethodImpl(MethodImplOptions.AggressiveInlining)]
114         public static float Dot(Vector3 vector1, Vector3 vector2)
115         {
116             return vector1.X * vector2.X +
117                    vector1.Y * vector2.Y +
118                    vector1.Z * vector2.Z;
119         }
120
121         /// <summary>
122         /// Returns a vector whose elements are the minimum of each of the pairs of elements in the two source vectors.
123         /// </summary>
124         /// <param name="value1">The first source vector.</param>
125         /// <param name="value2">The second source vector.</param>
126         /// <returns>The minimized vector.</returns>
127         [JitIntrinsic]
128         public static Vector3 Min(Vector3 value1, Vector3 value2)
129         {
130             return new Vector3(
131                 (value1.X < value2.X) ? value1.X : value2.X,
132                 (value1.Y < value2.Y) ? value1.Y : value2.Y,
133                 (value1.Z < value2.Z) ? value1.Z : value2.Z);
134         }
135
136         /// <summary>
137         /// Returns a vector whose elements are the maximum of each of the pairs of elements in the two source vectors.
138         /// </summary>
139         /// <param name="value1">The first source vector.</param>
140         /// <param name="value2">The second source vector.</param>
141         /// <returns>The maximized vector.</returns>
142         [JitIntrinsic]
143         [MethodImpl(MethodImplOptions.AggressiveInlining)]
144         public static Vector3 Max(Vector3 value1, Vector3 value2)
145         {
146             return new Vector3(
147                 (value1.X > value2.X) ? value1.X : value2.X,
148                 (value1.Y > value2.Y) ? value1.Y : value2.Y,
149                 (value1.Z > value2.Z) ? value1.Z : value2.Z);
150         }
151
152         /// <summary>
153         /// Returns a vector whose elements are the absolute values of each of the source vector's elements.
154         /// </summary>
155         /// <param name="value">The source vector.</param>
156         /// <returns>The absolute value vector.</returns>
157         [JitIntrinsic]
158         [MethodImpl(MethodImplOptions.AggressiveInlining)]
159         public static Vector3 Abs(Vector3 value)
160         {
161             return new Vector3(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z));
162         }
163
164         /// <summary>
165         /// Returns a vector whose elements are the square root of each of the source vector's elements.
166         /// </summary>
167         /// <param name="value">The source vector.</param>
168         /// <returns>The square root vector.</returns>
169         [JitIntrinsic]
170         [MethodImpl(MethodImplOptions.AggressiveInlining)]
171         public static Vector3 SquareRoot(Vector3 value)
172         {
173             return new Vector3((Single)Math.Sqrt(value.X), (Single)Math.Sqrt(value.Y), (Single)Math.Sqrt(value.Z));
174         }
175         #endregion Public Static Methods
176
177         #region Public Static Operators
178         /// <summary>
179         /// Adds two vectors together.
180         /// </summary>
181         /// <param name="left">The first source vector.</param>
182         /// <param name="right">The second source vector.</param>
183         /// <returns>The summed vector.</returns>
184         [JitIntrinsic]
185         [MethodImpl(MethodImplOptions.AggressiveInlining)]
186         public static Vector3 operator +(Vector3 left, Vector3 right)
187         {
188             return new Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
189         }
190
191         /// <summary>
192         /// Subtracts the second vector from the first.
193         /// </summary>
194         /// <param name="left">The first source vector.</param>
195         /// <param name="right">The second source vector.</param>
196         /// <returns>The difference vector.</returns>
197         [JitIntrinsic]
198         [MethodImpl(MethodImplOptions.AggressiveInlining)]
199         public static Vector3 operator -(Vector3 left, Vector3 right)
200         {
201             return new Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
202         }
203
204         /// <summary>
205         /// Multiplies two vectors together.
206         /// </summary>
207         /// <param name="left">The first source vector.</param>
208         /// <param name="right">The second source vector.</param>
209         /// <returns>The product vector.</returns>
210         [JitIntrinsic]
211         [MethodImpl(MethodImplOptions.AggressiveInlining)]
212         public static Vector3 operator *(Vector3 left, Vector3 right)
213         {
214             return new Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
215         }
216
217         /// <summary>
218         /// Multiplies a vector by the given scalar.
219         /// </summary>
220         /// <param name="left">The source vector.</param>
221         /// <param name="right">The scalar value.</param>
222         /// <returns>The scaled vector.</returns>
223         [JitIntrinsic]
224         [MethodImpl(MethodImplOptions.AggressiveInlining)]
225         public static Vector3 operator *(Vector3 left, Single right)
226         {
227             return left * new Vector3(right);
228         }
229
230         /// <summary>
231         /// Multiplies a vector by the given scalar.
232         /// </summary>
233         /// <param name="left">The scalar value.</param>
234         /// <param name="right">The source vector.</param>
235         /// <returns>The scaled vector.</returns>
236         [JitIntrinsic]
237         [MethodImpl(MethodImplOptions.AggressiveInlining)]
238         public static Vector3 operator *(Single left, Vector3 right)
239         {
240             return new Vector3(left) * right;
241         }
242
243         /// <summary>
244         /// Divides the first vector by the second.
245         /// </summary>
246         /// <param name="left">The first source vector.</param>
247         /// <param name="right">The second source vector.</param>
248         /// <returns>The vector resulting from the division.</returns>
249         [JitIntrinsic]
250         [MethodImpl(MethodImplOptions.AggressiveInlining)]
251         public static Vector3 operator /(Vector3 left, Vector3 right)
252         {
253             return new Vector3(left.X / right.X, left.Y / right.Y, left.Z / right.Z);
254         }
255
256         /// <summary>
257         /// Divides the vector by the given scalar.
258         /// </summary>
259         /// <param name="value1">The source vector.</param>
260         /// <param name="value2">The scalar value.</param>
261         /// <returns>The result of the division.</returns>
262         [JitIntrinsic]
263         [MethodImpl(MethodImplOptions.AggressiveInlining)]
264         public static Vector3 operator /(Vector3 value1, float value2)
265         {
266             float invDiv = 1.0f / value2;
267
268             return new Vector3(
269                 value1.X * invDiv,
270                 value1.Y * invDiv,
271                 value1.Z * invDiv);
272         }
273
274         /// <summary>
275         /// Negates a given vector.
276         /// </summary>
277         /// <param name="value">The source vector.</param>
278         /// <returns>The negated vector.</returns>
279         [MethodImpl(MethodImplOptions.AggressiveInlining)]
280         public static Vector3 operator -(Vector3 value)
281         {
282             return Zero - value;
283         }
284
285         /// <summary>
286         /// Returns a boolean indicating whether the two given vectors are equal.
287         /// </summary>
288         /// <param name="left">The first vector to compare.</param>
289         /// <param name="right">The second vector to compare.</param>
290         /// <returns>True if the vectors are equal; False otherwise.</returns>
291         [JitIntrinsic]
292         [MethodImpl(MethodImplOptions.AggressiveInlining)]
293         public static bool operator ==(Vector3 left, Vector3 right)
294         {
295             return (left.X == right.X &&
296                     left.Y == right.Y &&
297                     left.Z == right.Z);
298         }
299
300         /// <summary>
301         /// Returns a boolean indicating whether the two given vectors are not equal.
302         /// </summary>
303         /// <param name="left">The first vector to compare.</param>
304         /// <param name="right">The second vector to compare.</param>
305         /// <returns>True if the vectors are not equal; False if they are equal.</returns>
306         [MethodImpl(MethodImplOptions.AggressiveInlining)]
307         public static bool operator !=(Vector3 left, Vector3 right)
308         {
309             return (left.X != right.X ||
310                     left.Y != right.Y ||
311                     left.Z != right.Z);
312         }
313         #endregion Public Static Operators
314     }
315 }