raze/source/core/rendering/hw_sections2.cpp

111 lines
2.6 KiB
C++
Raw Normal View History

2021-12-08 18:17:45 +00:00
#include "build.h"
#include "hw_sections2.h"
int GetWindingOrder(TArray<int>& walls)
{
int check = -1;
int minY = INT_MAX;
int minXAtMinY = INT_MAX;
for (unsigned i = 0; i < walls.Size(); i++)
{
auto wal = &wall[walls[i]];
int y = wal->y;
if (y < minY)
{
minY = y;
minXAtMinY = INT_MAX, // must reset this if a new y is picked.
check = i;
}
else if (y == minY && wal->x < minXAtMinY)
{
minXAtMinY = wal->x;
}
}
unsigned prev = check == 0? walls.Size() - 1 : check - 1;
unsigned next = check == walls.Size()? 0 : check + 1;
DVector2 a = { (double)wall[walls[prev]].x, (double)wall[walls[prev]].y };
DVector2 b = { (double)wall[walls[check]].x, (double)wall[walls[check]].y };
DVector2 c = { (double)wall[walls[next]].x, (double)wall[walls[next]].y };
return (b.X * c.Y + a.X * b.Y + a.Y * c.X) - (a.Y * b.X + b.Y * c.X + a.X * c.Y) > 0;
}
struct loopcollect
{
TArray<TArray<int>> loops;
bool bugged;
};
void CollectLoops(TArray<loopcollect>& sectors)
{
BitArray visited;
visited.Resize(numwalls);
visited.Zero();
TArray<int> thisloop;
int count = 0;
for (int i = 0; i < numsectors; i++)
{
int first = sector[i].wallptr;
int last = first + sector[i].wallnum;
sectors.Reserve(1);
sectors.Last().bugged = false;
for (int w = first; w < last; w++)
{
if (visited[w]) continue;
thisloop.Clear();
thisloop.Push(w);
visited.Set(w);
2021-12-08 18:17:45 +00:00
for (int ww = wall[w].point2; ww != w; ww = wall[ww].point2)
{
if (ww < first || ww >= last)
{
Printf("Found wall %d outside sector %d in a loop\n", ww, i);
sectors.Last().bugged = true;
break;
}
if (visited[ww])
{
// quick check for the only known cause of this in proper maps:
// RRRA E1L3 and SW $yamato have a wall duplicate where the duplicate's index is the original's + 1. These can just be deleted here and be ignored.
if (ww > 1 && wall[ww-1].x == wall[ww-2].x && wall[ww-1].y == wall[ww-2].y && wall[ww-1].point2 == wall[ww-2].point2 && wall[ww - 1].point2 == ww)
{
thisloop.Clear();
break;
}
Printf("found already visited wall %d\nLinked by:", ww);
for (int i = 0; i < numwalls; i++)
{
if (wall[i].point2 == ww)
Printf(" %d,", i);
}
Printf("\n");
2021-12-08 18:17:45 +00:00
sectors.Last().bugged = true;
break;
}
thisloop.Push(ww);
visited.Set(ww);
}
if (thisloop.Size() > 0)
{
count++;
sectors.Last().loops.Push(std::move(thisloop));
}
2021-12-08 18:17:45 +00:00
}
}
Printf("Created %d loops from %d sectors, %d walls\n", count, numsectors, numwalls);
}
void hw_CreateSections2()
{
TArray<loopcollect> sectors;
CollectLoops(sectors);
}