You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
6.1 KiB
245 lines
6.1 KiB
//========= 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
|