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

📄 spheretessellation.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 "SphereTessellation.h"

Application2::Color SphereTessellation::ms_akColor[4] =
{
    Color(0,0,0),
    Color(255,0,0),
    Color(0,255,0),
    Color(0,0,255)
};

const int g_iSize = 512;
SphereTessellation g_kTheApp;

//----------------------------------------------------------------------------
SphereTessellation::SphereTessellation ()
    :
    Application2("SphereTessellation",0,0,g_iSize,g_iSize,
        ColorRGB(1.0f,1.0f,1.0f))
{
    m_bOctahedron = true;
    m_bPerspective = true;
}
//----------------------------------------------------------------------------
SphereTessellation::~SphereTessellation ()
{
}
//----------------------------------------------------------------------------
bool SphereTessellation::OnInitialize ()
{
    if ( !Application2::OnInitialize() )
        return false;

    // number of subdivisions of inscribed polyhedron
    m_iSteps = 0;

    // create and subdivide the polyhedron
    CreatePolyhedron(false);

    // initial camera orientation and eye point
    m_kRot.FromAxisAngle(Vector3f::UNIT_Z,0.0f);
    m_kEye = 2.0f*m_kRot.GetColumn(2);

    OnDisplay();
    return true;
}
//----------------------------------------------------------------------------
void SphereTessellation::OnTerminate ()
{
    QuadricSurfacef::DeletePolyhedron(m_kPoly);
    Application2::OnTerminate();
}
//----------------------------------------------------------------------------
void SphereTessellation::OnDisplay ()
{
    ClearScreen();
    DrawPolyhedron();
    Application2::OnDisplay();
}
//----------------------------------------------------------------------------
void SphereTessellation::OnKeyDown (unsigned char ucKey, int, int)
{
    if ( ucKey == 'q' || ucKey == 'Q' || ucKey == KEY_ESCAPE )
    {
        RequestTermination();
        return;
    }

    switch ( ucKey )
    {
    // increase subdivision level
    case '+':
    case '=':
        m_iSteps++;
        CreatePolyhedron(true);
        OnDisplay();
        break;

    // decrease subdivision level
    case '-':
    case '_':
        if ( m_iSteps >= 1 )
        {
            m_iSteps--;
            CreatePolyhedron(true);
            OnDisplay();
        }
        break;

    // toggle type of polyhedron
    case 'p':
    case 'P':
        m_bOctahedron = !m_bOctahedron;
        CreatePolyhedron(true);
        OnDisplay();
        break;

    // toggle type of camera
    case 'c':
    case 'C':
        m_bPerspective = !m_bPerspective;
        OnDisplay();
        break;
    }
}
//----------------------------------------------------------------------------
void SphereTessellation::OnSpecialKeyDown (int iKey, int, int)
{
    Matrix3f kIncr;

    if ( iKey == KEY_LEFT_ARROW )
    {
        // rotate camera about its 'up' vector
        kIncr.FromAxisAngle(m_kRot.GetColumn(1),0.1f);
        m_kRot = kIncr*m_kRot;
        m_kEye = 2.0f*m_kRot.GetColumn(2);
        OnDisplay();
    }
    else if ( iKey == KEY_RIGHT_ARROW )
    {
        // rotate camera about its 'up' vector
        kIncr.FromAxisAngle(m_kRot.GetColumn(1),-0.1f);
        m_kRot = kIncr*m_kRot;
        m_kEye = 2.0f*m_kRot.GetColumn(2);
        OnDisplay();
    }
    else if ( iKey == KEY_UP_ARROW )
    {
        // rotate camera about its 'right' vector
        kIncr.FromAxisAngle(m_kRot.GetColumn(0),-0.1f);
        m_kRot = kIncr*m_kRot;
        m_kEye = 2.0f*m_kRot.GetColumn(2);
        OnDisplay();
    }
    else if ( iKey == KEY_DOWN_ARROW )
    {
        // rotate camera about its 'right' vector
        kIncr.FromAxisAngle(m_kRot.GetColumn(0),0.1f);
        m_kRot = kIncr*m_kRot;
        m_kEye = 2.0f*m_kRot.GetColumn(2);
        OnDisplay();
    }
}
//----------------------------------------------------------------------------
void SphereTessellation::CreatePolyhedron (bool bDeleteOld)
{
    if ( bDeleteOld )
        QuadricSurfacef::DeletePolyhedron(m_kPoly);

    if ( m_bOctahedron )
        CreateOctahedron(m_kPoly);
    else
        CreateTetrahedron(m_kPoly);

    QuadricSurfacef::TessellateSphere(m_iSteps,m_kPoly);
}
//----------------------------------------------------------------------------
void SphereTessellation::CreateTetrahedron (
    QuadricSurfacef::ConvexPolyhedron& rkTetra)
{
    rkTetra.m_iNumVertices = 4;
    rkTetra.m_apkVertex = new QuadricSurfacef::Vertex[4];
    rkTetra.m_iNumEdges = 6;
    rkTetra.m_apkEdge = new QuadricSurfacef::Edge[6];
    rkTetra.m_iNumTriangles = 4;
    rkTetra.m_apkTriangle = new QuadricSurfacef::Triangle[4];

    // vertices
    rkTetra.m_apkVertex[0].m_pkPoint = new Vector3f;
    rkTetra.m_apkVertex[0].m_pkPoint->X() = 1.0f;
    rkTetra.m_apkVertex[0].m_pkPoint->Y() = 0.0f;
    rkTetra.m_apkVertex[0].m_pkPoint->Z() = 0.0f;
    rkTetra.m_apkVertex[0].m_iNumEdges = 3;
    rkTetra.m_apkVertex[0].m_apkEdge = new QuadricSurfacef::Edge*[3];
    rkTetra.m_apkVertex[0].m_apkEdge[0] = &rkTetra.m_apkEdge[0];
    rkTetra.m_apkVertex[0].m_apkEdge[1] = &rkTetra.m_apkEdge[2];
    rkTetra.m_apkVertex[0].m_apkEdge[2] = &rkTetra.m_apkEdge[3];

    rkTetra.m_apkVertex[1].m_pkPoint = new Vector3f;
    rkTetra.m_apkVertex[1].m_pkPoint->X() = 0.0f;
    rkTetra.m_apkVertex[1].m_pkPoint->Y() = 1.0f;
    rkTetra.m_apkVertex[1].m_pkPoint->Z() = 0.0f;
    rkTetra.m_apkVertex[1].m_iNumEdges = 3;
    rkTetra.m_apkVertex[1].m_apkEdge = new QuadricSurfacef::Edge*[3];
    rkTetra.m_apkVertex[1].m_apkEdge[0] = &rkTetra.m_apkEdge[0];
    rkTetra.m_apkVertex[1].m_apkEdge[1] = &rkTetra.m_apkEdge[1];
    rkTetra.m_apkVertex[1].m_apkEdge[2] = &rkTetra.m_apkEdge[4];

    rkTetra.m_apkVertex[2].m_pkPoint = new Vector3f;
    rkTetra.m_apkVertex[2].m_pkPoint->X() = 0.0f;
    rkTetra.m_apkVertex[2].m_pkPoint->Y() = 0.0f;
    rkTetra.m_apkVertex[2].m_pkPoint->Z() = 1.0f;
    rkTetra.m_apkVertex[2].m_iNumEdges = 3;
    rkTetra.m_apkVertex[2].m_apkEdge = new QuadricSurfacef::Edge*[3];
    rkTetra.m_apkVertex[2].m_apkEdge[0] = &rkTetra.m_apkEdge[1];
    rkTetra.m_apkVertex[2].m_apkEdge[1] = &rkTetra.m_apkEdge[2];
    rkTetra.m_apkVertex[2].m_apkEdge[2] = &rkTetra.m_apkEdge[5];

    rkTetra.m_apkVertex[3].m_pkPoint = new Vector3f;
    rkTetra.m_apkVertex[3].m_pkPoint->X() = Mathf::Sqrt(1.0f/3.0f);
    rkTetra.m_apkVertex[3].m_pkPoint->Y() = Mathf::Sqrt(1.0f/3.0f);
    rkTetra.m_apkVertex[3].m_pkPoint->Z() = Mathf::Sqrt(1.0f/3.0f);
    rkTetra.m_apkVertex[3].m_iNumEdges = 3;
    rkTetra.m_apkVertex[3].m_apkEdge = new QuadricSurfacef::Edge*[3];
    rkTetra.m_apkVertex[3].m_apkEdge[0] = &rkTetra.m_apkEdge[3];
    rkTetra.m_apkVertex[3].m_apkEdge[1] = &rkTetra.m_apkEdge[4];
    rkTetra.m_apkVertex[3].m_apkEdge[2] = &rkTetra.m_apkEdge[5];

    // edges
    rkTetra.m_apkEdge[0].m_apkVertex[0] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkEdge[0].m_apkVertex[1] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkEdge[0].m_apkTriangle[0] = &rkTetra.m_apkTriangle[0];
    rkTetra.m_apkEdge[0].m_apkTriangle[1] = &rkTetra.m_apkTriangle[1];

    rkTetra.m_apkEdge[1].m_apkVertex[0] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkEdge[1].m_apkVertex[1] = &rkTetra.m_apkVertex[2];
    rkTetra.m_apkEdge[1].m_apkTriangle[0] = &rkTetra.m_apkTriangle[0];
    rkTetra.m_apkEdge[1].m_apkTriangle[1] = &rkTetra.m_apkTriangle[2];

    rkTetra.m_apkEdge[2].m_apkVertex[0] = &rkTetra.m_apkVertex[2];
    rkTetra.m_apkEdge[2].m_apkVertex[1] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkEdge[2].m_apkTriangle[0] = &rkTetra.m_apkTriangle[0];
    rkTetra.m_apkEdge[2].m_apkTriangle[1] = &rkTetra.m_apkTriangle[3];

    rkTetra.m_apkEdge[3].m_apkVertex[0] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkEdge[3].m_apkVertex[1] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkEdge[3].m_apkTriangle[0] = &rkTetra.m_apkTriangle[1];
    rkTetra.m_apkEdge[3].m_apkTriangle[1] = &rkTetra.m_apkTriangle[3];

    rkTetra.m_apkEdge[4].m_apkVertex[0] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkEdge[4].m_apkVertex[1] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkEdge[4].m_apkTriangle[0] = &rkTetra.m_apkTriangle[1];
    rkTetra.m_apkEdge[4].m_apkTriangle[1] = &rkTetra.m_apkTriangle[2];

    rkTetra.m_apkEdge[5].m_apkVertex[0] = &rkTetra.m_apkVertex[2];
    rkTetra.m_apkEdge[5].m_apkVertex[1] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkEdge[5].m_apkTriangle[0] = &rkTetra.m_apkTriangle[2];
    rkTetra.m_apkEdge[5].m_apkTriangle[1] = &rkTetra.m_apkTriangle[3];

    // triangles
    rkTetra.m_apkTriangle[0].m_apkVertex[0] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkTriangle[0].m_apkVertex[1] = &rkTetra.m_apkVertex[2];
    rkTetra.m_apkTriangle[0].m_apkVertex[2] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkTriangle[0].m_apkEdge[0] = &rkTetra.m_apkEdge[2];
    rkTetra.m_apkTriangle[0].m_apkEdge[1] = &rkTetra.m_apkEdge[1];
    rkTetra.m_apkTriangle[0].m_apkEdge[2] = &rkTetra.m_apkEdge[0];
    rkTetra.m_apkTriangle[0].m_apkAdjacent[0] = &rkTetra.m_apkTriangle[3];
    rkTetra.m_apkTriangle[0].m_apkAdjacent[1] = &rkTetra.m_apkTriangle[2];
    rkTetra.m_apkTriangle[0].m_apkAdjacent[2] = &rkTetra.m_apkTriangle[1];

    rkTetra.m_apkTriangle[1].m_apkVertex[0] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkTriangle[1].m_apkVertex[1] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkTriangle[1].m_apkVertex[2] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkTriangle[1].m_apkEdge[0] = &rkTetra.m_apkEdge[0];
    rkTetra.m_apkTriangle[1].m_apkEdge[1] = &rkTetra.m_apkEdge[4];
    rkTetra.m_apkTriangle[1].m_apkEdge[2] = &rkTetra.m_apkEdge[3];
    rkTetra.m_apkTriangle[1].m_apkAdjacent[0] = &rkTetra.m_apkTriangle[0];
    rkTetra.m_apkTriangle[1].m_apkAdjacent[1] = &rkTetra.m_apkTriangle[2];
    rkTetra.m_apkTriangle[1].m_apkAdjacent[2] = &rkTetra.m_apkTriangle[3];

    rkTetra.m_apkTriangle[2].m_apkVertex[0] = &rkTetra.m_apkVertex[1];
    rkTetra.m_apkTriangle[2].m_apkVertex[1] = &rkTetra.m_apkVertex[2];
    rkTetra.m_apkTriangle[2].m_apkVertex[2] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkTriangle[2].m_apkEdge[0] = &rkTetra.m_apkEdge[1];
    rkTetra.m_apkTriangle[2].m_apkEdge[1] = &rkTetra.m_apkEdge[5];
    rkTetra.m_apkTriangle[2].m_apkEdge[2] = &rkTetra.m_apkEdge[4];
    rkTetra.m_apkTriangle[2].m_apkAdjacent[0] = &rkTetra.m_apkTriangle[0];
    rkTetra.m_apkTriangle[2].m_apkAdjacent[1] = &rkTetra.m_apkTriangle[3];
    rkTetra.m_apkTriangle[2].m_apkAdjacent[2] = &rkTetra.m_apkTriangle[1];

    rkTetra.m_apkTriangle[3].m_apkVertex[0] = &rkTetra.m_apkVertex[0];
    rkTetra.m_apkTriangle[3].m_apkVertex[1] = &rkTetra.m_apkVertex[3];
    rkTetra.m_apkTriangle[3].m_apkVertex[2] = &rkTetra.m_apkVertex[2];

⌨️ 快捷键说明

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