class Matrix4
{
public:
Matrix4();
Matrix4(const Matrix4 &M);
Matrix4(const Vec3f &V0, const Vec3f &V1, const Vec3f &V2);
#ifdef USE_D3D
Matrix4(const D3DXMATRIX &M);
#endif
Matrix4& operator = (const Matrix4 &M);
float Determinant() const;
Matrix4 Transpose() const;
Matrix4 Inverse() const;
__forceinline Vec3f TransformPoint(const Vec3f &point) const
{
float w = point.x * _Entries[0][3] + point.y * _Entries[1][3] + point.z * _Entries[2][3] + _Entries[3][3];
if(w)
{
const float invW = 1.0f / w;
return Vec3f( (point.x * _Entries[0][0] + point.y * _Entries[1][0] + point.z * _Entries[2][0] + _Entries[3][0]) * invW,
(point.x * _Entries[0][1] + point.y * _Entries[1][1] + point.z * _Entries[2][1] + _Entries[3][1]) * invW,
(point.x * _Entries[0][2] + point.y * _Entries[1][2] + point.z * _Entries[2][2] + _Entries[3][2]) * invW);
}
else
{
return Vec3f::Origin;
}
}
__forceinline Vec3f TransformNormal(const Vec3f &normal) const
{
return Vec3f(normal.x * _Entries[0][0] + normal.y * _Entries[1][0] + normal.z * _Entries[2][0],
normal.x * _Entries[0][1] + normal.y * _Entries[1][1] + normal.z * _Entries[2][1],
normal.x * _Entries[0][2] + normal.y * _Entries[1][2] + normal.z * _Entries[2][2]);
}
Plane TransformPlane(const Plane &P) const;
String CommaSeparatedString() const;
String CommaSeparatedStringSingleLine() const;
String SpaceSeperatedStringSingleLine() const;
String TabSeperatedString() const;
#ifdef USE_D3D
operator D3DXMATRIX() const;
#endif
__forceinline float* operator [] (int Row)
{
return _Entries[Row];
}
__forceinline const float* operator [] (int Row) const
{
return _Entries[Row];
}
__forceinline void SetColumn(UINT Column, const Vec4f &Values)
{
_Entries[0][Column] = Values.x;
_Entries[1][Column] = Values.y;
_Entries[2][Column] = Values.z;
_Entries[3][Column] = Values.w;
}
__forceinline void SetRow(UINT Row, const Vec4f &Values)
{
_Entries[Row][0] = Values.x;
_Entries[Row][1] = Values.y;
_Entries[Row][2] = Values.z;
_Entries[Row][3] = Values.w;
}
__forceinline Vec4f GetColumn(UINT Column)
{
Vec4f Result;
Result.x = _Entries[0][Column];
Result.y = _Entries[1][Column];
Result.z = _Entries[2][Column];
Result.w = _Entries[3][Column];
return Result;
}
__forceinline Vec4f GetRow(UINT Row)
{
Vec4f Result;
Result.x = _Entries[Row][0];
Result.y = _Entries[Row][1];
Result.z = _Entries[Row][2];
Result.w = _Entries[Row][3];
return Result;
}
static Matrix4 Identity();
static Matrix4 Scaling(const Vec3f &ScaleFactors);
static Matrix4 Scaling(float ScaleFactor)
{
return Scaling(Vec3f(ScaleFactor, ScaleFactor, ScaleFactor));
}
static Matrix4 Translation(const Vec3f &Pos);
static Matrix4 Rotation(const Vec3f &Axis, float Angle, const Vec3f &Center);
static Matrix4 Rotation(const Vec3f &Axis, float Angle);
static Matrix4 Rotation(float Yaw, float Pitch, float Roll);
static Matrix4 Rotation(const Vec3f &Basis1, const Vec3f &Basis2, const Vec3f &Basis3);
static Matrix4 RotationX(float Theta);
static Matrix4 RotationY(float Theta);
static Matrix4 RotationZ(float Theta);
static Matrix4 Camera(const Vec3f &Eye, const Vec3f &Look, const Vec3f &Up, const Vec3f &Right);
static Matrix4 LookAt(const Vec3f &Eye, const Vec3f &At, const Vec3f &Up);
static Matrix4 Orthogonal(float Width, float Height, float ZNear, float ZFar);
static Matrix4 Perspective(float Width, float Height, float ZNear, float ZFar);
static Matrix4 PerspectiveFov(float FOV, float Aspect, float ZNear, float ZFar);
static Matrix4 PerspectiveMultiFov(float FovX, float FovY, float ZNear, float ZFar);
static Matrix4 Face(const Vec3f &V0, const Vec3f &V1);
static Matrix4 Viewport(float Width, float Height);
static Matrix4 ChangeOfBasis(const Vec3f &Source0, const Vec3f &Source1, const Vec3f &Source2, const Vec3f &SourceOrigin,
const Vec3f &Target0, const Vec3f &Target1, const Vec3f &Target2, const Vec3f &TargetOrigin);
static float CompareMatrices(const Matrix4 &Left, const Matrix4 &Right);
private:
float _Entries[4][4];
};
ostream& operator << (ostream &os, const Matrix4 &m);
istream& operator >> (istream &os, Matrix4 &m);
Matrix4 operator * (const Matrix4 &Left, const Matrix4 &Right);
Matrix4 operator * (const Matrix4 &Left, float &Right);
Matrix4 operator * (float &Left, const Matrix4 &Right);
Matrix4 operator + (const Matrix4 &Left, const Matrix4 &Right);
Matrix4 operator - (const Matrix4 &Left, const Matrix4 &Right);
__forceinline Vec4f operator * (const Vec4f &Right, const Matrix4 &Left)
{
return Vec4f(Right.x * Left[0][0] + Right.y * Left[1][0] + Right.z * Left[2][0] + Right.w * Left[3][0],
Right.x * Left[0][1] + Right.y * Left[1][1] + Right.z * Left[2][1] + Right.w * Left[3][1],
Right.x * Left[0][2] + Right.y * Left[1][2] + Right.z * Left[2][2] + Right.w * Left[3][2],
Right.x * Left[0][3] + Right.y * Left[1][3] + Right.z * Left[2][3] + Right.w * Left[3][3]);
}