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

📄 mgcgprendererclip.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                rkNE1.Triangle(0) = uiNT1;
                rkNE1.Triangle(1) = MgcGPTriMesh::INVALID_INDEX;
                rkNT0.Vertex(0) = uiV0;
                rkNT0.Vertex(1) = uiClipV0;
                rkNT0.Vertex(2) = uiV2;
                rkNT0.Edge(0) = uiE;
                rkNT0.Edge(1) = uiNE0;
                rkNT0.Edge(2) = uiE2;
                rkNT1.Vertex(0) = uiClipV0;
                rkNT1.Vertex(1) = uiClipV1;
                rkNT1.Vertex(2) = uiV2;
                rkNT1.Edge(0) = uiNE1;
                rkNT1.Edge(1) = uiAE;
                rkNT1.Edge(2) = uiNE0;

                m_kMesh.Edge(uiE).Triangle(i) = uiNT0;

                MgcGPTriMesh::EdgeRecord& rkAE0 = m_kMesh.Edge(uiE2);
                if ( rkAE0.Triangle(0) == uiT )
                    rkAE0.Triangle(0) = uiNT0;
                else
                    rkAE0.Triangle(1) = uiNT0;

                MgcGPTriMesh::EdgeRecord& rkAE1 = m_kMesh.Edge(uiAE);
                if ( rkAE1.Triangle(0) == uiT )
                    rkAE1.Triangle(0) = uiNT1;
                else
                    rkAE1.Triangle(1) = uiNT1;
            }
            else
            {
                // triangle is clipped exactly at vertex uiV2

                // add edge
                uiNE = m_kMesh.AddEdge();
                MgcGPTriMesh::EdgeRecord& rkNE = m_kMesh.Edge(uiNE);

                // add triangle
                uiNT = m_kMesh.AddTriangle();
                MgcGPTriMesh::TriangleRecord& rkNT = m_kMesh.Triangle(uiNT);

                // update fields
                rkNE.Vertex(0) = uiClipV0;
                rkNE.Vertex(1) = uiV2;
                rkNE.Triangle(0) = uiNT;
                rkNE.Triangle(1) = MgcGPTriMesh::INVALID_INDEX;
                rkNT.Vertex(0) = uiV0;
                rkNT.Vertex(1) = uiClipV0;
                rkNT.Vertex(2) = uiV2;
                rkNT.Edge(0) = uiE;
                rkNT.Edge(1) = uiNE;
                rkNT.Edge(2) = uiE2;

                m_kMesh.Edge(uiE).Triangle(i) = uiNT;

                MgcGPTriMesh::EdgeRecord& rkAE = m_kMesh.Edge(uiE2);
                if ( rkAE.Triangle(0) == uiT )
                    rkAE.Triangle(0) = uiNT;
                else
                    rkAE.Triangle(1) = uiNT;
            }

            // cull old triangle
            m_kMesh.m_abEdgeVisible[uiE1] = false;
            m_kMesh.m_abTriangleVisible[uiT] = false;
        }
    }

    // update visibility flags for triangles
    bool bAllTrianglesCulled = true;
    for (uiT = 0; uiT < m_kMesh.m_uiTrianglesUsed; uiT++)
    {
        if ( m_kMesh.m_abTriangleVisible[uiT] )
        {
            MgcGPTriMesh::TriangleRecord& rkTri = m_kMesh.Triangle(uiT);

            unsigned int uiV0 = rkTri.Vertex(0);
            unsigned int uiV1 = rkTri.Vertex(1);
            unsigned int uiV2 = rkTri.Vertex(2);
            unsigned int uiE0 = rkTri.Edge(0);
            unsigned int uiE1 = rkTri.Edge(1);
            unsigned int uiE2 = rkTri.Edge(2);
            assert( uiV0 < m_kMesh.m_uiVerticesUsed );
            assert( uiV1 < m_kMesh.m_uiVerticesUsed );
            assert( uiV2 < m_kMesh.m_uiVerticesUsed );
            assert( uiE0 < m_kMesh.m_uiEdgesUsed );
            assert( uiE1 < m_kMesh.m_uiEdgesUsed );
            assert( uiE2 < m_kMesh.m_uiEdgesUsed );

            if ( m_kMesh.m_afDistance[uiV0] <= 0.0
            &&   m_kMesh.m_afDistance[uiV1] <= 0.0
            &&   m_kMesh.m_afDistance[uiV2] <= 0.0 )
            {
                // triangle is not visible, cull it
                m_kMesh.m_abTriangleVisible[uiT] = false;
                m_kMesh.m_abVertexVisible[uiV0] = false;
                m_kMesh.m_abVertexVisible[uiV1] = false;
                m_kMesh.m_abVertexVisible[uiV2] = false;
                m_kMesh.m_abEdgeVisible[uiE0] = false;
                m_kMesh.m_abEdgeVisible[uiE1] = false;
                m_kMesh.m_abEdgeVisible[uiE2] = false;
            }
            else
            {
                // Triangle is visible.  It is possible that vertices and
                // edges shared between a visible and an invisible triangle
                // were marked as invisible earlier.  Reset those vertices
                // and edges since the current triangle is visible.  (This
                // may happen because of floating point round-off error or
                // when a clipping plane exactly contains a vertex.)
                bAllTrianglesCulled = false;
                m_kMesh.m_abVertexVisible[uiV0] = true;
                m_kMesh.m_abVertexVisible[uiV1] = true;
                m_kMesh.m_abVertexVisible[uiV2] = true;
                m_kMesh.m_abEdgeVisible[uiE0] = true;
                m_kMesh.m_abEdgeVisible[uiE1] = true;
                m_kMesh.m_abEdgeVisible[uiE2] = true;
            }
        }
    }

    return bAllTrianglesCulled;
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipNear ()
{
    // constraint:  W - 1 >= 0

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = rkPoint.z - 1.0;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipFar ()
{
    // constraint:  F/N - W >= 0
    MgcReal fFarDivideNear = GetCamera()->GetFarDivideNear();

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = fFarDivideNear - rkPoint.z;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipLeft ()
{
    // constraint:  W + X >= 0

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = rkPoint.z + rkPoint.x;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipRight ()
{
    // constraint:  W - X >= 0

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = rkPoint.z - rkPoint.x;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipTop ()
{
    // constraint:  W - Y >= 0

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = rkPoint.z - rkPoint.y;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipBottom ()
{
    // constraint:  W + Y >= 0

    // compute vertex distances to plane
    for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
    {
        if ( m_kMesh.m_abVertexVisible[uiV] )
        {
            MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
            m_kMesh.m_afDistance[uiV] = rkPoint.z + rkPoint.y;
            if ( m_kMesh.m_afDistance[uiV] < 0.0 )
                m_kMesh.m_abVertexVisible[uiV] = false;
        }
    }

    return ClipTriMesh();
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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