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

📄 bspbrush.h

📁 3D游戏开发需要用到BSP树来经行场景渲染的管理。本代码包含完整的BSP及文件生成实现
💻 H
字号:
#pragma once

/*
	Brushes are responsible for creation and deletion of brushsides.
*/

#include "math.h"
#include "winding.h"
#include "brush.h"
#include "bspconv.h"

// TODO: faces could be reference-counted.
class _CBSPFace {
public:
	sPlane*			GetPlane();
	void			AddFaceRefencesToNodes(_CBSPTree *tree, bool alsoClipToVisible);
	void			Split(_CBSPFace* front, sPlane* plane);
	int				Emit(CBSP *bsp);

	CWinding		winding;
	CMapBrushSide*	brushSide;	// brush side that generated this face

private:
};

inline void _CBSPFace::Split(_CBSPFace* front, sPlane* plane) {
	front->brushSide = brushSide;
	winding.SplitWinding(front->winding, plane);
}

// Bridge; Adds face references and removes invisible parts of a face
class CBSPFaceClipper : public IBSPTreeVisitor {
public:
	// visitor interface
	void			VisitNodeBegin(_CBSPSplitNode *n);
	void			VisitNodeEnd(_CBSPSplitNode *n) {};
	void			VisitLeaf(_CBSPLeafNode *l);

	void			Clip(_CBSPTree *tree, _CBSPFace* target, bool addToConvexHull);
private:
	_CBSPFace*		targetFace;
	_CBSPFace*		clipFace;	// state
	bool			addToHull;
};



inline void CBSPFaceClipper::Clip(_CBSPTree *tree, _CBSPFace* target, bool addToConvexHull) {
	_CBSPFace clip(*target);
	targetFace = target;
	clipFace = &clip;
	addToHull = addToConvexHull;
	
	if(addToHull)
		targetFace->winding.GetPoints()->Clear();

	tree->Visit(this);
}

inline sPlane* _CBSPFace::GetPlane() {
	return brushSide->GetPlane();
}

inline void _CBSPFace::AddFaceRefencesToNodes(_CBSPTree *tree, bool alsoClipToVisible) {
	CBSPFaceClipper clipper;
	clipper.Clip(tree, this, alsoClipToVisible);
}

// NOTE: Contents of _CBSPBrush.faces are invalidated if
// CVector<_CBSPFace> reallocates storage.
class _CBSPBrush {
public:
				~_CBSPBrush();
	void		BuildBrush(CMapBrush *b);
	void		Condense();
	bool		IsValid();
	void		SplitBrush(_CBSPBrush *front, sPlane *plane);
	void		ClipSides(_CBSPTree *tree);
	_CBSPBrush&	operator=(_CBSPBrush& b); // allocates new faces

	int			FilterBrushAndMarkOpaqueNodes(_CBSPTree *tree);

	int			Emit(CBSP *bsp);

	CVector<_CBSPFace*>	faces;
};

inline _CBSPBrush::~_CBSPBrush() {
	for(int i=0; i<faces.GetNum(); i++)
		delete faces[i];
}

inline void _CBSPBrush::Condense() {
	for(int i=0; i<faces.GetNum(); i++)
		if(!faces[i]->winding.Empty()) {
			faces.Remove(i);
			i--;
		}
}

inline bool _CBSPBrush::IsValid() {
	for(int i=0; i<faces.GetNum(); i++)
		if(!faces[i]->winding.Empty())
			return true;
	return false;
}

class CBSPBrushFilter : public IBSPTreeVisitor {
public:	
	// visitor interface
	void		VisitNodeBegin(_CBSPSplitNode *n);
	void		VisitNodeEnd(_CBSPSplitNode *n) {};
	void		VisitLeaf(_CBSPLeafNode *l);

	int			FilterBrushAndMarkOpaqueNodes(_CBSPTree *tree, _CBSPBrush *t, _CBSPBrush *b);

private:

	_CBSPBrush*	target;
	_CBSPBrush*	clipBrush;
	int			nLeafs;

};

inline int _CBSPBrush::FilterBrushAndMarkOpaqueNodes(_CBSPTree *tree) {
	CBSPBrushFilter filter;
	_CBSPBrush *copy = new _CBSPBrush;
	*copy = *this;
	return filter.FilterBrushAndMarkOpaqueNodes(tree, this, copy);
}

inline int CBSPBrushFilter::FilterBrushAndMarkOpaqueNodes(_CBSPTree *tree, _CBSPBrush *t, _CBSPBrush *b) {
	target = t;
	clipBrush = b;
	nLeafs = 0;
	tree->Visit(this);
	return nLeafs;
}

⌨️ 快捷键说明

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