qbsp: change bspbrush_t.sides from face_t to side_t
This commit is contained in:
parent
fac5ea384d
commit
afec0a947e
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
10
qbsp/csg4.cc
10
qbsp/csg4.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue