void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth) { if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pu0, Pu1; partition_edge(sub.patch, &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0); partition_edge(sub.patch, &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1); /* split */ int tsplit = T(sub.patch, Pu0, Pu1); ef0.tv0 = ef.tv0; ef0.tv1 = tsplit; ef1.tv0 = tsplit; ef1.tv1 = ef.tv1; /* create subpatches */ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1}; QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11}; split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pv0, Pv1; partition_edge(sub.patch, &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0); partition_edge(sub.patch, &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1); /* split */ int tsplit = T(sub.patch, Pv0, Pv1); ef0.tu0 = ef.tu0; ef0.tu1 = tsplit; ef1.tu0 = tsplit; ef1.tu1 = ef.tu1; /* create subpatches */ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1}; QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11}; split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else dispatch(sub, ef); }
void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth) { 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)); if(depth == 0) { dispatch(sub, ef); return; } if(ef.tu == DSPLIT_NON_UNIFORM) { /* partition edges */ TriangleDice::EdgeFactors ef0, ef1; float2 Psplit; partition_edge(sub.patch, &Psplit, &ef1.tu, &ef0.tu, sub.Pv, sub.Pw, ef.tu); /* split */ int tsplit = T(sub.patch, sub.Pu, Psplit); ef0.tv = ef.tv; ef0.tw = tsplit; ef1.tv = tsplit; ef1.tw = ef.tw; /* create subpatches */ TriangleDice::SubPatch sub0 = {sub.patch, sub.Pu, Psplit, sub.Pw}; TriangleDice::SubPatch sub1 = {sub.patch, sub.Pu, sub.Pv, Psplit}; split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else if(ef.tv == DSPLIT_NON_UNIFORM) { /* partition edges */ TriangleDice::EdgeFactors ef0, ef1; float2 Psplit; partition_edge(sub.patch, &Psplit, &ef1.tu, &ef0.tu, sub.Pw, sub.Pu, ef.tv); /* split */ int tsplit = T(sub.patch, sub.Pv, Psplit); ef0.tv = ef.tw; ef0.tw = tsplit; ef1.tv = tsplit; ef1.tw = ef.tu; /* create subpatches */ TriangleDice::SubPatch sub0 = {sub.patch, sub.Pv, Psplit, sub.Pu}; TriangleDice::SubPatch sub1 = {sub.patch, sub.Pv, sub.Pw, Psplit}; split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else if(ef.tw == DSPLIT_NON_UNIFORM) { /* partition edges */ TriangleDice::EdgeFactors ef0, ef1; float2 Psplit; partition_edge(sub.patch, &Psplit, &ef1.tu, &ef0.tu, sub.Pu, sub.Pv, ef.tw); /* split */ int tsplit = T(sub.patch, sub.Pw, Psplit); ef0.tv = ef.tu; ef0.tw = tsplit; ef1.tv = tsplit; ef1.tw = ef.tv; /* create subpatches */ TriangleDice::SubPatch sub0 = {sub.patch, sub.Pw, Psplit, sub.Pv}; TriangleDice::SubPatch sub1 = {sub.patch, sub.Pw, sub.Pu, Psplit}; split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else dispatch(sub, ef); }
void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth) { 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); /* Split subpatches such that the ratio of T for opposite edges doesn't * exceed 1.5, this reduces over tessellation for some patches */ bool tmp_split_v = split_v; if(!split_u && min(ef.tu0, ef.tu1) > 8 && min(ef.tu0, ef.tu1)*1.5f < max(ef.tu0, ef.tu1)) split_v = true; if(!tmp_split_v && min(ef.tu0, ef.tu1) > 8 && min(ef.tv0, ef.tv1)*1.5f < max(ef.tv0, ef.tv1)) split_u = true; /* alternate axis */ if(split_u && split_v) { split_u = depth % 2; } if(split_u) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pu0, Pu1; partition_edge(sub.patch, &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0); partition_edge(sub.patch, &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1); /* split */ int tsplit = T(sub.patch, Pu0, Pu1); ef0.tv0 = ef.tv0; ef0.tv1 = tsplit; ef1.tv0 = tsplit; ef1.tv1 = ef.tv1; /* create subpatches */ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1}; QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11}; limit_edge_factors(sub0, ef0, 1 << params.max_level); limit_edge_factors(sub1, ef1, 1 << params.max_level); split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else if(split_v) { /* partition edges */ QuadDice::EdgeFactors ef0, ef1; float2 Pv0, Pv1; partition_edge(sub.patch, &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0); partition_edge(sub.patch, &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1); /* split */ int tsplit = T(sub.patch, Pv0, Pv1); ef0.tu0 = ef.tu0; ef0.tu1 = tsplit; ef1.tu0 = tsplit; ef1.tu1 = ef.tu1; /* create subpatches */ QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1}; QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11}; limit_edge_factors(sub0, ef0, 1 << params.max_level); limit_edge_factors(sub1, ef1, 1 << params.max_level); split(sub0, ef0, depth+1); split(sub1, ef1, depth+1); } else { dispatch(sub, ef); } }