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