00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PBRT_TRANSFORM_H
00025 #define PBRT_TRANSFORM_H
00026
00027 #include "pbrt.h"
00028 #include "geometry.h"
00029
00030 class COREDLL Transform {
00031 public:
00032
00033 Transform() {
00034 m = mInv = new Matrix4x4;
00035 }
00036 Transform(float mat[4][4]) {
00037 m=new Matrix4x4(mat[0][0],mat[0][1],mat[0][2],mat[0][3],
00038 mat[1][0],mat[1][1],mat[1][2],mat[1][3],
00039 mat[2][0],mat[2][1],mat[2][2],mat[2][3],
00040 mat[3][0],mat[3][1],mat[3][2],mat[3][3]);
00041 mInv = m->Inverse();
00042 }
00043 Transform(const Reference<Matrix4x4> &mat) {
00044 m = mat;
00045 mInv = m->Inverse();
00046 }
00047 Transform(const Reference<Matrix4x4> &mat,
00048 const Reference<Matrix4x4> &minv) {
00049 m = mat;
00050 mInv = minv;
00051 }
00052 friend ostream &operator<<(ostream &, const Transform &);
00053 Transform GetInverse() const {
00054 return Transform(mInv, m);
00055 }
00056 bool HasScale() const;
00057 inline Point operator()(const Point &pt) const;
00058 inline void operator()(const Point &pt,Point *ptrans) const;
00059 inline Vector operator()(const Vector &v) const;
00060 inline void operator()(const Vector &v, Vector *vt) const;
00061 inline Normal operator()(const Normal &) const;
00062 inline void operator()(const Normal &, Normal *nt) const;
00063 inline Ray operator()(const Ray &r) const;
00064 inline void operator()(const Ray &r, Ray *rt) const;
00065 BBox operator()(const BBox &b) const;
00066 Transform operator*(const Transform &t2) const;
00067 bool SwapsHandedness() const;
00068 private:
00069
00070 Reference<Matrix4x4> m, mInv;
00071 };
00072
00073 inline Point Transform::operator()(const Point &pt) const {
00074 float x = pt.x, y = pt.y, z = pt.z;
00075 float xp = m->m[0][0]*x + m->m[0][1]*y + m->m[0][2]*z + m->m[0][3];
00076 float yp = m->m[1][0]*x + m->m[1][1]*y + m->m[1][2]*z + m->m[1][3];
00077 float zp = m->m[2][0]*x + m->m[2][1]*y + m->m[2][2]*z + m->m[2][3];
00078 float wp = m->m[3][0]*x + m->m[3][1]*y + m->m[3][2]*z + m->m[3][3];
00079
00080 Assert(wp != 0);
00081 if (wp == 1.) return Point(xp, yp, zp);
00082 else return Point(xp, yp, zp)/wp;
00083 }
00084 inline void Transform::operator()(const Point &pt,
00085 Point *ptrans) const {
00086 float x = pt.x, y = pt.y, z = pt.z;
00087 ptrans->x = m->m[0][0]*x + m->m[0][1]*y + m->m[0][2]*z + m->m[0][3];
00088 ptrans->y = m->m[1][0]*x + m->m[1][1]*y + m->m[1][2]*z + m->m[1][3];
00089 ptrans->z = m->m[2][0]*x + m->m[2][1]*y + m->m[2][2]*z + m->m[2][3];
00090 float w = m->m[3][0]*x + m->m[3][1]*y + m->m[3][2]*z + m->m[3][3];
00091 if (w != 1.) *ptrans /= w;
00092 }
00093 inline Vector Transform::operator()(const Vector &v) const {
00094 float x = v.x, y = v.y, z = v.z;
00095 return Vector(m->m[0][0]*x + m->m[0][1]*y + m->m[0][2]*z,
00096 m->m[1][0]*x + m->m[1][1]*y + m->m[1][2]*z,
00097 m->m[2][0]*x + m->m[2][1]*y + m->m[2][2]*z);
00098 }
00099 inline void Transform::operator()(const Vector &v,
00100 Vector *vt) const {
00101 float x = v.x, y = v.y, z = v.z;
00102 vt->x = m->m[0][0] * x + m->m[0][1] * y + m->m[0][2] * z;
00103 vt->y = m->m[1][0] * x + m->m[1][1] * y + m->m[1][2] * z;
00104 vt->z = m->m[2][0] * x + m->m[2][1] * y + m->m[2][2] * z;
00105 }
00106 inline Normal Transform::operator()(const Normal &n) const {
00107 float x = n.x, y = n.y, z = n.z;
00108 return Normal(mInv->m[0][0]*x + mInv->m[1][0]*y + mInv->m[2][0]*z,
00109 mInv->m[0][1]*x + mInv->m[1][1]*y + mInv->m[2][1]*z,
00110 mInv->m[0][2]*x + mInv->m[1][2]*y + mInv->m[2][2]*z);
00111 }
00112 inline void Transform::operator()(const Normal &n,
00113 Normal *nt) const {
00114 float x = n.x, y = n.y, z = n.z;
00115 nt->x = mInv->m[0][0]*x + mInv->m[1][0]*y + mInv->m[2][0]*z;
00116 nt->y = mInv->m[0][1]*x + mInv->m[1][1]*y + mInv->m[2][1]*z;
00117 nt->z = mInv->m[0][2]*x + mInv->m[1][2]*y + mInv->m[2][2]*z;
00118 }
00119 inline Ray Transform::operator()(const Ray &r) const {
00120 Ray ret;
00121 (*this)(r.o, &ret.o);
00122 (*this)(r.d, &ret.d);
00123 ret.mint = r.mint;
00124 ret.maxt = r.maxt;
00125 ret.time = r.time;
00126 return ret;
00127 }
00128 inline void Transform::operator()(const Ray &r,
00129 Ray *rt) const {
00130 (*this)(r.o, &rt->o);
00131 (*this)(r.d, &rt->d);
00132 rt->mint = r.mint;
00133 rt->maxt = r.maxt;
00134 rt->time = r.time;
00135 }
00136 #endif // PBRT_TRANSFORM_H