Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region --- License ---
2
/*
3
Copyright (c) 2006 - 2008 The Open Toolkit library.
4
 
5
Permission is hereby granted, free of charge, to any person obtaining a copy of
6
this software and associated documentation files (the "Software"), to deal in
7
the Software without restriction, including without limitation the rights to
8
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
of the Software, and to permit persons to whom the Software is furnished to do
10
so, subject to the following conditions:
11
 
12
The above copyright notice and this permission notice shall be included in all
13
copies or substantial portions of the Software.
14
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
SOFTWARE.
22
 */
23
#endregion
24
 
25
using System;
26
using System.Runtime.InteropServices;
27
using System.Xml.Serialization;
28
namespace OpenTK
29
{
30
    /// <summary>Represents a 4D vector using four single-precision floating-point numbers.</summary>
31
    /// <remarks>
32
    /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats.
33
    /// </remarks>
34
    [Serializable]
35
    [StructLayout(LayoutKind.Sequential)]
36
    public struct Vector4 : IEquatable<Vector4>
37
    {
38
        #region Fields
39
 
40
        /// <summary>
41
        /// The X component of the Vector4.
42
        /// </summary>
43
        public float X;
44
 
45
        /// <summary>
46
        /// The Y component of the Vector4.
47
        /// </summary>
48
        public float Y;
49
 
50
        /// <summary>
51
        /// The Z component of the Vector4.
52
        /// </summary>
53
        public float Z;
54
 
55
        /// <summary>
56
        /// The W component of the Vector4.
57
        /// </summary>
58
        public float W;
59
 
60
        /// <summary>
61
        /// Defines a unit-length Vector4 that points towards the X-axis.
62
        /// </summary>
63
        public static Vector4 UnitX = new Vector4(1, 0, 0, 0);
64
 
65
        /// <summary>
66
        /// Defines a unit-length Vector4 that points towards the Y-axis.
67
        /// </summary>
68
        public static Vector4 UnitY = new Vector4(0, 1, 0, 0);
69
 
70
        /// <summary>
71
        /// Defines a unit-length Vector4 that points towards the Z-axis.
72
        /// </summary>
73
        public static Vector4 UnitZ = new Vector4(0, 0, 1, 0);
74
 
75
        /// <summary>
76
        /// Defines a unit-length Vector4 that points towards the W-axis.
77
        /// </summary>
78
        public static Vector4 UnitW = new Vector4(0, 0, 0, 1);
79
 
80
        /// <summary>
81
        /// Defines a zero-length Vector4.
82
        /// </summary>
83
        public static Vector4 Zero = new Vector4(0, 0, 0, 0);
84
 
85
        /// <summary>
86
        /// Defines an instance with all components set to 1.
87
        /// </summary>
88
        public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
89
 
90
        /// <summary>
91
        /// Defines the size of the Vector4 struct in bytes.
92
        /// </summary>
93
        public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
94
 
95
        #endregion
96
 
97
        #region Constructors
98
 
99
        /// <summary>
100
        /// Constructs a new Vector4.
101
        /// </summary>
102
        /// <param name="x">The x component of the Vector4.</param>
103
        /// <param name="y">The y component of the Vector4.</param>
104
        /// <param name="z">The z component of the Vector4.</param>
105
        /// <param name="w">The w component of the Vector4.</param>
106
        public Vector4(float x, float y, float z, float w)
107
        {
108
            X = x;
109
            Y = y;
110
            Z = z;
111
            W = w;
112
        }
113
 
114
        /// <summary>
115
        /// Constructs a new Vector4 from the given Vector2.
116
        /// </summary>
117
        /// <param name="v">The Vector2 to copy components from.</param>
118
        public Vector4(Vector2 v)
119
        {
120
            X = v.X;
121
            Y = v.Y;
122
            Z = 0.0f;
123
            W = 0.0f;
124
        }
125
 
126
        /// <summary>
127
        /// Constructs a new Vector4 from the given Vector3.
128
        /// </summary>
129
        /// <param name="v">The Vector3 to copy components from.</param>
130
        public Vector4(Vector3 v)
131
        {
132
            X = v.X;
133
            Y = v.Y;
134
            Z = v.Z;
135
            W = 0.0f;
136
        }
137
 
138
        /// <summary>
139
        /// Constructs a new Vector4 from the specified Vector3 and w component.
140
        /// </summary>
141
        /// <param name="v">The Vector3 to copy components from.</param>
142
        /// <param name="w">The w component of the new Vector4.</param>
143
        public Vector4(Vector3 v, float w)
144
        {
145
            X = v.X;
146
            Y = v.Y;
147
            Z = v.Z;
148
            W = w;
149
        }
150
 
151
        /// <summary>
152
        /// Constructs a new Vector4 from the given Vector4.
153
        /// </summary>
154
        /// <param name="v">The Vector4 to copy components from.</param>
155
        public Vector4(Vector4 v)
156
        {
157
            X = v.X;
158
            Y = v.Y;
159
            Z = v.Z;
160
            W = v.W;
161
        }
162
 
163
        #endregion
164
 
165
        #region Public Members
166
 
167
        #region Instance
168
 
169
        #region public void Add()
170
 
171
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
172
        /// <param name="right">Right operand. This parameter is only read from.</param>
173
        [Obsolete("Use static Add() method instead.")]
174
        public void Add(Vector4 right)
175
        {
176
            this.X += right.X;
177
            this.Y += right.Y;
178
            this.Z += right.Z;
179
            this.W += right.W;
180
        }
181
 
182
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
183
        /// <param name="right">Right operand. This parameter is only read from.</param>
184
        [CLSCompliant(false)]
185
        [Obsolete("Use static Add() method instead.")]
186
        public void Add(ref Vector4 right)
187
        {
188
            this.X += right.X;
189
            this.Y += right.Y;
190
            this.Z += right.Z;
191
            this.W += right.W;
192
        }
193
 
194
        #endregion public void Add()
195
 
196
        #region public void Sub()
197
 
198
        /// <summary>Subtract the Vector passed as parameter from this instance.</summary>
199
        /// <param name="right">Right operand. This parameter is only read from.</param>
200
        [Obsolete("Use static Subtract() method instead.")]
201
        public void Sub(Vector4 right)
202
        {
203
            this.X -= right.X;
204
            this.Y -= right.Y;
205
            this.Z -= right.Z;
206
            this.W -= right.W;
207
        }
208
 
209
        /// <summary>Subtract the Vector passed as parameter from this instance.</summary>
210
        /// <param name="right">Right operand. This parameter is only read from.</param>
211
        [CLSCompliant(false)]
212
        [Obsolete("Use static Subtract() method instead.")]
213
        public void Sub(ref Vector4 right)
214
        {
215
            this.X -= right.X;
216
            this.Y -= right.Y;
217
            this.Z -= right.Z;
218
            this.W -= right.W;
219
        }
220
 
221
        #endregion public void Sub()
222
 
223
        #region public void Mult()
224
 
225
        /// <summary>Multiply this instance by a scalar.</summary>
226
        /// <param name="f">Scalar operand.</param>
227
        [Obsolete("Use static Multiply() method instead.")]
228
        public void Mult(float f)
229
        {
230
            this.X *= f;
231
            this.Y *= f;
232
            this.Z *= f;
233
            this.W *= f;
234
        }
235
 
236
        #endregion public void Mult()
237
 
238
        #region public void Div()
239
 
240
        /// <summary>Divide this instance by a scalar.</summary>
241
        /// <param name="f">Scalar operand.</param>
242
        [Obsolete("Use static Divide() method instead.")]
243
        public void Div(float f)
244
        {
245
            float mult = 1.0f / f;
246
            this.X *= mult;
247
            this.Y *= mult;
248
            this.Z *= mult;
249
            this.W *= mult;
250
        }
251
 
252
        #endregion public void Div()
253
 
254
        #region public float Length
255
 
256
        /// <summary>
257
        /// Gets the length (magnitude) of the vector.
258
        /// </summary>
259
        /// <see cref="LengthFast"/>
260
        /// <seealso cref="LengthSquared"/>
261
        public float Length
262
        {
263
            get
264
            {
265
                return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
266
            }
267
        }
268
 
269
        #endregion
270
 
271
        #region public float LengthFast
272
 
273
        /// <summary>
274
        /// Gets an approximation of the vector length (magnitude).
275
        /// </summary>
276
        /// <remarks>
277
        /// This property uses an approximation of the square root function to calculate vector magnitude, with
278
        /// an upper error bound of 0.001.
279
        /// </remarks>
280
        /// <see cref="Length"/>
281
        /// <seealso cref="LengthSquared"/>
282
        public float LengthFast
283
        {
284
            get
285
            {
286
                return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
287
            }
288
        }
289
 
290
        #endregion
291
 
292
        #region public float LengthSquared
293
 
294
        /// <summary>
295
        /// Gets the square of the vector length (magnitude).
296
        /// </summary>
297
        /// <remarks>
298
        /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
299
        /// for comparisons.
300
        /// </remarks>
301
        /// <see cref="Length"/>
302
        /// <seealso cref="LengthFast"/>
303
        public float LengthSquared
304
        {
305
            get
306
            {
307
                return X * X + Y * Y + Z * Z + W * W;
308
            }
309
        }
310
 
311
        #endregion
312
 
313
        #region public void Normalize()
314
 
315
        /// <summary>
316
        /// Scales the Vector4 to unit length.
317
        /// </summary>
318
        public void Normalize()
319
        {
320
            float scale = 1.0f / this.Length;
321
            X *= scale;
322
            Y *= scale;
323
            Z *= scale;
324
            W *= scale;
325
        }
326
 
327
        #endregion
328
 
329
        #region public void NormalizeFast()
330
 
331
        /// <summary>
332
        /// Scales the Vector4 to approximately unit length.
333
        /// </summary>
334
        public void NormalizeFast()
335
        {
336
            float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
337
            X *= scale;
338
            Y *= scale;
339
            Z *= scale;
340
            W *= scale;
341
        }
342
 
343
        #endregion
344
 
345
        #region public void Scale()
346
 
347
        /// <summary>
348
        /// Scales the current Vector4 by the given amounts.
349
        /// </summary>
350
        /// <param name="sx">The scale of the X component.</param>
351
        /// <param name="sy">The scale of the Y component.</param>
352
        /// <param name="sz">The scale of the Z component.</param>
353
        /// <param name="sw">The scale of the Z component.</param>
354
        [Obsolete("Use static Multiply() method instead.")]
355
        public void Scale(float sx, float sy, float sz, float sw)
356
        {
357
            this.X = X * sx;
358
            this.Y = Y * sy;
359
            this.Z = Z * sz;
360
            this.W = W * sw;
361
        }
362
 
363
        /// <summary>Scales this instance by the given parameter.</summary>
364
        /// <param name="scale">The scaling of the individual components.</param>
365
        [Obsolete("Use static Multiply() method instead.")]
366
        public void Scale(Vector4 scale)
367
        {
368
            this.X *= scale.X;
369
            this.Y *= scale.Y;
370
            this.Z *= scale.Z;
371
            this.W *= scale.W;
372
        }
373
 
374
        /// <summary>Scales this instance by the given parameter.</summary>
375
        /// <param name="scale">The scaling of the individual components.</param>
376
        [CLSCompliant(false)]
377
        [Obsolete("Use static Multiply() method instead.")]
378
        public void Scale(ref Vector4 scale)
379
        {
380
            this.X *= scale.X;
381
            this.Y *= scale.Y;
382
            this.Z *= scale.Z;
383
            this.W *= scale.W;
384
        }
385
 
386
        #endregion public void Scale()
387
 
388
        #endregion
389
 
390
        #region Static
391
 
392
        #region Obsolete
393
 
394
        #region Sub
395
 
396
        /// <summary>
397
        /// Subtract one Vector from another
398
        /// </summary>
399
        /// <param name="a">First operand</param>
400
        /// <param name="b">Second operand</param>
401
        /// <returns>Result of subtraction</returns>
402
        public static Vector4 Sub(Vector4 a, Vector4 b)
403
        {
404
            a.X -= b.X;
405
            a.Y -= b.Y;
406
            a.Z -= b.Z;
407
            a.W -= b.W;
408
            return a;
409
        }
410
 
411
        /// <summary>
412
        /// Subtract one Vector from another
413
        /// </summary>
414
        /// <param name="a">First operand</param>
415
        /// <param name="b">Second operand</param>
416
        /// <param name="result">Result of subtraction</param>
417
        public static void Sub(ref Vector4 a, ref Vector4 b, out Vector4 result)
418
        {
419
            result.X = a.X - b.X;
420
            result.Y = a.Y - b.Y;
421
            result.Z = a.Z - b.Z;
422
            result.W = a.W - b.W;
423
        }
424
 
425
        #endregion
426
 
427
        #region Mult
428
 
429
        /// <summary>
430
        /// Multiply a vector and a scalar
431
        /// </summary>
432
        /// <param name="a">Vector operand</param>
433
        /// <param name="f">Scalar operand</param>
434
        /// <returns>Result of the multiplication</returns>
435
        public static Vector4 Mult(Vector4 a, float f)
436
        {
437
            a.X *= f;
438
            a.Y *= f;
439
            a.Z *= f;
440
            a.W *= f;
441
            return a;
442
        }
443
 
444
        /// <summary>
445
        /// Multiply a vector and a scalar
446
        /// </summary>
447
        /// <param name="a">Vector operand</param>
448
        /// <param name="f">Scalar operand</param>
449
        /// <param name="result">Result of the multiplication</param>
450
        public static void Mult(ref Vector4 a, float f, out Vector4 result)
451
        {
452
            result.X = a.X * f;
453
            result.Y = a.Y * f;
454
            result.Z = a.Z * f;
455
            result.W = a.W * f;
456
        }
457
 
458
        #endregion
459
 
460
        #region Div
461
 
462
        /// <summary>
463
        /// Divide a vector by a scalar
464
        /// </summary>
465
        /// <param name="a">Vector operand</param>
466
        /// <param name="f">Scalar operand</param>
467
        /// <returns>Result of the division</returns>
468
        public static Vector4 Div(Vector4 a, float f)
469
        {
470
            float mult = 1.0f / f;
471
            a.X *= mult;
472
            a.Y *= mult;
473
            a.Z *= mult;
474
            a.W *= mult;
475
            return a;
476
        }
477
 
478
        /// <summary>
479
        /// Divide a vector by a scalar
480
        /// </summary>
481
        /// <param name="a">Vector operand</param>
482
        /// <param name="f">Scalar operand</param>
483
        /// <param name="result">Result of the division</param>
484
        public static void Div(ref Vector4 a, float f, out Vector4 result)
485
        {
486
            float mult = 1.0f / f;
487
            result.X = a.X * mult;
488
            result.Y = a.Y * mult;
489
            result.Z = a.Z * mult;
490
            result.W = a.W * mult;
491
        }
492
 
493
        #endregion
494
 
495
        #endregion
496
 
497
        #region Add
498
 
499
        /// <summary>
500
        /// Adds two vectors.
501
        /// </summary>
502
        /// <param name="a">Left operand.</param>
503
        /// <param name="b">Right operand.</param>
504
        /// <returns>Result of operation.</returns>
505
        public static Vector4 Add(Vector4 a, Vector4 b)
506
        {
507
            Add(ref a, ref b, out a);
508
            return a;
509
        }
510
 
511
        /// <summary>
512
        /// Adds two vectors.
513
        /// </summary>
514
        /// <param name="a">Left operand.</param>
515
        /// <param name="b">Right operand.</param>
516
        /// <param name="result">Result of operation.</param>
517
        public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
518
        {
519
            result = new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W);
520
        }
521
 
522
        #endregion
523
 
524
        #region Subtract
525
 
526
        /// <summary>
527
        /// Subtract one Vector from another
528
        /// </summary>
529
        /// <param name="a">First operand</param>
530
        /// <param name="b">Second operand</param>
531
        /// <returns>Result of subtraction</returns>
532
        public static Vector4 Subtract(Vector4 a, Vector4 b)
533
        {
534
            Subtract(ref a, ref b, out a);
535
            return a;
536
        }
537
 
538
        /// <summary>
539
        /// Subtract one Vector from another
540
        /// </summary>
541
        /// <param name="a">First operand</param>
542
        /// <param name="b">Second operand</param>
543
        /// <param name="result">Result of subtraction</param>
544
        public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result)
545
        {
546
            result = new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W);
547
        }
548
 
549
        #endregion
550
 
551
        #region Multiply
552
 
553
        /// <summary>
554
        /// Multiplies a vector by a scalar.
555
        /// </summary>
556
        /// <param name="vector">Left operand.</param>
557
        /// <param name="scale">Right operand.</param>
558
        /// <returns>Result of the operation.</returns>
559
        public static Vector4 Multiply(Vector4 vector, float scale)
560
        {
561
            Multiply(ref vector, scale, out vector);
562
            return vector;
563
        }
564
 
565
        /// <summary>
566
        /// Multiplies a vector by a scalar.
567
        /// </summary>
568
        /// <param name="vector">Left operand.</param>
569
        /// <param name="scale">Right operand.</param>
570
        /// <param name="result">Result of the operation.</param>
571
        public static void Multiply(ref Vector4 vector, float scale, out Vector4 result)
572
        {
573
            result = new Vector4(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale);
574
        }
575
 
576
        /// <summary>
577
        /// Multiplies a vector by the components a vector (scale).
578
        /// </summary>
579
        /// <param name="vector">Left operand.</param>
580
        /// <param name="scale">Right operand.</param>
581
        /// <returns>Result of the operation.</returns>
582
        public static Vector4 Multiply(Vector4 vector, Vector4 scale)
583
        {
584
            Multiply(ref vector, ref scale, out vector);
585
            return vector;
586
        }
587
 
588
        /// <summary>
589
        /// Multiplies a vector by the components of a vector (scale).
590
        /// </summary>
591
        /// <param name="vector">Left operand.</param>
592
        /// <param name="scale">Right operand.</param>
593
        /// <param name="result">Result of the operation.</param>
594
        public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
595
        {
596
            result = new Vector4(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W);
597
        }
598
 
599
        #endregion
600
 
601
        #region Divide
602
 
603
        /// <summary>
604
        /// Divides a vector by a scalar.
605
        /// </summary>
606
        /// <param name="vector">Left operand.</param>
607
        /// <param name="scale">Right operand.</param>
608
        /// <returns>Result of the operation.</returns>
609
        public static Vector4 Divide(Vector4 vector, float scale)
610
        {
611
            Divide(ref vector, scale, out vector);
612
            return vector;
613
        }
614
 
615
        /// <summary>
616
        /// Divides a vector by a scalar.
617
        /// </summary>
618
        /// <param name="vector">Left operand.</param>
619
        /// <param name="scale">Right operand.</param>
620
        /// <param name="result">Result of the operation.</param>
621
        public static void Divide(ref Vector4 vector, float scale, out Vector4 result)
622
        {
623
            Multiply(ref vector, 1 / scale, out result);
624
        }
625
 
626
        /// <summary>
627
        /// Divides a vector by the components of a vector (scale).
628
        /// </summary>
629
        /// <param name="vector">Left operand.</param>
630
        /// <param name="scale">Right operand.</param>
631
        /// <returns>Result of the operation.</returns>
632
        public static Vector4 Divide(Vector4 vector, Vector4 scale)
633
        {
634
            Divide(ref vector, ref scale, out vector);
635
            return vector;
636
        }
637
 
638
        /// <summary>
639
        /// Divide a vector by the components of a vector (scale).
640
        /// </summary>
641
        /// <param name="vector">Left operand.</param>
642
        /// <param name="scale">Right operand.</param>
643
        /// <param name="result">Result of the operation.</param>
644
        public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
645
        {
646
            result = new Vector4(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W);
647
        }
648
 
649
        #endregion
650
 
651
        #region Min
652
 
653
        /// <summary>
654
        /// Calculate the component-wise minimum of two vectors
655
        /// </summary>
656
        /// <param name="a">First operand</param>
657
        /// <param name="b">Second operand</param>
658
        /// <returns>The component-wise minimum</returns>
659
        public static Vector4 Min(Vector4 a, Vector4 b)
660
        {
661
            a.X = a.X < b.X ? a.X : b.X;
662
            a.Y = a.Y < b.Y ? a.Y : b.Y;
663
            a.Z = a.Z < b.Z ? a.Z : b.Z;
664
            a.W = a.W < b.W ? a.W : b.W;
665
            return a;
666
        }
667
 
668
        /// <summary>
669
        /// Calculate the component-wise minimum of two vectors
670
        /// </summary>
671
        /// <param name="a">First operand</param>
672
        /// <param name="b">Second operand</param>
673
        /// <param name="result">The component-wise minimum</param>
674
        public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
675
        {
676
            result.X = a.X < b.X ? a.X : b.X;
677
            result.Y = a.Y < b.Y ? a.Y : b.Y;
678
            result.Z = a.Z < b.Z ? a.Z : b.Z;
679
            result.W = a.W < b.W ? a.W : b.W;
680
        }
681
 
682
        #endregion
683
 
684
        #region Max
685
 
686
        /// <summary>
687
        /// Calculate the component-wise maximum of two vectors
688
        /// </summary>
689
        /// <param name="a">First operand</param>
690
        /// <param name="b">Second operand</param>
691
        /// <returns>The component-wise maximum</returns>
692
        public static Vector4 Max(Vector4 a, Vector4 b)
693
        {
694
            a.X = a.X > b.X ? a.X : b.X;
695
            a.Y = a.Y > b.Y ? a.Y : b.Y;
696
            a.Z = a.Z > b.Z ? a.Z : b.Z;
697
            a.W = a.W > b.W ? a.W : b.W;
698
            return a;
699
        }
700
 
701
        /// <summary>
702
        /// Calculate the component-wise maximum of two vectors
703
        /// </summary>
704
        /// <param name="a">First operand</param>
705
        /// <param name="b">Second operand</param>
706
        /// <param name="result">The component-wise maximum</param>
707
        public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
708
        {
709
            result.X = a.X > b.X ? a.X : b.X;
710
            result.Y = a.Y > b.Y ? a.Y : b.Y;
711
            result.Z = a.Z > b.Z ? a.Z : b.Z;
712
            result.W = a.W > b.W ? a.W : b.W;
713
        }
714
 
715
        #endregion
716
 
717
        #region Clamp
718
 
719
        /// <summary>
720
        /// Clamp a vector to the given minimum and maximum vectors
721
        /// </summary>
722
        /// <param name="vec">Input vector</param>
723
        /// <param name="min">Minimum vector</param>
724
        /// <param name="max">Maximum vector</param>
725
        /// <returns>The clamped vector</returns>
726
        public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
727
        {
728
            vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
729
            vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
730
            vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
731
            vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
732
            return vec;
733
        }
734
 
735
        /// <summary>
736
        /// Clamp a vector to the given minimum and maximum vectors
737
        /// </summary>
738
        /// <param name="vec">Input vector</param>
739
        /// <param name="min">Minimum vector</param>
740
        /// <param name="max">Maximum vector</param>
741
        /// <param name="result">The clamped vector</param>
742
        public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
743
        {
744
            result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
745
            result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
746
            result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
747
            result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
748
        }
749
 
750
        #endregion
751
 
752
        #region Normalize
753
 
754
        /// <summary>
755
        /// Scale a vector to unit length
756
        /// </summary>
757
        /// <param name="vec">The input vector</param>
758
        /// <returns>The normalized vector</returns>
759
        public static Vector4 Normalize(Vector4 vec)
760
        {
761
            float scale = 1.0f / vec.Length;
762
            vec.X *= scale;
763
            vec.Y *= scale;
764
            vec.Z *= scale;
765
            vec.W *= scale;
766
            return vec;
767
        }
768
 
769
        /// <summary>
770
        /// Scale a vector to unit length
771
        /// </summary>
772
        /// <param name="vec">The input vector</param>
773
        /// <param name="result">The normalized vector</param>
774
        public static void Normalize(ref Vector4 vec, out Vector4 result)
775
        {
776
            float scale = 1.0f / vec.Length;
777
            result.X = vec.X * scale;
778
            result.Y = vec.Y * scale;
779
            result.Z = vec.Z * scale;
780
            result.W = vec.W * scale;
781
        }
782
 
783
        #endregion
784
 
785
        #region NormalizeFast
786
 
787
        /// <summary>
788
        /// Scale a vector to approximately unit length
789
        /// </summary>
790
        /// <param name="vec">The input vector</param>
791
        /// <returns>The normalized vector</returns>
792
        public static Vector4 NormalizeFast(Vector4 vec)
793
        {
794
            float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
795
            vec.X *= scale;
796
            vec.Y *= scale;
797
            vec.Z *= scale;
798
            vec.W *= scale;
799
            return vec;
800
        }
801
 
802
        /// <summary>
803
        /// Scale a vector to approximately unit length
804
        /// </summary>
805
        /// <param name="vec">The input vector</param>
806
        /// <param name="result">The normalized vector</param>
807
        public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
808
        {
809
            float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
810
            result.X = vec.X * scale;
811
            result.Y = vec.Y * scale;
812
            result.Z = vec.Z * scale;
813
            result.W = vec.W * scale;
814
        }
815
 
816
        #endregion
817
 
818
        #region Dot
819
 
820
        /// <summary>
821
        /// Calculate the dot product of two vectors
822
        /// </summary>
823
        /// <param name="left">First operand</param>
824
        /// <param name="right">Second operand</param>
825
        /// <returns>The dot product of the two inputs</returns>
826
        public static float Dot(Vector4 left, Vector4 right)
827
        {
828
            return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
829
        }
830
 
831
        /// <summary>
832
        /// Calculate the dot product of two vectors
833
        /// </summary>
834
        /// <param name="left">First operand</param>
835
        /// <param name="right">Second operand</param>
836
        /// <param name="result">The dot product of the two inputs</param>
837
        public static void Dot(ref Vector4 left, ref Vector4 right, out float result)
838
        {
839
            result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
840
        }
841
 
842
        #endregion
843
 
844
        #region Lerp
845
 
846
        /// <summary>
847
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
848
        /// </summary>
849
        /// <param name="a">First input vector</param>
850
        /// <param name="b">Second input vector</param>
851
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
852
        /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
853
        public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
854
        {
855
            a.X = blend * (b.X - a.X) + a.X;
856
            a.Y = blend * (b.Y - a.Y) + a.Y;
857
            a.Z = blend * (b.Z - a.Z) + a.Z;
858
            a.W = blend * (b.W - a.W) + a.W;
859
            return a;
860
        }
861
 
862
        /// <summary>
863
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
864
        /// </summary>
865
        /// <param name="a">First input vector</param>
866
        /// <param name="b">Second input vector</param>
867
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
868
        /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
869
        public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result)
870
        {
871
            result.X = blend * (b.X - a.X) + a.X;
872
            result.Y = blend * (b.Y - a.Y) + a.Y;
873
            result.Z = blend * (b.Z - a.Z) + a.Z;
874
            result.W = blend * (b.W - a.W) + a.W;
875
        }
876
 
877
        #endregion
878
 
879
        #region Barycentric
880
 
881
        /// <summary>
882
        /// Interpolate 3 Vectors using Barycentric coordinates
883
        /// </summary>
884
        /// <param name="a">First input Vector</param>
885
        /// <param name="b">Second input Vector</param>
886
        /// <param name="c">Third input Vector</param>
887
        /// <param name="u">First Barycentric Coordinate</param>
888
        /// <param name="v">Second Barycentric Coordinate</param>
889
        /// <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>
890
        public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
891
        {
892
            return a + u * (b - a) + v * (c - a);
893
        }
894
 
895
        /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
896
        /// <param name="a">First input Vector.</param>
897
        /// <param name="b">Second input Vector.</param>
898
        /// <param name="c">Third input Vector.</param>
899
        /// <param name="u">First Barycentric Coordinate.</param>
900
        /// <param name="v">Second Barycentric Coordinate.</param>
901
        /// <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>
902
        public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result)
903
        {
904
            result = a; // copy
905
 
906
            Vector4 temp = b; // copy
907
            Subtract(ref temp, ref a, out temp);
908
            Multiply(ref temp, u, out temp);
909
            Add(ref result, ref temp, out result);
910
 
911
            temp = c; // copy
912
            Subtract(ref temp, ref a, out temp);
913
            Multiply(ref temp, v, out temp);
914
            Add(ref result, ref temp, out result);
915
        }
916
 
917
        #endregion
918
 
919
        #region Transform
920
 
921
        /// <summary>Transform a Vector by the given Matrix</summary>
922
        /// <param name="vec">The vector to transform</param>
923
        /// <param name="mat">The desired transformation</param>
924
        /// <returns>The transformed vector</returns>
925
        public static Vector4 Transform(Vector4 vec, Matrix4 mat)
926
        {
927
            Vector4 result;
928
            Transform(ref vec, ref mat, out result);
929
            return result;
930
        }
931
 
932
        /// <summary>Transform a Vector by the given Matrix</summary>
933
        /// <param name="vec">The vector to transform</param>
934
        /// <param name="mat">The desired transformation</param>
935
        /// <param name="result">The transformed vector</param>
936
        public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result)
937
        {
938
            result = new Vector4(
939
                vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X,
940
                vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y,
941
                vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z,
942
                vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W);
943
        }
944
 
945
        /// <summary>
946
        /// Transforms a vector by a quaternion rotation.
947
        /// </summary>
948
        /// <param name="vec">The vector to transform.</param>
949
        /// <param name="quat">The quaternion to rotate the vector by.</param>
950
        /// <returns>The result of the operation.</returns>
951
        public static Vector4 Transform(Vector4 vec, Quaternion quat)
952
        {
953
            Vector4 result;
954
            Transform(ref vec, ref quat, out result);
955
            return result;
956
        }
957
 
958
        /// <summary>
959
        /// Transforms a vector by a quaternion rotation.
960
        /// </summary>
961
        /// <param name="vec">The vector to transform.</param>
962
        /// <param name="quat">The quaternion to rotate the vector by.</param>
963
        /// <param name="result">The result of the operation.</param>
964
        public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result)
965
        {
966
            Quaternion v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W), i, t;
967
            Quaternion.Invert(ref quat, out i);
968
            Quaternion.Multiply(ref quat, ref v, out t);
969
            Quaternion.Multiply(ref t, ref i, out v);
970
 
971
            result = new Vector4(v.X, v.Y, v.Z, v.W);
972
        }
973
 
974
        #endregion
975
 
976
        #endregion
977
 
978
        #region Swizzle
979
 
980
        /// <summary>
981
        /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
982
        /// </summary>
983
        [XmlIgnore]
984
        public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
985
 
986
        /// <summary>
987
        /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
988
        /// </summary>
989
        [XmlIgnore]
990
        public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
991
 
992
        #endregion
993
 
994
        #region Operators
995
 
996
        /// <summary>
997
        /// Adds two instances.
998
        /// </summary>
999
        /// <param name="left">The first instance.</param>
1000
        /// <param name="right">The second instance.</param>
1001
        /// <returns>The result of the calculation.</returns>
1002
        public static Vector4 operator +(Vector4 left, Vector4 right)
1003
        {
1004
            left.X += right.X;
1005
            left.Y += right.Y;
1006
            left.Z += right.Z;
1007
            left.W += right.W;
1008
            return left;
1009
        }
1010
 
1011
        /// <summary>
1012
        /// Subtracts two instances.
1013
        /// </summary>
1014
        /// <param name="left">The first instance.</param>
1015
        /// <param name="right">The second instance.</param>
1016
        /// <returns>The result of the calculation.</returns>
1017
        public static Vector4 operator -(Vector4 left, Vector4 right)
1018
        {
1019
            left.X -= right.X;
1020
            left.Y -= right.Y;
1021
            left.Z -= right.Z;
1022
            left.W -= right.W;
1023
            return left;
1024
        }
1025
 
1026
        /// <summary>
1027
        /// Negates an instance.
1028
        /// </summary>
1029
        /// <param name="vec">The instance.</param>
1030
        /// <returns>The result of the calculation.</returns>
1031
        public static Vector4 operator -(Vector4 vec)
1032
        {
1033
            vec.X = -vec.X;
1034
            vec.Y = -vec.Y;
1035
            vec.Z = -vec.Z;
1036
            vec.W = -vec.W;
1037
            return vec;
1038
        }
1039
 
1040
        /// <summary>
1041
        /// Multiplies an instance by a scalar.
1042
        /// </summary>
1043
        /// <param name="vec">The instance.</param>
1044
        /// <param name="scale">The scalar.</param>
1045
        /// <returns>The result of the calculation.</returns>
1046
        public static Vector4 operator *(Vector4 vec, float scale)
1047
        {
1048
            vec.X *= scale;
1049
            vec.Y *= scale;
1050
            vec.Z *= scale;
1051
            vec.W *= scale;
1052
            return vec;
1053
        }
1054
 
1055
        /// <summary>
1056
        /// Multiplies an instance by a scalar.
1057
        /// </summary>
1058
        /// <param name="scale">The scalar.</param>
1059
        /// <param name="vec">The instance.</param>
1060
        /// <returns>The result of the calculation.</returns>
1061
        public static Vector4 operator *(float scale, Vector4 vec)
1062
        {
1063
            vec.X *= scale;
1064
            vec.Y *= scale;
1065
            vec.Z *= scale;
1066
            vec.W *= scale;
1067
            return vec;
1068
        }
1069
 
1070
        /// <summary>
1071
        /// Divides an instance by a scalar.
1072
        /// </summary>
1073
        /// <param name="vec">The instance.</param>
1074
        /// <param name="scale">The scalar.</param>
1075
        /// <returns>The result of the calculation.</returns>
1076
        public static Vector4 operator /(Vector4 vec, float scale)
1077
        {
1078
            float mult = 1.0f / scale;
1079
            vec.X *= mult;
1080
            vec.Y *= mult;
1081
            vec.Z *= mult;
1082
            vec.W *= mult;
1083
            return vec;
1084
        }
1085
 
1086
        /// <summary>
1087
        /// Compares two instances for equality.
1088
        /// </summary>
1089
        /// <param name="left">The first instance.</param>
1090
        /// <param name="right">The second instance.</param>
1091
        /// <returns>True, if left equals right; false otherwise.</returns>
1092
        public static bool operator ==(Vector4 left, Vector4 right)
1093
        {
1094
            return left.Equals(right);
1095
        }
1096
 
1097
        /// <summary>
1098
        /// Compares two instances for inequality.
1099
        /// </summary>
1100
        /// <param name="left">The first instance.</param>
1101
        /// <param name="right">The second instance.</param>
1102
        /// <returns>True, if left does not equa lright; false otherwise.</returns>
1103
        public static bool operator !=(Vector4 left, Vector4 right)
1104
        {
1105
            return !left.Equals(right);
1106
        }
1107
 
1108
        /// <summary>
1109
        /// Returns a pointer to the first element of the specified instance.
1110
        /// </summary>
1111
        /// <param name="v">The instance.</param>
1112
        /// <returns>A pointer to the first element of v.</returns>
1113
        [CLSCompliant(false)]
1114
        unsafe public static explicit operator float*(Vector4 v)
1115
        {
1116
            return &v.X;
1117
        }
1118
 
1119
        /// <summary>
1120
        /// Returns a pointer to the first element of the specified instance.
1121
        /// </summary>
1122
        /// <param name="v">The instance.</param>
1123
        /// <returns>A pointer to the first element of v.</returns>
1124
        public static explicit operator IntPtr(Vector4 v)
1125
        {
1126
            unsafe
1127
            {
1128
                return (IntPtr)(&v.X);
1129
            }
1130
        }
1131
 
1132
        #endregion
1133
 
1134
        #region Overrides
1135
 
1136
        #region public override string ToString()
1137
 
1138
        /// <summary>
1139
        /// Returns a System.String that represents the current Vector4.
1140
        /// </summary>
1141
        /// <returns></returns>
1142
        public override string ToString()
1143
        {
1144
            return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
1145
        }
1146
 
1147
        #endregion
1148
 
1149
        #region public override int GetHashCode()
1150
 
1151
        /// <summary>
1152
        /// Returns the hashcode for this instance.
1153
        /// </summary>
1154
        /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
1155
        public override int GetHashCode()
1156
        {
1157
            return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
1158
        }
1159
 
1160
        #endregion
1161
 
1162
        #region public override bool Equals(object obj)
1163
 
1164
        /// <summary>
1165
        /// Indicates whether this instance and a specified object are equal.
1166
        /// </summary>
1167
        /// <param name="obj">The object to compare to.</param>
1168
        /// <returns>True if the instances are equal; false otherwise.</returns>
1169
        public override bool Equals(object obj)
1170
        {
1171
            if (!(obj is Vector4))
1172
                return false;
1173
 
1174
            return this.Equals((Vector4)obj);
1175
        }
1176
 
1177
        #endregion
1178
 
1179
        #endregion
1180
 
1181
        #endregion
1182
 
1183
        #region IEquatable<Vector4> Members
1184
 
1185
        /// <summary>Indicates whether the current vector is equal to another vector.</summary>
1186
        /// <param name="other">A vector to compare with this vector.</param>
1187
        /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
1188
        public bool Equals(Vector4 other)
1189
        {
1190
            return
1191
                X == other.X &&
1192
                Y == other.Y &&
1193
                Z == other.Z &&
1194
                W == other.W;
1195
        }
1196
 
1197
        #endregion
1198
    }
1199
}