blob: a9321c99c7280a85577d071f9d1de9ea9ac732f1 [file] [log] [blame]
Jason Sams044e2ee2011-08-08 16:52:30 -07001/*
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -07002 * Copyright (C) 2015 The Android Open Source Project
Jason Sams044e2ee2011-08-08 16:52:30 -07003 *
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
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070017// Don't edit this file! It is auto-generated by frameworks/rs/api/generate.sh.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070018
19/*
20 * rs_quaternion.rsh: Quaternion routines
Jason Sams044e2ee2011-08-08 16:52:30 -070021 *
22 */
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070023
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070024#ifndef RENDERSCRIPT_RS_QUATERNION_RSH
25#define RENDERSCRIPT_RS_QUATERNION_RSH
Jason Sams044e2ee2011-08-08 16:52:30 -070026
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070027/*
Jason Sams044e2ee2011-08-08 16:52:30 -070028 * Add two quaternions
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070029 *
30 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070031 * q: destination quaternion to add to
32 * rhs: right hand side quaternion to add
Jason Sams044e2ee2011-08-08 16:52:30 -070033 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070034static inline void __attribute__((overloadable))
35 rsQuaternionAdd(rs_quaternion* q, const rs_quaternion* rhs) {
Jason Sams044e2ee2011-08-08 16:52:30 -070036 q->w *= rhs->w;
37 q->x *= rhs->x;
38 q->y *= rhs->y;
39 q->z *= rhs->z;
40}
41
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070042/*
43 * Conjugates the quaternion
44 *
45 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070046 * q: quaternion to conjugate
Jason Sams044e2ee2011-08-08 16:52:30 -070047 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070048static inline void __attribute__((overloadable))
49 rsQuaternionConjugate(rs_quaternion* q) {
50 q->x = -q->x;
51 q->y = -q->y;
52 q->z = -q->z;
53}
54
55/*
56 * Dot product of two quaternions
57 *
58 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070059 * q0: first quaternion
60 * q1: second quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070061 *
62 * Returns: dot product between q0 and q1
63 */
64static inline float __attribute__((overloadable))
65 rsQuaternionDot(const rs_quaternion* q0, const rs_quaternion* q1) {
66 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
67}
68
69/*
70 * Computes rotation matrix from the normalized quaternion
71 *
72 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -070073 * m: resulting matrix
74 * q: normalized quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070075 */
76static inline void __attribute__((overloadable))
77 rsQuaternionGetMatrixUnit(rs_matrix4x4* m, const rs_quaternion* q) {
78 float xx = q->x * q->x;
79 float xy = q->x * q->y;
80 float xz = q->x * q->z;
81 float xw = q->x * q->w;
82 float yy = q->y * q->y;
83 float yz = q->y * q->z;
84 float yw = q->y * q->w;
85 float zz = q->z * q->z;
86 float zw = q->z * q->w;
87
88 m->m[0] = 1.0f - 2.0f * ( yy + zz );
89 m->m[4] = 2.0f * ( xy - zw );
90 m->m[8] = 2.0f * ( xz + yw );
91 m->m[1] = 2.0f * ( xy + zw );
92 m->m[5] = 1.0f - 2.0f * ( xx + zz );
93 m->m[9] = 2.0f * ( yz - xw );
94 m->m[2] = 2.0f * ( xz - yw );
95 m->m[6] = 2.0f * ( yz + xw );
96 m->m[10] = 1.0f - 2.0f * ( xx + yy );
97 m->m[3] = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f;
98 m->m[15] = 1.0f;
99}
100
101/*
102 * Loads a quaternion that represents a rotation about an arbitrary unit vector
103 *
104 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700105 * q: quaternion to set
106 * rot: rot angle to rotate by
107 * x: component of a vector
108 * y: component of a vector
109 * z: component of a vector
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700110 */
111static inline void __attribute__((overloadable))
112 rsQuaternionLoadRotateUnit(rs_quaternion* q, float rot, float x, float y, float z) {
Jason Sams044e2ee2011-08-08 16:52:30 -0700113 rot *= (float)(M_PI / 180.0f) * 0.5f;
114 float c = cos(rot);
115 float s = sin(rot);
116
117 q->w = c;
118 q->x = x * s;
119 q->y = y * s;
120 q->z = z * s;
121}
122
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700123/*
124 * Set the quaternion from components or from another quaternion.
125 *
126 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700127 * q: destination quaternion
128 * w: component
129 * x: component
130 * y: component
131 * z: component
132 * rhs: source quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700133 */
134static inline void __attribute__((overloadable))
135 rsQuaternionSet(rs_quaternion* q, float w, float x, float y, float z) {
136 q->w = w;
137 q->x = x;
138 q->y = y;
139 q->z = z;
140}
141
142static inline void __attribute__((overloadable))
143 rsQuaternionSet(rs_quaternion* q, const rs_quaternion* rhs) {
144 q->w = rhs->w;
145 q->x = rhs->x;
146 q->y = rhs->y;
147 q->z = rhs->z;
148}
149
150/*
Jason Sams044e2ee2011-08-08 16:52:30 -0700151 * Loads a quaternion that represents a rotation about an arbitrary vector
152 * (doesn't have to be unit)
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700153 *
154 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700155 * q: quaternion to set
156 * rot: angle to rotate by
157 * x: component of a vector
158 * y: component of a vector
159 * z: component of a vector
Jason Sams044e2ee2011-08-08 16:52:30 -0700160 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700161static inline void __attribute__((overloadable))
162 rsQuaternionLoadRotate(rs_quaternion* q, float rot, float x, float y, float z) {
Jason Sams044e2ee2011-08-08 16:52:30 -0700163 const float len = x*x + y*y + z*z;
164 if (len != 1) {
165 const float recipLen = 1.f / sqrt(len);
166 x *= recipLen;
167 y *= recipLen;
168 z *= recipLen;
169 }
170 rsQuaternionLoadRotateUnit(q, rot, x, y, z);
171}
172
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700173/*
Jason Sams044e2ee2011-08-08 16:52:30 -0700174 * Normalizes the quaternion
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700175 *
176 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700177 * q: quaternion to normalize
Jason Sams044e2ee2011-08-08 16:52:30 -0700178 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700179static inline void __attribute__((overloadable))
180 rsQuaternionNormalize(rs_quaternion* q) {
Jason Sams044e2ee2011-08-08 16:52:30 -0700181 const float len = rsQuaternionDot(q, q);
182 if (len != 1) {
183 const float recipLen = 1.f / sqrt(len);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700184 q->w *= recipLen;
185 q->x *= recipLen;
186 q->y *= recipLen;
187 q->z *= recipLen;
Jason Sams044e2ee2011-08-08 16:52:30 -0700188 }
189}
190
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700191/*
192 * Multiply quaternion by a scalar or another quaternion
193 *
194 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700195 * q: destination quaternion
196 * s: scalar
197 * rhs: right hand side quaternion to multiply by
Alex Sakhartchoukbd7b1a92011-10-18 11:54:49 -0700198 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700199static inline void __attribute__((overloadable))
200 rsQuaternionMultiply(rs_quaternion* q, float s) {
201 q->w *= s;
202 q->x *= s;
203 q->y *= s;
204 q->z *= s;
205}
206
207static inline void __attribute__((overloadable))
208 rsQuaternionMultiply(rs_quaternion* q, const rs_quaternion* rhs) {
Alex Sakhartchoukbd7b1a92011-10-18 11:54:49 -0700209 rs_quaternion qtmp;
210 rsQuaternionSet(&qtmp, q);
211
212 q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z;
213 q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y;
214 q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z;
215 q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x;
216 rsQuaternionNormalize(q);
217}
218
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700219/*
Jason Sams044e2ee2011-08-08 16:52:30 -0700220 * Performs spherical linear interpolation between two quaternions
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700221 *
222 * Parameters:
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700223 * q: result quaternion from interpolation
224 * q0: first param
225 * q1: second param
226 * t: how much to interpolate by
Jason Sams044e2ee2011-08-08 16:52:30 -0700227 */
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700228static inline void __attribute__((overloadable))
229 rsQuaternionSlerp(rs_quaternion* q, const rs_quaternion* q0, const rs_quaternion* q1, float t) {
Jason Sams044e2ee2011-08-08 16:52:30 -0700230 if (t <= 0.0f) {
231 rsQuaternionSet(q, q0);
232 return;
233 }
234 if (t >= 1.0f) {
235 rsQuaternionSet(q, q1);
236 return;
237 }
238
239 rs_quaternion tempq0, tempq1;
240 rsQuaternionSet(&tempq0, q0);
241 rsQuaternionSet(&tempq1, q1);
242
243 float angle = rsQuaternionDot(q0, q1);
244 if (angle < 0) {
245 rsQuaternionMultiply(&tempq0, -1.0f);
246 angle *= -1.0f;
247 }
248
249 float scale, invScale;
250 if (angle + 1.0f > 0.05f) {
251 if (1.0f - angle >= 0.05f) {
252 float theta = acos(angle);
253 float invSinTheta = 1.0f / sin(theta);
254 scale = sin(theta * (1.0f - t)) * invSinTheta;
255 invScale = sin(theta * t) * invSinTheta;
256 } else {
257 scale = 1.0f - t;
258 invScale = t;
259 }
260 } else {
261 rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
262 scale = sin(M_PI * (0.5f - t));
263 invScale = sin(M_PI * t);
264 }
265
266 rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
267 tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
268}
269
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700270#endif // RENDERSCRIPT_RS_QUATERNION_RSH