00001 #ifndef TRANSFORM_H
00002 #define TRANSFORM_H
00003
00004 #ifdef PHYSX
00005 #include <PxPhysicsAPI.h>
00006 #endif
00007
00008 #include <math/config.hpp>
00009 #include <math/vec3.hpp>
00010 #include <math/quat.hpp>
00011
00012 namespace math {
00013 template<typename T> class transform {
00014 public:
00018 transform(): p(0, 0, 0), q(1, 0, 0, 0) {}
00019 transform(const vec3<T>& np): p(np), q(0, 0, 0, 1) {}
00020 transform(quat<T> const & nq): p(0, 0, 0), q(nq) {
00021 assert(nq.isSane());
00022 }
00023 transform(math::vec3<T> const & p0, math::quat<T> const & q0): p(p0), q(q0) {
00024 if(!q.isSane()) {
00025 q = quat<T>();
00026 }
00027 }
00028 transform(mat44<T> const & m)
00029 {
00030 p = m.GetTranslatedVector3D(math::vec3<T>(0,0,0));
00031 q = math::quat<T>(m);
00032 }
00035 math::transform<T> operator*(const transform& x) const {
00036 assert(x.isSane());
00037 return transform(x);
00038 }
00039 math::transform<T> getInverse() const {
00040 assert(isFinite());
00041 return transform(q.rotateInv(-p),q.getConjugate());
00042 }
00043
00047 math::vec3<T> trans(vec3<T> const & input) const {
00048 assert(isFinite());
00049 return q.rotate(input) + p;
00050 }
00051 math::vec3<T> transInv(const vec3<T>& input) const {
00052 assert(isFinite());
00053 return q.rotateInv(input-p);
00054 }
00055 math::vec3<T> rotate(const vec3<T>& input) const {
00056 assert(isFinite());
00057 return q.rotate(input);
00058 }
00059 math::vec3<T> rotateInv(const vec3<T>& input) const {
00060 assert(isFinite());
00061 return q.rotateInv(input);
00062 }
00063 math::transform<T> trans(const transform& src) const {
00064 assert(src.isSane());
00065 assert(isSane());
00066
00067 return transform(q.rotate(src.p) + p, q*src.q);
00068 }
00069 math::transform<T> transInv(transform const & src) const {
00070 assert(src.isSane());
00071 assert(isFinite());
00072
00073 math::quat<T> qinv = q.getConjugate();
00074 return transform(qinv.rotate(src.p - p), qinv*src.q);
00075 }
00076 math::plane<T> trans(plane<T> const & plane) const {
00077 vec3<T> transformedNormal = rotate(plane.n);
00078 return math::plane<T>(transformedNormal, plane.d - p.dot(transformedNormal));
00079 }
00080 math::plane<T> transInverse(math::plane<T> const & plane) const {
00081 vec3<T> transformedNormal = rotateInv(plane.n);
00082 return math::plane<T>(transformedNormal, plane.d + p.dot(plane.n));
00083 }
00086 bool isValid() const {
00087 return p.IsFinite() && q.isFinite() && q.isUnit();
00088 }
00089 bool isSane() const {
00090 return isFinite() && q.isSane();
00091 }
00092 bool isFinite() const {
00093 return p.IsFinite() && q.isFinite();
00094 }
00095
00096 math::transform<T> getNormalized() const {
00097 return transform(p, q.getNormalized());
00098 }
00099 #ifdef PHYSX
00100 operator physx::PxTransform() const {
00101 return physx::PxTransform(p,q);
00102 }
00103 math::transform<T>& operator=(physx::PxTransform const & rhs) {
00104 p = rhs.p;
00105 q = rhs.q;
00106
00107 return *this;
00108 }
00109 #endif
00110
00111 vec3<T> p;
00112 quat<T> q;
00113 };
00114 }
00115
00116 #endif