1 #include "Quaternions.h"
4 quaternion Quat_Mult(quaternion q1, quaternion q2)
7 float a, b, c, d, e, f, g, h;
8 a = (q1.w + q1.x) * (q2.w + q2.x);
9 b = (q1.z - q1.y) * (q2.y - q2.z);
10 c = (q1.w - q1.x) * (q2.y + q2.z);
11 d = (q1.y + q1.z) * (q2.w - q2.x);
12 e = (q1.x + q1.z) * (q2.x + q2.y);
13 f = (q1.x - q1.z) * (q2.x - q2.y);
14 g = (q1.w + q1.y) * (q2.w - q2.z);
15 h = (q1.w - q1.y) * (q2.w + q2.z);
16 QResult.w = b + (-e - f + g + h) / 2;
17 QResult.x = a - (e + f + g + h) / 2;
18 QResult.y = c + (e - f + g - h) / 2;
19 QResult.z = d + (e - f - g + h) / 2;
25 quaternion To_Quat(Matrix_t m)
27 // From Jason Shankel, (C) 2000.
28 static quaternion Quat;
30 static double Tr = m[0][0] + m[1][1] + m[2][2] + 1.0, fourD;
36 fourD = 2.0*fast_sqrt(Tr);
38 q[0] = (m[2][1] - m[1][2]) / fourD;
39 q[1] = (m[0][2] - m[2][0]) / fourD;
40 q[2] = (m[1][0] - m[0][1]) / fourD;
44 if (m[0][0] > m[1][1])
52 if (m[2][2] > m[i][i])
58 fourD = 2.0*fast_sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0);
60 q[j] = (m[j][i] + m[i][j]) / fourD;
61 q[k] = (m[k][i] + m[i][k]) / fourD;
62 q[3] = (m[j][k] - m[k][j]) / fourD;
71 void Quat_2_Matrix(quaternion Quat, Matrix_t m)
73 // From the GLVelocity site (http://glvelocity.gamedev.net)
81 m[0][0] = 1.0f - 2.0f * (fYY + fZZ);
82 m[1][0] = 2.0f * (fX * fY + fW * fZ);
83 m[2][0] = 2.0f * (fX * fZ - fW * fY);
85 m[0][1] = 2.0f * (fX * fY - fW * fZ);
86 m[1][1] = 1.0f - 2.0f * (fXX + fZZ);
87 m[2][1] = 2.0f * (fY * fZ + fW * fX);
89 m[0][2] = 2.0f * (fX * fZ + fW * fY);
90 m[1][2] = 2.0f * (fX * fZ - fW * fX);
91 m[2][2] = 1.0f - 2.0f * (fXX + fYY);
98 quaternion To_Quat(angle_axis Ang_Ax)
100 // From the Quaternion Powers article on gamedev.net
101 static quaternion Quat;
103 Quat.x = Ang_Ax.x * sin(Ang_Ax.angle / 2);
104 Quat.y = Ang_Ax.y * sin(Ang_Ax.angle / 2);
105 Quat.z = Ang_Ax.z * sin(Ang_Ax.angle / 2);
106 Quat.w = cos(Ang_Ax.angle / 2);
109 angle_axis Quat_2_AA(quaternion Quat)
111 static angle_axis Ang_Ax;
112 static float scale, tw;
113 tw = (float)acosf(Quat.w) * 2;
114 scale = (float)sin(tw / 2.0);
115 Ang_Ax.x = Quat.x / scale;
116 Ang_Ax.y = Quat.y / scale;
117 Ang_Ax.z = Quat.z / scale;
119 Ang_Ax.angle = 2.0 * acosf(Quat.w)/(float)PI*180;
123 quaternion To_Quat(int In_Degrees, euler Euler)
125 // From the gamasutra quaternion article
126 static quaternion Quat;
127 static float cr, cp, cy, sr, sp, sy, cpcy, spsy;
128 //If we are in Degree mode, convert to Radians
130 Euler.x = Euler.x * (float)PI / 180;
131 Euler.y = Euler.y * (float)PI / 180;
132 Euler.z = Euler.z * (float)PI / 180;
134 //Calculate trig identities
135 //Formerly roll, pitch, yaw
136 cr = float(cos(Euler.x/2));
137 cp = float(cos(Euler.y/2));
138 cy = float(cos(Euler.z/2));
139 sr = float(sin(Euler.x/2));
140 sp = float(sin(Euler.y/2));
141 sy = float(sin(Euler.z/2));
145 Quat.w = cr * cpcy + sr * spsy;
146 Quat.x = sr * cpcy - cr * spsy;
147 Quat.y = cr * sp * cy + sr * cp * sy;
148 Quat.z = cr * cp * sy - sr * sp * cy;
153 quaternion QNormalize(quaternion Quat)
156 norm = Quat.x * Quat.x +
160 Quat.x = float(Quat.x / norm);
161 Quat.y = float(Quat.y / norm);
162 Quat.z = float(Quat.z / norm);
163 Quat.w = float(Quat.w / norm);
167 XYZ Quat2Vector(quaternion Quat)
178 tempvec.x = 2.0f*(fX*fZ-fW*fY);
179 tempvec.y = 2.0f*(fY*fZ+fW*fX);
180 tempvec.z = 1.0f-2.0f*(fX*fX+fY*fY);
185 bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33)
187 static float u0, u1, u2;
188 static float v0, v1, v2;
193 static float pointv[3];
197 static float normalv[3];
222 #define ABS(X) (((X)<0.f)?-(X):(X) )
223 #define MAX(A, B) (((A)<(B))?(B):(A))
224 max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2]));
226 if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z
227 if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z
228 if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y
231 u0 = pointv[i] - p1v[i];
232 v0 = pointv[j] - p1v[j];
233 u1 = p2v[i] - p1v[i];
234 v1 = p2v[j] - p1v[j];
235 u2 = p3v[i] - p1v[i];
236 v2 = p3v[j] - p1v[j];
238 if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f)
241 if (0.0f <= b && b <= 1.0f)
243 a = (v0 - b * v2) / v1;
244 if ((a >= 0.0f) && (( a + b ) <= 1.0f))
250 b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
251 if (0.0f <= b && b <= 1.0f)
253 a = (u0 - b * u2) / u1;
254 if ((a >= 0.0f) && (( a + b ) <= 1.0f ))
262 bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p)
265 static float a1,a2,a3;
266 static float total,denom,mu;
267 static Vector n,pa1,pa2,pa3;
269 //Calculate the parameters for the plane
270 n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
271 n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
272 n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
274 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
276 //Calculate the position on the line that intersects the plane
277 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
278 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
280 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
281 p->x = p1.x + mu * (p2.x - p1.x);
282 p->y = p1.y + mu * (p2.y - p1.y);
283 p->z = p1.z + mu * (p2.z - p1.z);
284 if (mu < 0 || mu > 1) // Intersection not along line segment
287 if(!PointInTriangle( p, n, pa.x, pa.y, pa.z, pb.x, pb.y, pb.z, pc.x, pc.y, pc.z)){return 0;}
292 bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3)
294 static float u0, u1, u2;
295 static float v0, v1, v2;
299 static bool bInter = 0;
300 static float pointv[3];
304 static float normalv[3];
329 #define ABS(X) (((X)<0.f)?-(X):(X) )
330 #define MAX(A, B) (((A)<(B))?(B):(A))
331 max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2]));
333 if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z
334 if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z
335 if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y
338 u0 = pointv[i] - p1v[i];
339 v0 = pointv[j] - p1v[j];
340 u1 = p2v[i] - p1v[i];
341 v1 = p2v[j] - p1v[j];
342 u2 = p3v[i] - p1v[i];
343 v2 = p3v[j] - p1v[j];
345 if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f)
348 if (0.0f <= b && b <= 1.0f)
350 a = (v0 - b * v2) / v1;
351 if ((a >= 0.0f) && (( a + b ) <= 1.0f))
357 b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
358 if (0.0f <= b && b <= 1.0f)
360 a = (u0 - b * u2) / u1;
361 if ((a >= 0.0f) && (( a + b ) <= 1.0f ))
369 bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p)
372 static float a1,a2,a3;
373 static float total,denom,mu;
374 static XYZ n,pa1,pa2,pa3;
376 //Calculate the parameters for the plane
377 n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
378 n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
379 n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
381 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
383 //Calculate the position on the line that intersects the plane
384 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
385 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
387 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
388 p->x = p1.x + mu * (p2.x - p1.x);
389 p->y = p1.y + mu * (p2.y - p1.y);
390 p->z = p1.z + mu * (p2.z - p1.z);
391 if (mu < 0 || mu > 1) // Intersection not along line segment
394 if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
399 float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p)
402 static float a1,a2,a3;
403 static float total,denom,mu;
404 static XYZ n,pa1,pa2,pa3;
406 //Calculate the parameters for the plane
407 n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
408 n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
409 n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
411 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
413 //Calculate the position on the line that intersects the plane
414 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
415 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
417 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
418 p->x = p1.x + mu * (p2.x - p1.x);
419 p->y = p1.y + mu * (p2.y - p1.y);
420 p->z = p1.z + mu * (p2.z - p1.z);
421 if (mu < 0 || mu > 1) // Intersection not along line segment
424 if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
429 float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc, XYZ n, XYZ *p)
432 static float a1,a2,a3;
433 static float total,denom,mu;
434 static XYZ pa1,pa2,pa3;
436 //Calculate the parameters for the plane
437 d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
439 //Calculate the position on the line that intersects the plane
440 denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
441 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
443 mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
444 p->x = p1.x + mu * (p2.x - p1.x);
445 p->y = p1.y + mu * (p2.y - p1.y);
446 p->z = p1.z + mu * (p2.z - p1.z);
447 if (mu < 0 || mu > 1) // Intersection not along line segment
450 if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
454 float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc, XYZ *p)
457 static float a1,a2,a3;
458 static float total,denom,mu;
459 static XYZ pa1,pa2,pa3,n;
461 //Calculate the parameters for the plane
462 n.x = (pb->y - pa->y)*(pc->z - pa->z) - (pb->z - pa->z)*(pc->y - pa->y);
463 n.y = (pb->z - pa->z)*(pc->x - pa->x) - (pb->x - pa->x)*(pc->z - pa->z);
464 n.z = (pb->x - pa->x)*(pc->y - pa->y) - (pb->y - pa->y)*(pc->x - pa->x);
466 d = - n.x * pa->x - n.y * pa->y - n.z * pa->z;
469 //Calculate the position on the line that intersects the plane
470 denom = n.x * (p2->x - p1->x) + n.y * (p2->y - p1->y) + n.z * (p2->z - p1->z);
471 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
473 mu = - (d + n.x * p1->x + n.y * p1->y + n.z * p1->z) / denom;
474 p->x = p1->x + mu * (p2->x - p1->x);
475 p->y = p1->y + mu * (p2->y - p1->y);
476 p->z = p1->z + mu * (p2->z - p1->z);
477 if (mu < 0 || mu > 1) // Intersection not along line segment
480 if(!PointInTriangle( p, n, pa, pb, pc)){return 0;}
484 float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc, XYZ *n, XYZ *p)
487 static float a1,a2,a3;
488 static float total,denom,mu;
489 static XYZ pa1,pa2,pa3;
491 //Calculate the parameters for the plane
492 d = - n->x * pa->x - n->y * pa->y - n->z * pa->z;
494 //Calculate the position on the line that intersects the plane
495 denom = n->x * (p2->x - p1->x) + n->y * (p2->y - p1->y) + n->z * (p2->z - p1->z);
496 if (fabs(denom) < 0.0000001) // Line and plane don't intersect
498 mu = - (d + n->x * p1->x + n->y * p1->y + n->z * p1->z) / denom;
499 p->x = p1->x + mu * (p2->x - p1->x);
500 p->y = p1->y + mu * (p2->y - p1->y);
501 p->z = p1->z + mu * (p2->z - p1->z);
502 if (mu < 0 || mu > 1) // Intersection not along line segment
505 if(!PointInTriangle( p, *n, pa, pb, pc)){return 0;}