|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SUBDIV_H
#define SUBDIV_H
#pragma once
class CMapDisp; class CSubdivEdge; class CSubdivQuad;
//=============================================================================
//
// Class Subdivision Point
//
class CSubdivPoint { public:
enum { POINT_ORDINARY = 0, POINT_CORNER = 1, POINT_CREASE = 2 }; enum { NUM_SUBDIV_EDGES = 8 };
Vector m_Point; Vector m_Normal; Vector m_NewPoint; Vector m_NewNormal; int m_Type; int m_Valence; CSubdivEdge *m_pEdges[NUM_SUBDIV_EDGES];
void Clear( void ); void Copy( const CSubdivPoint *pFrom );
void CalcNewVertexPoint( void ); void CalcNewVertexNormal( void );
friend bool CompareSubdivPoints( const CSubdivPoint *pPoint1, const CSubdivPoint *pPoint2, float tolerance ); friend bool CompareSubdivPointToPoint( const CSubdivPoint *pSubdivPoint, const Vector& point, float tolerance ); };
//=============================================================================
//
// Class Subdivision Edge
//
class CSubdivEdge { public:
short m_ndxPoint[2]; CSubdivQuad *m_pQuads[2]; short m_ndxQuadEdge[2]; float m_Sharpness; Vector m_NewEdgePoint; Vector m_NewEdgeNormal; bool m_Active;
void Clear( void ); void Copy( const CSubdivEdge *pFrom );
void CalcNewEdgePoint( void ); void CalcNewEdgeNormal( void );
friend bool CompareSubdivEdges( const CSubdivEdge *pEdge1, const CSubdivEdge *pEdge2 ); };
//=============================================================================
//
// Class Subdivision Quad
//
class CSubdivQuad { public:
short m_ndxQuad[4]; // quad indices -- see CSubdivManager
short m_ndxVert[4]; // vert indices -- see CSubdivManager
short m_ndxEdge[4]; // edge indices -- see CSubdivManager
Vector m_Centroid; // center of quad
Vector m_Normal; // quad normal
void GetCentroid( Vector& centroid ); void CalcCentroid( void );
void GetNormal( Vector& normal ); void CalcNormal( void ); };
//=============================================================================
//
// Class Subdivision Mesh
//
class CSubdivMesh { public:
//=========================================================================
//
// Creation/Destruction
//
CSubdivMesh(); ~CSubdivMesh();
//=========================================================================
//
//
//
inline void Clear( void ); void DoSubdivide( void );
//=========================================================================
//
//
//
inline int GetPointCount( void ); int AddPoint( const Vector& point, const Vector& normal ); void RemovePoint( Vector& point ); inline void GetPoint( int index, Vector& point ); inline void GetNormal( int index, Vector& normal );
inline int GetEdgeCount( void ); int AddEdge( CSubdivEdge *edge ); void RemoveEdge( CSubdivEdge *edge ); inline void GetEdge( int index, CSubdivEdge *edge );
private:
// enum { MAX_SUBDIV_POINTS = 32000 };
// enum { MAX_TREES = 64 };
int m_PointCount; int m_MaxPointCount; CSubdivPoint *m_pPoints; // CSubdivPoint m_Points[MAX_SUBDIV_POINTS]; // mesh list of subdivision verts
int m_EdgeCount; int m_MaxEdgeCount; CSubdivEdge *m_pEdges; // CSubdivEdge m_Edges[MAX_SUBDIV_POINTS]; // mesh list of subdivision edges
int m_TreeCount; int m_MaxTreeCount; CSubdivQuad **m_ppTrees; // CSubdivQuad *m_pTrees[MAX_TREES];
void CatmullClarkSubdivide( void ); int AddTree( CSubdivQuad *pTree ); int GetStartIndexFromLevel( int levelIndex ); int GetEndIndexFromLevel( int levelIndex ); void AddQuadToMesh( CSubdivQuad *pQuad );
inline void ClearEdges( void );
void CreateChildQuads( CSubdivQuad *pRoot, int quadIndex ); void SetEdgeData( CSubdivQuad *pRoot, int index, int parentIndex, int subdivIndex ); void CreateChildQuad1( CSubdivQuad *pRoot, int index, int parentIndex ); void CreateChildQuad2( CSubdivQuad *pRoot, int index, int parentIndex ); void CreateChildQuad3( CSubdivQuad *pRoot, int index, int parentIndex ); void CreateChildQuad4( CSubdivQuad *pRoot, int index, int parentIndex );
bool PreSubdivide( void ); void Subdivide( void ); void PostSubdivide( void );
bool AllocCache( int dispCount ); void FreeCache( void ); };
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CSubdivMesh::Clear( void ) { m_PointCount = 0; m_EdgeCount = 0; m_TreeCount = 0; m_MaxPointCount = 0; m_MaxEdgeCount = 0; m_MaxTreeCount = 0;
m_pPoints = NULL; m_pEdges = NULL; m_ppTrees = NULL; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline int CSubdivMesh::GetPointCount( void ) { return m_PointCount; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CSubdivMesh::GetPoint( int index, Vector& point ) { assert( index >= 0 ); assert( index < m_PointCount );
point = m_pPoints[index].m_Point; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CSubdivMesh::GetNormal( int index, Vector& normal ) { assert( index >= 0 ); assert( index < m_PointCount );
normal = m_pPoints[index].m_Normal; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline int CSubdivMesh::GetEdgeCount( void ) { return m_EdgeCount; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void CSubdivMesh::GetEdge( int index, CSubdivEdge *edge ) { assert( index >= 0 ); assert( index < m_EdgeCount );
edge->Copy( &m_pEdges[index] ); }
#endif // SUBDIV_H
|