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

📄 brush.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	while (pBrush != NULL)
	{
		BrushList_Remove (pList, pBrush);
		Brush_Destroy(&pBrush);
		pBrush = BrushList_GetNext (&bi);
	}
}

Brush *BrushList_GetFirst 
	(
	  BrushList *pList, 
	  BrushIterator *bi
	 )
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_GetFirst", MB_OK);
		return NULL;
	}

	assert (pList != NULL);
	assert (bi != NULL);


	
	if (pList->First == NULL)
	{
	
		*bi = NULL;
	}
	else
	{
		*bi = pList->First->Next;
	}
	return pList->First;
}

Brush *BrushList_GetNext 
	(
	  BrushIterator *bi
	)
{
	assert (bi != NULL);

	if (*bi == NULL)
	{
		return NULL;
	}
	else
	{
		Brush *b;

		b = *bi;
		*bi = (*bi)->Next;

		return b;
	}
}

Brush *BrushList_GetLast
	(
	  BrushList *pList, 
	  BrushIterator *bi
	 )
{
	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_GetLast", MB_OK);
		return NULL;
	}

	assert (pList != NULL);
	assert (bi != NULL);

	if (pList->Last == NULL)
	{
		*bi = NULL;
	}
	else
	{
		*bi = pList->Last->Prev;
	}
	return pList->Last;
}

Brush *BrushList_GetPrev
	(
	  BrushIterator *bi
	)
{
	assert (bi != NULL);

	if (*bi == NULL)
	{
		return NULL;
	}
	else
	{
		Brush *b;

		b = *bi;
		*bi = (*bi)->Prev;
		return b;
	}
}

int BrushList_Count
	(
	  BrushList const *pList,
	  int CountFlags
	)
{
	int Count;
	Brush *b;
//	geBoolean bResult = GE_TRUE;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_Count", MB_OK);
		return 0;
	}
	
	assert (pList != NULL);

	Count = 0;

	b = pList->First;
	while (b != NULL)
	{
		geBoolean CountIt;
		switch (b->Type)
		{
			case BRUSH_MULTI :
				CountIt = (CountFlags & BRUSH_COUNT_MULTI);
				break;

			case BRUSH_LEAF :
				CountIt = (CountFlags & BRUSH_COUNT_LEAF);
				break;

			case BRUSH_CSG :
				CountIt = (CountFlags & BRUSH_COUNT_CSG);
				break;

			default :
				assert (0);
				CountIt = GE_FALSE;
				break;
		}
		if (CountIt)
		{
			++Count;
		}

		if ((b->Type == BRUSH_MULTI) && (!(CountFlags & BRUSH_COUNT_NORECURSE)))
		{
			Count += BrushList_Count (b->BList, CountFlags);
		}
		b = b->Next;
	}

	return Count;
}

// call CallBack for top level brushes in the list...
geBoolean BrushList_Enum
	(
		BrushList const *pList,
		void *			lParam,
		BrushList_CB	CallBack
	)
{
	geBoolean bResult = GE_TRUE ;	// TRUE means entire list was processed
	Brush * b;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_Enum", MB_OK);
		return GE_FALSE;
	}

	assert (pList != NULL);

	b = pList->First;
	while (b != NULL)
	{
		if( (bResult = CallBack( b, lParam )) == GE_FALSE )
			break ;		
		b = b->Next;
	}
	return bResult ;
}

// call CallBack for all brushes in the list...
geBoolean BrushList_EnumAll
	(
		BrushList const *pList,
		void *			lParam,
		BrushList_CB	CallBack
	)
{
	geBoolean bResult = GE_TRUE ;	// TRUE means entire list was processed
	Brush * b;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_EnumAll", MB_OK);
		return GE_FALSE;
	}

	assert (pList != NULL);

	b = pList->First;
	while (b != NULL)
	{
		if( (bResult = CallBack( b, lParam )) == GE_FALSE )
			break ;		
		if (b->Type == BRUSH_MULTI)
		{
			bResult = BrushList_EnumAll (b->BList, lParam, CallBack);
			if (!bResult)
			{
				break;
			}
		}
		b = b->Next;
	}
	return bResult ;
}

//traverses inorder 
int	BrushList_EnumLeafBrushes(const BrushList	*pList,
							  void *			pVoid,
							  BrushList_CB		CallBack)
{
	geBoolean	bResult	=GE_TRUE;	// TRUE means entire list was processed
	Brush		*b;

	if (pList == NULL)		//	post 0.55
	{
		MessageBox(NULL, "pList == NULL", "BrushList_EnumLeafBrushes", MB_OK);
		return 0;
	}

	
	assert(pList != NULL);

	for(b=pList->First;b;b=b->Next)
	{
		assert(b->Type!=BRUSH_CSG);

		if(b->Type==BRUSH_MULTI)
		{
			if(!BrushList_EnumLeafBrushes(b->BList, pVoid, CallBack))
			{
				break;
			}
		}
		else if( (bResult = CallBack( b, pVoid )) == GE_FALSE )
		{
			break;
		}
	}
	return bResult ;
}

//grabs csg brushes and leafs with no children
//the exception being hollows which are all based
//on a parent multi and might contain a hollowcut
int	BrushList_EnumCSGBrushes(const BrushList	*pList,
							  void *			pVoid,
							  BrushList_CB		CallBack)
{
	geBoolean	bResult	=GE_TRUE;	// TRUE means entire list was processed
	Brush		*b;

	assert(pList != NULL);

	for(b=pList->First;b && bResult;b=b->Next)
	{
		switch (b->Type)
		{
			case BRUSH_MULTI :
				bResult = BrushList_EnumCSGBrushes (b->BList, pVoid, CallBack);
				break;
			case BRUSH_LEAF :
				if (b->BList)
				{
					bResult = BrushList_EnumCSGBrushes (b->BList, pVoid, CallBack);
				}
				else
				{
					if(!(b->Flags & (BRUSH_HOLLOW | BRUSH_HOLLOWCUT)))
					{
						bResult = CallBack (b, pVoid);
					}
				}
				break;
			case BRUSH_CSG :
				bResult = CallBack (b, pVoid);
				break;
			default :
				assert (0);		// bad brush type
				bResult = GE_FALSE;
				break;
		}
	}
	return bResult ;
}

geBoolean	Brush_GetParent(const BrushList	*pList,		//list to search
							const Brush		*b,			//brush to find
							Brush			**bParent)	//parent returned
{
	Brush	*b2;

	assert(b);
	assert(pList);
	assert(bParent);

	for(b2=pList->First;b2;b2=b2->Next)

	{
		if(b2==b)
		{
			*bParent	=(Brush *)b;	//const override!
			return		GE_TRUE;
		}

		if(b2->Type==BRUSH_LEAF)
		{
			if(b2->BList)
			{
				if(Brush_GetParent(b2->BList, b, bParent))
				{
					*bParent	=b2;
					return		GE_TRUE;
				}
			}
		}
		else if(b2->Type==BRUSH_MULTI)
		{
			if(Brush_GetParent(b2->BList, b, bParent))
			{
				*bParent	=b2;
				return		GE_TRUE;
			}
		}
	}
	return	GE_FALSE;

}


Brush *	Brush_GetTopLevelParent 
	(
	  const BrushList	*pList,		//list to search
	  const Brush		*b			//brush to find
	)
{
	Brush const *bWork;
	Brush *pImmediateParent;

	bWork = b;

	while (Brush_GetParent (pList, bWork, &pImmediateParent) == GE_TRUE)
	{
		if (bWork == pImmediateParent)
		{
			break;
		}
		bWork = pImmediateParent;
	}
	return (Brush *)bWork;
}


static geBoolean	Brush_SelectMatchingFace(Brush *b, Face *f, Face **pMatchingFace)
{
	Face		*f2;
	const Plane	*p, *p2;
	int			i;

	assert(b);

	p	=Face_GetPlane(f);
	for(i=0;i < FaceList_GetNumFaces(b->Faces);i++)
	{
		f2	=FaceList_GetFace(b->Faces, i);
		p2	=Face_GetPlane(f2);

		if(b->Flags & BRUSH_SUBTRACT)
		{
			geVec3d	InvNorm	=p2->Normal;
			geVec3d_Inverse(&InvNorm);

			if(geVec3d_Compare(&p->Normal, &InvNorm, 0.01f))
			{
				if(((p->Dist + p2->Dist) > -0.01f)&&((p->Dist + p2->Dist) < 0.01f))
				{
					Face_SetSelected(f2, GE_TRUE);
					*pMatchingFace = f2;
					return	GE_TRUE;
				}
			}
		}
		else
		{
			if(geVec3d_Compare(&p->Normal, &p2->Normal, 0.01f))
			{
				if(((p->Dist - p2->Dist) > -0.01f)&&((p->Dist - p2->Dist) < 0.01f))
				{
					Face_SetSelected(f2, GE_TRUE);
					*pMatchingFace = f2;
					return	GE_TRUE;
				}
			}
		}
	}
	return	GE_FALSE;
}


static geBoolean	BrushList_SelectMatchingCutFace
	(
		const BrushList	*pList,
		const Brush		*b,
		Face			*f,
		Brush			**CutBrush,
		Face			**pMatchingFace
	)
{
	Brush	*cb;

	assert(b);
	assert(CutBrush);
	assert(pList);
	assert(f);

	if(b->Type==BRUSH_LEAF)
	{
		for(cb=pList->Last;cb;cb=cb->Prev)
		{
			if(cb==b)
			{
				break;
			}
			if(Brush_TestBoundsIntersect(b, &cb->BoundingBox))
			{
				if(cb->Type==BRUSH_MULTI)
				{
					if(BrushList_SelectMatchingCutFace(cb->BList, b, f, CutBrush, pMatchingFace))
					{
						return	GE_TRUE;
					}
				}
				else if(cb->Flags & BRUSH_SUBTRACT)
				{
					if(Brush_SelectMatchingFace(cb, f, pMatchingFace))
					{
						*CutBrush	=cb;
						return		GE_TRUE;
					}
				}
			}
		}
	}
	return	GE_FALSE;
}

Brush * BrushList_FindFaceParent (const BrushList *pList, const Face *pFace)
{
	Brush *pBrush;

	for (pBrush = pList->First; pBrush != NULL; pBrush = pBrush->Next)
	{
		switch (pBrush->Type)

		{
			case BRUSH_MULTI :
			{
				Brush *pFound;

				pFound = BrushList_FindFaceParent (pBrush->BList, pFace);
				if (pFound != NULL)
				{
					return pFound;
				}
				break;
			}
			case BRUSH_LEAF :
			case BRUSH_CSG :




			{
				int i;
				for(i=0;i < Brush_GetNumFaces(pBrush);i++)


				{
					Face	*pCheckFace;

					pCheckFace = Brush_GetFace (pBrush, i);
					if (pFace == pCheckFace)
					{
						return pBrush;
					}
				}
				break;;
			}
			default :
				assert (0);
				break;
		}
	}
	return NULL;
}

Brush * BrushList_FindTopLevelFaceParent (const BrushList *pList, const Face *pFace)
{
	Brush *bFound;

	bFound = BrushList_FindFaceParent (pList, pFace);
	if (bFound != NULL)
	{
		bFound = Brush_GetTopLevelParent (pList, bFound);
	}
	return bFound;
}

static	geFloat		dists[256];
static	uint8		sides[256];
static	uint8		fsides[256];

enum SideFlags
{
	SIDE_FRONT	=0,
	SIDE_BACK	=1,
	SIDE_ON		=2,
	SIDE_SPLIT	=3
};


//handle cases where two brushes share a coplanar face
static int	Brush_MostlyOnSide(const Brush *b, const Plane *p)
{
	int		i, side;
	geFloat	max;

	max		=0;
	side	=SIDE_FRONT;
	for(i=0;i < FaceList_GetNumFaces(b->Faces);i++)
	{
		Face_MostlyOnSide(FaceList_GetFace(b->Faces, i), p, &max, &side);
	}
	return	side;
}

//Split the original brush by the face passed in returning
//the brush in front of and the brush behind the 
//face passed in.  
//front and back brush pointers should be null on entry
void	Brush_SplitByFace(Brush	*ogb,	//original brush
						  Face	*sf,	//split face
						  Brush	**fb,	//front brush
						  Brush	**bb)	//back brush
{
	const Plane	*p;
	int			i;
	uint8		cnt[3], fcnt[4];
	FaceList	*fl, *bl;
	const Face	*f;
	Face		*cpf, *ff, *bf, *midf;
	geBoolean	WasSplit	=GE_FALSE;

	assert(ogb);
	assert

⌨️ 快捷键说明

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