diff options
Diffstat (limited to 'intern/cycles/subd')
-rw-r--r-- | intern/cycles/subd/subd_dice.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/subd/subd_dice.h | 1 | ||||
-rw-r--r-- | intern/cycles/subd/subd_split.cpp | 54 | ||||
-rw-r--r-- | intern/cycles/subd/subd_split.h | 2 |
4 files changed, 54 insertions, 8 deletions
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index 44bab066dde..301f30c8d95 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -305,7 +305,12 @@ void QuadDice::dice(SubPatch& sub, EdgeFactors& ef) int Mu = max(ef.tu0, ef.tu1); int Mv = max(ef.tv0, ef.tv1); +#if 0 /* Doesnt work very well, especially at grazing angles. */ float S = scale_factor(sub, ef, Mu, Mv); +#else + float S = 1.0f; +#endif + Mu = max((int)ceil(S*Mu), 2); // XXX handle 0 & 1? Mv = max((int)ceil(S*Mv), 2); // XXX handle 0 & 1? diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h index b7e61748779..2b11e4b0bf5 100644 --- a/intern/cycles/subd/subd_dice.h +++ b/intern/cycles/subd/subd_dice.h @@ -41,6 +41,7 @@ struct SubdParams { int split_threshold; float dicing_rate; Camera *camera; + Transform objecttoworld; SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true, bool ptex_ = false) { diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp index df4d451e8eb..095eefeab22 100644 --- a/intern/cycles/subd/subd_split.cpp +++ b/intern/cycles/subd/subd_split.cpp @@ -46,13 +46,13 @@ void DiagSplit::dispatch(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& edgefactors_triangle.push_back(ef); } -float3 DiagSplit::project(Patch *patch, float2 uv) +float3 DiagSplit::to_world(Patch *patch, float2 uv) { float3 P; patch->eval(&P, NULL, NULL, uv.x, uv.y); if(params.camera) - P = transform_perspective(¶ms.camera->worldtoraster, P); + P = transform_point(¶ms.objecttoworld, P); return P; } @@ -66,10 +66,21 @@ int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend) for(int i = 0; i < params.test_steps; i++) { float t = i/(float)(params.test_steps-1); - float3 P = project(patch, Pstart + t*(Pend - Pstart)); + float3 P = to_world(patch, Pstart + t*(Pend - Pstart)); if(i > 0) { - float L = len(P - Plast); + float L; + + if(!params.camera) { + L = len(P - Plast); + } + else { + Camera* cam = params.camera; + + float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f); + L = len(P - Plast) / pixel_width; + } + Lsum += L; Lmax = max(L, Lmax); } @@ -103,6 +114,16 @@ void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2 void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth) { + if(depth > 32) { + /* We should never get here, but just in case end recursion safely. */ + ef.tu = 1; + ef.tv = 1; + ef.tw = 1; + + dispatch(sub, ef); + return; + } + assert(ef.tu == T(sub.patch, sub.Pv, sub.Pw)); assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu)); assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv)); @@ -187,7 +208,25 @@ void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth) { - if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) { + if(depth > 32) { + /* We should never get here, but just in case end recursion safely. */ + ef.tu0 = 1; + ef.tu1 = 1; + ef.tv0 = 1; + ef.tv1 = 1; + + dispatch(sub, ef); + return; + } + + bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM); + bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM); + + if(split_u && split_v) { + split_u = depth % 2; + } + + if(split_u) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pu0, Pu1; @@ -212,7 +251,7 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } - else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) { + else if(split_v) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pv0, Pv1; @@ -237,8 +276,9 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } - else + else { dispatch(sub, ef); + } } void DiagSplit::split_triangle(Patch *patch) diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h index df4935ee624..f04c51dedfe 100644 --- a/intern/cycles/subd/subd_split.h +++ b/intern/cycles/subd/subd_split.h @@ -45,7 +45,7 @@ public: DiagSplit(const SubdParams& params); - float3 project(Patch *patch, float2 uv); + float3 to_world(Patch *patch, float2 uv); int T(Patch *patch, float2 Pstart, float2 Pend); void partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t); |