splitter.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "../common/scene.h"
  18. #include "../common/primref.h"
  19. namespace embree
  20. {
  21. namespace isa
  22. {
  23. template<size_t N>
  24. __forceinline void splitPolygon(const BBox3fa& bounds,
  25. const size_t dim,
  26. const float pos,
  27. const Vec3fa (&v)[N+1],
  28. const Vec3fa (&inv_length)[N],
  29. BBox3fa& left_o,
  30. BBox3fa& right_o)
  31. {
  32. BBox3fa left = empty, right = empty;
  33. /* clip triangle to left and right box by processing all edges */
  34. for (size_t i=0; i<N; i++)
  35. {
  36. const Vec3fa &v0 = v[i];
  37. const Vec3fa &v1 = v[i+1];
  38. const float v0d = v0[dim];
  39. const float v1d = v1[dim];
  40. if (v0d <= pos) left. extend(v0); // this point is on left side
  41. if (v0d >= pos) right.extend(v0); // this point is on right side
  42. if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
  43. {
  44. assert((v1d-v0d) != 0.0f);
  45. const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length[i][dim]),v1-v0,v0);
  46. left.extend(c);
  47. right.extend(c);
  48. }
  49. }
  50. /* clip against current bounds */
  51. left_o = intersect(left,bounds);
  52. right_o = intersect(right,bounds);
  53. }
  54. template<size_t N>
  55. __forceinline void splitPolygon(const PrimRef& prim,
  56. const size_t dim,
  57. const float pos,
  58. const Vec3fa (&v)[N+1],
  59. PrimRef& left_o,
  60. PrimRef& right_o)
  61. {
  62. BBox3fa left = empty, right = empty;
  63. for (size_t i=0; i<N; i++)
  64. {
  65. const Vec3fa &v0 = v[i];
  66. const Vec3fa &v1 = v[i+1];
  67. const float v0d = v0[dim];
  68. const float v1d = v1[dim];
  69. if (v0d <= pos) left. extend(v0); // this point is on left side
  70. if (v0d >= pos) right.extend(v0); // this point is on right side
  71. if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
  72. {
  73. assert((v1d-v0d) != 0.0f);
  74. const float inv_length = 1.0f/(v1d-v0d);
  75. const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0);
  76. left.extend(c);
  77. right.extend(c);
  78. }
  79. }
  80. /* clip against current bounds */
  81. new (&left_o ) PrimRef(intersect(left ,prim.bounds()),prim.geomID(), prim.primID());
  82. new (&right_o) PrimRef(intersect(right,prim.bounds()),prim.geomID(), prim.primID());
  83. }
  84. struct TriangleSplitter
  85. {
  86. __forceinline TriangleSplitter(const Scene* scene, const PrimRef& prim)
  87. {
  88. const TriangleMesh* mesh = (const TriangleMesh*) scene->get(prim.geomID() & 0x00FFFFFF );
  89. TriangleMesh::Triangle tri = mesh->triangle(prim.primID());
  90. v[0] = mesh->vertex(tri.v[0]);
  91. v[1] = mesh->vertex(tri.v[1]);
  92. v[2] = mesh->vertex(tri.v[2]);
  93. v[3] = mesh->vertex(tri.v[0]);
  94. inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
  95. inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
  96. inv_length[2] = Vec3fa(1.0f) / (v[0]-v[2]);
  97. }
  98. __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
  99. splitPolygon<3>(prim,dim,pos,v,left_o,right_o);
  100. }
  101. __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
  102. splitPolygon<3>(prim,dim,pos,v,inv_length,left_o,right_o);
  103. }
  104. private:
  105. Vec3fa v[4];
  106. Vec3fa inv_length[3];
  107. };
  108. struct TriangleSplitterFactory
  109. {
  110. __forceinline TriangleSplitterFactory(const Scene* scene)
  111. : scene(scene) {}
  112. __forceinline TriangleSplitter operator() (const PrimRef& prim) const {
  113. return TriangleSplitter(scene,prim);
  114. }
  115. private:
  116. const Scene* scene;
  117. };
  118. struct QuadSplitter
  119. {
  120. __forceinline QuadSplitter(const Scene* scene, const PrimRef& prim)
  121. {
  122. const QuadMesh* mesh = (const QuadMesh*) scene->get(prim.geomID() & 0x00FFFFFF );
  123. QuadMesh::Quad quad = mesh->quad(prim.primID());
  124. v[0] = mesh->vertex(quad.v[0]);
  125. v[1] = mesh->vertex(quad.v[1]);
  126. v[2] = mesh->vertex(quad.v[2]);
  127. v[3] = mesh->vertex(quad.v[3]);
  128. v[4] = mesh->vertex(quad.v[0]);
  129. inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
  130. inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
  131. inv_length[2] = Vec3fa(1.0f) / (v[3]-v[2]);
  132. inv_length[3] = Vec3fa(1.0f) / (v[0]-v[3]);
  133. }
  134. __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
  135. splitPolygon<4>(prim,dim,pos,v,left_o,right_o);
  136. }
  137. __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
  138. splitPolygon<4>(prim,dim,pos,v,inv_length,left_o,right_o);
  139. }
  140. private:
  141. Vec3fa v[5];
  142. Vec3fa inv_length[4];
  143. };
  144. struct QuadSplitterFactory
  145. {
  146. __forceinline QuadSplitterFactory(const Scene* scene)
  147. : scene(scene) {}
  148. __forceinline QuadSplitter operator() (const PrimRef& prim) const {
  149. return QuadSplitter(scene,prim);
  150. }
  151. private:
  152. const Scene* scene;
  153. };
  154. }
  155. }