rs_core.rsh revision f6a28c6a71d8929fb90ca83634a617d69531d87d
1275b1e98bb949643d35546f10f8b1af009349526Jason Sams#ifndef __RS_CORE_RSH__ 2275b1e98bb949643d35546f10f8b1af009349526Jason Sams#define __RS_CORE_RSH__ 3275b1e98bb949643d35546f10f8b1af009349526Jason Sams 4f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#ifdef BCC_PREPARE_BC 5f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#define _RS_STATIC extern 6f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#else 7f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#define _RS_STATIC static 8f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#endif 9f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines 109bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao// Debugging, print to the LOG a description string and a value. 119bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 129bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, float); 139bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 149bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, float, float); 159bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 169bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, float, float, float); 179bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 189bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, float, float, float, float); 199bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 20df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines rsDebug(const char *, double); 21df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hinesextern void __attribute__((overloadable)) 229bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, const rs_matrix4x4 *); 239bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 249bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, const rs_matrix3x3 *); 259bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 269bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, const rs_matrix2x2 *); 279bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 289bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, int); 299bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 309bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, uint); 319bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liaoextern void __attribute__((overloadable)) 32df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines rsDebug(const char *, long); 33df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hinesextern void __attribute__((overloadable)) 34df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines rsDebug(const char *, unsigned long); 35df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hinesextern void __attribute__((overloadable)) 36df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines rsDebug(const char *, long long); 37df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hinesextern void __attribute__((overloadable)) 38df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines rsDebug(const char *, unsigned long long); 39df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hinesextern void __attribute__((overloadable)) 409bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao rsDebug(const char *, const void *); 419bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#define RS_DEBUG(a) rsDebug(#a, a) 429bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__) 439bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao 44f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float2 v) { 457dce6bc09126187534ab0297c66b30149643b162Jason Sams rsDebug(s, v.x, v.y); 467dce6bc09126187534ab0297c66b30149643b162Jason Sams} 47f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float3 v) { 487dce6bc09126187534ab0297c66b30149643b162Jason Sams rsDebug(s, v.x, v.y, v.z); 497dce6bc09126187534ab0297c66b30149643b162Jason Sams} 50f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float4 v) { 517dce6bc09126187534ab0297c66b30149643b162Jason Sams rsDebug(s, v.x, v.y, v.z, v.w); 527dce6bc09126187534ab0297c66b30149643b162Jason Sams} 53275b1e98bb949643d35546f10f8b1af009349526Jason Sams 54f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b) 55275b1e98bb949643d35546f10f8b1af009349526Jason Sams{ 56275b1e98bb949643d35546f10f8b1af009349526Jason Sams uchar4 c; 57275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.x = (uchar)(r * 255.f); 58275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.y = (uchar)(g * 255.f); 59275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.z = (uchar)(b * 255.f); 60275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.w = 255; 61275b1e98bb949643d35546f10f8b1af009349526Jason Sams return c; 62275b1e98bb949643d35546f10f8b1af009349526Jason Sams} 63275b1e98bb949643d35546f10f8b1af009349526Jason Sams 64f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a) 65275b1e98bb949643d35546f10f8b1af009349526Jason Sams{ 66275b1e98bb949643d35546f10f8b1af009349526Jason Sams uchar4 c; 67275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.x = (uchar)(r * 255.f); 68275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.y = (uchar)(g * 255.f); 69275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.z = (uchar)(b * 255.f); 70275b1e98bb949643d35546f10f8b1af009349526Jason Sams c.w = (uchar)(a * 255.f); 71275b1e98bb949643d35546f10f8b1af009349526Jason Sams return c; 72275b1e98bb949643d35546f10f8b1af009349526Jason Sams} 73275b1e98bb949643d35546f10f8b1af009349526Jason Sams 74f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color) 75275b1e98bb949643d35546f10f8b1af009349526Jason Sams{ 76275b1e98bb949643d35546f10f8b1af009349526Jason Sams color *= 255.f; 77275b1e98bb949643d35546f10f8b1af009349526Jason Sams uchar4 c = {color.x, color.y, color.z, 255}; 78275b1e98bb949643d35546f10f8b1af009349526Jason Sams return c; 79275b1e98bb949643d35546f10f8b1af009349526Jason Sams} 80275b1e98bb949643d35546f10f8b1af009349526Jason Sams 81f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color) 82275b1e98bb949643d35546f10f8b1af009349526Jason Sams{ 83275b1e98bb949643d35546f10f8b1af009349526Jason Sams color *= 255.f; 84275b1e98bb949643d35546f10f8b1af009349526Jason Sams uchar4 c = {color.x, color.y, color.z, color.w}; 85275b1e98bb949643d35546f10f8b1af009349526Jason Sams return c; 86275b1e98bb949643d35546f10f8b1af009349526Jason Sams} 87275b1e98bb949643d35546f10f8b1af009349526Jason Sams 88f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 rsUnpackColor8888(uchar4 c) 89275b1e98bb949643d35546f10f8b1af009349526Jason Sams{ 901b937f5c0d66a65daf07a45554c98a9f2481b9baJason Sams float4 ret = (float4)0.0039156862745f; 911b937f5c0d66a65daf07a45554c98a9f2481b9baJason Sams ret *= convert_float4(c); 92275b1e98bb949643d35546f10f8b1af009349526Jason Sams return ret; 93275b1e98bb949643d35546f10f8b1af009349526Jason Sams} 94275b1e98bb949643d35546f10f8b1af009349526Jason Sams 952a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams//extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float r, float g, float b); 962a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams//extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float3); 972a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams//extern float4 rsUnpackColor565(uchar4); 982a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams 992a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams 1007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams///////////////////////////////////////////////////// 1017fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams// Matrix ops 1027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams///////////////////////////////////////////////////// 1037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 104f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) { 1067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[row * 4 + col] = v; 1077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1087fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 109f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float __attribute__((overloadable)) 1107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) { 1117fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return m->m[row * 4 + col]; 1127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 114f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) { 1167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[row * 3 + col] = v; 1177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 119f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float __attribute__((overloadable)) 1207fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) { 1217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return m->m[row * 3 + col]; 1227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 124f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) { 1267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[row * 2 + col] = v; 1277fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 129f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float __attribute__((overloadable)) 1307fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) { 1317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return m->m[row * 2 + col]; 1327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 134f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadIdentity(rs_matrix4x4 *m) { 1367fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = 1.f; 1377fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = 0.f; 1387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = 0.f; 1397fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 0.f; 1407fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = 0.f; 1417fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = 1.f; 1427fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = 0.f; 1437fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = 0.f; 1447fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = 0.f; 1457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = 0.f; 1467fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = 1.f; 1477fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11] = 0.f; 1487fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = 0.f; 1497fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = 0.f; 1507fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = 0.f; 1517fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15] = 1.f; 1527fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1537fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 154f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1557fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadIdentity(rs_matrix3x3 *m) { 1567fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = 1.f; 1577fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = 0.f; 1587fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = 0.f; 1597fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 0.f; 1607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = 1.f; 1617fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = 0.f; 1627fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = 0.f; 1637fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = 0.f; 1647fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = 1.f; 1657fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 167f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1687fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadIdentity(rs_matrix2x2 *m) { 1697fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = 1.f; 1707fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = 0.f; 1717fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = 0.f; 1727fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 1.f; 1737fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1747fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 175f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1767fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix4x4 *m, const float *v) { 1777fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v[0]; 1787fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v[1]; 1797fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v[2]; 1807fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v[3]; 1817fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v[4]; 1827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v[5]; 1837fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = v[6]; 1847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = v[7]; 1857fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v[8]; 1867fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = v[9]; 1877fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = v[10]; 1887fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11] = v[11]; 1897fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = v[12]; 1907fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = v[13]; 1917fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = v[14]; 1927fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15] = v[15]; 1937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 1947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 195f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 1967fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix3x3 *m, const float *v) { 1977fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v[0]; 1987fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v[1]; 1997fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v[2]; 2007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v[3]; 2017fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v[4]; 2027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v[5]; 2037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = v[6]; 2047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = v[7]; 2057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v[8]; 2067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 208f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix2x2 *m, const float *v) { 2107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v[0]; 2117fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v[1]; 2127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v[2]; 2137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v[3]; 2147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 216f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v) { 2187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v->m[0]; 2197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v->m[1]; 2207fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v->m[2]; 2217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v->m[3]; 2227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v->m[4]; 2237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v->m[5]; 2247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = v->m[6]; 2257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = v->m[7]; 2267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v->m[8]; 2277fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = v->m[9]; 2287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = v->m[10]; 2297fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11] = v->m[11]; 2307fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = v->m[12]; 2317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = v->m[13]; 2327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = v->m[14]; 2337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15] = v->m[15]; 2347fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 236f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2377fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) { 2387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v->m[0]; 2397fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v->m[1]; 2407fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v->m[2]; 2417fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 0.f; 2427fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v->m[3]; 2437fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v->m[4]; 2447fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = v->m[5]; 2457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = 0.f; 2467fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v->m[6]; 2477fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = v->m[7]; 2487fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = v->m[8]; 2497fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11] = 0.f; 2507fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = 0.f; 2517fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = 0.f; 2527fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = 0.f; 2537fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15] = 1.f; 2547fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2557fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 256f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2577fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) { 2587fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v->m[0]; 2597fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v->m[1]; 2607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = 0.f; 2617fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 0.f; 2627fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v->m[3]; 2637fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v->m[4]; 2647fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = 0.f; 2657fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = 0.f; 2667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v->m[6]; 2677fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = v->m[7]; 2687fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = 1.f; 2697fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11] = 0.f; 2707fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = 0.f; 2717fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = 0.f; 2727fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = 0.f; 2737fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15] = 1.f; 2747fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2757fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 276f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2777fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v) { 2787fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v->m[0]; 2797fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v->m[1]; 2807fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v->m[2]; 2817fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v->m[3]; 2827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[4] = v->m[4]; 2837fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = v->m[5]; 2847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[6] = v->m[6]; 2857fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = v->m[7]; 2867fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = v->m[8]; 2877fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2887fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 289f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2907fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v) { 2917fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = v->m[0]; 2927fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[1] = v->m[1]; 2937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[2] = v->m[2]; 2947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = v->m[3]; 2957fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2967fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 297f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 2987fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 2997fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float c, s; 3007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[3] = 0; 3017fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[7] = 0; 3027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11]= 0; 3037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12]= 0; 3047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13]= 0; 3057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14]= 0; 3067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15]= 1; 3077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rot *= (float)(M_PI / 180.0f); 3087fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams c = cos(rot); 3097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams s = sin(rot); 3107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 3117fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float len = x*x + y*y + z*z; 31229a3fd50d1c85ef32b68838072452674ae311594Jason Sams if (len != 1) { 3137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float recipLen = 1.f / sqrt(len); 3147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams x *= recipLen; 3157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams y *= recipLen; 3167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams z *= recipLen; 3177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 3187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float nc = 1.0f - c; 3197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float xy = x * y; 3207fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float yz = y * z; 3217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float zx = z * x; 3227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float xs = x * s; 3237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float ys = y * s; 3247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float zs = z * s; 3257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 0] = x*x*nc + c; 3267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 4] = xy*nc - zs; 3277fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 8] = zx*nc + ys; 3287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 1] = xy*nc + zs; 3297fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 5] = y*y*nc + c; 3307fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 9] = yz*nc - xs; 3317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 2] = zx*nc - ys; 3327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[ 6] = yz*nc + xs; 3337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = z*z*nc + c; 3347fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 336f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3377fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) { 3387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadIdentity(m); 3397fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = x; 3407fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = y; 3417fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10] = z; 3427fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3437fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 344f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) { 3467fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadIdentity(m); 3477fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12] = x; 3487fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13] = y; 3497fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14] = z; 3507fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3517fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 352f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3537fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) { 3547fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int i=0 ; i<4 ; i++) { 3557fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri0 = 0; 3567fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri1 = 0; 3577fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri2 = 0; 3587fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri3 = 0; 3597fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int j=0 ; j<4 ; j++) { 3607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float rhs_ij = rsMatrixGet(rhs, i,j); 3617fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 3627fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 3637fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 3647fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij; 3657fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 3667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 0, ri0); 3677fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 1, ri1); 3687fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 2, ri2); 3697fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 3, ri3); 3707fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 3717fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3727fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 373f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3747fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) { 3757fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix4x4 mt; 3767fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadMultiply(&mt, m, rhs); 3777fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoad(m, &mt); 3787fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3797fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 380f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3817fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) { 3827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int i=0 ; i<3 ; i++) { 3837fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri0 = 0; 3847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri1 = 0; 3857fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri2 = 0; 3867fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int j=0 ; j<3 ; j++) { 3877fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float rhs_ij = rsMatrixGet(rhs, i,j); 3887fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 3897fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 3907fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 3917fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 3927fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 0, ri0); 3937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 1, ri1); 3947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 2, ri2); 3957fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 3967fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3977fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 398f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 3997fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) { 4007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix3x3 mt; 4017fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadMultiply(&mt, m, rhs); 4027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoad(m, &mt); 4037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 405f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) { 4077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int i=0 ; i<2 ; i++) { 4087fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri0 = 0; 4097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float ri1 = 0; 4107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams for (int j=0 ; j<2 ; j++) { 4117fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams const float rhs_ij = rsMatrixGet(rhs, i,j); 4127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 4137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 4147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 4157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 0, ri0); 4167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixSet(m, i, 1, ri1); 4177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams } 4187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 420f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) { 4227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix2x2 mt; 4237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadMultiply(&mt, m, rhs); 4247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoad(m, &mt); 4257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 427f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 4297fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix4x4 m1; 4307fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadRotate(&m1, rot, x, y, z); 4317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixMultiply(m, &m1); 4327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 434f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixScale(rs_matrix4x4 *m, float x, float y, float z) { 4367fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix4x4 m1; 4377fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadScale(&m1, x, y, z); 4387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixMultiply(m, &m1); 4397fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4407fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 441f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4427fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) { 4437fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rs_matrix4x4 m1; 4447fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadTranslate(&m1, x, y, z); 4457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixMultiply(m, &m1); 4467fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4477fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 448f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4497fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 4507fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadIdentity(m); 4517fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = 2.f / (right - left); 4527fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = 2.f / (top - bottom); 4537fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10]= -2.f / (far - near); 4547fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[12]= -(right + left) / (right - left); 4557fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[13]= -(top + bottom) / (top - bottom); 4567fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14]= -(far + near) / (far - near); 4577fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4587fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 459f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 4607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 4617fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams rsMatrixLoadIdentity(m); 4627fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[0] = 2.f * near / (right - left); 4637fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[5] = 2.f * near / (top - bottom); 4647fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[8] = (right + left) / (right - left); 4657fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[9] = (top + bottom) / (top - bottom); 4667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[10]= -(far + near) / (far - near); 4677fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[11]= -1.f; 4687fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[14]= -2.f * far * near / (far - near); 4697fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams m->m[15]= 0.f; 4707fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4717fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 472f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 473c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex SakhartchoukrsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far) { 474c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk float top = near * tan((float) (fovy * M_PI / 360.0f)); 475c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk float bottom = -top; 476c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk float left = bottom * aspect; 477c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk float right = top * aspect; 478c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk rsMatrixLoadFrustum(m, left, right, bottom, top, near, far); 479c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk} 480c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk 481f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable)) 4827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float4 in) { 4837fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float4 ret; 4847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w); 4857fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + (m->m[13] * in.w); 4867fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + (m->m[14] * in.w); 4877fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + (m->m[15] * in.w); 4887fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 4897fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 4907fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 491f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable)) 4927fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float3 in) { 4937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float4 ret; 4947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12]; 4957fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + m->m[13]; 4967fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + m->m[14]; 4977fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + m->m[15]; 4987fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 4997fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 5007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 501f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable)) 5027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float2 in) { 5037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float4 ret; 5047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12]; 5057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + m->m[13]; 5067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + m->m[14]; 5077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + m->m[15]; 5087fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 5097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 5107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 511f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float3 __attribute__((overloadable)) 5127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, float3 in) { 5137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float3 ret; 5147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z); 5157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[4] * in.y) + (m->m[7] * in.z); 5167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.z = (m->m[2] * in.x) + (m->m[5] * in.y) + (m->m[8] * in.z); 5177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 5187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 5197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 520f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float3 __attribute__((overloadable)) 5217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, float2 in) { 5227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float3 ret; 5237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[3] * in.y); 5247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[4] * in.y); 5257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.z = (m->m[2] * in.x) + (m->m[5] * in.y); 5267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 5277fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 5287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 529f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float2 __attribute__((overloadable)) 5307fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix2x2 *m, float2 in) { 5317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams float2 ret; 5327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.x = (m->m[0] * in.x) + (m->m[2] * in.y); 5337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ret.y = (m->m[1] * in.x) + (m->m[3] * in.y); 5347fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return ret; 5357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 5367fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 53720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk// Returns true if the matrix was successfully inversed 538f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC bool __attribute__((overloadable)) 53920c6c1febce7cdf398c58287bf506b3a4a210285Alex SakhartchoukrsMatrixInverse(rs_matrix4x4 *m) { 54020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk rs_matrix4x4 result; 54120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 54220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int i, j; 54320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 4; ++i) { 54420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (j = 0; j < 4; ++j) { 54520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk // computeCofactor for int i, int j 54620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c0 = (i+1) % 4; 54720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c1 = (i+2) % 4; 54820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c2 = (i+3) % 4; 54920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r0 = (j+1) % 4; 55020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r1 = (j+2) % 4; 55120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r2 = (j+3) % 4; 55220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 55320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 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])) 55420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk - (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])) 55520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk + (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])); 55620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 55720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float cofactor = (i+j) & 1 ? -minor : minor; 55820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 55920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk result.m[4*i + j] = cofactor; 56020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 56120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 56220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 56320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk // Dot product of 0th column of source and 0th row of result 56420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float det = m->m[0]*result.m[0] + m->m[4]*result.m[1] + 56520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[8]*result.m[2] + m->m[12]*result.m[3]; 56620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 56720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk if (fabs(det) < 1e-6) { 56820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk return false; 56920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 57020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 57120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk det = 1.0f / det; 57220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 16; ++i) { 57320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[i] = result.m[i] * det; 57420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 57520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 57620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk return true; 57720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk} 57820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 57920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk// Returns true if the matrix was successfully inversed 580f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC bool __attribute__((overloadable)) 58120c6c1febce7cdf398c58287bf506b3a4a210285Alex SakhartchoukrsMatrixInverseTranspose(rs_matrix4x4 *m) { 58220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk rs_matrix4x4 result; 58320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 58420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int i, j; 58520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 4; ++i) { 58620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (j = 0; j < 4; ++j) { 58720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk // computeCofactor for int i, int j 58820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c0 = (i+1) % 4; 58920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c1 = (i+2) % 4; 59020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int c2 = (i+3) % 4; 59120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r0 = (j+1) % 4; 59220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r1 = (j+2) % 4; 59320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int r2 = (j+3) % 4; 59420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 59520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 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])) 59620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk - (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])) 59720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk + (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])); 59820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 59920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float cofactor = (i+j) & 1 ? -minor : minor; 60020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 60120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk result.m[4*j + i] = cofactor; 60220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 60320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 60420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 60520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk // Dot product of 0th column of source and 0th column of result 60620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float det = m->m[0]*result.m[0] + m->m[4]*result.m[4] + 60720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[8]*result.m[8] + m->m[12]*result.m[12]; 60820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 60920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk if (fabs(det) < 1e-6) { 61020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk return false; 61120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 61220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 61320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk det = 1.0f / det; 61420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 16; ++i) { 61520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[i] = result.m[i] * det; 61620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 61720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 61820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk return true; 61920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk} 62020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 621f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 62220c6c1febce7cdf398c58287bf506b3a4a210285Alex SakhartchoukrsMatrixTranspose(rs_matrix4x4 *m) { 62320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int i, j; 62420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float temp; 62520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 3; ++i) { 62620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (j = i + 1; j < 4; ++j) { 62720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk temp = m->m[i*4 + j]; 62820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[i*4 + j] = m->m[j*4 + i]; 62920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[j*4 + i] = temp; 63020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 63120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 63220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk} 63320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 634f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 63520c6c1febce7cdf398c58287bf506b3a4a210285Alex SakhartchoukrsMatrixTranspose(rs_matrix3x3 *m) { 63620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk int i, j; 63720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float temp; 63820c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (i = 0; i < 2; ++i) { 63920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk for (j = i + 1; j < 3; ++j) { 64020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk temp = m->m[i*3 + j]; 64120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[i*3 + j] = m->m[j*4 + i]; 64220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[j*3 + i] = temp; 64320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 64420c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk } 64520c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk} 64620c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 647f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 64820c6c1febce7cdf398c58287bf506b3a4a210285Alex SakhartchoukrsMatrixTranspose(rs_matrix2x2 *m) { 64920c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk float temp = m->m[1]; 65020c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[1] = m->m[2]; 65120c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk m->m[2] = temp; 65220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk} 65320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 65429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk///////////////////////////////////////////////////// 65529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk// quaternion ops 65629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk///////////////////////////////////////////////////// 65729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 658f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 65929858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) { 66029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w = w; 66129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x = x; 66229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y = y; 66329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z = z; 66429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 66529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 666f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 66729858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) { 66829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w = rhs->w; 66929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x = rhs->x; 67029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y = rhs->y; 67129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z = rhs->z; 67229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 67329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 674f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 67529858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionMultiply(rs_quaternion *q, float s) { 67629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w *= s; 67729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x *= s; 67829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y *= s; 67929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z *= s; 68029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 68129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 682f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable)) 68329858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) { 68429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w; 68529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x; 68629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->z + q->w*rhs->y; 68729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z; 68829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 68929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 690f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 69129858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) { 69229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w *= rhs->w; 69329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x *= rhs->x; 69429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y *= rhs->y; 69529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z *= rhs->z; 69629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 69729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 698f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 69929858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) { 70029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rot *= (float)(M_PI / 180.0f) * 0.5f; 70129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float c = cos(rot); 70229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float s = sin(rot); 70329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 70429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->w = c; 70529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x = x * s; 70629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y = y * s; 70729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z = z * s; 70829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 70929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 710f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 71129858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) { 71229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk const float len = x*x + y*y + z*z; 71329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk if (len != 1) { 71429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk const float recipLen = 1.f / sqrt(len); 71529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk x *= recipLen; 71629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk y *= recipLen; 71729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk z *= recipLen; 71829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 71929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionLoadRotateUnit(q, rot, x, y, z); 72029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 72129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 722f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 72329858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionConjugate(rs_quaternion *q) { 72429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->x = -q->x; 72529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->y = -q->y; 72629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk q->z = -q->z; 72729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 72829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 729f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float 73029858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) { 73129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z; 73229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 73329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 734f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 73529858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionNormalize(rs_quaternion *q) { 73629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk const float len = rsQuaternionDot(q, q); 73729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk if (len != 1) { 73829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk const float recipLen = 1.f / sqrt(len); 73929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionMultiply(q, recipLen); 74029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 74129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 74229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 743f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void 74429858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) { 745afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (t <= 0.0f) { 74629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(q, q0); 74729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk return; 74829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 749afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (t >= 1.0f) { 75029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(q, q1); 75129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk return; 75229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 75329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 75429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rs_quaternion tempq0, tempq1; 75529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(&tempq0, q0); 75629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(&tempq1, q1); 75729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 75829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float angle = rsQuaternionDot(q0, q1); 759afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (angle < 0) { 76029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionMultiply(&tempq0, -1.0f); 76129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk angle *= -1.0f; 76229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 76329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 76429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float scale, invScale; 76529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk if (angle + 1.0f > 0.05f) { 76629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk if (1.0f - angle >= 0.05f) { 76729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float theta = acos(angle); 76829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float invSinTheta = 1.0f / sin(theta); 76929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk scale = sin(theta * (1.0f - t)) * invSinTheta; 77029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk invScale = sin(theta * t) * invSinTheta; 771afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } else { 77229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk scale = 1.0f - t; 77329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk invScale = t; 77429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 775afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } else { 77629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w); 77729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk scale = sin(M_PI * (0.5f - t)); 77829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk invScale = sin(M_PI * t); 77929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk } 78029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 78129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale, 78229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale); 78329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 78429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 785f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) { 78629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float x2 = 2.0f * q->x * q->x; 78729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float y2 = 2.0f * q->y * q->y; 78829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float z2 = 2.0f * q->z * q->z; 78929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float xy = 2.0f * q->x * q->y; 79029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float wz = 2.0f * q->w * q->z; 79129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float xz = 2.0f * q->x * q->z; 79229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float wy = 2.0f * q->w * q->y; 79329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float wx = 2.0f * q->w * q->x; 79429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk float yz = 2.0f * q->y * q->z; 79529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 79629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[0] = 1.0f - y2 - z2; 79729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[1] = xy - wz; 79829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[2] = xz + wy; 79929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[3] = 0.0f; 80029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 80129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[4] = xy + wz; 80229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[5] = 1.0f - x2 - z2; 80329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[6] = yz - wx; 80429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[7] = 0.0f; 80529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 80629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[8] = xz - wy; 80729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[9] = yz - wx; 80829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[10] = 1.0f - x2 - y2; 80929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[11] = 0.0f; 81029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 81129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[12] = 0.0f; 81229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[13] = 0.0f; 81329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[14] = 0.0f; 81429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk m->m[15] = 1.0f; 81529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk} 81629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk 81795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk///////////////////////////////////////////////////// 81895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk// utility funcs 81995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk///////////////////////////////////////////////////// 820f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC void __attribute__((overloadable, always_inline)) 82195333f998fd4a983f89e5128e85f6f710d200bd9Alex SakhartchoukrsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj, 82295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *left, float4 *right, 82395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *top, float4 *bottom, 82495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *near, float4 *far) { 82595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk // x y z w = a b c d in the plane equation 82695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk left->x = modelViewProj->m[3] + modelViewProj->m[0]; 82795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk left->y = modelViewProj->m[7] + modelViewProj->m[4]; 82895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk left->z = modelViewProj->m[11] + modelViewProj->m[8]; 82995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk left->w = modelViewProj->m[15] + modelViewProj->m[12]; 83095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 83195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk right->x = modelViewProj->m[3] - modelViewProj->m[0]; 83295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk right->y = modelViewProj->m[7] - modelViewProj->m[4]; 83395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk right->z = modelViewProj->m[11] - modelViewProj->m[8]; 83495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk right->w = modelViewProj->m[15] - modelViewProj->m[12]; 83595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 83695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk top->x = modelViewProj->m[3] - modelViewProj->m[1]; 83795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk top->y = modelViewProj->m[7] - modelViewProj->m[5]; 83895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk top->z = modelViewProj->m[11] - modelViewProj->m[9]; 83995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk top->w = modelViewProj->m[15] - modelViewProj->m[13]; 84095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 84195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk bottom->x = modelViewProj->m[3] + modelViewProj->m[1]; 84295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk bottom->y = modelViewProj->m[7] + modelViewProj->m[5]; 84395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk bottom->z = modelViewProj->m[11] + modelViewProj->m[9]; 84495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk bottom->w = modelViewProj->m[15] + modelViewProj->m[13]; 84595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 84695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk near->x = modelViewProj->m[3] + modelViewProj->m[2]; 84795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk near->y = modelViewProj->m[7] + modelViewProj->m[6]; 84895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk near->z = modelViewProj->m[11] + modelViewProj->m[10]; 84995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk near->w = modelViewProj->m[15] + modelViewProj->m[14]; 85095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 85195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk far->x = modelViewProj->m[3] - modelViewProj->m[2]; 85295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk far->y = modelViewProj->m[7] - modelViewProj->m[6]; 85395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk far->z = modelViewProj->m[11] - modelViewProj->m[10]; 85495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk far->w = modelViewProj->m[15] - modelViewProj->m[14]; 85595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 85695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float len = length(left->xyz); 85795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *left /= len; 85895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk len = length(right->xyz); 85995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *right /= len; 86095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk len = length(top->xyz); 86195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *top /= len; 86295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk len = length(bottom->xyz); 86395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *bottom /= len; 86495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk len = length(near->xyz); 86595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *near /= len; 86695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk len = length(far->xyz); 86795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk *far /= len; 86895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk} 86995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 870f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC bool __attribute__((overloadable, always_inline)) 87195333f998fd4a983f89e5128e85f6f710d200bd9Alex SakhartchoukrsIsSphereInFrustum(float4 *sphere, 87295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *left, float4 *right, 87395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *top, float4 *bottom, 87495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float4 *near, float4 *far) { 87595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 87695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk float distToCenter = dot(left->xyz, sphere->xyz) + left->w; 877afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 87895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 87995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 88095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk distToCenter = dot(right->xyz, sphere->xyz) + right->w; 881afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 88295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 88395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 88495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk distToCenter = dot(top->xyz, sphere->xyz) + top->w; 885afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 88695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 88795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 88895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w; 889afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 89095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 89195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 89295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk distToCenter = dot(near->xyz, sphere->xyz) + near->w; 893afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 89495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 89595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 89695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk distToCenter = dot(far->xyz, sphere->xyz) + far->w; 897afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (distToCenter < -sphere->w) { 89895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return false; 89995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk } 90095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk return true; 90195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk} 90295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk 90320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk 9047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams///////////////////////////////////////////////////// 9057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams// int ops 9067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams///////////////////////////////////////////////////// 9077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 908f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) { 9097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 911f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) { 9127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 914f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) { 9157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 917f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) { 9187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 920f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) { 9217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 923f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) { 9247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return amount < low ? low : (amount > high ? high : amount); 9257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 9267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 927f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#undef _RS_STATIC 928275b1e98bb949643d35546f10f8b1af009349526Jason Sams 929275b1e98bb949643d35546f10f8b1af009349526Jason Sams#endif 930275b1e98bb949643d35546f10f8b1af009349526Jason Sams 931