/*************************************************************************/ /* File : VxMatrix.h */ /* Author : Romain SIDIDRIS */ /* */ /* Virtools SDK */ /* Copyright (c) Virtools 2000, All Rights Reserved. */ /*************************************************************************/ #ifndef VXMATRIX_H #define VXMATRIX_H #ifdef DOCJET_DUMMY // Prevent doc processing #else #ifdef PSP #define ALIGNED16 __attribute__((aligned(16))) #else #define ALIGNED16 #endif #endif #include "VxQuaternion.h" class VxMatrix; VX_EXPORT void Vx3DMatrixIdentity (VxMatrix& Mat); VX_EXPORT void Vx3DMultiplyMatrixVector(VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector); VX_EXPORT void Vx3DMultiplyMatrixVectorMany(VxVector *ResultVectors,const VxMatrix& Mat,const VxVector *Vectors,int count,int stride); VX_EXPORT void Vx3DMultiplyMatrixVector4(VxVector4 *ResultVector,const VxMatrix& Mat,const VxVector4 *Vector); VX_EXPORT void Vx3DMultiplyMatrixVector4(VxVector4 *ResultVector,const VxMatrix& Mat,const VxVector *Vector); // w=1 VX_EXPORT void Vx3DRotateVector (VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector); VX_EXPORT void Vx3DRotateVectorMany (VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector,int count,int stride); VX_EXPORT void Vx3DMultiplyMatrix (VxMatrix& ResultMat,const VxMatrix& MatA,const VxMatrix& MatB); VX_EXPORT void Vx3DMultiplyMatrix4 (VxMatrix& ResultMat,const VxMatrix& MatA,const VxMatrix& MatB); VX_EXPORT void Vx3DInverseMatrix (VxMatrix& InverseMat,const VxMatrix& Mat); VX_EXPORT void Vx3DInverseMatrix44 (VxMatrix& InverseMat,const VxMatrix& Mat); VX_EXPORT float Vx3DMatrixDeterminant (const VxMatrix& Mat); VX_EXPORT void Vx3DMatrixFromRotation (VxMatrix& ResultMat,const VxVector& Vector, float Angle); VX_EXPORT void Vx3DMatrixFromRotationAndOrigin(VxMatrix& ResultMat,const VxVector& Vector,const VxVector& Origin, float Angle); VX_EXPORT void Vx3DMatrixFromEulerAngles(VxMatrix& Mat,float eax,float eay,float eaz); VX_EXPORT void Vx3DMatrixToEulerAngles (const VxMatrix& Mat,float *eax,float* eay,float* eaz); VX_EXPORT void Vx3DInterpolateMatrix(float step,VxMatrix& Res,const VxMatrix& A, const VxMatrix& B); VX_EXPORT void Vx3DInterpolateMatrixNoScale(float step,VxMatrix& Res,const VxMatrix& A, const VxMatrix& B); VX_EXPORT void Vx3DMultiplyMatrixVectorStrided(VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count); VX_EXPORT void Vx3DMultiplyMatrixVector4Strided(VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count); VX_EXPORT void Vx3DRotateVectorStrided (VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count); VX_EXPORT void Vx3DTransposeMatrix(VxMatrix& Result,const VxMatrix& A); VX_EXPORT void Vx3DDecomposeMatrix(const VxMatrix& A, VxQuaternion &Quat,VxVector &Pos,VxVector &Scale); VX_EXPORT float Vx3DDecomposeMatrixTotal(const VxMatrix& A, VxQuaternion &Quat,VxVector &Pos,VxVector &Scale,VxQuaternion &URot); VX_EXPORT float Vx3DDecomposeMatrixTotalPtr(const VxMatrix& A, VxQuaternion* Quat,VxVector* Pos,VxVector* Scale,VxQuaternion* URot); VX_EXPORT void VxInverseProject(const VxMatrix& iProjection, const Vx2DVector& i2D, const float iZ, VxVector* o3D); /***************************************** {filename:VxMatrix} ******************************************/ class VxMatrix { public: VxMatrix() {} #ifdef PSP VxMatrix(const float m[4][4]); VxMatrix(const VxMatrix& src); VxMatrix& operator= (const VxMatrix& src); #else VxMatrix(float m[4][4]) { m_Data[0][0] = m[0][0]; m_Data[0][1] = m[0][1]; m_Data[0][2] = m[0][2]; m_Data[0][3] = m[0][3]; m_Data[1][0] = m[1][0]; m_Data[1][1] = m[1][1]; m_Data[1][2] = m[1][2]; m_Data[1][3] = m[1][3]; m_Data[2][0] = m[2][0]; m_Data[2][1] = m[2][1]; m_Data[2][2] = m[2][2]; m_Data[2][3] = m[2][3]; m_Data[3][0] = m[3][0]; m_Data[3][1] = m[3][1]; m_Data[3][2] = m[3][2]; m_Data[3][3] = m[3][3]; } #endif #ifdef PSP const static VxMatrix& Identity(){ extern VxMatrix g_IdentityMatrix; return g_IdentityMatrix; } #else VX_EXPORT const static VxMatrix& Identity(); #endif VX_EXPORT XBOOL Compare(const VxMatrix &mat) const; // Matrix construction void Clear() {memset(m_Data,0,sizeof(VxMatrix));} void SetIdentity(); void Orthographic(float Zoom,float Aspect,float Near_plane,float Far_plane); void Perspective(float Fov,float Aspect,float Near_plane,float Far_plane); void OrthographicRect(float Left,float Right,float Top,float Bottom,float Near_plane,float Far_plane); void PerspectiveRect(float Left,float Right,float Top,float Bottom,float Near_plane,float Far_plane); VX_EXPORT void RecomposeMatrixEx(const VxVector *Pos,const VxVector *Scale,const VxQuaternion *Quat, const VxQuaternion *Shear, float Sign); VX_EXPORT void RecomposeMatrix(const VxVector *Pos, const VxVector *Scale, const VxQuaternion *Quat); // operators const VxVector4& operator[] (int i) const {return (const VxVector4&)(*(VxVector4*)(m_Data+i));} VxVector4& operator[] (int i){return (VxVector4&)(*(VxVector4*)(m_Data+i));} operator const void* () const {return &m_Data[0];} operator void* () {return &m_Data[0];} BOOL operator == (const VxMatrix& mat) const {return Compare(mat);} BOOL operator != (const VxMatrix& mat) const {return !Compare(mat);} VxMatrix& operator *= (const VxMatrix& mat) { VxMatrix tmp = *this; Vx3DMultiplyMatrix(*this,tmp,mat); return *this; } VxMatrix operator * (const VxMatrix& iMat) const { VxMatrix temp; Vx3DMultiplyMatrix(temp,*this,iMat); return temp; } friend VxVector operator * (const VxMatrix& m,const VxVector& v); friend VxVector4 operator * (const VxMatrix& m,const VxVector4& v); friend VxVector operator * (const VxVector& v,const VxMatrix& m); friend VxVector4 operator * (const VxVector4& v,const VxMatrix& m); protected: float m_Data[4][4]; } ALIGNED16; #ifdef PSP // Use of VFPU on the PSP. #include "VxMatrixPSP.h" #else ////////////////////////////////////////////////////////////////////// ////////////////////////// Matrix operations ///////////////////////// ////////////////////////////////////////////////////////////////////// inline void VxMatrix::SetIdentity() { m_Data[0][1] = m_Data[0][2] = m_Data[0][3] = m_Data[1][0] = m_Data[1][2] = m_Data[1][3] = m_Data[2][0] = m_Data[2][1] = m_Data[2][3] = m_Data[3][0] = m_Data[3][1] = m_Data[3][2] = 0; m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f; } inline VxVector operator * (const VxVector& v,const VxMatrix& m) { return VxVector(m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z+m[3][0], m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z+m[3][1], m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z+m[3][2]); } inline VxVector operator * (const VxMatrix& m,const VxVector& v) { return VxVector(m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z+m[3][0], m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z+m[3][1], m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z+m[3][2]); } inline VxVector4 operator * (const VxMatrix& m,const VxVector4& v) { return VxVector4(m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z+ m[3][0], m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z+ m[3][1], m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z+ m[3][2], m[0][3]*v.x + m[1][3]*v.y + m[2][3]*v.z+ m[3][3]); } inline VxVector4 operator * (const VxVector4& v,const VxMatrix& m) { return VxVector4(m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z+ m[3][0], m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z+ m[3][1], m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z+ m[3][2], m[0][3]*v.x + m[1][3]*v.y + m[2][3]*v.z+ m[3][3]); } /************************************************ Summary: Constructs a perspective projection matrix. Input Arguments: Fov: Field of View. Aspect: Aspect ratio (Width/height) Near_plane: Distance of the near clipping plane. Far_plane: Distance of the far clipping plane. Output Arguments: Mat: Matrix to set to the perspective projection. Remarks: Sets Mat to A =Cos(Fov/2)/Sin(Fov/2) F = Far_plane N = Near_plane [ A 0 0 0] [ 0 A*Aspect 0 0] MAT= [ 0 0 F/F-N 1] [ 0 0 -F.N/F-N 0] See also: PerspectiveRect,Orthographic,Identity,OrthographicRect ************************************************/ inline void VxMatrix::Perspective(float Fov,float Aspect,float Near_plane,float Far_plane) { Clear(); m_Data[0][0] = cosf(Fov*0.5f)/sinf(Fov*0.5f); m_Data[1][1] = m_Data[0][0]*Aspect; m_Data[2][2] = Far_plane / (Far_plane - Near_plane); m_Data[3][2] = -m_Data[2][2]*Near_plane; m_Data[2][3] = 1; } /************************************************ Summary: Constructs a perspective projection matrix given a view rectangle . Arguments: Left - [In][Out]Left clipping plane value. Right - Right clipping plane value. Top - [Out]top clipping plane value. Bottom - [In]bottom clipping plane value. Near_plane - [In][Out]Distance of the near clipping plane. Far_plane - [In/Out]Distance of the far clipping plane. Remarks: Sets Mat to F = Far_plane N = Near_plane R = Right L = Left T = Top B = Bottom [ 2/(R-L) 0 0 0] [ 0 2/(T-B) 0 0] MAT = [ -(L+R)/(R-L) (T+B)/(T-B) F/F-N 0] [ 0 0 -F.N/F-N 1] See also: Perspective,Orthographic,Identity,OrthographicRect ************************************************/ inline void VxMatrix::PerspectiveRect(float Left,float Right,float Top,float Bottom,float Near_plane,float Far_plane) { Clear(); float RL = 1.0f / (Right - Left); float TB = 1.0f / (Top - Bottom); m_Data[0][0] = 2.0f*Near_plane * RL; m_Data[1][1] = 2.0f*Near_plane * TB; m_Data[2][0] = -(Right+Left) * RL; m_Data[2][1] = -(Top + Bottom)* TB; m_Data[2][2] = Far_plane / (Far_plane - Near_plane); m_Data[3][2] = -m_Data[2][2]*Near_plane; m_Data[2][3] = 1; } /************************************************ Summary: Constructs a orthographic projection matrix. Input Arguments: Zoom: Zoom factor. Aspect: Aspect ratio (Width/height) Output Arguments: Near_plane: Distance of the near clipping plane. Far_plane: Distance of the far clipping plane. Remarks: Sets Mat to F = Far_plane N = Near_plane [ Zoom 0 0 0] [ 0 Zoom*Aspect 0 0] MAT = [ 0 0 1/F-N 0] [ 0 0 -N/F-N 1] See also: Vx3DMatrixIdentity,Perspective,OrthographicRect ************************************************/ inline void VxMatrix::Orthographic(float Zoom,float Aspect,float Near_plane,float Far_plane) { Clear(); float iz=1.0f/(Far_plane-Near_plane); m_Data[0][0]=Zoom; m_Data[1][1]=Zoom*Aspect; m_Data[2][2]=iz; m_Data[3][2]=-Near_plane*iz; m_Data[3][3]=1.0f; } /************************************************ Summary: Constructs a orthographic projection matrix. Input Arguments: Left: Left clipping plane value. Right: Right clipping plane value. Top: top clipping plane value. Bottom: bottom clipping plane value. Near_plane: Distance of the near clipping plane. Far_plane: Distance of the far clipping plane. Remarks: Sets Mat to F = Far_plane N = Near_plane R = Right L = Left T = Top B = Bottom [ 2/(R-L) 0 0 0] [ 0 -2/(T-B) 0 0] MAT = [ 0 0 1/F-N 0] [ -(L+R)/(R-L) (T+B)/(T-B) -N/F-N 1] See also: Vx3DMatrixIdentity,Perspective,Orthographic ************************************************/ inline void VxMatrix::OrthographicRect(float Left,float Right,float Top,float Bottom,float Near_plane,float Far_plane) { Clear(); float ix=1.0f/(Right-Left); float iy=1.0f/(Top-Bottom); float iz=1.0f/(Far_plane-Near_plane); m_Data[0][0]=2.0f*ix; m_Data[1][1]=2.0f*iy; m_Data[2][2]=iz; m_Data[3][0]=-(Left+Right)*ix; m_Data[3][1]=-(Top+Bottom)*iy; m_Data[3][2]=-Near_plane*iz; m_Data[3][3]=1.0f; } #endif // #ifdef PSP #endif