📄 spheretessellation.cpp
字号:
// 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 + -