accel.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "default.h"
  5. #include "ray.h"
  6. #include "point_query.h"
  7. #include "context.h"
  8. namespace embree
  9. {
  10. class Scene;
  11. /*! Base class for the acceleration structure data. */
  12. class AccelData : public RefCount
  13. {
  14. ALIGNED_CLASS_(16);
  15. public:
  16. enum Type { TY_UNKNOWN = 0, TY_ACCELN = 1, TY_ACCEL_INSTANCE = 2, TY_BVH4 = 3, TY_BVH8 = 4, TY_GPU = 5 };
  17. public:
  18. AccelData (const Type type)
  19. : bounds(empty), type(type) {}
  20. /*! notifies the acceleration structure about the deletion of some geometry */
  21. virtual void deleteGeometry(size_t geomID) {};
  22. /*! clears the acceleration structure data */
  23. virtual void clear() = 0;
  24. /*! returns normal bounds */
  25. __forceinline BBox3fa getBounds() const {
  26. return bounds.bounds();
  27. }
  28. /*! returns bounds for some time */
  29. __forceinline BBox3fa getBounds(float t) const {
  30. return bounds.interpolate(t);
  31. }
  32. /*! returns linear bounds */
  33. __forceinline LBBox3fa getLinearBounds() const {
  34. return bounds;
  35. }
  36. /*! checks if acceleration structure is empty */
  37. __forceinline bool isEmpty() const {
  38. return bounds.bounds0.lower.x == float(pos_inf);
  39. }
  40. public:
  41. LBBox3fa bounds; // linear bounds
  42. Type type;
  43. };
  44. /*! Base class for all intersectable and buildable acceleration structures. */
  45. class Accel : public AccelData
  46. {
  47. ALIGNED_CLASS_(16);
  48. public:
  49. struct Intersectors;
  50. /*! Type of collide function */
  51. typedef void (*CollideFunc)(void* bvh0, void* bvh1, RTCCollideFunc callback, void* userPtr);
  52. /*! Type of point query function */
  53. typedef bool(*PointQueryFunc)(Intersectors* This, /*!< this pointer to accel */
  54. PointQuery* query, /*!< point query for lookup */
  55. PointQueryContext* context); /*!< point query context */
  56. /*! Type of intersect function pointer for single rays. */
  57. typedef void (*IntersectFunc)(Intersectors* This, /*!< this pointer to accel */
  58. RTCRayHit& ray, /*!< ray to intersect */
  59. RayQueryContext* context);
  60. /*! Type of intersect function pointer for ray packets of size 4. */
  61. typedef void (*IntersectFunc4)(const void* valid, /*!< pointer to valid mask */
  62. Intersectors* This, /*!< this pointer to accel */
  63. RTCRayHit4& ray, /*!< ray packet to intersect */
  64. RayQueryContext* context);
  65. /*! Type of intersect function pointer for ray packets of size 8. */
  66. typedef void (*IntersectFunc8)(const void* valid, /*!< pointer to valid mask */
  67. Intersectors* This, /*!< this pointer to accel */
  68. RTCRayHit8& ray, /*!< ray packet to intersect */
  69. RayQueryContext* context);
  70. /*! Type of intersect function pointer for ray packets of size 16. */
  71. typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
  72. Intersectors* This, /*!< this pointer to accel */
  73. RTCRayHit16& ray, /*!< ray packet to intersect */
  74. RayQueryContext* context);
  75. /*! Type of occlusion function pointer for single rays. */
  76. typedef void (*OccludedFunc) (Intersectors* This, /*!< this pointer to accel */
  77. RTCRay& ray, /*!< ray to test occlusion */
  78. RayQueryContext* context);
  79. /*! Type of occlusion function pointer for ray packets of size 4. */
  80. typedef void (*OccludedFunc4) (const void* valid, /*!< pointer to valid mask */
  81. Intersectors* This, /*!< this pointer to accel */
  82. RTCRay4& ray, /*!< ray packet to test occlusion. */
  83. RayQueryContext* context);
  84. /*! Type of occlusion function pointer for ray packets of size 8. */
  85. typedef void (*OccludedFunc8) (const void* valid, /*!< pointer to valid mask */
  86. Intersectors* This, /*!< this pointer to accel */
  87. RTCRay8& ray, /*!< ray packet to test occlusion. */
  88. RayQueryContext* context);
  89. /*! Type of occlusion function pointer for ray packets of size 16. */
  90. typedef void (*OccludedFunc16) (const void* valid, /*!< pointer to valid mask */
  91. Intersectors* This, /*!< this pointer to accel */
  92. RTCRay16& ray, /*!< ray packet to test occlusion. */
  93. RayQueryContext* context);
  94. typedef void (*ErrorFunc) ();
  95. struct Collider
  96. {
  97. Collider (ErrorFunc error = nullptr)
  98. : collide((CollideFunc)error), name(nullptr) {}
  99. Collider (CollideFunc collide, const char* name)
  100. : collide(collide), name(name) {}
  101. operator bool() const { return name; }
  102. public:
  103. CollideFunc collide;
  104. const char* name;
  105. };
  106. struct Intersector1
  107. {
  108. Intersector1 (ErrorFunc error = nullptr)
  109. : intersect((IntersectFunc)error), occluded((OccludedFunc)error), name(nullptr) {}
  110. Intersector1 (IntersectFunc intersect, OccludedFunc occluded, const char* name)
  111. : intersect(intersect), occluded(occluded), pointQuery(nullptr), name(name) {}
  112. Intersector1 (IntersectFunc intersect, OccludedFunc occluded, PointQueryFunc pointQuery, const char* name)
  113. : intersect(intersect), occluded(occluded), pointQuery(pointQuery), name(name) {}
  114. operator bool() const { return name; }
  115. public:
  116. static const char* type;
  117. IntersectFunc intersect;
  118. OccludedFunc occluded;
  119. PointQueryFunc pointQuery;
  120. const char* name;
  121. };
  122. struct Intersector4
  123. {
  124. Intersector4 (ErrorFunc error = nullptr)
  125. : intersect((IntersectFunc4)error), occluded((OccludedFunc4)error), name(nullptr) {}
  126. Intersector4 (IntersectFunc4 intersect, OccludedFunc4 occluded, const char* name)
  127. : intersect(intersect), occluded(occluded), name(name) {}
  128. operator bool() const { return name; }
  129. public:
  130. static const char* type;
  131. IntersectFunc4 intersect;
  132. OccludedFunc4 occluded;
  133. const char* name;
  134. };
  135. struct Intersector8
  136. {
  137. Intersector8 (ErrorFunc error = nullptr)
  138. : intersect((IntersectFunc8)error), occluded((OccludedFunc8)error), name(nullptr) {}
  139. Intersector8 (IntersectFunc8 intersect, OccludedFunc8 occluded, const char* name)
  140. : intersect(intersect), occluded(occluded), name(name) {}
  141. operator bool() const { return name; }
  142. public:
  143. static const char* type;
  144. IntersectFunc8 intersect;
  145. OccludedFunc8 occluded;
  146. const char* name;
  147. };
  148. struct Intersector16
  149. {
  150. Intersector16 (ErrorFunc error = nullptr)
  151. : intersect((IntersectFunc16)error), occluded((OccludedFunc16)error), name(nullptr) {}
  152. Intersector16 (IntersectFunc16 intersect, OccludedFunc16 occluded, const char* name)
  153. : intersect(intersect), occluded(occluded), name(name) {}
  154. operator bool() const { return name; }
  155. public:
  156. static const char* type;
  157. IntersectFunc16 intersect;
  158. OccludedFunc16 occluded;
  159. const char* name;
  160. };
  161. struct Intersectors
  162. {
  163. Intersectors()
  164. : ptr(nullptr), leafIntersector(nullptr), collider(nullptr), intersector1(nullptr), intersector4(nullptr), intersector8(nullptr), intersector16(nullptr) {}
  165. Intersectors (ErrorFunc error)
  166. : ptr(nullptr), leafIntersector(nullptr), collider(error), intersector1(error), intersector4(error), intersector8(error), intersector16(error) {}
  167. void print(size_t ident)
  168. {
  169. if (collider.name) {
  170. for (size_t i=0; i<ident; i++) std::cout << " ";
  171. std::cout << "collider = " << collider.name << std::endl;
  172. }
  173. if (intersector1.name) {
  174. for (size_t i=0; i<ident; i++) std::cout << " ";
  175. std::cout << "intersector1 = " << intersector1.name << std::endl;
  176. }
  177. if (intersector4.name) {
  178. for (size_t i=0; i<ident; i++) std::cout << " ";
  179. std::cout << "intersector4 = " << intersector4.name << std::endl;
  180. }
  181. if (intersector8.name) {
  182. for (size_t i=0; i<ident; i++) std::cout << " ";
  183. std::cout << "intersector8 = " << intersector8.name << std::endl;
  184. }
  185. if (intersector16.name) {
  186. for (size_t i=0; i<ident; i++) std::cout << " ";
  187. std::cout << "intersector16 = " << intersector16.name << std::endl;
  188. }
  189. }
  190. void select(bool filter)
  191. {
  192. if (intersector4_filter) {
  193. if (filter) intersector4 = intersector4_filter;
  194. else intersector4 = intersector4_nofilter;
  195. }
  196. if (intersector8_filter) {
  197. if (filter) intersector8 = intersector8_filter;
  198. else intersector8 = intersector8_nofilter;
  199. }
  200. if (intersector16_filter) {
  201. if (filter) intersector16 = intersector16_filter;
  202. else intersector16 = intersector16_nofilter;
  203. }
  204. }
  205. __forceinline bool pointQuery (PointQuery* query, PointQueryContext* context) {
  206. assert(intersector1.pointQuery);
  207. return intersector1.pointQuery(this,query,context);
  208. }
  209. /*! collides two scenes */
  210. __forceinline void collide (Accel* scene0, Accel* scene1, RTCCollideFunc callback, void* userPtr) {
  211. assert(collider.collide);
  212. collider.collide(scene0->intersectors.ptr,scene1->intersectors.ptr,callback,userPtr);
  213. }
  214. /*! Intersects a single ray with the scene. */
  215. __forceinline void intersect (RTCRayHit& ray, RayQueryContext* context) {
  216. assert(intersector1.intersect);
  217. intersector1.intersect(this,ray,context);
  218. }
  219. /*! Intersects a packet of 4 rays with the scene. */
  220. __forceinline void intersect4 (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {
  221. assert(intersector4.intersect);
  222. intersector4.intersect(valid,this,ray,context);
  223. }
  224. /*! Intersects a packet of 8 rays with the scene. */
  225. __forceinline void intersect8 (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {
  226. assert(intersector8.intersect);
  227. intersector8.intersect(valid,this,ray,context);
  228. }
  229. /*! Intersects a packet of 16 rays with the scene. */
  230. __forceinline void intersect16 (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {
  231. assert(intersector16.intersect);
  232. intersector16.intersect(valid,this,ray,context);
  233. }
  234. /*! Intersects a packet of 4 rays with the scene. */
  235. __forceinline void intersect (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {
  236. assert(intersector4.intersect);
  237. intersector4.intersect(valid,this,ray,context);
  238. }
  239. /*! Intersects a packet of 8 rays with the scene. */
  240. __forceinline void intersect (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {
  241. assert(intersector8.intersect);
  242. intersector8.intersect(valid,this,ray,context);
  243. }
  244. /*! Intersects a packet of 16 rays with the scene. */
  245. __forceinline void intersect (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {
  246. assert(intersector16.intersect);
  247. intersector16.intersect(valid,this,ray,context);
  248. }
  249. #if defined(__SSE__) || defined(__ARM_NEON)
  250. __forceinline void intersect(const vbool4& valid, RayHitK<4>& ray, RayQueryContext* context) {
  251. const vint<4> mask = valid.mask32();
  252. intersect4(&mask,(RTCRayHit4&)ray,context);
  253. }
  254. #endif
  255. #if defined(__AVX__)
  256. __forceinline void intersect(const vbool8& valid, RayHitK<8>& ray, RayQueryContext* context) {
  257. const vint<8> mask = valid.mask32();
  258. intersect8(&mask,(RTCRayHit8&)ray,context);
  259. }
  260. #endif
  261. #if defined(__AVX512F__)
  262. __forceinline void intersect(const vbool16& valid, RayHitK<16>& ray, RayQueryContext* context) {
  263. const vint<16> mask = valid.mask32();
  264. intersect16(&mask,(RTCRayHit16&)ray,context);
  265. }
  266. #endif
  267. /*! Tests if single ray is occluded by the scene. */
  268. __forceinline void occluded (RTCRay& ray, RayQueryContext* context) {
  269. assert(intersector1.occluded);
  270. intersector1.occluded(this,ray,context);
  271. }
  272. /*! Tests if a packet of 4 rays is occluded by the scene. */
  273. __forceinline void occluded4 (const void* valid, RTCRay4& ray, RayQueryContext* context) {
  274. assert(intersector4.occluded);
  275. intersector4.occluded(valid,this,ray,context);
  276. }
  277. /*! Tests if a packet of 8 rays is occluded by the scene. */
  278. __forceinline void occluded8 (const void* valid, RTCRay8& ray, RayQueryContext* context) {
  279. assert(intersector8.occluded);
  280. intersector8.occluded(valid,this,ray,context);
  281. }
  282. /*! Tests if a packet of 16 rays is occluded by the scene. */
  283. __forceinline void occluded16 (const void* valid, RTCRay16& ray, RayQueryContext* context) {
  284. assert(intersector16.occluded);
  285. intersector16.occluded(valid,this,ray,context);
  286. }
  287. /*! Tests if a packet of 4 rays is occluded by the scene. */
  288. __forceinline void occluded (const void* valid, RTCRay4& ray, RayQueryContext* context) {
  289. assert(intersector4.occluded);
  290. intersector4.occluded(valid,this,ray,context);
  291. }
  292. /*! Tests if a packet of 8 rays is occluded by the scene. */
  293. __forceinline void occluded (const void* valid, RTCRay8& ray, RayQueryContext* context) {
  294. assert(intersector8.occluded);
  295. intersector8.occluded(valid,this,ray,context);
  296. }
  297. /*! Tests if a packet of 16 rays is occluded by the scene. */
  298. __forceinline void occluded (const void* valid, RTCRay16& ray, RayQueryContext* context) {
  299. assert(intersector16.occluded);
  300. intersector16.occluded(valid,this,ray,context);
  301. }
  302. #if defined(__SSE__) || defined(__ARM_NEON)
  303. __forceinline void occluded(const vbool4& valid, RayK<4>& ray, RayQueryContext* context) {
  304. const vint<4> mask = valid.mask32();
  305. occluded4(&mask,(RTCRay4&)ray,context);
  306. }
  307. #endif
  308. #if defined(__AVX__)
  309. __forceinline void occluded(const vbool8& valid, RayK<8>& ray, RayQueryContext* context) {
  310. const vint<8> mask = valid.mask32();
  311. occluded8(&mask,(RTCRay8&)ray,context);
  312. }
  313. #endif
  314. #if defined(__AVX512F__)
  315. __forceinline void occluded(const vbool16& valid, RayK<16>& ray, RayQueryContext* context) {
  316. const vint<16> mask = valid.mask32();
  317. occluded16(&mask,(RTCRay16&)ray,context);
  318. }
  319. #endif
  320. /*! Tests if single ray is occluded by the scene. */
  321. __forceinline void intersect(RTCRay& ray, RayQueryContext* context) {
  322. occluded(ray, context);
  323. }
  324. /*! Tests if a packet of K rays is occluded by the scene. */
  325. template<int K>
  326. __forceinline void intersect(const vbool<K>& valid, RayK<K>& ray, RayQueryContext* context) {
  327. occluded(valid, ray, context);
  328. }
  329. public:
  330. AccelData* ptr;
  331. void* leafIntersector;
  332. Collider collider;
  333. Intersector1 intersector1;
  334. Intersector4 intersector4;
  335. Intersector4 intersector4_filter;
  336. Intersector4 intersector4_nofilter;
  337. Intersector8 intersector8;
  338. Intersector8 intersector8_filter;
  339. Intersector8 intersector8_nofilter;
  340. Intersector16 intersector16;
  341. Intersector16 intersector16_filter;
  342. Intersector16 intersector16_nofilter;
  343. };
  344. public:
  345. /*! Construction */
  346. Accel (const AccelData::Type type)
  347. : AccelData(type) {}
  348. /*! Construction */
  349. Accel (const AccelData::Type type, const Intersectors& intersectors)
  350. : AccelData(type), intersectors(intersectors) {}
  351. /*! Virtual destructor */
  352. virtual ~Accel() {}
  353. /*! makes the acceleration structure immutable */
  354. virtual void immutable () {}
  355. /*! build acceleration structure */
  356. virtual void build () = 0;
  357. public:
  358. Intersectors intersectors;
  359. };
  360. #define DEFINE_COLLIDER(symbol,collider) \
  361. Accel::Collider symbol() { \
  362. return Accel::Collider((Accel::CollideFunc)collider::collide, \
  363. TOSTRING(isa) "::" TOSTRING(symbol)); \
  364. }
  365. #define DEFINE_INTERSECTOR1(symbol,intersector) \
  366. Accel::Intersector1 symbol() { \
  367. return Accel::Intersector1((Accel::IntersectFunc )intersector::intersect, \
  368. (Accel::OccludedFunc )intersector::occluded, \
  369. (Accel::PointQueryFunc)intersector::pointQuery,\
  370. TOSTRING(isa) "::" TOSTRING(symbol)); \
  371. }
  372. #define DEFINE_INTERSECTOR4(symbol,intersector) \
  373. Accel::Intersector4 symbol() { \
  374. return Accel::Intersector4((Accel::IntersectFunc4)intersector::intersect, \
  375. (Accel::OccludedFunc4)intersector::occluded, \
  376. TOSTRING(isa) "::" TOSTRING(symbol)); \
  377. }
  378. #define DEFINE_INTERSECTOR8(symbol,intersector) \
  379. Accel::Intersector8 symbol() { \
  380. return Accel::Intersector8((Accel::IntersectFunc8)intersector::intersect, \
  381. (Accel::OccludedFunc8)intersector::occluded, \
  382. TOSTRING(isa) "::" TOSTRING(symbol)); \
  383. }
  384. #define DEFINE_INTERSECTOR16(symbol,intersector) \
  385. Accel::Intersector16 symbol() { \
  386. return Accel::Intersector16((Accel::IntersectFunc16)intersector::intersect, \
  387. (Accel::OccludedFunc16)intersector::occluded, \
  388. TOSTRING(isa) "::" TOSTRING(symbol)); \
  389. }
  390. }