00001 #region --- License ---
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #endregion
00024
00025 using System;
00026 using System.Runtime.InteropServices;
00027 using System.Xml.Serialization;
00028
00029 namespace OpenTK
00030 {
00032 [Serializable]
00033 [StructLayout(LayoutKind.Sequential)]
00034 public struct Vector4d : IEquatable<Vector4d>
00035 {
00036 #region Fields
00037
00041 public double X;
00042
00046 public double Y;
00047
00051 public double Z;
00052
00056 public double W;
00057
00061 public static Vector4d UnitX = new Vector4d(1, 0, 0, 0);
00062
00066 public static Vector4d UnitY = new Vector4d(0, 1, 0, 0);
00067
00071 public static Vector4d UnitZ = new Vector4d(0, 0, 1, 0);
00072
00076 public static Vector4d UnitW = new Vector4d(0, 0, 0, 1);
00077
00081 public static Vector4d Zero = new Vector4d(0, 0, 0, 0);
00082
00086 public static readonly Vector4d One = new Vector4d(1, 1, 1, 1);
00087
00091 public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4d());
00092
00093 #endregion
00094
00095 #region Constructors
00096
00104 public Vector4d(double x, double y, double z, double w)
00105 {
00106 X = x;
00107 Y = y;
00108 Z = z;
00109 W = w;
00110 }
00111
00116 public Vector4d(Vector2d v)
00117 {
00118 X = v.X;
00119 Y = v.Y;
00120 Z = 0.0f;
00121 W = 0.0f;
00122 }
00123
00128 public Vector4d(Vector3d v)
00129 {
00130 X = v.X;
00131 Y = v.Y;
00132 Z = v.Z;
00133 W = 0.0f;
00134 }
00135
00141 public Vector4d(Vector3 v, double w)
00142 {
00143 X = v.X;
00144 Y = v.Y;
00145 Z = v.Z;
00146 W = w;
00147 }
00148
00153 public Vector4d(Vector4d v)
00154 {
00155 X = v.X;
00156 Y = v.Y;
00157 Z = v.Z;
00158 W = v.W;
00159 }
00160
00161 #endregion
00162
00163 #region Public Members
00164
00165 #region Instance
00166
00167 #region public void Add()
00168
00171 [Obsolete("Use static Add() method instead.")]
00172 public void Add(Vector4d right)
00173 {
00174 this.X += right.X;
00175 this.Y += right.Y;
00176 this.Z += right.Z;
00177 this.W += right.W;
00178 }
00179
00182 [CLSCompliant(false)]
00183 [Obsolete("Use static Add() method instead.")]
00184 public void Add(ref Vector4d right)
00185 {
00186 this.X += right.X;
00187 this.Y += right.Y;
00188 this.Z += right.Z;
00189 this.W += right.W;
00190 }
00191
00192 #endregion public void Add()
00193
00194 #region public void Sub()
00195
00198 [Obsolete("Use static Subtract() method instead.")]
00199 public void Sub(Vector4d right)
00200 {
00201 this.X -= right.X;
00202 this.Y -= right.Y;
00203 this.Z -= right.Z;
00204 this.W -= right.W;
00205 }
00206
00209 [CLSCompliant(false)]
00210 [Obsolete("Use static Subtract() method instead.")]
00211 public void Sub(ref Vector4d right)
00212 {
00213 this.X -= right.X;
00214 this.Y -= right.Y;
00215 this.Z -= right.Z;
00216 this.W -= right.W;
00217 }
00218
00219 #endregion public void Sub()
00220
00221 #region public void Mult()
00222
00225 [Obsolete("Use static Multiply() method instead.")]
00226 public void Mult(double f)
00227 {
00228 this.X *= f;
00229 this.Y *= f;
00230 this.Z *= f;
00231 this.W *= f;
00232 }
00233
00234 #endregion public void Mult()
00235
00236 #region public void Div()
00237
00240 [Obsolete("Use static Divide() method instead.")]
00241 public void Div(double f)
00242 {
00243 double mult = 1.0 / f;
00244 this.X *= mult;
00245 this.Y *= mult;
00246 this.Z *= mult;
00247 this.W *= mult;
00248 }
00249
00250 #endregion public void Div()
00251
00252 #region public double Length
00253
00259 public double Length
00260 {
00261 get
00262 {
00263 return System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
00264 }
00265 }
00266
00267 #endregion
00268
00269 #region public double LengthFast
00270
00280 public double LengthFast
00281 {
00282 get
00283 {
00284 return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
00285 }
00286 }
00287
00288 #endregion
00289
00290 #region public double LengthSquared
00291
00300 public double LengthSquared
00301 {
00302 get
00303 {
00304 return X * X + Y * Y + Z * Z + W * W;
00305 }
00306 }
00307
00308 #endregion
00309
00310 #region public void Normalize()
00311
00315 public void Normalize()
00316 {
00317 double scale = 1.0 / this.Length;
00318 X *= scale;
00319 Y *= scale;
00320 Z *= scale;
00321 W *= scale;
00322 }
00323
00324 #endregion
00325
00326 #region public void NormalizeFast()
00327
00331 public void NormalizeFast()
00332 {
00333 double scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
00334 X *= scale;
00335 Y *= scale;
00336 Z *= scale;
00337 W *= scale;
00338 }
00339
00340 #endregion
00341
00342 #region public void Scale()
00343
00351 [Obsolete("Use static Multiply() method instead.")]
00352 public void Scale(double sx, double sy, double sz, double sw)
00353 {
00354 this.X = X * sx;
00355 this.Y = Y * sy;
00356 this.Z = Z * sz;
00357 this.W = W * sw;
00358 }
00359
00362 [Obsolete("Use static Multiply() method instead.")]
00363 public void Scale(Vector4d scale)
00364 {
00365 this.X *= scale.X;
00366 this.Y *= scale.Y;
00367 this.Z *= scale.Z;
00368 this.W *= scale.W;
00369 }
00370
00373 [CLSCompliant(false)]
00374 [Obsolete("Use static Multiply() method instead.")]
00375 public void Scale(ref Vector4d scale)
00376 {
00377 this.X *= scale.X;
00378 this.Y *= scale.Y;
00379 this.Z *= scale.Z;
00380 this.W *= scale.W;
00381 }
00382
00383 #endregion public void Scale()
00384
00385 #endregion
00386
00387 #region Static
00388
00389 #region Obsolete
00390
00391 #region Sub
00392
00399 [Obsolete("Use static Subtract() method instead.")]
00400 public static Vector4d Sub(Vector4d a, Vector4d b)
00401 {
00402 a.X -= b.X;
00403 a.Y -= b.Y;
00404 a.Z -= b.Z;
00405 a.W -= b.W;
00406 return a;
00407 }
00408
00415 [Obsolete("Use static Subtract() method instead.")]
00416 public static void Sub(ref Vector4d a, ref Vector4d b, out Vector4d result)
00417 {
00418 result.X = a.X - b.X;
00419 result.Y = a.Y - b.Y;
00420 result.Z = a.Z - b.Z;
00421 result.W = a.W - b.W;
00422 }
00423
00424 #endregion
00425
00426 #region Mult
00427
00434 [Obsolete("Use static Multiply() method instead.")]
00435 public static Vector4d Mult(Vector4d a, double f)
00436 {
00437 a.X *= f;
00438 a.Y *= f;
00439 a.Z *= f;
00440 a.W *= f;
00441 return a;
00442 }
00443
00450 [Obsolete("Use static Multiply() method instead.")]
00451 public static void Mult(ref Vector4d a, double f, out Vector4d result)
00452 {
00453 result.X = a.X * f;
00454 result.Y = a.Y * f;
00455 result.Z = a.Z * f;
00456 result.W = a.W * f;
00457 }
00458
00459 #endregion
00460
00461 #region Div
00462
00469 [Obsolete("Use static Divide() method instead.")]
00470 public static Vector4d Div(Vector4d a, double f)
00471 {
00472 double mult = 1.0 / f;
00473 a.X *= mult;
00474 a.Y *= mult;
00475 a.Z *= mult;
00476 a.W *= mult;
00477 return a;
00478 }
00479
00486 [Obsolete("Use static Divide() method instead.")]
00487 public static void Div(ref Vector4d a, double f, out Vector4d result)
00488 {
00489 double mult = 1.0 / f;
00490 result.X = a.X * mult;
00491 result.Y = a.Y * mult;
00492 result.Z = a.Z * mult;
00493 result.W = a.W * mult;
00494 }
00495
00496 #endregion
00497
00498 #endregion
00499
00500 #region Add
00501
00508 public static Vector4d Add(Vector4d a, Vector4d b)
00509 {
00510 Add(ref a, ref b, out a);
00511 return a;
00512 }
00513
00520 public static void Add(ref Vector4d a, ref Vector4d b, out Vector4d result)
00521 {
00522 result = new Vector4d(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W);
00523 }
00524
00525 #endregion
00526
00527 #region Subtract
00528
00535 public static Vector4d Subtract(Vector4d a, Vector4d b)
00536 {
00537 Subtract(ref a, ref b, out a);
00538 return a;
00539 }
00540
00547 public static void Subtract(ref Vector4d a, ref Vector4d b, out Vector4d result)
00548 {
00549 result = new Vector4d(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W);
00550 }
00551
00552 #endregion
00553
00554 #region Multiply
00555
00562 public static Vector4d Multiply(Vector4d vector, double scale)
00563 {
00564 Multiply(ref vector, scale, out vector);
00565 return vector;
00566 }
00567
00574 public static void Multiply(ref Vector4d vector, double scale, out Vector4d result)
00575 {
00576 result = new Vector4d(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale);
00577 }
00578
00585 public static Vector4d Multiply(Vector4d vector, Vector4d scale)
00586 {
00587 Multiply(ref vector, ref scale, out vector);
00588 return vector;
00589 }
00590
00597 public static void Multiply(ref Vector4d vector, ref Vector4d scale, out Vector4d result)
00598 {
00599 result = new Vector4d(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W);
00600 }
00601
00602 #endregion
00603
00604 #region Divide
00605
00612 public static Vector4d Divide(Vector4d vector, double scale)
00613 {
00614 Divide(ref vector, scale, out vector);
00615 return vector;
00616 }
00617
00624 public static void Divide(ref Vector4d vector, double scale, out Vector4d result)
00625 {
00626 Multiply(ref vector, 1 / scale, out result);
00627 }
00628
00635 public static Vector4d Divide(Vector4d vector, Vector4d scale)
00636 {
00637 Divide(ref vector, ref scale, out vector);
00638 return vector;
00639 }
00640
00647 public static void Divide(ref Vector4d vector, ref Vector4d scale, out Vector4d result)
00648 {
00649 result = new Vector4d(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W);
00650 }
00651
00652 #endregion
00653
00654 #region Min
00655
00662 public static Vector4d Min(Vector4d a, Vector4d b)
00663 {
00664 a.X = a.X < b.X ? a.X : b.X;
00665 a.Y = a.Y < b.Y ? a.Y : b.Y;
00666 a.Z = a.Z < b.Z ? a.Z : b.Z;
00667 a.W = a.W < b.W ? a.W : b.W;
00668 return a;
00669 }
00670
00677 public static void Min(ref Vector4d a, ref Vector4d b, out Vector4d result)
00678 {
00679 result.X = a.X < b.X ? a.X : b.X;
00680 result.Y = a.Y < b.Y ? a.Y : b.Y;
00681 result.Z = a.Z < b.Z ? a.Z : b.Z;
00682 result.W = a.W < b.W ? a.W : b.W;
00683 }
00684
00685 #endregion
00686
00687 #region Max
00688
00695 public static Vector4d Max(Vector4d a, Vector4d b)
00696 {
00697 a.X = a.X > b.X ? a.X : b.X;
00698 a.Y = a.Y > b.Y ? a.Y : b.Y;
00699 a.Z = a.Z > b.Z ? a.Z : b.Z;
00700 a.W = a.W > b.W ? a.W : b.W;
00701 return a;
00702 }
00703
00710 public static void Max(ref Vector4d a, ref Vector4d b, out Vector4d result)
00711 {
00712 result.X = a.X > b.X ? a.X : b.X;
00713 result.Y = a.Y > b.Y ? a.Y : b.Y;
00714 result.Z = a.Z > b.Z ? a.Z : b.Z;
00715 result.W = a.W > b.W ? a.W : b.W;
00716 }
00717
00718 #endregion
00719
00720 #region Clamp
00721
00729 public static Vector4d Clamp(Vector4d vec, Vector4d min, Vector4d max)
00730 {
00731 vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
00732 vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
00733 vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
00734 vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
00735 return vec;
00736 }
00737
00745 public static void Clamp(ref Vector4d vec, ref Vector4d min, ref Vector4d max, out Vector4d result)
00746 {
00747 result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
00748 result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
00749 result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
00750 result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
00751 }
00752
00753 #endregion
00754
00755 #region Normalize
00756
00762 public static Vector4d Normalize(Vector4d vec)
00763 {
00764 double scale = 1.0 / vec.Length;
00765 vec.X *= scale;
00766 vec.Y *= scale;
00767 vec.Z *= scale;
00768 vec.W *= scale;
00769 return vec;
00770 }
00771
00777 public static void Normalize(ref Vector4d vec, out Vector4d result)
00778 {
00779 double scale = 1.0 / vec.Length;
00780 result.X = vec.X * scale;
00781 result.Y = vec.Y * scale;
00782 result.Z = vec.Z * scale;
00783 result.W = vec.W * scale;
00784 }
00785
00786 #endregion
00787
00788 #region NormalizeFast
00789
00795 public static Vector4d NormalizeFast(Vector4d vec)
00796 {
00797 double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
00798 vec.X *= scale;
00799 vec.Y *= scale;
00800 vec.Z *= scale;
00801 vec.W *= scale;
00802 return vec;
00803 }
00804
00810 public static void NormalizeFast(ref Vector4d vec, out Vector4d result)
00811 {
00812 double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
00813 result.X = vec.X * scale;
00814 result.Y = vec.Y * scale;
00815 result.Z = vec.Z * scale;
00816 result.W = vec.W * scale;
00817 }
00818
00819 #endregion
00820
00821 #region Dot
00822
00829 public static double Dot(Vector4d left, Vector4d right)
00830 {
00831 return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
00832 }
00833
00840 public static void Dot(ref Vector4d left, ref Vector4d right, out double result)
00841 {
00842 result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
00843 }
00844
00845 #endregion
00846
00847 #region Lerp
00848
00856 public static Vector4d Lerp(Vector4d a, Vector4d b, double blend)
00857 {
00858 a.X = blend * (b.X - a.X) + a.X;
00859 a.Y = blend * (b.Y - a.Y) + a.Y;
00860 a.Z = blend * (b.Z - a.Z) + a.Z;
00861 a.W = blend * (b.W - a.W) + a.W;
00862 return a;
00863 }
00864
00872 public static void Lerp(ref Vector4d a, ref Vector4d b, double blend, out Vector4d result)
00873 {
00874 result.X = blend * (b.X - a.X) + a.X;
00875 result.Y = blend * (b.Y - a.Y) + a.Y;
00876 result.Z = blend * (b.Z - a.Z) + a.Z;
00877 result.W = blend * (b.W - a.W) + a.W;
00878 }
00879
00880 #endregion
00881
00882 #region Barycentric
00883
00893 public static Vector4d BaryCentric(Vector4d a, Vector4d b, Vector4d c, double u, double v)
00894 {
00895 return a + u * (b - a) + v * (c - a);
00896 }
00897
00905 public static void BaryCentric(ref Vector4d a, ref Vector4d b, ref Vector4d c, double u, double v, out Vector4d result)
00906 {
00907 result = a;
00908
00909 Vector4d temp = b;
00910 Subtract(ref temp, ref a, out temp);
00911 Multiply(ref temp, u, out temp);
00912 Add(ref result, ref temp, out result);
00913
00914 temp = c;
00915 Subtract(ref temp, ref a, out temp);
00916 Multiply(ref temp, v, out temp);
00917 Add(ref result, ref temp, out result);
00918 }
00919
00920 #endregion
00921
00922 #region Transform
00923
00928 public static Vector4d Transform(Vector4d vec, Matrix4d mat)
00929 {
00930 Vector4d result;
00931 Transform(ref vec, ref mat, out result);
00932 return result;
00933 }
00934
00939 public static void Transform(ref Vector4d vec, ref Matrix4d mat, out Vector4d result)
00940 {
00941 result = new Vector4d(
00942 vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X,
00943 vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y,
00944 vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z,
00945 vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W);
00946 }
00947
00954 public static Vector4d Transform(Vector4d vec, Quaterniond quat)
00955 {
00956 Vector4d result;
00957 Transform(ref vec, ref quat, out result);
00958 return result;
00959 }
00960
00967 public static void Transform(ref Vector4d vec, ref Quaterniond quat, out Vector4d result)
00968 {
00969 Quaterniond v = new Quaterniond(vec.X, vec.Y, vec.Z, vec.W), i, t;
00970 Quaterniond.Invert(ref quat, out i);
00971 Quaterniond.Multiply(ref quat, ref v, out t);
00972 Quaterniond.Multiply(ref t, ref i, out v);
00973
00974 result = new Vector4d(v.X, v.Y, v.Z, v.W);
00975 }
00976
00977 #endregion
00978
00979 #endregion
00980
00981 #region Swizzle
00982
00986 [XmlIgnore]
00987 public Vector2d Xy { get { return new Vector2d(X, Y); } set { X = value.X; Y = value.Y; } }
00988
00992 [XmlIgnore]
00993 public Vector3d Xyz { get { return new Vector3d(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
00994
00995 #endregion
00996
00997 #region Operators
00998
01005 public static Vector4d operator +(Vector4d left, Vector4d right)
01006 {
01007 left.X += right.X;
01008 left.Y += right.Y;
01009 left.Z += right.Z;
01010 left.W += right.W;
01011 return left;
01012 }
01013
01020 public static Vector4d operator -(Vector4d left, Vector4d right)
01021 {
01022 left.X -= right.X;
01023 left.Y -= right.Y;
01024 left.Z -= right.Z;
01025 left.W -= right.W;
01026 return left;
01027 }
01028
01034 public static Vector4d operator -(Vector4d vec)
01035 {
01036 vec.X = -vec.X;
01037 vec.Y = -vec.Y;
01038 vec.Z = -vec.Z;
01039 vec.W = -vec.W;
01040 return vec;
01041 }
01042
01049 public static Vector4d operator *(Vector4d vec, double scale)
01050 {
01051 vec.X *= scale;
01052 vec.Y *= scale;
01053 vec.Z *= scale;
01054 vec.W *= scale;
01055 return vec;
01056 }
01057
01064 public static Vector4d operator *(double scale, Vector4d vec)
01065 {
01066 vec.X *= scale;
01067 vec.Y *= scale;
01068 vec.Z *= scale;
01069 vec.W *= scale;
01070 return vec;
01071 }
01072
01079 public static Vector4d operator /(Vector4d vec, double scale)
01080 {
01081 double mult = 1 / scale;
01082 vec.X *= mult;
01083 vec.Y *= mult;
01084 vec.Z *= mult;
01085 vec.W *= mult;
01086 return vec;
01087 }
01088
01095 public static bool operator ==(Vector4d left, Vector4d right)
01096 {
01097 return left.Equals(right);
01098 }
01099
01106 public static bool operator !=(Vector4d left, Vector4d right)
01107 {
01108 return !left.Equals(right);
01109 }
01110
01116 [CLSCompliant(false)]
01117 unsafe public static explicit operator double*(Vector4d v)
01118 {
01119 return &v.X;
01120 }
01121
01127 public static explicit operator IntPtr(Vector4d v)
01128 {
01129 unsafe
01130 {
01131 return (IntPtr)(&v.X);
01132 }
01133 }
01134
01138 public static explicit operator Vector4d(Vector4 v4)
01139 {
01140 return new Vector4d(v4.X, v4.Y, v4.Z, v4.W);
01141 }
01142
01146 public static explicit operator Vector4(Vector4d v4d)
01147 {
01148 return new Vector4((float)v4d.X, (float)v4d.Y, (float)v4d.Z, (float)v4d.W);
01149 }
01150
01151 #endregion
01152
01153 #region Overrides
01154
01155 #region public override string ToString()
01156
01161 public override string ToString()
01162 {
01163 return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
01164 }
01165
01166 #endregion
01167
01168 #region public override int GetHashCode()
01169
01174 public override int GetHashCode()
01175 {
01176 return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
01177 }
01178
01179 #endregion
01180
01181 #region public override bool Equals(object obj)
01182
01188 public override bool Equals(object obj)
01189 {
01190 if (!(obj is Vector4d))
01191 return false;
01192
01193 return this.Equals((Vector4d)obj);
01194 }
01195
01196 #endregion
01197
01198 #endregion
01199
01200 #endregion
01201
01202 #region IEquatable<Vector4d> Members
01203
01207 public bool Equals(Vector4d other)
01208 {
01209 return
01210 X == other.X &&
01211 Y == other.Y &&
01212 Z == other.Z &&
01213 W == other.W;
01214 }
01215
01216 #endregion
01217 }
01218 }