Map gen mostly works now :D
This commit is contained in:
parent
5a13579849
commit
0b41057244
4 changed files with 130 additions and 121 deletions
|
@ -1,56 +1,15 @@
|
|||
[00:07:49 AM] Info: Starting...
|
||||
[00:48:43 AM] Info: Starting...
|
||||
|
||||
KP3D version 2
|
||||
===============================
|
||||
Copyright (C) kpworld.xyz 2018-2024
|
||||
Contact me! @kp_cftsz
|
||||
|
||||
[00:07:49 AM] Info: Initializing SDL
|
||||
[00:07:49 AM] Info: Initializing OpenGL
|
||||
[00:07:49 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
|
||||
[00:07:49 AM] Info: Initializing GLEW
|
||||
[00:07:49 AM] Info: Initializing SDL_mixer
|
||||
[00:07:49 AM] Info: Reticulating splines...
|
||||
[00:07:49 AM] Info: Ready!
|
||||
[00:07:49 AM] Info: SECTOR HIERARCHY
|
||||
[00:07:49 AM] Info: Sector 3 (area: 1)
|
||||
[00:07:49 AM] Info: Parent:
|
||||
[00:07:49 AM] Info: - 1
|
||||
[00:07:49 AM] Info: Children:
|
||||
[00:07:49 AM] Info: - [NO CHILDREN]
|
||||
[00:07:49 AM] Info: -----
|
||||
[00:07:49 AM] Info: Sector 4 (area: 1)
|
||||
[00:07:49 AM] Info: Parent:
|
||||
[00:07:49 AM] Info: - 2
|
||||
[00:07:49 AM] Info: Children:
|
||||
[00:07:49 AM] Info: - [NO CHILDREN]
|
||||
[00:07:49 AM] Info: -----
|
||||
[00:07:49 AM] Info: Sector 2 (area: 19)
|
||||
[00:07:49 AM] Info: Parent:
|
||||
[00:07:49 AM] Info: - 1
|
||||
[00:07:49 AM] Info: Children:
|
||||
[00:07:49 AM] Info: - 4
|
||||
[00:07:49 AM] Info: -----
|
||||
[00:07:49 AM] Info: Sector 5 (area: 34)
|
||||
[00:07:49 AM] Info: Parent:
|
||||
[00:07:49 AM] Info: - [NO PARENT]
|
||||
[00:07:49 AM] Info: Children:
|
||||
[00:07:49 AM] Info: - [NO CHILDREN]
|
||||
[00:07:49 AM] Info: -----
|
||||
[00:07:49 AM] Info: Sector 1 (area: 105.5)
|
||||
[00:07:49 AM] Info: Parent:
|
||||
[00:07:49 AM] Info: - [NO PARENT]
|
||||
[00:07:49 AM] Info: Children:
|
||||
[00:07:49 AM] Info: - 3
|
||||
[00:07:49 AM] Info: - 2
|
||||
[00:07:49 AM] Info: -----
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 3
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 3
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 4
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 4
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 2
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 2
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 5
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 5
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 1
|
||||
[00:07:49 AM] Info: TRIANGULATING SECTOR: 1
|
||||
[00:48:43 AM] Info: Initializing SDL
|
||||
[00:48:43 AM] Info: Initializing OpenGL
|
||||
[00:48:43 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
|
||||
[00:48:43 AM] Info: Initializing GLEW
|
||||
[00:48:43 AM] Info: Initializing SDL_mixer
|
||||
[00:48:43 AM] Info: Reticulating splines...
|
||||
[00:48:43 AM] Info: Ready!
|
||||
[00:50:29 AM] Info: Stopping...
|
||||
|
|
|
@ -251,7 +251,7 @@ bool clip2tri::triangulateComplex(vector<Point> &outputTriangles, const Path &ou
|
|||
F64(S64(steiner_points->at(j).x * CLIPPER_SCALE_FACT)),
|
||||
F64(S64(steiner_points->at(j).y * CLIPPER_SCALE_FACT)),
|
||||
});
|
||||
//cdt->AddPoint(steiners[j]);
|
||||
cdt->AddPoint(steiners[j]);
|
||||
}
|
||||
}
|
||||
// end: steiner points
|
||||
|
|
|
@ -56,6 +56,56 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner) {
|
|||
return completely_inside || (count > 0 && partial_count < 4);
|
||||
}
|
||||
|
||||
using namespace kp3d;
|
||||
|
||||
// Function to find the barycentric coordinates of a point within a triangle
|
||||
void Barycentric(const Vec2& p, const Vec2& a, const Vec2& b, const Vec2& c, float& u, float& v, float& w) {
|
||||
Vec2 v0 = { b.x - a.x, b.y - a.y };
|
||||
Vec2 v1 = { c.x - a.x, c.y - a.y };
|
||||
Vec2 v2 = { p.x - a.x, p.y - a.y };
|
||||
float d00 = v0.x * v0.x + v0.y * v0.y;
|
||||
float d01 = v0.x * v1.x + v0.y * v1.y;
|
||||
float d11 = v1.x * v1.x + v1.y * v1.y;
|
||||
float d20 = v2.x * v0.x + v2.y * v0.y;
|
||||
float d21 = v2.x * v1.x + v2.y * v1.y;
|
||||
float denom = d00 * d11 - d01 * d01;
|
||||
v = (d11 * d20 - d01 * d21) / denom;
|
||||
w = (d00 * d21 - d01 * d20) / denom;
|
||||
u = 1.0f - v - w;
|
||||
}
|
||||
|
||||
// Function to interpolate Y value
|
||||
float InterpolateY(const Vec2& p, const Vertex3D& a, const Vertex3D& b, const Vertex3D& c) {
|
||||
float u, v, w;
|
||||
Vec2 pa = { a.position.x, a.position.z };
|
||||
Vec2 pb = { b.position.x, b.position.z };
|
||||
Vec2 pc = { c.position.x, c.position.z };
|
||||
Barycentric(p, pa, pb, pc, u, v, w);
|
||||
return u * a.position.y + v * b.position.y + w * c.position.y;
|
||||
}
|
||||
|
||||
// Sample floor vertices
|
||||
float SampleY(const std::vector<Vertex3D>& floor_vertices, const Vec2& sample_pos) {
|
||||
for (size_t i = 0; i < floor_vertices.size(); i += 3) {
|
||||
const Vertex3D& v0 = floor_vertices[i];
|
||||
const Vertex3D& v1 = floor_vertices[i + 1];
|
||||
const Vertex3D& v2 = floor_vertices[i + 2];
|
||||
|
||||
Vec2 pa = { v0.position.x, v0.position.z };
|
||||
Vec2 pb = { v1.position.x, v1.position.z };
|
||||
Vec2 pc = { v2.position.x, v2.position.z };
|
||||
|
||||
// Check if the sample position is inside the triangle
|
||||
float u, v, w;
|
||||
Barycentric(sample_pos, pa, pb, pc, u, v, w);
|
||||
if (u >= 0 && v >= 0 && w >= 0) {
|
||||
return InterpolateY(sample_pos, v0, v1, v2);
|
||||
}
|
||||
}
|
||||
return 0.0f; // Default value if the point is not found in any triangle (should not happen if inputs are correct)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace kp3d {
|
||||
|
@ -105,7 +155,6 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
|
|||
s->floor.texture = nullptr;
|
||||
if (FloatCmp(s->ceiling.base_height, sector.ceiling.base_height, e))
|
||||
s->ceiling.texture = nullptr;
|
||||
//continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -114,83 +163,68 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
|
|||
l.portal = §or;
|
||||
}
|
||||
ss.push_back({l.start.x, l.start.y});
|
||||
|
||||
area += l.start.x * l.end.y;
|
||||
area -= l.end.x * l.start.y;
|
||||
}
|
||||
|
||||
//if (area > 0)//<= 0.0f)
|
||||
// std::reverse(ss.begin(), ss.end());
|
||||
|
||||
subsector_polygons.push_back(ss);
|
||||
if (!s->inverted)
|
||||
subsector_polygons.push_back(ss);
|
||||
}
|
||||
|
||||
std::vector<c2t::Point> flat_polygons;
|
||||
for (Wall& l: sector.walls)
|
||||
flat_polygons.emplace_back(l.start.x, l.start.y);
|
||||
KP3D_LOG_INFO("TRIANGULATING SECTOR: {}", sector.id);
|
||||
//std::vector<std::vector<Vec2>> polygons = ClipPolygonHoles(flat_polygons, subsector_polygons);
|
||||
//for (const std::vector<Vec2>& polygon: polygons)
|
||||
//const auto& polygon = polygons[1 % polygons.size()];
|
||||
|
||||
// Triangulate the sector floors and ceilings and send the result to the mesh. To do this we're using version of the Clipper
|
||||
// library merged with poly2tri, called clip2tri, which I've since modified to support Steiner points.
|
||||
c2t::clip2tri clipper;
|
||||
std::vector<c2t::Point> clipper_out;
|
||||
clipper.triangulate(subsector_polygons, clipper_out, flat_polygons, &steiner_points);
|
||||
|
||||
const float MAX = 1000000.0f;
|
||||
float min_height = MAX;
|
||||
float max_height = -MAX;
|
||||
|
||||
for (int i = 0; i < clipper_out.size(); i += 3)
|
||||
{
|
||||
c2t::Point a = clipper_out.at(i + 0);
|
||||
c2t::Point b = clipper_out.at(i + 1);
|
||||
c2t::Point c = clipper_out.at(i + 2);
|
||||
|
||||
//std::vector<c2t::Point> sector_polygons;
|
||||
//for (const Vec2& l: sector.walls)
|
||||
// sector_polygons.push_back({l.x, l.y});
|
||||
float au = a.x * 0.5f, av = a.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;
|
||||
|
||||
// Triangulate the sector floors and ceilings and send the result to the mesh. To do this we're using version of the Clipper
|
||||
// library merged with poly2tri, called clip2tri, which I've since modified to support Steiner points.
|
||||
c2t::clip2tri clipper;
|
||||
std::vector<c2t::Point> clipper_out;
|
||||
clipper.triangulate(subsector_polygons, clipper_out, flat_polygons, &steiner_points);
|
||||
// Build mesh data for floor
|
||||
Vec3 fva = Vec3(a.x, flat.base_height, a.y);
|
||||
Vec3 fvb = Vec3(b.x, flat.base_height, b.y);
|
||||
Vec3 fvc = Vec3(c.x, flat.base_height, c.y);
|
||||
|
||||
const float MAX = 1000000.0f;
|
||||
float min_height = MAX;
|
||||
float max_height = -MAX;
|
||||
|
||||
for (int i = 0; i < clipper_out.size(); i += 3)
|
||||
for (const Vec3& steiner : flat.steiner_points)
|
||||
{
|
||||
c2t::Point a = clipper_out.at(i + 0);
|
||||
c2t::Point b = clipper_out.at(i + 1);
|
||||
c2t::Point c = clipper_out.at(i + 2);
|
||||
|
||||
float au = a.x * 0.5f, av = a.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;
|
||||
|
||||
// Build mesh data for floor
|
||||
Vec3 fva = Vec3(a.x, flat.base_height, a.y);
|
||||
Vec3 fvb = Vec3(b.x, flat.base_height, b.y);
|
||||
Vec3 fvc = Vec3(c.x, flat.base_height, c.y);
|
||||
|
||||
for (const Vec3& steiner : flat.steiner_points)
|
||||
{
|
||||
if (FloatCmp(fva.x, steiner.x, e) && FloatCmp(fva.z, steiner.z, e)) fva.y += steiner.y;
|
||||
if (FloatCmp(fvb.x, steiner.x, e) && FloatCmp(fvb.z, steiner.z, e)) fvb.y += steiner.y;
|
||||
if (FloatCmp(fvc.x, steiner.x, e) && FloatCmp(fvc.z, steiner.z, e)) fvc.y += steiner.y;
|
||||
}
|
||||
|
||||
if (fva.y < min_height) min_height = fva.y;
|
||||
if (fvb.y < min_height) min_height = fvb.y;
|
||||
if (fvc.y < min_height) min_height = fvc.y;
|
||||
if (fva.y > max_height) max_height = fva.y;
|
||||
if (fvb.y > max_height) max_height = fvb.y;
|
||||
if (fvc.y > max_height) max_height = fvc.y;
|
||||
if (FloatCmp(min_height, MAX)) min_height = flat.base_height;
|
||||
if (FloatCmp(max_height, -MAX)) max_height = flat.base_height;
|
||||
|
||||
// Fix up the UVs so they keep the right scale
|
||||
float tw = flat.texture ? texture_scale / flat.texture->GetWidth() : 0.0f;
|
||||
float th = flat.texture ? texture_scale / flat.texture->GetHeight() : 0.0f;
|
||||
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
|
||||
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
|
||||
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
|
||||
flat.triangulated_data.push_back(vtxa);
|
||||
flat.triangulated_data.push_back(vtxb);
|
||||
flat.triangulated_data.push_back(vtxc);
|
||||
if (flat.texture)
|
||||
m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert);
|
||||
if (FloatCmp(fva.x, steiner.x, e) && FloatCmp(fva.z, steiner.z, e)) fva.y += steiner.y;
|
||||
if (FloatCmp(fvb.x, steiner.x, e) && FloatCmp(fvb.z, steiner.z, e)) fvb.y += steiner.y;
|
||||
if (FloatCmp(fvc.x, steiner.x, e) && FloatCmp(fvc.z, steiner.z, e)) fvc.y += steiner.y;
|
||||
}
|
||||
|
||||
if (fva.y < min_height) min_height = fva.y;
|
||||
if (fvb.y < min_height) min_height = fvb.y;
|
||||
if (fvc.y < min_height) min_height = fvc.y;
|
||||
if (fva.y > max_height) max_height = fva.y;
|
||||
if (fvb.y > max_height) max_height = fvb.y;
|
||||
if (fvc.y > max_height) max_height = fvc.y;
|
||||
if (FloatCmp(min_height, MAX)) min_height = flat.base_height;
|
||||
if (FloatCmp(max_height, -MAX)) max_height = flat.base_height;
|
||||
|
||||
// Fix up the UVs so they keep the right scale
|
||||
float tw = flat.texture ? texture_scale / flat.texture->GetWidth() : 0.0f;
|
||||
float th = flat.texture ? texture_scale / flat.texture->GetHeight() : 0.0f;
|
||||
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
|
||||
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
|
||||
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
|
||||
flat.triangulated_data.push_back(vtxa);
|
||||
flat.triangulated_data.push_back(vtxb);
|
||||
flat.triangulated_data.push_back(vtxc);
|
||||
if (flat.texture)
|
||||
m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,6 +250,9 @@ void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Tex
|
|||
Vec2 mpos = {Distance({v.position.x, v.position.z}, {pos_a.x, pos_a.z}), v.position.y};
|
||||
points.push_back(mpos);
|
||||
}
|
||||
if (!points.empty())
|
||||
if (!FloatCmp(points.back().x, Distance({ pos_a.x, pos_a.y }, {pos_b.x, pos_b.y})))
|
||||
points.push_back({ Distance({ pos_a.x, pos_a.y }, {pos_b.x, pos_b.y}), flat_bottom.base_height});
|
||||
std::vector<Vec2> top_points;
|
||||
for (const Vertex3D& v: flat_top.triangulated_data)
|
||||
{
|
||||
|
@ -224,6 +261,11 @@ void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Tex
|
|||
Vec2 mpos = {Distance({v.position.x, v.position.z}, {pos_a.x, pos_a.z}), v.position.y};
|
||||
top_points.push_back(mpos);
|
||||
}
|
||||
if (!top_points.empty())
|
||||
if (!FloatCmp(top_points.back().x, 0.0f))
|
||||
top_points.push_back({ 0.0f, flat_top.base_height });
|
||||
// if (top_points.empty())
|
||||
// top_points.push_back({Distance({pos_a.x, pos_a.z}, {pos_b.x, pos_b.z}), flat_top.base_height});
|
||||
std::sort(points.begin(), points.end(), [&](Vec2 a, Vec2 b) { return a.x < b.x; });
|
||||
std::sort(top_points.begin(), top_points.end(), [&](Vec2 a, Vec2 b) { return a.x > b.x; });
|
||||
points.insert(points.end(), top_points.begin(), top_points.end());
|
||||
|
@ -303,6 +345,7 @@ void Map::JoinSectors(Sector& sector)
|
|||
|
||||
float yb = s.floor.base_height;
|
||||
float yt = s.ceiling.base_height;
|
||||
bool not_child = s.parent_id != sector.id;
|
||||
|
||||
for (Wall& l : s.walls)
|
||||
{
|
||||
|
@ -311,9 +354,8 @@ void Map::JoinSectors(Sector& sector)
|
|||
!PosCmp({l.start.x, 0.0f, l.start.y}, {pos_a.x, 0.0f, pos_a.z}) &&
|
||||
!PosCmp({l.start.x, 0.0f, l.start.y}, {pos_b.x, 0.0f, pos_b.z}) &&
|
||||
!PosCmp({l.end.x, 0.0f, l.end.y}, {pos_b.x, 0.0f, pos_b.z}) &&
|
||||
!PosCmp({l.end.x, 0.0f, l.end.y}, {pos_a.x, 0.0f, pos_a.z}))
|
||||
!PosCmp({l.end.x, 0.0f, l.end.y}, {pos_a.x, 0.0f, pos_a.z}) && not_child)
|
||||
{
|
||||
//KP3D_LOG_INFO("{} IS TOUCHING: {}", sector.id, s.id);
|
||||
XYf old_end = ld.end;
|
||||
ld.end.x = l.end.x;
|
||||
ld.end.y = l.end.y;
|
||||
|
@ -379,6 +421,10 @@ void Map::Init()
|
|||
{11,4},{14,4},{14,2},{16,2},{16,10},{11,10} // Neighbor of main sector
|
||||
};
|
||||
|
||||
XYf points6[] = {
|
||||
{1, 4},{3,4}, { 3,7 },{1,7}
|
||||
};
|
||||
|
||||
BuildSkybox("skybox_16.jpg");
|
||||
|
||||
static kp3d::Texture tex, tex2, tex3, tex4;
|
||||
|
@ -411,10 +457,12 @@ void Map::Init()
|
|||
|
||||
build_sector(&tex3, &tex, &tex2, -1.0f, 5.0f, 1, points, std::size(points));
|
||||
build_sector(&tex4, &tex2, &tex2, -1.5f, 4.0f, 2, points2, std::size(points2));
|
||||
build_sector(&tex4, &tex, &tex2, -1.5f, 4.0f, 3, points3, std::size(points3), true);
|
||||
build_sector(&tex4, &tex, &tex2, -1.0f, 4.0f, 4, points4, std::size(points4), true);
|
||||
build_sector(&tex4, &tex, &tex2, -1.5f, 5.0f, 3, points3, std::size(points3), true);
|
||||
build_sector(&tex4, &tex, &tex2, -1.5f, 4.0f, 4, points4, std::size(points4), true);
|
||||
//build_sector(&tex3, &tex, &tex2, -1.2f, 3.0f, 5, points5, std::size(points5));
|
||||
build_sector(&tex3, &tex, &tex2, test_u, test_l, 5, points5, std::size(points5), false);
|
||||
build_sector(&tex4, &tex4, &tex4, 1.0f, 1.4f, 6, points6, std::size(points6), true);
|
||||
|
||||
|
||||
// Correct sectors with counter-clockwise linedef order using the shoelace formula,
|
||||
// also while we're at it grab the sector areas (will be useful later) and reset old data.
|
||||
|
@ -473,7 +521,7 @@ void Map::Init()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
KP3D_LOG_INFO("SECTOR HIERARCHY");
|
||||
for (Sector& s: sectors)
|
||||
{
|
||||
|
@ -490,6 +538,7 @@ void Map::Init()
|
|||
KP3D_LOG_INFO(" - [NO CHILDREN]");
|
||||
KP3D_LOG_INFO("-----");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Preproc
|
||||
for (Sector& s: sectors)
|
||||
|
|
|
@ -37,6 +37,7 @@ void Sandbox::Update()
|
|||
if (IsKeyDown(kp3d::KEY_GRAVE))
|
||||
{
|
||||
kp3d::console::open ^= 1;
|
||||
SetMouseLockEnabled(!GetMouseLockEnabled());
|
||||
KeyReset(kp3d::KEY_GRAVE);
|
||||
}
|
||||
if (IsKeyDown(kp3d::KEY_F1))
|
||||
|
|
Loading…
Reference in a new issue