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

Paste will expire never. Expiration is locked.

  1. #include <stdbool.h>
  2. #include <spu_intrinsics.h>
  3.  
  4. struct matrix43_t
  5. {
  6.     vec_float4 row0;
  7.     vec_float4 row1;
  8.     vec_float4 row2;
  9.     vec_float4 row3;
  10. };
  11.  
  12. struct aabb_t
  13. {
  14.     vec_float4 min;
  15.     vec_float4 max;
  16. };
  17.  
  18. struct frustum_t
  19. {
  20.     vec_float4 planes[6];
  21. };
  22.  
  23. static inline qword transform_point(qword p, const struct matrix43_t* mat)
  24. {
  25.     qword px = si_shufb(p, p, (qword)(vec_uint4)(0x00010203));
  26.     qword py = si_shufb(p, p, (qword)(vec_uint4)(0x04050607));
  27.     qword pz = si_shufb(p, p, (qword)(vec_uint4)(0x08090a0b));
  28.  
  29.     qword result = (qword)mat->row3;
  30.  
  31.     result = si_fma(pz, (qword)mat->row2, result);
  32.     result = si_fma(py, (qword)mat->row1, result);
  33.     result = si_fma(px, (qword)mat->row0, result);
  34.  
  35.     result = si_selb(result, ((qword)(vec_float4){0, 0, 0, 1}), ((qword)(vec_uint4){0, 0, 0, ~0}));
  36.  
  37.     return result;
  38. }
  39.  
  40. static inline float dot(qword lhs, qword rhs)
  41. {
  42.     qword mul = si_fm(lhs, rhs);
  43.  
  44.     // two pairs of sums
  45.     qword mul_zwxy = si_rotqbyi(mul, 8);
  46.     qword sum_2 = si_fa(mul, mul_zwxy);
  47.  
  48.     // single sum
  49.     qword sum_2y = si_rotqbyi(sum_2, 4);
  50.     qword sum_1 = si_fa(sum_2, sum_2y);
  51.  
  52.     // return result
  53.     return si_to_float(sum_1);
  54. }
  55.  
  56. __attribute__((noinline)) bool is_visible(struct matrix43_t* transform, struct aabb_t* aabb, struct frustum_t* frustum)
  57. {
  58.     qword min = (qword)aabb->min;
  59.     qword max = (qword)aabb->max;
  60.  
  61.     // get aabb points
  62.     qword points[] =
  63.     {
  64.         min,                                                   // x y z
  65.         si_selb(min, max, ((qword)(vec_uint4){~0, 0, 0, 0}))// X y z
  66.         si_selb(min, max, ((qword)(vec_uint4){~0, ~0, 0, 0})), // X Y z
  67.         si_selb(min, max, ((qword)(vec_uint4){0, ~0, 0, 0}))// x Y z
  68.  
  69.         si_selb(min, max, ((qword)(vec_uint4){0, 0, ~0, 0}))// x y Z
  70.         si_selb(min, max, ((qword)(vec_uint4){~0, 0, ~0, 0})), // X y Z
  71.         max,                                                   // X Y Z
  72.         si_selb(min, max, ((qword)(vec_uint4){0, ~0, ~0, 0})), // x Y Z
  73.     };
  74.  
  75.     // transform points to world space
  76.     for (int i = 0; i < 8; ++i)
  77.     {
  78.         points[i] = transform_point(points[i], transform);
  79.    
  80.     }
  81.  
  82.     // for each plane...
  83.     for (int i = 0; i < 6; ++i)
  84.     {
  85.         bool inside = false;
  86.  
  87.         qword plane = (qword)frustum->planes[i];
  88.  
  89.         for (int j = 0; j < 8; ++j)
  90.         {
  91.             if (dot(points[j], plane) > 0)
  92.             {
  93.                 inside = true;
  94.                 break;
  95.             }
  96.         }
  97.  
  98.         if (!inside)
  99.         {
  100.             return false;
  101.         }
  102.     }
  103.  
  104.     return true;
  105. }
  106.  
  107. // simple ortho frustum
  108. struct frustum_t frustum =
  109. {
  110.     {
  111.         { 1, 0, 0, 10 },
  112.         { -1, 0, 0, 10 },
  113.         { 0, 1, 0, 10 },
  114.         { 0, -1, 0, 10 },
  115.         { 0, 0, 1, 10 },
  116.         { 0, 0, -1, 10 }
  117.     }
  118. };
  119.  
  120. // small box
  121. struct aabb_t aabb =
  122. {
  123.     { -1, -2, -3 },
  124.     { 1, 2, 3 }
  125. };
  126.  
  127. // and some weird matrix
  128. struct matrix43_t transform =
  129. {
  130.     { 0.123f, 0.456f, 0.789f },
  131.     { 0.456f, 0.123f, 0.789f },
  132.     { 0.789f, 0.123f, 0.456f },
  133.     { 1.f, -1.f, 1.f }
  134. };
  135.  
  136. void _start()
  137. {
  138.     is_visible(&transform, &aabb, &frustum);
  139.     si_stop(0);
  140. }


Editing is locked.