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

📄 wmlmtmesh.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlMTMesh.h"
#include <fstream>
using namespace Wml;
using namespace std;

//----------------------------------------------------------------------------
MTMesh::MTMesh (int iVQuantity, int iEQuantity, int iTQuantity)
    :
    m_akVertex(iVQuantity),
    m_akEdge(iEQuantity),
    m_akTriangle(iTQuantity)
{
    m_iInitialELabel = -1;
    m_iInitialTLabel = -1;
}
//----------------------------------------------------------------------------
MTMesh::MTMesh (const MTMesh& rkMesh)
{
    *this = rkMesh;
}
//----------------------------------------------------------------------------
MTMesh::~MTMesh ()
{
}
//----------------------------------------------------------------------------
void MTMesh::Reset (int iVQuantity, int iEQuantity, int iTQuantity)
{
    m_akVertex.Reset(iVQuantity);
    m_akEdge.Reset(iEQuantity);
    m_akTriangle.Reset(iTQuantity);
    m_kVMap.clear();
    m_kEMap.clear();
    m_kTMap.clear();
}
//----------------------------------------------------------------------------
MTMesh& MTMesh::operator= (const MTMesh& rkMesh)
{
    m_akVertex = rkMesh.m_akVertex;
    m_akEdge = rkMesh.m_akEdge;
    m_akTriangle = rkMesh.m_akTriangle;
    m_kVMap = rkMesh.m_kVMap;
    m_kEMap = rkMesh.m_kEMap;
    m_kTMap = rkMesh.m_kTMap;
    m_iInitialELabel = rkMesh.m_iInitialELabel;
    m_iInitialTLabel = rkMesh.m_iInitialTLabel;
    return *this;
}
//----------------------------------------------------------------------------
bool MTMesh::Insert (int iLabel0, int iLabel1, int iLabel2)
{
    // insert triangle
    int iT = InsertTriangle(iLabel0,iLabel1,iLabel2);
    if ( iT == -1 )
    {
        // triangle already exists
        return true;
    }

    // insert vertices
    int iV0 = InsertVertex(iLabel0);
    int iV1 = InsertVertex(iLabel1);
    int iV2 = InsertVertex(iLabel2);

    // insert edges
    int iE0 = InsertEdge(iLabel0,iLabel1);
    int iE1 = InsertEdge(iLabel1,iLabel2);
    int iE2 = InsertEdge(iLabel2,iLabel0);

    // set the connections between components
    MTTriangle& rkT = m_akTriangle[iT];
    MTVertex& rkV0 = m_akVertex[iV0];
    MTVertex& rkV1 = m_akVertex[iV1];
    MTVertex& rkV2 = m_akVertex[iV2];
    MTEdge& rkE0 = m_akEdge[iE0];
    MTEdge& rkE1 = m_akEdge[iE1];
    MTEdge& rkE2 = m_akEdge[iE2];

    // attach edges to vertices
    rkV0.InsertEdge(iE2);
    rkV0.InsertEdge(iE0);
    rkV1.InsertEdge(iE0);
    rkV1.InsertEdge(iE1);
    rkV2.InsertEdge(iE1);
    rkV2.InsertEdge(iE2);
    rkE0.Vertex(0) = iV0;
    rkE0.Vertex(1) = iV1;
    rkE1.Vertex(0) = iV1;
    rkE1.Vertex(1) = iV2;
    rkE2.Vertex(0) = iV2;
    rkE2.Vertex(1) = iV0;

    // attach triangles to vertices
    rkV0.InsertTriangle(iT);
    rkV1.InsertTriangle(iT);
    rkV2.InsertTriangle(iT);
    rkT.Vertex(0) = iV0;
    rkT.Vertex(1) = iV1;
    rkT.Vertex(2) = iV2;

    // attach triangle to edges
    AttachTriangleToEdge(iT,rkT,0,iE0,rkE0);
    AttachTriangleToEdge(iT,rkT,1,iE1,rkE1);
    AttachTriangleToEdge(iT,rkT,2,iE2,rkE2);

    return true;
}
//----------------------------------------------------------------------------
int MTMesh::InsertVertex (int iLabel)
{
    MTIVertex kV(iLabel);
    int iV;

    VIter pkV = m_kVMap.find(kV);
    if ( pkV != m_kVMap.end() )
    {
        // vertex already exists
        iV = pkV->second;
    }
    else
    {
        // create new vertex
        iV = m_akVertex.Append(MTVertex(iLabel));
        m_kVMap.insert(make_pair(kV,iV));
    }

    return iV;
}
//----------------------------------------------------------------------------
int MTMesh::InsertEdge (int iLabel0, int iLabel1)
{
    MTIEdge kE(iLabel0,iLabel1);
    int iE;

    EIter pkE = m_kEMap.find(kE);
    if ( pkE != m_kEMap.end() )
    {
        // edge already exists
        iE = pkE->second;
    }
    else
    {
        // create new edge
        iE = m_akEdge.Append(MTEdge(m_iInitialELabel));
        m_kEMap.insert(make_pair(kE,iE));
    }

    return iE;
}
//----------------------------------------------------------------------------
int MTMesh::InsertTriangle (int iLabel0, int iLabel1, int iLabel2)
{
    MTITriangle kT(iLabel0,iLabel1,iLabel2);
    int iT;

    TIter pkT = m_kTMap.find(kT);
    if ( pkT != m_kTMap.end() )
    {
        // triangle already exists
        iT = -1;
    }
    else
    {
        // create new triangle
        iT = m_akTriangle.Append(MTTriangle(m_iInitialTLabel));
        m_kTMap.insert(make_pair(kT,iT));
    }

    return iT;
}
//----------------------------------------------------------------------------
bool MTMesh::Remove (int iLabel0, int iLabel1, int iLabel2)
{
    MTITriangle kT(iLabel0,iLabel1,iLabel2);
    TIter pkT = m_kTMap.find(kT);
    if ( pkT == m_kTMap.end() )
    {
        // triangle does not exist
        return false;
    }
    int iT = pkT->second;

    MTTriangle& rkT = m_akTriangle[iT];

    // detach triangle from edges
    int iE0 = rkT.Edge(0), iE1 = rkT.Edge(1), iE2 = rkT.Edge(2);
    MTEdge& rkE0 = m_akEdge[iE0];
    MTEdge& rkE1 = m_akEdge[iE1];
    MTEdge& rkE2 = m_akEdge[iE2];
    DetachTriangleFromEdge(iT,rkT,0,iE0,rkE0);
    DetachTriangleFromEdge(iT,rkT,1,iE1,rkE1);
    DetachTriangleFromEdge(iT,rkT,2,iE2,rkE2);

    // detach triangles from vertices
    int iV0 = rkT.Vertex(0);
    MTVertex& rkV0 = m_akVertex[iV0];
    rkV0.RemoveTriangle(iT);

    int iV1 = rkT.Vertex(1);
    MTVertex& rkV1 = m_akVertex[iV1];
    rkV1.RemoveTriangle(iT);

    int iV2 = rkT.Vertex(2);
    MTVertex& rkV2 = m_akVertex[iV2];
    rkV2.RemoveTriangle(iT);

    // detach edges from vertices (only if last edge to reference vertex)
    bool bE0Destroy = (rkE0.Triangle(0) == -1);
    if ( bE0Destroy )
    {
        rkV0.RemoveEdge(iE0);
        rkV1.RemoveEdge(iE0);
    }

    bool bE1Destroy = (rkE1.Triangle(0) == -1);
    if ( bE1Destroy )
    {
        rkV1.RemoveEdge(iE1);
        rkV2.RemoveEdge(iE1);
    }

    bool bE2Destroy = (rkE2.Triangle(0) == -1);
    if ( bE2Destroy )
    {
        rkV0.RemoveEdge(iE2);
        rkV2.RemoveEdge(iE2);
    }

    // Removal of components from the sets and maps starts here.  Be careful
    // using set indices, component references, and map iterators since
    // deletion has side effects.  Deletion of a component might cause another
    // component to be moved within the corresponding set or map.
    bool bV0Destroy = (rkV0.GetEdgeQuantity() == 0);
    bool bV1Destroy = (rkV1.GetEdgeQuantity() == 0);
    bool bV2Destroy = (rkV2.GetEdgeQuantity() == 0);

    // remove edges if no longer used
    if ( bE0Destroy )
        RemoveEdge(iLabel0,iLabel1);

    if ( bE1Destroy )
        RemoveEdge(iLabel1,iLabel2);

    if ( bE2Destroy )
        RemoveEdge(iLabel2,iLabel0);

    // remove vertices if no longer used
    if ( bV0Destroy )
        RemoveVertex(iLabel0);

    if ( bV1Destroy )
        RemoveVertex(iLabel1);

    if ( bV2Destroy )
        RemoveVertex(iLabel2);

    // remove triangle (definitely no longer used)
    RemoveTriangle(iLabel0,iLabel1,iLabel2);
    return true;
}
//----------------------------------------------------------------------------
void MTMesh::RemoveVertex (int iLabel)
{
    // get array location of vertex
    VIter pkV = m_kVMap.find(MTIVertex(iLabel));
    assert( pkV != m_kVMap.end() );
    int iV = pkV->second;

    // remove the vertex from the array and from the map
    int iVOld, iVNew;
    m_akVertex.RemoveAt(iV,&iVOld,&iVNew);
    m_kVMap.erase(pkV);

    if ( iVNew >= 0 )
    {
        // The vertex at the end of the array moved into the slot vacated by
        // the deleted vertex.  Update all the components sharing the moved
        // vertex.
        MTVertex& rkV = m_akVertex[iVNew];
        int i;

        // inform edges about location change
        for (i = 0; i < rkV.GetEdgeQuantity(); i++)
        {
            MTEdge& rkE = m_akEdge[rkV.GetEdge(i)];
            rkE.ReplaceVertex(iVOld,iVNew);
        }

        // inform triangles about location change
        for (i = 0; i < rkV.GetTriangleQuantity(); i++)
        {
            MTTriangle& rkT = m_akTriangle[rkV.GetTriangle(i)];
            rkT.ReplaceVertex(iVOld,iVNew);
        }

        pkV = m_kVMap.find(MTIVertex(rkV.GetLabel()));
        assert( pkV != m_kVMap.end() );
        pkV->second = iVNew;
    }
}
//----------------------------------------------------------------------------
void MTMesh::RemoveEdge (int iLabel0, int iLabel1)
{
    // get array location of edge
    EIter pkE = m_kEMap.find(MTIEdge(iLabel0,iLabel1));
    assert( pkE != m_kEMap.end() );
    int iE = pkE->second;

    // remove the edge from the array and from the map
    int iEOld, iENew;
    m_akEdge.RemoveAt(iE,&iEOld,&iENew);
    m_kEMap.erase(pkE);

    if ( iENew >= 0 )
    {
        // The edge at the end of the array moved into the slot vacated by
        // the deleted edge.  Update all the components sharing the moved
        // edge.
        MTEdge& rkE = m_akEdge[iENew];

        // inform vertices about location change
        MTVertex& rkV0 = m_akVertex[rkE.Vertex(0)];
        MTVertex& rkV1 = m_akVertex[rkE.Vertex(1)];
        rkV0.ReplaceEdge(iEOld,iENew);
        rkV1.ReplaceEdge(iEOld,iENew);

        // inform triangles about location change
        for (int i = 0; i < 2; i++)
        {
            int iT = rkE.GetTriangle(i);
            if ( iT != -1 )
            {
                MTTriangle& rkT = m_akTriangle[iT];
                rkT.ReplaceEdge(iEOld,iENew);
            }
        }

        pkE = m_kEMap.find(MTIEdge(rkV0.GetLabel(),rkV1.GetLabel()));
        assert( pkE != m_kEMap.end() );
        pkE->second = iENew;
    }
}
//----------------------------------------------------------------------------
void MTMesh::RemoveTriangle (int iLabel0, int iLabel1, int iLabel2)
{
    // get array location of triangle
    TIter pkT = m_kTMap.find(MTITriangle(iLabel0,iLabel1,iLabel2));
    assert( pkT != m_kTMap.end() );
    int iT = pkT->second;

    // remove the triangle from the array and from the map
    int iTOld, iTNew;
    m_akTriangle.RemoveAt(iT,&iTOld,&iTNew);
    m_kTMap.erase(pkT);

    if ( iTNew >= 0 )
    {
        // The triangle at the end of the array moved into the slot vacated by
        // the deleted triangle.  Update all the components sharing the moved
        // triangle.
        MTTriangle& rkT = m_akTriangle[iTNew];

        // inform vertices about location change
        MTVertex& rkV0 = m_akVertex[rkT.Vertex(0)];
        MTVertex& rkV1 = m_akVertex[rkT.Vertex(1)];
        MTVertex& rkV2 = m_akVertex[rkT.Vertex(2)];
        rkV0.ReplaceTriangle(iTOld,iTNew);
        rkV1.ReplaceTriangle(iTOld,iTNew);
        rkV2.ReplaceTriangle(iTOld,iTNew);

        // inform edges about location change
        int i;
        for (i = 0; i < 3; i++)
        {
            MTEdge& rkE = m_akEdge[rkT.GetEdge(i)];
            rkE.ReplaceTriangle(iTOld,iTNew);
        }

        // inform adjacents about location change
        for (i = 0; i < 3; i++)
        {
            int iA = rkT.GetAdjacent(i);
            if ( iA != -1 )

⌨️ 快捷键说明

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