summaryrefslogblamecommitdiffstats
path: root/src/Vector3.h
blob: 79c47ae77f291a2d500ec7267a57cbc651f4e7aa (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                 











                                                    
                                                  


                                                                       





                                                                                           





































































































































































                                                                                                                       




                                                                                                    









                                                                                    




                                                                                                    









                                                                                    




                                                                                                    














                                                                                            
 


            



 



























                                                

#pragma once




#include <math.h>





template <typename T>
// 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<float>  & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {}
	Vector3(const Vector3<double> & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {}
	Vector3(const Vector3<int>    & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {}


	// 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)
	{
		T Len = 1.0 / Length();

		x *= Len;
		y *= Len;
		z *= Len;
	}

	inline Vector3<T> NormalizeCopy(void) const
	{
		T Len = 1.0 / Length();

		return Vector3<T>(
			x * Len,
			y * Len,
			z * Len
		);
	}

	inline void NormalizeCopy(Vector3<T> & a_Rhs) const
	{
		T Len = 1.0 / Length();

		a_Rhs.Set(
			x * Len,
			y * Len,
			z * Len
		);
	}

	inline T Length(void) const
	{
		return sqrt(x * x + y * y + z * z);
	}

	inline T SqrLength(void) const
	{
		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;
	}

	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;
	}

	// 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
		);
	}

	/** 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<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);
	}

	/** 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<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);
	}

	/** 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<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;

};
// tolua_end





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;