decompile: add some comments, skip empty brushes

This commit is contained in:
Eric Wasylishen 2021-02-04 22:01:28 -07:00
parent 708d3eccd3
commit e44dbf9307
1 changed files with 114 additions and 1 deletions

View File

@ -30,6 +30,7 @@
#include <vector> #include <vector>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <memory>
#include <utility> #include <utility>
#include <tuple> #include <tuple>
@ -332,6 +333,104 @@ static std::string DefaultTextureForContents(int contents)
} }
} }
// structures representing a brush
#if 0
struct decomp_brush_face_t {
/**
* The currently clipped section of the face
*/
std::unique_ptr<winding_t> winding;
/**
* The face we were originally derived from
*/
const bsp2_dface_t *original_face;
};
struct decomp_brush_side_t {
/**
* During decompilation, we can have multiple faces on a single plane of the brush.
* All vertices of these should lie on the plane.
*/
std::vector<decomp_brush_face_t> faces;
decomp_plane_t plane;
};
struct decomp_brush_t {
std::vector<decomp_brush_side_t> sides;
std::unique_ptr<decomp_brush_t> clone() const {
return std::unique_ptr<decomp_brush_t>(new decomp_brush_t(*this));
}
/**
* Returns the front and back side after clipping to the given plane.
*/
std::tuple<std::unique_ptr<decomp_brush_t>,
std::unique_ptr<decomp_brush_t>> clipToPlane(const qvec3d& normal, double distance) const {
// handle exact cases
for (auto& side : sides) {
if (side.plane.normal == normal && side.plane.distance == distance) {
// the whole brush is on/behind the plane
return {nullptr, clone()};
} else if (side.plane.normal == -normal && side.plane.distance == -distance) {
// the whole brush is on/in front of the plane
return {clone(), nullptr};
}
}
// general case.
}
};
static decomp_brush_t
BuildInitialBrush(const mbsp_t *bsp, std::vector<decomp_plane_t> planes)
{
std::vector<decomp_plane_t> result;
for (const decomp_plane_t &plane : planes) {
// outward-facing plane
vec3_t normal;
glm_to_vec3_t(plane.normal, normal);
winding_t *winding = BaseWindingForPlane(normal, plane.distance);
// clip `winding` by all of the other planes, flipped
for (const decomp_plane_t &plane2 : planes) {
if (&plane2 == &plane)
continue;
// get flipped plane
vec3_t plane2normal;
glm_to_vec3_t(plane2.normal * -1.0, plane2normal);
float plane2dist = -plane2.distance;
// frees winding.
winding_t *front = nullptr;
winding_t *back = nullptr;
ClipWinding(winding, plane2normal, plane2dist, &front, &back);
// discard the back, continue clipping the front part
free(back);
winding = front;
// check if everything was clipped away
if (winding == nullptr)
break;
}
if (winding != nullptr) {
// this plane is not redundant
result.push_back(plane);
}
free(winding);
}
return result;
}
#endif
/** /**
* Preconditions: * Preconditions:
* - The existing path of plane side choices have been pushed onto `planestack` * - The existing path of plane side choices have been pushed onto `planestack`
@ -345,7 +444,21 @@ DecompileLeaf(const std::vector<decomp_plane_t>* planestack, const mbsp_t *bsp,
} }
auto reducedPlanes = RemoveRedundantPlanes(bsp, *planestack); auto reducedPlanes = RemoveRedundantPlanes(bsp, *planestack);
//printf("before: %d after %d\n", (int)planestack->size(), (int)reducedPlanes.size()); if (reducedPlanes.empty()) {
printf("warning, skipping empty brush\n");
return;
}
printf("before: %d after %d\n", (int)planestack->size(), (int)reducedPlanes.size());
// At this point, we should gather all of the faces on `reducedPlanes` and clip away the
// parts that are outside of our brush. (keeping track of which of the nodes they belonged to)
// AFAIK it's possible that the faces are half-overlapping the leaf, so we may have to cut the
// faces in half.
// Next, for each plane in reducedPlanes, if there are 2+ faces on the plane with non-equal
// texinfo, we need to clip the brush perpendicular to the face until there are no longer
// 2+ faces on a plane with non-equal texinfo.
fprintf(file, "{\n"); fprintf(file, "{\n");
for (const auto& decompplane : reducedPlanes) { for (const auto& decompplane : reducedPlanes) {