move calculatesurfaceinfo into a member func
This commit is contained in:
parent
5dd2deba8e
commit
5f81657621
|
|
@ -42,6 +42,88 @@
|
|||
#include <common/bspfile.hh>
|
||||
#include <common/aabb.hh>
|
||||
|
||||
enum texcoord_style_t
|
||||
{
|
||||
TX_QUAKED = 0,
|
||||
TX_QUARK_TYPE1 = 1,
|
||||
TX_QUARK_TYPE2 = 2,
|
||||
TX_VALVE_220 = 3,
|
||||
TX_BRUSHPRIM = 4
|
||||
};
|
||||
|
||||
enum class conversion_t
|
||||
{
|
||||
quake,
|
||||
quake2,
|
||||
valve,
|
||||
bp
|
||||
};
|
||||
|
||||
class options_t
|
||||
{
|
||||
public:
|
||||
bool fNofill = false;
|
||||
bool fNoclip = false;
|
||||
bool fNoskip = false;
|
||||
bool fNodetail = false;
|
||||
bool fOnlyents = false;
|
||||
bool fConvertMapFormat = false;
|
||||
conversion_t convertMapFormat = conversion_t::quake;
|
||||
bool fVerbose = true;
|
||||
bool fAllverbose = false;
|
||||
bool fSplitspecial = false;
|
||||
bool fSplitturb = false;
|
||||
bool fSplitsky = false;
|
||||
bool fTranswater = true;
|
||||
bool fTranssky = false;
|
||||
bool fOldaxis = true;
|
||||
bool fNoverbose = false;
|
||||
bool fNopercent = false;
|
||||
bool forceGoodTree = false;
|
||||
bool fixRotateObjTexture = true;
|
||||
bool fbspx_brushes = false;
|
||||
bool fNoTextures = false;
|
||||
const bspversion_t *target_version = &bspver_q1;
|
||||
const gamedef_t *target_game = target_version->game;
|
||||
int dxSubdivide = 240;
|
||||
int dxLeakDist = 2;
|
||||
int maxNodeSize = 1024;
|
||||
/**
|
||||
* if 0 (default), use maxNodeSize for deciding when to switch to midsplit bsp heuristic.
|
||||
*
|
||||
* if 0 < midsplitSurfFraction <=1, switch to midsplit if the node contains more than this fraction of the model's
|
||||
* total surfaces. Try 0.15 to 0.5. Works better than maxNodeSize for maps with a 3D skybox (e.g. +-128K unit maps)
|
||||
*/
|
||||
float midsplitSurfFraction = 0.f;
|
||||
std::filesystem::path szMapName;
|
||||
std::filesystem::path szBSPName;
|
||||
|
||||
struct wadpath
|
||||
{
|
||||
std::filesystem::path path;
|
||||
bool external; // wads from this path are not to be embedded into the bsp, but will instead require the engine
|
||||
// to load them from elsewhere. strongly recommended for eg halflife.wad
|
||||
};
|
||||
|
||||
std::vector<wadpath> wadPathsVec;
|
||||
vec_t on_epsilon = 0.0001;
|
||||
bool fObjExport = false;
|
||||
bool fOmitDetail = false;
|
||||
bool fOmitDetailWall = false;
|
||||
bool fOmitDetailIllusionary = false;
|
||||
bool fOmitDetailFence = false;
|
||||
bool fForcePRT1 = false;
|
||||
bool fTestExpand = false;
|
||||
bool fLeakTest = false;
|
||||
bool fContentHack = false;
|
||||
vec_t worldExtent = 65536.0f;
|
||||
bool fNoThreads = false;
|
||||
bool includeSkip = false;
|
||||
bool fNoTJunc = false;
|
||||
};
|
||||
|
||||
extern options_t options;
|
||||
|
||||
/*
|
||||
* Clipnodes need to be stored as a 16-bit offset. Originally, this was a
|
||||
* signed value and only the positive values up to 32767 were available. Since
|
||||
|
|
@ -149,14 +231,39 @@ struct surface_t
|
|||
surface_t *next;
|
||||
int planenum;
|
||||
std::optional<size_t> outputplanenum; // only valid after WriteSurfacePlanes
|
||||
aabb3d bounds;
|
||||
bool onnode; // true if surface has already been used
|
||||
// as a splitting node
|
||||
bool detail_separator; // true if ALL faces are detail
|
||||
face_t *faces; // links to all faces on either side of the surf
|
||||
bool has_detail; // 1 if the surface has detail brushes
|
||||
bool has_struct; // 1 if the surface has non-detail brushes
|
||||
|
||||
// bounds of all the face windings; calculated via calculateInfo
|
||||
aabb3d bounds;
|
||||
// 1 if the surface has non-detail brushes; calculated via calculateInfo
|
||||
bool has_struct;
|
||||
// smallest lmshift of all faces; calculated via calculateInfo
|
||||
short lmshift;
|
||||
|
||||
// calculate bounds & info
|
||||
inline void calculateInfo()
|
||||
{
|
||||
bounds = {};
|
||||
lmshift = std::numeric_limits<short>::max();
|
||||
|
||||
for (const face_t *f = faces; f; f = f->next) {
|
||||
for (auto &contents : f->contents)
|
||||
if (!contents.is_valid(options.target_game, false))
|
||||
FError("Bad contents in face: {}", contents.to_string(options.target_game));
|
||||
|
||||
lmshift = min(f->lmshift.front, f->lmshift.back);
|
||||
|
||||
has_struct = !((f->contents[0].extended | f->contents[1].extended) &
|
||||
(CFLAGS_DETAIL | CFLAGS_DETAIL_ILLUSIONARY | CFLAGS_DETAIL_FENCE | CFLAGS_WAS_ILLUSIONARY));
|
||||
|
||||
bounds += f->w.bounds();
|
||||
|
||||
Q_assert(!qv::emptyExact(bounds.size()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// there is a node_t structure for every node and leaf in the bsp tree
|
||||
|
|
@ -202,89 +309,6 @@ struct node_t
|
|||
#include <qbsp/region.hh>
|
||||
#include <qbsp/writebsp.hh>
|
||||
#include <qbsp/outside.hh>
|
||||
|
||||
enum texcoord_style_t
|
||||
{
|
||||
TX_QUAKED = 0,
|
||||
TX_QUARK_TYPE1 = 1,
|
||||
TX_QUARK_TYPE2 = 2,
|
||||
TX_VALVE_220 = 3,
|
||||
TX_BRUSHPRIM = 4
|
||||
};
|
||||
|
||||
enum class conversion_t
|
||||
{
|
||||
quake,
|
||||
quake2,
|
||||
valve,
|
||||
bp
|
||||
};
|
||||
|
||||
class options_t
|
||||
{
|
||||
public:
|
||||
bool fNofill = false;
|
||||
bool fNoclip = false;
|
||||
bool fNoskip = false;
|
||||
bool fNodetail = false;
|
||||
bool fOnlyents = false;
|
||||
bool fConvertMapFormat = false;
|
||||
conversion_t convertMapFormat = conversion_t::quake;
|
||||
bool fVerbose = true;
|
||||
bool fAllverbose = false;
|
||||
bool fSplitspecial = false;
|
||||
bool fSplitturb = false;
|
||||
bool fSplitsky = false;
|
||||
bool fTranswater = true;
|
||||
bool fTranssky = false;
|
||||
bool fOldaxis = true;
|
||||
bool fNoverbose = false;
|
||||
bool fNopercent = false;
|
||||
bool forceGoodTree = false;
|
||||
bool fixRotateObjTexture = true;
|
||||
bool fbspx_brushes = false;
|
||||
bool fNoTextures = false;
|
||||
const bspversion_t *target_version = &bspver_q1;
|
||||
const gamedef_t *target_game = target_version->game;
|
||||
int dxSubdivide = 240;
|
||||
int dxLeakDist = 2;
|
||||
int maxNodeSize = 1024;
|
||||
/**
|
||||
* if 0 (default), use maxNodeSize for deciding when to switch to midsplit bsp heuristic.
|
||||
*
|
||||
* if 0 < midsplitSurfFraction <=1, switch to midsplit if the node contains more than this fraction of the model's
|
||||
* total surfaces. Try 0.15 to 0.5. Works better than maxNodeSize for maps with a 3D skybox (e.g. +-128K unit maps)
|
||||
*/
|
||||
float midsplitSurfFraction = 0.f;
|
||||
std::filesystem::path szMapName;
|
||||
std::filesystem::path szBSPName;
|
||||
|
||||
struct wadpath
|
||||
{
|
||||
std::filesystem::path path;
|
||||
bool external; // wads from this path are not to be embedded into the bsp, but will instead require the engine
|
||||
// to load them from elsewhere. strongly recommended for eg halflife.wad
|
||||
};
|
||||
|
||||
std::vector<wadpath> wadPathsVec;
|
||||
vec_t on_epsilon = 0.0001;
|
||||
bool fObjExport = false;
|
||||
bool fOmitDetail = false;
|
||||
bool fOmitDetailWall = false;
|
||||
bool fOmitDetailIllusionary = false;
|
||||
bool fOmitDetailFence = false;
|
||||
bool fForcePRT1 = false;
|
||||
bool fTestExpand = false;
|
||||
bool fLeakTest = false;
|
||||
bool fContentHack = false;
|
||||
vec_t worldExtent = 65536.0f;
|
||||
bool fNoThreads = false;
|
||||
bool includeSkip = false;
|
||||
bool fNoTJunc = false;
|
||||
};
|
||||
|
||||
extern options_t options;
|
||||
|
||||
#include <qbsp/map.hh>
|
||||
|
||||
int qbsp_main(int argc, const char **argv);
|
||||
|
|
|
|||
|
|
@ -26,5 +26,4 @@
|
|||
extern std::atomic<int> splitnodes;
|
||||
|
||||
void DetailToSolid(node_t *node);
|
||||
void CalcSurfaceInfo(surface_t *surf);
|
||||
void SubdivideFace(face_t *f, face_t **prevptr);
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ surface_t *BuildSurfaces(const std::map<int, face_t *> &planefaces)
|
|||
csgmergefaces++;
|
||||
|
||||
/* Calculate bounding box and flags */
|
||||
CalcSurfaceInfo(surf);
|
||||
surf->calculateInfo();
|
||||
}
|
||||
|
||||
return surfaces;
|
||||
|
|
|
|||
|
|
@ -491,38 +491,6 @@ static surface_t *SelectPartition(surface_t *surfaces)
|
|||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
=================
|
||||
CalcSurfaceInfo
|
||||
|
||||
Calculates the bounding box
|
||||
=================
|
||||
*/
|
||||
void CalcSurfaceInfo(surface_t *surf)
|
||||
{
|
||||
// calculate a bounding box
|
||||
surf->bounds = {};
|
||||
|
||||
surf->has_struct = false;
|
||||
|
||||
for (const face_t *f = surf->faces; f; f = f->next) {
|
||||
for (auto &contents : f->contents)
|
||||
if (!contents.is_valid(options.target_game, false))
|
||||
FError("Bad contents in face: {}", contents.to_string(options.target_game));
|
||||
|
||||
surf->lmshift = min(f->lmshift.front, f->lmshift.back);
|
||||
|
||||
surf->has_struct = !((f->contents[0].extended | f->contents[1].extended) &
|
||||
(CFLAGS_DETAIL | CFLAGS_DETAIL_ILLUSIONARY | CFLAGS_DETAIL_FENCE | CFLAGS_WAS_ILLUSIONARY));
|
||||
|
||||
for (int i = 0; i < f->w.size(); i++) {
|
||||
surf->bounds += f->w[i];
|
||||
}
|
||||
|
||||
Q_assert(!qv::emptyExact(surf->bounds.size()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
DividePlane
|
||||
|
|
@ -560,8 +528,8 @@ static void DividePlane(surface_t *in, const qplane3d &split, surface_t **front,
|
|||
|
||||
// ericw -- added these CalcSurfaceInfo to recalculate the surf bbox.
|
||||
// pretty sure their omission here was a bug.
|
||||
CalcSurfaceInfo(newsurf);
|
||||
CalcSurfaceInfo(in);
|
||||
newsurf->calculateInfo();
|
||||
in->calculateInfo();
|
||||
|
||||
if (in->faces)
|
||||
*front = in;
|
||||
|
|
@ -626,8 +594,8 @@ static void DividePlane(surface_t *in, const qplane3d &split, surface_t **front,
|
|||
*front = in;
|
||||
|
||||
// recalc bboxes and flags
|
||||
CalcSurfaceInfo(newsurf);
|
||||
CalcSurfaceInfo(in);
|
||||
newsurf->calculateInfo();
|
||||
in->calculateInfo();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void SubdivideFace(face_t *f, face_t **prevptr)
|
|||
next = f->next;
|
||||
SplitFace(f, plane, &front, &back);
|
||||
if (!front || !back) {
|
||||
printf("didn't split\n");
|
||||
LogPrintLocked("didn't split\n");
|
||||
break;
|
||||
// FError("Didn't split the polygon");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue