📄 bspbrush.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 + -