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