winding_t: make non-copyable
This commit is contained in:
parent
8b9c1bd784
commit
06a116670b
|
|
@ -413,8 +413,14 @@ std::pair<std::vector<qvec3f>, std::vector<qvec3f>> GLM_ClipPoly(const std::vect
|
|||
|
||||
auto clipped = w.clip({plane.xyz(), plane[3]});
|
||||
|
||||
return make_pair(
|
||||
clipped[0].value_or(winding_t{}).glm_winding_points(), clipped[1].value_or(winding_t{}).glm_winding_points());
|
||||
std::pair<std::vector<qvec3f>, std::vector<qvec3f>> result;
|
||||
if (clipped[0]) {
|
||||
result.first = clipped[0]->glm_winding_points();
|
||||
}
|
||||
if (clipped[1]) {
|
||||
result.second = clipped[1]->glm_winding_points();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<qvec3f> GLM_ShrinkPoly(const std::vector<qvec3f> &poly, const float amount)
|
||||
|
|
|
|||
|
|
@ -648,19 +648,14 @@ public:
|
|||
// initializer list constructor
|
||||
inline winding_base_t(std::initializer_list<qvec3d> l) : storage(l.begin(), l.end()) { }
|
||||
|
||||
// copy constructor; uses optimized method of copying
|
||||
// data over.
|
||||
inline winding_base_t(const winding_base_t ©) : storage(copy.storage) { }
|
||||
// copy constructor; we require copying to be done with clone() to avoid performance bugs
|
||||
inline winding_base_t(const winding_base_t ©) = delete;
|
||||
|
||||
// move constructor
|
||||
inline winding_base_t(winding_base_t &&move) noexcept : storage(std::move(move.storage)) { }
|
||||
|
||||
// assignment copy
|
||||
inline winding_base_t &operator=(const winding_base_t ©)
|
||||
{
|
||||
storage = copy.storage;
|
||||
return *this;
|
||||
}
|
||||
inline winding_base_t &operator=(const winding_base_t ©) = delete;
|
||||
|
||||
// assignment move
|
||||
inline winding_base_t &operator=(winding_base_t &&move) noexcept
|
||||
|
|
@ -745,6 +740,14 @@ public:
|
|||
|
||||
// non-storage functions
|
||||
|
||||
// explicit copying function
|
||||
winding_base_t clone() const
|
||||
{
|
||||
winding_base_t result;
|
||||
result.storage = storage;
|
||||
return result;
|
||||
}
|
||||
|
||||
vec_t area() const
|
||||
{
|
||||
vec_t total = 0;
|
||||
|
|
@ -996,12 +999,12 @@ public:
|
|||
std::array<size_t, SIDE_TOTAL> counts = calc_sides(plane, dists, sides, on_epsilon);
|
||||
|
||||
if (keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK])
|
||||
return {*this, std::nullopt};
|
||||
return {this->clone(), std::nullopt};
|
||||
|
||||
if (!counts[SIDE_FRONT])
|
||||
return {std::nullopt, *this};
|
||||
return {std::nullopt, this->clone()};
|
||||
else if (!counts[SIDE_BACK])
|
||||
return {*this, std::nullopt};
|
||||
return {this->clone(), std::nullopt};
|
||||
|
||||
twosided<winding_base_t> results{};
|
||||
|
||||
|
|
@ -1108,7 +1111,7 @@ public:
|
|||
result.push_back(mid);
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1250,7 +1253,7 @@ public:
|
|||
|
||||
winding_base_t translate(const qvec3d &offset) const
|
||||
{
|
||||
winding_base_t result(*this);
|
||||
winding_base_t result = this->clone();
|
||||
|
||||
for (qvec3d &p : result) {
|
||||
p += offset;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ struct side_t
|
|||
|
||||
bool tested;
|
||||
|
||||
side_t clone_non_winding_data() const;
|
||||
side_t clone() const;
|
||||
|
||||
bool is_visible() const;
|
||||
const maptexinfo_t &get_texinfo() const;
|
||||
const qbsp_plane_t &get_plane() const;
|
||||
|
|
@ -86,6 +89,8 @@ struct bspbrush_t
|
|||
bool update_bounds(bool warn_on_failures);
|
||||
|
||||
ptr copy_unique() const;
|
||||
|
||||
bspbrush_t clone() const;
|
||||
};
|
||||
|
||||
std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush, const contentflags_t &contents, const int hullnum);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct portal_t
|
|||
node_t *onnode; // nullptr = portal to the outside of the world (one of six sides of a box)
|
||||
node_t *nodes[2]; // [0] = front side of planenum
|
||||
portal_t *next[2]; // [0] = next portal in nodes[0]'s list of portals
|
||||
std::unique_ptr<winding_t> winding;
|
||||
winding_t winding;
|
||||
|
||||
bool sidefound; // false if ->side hasn't been checked
|
||||
side_t *sides[2]; // [0] = the brush side visible on nodes[0] - it could come from a brush in nodes[1]. NULL =
|
||||
|
|
@ -51,7 +51,7 @@ struct buildportal_t
|
|||
qbsp_plane_t plane;
|
||||
node_t *onnode = nullptr; // nullptr = portal to the outside of the world (one of six sides of a box)
|
||||
node_t *nodes[2] = {nullptr, nullptr}; // [0] = front side of planenum
|
||||
std::unique_ptr<winding_t> winding;
|
||||
winding_t winding;
|
||||
|
||||
inline void set_nodes(node_t *front, node_t *back) {
|
||||
nodes[0] = front;
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ struct winding_t : polylib::winding_base_t<polylib::winding_storage_hybrid_t<MAX
|
|||
}
|
||||
|
||||
// copy constructor
|
||||
inline winding_t(const winding_t ©) : winding_base_t(copy), origin(copy.origin), radius(copy.radius) { }
|
||||
inline winding_t(const winding_t ©) = delete;
|
||||
|
||||
// move constructor
|
||||
inline winding_t(winding_t &&move) noexcept : winding_base_t(move), origin(move.origin), radius(move.radius) { }
|
||||
inline winding_t(winding_t &&move) noexcept : winding_base_t(std::move(move)), origin(move.origin), radius(move.radius) { }
|
||||
|
||||
// sets origin & radius
|
||||
inline void set_winding_sphere()
|
||||
|
|
@ -84,15 +84,7 @@ struct winding_t : polylib::winding_base_t<polylib::winding_storage_hybrid_t<MAX
|
|||
}
|
||||
|
||||
// assignment copy
|
||||
inline winding_t &operator=(const winding_t ©)
|
||||
{
|
||||
origin = copy.origin;
|
||||
radius = copy.radius;
|
||||
|
||||
winding_base_t::operator=(copy);
|
||||
|
||||
return *this;
|
||||
}
|
||||
inline winding_t &operator=(const winding_t ©) = delete;
|
||||
|
||||
// assignment move
|
||||
inline winding_t &operator=(winding_t &&move) noexcept
|
||||
|
|
@ -100,7 +92,7 @@ struct winding_t : polylib::winding_base_t<polylib::winding_storage_hybrid_t<MAX
|
|||
origin = move.origin;
|
||||
radius = move.radius;
|
||||
|
||||
winding_base_t::operator=(move);
|
||||
winding_base_t::operator=(std::move(move));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,25 @@
|
|||
#include <qbsp/map.hh>
|
||||
#include <qbsp/qbsp.hh>
|
||||
|
||||
side_t side_t::clone_non_winding_data() const
|
||||
{
|
||||
side_t result;
|
||||
result.planenum = this->planenum;
|
||||
result.texinfo = this->texinfo;
|
||||
result.onnode = this->onnode;
|
||||
result.bevel = this->bevel;
|
||||
result.source = this->source;
|
||||
result.tested = this->tested;
|
||||
return result;
|
||||
}
|
||||
|
||||
side_t side_t::clone() const
|
||||
{
|
||||
side_t result = clone_non_winding_data();
|
||||
result.w = this->w.clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool side_t::is_visible() const
|
||||
{
|
||||
return source && source->visible;
|
||||
|
|
@ -50,7 +69,31 @@ const qbsp_plane_t &side_t::get_positive_plane() const
|
|||
|
||||
bspbrush_t::ptr bspbrush_t::copy_unique() const
|
||||
{
|
||||
return bspbrush_t::make_ptr(*this);
|
||||
return bspbrush_t::make_ptr(this->clone());
|
||||
}
|
||||
|
||||
bspbrush_t bspbrush_t::clone() const
|
||||
{
|
||||
bspbrush_t result;
|
||||
|
||||
result.original_ptr = this->original_ptr;
|
||||
result.mapbrush = this->mapbrush;
|
||||
|
||||
result.bounds = this->bounds;
|
||||
result.side = this->side;
|
||||
result.testside = this->testside;
|
||||
|
||||
result.sides.reserve(this->sides.size());
|
||||
for (auto &side : this->sides) {
|
||||
result.sides.push_back(side.clone());
|
||||
}
|
||||
|
||||
result.contents = this->contents;
|
||||
|
||||
result.sphere_origin = this->sphere_origin;
|
||||
result.sphere_radius = this->sphere_radius;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -238,7 +281,7 @@ bool CreateBrushWindings(bspbrush_t *brush)
|
|||
}
|
||||
}
|
||||
|
||||
side->w = *w;
|
||||
side->w = std::move(*w);
|
||||
} else {
|
||||
side->w.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ static twosided<bspbrush_t::ptr> SplitBrush(bspbrush_t::ptr brush, size_t planen
|
|||
logging::print("WARNING: huge winding\n");
|
||||
}
|
||||
|
||||
winding_t midwinding = *w;
|
||||
winding_t &midwinding = *w;
|
||||
|
||||
// split it for real
|
||||
|
||||
|
|
@ -512,7 +512,7 @@ static twosided<bspbrush_t::ptr> SplitBrush(bspbrush_t::ptr brush, size_t planen
|
|||
#endif
|
||||
|
||||
// add the clipped face to result[j]
|
||||
side_t faceCopy = face;
|
||||
side_t faceCopy = face.clone_non_winding_data();
|
||||
faceCopy.w = std::move(*cw[j]);
|
||||
|
||||
// fixme-brushbsp: configure any settings on the faceCopy?
|
||||
|
|
@ -583,7 +583,11 @@ static twosided<bspbrush_t::ptr> SplitBrush(bspbrush_t::ptr brush, size_t planen
|
|||
cs.onnode = true;
|
||||
// fixme-brushbsp: configure any other settings on the face?
|
||||
|
||||
cs.w = brushOnFront ? midwinding.flip() : midwinding;
|
||||
if (brushOnFront) {
|
||||
cs.w = midwinding.flip();
|
||||
} else {
|
||||
cs.w = std::move(midwinding);
|
||||
}
|
||||
|
||||
result[i]->sides.push_back(std::move(cs));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ std::unique_ptr<face_t> NewFaceFromFace(const face_t *in)
|
|||
std::unique_ptr<face_t> CopyFace(const face_t *in)
|
||||
{
|
||||
auto temp = NewFaceFromFace(in);
|
||||
temp->w = in->w;
|
||||
temp->w = in->w.clone();
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -504,9 +504,9 @@ static std::unique_ptr<face_t> FaceFromPortal(portal_t *p, bool pside)
|
|||
#endif
|
||||
|
||||
if (pside) {
|
||||
f->w = p->winding->flip();
|
||||
f->w = p->winding.flip();
|
||||
} else {
|
||||
f->w = *p->winding;
|
||||
f->w = p->winding.clone();
|
||||
}
|
||||
|
||||
f->contents = p->nodes[pside]->contents;
|
||||
|
|
|
|||
|
|
@ -2233,10 +2233,11 @@ inline void CalculateBrushBounds(mapbrush_t &ob)
|
|||
}
|
||||
|
||||
if (w) {
|
||||
ob.faces[i].winding = w.value();
|
||||
// calc bounds before moving from w
|
||||
for (auto &p : w.value()) {
|
||||
ob.bounds += p;
|
||||
}
|
||||
ob.faces[i].winding = std::move(w.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ static void WriteLeakLine(const mapentity_t *leakentity, const std::vector<porta
|
|||
qvec3d prevpt = leakentity->origin;
|
||||
|
||||
for (portal_t *portal : leakline) {
|
||||
qvec3d currpt = portal->winding->center();
|
||||
qvec3d currpt = portal->winding.center();
|
||||
|
||||
// draw dots from prevpt to currpt
|
||||
WriteLeakTrail(ptsfile, prevpt, currpt);
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ std::list<std::unique_ptr<buildportal_t>> MakeHeadnodePortals(tree_t *tree)
|
|||
}
|
||||
bool side = p->plane.set_plane(pl, true);
|
||||
|
||||
p->winding = std::make_unique<winding_t>(BaseWindingForPlane(pl));
|
||||
p->winding = BaseWindingForPlane(pl);
|
||||
if (side) {
|
||||
p->set_nodes(&tree->outside_node, tree->headnode);
|
||||
} else {
|
||||
|
|
@ -168,7 +168,7 @@ std::list<std::unique_ptr<buildportal_t>> MakeHeadnodePortals(tree_t *tree)
|
|||
|
||||
// clip the basewindings by all the other planes
|
||||
for (i = 0; i < 6; i++) {
|
||||
winding_t &w = *portals[i]->winding.get();
|
||||
winding_t &w = portals[i]->winding;
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (j == i)
|
||||
|
|
@ -266,7 +266,7 @@ std::unique_ptr<buildportal_t> MakeNodePortal(node_t *node, const std::list<std:
|
|||
auto new_portal = std::make_unique<buildportal_t>();
|
||||
new_portal->plane = node->get_plane();
|
||||
new_portal->onnode = node;
|
||||
new_portal->winding = std::make_unique<winding_t>(*w);
|
||||
new_portal->winding = std::move(*w);
|
||||
new_portal->set_nodes(node->children[0], node->children[1]);
|
||||
|
||||
return new_portal;
|
||||
|
|
@ -304,7 +304,7 @@ twosided<std::list<std::unique_ptr<buildportal_t>>> SplitNodePortals(const node_
|
|||
//
|
||||
// cut the portal into two portals, one on each side of the cut plane
|
||||
//
|
||||
auto [frontwinding, backwinding] = p->winding->clip(plane, SPLIT_WINDING_EPSILON, true);
|
||||
auto [frontwinding, backwinding] = p->winding.clip(plane, SPLIT_WINDING_EPSILON, true);
|
||||
|
||||
if (frontwinding && WindingIsTiny(*frontwinding)) {
|
||||
frontwinding = {};
|
||||
|
|
@ -345,8 +345,8 @@ twosided<std::list<std::unique_ptr<buildportal_t>>> SplitNodePortals(const node_
|
|||
new_portal->onnode = p->onnode;
|
||||
new_portal->nodes[0] = p->nodes[0];
|
||||
new_portal->nodes[1] = p->nodes[1];
|
||||
new_portal->winding = std::make_unique<winding_t>(*backwinding);
|
||||
p->winding = std::make_unique<winding_t>(*frontwinding);
|
||||
new_portal->winding = std::move(*backwinding);
|
||||
p->winding = std::move(*frontwinding);
|
||||
|
||||
if (side == SIDE_FRONT) {
|
||||
p->set_nodes(f, other_node);
|
||||
|
|
@ -392,7 +392,7 @@ void CalcNodeBounds(node_t *node)
|
|||
|
||||
for (portal_t *p = node->portals; p;) {
|
||||
int s = (p->nodes[1] == node);
|
||||
for (auto &point : *p->winding) {
|
||||
for (auto &point : p->winding) {
|
||||
node->bounds += point;
|
||||
}
|
||||
p = p->next[s];
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static void WritePortals_r(node_t *node, std::ofstream &portalFile, bool cluster
|
|||
if (!Portal_VisFlood(p))
|
||||
continue;
|
||||
|
||||
w = p->winding.get();
|
||||
w = &p->winding;
|
||||
front = clusters ? p->nodes[0]->viscluster : p->nodes[0]->visleafnum;
|
||||
back = clusters ? p->nodes[1]->viscluster : p->nodes[1]->visleafnum;
|
||||
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ TEST_CASE("winding iterators", "[winding_base_t]")
|
|||
|
||||
// check that constructors work
|
||||
{
|
||||
polylib::winding_base_t<polylib::winding_storage_hybrid_t<4>> winding_other(winding);
|
||||
polylib::winding_base_t<polylib::winding_storage_hybrid_t<4>> winding_other(winding.begin(), winding.end());
|
||||
|
||||
{
|
||||
auto it = winding_other.begin();
|
||||
|
|
|
|||
Loading…
Reference in New Issue