Code cleanup

This commit is contained in:
KP 2024-07-22 08:47:11 -05:00
parent ed4e817598
commit f57d6a467b
2 changed files with 47 additions and 222 deletions

View file

@ -1,22 +1,14 @@
[01:53:57 AM] Info: Starting... [08:40:36 AM] Info: Starting...
KP3D version 2 KP3D version 2
=============================== ===============================
Copyright (C) kpworld.xyz 2018-2024 Copyright (C) kpworld.xyz 2018-2024
Contact me! @kp_cftsz Contact me! @kp_cftsz
[01:53:57 AM] Info: Initializing SDL [08:40:36 AM] Info: Initializing SDL
[01:53:57 AM] Info: Initializing OpenGL [08:40:36 AM] Info: Initializing OpenGL
[01:53:57 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23 [08:40:36 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
[01:53:57 AM] Info: Initializing GLEW [08:40:36 AM] Info: Initializing GLEW
[01:53:57 AM] Info: Initializing SDL_mixer [08:40:36 AM] Info: Initializing SDL_mixer
[01:53:57 AM] Info: Reticulating splines... [08:40:36 AM] Info: Reticulating splines...
[01:53:57 AM] Info: Ready! [08:40:37 AM] Info: Ready!
[01:53:57 AM] Info: WALL POLYGON SIZE: 4 / POINTS SIZE: 4
[01:53:57 AM] Info: WALL POLYGON SIZE: 5 / POINTS SIZE: 5
[01:53:57 AM] Info: WALL POLYGON SIZE: 4 / POINTS SIZE: 4
[01:53:57 AM] Info: WALL POLYGON SIZE: 4 / POINTS SIZE: 4
[01:53:57 AM] Info: WALL POLYGON SIZE: 7 / POINTS SIZE: 7
[01:53:57 AM] Info: WALL POLYGON SIZE: 4 / POINTS SIZE: 4
[01:53:57 AM] Info: WALL POLYGON SIZE: 25 / POINTS SIZE: 25
[01:59:59 AM] Info: Stopping...

View file

@ -6,9 +6,6 @@
#include <clipper/clipper.hpp> #include <clipper/clipper.hpp>
#include <poly2tri/poly2tri.h> #include <poly2tri/poly2tri.h>
#define CSGJSCPP_IMPLEMENTATION
#include <csgjs.h>
#include "KP3D_Renderer3D.h" #include "KP3D_Renderer3D.h"
#include "KP3D_Shader.h" #include "KP3D_Shader.h"
@ -266,6 +263,9 @@ ErrCode Map::SaveToFile(const std::string& path)
return FAILURE; return FAILURE;
} }
/*
* Builds a "flat" by triangulating its polygon and sending it to the mesh
*/
void Map::BuildFlat(Sector& sector, Flat& flat, bool invert) void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
{ {
const float e = 0.001f; const float e = 0.001f;
@ -336,183 +336,56 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
} }
} }
/*
* Builds a wall quad by clipping the input quad a/b against the sector's flats, then triangulating the resulting polygon
*
* To do this we perform a similar approach to BuildFlat, but because the walls aren't strictly along one axis we have to
* "flatten" them to perform the math to triangulate them. This is done by projecting the 3D points to 2D.
*/
void Map::BuildQuad(Sector& sector, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset) void Map::BuildQuad(Sector& sector, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset)
{ {
Vec2 dist(fabsf(pos_a.x - pos_b.x), fabsf(pos_a.z - pos_b.z));
float u = ceilf(dist.Length()) * 0.5f;
float v = fabsf(pos_a.y - pos_b.y) * 0.5f;
if (flip_u) u = -u;
if (flip_v) v = -v;
float uo = uv_offset.x / texture_scale;
float vo = uv_offset.y / texture_scale;
float tw = (texture_scale / texture->GetWidth());
float th = (texture_scale / texture->GetHeight());
// Define the 4 points of the quad
Vec3 p1 = Vec3(pos_a.x, pos_a.y, pos_a.z); Vec3 p1 = Vec3(pos_a.x, pos_a.y, pos_a.z);
Vec3 p2 = Vec3(pos_a.x, pos_b.y, pos_a.z); Vec3 p2 = Vec3(pos_a.x, pos_b.y, pos_a.z);
Vec3 p3 = Vec3(pos_b.x, pos_a.y, pos_b.z); Vec3 p3 = Vec3(pos_b.x, pos_a.y, pos_b.z);
Vec3 p4 = Vec3(pos_b.x, pos_b.y, pos_b.z); Vec3 p4 = Vec3(pos_b.x, pos_b.y, pos_b.z);
// Calculate vectors lying on the plane
Vec3 v1 = { p3.x - p1.x, p3.y - p1.y, p3.z - p1.z };
Vec3 v2 = { p4.x - p1.x, p4.y - p1.y, p4.z - p1.z };
Vec3 vtx0 = p1;// Vec3(pos_a.x, pos_a.y, pos_b.z);
Vec3 vtx1 = p2;// Vec3(pos_a.x, pos_b.y, pos_b.z);
Vec3 vtx2 = p3;// Vec3(pos_b.x, pos_a.y, pos_a.z);
Vec3 vtx3 = p4;// Vec3(pos_b.x, pos_b.y, pos_a.z);
Vec3 vtx4 = p3;// Vec3(pos_b.x, pos_a.y, pos_a.z);
Vec3 vtx5 = p2;// Vec3(pos_a.x, pos_b.y, pos_b.z);
// Now build up a polygon based on the sector's triangulated data
// I could alternatively use the steiner points only, but I don't wanna count on that.
csgjscpp::Polygon p_flat;
csgjscpp::Polygon p_wall;
std::vector<Vec3> points; std::vector<Vec3> points;
points.emplace_back(0.0f);
std::unordered_map<Vec3, Vec3, Vec3Hash> og_zs;
Vec3 mp1 = p1;
mp1 -= p1;
//mp1.y = p1.y;
m_dots.clear();
points.clear();
points.push_back(mp1);
Vec3 mp3 = {
Distance({p3.x, p3.z}, {p1.x, p1.z}),
p3.y,
0
};
//points.push_back(mp3);
for (const Vertex3D& v: sector.floor.triangulated_data) for (const Vertex3D& v: sector.floor.triangulated_data)
{ {
if (!PointInLine(v.position.x, v.position.z, pos_a.x, pos_a.z, pos_b.x, pos_b.z)) if (!PointInLine(v.position.x, v.position.z, pos_a.x, pos_a.z, pos_b.x, pos_b.z))
continue; continue;
//Vec3 mod_pos = v.position; // Project 3D point into 2D
Vec3 mpos = { Vec3 mpos = {Distance({v.position.x, v.position.z}, {p1.x, p1.z}), v.position.y, 0};
Distance({v.position.x, v.position.z}, {p1.x, p1.z}),
v.position.y, // Overwrite the start point if we've landed on it
0 if (FloatCmp(v.position.x, p1.x, 0.0001f) && FloatCmp(v.position.z, p1.z, 0.0001f))
}; points[0] = mpos;
if (FloatCmp(v.position.x, p1.x, 0.0001f) && FloatCmp(v.position.z, p1.z, 0.0001f))
{
// Overwrite the start point if we've landed on it
points[0] = mpos;
//continue;
}
og_zs.emplace(mpos, v.position);
points.push_back(mpos); points.push_back(mpos);
} }
points.emplace_back(Distance({p4.x, p4.z}, {p1.x, p1.z}), p4.y, 0);
points.emplace_back(Distance({p2.x, p2.z}, {p1.x, p1.z}), p2.y, 0);
//std::sort(points.begin() + 1, points.end(), [](Vec3 a, Vec3 b) std::sort(points.begin() + 1, points.end() - 2, [&](Vec3 a, Vec3 b) { return a.x < b.x; });
// {
// return a.x < b.x;//Distance({a.x, })
// });
//Vec3 mp2 = p2 - p1;
//Vec3 mp3 = p3 - p1;
Vec3 mp4 = {
Distance({p4.x, p4.z}, {p1.x, p1.z}),
p4.y,
0
};
points.push_back(mp4);
for (Vec3& p : points)
{
if (FloatCmp(p.x, mp4.x, 0.0001f) && FloatCmp(p.y, mp4.y))
{
}
}
Vec3 mp2 = {
Distance({p2.x, p2.z}, {p1.x, p1.z}),
p2.y,
0
};
points.push_back(mp2);
// Test: Put points back in their original positions // Test: Put points back in their original positions
float angle = atan2({ p4.z - p1.z }, { p4.x - p1.x }); float angle = atan2({ p4.z - p1.z }, { p4.x - p1.x });
for (Vec3& p: points)
{
// Convert back into 3D (this is correct, just uncomment me as needed)
//p = p.Rotated({0, 1, 0}, -ToDegrees(angle));
//p.x += p1.x;
//p.z += p1.z;
}
//Vec3 mp2 = {
//
//}
//points.push_back(mp2);
// points.push_back(pos_b);
//
// points.push_back(pos_a);
//points.push_back(pos_a);
//points.push_back({pos_a.x, pos_b.y, pos_a.z});
//points.push_back(pos_b);
#if 1
for (Vec3 p : points)
{
m_dots.push_back(p);
}
#endif
#if 1
Vec3 center = calculateCentroid(points); //pos_a + ((pos_b - pos_a) * 0.5f);
std::sort(
points.begin() + 1,
points.end() - 2,
[&](Vec3 a, Vec3 b)
{
/*
if (a.x - center.x >= 0 && b.x - center.x < 0)
return true;
if (a.x - center.x < 0 && b.x - center.x >= 0)
return false;
if (a.x - center.x == 0 && b.x - center.x == 0)
{
if (a.y - center.y >= 0 || b.y - center.y >= 0)
return a.y > b.y;
return b.y > a.y;
}
// compute the cross product of vectors (center -> a) x (center -> b)
int det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y);
if (det < 0)
return true;
if (det > 0)
return false;
// points a and b are on the same line from the center
// check which point is closer to the center
int d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
int d2 = (b.x - center.x) * (b.x - center.x) + (b.y - center.y) * (b.y - center.y);
return d1 > d2;
*/
//return Distance({ a.x, a.y }, {mp1.x, mp1.y});
return a.x < b.x;
//return Vec2(a.x, a.y) < Vec2(b.x, b.y);
}
);
#if 0 #if 0
// Debug
for (Vec3& p: points)
{
// Convert back into 3D
p = p.Rotated({0, 1, 0}, -ToDegrees(angle));
p.x += p1.x;
p.z += p1.z;
}
for (Vec3 p: points)
m_dots.push_back(p);
// Begin: Enforce clockwise-ness // Enforce clockwise-ness
float area = 0.0f; float area = 0.0f;
for (int i = 0; i < points.size(); i++) for (int i = 0; i < points.size(); i++)
{ {
@ -528,25 +401,14 @@ void Map::BuildQuad(Sector& sector, const Texture* texture, Vec3 pos_a, Vec3 pos
points.erase(unique(points.begin(), points.end()), points.end()); points.erase(unique(points.begin(), points.end()), points.end());
std::vector<std::vector<c2t::Point>> ss; // unused for now std::vector<std::vector<c2t::Point>> holes; // unused for now
std::vector<c2t::Point> wall_polygon; std::vector<c2t::Point> wall_polygon;
for (Vec3& p: points) for (Vec3& p: points)
{
wall_polygon.emplace_back(p.x, p.y); wall_polygon.emplace_back(p.x, p.y);
}
// End: Enforce clockwise-ness
glDisable(GL_CULL_FACE);
KP3D_LOG_INFO("WALL POLYGON SIZE: {} / POINTS SIZE: {}", wall_polygon.size(), points.size());
#if 1
//if (wall_polygon.size() < 10)
// return;
c2t::clip2tri clipper; c2t::clip2tri clipper;
std::vector<c2t::Point> clipper_out; std::vector<c2t::Point> clipper_out;
clipper.triangulate(ss, clipper_out, wall_polygon); clipper.triangulate(holes, clipper_out, wall_polygon);
for (int i = 0; i < clipper_out.size(); i += 3) for (int i = 0; i < clipper_out.size(); i += 3)
{ {
@ -558,15 +420,10 @@ void Map::BuildQuad(Sector& sector, const Texture* texture, Vec3 pos_a, Vec3 pos
float bu = b.x * 0.5f, bv = b.y * 0.5f; float bu = b.x * 0.5f, bv = b.y * 0.5f;
float cu = c.x * 0.5f, cv = c.y * 0.5f; float cu = c.x * 0.5f, cv = c.y * 0.5f;
// Build mesh data for floor // Build mesh data for wall
Vec3 fva = Vec3(a.x, a.y, 0.0f); Vec3 fva = Vec3(a.x, a.y, 0.0f).Rotated({ 0, 1, 0 }, -ToDegrees(angle)); fva.x += p1.x; fva.z += p1.z;
Vec3 fvb = Vec3(b.x, b.y, 0.0f); Vec3 fvb = Vec3(b.x, b.y, 0.0f).Rotated({ 0, 1, 0 }, -ToDegrees(angle)); fvb.x += p1.x; fvb.z += p1.z;
Vec3 fvc = Vec3(c.x, c.y, 0.0f); Vec3 fvc = Vec3(c.x, c.y, 0.0f).Rotated({ 0, 1, 0 }, -ToDegrees(angle)); fvc.x += p1.x; fvc.z += p1.z;
#define FIX(v) v = v.Rotated({0, 1, 0}, -ToDegrees(angle)); v.x += p1.x; v.z += p1.z;
FIX(fva);
FIX(fvb);
FIX(fvc)
// Fix up the UVs so they keep the right scale // Fix up the UVs so they keep the right scale
float tw = texture_scale / texture->GetWidth(); float tw = texture_scale / texture->GetWidth();
@ -576,34 +433,12 @@ void Map::BuildQuad(Sector& sector, const Texture* texture, Vec3 pos_a, Vec3 pos
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th)); Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
m_mesh.AddBatch(texture, {vtxa, vtxb, vtxc}, flip); m_mesh.AddBatch(texture, {vtxa, vtxb, vtxc}, flip);
} }
#endif
#endif
// We need to do the following:
/*
- Project the line to "2D", i.e. rotate it such that Z is zero so we may perform 2D computations
- Build a polygon (starting with a quad) from the 2D data
- Build another polygon from the 2D data we wish to "clip" off of this one.
- Clip the starting polygon and triangulate it; now we have our mesh
*/
} }
void Map::BuildWall(Sector& sector, Wall& wall) void Map::BuildWall(Sector& sector, Wall& wall)
{ {
Vec3 a = { Vec3 a = {wall.start.x, sector.floor.base_height, wall.start.y};
wall.start.x, Vec3 b = {wall.end.x, sector.ceiling.base_height, wall.end.y};
sector.floor.base_height,
wall.start.y
};
Vec3 b = {
wall.end.x,
sector.ceiling.base_height,
wall.end.y
};
BuildQuad(sector, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]); BuildQuad(sector, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]);
} }
@ -680,9 +515,7 @@ void Map::Init()
BuildFlat(s, s.ceiling, true); BuildFlat(s, s.ceiling, true);
for (Wall& ld: s.walls) for (Wall& ld: s.walls)
{
BuildWall(s, ld); BuildWall(s, ld);
}
m_mesh.Finalize(); m_mesh.Finalize();
} }