#pragma once #define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) #include template // tolua_begin class Vector3 { TOLUA_TEMPLATE_BIND((T, int, float, double)) public: T x, y, z; inline Vector3(void) : x(0), y(0), z(0) {} inline Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {} // Hardcoded copy constructors (tolua++ does not support function templates .. yet) Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} // tolua_end template Vector3(const Vector3<_T> & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} template 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) { double Len = 1.0 / Length(); x = (T)(x * Len); y = (T)(y * Len); z = (T)(z * Len); } inline Vector3 NormalizeCopy(void) const { double Len = 1.0 / Length(); return Vector3( (T)(x * Len), (T)(y * Len), (T)(z * Len) ); } inline void NormalizeCopy(Vector3 & a_Rhs) const { double Len = 1.0 / Length(); a_Rhs.Set( (T)(x * Len), (T)(y * Len), (T)(z * Len) ); } inline double Length(void) const { return sqrt((double)(x * x + y * y + z * z)); } inline double SqrLength(void) const { return x * x + y * y + z * z; } inline T Dot(const Vector3 & a_Rhs) const { return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z; } inline Vector3 Cross(const Vector3 & a_Rhs) const { return Vector3( 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 & a_Rhs) const { return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z; } inline bool operator < (const Vector3 & 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; } inline void Move(const Vector3 & a_Diff) { x += a_Diff.x; y += a_Diff.y; z += a_Diff.z; } // tolua_end inline void operator += (const Vector3 & a_Rhs) { x += a_Rhs.x; y += a_Rhs.y; z += a_Rhs.z; } inline void operator -= (const Vector3 & a_Rhs) { x -= a_Rhs.x; y -= a_Rhs.y; z -= a_Rhs.z; } inline void operator *= (const Vector3 & 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 operator + (const Vector3& a_Rhs) const { return Vector3( x + a_Rhs.x, y + a_Rhs.y, z + a_Rhs.z ); } inline Vector3 operator - (const Vector3& a_Rhs) const { return Vector3( x - a_Rhs.x, y - a_Rhs.y, z - a_Rhs.z ); } inline Vector3 operator * (const Vector3& a_Rhs) const { return Vector3( x * a_Rhs.x, y * a_Rhs.y, z * a_Rhs.z ); } inline Vector3 operator * (T a_v) const { return Vector3( x * a_v, y * a_v, z * a_v ); } inline Vector3 operator / (T a_v) const { return Vector3( x / a_v, y / a_v, z / a_v ); } /** 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 */ inline double LineCoeffToXYPlane(const Vector3 & a_OtherEnd, T a_Z) const { if (abs(z - a_OtherEnd.z) < EPS) { return NO_INTERSECTION; } return (a_Z - z) / (a_OtherEnd.z - z); } /** 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 */ inline double LineCoeffToXZPlane(const Vector3 & a_OtherEnd, T a_Y) const { if (abs(y - a_OtherEnd.y) < EPS) { return NO_INTERSECTION; } return (a_Y - y) / (a_OtherEnd.y - y); } /** 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 */ inline double LineCoeffToYZPlane(const Vector3 & 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; }; // tolua_end template const double Vector3::EPS = 0.000001; template const double Vector3::NO_INTERSECTION = 1e70; // tolua_begin typedef Vector3 Vector3d; typedef Vector3 Vector3f; typedef Vector3 Vector3i; // tolua_end typedef std::list cVector3iList; typedef std::vector cVector3iArray;