Line data Source code
1 0 : /*
2 :
3 : OOQuaternion.h
4 :
5 : Mathematical framework for Oolite.
6 :
7 : Oolite
8 : Copyright (C) 2004-2013 Giles C Williams and contributors
9 :
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 : MA 02110-1301, USA.
24 :
25 : */
26 :
27 :
28 : #ifndef INCLUDED_OOMATHS_h
29 : #error Do not include OOQuaternion.h directly; include OOMaths.h.
30 : #else
31 :
32 :
33 : typedef struct Quaternion
34 : {
35 : OOScalar w;
36 : OOScalar x;
37 : OOScalar y;
38 : OOScalar z;
39 : } Quaternion;
40 :
41 :
42 : extern const Quaternion kIdentityQuaternion; // 1, 0, 0, 0
43 : extern const Quaternion kZeroQuaternion; // 0, 0, 0, 0
44 :
45 :
46 : /* Construct quaternion */
47 : OOINLINE Quaternion make_quaternion(OOScalar qw, OOScalar qx, OOScalar qy, OOScalar qz) INLINE_CONST_FUNC;
48 :
49 : /* Comparison of quaternions */
50 : OOINLINE bool quaternion_equal(Quaternion a, Quaternion b) INLINE_CONST_FUNC;
51 :
52 : /* Multiply quaternions */
53 : Quaternion quaternion_multiply(Quaternion q1, Quaternion q2) CONST_FUNC;
54 :
55 : /* Negation, or additive inverse -- negate all components */
56 : OOINLINE Quaternion quaternion_negate(Quaternion q) INLINE_CONST_FUNC;
57 :
58 : /* Conjugate, or spacial inverse -- negate x, y, z components */
59 : OOINLINE Quaternion quaternion_conjugate(Quaternion q) INLINE_CONST_FUNC;
60 :
61 : #if !OOMATHS_STANDALONE
62 : /* Set quaternion to random unit quaternion */
63 : void quaternion_set_random(Quaternion *quat) NONNULL_FUNC;
64 : OOINLINE Quaternion OORandomQuaternion(void) ALWAYS_INLINE_FUNC;
65 : #endif
66 :
67 : /* Build quaternion representing a rotation around a given axis */
68 : OOINLINE void quaternion_set_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle) NONNULL_FUNC;
69 :
70 : /* Inner product of two quaternions */
71 : OOINLINE OOScalar quaternion_dot_product(Quaternion q1, Quaternion q2) CONST_FUNC;
72 :
73 : /* Create basis vectors from a quaternion. */
74 : Vector vector_forward_from_quaternion(Quaternion quat) CONST_FUNC;
75 : Vector vector_up_from_quaternion(Quaternion quat) CONST_FUNC;
76 : Vector vector_right_from_quaternion(Quaternion quat) CONST_FUNC;
77 :
78 : HPVector HPvector_forward_from_quaternion(Quaternion quat) CONST_FUNC;
79 :
80 : void basis_vectors_from_quaternion(Quaternion quat, Vector *outRight, Vector *outUp, Vector *outForward);
81 :
82 : /* produce a quaternion representing an angle between two vectors. Assumes the vectors are normalized. */
83 : Quaternion quaternion_rotation_between(Vector v0, Vector v1) CONST_FUNC;
84 : Quaternion quaternion_rotation_betweenHP(HPVector v0, HPVector v1) CONST_FUNC;
85 :
86 : /* produce a quaternion representing an angle between two vectors with a maximum arc */
87 : Quaternion quaternion_limited_rotation_between(Vector v0, Vector v1, float maxArc) CONST_FUNC;
88 :
89 : /* Rotate a quaternion about a fixed axis. */
90 : void quaternion_rotate_about_x(Quaternion *quat, OOScalar angle) NONNULL_FUNC;
91 : void quaternion_rotate_about_y(Quaternion *quat, OOScalar angle) NONNULL_FUNC;
92 : void quaternion_rotate_about_z(Quaternion *quat, OOScalar angle) NONNULL_FUNC;
93 : void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle) NONNULL_FUNC;
94 :
95 : /* Normalize quaternion */
96 : OOINLINE void quaternion_normalize(Quaternion *quat) NONNULL_FUNC ALWAYS_INLINE_FUNC;
97 :
98 : #if __OBJC__
99 : NSString *QuaternionDescription(Quaternion quaternion); // @"(w + xi + yj + zk)"
100 : #endif
101 :
102 :
103 : Vector quaternion_rotate_vector(Quaternion q, Vector vector) CONST_FUNC;
104 : HPVector quaternion_rotate_HPvector(Quaternion q, HPVector vector) CONST_FUNC;
105 :
106 :
107 :
108 : /*** Only inline definitions beyond this point ***/
109 :
110 : OOINLINE Quaternion make_quaternion(OOScalar qw, OOScalar qx, OOScalar qy, OOScalar qz)
111 : {
112 : Quaternion result;
113 : result.w = qw;
114 : result.x = qx;
115 : result.y = qy;
116 : result.z = qz;
117 : return result;
118 : }
119 :
120 :
121 : OOINLINE bool quaternion_equal(Quaternion a, Quaternion b)
122 : {
123 : return a.w == b.w && a.x == b.x && a.y == b.y && a.z == b.z;
124 : }
125 :
126 :
127 : OOINLINE Quaternion quaternion_negate(Quaternion q)
128 : {
129 : return make_quaternion(-q.w, -q.x, -q.y, -q.z);
130 : }
131 :
132 :
133 : OOINLINE Quaternion quaternion_conjugate(Quaternion q)
134 : {
135 : return make_quaternion(q.w, -q.x, -q.y, -q.z);
136 : }
137 :
138 :
139 : OOINLINE void quaternion_set_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
140 : {
141 : OOScalar a = angle * 0.5f;
142 : OOScalar scale = sin(a);
143 :
144 : quat->w = cos(a);
145 : quat->x = axis.x * scale;
146 : quat->y = axis.y * scale;
147 : quat->z = axis.z * scale;
148 : }
149 :
150 :
151 : OOINLINE OOScalar quaternion_dot_product(Quaternion q1, Quaternion q2)
152 : {
153 : return q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z;
154 : }
155 :
156 :
157 : OOINLINE void quaternion_normalize(Quaternion *quat)
158 : {
159 : OOScalar w = quat->w;
160 : OOScalar x = quat->x;
161 : OOScalar y = quat->y;
162 : OOScalar z = quat->z;
163 :
164 : OOScalar lv = 1.0f / sqrt(w*w + x*x + y*y + z*z);
165 :
166 : quat->w = lv * w;
167 : quat->x = lv * x;
168 : quat->y = lv * y;
169 : quat->z = lv * z;
170 : }
171 :
172 :
173 : #if !OOMATHS_STANDALONE
174 : OOINLINE Quaternion OORandomQuaternion(void)
175 : {
176 : Quaternion q;
177 : quaternion_set_random(&q);
178 : return q;
179 : }
180 : #endif
181 :
182 : #endif /* INCLUDED_OOMATHS_h */
|