37# define VECTOR_FABS Q_fabs
39# define VECTOR_FABS fabs
42static float vrsqrt(
float number)
50 const float threehalfs = 1.5F;
54 t.i = 0x5f3759df - (t.i >> 1);
56 y = y * (threehalfs - (x2 * y * y));
68 Vector(
const vec3_t src);
69 Vector(
const float x,
const float y,
const float z);
70 explicit Vector(
const char *text);
73 operator const float *()
const;
75 float pitch(
void)
const;
76 float yaw(
void)
const;
77 float roll(
void)
const;
78 float operator[](
const int index)
const;
79 float & operator[](
const int index);
80 void copyTo(vec3_t vec)
const;
81 void setPitch(
const float x);
82 void setYaw(
const float y);
83 void setRoll(
const float z);
84 void setXYZ(
const float x,
const float y,
const float z);
85 const Vector & operator=(
const Vector &a);
86 const Vector & operator=(vec3_t a);
87 const Vector & operator=(
const char *a);
88 friend Vector operator+(
const Vector &a,
const Vector &b);
89 friend Vector operator+(vec3_t a,
const Vector &b);
90 friend Vector operator+(
const Vector &a, vec3_t b);
91 const Vector & operator+=(
const Vector &a);
92 const Vector & operator+=(vec3_t a);
93 friend Vector operator-(
const Vector &a,
const Vector &b);
94 friend Vector operator-(vec3_t a,
const Vector &b);
95 friend Vector operator-(
const Vector &a, vec3_t b);
96 const Vector & operator-=(
const Vector &a);
97 const Vector & operator-=(vec3_t a);
98 friend Vector operator*(
const Vector &a,
const float b);
99 friend Vector operator*(
const float a,
const Vector &b);
100 friend float operator*(
const Vector &a,
const Vector &b);
101 friend float operator*(vec3_t a,
const Vector &b);
102 friend float operator*(
const Vector &a, vec3_t b);
103 const Vector & operator*=(
const float a);
104 friend Vector operator/(
const Vector &a,
const float b);
105 friend Vector operator/(
const float a,
const Vector &b);
106 friend float operator/(
const Vector &a,
const Vector &b);
107 friend float operator/(vec3_t a,
const Vector &b);
108 friend float operator/(
const Vector &a, vec3_t b);
109 const Vector & operator/=(
const float a);
110 friend int operator==(
const Vector &a,
const Vector &b);
111 friend int operator==(vec3_t a,
const Vector &b);
112 friend int operator==(
const Vector &a, vec3_t b);
113 friend int operator!=(
const Vector &a,
const Vector &b);
114 friend int operator!=(vec3_t a,
const Vector &b);
115 friend int operator!=(
const Vector &a, vec3_t b);
116 int FuzzyEqual(
const Vector &b,
const float epsilon)
const;
117 int FuzzyEqual(vec3_t b,
const float epsilon)
const;
118 const Vector & CrossProduct(
const Vector a,
const Vector b);
119 const Vector & CrossProduct(vec3_t a,
const Vector b);
120 const Vector & CrossProduct(
const Vector a, vec3_t b);
121 float length(
void)
const;
122 float lengthfast(
void)
const;
123 float lengthSquared(
void)
const;
124 float lengthXY()
const;
125 float lengthXYSquared()
const;
126 float normalize(
void);
127 void normalizefast(
void);
128 void EulerNormalize(
void);
129 void EulerNormalize360(
void);
130 static Vector Clamp(
const Vector &value,
const Vector &min,
const Vector &max);
131 static void Clamp(Vector &value,
const Vector &min,
const Vector &max);
132 static Vector Cross(
const Vector &vector1,
const Vector &vector2);
133 static float Dot(
const Vector &vector1,
const Vector &vector2);
134 static float Dot(vec3_t a,
const Vector &b);
135 static float Dot(
const Vector &a, vec3_t b);
136 static float Distance(
const Vector &vector1,
const Vector &vector2);
137 static float DistanceSquared(
const Vector &vector1,
const Vector &vector2);
138 static float DistanceXY(
const Vector &vector1,
const Vector &vector2);
139 static Vector AnglesBetween(
const Vector &vector1,
const Vector &vector2);
140 static float AngleBetween(
const Vector &vector1,
const Vector &vector2);
141 static bool CloseEnough(
const Vector &vector1,
const Vector &vector2,
const float epsilon = Vector::Epsilon());
142 static bool SmallEnough(
const Vector &vector,
const float epsilon = Vector::Epsilon());
143 static float Epsilon(
void);
144 static Vector& Identity(
void);
145 Vector operator-(
void)
const;
146 friend Vector fabs(
const Vector &a);
147 float toYaw(
void)
const;
148 float toPitch(
void)
const;
149 Vector toAngles(
void)
const;
150 Vector AnglesMod(
void)
const;
151 void AngleVectors(Vector *forward, Vector *right = NULL, Vector *up = NULL)
const;
152 void AngleVectorsLeft(Vector *forward, Vector *right = NULL, Vector *up = NULL)
const;
153 friend Vector LerpVector(
const Vector &w1,
const Vector &w2,
const float t);
154 friend float MaxValue(
const Vector &a);
155 Vector GetRotatedX(
float angle)
const;
156 void RotateX(
double angle);
157 Vector GetRotatedY(
float angle)
const;
158 void RotateY(
double angle);
159 Vector GetRotatedZ(
float angle)
const;
160 void RotateZ(
float angle);
162 Vector GetPackedTo01()
const;
169inline float Vector::pitch(
void)
const
174inline float Vector::yaw(
void)
const
179inline float Vector::roll(
void)
const
184inline void Vector::setPitch(
float pitch)
189inline void Vector::setYaw(
float yaw)
194inline void Vector::setRoll(
float roll)
199inline void Vector::copyTo(vec3_t vec)
const
206inline float Vector::operator[](
const int index)
const
208 assert((index >= 0) && (index < 3));
212inline float& Vector::operator[](
const int index)
214 assert((index >= 0) && (index < 3));
218inline void Vector::setXYZ(
const float new_x,
const float new_y,
const float new_z)
225inline Vector::Vector()
231inline Vector::Vector(
const vec3_t src)
237inline Vector::Vector(
const float init_x,
const float init_y,
const float init_z)
243inline Vector::Vector(
const char *text)
249 if (text[0] ==
'"') {
250 sscanf(text,
"\"%f %f %f\"", &x, &y, &z);
252 sscanf(text,
"%f %f %f", &x, &y, &z);
257inline Vector::operator
float *(void)
262inline Vector::operator
const float *(void)
const
276inline const Vector& Vector::operator=(vec3_t a)
285inline const Vector& Vector::operator=(
const char *a)
289 sscanf(a,
"\"%f %f %f\"", &x, &y, &z);
291 sscanf(a,
"%f %f %f", &x, &y, &z);
300 return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
305 return Vector(a[0] + b.x, a[1] + b.y, a[2] + b.z);
310 return Vector(a.x + b[0], a.y + b[1], a.z + b[2]);
322inline const Vector& Vector::operator+=(vec3_t a)
333 return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
338 return Vector(a[0] - b.x, a[1] - b.y, a[2] - b.z);
343 return Vector(a.x - b[0], a.y - b[1], a.z - b[2]);
355inline const Vector& Vector::operator-=(vec3_t a)
366 return Vector(a.x * b, a.y * b, a.z * b);
376 return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
379inline float operator*(vec3_t a,
const Vector& b)
381 return (a[0] * b.x) + (a[1] * b.y) + (a[2] * b.z);
384inline float operator*(
const Vector& a, vec3_t b)
386 return (a.x * b[0]) + (a.y * b[1]) + (a.z * b[2]);
389inline const Vector& Vector::operator*=(
const float a)
400 return Vector(a.x / b, a.y / b, a.z / b);
410 return (a.x / b.x) + (a.y / b.y) + (a.z / b.z);
413inline float operator/(vec3_t a,
const Vector& b)
415 return (a[0] / b.x) + (a[1] / b.y) + (a[2] / b.z);
418inline float operator/(
const Vector& a, vec3_t b)
420 return (a.x / b[0]) + (a.y / b[1]) + (a.z / b[2]);
423inline const Vector& Vector::operator/=(
const float a)
429inline int Vector::FuzzyEqual(
const Vector& b,
const float epsilon)
const
431 return ((VECTOR_FABS(x - b.x) < epsilon) && (VECTOR_FABS(y - b.y) < epsilon) && (VECTOR_FABS(z - b.z) < epsilon));
434inline int Vector::FuzzyEqual(vec3_t b,
const float epsilon)
const
437 (VECTOR_FABS(x - b[0]) < epsilon) && (VECTOR_FABS(y - b[1]) < epsilon) && (VECTOR_FABS(z - b[2]) < epsilon)
443 return ((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
446inline int operator==(vec3_t a,
const Vector& b)
448 return ((a[0] == b.x) && (a[1] == b.y) && (a[2] == b.z));
451inline int operator==(
const Vector& a, vec3_t b)
453 return ((a.x == b[0]) && (a.y == b[1]) && (a.z == b[2]));
458 return ((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
461inline int operator!=(vec3_t a,
const Vector& b)
463 return ((a[0] != b.x) || (a[1] != b.y) || (a[2] != b.z));
466inline int operator!=(
const Vector& a, vec3_t b)
468 return ((a.x != b[0]) || (a.y != b[1]) || (a.z != b[2]));
473 x = (a.y * b.z) - (a.z * b.y);
474 y = (a.z * b.x) - (a.x * b.z);
475 z = (a.x * b.y) - (a.y * b.x);
480inline const Vector& Vector::CrossProduct(vec3_t a,
const Vector b)
482 x = (a[1] * b.z) - (a[2] * b.y);
483 y = (a[2] * b.x) - (a[0] * b.z);
484 z = (a[0] * b.y) - (a[1] * b.x);
489inline const Vector& Vector::CrossProduct(
const Vector a, vec3_t b)
491 x = (a.y * b[2]) - (a.z * b[1]);
492 y = (a.z * b[0]) - (a.x * b[2]);
493 z = (a.x * b[1]) - (a.y * b[0]);
500 Vector clamped(value);
501 Vector::Clamp(clamped, minimum, maximum);
507 for (
int i = 0; i < 3; i++) {
508 Q_clamp(value[i], minimum[i], maximum[i]);
515 (vector1.y * vector2.z) - (vector1.z * vector2.y),
516 (vector1.z * vector2.x) - (vector1.x * vector2.z),
517 (vector1.x * vector2.y) - (vector1.y * vector2.x)
523inline float Vector::Dot(
const Vector& vector1,
const Vector& vector2)
525 return vector1 * vector2;
528inline float Vector::Dot(vec3_t vector1,
const Vector& vector2)
530 return vector1 * vector2;
533inline float Vector::Dot(
const Vector& vector1, vec3_t vector2)
535 return vector1 * vector2;
548inline float Vector::lengthSquared(
void)
const
550 return (x * x) + (y * y) + (z * z);
553inline float Vector::length(
void)
const
555 return sqrt(lengthSquared());
558inline float Vector::lengthfast(
void)
const
560 return vrsqrt(lengthSquared());
574inline float Vector::lengthXY()
const
576 return sqrt((x * x) + (y * y));
590inline float Vector::lengthXYSquared()
const
592 return (x * x) + (y * y);
605inline float Vector::normalize(
void)
607 return VectorNormalize(*
this);
620inline void Vector::normalizefast(
void)
624 ilength = this->lengthfast();
644inline void Vector::EulerNormalize(
void)
646 x = AngleNormalize180(x);
647 y = AngleNormalize180(y);
648 z = AngleNormalize180(z);
664inline void Vector::EulerNormalize360(
void)
666 x = AngleNormalize360(x);
667 y = AngleNormalize360(y);
668 z = AngleNormalize360(z);
681inline float Vector::Epsilon(
void)
696inline Vector& Vector::Identity(
void)
713inline float Vector::Distance(
const Vector& vector1,
const Vector& vector2)
715 return (vector1 - vector2).length();
730inline float Vector::DistanceSquared(
const Vector& vector1,
const Vector& vector2)
732 return (vector1 - vector2).lengthSquared();
749inline float Vector::DistanceXY(
const Vector& vector1,
const Vector& vector2)
751 return (vector1 - vector2).lengthXY();
754inline Vector Vector::toAngles(
void)
const
759 if ((x == 0.0f) && (y == 0.0f)) {
767 yaw = atan2(y, x) * 180.0f / M_PI;
772 forward = (float)sqrt(x * x + y * y);
773 pitch = atan2(z, forward) * 180.0f / M_PI;
779 return Vector(-pitch, yaw, 0.0f);
797 Vector unitVector1(vector1);
798 unitVector1.normalize();
799 Vector unitVector2(vector2);
800 unitVector2.normalize();
801 Vector angles(unitVector1.toAngles() - unitVector2.toAngles());
802 angles.EulerNormalize();
820inline float Vector::AngleBetween(
const Vector& vector1,
const Vector& vector2)
822 Vector unitVector1(vector1);
823 unitVector1.normalize();
824 Vector unitVector2(vector2);
825 unitVector2.normalize();
827 return acos(Vector::Dot(unitVector1, unitVector2));
845inline bool Vector::CloseEnough(
const Vector& vector1,
const Vector& vector2,
const float epsilon)
847 return Distance(vector1, vector2) < epsilon;
864inline bool Vector::SmallEnough(
const Vector& vector,
const float epsilon)
866 return CloseEnough(vector, Vector::Identity(), epsilon);
869inline Vector Vector::operator-()
const
871 return Vector(-x, -y, -z);
876 return Vector(VECTOR_FABS(a.x), VECTOR_FABS(a.y), VECTOR_FABS(a.z));
879inline float MaxValue(
const Vector& a)
885 max = VECTOR_FABS(a.x);
886 maxy = VECTOR_FABS(a.y);
887 maxz = VECTOR_FABS(a.z);
898inline float Vector::toYaw(
void)
const
902 if ((y == 0.0f) && (x == 0.0f)) {
905 yaw = (float)((
int)(atan2(y, x) * 180.0f / M_PI));
914inline float Vector::toPitch(
void)
const
919 forward = (float)sqrt((x * x) + (y * y));
920 pitch = (float)((
int)(atan2(z, forward) * 180 / M_PI));
928inline Vector Vector::AnglesMod(
void)
const
930 return Vector(AngleMod(x), AngleMod(y), AngleMod(z));
936 static float sr, sp, sy, cr, cp, cy;
938 angle = yaw() * (M_PI * 2.0f / 360.0f);
942 angle = pitch() * (M_PI * 2.0f / 360.0f);
946 angle = roll() * (M_PI * 2.0f / 360.0f);
951 forward->setXYZ(cp * cy, cp * sy, -sp);
955 right->setXYZ((-1 * sr * sp * cy) + (-1 * cr * -sy), (-1 * sr * sp * sy) + (-1 * cr * cy), -1 * sr * cp);
959 up->setXYZ((cr * sp * cy) + (-sr * -sy), (cr * sp * sy) + (-sr * cy), cr * cp);
966 static float sr, sp, sy, cr, cp, cy;
968 angle = yaw() * (M_PI * 2 / 360);
972 angle = pitch() * (M_PI * 2 / 360);
976 angle = roll() * (M_PI * 2 / 360);
981 forward->setXYZ(cp * cy, cp * sy, -sp);
985 left->setXYZ((sr * sp * cy) + (cr * -sy), (sr * sp * sy) + (cr * cy), sr * cp);
989 up->setXYZ((cr * sp * cy) + (-sr * -sy), (cr * sp * sy) + (-sr * cy), cr * cp);
993#define LERP_DELTA 1e-6
997 float omega, cosom, sinom, scale0, scale1;
1006 if ((1.0f - cosom) > LERP_DELTA) {
1007 omega = acos(cosom);
1009 scale0 = sin((1.0f - t) * omega) / sinom;
1010 scale1 = sin(t * omega) / sinom;
1016 return ((w1 * scale0) + (w2 * scale1));
1029 Quat(
float scrMatrix[3][3]);
1030 Quat(
const float x,
const float y,
const float z,
const float w);
1033 float operator[](
const int index)
const;
1034 float & operator[](
const int index);
1035 void set(
const float x,
const float y,
const float z,
const float w);
1036 const Quat& operator=(
const Quat& a);
1037 friend Quat operator+(
const Quat& a,
const Quat& b);
1038 const Quat& operator+=(
const Quat& a);
1039 friend Quat operator-(
const Quat& a,
const Quat& b);
1040 const Quat& operator-=(
const Quat& a);
1041 friend Quat operator*(
const Quat& a,
const float b);
1042 friend Quat operator*(
const float a,
const Quat& b);
1043 const Quat& operator*=(
const float a);
1044 friend int operator==(
const Quat &a,
const Quat &b);
1045 friend int operator!=(
const Quat &a,
const Quat &b);
1046 float length(
void)
const;
1047 float lengthSquared(
void)
const;
1048 const Quat& normalize(
void);
1049 Quat operator-()
const;
1060inline Quat::Quat(
Vector Angles)
1062 EulerToQuat(Angles, this->vec4());
1065inline Quat::Quat(
float srcMatrix[3][3])
1067 MatToQuat(srcMatrix, this->vec4());
1070inline Quat::Quat(
const float init_x,
const float init_y,
const float init_z,
const float init_w)
1077inline float Quat::operator[](
const int index)
const
1079 assert((index >= 0) && (index < 4));
1083inline float& Quat::operator[](
const int index)
1085 assert((index >= 0) && (index < 4));
1089inline float *Quat::vec4(
void)
1094inline void Quat::set(
const float new_x,
const float new_y,
const float new_z,
const float new_w)
1102inline const Quat& Quat::operator=(
const Quat& a)
1114 return Quat(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
1117inline const Quat& Quat::operator+=(
const Quat& a)
1126 return Quat(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
1129inline const Quat& Quat::operator-=(
const Quat& a)
1136inline Quat operator*(
const Quat& a,
const float b)
1138 return Quat(a.x * b, a.y * b, a.z * b, a.w * b);
1141inline Quat operator*(
const float a,
const Quat& b)
1146inline const Quat& Quat::operator*=(
const float a)
1153inline int operator==(
const Quat& a,
const Quat& b)
1155 return ((a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w));
1158inline int operator!=(
const Quat& a,
const Quat& b)
1160 return (((a.x != b.x) || (a.y != b.y)) || ((a.z != b.z) && (a.w != b.w)));
1163inline float Quat::length(
void)
const
1167 length = (x * x) + (y * y) + (z * z) + (w * w);
1168 return sqrt(length);
1171inline const Quat& Quat::normalize(
void)
1173 float length, ilength;
1175 length = this->length();
1177 ilength = 1.0f / length;
1184inline Quat Quat::operator-()
const
1186 return Quat(-x, -y, -z, -w);
1189inline Vector Quat::toAngles(
void)
1194 QuatToMat(this->vec4(), m);
1195 MatrixToEulerAngles(m, angles);
1196 return Vector(angles);
1199inline Vector Vector::GetRotatedX(
float angle)
const
1205 float sinAngle = (float)sin(M_PI * angle / 180);
1206 float cosAngle = (float)cos(M_PI * angle / 180);
1208 return Vector(x, y * cosAngle - z * sinAngle, y * sinAngle + z * cosAngle);
1211inline void Vector::RotateX(
double angle)
1213 (*this) = GetRotatedX(angle);
1216inline Vector Vector::GetRotatedY(
float angle)
const
1222 float sinAngle = (float)sin(M_PI * angle / 180);
1223 float cosAngle = (float)cos(M_PI * angle / 180);
1225 return Vector(x * cosAngle + z * sinAngle, y, -x * sinAngle + z * cosAngle);
1228inline void Vector::RotateY(
double angle)
1230 (*this) = GetRotatedY(angle);
1233inline Vector Vector::GetRotatedZ(
float angle)
const
1239 float sinAngle = (float)sin(M_PI * angle / 180);
1240 float cosAngle = (float)cos(M_PI * angle / 180);
1242 return Vector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z);
1245inline void Vector::RotateZ(
float angle)
1247 (*this) = GetRotatedZ(angle);
1250inline void Vector::PackTo01()
1252 (*this) = GetPackedTo01();
1255inline Vector Vector::GetPackedTo01()
const
1261 temp = temp * 0.5f + Vector(0.5f, 0.5f, 0.5f);