blob: d9d2b9488209b4774ad86d5c4f89b53329dce9ba [file] [log] [blame]
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -07001#
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:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070018summary: Quaternion Functions
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070019description:
Jean-Luc Brouillet6386ceb2015-04-28 15:06:30 -070020 The following functions manipulate quaternions.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070021end:
22
23function: rsQuaternionAdd
Verena Beckham336fc4b2015-11-18 10:44:03 +000024version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070025ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070026arg: rs_quaternion* q, "Destination quaternion to add to."
27arg: const rs_quaternion* rhs, "Quaternion to add."
28summary: Add two quaternions
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070029description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070030 Adds two quaternions, i.e. <code>*q += *rhs;</code>
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070031inline:
Yang Nie7fd36a2016-02-01 10:42:29 -080032 q->w += rhs->w;
33 q->x += rhs->x;
34 q->y += rhs->y;
35 q->z += rhs->z;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070036test: none
37end:
38
39function: rsQuaternionConjugate
Verena Beckham336fc4b2015-11-18 10:44:03 +000040version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070041ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070042arg: rs_quaternion* q, "Quaternion to modify."
43summary: Conjugate a quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070044description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070045 Conjugates the quaternion.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070046inline:
47 q->x = -q->x;
48 q->y = -q->y;
49 q->z = -q->z;
50test: none
51end:
52
53function: rsQuaternionDot
Verena Beckham336fc4b2015-11-18 10:44:03 +000054version: 9 23
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070055ret: float
56arg: const rs_quaternion* q0, "First quaternion."
57arg: const rs_quaternion* q1, "Second quaternion."
58summary: Dot product of two quaternions
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070059description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070060 Returns the dot product of two quaternions.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070061inline:
62 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
63test: none
64end:
65
66function: rsQuaternionGetMatrixUnit
Verena Beckham336fc4b2015-11-18 10:44:03 +000067version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070068ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070069arg: rs_matrix4x4* m, "Resulting matrix."
70arg: const rs_quaternion* q, "Normalized quaternion."
71summary: Get a rotation matrix from a quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070072description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -070073 Computes a rotation matrix from the normalized quaternion.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070074inline:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000100version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700101ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700102arg: 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700108description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700109 Loads a quaternion that represents a rotation about an arbitrary unit vector.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700110inline:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000123version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700124ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700125arg: 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."
Jean-Luc Brouillet6386ceb2015-04-28 15:06:30 -0700130summary: Create a quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700131description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700132 Creates a quaternion from its four components or from another quaternion.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700133inline:
134 q->w = w;
135 q->x = x;
136 q->y = y;
137 q->z = z;
138test: none
139end:
140
141function: rsQuaternionSet
Verena Beckham336fc4b2015-11-18 10:44:03 +0000142version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700143ret: void
144arg: rs_quaternion* q
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700145arg: const rs_quaternion* rhs, "Source quaternion."
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700146inline:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000158version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700159ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700160arg: 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700166description:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000182version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700183ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700184arg: rs_quaternion* q, "Quaternion to normalize."
185summary: Normalize a quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700186description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700187 Normalizes the quaternion.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700188inline:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000201version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700202ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700203arg: rs_quaternion* q, "Destination quaternion."
Jean-Luc Brouillet6386ceb2015-04-28 15:06:30 -0700204arg: float scalar, "Scalar to multiply the quaternion by."
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700205summary: Multiply a quaternion by a scalar or another quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700206description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700207 Multiplies a quaternion by a scalar or by another quaternion, e.g
208 <code>*q = *q * scalar;</code> or <code>*q = *q * *rhs;</code>.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700209inline:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700210 q->w *= scalar;
211 q->x *= scalar;
212 q->y *= scalar;
213 q->z *= scalar;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700214test: none
215end:
216
217function: rsQuaternionMultiply
Verena Beckham336fc4b2015-11-18 10:44:03 +0000218version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700219ret: void
220arg: rs_quaternion* q
Jean-Luc Brouillet6386ceb2015-04-28 15:06:30 -0700221arg: const rs_quaternion* rhs, "Quaternion to multiply the destination quaternion by."
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700222inline:
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
Verena Beckham336fc4b2015-11-18 10:44:03 +0000235version: 9 23
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700236ret: void
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700237arg: 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700242description:
Jean-Luc Brouillet20b27d62015-04-03 14:39:53 -0700243 Performs spherical linear interpolation between two quaternions.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700244inline:
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:
Verena Beckham336fc4b2015-11-18 10:44:03 +0000285
286# New versions. Same signatures but don't contain a body.
287function: rsQuaternionAdd
288version: UNRELEASED
289ret: void
290arg: rs_quaternion* q
291arg: const rs_quaternion* rhs
292test: none
293end:
294
295function: rsQuaternionConjugate
296version: UNRELEASED
297ret: void
298arg: rs_quaternion* q
299test: none
300end:
301
302function: rsQuaternionDot
303version: UNRELEASED
304ret: float
305arg: const rs_quaternion* q0
306arg: const rs_quaternion* q1
307test: none
308end:
309
310function: rsQuaternionGetMatrixUnit
311version: UNRELEASED
312ret: void
313arg: rs_matrix4x4* m
314arg: const rs_quaternion* q
315test: none
316end:
317
318function: rsQuaternionLoadRotateUnit
319version: UNRELEASED
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: UNRELEASED
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: UNRELEASED
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: UNRELEASED
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: UNRELEASED
364ret: void
365arg: rs_quaternion* q
366test: none
367end:
368
369function: rsQuaternionMultiply
370version: UNRELEASED
371ret: void
372arg: rs_quaternion* q
373arg: float scalar
374test: none
375end:
376
377function: rsQuaternionMultiply
378version: UNRELEASED
379ret: void
380arg: rs_quaternion* q
381arg: const rs_quaternion* rhs
382test: none
383end:
384
385function: rsQuaternionSlerp
386version: UNRELEASED
387ret: void
388arg: rs_quaternion* q
389arg: const rs_quaternion* q0
390arg: const rs_quaternion* q1
391arg: float t
392test: none
393end: