rs_core.rsh revision 95333f998fd4a983f89e5128e85f6f710d200bd9
1#ifndef __RS_CORE_RSH__ 2#define __RS_CORE_RSH__ 3 4static void __attribute__((overloadable)) rsDebug(const char *s, float2 v) { 5 rsDebug(s, v.x, v.y); 6} 7static void __attribute__((overloadable)) rsDebug(const char *s, float3 v) { 8 rsDebug(s, v.x, v.y, v.z); 9} 10static void __attribute__((overloadable)) rsDebug(const char *s, float4 v) { 11 rsDebug(s, v.x, v.y, v.z, v.w); 12} 13 14static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b) 15{ 16 uchar4 c; 17 c.x = (uchar)(r * 255.f); 18 c.y = (uchar)(g * 255.f); 19 c.z = (uchar)(b * 255.f); 20 c.w = 255; 21 return c; 22} 23 24static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a) 25{ 26 uchar4 c; 27 c.x = (uchar)(r * 255.f); 28 c.y = (uchar)(g * 255.f); 29 c.z = (uchar)(b * 255.f); 30 c.w = (uchar)(a * 255.f); 31 return c; 32} 33 34static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color) 35{ 36 color *= 255.f; 37 uchar4 c = {color.x, color.y, color.z, 255}; 38 return c; 39} 40 41static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color) 42{ 43 color *= 255.f; 44 uchar4 c = {color.x, color.y, color.z, color.w}; 45 return c; 46} 47 48static float4 rsUnpackColor8888(uchar4 c) 49{ 50 float4 ret = (float4)0.0039156862745f; 51 ret *= convert_float4(c); 52 return ret; 53} 54 55//extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float r, float g, float b); 56//extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float3); 57//extern float4 rsUnpackColor565(uchar4); 58 59 60///////////////////////////////////////////////////// 61// Matrix ops 62///////////////////////////////////////////////////// 63 64static void __attribute__((overloadable)) 65rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) { 66 m->m[row * 4 + col] = v; 67} 68 69static float __attribute__((overloadable)) 70rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) { 71 return m->m[row * 4 + col]; 72} 73 74static void __attribute__((overloadable)) 75rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) { 76 m->m[row * 3 + col] = v; 77} 78 79static float __attribute__((overloadable)) 80rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) { 81 return m->m[row * 3 + col]; 82} 83 84static void __attribute__((overloadable)) 85rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) { 86 m->m[row * 2 + col] = v; 87} 88 89static float __attribute__((overloadable)) 90rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) { 91 return m->m[row * 2 + col]; 92} 93 94static void __attribute__((overloadable)) 95rsMatrixLoadIdentity(rs_matrix4x4 *m) { 96 m->m[0] = 1.f; 97 m->m[1] = 0.f; 98 m->m[2] = 0.f; 99 m->m[3] = 0.f; 100 m->m[4] = 0.f; 101 m->m[5] = 1.f; 102 m->m[6] = 0.f; 103 m->m[7] = 0.f; 104 m->m[8] = 0.f; 105 m->m[9] = 0.f; 106 m->m[10] = 1.f; 107 m->m[11] = 0.f; 108 m->m[12] = 0.f; 109 m->m[13] = 0.f; 110 m->m[14] = 0.f; 111 m->m[15] = 1.f; 112} 113 114static void __attribute__((overloadable)) 115rsMatrixLoadIdentity(rs_matrix3x3 *m) { 116 m->m[0] = 1.f; 117 m->m[1] = 0.f; 118 m->m[2] = 0.f; 119 m->m[3] = 0.f; 120 m->m[4] = 1.f; 121 m->m[5] = 0.f; 122 m->m[6] = 0.f; 123 m->m[7] = 0.f; 124 m->m[8] = 1.f; 125} 126 127static void __attribute__((overloadable)) 128rsMatrixLoadIdentity(rs_matrix2x2 *m) { 129 m->m[0] = 1.f; 130 m->m[1] = 0.f; 131 m->m[2] = 0.f; 132 m->m[3] = 1.f; 133} 134 135static void __attribute__((overloadable)) 136rsMatrixLoad(rs_matrix4x4 *m, const float *v) { 137 m->m[0] = v[0]; 138 m->m[1] = v[1]; 139 m->m[2] = v[2]; 140 m->m[3] = v[3]; 141 m->m[4] = v[4]; 142 m->m[5] = v[5]; 143 m->m[6] = v[6]; 144 m->m[7] = v[7]; 145 m->m[8] = v[8]; 146 m->m[9] = v[9]; 147 m->m[10] = v[10]; 148 m->m[11] = v[11]; 149 m->m[12] = v[12]; 150 m->m[13] = v[13]; 151 m->m[14] = v[14]; 152 m->m[15] = v[15]; 153} 154 155static void __attribute__((overloadable)) 156rsMatrixLoad(rs_matrix3x3 *m, const float *v) { 157 m->m[0] = v[0]; 158 m->m[1] = v[1]; 159 m->m[2] = v[2]; 160 m->m[3] = v[3]; 161 m->m[4] = v[4]; 162 m->m[5] = v[5]; 163 m->m[6] = v[6]; 164 m->m[7] = v[7]; 165 m->m[8] = v[8]; 166} 167 168static void __attribute__((overloadable)) 169rsMatrixLoad(rs_matrix2x2 *m, const float *v) { 170 m->m[0] = v[0]; 171 m->m[1] = v[1]; 172 m->m[2] = v[2]; 173 m->m[3] = v[3]; 174} 175 176static void __attribute__((overloadable)) 177rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v) { 178 m->m[0] = v->m[0]; 179 m->m[1] = v->m[1]; 180 m->m[2] = v->m[2]; 181 m->m[3] = v->m[3]; 182 m->m[4] = v->m[4]; 183 m->m[5] = v->m[5]; 184 m->m[6] = v->m[6]; 185 m->m[7] = v->m[7]; 186 m->m[8] = v->m[8]; 187 m->m[9] = v->m[9]; 188 m->m[10] = v->m[10]; 189 m->m[11] = v->m[11]; 190 m->m[12] = v->m[12]; 191 m->m[13] = v->m[13]; 192 m->m[14] = v->m[14]; 193 m->m[15] = v->m[15]; 194} 195 196static void __attribute__((overloadable)) 197rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) { 198 m->m[0] = v->m[0]; 199 m->m[1] = v->m[1]; 200 m->m[2] = v->m[2]; 201 m->m[3] = 0.f; 202 m->m[4] = v->m[3]; 203 m->m[5] = v->m[4]; 204 m->m[6] = v->m[5]; 205 m->m[7] = 0.f; 206 m->m[8] = v->m[6]; 207 m->m[9] = v->m[7]; 208 m->m[10] = v->m[8]; 209 m->m[11] = 0.f; 210 m->m[12] = 0.f; 211 m->m[13] = 0.f; 212 m->m[14] = 0.f; 213 m->m[15] = 1.f; 214} 215 216static void __attribute__((overloadable)) 217rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) { 218 m->m[0] = v->m[0]; 219 m->m[1] = v->m[1]; 220 m->m[2] = 0.f; 221 m->m[3] = 0.f; 222 m->m[4] = v->m[3]; 223 m->m[5] = v->m[4]; 224 m->m[6] = 0.f; 225 m->m[7] = 0.f; 226 m->m[8] = v->m[6]; 227 m->m[9] = v->m[7]; 228 m->m[10] = 1.f; 229 m->m[11] = 0.f; 230 m->m[12] = 0.f; 231 m->m[13] = 0.f; 232 m->m[14] = 0.f; 233 m->m[15] = 1.f; 234} 235 236static void __attribute__((overloadable)) 237rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v) { 238 m->m[0] = v->m[0]; 239 m->m[1] = v->m[1]; 240 m->m[2] = v->m[2]; 241 m->m[3] = v->m[3]; 242 m->m[4] = v->m[4]; 243 m->m[5] = v->m[5]; 244 m->m[6] = v->m[6]; 245 m->m[7] = v->m[7]; 246 m->m[8] = v->m[8]; 247} 248 249static void __attribute__((overloadable)) 250rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v) { 251 m->m[0] = v->m[0]; 252 m->m[1] = v->m[1]; 253 m->m[2] = v->m[2]; 254 m->m[3] = v->m[3]; 255} 256 257static void __attribute__((overloadable)) 258rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 259 float c, s; 260 m->m[3] = 0; 261 m->m[7] = 0; 262 m->m[11]= 0; 263 m->m[12]= 0; 264 m->m[13]= 0; 265 m->m[14]= 0; 266 m->m[15]= 1; 267 rot *= (float)(M_PI / 180.0f); 268 c = cos(rot); 269 s = sin(rot); 270 271 const float len = x*x + y*y + z*z; 272 if (len != 1) { 273 const float recipLen = 1.f / sqrt(len); 274 x *= recipLen; 275 y *= recipLen; 276 z *= recipLen; 277 } 278 const float nc = 1.0f - c; 279 const float xy = x * y; 280 const float yz = y * z; 281 const float zx = z * x; 282 const float xs = x * s; 283 const float ys = y * s; 284 const float zs = z * s; 285 m->m[ 0] = x*x*nc + c; 286 m->m[ 4] = xy*nc - zs; 287 m->m[ 8] = zx*nc + ys; 288 m->m[ 1] = xy*nc + zs; 289 m->m[ 5] = y*y*nc + c; 290 m->m[ 9] = yz*nc - xs; 291 m->m[ 2] = zx*nc - ys; 292 m->m[ 6] = yz*nc + xs; 293 m->m[10] = z*z*nc + c; 294} 295 296static void __attribute__((overloadable)) 297rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) { 298 rsMatrixLoadIdentity(m); 299 m->m[0] = x; 300 m->m[5] = y; 301 m->m[10] = z; 302} 303 304static void __attribute__((overloadable)) 305rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) { 306 rsMatrixLoadIdentity(m); 307 m->m[12] = x; 308 m->m[13] = y; 309 m->m[14] = z; 310} 311 312static void __attribute__((overloadable)) 313rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) { 314 for (int i=0 ; i<4 ; i++) { 315 float ri0 = 0; 316 float ri1 = 0; 317 float ri2 = 0; 318 float ri3 = 0; 319 for (int j=0 ; j<4 ; j++) { 320 const float rhs_ij = rsMatrixGet(rhs, i,j); 321 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 322 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 323 ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 324 ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij; 325 } 326 rsMatrixSet(m, i, 0, ri0); 327 rsMatrixSet(m, i, 1, ri1); 328 rsMatrixSet(m, i, 2, ri2); 329 rsMatrixSet(m, i, 3, ri3); 330 } 331} 332 333static void __attribute__((overloadable)) 334rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) { 335 rs_matrix4x4 mt; 336 rsMatrixLoadMultiply(&mt, m, rhs); 337 rsMatrixLoad(m, &mt); 338} 339 340static void __attribute__((overloadable)) 341rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) { 342 for (int i=0 ; i<3 ; i++) { 343 float ri0 = 0; 344 float ri1 = 0; 345 float ri2 = 0; 346 for (int j=0 ; j<3 ; j++) { 347 const float rhs_ij = rsMatrixGet(rhs, i,j); 348 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 349 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 350 ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 351 } 352 rsMatrixSet(m, i, 0, ri0); 353 rsMatrixSet(m, i, 1, ri1); 354 rsMatrixSet(m, i, 2, ri2); 355 } 356} 357 358static void __attribute__((overloadable)) 359rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) { 360 rs_matrix3x3 mt; 361 rsMatrixLoadMultiply(&mt, m, rhs); 362 rsMatrixLoad(m, &mt); 363} 364 365static void __attribute__((overloadable)) 366rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) { 367 for (int i=0 ; i<2 ; i++) { 368 float ri0 = 0; 369 float ri1 = 0; 370 for (int j=0 ; j<2 ; j++) { 371 const float rhs_ij = rsMatrixGet(rhs, i,j); 372 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 373 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 374 } 375 rsMatrixSet(m, i, 0, ri0); 376 rsMatrixSet(m, i, 1, ri1); 377 } 378} 379 380static void __attribute__((overloadable)) 381rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) { 382 rs_matrix2x2 mt; 383 rsMatrixLoadMultiply(&mt, m, rhs); 384 rsMatrixLoad(m, &mt); 385} 386 387static void __attribute__((overloadable)) 388rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 389 rs_matrix4x4 m1; 390 rsMatrixLoadRotate(&m1, rot, x, y, z); 391 rsMatrixMultiply(m, &m1); 392} 393 394static void __attribute__((overloadable)) 395rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z) { 396 rs_matrix4x4 m1; 397 rsMatrixLoadScale(&m1, x, y, z); 398 rsMatrixMultiply(m, &m1); 399} 400 401static void __attribute__((overloadable)) 402rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) { 403 rs_matrix4x4 m1; 404 rsMatrixLoadTranslate(&m1, x, y, z); 405 rsMatrixMultiply(m, &m1); 406} 407 408static void __attribute__((overloadable)) 409rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 410 rsMatrixLoadIdentity(m); 411 m->m[0] = 2.f / (right - left); 412 m->m[5] = 2.f / (top - bottom); 413 m->m[10]= -2.f / (far - near); 414 m->m[12]= -(right + left) / (right - left); 415 m->m[13]= -(top + bottom) / (top - bottom); 416 m->m[14]= -(far + near) / (far - near); 417} 418 419static void __attribute__((overloadable)) 420rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 421 rsMatrixLoadIdentity(m); 422 m->m[0] = 2.f * near / (right - left); 423 m->m[5] = 2.f * near / (top - bottom); 424 m->m[8] = (right + left) / (right - left); 425 m->m[9] = (top + bottom) / (top - bottom); 426 m->m[10]= -(far + near) / (far - near); 427 m->m[11]= -1.f; 428 m->m[14]= -2.f * far * near / (far - near); 429 m->m[15]= 0.f; 430} 431 432static float4 __attribute__((overloadable)) 433rsMatrixMultiply(rs_matrix4x4 *m, float4 in) { 434 float4 ret; 435 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w); 436 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + (m->m[13] * in.w); 437 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + (m->m[14] * in.w); 438 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + (m->m[15] * in.w); 439 return ret; 440} 441 442static float4 __attribute__((overloadable)) 443rsMatrixMultiply(rs_matrix4x4 *m, float3 in) { 444 float4 ret; 445 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12]; 446 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + m->m[13]; 447 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + m->m[14]; 448 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + m->m[15]; 449 return ret; 450} 451 452static float4 __attribute__((overloadable)) 453rsMatrixMultiply(rs_matrix4x4 *m, float2 in) { 454 float4 ret; 455 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12]; 456 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + m->m[13]; 457 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + m->m[14]; 458 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + m->m[15]; 459 return ret; 460} 461 462static float3 __attribute__((overloadable)) 463rsMatrixMultiply(rs_matrix3x3 *m, float3 in) { 464 float3 ret; 465 ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z); 466 ret.y = (m->m[1] * in.x) + (m->m[4] * in.y) + (m->m[7] * in.z); 467 ret.z = (m->m[2] * in.x) + (m->m[5] * in.y) + (m->m[8] * in.z); 468 return ret; 469} 470 471static float3 __attribute__((overloadable)) 472rsMatrixMultiply(rs_matrix3x3 *m, float2 in) { 473 float3 ret; 474 ret.x = (m->m[0] * in.x) + (m->m[3] * in.y); 475 ret.y = (m->m[1] * in.x) + (m->m[4] * in.y); 476 ret.z = (m->m[2] * in.x) + (m->m[5] * in.y); 477 return ret; 478} 479 480static float2 __attribute__((overloadable)) 481rsMatrixMultiply(rs_matrix2x2 *m, float2 in) { 482 float2 ret; 483 ret.x = (m->m[0] * in.x) + (m->m[2] * in.y); 484 ret.y = (m->m[1] * in.x) + (m->m[3] * in.y); 485 return ret; 486} 487 488// Returns true if the matrix was successfully inversed 489static bool __attribute__((overloadable)) 490rsMatrixInverse(rs_matrix4x4 *m) { 491 rs_matrix4x4 result; 492 493 int i, j; 494 for (i = 0; i < 4; ++i) { 495 for (j = 0; j < 4; ++j) { 496 // computeCofactor for int i, int j 497 int c0 = (i+1) % 4; 498 int c1 = (i+2) % 4; 499 int c2 = (i+3) % 4; 500 int r0 = (j+1) % 4; 501 int r1 = (j+2) % 4; 502 int r2 = (j+3) % 4; 503 504 float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1])) 505 - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0])) 506 + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0])); 507 508 float cofactor = (i+j) & 1 ? -minor : minor; 509 510 result.m[4*i + j] = cofactor; 511 } 512 } 513 514 // Dot product of 0th column of source and 0th row of result 515 float det = m->m[0]*result.m[0] + m->m[4]*result.m[1] + 516 m->m[8]*result.m[2] + m->m[12]*result.m[3]; 517 518 if (fabs(det) < 1e-6) { 519 return false; 520 } 521 522 det = 1.0f / det; 523 for (i = 0; i < 16; ++i) { 524 m->m[i] = result.m[i] * det; 525 } 526 527 return true; 528} 529 530// Returns true if the matrix was successfully inversed 531static bool __attribute__((overloadable)) 532rsMatrixInverseTranspose(rs_matrix4x4 *m) { 533 rs_matrix4x4 result; 534 535 int i, j; 536 for (i = 0; i < 4; ++i) { 537 for (j = 0; j < 4; ++j) { 538 // computeCofactor for int i, int j 539 int c0 = (i+1) % 4; 540 int c1 = (i+2) % 4; 541 int c2 = (i+3) % 4; 542 int r0 = (j+1) % 4; 543 int r1 = (j+2) % 4; 544 int r2 = (j+3) % 4; 545 546 float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1])) 547 - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0])) 548 + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0])); 549 550 float cofactor = (i+j) & 1 ? -minor : minor; 551 552 result.m[4*j + i] = cofactor; 553 } 554 } 555 556 // Dot product of 0th column of source and 0th column of result 557 float det = m->m[0]*result.m[0] + m->m[4]*result.m[4] + 558 m->m[8]*result.m[8] + m->m[12]*result.m[12]; 559 560 if (fabs(det) < 1e-6) { 561 return false; 562 } 563 564 det = 1.0f / det; 565 for (i = 0; i < 16; ++i) { 566 m->m[i] = result.m[i] * det; 567 } 568 569 return true; 570} 571 572static void __attribute__((overloadable)) 573rsMatrixTranspose(rs_matrix4x4 *m) { 574 int i, j; 575 float temp; 576 for (i = 0; i < 3; ++i) { 577 for (j = i + 1; j < 4; ++j) { 578 temp = m->m[i*4 + j]; 579 m->m[i*4 + j] = m->m[j*4 + i]; 580 m->m[j*4 + i] = temp; 581 } 582 } 583} 584 585static void __attribute__((overloadable)) 586rsMatrixTranspose(rs_matrix3x3 *m) { 587 int i, j; 588 float temp; 589 for (i = 0; i < 2; ++i) { 590 for (j = i + 1; j < 3; ++j) { 591 temp = m->m[i*3 + j]; 592 m->m[i*3 + j] = m->m[j*4 + i]; 593 m->m[j*3 + i] = temp; 594 } 595 } 596} 597 598static void __attribute__((overloadable)) 599rsMatrixTranspose(rs_matrix2x2 *m) { 600 float temp = m->m[1]; 601 m->m[1] = m->m[2]; 602 m->m[2] = temp; 603} 604 605///////////////////////////////////////////////////// 606// quaternion ops 607///////////////////////////////////////////////////// 608 609static void __attribute__((overloadable)) 610rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) { 611 q->w = w; 612 q->x = x; 613 q->y = y; 614 q->z = z; 615} 616 617static void __attribute__((overloadable)) 618rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) { 619 q->w = rhs->w; 620 q->x = rhs->x; 621 q->y = rhs->y; 622 q->z = rhs->z; 623} 624 625static void __attribute__((overloadable)) 626rsQuaternionMultiply(rs_quaternion *q, float s) { 627 q->w *= s; 628 q->x *= s; 629 q->y *= s; 630 q->z *= s; 631} 632 633static void __attribute__((overloadable)) 634rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) { 635 q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w; 636 q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x; 637 q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->z + q->w*rhs->y; 638 q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z; 639} 640 641static void 642rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) { 643 q->w *= rhs->w; 644 q->x *= rhs->x; 645 q->y *= rhs->y; 646 q->z *= rhs->z; 647} 648 649static void 650rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) { 651 rot *= (float)(M_PI / 180.0f) * 0.5f; 652 float c = cos(rot); 653 float s = sin(rot); 654 655 q->w = c; 656 q->x = x * s; 657 q->y = y * s; 658 q->z = z * s; 659} 660 661static void 662rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) { 663 const float len = x*x + y*y + z*z; 664 if (len != 1) { 665 const float recipLen = 1.f / sqrt(len); 666 x *= recipLen; 667 y *= recipLen; 668 z *= recipLen; 669 } 670 rsQuaternionLoadRotateUnit(q, rot, x, y, z); 671} 672 673static void 674rsQuaternionConjugate(rs_quaternion *q) { 675 q->x = -q->x; 676 q->y = -q->y; 677 q->z = -q->z; 678} 679 680static float 681rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) { 682 return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z; 683} 684 685static void 686rsQuaternionNormalize(rs_quaternion *q) { 687 const float len = rsQuaternionDot(q, q); 688 if (len != 1) { 689 const float recipLen = 1.f / sqrt(len); 690 rsQuaternionMultiply(q, recipLen); 691 } 692} 693 694static void 695rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) { 696 if(t <= 0.0f) { 697 rsQuaternionSet(q, q0); 698 return; 699 } 700 if(t >= 1.0f) { 701 rsQuaternionSet(q, q1); 702 return; 703 } 704 705 rs_quaternion tempq0, tempq1; 706 rsQuaternionSet(&tempq0, q0); 707 rsQuaternionSet(&tempq1, q1); 708 709 float angle = rsQuaternionDot(q0, q1); 710 if(angle < 0) { 711 rsQuaternionMultiply(&tempq0, -1.0f); 712 angle *= -1.0f; 713 } 714 715 float scale, invScale; 716 if (angle + 1.0f > 0.05f) { 717 if (1.0f - angle >= 0.05f) { 718 float theta = acos(angle); 719 float invSinTheta = 1.0f / sin(theta); 720 scale = sin(theta * (1.0f - t)) * invSinTheta; 721 invScale = sin(theta * t) * invSinTheta; 722 } 723 else { 724 scale = 1.0f - t; 725 invScale = t; 726 } 727 } 728 else { 729 rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w); 730 scale = sin(M_PI * (0.5f - t)); 731 invScale = sin(M_PI * t); 732 } 733 734 rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale, 735 tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale); 736} 737 738static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) { 739 float x2 = 2.0f * q->x * q->x; 740 float y2 = 2.0f * q->y * q->y; 741 float z2 = 2.0f * q->z * q->z; 742 float xy = 2.0f * q->x * q->y; 743 float wz = 2.0f * q->w * q->z; 744 float xz = 2.0f * q->x * q->z; 745 float wy = 2.0f * q->w * q->y; 746 float wx = 2.0f * q->w * q->x; 747 float yz = 2.0f * q->y * q->z; 748 749 m->m[0] = 1.0f - y2 - z2; 750 m->m[1] = xy - wz; 751 m->m[2] = xz + wy; 752 m->m[3] = 0.0f; 753 754 m->m[4] = xy + wz; 755 m->m[5] = 1.0f - x2 - z2; 756 m->m[6] = yz - wx; 757 m->m[7] = 0.0f; 758 759 m->m[8] = xz - wy; 760 m->m[9] = yz - wx; 761 m->m[10] = 1.0f - x2 - y2; 762 m->m[11] = 0.0f; 763 764 m->m[12] = 0.0f; 765 m->m[13] = 0.0f; 766 m->m[14] = 0.0f; 767 m->m[15] = 1.0f; 768} 769 770///////////////////////////////////////////////////// 771// utility funcs 772///////////////////////////////////////////////////// 773void __attribute__((overloadable)) 774rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj, 775 float4 *left, float4 *right, 776 float4 *top, float4 *bottom, 777 float4 *near, float4 *far) { 778 // x y z w = a b c d in the plane equation 779 left->x = modelViewProj->m[3] + modelViewProj->m[0]; 780 left->y = modelViewProj->m[7] + modelViewProj->m[4]; 781 left->z = modelViewProj->m[11] + modelViewProj->m[8]; 782 left->w = modelViewProj->m[15] + modelViewProj->m[12]; 783 784 right->x = modelViewProj->m[3] - modelViewProj->m[0]; 785 right->y = modelViewProj->m[7] - modelViewProj->m[4]; 786 right->z = modelViewProj->m[11] - modelViewProj->m[8]; 787 right->w = modelViewProj->m[15] - modelViewProj->m[12]; 788 789 top->x = modelViewProj->m[3] - modelViewProj->m[1]; 790 top->y = modelViewProj->m[7] - modelViewProj->m[5]; 791 top->z = modelViewProj->m[11] - modelViewProj->m[9]; 792 top->w = modelViewProj->m[15] - modelViewProj->m[13]; 793 794 bottom->x = modelViewProj->m[3] + modelViewProj->m[1]; 795 bottom->y = modelViewProj->m[7] + modelViewProj->m[5]; 796 bottom->z = modelViewProj->m[11] + modelViewProj->m[9]; 797 bottom->w = modelViewProj->m[15] + modelViewProj->m[13]; 798 799 near->x = modelViewProj->m[3] + modelViewProj->m[2]; 800 near->y = modelViewProj->m[7] + modelViewProj->m[6]; 801 near->z = modelViewProj->m[11] + modelViewProj->m[10]; 802 near->w = modelViewProj->m[15] + modelViewProj->m[14]; 803 804 far->x = modelViewProj->m[3] - modelViewProj->m[2]; 805 far->y = modelViewProj->m[7] - modelViewProj->m[6]; 806 far->z = modelViewProj->m[11] - modelViewProj->m[10]; 807 far->w = modelViewProj->m[15] - modelViewProj->m[14]; 808 809 float len = length(left->xyz); 810 *left /= len; 811 len = length(right->xyz); 812 *right /= len; 813 len = length(top->xyz); 814 *top /= len; 815 len = length(bottom->xyz); 816 *bottom /= len; 817 len = length(near->xyz); 818 *near /= len; 819 len = length(far->xyz); 820 *far /= len; 821} 822 823bool __attribute__((overloadable)) 824rsIsSphereInFrustum(float4 *sphere, 825 float4 *left, float4 *right, 826 float4 *top, float4 *bottom, 827 float4 *near, float4 *far) { 828 829 float distToCenter = dot(left->xyz, sphere->xyz) + left->w; 830 if(distToCenter < -sphere->w) { 831 return false; 832 } 833 distToCenter = dot(right->xyz, sphere->xyz) + right->w; 834 if(distToCenter < -sphere->w) { 835 return false; 836 } 837 distToCenter = dot(top->xyz, sphere->xyz) + top->w; 838 if(distToCenter < -sphere->w) { 839 return false; 840 } 841 distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w; 842 if(distToCenter < -sphere->w) { 843 return false; 844 } 845 distToCenter = dot(near->xyz, sphere->xyz) + near->w; 846 if(distToCenter < -sphere->w) { 847 return false; 848 } 849 distToCenter = dot(far->xyz, sphere->xyz) + far->w; 850 if(distToCenter < -sphere->w) { 851 return false; 852 } 853 return true; 854} 855 856 857///////////////////////////////////////////////////// 858// int ops 859///////////////////////////////////////////////////// 860 861__inline__ static uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) { 862 return amount < low ? low : (amount > high ? high : amount); 863} 864__inline__ static int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) { 865 return amount < low ? low : (amount > high ? high : amount); 866} 867__inline__ static ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) { 868 return amount < low ? low : (amount > high ? high : amount); 869} 870__inline__ static short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) { 871 return amount < low ? low : (amount > high ? high : amount); 872} 873__inline__ static uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) { 874 return amount < low ? low : (amount > high ? high : amount); 875} 876__inline__ static char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) { 877 return amount < low ? low : (amount > high ? high : amount); 878} 879 880 881 882#endif 883 884