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