acceln.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include "acceln.h"
  4. #include "ray.h"
  5. #include "../../include/embree3/rtcore_ray.h"
  6. #include "../../common/algorithms/parallel_for.h"
  7. namespace embree
  8. {
  9. AccelN::AccelN()
  10. : Accel(AccelData::TY_ACCELN), accels() {}
  11. AccelN::~AccelN()
  12. {
  13. for (size_t i=0; i<accels.size(); i++)
  14. delete accels[i];
  15. }
  16. void AccelN::accels_add(Accel* accel)
  17. {
  18. assert(accel);
  19. accels.push_back(accel);
  20. }
  21. void AccelN::accels_init()
  22. {
  23. for (size_t i=0; i<accels.size(); i++)
  24. delete accels[i];
  25. accels.clear();
  26. }
  27. bool AccelN::pointQuery (Accel::Intersectors* This_in, PointQuery* query, PointQueryContext* context)
  28. {
  29. bool changed = false;
  30. AccelN* This = (AccelN*)This_in->ptr;
  31. for (size_t i=0; i<This->accels.size(); i++)
  32. if (!This->accels[i]->isEmpty())
  33. changed |= This->accels[i]->intersectors.pointQuery(query,context);
  34. return changed;
  35. }
  36. void AccelN::intersect (Accel::Intersectors* This_in, RTCRayHit& ray, IntersectContext* context)
  37. {
  38. AccelN* This = (AccelN*)This_in->ptr;
  39. for (size_t i=0; i<This->accels.size(); i++)
  40. if (!This->accels[i]->isEmpty())
  41. This->accels[i]->intersectors.intersect(ray,context);
  42. }
  43. void AccelN::intersect4 (const void* valid, Accel::Intersectors* This_in, RTCRayHit4& ray, IntersectContext* context)
  44. {
  45. AccelN* This = (AccelN*)This_in->ptr;
  46. for (size_t i=0; i<This->accels.size(); i++)
  47. if (!This->accels[i]->isEmpty())
  48. This->accels[i]->intersectors.intersect4(valid,ray,context);
  49. }
  50. void AccelN::intersect8 (const void* valid, Accel::Intersectors* This_in, RTCRayHit8& ray, IntersectContext* context)
  51. {
  52. AccelN* This = (AccelN*)This_in->ptr;
  53. for (size_t i=0; i<This->accels.size(); i++)
  54. if (!This->accels[i]->isEmpty())
  55. This->accels[i]->intersectors.intersect8(valid,ray,context);
  56. }
  57. void AccelN::intersect16 (const void* valid, Accel::Intersectors* This_in, RTCRayHit16& ray, IntersectContext* context)
  58. {
  59. AccelN* This = (AccelN*)This_in->ptr;
  60. for (size_t i=0; i<This->accels.size(); i++)
  61. if (!This->accels[i]->isEmpty())
  62. This->accels[i]->intersectors.intersect16(valid,ray,context);
  63. }
  64. void AccelN::intersectN (Accel::Intersectors* This_in, RTCRayHitN** ray, const size_t N, IntersectContext* context)
  65. {
  66. AccelN* This = (AccelN*)This_in->ptr;
  67. for (size_t i=0; i<This->accels.size(); i++)
  68. if (!This->accels[i]->isEmpty())
  69. This->accels[i]->intersectors.intersectN(ray,N,context);
  70. }
  71. void AccelN::occluded (Accel::Intersectors* This_in, RTCRay& ray, IntersectContext* context)
  72. {
  73. AccelN* This = (AccelN*)This_in->ptr;
  74. for (size_t i=0; i<This->accels.size(); i++) {
  75. if (This->accels[i]->isEmpty()) continue;
  76. This->accels[i]->intersectors.occluded(ray,context);
  77. if (ray.tfar < 0.0f) break;
  78. }
  79. }
  80. void AccelN::occluded4 (const void* valid, Accel::Intersectors* This_in, RTCRay4& ray, IntersectContext* context)
  81. {
  82. AccelN* This = (AccelN*)This_in->ptr;
  83. for (size_t i=0; i<This->accels.size(); i++) {
  84. if (This->accels[i]->isEmpty()) continue;
  85. This->accels[i]->intersectors.occluded4(valid,ray,context);
  86. #if defined(__SSE2__) || defined(__ARM_NEON)
  87. vbool4 valid0 = asBool(((vint4*)valid)[0]);
  88. vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero);
  89. if (unlikely(none(valid0 & hit0))) break;
  90. #endif
  91. }
  92. }
  93. void AccelN::occluded8 (const void* valid, Accel::Intersectors* This_in, RTCRay8& ray, IntersectContext* context)
  94. {
  95. AccelN* This = (AccelN*)This_in->ptr;
  96. for (size_t i=0; i<This->accels.size(); i++) {
  97. if (This->accels[i]->isEmpty()) continue;
  98. This->accels[i]->intersectors.occluded8(valid,ray,context);
  99. #if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA
  100. vbool4 valid0 = asBool(((vint4*)valid)[0]);
  101. vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero);
  102. vbool4 valid1 = asBool(((vint4*)valid)[1]);
  103. vbool4 hit1 = ((vfloat4*)ray.tfar)[1] >= vfloat4(zero);
  104. if (unlikely((none((valid0 & hit0) | (valid1 & hit1))))) break;
  105. #endif
  106. }
  107. }
  108. void AccelN::occluded16 (const void* valid, Accel::Intersectors* This_in, RTCRay16& ray, IntersectContext* context)
  109. {
  110. AccelN* This = (AccelN*)This_in->ptr;
  111. for (size_t i=0; i<This->accels.size(); i++) {
  112. if (This->accels[i]->isEmpty()) continue;
  113. This->accels[i]->intersectors.occluded16(valid,ray,context);
  114. #if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA
  115. vbool4 valid0 = asBool(((vint4*)valid)[0]);
  116. vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero);
  117. vbool4 valid1 = asBool(((vint4*)valid)[1]);
  118. vbool4 hit1 = ((vfloat4*)ray.tfar)[1] >= vfloat4(zero);
  119. vbool4 valid2 = asBool(((vint4*)valid)[2]);
  120. vbool4 hit2 = ((vfloat4*)ray.tfar)[2] >= vfloat4(zero);
  121. vbool4 valid3 = asBool(((vint4*)valid)[3]);
  122. vbool4 hit3 = ((vfloat4*)ray.tfar)[3] >= vfloat4(zero);
  123. if (unlikely((none((valid0 & hit0) | (valid1 & hit1) | (valid2 & hit2) | (valid3 & hit3))))) break;
  124. #endif
  125. }
  126. }
  127. void AccelN::occludedN (Accel::Intersectors* This_in, RTCRayN** ray, const size_t N, IntersectContext* context)
  128. {
  129. AccelN* This = (AccelN*)This_in->ptr;
  130. size_t M = N;
  131. for (size_t i=0; i<This->accels.size(); i++)
  132. if (!This->accels[i]->isEmpty())
  133. This->accels[i]->intersectors.occludedN(ray,M,context);
  134. }
  135. void AccelN::accels_print(size_t ident)
  136. {
  137. for (size_t i=0; i<accels.size(); i++)
  138. {
  139. for (size_t j=0; j<ident; j++) std::cout << " ";
  140. std::cout << "accels[" << i << "]" << std::endl;
  141. accels[i]->intersectors.print(ident+2);
  142. }
  143. }
  144. void AccelN::accels_immutable()
  145. {
  146. for (size_t i=0; i<accels.size(); i++)
  147. accels[i]->immutable();
  148. }
  149. void AccelN::accels_build ()
  150. {
  151. /* reduce memory consumption */
  152. accels.shrink_to_fit();
  153. /* build all acceleration structures in parallel */
  154. parallel_for (accels.size(), [&] (size_t i) {
  155. accels[i]->build();
  156. });
  157. /* create list of non-empty acceleration structures */
  158. bool valid1 = true;
  159. bool valid4 = true;
  160. bool valid8 = true;
  161. bool valid16 = true;
  162. for (size_t i=0; i<accels.size(); i++) {
  163. valid1 &= (bool) accels[i]->intersectors.intersector1;
  164. valid4 &= (bool) accels[i]->intersectors.intersector4;
  165. valid8 &= (bool) accels[i]->intersectors.intersector8;
  166. valid16 &= (bool) accels[i]->intersectors.intersector16;
  167. }
  168. if (accels.size() == 1) {
  169. type = accels[0]->type; // FIXME: should just assign entire Accel
  170. bounds = accels[0]->bounds;
  171. intersectors = accels[0]->intersectors;
  172. }
  173. else
  174. {
  175. type = AccelData::TY_ACCELN;
  176. intersectors.ptr = this;
  177. intersectors.intersector1 = Intersector1(&intersect,&occluded,&pointQuery,valid1 ? "AccelN::intersector1": nullptr);
  178. intersectors.intersector4 = Intersector4(&intersect4,&occluded4,valid4 ? "AccelN::intersector4" : nullptr);
  179. intersectors.intersector8 = Intersector8(&intersect8,&occluded8,valid8 ? "AccelN::intersector8" : nullptr);
  180. intersectors.intersector16 = Intersector16(&intersect16,&occluded16,valid16 ? "AccelN::intersector16": nullptr);
  181. intersectors.intersectorN = IntersectorN(&intersectN,&occludedN,"AccelN::intersectorN");
  182. /*! calculate bounds */
  183. bounds = empty;
  184. for (size_t i=0; i<accels.size(); i++)
  185. bounds.extend(accels[i]->bounds);
  186. }
  187. }
  188. void AccelN::accels_select(bool filter)
  189. {
  190. for (size_t i=0; i<accels.size(); i++)
  191. accels[i]->intersectors.select(filter);
  192. }
  193. void AccelN::accels_deleteGeometry(size_t geomID)
  194. {
  195. for (size_t i=0; i<accels.size(); i++)
  196. accels[i]->deleteGeometry(geomID);
  197. }
  198. void AccelN::accels_clear()
  199. {
  200. for (size_t i=0; i<accels.size(); i++) {
  201. accels[i]->clear();
  202. }
  203. }
  204. }