subdivpatch1base.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 "subdivpatch1base.h"
  17. namespace embree
  18. {
  19. SubdivPatch1Base::SubdivPatch1Base (const unsigned int gID,
  20. const unsigned int pID,
  21. const unsigned int subPatch,
  22. const SubdivMesh *const mesh,
  23. const size_t time,
  24. const Vec2f uv[4],
  25. const float edge_level[4],
  26. const int subdiv[4],
  27. const int simd_width)
  28. : flags(0), type(INVALID_PATCH), geom(gID), prim(pID), time_(unsigned(time))
  29. {
  30. static_assert(sizeof(SubdivPatch1Base) == 5 * 64, "SubdivPatch1Base has wrong size");
  31. const HalfEdge* edge = mesh->getHalfEdge(0,pID);
  32. if (edge->patch_type == HalfEdge::BILINEAR_PATCH)
  33. {
  34. type = BILINEAR_PATCH;
  35. new (patch_v) BilinearPatch3fa(edge,mesh->getVertexBuffer(time));
  36. }
  37. else if (edge->patch_type == HalfEdge::REGULAR_QUAD_PATCH)
  38. {
  39. #if PATCH_USE_BEZIER_PATCH
  40. type = BEZIER_PATCH;
  41. new (patch_v) BezierPatch3fa(BSplinePatch3fa(CatmullClarkPatch3fa(edge,mesh->getVertexBuffer(time))));
  42. #else
  43. type = BSPLINE_PATCH;
  44. new (patch_v) BSplinePatch3fa(CatmullClarkPatch3fa(edge,mesh->getVertexBuffer(time))); // FIXME: init BSpline directly from half edge structure
  45. #endif
  46. }
  47. #if PATCH_USE_GREGORY == 2
  48. else if (edge->patch_type == HalfEdge::IRREGULAR_QUAD_PATCH)
  49. {
  50. type = GREGORY_PATCH;
  51. new (patch_v) DenseGregoryPatch3fa(GregoryPatch3fa(CatmullClarkPatch3fa(edge,mesh->getVertexBuffer(time))));
  52. }
  53. #endif
  54. else
  55. {
  56. type = EVAL_PATCH;
  57. set_edge(mesh->getHalfEdge(0,pID));
  58. set_subPatch(subPatch);
  59. }
  60. for (size_t i=0; i<4; i++) {
  61. u[i] = (unsigned short)clamp(uv[i].x * 32768.0f, 0.0f, 32768.0f);
  62. v[i] = (unsigned short)clamp(uv[i].y * 32768.0f, 0.0f, 32768.0f);
  63. }
  64. updateEdgeLevels(edge_level,subdiv,mesh,simd_width);
  65. }
  66. void SubdivPatch1Base::computeEdgeLevels(const float edge_level[4], const int subdiv[4], float level[4])
  67. {
  68. /* init discrete edge tessellation levels and grid resolution */
  69. assert( edge_level[0] >= 0.0f );
  70. assert( edge_level[1] >= 0.0f );
  71. assert( edge_level[2] >= 0.0f );
  72. assert( edge_level[3] >= 0.0f );
  73. level[0] = max(ceilf(adjustTessellationLevel(edge_level[0],subdiv[0])),1.0f);
  74. level[1] = max(ceilf(adjustTessellationLevel(edge_level[1],subdiv[1])),1.0f);
  75. level[2] = max(ceilf(adjustTessellationLevel(edge_level[2],subdiv[2])),1.0f);
  76. level[3] = max(ceilf(adjustTessellationLevel(edge_level[3],subdiv[3])),1.0f);
  77. }
  78. Vec2i SubdivPatch1Base::computeGridSize(const float level[4])
  79. {
  80. return Vec2i((int)max(level[0],level[2])+1,
  81. (int)max(level[1],level[3])+1);
  82. }
  83. bool SubdivPatch1Base::updateEdgeLevels(const float edge_level[4], const int subdiv[4], const SubdivMesh *const mesh, const int simd_width)
  84. {
  85. /* calculate edge levels */
  86. float new_level[4];
  87. computeEdgeLevels(edge_level,subdiv,new_level);
  88. /* calculate if tessellation pattern changed */
  89. bool grid_changed = false;
  90. for (size_t i=0; i<4; i++) {
  91. grid_changed |= (int)new_level[i] != (int)level[i];
  92. level[i] = new_level[i];
  93. }
  94. /* compute grid resolution */
  95. Vec2i res = computeGridSize(level);
  96. grid_u_res = res.x; grid_v_res = res.y;
  97. grid_size_simd_blocks = ((grid_u_res*grid_v_res+simd_width-1)&(-simd_width)) / simd_width;
  98. /* need stiching? */
  99. flags &= ~TRANSITION_PATCH;
  100. const int int_edge_points0 = (int)level[0] + 1;
  101. const int int_edge_points1 = (int)level[1] + 1;
  102. const int int_edge_points2 = (int)level[2] + 1;
  103. const int int_edge_points3 = (int)level[3] + 1;
  104. if (int_edge_points0 < (int)grid_u_res ||
  105. int_edge_points2 < (int)grid_u_res ||
  106. int_edge_points1 < (int)grid_v_res ||
  107. int_edge_points3 < (int)grid_v_res) {
  108. flags |= TRANSITION_PATCH;
  109. }
  110. return grid_changed;
  111. }
  112. }