Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

locmath.cpp

Go to the documentation of this file.
00001 #include <windows.h>
00002 #include "locmath.h"
00003 #include "vector.h"
00004 #include "quat.h"
00005 #include "vertex.h"
00006 #include "mmgr.h"
00007 
00008 void LoadIdentity(float m[])
00009 {
00010         m[0]=1.0f;
00011         m[1]=0.0f;
00012         m[2]=0.0f;
00013         m[3]=0.0f;
00014 
00015         m[4]=0.0f;
00016         m[5]=1.0f;
00017         m[6]=0.0f;
00018         m[7]=0.0f;
00019 
00020         m[8]=0.0f;
00021         m[9]=0.0f;
00022         m[10]=1.0f;
00023         m[11]=0.0f;
00024 
00025         m[12]=0.0f;
00026         m[13]=0.0f;
00027         m[14]=0.0f;
00028         m[15]=1.0f;
00029 }
00030 
00031 void CopyMatrix(float m[], float n[])
00032 {
00033         m[0 ] = n[0 ];
00034         m[1 ] = n[1 ];
00035         m[2 ] = n[2 ];
00036         m[3 ] = n[3 ];
00037         m[4 ] = n[4 ];
00038         m[5 ] = n[5 ];
00039         m[6 ] = n[6 ];
00040         m[7 ] = n[7 ];
00041         m[8 ] = n[8 ];
00042         m[9 ] = n[9 ];
00043         m[10] = n[10];
00044         m[11] = n[11];
00045         m[12] = n[12];
00046         m[13] = n[13];
00047         m[14] = n[14];
00048         m[15] = n[15];
00049 }
00050 
00051 void MultMatrix(float m[], float n[])
00052 {
00053         float temp[16];
00054 
00055         CopyMatrix(temp, m);
00056       m[0] = temp[0 ]*n[0 ]
00057                + temp[4 ]*n[1 ]
00058                + temp[8 ]*n[2 ]
00059                + temp[12]*n[3 ];
00060 
00061       m[1] = temp[1 ]*n[0 ]
00062                + temp[5 ]*n[1 ]
00063                + temp[9 ]*n[2 ]
00064                + temp[13]*n[3 ];
00065 
00066       m[2] = temp[2 ]*n[0 ]
00067                + temp[6 ]*n[1 ]
00068                + temp[10]*n[2 ]
00069                + temp[14]*n[3 ];
00070 
00071       m[3] = temp[3 ]*n[0 ]
00072                + temp[7 ]*n[1 ]
00073                + temp[11]*n[2 ]
00074                + temp[15]*n[3 ];
00075 
00076       m[4] = temp[0 ]*n[4 ]
00077                + temp[4 ]*n[5 ]
00078                + temp[8 ]*n[6 ]
00079                + temp[12]*n[7 ];
00080 
00081       m[5] = temp[1 ]*n[4 ]
00082                + temp[5 ]*n[5 ]
00083                + temp[9 ]*n[6 ]
00084                + temp[13]*n[7 ];
00085 
00086       m[6] = temp[2 ]*n[4 ]
00087                + temp[6 ]*n[5 ]
00088                + temp[10]*n[6 ]
00089                + temp[14]*n[7 ];
00090 
00091       m[7] = temp[3 ]*n[4 ]
00092                + temp[7 ]*n[5 ]
00093                + temp[11]*n[6 ]
00094                + temp[15]*n[7 ];
00095 
00096       m[8] = temp[0 ]*n[8 ]
00097                + temp[4 ]*n[9 ]
00098                + temp[8 ]*n[10]
00099                + temp[12]*n[11];
00100 
00101       m[9] = temp[1 ]*n[8 ]
00102                + temp[5 ]*n[9 ]
00103                + temp[9 ]*n[10]
00104                + temp[13]*n[11];
00105 
00106       m[10]= temp[2 ]*n[8 ]
00107                + temp[6 ]*n[9 ]
00108                + temp[10]*n[10]
00109                + temp[14]*n[11];
00110 
00111       m[11]= temp[3 ]*n[8 ]
00112                + temp[7 ]*n[9 ]
00113                + temp[11]*n[10]
00114                + temp[15]*n[11];
00115 
00116       m[12]= temp[0 ]*n[12]
00117                + temp[4 ]*n[13]
00118                + temp[8 ]*n[14]
00119                + temp[12]*n[15];
00120 
00121       m[13]= temp[1 ]*n[12]
00122                + temp[5 ]*n[13]
00123                + temp[9 ]*n[14]
00124                + temp[13]*n[15];
00125 
00126       m[14]= temp[2 ]*n[12]
00127                + temp[6 ]*n[13]
00128                + temp[10]*n[14]
00129                + temp[14]*n[15];
00130 
00131       m[15]= temp[3 ]*n[12]
00132                + temp[7 ]*n[13]
00133                + temp[11]*n[14]
00134                + temp[15]*n[15];
00135 }
00136 
00137 void MatrixInverse(float m[])
00138 {
00139     float n[16];
00140 
00141       CopyMatrix(n, m);
00142       m[0 ] = n[0 ];
00143       m[1 ] = n[4 ];
00144       m[2 ] = n[8 ];
00145 
00146       m[4 ] = n[1 ];
00147       m[5 ] = n[5 ];
00148       m[6 ] = n[9 ];
00149 
00150       m[8 ] = n[2 ];
00151       m[9 ] = n[6 ];
00152       m[10] = n[10];
00153 
00154       m[12] *= -1.0f;
00155       m[13] *= -1.0f;
00156       m[14] *= -1.0f;
00157 }
00158 
00159     /* The following routine converts an angle and a unit axis vector
00160         * to a matrix, returning the corresponding unit quaternion at no
00161         * extra cost. It is written in such a way as to allow both fixed
00162         * point and floating point versions to be created by appropriate
00163         * definitions of FPOINT, ANGLE, VECTOR, QUAT, MATRIX, MUL, HALF,
00164         * TWICE, COS, SIN, ONE, and ZERO.
00165         * The following is an example of floating point definitions.*/
00166 QUAT AxisAngleToMatrix(VECTOR axis, float theta, float m[16])
00167 {
00168         QUAT q;
00169         float halfTheta = theta * 0.5;
00170         float cosHalfTheta = cos(halfTheta);
00171         float sinHalfTheta = sin(halfTheta);
00172         float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
00173         q.x = axis.x * sinHalfTheta;
00174         q.y = axis.y * sinHalfTheta;
00175         q.z = axis.z * sinHalfTheta;
00176         q.w = cosHalfTheta;
00177         xs = q.x * 2;  ys = q.y * 2;  zs = q.z * 2;
00178         wx = q.w * xs; wy = q.w * ys; wz = q.w * zs;
00179         xx = q.x * xs; xy = q.x * ys; xz = q.x * zs;
00180         yy = q.y * ys; yz = q.y * zs; zz = q.z * zs;
00181         m[0] = 1 - (yy + zz);
00182         m[1] = xy - wz;
00183         m[2] = xz + wy;
00184         m[4] = xy + wz;
00185         m[5] = 1 - (xx + zz);
00186         m[6] = yz - wx;
00187         m[8] = xz - wy;
00188         m[9] = yz + wx;
00189         m[10] = 1 - (xx + yy);
00190         /* Fill in remainder of 4x4 homogeneous transform matrix. */
00191         m[12] = m[13] = m[14] = m[3] = m[7] = m[11] = 0;
00192         m[15] = 1;
00193         return (q);
00194 }
00195 
00196 float DotProduct(VECTOR vec1, VECTOR vec2)
00197 {
00198     /*
00199     Dot Product of two Vectors.
00200 
00201     U = (Ux, Uy, Uz)
00202     V = (Vx, Vy, Vz)
00203     U*V = UxVx + UyVy + UzVz
00204     U*V = |U||V|cos(t) (where t is the angle theta between the two vectors)
00205     */
00206       float dot;
00207       dot = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
00208       return dot;
00209 }
00210 
00211 VECTOR CrossVector(VECTOR vec1, VECTOR vec2)
00212 {
00213     /*
00214     Cross Product of Two Vectors.
00215 
00216     a × b = ( a.y * b.z - a.z * b.y,
00217 
00218     a.z * b.x - a.x * b.z,
00219 
00220     a.x * b.y - a.y * b.x )
00221 
00222     | a × b | = |a| * |b| * sin(ø)
00223     */
00224       VECTOR vec3;
00225       vec3.x = vec1.y * vec2.z - vec1.z * vec2.y;
00226       vec3.y = vec1.z * vec2.x - vec1.x * vec2.z;
00227       vec3.z = vec1.x * vec2.y - vec1.y * vec2.x;
00228       return vec3;
00229 }
00230 
00231 void EulerToQuat(float roll, float pitch, float yaw, QUAT * quat)
00232 {
00233     /*
00234     Euler Angle to Quarternion.
00235 
00236     q = qyaw qpitch qroll where:
00237 
00238     qyaw = [cos(f /2), (0, 0, sin(f /2)]
00239     qpitch = [cos (q/2), (0, sin(q/2), 0)]
00240     qroll = [cos (y/2), (sin(y/2), 0, 0)]
00241     */
00242     float cr, cp, cy, sr, sp, sy, cpcy, spsy;  // calculate trig identities
00243         cr = cos(roll/2);
00244     cp = cos(pitch/2);
00245         cy = cos(yaw/2);
00246         sr = sin(roll/2);
00247     sp = sin(pitch/2);
00248         sy = sin(yaw/2);
00249         cpcy = cp * cy;
00250         spsy = sp * sy;
00251     quat->w = cr * cpcy + sr * spsy;
00252         quat->x = sr * cpcy - cr * spsy;
00253     quat->y = cr * sp * cy + sr * cp * sy;
00254         quat->z = cr * cp * sy - sr * sp * cy;
00255 }
00256 
00257 float MagnitudeQuat(QUAT q1)
00258 {
00259       return( sqrt(q1.w*q1.w+q1.x*q1.x+q1.y*q1.y+q1.z*q1.z));
00260 }
00261 
00262 QUAT NormaliseQuat(QUAT q1)
00263 {
00264       QUAT q2;
00265       float Mag;
00266       Mag = MagnitudeQuat(q1);
00267       q2.w = q1.w/Mag;
00268       q2.x = q1.x/Mag;
00269       q2.y = q1.y/Mag;
00270       q2.z = q1.z/Mag;
00271       return q2;
00272 }
00273 
00274 void QuatToMatrix(QUAT quat, float m[16])
00275 {
00276       float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
00277       // calculate coefficients
00278       x2 = quat.x + quat.x;
00279       y2 = quat.y + quat.y;
00280       z2 = quat.z + quat.z;
00281       xx = quat.x * x2;
00282       xy = quat.x * y2;
00283       xz = quat.x * z2;
00284       yy = quat.y * y2;
00285       yz = quat.y * z2;
00286       zz = quat.z * z2;
00287       wx = quat.w * x2;
00288       wy = quat.w * y2;
00289       wz = quat.w * z2;
00290       m[0] = 1.0 - (yy + zz);
00291       m[1] = xy - wz;
00292       m[2] = xz + wy;
00293       m[3] = 0.0;
00294       m[4] = xy + wz;
00295       m[5] = 1.0 - (xx + zz);
00296       m[6] = yz - wx;
00297       m[7] = 0.0;
00298       m[8] = xz - wy;
00299       m[9] = yz + wx;
00300       m[10] = 1.0 - (xx + yy);
00301       m[11] = 0.0;
00302       m[12] = 0;
00303       m[13] = 0;
00304       m[14] = 0;
00305       m[15] = 1;
00306 }
00307 
00308 QUAT MultQuat(QUAT q1, QUAT q2)
00309 {
00310     /*
00311     Multiplication of two Quarternions.
00312 
00313     qq´ = [ww´ - v · v´, v x v´ + wv´ +w´v]
00314     ( · is vector dot product and x is vector cross product )
00315     */
00316       QUAT q3;
00317       VECTOR vectorq1;
00318       VECTOR vectorq2;
00319       vectorq1.x = q1.x;
00320       vectorq1.y = q1.y;
00321       vectorq1.z = q1.z;
00322       vectorq2.x = q2.x;
00323       vectorq2.y = q2.y;
00324       vectorq2.z = q2.z;
00325 
00326       VECTOR tempvec1;
00327       VECTOR tempvec2;
00328       VECTOR tempvec3;
00329       q3.w = (q1.w*q2.w) - DotProduct(vectorq1, vectorq2);
00330       tempvec1 = CrossVector(vectorq1, vectorq2);
00331       tempvec2.x = q1.w * q2.x;
00332       tempvec2.y = q1.w * q2.y;
00333       tempvec2.z = q1.w * q2.z;
00334       tempvec3.x = q2.w * q1.x;
00335       tempvec3.y = q2.w * q1.y;
00336       tempvec3.z = q2.w * q1.z;
00337       q3.x = tempvec1.x + tempvec2.x + tempvec3.x;
00338       q3.y = tempvec1.y + tempvec2.y + tempvec3.y;
00339       q3.z = tempvec1.z + tempvec2.z + tempvec3.z;
00340       return NormaliseQuat(q3);
00341 }
00342 
00343 VERTEX GetNorm(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
00344 {
00345         float ux;
00346         float uy;
00347         float uz;
00348         float vx;
00349         float vy;
00350         float vz;
00351           VERTEX temp_vertex;
00352           ux = x1 - x2;
00353           uy = y1 - y2;
00354           uz = z1 - z2;
00355           vx = x3 - x2;
00356           vy = y3 - y2;
00357           vz = z3 - z2;
00358           temp_vertex.nx = (uy*vz)-(vy*uz);
00359           temp_vertex.ny = (uz*vx)-(vz*ux);
00360           temp_vertex.nz = (ux*vy)-(vx*uy);
00361           return temp_vertex;
00362 }
00363 
00364 GLfloat MagnitudeVector(VECTOR vec1)
00365 {
00366   return(sqrt(vec1.x*vec1.x+vec1.y*vec1.y+vec1.z*vec1.z));
00367 }
00368 
00369 VECTOR GetUnitVector(VECTOR vector)
00370 {
00371         // Reduces a normal vector specified as a set of three coordinates,
00372         // to a unit normal vector of length one.
00373 
00374         // Calculate the length of the vector           
00375         float length = (float) sqrt(( vector.x * vector.x) + 
00376                                                         ( vector.y * vector.y) +
00377                                                         ( vector.z * vector.z) );
00378 
00379         // Keep the program from blowing up by providing an exceptable
00380         // value for vectors that may calculated too close to zero.
00381         if(length == 0.0f)
00382                 length = 1.0f;
00383 
00384         // Dividing each element by the length will result in a
00385         // unit normal vector.
00386         vector.x /= length;
00387         vector.y /= length;
00388         vector.z /= length;
00389         return vector;
00390 }
00391 
00392 VECTOR GetEdgeVector(VECTOR point1, VECTOR point2)
00393 {
00394   VECTOR temp_vector;
00395   temp_vector.x = point1.x - point2.x;
00396   temp_vector.y = point1.y - point2.y;
00397   temp_vector.z = point1.z - point2.z;
00398   return temp_vector;
00399 }

Generated on Fri Dec 23 05:20:18 2005 for Portals by doxygen1.2.15