2014-03-11 10:01:17 -04:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-12 10:13:03 -04:00
|
|
|
#define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC)
|
2014-03-11 10:01:17 -04:00
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
// tolua_begin
|
|
|
|
class Vector3
|
|
|
|
{
|
|
|
|
|
|
|
|
TOLUA_TEMPLATE_BIND((T, int, float, double))
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
T x, y, z;
|
|
|
|
|
|
|
|
|
2014-03-11 12:32:33 -04:00
|
|
|
inline Vector3(void) : x(0), y(0), z(0) {}
|
2014-03-11 10:01:17 -04:00
|
|
|
inline Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {}
|
|
|
|
|
|
|
|
|
2014-03-11 15:58:50 -04:00
|
|
|
// Hardcoded copy constructors (tolua++ does not support function templates .. yet)
|
2014-03-12 09:13:19 -04:00
|
|
|
Vector3(const Vector3<float> & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {}
|
|
|
|
Vector3(const Vector3<double> & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {}
|
|
|
|
Vector3(const Vector3<int> & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {}
|
2014-03-11 15:58:50 -04:00
|
|
|
|
|
|
|
|
2014-03-11 10:01:17 -04:00
|
|
|
// tolua_end
|
|
|
|
template <typename _T>
|
|
|
|
Vector3(const Vector3<_T> & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {}
|
|
|
|
|
|
|
|
template <typename _T>
|
|
|
|
Vector3(const Vector3<_T> * a_Rhs) : x(a_Rhs->x), y(a_Rhs->y), z(a_Rhs->z) {}
|
|
|
|
// tolua_begin
|
|
|
|
|
|
|
|
|
|
|
|
inline void Set(T a_x, T a_y, T a_z)
|
|
|
|
{
|
|
|
|
x = a_x;
|
|
|
|
y = a_y;
|
|
|
|
z = a_z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void Normalize(void)
|
|
|
|
{
|
2014-03-12 09:13:19 -04:00
|
|
|
double Len = 1.0 / Length();
|
2014-03-11 10:01:17 -04:00
|
|
|
|
2014-03-12 10:30:57 -04:00
|
|
|
x = (T)(x * Len);
|
|
|
|
y = (T)(y * Len);
|
|
|
|
z = (T)(z * Len);
|
2014-03-11 10:01:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> NormalizeCopy(void) const
|
|
|
|
{
|
2014-03-12 09:13:19 -04:00
|
|
|
double Len = 1.0 / Length();
|
2014-03-11 10:01:17 -04:00
|
|
|
|
|
|
|
return Vector3<T>(
|
2014-03-12 10:30:57 -04:00
|
|
|
(T)(x * Len),
|
|
|
|
(T)(y * Len),
|
|
|
|
(T)(z * Len)
|
2014-03-11 10:01:17 -04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void NormalizeCopy(Vector3<T> & a_Rhs) const
|
|
|
|
{
|
2014-03-12 09:13:19 -04:00
|
|
|
double Len = 1.0 / Length();
|
2014-03-11 10:01:17 -04:00
|
|
|
|
|
|
|
a_Rhs.Set(
|
2014-03-12 10:30:57 -04:00
|
|
|
(T)(x * Len),
|
|
|
|
(T)(y * Len),
|
|
|
|
(T)(z * Len)
|
2014-03-11 10:01:17 -04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-03-12 09:13:19 -04:00
|
|
|
inline double Length(void) const
|
2014-03-11 10:01:17 -04:00
|
|
|
{
|
2014-03-12 09:13:19 -04:00
|
|
|
return sqrt((double)(x * x + y * y + z * z));
|
2014-03-11 10:01:17 -04:00
|
|
|
}
|
|
|
|
|
2014-03-12 09:13:19 -04:00
|
|
|
inline double SqrLength(void) const
|
2014-03-11 10:01:17 -04:00
|
|
|
{
|
|
|
|
return x * x + y * y + z * z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline T Dot(const Vector3<T> & a_Rhs) const
|
|
|
|
{
|
|
|
|
return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> Cross(const Vector3<T> & a_Rhs) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
y * a_Rhs.z - z * a_Rhs.y,
|
|
|
|
z * a_Rhs.x - x * a_Rhs.z,
|
|
|
|
x * a_Rhs.y - y * a_Rhs.x
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Equals(const Vector3<T> & a_Rhs) const
|
|
|
|
{
|
|
|
|
return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z;
|
|
|
|
}
|
|
|
|
|
2014-04-15 08:15:56 -04:00
|
|
|
inline bool operator == (const Vector3<T> & a_Rhs) const
|
|
|
|
{
|
|
|
|
return Equals(a_Rhs);
|
|
|
|
}
|
|
|
|
|
2014-03-11 10:01:17 -04:00
|
|
|
inline bool operator < (const Vector3<T> & a_Rhs)
|
|
|
|
{
|
|
|
|
// return (x < a_Rhs.x) && (y < a_Rhs.y) && (z < a_Rhs.z); ?
|
|
|
|
return (x < a_Rhs.x) || (x == a_Rhs.x && y < a_Rhs.y) || (x == a_Rhs.x && y == a_Rhs.y && z < a_Rhs.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void Move(T a_X, T a_Y, T a_Z)
|
|
|
|
{
|
|
|
|
x += a_X;
|
|
|
|
y += a_Y;
|
|
|
|
z += a_Z;
|
|
|
|
}
|
|
|
|
|
2014-03-25 16:33:23 -04:00
|
|
|
inline void Move(const Vector3<T> & a_Diff)
|
|
|
|
{
|
|
|
|
x += a_Diff.x;
|
|
|
|
y += a_Diff.y;
|
|
|
|
z += a_Diff.z;
|
|
|
|
}
|
|
|
|
|
2014-03-11 10:01:17 -04:00
|
|
|
// tolua_end
|
|
|
|
|
|
|
|
inline void operator += (const Vector3<T> & a_Rhs)
|
|
|
|
{
|
|
|
|
x += a_Rhs.x;
|
|
|
|
y += a_Rhs.y;
|
|
|
|
z += a_Rhs.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void operator -= (const Vector3<T> & a_Rhs)
|
|
|
|
{
|
|
|
|
x -= a_Rhs.x;
|
|
|
|
y -= a_Rhs.y;
|
|
|
|
z -= a_Rhs.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void operator *= (const Vector3<T> & a_Rhs)
|
|
|
|
{
|
|
|
|
x *= a_Rhs.x;
|
|
|
|
y *= a_Rhs.y;
|
|
|
|
z *= a_Rhs.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void operator *= (T a_v)
|
|
|
|
{
|
|
|
|
x *= a_v;
|
|
|
|
y *= a_v;
|
|
|
|
z *= a_v;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tolua_begin
|
|
|
|
|
|
|
|
inline Vector3<T> operator + (const Vector3<T>& a_Rhs) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
x + a_Rhs.x,
|
|
|
|
y + a_Rhs.y,
|
|
|
|
z + a_Rhs.z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> operator - (const Vector3<T>& a_Rhs) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
x - a_Rhs.x,
|
|
|
|
y - a_Rhs.y,
|
|
|
|
z - a_Rhs.z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> operator * (const Vector3<T>& a_Rhs) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
x * a_Rhs.x,
|
|
|
|
y * a_Rhs.y,
|
|
|
|
z * a_Rhs.z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> operator * (T a_v) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
x * a_v,
|
|
|
|
y * a_v,
|
|
|
|
z * a_v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Vector3<T> operator / (T a_v) const
|
|
|
|
{
|
|
|
|
return Vector3<T>(
|
|
|
|
x / a_v,
|
|
|
|
y / a_v,
|
|
|
|
z / a_v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-03-11 12:10:15 -04:00
|
|
|
/** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord.
|
|
|
|
The result satisfies the following equation:
|
|
|
|
(*this + Result * (a_OtherEnd - *this)).z = a_Z
|
|
|
|
If the line is too close to being parallel, this function returns NO_INTERSECTION
|
|
|
|
*/
|
2014-03-11 10:01:17 -04:00
|
|
|
inline double LineCoeffToXYPlane(const Vector3<T> & a_OtherEnd, T a_Z) const
|
|
|
|
{
|
|
|
|
if (abs(z - a_OtherEnd.z) < EPS)
|
|
|
|
{
|
|
|
|
return NO_INTERSECTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (a_Z - z) / (a_OtherEnd.z - z);
|
|
|
|
}
|
|
|
|
|
2014-03-11 12:10:15 -04:00
|
|
|
/** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord.
|
|
|
|
The result satisfies the following equation:
|
|
|
|
(*this + Result * (a_OtherEnd - *this)).y = a_Y
|
|
|
|
If the line is too close to being parallel, this function returns NO_INTERSECTION
|
|
|
|
*/
|
2014-03-11 10:01:17 -04:00
|
|
|
inline double LineCoeffToXZPlane(const Vector3<T> & a_OtherEnd, T a_Y) const
|
|
|
|
{
|
|
|
|
if (abs(y - a_OtherEnd.y) < EPS)
|
|
|
|
{
|
|
|
|
return NO_INTERSECTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (a_Y - y) / (a_OtherEnd.y - y);
|
|
|
|
}
|
|
|
|
|
2014-03-11 12:10:15 -04:00
|
|
|
/** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord.
|
|
|
|
The result satisfies the following equation:
|
|
|
|
(*this + Result * (a_OtherEnd - *this)).x = a_X
|
|
|
|
If the line is too close to being parallel, this function returns NO_INTERSECTION
|
|
|
|
*/
|
2014-03-11 10:01:17 -04:00
|
|
|
inline double LineCoeffToYZPlane(const Vector3<T> & a_OtherEnd, T a_X) const
|
|
|
|
{
|
|
|
|
if (abs(x - a_OtherEnd.x) < EPS)
|
|
|
|
{
|
|
|
|
return NO_INTERSECTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (a_X - x) / (a_OtherEnd.x - x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** The max difference between two coords for which the coords are assumed equal. */
|
|
|
|
static const double EPS;
|
|
|
|
|
|
|
|
/** Return value of LineCoeffToPlane() if the line is parallel to the plane. */
|
|
|
|
static const double NO_INTERSECTION;
|
2014-03-11 12:10:15 -04:00
|
|
|
|
2014-03-11 10:01:17 -04:00
|
|
|
};
|
|
|
|
// tolua_end
|
|
|
|
|
2014-03-11 12:10:15 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-11 10:01:17 -04:00
|
|
|
template <typename T>
|
|
|
|
const double Vector3<T>::EPS = 0.000001;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
const double Vector3<T>::NO_INTERSECTION = 1e70;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// tolua_begin
|
|
|
|
typedef Vector3<double> Vector3d;
|
|
|
|
typedef Vector3<float> Vector3f;
|
|
|
|
typedef Vector3<int> Vector3i;
|
|
|
|
// tolua_end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::list<Vector3i> cVector3iList;
|
|
|
|
typedef std::vector<Vector3i> cVector3iArray;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|