⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mesh.h

📁 游戏编程精粹2第四章源码
💻 H
📖 第 1 页 / 共 4 页
字号:
		pPt3->RemoveTri ( this );
		pPt3 = NULL;
	}
#if MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_TRIS
	else
	{
		// The only good reason is if this is a local var,
		// in which case everything should be NULL.
		ASSERT ( pEdge12 == NULL );
		ASSERT ( pEdge23 == NULL );
		ASSERT ( pEdge31 == NULL );
		ASSERT ( pPt1 == NULL );
		ASSERT ( pPt2 == NULL );
		ASSERT ( pPt3 == NULL );
	}
#endif

	ListDel();
}

inline MeshTri::~MeshTri ( void )
{
	InternalDelete ( FALSE );
}

inline MeshTri::Delete ( BOOL bBinUnusedEdges /*= FALSE*/ )
{
	InternalDelete ( bBinUnusedEdges );
	delete this;
}


inline void MeshTri::AddEdge ( MeshEdge *pEdge )
{
#if MESHCTRL_EDGES_ALWAYS_ADDED_BEFORE_TRIS
	// Can't mess with a tri's edges once created.
	ASSERT ( FALSE );
#else

	ASSERT ( pEdge != NULL );
	if ( ( ( pEdge->pPt1 == pPt1 ) && ( pEdge->pPt2 == pPt2 ) ) ||
		 ( ( pEdge->pPt2 == pPt1 ) && ( pEdge->pPt1 == pPt2 ) ) )
	{
		ASSERT ( pEdge12 == NULL );
		pEdge12 = pEdge;
	}
	else if ( ( ( pEdge->pPt1 == pPt2 ) && ( pEdge->pPt2 == pPt3 ) ) ||
			  ( ( pEdge->pPt2 == pPt2 ) && ( pEdge->pPt1 == pPt3 ) ) )
	{
		ASSERT ( pEdge23 == NULL );
		pEdge23 = pEdge;
	}
	else
	{
		ASSERT ( ( ( pEdge->pPt1 == pPt3 ) && ( pEdge->pPt2 == pPt1 ) ) ||
				 ( ( pEdge->pPt2 == pPt3 ) && ( pEdge->pPt1 == pPt1 ) ) );
		ASSERT ( pEdge31 == NULL );
		pEdge31 = pEdge;
	}
#endif
}

inline void MeshTri::RemoveEdge ( MeshEdge *pEdge )
{
	ASSERT ( pEdge != NULL );
	if ( pEdge12 == pEdge )
	{
		pEdge12 = NULL;
	}
	else if ( pEdge23 == pEdge )
	{
		pEdge23 = NULL;
	}
	else
	{
		ASSERT ( pEdge31 == pEdge );
		pEdge31 = NULL;
	}
}

inline void MeshTri::RemovePt ( MeshPt *pPt )
{
	ASSERT ( pPt != NULL );
	if ( pPt1 == pPt )
	{
		pPt1 = NULL;
	}
	else if ( pPt2 == pPt )
	{
		pPt2 = NULL;
	}
	else
	{
		ASSERT ( pPt3 == pPt );
		pPt3 = NULL;
	}
}


inline MeshTri *MeshTri::QueryList ( void )
{
	MeshTri *pListRoot = ListFindFirst();
	if ( pListRoot == this )
	{
		ASSERT ( ListFindLast() == this );
		pListRoot = NULL;
	}
	return ( pListRoot );
}

inline void MeshTri::SetList ( MeshTri *pListRoot )
{
	ListDel();
	if ( pListRoot != NULL )
	{
		ListAddAfter ( pListRoot );
	}
}

#define FAIL_CHECK() bRes = FALSE; ASSERT ( FALSE )
inline bool MeshTri::ConsistencyCheck ( MeshPt *pPtRoot, MeshEdge *pEdgeRoot, MeshTri *pTriRoot )
{
	bool bRes = TRUE;
	if ( ( pTriRoot != NULL ) && ( QueryList() != pTriRoot ) )
	{
		FAIL_CHECK();
	}

	if ( pEdge12 != NULL )
	{
		if ( ( pEdgeRoot != NULL ) && ( pEdge12->QueryList() != pEdgeRoot ) )
		{
			FAIL_CHECK();
		}
		
		if ( pEdge12->pTri12 == this )
		{
			if ( ( pEdge12->pPt1 != pPt1 ) || ( pEdge12->pPt2 != pPt2 ) )
			{
				FAIL_CHECK();
			}
		}
		else if ( pEdge12->pTri21 == this )
		{
			if ( ( pEdge12->pPt1 != pPt2 ) || ( pEdge12->pPt2 != pPt1 ) )
			{
				FAIL_CHECK();
			}
		}
		else
		{
			FAIL_CHECK();
		}
	}
	else
	{
		FAIL_CHECK();
	}

	if ( pEdge23 != NULL )
	{
		if ( ( pEdgeRoot != NULL ) && ( pEdge23->QueryList() != pEdgeRoot ) )
		{
			FAIL_CHECK();
		}
		
		if ( pEdge23->pTri12 == this )
		{
			if ( ( pEdge23->pPt1 != pPt2 ) || ( pEdge23->pPt2 != pPt3 ) )
			{
				FAIL_CHECK();
			}
		}
		else if ( pEdge23->pTri21 == this )
		{
			if ( ( pEdge23->pPt1 != pPt3 ) || ( pEdge23->pPt2 != pPt2 ) )
			{
				FAIL_CHECK();
			}
		}
		else
		{
			FAIL_CHECK();
		}
	}
	else
	{
		FAIL_CHECK();
	}

	if ( pEdge31 != NULL )
	{
		if ( ( pEdgeRoot != NULL ) && ( pEdge31->QueryList() != pEdgeRoot ) )
		{
			FAIL_CHECK();
		}
		
		if ( pEdge31->pTri12 == this )
		{
			if ( ( pEdge31->pPt1 != pPt3 ) || ( pEdge31->pPt2 != pPt1 ) )
			{
				FAIL_CHECK();
			}
		}
		else if ( pEdge31->pTri21 == this )
		{
			if ( ( pEdge31->pPt1 != pPt1 ) || ( pEdge31->pPt2 != pPt3 ) )
			{
				FAIL_CHECK();
			}
		}
		else
		{
			FAIL_CHECK();
		}
	}
	else
	{
		FAIL_CHECK();
	}

	if ( ( pPt1 == NULL ) || ( pPt2 == NULL ) || ( pPt3 == NULL ) )
	{
		FAIL_CHECK();
	}
	else
	{
		if ( pPtRoot != NULL )
		{
			if ( pPt1->QueryList() != pPtRoot )
			{
				FAIL_CHECK();
			}
			if ( pPt2->QueryList() != pPtRoot )
			{
				FAIL_CHECK();
			}
			if ( pPt3->QueryList() != pPtRoot )
			{
				FAIL_CHECK();
			}
		}

// Multiple tris that have this order may exist - can't be arsed to
// do a FirstTri/NextTri search.
#if 0
		if ( pPt1->FindTri ( pPt2 ) != this )
		{
			FAIL_CHECK();
		}
		if ( pPt2->FindTri ( pPt3 ) != this )
		{
			FAIL_CHECK();
		}
		if ( pPt3->FindTri ( pPt1 ) != this )
		{
			FAIL_CHECK();
		}
#endif

// Falls over if more than one edge has these points.
// Can happen if more than two tris meet on one edge.
#if 0
		if ( pPt1->FindEdge ( pPt2 ) != pEdge12 )
		{
			FAIL_CHECK();
		}
		if ( pPt2->FindEdge ( pPt3 ) != pEdge23 )
		{
			FAIL_CHECK();
		}
		if ( pPt3->FindEdge ( pPt1 ) != pEdge31 )
		{
			FAIL_CHECK();
		}
#endif
	}

	return ( bRes );
}










inline MeshEdge::MeshEdge ( void )
{
	pPt1 = NULL;
	pPt2 = NULL;
	pTri12 = NULL;
	pTri21 = NULL;
	pEdgeProx = NULL;
	ListInit();
}

inline MeshEdge::MeshEdge ( MeshPt *pNewPt1, MeshPt *pNewPt2, MeshEdge *pListRoot )
{
	ASSERT ( pNewPt1 != NULL );
	ASSERT ( pNewPt2 != NULL );
	pPt1 = pNewPt1;
	pPt2 = pNewPt2;
	pTri12 = NULL;
	pTri21 = NULL;
	pEdgeProx = NULL;

	pPt1->AddEdge ( this );
	pPt2->AddEdge ( this );

#if MESHCTRL_EDGES_ALWAYS_ADDED_BEFORE_TRIS
	// No auto-adding of tris.
#else
	pTri12 = pPt1->FindTri ( pPt2 );
	if ( pTri12 != NULL )
	{
		pTri12->AddEdge ( this );
	}
	pTri21 = pPt2->FindTri ( pPt1 );
	if ( pTri21 != NULL )
	{
		pTri21->AddEdge ( this );
	}
#endif

	ListInit();
	if ( pListRoot != NULL )
	{
		ListAddAfter ( pListRoot );
	}
}

inline MeshEdge::~MeshEdge ( void )
{
	RemoveProx();

	if ( pPt1 != NULL )
	{
		MeshPt *pPt = pPt1;
		RemovePt ( pPt );
		pPt->RemoveEdge ( this );
	}
#if MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_EDGES
	else
	{
		// The only good reason is if this is a local var,
		// in which case everything should be NULL.
		ASSERT ( pPt1 == NULL );
		ASSERT ( pPt2 == NULL );
		ASSERT ( pTri12 == NULL );
		ASSERT ( pTri21 == NULL );
	}
#endif


	if ( pPt2 != NULL )
	{
		MeshPt *pPt = pPt2;
		RemovePt ( pPt );
		pPt->RemoveEdge ( this );
	}
#if MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_EDGES
	else
	{
		// The only good reason is if this is a local var,
		// in which case everything should be NULL.
		ASSERT ( pPt1 == NULL );
		ASSERT ( pPt2 == NULL );
		ASSERT ( pTri12 == NULL );
		ASSERT ( pTri21 == NULL );
	}
#endif


#if MESHCTRL_EDGES_ALWAYS_ADDED_BEFORE_TRIS
	// Any tri should have been binned already
	ASSERT ( pTri12 == NULL );
	ASSERT ( pTri21 == NULL );
#else
	if ( pTri12 != NULL )
	{
		MeshTri *pTri = pTri12;
		RemoveTri ( pTri );
		pTri->RemoveEdge ( this );
	}

	if ( pTri21 != NULL )
	{
		MeshTri *pTri = pTri21;
		RemoveTri ( pTri );
		pTri->RemoveEdge ( this );
	}
#endif

	ListDel();
}


// Remove this edge from the tri.
inline void MeshEdge::RemoveTri ( MeshTri *pTri )
{
	ASSERT ( pTri != NULL );
	if ( pTri12 == pTri )
	{
		pTri12 = NULL;
	}
	else
	{
		ASSERT ( pTri21 == pTri );
		pTri21 = NULL;
	}
}

// Remove this edge from the pt.
inline void MeshEdge::RemovePt ( MeshPt *pPt )
{
	ASSERT ( pPt != NULL );
	if ( pPt1 == pPt )
	{
		pPt1 = NULL;
	}
	else
	{
		ASSERT ( pPt2 == pPt );
		pPt2 = NULL;
	}
}

inline void MeshEdge::AddTri ( MeshTri *pTri )
{
	ASSERT ( pTri != NULL );
	// Assumes the tri's pt pointers have already been set up.
	if ( ( ( pPt1 == pTri->pPt1 ) && ( pPt2 == pTri->pPt2 ) ) ||
		 ( ( pPt1 == pTri->pPt2 ) && ( pPt2 == pTri->pPt3 ) ) ||
		 ( ( pPt1 == pTri->pPt3 ) && ( pPt2 == pTri->pPt1 ) ) )
	{
		ASSERT ( pTri12 == NULL );
		pTri12 = pTri;
	}
	else
	{
		ASSERT ( ( ( pPt1 == pTri->pPt2 ) && ( pPt2 == pTri->pPt1 ) ) ||
				 ( ( pPt1 == pTri->pPt3 ) && ( pPt2 == pTri->pPt2 ) ) ||
				 ( ( pPt1 == pTri->pPt1 ) && ( pPt2 == pTri->pPt3 ) ) );
		ASSERT ( pTri21 == NULL );
		pTri21 = pTri;
	}
}

// Returns the other triangle that uses this edge.
inline MeshTri *MeshEdge::OtherTri ( MeshTri *pTri )
{
	ASSERT ( pTri != NULL );
	if ( pTri == pTri12 )
	{
		return ( pTri21 );
	}
	else
	{
		ASSERT ( pTri == pTri21 );
		return ( pTri12 );
	}
}

inline MeshPt *MeshEdge::OtherPt ( MeshPt *pPt )
{
	ASSERT ( pPt != NULL );
	if ( pPt == pPt1 )
	{
		return ( pPt2 );
	}
	else
	{
		ASSERT ( pPt == pPt2 );
		return ( pPt1 );
	}
}

// Try to merge these two edges. Result is TRUE if it succeeded - note that the other edge will be NOT deleted.
inline bool MeshEdge::bTryToMergeEdges ( MeshEdge *pedge )
{
	ASSERT ( pedge != this );
	if ( pPt1 == pedge->pPt1 )
	{
		ASSERT ( pPt2 == pedge->pPt2 );
		if ( ( pTri12 == NULL ) && ( pedge->pTri21 == NULL ) &&
			 ( ( pEdgeProx == NULL ) || ( pedge->pEdgeProx == NULL ) ) )
		{
			// Merge them.
			pTri12 = pedge->pTri12;
			if ( pTri12 != NULL )
			{
				if ( pTri12->pEdge12 == pedge )
				{
					pTri12->pEdge12 = this;
				}
				else if ( pTri12->pEdge23 == pedge )
				{
					pTri12->pEdge23 = this;
				}
				else
				{
					ASSERT ( pTri12->pEdge31 == pedge );
					pTri12->pEdge31 = this;
				}
			}
			pedge->pTri12 = NULL;
			if ( pedge->pEdgeProx != NULL )
			{
				ASSERT ( pEdgeProx == NULL );
				pEdgeProx = pedge->pEdgeProx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -