rs_core.rsh revision 693080efdafbf49d675fe5f959f0286f83b30c81
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
134693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m);
135693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m);
136693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m);
137693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v);
138693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v);
139693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v);
140693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v);
141693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v);
142693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v);
143693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v);
144693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v);
1457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
146693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
147693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
1487fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
149693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
150693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
1517fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
152693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
153693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
1547fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
155693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
156693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
1577fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
158693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
159693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
1607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
161693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
162693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
1637fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
164693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
165693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
1667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
167693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
168693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
1697fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
170693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
171693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
1727fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
173693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
174693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
1757fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
176693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
177693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
1787fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
179693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
180693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
1817fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
182693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
183693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
1847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
185693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
186693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
1877fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
188693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable))
189693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsrsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
190c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk
191f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable))
1927fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
1937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float4 ret;
1947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w);
1957fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + (m->m[13] * in.w);
1967fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + (m->m[14] * in.w);
1977fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + (m->m[15] * in.w);
1987fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
1997fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2007fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
201f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable))
2027fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
2037fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float4 ret;
2047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12];
2057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + m->m[13];
2067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + m->m[14];
2077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + m->m[15];
2087fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
2097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
211f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float4 __attribute__((overloadable))
2127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
2137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float4 ret;
2147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12];
2157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + m->m[13];
2167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + m->m[14];
2177fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + m->m[15];
2187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
2197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2207fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
221f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float3 __attribute__((overloadable))
2227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
2237fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float3 ret;
2247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z);
2257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[4] * in.y) + (m->m[7] * in.z);
2267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.z = (m->m[2] * in.x) + (m->m[5] * in.y) + (m->m[8] * in.z);
2277fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
2287fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2297fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
230f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float3 __attribute__((overloadable))
2317fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
2327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float3 ret;
2337fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[3] * in.y);
2347fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[4] * in.y);
2357fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.z = (m->m[2] * in.x) + (m->m[5] * in.y);
2367fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
2377fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
239f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float2 __attribute__((overloadable))
2407fe6bce13c30b8d14dc833e06468666d28e56ee1Jason SamsrsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
2417fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    float2 ret;
2427fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
2437fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    ret.y = (m->m[1] * in.x) + (m->m[3] * in.y);
2447fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return ret;
2457fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
2467fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
24720c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk// Returns true if the matrix was successfully inversed
248693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m);
249693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m);
250693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m);
251693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m);
252693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsextern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
25320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk
25429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk/////////////////////////////////////////////////////
25529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk// quaternion ops
25629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk/////////////////////////////////////////////////////
25729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
258f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable))
25929858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
26029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w = w;
26129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x = x;
26229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y = y;
26329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z = z;
26429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
26529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
266f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable))
26729858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
26829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w = rhs->w;
26929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x = rhs->x;
27029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y = rhs->y;
27129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z = rhs->z;
27229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
27329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
274f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable))
27529858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionMultiply(rs_quaternion *q, float s) {
27629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w *= s;
27729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x *= s;
27829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y *= s;
27929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z *= s;
28029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
28129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
282f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void __attribute__((overloadable))
28329858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
28429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
28529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
286711e7316c7bc274dd0ee9e4f3f043a85c1a706a8Stephen Hines    q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
28729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
28829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
28929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
290f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
29129858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
29229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w *= rhs->w;
29329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x *= rhs->x;
29429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y *= rhs->y;
29529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z *= rhs->z;
29629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
29729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
298f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
29929858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
30029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rot *= (float)(M_PI / 180.0f) * 0.5f;
30129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float c = cos(rot);
30229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float s = sin(rot);
30329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
30429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->w = c;
30529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x = x * s;
30629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y = y * s;
30729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z = z * s;
30829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
30929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
310f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
31129858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
31229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    const float len = x*x + y*y + z*z;
31329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    if (len != 1) {
31429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        const float recipLen = 1.f / sqrt(len);
31529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        x *= recipLen;
31629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        y *= recipLen;
31729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        z *= recipLen;
31829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
31929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rsQuaternionLoadRotateUnit(q, rot, x, y, z);
32029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
32129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
322f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
32329858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionConjugate(rs_quaternion *q) {
32429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->x = -q->x;
32529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->y = -q->y;
32629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    q->z = -q->z;
32729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
32829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
329f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC float
33029858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
33129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
33229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
33329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
334f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
33529858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionNormalize(rs_quaternion *q) {
33629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    const float len = rsQuaternionDot(q, q);
33729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    if (len != 1) {
33829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        const float recipLen = 1.f / sqrt(len);
33929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        rsQuaternionMultiply(q, recipLen);
34029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
34129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
34229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
343f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void
34429858059ffff967607f7583ae9146dc4c720f92eAlex SakhartchoukrsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
345afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (t <= 0.0f) {
34629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        rsQuaternionSet(q, q0);
34729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        return;
34829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
349afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (t >= 1.0f) {
35029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        rsQuaternionSet(q, q1);
35129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        return;
35229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
35329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
35429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rs_quaternion tempq0, tempq1;
35529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rsQuaternionSet(&tempq0, q0);
35629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rsQuaternionSet(&tempq1, q1);
35729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
35829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float angle = rsQuaternionDot(q0, q1);
359afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (angle < 0) {
36029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        rsQuaternionMultiply(&tempq0, -1.0f);
36129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        angle *= -1.0f;
36229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
36329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
36429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float scale, invScale;
36529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    if (angle + 1.0f > 0.05f) {
36629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        if (1.0f - angle >= 0.05f) {
36729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            float theta = acos(angle);
36829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            float invSinTheta = 1.0f / sin(theta);
36929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            scale = sin(theta * (1.0f - t)) * invSinTheta;
37029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            invScale = sin(theta * t) * invSinTheta;
371afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        } else {
37229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            scale = 1.0f - t;
37329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk            invScale = t;
37429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        }
375afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    } else {
37629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
37729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        scale = sin(M_PI * (0.5f - t));
37829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk        invScale = sin(M_PI * t);
37929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    }
38029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
38129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
38229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk                        tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
38329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
38429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
385f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines_RS_STATIC void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
38629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float x2 = 2.0f * q->x * q->x;
38729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float y2 = 2.0f * q->y * q->y;
38829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float z2 = 2.0f * q->z * q->z;
38929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float xy = 2.0f * q->x * q->y;
39029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float wz = 2.0f * q->w * q->z;
39129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float xz = 2.0f * q->x * q->z;
39229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float wy = 2.0f * q->w * q->y;
39329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float wx = 2.0f * q->w * q->x;
39429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    float yz = 2.0f * q->y * q->z;
39529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
39629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[0] = 1.0f - y2 - z2;
39729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[1] = xy - wz;
39829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[2] = xz + wy;
39929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[3] = 0.0f;
40029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
40129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[4] = xy + wz;
40229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[5] = 1.0f - x2 - z2;
40329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[6] = yz - wx;
40429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[7] = 0.0f;
40529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
40629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[8] = xz - wy;
40729858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[9] = yz - wx;
40829858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[10] = 1.0f - x2 - y2;
40929858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[11] = 0.0f;
41029858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
41129858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[12] = 0.0f;
41229858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[13] = 0.0f;
41329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[14] = 0.0f;
41429858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk    m->m[15] = 1.0f;
41529858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk}
41629858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk
41795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk/////////////////////////////////////////////////////
41895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk// utility funcs
41995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk/////////////////////////////////////////////////////
420f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC void __attribute__((overloadable, always_inline))
42195333f998fd4a983f89e5128e85f6f710d200bd9Alex SakhartchoukrsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
42295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                         float4 *left, float4 *right,
42395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                         float4 *top, float4 *bottom,
42495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                         float4 *near, float4 *far) {
42595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    // x y z w = a b c d in the plane equation
42695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    left->x = modelViewProj->m[3] + modelViewProj->m[0];
42795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    left->y = modelViewProj->m[7] + modelViewProj->m[4];
42895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    left->z = modelViewProj->m[11] + modelViewProj->m[8];
42995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    left->w = modelViewProj->m[15] + modelViewProj->m[12];
43095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
43195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    right->x = modelViewProj->m[3] - modelViewProj->m[0];
43295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    right->y = modelViewProj->m[7] - modelViewProj->m[4];
43395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    right->z = modelViewProj->m[11] - modelViewProj->m[8];
43495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    right->w = modelViewProj->m[15] - modelViewProj->m[12];
43595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
43695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    top->x = modelViewProj->m[3] - modelViewProj->m[1];
43795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    top->y = modelViewProj->m[7] - modelViewProj->m[5];
43895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    top->z = modelViewProj->m[11] - modelViewProj->m[9];
43995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    top->w = modelViewProj->m[15] - modelViewProj->m[13];
44095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
44195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    bottom->x = modelViewProj->m[3] + modelViewProj->m[1];
44295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    bottom->y = modelViewProj->m[7] + modelViewProj->m[5];
44395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    bottom->z = modelViewProj->m[11] + modelViewProj->m[9];
44495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    bottom->w = modelViewProj->m[15] + modelViewProj->m[13];
44595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
44695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    near->x = modelViewProj->m[3] + modelViewProj->m[2];
44795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    near->y = modelViewProj->m[7] + modelViewProj->m[6];
44895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    near->z = modelViewProj->m[11] + modelViewProj->m[10];
44995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    near->w = modelViewProj->m[15] + modelViewProj->m[14];
45095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
45195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    far->x = modelViewProj->m[3] - modelViewProj->m[2];
45295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    far->y = modelViewProj->m[7] - modelViewProj->m[6];
45395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    far->z = modelViewProj->m[11] - modelViewProj->m[10];
45495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    far->w = modelViewProj->m[15] - modelViewProj->m[14];
45595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
45695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    float len = length(left->xyz);
45795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *left /= len;
45895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    len = length(right->xyz);
45995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *right /= len;
46095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    len = length(top->xyz);
46195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *top /= len;
46295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    len = length(bottom->xyz);
46395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *bottom /= len;
46495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    len = length(near->xyz);
46595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *near /= len;
46695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    len = length(far->xyz);
46795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    *far /= len;
46895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk}
46995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
470f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC bool __attribute__((overloadable, always_inline))
47195333f998fd4a983f89e5128e85f6f710d200bd9Alex SakhartchoukrsIsSphereInFrustum(float4 *sphere,
47295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                      float4 *left, float4 *right,
47395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                      float4 *top, float4 *bottom,
47495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk                      float4 *near, float4 *far) {
47595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
47695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
477afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
47895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
47995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
48095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    distToCenter = dot(right->xyz, sphere->xyz) + right->w;
481afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
48295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
48395333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
48495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    distToCenter = dot(top->xyz, sphere->xyz) + top->w;
485afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
48695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
48795333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
48895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
489afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
49095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
49195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
49295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    distToCenter = dot(near->xyz, sphere->xyz) + near->w;
493afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
49495333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
49595333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
49695333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    distToCenter = dot(far->xyz, sphere->xyz) + far->w;
497afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (distToCenter < -sphere->w) {
49895333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk        return false;
49995333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    }
50095333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk    return true;
50195333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk}
50295333f998fd4a983f89e5128e85f6f710d200bd9Alex Sakhartchouk
50320c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk
5047fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams/////////////////////////////////////////////////////
5057fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams// int ops
5067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams/////////////////////////////////////////////////////
5077fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
508f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
5097fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5107fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
511f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
5127fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
514f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
5157fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5167fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
517f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
5187fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5197fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
520f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
5217fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5227fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
523f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines__inline__ _RS_STATIC char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
5247fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams    return amount < low ? low : (amount > high ? high : amount);
5257fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams}
5267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams
527f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines#undef _RS_STATIC
528275b1e98bb949643d35546f10f8b1af009349526Jason Sams
529275b1e98bb949643d35546f10f8b1af009349526Jason Sams#endif
530275b1e98bb949643d35546f10f8b1af009349526Jason Sams
531