scene.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 "default.h"
  18. #include "device.h"
  19. #include "scene_triangle_mesh.h"
  20. #include "scene_quad_mesh.h"
  21. #include "scene_user_geometry.h"
  22. #include "scene_instance.h"
  23. #include "scene_geometry_instance.h"
  24. #include "scene_bezier_curves.h"
  25. #include "scene_line_segments.h"
  26. #include "scene_subdiv_mesh.h"
  27. #include "../subdiv/tessellation_cache.h"
  28. #include "acceln.h"
  29. #include "geometry.h"
  30. namespace embree
  31. {
  32. /*! Base class all scenes are derived from */
  33. class Scene : public Accel
  34. {
  35. ALIGNED_CLASS;
  36. public:
  37. template<typename Ty, bool mblur = false>
  38. class Iterator
  39. {
  40. public:
  41. Iterator () {}
  42. Iterator (Scene* scene, bool all = false)
  43. : scene(scene), all(all) {}
  44. __forceinline Ty* at(const size_t i)
  45. {
  46. Geometry* geom = scene->geometries[i];
  47. if (geom == nullptr) return nullptr;
  48. if (!all && !geom->isEnabled()) return nullptr;
  49. if (geom->getType() != Ty::geom_type) return nullptr;
  50. if ((geom->numTimeSteps != 1) != mblur) return nullptr;
  51. return (Ty*) geom;
  52. }
  53. __forceinline Ty* operator[] (const size_t i) {
  54. return at(i);
  55. }
  56. __forceinline size_t size() const {
  57. return scene->size();
  58. }
  59. __forceinline size_t numPrimitives() const {
  60. return scene->getNumPrimitives<Ty,mblur>();
  61. }
  62. __forceinline size_t maxPrimitivesPerGeometry()
  63. {
  64. size_t ret = 0;
  65. for (size_t i=0; i<scene->size(); i++) {
  66. Ty* mesh = at(i);
  67. if (mesh == nullptr) continue;
  68. ret = max(ret,mesh->size());
  69. }
  70. return ret;
  71. }
  72. __forceinline unsigned maxTimeStepsPerGeometry()
  73. {
  74. unsigned ret = 0;
  75. for (size_t i=0; i<scene->size(); i++) {
  76. Ty* mesh = at(i);
  77. if (mesh == nullptr) continue;
  78. ret = max(ret,mesh->numTimeSteps);
  79. }
  80. return ret;
  81. }
  82. private:
  83. Scene* scene;
  84. bool all;
  85. };
  86. public:
  87. /*! Scene construction */
  88. Scene (Device* device, RTCSceneFlags flags, RTCAlgorithmFlags aflags);
  89. private:
  90. /*! class is non-copyable */
  91. Scene (const Scene& other) DELETED; // do not implement
  92. Scene& operator= (const Scene& other) DELETED; // do not implement
  93. public:
  94. void createTriangleAccel();
  95. void createQuadAccel();
  96. void createTriangleMBAccel();
  97. void createQuadMBAccel();
  98. void createHairAccel();
  99. void createHairMBAccel();
  100. void createLineAccel();
  101. void createLineMBAccel();
  102. void createSubdivAccel();
  103. void createSubdivMBAccel();
  104. void createUserGeometryAccel();
  105. void createUserGeometryMBAccel();
  106. /*! Scene destruction */
  107. ~Scene ();
  108. /*! clears the scene */
  109. void clear();
  110. /*! Creates new user geometry. */
  111. unsigned int newUserGeometry (RTCGeometryFlags gflags, size_t items, size_t numTimeSteps);
  112. /*! Creates a new scene instance. */
  113. unsigned int newInstance (Scene* scene, size_t numTimeSteps);
  114. /*! Creates a new geometry instance. */
  115. unsigned int newGeometryInstance (Geometry* geom);
  116. /*! Creates a new triangle mesh. */
  117. unsigned int newTriangleMesh (RTCGeometryFlags flags, size_t maxTriangles, size_t maxVertices, size_t numTimeSteps);
  118. /*! Creates a new quad mesh. */
  119. unsigned int newQuadMesh (RTCGeometryFlags flags, size_t maxQuads, size_t maxVertices, size_t numTimeSteps);
  120. /*! Creates a new collection of quadratic bezier curves. */
  121. unsigned int newCurves (NativeCurves::SubType subtype, NativeCurves::Basis basis, RTCGeometryFlags flags, size_t maxCurves, size_t maxVertices, size_t numTimeSteps);
  122. /*! Creates a new collection of line segments. */
  123. unsigned int newLineSegments (RTCGeometryFlags flags, size_t maxSegments, size_t maxVertices, size_t numTimeSteps);
  124. /*! Creates a new subdivision mesh. */
  125. unsigned int newSubdivisionMesh (RTCGeometryFlags flags, size_t numFaces, size_t numEdges, size_t numVertices, size_t numEdgeCreases, size_t numVertexCreases, size_t numHoles, size_t numTimeSteps);
  126. /*! deletes some geometry */
  127. void deleteGeometry(size_t geomID);
  128. /*! Builds acceleration structure for the scene. */
  129. void commit (size_t threadIndex, size_t threadCount, bool useThreadPool);
  130. void commit_task ();
  131. void build () {}
  132. void updateInterface();
  133. /* return number of geometries */
  134. __forceinline size_t size() const { return geometries.size(); }
  135. /* add user geometry to scene */
  136. unsigned int add (Geometry* geometry);
  137. /* determines of the scene is ready to get build */
  138. bool ready() { return numMappedBuffers == 0; }
  139. /* determines if scene is modified */
  140. __forceinline bool isModified() const { return modified; }
  141. /* sets modified flag */
  142. __forceinline void setModified(bool f = true) {
  143. modified = f;
  144. }
  145. /* get mesh by ID */
  146. __forceinline Geometry* get(size_t i) { assert(i < geometries.size()); return geometries[i]; }
  147. __forceinline const Geometry* get(size_t i) const { assert(i < geometries.size()); return geometries[i]; }
  148. template<typename Mesh>
  149. __forceinline Mesh* get(size_t i) {
  150. assert(i < geometries.size());
  151. assert(geometries[i]->getType() == Mesh::geom_type);
  152. return (Mesh*)geometries[i];
  153. }
  154. template<typename Mesh>
  155. __forceinline const Mesh* get(size_t i) const {
  156. assert(i < geometries.size());
  157. assert(geometries[i]->getType() == Mesh::geom_type);
  158. return (Mesh*)geometries[i];
  159. }
  160. template<typename Mesh>
  161. __forceinline Mesh* getSafe(size_t i) {
  162. assert(i < geometries.size());
  163. if (geometries[i] == nullptr) return nullptr;
  164. if (geometries[i]->getType() != Mesh::geom_type) return nullptr;
  165. else return (Mesh*) geometries[i];
  166. }
  167. __forceinline Geometry* get_locked(size_t i) {
  168. Lock<SpinLock> lock(geometriesMutex);
  169. Geometry *g = geometries[i];
  170. assert(i < geometries.size());
  171. return g;
  172. }
  173. /* test if this is a static scene */
  174. __forceinline bool isStatic() const { return embree::isStatic(flags); }
  175. /* test if this is a dynamic scene */
  176. __forceinline bool isDynamic() const { return embree::isDynamic(flags); }
  177. __forceinline bool isCompact() const { return embree::isCompact(flags); }
  178. __forceinline bool isCoherent() const { return embree::isCoherent(flags); }
  179. __forceinline bool isRobust() const { return embree::isRobust(flags); }
  180. __forceinline bool isHighQuality() const { return embree::isHighQuality(flags); }
  181. __forceinline bool isInterpolatable() const { return embree::isInterpolatable(aflags); }
  182. __forceinline bool isStreamMode() const { return embree::isStreamMode(aflags); }
  183. __forceinline bool isExclusiveIntersect1Mode() const {
  184. if (!embree::isIntersect1Mode(aflags)) return false;
  185. if (embree::isIntersect4Mode(aflags)) return false;
  186. if (embree::isIntersect8Mode(aflags)) return false;
  187. if (embree::isIntersect16Mode(aflags)) return false;
  188. return true;
  189. }
  190. /* test if scene got already build */
  191. __forceinline bool isBuild() const { return is_build; }
  192. public:
  193. IDPool<unsigned> id_pool;
  194. std::vector<Geometry*> geometries; //!< list of all user geometries
  195. public:
  196. Device* device;
  197. AccelN accels;
  198. std::atomic<size_t> commitCounterSubdiv;
  199. std::atomic<size_t> numMappedBuffers; //!< number of mapped buffers
  200. RTCSceneFlags flags;
  201. RTCAlgorithmFlags aflags;
  202. bool needTriangleIndices;
  203. bool needTriangleVertices;
  204. bool needQuadIndices;
  205. bool needQuadVertices;
  206. bool needBezierIndices;
  207. bool needBezierVertices;
  208. bool needLineIndices;
  209. bool needLineVertices;
  210. bool needSubdivIndices;
  211. bool needSubdivVertices;
  212. MutexSys buildMutex;
  213. SpinLock geometriesMutex;
  214. bool is_build;
  215. bool modified; //!< true if scene got modified
  216. /*! global lock step task scheduler */
  217. #if defined(TASKING_INTERNAL)
  218. MutexSys schedulerMutex;
  219. Ref<TaskScheduler> scheduler;
  220. #elif defined(TASKING_TBB)
  221. tbb::task_group* group;
  222. BarrierActiveAutoReset group_barrier;
  223. #elif defined(TASKING_PPL)
  224. concurrency::task_group* group;
  225. BarrierActiveAutoReset group_barrier;
  226. #endif
  227. public:
  228. struct BuildProgressMonitorInterface : public BuildProgressMonitor {
  229. BuildProgressMonitorInterface(Scene* scene)
  230. : scene(scene) {}
  231. void operator() (size_t dn) const { scene->progressMonitor(double(dn)); }
  232. private:
  233. Scene* scene;
  234. };
  235. BuildProgressMonitorInterface progressInterface;
  236. RTCProgressMonitorFunc progress_monitor_function;
  237. void* progress_monitor_ptr;
  238. std::atomic<size_t> progress_monitor_counter;
  239. void progressMonitor(double nprims);
  240. void setProgressMonitorFunction(RTCProgressMonitorFunc func, void* ptr);
  241. public:
  242. struct GeometryCounts
  243. {
  244. __forceinline GeometryCounts()
  245. : numTriangles(0), numQuads(0), numBezierCurves(0), numLineSegments(0), numSubdivPatches(0), numUserGeometries(0) {}
  246. __forceinline size_t size() const {
  247. return numTriangles + numQuads + numBezierCurves + numLineSegments + numSubdivPatches + numUserGeometries;
  248. }
  249. std::atomic<size_t> numTriangles; //!< number of enabled triangles
  250. std::atomic<size_t> numQuads; //!< number of enabled quads
  251. std::atomic<size_t> numBezierCurves; //!< number of enabled curves
  252. std::atomic<size_t> numLineSegments; //!< number of enabled line segments
  253. std::atomic<size_t> numSubdivPatches; //!< number of enabled subdivision patches
  254. std::atomic<size_t> numUserGeometries; //!< number of enabled user geometries
  255. };
  256. GeometryCounts world; //!< counts for non-motion blurred geometry
  257. GeometryCounts worldMB; //!< counts for motion blurred geometry
  258. GeometryCounts instanced; //!< instance counts for non-motion blurred geometry
  259. GeometryCounts instancedMB; //!< instance counts for motion blurred geometry
  260. std::atomic<size_t> numSubdivEnableDisableEvents; //!< number of enable/disable calls for any subdiv geometry
  261. __forceinline size_t numPrimitives() const {
  262. return world.size() + worldMB.size();
  263. }
  264. template<typename Mesh, bool mblur> __forceinline size_t getNumPrimitives() const;
  265. template<typename Mesh, bool mblur>
  266. __forceinline unsigned getNumTimeSteps()
  267. {
  268. if (!mblur)
  269. return 1;
  270. Scene::Iterator<Mesh,mblur> iter(this);
  271. return iter.maxTimeStepsPerGeometry();
  272. }
  273. std::atomic<size_t> numIntersectionFilters1; //!< number of enabled intersection/occlusion filters for single rays
  274. std::atomic<size_t> numIntersectionFilters4; //!< number of enabled intersection/occlusion filters for 4-wide ray packets
  275. std::atomic<size_t> numIntersectionFilters8; //!< number of enabled intersection/occlusion filters for 8-wide ray packets
  276. std::atomic<size_t> numIntersectionFilters16; //!< number of enabled intersection/occlusion filters for 16-wide ray packets
  277. std::atomic<size_t> numIntersectionFiltersN; //!< number of enabled intersection/occlusion filters for N-wide ray packets
  278. };
  279. template<> __forceinline size_t Scene::getNumPrimitives<TriangleMesh,false>() const { return world.numTriangles; }
  280. template<> __forceinline size_t Scene::getNumPrimitives<TriangleMesh,true>() const { return worldMB.numTriangles; }
  281. template<> __forceinline size_t Scene::getNumPrimitives<QuadMesh,false>() const { return world.numQuads; }
  282. template<> __forceinline size_t Scene::getNumPrimitives<QuadMesh,true>() const { return worldMB.numQuads; }
  283. template<> __forceinline size_t Scene::getNumPrimitives<NativeCurves,false>() const { return world.numBezierCurves; }
  284. template<> __forceinline size_t Scene::getNumPrimitives<NativeCurves,true>() const { return worldMB.numBezierCurves; }
  285. template<> __forceinline size_t Scene::getNumPrimitives<LineSegments,false>() const { return world.numLineSegments; }
  286. template<> __forceinline size_t Scene::getNumPrimitives<LineSegments,true>() const { return worldMB.numLineSegments; }
  287. template<> __forceinline size_t Scene::getNumPrimitives<SubdivMesh,false>() const { return world.numSubdivPatches; }
  288. template<> __forceinline size_t Scene::getNumPrimitives<SubdivMesh,true>() const { return worldMB.numSubdivPatches; }
  289. template<> __forceinline size_t Scene::getNumPrimitives<AccelSet,false>() const { return world.numUserGeometries; }
  290. template<> __forceinline size_t Scene::getNumPrimitives<AccelSet,true>() const { return worldMB.numUserGeometries; }
  291. }