00001 // RC 6/11/2002 \Randy95\Include\Rotate.h 00002 00003 #define __ROTATE_H 00004 00005 #ifndef __VECTOR_H 00006 #include "Vector.h" 00007 #endif 00008 #ifndef __QUATERNI_H 00009 #include "Quaterni.h" 00010 #endif 00011 00012 class Rotate { 00013 public: 00014 float swivel, tilt, roll; 00015 // x z y 00016 00017 Rotate() {} 00018 Rotate( const float scalar ) { swivel = tilt = roll = scalar; } 00019 Rotate( const float pswivel, const float ptilt, const float proll ) 00020 { swivel = pswivel; tilt = ptilt; roll = proll; } 00021 int operator == ( const Rotate &a ) const { return swivel==a.swivel && tilt == a.tilt && roll==a.roll; } 00022 int operator != ( const Rotate &a ) const { return !(*this == a); } 00023 }; 00024 00025 class RotateSphere; 00026 class RotateEuler; 00027 00028 class RotateVector { 00029 public: 00030 Vector end; 00031 float roll; 00032 00033 RotateVector() {} 00034 RotateVector( const Vector &pend, float proll ) { end=pend; roll=proll; } 00035 ~RotateVector() {} 00036 RotateVector( const RotateSphere &sphere ); 00037 RotateVector( const RotateEuler &euler ); 00038 RotateVector( const Matrix34 &matrix ); 00039 RotateVector( const Quaternion &quat ); 00040 00041 friend int operator != ( const RotateVector &a, const RotateVector &b ) 00042 { return a.end!=b.end || a.roll!=b.roll; } 00043 }; 00044 00045 class RotateSphere { 00046 public: 00047 float latitude, 00048 longitude, 00049 roll; 00050 RotateSphere() {} 00051 ~RotateSphere() {} 00052 RotateSphere( const Vector &vec ); 00053 RotateSphere( const RotateVector &rotateend ); 00054 RotateSphere( const Quaternion &quat ); 00055 RotateSphere( const Quaternion &quat, Bone *bone ); 00056 }; 00057 00058 class RotateEuler { 00059 public: 00060 float x, y, z; 00061 00062 RotateEuler() {} 00063 ~RotateEuler() {} 00064 RotateEuler( float px, float py, float pz ) { x=px; y=py; z=pz; } 00065 RotateEuler( const Matrix34 &t ); 00066 RotateEuler( const RotateVector &rotateend ); 00067 RotateEuler( const Quaternion &quat ); 00068 void ToEuler( const Matrix34 &t ); 00069 RotateEuler operator * ( float scale ) { RotateEuler other; other.x = x * scale; other.y = y * scale; other.z = z * scale; return other; } 00070 float operator[]( int i ) const 00071 { 00072 return (&x)[i]; 00073 } 00074 float &operator[]( int i ) 00075 { 00076 return (&x)[i]; 00077 } 00078 }; 00079 00080 class TSR { 00081 public: 00082 Vector translate; 00083 Vector scale; 00084 RotateVector rotate; 00085 00086 friend int operator != ( const TSR &a, const TSR &b ) 00087 { return a.rotate!=b.rotate || a.translate!=b.translate || a.scale!=b.scale; } 00088 void SetDefault() 00089 { translate.Set(0.0f); scale.Set(1.0f); rotate.end.Set(0.0f,0.0f,1.0f); rotate.roll=0.0f; } 00090 }; 00091 00092 class MATRIXEXPORT TSQ { 00093 public: 00094 Vector translate; 00095 Vector scale; 00096 Quaternion quat; 00097 float roll; 00098 BOOL m_isrollcomputed; 00099 00100 TSQ(){} 00101 TSQ(const Matrix34 &actionmatrix); 00102 TSQ(const Vector &ptranslate, const Vector &pscale, const Quaternion &pquat) 00103 { 00104 translate = ptranslate; 00105 scale = pscale; 00106 quat = pquat; 00107 } 00108 00109 int operator != ( const TSQ &b ) const 00110 { return quat!=b.quat || translate!=b.translate || scale!=b.scale; } 00111 void SetDefault() 00112 { translate.Set(0.0f); scale.Set(1.0f); quat.SetIdentity(); } 00113 TSQ &operator += ( const TSQ &other ) 00114 { 00115 translate += other.translate; 00116 scale += other.scale; 00117 quat += other.quat; 00118 return *this; 00119 } 00120 TSQ &operator *= ( float scalar ) 00121 { 00122 translate *= scalar; 00123 scale *= scalar; 00124 quat *= scalar; 00125 return *this; 00126 } 00127 void PostBlend() 00128 { 00129 quat.Normalize(); 00130 } 00131 void FillMatrices( Matrix34 &matrix, Matrix34 &inverse ); 00132 }; 00133 00134 // ANY ROTATION TYPE TO AND FROM QUATERNION 00135 00136 inline RotateEuler::RotateEuler( const Quaternion &quat ) 00137 { 00138 Vector end( quat.GetZAxis()); 00139 y = (float)(atan2( end.x, end.z ) * RADIANS); 00140 x = (float)(atan2( -end.y, sqrt(end.x*end.x + end.z*end.z)) * RADIANS); 00141 Vector rolldir( quat.GetYAxis()); 00142 rolldir *= YXRotateQ( y, x ).Inverse(); 00143 z = (float)(atan2( -rolldir.x, rolldir.y ) * RADIANS); 00144 } 00145 00146 inline RotateVector::RotateVector( const Quaternion &quat ) // SOB STYLE ROLL 00147 { 00148 end = quat.GetZAxis(); 00149 float y = (float)atan2( end.x, end.z ); 00150 float x = (float)atan2( -end.y, (float)sqrt(end.x*end.x + end.z*end.z)); 00151 Vector rolldir = quat.GetYAxis(); 00152 rolldir *= YXRotateRadiansQ( y, x ).Inverse(); 00153 roll = (float)atan2( -rolldir.x, rolldir.y ) * RADIANS; 00154 } 00155 00156 inline Quaternion::Quaternion( const RotateVector &rv ) // SOB STYLE ROLL 00157 { 00158 float y = (float)atan2( rv.end.x, rv.end.z ); 00159 float x = (float)atan2( -rv.end.y, (float)sqrt(rv.end.x*rv.end.x + rv.end.z*rv.end.z)); 00160 if ( rv.roll ) 00161 *this = YXZRotateRadiansQ( y, x, rv.roll / RADIANS ); 00162 else 00163 *this = YXRotateRadiansQ( y, x ); 00164 } 00165 00166 inline RotateSphere::RotateSphere( const Quaternion &quat ) 00167 { 00168 *this = RotateSphere(RotateVector(quat)); 00169 } 00170 00171 inline Quaternion::Quaternion( const RotateSphere &rs ) 00172 { 00173 *this = Quaternion(RotateVector(rs)); 00174 } 00175 00176 inline Quaternion::Quaternion( const RotateEuler &re ) 00177 { 00178 if ( re.z ) 00179 *this = YXZRotateQ( re.y, re.x, re.z ); 00180 else 00181 *this = YXRotateQ( re.y, re.x ); 00182 } 00183 00184 inline Quaternion::Quaternion( const RotateEuler &re, BOOL isyxz ) 00185 { 00186 if (isyxz) { 00187 if ( re.z ) 00188 *this = YXZRotateQ( re.y, re.x, re.z ); 00189 else 00190 *this = YXRotateQ( re.y, re.x ); 00191 } 00192 else { 00193 if ( re.z ) 00194 *this = XYZRotateQ( re.x, re.y, re.z ); 00195 else 00196 *this = XYRotateQ( re.x, re.y ); 00197 } 00198 } 00199 00200 // CONVERSIONS BETWEEN ROTATE TYPES 00201 00202 inline RotateSphere::RotateSphere( const Vector &vec ) 00203 { 00204 longitude = (float)atan2( -vec.x, vec.y )*RADIANS; 00205 latitude = (float)atan2( (float)sqrt(vec.x*vec.x + vec.y*vec.y), vec.z )*RADIANS; 00206 } 00207 00208 inline RotateSphere::RotateSphere( const RotateVector &rotate ) 00209 { 00210 longitude = (float)atan2( -rotate.end.x, rotate.end.y )*RADIANS; 00211 latitude = (float)atan2( (float)sqrt(rotate.end.x*rotate.end.x + rotate.end.y*rotate.end.y), 00212 rotate.end.z )*RADIANS; 00213 roll = rotate.roll; 00214 } 00215 00216 inline RotateVector::RotateVector( const RotateSphere &sphere ) 00217 { 00218 float r = (float)sin( sphere.latitude/RADIANS ); 00219 end.z = (float)cos( sphere.latitude/RADIANS ); 00220 end.y = r * (float)cos( sphere.longitude/RADIANS ); 00221 end.x = -r * (float)sin( sphere.longitude/RADIANS ); 00222 roll = sphere.roll; 00223 } 00224 00225 inline RotateVector::RotateVector( const RotateEuler &euler ) 00226 { 00227 float cy = (float)cos( euler.y / RADIANS ), 00228 sy = (float)sin( euler.y / RADIANS ), 00229 cx = (float)cos( euler.x / RADIANS ), 00230 sx = (float)sin( euler.x / RADIANS ); 00231 end.Set( sy*cx, -sx, cy*cx ); // SPEED UP: THESE ARE THE Z COLUMN OUT OF YXROTATE, WHICH IS THE SAME AS BUILDING THAT MATRIX, THEN TRANSFORMING (0,0,1) BY IT 00232 roll = euler.z; 00233 } 00234 00235 inline RotateEuler::RotateEuler( const RotateVector &rotatev ) 00236 { 00237 y = (float)atan2( rotatev.end.x, rotatev.end.z ) * RADIANS; 00238 x = (float)atan2( -rotatev.end.y, (float)sqrt(rotatev.end.x*rotatev.end.x + 00239 rotatev.end.z*rotatev.end.z)) * RADIANS; 00240 z = rotatev.roll; 00241 } 00242 00243 // THE 4 FUNCTIONS BELOW WORK ONLY 0 TO 90 DEGREES 00244 00245 inline float VectorsToLinear( const Vector &v, const Vector &v1 ) 00246 { 00247 float cosa = Dot(v.Normalized(), v1.Normalized()); 00248 if ( cosa == 0.0f ) 00249 return 0.0f; 00250 float sina = (float)sqrt( 1.0f - cosa*cosa ); 00251 float slope = sina / cosa; 00252 float percent = slope / (slope + 1.0f); 00253 return percent *= 90.0f; 00254 } 00255 00256 inline float VectorsToAngle( const Vector &v, const Vector &v1 ) 00257 { 00258 return (float)acos(Dot(v.Normalized(), v1.Normalized())) * RADIANS; 00259 } 00260 00261 inline float LinearToAngle( float linear ) 00262 { 00263 return (float)atan( linear / (90-linear)) * RADIANS; 00264 } 00265 00266 inline float LinearToAngle360( float linear ) 00267 { 00268 if ( linear < 0 ) 00269 return -LinearToAngle360( -linear ); 00270 if ( linear <= 90 ) 00271 return LinearToAngle( linear ); 00272 float remainder = (float)fmod( linear, 90 ); 00273 float excess = linear - remainder; 00274 return excess + LinearToAngle( remainder ); 00275 } 00276
Generated on Thu Oct 27 11:46:45 2005 with
1.4.5 written by Dimitri van Heesch,
© 1997-2001