/*
Matrix.h
Written by Matthew Fisher

a 4x4 matrix structure.  Used very often for affine vector transformations.
*/

class Matrix
{
public:
    //Initalization
    Matrix();
    Matrix(const Matrix &M);

#ifdef USE_DIRECTX
    Matrix(const D3DXMATRIX &M);    //initalizes the matrix with a D3DXMATRIX
#endif

    //Assignment
    Matrix& operator = (const Matrix &M);

    //Basic Transforms
    void Identity();
    void Scaling(const Vec3 &ScaleFactors);
    void Scaling(float Scale)
    {
        Scaling(Vec3(Scale, Scale, Scale));
    }
    void Translation(const Vec3 &Pos);

    //Rotation Transforms
    void Rotation(const Vec3 &Axis, float Angle, const Vec3 &Center);
    void Rotation(const Vec3 &Axis, float Angle);
    void Rotation(float Yaw, float Pitch, float Roll);
    void RotationX(float Theta);
    void RotationY(float Theta);
    void RotationZ(float Theta);

    //Complex or Composite Transforms
    void LookAt(const Vec3 &Eye, const Vec3 &At, const Vec3 &Up);
    void Orthogonal(float Width, float Height, float ZNear, float ZFar);
    void Perspective(float Width, float Height, float ZNear, float ZFar);
    void PerspectiveFov(float FOV, float Aspect, float ZNear, float ZFar);
    void Face(const Vec3 &v1, const Vec3 &v2);      //Constructs a matrix that will make all the vector facing v1 now face towards v2.
    void Viewport(float Width, float Height);

    void SetProduct(const Matrix &Left, const Matrix &Right);   //loads this matrix as the product of the given matrices
    void Invert();          //Inverts the current matrix
    void Transpose();       //Transposes the current matrix
    float Determinant();    //returns the determinant of this matrix

#ifdef USE_DIRECTX
    operator D3DXMATRIX();  //converts this matrix into a D3DXMATRIX
#endif

    inline float* operator [] (int Row);                //returns the 4 elements in the requested Row
    inline const float* operator [] (int Row) const;    //returns the 4 elements in the requested Row

    float Data[4][4];   //the data itself
};

ostream& operator << (ostream &os, const Matrix &m);        //Outputs the 16 elements in the matrix
istream& operator >> (istream &os, Matrix &m);              //Inputs the 16 elements in the matrix

Matrix operator * (const Matrix &Left, const Matrix &Right);
Matrix operator * (const Matrix &Left, float &Right);
Matrix operator * (float &Left, const Matrix &Right);           //Matrix-Matrix and Matrix-float multiplication
Matrix operator + (const Matrix &Left, const Matrix &Right);
Matrix operator - (const Matrix &Left, const Matrix &Right);    //Matrix-Matrix addition/mulitplication

Vec4 operator * (const Vec4 &Left, const Matrix &Right);        //4-vector Matrix multiplication

//transforms the vector Left, extended to (x, y, z, 1), by the matrix Right, storing the result in Target
void Vec3TransformCoord(Vec3 &Target, const Vec3 &Left, const Matrix &Right);

//transforms the vector Left, extended to (x, y, z, 0), by the matrix Right, storing the result in Target
void Vec3TransformNormal(Vec3 &Target, const Vec3 &Left, const Matrix &Right);

//transforms the vector Left, extended to (x, y, z, 1), by the matrix Right, projecting the result
//back into w = 1, and storing the result in Target
void Vec3TransformProjectCoord(Vec3 &Target, const Vec3 &Left, const Matrix &Right);

//Matrix inline functions
#ifndef __MATRIX_INLINE
#define __MATRIX_INLINE
inline float* Matrix::operator [] (int Row)
{
    return Data[Row];
}

inline const float* Matrix::operator [] (int Row) const
{
    return Data[Row];
}
#endif

Top