afQuat.cpp
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:6k
源码类别:

其他游戏

开发平台:

Visual C++

  1. #include "afQuat.h"
  2. #include "afMathTool.h"
  3. /*************** CONSTRUCTORS *****************************************************/
  4. afQuat::afQuat( float xval, float yval, float zval, float wval ) 
  5. {
  6. x=xval; 
  7. y=yval; 
  8. z=zval; 
  9. w=wval;
  10. }
  11. afQuat::afQuat( const afQuat& other )
  12. {
  13.     x = other.x;
  14.     y = other.y;
  15. z = other.z;
  16. w = other.w;
  17. }
  18. afQuat::afQuat (const afVec3& dir)
  19. {
  20. set(dir);
  21. }
  22. /*************** OPERATORS *****************************************************/
  23. afQuat& afQuat::operator= (const afQuat& quat)
  24. {
  25. x = quat.x;
  26. y = quat.y;
  27. z = quat.z;
  28. w = quat.w;
  29. return *this;
  30. }
  31. afQuat afQuat::operator* (const afQuat& quat)
  32. {
  33. return afQuat ( w*quat.x + x*quat.w + y*quat.z - z*quat.y, 
  34. w*quat.y + y*quat.w + z*quat.x - x*quat.z,
  35. w*quat.z + z*quat.w + x*quat.y - y*quat.x, 
  36. w*quat.w - x*quat.x - y*quat.y - z*quat.z );
  37. }
  38. afQuat& afQuat::operator*= (const afQuat& quat)
  39. {
  40. float tempx = x*quat.x - y*quat.y - z*quat.z - w*quat.w;
  41. float tempy = x*quat.y + y*quat.x + z*quat.w - w*quat.z;
  42. float tempz = x*quat.z - y*quat.w + z*quat.x + w*quat.y;
  43. float tempw = x*quat.w + y*quat.z - z*quat.y + w*quat.x;
  44. x=tempx;
  45. y=tempy;
  46. z=tempz;
  47. w=tempw;
  48. return *this;
  49. }
  50. afQuat& afQuat::operator>= (const afQuat& quat)
  51. {
  52. float tempx = quat.x*x - quat.y*y - quat.z*z - quat.w*w;
  53. float tempy = quat.y*x + quat.x*y + quat.w*z - quat.z*w;
  54. float tempz = quat.z*x - quat.w*y + quat.x*z + quat.y*w;
  55. float tempw = quat.w*x + quat.z*y - quat.y*z + quat.x*w;
  56. x=tempx;
  57. y=tempy;
  58. z=tempz;
  59. w=tempw;
  60. return *this;
  61. }
  62. bool afQuat::operator== (const afQuat& quat)
  63. {
  64. return ( (x == quat.x) && (y == quat.y) && (z == quat.z) && (w == quat.w)  );
  65. }
  66. bool afQuat::operator!= (const afQuat& quat)
  67. {
  68. return ( (x!=quat.x) || (y!=quat.y) || (z!=quat.z) || (w!=quat.w) );
  69. }
  70. /***************** MEMBER FUNCTIONS ************************************************/
  71. void afQuat::setMatrix(afMatrix& mat)
  72. {
  73. float xx = x*x;
  74.     float xy = x*y;
  75.     float xz = x*z;
  76.     float xw = x*w;
  77.     float yy = y*y;
  78.     float yz = y*z;
  79.     float yw = y*w;
  80.     float zz = z*z;
  81.     float zw = z*w;
  82.     mat.m00 = 1-2*( yy+zz );
  83.     mat.m10 =   2*( xy+zw );
  84.     mat.m20 =   2*( xz-yw );
  85.     mat.m01 =   2*( xy-zw );
  86.     mat.m11 = 1-2*( xx+zz );
  87.     mat.m21 =   2*( yz+xw );
  88.     mat.m02 =   2*( xz+yw );
  89.     mat.m12 =   2*( yz-xw );
  90.     mat.m22 = 1-2*( xx+yy );
  91.     mat.m30 = mat.m31 = mat.m32 = mat.m03 = mat.m13 = mat.m23 = 0;
  92.     mat.m33 = 1;
  93. }
  94. void afQuat::set(const afVec3& dir) 
  95. {    
  96. float c1 = afMathTool::cos(dir.x);    
  97. float s1 = afMathTool::sin(dir.x);    
  98. float c2 = afMathTool::cos(dir.y);    
  99. float s2 = afMathTool::sin(dir.y);    
  100. float c3 = afMathTool::cos(dir.z);    
  101. float s3 = afMathTool::sin(dir.z);
  102. x = c1*c2*c3 + s1*s2*s3;
  103. y = c1*c2*s3 - s1*s2*c3;
  104. z = c1*s2*c3 + s1*c2*s3;
  105. w = s1*c2*c3 - c1*s2*s3;
  106. }
  107. void afQuat::set(const afMatrix& mat)
  108. {
  109. float  tr, s, q[4];
  110. int    i, j, k;
  111. int nxt[3] = {1, 2, 0};
  112. tr = mat[0][0] + mat[1][1] + mat[2][2];
  113. // check the diagonal
  114. if (tr > 0.0) 
  115. {
  116. s = afMathTool::sqrt (tr + 1.0f);
  117. w = s / 2.0f;
  118. s = 0.5f / s;
  119. x = (mat.m12 - mat.m21) * s;
  120. y = (mat.m20 - mat.m02) * s;
  121. z = (mat.m01 - mat.m10) * s;
  122. else 
  123. {
  124. // diagonal is negative
  125. i = 0;
  126. if (mat.m11 > mat.m00) i = 1;
  127. if (mat.m22 > mat[i][i]) i = 2;
  128. j = nxt[i];
  129. k = nxt[j];
  130. s = afMathTool::sqrt ((mat[i][i] - (mat[j][j] + mat[k][k])) + 1.0f);
  131. q[i] = s * 0.5f;
  132. if (s != 0.0f) s = 0.5f / s;
  133. q[3] = (mat[j][k] - mat[k][j]) * s;
  134. q[j] = (mat[i][j] + mat[j][i]) * s;
  135. q[k] = (mat[i][k] + mat[k][i]) * s;
  136. x = q[0];
  137. y = q[1];
  138. z = q[2];
  139. w = q[3];
  140. }
  141. }
  142. void afQuat::makeRotX (float nX)
  143. {
  144. x = afMathTool::sin(nX*0.5f);
  145. y = 0.0f;
  146. z = 0.0f;
  147. w = afMathTool::cos(nX*0.5f);
  148. }
  149. void afQuat::makeRotY (float nY)
  150. {
  151. x = 0.0f;
  152. y = afMathTool::sin(nY*0.5f);
  153. z = 0.0f;
  154. w = afMathTool::cos(nY*0.5f);
  155. }
  156. void afQuat::makeRotZ (float nZ)
  157. {
  158. x = 0.0f;
  159. y = 0.0f;
  160. z = afMathTool::sin(nZ*0.5f);
  161. w = afMathTool::cos(nZ*0.5f);
  162. }
  163. float afQuat::dot(const afQuat& left,const afQuat& right)
  164. {
  165.     return left.x*right.x+left.y*right.y+left.z*right.z+left.w*right.w;
  166. }
  167. /*
  168. void
  169. afQuat::Slerp(const afQuat& from,const afQuat& to,float slice)
  170. {
  171. float to1[4];
  172. float omega, cosom, sinom, scale0, scale1;
  173. // calc cosine
  174. cosom = from.x * to.x + from.y * to.y + from.z * to.z+ from.w * to.w;
  175. // adjust signs (if necessary)
  176. if ( cosom <0.0 )
  177. cosom = -cosom; to1[0] = - to.x;
  178. to1[1] = - to.y;
  179. to1[2] = - to.z;
  180. to1[3] = - to.w;
  181. else  
  182. {
  183. to1[0] = to.x;
  184. to1[1] = to.y;
  185. to1[2] = to.z;
  186. to1[3] = to.w;
  187. }
  188. // calculate coefficients
  189. if ( (1.0 - cosom) > FLT_EPSILON ) 
  190. {
  191. // standard case (slerp)
  192. omega = afAcos(cosom);
  193. sinom = afSin(omega);
  194. scale0 = afSin((1.0f - slice) * omega) / sinom;
  195. scale1 = afSin(slice * omega) / sinom;
  196. else 
  197. {        
  198. // "from" and "to" quaternions are very close 
  199. //  ... so we can do a linear interpolation
  200. scale0 = 1.0f - slice;
  201. scale1 = slice;
  202. }
  203. // calculate final values
  204. x = scale0 * from.x + scale1 * to1[0];
  205. y = scale0 * from.y + scale1 * to1[1];
  206. z = scale0 * from.z + scale1 * to1[2];
  207. w = scale0 * from.w + scale1 * to1[3];
  208. }
  209. afQuat
  210. afQuat::conjugate()
  211. {
  212. return afQuat(x,-y,-z,-w);
  213. }
  214. float
  215. afQuat::norm2()
  216. {
  217. return (x*x+y*y+z*z+w*w);
  218. }
  219. afQuat
  220. afQuat::inverse()
  221. {
  222. float  n = norm2();
  223. afQuat q = conjugate();
  224. if (n>FLT_EPSILON)
  225.         return afQuat(q.x/n,q.y/n,q.z/n,q.w/n);
  226. else
  227.         return afQuat(q.x,q.y,q.z,q.w);
  228. }
  229. float
  230. afQuat::normalize()
  231. {
  232. float  n = afSqrt(norm2());
  233. if (n>FLT_EPSILON)
  234. {
  235. x /= n;
  236. y /= n;
  237. z /= n;
  238. w /= n;
  239. }
  240. return n;
  241. }*/