⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcquadricsurface.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

            // Set as a flag for later use (avoids redundant copies of
            // edge triangle pointers).
            pkE0->m_apkTriangle[0] = 0;
            pkE1->m_apkTriangle[0] = 0;

            // For testing purposes, but not necessary for the algorithm.
            // This allows the display program to show the subdivision
            // structure.
            pkE1->m_uiStep = pkE0->m_uiStep;
        }

        // compute new centroid (for next step of iteration)
        ComputeCentroid(rkPoly,iVMax+iEMax);

        // Add new edges.  Vertex pointers are set to the new vertices, but
        // the triangle pointers are not calculated until later.
        //
        // Add new triangles.  The middle triangle will replace the old
        // triangle to save storage.  As a result, the adjacency values for
        // the middle triangle are calculated later since the current value
        // are needed globally for computing the other adjacencies.
        Triangle *pkT0, *pkT1, *pkT2, *pkT3;
        Vertex *pkM0, *pkM1, *pkM2;
        int iT, i0, i1, i2, i3, iOrient;
        int iTM1 = iTMax, iTM2 = 2*iTMax, iTM3 = 3*iTMax;
        iE = 2*iEMax;
        for (iT = 0; iT < iTMax; iT++, iTM1++, iTM2++, iTM3++)
        {
            // get triangle
            pkT0 = &rkPoly.m_apkTriangle[iT];

            // get vertices
            Vertex* pkV0 = pkT0->m_apkVertex[0];
            Vertex* pkV1 = pkT0->m_apkVertex[1];
            Vertex* pkV2 = pkT0->m_apkVertex[2];

            // get edges
            Edge* pkE0 = pkT0->m_apkEdge[0];
            Edge* pkE1 = pkT0->m_apkEdge[1];
            Edge* pkE2 = pkT0->m_apkEdge[2];

            // get adjacent triangles
            Triangle* pkA0 = pkT0->m_apkAdjacent[0];
            Triangle* pkA1 = pkT0->m_apkAdjacent[1];
            Triangle* pkA2 = pkT0->m_apkAdjacent[2];

            // get midpoints of triangle edges
            pkM0 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,pkE0)];
            pkM1 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,pkE1)];
            pkM2 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,pkE2)];

            // get new edges and set vertex values
            Edge* pkE0New = &rkPoly.m_apkEdge[iE++];
            pkE0New->m_apkVertex[0] = pkM2;
            pkE0New->m_apkVertex[1] = pkM0;
            Edge* pkE1New = &rkPoly.m_apkEdge[iE++];
            pkE1New->m_apkVertex[0] = pkM0;
            pkE1New->m_apkVertex[1] = pkM1;
            Edge* pkE2New = &rkPoly.m_apkEdge[iE++];
            pkE2New->m_apkVertex[0] = pkM1;
            pkE2New->m_apkVertex[1] = pkM2;

            // For testing purposes, but not necessary for the algorithm.
            // This allows the display program to show the subdivision
            // structure.
            pkE0New->m_uiStep = uiS;
            pkE1New->m_uiStep = uiS;
            pkE2New->m_uiStep = uiS;

            // construct triangle T1
            pkT1 = &rkPoly.m_apkTriangle[iTM1];
            pkT1->m_apkVertex[0] = pkV0;
            pkT1->m_apkVertex[1] = pkM0;
            pkT1->m_apkVertex[2] = pkM2;
            pkT1->m_apkEdge[0] =
                ( pkE0->m_apkVertex[0] == pkV0 ? pkE0 : pkE0+iEMax );
            pkT1->m_apkEdge[1] = pkE0New;
            pkT1->m_apkEdge[2] =
                ( pkE2->m_apkVertex[0] == pkV0 ? pkE2 : pkE2+iEMax );
            pkT1->m_apkAdjacent[1] = pkT0;

            // construct triangle T2
            pkT2 = &rkPoly.m_apkTriangle[iTM2];
            pkT2->m_apkVertex[0] = pkM0;
            pkT2->m_apkVertex[1] = pkV1;
            pkT2->m_apkVertex[2] = pkM1;
            pkT2->m_apkEdge[0] =
                ( pkE0->m_apkVertex[0] == pkV1 ? pkE0 : pkE0+iEMax );
            pkT2->m_apkEdge[1] =
                ( pkE1->m_apkVertex[0] == pkV1 ? pkE1 : pkE1+iEMax );
            pkT2->m_apkEdge[2] = pkE1New;
            pkT2->m_apkAdjacent[2] = pkT0;

            // construct triangle T3
            pkT3 = &rkPoly.m_apkTriangle[iTM3];
            pkT3->m_apkVertex[0] = pkM2;
            pkT3->m_apkVertex[1] = pkM1;
            pkT3->m_apkVertex[2] = pkV2;
            pkT3->m_apkEdge[0] = pkE2New;
            pkT3->m_apkEdge[1] =
                ( pkE1->m_apkVertex[0] == pkV2 ? pkE1 : pkE1+iEMax );
            pkT3->m_apkEdge[2] =
                ( pkE2->m_apkVertex[0] == pkV2 ? pkE2 : pkE2+iEMax );
            pkT3->m_apkAdjacent[0] = pkT0;

            // set edge triangle pointers
            pkE0New->m_apkTriangle[0] = pkT0;
            pkE0New->m_apkTriangle[1] = pkT1;
            pkE1New->m_apkTriangle[0] = pkT0;
            pkE1New->m_apkTriangle[1] = pkT2;
            pkE2New->m_apkTriangle[0] = pkT0;
            pkE2New->m_apkTriangle[1] = pkT3;

            // get the indices for the subdivided triangles of A0
            i0 = TriangleIndex(rkPoly,pkA0);
            i1 = i0+iTMax;
            i2 = i1+iTMax;
            i3 = i2+iTMax;

            // Determine the orientation of A0 relative to T0 and set the
            // adjacency links.
            iOrient = AdjacentOrient(pkT0,pkA0);
            if ( iOrient == 0 )
            {
                pkT1->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i2];
                pkT2->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i1];
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[0] = pkT1;
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[0] = pkT2;
            }
            else if ( iOrient == 1 )
            {
                pkT1->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i3];
                pkT2->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i2];
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[1] = pkT1;
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[1] = pkT2;
            }
            else
            {
                pkT1->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i1];
                pkT2->m_apkAdjacent[0] = &rkPoly.m_apkTriangle[i3];
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[2] = pkT1;
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[2] = pkT2;
            }

            // get the indices for the subdivided triangles of A1
            i0 = TriangleIndex(rkPoly,pkA1);
            i1 = i0+iTMax;
            i2 = i1+iTMax;
            i3 = i2+iTMax;

            // Determine the orientation of A1 relative to T0 and set the
            // adjacency links.
            iOrient = AdjacentOrient(pkT0,pkA1);
            if ( iOrient == 0 )
            {
                pkT2->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i2];
                pkT3->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i1];
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[0] = pkT2;
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[0] = pkT3;
            }
            else if ( iOrient == 1 )
            {
                pkT2->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i3];
                pkT3->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i2];
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[1] = pkT2;
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[1] = pkT3;
            }
            else
            {
                pkT2->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i1];
                pkT3->m_apkAdjacent[1] = &rkPoly.m_apkTriangle[i3];
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[2] = pkT2;
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[2] = pkT3;
            }

            // get the indices for the subdivided triangles of A2
            i0 = TriangleIndex(rkPoly,pkA2);
            i1 = i0+iTMax;
            i2 = i1+iTMax;
            i3 = i2+iTMax;

            // Determine the orientation of A2 relative to T0 and set the
            // adjacency links.
            iOrient = AdjacentOrient(pkT0,pkA2);
            if ( iOrient == 0 )
            {
                pkT3->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i2];
                pkT1->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i1];
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[0] = pkT3;
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[0] = pkT1;
            }
            else if ( iOrient == 1 )
            {
                pkT3->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i3];
                pkT1->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i2];
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[1] = pkT3;
                rkPoly.m_apkTriangle[i2].m_apkAdjacent[1] = pkT1;
            }
            else
            {
                pkT3->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i1];
                pkT1->m_apkAdjacent[2] = &rkPoly.m_apkTriangle[i3];
                rkPoly.m_apkTriangle[i1].m_apkAdjacent[2] = pkT3;
                rkPoly.m_apkTriangle[i3].m_apkAdjacent[2] = pkT1;
            }

            // add edge links to midpoint vertices
            if ( pkM0->m_iNumEdges == 0 )
            {
                // add four edges (first time edges are added for this vertex)
                pkM0->m_iNumEdges = 4;
                pkM0->m_apkEdge[0] = pkT1->m_apkEdge[0];
                pkM0->m_apkEdge[1] = pkT1->m_apkEdge[1];
                pkM0->m_apkEdge[2] = pkT2->m_apkEdge[2];
                pkM0->m_apkEdge[3] = pkT2->m_apkEdge[0];
            }
            else if ( pkM0->m_iNumEdges == 4 )
            {
                // add two edges (last time edges are added for this vertex)
                pkM0->m_iNumEdges = 6;
                pkM0->m_apkEdge[4] = pkT1->m_apkEdge[1];
                pkM0->m_apkEdge[5] = pkT2->m_apkEdge[2];
            }

            if ( pkM1->m_iNumEdges == 0 )
            {
                // add four edges (first time edges are added for this vertex)
                pkM1->m_iNumEdges = 4;
                pkM1->m_apkEdge[0] = pkT2->m_apkEdge[1];
                pkM1->m_apkEdge[1] = pkT2->m_apkEdge[2];
                pkM1->m_apkEdge[2] = pkT3->m_apkEdge[0];
                pkM1->m_apkEdge[3] = pkT3->m_apkEdge[1];
            }
            else if ( pkM1->m_iNumEdges == 4 )
            {
                // add two edges (last time edges are added for this vertex)
                pkM1->m_iNumEdges = 6;
                pkM1->m_apkEdge[4] = pkT2->m_apkEdge[2];
                pkM1->m_apkEdge[5] = pkT3->m_apkEdge[0];
            }

            if ( pkM2->m_iNumEdges == 0 )
            {
                // add four edges (first time edges are added for this vertex)
                pkM2->m_iNumEdges = 4;
                pkM2->m_apkEdge[0] = pkT1->m_apkEdge[2];
                pkM2->m_apkEdge[1] = pkT1->m_apkEdge[1];
                pkM2->m_apkEdge[2] = pkT3->m_apkEdge[0];
                pkM2->m_apkEdge[3] = pkT3->m_apkEdge[2];
            }
            else if ( pkM2->m_iNumEdges == 4 )
            {
                // add two edges (last time edges are added for this vertex)
                pkM2->m_iNumEdges = 6;
                pkM2->m_apkEdge[4] = pkT1->m_apkEdge[1];
                pkM2->m_apkEdge[5] = pkT3->m_apkEdge[0];
            }
        }

        // Set middle triangle vertex, edge, and triangle pointers.  Set
        // edge triangle pointers.
        iTM1 = iTMax;
        iTM2 = 2*iTMax;
        iTM3 = 3*iTMax;
        for (iT = 0; iT < iTMax; iT++, iTM1++, iTM2++, iTM3++)
        {
            // get subdivided triangles
            pkT0 = &rkPoly.m_apkTriangle[iT];
            pkT1 = &rkPoly.m_apkTriangle[iTM1];
            pkT2 = &rkPoly.m_apkTriangle[iTM2];
            pkT3 = &rkPoly.m_apkTriangle[iTM3];

            // get midpoints of original triangle edges
            pkM0 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,
                pkT0->m_apkEdge[0])];
            pkM1 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,
                pkT0->m_apkEdge[1])];
            pkM2 = &rkPoly.m_apkVertex[iVMax+EdgeIndex(rkPoly,
                pkT0->m_apkEdge[2])];

            // set vertices for middle triangle
            pkT0->m_apkVertex[0] = pkM2;
            pkT0->m_apkVertex[1] = pkM0;
            pkT0->m_apkVertex[2] = pkM1;

            // set edges for middle triangle
            pkT0->m_apkEdge[0] = pkT1->m_apkEdge[1];
            pkT0->m_apkEdge[1] = pkT2->m_apkEdge[2];
            pkT0->m_apkEdge[2] = pkT3->m_apkEdge[0];

            // set adjacencies for middle triangle
            pkT0->m_apkAdjacent[0] = pkT1;
            pkT0->m_apkAdjacent[1] = pkT2;
            pkT0->m_apkAdjacent[2] = pkT3;

            // set edge triangle pointers
            if ( pkT1->m_apkEdge[0]->m_apkTriangle[0] == 0 )
            {
                pkT1->m_apkEdge[0]->m_apkTriangle[0] = pkT1;
                pkT1->m_apkEdge[0]->m_apkTriangle[1] = pkT1->m_apkAdjacent[0];
            }
            if ( pkT1->m_apkEdge[2]->m_apkTriangle[0] == 0 )
            {
                pkT1->m_apkEdge[2]->m_apkTriangle[0] = pkT1;
                pkT1->m_apkEdge[2]->m_apkTriangle[1] = pkT1->m_apkAdjacent[2];
            }

            if ( pkT2->m_apkEdge[0]->m_apkTriangle[0] == 0 )
            {
                pkT2->m_apkEdge[0]->m_apkTriangle[0] = pkT2;
                pkT2->m_apkEdge[0]->m_apkTriangle[1] = pkT2->m_apkAdjacent[0];
            }
            if ( pkT2->m_apkEdge[1]->m_apkTriangle[0] == 0 )
            {
                pkT2->m_apkEdge[1]->m_apkTriangle[0] = pkT2;
                pkT2->m_apkEdge[1]->m_apkTriangle[1] = pkT2->m_apkAdjacent[1];
            }

            if ( pkT3->m_apkEdge[1]->m_apkTriangle[0] == 0 )
            {
                pkT3->m_apkEdge[1]->m_apkTriangle[0] = pkT3;
                pkT3->m_apkEdge[1]->m_apkTriangle[1] = pkT3->m_apkAdjacent[1];
            }
            if ( pkT3->m_apkEdge[2]->m_apkTriangle[0] == 0 )
            {
                pkT3->m_apkEdge[2]->m_apkTriangle[0] = pkT3;
                pkT3->m_apkEdge[2]->m_apkTriangle[1] = pkT3->m_apkAdjacent[2];
            }
        }

        // Adjust edge pointers of original vertices to account for the
        // edge splitting.
        for (int iV = 0; iV < iVMax; iV++)
        {
            Vertex* pkV = &rkPoly.m_apkVertex[iV];
            for (iE = 0; iE < pkV->m_iNumEdges; iE++)
            {
                Edge* pkE = pkV->m_apkEdge[iE];
                if ( pkE->m_apkVertex[0] != pkV
                &&   pkE->m_apkVertex[1] != pkV )
                {
                    pkV->m_apkEdge[iE] = &rkPoly.m_apkEdge[
                        iEMax+EdgeIndex(rkPoly,pkE)];
                }
            }
        }

        // update indices
        iVMax = iVMax + iEMax;
        iEMax = 2*iEMax + 3*iTMax;
        iTMax = 4*iTMax;
    }
}
//---------------------------------------------------------------------------
void MgcQuadricSurface::DeletePolyhedron (ConvexPolyhedron& rkPoly)
{
    // assumes that rkPoly.vertex[*].point was dynamically allocated
    for (int i = 0; i < rkPoly.m_iNumVertices; i++)
    {
        delete rkPoly.m_apkVertex[i].m_pkPoint;
        delete[] rkPoly.m_apkVertex[i].m_apkEdge;
    }

    delete[] rkPoly.m_apkVertex;
    delete[] rkPoly.m_apkEdge;
    delete[] rkPoly.m_apkTriangle;

    rkPoly.m_iNumVertices = 0;
    rkPoly.m_apkVertex = 0;
    rkPoly.m_iNumEdges = 0;
    rkPoly.m_apkEdge = 0;
    rkPoly.m_iNumTriangles = 0;
    rkPoly.m_apkTriangle = 0;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -