going back to using planenums, but going for the qbsp3-esque system
This commit is contained in:
parent
93655913c0
commit
1ad0eb530d
|
|
@ -39,7 +39,8 @@ struct bspbrush_t;
|
|||
|
||||
struct mapface_t
|
||||
{
|
||||
qbsp_plane_t plane{};
|
||||
//qbsp_plane_t plane{};
|
||||
size_t planenum;
|
||||
std::array<qvec3d, 3> planepts{};
|
||||
std::string texname{};
|
||||
int texinfo = 0;
|
||||
|
|
@ -58,6 +59,8 @@ struct mapface_t
|
|||
|
||||
const texvecf &get_texvecs() const;
|
||||
void set_texvecs(const texvecf &vecs);
|
||||
|
||||
const qbsp_plane_t &get_plane() const;
|
||||
};
|
||||
|
||||
enum class brushformat_t
|
||||
|
|
@ -139,7 +142,46 @@ struct mapdata_t
|
|||
std::vector<mapface_t> faces;
|
||||
std::vector<mapbrush_t> brushes;
|
||||
std::vector<mapentity_t> entities;
|
||||
|
||||
// this vector stores all of the planes that can potentially be
|
||||
// output in the BSP, from the map's own sides. The positive planes
|
||||
// come first (are even-numbered, with 0 being even) and the negative
|
||||
// planes are odd-numbered.
|
||||
std::vector<mapplane_t> planes;
|
||||
|
||||
// add the specified plane to the list
|
||||
inline size_t add_plane(const qplane3d &plane)
|
||||
{
|
||||
planes.reserve(planes.size() + 2);
|
||||
auto &positive = planes.emplace_back(plane);
|
||||
auto &negative = planes.emplace_back(-plane);
|
||||
|
||||
if (positive.get_normal()[static_cast<int32_t>(positive.get_type()) % 3] < 0.0) {
|
||||
std::swap(positive, negative);
|
||||
return planes.size() - 1;
|
||||
}
|
||||
|
||||
return planes.size() - 2;
|
||||
}
|
||||
|
||||
// find the specified plane in the list if it exists, or
|
||||
// return a new one
|
||||
inline size_t add_or_find_plane(const qplane3d &plane)
|
||||
{
|
||||
for (size_t i = 0; i < planes.size(); i++) {
|
||||
if (qv::epsilonEqual(planes[i], plane)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return add_plane(plane);
|
||||
}
|
||||
|
||||
inline const qbsp_plane_t &get_plane(size_t pnum)
|
||||
{
|
||||
return planes[pnum];
|
||||
}
|
||||
|
||||
std::vector<maptexdata_t> miptex;
|
||||
std::vector<maptexinfo_t> mtexinfos;
|
||||
|
||||
|
|
@ -221,12 +263,6 @@ struct mapdata_t
|
|||
|
||||
const std::string &texinfoTextureName(int texinfo) const { return miptexTextureName(mtexinfos.at(texinfo).miptex); }
|
||||
|
||||
inline qbsp_plane_t get_plane(int pnum)
|
||||
{
|
||||
std::shared_lock lock(map_planes_lock);
|
||||
return planes.at(pnum);
|
||||
}
|
||||
|
||||
int skip_texinfo;
|
||||
|
||||
mapentity_t *world_entity();
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ static std::vector<side_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t
|
|||
continue;
|
||||
}
|
||||
|
||||
w = BaseWindingForPlane(mapface.plane);
|
||||
w = BaseWindingForPlane(mapface.get_plane());
|
||||
|
||||
for (auto &mapface2 : hullbrush->faces) {
|
||||
if (&mapface == &mapface2)
|
||||
|
|
@ -277,7 +277,7 @@ static std::vector<side_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t
|
|||
break;
|
||||
|
||||
// flip the plane, because we want to keep the back side
|
||||
plane = -mapface2.plane;
|
||||
plane = -mapface2.get_plane();
|
||||
|
||||
w = w->clip(plane, qbsp_options.epsilon.value(), false)[SIDE_FRONT];
|
||||
}
|
||||
|
|
@ -320,8 +320,8 @@ static std::vector<side_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t
|
|||
mapface.texinfo = FindTexinfo(texInfoNew);
|
||||
}
|
||||
|
||||
plane.normal = mapface.plane.get_normal();
|
||||
point = mapface.plane.get_normal() * mapface.plane.get_dist();
|
||||
plane.normal = mapface.get_plane().get_normal();
|
||||
point = mapface.get_plane().get_normal() * mapface.get_plane().get_dist();
|
||||
point -= rotate_offset;
|
||||
plane.dist = qv::dot(plane.normal, point);
|
||||
|
||||
|
|
@ -388,7 +388,7 @@ static void AddBrushPlane(hullbrush_t *hullbrush, const qbsp_plane_t &plane)
|
|||
FError("invalid normal (vector length {:.4})", len);
|
||||
|
||||
for (auto &mapface : hullbrush->faces) {
|
||||
if (qv::epsilonEqual(mapface.plane, plane, EQUAL_EPSILON, qbsp_options.epsilon.value())) {
|
||||
if (qv::epsilonEqual(mapface.get_plane(), plane, EQUAL_EPSILON, qbsp_options.epsilon.value())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ static void AddBrushPlane(hullbrush_t *hullbrush, const qbsp_plane_t &plane)
|
|||
}
|
||||
|
||||
mapface_t &mapface = hullbrush->faces.emplace_back();
|
||||
mapface.plane = plane;
|
||||
mapface.planenum = map.add_or_find_plane(plane);
|
||||
mapface.texinfo = 0;
|
||||
}
|
||||
|
||||
|
|
@ -418,9 +418,9 @@ static void TestAddPlane(hullbrush_t *hullbrush, qbsp_plane_t &plane)
|
|||
|
||||
/* see if the plane has already been added */
|
||||
for (auto &mapface : hullbrush->faces) {
|
||||
if (qv::epsilonEqual(plane, mapface.plane))
|
||||
if (qv::epsilonEqual(plane, mapface.get_plane()))
|
||||
return;
|
||||
if (qv::epsilonEqual(-plane, mapface.plane))
|
||||
if (qv::epsilonEqual(-plane, mapface.get_plane()))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -562,12 +562,14 @@ static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, std::ve
|
|||
continue;
|
||||
qvec3d corner{};
|
||||
for (x = 0; x < 3; x++) {
|
||||
if (mapface.plane.get_normal()[x] > 0)
|
||||
if (mapface.get_plane().get_normal()[x] > 0)
|
||||
corner[x] = hull_size[1][x];
|
||||
else if (mapface.plane.get_normal()[x] < 0)
|
||||
else if (mapface.get_plane().get_normal()[x] < 0)
|
||||
corner[x] = hull_size[0][x];
|
||||
}
|
||||
mapface.plane.get_dist() += qv::dot(corner, mapface.plane.get_normal());
|
||||
qplane3d plane = mapface.get_plane();
|
||||
plane.dist += qv::dot(corner, plane.normal);
|
||||
mapface.planenum = map.add_or_find_plane(plane);
|
||||
}
|
||||
|
||||
// add any axis planes not contained in the brush to bevel off corners
|
||||
|
|
|
|||
39
qbsp/map.cc
39
qbsp/map.cc
|
|
@ -1540,9 +1540,10 @@ bool mapface_t::set_planepts(const std::array<qvec3d, 3> &pts)
|
|||
qvec3d cb = planepts[2] - planepts[1];
|
||||
|
||||
vec_t length;
|
||||
|
||||
plane.set_normal(qv::normalize(qv::cross(ab, cb), length));
|
||||
plane.get_dist() = qv::dot(planepts[1], plane.get_normal());
|
||||
qvec3d normal = qv::normalize(qv::cross(ab, cb), length);
|
||||
vec_t dist = qv::dot(planepts[1], normal);
|
||||
|
||||
planenum = map.add_or_find_plane({ normal, dist });
|
||||
|
||||
return length >= NORMAL_EPSILON;
|
||||
}
|
||||
|
|
@ -1561,6 +1562,11 @@ void mapface_t::set_texvecs(const texvecf &vecs)
|
|||
this->texinfo = FindTexinfo(texInfoNew);
|
||||
}
|
||||
|
||||
const qbsp_plane_t &mapface_t::get_plane() const
|
||||
{
|
||||
return map.get_plane(planenum);
|
||||
}
|
||||
|
||||
bool IsValidTextureProjection(const qvec3f &faceNormal, const qvec3f &s_vec, const qvec3f &t_vec)
|
||||
{
|
||||
// TODO: This doesn't match how light does it (TexSpaceToWorld)
|
||||
|
|
@ -1582,7 +1588,7 @@ bool IsValidTextureProjection(const qvec3f &faceNormal, const qvec3f &s_vec, con
|
|||
|
||||
inline bool IsValidTextureProjection(const mapface_t &mapface, const maptexinfo_t *tx)
|
||||
{
|
||||
return IsValidTextureProjection(mapface.plane.get_normal(), tx->vecs.row(0).xyz(), tx->vecs.row(1).xyz());
|
||||
return IsValidTextureProjection(mapface.get_plane().get_normal(), tx->vecs.row(0).xyz(), tx->vecs.row(1).xyz());
|
||||
}
|
||||
|
||||
static void ValidateTextureProjection(mapface_t &mapface, maptexinfo_t *tx)
|
||||
|
|
@ -1596,7 +1602,7 @@ static void ValidateTextureProjection(mapface_t &mapface, maptexinfo_t *tx)
|
|||
const std::array<vec_t, 2> shift{0, 0};
|
||||
const vec_t rotate = 0;
|
||||
const std::array<vec_t, 2> scale = {1, 1};
|
||||
SetTexinfo_QuakeEd(mapface.plane, mapface.planepts, shift, rotate, scale, tx);
|
||||
SetTexinfo_QuakeEd(mapface.get_plane(), mapface.planepts, shift, rotate, scale, tx);
|
||||
|
||||
Q_assert(IsValidTextureProjection(mapface, tx));
|
||||
}
|
||||
|
|
@ -1615,7 +1621,7 @@ static std::unique_ptr<mapface_t> ParseBrushFace(parser_t &parser, const mapbrus
|
|||
|
||||
normal_ok = face->set_planepts(planepts);
|
||||
|
||||
ParseTextureDef(parser, *face, brush, &tx, face->planepts, face->plane);
|
||||
ParseTextureDef(parser, *face, brush, &tx, face->planepts, face->get_plane());
|
||||
|
||||
if (!normal_ok) {
|
||||
logging::print("WARNING: line {}: Brush plane with no normal\n", parser.linenum);
|
||||
|
|
@ -1679,24 +1685,27 @@ mapbrush_t ParseBrush(parser_t &parser, const mapentity_t *entity)
|
|||
bool discardFace = false;
|
||||
for (int i = 0; i < brush.numfaces; i++) {
|
||||
const mapface_t &check = brush.face(i);
|
||||
if (qv::epsilonEqual(check.plane, face->plane)) {
|
||||
if (qv::epsilonEqual(check.get_plane(), face->get_plane())) {
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.linenum);
|
||||
discardFace = true;
|
||||
continue;
|
||||
}
|
||||
if (qv::epsilonEqual(-check.plane, face->plane)) {
|
||||
if (qv::epsilonEqual(-check.get_plane(), face->get_plane())) {
|
||||
/* FIXME - this is actually an invalid brush */
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.linenum);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (discardFace)
|
||||
|
||||
if (discardFace) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Save the face, update progress */
|
||||
|
||||
if (0 == brush.numfaces)
|
||||
if (!brush.numfaces) {
|
||||
brush.firstface = map.faces.size();
|
||||
}
|
||||
|
||||
brush.numfaces++;
|
||||
map.faces.push_back(*face);
|
||||
}
|
||||
|
|
@ -2154,7 +2163,7 @@ static void ConvertMapFace(std::ofstream &f, const mapface_t &mapface, const con
|
|||
case conversion_t::quake:
|
||||
case conversion_t::quake2: {
|
||||
const texdef_quake_ed_t quakeed =
|
||||
TexDef_BSPToQuakeEd(mapface.plane, texture, texinfo.vecs, mapface.planepts);
|
||||
TexDef_BSPToQuakeEd(mapface.get_plane(), texture, texinfo.vecs, mapface.planepts);
|
||||
|
||||
fmt::print(f, "{} ", mapface.texname);
|
||||
fprintDoubleAndSpc(f, quakeed.shift[0]);
|
||||
|
|
@ -2199,7 +2208,7 @@ static void ConvertMapFace(std::ofstream &f, const mapface_t &mapface, const con
|
|||
texSize[0] = texture ? texture->width : 64;
|
||||
texSize[1] = texture ? texture->height : 64;
|
||||
|
||||
const texdef_brush_primitives_t bp = TexDef_BSPToBrushPrimitives(mapface.plane, texSize, texinfo.vecs);
|
||||
const texdef_brush_primitives_t bp = TexDef_BSPToBrushPrimitives(mapface.get_plane(), texSize, texinfo.vecs);
|
||||
f << "( ( ";
|
||||
fprintDoubleAndSpc(f, bp.at(0, 0));
|
||||
fprintDoubleAndSpc(f, bp.at(0, 1));
|
||||
|
|
@ -2360,14 +2369,14 @@ inline vec_t GetBrushExtents(const mapbrush_t &hullbrush)
|
|||
auto &fk = hullbrush.face(k);
|
||||
|
||||
bool legal = true;
|
||||
auto vertex = GetIntersection(fi.plane, fj.plane, fk.plane);
|
||||
auto vertex = GetIntersection(fi.get_plane(), fj.get_plane(), fk.get_plane());
|
||||
|
||||
if (!vertex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t m = 0; m < hullbrush.numfaces; m++) {
|
||||
if (hullbrush.face(m).plane.distance_to(*vertex) > NORMAL_EPSILON) {
|
||||
if (hullbrush.face(m).get_plane().distance_to(*vertex) > NORMAL_EPSILON) {
|
||||
legal = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ TEST_CASE("InvalidTextureProjection", "[qbsp]")
|
|||
const mapface_t *face = &worldspawn.mapbrush(0).face(5);
|
||||
REQUIRE("skip" == face->texname);
|
||||
const auto texvecs = face->get_texvecs();
|
||||
CHECK(IsValidTextureProjection(face->plane.get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
CHECK(IsValidTextureProjection(face->get_plane().get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -462,7 +462,7 @@ TEST_CASE("InvalidTextureProjection2", "[qbsp]")
|
|||
const mapface_t *face = &worldspawn.mapbrush(0).face(5);
|
||||
REQUIRE("skip" == face->texname);
|
||||
const auto texvecs = face->get_texvecs();
|
||||
CHECK(IsValidTextureProjection(face->plane.get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
CHECK(IsValidTextureProjection(face->get_plane().get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -493,7 +493,7 @@ TEST_CASE("InvalidTextureProjection3", "[qbsp]")
|
|||
const mapface_t *face = &worldspawn.mapbrush(0).face(3);
|
||||
REQUIRE("*lava1" == face->texname);
|
||||
const auto texvecs = face->get_texvecs();
|
||||
CHECK(IsValidTextureProjection(face->plane.get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
CHECK(IsValidTextureProjection(face->get_plane().get_normal(), texvecs.row(0), texvecs.row(1)));
|
||||
}
|
||||
|
||||
TEST_CASE("WindingArea", "[mathlib]")
|
||||
|
|
|
|||
Loading…
Reference in New Issue