splitter.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "../common/scene.h"
  5. #include "../common/primref.h"
  6. namespace embree
  7. {
  8. namespace isa
  9. {
  10. template<size_t N>
  11. __forceinline void splitPolygon(const BBox3fa& bounds,
  12. const size_t dim,
  13. const float pos,
  14. const Vec3fa (&v)[N+1],
  15. const Vec3fa (&inv_length)[N],
  16. BBox3fa& left_o,
  17. BBox3fa& right_o)
  18. {
  19. BBox3fa left = empty, right = empty;
  20. /* clip triangle to left and right box by processing all edges */
  21. for (size_t i=0; i<N; i++)
  22. {
  23. const Vec3fa &v0 = v[i];
  24. const Vec3fa &v1 = v[i+1];
  25. const float v0d = v0[dim];
  26. const float v1d = v1[dim];
  27. if (v0d <= pos) left. extend(v0); // this point is on left side
  28. if (v0d >= pos) right.extend(v0); // this point is on right side
  29. if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
  30. {
  31. assert((v1d-v0d) != 0.0f);
  32. const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length[i][dim]),v1-v0,v0);
  33. left.extend(c);
  34. right.extend(c);
  35. }
  36. }
  37. /* clip against current bounds */
  38. left_o = intersect(left,bounds);
  39. right_o = intersect(right,bounds);
  40. }
  41. template<size_t N>
  42. __forceinline void splitPolygon(const PrimRef& prim,
  43. const size_t dim,
  44. const float pos,
  45. const Vec3fa (&v)[N+1],
  46. PrimRef& left_o,
  47. PrimRef& right_o)
  48. {
  49. BBox3fa left = empty, right = empty;
  50. for (size_t i=0; i<N; i++)
  51. {
  52. const Vec3fa &v0 = v[i];
  53. const Vec3fa &v1 = v[i+1];
  54. const float v0d = v0[dim];
  55. const float v1d = v1[dim];
  56. if (v0d <= pos) left. extend(v0); // this point is on left side
  57. if (v0d >= pos) right.extend(v0); // this point is on right side
  58. if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
  59. {
  60. assert((v1d-v0d) != 0.0f);
  61. const float inv_length = 1.0f/(v1d-v0d);
  62. const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0);
  63. left.extend(c);
  64. right.extend(c);
  65. }
  66. }
  67. /* clip against current bounds */
  68. new (&left_o ) PrimRef(intersect(left ,prim.bounds()),prim.geomID(), prim.primID());
  69. new (&right_o) PrimRef(intersect(right,prim.bounds()),prim.geomID(), prim.primID());
  70. }
  71. struct TriangleSplitter
  72. {
  73. __forceinline TriangleSplitter(const Scene* scene, const PrimRef& prim)
  74. {
  75. const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
  76. const TriangleMesh* mesh = (const TriangleMesh*) scene->get(prim.geomID() & mask );
  77. TriangleMesh::Triangle tri = mesh->triangle(prim.primID());
  78. v[0] = mesh->vertex(tri.v[0]);
  79. v[1] = mesh->vertex(tri.v[1]);
  80. v[2] = mesh->vertex(tri.v[2]);
  81. v[3] = mesh->vertex(tri.v[0]);
  82. inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
  83. inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
  84. inv_length[2] = Vec3fa(1.0f) / (v[0]-v[2]);
  85. }
  86. __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
  87. splitPolygon<3>(prim,dim,pos,v,left_o,right_o);
  88. }
  89. __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
  90. splitPolygon<3>(prim,dim,pos,v,inv_length,left_o,right_o);
  91. }
  92. private:
  93. Vec3fa v[4];
  94. Vec3fa inv_length[3];
  95. };
  96. struct TriangleSplitterFactory
  97. {
  98. __forceinline TriangleSplitterFactory(const Scene* scene)
  99. : scene(scene) {}
  100. __forceinline TriangleSplitter operator() (const PrimRef& prim) const {
  101. return TriangleSplitter(scene,prim);
  102. }
  103. private:
  104. const Scene* scene;
  105. };
  106. struct QuadSplitter
  107. {
  108. __forceinline QuadSplitter(const Scene* scene, const PrimRef& prim)
  109. {
  110. const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
  111. const QuadMesh* mesh = (const QuadMesh*) scene->get(prim.geomID() & mask );
  112. QuadMesh::Quad quad = mesh->quad(prim.primID());
  113. v[0] = mesh->vertex(quad.v[1]);
  114. v[1] = mesh->vertex(quad.v[2]);
  115. v[2] = mesh->vertex(quad.v[3]);
  116. v[3] = mesh->vertex(quad.v[0]);
  117. v[4] = mesh->vertex(quad.v[1]);
  118. v[5] = mesh->vertex(quad.v[3]);
  119. inv_length[0] = Vec3fa(1.0f) / (v[1] - v[0]);
  120. inv_length[1] = Vec3fa(1.0f) / (v[2] - v[1]);
  121. inv_length[2] = Vec3fa(1.0f) / (v[3] - v[2]);
  122. inv_length[3] = Vec3fa(1.0f) / (v[4] - v[3]);
  123. inv_length[4] = Vec3fa(1.0f) / (v[5] - v[4]);
  124. }
  125. __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
  126. splitPolygon<5>(prim,dim,pos,v,left_o,right_o);
  127. }
  128. __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
  129. splitPolygon<5>(prim,dim,pos,v,inv_length,left_o,right_o);
  130. }
  131. private:
  132. Vec3fa v[6];
  133. Vec3fa inv_length[5];
  134. };
  135. struct QuadSplitterFactory
  136. {
  137. __forceinline QuadSplitterFactory(const Scene* scene)
  138. : scene(scene) {}
  139. __forceinline QuadSplitter operator() (const PrimRef& prim) const {
  140. return QuadSplitter(scene,prim);
  141. }
  142. private:
  143. const Scene* scene;
  144. };
  145. struct DummySplitter
  146. {
  147. __forceinline DummySplitter(const Scene* scene, const PrimRef& prim)
  148. {
  149. }
  150. };
  151. struct DummySplitterFactory
  152. {
  153. __forceinline DummySplitterFactory(const Scene* scene)
  154. : scene(scene) {}
  155. __forceinline DummySplitter operator() (const PrimRef& prim) const {
  156. return DummySplitter(scene,prim);
  157. }
  158. private:
  159. const Scene* scene;
  160. };
  161. }
  162. }