// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu) // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License v2 or later. #ifndef TRANSFORM_h #define TRANSFORM_h #include #include "general.h" #include "pt3d.h" #include "ang3d.h" //========================================================================== // Transformation matrix classes // // tcomp - an affine transformation, represented as a cartesian offset, // a 3D angle, and a scaling factor. // // tmtrx - an affine transformation represented as a 4x4 matrix //=========================================================================== class tmtrx; // forward reference class tcomp { pt3d cart; ang3d ang; pt3d scale; public: tcomp(ang2d a=0) : cart(pt3d(0,0,0)), ang(ang3d(a)), scale(pt3d(1,1,1)) {} tcomp(const ang3d& a) : cart(pt3d(0,0,0)), ang(a), scale(pt3d(1,1,1)) {} tcomp(const pt3d& c, const ang3d& a=ang3d(0), const pt3d& s=pt3d(1,1,1)) : cart(c), ang(a), scale(s) {} tcomp(const tmtrx& t); // Warning: assumes t has unity scaling pt3d& Cart() {return cart;} ang3d& Ang() {return ang;} pt3d& Scale() {return scale;} const pt3d& Cart() const {return cart;} const ang3d& Ang() const {return ang;} const pt3d& Scale() const {return scale;} tcomp& operator+=(tcomp& t); tcomp& operator-=(tcomp& t); tcomp operator- () {return tcomp(-Cart(),-Ang(),-Scale());} tcomp operator+ (tcomp& t) {return tcomp(Cart()+t.Cart(),Ang()+t.Ang(),Scale()+t.Scale());} tcomp operator- (tcomp& t) {return tcomp(Cart()-t.Cart(),Ang()-t.Ang(),Scale()-t.Scale());} //tcomp Plus(tcomp&); //tcomp Plus2(tcomp&); //tcomp Clamped1(); //tcomp Clamped2(); // replace next two funcs by plain max() & min() someday -PAH void SetMax(tcomp& t) {Cart().SetMax(t.Cart()); Ang().SetMax(t.Ang());} void SetMin(tcomp& t) {Cart().SetMin(t.Cart()); Ang().SetMin(t.Ang());} friend ostream& operator<<(ostream&, const tcomp&); }; //=========================================================================== class tmtrx { friend struct player; typedef double fourby3[4][3]; fourby3 m; public: tmtrx() {} tmtrx(const tmtrx& t) {Copy(t.m);} tmtrx(const fourby3 newm) {Copy(newm);} tmtrx(const tcomp& t) {SetMtrx(t.Ang(),t.Scale()); Cart()=t.Cart();} tmtrx(ang2d a) {SetMtrx(ang3d(a,0,0)); Cart()= pt3d(0,0,0);} tmtrx(const ang3d& a) {SetMtrx(a); Cart()= pt3d(0,0,0);} tmtrx(const pt3d& c, const ang3d& a=ang3d(0), const pt3d& sc=pt3d(1,1,1)) { SetMtrx(a,sc); Cart()=c; } pt3d& Cart() const {return *((pt3d*) m[3]);} ang3d Ang() const; double *operator[](int i) {return m[i];} const double *operator[](int i) const {return m[i];} tmtrx& operator= (const tmtrx& t) {if (this != &t) Copy(t.m); return *this;} bool operator==(const tmtrx& t) const; tmtrx operator* (const tmtrx&) const; tmtrx Inverse() const; bool RotationSame(const tmtrx& t) const; private: void SetMtrx(const ang3d& a, const pt3d& s=pt3d(1,1,1)); void Copy(const fourby3); friend ostream& operator<<(ostream&,const tmtrx&); }; inline tmtrx operator*(const tcomp& tc, const tmtrx& tm) {return tmtrx(tc) * tm;} //=========================================================================== // these could easily be templatized to work with both tmtrx or double[4][4] pt3d operator*(const pt3d& p, const tmtrx& t); pt3d operator/(const pt3d& p, const tmtrx& t); inline pt3d operator>>(const pt3d& p, const tmtrx& t) {return p*t;} inline pt3d operator<<(const pt3d& p, const tmtrx& t) {return p/t;} #endif