patch_eval.h 6.3 KB

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