- He fet una cosa que m'ha dit copailot, pero no ha valgut pa res. Ja ho miraré en calma
This commit is contained in:
146
main.cpp
146
main.cpp
@@ -7,6 +7,10 @@
|
|||||||
#include "wad.h"
|
#include "wad.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define FOV 277
|
#define FOV 277
|
||||||
|
|
||||||
@@ -66,6 +70,144 @@ struct sidedef {
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Área firmada de un contorno
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
float signed_area(const std::vector<wall>& contour,
|
||||||
|
const std::vector<vec2>& verts)
|
||||||
|
{
|
||||||
|
float area = 0.0f;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < contour.size(); i++) {
|
||||||
|
int a = contour[i].v1;
|
||||||
|
int b = contour[i].v2;
|
||||||
|
|
||||||
|
const vec2& p = verts[a];
|
||||||
|
const vec2& q = verts[b];
|
||||||
|
|
||||||
|
area += (p.x * q.y - q.x * p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return area * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Extrae todos los contornos (ciclos) del sector
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
std::vector<std::vector<wall>>
|
||||||
|
extract_contours(std::vector<wall> walls)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<wall>> contours;
|
||||||
|
std::unordered_multimap<int,int> startMap;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)walls.size(); i++)
|
||||||
|
startMap.emplace(walls[i].v1, i);
|
||||||
|
|
||||||
|
std::vector<bool> used(walls.size(), false);
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)walls.size(); i++) {
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
std::vector<wall> contour;
|
||||||
|
int current = i;
|
||||||
|
|
||||||
|
contour.push_back(walls[current]);
|
||||||
|
used[current] = true;
|
||||||
|
|
||||||
|
int v = walls[current].v2;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto range = startMap.equal_range(v);
|
||||||
|
int next = -1;
|
||||||
|
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
int idx = it->second;
|
||||||
|
if (!used[idx]) {
|
||||||
|
next = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next == -1)
|
||||||
|
break; // ciclo cerrado
|
||||||
|
|
||||||
|
contour.push_back(walls[next]);
|
||||||
|
used[next] = true;
|
||||||
|
v = walls[next].v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
contours.push_back(contour);
|
||||||
|
}
|
||||||
|
|
||||||
|
return contours;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Ordena y fuerza sentido horario en contorno exterior
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
void order_sector_walls_with_holes(sector& sector)
|
||||||
|
{
|
||||||
|
if (sector.walls.empty()) return;
|
||||||
|
|
||||||
|
// 1. Extraer contornos
|
||||||
|
auto contours = extract_contours(sector.walls);
|
||||||
|
|
||||||
|
// 2. Clasificar contornos por área
|
||||||
|
struct ContourInfo {
|
||||||
|
std::vector<wall> walls;
|
||||||
|
float area;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ContourInfo> info;
|
||||||
|
info.reserve(contours.size());
|
||||||
|
|
||||||
|
for (auto& c : contours) {
|
||||||
|
float a = signed_area(c, verts);
|
||||||
|
info.push_back({c, a});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Encontrar el contorno exterior (el de mayor área absoluta)
|
||||||
|
int exteriorIndex = 0;
|
||||||
|
float maxAbsArea = std::abs(info[0].area);
|
||||||
|
|
||||||
|
for (int i = 1; i < (int)info.size(); i++) {
|
||||||
|
float absA = std::abs(info[i].area);
|
||||||
|
if (absA > maxAbsArea) {
|
||||||
|
maxAbsArea = absA;
|
||||||
|
exteriorIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Forzar sentido horario en el contorno exterior
|
||||||
|
if (info[exteriorIndex].area < 0.0f) {
|
||||||
|
std::reverse(info[exteriorIndex].walls.begin(),
|
||||||
|
info[exteriorIndex].walls.end());
|
||||||
|
for (auto& w : info[exteriorIndex].walls)
|
||||||
|
std::swap(w.v1, w.v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Mantener agujeros en antihorario (o invertir si tu motor lo exige)
|
||||||
|
for (int i = 0; i < (int)info.size(); i++) {
|
||||||
|
if (i == exteriorIndex) continue;
|
||||||
|
|
||||||
|
// Si quieres agujeros en horario, descomenta:
|
||||||
|
/*
|
||||||
|
if (info[i].area < 0.0f) {
|
||||||
|
std::reverse(info[i].walls.begin(), info[i].walls.end());
|
||||||
|
for (auto& w : info[i].walls)
|
||||||
|
std::swap(w.v1, w.v2);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Reconstruir la lista final de paredes
|
||||||
|
sector.walls.clear();
|
||||||
|
for (auto& c : info)
|
||||||
|
for (auto& w : c.walls)
|
||||||
|
sector.walls.push_back(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void loadMap(const char* name)
|
void loadMap(const char* name)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
@@ -141,6 +283,8 @@ void loadMap(const char* name)
|
|||||||
|
|
||||||
for (auto &s : sectors )
|
for (auto &s : sectors )
|
||||||
{
|
{
|
||||||
|
order_sector_walls_with_holes(s);
|
||||||
|
|
||||||
for (auto &w : s.walls )
|
for (auto &w : s.walls )
|
||||||
{
|
{
|
||||||
const int width = w.surf ? w.surf->w : w.upper_surf ? w.upper_surf->w : w.lower_surf ? w.lower_surf->w : 64;
|
const int width = w.surf ? w.surf->w : w.upper_surf ? w.upper_surf->w : w.lower_surf ? w.lower_surf->w : 64;
|
||||||
@@ -324,7 +468,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
wall_end = SDL_min(wall_end, end);
|
wall_end = SDL_min(wall_end, end);
|
||||||
|
|
||||||
//SDL_assert(&s != §ors[w->portal]);
|
//SDL_assert(&s != §ors[w->portal]);
|
||||||
printf("Anem al sector: %i\n", w->portal);
|
//printf("Anem al sector: %i\n", w->portal);
|
||||||
//SDL_assert(w->portal != last_sector);
|
//SDL_assert(w->portal != last_sector);
|
||||||
last_sector = actual_sector;
|
last_sector = actual_sector;
|
||||||
actual_sector = w->portal;
|
actual_sector = w->portal;
|
||||||
|
|||||||
Reference in New Issue
Block a user