#pragma once #include "scalar.h" #include class AffineMatrix; class TransposedMatrix; class Origin; class Hinge; class EulerAngles; class YawPitchRoll; class Point3D; class Quaternion; class AbstractMatrix4x4 { public: Scalar entries[16]; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile AbstractMatrix4x4 *); #endif AbstractMatrix4x4& operator=(const AbstractMatrix4x4& m); Logical TestInstance() const; protected: AbstractMatrix4x4() {} AbstractMatrix4x4& Transpose(const AbstractMatrix4x4 &m); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Matrix4x4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Matrix4x4 : public AbstractMatrix4x4 { public: static const Matrix4x4 Identity; Matrix4x4() {} Matrix4x4& BuildIdentity(); Matrix4x4(int) { BuildIdentity(); } Matrix4x4& operator=(const Matrix4x4 &m) { Check_Pointer(this); Check(&m); AbstractMatrix4x4::operator=(m); return *this; } Matrix4x4& operator=(const TransposedMatrix &m); Matrix4x4& operator=(const AffineMatrix &m); Matrix4x4& operator=(const Origin &p); Matrix4x4& operator=(const Hinge &hinge); Matrix4x4& operator=(const EulerAngles &angles); Matrix4x4& operator=(const YawPitchRoll &angles); Matrix4x4& operator=(const D3DXMATRIX &m); Matrix4x4& BuildRotation(const Quaternion &q); Matrix4x4& operator=(const Quaternion &q); Matrix4x4& BuildTranslation(const Point3D &p); Matrix4x4& operator=(const Point3D &p); // // Index operators // Note that Matrix4x4 is stored in row major format, not column major, // although they are indexed the same // Scalar& operator ()(size_t Row,size_t Column) { Check_Pointer(this); Warn(Row>3); Warn(Column>3); return entries[(Row<<2)+Column]; } const Scalar& operator ()(size_t Row,size_t Column) const { Check_Pointer(this); Warn(Row>3); Warn(Column>3); return entries[(Row<<2)+Column]; } Matrix4x4& Multiply(const Matrix4x4& Source1, const Matrix4x4& Source2); Matrix4x4& operator *=(const Matrix4x4& m) { Matrix4x4 temp(*this); return Multiply(temp,m); } Matrix4x4& Multiply(const Matrix4x4& Source1, const AffineMatrix &Source2); Matrix4x4& operator *=(const AffineMatrix& m) { Matrix4x4 temp(*this); return Multiply(temp,m); } Matrix4x4& Multiply(const AffineMatrix &Source1, const Matrix4x4& Source2); Matrix4x4& Multiply(const AffineMatrix &Source1, const AffineMatrix &Source2); #if 0 Matrix4x4& Invert(const Matrix4x4& Source); Matrix4x4& Invert() { Matrix4x4 src(*this); return Invert(src); } #endif Matrix4x4& SetToProjection(Scalar Z_Plane, Scalar Inv_Q, Scalar Dx, Scalar Dy, Scalar Dz); Matrix4x4& SetToPerspectiveProjection(Scalar Distance) { Verify(Distance != 0.0); return SetToProjection(0.0, 1.0 / Distance, 0.0, 0.0, -1.0); } Matrix4x4& SetToOrthogonalProjection() { return SetToProjection(0.0, 0.0, 0.0, 0.0, -1.0); } D3DXMATRIX ToD3DMatrix(); friend std::ostream& operator <<(std::ostream& stream, const Matrix4x4& Matrix4x4); static Logical TestClass(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Matrix4x4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class TransposedMatrix : public AbstractMatrix4x4 { public: // // Constructors // TransposedMatrix() {} // // Assignment operators // TransposedMatrix& operator=(const Matrix4x4 &m) { Check_Pointer(this); Check(&m); AbstractMatrix4x4::Transpose(m); return *this; } TransposedMatrix& operator=(const TransposedMatrix &m) { Check_Pointer(this); Check(&m); AbstractMatrix4x4::operator=(m); return *this; } TransposedMatrix& operator=(const AffineMatrix &m); // // Index operators // Scalar& operator()(size_t Row,size_t Column) { Check_Pointer(this); Warn(Row>3); Warn(Column>3); return entries[(Column<<2)+Row]; } const Scalar& operator()(size_t Row,size_t Column) const { Check_Pointer(this); Warn(Row>3); Warn(Column>3); return entries[(Column<<2)+Row]; } // // Support Functions // friend std::ostream& operator <<(std::ostream& stream, const TransposedMatrix& Matrix4x4); }; inline Matrix4x4& Matrix4x4::operator=(const TransposedMatrix &m) { Check_Pointer(this); Check(&m); AbstractMatrix4x4::Transpose(m); return *this; }