00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <common/FixedVector4.h>
00022 #include <common/Defines.h>
00023
00024
00025 #define _R(i,j) R[(i)*4+(j)]
00026 #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[(p)*2]*(b)[(q)*2])
00027 #define dDOT41(a,b) dDOTpq(a,b,4,1)
00028 #define dDOT(a,b) dDOTpq(a,b,1,1)
00029 #define dMULTIPLYOP1_331(A,op,B,C) \
00030 do { \
00031 (A)[0] op dDOT41((B),(C)); \
00032 (A)[1] op dDOT41((B+1),(C)); \
00033 (A)[2] op dDOT41((B+2),(C)); \
00034 } while(0)
00035 #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
00036
00037 static FixedVector4 nullVector;
00038
00039 FixedVector4 &FixedVector4::getNullVector()
00040 {
00041 nullVector.zero();
00042 return nullVector;
00043 }
00044
00045 void FixedVector4::setQuatFromAxisAndAngle(FixedVector &axis, fixed angle)
00046 {
00047 fixed l = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2];
00048 if (l > 0)
00049 {
00050 angle /= 2;;
00051 V[0] = angle.cos();
00052 l = angle.sin() * (fixed(1)/l.sqrt());
00053 V[1] = axis[0] * l;
00054 V[2] = axis[1] * l;
00055 V[3] = axis[2] * l;
00056 }
00057 else
00058 {
00059 V[0] = 1;
00060 V[1] = 0;
00061 V[2] = 0;
00062 V[3] = 0;
00063 }
00064 }
00065
00066
00067
00068
00069
00070 void FixedVector4::getRotationMatrix(fixed *R)
00071 {
00072
00073 fixed qq1 = V[1]*V[1]*2;
00074 fixed qq2 = V[2]*V[2]*2;
00075 fixed qq3 = V[3]*V[3]*2;
00076 _R(0,0) = fixed(1) - qq2 - qq3;
00077 _R(0,1) = fixed(2)*(V[1]*V[2] - V[0]*V[3]);
00078 _R(0,2) = fixed(2)*(V[1]*V[3] + V[0]*V[2]);
00079 _R(0,3) = 0;
00080 _R(1,0) = fixed(2)*(V[1]*V[2] + V[0]*V[3]);
00081 _R(1,1) = fixed(1) - qq1 - qq3;
00082 _R(1,2) = fixed(2)*(V[2]*V[3] - V[0]*V[1]);
00083 _R(1,3) = fixed(0);
00084 _R(2,0) = fixed(2)*(V[1]*V[3] - V[0]*V[2]);
00085 _R(2,1) = fixed(2)*(V[2]*V[3] + V[0]*V[1]);
00086 _R(2,2) = fixed(1) - qq1 - qq2;
00087 _R(2,3) = 0;
00088 }
00089
00090 void FixedVector4::getOpenGLRotationMatrix(float *rotMatrix)
00091 {
00092 static fixed matrix[12];
00093 getRotationMatrix(matrix);
00094
00095 rotMatrix[0] = matrix[0].asFloat();
00096 rotMatrix[1] = matrix[4].asFloat();
00097 rotMatrix[2] = matrix[8].asFloat();
00098 rotMatrix[4] = matrix[1].asFloat();
00099 rotMatrix[5] = matrix[5].asFloat();
00100 rotMatrix[6] = matrix[9].asFloat();
00101 rotMatrix[8] = matrix[2].asFloat();
00102 rotMatrix[9] = matrix[6].asFloat();
00103 rotMatrix[10] = matrix[10].asFloat();
00104 rotMatrix[3] = rotMatrix[7] = rotMatrix[11] = 0.0f;
00105 rotMatrix[15] = 1.0f;
00106 rotMatrix[12] = rotMatrix[13] = rotMatrix[14] = 0.0f;
00107 }
00108
00109 void FixedVector4::Normalize()
00110 {
00111 fixed l = dDOT(V,V) + V[3] * V[3];
00112 if (l > 0)
00113 {
00114 l = fixed(1) / l.sqrt();
00115 V[0] *= l;
00116 V[1] *= l;
00117 V[2] *= l;
00118 V[3] *= l;
00119 }
00120 else
00121 {
00122 V[0] = 1;
00123 V[1] = 0;
00124 V[2] = 0;
00125 V[3] = 0;
00126 }
00127 }
00128
00129 void FixedVector4::getRelativeVector(FixedVector &r, FixedVector &p)
00130 {
00131 static fixed matrix[12];
00132 getRotationMatrix(matrix);
00133
00134 fixed *result = r;
00135 fixed *position = p;
00136 dMULTIPLY1_331(result, matrix, position);
00137 }
00138
00139 void FixedVector4::dDQfromW(FixedVector4 &dq, FixedVector &w, FixedVector4 &q)
00140 {
00141 dq[0] = (- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]) / 2;
00142 dq[1] = ( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]) / 2;
00143 dq[2] = (- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]) / 2;
00144 dq[3] = ( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]) / 2;
00145 }