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