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