move calculatesurfaceinfo into a member func

This commit is contained in:
Jonathan 2022-01-23 00:46:11 -05:00
parent 5dd2deba8e
commit 5f81657621
5 changed files with 116 additions and 125 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();
}
/*

View File

@ -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");
}