subd_split.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  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 "render/camera.h"
  17. #include "render/mesh.h"
  18. #include "subd/subd_dice.h"
  19. #include "subd/subd_patch.h"
  20. #include "subd/subd_split.h"
  21. #include "util/util_math.h"
  22. #include "util/util_types.h"
  23. CCL_NAMESPACE_BEGIN
  24. /* DiagSplit */
  25. DiagSplit::DiagSplit(const SubdParams &params_) : params(params_)
  26. {
  27. }
  28. void DiagSplit::dispatch(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef)
  29. {
  30. subpatches_quad.push_back(sub);
  31. edgefactors_quad.push_back(ef);
  32. }
  33. float3 DiagSplit::to_world(Patch *patch, float2 uv)
  34. {
  35. float3 P;
  36. patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
  37. if (params.camera)
  38. P = transform_point(&params.objecttoworld, P);
  39. return P;
  40. }
  41. int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
  42. {
  43. float3 Plast = make_float3(0.0f, 0.0f, 0.0f);
  44. float Lsum = 0.0f;
  45. float Lmax = 0.0f;
  46. for (int i = 0; i < params.test_steps; i++) {
  47. float t = i / (float)(params.test_steps - 1);
  48. float3 P = to_world(patch, Pstart + t * (Pend - Pstart));
  49. if (i > 0) {
  50. float L;
  51. if (!params.camera) {
  52. L = len(P - Plast);
  53. }
  54. else {
  55. Camera *cam = params.camera;
  56. float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f);
  57. L = len(P - Plast) / pixel_width;
  58. }
  59. Lsum += L;
  60. Lmax = max(L, Lmax);
  61. }
  62. Plast = P;
  63. }
  64. int tmin = (int)ceil(Lsum / params.dicing_rate);
  65. int tmax = (int)ceil((params.test_steps - 1) * Lmax /
  66. params.dicing_rate); // XXX paper says N instead of N-1, seems wrong?
  67. if (tmax - tmin > params.split_threshold)
  68. return DSPLIT_NON_UNIFORM;
  69. return tmax;
  70. }
  71. void DiagSplit::partition_edge(
  72. Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t)
  73. {
  74. if (t == DSPLIT_NON_UNIFORM) {
  75. *P = (Pstart + Pend) * 0.5f;
  76. *t0 = T(patch, Pstart, *P);
  77. *t1 = T(patch, *P, Pend);
  78. }
  79. else {
  80. int I = (int)floor((float)t * 0.5f);
  81. *P = interp(Pstart, Pend, (t == 0) ? 0 : I / (float)t); /* XXX is t faces or verts */
  82. *t0 = I;
  83. *t1 = t - I;
  84. }
  85. }
  86. static void limit_edge_factors(const QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef, int max_t)
  87. {
  88. float2 P00 = sub.P00;
  89. float2 P01 = sub.P01;
  90. float2 P10 = sub.P10;
  91. float2 P11 = sub.P11;
  92. int tu0 = int(max_t * len(P10 - P00));
  93. int tu1 = int(max_t * len(P11 - P01));
  94. int tv0 = int(max_t * len(P01 - P00));
  95. int tv1 = int(max_t * len(P11 - P10));
  96. ef.tu0 = tu0 <= 1 ? 1 : min(ef.tu0, tu0);
  97. ef.tu1 = tu1 <= 1 ? 1 : min(ef.tu1, tu1);
  98. ef.tv0 = tv0 <= 1 ? 1 : min(ef.tv0, tv0);
  99. ef.tv1 = tv1 <= 1 ? 1 : min(ef.tv1, tv1);
  100. }
  101. void DiagSplit::split(QuadDice::SubPatch &sub, QuadDice::EdgeFactors &ef, int depth)
  102. {
  103. if (depth > 32) {
  104. /* We should never get here, but just in case end recursion safely. */
  105. ef.tu0 = 1;
  106. ef.tu1 = 1;
  107. ef.tv0 = 1;
  108. ef.tv1 = 1;
  109. dispatch(sub, ef);
  110. return;
  111. }
  112. bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM);
  113. bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM);
  114. /* Split subpatches such that the ratio of T for opposite edges doesn't
  115. * exceed 1.5, this reduces over tessellation for some patches
  116. */
  117. bool tmp_split_v = split_v;
  118. if (!split_u && min(ef.tu0, ef.tu1) > 8 && min(ef.tu0, ef.tu1) * 1.5f < max(ef.tu0, ef.tu1))
  119. split_v = true;
  120. if (!tmp_split_v && min(ef.tu0, ef.tu1) > 8 && min(ef.tv0, ef.tv1) * 1.5f < max(ef.tv0, ef.tv1))
  121. split_u = true;
  122. /* alternate axis */
  123. if (split_u && split_v) {
  124. split_u = depth % 2;
  125. }
  126. if (split_u) {
  127. /* partition edges */
  128. QuadDice::EdgeFactors ef0, ef1;
  129. float2 Pu0, Pu1;
  130. partition_edge(sub.patch, &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0);
  131. partition_edge(sub.patch, &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1);
  132. /* split */
  133. int tsplit = T(sub.patch, Pu0, Pu1);
  134. ef0.tv0 = ef.tv0;
  135. ef0.tv1 = tsplit;
  136. ef1.tv0 = tsplit;
  137. ef1.tv1 = ef.tv1;
  138. /* create subpatches */
  139. QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1};
  140. QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11};
  141. limit_edge_factors(sub0, ef0, 1 << params.max_level);
  142. limit_edge_factors(sub1, ef1, 1 << params.max_level);
  143. split(sub0, ef0, depth + 1);
  144. split(sub1, ef1, depth + 1);
  145. }
  146. else if (split_v) {
  147. /* partition edges */
  148. QuadDice::EdgeFactors ef0, ef1;
  149. float2 Pv0, Pv1;
  150. partition_edge(sub.patch, &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0);
  151. partition_edge(sub.patch, &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1);
  152. /* split */
  153. int tsplit = T(sub.patch, Pv0, Pv1);
  154. ef0.tu0 = ef.tu0;
  155. ef0.tu1 = tsplit;
  156. ef1.tu0 = tsplit;
  157. ef1.tu1 = ef.tu1;
  158. /* create subpatches */
  159. QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1};
  160. QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11};
  161. limit_edge_factors(sub0, ef0, 1 << params.max_level);
  162. limit_edge_factors(sub1, ef1, 1 << params.max_level);
  163. split(sub0, ef0, depth + 1);
  164. split(sub1, ef1, depth + 1);
  165. }
  166. else {
  167. dispatch(sub, ef);
  168. }
  169. }
  170. void DiagSplit::split_quad(Patch *patch, QuadDice::SubPatch *subpatch)
  171. {
  172. QuadDice::SubPatch sub_split;
  173. QuadDice::EdgeFactors ef_split;
  174. if (subpatch) {
  175. sub_split = *subpatch;
  176. }
  177. else {
  178. sub_split.patch = patch;
  179. sub_split.P00 = make_float2(0.0f, 0.0f);
  180. sub_split.P10 = make_float2(1.0f, 0.0f);
  181. sub_split.P01 = make_float2(0.0f, 1.0f);
  182. sub_split.P11 = make_float2(1.0f, 1.0f);
  183. }
  184. ef_split.tu0 = T(patch, sub_split.P00, sub_split.P10);
  185. ef_split.tu1 = T(patch, sub_split.P01, sub_split.P11);
  186. ef_split.tv0 = T(patch, sub_split.P00, sub_split.P01);
  187. ef_split.tv1 = T(patch, sub_split.P10, sub_split.P11);
  188. limit_edge_factors(sub_split, ef_split, 1 << params.max_level);
  189. split(sub_split, ef_split);
  190. QuadDice dice(params);
  191. for (size_t i = 0; i < subpatches_quad.size(); i++) {
  192. QuadDice::SubPatch &sub = subpatches_quad[i];
  193. QuadDice::EdgeFactors &ef = edgefactors_quad[i];
  194. ef.tu0 = max(ef.tu0, 1);
  195. ef.tu1 = max(ef.tu1, 1);
  196. ef.tv0 = max(ef.tv0, 1);
  197. ef.tv1 = max(ef.tv1, 1);
  198. dice.dice(sub, ef);
  199. }
  200. subpatches_quad.clear();
  201. edgefactors_quad.clear();
  202. }
  203. CCL_NAMESPACE_END