rs_quaternion.rsh revision e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01
1044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams/*
2c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Copyright (C) 2015 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 */
37c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
38c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionAdd(rs_quaternion* q, const rs_quaternion* rhs) {
39e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->w += rhs->w;
40e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->x += rhs->x;
41e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->y += rhs->y;
42e7fd36a8ed1cdaf939852c08835d5c6b8e0eca01Yang Ni    q->z += rhs->z;
43044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
44044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
45c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
4620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionConjugate: Conjugate a quaternion
4720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
4820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Conjugates the quaternion.
49c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
5120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Quaternion to modify.
52044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
53c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
54c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionConjugate(rs_quaternion* q) {
55c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = -q->x;
56c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = -q->y;
57c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = -q->z;
58044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
59044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
6120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionDot: Dot product of two quaternions
62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
6320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Returns the dot product of two quaternions.
64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
6520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Parameters:
6620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q0: First quaternion.
6720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q1: Second quaternion.
68044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
69c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline float __attribute__((overloadable))
70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionDot(const rs_quaternion* q0, const rs_quaternion* q1) {
71c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
72044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
73044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
7520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionGetMatrixUnit: Get a rotation matrix from a quaternion
7620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
7720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Computes a rotation matrix from the normalized quaternion.
78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
8020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   m: Resulting matrix.
8120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Normalized quaternion.
82044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionGetMatrixUnit(rs_matrix4x4* m, const rs_quaternion* q) {
85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xx = q->x * q->x;
86c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xy = q->x * q->y;
87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xz = q->x * q->z;
88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float xw = q->x * q->w;
89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yy = q->y * q->y;
90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yz = q->y * q->z;
91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float yw = q->y * q->w;
92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float zz = q->z * q->z;
93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    float zw = q->z * q->w;
94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[0]  = 1.0f - 2.0f * ( yy + zz );
96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[4]  =        2.0f * ( xy - zw );
97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[8]  =        2.0f * ( xz + yw );
98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[1]  =        2.0f * ( xy + zw );
99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[5]  = 1.0f - 2.0f * ( xx + zz );
100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[9]  =        2.0f * ( yz - xw );
101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[2]  =        2.0f * ( xz - yw );
102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[6]  =        2.0f * ( yz + xw );
103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[10] = 1.0f - 2.0f * ( xx + yy );
104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[3]  = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f;
105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    m->m[15] = 1.0f;
106044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
107044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
10920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionLoadRotateUnit: Quaternion that represents a rotation about an arbitrary unit vector
11020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
11120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Loads a quaternion that represents a rotation about an arbitrary unit vector.
112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
113c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
11420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
11520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rot: Angle to rotate by, in radians.
11620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component of the vector.
11720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component of the vector.
11820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component of the vector.
119044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionLoadRotateUnit(rs_quaternion* q, float rot, float x, float y, float z) {
122044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rot *= (float)(M_PI / 180.0f) * 0.5f;
123044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float c = cos(rot);
124044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float s = sin(rot);
125044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
126044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->w = c;
127044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->x = x * s;
128044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->y = y * s;
129044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    q->z = z * s;
130044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
131044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
132c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
1336386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet * rsQuaternionSet: Create a quaternion
13420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
13520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Creates a quaternion from its four components or from another quaternion.
136c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
137c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
13820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
13920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   w: W component.
14020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component.
14120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component.
14220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component.
14320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rhs: Source quaternion.
144c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */
145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSet(rs_quaternion* q, float w, float x, float y, float z) {
147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->w = w;
148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = x;
149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = y;
150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = z;
151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSet(rs_quaternion* q, const rs_quaternion* rhs) {
155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->w = rhs->w;
156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->x = rhs->x;
157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->y = rhs->y;
158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    q->z = rhs->z;
159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
16220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionLoadRotate: Create a rotation quaternion
16320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
164044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * Loads a quaternion that represents a rotation about an arbitrary vector
165044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams * (doesn't have to be unit)
166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
16820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
16920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   rot: Angle to rotate by.
17020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   x: X component of a vector.
17120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   y: Y component of a vector.
17220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   z: Z component of a vector.
173044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionLoadRotate(rs_quaternion* q, float rot, float x, float y, float z) {
176044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    const float len = x*x + y*y + z*z;
177044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (len != 1) {
178044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        const float recipLen = 1.f / sqrt(len);
179044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        x *= recipLen;
180044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        y *= recipLen;
181044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        z *= recipLen;
182044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
183044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionLoadRotateUnit(q, rot, x, y, z);
184044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
185044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
186c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
18720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionNormalize: Normalize a quaternion
18820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
18920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Normalizes the quaternion.
190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
191c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
19220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Quaternion to normalize.
193044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionNormalize(rs_quaternion* q) {
196044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    const float len = rsQuaternionDot(q, q);
197044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (len != 1) {
198044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        const float recipLen = 1.f / sqrt(len);
199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->w *= recipLen;
200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->x *= recipLen;
201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->y *= recipLen;
202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        q->z *= recipLen;
203044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
204044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
205044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
20720b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionMultiply: Multiply a quaternion by a scalar or another quaternion
20820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
20920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Multiplies a quaternion by a scalar or by another quaternion, e.g
21020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * *q = *q * scalar; or *q = *q * *rhs;.
211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
21320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Destination quaternion.
2146386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet *   scalar: Scalar to multiply the quaternion by.
2156386ceb3bf25e442513224aaa45691dfe49562d9Jean-Luc Brouillet *   rhs: Quaternion to multiply the destination quaternion by.
216bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk */
217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
21820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    rsQuaternionMultiply(rs_quaternion* q, float scalar) {
21920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->w *= scalar;
22020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->x *= scalar;
22120b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->y *= scalar;
22220b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet    q->z *= scalar;
223c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
224c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
225c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
226c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionMultiply(rs_quaternion* q, const rs_quaternion* rhs) {
227bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rs_quaternion qtmp;
228bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rsQuaternionSet(&qtmp, q);
229bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk
230bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z;
231bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y;
232bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z;
233bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x;
234bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk    rsQuaternionNormalize(q);
235bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk}
236bd7b1a9612b3f5119af42ed7ec4a88929a2d0d10Alex Sakhartchouk
237c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/*
23820b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * rsQuaternionSlerp: Spherical linear interpolation between two quaternions
23920b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *
24020b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet * Performs spherical linear interpolation between two quaternions.
241c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *
242c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Parameters:
24320b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q: Result quaternion from the interpolation.
24420b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q0: First input quaternion.
24520b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   q1: Second input quaternion.
24620b27d602a4778ed50a83df2147416a35b7c92beJean-Luc Brouillet *   t: How much to interpolate by.
247044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams */
248c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic inline void __attribute__((overloadable))
249c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    rsQuaternionSlerp(rs_quaternion* q, const rs_quaternion* q0, const rs_quaternion* q1, float t) {
250044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (t <= 0.0f) {
251044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(q, q0);
252044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        return;
253044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
254044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (t >= 1.0f) {
255044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(q, q1);
256044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        return;
257044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
258044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
259044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rs_quaternion tempq0, tempq1;
260044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(&tempq0, q0);
261044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(&tempq1, q1);
262044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
263044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float angle = rsQuaternionDot(q0, q1);
264044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (angle < 0) {
265044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionMultiply(&tempq0, -1.0f);
266044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        angle *= -1.0f;
267044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
268044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
269044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    float scale, invScale;
270044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    if (angle + 1.0f > 0.05f) {
271044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        if (1.0f - angle >= 0.05f) {
272044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            float theta = acos(angle);
273044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            float invSinTheta = 1.0f / sin(theta);
274044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            scale = sin(theta * (1.0f - t)) * invSinTheta;
275044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            invScale = sin(theta * t) * invSinTheta;
276044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        } else {
277044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            scale = 1.0f - t;
278044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams            invScale = t;
279044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        }
280044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    } else {
281044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
282044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        scale = sin(M_PI * (0.5f - t));
283044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams        invScale = sin(M_PI * t);
284044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    }
285044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
286044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams    rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
287044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams                        tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
288044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams}
289044e2ee36ffe6520570a7f0207d75a8fce8b8e91Jason Sams
290c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#endif // RENDERSCRIPT_RS_QUATERNION_RSH
291