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

📄 mgcbeziermesh.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcBezierCylinder.h"
#include "MgcBezierMesh.h"
#include "MgcTriMesh.h"

MgcImplementRTTI(MgcBezierMesh,MgcGeometry);
MgcImplementStream(MgcBezierMesh);

//----------------------------------------------------------------------------
MgcBezierMesh::MgcBezierMesh (unsigned int uiCtrlQuantity,
    MgcVector3* akCtrlVertex, bool bUseNormals, MgcColor* akCtrlColor,
    MgcVector2* akCtrlTexture, unsigned int uiPatchQuantity,
    MgcBezierPatchPtr* aspkPatch)
    :
    MgcGeometry(uiCtrlQuantity,akCtrlVertex,0,akCtrlColor,akCtrlTexture)
{
    m_uiPatchQuantity = uiPatchQuantity;
    m_aspkPatch = aspkPatch;
    m_uiTrianglePatchQuantity = 0;
    m_uiRectanglePatchQuantity = 0;
    m_uiCylinderPatchQuantity = 0;
    for (unsigned int uiI = 0; uiI < m_uiPatchQuantity; uiI++)
    {
        MgcBezierPatch::PatchType eType = m_aspkPatch[uiI]->GetType();
        if ( eType == MgcBezierPatch::PT_TRIANGLE )
            m_uiTrianglePatchQuantity++;
        else if ( eType == MgcBezierPatch::PT_RECTANGLE )
            m_uiRectanglePatchQuantity++;
        else
            m_uiCylinderPatchQuantity++;
    }

    // allocate space for trimesh (default level = 0)
    unsigned int uiVertexQuantity, uiTriangleQuantity;
    GetMeshQuantities(0,uiVertexQuantity,uiTriangleQuantity);

    MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];

    MgcVector3* akNormal;
    if ( bUseNormals )
        akNormal = new MgcVector3[uiVertexQuantity];
    else
        akNormal = 0;

    MgcColor* akColor;
    if ( akCtrlColor )
        akColor = new MgcColor[uiVertexQuantity];
    else
        akColor = 0;

    MgcVector2* akTexture;
    if ( akCtrlTexture )
        akTexture = new MgcVector2[uiVertexQuantity];
    else
        akTexture = 0;

    unsigned int* auiConnect = new unsigned int[3*uiTriangleQuantity];

    m_pkMesh = new MgcTriMesh(uiVertexQuantity,akVertex,akNormal,akColor,
        akTexture,uiTriangleQuantity,auiConnect);

    Tessellate(0);
}
//----------------------------------------------------------------------------
MgcBezierMesh::MgcBezierMesh ()
{
    m_uiPatchQuantity = 0;
    m_uiTrianglePatchQuantity = 0;
    m_uiRectanglePatchQuantity = 0;
    m_uiCylinderPatchQuantity = 0;
    m_aspkPatch = 0;
    m_pkMesh = 0;
    m_uiLevel = 0;
}
//----------------------------------------------------------------------------
MgcBezierMesh::~MgcBezierMesh ()
{
    if ( m_aspkPatch )
    {
        for (unsigned int uiI = 0; uiI < m_uiPatchQuantity; uiI++)
            m_aspkPatch[uiI] = 0;
        delete[] m_aspkPatch;
    }

    delete m_pkMesh;
}
//----------------------------------------------------------------------------
void MgcBezierMesh::UpdateModelNormals ()
{
    // TO DO.  Implement?  Control point normals don't make sense here.
}
//----------------------------------------------------------------------------
void MgcBezierMesh::UpdateRenderState (MgcRenderState* apkState[])
{
    // MgcGeometry base never gets drawn, it is just a repository for control
    // points.  Transfer the render state to the trimesh that is drawn.
    m_pkMesh->UpdateRenderState(apkState);
}
//----------------------------------------------------------------------------
void MgcBezierMesh::Draw (MgcRenderer& rkRenderer)
{
    // MgcGeometry base never gets drawn, it is just a repository for control
    // points.  Draw the trimesh instead.
    m_pkMesh->Draw(rkRenderer);
}
//----------------------------------------------------------------------------
void MgcBezierMesh::GetMeshQuantities (unsigned int uiLevel,
    unsigned int& uiVertexQuantity, unsigned int& uiTriangleQuantity)
{
    // compute number of vertices and triangles needed for trimesh
    uiVertexQuantity = 0;
    uiTriangleQuantity = 0;

    if ( m_uiTrianglePatchQuantity > 0 )
    {
        uiVertexQuantity +=
            MgcBezierPatch::GetVerticesPerTrianglePatch(uiLevel) *
            m_uiTrianglePatchQuantity;

        uiTriangleQuantity +=
            MgcBezierPatch::GetTrianglesPerTrianglePatch(uiLevel) *
            m_uiTrianglePatchQuantity;
    }

    if ( m_uiRectanglePatchQuantity > 0 )
    {
        uiVertexQuantity +=
            MgcBezierPatch::GetVerticesPerRectanglePatch(uiLevel) *
            m_uiRectanglePatchQuantity;

        uiTriangleQuantity +=
            MgcBezierPatch::GetTrianglesPerRectanglePatch(uiLevel) *
            m_uiRectanglePatchQuantity;
    }

    if ( m_uiCylinderPatchQuantity > 0 )
    {
        for (unsigned int uiI = 0; uiI < m_uiPatchQuantity; uiI++)
        {
            if ( m_aspkPatch[uiI]->GetType() == MgcBezierPatch::PT_CYLINDER )
            {
                MgcBezierCylinder* pkCyln =
                    MgcSmartPointerCast(MgcBezierCylinder,m_aspkPatch[uiI]);

                uiVertexQuantity +=
                    MgcBezierPatch::GetVerticesPerCylinderPatch(uiLevel,
                    pkCyln->CylinderLevel());

                uiTriangleQuantity +=
                    MgcBezierPatch::GetTrianglesPerCylinderPatch(uiLevel,
                    pkCyln->CylinderLevel());
            }
        }
    }
}
//----------------------------------------------------------------------------
void MgcBezierMesh::Tessellate (unsigned int uiLevel)
{
    m_uiLevel = uiLevel;

    // reallocate space for trimesh
    unsigned int uiVertexQuantity, uiTriangleQuantity;
    GetMeshQuantities(uiLevel,uiVertexQuantity,uiTriangleQuantity);
    m_pkMesh->Reconstruct(uiVertexQuantity,uiTriangleQuantity);

    // fill in the trimesh with tessellated patch triangles
    uiVertexQuantity = 0;
    uiTriangleQuantity = 0;
    for (unsigned int uiI = 0; uiI < m_uiPatchQuantity; uiI++)
    {
        m_aspkPatch[uiI]->Tessellate(uiLevel,Vertices(),Colors(),Textures(),
            m_pkMesh,uiVertexQuantity,uiTriangleQuantity);
    }
}
//----------------------------------------------------------------------------

//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcBezierMesh::Factory (MgcStream& rkStream)
{
    MgcBezierMesh* pkObject = new MgcBezierMesh;
    MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
    pkObject->Load(rkStream,pkLink);
    return pkObject;
}
//---------------------------------------------------------------------------
void MgcBezierMesh::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcGeometry::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcBezierMesh::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcGeometry::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcBezierMesh::Register (MgcStream& rkStream)
{
    return MgcGeometry::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcBezierMesh::Save (MgcStream& rkStream)
{
    MgcGeometry::Save(rkStream);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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