use custom type for two-sided things to simplify brain power (.front/.back is easier to process than [0]/[1])
This commit is contained in:
parent
5a2d522892
commit
5dd2deba8e
|
|
@ -1069,3 +1069,46 @@ std::vector<V> PointsAlongLine(const V &start, const V &end, const float step)
|
||||||
|
|
||||||
bool LinesOverlap(const qvec3f &p0, const qvec3f &p1, const qvec3f &q0, const qvec3f &q1,
|
bool LinesOverlap(const qvec3f &p0, const qvec3f &p1, const qvec3f &q0, const qvec3f &q1,
|
||||||
const vec_t &on_epsilon = DEFAULT_ON_EPSILON);
|
const vec_t &on_epsilon = DEFAULT_ON_EPSILON);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct twosided
|
||||||
|
{
|
||||||
|
T front, back;
|
||||||
|
|
||||||
|
// 0 is front, 1 is back
|
||||||
|
constexpr T &operator[](const int32_t &i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: return front;
|
||||||
|
case 1: return back;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
// 0 is front, 1 is back
|
||||||
|
constexpr const T &operator[](const int32_t &i) const
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: return front;
|
||||||
|
case 1: return back;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterator support
|
||||||
|
T *begin() { return &front; }
|
||||||
|
T *end() { return (&back) + 1; }
|
||||||
|
|
||||||
|
const T *begin() const { return &front; }
|
||||||
|
const T *end() const { return (&back) + 1; }
|
||||||
|
|
||||||
|
// swap the front and back values
|
||||||
|
constexpr void swap() { std::swap(front, back); }
|
||||||
|
|
||||||
|
// equality checks
|
||||||
|
constexpr bool operator==(const twosided &other) const { return front == other.front && back == other.back; }
|
||||||
|
constexpr bool operator!=(const twosided &other) const { return !(*this == other); }
|
||||||
|
};
|
||||||
|
|
@ -129,8 +129,8 @@ struct face_t
|
||||||
int planenum;
|
int planenum;
|
||||||
int planeside; // which side is the front of the face
|
int planeside; // which side is the front of the face
|
||||||
int texinfo;
|
int texinfo;
|
||||||
contentflags_t contents[2]; // 0 = front side
|
twosided<contentflags_t> contents;
|
||||||
short lmshift[2]; // lightmap scale.
|
twosided<int16_t> lmshift;
|
||||||
|
|
||||||
mapentity_t *src_entity; // source entity
|
mapentity_t *src_entity; // source entity
|
||||||
face_t *original; // face on node
|
face_t *original; // face on node
|
||||||
|
|
@ -147,7 +147,6 @@ struct face_t
|
||||||
struct surface_t
|
struct surface_t
|
||||||
{
|
{
|
||||||
surface_t *next;
|
surface_t *next;
|
||||||
surface_t *original; // before BSP cuts it up
|
|
||||||
int planenum;
|
int planenum;
|
||||||
std::optional<size_t> outputplanenum; // only valid after WriteSurfacePlanes
|
std::optional<size_t> outputplanenum; // only valid after WriteSurfacePlanes
|
||||||
aabb3d bounds;
|
aabb3d bounds;
|
||||||
|
|
|
||||||
18
qbsp/csg4.cc
18
qbsp/csg4.cc
|
|
@ -77,10 +77,8 @@ face_t *NewFaceFromFace(face_t *in)
|
||||||
newf->texinfo = in->texinfo;
|
newf->texinfo = in->texinfo;
|
||||||
newf->planeside = in->planeside;
|
newf->planeside = in->planeside;
|
||||||
newf->original = in->original;
|
newf->original = in->original;
|
||||||
newf->contents[0] = in->contents[0];
|
newf->contents = in->contents;
|
||||||
newf->contents[1] = in->contents[1];
|
newf->lmshift = in->lmshift;
|
||||||
newf->lmshift[0] = in->lmshift[0];
|
|
||||||
newf->lmshift[1] = in->lmshift[1];
|
|
||||||
newf->src_entity = in->src_entity;
|
newf->src_entity = in->src_entity;
|
||||||
|
|
||||||
newf->origin = in->origin;
|
newf->origin = in->origin;
|
||||||
|
|
@ -328,10 +326,8 @@ void SaveFacesToPlaneList(face_t *facelist, bool mirror, std::map<int, face_t *>
|
||||||
face_t *newface = NewFaceFromFace(face);
|
face_t *newface = NewFaceFromFace(face);
|
||||||
newface->w = face->w.flip();
|
newface->w = face->w.flip();
|
||||||
newface->planeside = face->planeside ^ 1;
|
newface->planeside = face->planeside ^ 1;
|
||||||
newface->contents[0] = face->contents[1];
|
newface->contents.swap();
|
||||||
newface->contents[1] = face->contents[0];
|
newface->lmshift.swap();
|
||||||
newface->lmshift[0] = face->lmshift[1];
|
|
||||||
newface->lmshift[1] = face->lmshift[0];
|
|
||||||
|
|
||||||
// e.g. for a water volume:
|
// e.g. for a water volume:
|
||||||
// the face facing the air:
|
// the face facing the air:
|
||||||
|
|
@ -503,10 +499,8 @@ static face_t *CopyBrushFaces(const brush_t &brush)
|
||||||
for (auto &face : brush.faces) {
|
for (auto &face : brush.faces) {
|
||||||
brushfaces++;
|
brushfaces++;
|
||||||
newface = new face_t(face);
|
newface = new face_t(face);
|
||||||
newface->contents[0] = options.target_game->create_empty_contents();
|
newface->contents = { options.target_game->create_empty_contents(), brush.contents };
|
||||||
newface->contents[1] = brush.contents;
|
newface->lmshift = { brush.lmshift, brush.lmshift };
|
||||||
newface->lmshift[0] = brush.lmshift;
|
|
||||||
newface->lmshift[1] = brush.lmshift;
|
|
||||||
newface->next = facelist;
|
newface->next = facelist;
|
||||||
facelist = newface;
|
facelist = newface;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,7 @@ static face_t *TryMerge(face_t *f1, face_t *f2)
|
||||||
bool keep1, keep2;
|
bool keep1, keep2;
|
||||||
|
|
||||||
if (!f1->w.size() || !f2->w.size() || f1->planeside != f2->planeside || f1->texinfo != f2->texinfo ||
|
if (!f1->w.size() || !f2->w.size() || f1->planeside != f2->planeside || f1->texinfo != f2->texinfo ||
|
||||||
f1->contents[0] != f2->contents[0] || f1->contents[1] != f2->contents[1] || f1->lmshift[0] != f2->lmshift[0] ||
|
f1->contents != f2->contents || f1->lmshift != f2->lmshift)
|
||||||
f1->lmshift[1] != f2->lmshift[1])
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// find a common edge
|
// find a common edge
|
||||||
|
|
@ -194,9 +193,9 @@ face_t *FreeMergeListScraps(face_t *merged)
|
||||||
head = NULL;
|
head = NULL;
|
||||||
for (; merged; merged = next) {
|
for (; merged; merged = next) {
|
||||||
next = merged->next;
|
next = merged->next;
|
||||||
if (!merged->w.size())
|
if (!merged->w.size()) {
|
||||||
delete merged;
|
delete merged;
|
||||||
else {
|
} else {
|
||||||
merged->next = head;
|
merged->next = head;
|
||||||
head = merged;
|
head = merged;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -503,7 +503,6 @@ void CalcSurfaceInfo(surface_t *surf)
|
||||||
// calculate a bounding box
|
// calculate a bounding box
|
||||||
surf->bounds = {};
|
surf->bounds = {};
|
||||||
|
|
||||||
surf->has_detail = false;
|
|
||||||
surf->has_struct = false;
|
surf->has_struct = false;
|
||||||
|
|
||||||
for (const face_t *f = surf->faces; f; f = f->next) {
|
for (const face_t *f = surf->faces; f; f = f->next) {
|
||||||
|
|
@ -511,18 +510,10 @@ void CalcSurfaceInfo(surface_t *surf)
|
||||||
if (!contents.is_valid(options.target_game, false))
|
if (!contents.is_valid(options.target_game, false))
|
||||||
FError("Bad contents in face: {}", contents.to_string(options.target_game));
|
FError("Bad contents in face: {}", contents.to_string(options.target_game));
|
||||||
|
|
||||||
surf->lmshift = (f->lmshift[0] < f->lmshift[1]) ? f->lmshift[0] : f->lmshift[1];
|
surf->lmshift = min(f->lmshift.front, f->lmshift.back);
|
||||||
|
|
||||||
bool faceIsDetail = false;
|
surf->has_struct = !((f->contents[0].extended | f->contents[1].extended) &
|
||||||
|
(CFLAGS_DETAIL | CFLAGS_DETAIL_ILLUSIONARY | CFLAGS_DETAIL_FENCE | CFLAGS_WAS_ILLUSIONARY));
|
||||||
if ((f->contents[0].extended | f->contents[1].extended) &
|
|
||||||
(CFLAGS_DETAIL | CFLAGS_DETAIL_ILLUSIONARY | CFLAGS_DETAIL_FENCE | CFLAGS_WAS_ILLUSIONARY))
|
|
||||||
faceIsDetail = true;
|
|
||||||
|
|
||||||
if (faceIsDetail)
|
|
||||||
surf->has_detail = true;
|
|
||||||
else
|
|
||||||
surf->has_struct = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < f->w.size(); i++) {
|
for (int i = 0; i < f->w.size(); i++) {
|
||||||
surf->bounds += f->w[i];
|
surf->bounds += f->w[i];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue