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 namespace OpenTK
00029 {
00034 [Serializable]
00035 [StructLayout(LayoutKind.Sequential)]
00036 public struct Vector4 : IEquatable<Vector4>
00037 {
00038 #region Fields
00039
00043 public float X;
00044
00048 public float Y;
00049
00053 public float Z;
00054
00058 public float W;
00059
00063 public static Vector4 UnitX = new Vector4(1, 0, 0, 0);
00064
00068 public static Vector4 UnitY = new Vector4(0, 1, 0, 0);
00069
00073 public static Vector4 UnitZ = new Vector4(0, 0, 1, 0);
00074
00078 public static Vector4 UnitW = new Vector4(0, 0, 0, 1);
00079
00083 public static Vector4 Zero = new Vector4(0, 0, 0, 0);
00084
00088 public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
00089
00093 public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
00094
00095 #endregion
00096
00097 #region Constructors
00098
00106 public Vector4(float x, float y, float z, float w)
00107 {
00108 X = x;
00109 Y = y;
00110 Z = z;
00111 W = w;
00112 }
00113
00118 public Vector4(Vector2 v)
00119 {
00120 X = v.X;
00121 Y = v.Y;
00122 Z = 0.0f;
00123 W = 0.0f;
00124 }
00125
00130 public Vector4(Vector3 v)
00131 {
00132 X = v.X;
00133 Y = v.Y;
00134 Z = v.Z;
00135 W = 0.0f;
00136 }
00137
00143 public Vector4(Vector3 v, float w)
00144 {
00145 X = v.X;
00146 Y = v.Y;
00147 Z = v.Z;
00148 W = w;
00149 }
00150
00155 public Vector4(Vector4 v)
00156 {
00157 X = v.X;
00158 Y = v.Y;
00159 Z = v.Z;
00160 W = v.W;
00161 }
00162
00163 #endregion
00164
00165 #region Public Members
00166
00167 #region Instance
00168
00169 #region public void Add()
00170
00173 [Obsolete("Use static Add() method instead.")]
00174 public void Add(Vector4 right)
00175 {
00176 this.X += right.X;
00177 this.Y += right.Y;
00178 this.Z += right.Z;
00179 this.W += right.W;
00180 }
00181
00184 [CLSCompliant(false)]
00185 [Obsolete("Use static Add() method instead.")]
00186 public void Add(ref Vector4 right)
00187 {
00188 this.X += right.X;
00189 this.Y += right.Y;
00190 this.Z += right.Z;
00191 this.W += right.W;
00192 }
00193
00194 #endregion public void Add()
00195
00196 #region public void Sub()
00197
00200 [Obsolete("Use static Subtract() method instead.")]
00201 public void Sub(Vector4 right)
00202 {
00203 this.X -= right.X;
00204 this.Y -= right.Y;
00205 this.Z -= right.Z;
00206 this.W -= right.W;
00207 }
00208
00211 [CLSCompliant(false)]
00212 [Obsolete("Use static Subtract() method instead.")]
00213 public void Sub(ref Vector4 right)
00214 {
00215 this.X -= right.X;
00216 this.Y -= right.Y;
00217 this.Z -= right.Z;
00218 this.W -= right.W;
00219 }
00220
00221 #endregion public void Sub()
00222
00223 #region public void Mult()
00224
00227 [Obsolete("Use static Multiply() method instead.")]
00228 public void Mult(float f)
00229 {
00230 this.X *= f;
00231 this.Y *= f;
00232 this.Z *= f;
00233 this.W *= f;
00234 }
00235
00236 #endregion public void Mult()
00237
00238 #region public void Div()
00239
00242 [Obsolete("Use static Divide() method instead.")]
00243 public void Div(float f)
00244 {
00245 float mult = 1.0f / f;
00246 this.X *= mult;
00247 this.Y *= mult;
00248 this.Z *= mult;
00249 this.W *= mult;
00250 }
00251
00252 #endregion public void Div()
00253
00254 #region public float Length
00255
00261 public float Length
00262 {
00263 get
00264 {
00265 return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
00266 }
00267 }
00268
00269 #endregion
00270
00271 #region public float LengthFast
00272
00282 public float LengthFast
00283 {
00284 get
00285 {
00286 return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
00287 }
00288 }
00289
00290 #endregion
00291
00292 #region public float LengthSquared
00293
00303 public float LengthSquared
00304 {
00305 get
00306 {
00307 return X * X + Y * Y + Z * Z + W * W;
00308 }
00309 }
00310
00311 #endregion
00312
00313 #region public void Normalize()
00314
00318 public void Normalize()
00319 {
00320 float scale = 1.0f / this.Length;
00321 X *= scale;
00322 Y *= scale;
00323 Z *= scale;
00324 W *= scale;
00325 }
00326
00327 #endregion
00328
00329 #region public void NormalizeFast()
00330
00334 public void NormalizeFast()
00335 {
00336 float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
00337 X *= scale;
00338 Y *= scale;
00339 Z *= scale;
00340 W *= scale;
00341 }
00342
00343 #endregion
00344
00345 #region public void Scale()
00346
00354 [Obsolete("Use static Multiply() method instead.")]
00355 public void Scale(float sx, float sy, float sz, float sw)
00356 {
00357 this.X = X * sx;
00358 this.Y = Y * sy;
00359 this.Z = Z * sz;
00360 this.W = W * sw;
00361 }
00362
00365 [Obsolete("Use static Multiply() method instead.")]
00366 public void Scale(Vector4 scale)
00367 {
00368 this.X *= scale.X;
00369 this.Y *= scale.Y;
00370 this.Z *= scale.Z;
00371 this.W *= scale.W;
00372 }
00373
00376 [CLSCompliant(false)]
00377 [Obsolete("Use static Multiply() method instead.")]
00378 public void Scale(ref Vector4 scale)
00379 {
00380 this.X *= scale.X;
00381 this.Y *= scale.Y;
00382 this.Z *= scale.Z;
00383 this.W *= scale.W;
00384 }
00385
00386 #endregion public void Scale()
00387
00388 #endregion
00389
00390 #region Static
00391
00392 #region Obsolete
00393
00394 #region Sub
00395
00402 public static Vector4 Sub(Vector4 a, Vector4 b)
00403 {
00404 a.X -= b.X;
00405 a.Y -= b.Y;
00406 a.Z -= b.Z;
00407 a.W -= b.W;
00408 return a;
00409 }
00410
00417 public static void Sub(ref Vector4 a, ref Vector4 b, out Vector4 result)
00418 {
00419 result.X = a.X - b.X;
00420 result.Y = a.Y - b.Y;
00421 result.Z = a.Z - b.Z;
00422 result.W = a.W - b.W;
00423 }
00424
00425 #endregion
00426
00427 #region Mult
00428
00435 public static Vector4 Mult(Vector4 a, float f)
00436 {
00437 a.X *= f;
00438 a.Y *= f;
00439 a.Z *= f;
00440 a.W *= f;
00441 return a;
00442 }
00443
00450 public static void Mult(ref Vector4 a, float f, out Vector4 result)
00451 {
00452 result.X = a.X * f;
00453 result.Y = a.Y * f;
00454 result.Z = a.Z * f;
00455 result.W = a.W * f;
00456 }
00457
00458 #endregion
00459
00460 #region Div
00461
00468 public static Vector4 Div(Vector4 a, float f)
00469 {
00470 float mult = 1.0f / f;
00471 a.X *= mult;
00472 a.Y *= mult;
00473 a.Z *= mult;
00474 a.W *= mult;
00475 return a;
00476 }
00477
00484 public static void Div(ref Vector4 a, float f, out Vector4 result)
00485 {
00486 float mult = 1.0f / f;
00487 result.X = a.X * mult;
00488 result.Y = a.Y * mult;
00489 result.Z = a.Z * mult;
00490 result.W = a.W * mult;
00491 }
00492
00493 #endregion
00494
00495 #endregion
00496
00497 #region Add
00498
00505 public static Vector4 Add(Vector4 a, Vector4 b)
00506 {
00507 Add(ref a, ref b, out a);
00508 return a;
00509 }
00510
00517 public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
00518 {
00519 result = new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W);
00520 }
00521
00522 #endregion
00523
00524 #region Subtract
00525
00532 public static Vector4 Subtract(Vector4 a, Vector4 b)
00533 {
00534 Subtract(ref a, ref b, out a);
00535 return a;
00536 }
00537
00544 public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result)
00545 {
00546 result = new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W);
00547 }
00548
00549 #endregion
00550
00551 #region Multiply
00552
00559 public static Vector4 Multiply(Vector4 vector, float scale)
00560 {
00561 Multiply(ref vector, scale, out vector);
00562 return vector;
00563 }
00564
00571 public static void Multiply(ref Vector4 vector, float scale, out Vector4 result)
00572 {
00573 result = new Vector4(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale);
00574 }
00575
00582 public static Vector4 Multiply(Vector4 vector, Vector4 scale)
00583 {
00584 Multiply(ref vector, ref scale, out vector);
00585 return vector;
00586 }
00587
00594 public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
00595 {
00596 result = new Vector4(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W);
00597 }
00598
00599 #endregion
00600
00601 #region Divide
00602
00609 public static Vector4 Divide(Vector4 vector, float scale)
00610 {
00611 Divide(ref vector, scale, out vector);
00612 return vector;
00613 }
00614
00621 public static void Divide(ref Vector4 vector, float scale, out Vector4 result)
00622 {
00623 Multiply(ref vector, 1 / scale, out result);
00624 }
00625
00632 public static Vector4 Divide(Vector4 vector, Vector4 scale)
00633 {
00634 Divide(ref vector, ref scale, out vector);
00635 return vector;
00636 }
00637
00644 public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
00645 {
00646 result = new Vector4(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W);
00647 }
00648
00649 #endregion
00650
00651 #region Min
00652
00659 public static Vector4 Min(Vector4 a, Vector4 b)
00660 {
00661 a.X = a.X < b.X ? a.X : b.X;
00662 a.Y = a.Y < b.Y ? a.Y : b.Y;
00663 a.Z = a.Z < b.Z ? a.Z : b.Z;
00664 a.W = a.W < b.W ? a.W : b.W;
00665 return a;
00666 }
00667
00674 public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
00675 {
00676 result.X = a.X < b.X ? a.X : b.X;
00677 result.Y = a.Y < b.Y ? a.Y : b.Y;
00678 result.Z = a.Z < b.Z ? a.Z : b.Z;
00679 result.W = a.W < b.W ? a.W : b.W;
00680 }
00681
00682 #endregion
00683
00684 #region Max
00685
00692 public static Vector4 Max(Vector4 a, Vector4 b)
00693 {
00694 a.X = a.X > b.X ? a.X : b.X;
00695 a.Y = a.Y > b.Y ? a.Y : b.Y;
00696 a.Z = a.Z > b.Z ? a.Z : b.Z;
00697 a.W = a.W > b.W ? a.W : b.W;
00698 return a;
00699 }
00700
00707 public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
00708 {
00709 result.X = a.X > b.X ? a.X : b.X;
00710 result.Y = a.Y > b.Y ? a.Y : b.Y;
00711 result.Z = a.Z > b.Z ? a.Z : b.Z;
00712 result.W = a.W > b.W ? a.W : b.W;
00713 }
00714
00715 #endregion
00716
00717 #region Clamp
00718
00726 public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
00727 {
00728 vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
00729 vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
00730 vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
00731 vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
00732 return vec;
00733 }
00734
00742 public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
00743 {
00744 result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
00745 result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
00746 result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
00747 result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
00748 }
00749
00750 #endregion
00751
00752 #region Normalize
00753
00759 public static Vector4 Normalize(Vector4 vec)
00760 {
00761 float scale = 1.0f / vec.Length;
00762 vec.X *= scale;
00763 vec.Y *= scale;
00764 vec.Z *= scale;
00765 vec.W *= scale;
00766 return vec;
00767 }
00768
00774 public static void Normalize(ref Vector4 vec, out Vector4 result)
00775 {
00776 float scale = 1.0f / vec.Length;
00777 result.X = vec.X * scale;
00778 result.Y = vec.Y * scale;
00779 result.Z = vec.Z * scale;
00780 result.W = vec.W * scale;
00781 }
00782
00783 #endregion
00784
00785 #region NormalizeFast
00786
00792 public static Vector4 NormalizeFast(Vector4 vec)
00793 {
00794 float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
00795 vec.X *= scale;
00796 vec.Y *= scale;
00797 vec.Z *= scale;
00798 vec.W *= scale;
00799 return vec;
00800 }
00801
00807 public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
00808 {
00809 float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
00810 result.X = vec.X * scale;
00811 result.Y = vec.Y * scale;
00812 result.Z = vec.Z * scale;
00813 result.W = vec.W * scale;
00814 }
00815
00816 #endregion
00817
00818 #region Dot
00819
00826 public static float Dot(Vector4 left, Vector4 right)
00827 {
00828 return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
00829 }
00830
00837 public static void Dot(ref Vector4 left, ref Vector4 right, out float result)
00838 {
00839 result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
00840 }
00841
00842 #endregion
00843
00844 #region Lerp
00845
00853 public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
00854 {
00855 a.X = blend * (b.X - a.X) + a.X;
00856 a.Y = blend * (b.Y - a.Y) + a.Y;
00857 a.Z = blend * (b.Z - a.Z) + a.Z;
00858 a.W = blend * (b.W - a.W) + a.W;
00859 return a;
00860 }
00861
00869 public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result)
00870 {
00871 result.X = blend * (b.X - a.X) + a.X;
00872 result.Y = blend * (b.Y - a.Y) + a.Y;
00873 result.Z = blend * (b.Z - a.Z) + a.Z;
00874 result.W = blend * (b.W - a.W) + a.W;
00875 }
00876
00877 #endregion
00878
00879 #region Barycentric
00880
00890 public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
00891 {
00892 return a + u * (b - a) + v * (c - a);
00893 }
00894
00902 public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result)
00903 {
00904 result = a;
00905
00906 Vector4 temp = b;
00907 Subtract(ref temp, ref a, out temp);
00908 Multiply(ref temp, u, out temp);
00909 Add(ref result, ref temp, out result);
00910
00911 temp = c;
00912 Subtract(ref temp, ref a, out temp);
00913 Multiply(ref temp, v, out temp);
00914 Add(ref result, ref temp, out result);
00915 }
00916
00917 #endregion
00918
00919 #region Transform
00920
00925 public static Vector4 Transform(Vector4 vec, Matrix4 mat)
00926 {
00927 Vector4 result;
00928 Transform(ref vec, ref mat, out result);
00929 return result;
00930 }
00931
00936 public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result)
00937 {
00938 result = new Vector4(
00939 vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X,
00940 vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y,
00941 vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z,
00942 vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W);
00943 }
00944
00951 public static Vector4 Transform(Vector4 vec, Quaternion quat)
00952 {
00953 Vector4 result;
00954 Transform(ref vec, ref quat, out result);
00955 return result;
00956 }
00957
00964 public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result)
00965 {
00966 Quaternion v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W), i, t;
00967 Quaternion.Invert(ref quat, out i);
00968 Quaternion.Multiply(ref quat, ref v, out t);
00969 Quaternion.Multiply(ref t, ref i, out v);
00970
00971 result = new Vector4(v.X, v.Y, v.Z, v.W);
00972 }
00973
00974 #endregion
00975
00976 #endregion
00977
00978 #region Swizzle
00979
00983 [XmlIgnore]
00984 public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
00985
00989 [XmlIgnore]
00990 public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
00991
00992 #endregion
00993
00994 #region Operators
00995
01002 public static Vector4 operator +(Vector4 left, Vector4 right)
01003 {
01004 left.X += right.X;
01005 left.Y += right.Y;
01006 left.Z += right.Z;
01007 left.W += right.W;
01008 return left;
01009 }
01010
01017 public static Vector4 operator -(Vector4 left, Vector4 right)
01018 {
01019 left.X -= right.X;
01020 left.Y -= right.Y;
01021 left.Z -= right.Z;
01022 left.W -= right.W;
01023 return left;
01024 }
01025
01031 public static Vector4 operator -(Vector4 vec)
01032 {
01033 vec.X = -vec.X;
01034 vec.Y = -vec.Y;
01035 vec.Z = -vec.Z;
01036 vec.W = -vec.W;
01037 return vec;
01038 }
01039
01046 public static Vector4 operator *(Vector4 vec, float scale)
01047 {
01048 vec.X *= scale;
01049 vec.Y *= scale;
01050 vec.Z *= scale;
01051 vec.W *= scale;
01052 return vec;
01053 }
01054
01061 public static Vector4 operator *(float scale, Vector4 vec)
01062 {
01063 vec.X *= scale;
01064 vec.Y *= scale;
01065 vec.Z *= scale;
01066 vec.W *= scale;
01067 return vec;
01068 }
01069
01076 public static Vector4 operator /(Vector4 vec, float scale)
01077 {
01078 float mult = 1.0f / scale;
01079 vec.X *= mult;
01080 vec.Y *= mult;
01081 vec.Z *= mult;
01082 vec.W *= mult;
01083 return vec;
01084 }
01085
01092 public static bool operator ==(Vector4 left, Vector4 right)
01093 {
01094 return left.Equals(right);
01095 }
01096
01103 public static bool operator !=(Vector4 left, Vector4 right)
01104 {
01105 return !left.Equals(right);
01106 }
01107
01113 [CLSCompliant(false)]
01114 unsafe public static explicit operator float*(Vector4 v)
01115 {
01116 return &v.X;
01117 }
01118
01124 public static explicit operator IntPtr(Vector4 v)
01125 {
01126 unsafe
01127 {
01128 return (IntPtr)(&v.X);
01129 }
01130 }
01131
01132 #endregion
01133
01134 #region Overrides
01135
01136 #region public override string ToString()
01137
01142 public override string ToString()
01143 {
01144 return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
01145 }
01146
01147 #endregion
01148
01149 #region public override int GetHashCode()
01150
01155 public override int GetHashCode()
01156 {
01157 return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
01158 }
01159
01160 #endregion
01161
01162 #region public override bool Equals(object obj)
01163
01169 public override bool Equals(object obj)
01170 {
01171 if (!(obj is Vector4))
01172 return false;
01173
01174 return this.Equals((Vector4)obj);
01175 }
01176
01177 #endregion
01178
01179 #endregion
01180
01181 #endregion
01182
01183 #region IEquatable<Vector4> Members
01184
01188 public bool Equals(Vector4 other)
01189 {
01190 return
01191 X == other.X &&
01192 Y == other.Y &&
01193 Z == other.Z &&
01194 W == other.W;
01195 }
01196
01197 #endregion
01198 }
01199 }