v 0. Pasted by Zeux as cpp at 2009-02-08 14:43:35 MSK and set expiration to never.

Paste will expire never. Expiration is locked.

  1. #include <stdbool.h>
  2. #include <spu_intrinsics.h>
  3.  
  4. // shuffle helpers
  5. #define L0 0x00010203
  6. #define L1 0x04050607
  7. #define L2 0x08090a0b
  8. #define L3 0x0c0d0e0f
  9.  
  10. #define R0 0x10111213
  11. #define R1 0x14151617
  12. #define R2 0x18191a1b
  13. #define R3 0x1c1d1e1f
  14.  
  15. #define SHUFFLE(l, r, x, y, z, w) si_shufb(l, r, ((qword)(vec_uint4){x, y, z, w}))
  16.  
  17. // splat helper
  18. #define SPLAT(v, idx) si_shufb(v, v, (qword)(vec_uint4)(L ## idx))
  19.  
  20. struct matrix43_t
  21. {
  22.     vec_float4 row0;
  23.     vec_float4 row1;
  24.     vec_float4 row2;
  25.     vec_float4 row3;
  26. };
  27.  
  28. struct aabb_t
  29. {
  30.     vec_float4 min;
  31.     vec_float4 max;
  32. };
  33.  
  34. struct frustum_t
  35. {
  36.     vec_float4 planes[6];
  37. };
  38.  
  39. static inline void transform_points_4(qword* dest, qword x, qword y, qword z, const struct matrix43_t* mat)
  40. {
  41. #define COMP(c) \
  42.     qword res_ ## c = SPLAT((qword)mat->row3, c); \
  43.     res_ ## c = si_fma(z, SPLAT((qword)mat->row2, c), res_ ## c); \
  44.     res_ ## c = si_fma(y, SPLAT((qword)mat->row1, c), res_ ## c); \
  45.     res_ ## c = si_fma(x, SPLAT((qword)mat->row0, c), res_ ## c); \
  46.     dest[c] = res_ ## c;
  47.  
  48.     COMP(0);
  49.     COMP(1);
  50.     COMP(2);
  51.    
  52. #undef COMP
  53. }
  54.  
  55. static inline qword dot4(qword v, qword x, qword y, qword z)
  56. {
  57.     qword result = SPLAT(v, 3);
  58.  
  59.     result = si_fma(SPLAT(v, 2), z, result);
  60.     result = si_fma(SPLAT(v, 1), y, result);
  61.     result = si_fma(SPLAT(v, 0), x, result);
  62.  
  63.     return result;
  64. }
  65.  
  66. __attribute__((noinline)) bool is_visible(const struct matrix43_t* transform, const struct aabb_t* aabb, const struct frustum_t* frustum)
  67. {
  68.     qword min = (qword)aabb->min;
  69.     qword max = (qword)aabb->max;
  70.  
  71.     // get aabb points (SoA)
  72.     qword minmax_x = SHUFFLE(min, max, L0, R0, L0, R0); // x X x X
  73.     qword minmax_y = SHUFFLE(min, max, L1, L1, R1, R1); // y y Y Y
  74.     qword minmax_z_0 = SPLAT(min, 2); // z z z z
  75.     qword minmax_z_1 = SPLAT(max, 2); // Z Z Z Z
  76.  
  77.     // transform points to world space
  78.     qword points_ws_0[3];
  79.     qword points_ws_1[3];
  80.  
  81.     transform_points_4(points_ws_0, minmax_x, minmax_y, minmax_z_0, transform);
  82.     transform_points_4(points_ws_1, minmax_x, minmax_y, minmax_z_1, transform);
  83.  
  84.     // for each plane...
  85.     for (int i = 0; i < 6; ++i)
  86.     {
  87.         qword plane = (qword)frustum->planes[i];
  88.  
  89.         // calculate 8 dot products
  90.         qword dp0 = dot4(plane, points_ws_0[0], points_ws_0[1], points_ws_0[2]);
  91.         qword dp1 = dot4(plane, points_ws_1[0], points_ws_1[1], points_ws_1[2]);
  92.  
  93.         // get signs
  94.         qword dp0neg = si_fcgt((qword)(0), dp0);
  95.         qword dp1neg = si_fcgt((qword)(0), dp1);
  96.  
  97.         if (si_to_uint(si_gb(si_and(dp0neg, dp1neg))) == 15)
  98.         {
  99.             return false;
  100.         }
  101.     }
  102.  
  103.     return true;
  104. }
  105.  
  106. // simple ortho frustum
  107. struct frustum_t frustum =
  108. {
  109.     {
  110.         { 1, 0, 0, 10 },
  111.         { -1, 0, 0, 10 },
  112.         { 0, 1, 0, 10 },
  113.         { 0, -1, 0, 10 },
  114.         { 0, 0, 1, 10 },
  115.         { 0, 0, -1, 10 }
  116.     }
  117. };
  118.  
  119. // small box
  120. struct aabb_t aabb =
  121. {
  122.     { -1, -2, -3 },
  123.     { 1, 2, 3 }
  124. };
  125.  
  126. // and some weird matrix
  127. struct matrix43_t transform =
  128. {
  129.     { 0.123f, 0.456f, 0.789f },
  130.     { 0.456f, 0.123f, 0.789f },
  131.     { 0.789f, 0.123f, 0.456f },
  132.     { 1.f, -1.f, 1.f }
  133. };
  134.  
  135. void _start()
  136. {
  137.     is_visible(&transform, &aabb, &frustum);
  138.     si_stop(0);
  139. }


Editing is locked.