afQuat.cpp
资源名称:AirForce.rar [点击查看]
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:6k
源码类别:
其他游戏
开发平台:
Visual C++
- #include "afQuat.h"
- #include "afMathTool.h"
- /*************** CONSTRUCTORS *****************************************************/
- afQuat::afQuat( float xval, float yval, float zval, float wval )
- {
- x=xval;
- y=yval;
- z=zval;
- w=wval;
- }
- afQuat::afQuat( const afQuat& other )
- {
- x = other.x;
- y = other.y;
- z = other.z;
- w = other.w;
- }
- afQuat::afQuat (const afVec3& dir)
- {
- set(dir);
- }
- /*************** OPERATORS *****************************************************/
- afQuat& afQuat::operator= (const afQuat& quat)
- {
- x = quat.x;
- y = quat.y;
- z = quat.z;
- w = quat.w;
- return *this;
- }
- afQuat afQuat::operator* (const afQuat& quat)
- {
- return afQuat ( w*quat.x + x*quat.w + y*quat.z - z*quat.y,
- w*quat.y + y*quat.w + z*quat.x - x*quat.z,
- w*quat.z + z*quat.w + x*quat.y - y*quat.x,
- w*quat.w - x*quat.x - y*quat.y - z*quat.z );
- }
- afQuat& afQuat::operator*= (const afQuat& quat)
- {
- float tempx = x*quat.x - y*quat.y - z*quat.z - w*quat.w;
- float tempy = x*quat.y + y*quat.x + z*quat.w - w*quat.z;
- float tempz = x*quat.z - y*quat.w + z*quat.x + w*quat.y;
- float tempw = x*quat.w + y*quat.z - z*quat.y + w*quat.x;
- x=tempx;
- y=tempy;
- z=tempz;
- w=tempw;
- return *this;
- }
- afQuat& afQuat::operator>= (const afQuat& quat)
- {
- float tempx = quat.x*x - quat.y*y - quat.z*z - quat.w*w;
- float tempy = quat.y*x + quat.x*y + quat.w*z - quat.z*w;
- float tempz = quat.z*x - quat.w*y + quat.x*z + quat.y*w;
- float tempw = quat.w*x + quat.z*y - quat.y*z + quat.x*w;
- x=tempx;
- y=tempy;
- z=tempz;
- w=tempw;
- return *this;
- }
- bool afQuat::operator== (const afQuat& quat)
- {
- return ( (x == quat.x) && (y == quat.y) && (z == quat.z) && (w == quat.w) );
- }
- bool afQuat::operator!= (const afQuat& quat)
- {
- return ( (x!=quat.x) || (y!=quat.y) || (z!=quat.z) || (w!=quat.w) );
- }
- /***************** MEMBER FUNCTIONS ************************************************/
- void afQuat::setMatrix(afMatrix& mat)
- {
- float xx = x*x;
- float xy = x*y;
- float xz = x*z;
- float xw = x*w;
- float yy = y*y;
- float yz = y*z;
- float yw = y*w;
- float zz = z*z;
- float zw = z*w;
- mat.m00 = 1-2*( yy+zz );
- mat.m10 = 2*( xy+zw );
- mat.m20 = 2*( xz-yw );
- mat.m01 = 2*( xy-zw );
- mat.m11 = 1-2*( xx+zz );
- mat.m21 = 2*( yz+xw );
- mat.m02 = 2*( xz+yw );
- mat.m12 = 2*( yz-xw );
- mat.m22 = 1-2*( xx+yy );
- mat.m30 = mat.m31 = mat.m32 = mat.m03 = mat.m13 = mat.m23 = 0;
- mat.m33 = 1;
- }
- void afQuat::set(const afVec3& dir)
- {
- float c1 = afMathTool::cos(dir.x);
- float s1 = afMathTool::sin(dir.x);
- float c2 = afMathTool::cos(dir.y);
- float s2 = afMathTool::sin(dir.y);
- float c3 = afMathTool::cos(dir.z);
- float s3 = afMathTool::sin(dir.z);
- x = c1*c2*c3 + s1*s2*s3;
- y = c1*c2*s3 - s1*s2*c3;
- z = c1*s2*c3 + s1*c2*s3;
- w = s1*c2*c3 - c1*s2*s3;
- }
- void afQuat::set(const afMatrix& mat)
- {
- float tr, s, q[4];
- int i, j, k;
- int nxt[3] = {1, 2, 0};
- tr = mat[0][0] + mat[1][1] + mat[2][2];
- // check the diagonal
- if (tr > 0.0)
- {
- s = afMathTool::sqrt (tr + 1.0f);
- w = s / 2.0f;
- s = 0.5f / s;
- x = (mat.m12 - mat.m21) * s;
- y = (mat.m20 - mat.m02) * s;
- z = (mat.m01 - mat.m10) * s;
- }
- else
- {
- // diagonal is negative
- i = 0;
- if (mat.m11 > mat.m00) i = 1;
- if (mat.m22 > mat[i][i]) i = 2;
- j = nxt[i];
- k = nxt[j];
- s = afMathTool::sqrt ((mat[i][i] - (mat[j][j] + mat[k][k])) + 1.0f);
- q[i] = s * 0.5f;
- if (s != 0.0f) s = 0.5f / s;
- q[3] = (mat[j][k] - mat[k][j]) * s;
- q[j] = (mat[i][j] + mat[j][i]) * s;
- q[k] = (mat[i][k] + mat[k][i]) * s;
- x = q[0];
- y = q[1];
- z = q[2];
- w = q[3];
- }
- }
- void afQuat::makeRotX (float nX)
- {
- x = afMathTool::sin(nX*0.5f);
- y = 0.0f;
- z = 0.0f;
- w = afMathTool::cos(nX*0.5f);
- }
- void afQuat::makeRotY (float nY)
- {
- x = 0.0f;
- y = afMathTool::sin(nY*0.5f);
- z = 0.0f;
- w = afMathTool::cos(nY*0.5f);
- }
- void afQuat::makeRotZ (float nZ)
- {
- x = 0.0f;
- y = 0.0f;
- z = afMathTool::sin(nZ*0.5f);
- w = afMathTool::cos(nZ*0.5f);
- }
- float afQuat::dot(const afQuat& left,const afQuat& right)
- {
- return left.x*right.x+left.y*right.y+left.z*right.z+left.w*right.w;
- }
- /*
- void
- afQuat::Slerp(const afQuat& from,const afQuat& to,float slice)
- {
- float to1[4];
- float omega, cosom, sinom, scale0, scale1;
- // calc cosine
- cosom = from.x * to.x + from.y * to.y + from.z * to.z+ from.w * to.w;
- // adjust signs (if necessary)
- if ( cosom <0.0 )
- {
- cosom = -cosom; to1[0] = - to.x;
- to1[1] = - to.y;
- to1[2] = - to.z;
- to1[3] = - to.w;
- }
- else
- {
- to1[0] = to.x;
- to1[1] = to.y;
- to1[2] = to.z;
- to1[3] = to.w;
- }
- // calculate coefficients
- if ( (1.0 - cosom) > FLT_EPSILON )
- {
- // standard case (slerp)
- omega = afAcos(cosom);
- sinom = afSin(omega);
- scale0 = afSin((1.0f - slice) * omega) / sinom;
- scale1 = afSin(slice * omega) / sinom;
- }
- else
- {
- // "from" and "to" quaternions are very close
- // ... so we can do a linear interpolation
- scale0 = 1.0f - slice;
- scale1 = slice;
- }
- // calculate final values
- x = scale0 * from.x + scale1 * to1[0];
- y = scale0 * from.y + scale1 * to1[1];
- z = scale0 * from.z + scale1 * to1[2];
- w = scale0 * from.w + scale1 * to1[3];
- }
- afQuat
- afQuat::conjugate()
- {
- return afQuat(x,-y,-z,-w);
- }
- float
- afQuat::norm2()
- {
- return (x*x+y*y+z*z+w*w);
- }
- afQuat
- afQuat::inverse()
- {
- float n = norm2();
- afQuat q = conjugate();
- if (n>FLT_EPSILON)
- return afQuat(q.x/n,q.y/n,q.z/n,q.w/n);
- else
- return afQuat(q.x,q.y,q.z,q.w);
- }
- float
- afQuat::normalize()
- {
- float n = afSqrt(norm2());
- if (n>FLT_EPSILON)
- {
- x /= n;
- y /= n;
- z /= n;
- w /= n;
- }
- return n;
- }*/