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
 
29
namespace OpenTK.Math
30
{
31
    /// <summary>Represents a 4D vector using four single-precision floating-point numbers.</summary>
32
    /// <remarks>
33
    /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats.
34
    /// </remarks>
35
    [Obsolete("OpenTK.Math functions have been moved to the root OpenTK namespace (reason: XNA compatibility")]
36
    [Serializable]
37
    [StructLayout(LayoutKind.Sequential)]
38
    public struct Vector4 : IEquatable<Vector4>
39
    {
40
        #region Fields
41
 
42
        /// <summary>
43
        /// The X component of the Vector4.
44
        /// </summary>
45
        public float X;
46
 
47
        /// <summary>
48
        /// The Y component of the Vector4.
49
        /// </summary>
50
        public float Y;
51
 
52
        /// <summary>
53
        /// The Z component of the Vector4.
54
        /// </summary>
55
        public float Z;
56
 
57
        /// <summary>
58
        /// The W component of the Vector4.
59
        /// </summary>
60
        public float W;
61
 
62
        /// <summary>
63
        /// Defines a unit-length Vector4 that points towards the X-axis.
64
        /// </summary>
65
        public static Vector4 UnitX = new Vector4(1, 0, 0, 0);
66
 
67
        /// <summary>
68
        /// Defines a unit-length Vector4 that points towards the Y-axis.
69
        /// </summary>
70
        public static Vector4 UnitY = new Vector4(0, 1, 0, 0);
71
 
72
        /// <summary>
73
        /// Defines a unit-length Vector4 that points towards the Z-axis.
74
        /// </summary>
75
        public static Vector4 UnitZ = new Vector4(0, 0, 1, 0);
76
 
77
        /// <summary>
78
        /// Defines a unit-length Vector4 that points towards the W-axis.
79
        /// </summary>
80
        public static Vector4 UnitW = new Vector4(0, 0, 0, 1);
81
 
82
        /// <summary>
83
        /// Defines a zero-length Vector4.
84
        /// </summary>
85
        public static Vector4 Zero = new Vector4(0, 0, 0, 0);
86
 
87
        /// <summary>
88
        /// Defines an instance with all components set to 1.
89
        /// </summary>
90
        public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
91
 
92
        /// <summary>
93
        /// Defines the size of the Vector4 struct in bytes.
94
        /// </summary>
95
        public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
96
 
97
        #endregion
98
 
99
        #region Constructors
100
 
101
        /// <summary>
102
        /// Constructs a new Vector4.
103
        /// </summary>
104
        /// <param name="x">The x component of the Vector4.</param>
105
        /// <param name="y">The y component of the Vector4.</param>
106
        /// <param name="z">The z component of the Vector4.</param>
107
        /// <param name="w">The w component of the Vector4.</param>
108
        public Vector4(float x, float y, float z, float w)
109
        {
110
            X = x;
111
            Y = y;
112
            Z = z;
113
            W = w;
114
        }
115
 
116
        /// <summary>
117
        /// Constructs a new Vector4 from the given Vector2.
118
        /// </summary>
119
        /// <param name="v">The Vector2 to copy components from.</param>
120
        public Vector4(Vector2 v)
121
        {
122
            X = v.X;
123
            Y = v.Y;
124
            Z = 0.0f;
125
            W = 0.0f;
126
        }
127
 
128
        /// <summary>
129
        /// Constructs a new Vector4 from the given Vector3.
130
        /// </summary>
131
        /// <param name="v">The Vector3 to copy components from.</param>
132
        public Vector4(Vector3 v)
133
        {
134
            X = v.X;
135
            Y = v.Y;
136
            Z = v.Z;
137
            W = 0.0f;
138
        }
139
 
140
        /// <summary>
141
        /// Constructs a new Vector4 from the specified Vector3 and w component.
142
        /// </summary>
143
        /// <param name="v">The Vector3 to copy components from.</param>
144
        /// <param name="w">The w component of the new Vector4.</param>
145
        public Vector4(Vector3 v, float w)
146
        {
147
            X = v.X;
148
            Y = v.Y;
149
            Z = v.Z;
150
            W = w;
151
        }
152
 
153
        /// <summary>
154
        /// Constructs a new Vector4 from the given Vector4.
155
        /// </summary>
156
        /// <param name="v">The Vector4 to copy components from.</param>
157
        public Vector4(Vector4 v)
158
        {
159
            X = v.X;
160
            Y = v.Y;
161
            Z = v.Z;
162
            W = v.W;
163
        }
164
 
165
        #endregion
166
 
167
        #region Public Members
168
 
169
        #region Instance
170
 
171
        #region public void Add()
172
 
173
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
174
        /// <param name="right">Right operand. This parameter is only read from.</param>
175
        public void Add( Vector4 right )
176
        {
177
            this.X += right.X;
178
            this.Y += right.Y;
179
            this.Z += right.Z;
180
            this.W += right.W;
181
        }
182
 
183
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
184
        /// <param name="right">Right operand. This parameter is only read from.</param>
185
        [CLSCompliant(false)]
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
        public void Sub( Vector4 right )
201
        {
202
            this.X -= right.X;
203
            this.Y -= right.Y;
204
            this.Z -= right.Z;
205
            this.W -= right.W;
206
        }
207
 
208
        /// <summary>Subtract the Vector passed as parameter from this instance.</summary>
209
        /// <param name="right">Right operand. This parameter is only read from.</param>
210
        [CLSCompliant(false)]
211
        public void Sub( ref Vector4 right )
212
        {
213
            this.X -= right.X;
214
            this.Y -= right.Y;
215
            this.Z -= right.Z;
216
            this.W -= right.W;
217
        }
218
 
219
        #endregion public void Sub()
220
 
221
        #region public void Mult()
222
 
223
        /// <summary>Multiply this instance by a scalar.</summary>
224
        /// <param name="f">Scalar operand.</param>
225
        public void Mult( float f )
226
        {
227
            this.X *= f;
228
            this.Y *= f;
229
            this.Z *= f;
230
            this.W *= f;
231
        }
232
 
233
        #endregion public void Mult()
234
 
235
        #region public void Div()
236
 
237
        /// <summary>Divide this instance by a scalar.</summary>
238
        /// <param name="f">Scalar operand.</param>
239
        public void Div( float f )
240
        {
241
            float mult = 1.0f / f;
242
            this.X *= mult;
243
            this.Y *= mult;
244
            this.Z *= mult;
245
            this.W *= mult;
246
        }
247
 
248
        #endregion public void Div()
249
 
250
        #region public float Length
251
 
252
        /// <summary>
253
        /// Gets the length (magnitude) of the vector.
254
        /// </summary>
255
        /// <see cref="LengthFast"/>
256
        /// <seealso cref="LengthSquared"/>
257
        public float Length
258
        {
259
            get
260
            {
261
                return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
262
            }
263
        }
264
 
265
        #endregion
266
 
267
        #region public float LengthFast
268
 
269
        /// <summary>
270
        /// Gets an approximation of the vector length (magnitude).
271
        /// </summary>
272
        /// <remarks>
273
        /// This property uses an approximation of the square root function to calculate vector magnitude, with
274
        /// an upper error bound of 0.001.
275
        /// </remarks>
276
        /// <see cref="Length"/>
277
        /// <seealso cref="LengthSquared"/>
278
        public float LengthFast
279
        {
280
            get
281
            {
282
                return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
283
            }
284
        }
285
 
286
        #endregion
287
 
288
        #region public float LengthSquared
289
 
290
        /// <summary>
291
        /// Gets the square of the vector length (magnitude).
292
        /// </summary>
293
        /// <remarks>
294
        /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
295
        /// for comparisons.
296
        /// </remarks>
297
        /// <see cref="Length"/>
298
        /// <seealso cref="LengthFast"/>
299
        public float LengthSquared
300
        {
301
            get
302
            {
303
                return X * X + Y * Y + Z * Z + W * W;
304
            }
305
        }
306
 
307
        #endregion
308
 
309
        #region public void Normalize()
310
 
311
        /// <summary>
312
        /// Scales the Vector4 to unit length.
313
        /// </summary>
314
        public void Normalize()
315
        {
316
            float scale = 1.0f / this.Length;
317
            X *= scale;
318
            Y *= scale;
319
            Z *= scale;
320
            W *= scale;
321
        }
322
 
323
        #endregion
324
 
325
        #region public void NormalizeFast()
326
 
327
        /// <summary>
328
        /// Scales the Vector4 to approximately unit length.
329
        /// </summary>
330
        public void NormalizeFast()
331
        {
332
            float scale = Functions.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
333
            X *= scale;
334
            Y *= scale;
335
            Z *= scale;
336
            W *= scale;
337
        }
338
 
339
        #endregion
340
 
341
        #region public void Scale()
342
 
343
        /// <summary>
344
        /// Scales the current Vector4 by the given amounts.
345
        /// </summary>
346
        /// <param name="sx">The scale of the X component.</param>
347
        /// <param name="sy">The scale of the Y component.</param>
348
        /// <param name="sz">The scale of the Z component.</param>
349
        /// <param name="sw">The scale of the Z component.</param>
350
        public void Scale( float sx, float sy, float sz, float sw )
351
        {
352
            this.X = X * sx;
353
            this.Y = Y * sy;
354
            this.Z = Z * sz;
355
            this.W = W * sw;
356
        }
357
 
358
        /// <summary>Scales this instance by the given parameter.</summary>
359
        /// <param name="scale">The scaling of the individual components.</param>
360
        public void Scale( Vector4 scale )
361
        {
362
            this.X *= scale.X;
363
            this.Y *= scale.Y;
364
            this.Z *= scale.Z;
365
            this.W *= scale.W;
366
        }
367
 
368
        /// <summary>Scales this instance by the given parameter.</summary>
369
        /// <param name="scale">The scaling of the individual components.</param>
370
        [CLSCompliant(false)]
371
        public void Scale( ref Vector4 scale )
372
        {
373
            this.X *= scale.X;
374
            this.Y *= scale.Y;
375
            this.Z *= scale.Z;
376
            this.W *= scale.W;
377
        }
378
 
379
        #endregion public void Scale()
380
 
381
        #endregion
382
 
383
        #region Static
384
 
385
        #region Add
386
 
387
        /// <summary>
388
        /// Add two Vectors
389
        /// </summary>
390
        /// <param name="a">First operand</param>
391
        /// <param name="b">Second operand</param>
392
        /// <returns>Result of addition</returns>
393
        public static Vector4 Add(Vector4 a, Vector4 b)
394
        {
395
            a.X += b.X;
396
            a.Y += b.Y;
397
            a.Z += b.Z;
398
            a.W += b.W;
399
            return a;
400
        }
401
 
402
        /// <summary>
403
        /// Add two Vectors
404
        /// </summary>
405
        /// <param name="a">First operand</param>
406
        /// <param name="b">Second operand</param>
407
        /// <param name="result">Result of addition</param>
408
        public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
409
        {
410
            result.X = a.X + b.X;
411
            result.Y = a.Y + b.Y;
412
            result.Z = a.Z + b.Z;
413
            result.W = a.W + b.W;
414
        }
415
 
416
        #endregion
417
 
418
        #region Sub
419
 
420
        /// <summary>
421
        /// Subtract one Vector from another
422
        /// </summary>
423
        /// <param name="a">First operand</param>
424
        /// <param name="b">Second operand</param>
425
        /// <returns>Result of subtraction</returns>
426
        public static Vector4 Sub(Vector4 a, Vector4 b)
427
        {
428
            a.X -= b.X;
429
            a.Y -= b.Y;
430
            a.Z -= b.Z;
431
            a.W -= b.W;
432
            return a;
433
        }
434
 
435
        /// <summary>
436
        /// Subtract one Vector from another
437
        /// </summary>
438
        /// <param name="a">First operand</param>
439
        /// <param name="b">Second operand</param>
440
        /// <param name="result">Result of subtraction</param>
441
        public static void Sub(ref Vector4 a, ref Vector4 b, out Vector4 result)
442
        {
443
            result.X = a.X - b.X;
444
            result.Y = a.Y - b.Y;
445
            result.Z = a.Z - b.Z;
446
            result.W = a.W - b.W;
447
        }
448
 
449
        #endregion
450
 
451
        #region Mult
452
 
453
        /// <summary>
454
        /// Multiply a vector and a scalar
455
        /// </summary>
456
        /// <param name="a">Vector operand</param>
457
        /// <param name="f">Scalar operand</param>
458
        /// <returns>Result of the multiplication</returns>
459
        public static Vector4 Mult(Vector4 a, float f)
460
        {
461
            a.X *= f;
462
            a.Y *= f;
463
            a.Z *= f;
464
            a.W *= f;
465
            return a;
466
        }
467
 
468
        /// <summary>
469
        /// Multiply a vector and a scalar
470
        /// </summary>
471
        /// <param name="a">Vector operand</param>
472
        /// <param name="f">Scalar operand</param>
473
        /// <param name="result">Result of the multiplication</param>
474
        public static void Mult(ref Vector4 a, float f, out Vector4 result)
475
        {
476
            result.X = a.X * f;
477
            result.Y = a.Y * f;
478
            result.Z = a.Z * f;
479
            result.W = a.W * f;
480
        }
481
 
482
        #endregion
483
 
484
        #region Div
485
 
486
        /// <summary>
487
        /// Divide a vector by a scalar
488
        /// </summary>
489
        /// <param name="a">Vector operand</param>
490
        /// <param name="f">Scalar operand</param>
491
        /// <returns>Result of the division</returns>
492
        public static Vector4 Div(Vector4 a, float f)
493
        {
494
            float mult = 1.0f / f;
495
            a.X *= mult;
496
            a.Y *= mult;
497
            a.Z *= mult;
498
            a.W *= mult;
499
            return a;
500
        }
501
 
502
        /// <summary>
503
        /// Divide a vector by a scalar
504
        /// </summary>
505
        /// <param name="a">Vector operand</param>
506
        /// <param name="f">Scalar operand</param>
507
        /// <param name="result">Result of the division</param>
508
        public static void Div(ref Vector4 a, float f, out Vector4 result)
509
        {
510
            float mult = 1.0f / f;
511
            result.X = a.X * mult;
512
            result.Y = a.Y * mult;
513
            result.Z = a.Z * mult;
514
            result.W = a.W * mult;
515
        }
516
 
517
        #endregion
518
 
519
        #region Min
520
 
521
        /// <summary>
522
        /// Calculate the component-wise minimum of two vectors
523
        /// </summary>
524
        /// <param name="a">First operand</param>
525
        /// <param name="b">Second operand</param>
526
        /// <returns>The component-wise minimum</returns>
527
        public static Vector4 Min(Vector4 a, Vector4 b)
528
        {
529
            a.X = a.X < b.X ? a.X : b.X;
530
            a.Y = a.Y < b.Y ? a.Y : b.Y;
531
            a.Z = a.Z < b.Z ? a.Z : b.Z;
532
            a.W = a.W < b.W ? a.W : b.W;
533
            return a;
534
        }
535
 
536
        /// <summary>
537
        /// Calculate the component-wise minimum of two vectors
538
        /// </summary>
539
        /// <param name="a">First operand</param>
540
        /// <param name="b">Second operand</param>
541
        /// <param name="result">The component-wise minimum</param>
542
        public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
543
        {
544
            result.X = a.X < b.X ? a.X : b.X;
545
            result.Y = a.Y < b.Y ? a.Y : b.Y;
546
            result.Z = a.Z < b.Z ? a.Z : b.Z;
547
            result.W = a.W < b.W ? a.W : b.W;
548
        }
549
 
550
        #endregion
551
 
552
        #region Max
553
 
554
        /// <summary>
555
        /// Calculate the component-wise maximum of two vectors
556
        /// </summary>
557
        /// <param name="a">First operand</param>
558
        /// <param name="b">Second operand</param>
559
        /// <returns>The component-wise maximum</returns>
560
        public static Vector4 Max(Vector4 a, Vector4 b)
561
        {
562
            a.X = a.X > b.X ? a.X : b.X;
563
            a.Y = a.Y > b.Y ? a.Y : b.Y;
564
            a.Z = a.Z > b.Z ? a.Z : b.Z;
565
            a.W = a.W > b.W ? a.W : b.W;
566
            return a;
567
        }
568
 
569
        /// <summary>
570
        /// Calculate the component-wise maximum of two vectors
571
        /// </summary>
572
        /// <param name="a">First operand</param>
573
        /// <param name="b">Second operand</param>
574
        /// <param name="result">The component-wise maximum</param>
575
        public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
576
        {
577
            result.X = a.X > b.X ? a.X : b.X;
578
            result.Y = a.Y > b.Y ? a.Y : b.Y;
579
            result.Z = a.Z > b.Z ? a.Z : b.Z;
580
            result.W = a.W > b.W ? a.W : b.W;
581
        }
582
 
583
        #endregion
584
 
585
        #region Clamp
586
 
587
        /// <summary>
588
        /// Clamp a vector to the given minimum and maximum vectors
589
        /// </summary>
590
        /// <param name="vec">Input vector</param>
591
        /// <param name="min">Minimum vector</param>
592
        /// <param name="max">Maximum vector</param>
593
        /// <returns>The clamped vector</returns>
594
        public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
595
        {
596
            vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
597
            vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
598
            vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
599
            vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
600
            return vec;
601
        }
602
 
603
        /// <summary>
604
        /// Clamp a vector to the given minimum and maximum vectors
605
        /// </summary>
606
        /// <param name="vec">Input vector</param>
607
        /// <param name="min">Minimum vector</param>
608
        /// <param name="max">Maximum vector</param>
609
        /// <param name="result">The clamped vector</param>
610
        public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
611
        {
612
            result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
613
            result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
614
            result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
615
            result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
616
        }
617
 
618
        #endregion
619
 
620
        #region Normalize
621
 
622
        /// <summary>
623
        /// Scale a vector to unit length
624
        /// </summary>
625
        /// <param name="vec">The input vector</param>
626
        /// <returns>The normalized vector</returns>
627
        public static Vector4 Normalize(Vector4 vec)
628
        {
629
            float scale = 1.0f / vec.Length;
630
            vec.X *= scale;
631
            vec.Y *= scale;
632
            vec.Z *= scale;
633
            vec.W *= scale;
634
            return vec;
635
        }
636
 
637
        /// <summary>
638
        /// Scale a vector to unit length
639
        /// </summary>
640
        /// <param name="vec">The input vector</param>
641
        /// <param name="result">The normalized vector</param>
642
        public static void Normalize(ref Vector4 vec, out Vector4 result)
643
        {
644
            float scale = 1.0f / vec.Length;
645
            result.X = vec.X * scale;
646
            result.Y = vec.Y * scale;
647
            result.Z = vec.Z * scale;
648
            result.W = vec.W * scale;
649
        }
650
 
651
        #endregion
652
 
653
        #region NormalizeFast
654
 
655
        /// <summary>
656
        /// Scale a vector to approximately unit length
657
        /// </summary>
658
        /// <param name="vec">The input vector</param>
659
        /// <returns>The normalized vector</returns>
660
        public static Vector4 NormalizeFast(Vector4 vec)
661
        {
662
            float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
663
            vec.X *= scale;
664
            vec.Y *= scale;
665
            vec.Z *= scale;
666
            vec.W *= scale;
667
            return vec;
668
        }
669
 
670
        /// <summary>
671
        /// Scale a vector to approximately unit length
672
        /// </summary>
673
        /// <param name="vec">The input vector</param>
674
        /// <param name="result">The normalized vector</param>
675
        public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
676
        {
677
            float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
678
            result.X = vec.X * scale;
679
            result.Y = vec.Y * scale;
680
            result.Z = vec.Z * scale;
681
            result.W = vec.W * scale;
682
        }
683
 
684
        #endregion
685
 
686
        #region Dot
687
 
688
        /// <summary>
689
        /// Calculate the dot product of two vectors
690
        /// </summary>
691
        /// <param name="left">First operand</param>
692
        /// <param name="right">Second operand</param>
693
        /// <returns>The dot product of the two inputs</returns>
694
        public static float Dot(Vector4 left, Vector4 right)
695
        {
696
            return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
697
        }
698
 
699
        /// <summary>
700
        /// Calculate the dot product of two vectors
701
        /// </summary>
702
        /// <param name="left">First operand</param>
703
        /// <param name="right">Second operand</param>
704
        /// <param name="result">The dot product of the two inputs</param>
705
        public static void Dot( ref Vector4 left, ref Vector4 right, out float result )
706
        {
707
            result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
708
        }
709
 
710
        #endregion
711
 
712
        #region Lerp
713
 
714
        /// <summary>
715
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
716
        /// </summary>
717
        /// <param name="a">First input vector</param>
718
        /// <param name="b">Second input vector</param>
719
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
720
        /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
721
        public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
722
        {
723
            a.X = blend * (b.X - a.X) + a.X;
724
            a.Y = blend * (b.Y - a.Y) + a.Y;
725
            a.Z = blend * (b.Z - a.Z) + a.Z;
726
            a.W = blend * (b.W - a.W) + a.W;
727
            return a;
728
        }
729
 
730
        /// <summary>
731
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
732
        /// </summary>
733
        /// <param name="a">First input vector</param>
734
        /// <param name="b">Second input vector</param>
735
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
736
        /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
737
        public static void Lerp( ref Vector4 a, ref Vector4 b, float blend, out Vector4 result )
738
        {
739
            result.X = blend * ( b.X - a.X ) + a.X;
740
            result.Y = blend * ( b.Y - a.Y ) + a.Y;
741
            result.Z = blend * ( b.Z - a.Z ) + a.Z;
742
            result.W = blend * ( b.W - a.W ) + a.W;
743
        }
744
 
745
        #endregion
746
 
747
        #region Barycentric
748
 
749
        /// <summary>
750
        /// Interpolate 3 Vectors using Barycentric coordinates
751
        /// </summary>
752
        /// <param name="a">First input Vector</param>
753
        /// <param name="b">Second input Vector</param>
754
        /// <param name="c">Third input Vector</param>
755
        /// <param name="u">First Barycentric Coordinate</param>
756
        /// <param name="v">Second Barycentric Coordinate</param>
757
        /// <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>
758
        public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
759
        {
760
            return a + u * (b - a) + v * (c - a);
761
        }
762
 
763
        /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
764
        /// <param name="a">First input Vector.</param>
765
        /// <param name="b">Second input Vector.</param>
766
        /// <param name="c">Third input Vector.</param>
767
        /// <param name="u">First Barycentric Coordinate.</param>
768
        /// <param name="v">Second Barycentric Coordinate.</param>
769
        /// <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>
770
        public static void BaryCentric( ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result )
771
        {
772
            result = a; // copy
773
 
774
            Vector4 temp = b; // copy
775
            temp.Sub( ref a );
776
            temp.Mult( u );
777
            result.Add( ref temp );
778
 
779
            temp = c; // copy
780
            temp.Sub( ref a );
781
            temp.Mult( v );
782
            result.Add( ref temp );
783
        }
784
 
785
        #endregion
786
 
787
        #region Transform
788
 
789
        /// <summary>Transform a Vector by the given Matrix</summary>
790
        /// <param name="vec">The vector to transform</param>
791
        /// <param name="mat">The desired transformation</param>
792
        /// <returns>The transformed vector</returns>
793
        public static Vector4 Transform(Vector4 vec, Matrix4 mat)
794
        {
795
            Vector4 result;
796
            result.X = Vector4.Dot(vec, mat.Column0);
797
            result.Y = Vector4.Dot(vec, mat.Column1);
798
            result.Z = Vector4.Dot(vec, mat.Column2);
799
            result.W = Vector4.Dot(vec, mat.Column3);
800
            return result;
801
        }
802
 
803
        /// <summary>Transform a Vector by the given Matrix</summary>
804
        /// <param name="vec">The vector to transform</param>
805
        /// <param name="mat">The desired transformation</param>
806
        /// <param name="result">The transformed vector</param>
807
        public static void Transform( ref Vector4 vec, ref Matrix4 mat, out Vector4 result )
808
        {
809
            result.X = vec.X * mat.Row0.X +
810
                       vec.Y * mat.Row1.X +
811
                       vec.Z * mat.Row2.X +
812
                       vec.W * mat.Row3.X;
813
 
814
            result.Y = vec.X * mat.Row0.Y +
815
                       vec.Y * mat.Row1.Y +
816
                       vec.Z * mat.Row2.Y +
817
                       vec.W * mat.Row3.Y;
818
 
819
            result.Z = vec.X * mat.Row0.Z +
820
                       vec.Y * mat.Row1.Z +
821
                       vec.Z * mat.Row2.Z +
822
                       vec.W * mat.Row3.Z;
823
 
824
            result.W = vec.X * mat.Row0.W +
825
                       vec.Y * mat.Row1.W +
826
                       vec.Z * mat.Row2.W +
827
                       vec.W * mat.Row3.W;
828
        }
829
 
830
        #endregion
831
 
832
        #endregion
833
 
834
        #region Swizzle
835
 
836
        /// <summary>
837
        /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
838
        /// </summary>
839
        [XmlIgnore]
840
        public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
841
 
842
        /// <summary>
843
        /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
844
        /// </summary>
845
        [XmlIgnore]
846
        public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
847
 
848
        #endregion
849
 
850
        #region Operators
851
 
852
        public static Vector4 operator +(Vector4 left, Vector4 right)
853
        {
854
            left.X += right.X;
855
            left.Y += right.Y;
856
            left.Z += right.Z;
857
            left.W += right.W;
858
            return left;
859
        }
860
 
861
        public static Vector4 operator -(Vector4 left, Vector4 right)
862
        {
863
            left.X -= right.X;
864
            left.Y -= right.Y;
865
            left.Z -= right.Z;
866
            left.W -= right.W;
867
            return left;
868
        }
869
 
870
        public static Vector4 operator -(Vector4 vec)
871
        {
872
            vec.X = -vec.X;
873
            vec.Y = -vec.Y;
874
            vec.Z = -vec.Z;
875
            vec.W = -vec.W;
876
            return vec;
877
        }
878
 
879
        public static Vector4 operator *(Vector4 vec, float f)
880
        {
881
            vec.X *= f;
882
            vec.Y *= f;
883
            vec.Z *= f;
884
            vec.W *= f;
885
            return vec;
886
        }
887
 
888
        public static Vector4 operator *(float f, Vector4 vec)
889
        {
890
            vec.X *= f;
891
            vec.Y *= f;
892
            vec.Z *= f;
893
            vec.W *= f;
894
            return vec;
895
        }
896
 
897
        public static Vector4 operator /(Vector4 vec, float f)
898
        {
899
            float mult = 1.0f / f;
900
            vec.X *= mult;
901
            vec.Y *= mult;
902
            vec.Z *= mult;
903
            vec.W *= mult;
904
            return vec;
905
        }
906
 
907
        public static bool operator ==(Vector4 left, Vector4 right)
908
        {
909
            return left.Equals(right);
910
        }
911
 
912
        public static bool operator !=(Vector4 left, Vector4 right)
913
        {
914
            return !left.Equals(right);
915
        }
916
 
917
        [CLSCompliant(false)]
918
        unsafe public static explicit operator float*(Vector4 v)
919
        {
920
            return &v.X;
921
        }
922
 
923
        public static explicit operator IntPtr(Vector4 v)
924
        {
925
            unsafe
926
            {
927
                return (IntPtr)(&v.X);
928
            }
929
        }
930
 
931
        #endregion
932
 
933
        #region Overrides
934
 
935
        #region public override string ToString()
936
 
937
        /// <summary>
938
        /// Returns a System.String that represents the current Vector4.
939
        /// </summary>
940
        /// <returns></returns>
941
        public override string ToString()
942
        {
943
            return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
944
        }
945
 
946
        #endregion
947
 
948
        #region public override int GetHashCode()
949
 
950
        /// <summary>
951
        /// Returns the hashcode for this instance.
952
        /// </summary>
953
        /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
954
        public override int GetHashCode()
955
        {
956
            return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
957
        }
958
 
959
        #endregion
960
 
961
        #region public override bool Equals(object obj)
962
 
963
        /// <summary>
964
        /// Indicates whether this instance and a specified object are equal.
965
        /// </summary>
966
        /// <param name="obj">The object to compare to.</param>
967
        /// <returns>True if the instances are equal; false otherwise.</returns>
968
        public override bool Equals(object obj)
969
        {
970
            if (!(obj is Vector4))
971
                return false;
972
 
973
            return this.Equals((Vector4)obj);
974
        }
975
 
976
        #endregion
977
 
978
        #endregion
979
 
980
        #endregion
981
 
982
        #region IEquatable<Vector4> Members
983
 
984
        /// <summary>Indicates whether the current vector is equal to another vector.</summary>
985
        /// <param name="other">A vector to compare with this vector.</param>
986
        /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
987
        public bool Equals(Vector4 other)
988
        {
989
            return
990
                X == other.X &&
991
                Y == other.Y &&
992
                Z == other.Z &&
993
                W == other.W;
994
        }
995
 
996
        #endregion
997
    }
998
}