geometry.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. #include "geometry.h"
  17. #include "scene.h"
  18. namespace embree
  19. {
  20. Geometry::Geometry (Scene* parent, Type type, size_t numPrimitives, size_t numTimeSteps, RTCGeometryFlags flags)
  21. : parent(parent), id(0), type(type),
  22. numPrimitives(numPrimitives), numPrimitivesChanged(false),
  23. numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), flags(flags),
  24. enabled(true), modified(true), userPtr(nullptr), mask(-1), used(1),
  25. intersectionFilter1(nullptr), occlusionFilter1(nullptr),
  26. intersectionFilter4(nullptr), occlusionFilter4(nullptr),
  27. intersectionFilter8(nullptr), occlusionFilter8(nullptr),
  28. intersectionFilter16(nullptr), occlusionFilter16(nullptr),
  29. intersectionFilterN(nullptr), occlusionFilterN(nullptr),
  30. hasIntersectionFilterMask(0), hasOcclusionFilterMask(0), ispcIntersectionFilterMask(0), ispcOcclusionFilterMask(0)
  31. {
  32. parent->setModified();
  33. }
  34. Geometry::~Geometry() {
  35. }
  36. void Geometry::preCommit() {
  37. }
  38. void Geometry::postCommit()
  39. {
  40. /* make static geometry immutable */
  41. if (parent->isStatic())
  42. immutable();
  43. /* clear modified flag */
  44. if (isEnabled())
  45. clearModified();
  46. }
  47. void Geometry::updateIntersectionFilters(bool enable)
  48. {
  49. const size_t num1 = (intersectionFilter1 != nullptr) + (occlusionFilter1 != nullptr);
  50. const size_t num4 = (intersectionFilter4 != nullptr) + (occlusionFilter4 != nullptr);
  51. const size_t num8 = (intersectionFilter8 != nullptr) + (occlusionFilter8 != nullptr);
  52. const size_t num16 = (intersectionFilter16 != nullptr) + (occlusionFilter16 != nullptr);
  53. const size_t numN = (intersectionFilterN != nullptr) + (occlusionFilterN != nullptr);
  54. if (enable) {
  55. parent->numIntersectionFilters1 += num1;
  56. parent->numIntersectionFilters4 += num4;
  57. parent->numIntersectionFilters8 += num8;
  58. parent->numIntersectionFilters16 += num16;
  59. parent->numIntersectionFiltersN += numN;
  60. } else {
  61. parent->numIntersectionFilters1 -= num1;
  62. parent->numIntersectionFilters4 -= num4;
  63. parent->numIntersectionFilters8 -= num8;
  64. parent->numIntersectionFilters16 -= num16;
  65. parent->numIntersectionFiltersN -= numN;
  66. }
  67. }
  68. void Geometry::enable ()
  69. {
  70. if (parent->isStatic() && parent->isBuild())
  71. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  72. if (isEnabled())
  73. return;
  74. updateIntersectionFilters(true);
  75. parent->setModified();
  76. used++;
  77. enabled = true;
  78. enabling();
  79. }
  80. void Geometry::update()
  81. {
  82. if (parent->isStatic() && parent->isBuild())
  83. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  84. parent->setModified();
  85. modified = true;
  86. }
  87. void Geometry::disable ()
  88. {
  89. if (parent->isStatic() && parent->isBuild())
  90. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  91. if (isDisabled())
  92. return;
  93. updateIntersectionFilters(false);
  94. parent->setModified();
  95. used--;
  96. enabled = false;
  97. disabling();
  98. }
  99. void Geometry::setUserData (void* ptr)
  100. {
  101. if (parent->isStatic() && parent->isBuild())
  102. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  103. userPtr = ptr;
  104. }
  105. void Geometry::setIntersectionFilterFunction (RTCFilterFunc filter, bool ispc)
  106. {
  107. if (parent->isStreamMode())
  108. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetIntersectionFilterFunctionN in stream mode");
  109. if (parent->isStatic() && parent->isBuild())
  110. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  111. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  112. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  113. parent->numIntersectionFilters1 -= intersectionFilter1 != nullptr;
  114. parent->numIntersectionFilters1 += filter != nullptr;
  115. intersectionFilter1 = filter;
  116. if (filter) hasIntersectionFilterMask |= HAS_FILTER1; else hasIntersectionFilterMask &= ~HAS_FILTER1;
  117. }
  118. void Geometry::setIntersectionFilterFunction4 (RTCFilterFunc4 filter, bool ispc)
  119. {
  120. if (parent->isStreamMode())
  121. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetIntersectionFilterFunctionN in stream mode");
  122. if (parent->isStatic() && parent->isBuild())
  123. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  124. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  125. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  126. parent->numIntersectionFilters4 -= intersectionFilter4 != nullptr;
  127. parent->numIntersectionFilters4 += filter != nullptr;
  128. intersectionFilter4 = filter;
  129. if (filter) hasIntersectionFilterMask |= HAS_FILTER4; else hasIntersectionFilterMask &= ~HAS_FILTER4;
  130. if (ispc ) ispcIntersectionFilterMask |= HAS_FILTER4; else ispcIntersectionFilterMask &= ~HAS_FILTER4;
  131. }
  132. void Geometry::setIntersectionFilterFunction8 (RTCFilterFunc8 filter, bool ispc)
  133. {
  134. if (parent->isStreamMode())
  135. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetIntersectionFilterFunctionN in stream mode");
  136. if (parent->isStatic() && parent->isBuild())
  137. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  138. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  139. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  140. parent->numIntersectionFilters8 -= intersectionFilter8 != nullptr;
  141. parent->numIntersectionFilters8 += filter != nullptr;
  142. intersectionFilter8 = filter;
  143. if (filter) hasIntersectionFilterMask |= HAS_FILTER8; else hasIntersectionFilterMask &= ~HAS_FILTER8;
  144. if (ispc ) ispcIntersectionFilterMask |= HAS_FILTER8; else ispcIntersectionFilterMask &= ~HAS_FILTER8;
  145. }
  146. void Geometry::setIntersectionFilterFunction16 (RTCFilterFunc16 filter, bool ispc)
  147. {
  148. if (parent->isStreamMode())
  149. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetIntersectionFilterFunctionN in stream mode");
  150. if (parent->isStatic() && parent->isBuild())
  151. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  152. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  153. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  154. parent->numIntersectionFilters16 -= intersectionFilter16 != nullptr;
  155. parent->numIntersectionFilters16 += filter != nullptr;
  156. intersectionFilter16 = filter;
  157. if (filter) hasIntersectionFilterMask |= HAS_FILTER16; else hasIntersectionFilterMask &= ~HAS_FILTER16;
  158. if (ispc ) ispcIntersectionFilterMask |= HAS_FILTER16; else ispcIntersectionFilterMask &= ~HAS_FILTER16;
  159. }
  160. void Geometry::setIntersectionFilterFunctionN (RTCFilterFuncN filter)
  161. {
  162. if (!parent->isStreamMode())
  163. throw_RTCError(RTC_INVALID_OPERATION,"you can use rtcSetIntersectionFilterFunctionN only in stream mode");
  164. if (parent->isStatic() && parent->isBuild())
  165. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  166. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  167. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  168. parent->numIntersectionFiltersN -= intersectionFilterN != nullptr;
  169. parent->numIntersectionFiltersN += filter != nullptr;
  170. intersectionFilterN = filter;
  171. if (filter) hasIntersectionFilterMask |= HAS_FILTERN; else hasIntersectionFilterMask &= ~HAS_FILTERN;
  172. }
  173. void Geometry::setOcclusionFilterFunction (RTCFilterFunc filter, bool ispc)
  174. {
  175. if (parent->isStreamMode())
  176. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetOcclusionFilterFunctionN in stream mode");
  177. if (parent->isStatic() && parent->isBuild())
  178. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  179. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  180. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  181. parent->numIntersectionFilters1 -= occlusionFilter1 != nullptr;
  182. parent->numIntersectionFilters1 += filter != nullptr;
  183. occlusionFilter1 = filter;
  184. if (filter) hasOcclusionFilterMask |= HAS_FILTER1; else hasOcclusionFilterMask &= ~HAS_FILTER1;
  185. }
  186. void Geometry::setOcclusionFilterFunction4 (RTCFilterFunc4 filter, bool ispc)
  187. {
  188. if (parent->isStreamMode())
  189. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetOcclusionFilterFunctionN in stream mode");
  190. if (parent->isStatic() && parent->isBuild())
  191. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  192. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  193. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  194. parent->numIntersectionFilters4 -= occlusionFilter4 != nullptr;
  195. parent->numIntersectionFilters4 += filter != nullptr;
  196. occlusionFilter4 = filter;
  197. if (filter) hasOcclusionFilterMask |= HAS_FILTER4; else hasOcclusionFilterMask &= ~HAS_FILTER4;
  198. if (ispc ) ispcOcclusionFilterMask |= HAS_FILTER4; else ispcOcclusionFilterMask &= ~HAS_FILTER4;
  199. }
  200. void Geometry::setOcclusionFilterFunction8 (RTCFilterFunc8 filter, bool ispc)
  201. {
  202. if (parent->isStreamMode())
  203. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetOcclusionFilterFunctionN in stream mode");
  204. if (parent->isStatic() && parent->isBuild())
  205. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  206. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  207. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  208. parent->numIntersectionFilters8 -= occlusionFilter8 != nullptr;
  209. parent->numIntersectionFilters8 += filter != nullptr;
  210. occlusionFilter8 = filter;
  211. if (filter) hasOcclusionFilterMask |= HAS_FILTER8; else hasOcclusionFilterMask &= ~HAS_FILTER8;
  212. if (ispc ) ispcOcclusionFilterMask |= HAS_FILTER8; else ispcOcclusionFilterMask &= ~HAS_FILTER8;
  213. }
  214. void Geometry::setOcclusionFilterFunction16 (RTCFilterFunc16 filter, bool ispc)
  215. {
  216. if (parent->isStreamMode())
  217. throw_RTCError(RTC_INVALID_OPERATION,"you have to use rtcSetOcclusionFilterFunctionN in stream mode");
  218. if (parent->isStatic() && parent->isBuild())
  219. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  220. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  221. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  222. parent->numIntersectionFilters16 -= occlusionFilter16 != nullptr;
  223. parent->numIntersectionFilters16 += filter != nullptr;
  224. occlusionFilter16 = filter;
  225. if (filter) hasOcclusionFilterMask |= HAS_FILTER16; else hasOcclusionFilterMask &= ~HAS_FILTER16;
  226. if (ispc ) ispcOcclusionFilterMask |= HAS_FILTER16; else ispcOcclusionFilterMask &= ~HAS_FILTER16;
  227. }
  228. void Geometry::setOcclusionFilterFunctionN (RTCFilterFuncN filter)
  229. {
  230. if (!parent->isStreamMode())
  231. throw_RTCError(RTC_INVALID_OPERATION,"you can use rtcSetOcclusionFilterFunctionN only in stream mode");
  232. if (parent->isStatic() && parent->isBuild())
  233. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  234. if (type != TRIANGLE_MESH && type != QUAD_MESH && type != LINE_SEGMENTS && type != BEZIER_CURVES && type != SUBDIV_MESH)
  235. throw_RTCError(RTC_INVALID_OPERATION,"filter functions not supported for this geometry");
  236. parent->numIntersectionFiltersN -= occlusionFilterN != nullptr;
  237. parent->numIntersectionFiltersN += filter != nullptr;
  238. occlusionFilterN = filter;
  239. if (filter) hasOcclusionFilterMask |= HAS_FILTERN; else hasOcclusionFilterMask &= ~HAS_FILTERN;
  240. }
  241. void Geometry::interpolateN(const void* valid_i, const unsigned* primIDs, const float* u, const float* v, size_t numUVs,
  242. RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats)
  243. {
  244. if (numFloats > 256) throw_RTCError(RTC_INVALID_OPERATION,"maximally 256 floating point values can be interpolated per vertex");
  245. const int* valid = (const int*) valid_i;
  246. __aligned(64) float P_tmp[256];
  247. __aligned(64) float dPdu_tmp[256];
  248. __aligned(64) float dPdv_tmp[256];
  249. __aligned(64) float ddPdudu_tmp[256];
  250. __aligned(64) float ddPdvdv_tmp[256];
  251. __aligned(64) float ddPdudv_tmp[256];
  252. float* Pt = P ? P_tmp : nullptr;
  253. float* dPdut = nullptr, *dPdvt = nullptr;
  254. if (dPdu) { dPdut = dPdu_tmp; dPdvt = dPdv_tmp; }
  255. float* ddPdudut = nullptr, *ddPdvdvt = nullptr, *ddPdudvt = nullptr;
  256. if (ddPdudu) { ddPdudut = ddPdudu_tmp; ddPdvdvt = ddPdvdv_tmp; ddPdudvt = ddPdudv_tmp; }
  257. for (size_t i=0; i<numUVs; i++)
  258. {
  259. if (valid && !valid[i]) continue;
  260. interpolate(primIDs[i],u[i],v[i],buffer,Pt,dPdut,dPdvt,ddPdudut,ddPdvdvt,ddPdudvt,numFloats);
  261. if (likely(P)) {
  262. for (size_t j=0; j<numFloats; j++)
  263. P[j*numUVs+i] = Pt[j];
  264. }
  265. if (likely(dPdu))
  266. {
  267. for (size_t j=0; j<numFloats; j++) {
  268. dPdu[j*numUVs+i] = dPdut[j];
  269. dPdv[j*numUVs+i] = dPdvt[j];
  270. }
  271. }
  272. if (likely(ddPdudu))
  273. {
  274. for (size_t j=0; j<numFloats; j++) {
  275. ddPdudu[j*numUVs+i] = ddPdudut[j];
  276. ddPdvdv[j*numUVs+i] = ddPdvdvt[j];
  277. ddPdudv[j*numUVs+i] = ddPdudvt[j];
  278. }
  279. }
  280. }
  281. }
  282. }