示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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);
	}
}