mirror of
https://github.com/DrBeef/Raze.git
synced 2025-04-02 06:01:05 +00:00
- removed SectorGeometry class.
This commit is contained in:
parent
7a9596ae81
commit
bb9313454d
6 changed files with 1 additions and 415 deletions
|
@ -491,7 +491,6 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
|
|||
setWallSectors();
|
||||
hw_BuildSections();
|
||||
hw_CreateSections2();
|
||||
sectorGeometry.SetSize(Sections.Size());
|
||||
sectionGeometry.SetSize(sections2.Size());
|
||||
|
||||
|
||||
|
|
|
@ -372,378 +372,3 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// moved out of the way
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SectorGeometry::MakeVertices(unsigned int secnum, int plane, const FVector2& offset)
|
||||
{
|
||||
auto sec = &Sections[secnum];
|
||||
auto sectorp = §or[sec->sector];
|
||||
int numvertices = sec->lines.Size();
|
||||
|
||||
TArray<FVector3> points(numvertices, true);
|
||||
using Point = std::pair<float, float>;
|
||||
std::vector<std::vector<Point>> polygon;
|
||||
std::vector<Point>* curPoly;
|
||||
|
||||
polygon.resize(1);
|
||||
curPoly = &polygon.back();
|
||||
FixedBitArray<MAXWALLSB> done;
|
||||
|
||||
int fz = sectorp->floorz, cz = sectorp->ceilingz;
|
||||
|
||||
int vertstoadd = numvertices;
|
||||
|
||||
done.Zero();
|
||||
while (vertstoadd > 0)
|
||||
{
|
||||
int start = 0;
|
||||
while (done[start] && start < numvertices) start++;
|
||||
int s = start;
|
||||
if (start >= 0 && start < numvertices)
|
||||
{
|
||||
while (start >= 0 && start < numvertices && !done[start])
|
||||
{
|
||||
auto sline = §ionLines[sec->lines[start]];
|
||||
auto wallp = &wall[sline->startpoint];
|
||||
float X = float(WallStartX(wallp));
|
||||
float Y = float(WallStartY(wallp));
|
||||
if (fabs(X) > 32768.f || fabs(Y) > 32768.f)
|
||||
{
|
||||
// If we get here there's some fuckery going around with the coordinates. Let's better abort and wait for things to realign.
|
||||
// Do not try alternative methods if this happens.
|
||||
return true;
|
||||
}
|
||||
curPoly->push_back(std::make_pair(X, Y));
|
||||
done.Set(start);
|
||||
vertstoadd--;
|
||||
start = sline->point2index;
|
||||
}
|
||||
polygon.resize(polygon.size() + 1);
|
||||
curPoly = &polygon.back();
|
||||
if (start != s) return false; // means the sector is badly defined. RRRA'S E1L3 triggers this.
|
||||
}
|
||||
}
|
||||
// Now make sure that the outer boundary is the first polygon by picking a point that's as much to the outside as possible.
|
||||
int outer = 0;
|
||||
float minx = FLT_MAX;
|
||||
float miny = FLT_MAX;
|
||||
for (size_t a = 0; a < polygon.size(); a++)
|
||||
{
|
||||
for (auto& pt : polygon[a])
|
||||
{
|
||||
if (pt.first < minx || (pt.first == minx && pt.second < miny))
|
||||
{
|
||||
minx = pt.first;
|
||||
miny = pt.second;
|
||||
outer = int(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outer != 0) std::swap(polygon[0], polygon[outer]);
|
||||
auto indices = mapbox::earcut(polygon);
|
||||
if (indices.size() < 3 * (sec->lines.Size() - 2))
|
||||
{
|
||||
// this means that full triangulation failed.
|
||||
return false;
|
||||
}
|
||||
sectorp->floorz = sectorp->ceilingz = 0;
|
||||
|
||||
int p = 0;
|
||||
for (size_t a = 0; a < polygon.size(); a++)
|
||||
{
|
||||
for (auto& pt : polygon[a])
|
||||
{
|
||||
float planez = 0;
|
||||
PlanesAtPoint(sectorp, (pt.first * 16), (pt.second * -16), plane ? &planez : nullptr, !plane ? &planez : nullptr);
|
||||
FVector3 point = { pt.first, pt.second, planez };
|
||||
points[p++] = point;
|
||||
}
|
||||
}
|
||||
|
||||
auto& entry = data[secnum].planes[plane];
|
||||
entry.vertices.Resize((unsigned)indices.size());
|
||||
entry.texcoords.Resize((unsigned)indices.size());
|
||||
entry.normal = CalcNormal(sectorp, plane);
|
||||
|
||||
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);
|
||||
|
||||
UVCalculator1 uvcalc(sectorp, plane, texture, offset);
|
||||
|
||||
for(unsigned i = 0; i < entry.vertices.Size(); i++)
|
||||
{
|
||||
auto& pt = points[indices[i]];
|
||||
entry.vertices[i] = pt;
|
||||
entry.texcoords[i] = uvcalc.GetUV(int(pt.X * 16), int(pt.Y * -16), pt.Z);
|
||||
}
|
||||
|
||||
sectorp->floorz = fz;
|
||||
sectorp->ceilingz = cz;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Use ZDoom's node builder if the simple approach fails.
|
||||
// This will create something usable in the vast majority of cases,
|
||||
// even if the result is less efficient.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SectorGeometry::MakeVertices2(unsigned int secnum, int plane, const FVector2& offset)
|
||||
{
|
||||
auto sec = &Sections[secnum];
|
||||
auto sectorp = §or[sec->sector];
|
||||
int numvertices = sec->lines.Size();
|
||||
|
||||
// Convert our sector into something the node builder understands
|
||||
TArray<vertex_t> vertexes(sectorp->wallnum, true);
|
||||
TArray<line_t> lines(numvertices, true);
|
||||
TArray<side_t> sides(numvertices, true);
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < numvertices; i++)
|
||||
{
|
||||
auto sline = §ionLines[sec->lines[i]];
|
||||
if (sline->point2index < 0) continue; // Exhumed LEV14 triggers this on sector 169.
|
||||
|
||||
auto wallp = &wall[sline->startpoint];
|
||||
vertexes[j].p = { wallp->x * (1 / 16.), wallp->y * (1 / -16.) };
|
||||
|
||||
if (fabs(vertexes[j].p.X) > 32768.f || fabs(vertexes[j].p.Y) > 32768.f)
|
||||
{
|
||||
// If we get here there's some fuckery going around with the coordinates. Let's better abort and wait for things to realign.
|
||||
return true;
|
||||
}
|
||||
|
||||
lines[j].backsector = nullptr;
|
||||
lines[j].frontsector = sectorp;
|
||||
lines[j].linenum = j;
|
||||
lines[j].wallnum = sline->wall;
|
||||
lines[j].sidedef[0] = &sides[j];
|
||||
lines[j].sidedef[1] = nullptr;
|
||||
lines[j].v1 = &vertexes[j];
|
||||
lines[j].v2 = &vertexes[sline->point2index + j - i];
|
||||
|
||||
sides[j].sidenum = j;
|
||||
sides[j].sector = sectorp;
|
||||
j++;
|
||||
}
|
||||
|
||||
vertexes.Clamp(j);
|
||||
lines.Clamp(j);
|
||||
sides.Clamp(j);
|
||||
// Weed out any overlaps. These often happen with door setups and can lead to bad subsectors
|
||||
for (unsigned i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
auto p1 = lines[i].v1->p, p2 = lines[i].v2->p;
|
||||
|
||||
// Throw out any line with zero length.
|
||||
if (p1 == p2)
|
||||
{
|
||||
lines.Delete(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned j = i + 1; j < lines.Size(); j++)
|
||||
{
|
||||
auto pp1 = lines[j].v1->p, pp2 = lines[j].v2->p;
|
||||
|
||||
if (pp1 == p2 && pp2 == p1)
|
||||
{
|
||||
// handle the simple case first, i.e. line j is the inverse of line i.
|
||||
// in this case both lines need to be deleted.
|
||||
lines.Delete(j);
|
||||
lines.Delete(i);
|
||||
i--;
|
||||
goto nexti;
|
||||
}
|
||||
else if (pp1 == p2)
|
||||
{
|
||||
// only the second line's start point matches.
|
||||
// In this case we have to delete the shorter line and truncate the other one.
|
||||
|
||||
// check if the second line's end point is on the line we are checking
|
||||
double d1 = PointOnLineSide(pp2, p1, p2);
|
||||
if (fabs(d1) > FLT_EPSILON) continue; // not colinear
|
||||
bool vert = p1.X == p2.X;
|
||||
double p1x = vert ? p1.X : p1.Y;
|
||||
double p2x = vert ? p2.X : p2.Y;
|
||||
double pp1x = vert ? pp1.X : pp1.Y;
|
||||
double pp2x = vert ? pp2.X : pp2.Y;
|
||||
|
||||
if (pp2x > min(p1x, p2x) && pp2x < max(p1x, p2x))
|
||||
{
|
||||
// pp2 is on line i.
|
||||
lines[i].v2 = lines[j].v2;
|
||||
lines.Delete(j);
|
||||
continue;
|
||||
}
|
||||
else if (p1x > min(pp1x, pp2x) && p1x < max(pp1x, pp2x))
|
||||
{
|
||||
// p1 is on line j
|
||||
lines[j].v1 = lines[j].v2;
|
||||
lines.Delete(i);
|
||||
goto nexti;
|
||||
}
|
||||
}
|
||||
else if (pp2 == p1)
|
||||
{
|
||||
// only the second line's start point matches.
|
||||
// In this case we have to delete the shorter line and truncate the other one.
|
||||
|
||||
// check if the second line's end point is on the line we are checking
|
||||
double d1 = PointOnLineSide(pp1, p1, p2);
|
||||
if (fabs(d1) > FLT_EPSILON) continue; // not colinear
|
||||
bool vert = p1.X == p2.X;
|
||||
double p1x = vert ? p1.X : p1.Y;
|
||||
double p2x = vert ? p2.X : p2.Y;
|
||||
double pp1x = vert ? pp1.X : pp1.Y;
|
||||
double pp2x = vert ? pp2.X : pp2.Y;
|
||||
|
||||
if (pp1x > min(p1x, p2x) && pp1x < max(p1x, p2x))
|
||||
{
|
||||
// pp1 is on line i.
|
||||
lines[i].v1 = lines[j].v1;
|
||||
lines.Delete(j);
|
||||
continue;
|
||||
}
|
||||
else if (p2x > min(pp1x, pp2x) && p2x < max(pp1x, pp2x))
|
||||
{
|
||||
// p2 is on line j
|
||||
lines[j].v2 = lines[j].v1;
|
||||
lines.Delete(i);
|
||||
goto nexti;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no idea if we should do further checks here. Blood's doors do not need them. We'll see.
|
||||
}
|
||||
}
|
||||
nexti:;
|
||||
}
|
||||
|
||||
if (lines.Size() < 4)
|
||||
{
|
||||
// nothing to generate. If line count is < 4 this sector is degenerate and should not be processed further.
|
||||
auto& entry = data[secnum].planes[plane];
|
||||
entry.vertices.Clear();
|
||||
entry.texcoords.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FNodeBuilder::FLevel leveldata =
|
||||
{
|
||||
&vertexes[0], (int)vertexes.Size(),
|
||||
&sides[0], (int)sides.Size(),
|
||||
&lines[0], (int)lines.Size(),
|
||||
0, 0, 0, 0
|
||||
};
|
||||
leveldata.FindMapBounds();
|
||||
FNodeBuilder builder(leveldata);
|
||||
|
||||
FLevelLocals Level;
|
||||
builder.Extract(Level);
|
||||
|
||||
// Now turn the generated subsectors into triangle meshes
|
||||
|
||||
auto& entry = data[secnum].planes[plane];
|
||||
entry.vertices.Clear();
|
||||
entry.texcoords.Clear();
|
||||
|
||||
int fz = sectorp->floorz, cz = sectorp->ceilingz;
|
||||
sectorp->floorz = sectorp->ceilingz = 0;
|
||||
|
||||
for (auto& sub : Level.subsectors)
|
||||
{
|
||||
if (sub.numlines <= 2) continue;
|
||||
auto v0 = sub.firstline->v1;
|
||||
for (unsigned i = 1; i < sub.numlines - 1; i++)
|
||||
{
|
||||
auto v1 = sub.firstline[i].v1;
|
||||
auto v2 = sub.firstline[i].v2;
|
||||
|
||||
entry.vertices.Push({ (float)v0->fX(), (float)v0->fY(), 0 });
|
||||
entry.vertices.Push({ (float)v1->fX(), (float)v1->fY(), 0 });
|
||||
entry.vertices.Push({ (float)v2->fX(), (float)v2->fY(), 0 });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// calculate the rest.
|
||||
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);
|
||||
|
||||
UVCalculator1 uvcalc(sectorp, plane, texture, offset);
|
||||
|
||||
entry.texcoords.Resize(entry.vertices.Size());
|
||||
for (unsigned i = 0; i < entry.vertices.Size(); i++)
|
||||
{
|
||||
auto& pt = entry.vertices[i];
|
||||
|
||||
float planez = 0;
|
||||
PlanesAtPoint(sectorp, (pt.X * 16), (pt.Y * -16), plane ? &planez : nullptr, !plane ? &planez : nullptr);
|
||||
entry.vertices[i].Z = planez;
|
||||
entry.texcoords[i] = uvcalc.GetUV(int(pt.X * 16.), int(pt.Y * -16.), pt.Z);
|
||||
}
|
||||
entry.normal = CalcNormal(sectorp, plane);
|
||||
sectorp->floorz = fz;
|
||||
sectorp->ceilingz = cz;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SectorGeometry::ValidateSector(unsigned int secnum, int plane, const FVector2& offset)
|
||||
{
|
||||
auto sec = §or[Sections[secnum].sector];
|
||||
|
||||
auto compare = &data[secnum].compare[plane];
|
||||
if (plane == 0)
|
||||
{
|
||||
if (sec->floorheinum == compare->floorheinum &&
|
||||
sec->floorpicnum == compare->floorpicnum &&
|
||||
((sec->floorstat ^ compare->floorstat) & (CSTAT_SECTOR_ALIGN | CSTAT_SECTOR_YFLIP | CSTAT_SECTOR_XFLIP | CSTAT_SECTOR_TEXHALF | CSTAT_SECTOR_SWAPXY)) == 0 &&
|
||||
sec->floorxpan_ == compare->floorxpan_ &&
|
||||
sec->floorypan_ == compare->floorypan_ &&
|
||||
sec->firstWall()->pos == data[secnum].poscompare[0] &&
|
||||
sec->firstWall()->point2Wall()->pos == data[secnum].poscompare2[0] &&
|
||||
!(sec->dirty & 1) && data[secnum].planes[plane].vertices.Size() ) return;
|
||||
|
||||
sec->dirty &= ~1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sec->ceilingheinum == compare->ceilingheinum &&
|
||||
sec->ceilingpicnum == compare->ceilingpicnum &&
|
||||
((sec->ceilingstat ^ compare->ceilingstat) & (CSTAT_SECTOR_ALIGN | CSTAT_SECTOR_YFLIP | CSTAT_SECTOR_XFLIP | CSTAT_SECTOR_TEXHALF | CSTAT_SECTOR_SWAPXY)) == 0 &&
|
||||
sec->ceilingxpan_ == compare->ceilingxpan_ &&
|
||||
sec->ceilingypan_ == compare->ceilingypan_ &&
|
||||
sec->firstWall()->pos == data[secnum].poscompare[1] &&
|
||||
sec->firstWall()->point2Wall()->pos == data[secnum].poscompare2[1] &&
|
||||
!(sec->dirty & 2) && data[secnum].planes[1].vertices.Size()) return;
|
||||
|
||||
sec->dirty &= ~2;
|
||||
}
|
||||
*compare = *sec;
|
||||
data[secnum].poscompare[plane] = sec->firstWall()->pos;
|
||||
data[secnum].poscompare2[plane] = sec->firstWall()->point2Wall()->pos;
|
||||
if (data[secnum].degenerate || !MakeVertices(secnum, plane, offset))
|
||||
{
|
||||
data[secnum].degenerate = true;
|
||||
//Printf(TEXTCOLOR_YELLOW "Normal triangulation failed for sector %d. Retrying with alternative approach\n", secnum);
|
||||
MakeVertices2(secnum, plane, offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -727,7 +727,7 @@ void SerializeMap(FSerializer& arc)
|
|||
setWallSectors();
|
||||
hw_BuildSections();
|
||||
hw_CreateSections2();
|
||||
sectorGeometry.SetSize(Sections.Size());
|
||||
sectionGeometry.SetSize(sections2.Size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "hw_sections2.h"
|
||||
#include "tesselator.h"
|
||||
|
||||
SectorGeometry sectorGeometry;
|
||||
SectionGeometry sectionGeometry;
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -13,41 +13,6 @@ struct SectorGeometryPlane
|
|||
FVector3 normal{};
|
||||
};
|
||||
|
||||
struct SectorGeometryData
|
||||
{
|
||||
SectorGeometryPlane planes[2];
|
||||
sectortype compare[2] = {};
|
||||
vec2_t poscompare[2] = {};
|
||||
vec2_t poscompare2[2] = {};
|
||||
bool degenerate = false;
|
||||
};
|
||||
|
||||
class SectorGeometry
|
||||
{
|
||||
TArray<SectorGeometryData> data;
|
||||
|
||||
void ValidateSector(unsigned sectnum, int plane, const FVector2& offset);
|
||||
bool MakeVertices(unsigned sectnum, int plane, const FVector2& offset);
|
||||
bool MakeVertices2(unsigned sectnum, int plane, const FVector2& offset);
|
||||
|
||||
public:
|
||||
SectorGeometryPlane* get(unsigned sectnum, int plane, const FVector2& offset)
|
||||
{
|
||||
if (sectnum >= data.Size()) return nullptr;
|
||||
ValidateSector(sectnum, plane, offset);
|
||||
return &data[sectnum].planes[plane];
|
||||
}
|
||||
|
||||
void SetSize(unsigned sectcount)
|
||||
{
|
||||
data.Clear(); // delete old content
|
||||
data.Resize(sectcount);
|
||||
}
|
||||
};
|
||||
|
||||
extern SectorGeometry sectorGeometry;
|
||||
|
||||
|
||||
enum GeomFlags
|
||||
{
|
||||
NoEarcut = 1,
|
||||
|
@ -89,7 +54,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
extern SectorGeometry sectorGeometry;
|
||||
extern SectionGeometry sectionGeometry;
|
||||
|
||||
|
|
@ -730,7 +730,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
|
|||
setWallSectors();
|
||||
hw_BuildSections();
|
||||
hw_CreateSections2();
|
||||
sectorGeometry.SetSize(Sections.Size());
|
||||
sectionGeometry.SetSize(sections2.Size());
|
||||
wallbackup = wall;
|
||||
sectorbackup = sector;
|
||||
|
|
Loading…
Reference in a new issue