[OpenTK] Introduce OpenTK (#336)
[platform/core/csapi/tizenfx.git] / external / src / OpenTK / OpenTK / Math / Vector4.cs
1 /*
2 Copyright (c) 2006 - 2008 The Open Toolkit library.
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21  */
22
23 using System;
24 using System.Runtime.InteropServices;
25 using System.Xml.Serialization;
26
27 namespace OpenTK
28 {
29     /// <summary>Represents a 4D vector using four single-precision floating-point numbers.</summary>
30     /// <remarks>
31     /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats.
32     /// </remarks>
33     [Serializable]
34     [StructLayout(LayoutKind.Sequential)]
35     public struct Vector4 : IEquatable<Vector4>
36     {
37         /// <summary>
38         /// The X component of the Vector4.
39         /// </summary>
40         public float X;
41
42         /// <summary>
43         /// The Y component of the Vector4.
44         /// </summary>
45         public float Y;
46
47         /// <summary>
48         /// The Z component of the Vector4.
49         /// </summary>
50         public float Z;
51
52         /// <summary>
53         /// The W component of the Vector4.
54         /// </summary>
55         public float W;
56
57         /// <summary>
58         /// Defines a unit-length Vector4 that points towards the X-axis.
59         /// </summary>
60         public static readonly Vector4 UnitX = new Vector4(1, 0, 0, 0);
61
62         /// <summary>
63         /// Defines a unit-length Vector4 that points towards the Y-axis.
64         /// </summary>
65         public static readonly Vector4 UnitY = new Vector4(0, 1, 0, 0);
66
67         /// <summary>
68         /// Defines a unit-length Vector4 that points towards the Z-axis.
69         /// </summary>
70         public static readonly Vector4 UnitZ = new Vector4(0, 0, 1, 0);
71
72         /// <summary>
73         /// Defines a unit-length Vector4 that points towards the W-axis.
74         /// </summary>
75         public static readonly Vector4 UnitW = new Vector4(0, 0, 0, 1);
76
77         /// <summary>
78         /// Defines a zero-length Vector4.
79         /// </summary>
80         public static readonly Vector4 Zero = new Vector4(0, 0, 0, 0);
81
82         /// <summary>
83         /// Defines an instance with all components set to 1.
84         /// </summary>
85         public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
86
87         /// <summary>
88         /// Defines the size of the Vector4 struct in bytes.
89         /// </summary>
90         public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
91
92         /// <summary>
93         /// Constructs a new instance.
94         /// </summary>
95         /// <param name="value">The value that will initialize this instance.</param>
96         public Vector4(float value)
97         {
98             X = value;
99             Y = value;
100             Z = value;
101             W = value;
102         }
103
104         /// <summary>
105         /// Constructs a new Vector4.
106         /// </summary>
107         /// <param name="x">The x component of the Vector4.</param>
108         /// <param name="y">The y component of the Vector4.</param>
109         /// <param name="z">The z component of the Vector4.</param>
110         /// <param name="w">The w component of the Vector4.</param>
111         public Vector4(float x, float y, float z, float w)
112         {
113             X = x;
114             Y = y;
115             Z = z;
116             W = w;
117         }
118
119         /// <summary>
120         /// Constructs a new Vector4 from the given Vector2.
121         /// </summary>
122         /// <param name="v">The Vector2 to copy components from.</param>
123         public Vector4(Vector2 v)
124         {
125             X = v.X;
126             Y = v.Y;
127             Z = 0.0f;
128             W = 0.0f;
129         }
130
131         /// <summary>
132         /// Constructs a new Vector4 from the given Vector3.
133         /// The w component is initialized to 0.
134         /// </summary>
135         /// <param name="v">The Vector3 to copy components from.</param>
136         /// <remarks><seealso cref="Vector4(Vector3, float)"/></remarks>
137         public Vector4(Vector3 v)
138         {
139             X = v.X;
140             Y = v.Y;
141             Z = v.Z;
142             W = 0.0f;
143         }
144
145         /// <summary>
146         /// Constructs a new Vector4 from the specified Vector3 and w component.
147         /// </summary>
148         /// <param name="v">The Vector3 to copy components from.</param>
149         /// <param name="w">The w component of the new Vector4.</param>
150         public Vector4(Vector3 v, float w)
151         {
152             X = v.X;
153             Y = v.Y;
154             Z = v.Z;
155             W = w;
156         }
157
158         /// <summary>
159         /// Constructs a new Vector4 from the given Vector4.
160         /// </summary>
161         /// <param name="v">The Vector4 to copy components from.</param>
162         public Vector4(Vector4 v)
163         {
164             X = v.X;
165             Y = v.Y;
166             Z = v.Z;
167             W = v.W;
168         }
169
170         /// <summary>
171         /// Gets or sets the value at the index of the Vector.
172         /// </summary>
173         public float this[int index] {
174             get{
175                 if (index == 0)
176                 {
177                     return X;
178                 }
179                 else if (index == 1)
180                 {
181                     return Y;
182                 }
183                 else if (index == 2)
184                 {
185                     return Z;
186                 }
187                 else if (index == 3)
188                 {
189                     return W;
190                 }
191                 throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
192             } set{
193                 if (index == 0)
194                 {
195                     X = value;
196                 }
197                 else if (index == 1)
198                 {
199                     Y = value;
200                 }
201                 else if (index == 2)
202                 {
203                     Z = value;
204                 }
205                 else if (index == 3)
206                 {
207                     W = value;
208                 }
209                 else
210                 {
211                     throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
212                 }
213             }
214         }
215
216         /// <summary>
217         /// Gets the length (magnitude) of the vector.
218         /// </summary>
219         /// <see cref="LengthFast"/>
220         /// <seealso cref="LengthSquared"/>
221         public float Length
222         {
223             get
224             {
225                 return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
226             }
227         }
228
229         /// <summary>
230         /// Gets an approximation of the vector length (magnitude).
231         /// </summary>
232         /// <remarks>
233         /// This property uses an approximation of the square root function to calculate vector magnitude, with
234         /// an upper error bound of 0.001.
235         /// </remarks>
236         /// <see cref="Length"/>
237         /// <seealso cref="LengthSquared"/>
238         public float LengthFast
239         {
240             get
241             {
242                 return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
243             }
244         }
245
246         /// <summary>
247         /// Gets the square of the vector length (magnitude).
248         /// </summary>
249         /// <remarks>
250         /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
251         /// for comparisons.
252         /// </remarks>
253         /// <see cref="Length"/>
254         /// <seealso cref="LengthFast"/>
255         public float LengthSquared
256         {
257             get
258             {
259                 return X * X + Y * Y + Z * Z + W * W;
260             }
261         }
262
263         /// <summary>
264         /// Returns a copy of the Vector4 scaled to unit length.
265         /// </summary>
266         public Vector4 Normalized()
267         {
268             Vector4 v = this;
269             v.Normalize();
270             return v;
271         }
272
273         /// <summary>
274         /// Scales the Vector4 to unit length.
275         /// </summary>
276         public void Normalize()
277         {
278             float scale = 1.0f / this.Length;
279             X *= scale;
280             Y *= scale;
281             Z *= scale;
282             W *= scale;
283         }
284
285         /// <summary>
286         /// Scales the Vector4 to approximately unit length.
287         /// </summary>
288         public void NormalizeFast()
289         {
290             float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
291             X *= scale;
292             Y *= scale;
293             Z *= scale;
294             W *= scale;
295         }
296
297         /// <summary>
298         /// Adds two vectors.
299         /// </summary>
300         /// <param name="a">Left operand.</param>
301         /// <param name="b">Right operand.</param>
302         /// <returns>Result of operation.</returns>
303         public static Vector4 Add(Vector4 a, Vector4 b)
304         {
305             Add(ref a, ref b, out a);
306             return a;
307         }
308
309         /// <summary>
310         /// Adds two vectors.
311         /// </summary>
312         /// <param name="a">Left operand.</param>
313         /// <param name="b">Right operand.</param>
314         /// <param name="result">Result of operation.</param>
315         public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
316         {
317             result.X = a.X + b.X;
318             result.Y = a.Y + b.Y;
319             result.Z = a.Z + b.Z;
320             result.W = a.W + b.W;
321         }
322
323         /// <summary>
324         /// Subtract one Vector from another
325         /// </summary>
326         /// <param name="a">First operand</param>
327         /// <param name="b">Second operand</param>
328         /// <returns>Result of subtraction</returns>
329         public static Vector4 Subtract(Vector4 a, Vector4 b)
330         {
331             Subtract(ref a, ref b, out a);
332             return a;
333         }
334
335         /// <summary>
336         /// Subtract one Vector from another
337         /// </summary>
338         /// <param name="a">First operand</param>
339         /// <param name="b">Second operand</param>
340         /// <param name="result">Result of subtraction</param>
341         public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result)
342         {
343             result.X = a.X - b.X;
344             result.Y = a.Y - b.Y;
345             result.Z = a.Z - b.Z;
346             result.W = a.W - b.W;
347         }
348
349         /// <summary>
350         /// Multiplies a vector by a scalar.
351         /// </summary>
352         /// <param name="vector">Left operand.</param>
353         /// <param name="scale">Right operand.</param>
354         /// <returns>Result of the operation.</returns>
355         public static Vector4 Multiply(Vector4 vector, float scale)
356         {
357             Multiply(ref vector, scale, out vector);
358             return vector;
359         }
360
361         /// <summary>
362         /// Multiplies a vector by a scalar.
363         /// </summary>
364         /// <param name="vector">Left operand.</param>
365         /// <param name="scale">Right operand.</param>
366         /// <param name="result">Result of the operation.</param>
367         public static void Multiply(ref Vector4 vector, float scale, out Vector4 result)
368         {
369             result.X = vector.X * scale;
370             result.Y = vector.Y * scale;
371             result.Z = vector.Z * scale;
372             result.W = vector.W * scale;
373         }
374
375         /// <summary>
376         /// Multiplies a vector by the components a vector (scale).
377         /// </summary>
378         /// <param name="vector">Left operand.</param>
379         /// <param name="scale">Right operand.</param>
380         /// <returns>Result of the operation.</returns>
381         public static Vector4 Multiply(Vector4 vector, Vector4 scale)
382         {
383             Multiply(ref vector, ref scale, out vector);
384             return vector;
385         }
386
387         /// <summary>
388         /// Multiplies a vector by the components of a vector (scale).
389         /// </summary>
390         /// <param name="vector">Left operand.</param>
391         /// <param name="scale">Right operand.</param>
392         /// <param name="result">Result of the operation.</param>
393         public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
394         {
395             result.X = vector.X * scale.X;
396             result.Y = vector.Y * scale.Y;
397             result.Z = vector.Z * scale.Z;
398             result.W = vector.W * scale.W;
399         }
400
401         /// <summary>
402         /// Divides a vector by a scalar.
403         /// </summary>
404         /// <param name="vector">Left operand.</param>
405         /// <param name="scale">Right operand.</param>
406         /// <returns>Result of the operation.</returns>
407         public static Vector4 Divide(Vector4 vector, float scale)
408         {
409             Divide(ref vector, scale, out vector);
410             return vector;
411         }
412
413         /// <summary>
414         /// Divides a vector by a scalar.
415         /// </summary>
416         /// <param name="vector">Left operand.</param>
417         /// <param name="scale">Right operand.</param>
418         /// <param name="result">Result of the operation.</param>
419         public static void Divide(ref Vector4 vector, float scale, out Vector4 result)
420         {
421             result.X = vector.X / scale;
422             result.Y = vector.Y / scale;
423             result.Z = vector.Z / scale;
424             result.W = vector.W / scale;
425         }
426
427         /// <summary>
428         /// Divides a vector by the components of a vector (scale).
429         /// </summary>
430         /// <param name="vector">Left operand.</param>
431         /// <param name="scale">Right operand.</param>
432         /// <returns>Result of the operation.</returns>
433         public static Vector4 Divide(Vector4 vector, Vector4 scale)
434         {
435             Divide(ref vector, ref scale, out vector);
436             return vector;
437         }
438
439         /// <summary>
440         /// Divide a vector by the components of a vector (scale).
441         /// </summary>
442         /// <param name="vector">Left operand.</param>
443         /// <param name="scale">Right operand.</param>
444         /// <param name="result">Result of the operation.</param>
445         public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
446         {
447             result.X = vector.X / scale.X;
448             result.Y = vector.Y / scale.Y;
449             result.Z = vector.Z / scale.Z;
450             result.W = vector.W / scale.W;
451         }
452
453         /// <summary>
454         /// Calculate the component-wise minimum of two vectors
455         /// </summary>
456         /// <param name="a">First operand</param>
457         /// <param name="b">Second operand</param>
458         /// <returns>The component-wise minimum</returns>
459         [Obsolete("Use ComponentMin() instead.")]
460         public static Vector4 Min(Vector4 a, Vector4 b)
461         {
462             a.X = a.X < b.X ? a.X : b.X;
463             a.Y = a.Y < b.Y ? a.Y : b.Y;
464             a.Z = a.Z < b.Z ? a.Z : b.Z;
465             a.W = a.W < b.W ? a.W : b.W;
466             return a;
467         }
468
469         /// <summary>
470         /// Calculate the component-wise minimum of two vectors
471         /// </summary>
472         /// <param name="a">First operand</param>
473         /// <param name="b">Second operand</param>
474         /// <param name="result">The component-wise minimum</param>
475         [Obsolete("Use ComponentMin() instead.")]
476         public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
477         {
478             result.X = a.X < b.X ? a.X : b.X;
479             result.Y = a.Y < b.Y ? a.Y : b.Y;
480             result.Z = a.Z < b.Z ? a.Z : b.Z;
481             result.W = a.W < b.W ? a.W : b.W;
482         }
483
484         /// <summary>
485         /// Calculate the component-wise maximum of two vectors
486         /// </summary>
487         /// <param name="a">First operand</param>
488         /// <param name="b">Second operand</param>
489         /// <returns>The component-wise maximum</returns>
490         [Obsolete("Use ComponentMax() instead.")]
491         public static Vector4 Max(Vector4 a, Vector4 b)
492         {
493             a.X = a.X > b.X ? a.X : b.X;
494             a.Y = a.Y > b.Y ? a.Y : b.Y;
495             a.Z = a.Z > b.Z ? a.Z : b.Z;
496             a.W = a.W > b.W ? a.W : b.W;
497             return a;
498         }
499
500         /// <summary>
501         /// Calculate the component-wise maximum of two vectors
502         /// </summary>
503         /// <param name="a">First operand</param>
504         /// <param name="b">Second operand</param>
505         /// <param name="result">The component-wise maximum</param>
506         [Obsolete("Use ComponentMax() instead.")]
507         public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
508         {
509             result.X = a.X > b.X ? a.X : b.X;
510             result.Y = a.Y > b.Y ? a.Y : b.Y;
511             result.Z = a.Z > b.Z ? a.Z : b.Z;
512             result.W = a.W > b.W ? a.W : b.W;
513         }
514
515         /// <summary>
516         /// Returns a vector created from the smallest of the corresponding components of the given vectors.
517         /// </summary>
518         /// <param name="a">First operand</param>
519         /// <param name="b">Second operand</param>
520         /// <returns>The component-wise minimum</returns>
521         public static Vector4 ComponentMin(Vector4 a, Vector4 b)
522         {
523             a.X = a.X < b.X ? a.X : b.X;
524             a.Y = a.Y < b.Y ? a.Y : b.Y;
525             a.Z = a.Z < b.Z ? a.Z : b.Z;
526             a.W = a.W < b.W ? a.W : b.W;
527             return a;
528         }
529
530         /// <summary>
531         /// Returns a vector created from the smallest of the corresponding components of the given vectors.
532         /// </summary>
533         /// <param name="a">First operand</param>
534         /// <param name="b">Second operand</param>
535         /// <param name="result">The component-wise minimum</param>
536         public static void ComponentMin(ref Vector4 a, ref Vector4 b, out Vector4 result)
537         {
538             result.X = a.X < b.X ? a.X : b.X;
539             result.Y = a.Y < b.Y ? a.Y : b.Y;
540             result.Z = a.Z < b.Z ? a.Z : b.Z;
541             result.W = a.W < b.W ? a.W : b.W;
542         }
543
544         /// <summary>
545         /// Returns a vector created from the largest of the corresponding components of the given vectors.
546         /// </summary>
547         /// <param name="a">First operand</param>
548         /// <param name="b">Second operand</param>
549         /// <returns>The component-wise maximum</returns>
550         public static Vector4 ComponentMax(Vector4 a, Vector4 b)
551         {
552             a.X = a.X > b.X ? a.X : b.X;
553             a.Y = a.Y > b.Y ? a.Y : b.Y;
554             a.Z = a.Z > b.Z ? a.Z : b.Z;
555             a.W = a.W > b.W ? a.W : b.W;
556             return a;
557         }
558
559         /// <summary>
560         /// Returns a vector created from the largest of the corresponding components of the given vectors.
561         /// </summary>
562         /// <param name="a">First operand</param>
563         /// <param name="b">Second operand</param>
564         /// <param name="result">The component-wise maximum</param>
565         public static void ComponentMax(ref Vector4 a, ref Vector4 b, out Vector4 result)
566         {
567             result.X = a.X > b.X ? a.X : b.X;
568             result.Y = a.Y > b.Y ? a.Y : b.Y;
569             result.Z = a.Z > b.Z ? a.Z : b.Z;
570             result.W = a.W > b.W ? a.W : b.W;
571         }
572
573         /// <summary>
574         /// Returns the Vector4 with the minimum magnitude. If the magnitudes are equal, the second vector
575         /// is selected.
576         /// </summary>
577         /// <param name="left">Left operand</param>
578         /// <param name="right">Right operand</param>
579         /// <returns>The minimum Vector4</returns>
580         public static Vector4 MagnitudeMin(Vector4 left, Vector4 right)
581         {
582             return left.LengthSquared < right.LengthSquared ? left : right;
583         }
584
585         /// <summary>
586         /// Returns the Vector4 with the minimum magnitude. If the magnitudes are equal, the second vector
587         /// is selected.
588         /// </summary>
589         /// <param name="left">Left operand</param>
590         /// <param name="right">Right operand</param>
591         /// <param name="result">The magnitude-wise minimum</param>
592         /// <returns>The minimum Vector4</returns>
593         public static void MagnitudeMin(ref Vector4 left, ref Vector4 right, out Vector4 result)
594         {
595             result = left.LengthSquared < right.LengthSquared ? left : right;
596         }
597
598         /// <summary>
599         /// Returns the Vector4 with the maximum magnitude. If the magnitudes are equal, the first vector
600         /// is selected.
601         /// </summary>
602         /// <param name="left">Left operand</param>
603         /// <param name="right">Right operand</param>
604         /// <returns>The maximum Vector4</returns>
605         public static Vector4 MagnitudeMax(Vector4 left, Vector4 right)
606         {
607             return left.LengthSquared >= right.LengthSquared ? left : right;
608         }
609
610         /// <summary>
611         /// Returns the Vector4 with the maximum magnitude. If the magnitudes are equal, the first vector
612         /// is selected.
613         /// </summary>
614         /// <param name="left">Left operand</param>
615         /// <param name="right">Right operand</param>
616         /// <param name="result">The magnitude-wise maximum</param>
617         /// <returns>The maximum Vector4</returns>
618         public static void MagnitudeMax(ref Vector4 left, ref Vector4 right, out Vector4 result)
619         {
620             result = left.LengthSquared >= right.LengthSquared ? left : right;
621         }
622
623         /// <summary>
624         /// Clamp a vector to the given minimum and maximum vectors
625         /// </summary>
626         /// <param name="vec">Input vector</param>
627         /// <param name="min">Minimum vector</param>
628         /// <param name="max">Maximum vector</param>
629         /// <returns>The clamped vector</returns>
630         public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
631         {
632             vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
633             vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
634             vec.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
635             vec.W = vec.W < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
636             return vec;
637         }
638
639         /// <summary>
640         /// Clamp a vector to the given minimum and maximum vectors
641         /// </summary>
642         /// <param name="vec">Input vector</param>
643         /// <param name="min">Minimum vector</param>
644         /// <param name="max">Maximum vector</param>
645         /// <param name="result">The clamped vector</param>
646         public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
647         {
648             result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
649             result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
650             result.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
651             result.W = vec.W < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
652         }
653
654         /// <summary>
655         /// Scale a vector to unit length
656         /// </summary>
657         /// <param name="vec">The input vector</param>
658         /// <returns>The normalized vector</returns>
659         public static Vector4 Normalize(Vector4 vec)
660         {
661             float scale = 1.0f / vec.Length;
662             vec.X *= scale;
663             vec.Y *= scale;
664             vec.Z *= scale;
665             vec.W *= scale;
666             return vec;
667         }
668
669         /// <summary>
670         /// Scale a vector to unit length
671         /// </summary>
672         /// <param name="vec">The input vector</param>
673         /// <param name="result">The normalized vector</param>
674         public static void Normalize(ref Vector4 vec, out Vector4 result)
675         {
676             float scale = 1.0f / vec.Length;
677             result.X = vec.X * scale;
678             result.Y = vec.Y * scale;
679             result.Z = vec.Z * scale;
680             result.W = vec.W * scale;
681         }
682
683         /// <summary>
684         /// Scale a vector to approximately unit length
685         /// </summary>
686         /// <param name="vec">The input vector</param>
687         /// <returns>The normalized vector</returns>
688         public static Vector4 NormalizeFast(Vector4 vec)
689         {
690             float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
691             vec.X *= scale;
692             vec.Y *= scale;
693             vec.Z *= scale;
694             vec.W *= scale;
695             return vec;
696         }
697
698         /// <summary>
699         /// Scale a vector to approximately unit length
700         /// </summary>
701         /// <param name="vec">The input vector</param>
702         /// <param name="result">The normalized vector</param>
703         public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
704         {
705             float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
706             result.X = vec.X * scale;
707             result.Y = vec.Y * scale;
708             result.Z = vec.Z * scale;
709             result.W = vec.W * scale;
710         }
711
712         /// <summary>
713         /// Calculate the dot product of two vectors
714         /// </summary>
715         /// <param name="left">First operand</param>
716         /// <param name="right">Second operand</param>
717         /// <returns>The dot product of the two inputs</returns>
718         public static float Dot(Vector4 left, Vector4 right)
719         {
720             return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
721         }
722
723         /// <summary>
724         /// Calculate the dot product of two vectors
725         /// </summary>
726         /// <param name="left">First operand</param>
727         /// <param name="right">Second operand</param>
728         /// <param name="result">The dot product of the two inputs</param>
729         public static void Dot(ref Vector4 left, ref Vector4 right, out float result)
730         {
731             result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
732         }
733
734         /// <summary>
735         /// Returns a new Vector that is the linear blend of the 2 given Vectors
736         /// </summary>
737         /// <param name="a">First input vector</param>
738         /// <param name="b">Second input vector</param>
739         /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
740         /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
741         public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
742         {
743             a.X = blend * (b.X - a.X) + a.X;
744             a.Y = blend * (b.Y - a.Y) + a.Y;
745             a.Z = blend * (b.Z - a.Z) + a.Z;
746             a.W = blend * (b.W - a.W) + a.W;
747             return a;
748         }
749
750         /// <summary>
751         /// Returns a new Vector that is the linear blend of the 2 given Vectors
752         /// </summary>
753         /// <param name="a">First input vector</param>
754         /// <param name="b">Second input vector</param>
755         /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
756         /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
757         public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result)
758         {
759             result.X = blend * (b.X - a.X) + a.X;
760             result.Y = blend * (b.Y - a.Y) + a.Y;
761             result.Z = blend * (b.Z - a.Z) + a.Z;
762             result.W = blend * (b.W - a.W) + a.W;
763         }
764
765         /// <summary>
766         /// Interpolate 3 Vectors using Barycentric coordinates
767         /// </summary>
768         /// <param name="a">First input Vector</param>
769         /// <param name="b">Second input Vector</param>
770         /// <param name="c">Third input Vector</param>
771         /// <param name="u">First Barycentric Coordinate</param>
772         /// <param name="v">Second Barycentric Coordinate</param>
773         /// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
774         public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
775         {
776             return a + u * (b - a) + v * (c - a);
777         }
778
779         /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
780         /// <param name="a">First input Vector.</param>
781         /// <param name="b">Second input Vector.</param>
782         /// <param name="c">Third input Vector.</param>
783         /// <param name="u">First Barycentric Coordinate.</param>
784         /// <param name="v">Second Barycentric Coordinate.</param>
785         /// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
786         public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result)
787         {
788             result = a; // copy
789
790             Vector4 temp = b; // copy
791             Subtract(ref temp, ref a, out temp);
792             Multiply(ref temp, u, out temp);
793             Add(ref result, ref temp, out result);
794
795             temp = c; // copy
796             Subtract(ref temp, ref a, out temp);
797             Multiply(ref temp, v, out temp);
798             Add(ref result, ref temp, out result);
799         }
800
801         /// <summary>Transform a Vector by the given Matrix</summary>
802         /// <param name="vec">The vector to transform</param>
803         /// <param name="mat">The desired transformation</param>
804         /// <returns>The transformed vector</returns>
805         public static Vector4 Transform(Vector4 vec, Matrix4 mat)
806         {
807             Vector4 result;
808             Transform(ref vec, ref mat, out result);
809             return result;
810         }
811
812         /// <summary>Transform a Vector by the given Matrix</summary>
813         /// <param name="vec">The vector to transform</param>
814         /// <param name="mat">The desired transformation</param>
815         /// <param name="result">The transformed vector</param>
816         public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result)
817         {
818             result = new Vector4(
819                 vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X,
820                 vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y,
821                 vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z,
822                 vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W);
823         }
824
825         /// <summary>
826         /// Transforms a vector by a quaternion rotation.
827         /// </summary>
828         /// <param name="vec">The vector to transform.</param>
829         /// <param name="quat">The quaternion to rotate the vector by.</param>
830         /// <returns>The result of the operation.</returns>
831         public static Vector4 Transform(Vector4 vec, Quaternion quat)
832         {
833             Vector4 result;
834             Transform(ref vec, ref quat, out result);
835             return result;
836         }
837
838         /// <summary>
839         /// Transforms a vector by a quaternion rotation.
840         /// </summary>
841         /// <param name="vec">The vector to transform.</param>
842         /// <param name="quat">The quaternion to rotate the vector by.</param>
843         /// <param name="result">The result of the operation.</param>
844         public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result)
845         {
846             Quaternion v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W), i, t;
847             Quaternion.Invert(ref quat, out i);
848             Quaternion.Multiply(ref quat, ref v, out t);
849             Quaternion.Multiply(ref t, ref i, out v);
850
851             result.X = v.X;
852             result.Y = v.Y;
853             result.Z = v.Z;
854             result.W = v.W;
855         }
856
857         /// <summary>Transform a Vector by the given Matrix using right-handed notation</summary>
858         /// <param name="mat">The desired transformation</param>
859         /// <param name="vec">The vector to transform</param>
860         public static Vector4 Transform(Matrix4 mat, Vector4 vec)
861         {
862             Vector4 result;
863             Transform(ref mat, ref vec, out result);
864             return result;
865         }
866
867         /// <summary>Transform a Vector by the given Matrix using right-handed notation</summary>
868         /// <param name="mat">The desired transformation</param>
869         /// <param name="vec">The vector to transform</param>
870         /// <param name="result">The transformed vector</param>
871         public static void Transform(ref Matrix4 mat, ref Vector4 vec, out Vector4 result)
872         {
873             result = new Vector4(
874                 mat.Row0.X * vec.X + mat.Row0.Y * vec.Y + mat.Row0.Z * vec.Z + mat.Row0.W * vec.W,
875                 mat.Row1.X * vec.X + mat.Row1.Y * vec.Y + mat.Row1.Z * vec.Z + mat.Row1.W * vec.W,
876                 mat.Row2.X * vec.X + mat.Row2.Y * vec.Y + mat.Row2.Z * vec.Z + mat.Row2.W * vec.W,
877                 mat.Row3.X * vec.X + mat.Row3.Y * vec.Y + mat.Row3.Z * vec.Z + mat.Row3.W * vec.W);
878         }
879
880         /// <summary>
881         /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
882         /// </summary>
883         [XmlIgnore]
884         public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
885
886         /// <summary>
887         /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance.
888         /// </summary>
889         [XmlIgnore]
890         public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } }
891
892         /// <summary>
893         /// Gets or sets an OpenTK.Vector2 with the X and W components of this instance.
894         /// </summary>
895         [XmlIgnore]
896         public Vector2 Xw { get { return new Vector2(X, W); } set { X = value.X; W = value.Y; } }
897
898         /// <summary>
899         /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance.
900         /// </summary>
901         [XmlIgnore]
902         public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } }
903
904         /// <summary>
905         /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance.
906         /// </summary>
907         [XmlIgnore]
908         public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } }
909
910         /// <summary>
911         /// Gets or sets an OpenTK.Vector2 with the Y and W components of this instance.
912         /// </summary>
913         [XmlIgnore]
914         public Vector2 Yw { get { return new Vector2(Y, W); } set { Y = value.X; W = value.Y; } }
915
916         /// <summary>
917         /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance.
918         /// </summary>
919         [XmlIgnore]
920         public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } }
921
922         /// <summary>
923         /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance.
924         /// </summary>
925         [XmlIgnore]
926         public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } }
927
928         /// <summary>
929         /// Gets an OpenTK.Vector2 with the Z and W components of this instance.
930         /// </summary>
931         [XmlIgnore]
932         public Vector2 Zw { get { return new Vector2(Z, W); } set { Z = value.X; W = value.Y; } }
933
934         /// <summary>
935         /// Gets or sets an OpenTK.Vector2 with the W and X components of this instance.
936         /// </summary>
937         [XmlIgnore]
938         public Vector2 Wx { get { return new Vector2(W, X); } set { W = value.X; X = value.Y; } }
939
940         /// <summary>
941         /// Gets or sets an OpenTK.Vector2 with the W and Y components of this instance.
942         /// </summary>
943         [XmlIgnore]
944         public Vector2 Wy { get { return new Vector2(W, Y); } set { W = value.X; Y = value.Y; } }
945
946         /// <summary>
947         /// Gets or sets an OpenTK.Vector2 with the W and Z components of this instance.
948         /// </summary>
949         [XmlIgnore]
950         public Vector2 Wz { get { return new Vector2(W, Z); } set { W = value.X; Z = value.Y; } }
951
952         /// <summary>
953         /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
954         /// </summary>
955         [XmlIgnore]
956         public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
957
958         /// <summary>
959         /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
960         /// </summary>
961         [XmlIgnore]
962         public Vector3 Xyw { get { return new Vector3(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } }
963
964         /// <summary>
965         /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance.
966         /// </summary>
967         [XmlIgnore]
968         public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
969
970         /// <summary>
971         /// Gets or sets an OpenTK.Vector3 with the X, Z, and W components of this instance.
972         /// </summary>
973         [XmlIgnore]
974         public Vector3 Xzw { get { return new Vector3(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } }
975
976         /// <summary>
977         /// Gets or sets an OpenTK.Vector3 with the X, W, and Y components of this instance.
978         /// </summary>
979         [XmlIgnore]
980         public Vector3 Xwy { get { return new Vector3(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } }
981
982         /// <summary>
983         /// Gets or sets an OpenTK.Vector3 with the X, W, and Z components of this instance.
984         /// </summary>
985         [XmlIgnore]
986         public Vector3 Xwz { get { return new Vector3(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } }
987
988         /// <summary>
989         /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance.
990         /// </summary>
991         [XmlIgnore]
992         public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
993
994         /// <summary>
995         /// Gets or sets an OpenTK.Vector3 with the Y, X, and W components of this instance.
996         /// </summary>
997         [XmlIgnore]
998         public Vector3 Yxw { get { return new Vector3(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } }
999
1000         /// <summary>
1001         /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance.
1002         /// </summary>
1003         [XmlIgnore]
1004         public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
1005
1006         /// <summary>
1007         /// Gets or sets an OpenTK.Vector3 with the Y, Z, and W components of this instance.
1008         /// </summary>
1009         [XmlIgnore]
1010         public Vector3 Yzw { get { return new Vector3(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } }
1011
1012         /// <summary>
1013         /// Gets or sets an OpenTK.Vector3 with the Y, W, and X components of this instance.
1014         /// </summary>
1015         [XmlIgnore]
1016         public Vector3 Ywx { get { return new Vector3(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } }
1017
1018         /// <summary>
1019         /// Gets an OpenTK.Vector3 with the Y, W, and Z components of this instance.
1020         /// </summary>
1021         [XmlIgnore]
1022         public Vector3 Ywz { get { return new Vector3(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } }
1023
1024         /// <summary>
1025         /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance.
1026         /// </summary>
1027         [XmlIgnore]
1028         public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
1029
1030         /// <summary>
1031         /// Gets or sets an OpenTK.Vector3 with the Z, X, and W components of this instance.
1032         /// </summary>
1033         [XmlIgnore]
1034         public Vector3 Zxw { get { return new Vector3(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } }
1035
1036         /// <summary>
1037         /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance.
1038         /// </summary>
1039         [XmlIgnore]
1040         public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
1041
1042         /// <summary>
1043         /// Gets or sets an OpenTK.Vector3 with the Z, Y, and W components of this instance.
1044         /// </summary>
1045         [XmlIgnore]
1046         public Vector3 Zyw { get { return new Vector3(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } }
1047
1048         /// <summary>
1049         /// Gets or sets an OpenTK.Vector3 with the Z, W, and X components of this instance.
1050         /// </summary>
1051         [XmlIgnore]
1052         public Vector3 Zwx { get { return new Vector3(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } }
1053
1054         /// <summary>
1055         /// Gets or sets an OpenTK.Vector3 with the Z, W, and Y components of this instance.
1056         /// </summary>
1057         [XmlIgnore]
1058         public Vector3 Zwy { get { return new Vector3(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } }
1059
1060         /// <summary>
1061         /// Gets or sets an OpenTK.Vector3 with the W, X, and Y components of this instance.
1062         /// </summary>
1063         [XmlIgnore]
1064         public Vector3 Wxy { get { return new Vector3(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } }
1065
1066         /// <summary>
1067         /// Gets or sets an OpenTK.Vector3 with the W, X, and Z components of this instance.
1068         /// </summary>
1069         [XmlIgnore]
1070         public Vector3 Wxz { get { return new Vector3(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } }
1071
1072         /// <summary>
1073         /// Gets or sets an OpenTK.Vector3 with the W, Y, and X components of this instance.
1074         /// </summary>
1075         [XmlIgnore]
1076         public Vector3 Wyx { get { return new Vector3(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } }
1077
1078         /// <summary>
1079         /// Gets or sets an OpenTK.Vector3 with the W, Y, and Z components of this instance.
1080         /// </summary>
1081         [XmlIgnore]
1082         public Vector3 Wyz { get { return new Vector3(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } }
1083
1084         /// <summary>
1085         /// Gets or sets an OpenTK.Vector3 with the W, Z, and X components of this instance.
1086         /// </summary>
1087         [XmlIgnore]
1088         public Vector3 Wzx { get { return new Vector3(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } }
1089
1090         /// <summary>
1091         /// Gets or sets an OpenTK.Vector3 with the W, Z, and Y components of this instance.
1092         /// </summary>
1093         [XmlIgnore]
1094         public Vector3 Wzy { get { return new Vector3(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } }
1095
1096         /// <summary>
1097         /// Gets or sets an OpenTK.Vector4 with the X, Y, W, and Z components of this instance.
1098         /// </summary>
1099         [XmlIgnore]
1100         public Vector4 Xywz { get { return new Vector4(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
1101
1102         /// <summary>
1103         /// Gets or sets an OpenTK.Vector4 with the X, Z, Y, and W components of this instance.
1104         /// </summary>
1105         [XmlIgnore]
1106         public Vector4 Xzyw { get { return new Vector4(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
1107
1108         /// <summary>
1109         /// Gets or sets an OpenTK.Vector4 with the X, Z, W, and Y components of this instance.
1110         /// </summary>
1111         [XmlIgnore]
1112         public Vector4 Xzwy { get { return new Vector4(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } }
1113
1114         /// <summary>
1115         /// Gets or sets an OpenTK.Vector4 with the X, W, Y, and Z components of this instance.
1116         /// </summary>
1117         [XmlIgnore]
1118         public Vector4 Xwyz { get { return new Vector4(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } }
1119
1120         /// <summary>
1121         /// Gets or sets an OpenTK.Vector4 with the X, W, Z, and Y components of this instance.
1122         /// </summary>
1123         [XmlIgnore]
1124         public Vector4 Xwzy { get { return new Vector4(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
1125
1126         /// <summary>
1127         /// Gets or sets an OpenTK.Vector4 with the Y, X, Z, and W components of this instance.
1128         /// </summary>
1129         [XmlIgnore]
1130         public Vector4 Yxzw { get { return new Vector4(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } }
1131
1132         /// <summary>
1133         /// Gets or sets an OpenTK.Vector4 with the Y, X, W, and Z components of this instance.
1134         /// </summary>
1135         [XmlIgnore]
1136         public Vector4 Yxwz { get { return new Vector4(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } }
1137
1138         /// <summary>
1139         /// Gets an OpenTK.Vector4 with the Y, Y, Z, and W components of this instance.
1140         /// </summary>
1141         [XmlIgnore]
1142         public Vector4 Yyzw { get { return new Vector4(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } }
1143
1144         /// <summary>
1145         /// Gets an OpenTK.Vector4 with the Y, Y, W, and Z components of this instance.
1146         /// </summary>
1147         [XmlIgnore]
1148         public Vector4 Yywz { get { return new Vector4(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
1149
1150         /// <summary>
1151         /// Gets or sets an OpenTK.Vector4 with the Y, Z, X, and W components of this instance.
1152         /// </summary>
1153         [XmlIgnore]
1154         public Vector4 Yzxw { get { return new Vector4(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } }
1155
1156         /// <summary>
1157         /// Gets or sets an OpenTK.Vector4 with the Y, Z, W, and X components of this instance.
1158         /// </summary>
1159         [XmlIgnore]
1160         public Vector4 Yzwx { get { return new Vector4(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } }
1161
1162         /// <summary>
1163         /// Gets or sets an OpenTK.Vector4 with the Y, W, X, and Z components of this instance.
1164         /// </summary>
1165         [XmlIgnore]
1166         public Vector4 Ywxz { get { return new Vector4(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } }
1167
1168         /// <summary>
1169         /// Gets or sets an OpenTK.Vector4 with the Y, W, Z, and X components of this instance.
1170         /// </summary>
1171         [XmlIgnore]
1172         public Vector4 Ywzx { get { return new Vector4(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } }
1173
1174         /// <summary>
1175         /// Gets or sets an OpenTK.Vector4 with the Z, X, Y, and Z components of this instance.
1176         /// </summary>
1177         [XmlIgnore]
1178         public Vector4 Zxyw { get { return new Vector4(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } }
1179
1180         /// <summary>
1181         /// Gets or sets an OpenTK.Vector4 with the Z, X, W, and Y components of this instance.
1182         /// </summary>
1183         [XmlIgnore]
1184         public Vector4 Zxwy { get { return new Vector4(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } }
1185
1186         /// <summary>
1187         /// Gets or sets an OpenTK.Vector4 with the Z, Y, X, and W components of this instance.
1188         /// </summary>
1189         [XmlIgnore]
1190         public Vector4 Zyxw { get { return new Vector4(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } }
1191
1192         /// <summary>
1193         /// Gets or sets an OpenTK.Vector4 with the Z, Y, W, and X components of this instance.
1194         /// </summary>
1195         [XmlIgnore]
1196         public Vector4 Zywx { get { return new Vector4(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } }
1197
1198         /// <summary>
1199         /// Gets or sets an OpenTK.Vector4 with the Z, W, X, and Y components of this instance.
1200         /// </summary>
1201         [XmlIgnore]
1202         public Vector4 Zwxy { get { return new Vector4(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } }
1203
1204         /// <summary>
1205         /// Gets or sets an OpenTK.Vector4 with the Z, W, Y, and X components of this instance.
1206         /// </summary>
1207         [XmlIgnore]
1208         public Vector4 Zwyx { get { return new Vector4(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } }
1209
1210         /// <summary>
1211         /// Gets an OpenTK.Vector4 with the Z, W, Z, and Y components of this instance.
1212         /// </summary>
1213         [XmlIgnore]
1214         public Vector4 Zwzy { get { return new Vector4(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
1215
1216         /// <summary>
1217         /// Gets or sets an OpenTK.Vector4 with the W, X, Y, and Z components of this instance.
1218         /// </summary>
1219         [XmlIgnore]
1220         public Vector4 Wxyz { get { return new Vector4(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } }
1221
1222         /// <summary>
1223         /// Gets or sets an OpenTK.Vector4 with the W, X, Z, and Y components of this instance.
1224         /// </summary>
1225         [XmlIgnore]
1226         public Vector4 Wxzy { get { return new Vector4(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } }
1227
1228         /// <summary>
1229         /// Gets or sets an OpenTK.Vector4 with the W, Y, X, and Z components of this instance.
1230         /// </summary>
1231         [XmlIgnore]
1232         public Vector4 Wyxz { get { return new Vector4(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } }
1233
1234         /// <summary>
1235         /// Gets or sets an OpenTK.Vector4 with the W, Y, Z, and X components of this instance.
1236         /// </summary>
1237         [XmlIgnore]
1238         public Vector4 Wyzx { get { return new Vector4(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } }
1239
1240         /// <summary>
1241         /// Gets or sets an OpenTK.Vector4 with the W, Z, X, and Y components of this instance.
1242         /// </summary>
1243         [XmlIgnore]
1244         public Vector4 Wzxy { get { return new Vector4(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } }
1245
1246         /// <summary>
1247         /// Gets or sets an OpenTK.Vector4 with the W, Z, Y, and X components of this instance.
1248         /// </summary>
1249         [XmlIgnore]
1250         public Vector4 Wzyx { get { return new Vector4(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } }
1251
1252         /// <summary>
1253         /// Gets an OpenTK.Vector4 with the W, Z, Y, and W components of this instance.
1254         /// </summary>
1255         [XmlIgnore]
1256         public Vector4 Wzyw { get { return new Vector4(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
1257
1258         /// <summary>
1259         /// Adds two instances.
1260         /// </summary>
1261         /// <param name="left">The first instance.</param>
1262         /// <param name="right">The second instance.</param>
1263         /// <returns>The result of the calculation.</returns>
1264         public static Vector4 operator +(Vector4 left, Vector4 right)
1265         {
1266             left.X += right.X;
1267             left.Y += right.Y;
1268             left.Z += right.Z;
1269             left.W += right.W;
1270             return left;
1271         }
1272
1273         /// <summary>
1274         /// Subtracts two instances.
1275         /// </summary>
1276         /// <param name="left">The first instance.</param>
1277         /// <param name="right">The second instance.</param>
1278         /// <returns>The result of the calculation.</returns>
1279         public static Vector4 operator -(Vector4 left, Vector4 right)
1280         {
1281             left.X -= right.X;
1282             left.Y -= right.Y;
1283             left.Z -= right.Z;
1284             left.W -= right.W;
1285             return left;
1286         }
1287
1288         /// <summary>
1289         /// Negates an instance.
1290         /// </summary>
1291         /// <param name="vec">The instance.</param>
1292         /// <returns>The result of the calculation.</returns>
1293         public static Vector4 operator -(Vector4 vec)
1294         {
1295             vec.X = -vec.X;
1296             vec.Y = -vec.Y;
1297             vec.Z = -vec.Z;
1298             vec.W = -vec.W;
1299             return vec;
1300         }
1301
1302         /// <summary>
1303         /// Multiplies an instance by a scalar.
1304         /// </summary>
1305         /// <param name="vec">The instance.</param>
1306         /// <param name="scale">The scalar.</param>
1307         /// <returns>The result of the calculation.</returns>
1308         public static Vector4 operator *(Vector4 vec, float scale)
1309         {
1310             vec.X *= scale;
1311             vec.Y *= scale;
1312             vec.Z *= scale;
1313             vec.W *= scale;
1314             return vec;
1315         }
1316
1317         /// <summary>
1318         /// Multiplies an instance by a scalar.
1319         /// </summary>
1320         /// <param name="scale">The scalar.</param>
1321         /// <param name="vec">The instance.</param>
1322         /// <returns>The result of the calculation.</returns>
1323         public static Vector4 operator *(float scale, Vector4 vec)
1324         {
1325             vec.X *= scale;
1326             vec.Y *= scale;
1327             vec.Z *= scale;
1328             vec.W *= scale;
1329             return vec;
1330         }
1331
1332         /// <summary>
1333         /// Component-wise multiplication between the specified instance by a scale vector.
1334         /// </summary>
1335         /// <param name="scale">Left operand.</param>
1336         /// <param name="vec">Right operand.</param>
1337         /// <returns>Result of multiplication.</returns>
1338         public static Vector4 operator *(Vector4 vec, Vector4 scale)
1339         {
1340             vec.X *= scale.X;
1341             vec.Y *= scale.Y;
1342             vec.Z *= scale.Z;
1343             vec.W *= scale.W;
1344             return vec;
1345         }
1346
1347         /// <summary>
1348         /// Transform a Vector by the given Matrix.
1349         /// </summary>
1350         /// <param name="vec">The vector to transform</param>
1351         /// <param name="mat">The desired transformation</param>
1352         /// <returns>The transformed vector</returns>
1353         public static Vector4 operator *(Vector4 vec, Matrix4 mat)
1354         {
1355             Vector4 result;
1356             Vector4.Transform(ref vec, ref mat, out result);
1357             return result;
1358         }
1359
1360         /// <summary>
1361         /// Transform a Vector by the given Matrix using right-handed notation
1362         /// </summary>
1363         /// <param name="mat">The desired transformation</param>
1364         /// <param name="vec">The vector to transform</param>
1365         /// <returns>The transformed vector</returns>
1366         public static Vector4 operator *(Matrix4 mat, Vector4 vec)
1367         {
1368             Vector4 result;
1369             Vector4.Transform(ref mat, ref vec, out result);
1370             return result;
1371         }
1372
1373         /// <summary>
1374         /// Transforms a vector by a quaternion rotation.
1375         /// </summary>
1376         /// <param name="quat">The quaternion to rotate the vector by.</param>
1377         /// <param name="vec">The vector to transform.</param>
1378         /// <returns>The transformed vector</returns>
1379         public static Vector4 operator *(Quaternion quat, Vector4 vec)
1380         {
1381             Vector4 result;
1382             Vector4.Transform(ref vec, ref quat, out result);
1383             return result;
1384         }
1385
1386         /// <summary>
1387         /// Divides an instance by a scalar.
1388         /// </summary>
1389         /// <param name="vec">The instance.</param>
1390         /// <param name="scale">The scalar.</param>
1391         /// <returns>The result of the calculation.</returns>
1392         public static Vector4 operator /(Vector4 vec, float scale)
1393         {
1394             vec.X /= scale;
1395             vec.Y /= scale;
1396             vec.Z /= scale;
1397             vec.W /= scale;
1398             return vec;
1399         }
1400
1401         /// <summary>
1402         /// Compares two instances for equality.
1403         /// </summary>
1404         /// <param name="left">The first instance.</param>
1405         /// <param name="right">The second instance.</param>
1406         /// <returns>True, if left equals right; false otherwise.</returns>
1407         public static bool operator ==(Vector4 left, Vector4 right)
1408         {
1409             return left.Equals(right);
1410         }
1411
1412         /// <summary>
1413         /// Compares two instances for inequality.
1414         /// </summary>
1415         /// <param name="left">The first instance.</param>
1416         /// <param name="right">The second instance.</param>
1417         /// <returns>True, if left does not equa lright; false otherwise.</returns>
1418         public static bool operator !=(Vector4 left, Vector4 right)
1419         {
1420             return !left.Equals(right);
1421         }
1422
1423         /// <summary>
1424         /// Returns a pointer to the first element of the specified instance.
1425         /// </summary>
1426         /// <param name="v">The instance.</param>
1427         /// <returns>A pointer to the first element of v.</returns>
1428         [CLSCompliant(false)]
1429         unsafe public static explicit operator float*(Vector4 v)
1430         {
1431             return &v.X;
1432         }
1433
1434         /// <summary>
1435         /// Returns a pointer to the first element of the specified instance.
1436         /// </summary>
1437         /// <param name="v">The instance.</param>
1438         /// <returns>A pointer to the first element of v.</returns>
1439         public static explicit operator IntPtr(Vector4 v)
1440         {
1441             unsafe
1442             {
1443                 return (IntPtr)(&v.X);
1444             }
1445         }
1446
1447         private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
1448         /// <summary>
1449         /// Returns a System.String that represents the current Vector4.
1450         /// </summary>
1451         /// <returns></returns>
1452         public override string ToString()
1453         {
1454             return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator);
1455         }
1456
1457         /// <summary>
1458         /// Returns the hashcode for this instance.
1459         /// </summary>
1460         /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
1461         public override int GetHashCode()
1462         {
1463             unchecked
1464             {
1465                 var hashCode = this.X.GetHashCode();
1466                 hashCode = (hashCode * 397) ^ this.Y.GetHashCode();
1467                 hashCode = (hashCode * 397) ^ this.Z.GetHashCode();
1468                 hashCode = (hashCode * 397) ^ this.W.GetHashCode();
1469                 return hashCode;
1470             }
1471         }
1472
1473         /// <summary>
1474         /// Indicates whether this instance and a specified object are equal.
1475         /// </summary>
1476         /// <param name="obj">The object to compare to.</param>
1477         /// <returns>True if the instances are equal; false otherwise.</returns>
1478         public override bool Equals(object obj)
1479         {
1480             if (!(obj is Vector4))
1481             {
1482                 return false;
1483             }
1484
1485             return this.Equals((Vector4)obj);
1486         }
1487
1488         /// <summary>Indicates whether the current vector is equal to another vector.</summary>
1489         /// <param name="other">A vector to compare with this vector.</param>
1490         /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
1491         public bool Equals(Vector4 other)
1492         {
1493             return
1494                 X == other.X &&
1495                 Y == other.Y &&
1496                 Z == other.Z &&
1497                 W == other.W;
1498         }
1499     }
1500 }