1044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams/*
2291330fbaf7486a1cea33de7dd26c18e57c71391Stephen Hines * Copyright (C) 2016 The Android Open Source Project
3044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams *
4044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * you may not use this file except in compliance with the License.
6044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * You may obtain a copy of the License at
7044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams *
8044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams *
10044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * Unless required by applicable law or agreed to in writing, software
11044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * See the License for the specific language governing permissions and
14044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * limitations under the License.
15044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
16044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
174a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
18c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
19c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
2020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rs_quaternion.rsh: Quaternion Functions
21044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams *
226386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet * The following functions manipulate quaternions.
23044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
244a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet
25c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#ifndef RENDERSCRIPT_RS_QUATERNION_RSH
26c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#define RENDERSCRIPT_RS_QUATERNION_RSH
27044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
28c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
2920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionAdd: Add two quaternions
3020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
3120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Adds two quaternions, i.e. *q += *rhs;
32c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
33c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
3420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion to add to.
3520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rhs: Quaternion to add.
36044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
3714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
38c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
39c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionAdd(rs_quaternion* q, const rs_quaternion* rhs) {
40e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->w += rhs->w;
41e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->x += rhs->x;
42e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->y += rhs->y;
43e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->z += rhs->z;
44044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
4514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
46044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
4820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionConjugate: Conjugate a quaternion
4920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
5020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Conjugates the quaternion.
51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
52c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
5320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Quaternion to modify.
54044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
5514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
56c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
57c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionConjugate(rs_quaternion* q) {
58c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = -q->x;
59c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = -q->y;
60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = -q->z;
61044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
6214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
63044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
6520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionDot: Dot product of two quaternions
66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
6720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Returns the dot product of two quaternions.
68c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
6920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Parameters:
7020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q0: First quaternion.
7120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q1: Second quaternion.
72044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
7314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline float __attribute__((overloadable))
75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionDot(const rs_quaternion* q0, const rs_quaternion* q1) {
76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
77044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
7814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
79044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
8120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionGetMatrixUnit: Get a rotation matrix from a quaternion
8220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
8320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Computes a rotation matrix from the normalized quaternion.
84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
8620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   m: Resulting matrix.
8720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Normalized quaternion.
88044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
8914c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionGetMatrixUnit(rs_matrix4x4* m, const rs_quaternion* q) {
92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xx = q->x * q->x;
93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xy = q->x * q->y;
94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xz = q->x * q->z;
95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xw = q->x * q->w;
96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yy = q->y * q->y;
97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yz = q->y * q->z;
98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yw = q->y * q->w;
99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float zz = q->z * q->z;
100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float zw = q->z * q->w;
101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[0]  = 1.0f - 2.0f * ( yy + zz );
103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[4]  =        2.0f * ( xy - zw );
104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[8]  =        2.0f * ( xz + yw );
105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[1]  =        2.0f * ( xy + zw );
106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[5]  = 1.0f - 2.0f * ( xx + zz );
107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[9]  =        2.0f * ( yz - xw );
108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[2]  =        2.0f * ( xz - yw );
109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[6]  =        2.0f * ( yz + xw );
110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[10] = 1.0f - 2.0f * ( xx + yy );
111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[3]  = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f;
112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[15] = 1.0f;
113044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
11414c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
115044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
116c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
11720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionLoadRotateUnit: Quaternion that represents a rotation about an arbitrary unit vector
11820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
11920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Loads a quaternion that represents a rotation about an arbitrary unit vector.
120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
12220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
12320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rot: Angle to rotate by, in radians.
12420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component of the vector.
12520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component of the vector.
12620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component of the vector.
127044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
12814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionLoadRotateUnit(rs_quaternion* q, float rot, float x, float y, float z) {
131044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rot *= (float)(M_PI / 180.0f) * 0.5f;
132044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float c = cos(rot);
133044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float s = sin(rot);
134044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
135044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->w = c;
136044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->x = x * s;
137044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->y = y * s;
138044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->z = z * s;
139044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
14014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
141044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
1436386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet * rsQuaternionSet: Create a quaternion
14420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
14520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Creates a quaternion from its four components or from another quaternion.
146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
14820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
14920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   w: W component.
15020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component.
15120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component.
15220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component.
15320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rhs: Source quaternion.
154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
15514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSet(rs_quaternion* q, float w, float x, float y, float z) {
158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->w = w;
159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = x;
160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = y;
161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = z;
162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
16314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
16514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSet(rs_quaternion* q, const rs_quaternion* rhs) {
168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->w = rhs->w;
169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = rhs->x;
170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = rhs->y;
171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = rhs->z;
172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
17314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
17620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionLoadRotate: Create a rotation quaternion
17720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
178044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * Loads a quaternion that represents a rotation about an arbitrary vector
179044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * (doesn't have to be unit)
180c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
181c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
18220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
18320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rot: Angle to rotate by.
18420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component of a vector.
18520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component of a vector.
18620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component of a vector.
187044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
18814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionLoadRotate(rs_quaternion* q, float rot, float x, float y, float z) {
191044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    const float len = x*x + y*y + z*z;
192044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (len != 1) {
193044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        const float recipLen = 1.f / sqrt(len);
194044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        x *= recipLen;
195044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        y *= recipLen;
196044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        z *= recipLen;
197044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
198044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionLoadRotateUnit(q, rot, x, y, z);
199044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
20014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
201044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
20320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionNormalize: Normalize a quaternion
20420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
20520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Normalizes the quaternion.
206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
207c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
20820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Quaternion to normalize.
209044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
21014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionNormalize(rs_quaternion* q) {
213044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    const float len = rsQuaternionDot(q, q);
214044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (len != 1) {
215044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        const float recipLen = 1.f / sqrt(len);
216c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->w *= recipLen;
217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->x *= recipLen;
218c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->y *= recipLen;
219c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->z *= recipLen;
220044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
221044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
22214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
223044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
224c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
22520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionMultiply: Multiply a quaternion by a scalar or another quaternion
22620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
22720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Multiplies a quaternion by a scalar or by another quaternion, e.g
22820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * *q = *q * scalar; or *q = *q * *rhs;.
229c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
230c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
23120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
2326386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet *   scalar: Scalar to multiply the quaternion by.
2336386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet *   rhs: Quaternion to multiply the destination quaternion by.
234bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk */
23514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
236c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
23720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    rsQuaternionMultiply(rs_quaternion* q, float scalar) {
23820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->w *= scalar;
23920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->x *= scalar;
24020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->y *= scalar;
24120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->z *= scalar;
242c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
24314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
244c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
24514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
246c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
247c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionMultiply(rs_quaternion* q, const rs_quaternion* rhs) {
248bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rs_quaternion qtmp;
249bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rsQuaternionSet(&qtmp, q);
250bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk
251bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z;
252bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y;
253bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z;
254bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x;
255bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rsQuaternionNormalize(q);
256bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk}
25714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
258bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk
259c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
26020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionSlerp: Spherical linear interpolation between two quaternions
26120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
26220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Performs spherical linear interpolation between two quaternions.
263c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
264c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
26520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Result quaternion from the interpolation.
26620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q0: First input quaternion.
26720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q1: Second input quaternion.
26820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   t: How much to interpolate by.
269044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
27014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#if !defined(RS_VERSION) || (RS_VERSION <= 23)
271c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
272c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSlerp(rs_quaternion* q, const rs_quaternion* q0, const rs_quaternion* q1, float t) {
273044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (t <= 0.0f) {
274044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(q, q0);
275044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        return;
276044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
277044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (t >= 1.0f) {
278044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(q, q1);
279044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        return;
280044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
281044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
282044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rs_quaternion tempq0, tempq1;
283044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(&tempq0, q0);
284044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(&tempq1, q1);
285044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
286044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float angle = rsQuaternionDot(q0, q1);
287044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (angle < 0) {
288044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionMultiply(&tempq0, -1.0f);
289044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        angle *= -1.0f;
290044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
291044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
292044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float scale, invScale;
293044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (angle + 1.0f > 0.05f) {
294044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        if (1.0f - angle >= 0.05f) {
295044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            float theta = acos(angle);
296044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            float invSinTheta = 1.0f / sin(theta);
297044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            scale = sin(theta * (1.0f - t)) * invSinTheta;
298044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            invScale = sin(theta * t) * invSinTheta;
299044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        } else {
300044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            scale = 1.0f - t;
301044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            invScale = t;
302044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        }
303044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    } else {
304044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
305044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        scale = sin(M_PI * (0.5f - t));
306044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        invScale = sin(M_PI * t);
307044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
308044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
309044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
310044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams                        tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
311044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
31214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
31314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
314bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
31514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
31614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionAdd(rs_quaternion* q, const rs_quaternion* rhs);
31714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
31814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
319bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
32014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
32114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionConjugate(rs_quaternion* q);
32214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
32314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
324bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
32514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern float __attribute__((overloadable))
32614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionDot(const rs_quaternion* q0, const rs_quaternion* q1);
32714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
32814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
329bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
33014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
33114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionGetMatrixUnit(rs_matrix4x4* m, const rs_quaternion* q);
33214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
33314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
334bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
33514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
33614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionLoadRotateUnit(rs_quaternion* q, float rot, float x, float y, float z);
33714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
33814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
339bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
34014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
34114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionSet(rs_quaternion* q, float w, float x, float y, float z);
34214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
34314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
344bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
34514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
34614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionSet(rs_quaternion* q, const rs_quaternion* rhs);
34714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
34814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
349bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
35014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
35114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionLoadRotate(rs_quaternion* q, float rot, float x, float y, float z);
35214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
35314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
354bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
35514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
35614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionNormalize(rs_quaternion* q);
35714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
35814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
359bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
36014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
36114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionMultiply(rs_quaternion* q, float scalar);
36214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
36314c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
364bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
36514c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
36614c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionMultiply(rs_quaternion* q, const rs_quaternion* rhs);
36714c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
36814c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham
369bfa4eede0cb2430e8c7523a8425435cd8a8b6b6eStephen Hines#if (defined(RS_VERSION) && (RS_VERSION >= 24))
37014c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckhamextern void __attribute__((overloadable))
37114c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham    rsQuaternionSlerp(rs_quaternion* q, const rs_quaternion* q0, const rs_quaternion* q1, float t);
37214c8aa51782107afb6f84187233f5ac8f6da0373Verena Beckham#endif
373044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
374c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#endif // RENDERSCRIPT_RS_QUATERNION_RSH
375