in d3d/archive/images/d3d11/tessellator.cpp [791:961]
void CHWTessellator::QuadGenerateConnectivity( const PROCESSED_TESS_FACTORS_QUAD& processedTessFactors )
{
// Generate primitives for all the concentric rings, one side at a time for each ring
static const int startRing = 1;
int numPointRowsToCenter[QUAD_AXES] = {((processedTessFactors.numPointsForInsideTessFactor[U]+1) >> 1),
((processedTessFactors.numPointsForInsideTessFactor[V]+1) >> 1)}; // +1 is so even tess includes the center point
int numRings = min(numPointRowsToCenter[U],numPointRowsToCenter[V]);
int degeneratePointRing[QUAD_AXES] = { // Even partitioning causes degenerate row of points,
// which results in exceptions to the point ordering conventions
// when travelling around the rings counterclockwise.
(TESSELLATOR_PARITY_EVEN == processedTessFactors.insideTessFactorParity[V]) ? numPointRowsToCenter[V] - 1 : -1,
(TESSELLATOR_PARITY_EVEN == processedTessFactors.insideTessFactorParity[U]) ? numPointRowsToCenter[U] - 1 : -1 };
const TESS_FACTOR_CONTEXT* outsideTessFactorCtx[QUAD_EDGES] = {&processedTessFactors.outsideTessFactorCtx[Ueq0],
&processedTessFactors.outsideTessFactorCtx[Veq0],
&processedTessFactors.outsideTessFactorCtx[Ueq1],
&processedTessFactors.outsideTessFactorCtx[Veq1]};
TESSELLATOR_PARITY outsideTessFactorParity[QUAD_EDGES] = {processedTessFactors.outsideTessFactorParity[Ueq0],
processedTessFactors.outsideTessFactorParity[Veq0],
processedTessFactors.outsideTessFactorParity[Ueq1],
processedTessFactors.outsideTessFactorParity[Veq1]};
int numPointsForOutsideEdge[QUAD_EDGES] = {processedTessFactors.numPointsForOutsideEdge[Ueq0],
processedTessFactors.numPointsForOutsideEdge[Veq0],
processedTessFactors.numPointsForOutsideEdge[Ueq1],
processedTessFactors.numPointsForOutsideEdge[Veq1]};
int insideEdgePointBaseOffset = processedTessFactors.insideEdgePointBaseOffset;
int outsideEdgePointBaseOffset = 0;
int edge;
for(int ring = startRing; ring < numRings; ring++)
{
int numPointsForInsideEdge[QUAD_AXES] = {processedTessFactors.numPointsForInsideTessFactor[U] - 2*ring,
processedTessFactors.numPointsForInsideTessFactor[V] - 2*ring};
int edge0InsidePointBaseOffset = insideEdgePointBaseOffset;
int edge0OutsidePointBaseOffset = outsideEdgePointBaseOffset;
for(edge = 0; edge < QUAD_EDGES; edge++ )
{
int parity = (edge+1)&0x1;
int numTriangles = numPointsForInsideEdge[parity] + numPointsForOutsideEdge[edge] - 2;
int insideBaseOffset;
int outsideBaseOffset;
if( edge == 3 ) // We need to patch the indexing so Stitch() can think it sees
// 2 sequentially increasing rows of points, even though we have wrapped around
// to the end of the inner and outer ring's points, so the last point is really
// the first point for the ring.
// We make it so that when Stitch() calls AddIndex(), that function
// will do any necessary index adjustment.
{
if( ring == degeneratePointRing[parity] )
{
m_IndexPatchContext2.baseIndexToInvert = insideEdgePointBaseOffset + 1;
m_IndexPatchContext2.cornerCaseBadValue = outsideEdgePointBaseOffset + numPointsForOutsideEdge[edge] - 1;
m_IndexPatchContext2.cornerCaseReplacementValue = edge0OutsidePointBaseOffset;
m_IndexPatchContext2.indexInversionEndPoint = (m_IndexPatchContext2.baseIndexToInvert << 1) - 1;
insideBaseOffset = m_IndexPatchContext2.baseIndexToInvert;
outsideBaseOffset = outsideEdgePointBaseOffset;
SetUsingPatchedIndices2(true);
}
else
{
m_IndexPatchContext.insidePointIndexDeltaToRealValue = insideEdgePointBaseOffset;
m_IndexPatchContext.insidePointIndexBadValue = numPointsForInsideEdge[parity] - 1;
m_IndexPatchContext.insidePointIndexReplacementValue = edge0InsidePointBaseOffset;
m_IndexPatchContext.outsidePointIndexPatchBase = m_IndexPatchContext.insidePointIndexBadValue+1; // past inside patched index range
m_IndexPatchContext.outsidePointIndexDeltaToRealValue = outsideEdgePointBaseOffset
- m_IndexPatchContext.outsidePointIndexPatchBase;
m_IndexPatchContext.outsidePointIndexBadValue = m_IndexPatchContext.outsidePointIndexPatchBase
+ numPointsForOutsideEdge[edge] - 1;
m_IndexPatchContext.outsidePointIndexReplacementValue = edge0OutsidePointBaseOffset;
insideBaseOffset = 0;
outsideBaseOffset = m_IndexPatchContext.outsidePointIndexPatchBase;
SetUsingPatchedIndices(true);
}
}
else if( (edge == 2) && (ring == degeneratePointRing[parity]) )
{
m_IndexPatchContext2.baseIndexToInvert = insideEdgePointBaseOffset;
m_IndexPatchContext2.cornerCaseBadValue = -1; // unused
m_IndexPatchContext2.cornerCaseReplacementValue = -1; // unused
m_IndexPatchContext2.indexInversionEndPoint = m_IndexPatchContext2.baseIndexToInvert << 1;
insideBaseOffset = m_IndexPatchContext2.baseIndexToInvert;
outsideBaseOffset = outsideEdgePointBaseOffset;
SetUsingPatchedIndices2(true);
}
else
{
insideBaseOffset = insideEdgePointBaseOffset;
outsideBaseOffset = outsideEdgePointBaseOffset;
}
if( ring == startRing )
{
StitchTransition(/*baseIndexOffset: */m_NumIndices,
insideBaseOffset,processedTessFactors.insideTessFactorCtx[parity].numHalfTessFactorPoints,processedTessFactors.insideTessFactorParity[parity],
outsideBaseOffset,outsideTessFactorCtx[edge]->numHalfTessFactorPoints,outsideTessFactorParity[edge]);
}
else
{
StitchRegular(/*bTrapezoid*/true, DIAGONALS_MIRRORED,
/*baseIndexOffset: */m_NumIndices,
numPointsForInsideEdge[parity],
insideBaseOffset,outsideBaseOffset);
}
SetUsingPatchedIndices(false);
SetUsingPatchedIndices2(false);
m_NumIndices += numTriangles*3;
outsideEdgePointBaseOffset += numPointsForOutsideEdge[edge] - 1;
if( (edge == 2) && (ring == degeneratePointRing[parity]) )
{
insideEdgePointBaseOffset -= numPointsForInsideEdge[parity] - 1;
}
else
{
insideEdgePointBaseOffset += numPointsForInsideEdge[parity] - 1;
}
numPointsForOutsideEdge[edge] = numPointsForInsideEdge[parity];
}
if( startRing == ring )
{
for(edge = 0; edge < QUAD_EDGES; edge++ )
{
outsideTessFactorCtx[edge] = &processedTessFactors.insideTessFactorCtx[edge&1];
outsideTessFactorParity[edge] = processedTessFactors.insideTessFactorParity[edge&1];
}
}
}
// Triangulate center - a row of quads if odd
// This triangulation may be producing diagonals that are asymmetric about
// the center of the patch in this region.
if( (processedTessFactors.numPointsForInsideTessFactor[U] > processedTessFactors.numPointsForInsideTessFactor[V]) &&
(TESSELLATOR_PARITY_ODD == processedTessFactors.insideTessFactorParity[V] ) )
{
SetUsingPatchedIndices2(true);
int stripNumQuads = (((processedTessFactors.numPointsForInsideTessFactor[U]>>1) - (processedTessFactors.numPointsForInsideTessFactor[V]>>1))<<1)+
((TESSELLATOR_PARITY_EVEN == processedTessFactors.insideTessFactorParity[U] ) ? 2 : 1);
m_IndexPatchContext2.baseIndexToInvert = outsideEdgePointBaseOffset + stripNumQuads + 2;
m_IndexPatchContext2.cornerCaseBadValue = m_IndexPatchContext2.baseIndexToInvert;
m_IndexPatchContext2.cornerCaseReplacementValue = outsideEdgePointBaseOffset;
m_IndexPatchContext2.indexInversionEndPoint = m_IndexPatchContext2.baseIndexToInvert +
m_IndexPatchContext2.baseIndexToInvert + stripNumQuads;
StitchRegular(/*bTrapezoid*/false,DIAGONALS_INSIDE_TO_OUTSIDE,
/*baseIndexOffset: */m_NumIndices, /*numInsideEdgePoints:*/stripNumQuads+1,
/*insideEdgePointBaseOffset*/m_IndexPatchContext2.baseIndexToInvert,
outsideEdgePointBaseOffset+1);
SetUsingPatchedIndices2(false);
m_NumIndices += stripNumQuads*6;
}
else if((processedTessFactors.numPointsForInsideTessFactor[V] >= processedTessFactors.numPointsForInsideTessFactor[U]) &&
(TESSELLATOR_PARITY_ODD == processedTessFactors.insideTessFactorParity[U]) )
{
SetUsingPatchedIndices2(true);
int stripNumQuads = (((processedTessFactors.numPointsForInsideTessFactor[V]>>1) - (processedTessFactors.numPointsForInsideTessFactor[U]>>1))<<1)+
((TESSELLATOR_PARITY_EVEN == processedTessFactors.insideTessFactorParity[V] ) ? 2 : 1);
m_IndexPatchContext2.baseIndexToInvert = outsideEdgePointBaseOffset + stripNumQuads + 1;
m_IndexPatchContext2.cornerCaseBadValue = -1; // unused
m_IndexPatchContext2.indexInversionEndPoint = m_IndexPatchContext2.baseIndexToInvert +
m_IndexPatchContext2.baseIndexToInvert + stripNumQuads;
DIAGONALS diag = (TESSELLATOR_PARITY_EVEN == processedTessFactors.insideTessFactorParity[V]) ?
DIAGONALS_INSIDE_TO_OUTSIDE : DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE;
StitchRegular(/*bTrapezoid*/false,diag,
/*baseIndexOffset: */m_NumIndices, /*numInsideEdgePoints:*/stripNumQuads+1,
/*insideEdgePointBaseOffset*/m_IndexPatchContext2.baseIndexToInvert,
outsideEdgePointBaseOffset);
SetUsingPatchedIndices2(false);
m_NumIndices += stripNumQuads*6;
}
}