patch_eval.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "patch.h"
  5. #include "feature_adaptive_eval.h"
  6. namespace embree
  7. {
  8. namespace isa
  9. {
  10. template<typename Vertex, typename Vertex_t = Vertex>
  11. struct PatchEval
  12. {
  13. public:
  14. typedef PatchT<Vertex,Vertex_t> Patch;
  15. typedef typename Patch::Ref Ref;
  16. typedef CatmullClarkPatchT<Vertex,Vertex_t> CatmullClarkPatch;
  17. PatchEval (SharedLazyTessellationCache::CacheEntry& entry, size_t commitCounter,
  18. const HalfEdge* edge, const char* vertices, size_t stride, const float u, const float v,
  19. Vertex* P, Vertex* dPdu, Vertex* dPdv, Vertex* ddPdudu, Vertex* ddPdvdv, Vertex* ddPdudv)
  20. : P(P), dPdu(dPdu), dPdv(dPdv), ddPdudu(ddPdudu), ddPdvdv(ddPdvdv), ddPdudv(ddPdudv)
  21. {
  22. /* conservative time for the very first allocation */
  23. auto time = SharedLazyTessellationCache::sharedLazyTessellationCache.getTime(commitCounter);
  24. Ref patch = SharedLazyTessellationCache::lookup(entry,commitCounter,[&] () {
  25. auto alloc = [&](size_t bytes) { return SharedLazyTessellationCache::malloc(bytes); };
  26. return Patch::create(alloc,edge,vertices,stride);
  27. },true);
  28. auto curTime = SharedLazyTessellationCache::sharedLazyTessellationCache.getTime(commitCounter);
  29. const bool allAllocationsValid = SharedLazyTessellationCache::validTime(time,curTime);
  30. if (patch && allAllocationsValid && eval(patch,u,v,1.0f,0)) {
  31. SharedLazyTessellationCache::unlock();
  32. return;
  33. }
  34. SharedLazyTessellationCache::unlock();
  35. FeatureAdaptiveEval<Vertex,Vertex_t>(edge,vertices,stride,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv);
  36. PATCH_DEBUG_SUBDIVISION(edge,c,-1,-1);
  37. }
  38. __forceinline bool eval_quad(const typename Patch::SubdividedQuadPatch* This, const float u, const float v, const float dscale, const size_t depth)
  39. {
  40. if (v < 0.5f) {
  41. if (u < 0.5f) return eval(This->child[0],2.0f*u,2.0f*v,2.0f*dscale,depth+1);
  42. else return eval(This->child[1],2.0f*u-1.0f,2.0f*v,2.0f*dscale,depth+1);
  43. } else {
  44. if (u > 0.5f) return eval(This->child[2],2.0f*u-1.0f,2.0f*v-1.0f,2.0f*dscale,depth+1);
  45. else return eval(This->child[3],2.0f*u,2.0f*v-1.0f,2.0f*dscale,depth+1);
  46. }
  47. }
  48. bool eval_general(const typename Patch::SubdividedGeneralPatch* This, const float U, const float V, const size_t depth)
  49. {
  50. const unsigned l = (unsigned) floor(0.5f*U); const float u = 2.0f*frac(0.5f*U)-0.5f;
  51. const unsigned h = (unsigned) floor(0.5f*V); const float v = 2.0f*frac(0.5f*V)-0.5f;
  52. const unsigned i = 4*h+l; assert(i<This->N);
  53. return eval(This->child[i],u,v,1.0f,depth+1);
  54. }
  55. bool eval(Ref This, const float& u, const float& v, const float dscale, const size_t depth)
  56. {
  57. if (!This) return false;
  58. //PRINT(depth);
  59. //PRINT2(u,v);
  60. switch (This.type())
  61. {
  62. case Patch::BILINEAR_PATCH: {
  63. //PRINT("bilinear");
  64. ((typename Patch::BilinearPatch*)This.object())->patch.eval(u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale);
  65. PATCH_DEBUG_SUBDIVISION(This,-1,c,c);
  66. return true;
  67. }
  68. case Patch::BSPLINE_PATCH: {
  69. //PRINT("bspline");
  70. ((typename Patch::BSplinePatch*)This.object())->patch.eval(u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale);
  71. PATCH_DEBUG_SUBDIVISION(This,-1,c,-1);
  72. return true;
  73. }
  74. case Patch::BEZIER_PATCH: {
  75. //PRINT("bezier");
  76. ((typename Patch::BezierPatch*)This.object())->patch.eval(u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale);
  77. PATCH_DEBUG_SUBDIVISION(This,-1,c,-1);
  78. return true;
  79. }
  80. case Patch::GREGORY_PATCH: {
  81. //PRINT("gregory");
  82. ((typename Patch::GregoryPatch*)This.object())->patch.eval(u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale);
  83. PATCH_DEBUG_SUBDIVISION(This,-1,-1,c);
  84. return true;
  85. }
  86. case Patch::SUBDIVIDED_QUAD_PATCH: {
  87. //PRINT("subdivided quad");
  88. return eval_quad(((typename Patch::SubdividedQuadPatch*)This.object()),u,v,dscale,depth);
  89. }
  90. case Patch::SUBDIVIDED_GENERAL_PATCH: {
  91. //PRINT("general_patch");
  92. assert(dscale == 1.0f);
  93. return eval_general(((typename Patch::SubdividedGeneralPatch*)This.object()),u,v,depth);
  94. }
  95. case Patch::EVAL_PATCH: {
  96. //PRINT("eval_patch");
  97. CatmullClarkPatch patch; patch.deserialize(This.object());
  98. FeatureAdaptiveEval<Vertex,Vertex_t>(patch,u,v,dscale,depth,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv);
  99. return true;
  100. }
  101. default:
  102. assert(false);
  103. return false;
  104. }
  105. }
  106. private:
  107. Vertex* const P;
  108. Vertex* const dPdu;
  109. Vertex* const dPdv;
  110. Vertex* const ddPdudu;
  111. Vertex* const ddPdvdv;
  112. Vertex* const ddPdudv;
  113. };
  114. }
  115. }