1 #ifndef __RS_CORE_RSH__ 2 #define __RS_CORE_RSH__ 3 4 #define _RS_RUNTIME extern 5 6 /** 7 * Debug function. Prints a string and value to the log. 8 */ 9 extern void __attribute__((overloadable)) 10 rsDebug(const char *, float); 11 /** 12 * Debug function. Prints a string and value to the log. 13 */ 14 extern void __attribute__((overloadable)) 15 rsDebug(const char *, float, float); 16 /** 17 * Debug function. Prints a string and value to the log. 18 */ 19 extern void __attribute__((overloadable)) 20 rsDebug(const char *, float, float, float); 21 /** 22 * Debug function. Prints a string and value to the log. 23 */ 24 extern void __attribute__((overloadable)) 25 rsDebug(const char *, float, float, float, float); 26 /** 27 * Debug function. Prints a string and value to the log. 28 */ 29 extern void __attribute__((overloadable)) 30 rsDebug(const char *, double); 31 /** 32 * Debug function. Prints a string and value to the log. 33 */ 34 extern void __attribute__((overloadable)) 35 rsDebug(const char *, const rs_matrix4x4 *); 36 /** 37 * Debug function. Prints a string and value to the log. 38 */ 39 extern void __attribute__((overloadable)) 40 rsDebug(const char *, const rs_matrix3x3 *); 41 /** 42 * Debug function. Prints a string and value to the log. 43 */ 44 extern void __attribute__((overloadable)) 45 rsDebug(const char *, const rs_matrix2x2 *); 46 /** 47 * Debug function. Prints a string and value to the log. 48 */ 49 extern void __attribute__((overloadable)) 50 rsDebug(const char *, int); 51 /** 52 * Debug function. Prints a string and value to the log. 53 */ 54 extern void __attribute__((overloadable)) 55 rsDebug(const char *, uint); 56 /** 57 * Debug function. Prints a string and value to the log. 58 */ 59 extern void __attribute__((overloadable)) 60 rsDebug(const char *, long); 61 /** 62 * Debug function. Prints a string and value to the log. 63 */ 64 extern void __attribute__((overloadable)) 65 rsDebug(const char *, unsigned long); 66 /** 67 * Debug function. Prints a string and value to the log. 68 */ 69 extern void __attribute__((overloadable)) 70 rsDebug(const char *, long long); 71 /** 72 * Debug function. Prints a string and value to the log. 73 */ 74 extern void __attribute__((overloadable)) 75 rsDebug(const char *, unsigned long long); 76 /** 77 * Debug function. Prints a string and value to the log. 78 */ 79 extern void __attribute__((overloadable)) 80 rsDebug(const char *, const void *); 81 #define RS_DEBUG(a) rsDebug(#a, a) 82 #define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__) 83 84 85 /** 86 * Debug function. Prints a string and value to the log. 87 */ 88 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float2 v); 89 /** 90 * Debug function. Prints a string and value to the log. 91 */ 92 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float3 v); 93 /** 94 * Debug function. Prints a string and value to the log. 95 */ 96 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float4 v); 97 98 99 /** 100 * Pack floating point (0-1) RGB values into a uchar4. The alpha component is 101 * set to 255 (1.0). 102 * 103 * @param r 104 * @param g 105 * @param b 106 * 107 * @return uchar4 108 */ 109 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b); 110 111 /** 112 * Pack floating point (0-1) RGBA values into a uchar4. 113 * 114 * @param r 115 * @param g 116 * @param b 117 * @param a 118 * 119 * @return uchar4 120 */ 121 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a); 122 123 /** 124 * Pack floating point (0-1) RGB values into a uchar4. The alpha component is 125 * set to 255 (1.0). 126 * 127 * @param color 128 * 129 * @return uchar4 130 */ 131 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color); 132 133 /** 134 * Pack floating point (0-1) RGBA values into a uchar4. 135 * 136 * @param color 137 * 138 * @return uchar4 139 */ 140 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color); 141 142 /** 143 * Unpack a uchar4 color to float4. The resulting float range will be (0-1). 144 * 145 * @param c 146 * 147 * @return float4 148 */ 149 _RS_RUNTIME float4 rsUnpackColor8888(uchar4 c); 150 151 152 ///////////////////////////////////////////////////// 153 // Matrix ops 154 ///////////////////////////////////////////////////// 155 156 /** 157 * Set one element of a matrix. 158 * 159 * @param m The matrix to be set 160 * @param row 161 * @param col 162 * @param v 163 * 164 * @return void 165 */ 166 _RS_RUNTIME void __attribute__((overloadable)) 167 rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v); 168 _RS_RUNTIME void __attribute__((overloadable)) 169 rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v); 170 _RS_RUNTIME void __attribute__((overloadable)) 171 rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v); 172 173 /** 174 * Get one element of a matrix. 175 * 176 * @param m The matrix to read from 177 * @param row 178 * @param col 179 * 180 * @return float 181 */ 182 _RS_RUNTIME float __attribute__((overloadable)) 183 rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col); 184 _RS_RUNTIME float __attribute__((overloadable)) 185 rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col); 186 _RS_RUNTIME float __attribute__((overloadable)) 187 rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col); 188 189 /** 190 * Set the elements of a matrix to the identity matrix. 191 * 192 * @param m 193 */ 194 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m); 195 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m); 196 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m); 197 198 /** 199 * Set the elements of a matrix from an array of floats. 200 * 201 * @param m 202 */ 203 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v); 204 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v); 205 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v); 206 207 /** 208 * Set the elements of a matrix from another matrix. 209 * 210 * @param m 211 */ 212 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v); 213 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v); 214 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v); 215 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v); 216 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v); 217 218 /** 219 * Load a rotation matrix. 220 * 221 * @param m 222 * @param rot 223 * @param x 224 * @param y 225 * @param z 226 */ 227 extern void __attribute__((overloadable)) 228 rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z); 229 230 extern void __attribute__((overloadable)) 231 rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z); 232 233 extern void __attribute__((overloadable)) 234 rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z); 235 236 extern void __attribute__((overloadable)) 237 rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs); 238 239 extern void __attribute__((overloadable)) 240 rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs); 241 242 extern void __attribute__((overloadable)) 243 rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs); 244 245 extern void __attribute__((overloadable)) 246 rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs); 247 248 extern void __attribute__((overloadable)) 249 rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs); 250 251 extern void __attribute__((overloadable)) 252 rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs); 253 254 extern void __attribute__((overloadable)) 255 rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z); 256 257 extern void __attribute__((overloadable)) 258 rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z); 259 260 extern void __attribute__((overloadable)) 261 rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z); 262 263 extern void __attribute__((overloadable)) 264 rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far); 265 266 extern void __attribute__((overloadable)) 267 rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far); 268 269 extern void __attribute__((overloadable)) 270 rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far); 271 272 _RS_RUNTIME float4 __attribute__((overloadable)) 273 rsMatrixMultiply(rs_matrix4x4 *m, float4 in); 274 275 _RS_RUNTIME float4 __attribute__((overloadable)) 276 rsMatrixMultiply(rs_matrix4x4 *m, float3 in); 277 278 _RS_RUNTIME float4 __attribute__((overloadable)) 279 rsMatrixMultiply(rs_matrix4x4 *m, float2 in); 280 281 _RS_RUNTIME float3 __attribute__((overloadable)) 282 rsMatrixMultiply(rs_matrix3x3 *m, float3 in); 283 284 _RS_RUNTIME float3 __attribute__((overloadable)) 285 rsMatrixMultiply(rs_matrix3x3 *m, float2 in); 286 287 _RS_RUNTIME float2 __attribute__((overloadable)) 288 rsMatrixMultiply(rs_matrix2x2 *m, float2 in); 289 290 // Returns true if the matrix was successfully inversed 291 extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m); 292 extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m); 293 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m); 294 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m); 295 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m); 296 297 ///////////////////////////////////////////////////// 298 // quaternion ops 299 ///////////////////////////////////////////////////// 300 301 static void __attribute__((overloadable)) 302 rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) { 303 q->w = w; 304 q->x = x; 305 q->y = y; 306 q->z = z; 307 } 308 309 static void __attribute__((overloadable)) 310 rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) { 311 q->w = rhs->w; 312 q->x = rhs->x; 313 q->y = rhs->y; 314 q->z = rhs->z; 315 } 316 317 static void __attribute__((overloadable)) 318 rsQuaternionMultiply(rs_quaternion *q, float s) { 319 q->w *= s; 320 q->x *= s; 321 q->y *= s; 322 q->z *= s; 323 } 324 325 static void __attribute__((overloadable)) 326 rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) { 327 q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w; 328 q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x; 329 q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y; 330 q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z; 331 } 332 333 static void 334 rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) { 335 q->w *= rhs->w; 336 q->x *= rhs->x; 337 q->y *= rhs->y; 338 q->z *= rhs->z; 339 } 340 341 static void 342 rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) { 343 rot *= (float)(M_PI / 180.0f) * 0.5f; 344 float c = cos(rot); 345 float s = sin(rot); 346 347 q->w = c; 348 q->x = x * s; 349 q->y = y * s; 350 q->z = z * s; 351 } 352 353 static void 354 rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) { 355 const float len = x*x + y*y + z*z; 356 if (len != 1) { 357 const float recipLen = 1.f / sqrt(len); 358 x *= recipLen; 359 y *= recipLen; 360 z *= recipLen; 361 } 362 rsQuaternionLoadRotateUnit(q, rot, x, y, z); 363 } 364 365 static void 366 rsQuaternionConjugate(rs_quaternion *q) { 367 q->x = -q->x; 368 q->y = -q->y; 369 q->z = -q->z; 370 } 371 372 static float 373 rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) { 374 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z; 375 } 376 377 static void 378 rsQuaternionNormalize(rs_quaternion *q) { 379 const float len = rsQuaternionDot(q, q); 380 if (len != 1) { 381 const float recipLen = 1.f / sqrt(len); 382 rsQuaternionMultiply(q, recipLen); 383 } 384 } 385 386 static void 387 rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) { 388 if (t <= 0.0f) { 389 rsQuaternionSet(q, q0); 390 return; 391 } 392 if (t >= 1.0f) { 393 rsQuaternionSet(q, q1); 394 return; 395 } 396 397 rs_quaternion tempq0, tempq1; 398 rsQuaternionSet(&tempq0, q0); 399 rsQuaternionSet(&tempq1, q1); 400 401 float angle = rsQuaternionDot(q0, q1); 402 if (angle < 0) { 403 rsQuaternionMultiply(&tempq0, -1.0f); 404 angle *= -1.0f; 405 } 406 407 float scale, invScale; 408 if (angle + 1.0f > 0.05f) { 409 if (1.0f - angle >= 0.05f) { 410 float theta = acos(angle); 411 float invSinTheta = 1.0f / sin(theta); 412 scale = sin(theta * (1.0f - t)) * invSinTheta; 413 invScale = sin(theta * t) * invSinTheta; 414 } else { 415 scale = 1.0f - t; 416 invScale = t; 417 } 418 } else { 419 rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w); 420 scale = sin(M_PI * (0.5f - t)); 421 invScale = sin(M_PI * t); 422 } 423 424 rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale, 425 tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale); 426 } 427 428 static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) { 429 float x2 = 2.0f * q->x * q->x; 430 float y2 = 2.0f * q->y * q->y; 431 float z2 = 2.0f * q->z * q->z; 432 float xy = 2.0f * q->x * q->y; 433 float wz = 2.0f * q->w * q->z; 434 float xz = 2.0f * q->x * q->z; 435 float wy = 2.0f * q->w * q->y; 436 float wx = 2.0f * q->w * q->x; 437 float yz = 2.0f * q->y * q->z; 438 439 m->m[0] = 1.0f - y2 - z2; 440 m->m[1] = xy - wz; 441 m->m[2] = xz + wy; 442 m->m[3] = 0.0f; 443 444 m->m[4] = xy + wz; 445 m->m[5] = 1.0f - x2 - z2; 446 m->m[6] = yz - wx; 447 m->m[7] = 0.0f; 448 449 m->m[8] = xz - wy; 450 m->m[9] = yz - wx; 451 m->m[10] = 1.0f - x2 - y2; 452 m->m[11] = 0.0f; 453 454 m->m[12] = 0.0f; 455 m->m[13] = 0.0f; 456 m->m[14] = 0.0f; 457 m->m[15] = 1.0f; 458 } 459 460 ///////////////////////////////////////////////////// 461 // utility funcs 462 ///////////////////////////////////////////////////// 463 __inline__ static void __attribute__((overloadable, always_inline)) 464 rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj, 465 float4 *left, float4 *right, 466 float4 *top, float4 *bottom, 467 float4 *near, float4 *far) { 468 // x y z w = a b c d in the plane equation 469 left->x = modelViewProj->m[3] + modelViewProj->m[0]; 470 left->y = modelViewProj->m[7] + modelViewProj->m[4]; 471 left->z = modelViewProj->m[11] + modelViewProj->m[8]; 472 left->w = modelViewProj->m[15] + modelViewProj->m[12]; 473 474 right->x = modelViewProj->m[3] - modelViewProj->m[0]; 475 right->y = modelViewProj->m[7] - modelViewProj->m[4]; 476 right->z = modelViewProj->m[11] - modelViewProj->m[8]; 477 right->w = modelViewProj->m[15] - modelViewProj->m[12]; 478 479 top->x = modelViewProj->m[3] - modelViewProj->m[1]; 480 top->y = modelViewProj->m[7] - modelViewProj->m[5]; 481 top->z = modelViewProj->m[11] - modelViewProj->m[9]; 482 top->w = modelViewProj->m[15] - modelViewProj->m[13]; 483 484 bottom->x = modelViewProj->m[3] + modelViewProj->m[1]; 485 bottom->y = modelViewProj->m[7] + modelViewProj->m[5]; 486 bottom->z = modelViewProj->m[11] + modelViewProj->m[9]; 487 bottom->w = modelViewProj->m[15] + modelViewProj->m[13]; 488 489 near->x = modelViewProj->m[3] + modelViewProj->m[2]; 490 near->y = modelViewProj->m[7] + modelViewProj->m[6]; 491 near->z = modelViewProj->m[11] + modelViewProj->m[10]; 492 near->w = modelViewProj->m[15] + modelViewProj->m[14]; 493 494 far->x = modelViewProj->m[3] - modelViewProj->m[2]; 495 far->y = modelViewProj->m[7] - modelViewProj->m[6]; 496 far->z = modelViewProj->m[11] - modelViewProj->m[10]; 497 far->w = modelViewProj->m[15] - modelViewProj->m[14]; 498 499 float len = length(left->xyz); 500 *left /= len; 501 len = length(right->xyz); 502 *right /= len; 503 len = length(top->xyz); 504 *top /= len; 505 len = length(bottom->xyz); 506 *bottom /= len; 507 len = length(near->xyz); 508 *near /= len; 509 len = length(far->xyz); 510 *far /= len; 511 } 512 513 __inline__ static bool __attribute__((overloadable, always_inline)) 514 rsIsSphereInFrustum(float4 *sphere, 515 float4 *left, float4 *right, 516 float4 *top, float4 *bottom, 517 float4 *near, float4 *far) { 518 519 float distToCenter = dot(left->xyz, sphere->xyz) + left->w; 520 if (distToCenter < -sphere->w) { 521 return false; 522 } 523 distToCenter = dot(right->xyz, sphere->xyz) + right->w; 524 if (distToCenter < -sphere->w) { 525 return false; 526 } 527 distToCenter = dot(top->xyz, sphere->xyz) + top->w; 528 if (distToCenter < -sphere->w) { 529 return false; 530 } 531 distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w; 532 if (distToCenter < -sphere->w) { 533 return false; 534 } 535 distToCenter = dot(near->xyz, sphere->xyz) + near->w; 536 if (distToCenter < -sphere->w) { 537 return false; 538 } 539 distToCenter = dot(far->xyz, sphere->xyz) + far->w; 540 if (distToCenter < -sphere->w) { 541 return false; 542 } 543 return true; 544 } 545 546 547 ///////////////////////////////////////////////////// 548 // int ops 549 ///////////////////////////////////////////////////// 550 551 _RS_RUNTIME uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high); 552 _RS_RUNTIME int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high); 553 _RS_RUNTIME ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high); 554 _RS_RUNTIME short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high); 555 _RS_RUNTIME uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high); 556 _RS_RUNTIME char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high); 557 558 #undef _RS_RUNTIME 559 560 #endif 561