1 /*
2 	quaternion.h
3 
4 	Quaternion functions
5 
6 	Copyright (C) 2004 Bill Currie <bill@taniwha.org>
7 
8 	Author: Bill Currie <bill@taniwha.org>
9 	Date: 2004/4/7
10 
11 	This program is free software; you can redistribute it and/or
12 	modify it under the terms of the GNU General Public License
13 	as published by the Free Software Foundation; either version 2
14 	of the License, or (at your option) any later version.
15 
16 	This program is distributed in the hope that it will be useful,
17 	but WITHOUT ANY WARRANTY; without even the implied warranty of
18 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 	See the GNU General Public License for more details.
21 
22 	You should have received a copy of the GNU General Public License
23 	along with this program; if not, write to:
24 
25 		Free Software Foundation, Inc.
26 		59 Temple Place - Suite 330
27 		Boston, MA  02111-1307, USA
28 
29 */
30 
31 #ifndef __QF_math_quaternion_h
32 #define __QF_math_quaternion_h
33 
34 /** \defgroup mathlib_quaternion Quaternion functions
35 	\ingroup utils
36 */
37 //@{
38 
39 #include "QF/qtypes.h"
40 
41 extern const vec_t *const quat_origin;
42 
43 #define QDotProduct(a,b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] \
44 						  + (a)[2] * (b)[2] + (a)[3] * (b)[3])
45 #define QuatSubtract(a,b,c) \
46 	do { \
47 		(c)[0] = (a)[0] - (b)[0]; \
48 		(c)[1] = (a)[1] - (b)[1]; \
49 		(c)[2] = (a)[2] - (b)[2]; \
50 		(c)[3] = (a)[3] - (b)[3]; \
51 	} while (0)
52 #define QuatNegate(a,b) \
53 	do { \
54 		(b)[0] = -(a)[0]; \
55 		(b)[1] = -(a)[1]; \
56 		(b)[2] = -(a)[2]; \
57 		(b)[3] = -(a)[3]; \
58 	} while (0)
59 #define QuatConj(a,b) \
60 	do { \
61 		(b)[0] = (a)[0]; \
62 		(b)[1] = -(a)[1]; \
63 		(b)[2] = -(a)[2]; \
64 		(b)[3] = -(a)[3]; \
65 	} while (0)
66 #define QuatAdd(a,b,c) \
67 	do { \
68 		(c)[0] = (a)[0] + (b)[0]; \
69 		(c)[1] = (a)[1] + (b)[1]; \
70 		(c)[2] = (a)[2] + (b)[2]; \
71 		(c)[3] = (a)[3] + (b)[3]; \
72 	} while (0)
73 #define QuatCopy(a,b) \
74 	do { \
75 		(b)[0] = (a)[0]; \
76 		(b)[1] = (a)[1]; \
77 		(b)[2] = (a)[2]; \
78 		(b)[3] = (a)[3]; \
79 	} while (0)
80 #define QuatMultAdd(a,s,b,c) \
81 	do { \
82 		(c)[0] = (a)[0] + (s) * (b)[0]; \
83 		(c)[1] = (a)[1] + (s) * (b)[1]; \
84 		(c)[2] = (a)[2] + (s) * (b)[2]; \
85 		(c)[3] = (a)[3] + (s) * (b)[3]; \
86 	} while (0)
87 #define QuatMultSub(a,s,b,c) \
88 	do { \
89 		(c)[0] = (a)[0] - (s) * (b)[0]; \
90 		(c)[1] = (a)[1] - (s) * (b)[1]; \
91 		(c)[2] = (a)[2] - (s) * (b)[2]; \
92 		(c)[3] = (a)[3] - (s) * (b)[3]; \
93 	} while (0)
94 #define QuatLength(a) sqrt(QDotProduct(a, a))
95 
96 #define QuatScale(a,b,c) \
97 	do { \
98 		(c)[0] = (a)[0] * (b); \
99 		(c)[1] = (a)[1] * (b); \
100 		(c)[2] = (a)[2] * (b); \
101 		(c)[3] = (a)[3] * (b); \
102 	} while (0)
103 
104 #define QuatCompMult(a,b,c) \
105 	do { \
106 		(c)[0] = (a)[0] * (b)[0]; \
107 		(c)[1] = (a)[1] * (b)[1]; \
108 		(c)[2] = (a)[2] * (b)[2]; \
109 		(c)[3] = (a)[3] * (b)[3]; \
110 	} while (0)
111 #define QuatCompDiv(a,b,c) \
112 	do { \
113 		(c)[0] = (a)[0] / (b)[0]; \
114 		(c)[1] = (a)[1] / (b)[1]; \
115 		(c)[2] = (a)[2] / (b)[2]; \
116 		(c)[3] = (a)[3] / (b)[3]; \
117 	} while (0)
118 #define QuatCompCompare(x, op, y) \
119 	(((x)[0] op (y)[0]) && ((x)[1] op (y)[1]) \
120 	 && ((x)[2] op (y)[2]) && ((x)[3] op (y)[3]))
121 #define QuatCompare(x, y) QuatCompCompare (x, ==, y)
122 #define QuatCompMin(a, b, c) \
123 	do { \
124 		(c)[0] = min ((a)[0], (b)[0]); \
125 		(c)[1] = min ((a)[1], (b)[1]); \
126 		(c)[2] = min ((a)[2], (b)[2]); \
127 		(c)[3] = min ((a)[3], (b)[3]); \
128 	} while (0)
129 #define QuatCompMax(a, b, c) \
130 	do { \
131 		(c)[0] = max ((a)[0], (b)[0]); \
132 		(c)[1] = max ((a)[1], (b)[1]); \
133 		(c)[2] = max ((a)[2], (b)[2]); \
134 		(c)[3] = max ((a)[3], (b)[3]); \
135 	} while (0)
136 #define QuatCompBound(a, b, c, d) \
137 	do { \
138 		(d)[0] = bound ((a)[0], (b)[0], (c)[0]); \
139 		(d)[1] = bound ((a)[1], (b)[1], (c)[1]); \
140 		(d)[2] = bound ((a)[2], (b)[2], (c)[2]); \
141 		(d)[3] = bound ((a)[3], (b)[3], (c)[3]); \
142 	} while (0)
143 
144 #define QuatIsZero(a) (!(a)[0] && !(a)[1] && !(a)[2] && !(a)[3])
145 #define QuatZero(a) ((a)[3] = (a)[2] = (a)[1] = (a)[0] = 0);
146 #define QuatSet(a,b,c,d,e) \
147 	do { \
148 		(e)[0] = a; \
149 		(e)[1] = b; \
150 		(e)[2] = c; \
151 		(e)[3] = d; \
152 	} while (0)
153 
154 #define QuatBlend(q1,q2,b,q) \
155 	do { \
156 		(q)[0] = (q1)[0] * (1 - (b)) + (q2)[0] * (b); \
157 		(q)[1] = (q1)[1] * (1 - (b)) + (q2)[1] * (b); \
158 		(q)[2] = (q1)[2] * (1 - (b)) + (q2)[2] * (b); \
159 		(q)[3] = (q1)[3] * (1 - (b)) + (q2)[3] * (b); \
160 	} while (0)
161 
162 //For printf etc
163 #define QuatExpand(q) (q)[0], (q)[1], (q)[2], (q)[3]
164 
165 void QuatMult (const quat_t q1, const quat_t q2, quat_t out);
166 void QuatMultVec (const quat_t q, const vec3_t v, vec3_t out);
167 void QuatInverse (const quat_t in, quat_t out);
168 void QuatExp (const quat_t a, quat_t b);
169 void QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical);
170 
171 //@}
172 
173 #endif // __QF_math_quaternion_h
174