1#
2# Copyright (C) 2015 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17header:
18summary: Quaternion Functions
19description:
20 The following functions manipulate quaternions.
21end:
22
23function: rsQuaternionAdd
24version: 9 23
25ret: void
26arg: rs_quaternion* q, "Destination quaternion to add to."
27arg: const rs_quaternion* rhs, "Quaternion to add."
28summary: Add two quaternions
29description:
30 Adds two quaternions, i.e. <code>*q += *rhs;</code>
31inline:
32 q->w += rhs->w;
33 q->x += rhs->x;
34 q->y += rhs->y;
35 q->z += rhs->z;
36test: none
37end:
38
39function: rsQuaternionConjugate
40version: 9 23
41ret: void
42arg: rs_quaternion* q, "Quaternion to modify."
43summary: Conjugate a quaternion
44description:
45 Conjugates the quaternion.
46inline:
47 q->x = -q->x;
48 q->y = -q->y;
49 q->z = -q->z;
50test: none
51end:
52
53function: rsQuaternionDot
54version: 9 23
55ret: float
56arg: const rs_quaternion* q0, "First quaternion."
57arg: const rs_quaternion* q1, "Second quaternion."
58summary:  Dot product of two quaternions
59description:
60 Returns the dot product of two quaternions.
61inline:
62 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
63test: none
64end:
65
66function: rsQuaternionGetMatrixUnit
67version: 9 23
68ret: void
69arg: rs_matrix4x4* m, "Resulting matrix."
70arg: const rs_quaternion* q, "Normalized quaternion."
71summary: Get a rotation matrix from a quaternion
72description:
73 Computes a rotation matrix from the normalized quaternion.
74inline:
75 float xx = q->x * q->x;
76 float xy = q->x * q->y;
77 float xz = q->x * q->z;
78 float xw = q->x * q->w;
79 float yy = q->y * q->y;
80 float yz = q->y * q->z;
81 float yw = q->y * q->w;
82 float zz = q->z * q->z;
83 float zw = q->z * q->w;
84
85 m->m[0]  = 1.0f - 2.0f * ( yy + zz );
86 m->m[4]  =        2.0f * ( xy - zw );
87 m->m[8]  =        2.0f * ( xz + yw );
88 m->m[1]  =        2.0f * ( xy + zw );
89 m->m[5]  = 1.0f - 2.0f * ( xx + zz );
90 m->m[9]  =        2.0f * ( yz - xw );
91 m->m[2]  =        2.0f * ( xz - yw );
92 m->m[6]  =        2.0f * ( yz + xw );
93 m->m[10] = 1.0f - 2.0f * ( xx + yy );
94 m->m[3]  = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f;
95 m->m[15] = 1.0f;
96test: none
97end:
98
99function: rsQuaternionLoadRotateUnit
100version: 9 23
101ret: void
102arg: rs_quaternion* q, "Destination quaternion."
103arg: float rot, "Angle to rotate by, in radians."
104arg: float x, "X component of the vector."
105arg: float y, "Y component of the vector."
106arg: float z, "Z component of the vector."
107summary:  Quaternion that represents a rotation about an arbitrary unit vector
108description:
109 Loads a quaternion that represents a rotation about an arbitrary unit vector.
110inline:
111 rot *= (float)(M_PI / 180.0f) * 0.5f;
112 float c = cos(rot);
113 float s = sin(rot);
114
115 q->w = c;
116 q->x = x * s;
117 q->y = y * s;
118 q->z = z * s;
119test: none
120end:
121
122function: rsQuaternionSet
123version: 9 23
124ret: void
125arg: rs_quaternion* q, "Destination quaternion."
126arg: float w, "W component."
127arg: float x, "X component."
128arg: float y, "Y component."
129arg: float z, "Z component."
130summary: Create a quaternion
131description:
132 Creates a quaternion from its four components or from another quaternion.
133inline:
134 q->w = w;
135 q->x = x;
136 q->y = y;
137 q->z = z;
138test: none
139end:
140
141function: rsQuaternionSet
142version: 9 23
143ret: void
144arg: rs_quaternion* q
145arg: const rs_quaternion* rhs, "Source quaternion."
146inline:
147 q->w = rhs->w;
148 q->x = rhs->x;
149 q->y = rhs->y;
150 q->z = rhs->z;
151test: none
152end:
153
154# NOTE: The following inline definitions depend on each other.  The order must be preserved
155# for the compilation to work.
156
157function: rsQuaternionLoadRotate
158version: 9 23
159ret: void
160arg: rs_quaternion* q, "Destination quaternion."
161arg: float rot, "Angle to rotate by."
162arg: float x, "X component of a vector."
163arg: float y, "Y component of a vector."
164arg: float z, "Z component of a vector."
165summary: Create a rotation quaternion
166description:
167 Loads a quaternion that represents a rotation about an arbitrary vector
168 (doesn't have to be unit)
169inline:
170 const float len = x*x + y*y + z*z;
171 if (len != 1) {
172     const float recipLen = 1.f / sqrt(len);
173     x *= recipLen;
174     y *= recipLen;
175     z *= recipLen;
176 }
177 rsQuaternionLoadRotateUnit(q, rot, x, y, z);
178test: none
179end:
180
181function: rsQuaternionNormalize
182version: 9 23
183ret: void
184arg: rs_quaternion* q, "Quaternion to normalize."
185summary:  Normalize a quaternion
186description:
187 Normalizes the quaternion.
188inline:
189 const float len = rsQuaternionDot(q, q);
190 if (len != 1) {
191     const float recipLen = 1.f / sqrt(len);
192     q->w *= recipLen;
193     q->x *= recipLen;
194     q->y *= recipLen;
195     q->z *= recipLen;
196 }
197test: none
198end:
199
200function: rsQuaternionMultiply
201version: 9 23
202ret: void
203arg: rs_quaternion* q, "Destination quaternion."
204arg: float scalar, "Scalar to multiply the quaternion by."
205summary:  Multiply a quaternion by a scalar or another quaternion
206description:
207 Multiplies a quaternion by a scalar or by another quaternion, e.g
208 <code>*q = *q * scalar;</code> or <code>*q = *q * *rhs;</code>.
209inline:
210 q->w *= scalar;
211 q->x *= scalar;
212 q->y *= scalar;
213 q->z *= scalar;
214test: none
215end:
216
217function: rsQuaternionMultiply
218version: 9 23
219ret: void
220arg: rs_quaternion* q
221arg: const rs_quaternion* rhs, "Quaternion to multiply the destination quaternion by."
222inline:
223 rs_quaternion qtmp;
224 rsQuaternionSet(&qtmp, q);
225
226 q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z;
227 q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y;
228 q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z;
229 q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x;
230 rsQuaternionNormalize(q);
231test: none
232end:
233
234function: rsQuaternionSlerp
235version: 9 23
236ret: void
237arg: rs_quaternion* q, "Result quaternion from the interpolation."
238arg: const rs_quaternion* q0, "First input quaternion."
239arg: const rs_quaternion* q1, "Second input quaternion."
240arg: float t, "How much to interpolate by."
241summary: Spherical linear interpolation between two quaternions
242description:
243 Performs spherical linear interpolation between two quaternions.
244inline:
245 if (t <= 0.0f) {
246     rsQuaternionSet(q, q0);
247     return;
248 }
249 if (t >= 1.0f) {
250     rsQuaternionSet(q, q1);
251     return;
252 }
253
254 rs_quaternion tempq0, tempq1;
255 rsQuaternionSet(&tempq0, q0);
256 rsQuaternionSet(&tempq1, q1);
257
258 float angle = rsQuaternionDot(q0, q1);
259 if (angle < 0) {
260     rsQuaternionMultiply(&tempq0, -1.0f);
261     angle *= -1.0f;
262 }
263
264 float scale, invScale;
265 if (angle + 1.0f > 0.05f) {
266     if (1.0f - angle >= 0.05f) {
267         float theta = acos(angle);
268         float invSinTheta = 1.0f / sin(theta);
269         scale = sin(theta * (1.0f - t)) * invSinTheta;
270         invScale = sin(theta * t) * invSinTheta;
271     } else {
272         scale = 1.0f - t;
273         invScale = t;
274     }
275 } else {
276     rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
277     scale = sin(M_PI * (0.5f - t));
278     invScale = sin(M_PI * t);
279 }
280
281 rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
282                     tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
283test: none
284end:
285
286# New versions. Same signatures but don't contain a body.
287function: rsQuaternionAdd
288version: 24
289ret: void
290arg: rs_quaternion* q
291arg: const rs_quaternion* rhs
292test: none
293end:
294
295function: rsQuaternionConjugate
296version: 24
297ret: void
298arg: rs_quaternion* q
299test: none
300end:
301
302function: rsQuaternionDot
303version: 24
304ret: float
305arg: const rs_quaternion* q0
306arg: const rs_quaternion* q1
307test: none
308end:
309
310function: rsQuaternionGetMatrixUnit
311version: 24
312ret: void
313arg: rs_matrix4x4* m
314arg: const rs_quaternion* q
315test: none
316end:
317
318function: rsQuaternionLoadRotateUnit
319version: 24
320ret: void
321arg: rs_quaternion* q
322arg: float rot
323arg: float x
324arg: float y
325arg: float z
326test: none
327end:
328
329function: rsQuaternionSet
330version: 24
331ret: void
332arg: rs_quaternion* q
333arg: float w
334arg: float x
335arg: float y
336arg: float z
337test: none
338end:
339
340function: rsQuaternionSet
341version: 24
342ret: void
343arg: rs_quaternion* q
344arg: const rs_quaternion* rhs
345test: none
346end:
347
348# NOTE: The following inline definitions depend on each other.  The order must be preserved
349# for the compilation to work.
350
351function: rsQuaternionLoadRotate
352version: 24
353ret: void
354arg: rs_quaternion* q
355arg: float rot
356arg: float x
357arg: float y
358arg: float z
359test: none
360end:
361
362function: rsQuaternionNormalize
363version: 24
364ret: void
365arg: rs_quaternion* q
366test: none
367end:
368
369function: rsQuaternionMultiply
370version: 24
371ret: void
372arg: rs_quaternion* q
373arg: float scalar
374test: none
375end:
376
377function: rsQuaternionMultiply
378version: 24
379ret: void
380arg: rs_quaternion* q
381arg: const rs_quaternion* rhs
382test: none
383end:
384
385function: rsQuaternionSlerp
386version: 24
387ret: void
388arg: rs_quaternion* q
389arg: const rs_quaternion* q0
390arg: const rs_quaternion* q1
391arg: float t
392test: none
393end:
394