diff options
Diffstat (limited to 'hammer/subdiv.h')
| -rw-r--r-- | hammer/subdiv.h | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/hammer/subdiv.h b/hammer/subdiv.h new file mode 100644 index 0000000..8ef1503 --- /dev/null +++ b/hammer/subdiv.h @@ -0,0 +1,245 @@ +//========= Copyright 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
\ No newline at end of file |