qbsp: change bspbrush_t.sides from face_t to side_t

This commit is contained in:
Eric Wasylishen 2022-06-24 00:43:40 -06:00
parent fac5ea384d
commit afec0a947e
10 changed files with 67 additions and 36 deletions

View File

@ -63,7 +63,7 @@ struct bspbrush_t {
bspbrush_t *original;
uint32_t file_order;
aabb3d bounds;
std::vector<face_t> sides;
std::vector<side_t> sides;
contentflags_t contents; /* BSP contents */
short lmshift; /* lightmap scaling (qu/lightmap pixel), passed to the light util */
std::optional<uint32_t> outputnumber; /* only set for original brushes */
@ -75,6 +75,7 @@ struct bspbrush_t {
class mapbrush_t;
qplane3d Face_Plane(const face_t *face);
qplane3d Face_Plane(const side_t *face);
enum class rotation_t
{

View File

@ -29,11 +29,13 @@
struct bspbrush_t;
struct face_t;
struct side_t;
face_t *NewFaceFromFace(const face_t *in);
face_t *CopyFace(const face_t *in);
face_t *MirrorFace(const face_t *face);
std::tuple<face_t *, face_t *> SplitFace(face_t *in, const qplane3d &split);
void UpdateFaceSphere(face_t *in);
void UpdateFaceSphere(side_t *in);
bool BrushGE(const bspbrush_t &a, const bspbrush_t &b);
std::vector<std::unique_ptr<bspbrush_t>> ChopBrushes(const std::vector<std::unique_ptr<bspbrush_t>> &input);

View File

@ -26,6 +26,8 @@
#include <atomic>
struct side_t;
struct portal_t
{
int planenum;
@ -35,7 +37,7 @@ struct portal_t
std::optional<winding_t> winding;
bool sidefound; // false if ->side hasn't been checked
face_t *side; // NULL = non-visible // fixme-brushbsp: change to side_t
side_t *side; // NULL = non-visible
face_t *face[2]; // output face in bsp file
};

View File

@ -65,6 +65,17 @@ qplane3d Face_Plane(const face_t *face)
return result;
}
qplane3d Face_Plane(const side_t *face)
{
const qplane3d &result = map.planes.at(face->planenum);
if (face->planeside) {
return -result;
}
return result;
}
/*
=================
CheckFace
@ -72,7 +83,7 @@ CheckFace
Note: this will not catch 0 area polygons
=================
*/
static void CheckFace(face_t *face, const mapface_t &sourceface)
static void CheckFace(side_t *face, const mapface_t &sourceface)
{
const qbsp_plane_t &plane = map.planes.at(face->planenum);
@ -358,13 +369,13 @@ static bool MapBrush_IsHint(const mapbrush_t &brush)
CreateBrushFaces
=================
*/
static std::vector<face_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, const int hullnum,
static std::vector<side_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, const int hullnum,
const rotation_t rottype = rotation_t::none, const qvec3d &rotate_offset = {})
{
vec_t r;
std::optional<winding_t> w;
qbsp_plane_t plane;
std::vector<face_t> facelist;
std::vector<side_t> facelist;
qvec3d point;
vec_t max, min;
@ -405,7 +416,7 @@ static std::vector<face_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t
}
// this face is a keeper
face_t &f = facelist.emplace_back();
side_t &f = facelist.emplace_back();
f.planenum = PLANENUM_LEAF;
f.w.resize(w->size());
@ -660,7 +671,7 @@ static void AddHullEdge(hullbrush_t *hullbrush, const qvec3d &p1, const qvec3d &
ExpandBrush
=============
*/
static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, std::vector<face_t> &facelist)
static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, std::vector<side_t> &facelist)
{
int x, s;
qbsp_plane_t plane;
@ -759,7 +770,7 @@ std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, const mapbrush_t *ma
const qvec3d &rotate_offset, const rotation_t rottype, const int hullnum)
{
hullbrush_t hullbrush;
std::vector<face_t> facelist;
std::vector<side_t> facelist;
// create the faces
@ -1060,7 +1071,7 @@ void Brush_LoadEntity(mapentity_t *entity, const int hullnum)
void bspbrush_t::update_bounds()
{
this->bounds = {};
for (const face_t &face : sides) {
for (const auto &face : sides) {
this->bounds = this->bounds.unionWith(face.w.bounds());
}
}

View File

@ -142,7 +142,7 @@ FaceSide
For BSP hueristic
==================
*/
static int FaceSide__(const face_t *in, const qbsp_plane_t &split)
static int FaceSide__(const winding_t &w, const qbsp_plane_t &split)
{
bool have_front, have_back;
int i;
@ -151,8 +151,8 @@ static int FaceSide__(const face_t *in, const qbsp_plane_t &split)
if (split.type < plane_type_t::PLANE_ANYX) {
/* shortcut for axial planes */
const vec_t *p = &in->w[0][static_cast<size_t>(split.type)];
for (i = 0; i < in->w.size(); i++, p += 3) {
const vec_t *p = &w[0][static_cast<size_t>(split.type)];
for (i = 0; i < w.size(); i++, p += 3) {
if (*p > split.dist + options.epsilon.value()) {
if (have_back)
return SIDE_ON;
@ -165,8 +165,8 @@ static int FaceSide__(const face_t *in, const qbsp_plane_t &split)
}
} else {
/* sloping planes take longer */
for (i = 0; i < in->w.size(); i++) {
const vec_t dot = split.distance_to(in->w[i]);
for (i = 0; i < w.size(); i++) {
const vec_t dot = split.distance_to(w[i]);
if (dot > options.epsilon.value()) {
if (have_back)
return SIDE_ON;
@ -196,7 +196,19 @@ inline int FaceSide(const face_t *in, const qbsp_plane_t &split)
else if (dist < -in->radius)
return SIDE_BACK;
else
return FaceSide__(in, split);
return FaceSide__(in->w, split);
}
inline int FaceSide(const side_t *in, const qbsp_plane_t &split)
{
vec_t dist = split.distance_to(in->origin);
if (dist > in->radius)
return SIDE_FRONT;
else if (dist < -in->radius)
return SIDE_BACK;
else
return FaceSide__(in->w, split);
}
/*
@ -309,13 +321,13 @@ ChooseMidPlaneFromList
The clipping hull BSP doesn't worry about avoiding splits
==================
*/
static const face_t *ChooseMidPlaneFromList(const std::vector<std::unique_ptr<bspbrush_t>> &brushes, const aabb3d &bounds)
static const side_t *ChooseMidPlaneFromList(const std::vector<std::unique_ptr<bspbrush_t>> &brushes, const aabb3d &bounds)
{
/* pick the plane that splits the least */
vec_t bestaxialmetric = VECT_MAX;
face_t *bestaxialsurface = nullptr;
side_t *bestaxialsurface = nullptr;
vec_t bestanymetric = VECT_MAX;
face_t *bestanysurface = nullptr;
side_t *bestanysurface = nullptr;
for (int pass = 0; pass < 2; pass++) {
for (auto &brush : brushes) {
@ -375,12 +387,12 @@ The real BSP heuristic
fixme-brushbsp: prefer splits that include a lot of brush sides?
==================
*/
static const face_t *ChoosePlaneFromList(const std::vector<std::unique_ptr<bspbrush_t>> &brushes, const aabb3d &bounds)
static const side_t *ChoosePlaneFromList(const std::vector<std::unique_ptr<bspbrush_t>> &brushes, const aabb3d &bounds)
{
/* pick the plane that splits the least */
int minsplits = INT_MAX - 1;
vec_t bestdistribution = VECT_MAX;
face_t *bestsurface = nullptr;
side_t *bestsurface = nullptr;
/* passes:
* 0: structural visible
@ -477,7 +489,7 @@ returns NULL if the surface list can not be divided any more (a leaf)
Called in parallel.
==================
*/
static const face_t *SelectPartition(const std::vector<std::unique_ptr<bspbrush_t>> &brushes)
static const side_t *SelectPartition(const std::vector<std::unique_ptr<bspbrush_t>> &brushes)
{
// calculate a bounding box of the entire surfaceset
aabb3d bounds;
@ -716,7 +728,7 @@ twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush_t> bru
#endif
// add the clipped face to result[j]
face_t faceCopy = face;
side_t faceCopy = face;
faceCopy.w = *cw[j];
// fixme-brushbsp: configure any settings on the faceCopy?
@ -762,7 +774,7 @@ twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush_t> bru
// add the midwinding to both sides
for (int i = 0; i < 2; i++) {
face_t cs{};
side_t cs{};
const bool brushOnFront = (i == 0);
@ -852,7 +864,7 @@ Called in parallel.
*/
static void PartitionBrushes(std::vector<std::unique_ptr<bspbrush_t>> brushes, node_t *node)
{
face_t *split = const_cast<face_t *>(SelectPartition(brushes));
auto *split = const_cast<side_t *>(SelectPartition(brushes));
if (split == nullptr) { // this is a leaf node
node->planenum = PLANENUM_LEAF;

View File

@ -80,6 +80,16 @@ void UpdateFaceSphere(face_t *in)
in->radius = sqrt(in->radius);
}
void UpdateFaceSphere(side_t *in)
{
in->origin = in->w.center();
in->radius = 0;
for (size_t i = 0; i < in->w.size(); i++) {
in->radius = max(in->radius, qv::distance2(in->w[i], in->origin));
}
in->radius = sqrt(in->radius);
}
/*
==================
SplitFace

View File

@ -124,13 +124,6 @@ void ExportObj_Faces(const std::string &filesuffix, const std::vector<const face
void ExportObj_Brushes(const std::string &filesuffix, const std::vector<const bspbrush_t *> &brushes)
{
std::vector<const face_t *> faces;
for (const bspbrush_t *brush : brushes)
for (auto &face : brush->sides)
faces.push_back(&face);
ExportObj_Faces(filesuffix, faces);
}
static void ExportObj_Nodes_r(const node_t *node, std::vector<const face_t *> *dest)

View File

@ -445,7 +445,7 @@ static void FindPortalSide(portal_t *p)
return;
int planenum = p->onnode->planenum;
face_t *bestside = nullptr;
side_t *bestside = nullptr;
float bestdot = 0;
for (int j = 0; j < 2; j++)
@ -460,7 +460,7 @@ static void FindPortalSide(portal_t *p)
auto *brush = *it;
if (!options.target_game->contents_contains(brush->contents, viscontents))
continue;
for (face_t &side : brush->sides)
for (auto &side : brush->sides)
{
// fixme-brushbsp: port these
// if (side.bevel)

View File

@ -296,10 +296,10 @@ Adds any additional planes necessary to allow the brush to be expanded
against axial bounding boxes
=================
*/
static std::vector<std::tuple<size_t, const face_t *>> AddBrushBevels(const bspbrush_t &b)
static std::vector<std::tuple<size_t, const side_t *>> AddBrushBevels(const bspbrush_t &b)
{
// add already-present planes
std::vector<std::tuple<size_t, const face_t *>> planes;
std::vector<std::tuple<size_t, const side_t *>> planes;
for (auto &f : b.sides) {
int32_t planenum = f.planenum;

View File

@ -597,7 +597,7 @@ see also FindPortalSide which populates p->side
*/
static face_t *FaceFromPortal(portal_t *p, int pside)
{
face_t *side = p->side;
side_t *side = p->side;
if (!side)
return nullptr; // portal does not bridge different visible contents