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