rs_quaternion.rsh revision 20b27d602a4778ed50a83df2147416a35b7c92be
1/* 2 * Copyright (C) 2015 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 */ 23 24#ifndef RENDERSCRIPT_RS_QUATERNION_RSH 25#define RENDERSCRIPT_RS_QUATERNION_RSH 26 27/* 28 * rsQuaternionAdd: Add two quaternions 29 * 30 * Adds two quaternions, i.e. *q += *rhs; 31 * 32 * Parameters: 33 * q: Destination quaternion to add to. 34 * rhs: Quaternion to add. 35 */ 36static inline void __attribute__((overloadable)) 37 rsQuaternionAdd(rs_quaternion* q, const rs_quaternion* rhs) { 38 q->w *= rhs->w; 39 q->x *= rhs->x; 40 q->y *= rhs->y; 41 q->z *= rhs->z; 42} 43 44/* 45 * rsQuaternionConjugate: Conjugate a quaternion 46 * 47 * Conjugates the quaternion. 48 * 49 * Parameters: 50 * q: Quaternion to modify. 51 */ 52static inline void __attribute__((overloadable)) 53 rsQuaternionConjugate(rs_quaternion* q) { 54 q->x = -q->x; 55 q->y = -q->y; 56 q->z = -q->z; 57} 58 59/* 60 * rsQuaternionDot: Dot product of two quaternions 61 * 62 * Returns the dot product of two quaternions. 63 * 64 * Parameters: 65 * q0: First quaternion. 66 * q1: Second quaternion. 67 */ 68static inline float __attribute__((overloadable)) 69 rsQuaternionDot(const rs_quaternion* q0, const rs_quaternion* q1) { 70 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z; 71} 72 73/* 74 * rsQuaternionGetMatrixUnit: Get a rotation matrix from a quaternion 75 * 76 * Computes a rotation matrix from the normalized quaternion. 77 * 78 * Parameters: 79 * m: Resulting matrix. 80 * q: Normalized quaternion. 81 */ 82static inline void __attribute__((overloadable)) 83 rsQuaternionGetMatrixUnit(rs_matrix4x4* m, const rs_quaternion* q) { 84 float xx = q->x * q->x; 85 float xy = q->x * q->y; 86 float xz = q->x * q->z; 87 float xw = q->x * q->w; 88 float yy = q->y * q->y; 89 float yz = q->y * q->z; 90 float yw = q->y * q->w; 91 float zz = q->z * q->z; 92 float zw = q->z * q->w; 93 94 m->m[0] = 1.0f - 2.0f * ( yy + zz ); 95 m->m[4] = 2.0f * ( xy - zw ); 96 m->m[8] = 2.0f * ( xz + yw ); 97 m->m[1] = 2.0f * ( xy + zw ); 98 m->m[5] = 1.0f - 2.0f * ( xx + zz ); 99 m->m[9] = 2.0f * ( yz - xw ); 100 m->m[2] = 2.0f * ( xz - yw ); 101 m->m[6] = 2.0f * ( yz + xw ); 102 m->m[10] = 1.0f - 2.0f * ( xx + yy ); 103 m->m[3] = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f; 104 m->m[15] = 1.0f; 105} 106 107/* 108 * rsQuaternionLoadRotateUnit: Quaternion that represents a rotation about an arbitrary unit vector 109 * 110 * Loads a quaternion that represents a rotation about an arbitrary unit vector. 111 * 112 * Parameters: 113 * q: Destination quaternion. 114 * rot: Angle to rotate by, in radians. 115 * x: X component of the vector. 116 * y: Y component of the vector. 117 * z: Z component of the vector. 118 */ 119static inline void __attribute__((overloadable)) 120 rsQuaternionLoadRotateUnit(rs_quaternion* q, float rot, float x, float y, float z) { 121 rot *= (float)(M_PI / 180.0f) * 0.5f; 122 float c = cos(rot); 123 float s = sin(rot); 124 125 q->w = c; 126 q->x = x * s; 127 q->y = y * s; 128 q->z = z * s; 129} 130 131/* 132 * rsQuaternionSet: Create a quarternion 133 * 134 * Creates a quaternion from its four components or from another quaternion. 135 * 136 * Parameters: 137 * q: Destination quaternion. 138 * w: W component. 139 * x: X component. 140 * y: Y component. 141 * z: Z component. 142 * rhs: Source quaternion. 143 */ 144static inline void __attribute__((overloadable)) 145 rsQuaternionSet(rs_quaternion* q, float w, float x, float y, float z) { 146 q->w = w; 147 q->x = x; 148 q->y = y; 149 q->z = z; 150} 151 152static inline void __attribute__((overloadable)) 153 rsQuaternionSet(rs_quaternion* q, const rs_quaternion* rhs) { 154 q->w = rhs->w; 155 q->x = rhs->x; 156 q->y = rhs->y; 157 q->z = rhs->z; 158} 159 160/* 161 * rsQuaternionLoadRotate: Create a rotation quaternion 162 * 163 * Loads a quaternion that represents a rotation about an arbitrary vector 164 * (doesn't have to be unit) 165 * 166 * Parameters: 167 * q: Destination quaternion. 168 * rot: Angle to rotate by. 169 * x: X component of a vector. 170 * y: Y component of a vector. 171 * z: Z component of a vector. 172 */ 173static inline void __attribute__((overloadable)) 174 rsQuaternionLoadRotate(rs_quaternion* q, float rot, float x, float y, float z) { 175 const float len = x*x + y*y + z*z; 176 if (len != 1) { 177 const float recipLen = 1.f / sqrt(len); 178 x *= recipLen; 179 y *= recipLen; 180 z *= recipLen; 181 } 182 rsQuaternionLoadRotateUnit(q, rot, x, y, z); 183} 184 185/* 186 * rsQuaternionNormalize: Normalize a quaternion 187 * 188 * Normalizes the quaternion. 189 * 190 * Parameters: 191 * q: Quaternion to normalize. 192 */ 193static inline void __attribute__((overloadable)) 194 rsQuaternionNormalize(rs_quaternion* q) { 195 const float len = rsQuaternionDot(q, q); 196 if (len != 1) { 197 const float recipLen = 1.f / sqrt(len); 198 q->w *= recipLen; 199 q->x *= recipLen; 200 q->y *= recipLen; 201 q->z *= recipLen; 202 } 203} 204 205/* 206 * rsQuaternionMultiply: Multiply a quaternion by a scalar or another quaternion 207 * 208 * Multiplies a quaternion by a scalar or by another quaternion, e.g 209 * *q = *q * scalar; or *q = *q * *rhs;. 210 * 211 * Parameters: 212 * q: Destination quaternion. 213 * scalar: Scalar to multiply the quarternion by. 214 * rhs: Quarternion to multiply the destination quaternion by. 215 */ 216static inline void __attribute__((overloadable)) 217 rsQuaternionMultiply(rs_quaternion* q, float scalar) { 218 q->w *= scalar; 219 q->x *= scalar; 220 q->y *= scalar; 221 q->z *= scalar; 222} 223 224static inline void __attribute__((overloadable)) 225 rsQuaternionMultiply(rs_quaternion* q, const rs_quaternion* rhs) { 226 rs_quaternion qtmp; 227 rsQuaternionSet(&qtmp, q); 228 229 q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z; 230 q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y; 231 q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z; 232 q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x; 233 rsQuaternionNormalize(q); 234} 235 236/* 237 * rsQuaternionSlerp: Spherical linear interpolation between two quaternions 238 * 239 * Performs spherical linear interpolation between two quaternions. 240 * 241 * Parameters: 242 * q: Result quaternion from the interpolation. 243 * q0: First input quaternion. 244 * q1: Second input quaternion. 245 * t: How much to interpolate by. 246 */ 247static inline void __attribute__((overloadable)) 248 rsQuaternionSlerp(rs_quaternion* q, const rs_quaternion* q0, const rs_quaternion* q1, float t) { 249 if (t <= 0.0f) { 250 rsQuaternionSet(q, q0); 251 return; 252 } 253 if (t >= 1.0f) { 254 rsQuaternionSet(q, q1); 255 return; 256 } 257 258 rs_quaternion tempq0, tempq1; 259 rsQuaternionSet(&tempq0, q0); 260 rsQuaternionSet(&tempq1, q1); 261 262 float angle = rsQuaternionDot(q0, q1); 263 if (angle < 0) { 264 rsQuaternionMultiply(&tempq0, -1.0f); 265 angle *= -1.0f; 266 } 267 268 float scale, invScale; 269 if (angle + 1.0f > 0.05f) { 270 if (1.0f - angle >= 0.05f) { 271 float theta = acos(angle); 272 float invSinTheta = 1.0f / sin(theta); 273 scale = sin(theta * (1.0f - t)) * invSinTheta; 274 invScale = sin(theta * t) * invSinTheta; 275 } else { 276 scale = 1.0f - t; 277 invScale = t; 278 } 279 } else { 280 rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w); 281 scale = sin(M_PI * (0.5f - t)); 282 invScale = sin(M_PI * t); 283 } 284 285 rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale, 286 tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale); 287} 288 289#endif // RENDERSCRIPT_RS_QUATERNION_RSH 290