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
5 years ago
|
//========= 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
|