Final draft (Vector/matrix class replacement)

Everything related to the code /
Tout ce qui touche au code
Post Reply
User avatar
Cire
Moderator
Posts: 350
Joined: Tue Oct 31, 2006 5:59 pm
Location: Somewhere on Earth

Final draft (Vector/matrix class replacement)

Post by Cire » Mon Jan 14, 2008 8:51 pm

This is my final draft, i still need to clean up some various tidbits, but as you can see I added support for arrays which should make passing to various opengl calls faster. The matrix class supports pulling vectors directly from it as well as building matrix's from vectors.

I'll try to add more detailed documention to the classes soon as I get a few mins, and to finish it off, as well as testing it within TA3D, and working out any issues that might arrise.

I must applogize for the delay within the class, but i've been so busy irl that my 'freetime' has been very limitied, but rest assured i'am still working on various things within the project and keeping any eye on things as well.

Here is the new code, ps: zuff do not install this code yet, its NOT ready.

Code: Select all

#pragma once

#include <math.h>

namespace TA3D
{
	template < class T > class TA3D_Matrix;

	/*
	** Class: TA3D_Vector
	**    This template class should allow us to handle most of our vector ops.
	**    It can handle 2d, 3d, and 4d cords.  Can construct vectors based on various
	**    other vectors, supports most vector math ops, and is templated so that
	**    it can support double, float, int, ect types.
	*/
	template < class T > class TA3D_Vector
	{
		typedef TA3D_Vector<T> MyType; /* makes function handling easier. */

	public:
		union
		{
			T m_arr[4]; // unioned with x,y,z,w : should make
			            //    passing data to OGL, or anything working
			            //    with an array easier.

			struct
			{
				T x;
				T y;
				T z;
				T w;
			};
		};

//Constructors:
		/* TA3D_Vector()
		**   Args: None
		**  Notes: Zeros everything (empty constructor)
		*/
		__forceinline TA3D_Vector() : x(0), y(0), z(0), w(0) { return; }

		/* TA3D_Vector()
		**   Args: Another vector
		**  Notes: copys other constructor data to ours, using the Set
		**         function call
		*/
		__forceinline TA3D_Vector( const MyType &Vec ) { Set( Vec ); return; }

		/* TA3D_Vector()
		**   Args: typename x and y coords (2D)
		**  Notes: zeros z and w, and copies x and y to our data.
		*/
		__forceinline TA3D_Vector( const T Axis_X, const T Axis_Y) :
				x(Axis_X), y(Axis_Y), z(0), w(0) { return; }

		/* TA3D_Vector()
		**   Args: typename x, y, and z coords (3D)
		**  Notes: zeros w, and copies x,y,z to our data.
		*/
		__forceinline TA3D_Vector( const T Axis_X, const T Axis_Y, const T Axis_Z) :
				x(Axis_X), y(Axis_Y), z(Axis_Z), w(0) { return; }

		/* TA3D_Vector()
		**   Args: typename x, y, z and w coords (4D)
		**  Notes: assigns all coords to ur data members
		*/
		__forceinline TA3D_Vector( const T Axis_X, 
			                       const T Axis_Y, 
								   const T Axis_Z,
								   const T Axis_W ) :

				x(Axis_X), y(Axis_Y), z(Axis_Z), w(Axis_W) { return; }

		/* TA3D_Vector()
		**   Args: typename all
		**  Notes: assigns all coords the passed value
		*/
		__forceinline TA3D_Vector( const T vAll ) :
				x(vAll), y(vAll), z(vAll), w(vAll) { return; }

		// Destructor:
		__forceinline ~TA3D_Vector() { return; }

// Begin Operators
		// Assingment operators
		__forceinline MyType &operator= (const MyType &rhs)
		{
			Set( rhs );
			return (*this);
		}

		// Collum access
		__forceinline T &operator[] (const int column)
		{
			return (m_arr[column]);
		}

		__forceinline T operator[] (const int column) const
		{
			return (m_arr[column]);
		}

		// Equality operator:
		__forceinline bool operator== (const MyType &rhs)
		{
			return ((x == rhs.x) && (y == rhs.y) && (z = rhs.z) && (w = rhs.w));
		}

		// InEquality operator
		__forceinline bool operator!= (const MyType &rhs)
		{
			return (!(*this == rhs));
		}

		__forceinline MyType &operator+= (MyType &rhs)
		{
			x += rhs.x;
			y += rhs.y;
			z += rhs.z;
			w += rhs.w;
			return (*this);
		}

		__forceinline MyType &operator-= (MyType &rhs)
		{
			x -= rhs.x;
			y -= rhs.y;
			z -= rhs.z;
			w -= rhs.w;

			return (*this);
		}

		__forceinline MyType &operator*= (const MyType &rhs)
		{
			x *= rhs.x;
			y *= rhs.y;
			z *= rhs.z;
			w *= rhs.w;

			return (*this);
		}

		__forceinline MyType &operator*= (const T rhs)
		{
			x *= rhs;
			y *= rhs;
			z *= rhs;
			w *= rhs;

			return (*this);
		}

		__forceinline MyType &operator/= (const MyType &rhs)
		{
			x /= rhs.x;
			y /= rhs.y;
			z /= rhs.z;
			w /= rhs.w;

			return (*this);
		}

		__forceinline MyType &operator/= (const T rhs)
		{
			x /= rhs;
			y /= rhs;
			z /= rhs;
			w /= rhs;

			return (*this);
		}

		// Non-member Addition operator:
		friend __forceinline MyType operator+ (const MyType &lhs, const MyType &rhs)
		{
			return (MyType (lhs.x + rhs.x, lhs.y + rhs.y));
		}

		// Non-member Subtraction operator:
		friend __forceinline MyType operator- (const MyType &lhs, const MyType &rhs)
		{
			return (MyType (lhs.x - rhs.x, lhs.y - rhs.y));
		}

		// Non-member Multiplication operators:
		friend __forceinline MyType operator* (const MyType &lhs, const MyType &rhs)
		{
			return (MyType (lhs.x * rhs.x, lhs.y * rhs.y));
		}

		friend __forceinline MyType operator* (const MyType &lhs, const T rhs)
		{
			return (MyType (lhs.x * rhs, lhs.y * rhs));
		}

		friend __forceinline MyType operator* (const T lhs, const MyType &rhs)
		{
			return (MyType (lhs * rhs.x, lhs * rhs.y));
		}

		// Non-member division operators:
		friend __forceinline MyType operator/ (const MyType &lhs, const MyType &rhs)
		{
			return (MyType (lhs.x / rhs.x, lhs.y / rhs.y));
		}

		friend __forceinline MyType operator/ (const MyType &lhs, const T rhs)
		{
			return (MyType (lhs.x / rhs, lhs.y / rhs));
		}
// End operators:

		// Sum2D ( X + Y )
		__forceinline T Sum2D (void)
		{
			return (x + y);
		}

		// Sum3D ( X + Y + Z )
		__forceinline T Sum3D (void)
		{
			return (Sum2D() + z);
		}

		// Sum4D ( X + Y + Z + W )
		__forceinline T Sum(void)
		{
			return (Sum3D() + w);
		}

		// Dot ops: Multiply cords and return sum;
		__forceinline T Dot2D(const MyType &rhs)
		{
			x *= rhs.x;
			y *= rhs.y;

			return Sum2D();
		}

		__forceinline T Dot3D(const MyType &rhs)
		{
			x *= rhs.x;
			y *= rhs.y;
			z *= rhs.z;

			return Sum3D();
		}

		__forceinline T Dot(const MyType &rhs)
		{
			x *= rhs.x;
			y *= rhs.y;
			z *= rhs.z;
			w *= rhs.w;

			return Sum();
		}

		// Magnitude the square root of our sum
		__forceinline T Magnitude2D (void)
		{
			return (std::sqrt( Dot2D(*this)) );
		}

		__forceinline T Magnitude3D (void)
		{
			return (std::sqrt( Dot3D(*this)) );
		}

		__forceinline T Magnitude(void)
		{
			return (std::sqrt( Dot(*this)) );
		}

		// Normalize x and y divided by magnitude
		__forceinline void Normalize2D (void)
		{
			T tmp = Magnitude2D();
			x /= tmp;
			y /= tmp;

			return;
		}

		__forceinline void Normalize3D (void)
		{
			T tmp = Magnitude3D();
			x /= tmp;
			y /= tmp;
			x /= tmp;
			return;
		}

		// cross3:
		// returns new vector where:
		//         x=(y1*z2)-(z1*y2)
		//         y=(z1*x2)-(x1*z2)
		//         z=(x1*y2)-(y1*x2)
		//         w=0
		__forceinline MyType Cross3 (MyType &rhs)
		{
			return (MyType ((m_arr[1] * rhs[2]) - (m_arr[2] * rhs[1]),
							(m_arr[2] * rhs[0]) - (m_arr[0] * rhs[2]),
							(m_arr[0] * rhs[1]) - (m_arr[1] * rhs[0])));
		}

		// Normalize x and y divided by magnitude
		__forceinline void Normalize (void)
		{
			*this /= Magnitude();
			return;
		}

		// GetProjection along axis vector.
		__forceinline MyType GetProjection( MyType &AxisVec )
		{
			return ((this->Dot(AxisVec) / AxisVec.Dot(AxisVec)) * AxisVec);
		}

		// Get projections
		__forceinline void GetProjections (MyType &AxisVec, MyType &OutX, MyType &OutY)
		{
			OutX = this->GetProjection (AxisVec);
			OutY = (*this) - OutX;
			return;
		}


		// Sin result based on another vector
		__forceinline MyType sin (const MyType &Vec)
		{
			MyType Return;

			Return[0] = ::sin ( Vec[0] );
			Return[1] = ::sin ( Vec[1] );
			Return[2] = ::sin ( Vec[2] );
			Return[3] = ::sin ( Vec[3] );

			return (Return);
		}

		// sin result of our vector
		__forceinline void sin (void)
		{
			m_arr[0] = ::sin( m_arr[0] );
			m_arr[1] = ::sin( m_arr[1] );
			m_arr[2] = ::sin( m_arr[2] );
			m_arr[3] = ::sin( m_arr[3] );

			return;       
		}

		// cos
		__forceinline MyType cos (const MyType &Vec)
		{
			MyType Return;

			Return[0] = ::cos( Vec[0] );
			Return[1] = ::cos( Vec[1] );
			Return[2] = ::cos( Vec[2] );
			Return[3] = ::cos( Vec[3] );

			return (Return);
		}

		__forceinline void cos (void)
		{
			m_arr[0] = ::cos( m_arr[0] );
			m_arr[1] = ::cos( m_arr[1] );
			m_arr[2] = ::cos( m_arr[2] );
			m_arr[3] = ::cos( m_arr[3] );
			return;       
		}

		// tan
		__forceinline MyType tan (const MyType &Vec)
		{
			MyType Return;

			Return[0] = ::tan( Vec[0] );
			Return[1] = ::tan( Vec[1] );
			Return[2] = ::tan( Vec[2] );
			Return[3] = ::tan( Vec[3] );

			return (Return);
		}

		__forceinline void tan (void)
		{
			m_arr[0] = ::tan( m_arr[0] );
			m_arr[1] = ::tan( m_arr[1] );
			m_arr[2] = ::tan( m_arr[2] );
			m_arr[3] = ::tan( m_arr[3] );

			return;       
		}

		// square root
		__forceinline MyType sqrt (const MyType &Vec)
		{
			MyType Return;

			Return[0] = ::sqrt( Vec[0] );
			Return[1] = ::sqrt( Vec[1] );
			Return[2] = ::sqrt( Vec[2] );
			Return[3] = ::sqrt( Vec[3] );


			return (Return);
		}

		__forceinline void sqrt (void)
		{
			m_arr[0] = ::sqrt( m_arr[0] );
			m_arr[1] = ::sqrt( m_arr[1] );
			m_arr[2] = ::sqrt( m_arr[2] );
			m_arr[3] = ::sqrt( m_arr[3] );

			return;       
		}

		// Note: Set does not 'Zero' non given parms.
		__forceinline void Set( const MyType &Vec )
		{
			m_arr[0] = Vec[0];
			m_arr[1] = Vec[1];
			m_arr[2] = Vec[2];
			m_arr[3] = Vec[3];

			return;
		}

		__forceinline void Set( const T Axis_X, const T Axis_Y )
		{
			m_arr[0] = Axis_X;
			m_arr[1] = Axis_Y;
			return;
		}

		__forceinline void Set( const T Axis_X, const T Axis_Y,  const T Axis_Z )
		{
			m_arr[0] = Axis_X;
			m_arr[1] = Axis_Y;
			m_arr[2] = Axis_Z;
			return;
		}
	}; // template class<T> class TA3D_Vector;


	template < class T > class TA3D_Matrix
	{
	public:
		typedef TA3D_Matrix<T> MyType;
		typedef TA3D_Vector<T> VectorType;

		T Rows[4][4];

		__forceinline TA3D_Matrix()
		{
			return;
		}

		__forceinline ~TA3D_Matrix()
		{
			return;
		}

		__forceinline TA3D_Matrix( MyType &NewMatrix )
		{
			Set (NewMatrix);
			return;
		}

		__forceinline TA3D_Matrix( T CAll )
		{
			Set (CAll);
			return;
		}

		__forceinline TA3D_Matrix( T _11, T _12, T _13, T _14,
								    T _21, T _22, T _23, T _24,
								    T _31, T _32, T _33, T _34,
								    T _41, T _42, T _43, T _44)
		{
			Set (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44);
			return;
		}

		__forceinline void Set (MyType &NewMatrix)
		{
			Set( NewMatrix[0][0], NewMatrix[0][1], NewMatrix[0][2], NewMatrix[0][3],
				 NewMatrix[1][0], NewMatrix[1][1], NewMatrix[1][2], NewMatrix[1][3],
				 NewMatrix[2][0], NewMatrix[2][1], NewMatrix[2][2], NewMatrix[2][3],
				 NewMatrix[3][0], NewMatrix[3][1], NewMatrix[3][2], NewMatrix[3][3] );

			return;
		}

		__forceinline void Set( T CAll )
		{
			Set(CAll, CAll, CAll, CAll,
				CAll, CAll, CAll, CAll,
				CAll, CAll, CAll, CAll,
				CAll, CAll, CAll, CAll );
			return;
		}

		__forceinline void Set ( T _11, T _12, T _13, T _14,
								 T _21, T _22, T _23, T _24,
								 T _31, T _32, T _33, T _34,
								 T _41, T _42, T _43, T _44)
		{
			Rows[0][0] =_11; Rows[0][1] = _12; Rows[0][2] =_13 Rows[0][3] = _14;
			Rows[1][0] =_21; Rows[1][1] = _22; Rows[1][2] =_23 Rows[1][3] = _24;
			Rows[2][0] =_31; Rows[2][1] = _32; Rows[2][2] =_33 Rows[2][3] = _34;
			Rows[3][0] =_41; Rows[3][1] = _42; Rows[3][2] =_43 Rows[3][3] = _44;
			return;
		}

		// More complex Set* functions.
		__forceinline void SetIdentity (void)
		{
			Set( 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);

			return;
		}

		__forceinline void SetTranslation ( T Tx, T Ty, T Tz )
		{
			Set( 1,0,0,0,0,1,0,0,0,0,1,0,Tx,Ty,Tz,1);

			return;
		}

		__forceinline void SetScalingUniform( T S )
		{
			Set( S,0,0,0,0,S,0,0,0,0,S,0,0,0,0,1);
			return;
		}

		__forceinline void SetScalingXYZ (T Sx, T Sy, T Sz)
		{
			Set( Sx,0,0,0,0,Sy,0,0,0,0,Sz,0,0,0,0,1);
			return;
		}

		// Angles are measured clockwise as you look along the axis of rotation
		__forceinline void SetRotationX (T Rx)
		{
			ScalarType C;
			ScalarType S;

			C = cos (Rx);
			S = sin (Rx);

			Set( 1,0,0,0,0,C,S,0,0,-S,C,0,0,0,0,1);

			return;
		}

		__forceinline void SetRotationY (T Ry)
		{
			ScalarType C;
			ScalarType S;

			C = cos (Ry);
			S = sin (Ry);

			Set( C,0,-S,0, 0,1,0,0, S,0,C,0, 0,0,0,1);

			return;
		}

		__forceinline void SetRotationZ (T Rz)
		{
			ScalarType C;
			ScalarType S;

			C = cos (Rz);
			S = sin (Rz);

			Set( C,S,0,0, -S,C,0,0, 0,0,1,0, 0,0,0,1);

			return;
		}

		// Give number from 0 to 3

		__forceinline TA3D_Vector<T> GetColumn (int Column)
		{
			return TA3D_Vector<T> ( 
				Rows[0][Column], 
				Rows[1][Column],
				Rows[2][Column],
				Rows[3][Column] );
		}

		__forceinline void GetColumn (TA3D_Vector<T> &Out, int Column)
		{
			Out.Set (Rows[0][Column], Rows[1][Column], Rows[2][Column], Rows[3][Column]);
			return;
		}

		__forceinline TA3D_Vector<T> operator[] (int indice)
		{
			return TA3D_Vector<T> ( 
				Rows[indice][0], 
				Rows[indice][1],
				Rows[indice][2],
				Rows[indice][3] );
		}

		__forceinline TA3D_Vector<T> operator[] (int indice) const
		{
			return TA3D_Vector<T> ( 
				Rows[indice][0], 
				Rows[indice][1],
				Rows[indice][2],
				Rows[indice][3] );
		}

		__forceinline MyType GetTranspose (void)
		{
			return (MyType ( Rows[0][0], Rows[1][0], Rows[2][0], Rows[3][0],
							 Rows[0][1], Rows[1][1], Rows[2][1], Rows[3][1], 
							 Rows[0][2], Rows[1][2], Rows[2][2], Rows[3][2], 
							 Rows[0][3], Rows[1][3], Rows[2][3], Rows[3][3] ));
		}

		__forceinline void Transpose (void)
		{
			*this = GetTranspose ();
			return;
		}

		__forceinline MyType &operator= (MyType &rhs)
		{
			Set( rhs );
			return (*this);
		}

		__forceinline MyType &operator= (T rhs)
		{
			Set( rhs );
			return (*this);
		}

		__forceinline bool operator== (MyType &rhs)
		{
			bool r;

			for( int i = 0; i < 4; i++ )
			{
				r = ( (Rows[0][i] == rhs[0][i]) && 
					  (Rows[1][i] == rhs[1][i]) && 
					  (Rows[2][i] == rhs[2][i]) && 
					  (Rows[3][i] == rhs[3][i]) );
				if( r == false ) break;
			}

			return r;
		}

		__forceinline bool operator!= (MyType &rhs)
		{
			return (!(*this == rhs));
		}

		// Matrix addition
		friend __forceinline MyType operator+ (MyType &lhs, MyType &rhs)
		{
			return (MyType( 
				lhs[0][0] + rhs[0][0], lhs[0][1] + rhs[0][1], lhs[0][2] + rhs[0][2], lhs[0][3] + rhs[0][3],
				lhs[1][0] + rhs[1][0], lhs[1][1] + rhs[1][1], lhs[1][2] + rhs[1][2], lhs[1][3] + rhs[1][3],
				lhs[2][0] + rhs[2][0], lhs[2][1] + rhs[2][1], lhs[2][2] + rhs[2][2], lhs[2][3] + rhs[2][3],
				lhs[3][0] + rhs[3][0], lhs[3][1] + rhs[3][1], lhs[3][2] + rhs[3][2], lhs[3][3] + rhs[3][3] 
			) );
		}

		__forceinline MyType &operator+= (MyType &rhs)
		{
			for( int i = 0; i < 4; i++ )
			{
			    Rows[i][0] += rhs[i][0]; 
			    Rows[i][1] += rhs[i][1];
			    Rows[i][2] += rhs[i][2]; 
			    Rows[i][3] += rhs[i][3];
			}

			return (*this);
		}

		// Matrix subraction
		friend __forceinline MyType operator- (MyType &lhs, MyType &rhs)
		{
			return (MyType( 
				lhs[0][0] - rhs[0][0], lhs[0][1] - rhs[0][1], lhs[0][2] - rhs[0][2], lhs[0][3] - rhs[0][3],
				lhs[1][0] - rhs[1][0], lhs[1][1] - rhs[1][1], lhs[1][2] - rhs[1][2], lhs[1][3] - rhs[1][3],
				lhs[2][0] - rhs[2][0], lhs[2][1] - rhs[2][1], lhs[2][2] - rhs[2][2], lhs[2][3] - rhs[2][3],
				lhs[3][0] - rhs[3][0], lhs[3][1] - rhs[3][1], lhs[3][2] - rhs[3][2], lhs[3][3] - rhs[3][3] 
			) );
		}

		__forceinline MyType &operator-= (MyType &rhs)
		{
			for( int i = 0; i < 4; i++ )
			{
			    Rows[i][0] -= rhs[i][0]; 
			    Rows[i][1] -= rhs[i][1];
			    Rows[i][2] -= rhs[i][2]; 
			    Rows[i][3] -= rhs[i][3];
			}

			return (*this);
		}

		// Matrix multiplication
		friend __forceinline MyType operator* (MyType &lhs, T rhs)
		{
			return (MyType( 
				lhs[0][0] * rhs, lhs[0][1] * rhs, lhs[0][2] * rhs, lhs[0][3] * rhs,
				lhs[1][0] * rhs, lhs[1][1] * rhs, lhs[1][2] * rhs, lhs[1][3] * rhs,
				lhs[2][0] * rhs, lhs[2][1] * rhs, lhs[2][2] * rhs, lhs[2][3] * rhs,
				lhs[3][0] * rhs, lhs[3][1] * rhs, lhs[3][2] * rhs, lhs[3][3] * rhs 
			) );
		}

		friend __forceinline MyType operator* (T lhs, MyType &rhs)
		{
			return (MyType( 
				rhs[0][0] * lhs, rhs[0][1] * lhs, rhs[0][2] * lhs, rhs[0][3] * lhs,
				rhs[1][0] * lhs, rhs[1][1] * lhs, rhs[1][2] * lhs, rhs[1][3] * lhs,
				rhs[2][0] * lhs, rhs[2][1] * lhs, rhs[2][2] * lhs, rhs[2][3] * lhs,
				rhs[3][0] * lhs, rhs[3][1] * lhs, rhs[3][2] * lhs, rhs[3][3] * lhs 
			) );
		}

		__forceinline MyType &operator*= (T rhs)
		{
			for( int i = 0; i < 4; i++ )
			{
			    Rows[i][0] *= rhs[i][0]; 
			    Rows[i][1] *= rhs[i][1];
			    Rows[i][2] *= rhs[i][2]; 
			    Rows[i][3] *= rhs[i][3];
			}

			return (*this);

		}

		friend __forceinline MyType operator* (MyType &lhs, MyType &rhs)
		{
			VectorType C1, C2, C3, C4;
			VectorType O1, O2, O3, O4;

			rhs.GetColumn (C1, 0);
			rhs.GetColumn (C2, 1);
			rhs.GetColumn (C3, 2);
			rhs.GetColumn (C4, 3);

			O1 = VectorType
				 (
					 lhs[0].Dot (C1),
					 lhs[0].Dot (C2),
					 lhs[0].Dot (C3),
					 lhs[0].Dot (C4)
				 );

			O2 = VectorType
				 (
					 lhs[1].Dot (C1),
					 lhs[1].Dot (C2),
					 lhs[1].Dot (C3),
					 lhs[1].Dot (C4)
				 );

			O3 = VectorType
				 (
					 lhs[2].Dot (C1),
					 lhs[2].Dot (C2),
					 lhs[2].Dot (C3),
					 lhs[2].Dot (C4)
				 );

			O4 = VectorType
				 (
					 lhs[3].Dot (C1),
					 lhs[3].Dot (C2),
					 lhs[3].Dot (C3),
					 lhs[3].Dot (C4)
				 );

			return ( MyType( O1[0], O1[1], O1[2], O1[3],
							 O2[0], O2[1], O2[2], O2[3], 
							 O3[0], O3[1], O3[2], O3[3], 
							 O4[0], O4[1], O4[2], O4[3] ) );
		}

		__forceinline MyType &operator*= (MyType &rhs)
		{
			VectorType C1, C2, C3, C4;
			VectorType R1, R2, R3, R4;

			R1 = Rows[0];
			R2 = Rows[1];
			R3 = Rows[2];
			R4 = Rows[3];

			C1.Set (rhs[0][0], rhs[1][0], rhs[2][0], rhs[3][0]);
			C2.Set (rhs[0][1], rhs[1][1], rhs[2][1], rhs[3][1]);
			C3.Set (rhs[0][2], rhs[1][2], rhs[2][2], rhs[3][2]);
			C4.Set (rhs[0][3], rhs[1][3], rhs[2][3], rhs[3][3]);

			Rows[0].Set (R1.Dot (C1), R1.Dot (C2), R1.Dot (C3), R1.Dot (C4));
			Rows[1].Set (R2.Dot (C1), R2.Dot (C2), R2.Dot (C3), R2.Dot (C4));
			Rows[2].Set (R3.Dot (C1), R3.Dot (C2), R3.Dot (C3), R3.Dot (C4));
			Rows[3].Set (R4.Dot (C1), R4.Dot (C2), R4.Dot (C3), R4.Dot (C4));

			return (*this);
		}

		// Matrix * Vector implies Matrix * COLUMN vector, in this case
		friend __forceinline VectorType operator* (MyType &lhs, VectorType &rhs)
		{
			return (VectorType (lhs[0].Dot (rhs), 
								lhs[1].Dot (rhs), 
								lhs[2].Dot (rhs), 
								lhs[3].Dot (rhs)));
		}

		__forceinline void Transform (VectorType &x, VectorType &b)
		{
			b.Set (Rows[0].Dot (x), Rows[1].Dot (x), Rows[2].Dot (x), Rows[3].Dot (x));
			return;
		}

		// Note that we can not do a *= operator for this.

		friend __forceinline MyType operator/ (MyType &lhs, T rhs)
		{
			return (MyType (Rows[0] / rhs, Rows[0] / rhs, Rows[1] / rhs, Rows[2] / rhs));
		}

		__forceinline MyType &operator/= (T rhs)
		{
			Rows[0] /= rhs;
			Rows[1] /= rhs;
			Rows[2] /= rhs;
			Rows[3] /= rhs;
			return (*this);
		}

		// Returns the summation of all matrix elements
		__forceinline T Sum (void)
		{
			//return ((Rows[0] + Rows[1] + Rows[2] + Rows[3]).Sum());
			return (Rows[0].Sum() + Rows[1].Sum() + Rows[2].Sum() + Rows[3].Sum());
		}

		// Linear algebra row operations

		// Swaps two rows
		__forceinline void InterchangeRows (int RowA, int RowB)
		{
			::Swap (Rows[RowA], Rows[RowB]);
			return;
		}

		// RowA = RowA + (Scalar * RowB)
		__forceinline void ReplaceRow (int RowA, int RowB, T Scalar)
		{
			Rows[RowA] += Rows[RowB] * Scalar;
			return;
		}

		// Row = Row * Scalar;
		__forceinline void ScaleRow (int Row, T Scalar)
		{
			Rows[Row] *= Scalar;
			return;
		}
	}; // template <class SType > class TA3D_Matrix4


	typedef TA3D_Vector<float>		POINT2D;
	typedef TA3D_Vector<float>		POINT3D;
	typedef TA3D_Vector<float>		POINT4D;

	typedef TA3D_Vector<float>		VECTOR;
	typedef POINT3D					POINTF; 
    
	typedef TA3D_Vector<float>		VECTOR3D;

	typedef TA3D_Matrix<float>     MATRIX_4x4;
} // namespace TA3D
Females: impossible to live with, most powerful money reducing agent known to man, 99% of the time they drive us insane; yet somehow we desire to have as many as we can.

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Mon Jan 14, 2008 10:12 pm

hmm, good I'll test it :D
=>;-D Penguin Powered

User avatar
AF
Administrateur - Site Admin
Posts: 139
Joined: Thu Dec 28, 2006 8:19 pm
Location: NW UK
Contact:

Post by AF » Mon Jan 14, 2008 10:49 pm

With regards to comments it may be better to use the javadoc/doxygen style notation e.g.:

Code: Select all

/*
 * random function
 * 
 * @param x A random x variable
 * @param y A random y variable
 *
 * @return a bannana variable
 */
Any thoughts on this?

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Mon Jan 14, 2008 10:56 pm

I think it can help indeed. We should start adding those comments ... it's a lots of painful work but if we add them each time we edit a function, it'll be done before we even notice it (a bit like comments translation ... but some are still in French :? )
=>;-D Penguin Powered

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Mon Jan 14, 2008 11:14 pm

hm, after some tests, compatibility with current classes is far from perfect, still lots of work to do. I'll wait until you have the code ready, then we'll work on compatibility :wink:
=>;-D Penguin Powered

User avatar
Cire
Moderator
Posts: 350
Joined: Tue Oct 31, 2006 5:59 pm
Location: Somewhere on Earth

Post by Cire » Tue Jan 15, 2008 6:12 pm

Majority of issues arrising with it are missing operators, that i havn't implemented yet because i couln't grasp what you were doing...for example....

in 3do.h theres a function that starts like...

Code: Select all

	float compute_size_sq(POINTF center)		// Carré de la taille(on fera une racine après)
	{
		float size=0.0f;
		for(int i=0;i<nb_vtx;i++) {
			float dist=((VECTOR)(center>>points[i])).Sq();
			if(size<dist)
				size=dist;
			}
the odd line is...

Code: Select all

float dist=((VECTOR)(center>>points[i])).Sq();
Now the wird thing here is that it looks like its constructing a 3d vector from 2 points that are 'shifted' based on the second point, and then collecting the squreroot from that vector. But if i look at the operator for shifting passing it 2 points and exectping the code looks like...

Code: Select all

inline VECTOR2D operator>>(const POINT2D &a,const POINT2D &b)        // 2D
{
   VECTOR2D ab;
   ab.x=b.x-a.x;
   ab.y=b.y-a.y;
   return ab;
}
There is acutally no shifting operation taking place at all in fact, it looks like a simple subtraction operation taking place, and this code reduancy taking place.....

Am I missing something here or...

++Cire.
Females: impossible to live with, most powerful money reducing agent known to man, 99% of the time they drive us insane; yet somehow we desire to have as many as we can.

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Tue Jan 15, 2008 6:54 pm

No, it's correct the >> operator creates a VECTOR from 2 POINTF
A>>B is the VECTOR from A to B

a function returning the squared distance between A and B would be more appropriate here, but for now lets start with compatibility we'll optimize this when we'll get it working.
=>;-D Penguin Powered

User avatar
AF
Administrateur - Site Admin
Posts: 139
Joined: Thu Dec 28, 2006 8:19 pm
Location: NW UK
Contact:

Post by AF » Wed Jan 16, 2008 9:57 am

So basically the something along the lines of a VECTOR POINTF::distance2D(POINTF p) method??

Is it just me or do is there somewhat of a redundancy here? Surely POINT and VECTOR are the same thing but using different concepts?

From what I can tell people usually use the same class for vectors and co-ordinates, for example the spring class float3, after all a single point can easily be interpreted as a vector and vice versa.

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Wed Jan 16, 2008 1:05 pm

The only difference between VECTOR and POINTF is the way matrix calculations are done:
_ VECTOR * MATRIX_4x4 only uses the rotation part of the matrix
_ POINTF * MATRIX_4x4 uses all the matrix

basically you can use VECTOR for normals and do all the matrix math you want you'll get the result you expect, and use POINTF for object geometry to get correct world transformation.

I did this because I didn't want to use a 4D Vector (x,y,z,w) with the w coordinate telling if it's a vector or a point.
=>;-D Penguin Powered

User avatar
Cire
Moderator
Posts: 350
Joined: Tue Oct 31, 2006 5:59 pm
Location: Somewhere on Earth

Post by Cire » Fri Jan 18, 2008 6:56 pm

So your using the shift operator more or less as a common method of calculating a vector, based on a mix of another vector or matrix or point?

I think it would be a smarter move here to add a function, that can return either a float, or vector, and do the same calculations in class, that way you reduce overhead of accessing one of the classes members, perhaps passing a second 'vector' as a optional parm to store the resulting vector in. This way you can do something like...

float f;
vector v;

v = vec2.somefunction( vec3 );
or
f = vec2.somefunction( vec3 );

just tring to think outside the box so we can speed things up on key classes, remember that vectors are just about the most commonly used class when you boil all things down.

Applogises for being away for the last week, damn real life business.

++Cire.
Females: impossible to live with, most powerful money reducing agent known to man, 99% of the time they drive us insane; yet somehow we desire to have as many as we can.

User avatar
zuzuf
Administrateur - Site Admin
Posts: 3281
Joined: Mon Oct 30, 2006 8:49 pm
Location: Toulouse, France
Contact:

Post by zuzuf » Fri Jan 18, 2008 7:29 pm

So your using the shift operator more or less as a common method of calculating a vector, based on a mix of another vector or matrix or point?
That's it :)

I agree with the solution you propose. I noticed that the most used functions are related to the VECTOR class. If I run a profiler some very basic functions can easily get more than half CPU time !! (ok running without compiler optimizations and with debug level set to maximum in order to get statistics on all the functions & symbols).

I suggest we start with a compatibility layer just to make sure it works, then replace those slow operators with class functions and get rid of POINTF objects which can be safely replaced with vectors. Then we can optimize some functions like calls to make a rotation matrix because we often need to compute that kind of matrix from 3 euler angles, and doing:
M_x_axis * M_y_axis * M_z_axis isn't good at all.
=>;-D Penguin Powered

Post Reply

Who is online

Users browsing this forum: No registered users and 31 guests