// File: /workspace/github_cpp_makefile_star2_O2/YiweiMao[P]tessDX/src/tessellator.cpp
// Function: CHWTessellator::TriGenerateConnectivity(CHWTessellator::PROCESSED_TESS_FACTORS_TRI const&)
void CHWTessellator::TriGenerateConnectivity( const PROCESSED_TESS_FACTORS_TRI& processedTessFactors )
{
    // Generate primitives for all the concentric rings, one side at a time for each ring
    static const int startRing = 1;
    int numRings = ((processedTessFactors.numPointsForInsideTessFactor+1) >> 1); // +1 is so even tess includes the center point, which we want to now
    const TESS_FACTOR_CONTEXT* outsideTessFactorCtx[TRI_EDGES] = {&processedTessFactors.outsideTessFactorCtx[Ueq0],
                                            &processedTessFactors.outsideTessFactorCtx[Veq0],
                                            &processedTessFactors.outsideTessFactorCtx[Weq0]};
    TESSELLATOR_PARITY outsideTessFactorParity[TRI_EDGES] = {processedTessFactors.outsideTessFactorParity[Ueq0],
                                            processedTessFactors.outsideTessFactorParity[Veq0],
                                            processedTessFactors.outsideTessFactorParity[Weq0]};
    int numPointsForOutsideEdge[TRI_EDGES] = {processedTessFactors.numPointsForOutsideEdge[Ueq0],
                                              processedTessFactors.numPointsForOutsideEdge[Veq0],
                                              processedTessFactors.numPointsForOutsideEdge[Weq0]};

    int insideEdgePointBaseOffset = processedTessFactors.insideEdgePointBaseOffset;
    int outsideEdgePointBaseOffset = 0;
    int edge;
    for(int ring = startRing; ring < numRings; ring++)
    {
        int numPointsForInsideEdge = processedTessFactors.numPointsForInsideTessFactor - 2*ring;
        int edge0InsidePointBaseOffset = insideEdgePointBaseOffset;
        int edge0OutsidePointBaseOffset = outsideEdgePointBaseOffset;
        for(edge = 0; edge < TRI_EDGES; edge++ )
        {
            int numTriangles = numPointsForInsideEdge + numPointsForOutsideEdge[edge] - 2;

            int insideBaseOffset;
            int outsideBaseOffset;
            if( edge == 2 )
            {
                m_IndexPatchContext.insidePointIndexDeltaToRealValue    = insideEdgePointBaseOffset;
                m_IndexPatchContext.insidePointIndexBadValue            = numPointsForInsideEdge - 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;
                SetUsingPatchedIndices(true);
                insideBaseOffset = 0;
                outsideBaseOffset = m_IndexPatchContext.outsidePointIndexPatchBase;
            }
            else
            {
                insideBaseOffset = insideEdgePointBaseOffset;
                outsideBaseOffset = outsideEdgePointBaseOffset;
            }
            if( ring == startRing )
            {
                StitchTransition(/*baseIndexOffset: */m_NumIndices, 
                               insideBaseOffset,processedTessFactors.insideTessFactorCtx.numHalfTessFactorPoints,processedTessFactors.insideTessFactorParity,
                               outsideBaseOffset,outsideTessFactorCtx[edge]->numHalfTessFactorPoints,outsideTessFactorParity[edge]);
            }
            else
            {
                StitchRegular(/*bTrapezoid*/true, DIAGONALS_MIRRORED,
                              /*baseIndexOffset: */m_NumIndices,
                              numPointsForInsideEdge,
                              insideBaseOffset,outsideBaseOffset);
            }
            if( 2 == edge )
            {
                SetUsingPatchedIndices(false);
            }
            m_NumIndices += numTriangles*3;
            outsideEdgePointBaseOffset += numPointsForOutsideEdge[edge] - 1;
            insideEdgePointBaseOffset += numPointsForInsideEdge - 1;
            numPointsForOutsideEdge[edge] = numPointsForInsideEdge;
        }
        if( startRing == ring )
        {
            for(edge = 0; edge < TRI_EDGES; edge++ )
            {
                outsideTessFactorCtx[edge] = &processedTessFactors.insideTessFactorCtx;
                outsideTessFactorParity[edge] = processedTessFactors.insideTessFactorParity;
            }
        }
    }
    if( Odd() )
    {
        // Triangulate center (a single triangle)
        DefineClockwiseTriangle(outsideEdgePointBaseOffset, outsideEdgePointBaseOffset+1, outsideEdgePointBaseOffset+2, 
                       m_NumIndices);
        m_NumIndices += 3;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %rbx
movl 0x80(%rsi), %eax
incl %eax
sarl %eax
movl %eax, 0x1c(%rsp)
leaq 0x20(%rsi), %rax
movq %rax, 0x70(%rsp)
leaq 0x34(%rsi), %rax
movq %rax, 0x78(%rsp)
leaq 0x48(%rsi), %rax
movq %rax, 0x80(%rsp)
movq 0x10(%rsi), %rax
movq %rax, 0x38(%rsp)
movl 0x18(%rsi), %eax
movl %eax, 0x40(%rsp)
movq 0x74(%rsi), %rax
movq %rax, 0x28(%rsp)
movl 0x7c(%rsi), %eax
movl %eax, 0x30(%rsp)
movl 0x84(%rsi), %eax
movl %eax, 0x4(%rsp)
movq %rsi, 0x10(%rsp)
leaq 0x5c(%rsi), %rdx
movq $0x0, 0x8(%rsp)
pushq $0x1
popq %rax
pushq $-0x3
popq %rsi
movl %eax, %r12d
movq %rdx, 0x48(%rsp)
cmpl 0x1c(%rsp), %r12d
jge 0x403e4b
movq 0x10(%rsp), %rax
movl 0x80(%rax), %ecx
leal (%r12,%r12), %eax
movl %ecx, %r13d
subl %eax, %r13d
negl %eax
addl %ecx, %eax
decl %eax
movl %eax, 0x24(%rsp)
movl %esi, 0x20(%rsp)
addl %esi, %ecx
movq %rcx, 0x58(%rsp)
movl 0x4(%rsp), %ebp
xorl %r15d, %r15d
movq 0x8(%rsp), %rax
movl %eax, %r14d
cmpq $0xc, %r15
je 0x403e07
movl 0x28(%rsp,%r15), %ecx
movq %rcx, 0x68(%rsp)
addl %r13d, %ecx
movl %ebp, %r9d
movl %r14d, %eax
cmpq $0x8, %r15
jne 0x403d61
movl %ebp, 0x34(%rbx)
movl 0x24(%rsp), %eax
movl %eax, 0x38(%rbx)
movl 0x4(%rsp), %eax
movl %eax, 0x3c(%rbx)
movl %r13d, 0x40(%rbx)
movl %r14d, %eax
subl %r13d, %eax
movl %eax, 0x44(%rbx)
leal -0x1(%rcx), %eax
movl %eax, 0x48(%rbx)
movq 0x8(%rsp), %rax
movl %eax, 0x4c(%rbx)
movb $0x1, 0x31(%rbx)
xorl %r9d, %r9d
movl %r13d, %eax
movq %rcx, 0x60(%rsp)
movl 0x2c(%rbx), %ecx
cmpl $0x1, %r12d
jne 0x403db5
movq 0x10(%rsp), %rdx
movl 0x1c(%rdx), %r8d
movl 0x68(%rdx), %r10d
movq 0x70(%rsp,%r15,2), %rdx
movl 0xc(%rdx), %edx
movq %rdx, 0x50(%rsp)
movl %ebp, %r11d
movq %r12, %rbp
movl 0x38(%rsp,%r15), %r12d
movq %rbx, %rdi
movl %ecx, %esi
movl %r9d, %edx
movl %r10d, %ecx
movl %eax, %r9d
pushq %r12
movq %rbp, %r12
movl %r11d, %ebp
pushq 0x58(%rsp)
callq 0x402f7a
jmp 0x403dcb
subq $0x8, %rsp
movq %rbx, %rdi
pushq $0x1
popq %rsi
pushq $0x2
popq %rdx
movl %r13d, %r8d
pushq %rax
callq 0x40322e
popq %rax
popq %rcx
cmpq $0x8, %r15
movq 0x60(%rsp), %rax
jne 0x403ddc
movb $0x0, 0x31(%rbx)
leal (%rax,%rax,2), %eax
movl 0x2c(%rbx), %ecx
addl %ecx, %eax
addl $-0x6, %eax
movl %eax, 0x2c(%rbx)
movq 0x68(%rsp), %rax
addl %eax, %r14d
decl %r14d
movl %r13d, 0x28(%rsp,%r15)
addq $0x4, %r15
addl 0x58(%rsp), %ebp
jmp 0x403d08
cmpl $0x1, %r12d
movq 0x48(%rsp), %rdx
movl 0x20(%rsp), %esi
jne 0x403e34
movq 0x10(%rsp), %rax
movl 0x1c(%rax), %eax
xorl %ecx, %ecx
cmpq $0x3, %rcx
je 0x403e34
movq %rdx, 0x70(%rsp,%rcx,8)
movl %eax, 0x38(%rsp,%rcx,4)
incq %rcx
jmp 0x403e20
incl %r12d
addl $-0x2, %esi
movl %r14d, %eax
movq %rax, 0x8(%rsp)
movl %ebp, 0x4(%rsp)
jmp 0x403cc4
cmpl $0x1, 0x4(%rbx)
jne 0x403e6c
movq 0x8(%rsp), %rsi
leal 0x1(%rsi), %edx
leal 0x2(%rsi), %ecx
movl 0x2c(%rbx), %r8d
movq %rbx, %rdi
callq 0x402592
addl $0x3, 0x2c(%rbx)
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq