00001 #ifndef vec3_H
00002 #define vec3_H
00003
00004 #ifdef PHYSX
00005 #include <PxPhysicsAPI.h>
00006 #endif
00007
00008
00009 #include <math/math.hpp>
00010 #include <math/vecbase.hpp>
00011
00012 namespace math {
00013 template <typename T> class vec3: public math::vecbase<T,3> {
00014 public:
00018 vec3() { vecbase<T,3>::loadZero(); }
00019 vec3(math::vec3<T> const & rhs): math::vecbase<double,3>(rhs) {}
00020 vec3(double const & nx, double const & ny, double const & nz) {
00021 vecbase<T,3>::v[0] = nx;
00022 vecbase<T,3>::v[1] = ny;
00023 vecbase<T,3>::v[2] = nz;
00024 }
00025 vec3(double const * const v): math::vecbase<double,3>(v) {}
00026
00027 #ifdef PHYSX
00028 vec3(physx::PxVec3 const & rhs) {
00029 vecbase<T,3>::v[0] = rhs.x;
00030 vecbase<T,3>::v[1] = rhs.y;
00031 vecbase<T,3>::v[2] = rhs.z;
00032 }
00033 #endif
00034
00036 ~vec3() {}
00037
00041
00042 T& x() { return math::vecbase<T,3>::v[0]; }
00043
00044 T& y() { return math::vecbase<T,3>::v[1]; }
00045
00046 T& z() { return math::vecbase<T,3>::v[2]; }
00047
00048 T const & x() const { return math::vecbase<T,3>::v[0]; }
00049
00050 T const & y() const { return math::vecbase<T,3>::v[1]; }
00051
00052 T const & z() const { return math::vecbase<T,3>::v[2]; }
00053
00056
00057 T dot(math::vec3<T> const & rhs) const {
00058 return vecbase<T,3>::dot(rhs);
00059 }
00060 math::vec3<T> cross(const vec3<T> & rhs) const {
00061 return vec3<T>(y()*rhs.z() - z()*rhs.y(), z()*rhs.x() - x()*rhs.z(), x()*rhs.y() - y()*rhs.x());
00062 }
00063 T angle(vec3<T> const & rhs) const {
00064
00065 math::vec3<T> v = cross(rhs);
00066
00067 return acos( v.magnitude() / vecbase<T,3>::magnitude() / rhs.magnitude() );
00068 }
00069 math::vec3<T> GetNormalized() const {
00070
00071 vec3<T> result(*this);
00072
00073 result.Normalize();
00074
00075 return result;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 math::vec3<T> GetRotatedX(T angle) const {
00089
00090 if(angle==0.0) return (*this);
00091
00092 float sinAngle=(float)sin(M_PI*angle/180);
00093 float cosAngle=(float)cos(M_PI*angle/180);
00094
00095 return vec3<T>( x(),
00096 y()*cosAngle - z()*sinAngle,
00097 y()*sinAngle + z()*cosAngle);
00098 }
00099 void RotateX(T angle) {
00100 (*this)=GetRotatedX(angle);
00101 }
00102 math::vec3<T> GetRotatedY(double angle) const {
00103
00104 if(angle==0.0) return (*this);
00105
00106 float sinAngle=(float)sin(M_PI*angle/180);
00107 float cosAngle=(float)cos(M_PI*angle/180);
00108
00109 return math::vec3<T>(
00110 x()*cosAngle + z()*sinAngle,
00111 y(),
00112 -x()*sinAngle + z()*cosAngle);
00113 }
00114 void RotateY(double angle) {
00115
00116 (*this)=GetRotatedY(angle);
00117 }
00118 math::vec3<T> GetRotatedZ(double angle) const {
00119
00120 if(angle==0.0) return (*this);
00121
00122 float sinAngle=(float)sin(M_PI*angle/180);
00123 float cosAngle=(float)cos(M_PI*angle/180);
00124
00125 return math::vec3<T>(
00126 x()*cosAngle - y()*sinAngle,
00127 x()*sinAngle + y()*cosAngle,
00128 z());
00129 }
00130 void RotateZ(double angle) {
00131
00132 (*this)=GetRotatedZ(angle);
00133 }
00134 math::vec3<T> GetRotatedAxis(double angle, const math::vec3<T> & axis) const {
00135
00136 if(angle==0.0) return (*this);
00137
00138 math::vec3<T> u = axis.GetNormalized();
00139
00140 math::vec3<T> rotMatrixRow0, rotMatrixRow1, rotMatrixRow2;
00141
00142 float sinAngle=(float)sin(M_PI*angle/180);
00143 float cosAngle=(float)cos(M_PI*angle/180);
00144 float oneMinusCosAngle=1.0f-cosAngle;
00145
00146 rotMatrixRow0.v[0]=(u.v[0])*(u.v[0]) + cosAngle*(1-(u.v[0])*(u.v[0]));
00147 rotMatrixRow0.v[1]=(u.v[0])*(u.v[1])*(oneMinusCosAngle) - sinAngle*u.v[2];
00148 rotMatrixRow0.v[2]=(u.v[0])*(u.v[2])*(oneMinusCosAngle) + sinAngle*u.v[1];
00149
00150 rotMatrixRow1.v[0]=(u.v[0])*(u.v[1])*(oneMinusCosAngle) + sinAngle*u.v[2];
00151 rotMatrixRow1.v[1]=(u.v[1])*(u.v[1]) + cosAngle*(1-(u.v[1])*(u.v[1]));
00152 rotMatrixRow1.v[2]=(u.v[1])*(u.v[2])*(oneMinusCosAngle) - sinAngle*u.v[0];
00153
00154 rotMatrixRow2.v[0]=(u.v[0])*(u.v[2])*(oneMinusCosAngle) - sinAngle*u.v[1];
00155 rotMatrixRow2.v[1]=(u.v[1])*(u.v[2])*(oneMinusCosAngle) + sinAngle*u.v[0];
00156 rotMatrixRow2.v[2]=(u.v[2])*(u.v[2]) + cosAngle*(1-(u.v[2])*(u.v[2]));
00157
00158 return math::vec3<T>( dot(rotMatrixRow0), dot(rotMatrixRow1), dot(rotMatrixRow2));
00159 }
00160
00161 void PackTo01() {
00162 vecbase<T,3>::Normalize();
00163
00164 operator*=(0.5f);
00165 operator+=(math::vec3<T>(0.5f, 0.5f, 0.5f));
00166
00167 }
00168 math::vec3<T> GetPackedTo01() const {
00169
00170 math::vec3<T> temp(*this);
00171
00172 temp.packTo01();
00173
00174
00175 return temp;
00176 }
00177
00178 vec3<T> lerp(const vec3<T> & v2, T factor) const
00179 {
00180 return (*this)*(1.0f-factor) + v2*factor;
00181 }
00182 vec3<T> QuadraticInterpolate(
00183 const vec3<T> & v2,
00184 const vec3<T> & v3,
00185 T factor) const
00186 {
00187 return (*this)*(1.0f-factor)*(1.0f-factor)+
00188 v2 * 2 * factor*(1.0f-factor)+
00189 v3 * factor * factor;
00190 }
00191
00195 vec3<T> operator+(const vec3<T> & rhs) const
00196 {
00197 vec3<T> a(*this);
00198 a += rhs;
00199 return a;
00200 }
00201 vec3<T> operator-(const vec3<T> & rhs) const {
00202 vec3<T> a(*this);
00203 a -= rhs;
00204 return a;
00205 }
00206 vec3<T> operator*(const double rhs) const {
00207 vec3<T> a(*this);
00208 a *= rhs;
00209 return a;
00210 }
00211 vec3<T> operator/(const double rhs) const {
00212 vec3<T> a(*this);
00213 a /= rhs;
00214 return a;
00215 }
00218
00219
00220
00221
00225 math::vec3<T>& operator+=(math::vec3<T> const & rhs) {
00226 math::vecbase<double,3>::operator+=(rhs);
00227 return *this;
00228 }
00229 math::vec3<T>& operator-=(const vec3<T> & rhs) {
00230 math::vecbase<double,3>::operator-=(rhs);
00231 return *this;
00232 }
00233 math::vec3<T>& operator*=(const double rhs) {
00234 math::vecbase<double,3>::operator*=(rhs);
00235 return *this;
00236 }
00237 math::vec3<T>& operator/=(const double rhs) {
00238 math::vecbase<double,3>::operator/=(rhs);
00239 return *this;
00240 }
00242
00243 vec3<T> operator-() const { vec3<T> a(*this); a.minus(); return a; }
00244 vec3<T> operator+() const {return *this;}
00245 vec3<T> Abs() { vec3<T> a(*this); a.vecbase<T,3>::Abs(); return a; }
00246
00247 bool operator<(vec3<T> const & rhs) { return vecbase<T,3>::operator<(rhs); }
00248
00249 operator T* () const {return (T*) this;}
00250 operator const T* () const {return (const T*) this;}
00251
00252 #ifdef PHYSX
00253 operator physx::PxVec3() const { return physx::PxVec3(x(),y(),z()); }
00254 vec3<T>& operator=(physx::PxVec3 const & rhs) {
00255 vecbase<T,3>::v[0] = rhs.x;
00256 vecbase<T,3>::v[1] = rhs.y;
00257 vecbase<T,3>::v[2] = rhs.z;
00258 return *this;
00259 }
00260 #endif
00261
00262
00263
00264
00265
00266
00267
00268 void RotateAxis(double angle, const math::vec3<T> & axis) {
00269
00270 (*this) = GetRotatedAxis(angle, axis);
00271 }
00272
00273
00274 };
00275
00276 }
00277
00278 #endif //vec3<T>_H
00279
00280
00281
00282
00283
00284