Advertisement
Guest User

Untitled

a guest
Feb 12th, 2016
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement