geometry.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include "geometry.h"
  4. #include "scene.h"
  5. namespace embree
  6. {
  7. const char* Geometry::gtype_names[Geometry::GTY_END] =
  8. {
  9. "flat_linear_curve",
  10. "round_linear_curve",
  11. "oriented_linear_curve",
  12. "",
  13. "flat_bezier_curve",
  14. "round_bezier_curve",
  15. "oriented_bezier_curve",
  16. "",
  17. "flat_bspline_curve",
  18. "round_bspline_curve",
  19. "oriented_bspline_curve",
  20. "",
  21. "flat_hermite_curve",
  22. "round_hermite_curve",
  23. "oriented_hermite_curve",
  24. "",
  25. "flat_catmull_rom_curve",
  26. "round_catmull_rom_curve",
  27. "oriented_catmull_rom_curve",
  28. "",
  29. "triangles",
  30. "quads",
  31. "grid",
  32. "subdivs",
  33. "",
  34. "sphere",
  35. "disc",
  36. "oriented_disc",
  37. "",
  38. "usergeom",
  39. "instance_cheap",
  40. "instance_expensive",
  41. };
  42. Geometry::Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps)
  43. : device(device), userPtr(nullptr),
  44. numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), time_range(0.0f,1.0f),
  45. mask(-1),
  46. gtype(gtype),
  47. gsubtype(GTY_SUBTYPE_DEFAULT),
  48. quality(RTC_BUILD_QUALITY_MEDIUM),
  49. state((unsigned)State::MODIFIED),
  50. enabled(true),
  51. intersectionFilterN(nullptr), occlusionFilterN(nullptr), pointQueryFunc(nullptr)
  52. {
  53. device->refInc();
  54. }
  55. Geometry::~Geometry()
  56. {
  57. device->refDec();
  58. }
  59. void Geometry::setNumPrimitives(unsigned int numPrimitives_in)
  60. {
  61. if (numPrimitives_in == numPrimitives) return;
  62. numPrimitives = numPrimitives_in;
  63. Geometry::update();
  64. }
  65. void Geometry::setNumTimeSteps (unsigned int numTimeSteps_in)
  66. {
  67. if (numTimeSteps_in == numTimeSteps) {
  68. return;
  69. }
  70. numTimeSteps = numTimeSteps_in;
  71. fnumTimeSegments = float(numTimeSteps_in-1);
  72. Geometry::update();
  73. }
  74. void Geometry::setTimeRange (const BBox1f range)
  75. {
  76. time_range = range;
  77. Geometry::update();
  78. }
  79. void Geometry::update()
  80. {
  81. ++modCounter_; // FIXME: required?
  82. state = (unsigned)State::MODIFIED;
  83. }
  84. void Geometry::commit()
  85. {
  86. ++modCounter_;
  87. state = (unsigned)State::COMMITTED;
  88. }
  89. void Geometry::preCommit()
  90. {
  91. if (State::MODIFIED == (State)state)
  92. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"geometry not committed");
  93. }
  94. void Geometry::postCommit()
  95. {
  96. }
  97. void Geometry::enable ()
  98. {
  99. if (isEnabled())
  100. return;
  101. enabled = true;
  102. ++modCounter_;
  103. }
  104. void Geometry::disable ()
  105. {
  106. if (isDisabled())
  107. return;
  108. enabled = false;
  109. ++modCounter_;
  110. }
  111. void Geometry::setUserData (void* ptr)
  112. {
  113. userPtr = ptr;
  114. }
  115. void Geometry::setIntersectionFilterFunctionN (RTCFilterFunctionN filter)
  116. {
  117. if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
  118. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
  119. intersectionFilterN = filter;
  120. }
  121. void Geometry::setOcclusionFilterFunctionN (RTCFilterFunctionN filter)
  122. {
  123. if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
  124. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
  125. occlusionFilterN = filter;
  126. }
  127. void Geometry::setPointQueryFunction (RTCPointQueryFunction func)
  128. {
  129. pointQueryFunc = func;
  130. }
  131. void Geometry::interpolateN(const RTCInterpolateNArguments* const args)
  132. {
  133. const void* valid_i = args->valid;
  134. const unsigned* primIDs = args->primIDs;
  135. const float* u = args->u;
  136. const float* v = args->v;
  137. unsigned int N = args->N;
  138. RTCBufferType bufferType = args->bufferType;
  139. unsigned int bufferSlot = args->bufferSlot;
  140. float* P = args->P;
  141. float* dPdu = args->dPdu;
  142. float* dPdv = args->dPdv;
  143. float* ddPdudu = args->ddPdudu;
  144. float* ddPdvdv = args->ddPdvdv;
  145. float* ddPdudv = args->ddPdudv;
  146. unsigned int valueCount = args->valueCount;
  147. if (valueCount > 256) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"maximally 256 floating point values can be interpolated per vertex");
  148. const int* valid = (const int*) valid_i;
  149. __aligned(64) float P_tmp[256];
  150. __aligned(64) float dPdu_tmp[256];
  151. __aligned(64) float dPdv_tmp[256];
  152. __aligned(64) float ddPdudu_tmp[256];
  153. __aligned(64) float ddPdvdv_tmp[256];
  154. __aligned(64) float ddPdudv_tmp[256];
  155. float* Pt = P ? P_tmp : nullptr;
  156. float* dPdut = nullptr, *dPdvt = nullptr;
  157. if (dPdu) { dPdut = dPdu_tmp; dPdvt = dPdv_tmp; }
  158. float* ddPdudut = nullptr, *ddPdvdvt = nullptr, *ddPdudvt = nullptr;
  159. if (ddPdudu) { ddPdudut = ddPdudu_tmp; ddPdvdvt = ddPdvdv_tmp; ddPdudvt = ddPdudv_tmp; }
  160. for (unsigned int i=0; i<N; i++)
  161. {
  162. if (valid && !valid[i]) continue;
  163. RTCInterpolateArguments iargs;
  164. iargs.primID = primIDs[i];
  165. iargs.u = u[i];
  166. iargs.v = v[i];
  167. iargs.bufferType = bufferType;
  168. iargs.bufferSlot = bufferSlot;
  169. iargs.P = Pt;
  170. iargs.dPdu = dPdut;
  171. iargs.dPdv = dPdvt;
  172. iargs.ddPdudu = ddPdudut;
  173. iargs.ddPdvdv = ddPdvdvt;
  174. iargs.ddPdudv = ddPdudvt;
  175. iargs.valueCount = valueCount;
  176. interpolate(&iargs);
  177. if (likely(P)) {
  178. for (unsigned int j=0; j<valueCount; j++)
  179. P[j*N+i] = Pt[j];
  180. }
  181. if (likely(dPdu))
  182. {
  183. for (unsigned int j=0; j<valueCount; j++) {
  184. dPdu[j*N+i] = dPdut[j];
  185. dPdv[j*N+i] = dPdvt[j];
  186. }
  187. }
  188. if (likely(ddPdudu))
  189. {
  190. for (unsigned int j=0; j<valueCount; j++) {
  191. ddPdudu[j*N+i] = ddPdudut[j];
  192. ddPdvdv[j*N+i] = ddPdvdvt[j];
  193. ddPdudv[j*N+i] = ddPdudvt[j];
  194. }
  195. }
  196. }
  197. }
  198. bool Geometry::pointQuery(PointQuery* query, PointQueryContext* context)
  199. {
  200. assert(context->primID < size());
  201. RTCPointQueryFunctionArguments args;
  202. args.query = (RTCPointQuery*)context->query_ws;
  203. args.userPtr = context->userPtr;
  204. args.primID = context->primID;
  205. args.geomID = context->geomID;
  206. args.context = context->userContext;
  207. args.similarityScale = context->similarityScale;
  208. bool update = false;
  209. if(context->func) update |= context->func(&args);
  210. if(pointQueryFunc) update |= pointQueryFunc(&args);
  211. if (update && context->userContext->instStackSize > 0)
  212. {
  213. // update point query
  214. if (context->query_type == POINT_QUERY_TYPE_AABB) {
  215. context->updateAABB();
  216. } else {
  217. assert(context->similarityScale > 0.f);
  218. query->radius = context->query_ws->radius * context->similarityScale;
  219. }
  220. }
  221. return update;
  222. }
  223. }