From a407e86ff66e8e96a254bae3bbdfe36a63db6a9d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Dec 2021 17:40:03 +0100 Subject: [PATCH] - migrated automap to new SectionGeometry class. --- source/core/automap.cpp | 23 ++++++----- source/core/rendering/hw_sections2.h | 4 +- source/core/sectorgeometry.cpp | 60 ++++++++++++++++------------ source/core/sectorgeometry.h | 2 - 4 files changed, 50 insertions(+), 39 deletions(-) diff --git a/source/core/automap.cpp b/source/core/automap.cpp index c27682af7..7f7915e84 100644 --- a/source/core/automap.cpp +++ b/source/core/automap.cpp @@ -581,28 +581,31 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang) int picnum = sect->floorpicnum; if ((unsigned)picnum >= (unsigned)MAXTILES) continue; + int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal); + PalEntry light = shadeToLight(sector[i].floorshade); + setgotpic(picnum); + for (auto sect : sections2PerSector[i]) { TArray* indices; auto mesh = sectionGeometry.get(sect, 0, { 0.f, 0.f }, &indices); - vertices.Resize(indices->Size()); - for (unsigned jj = 0; jj < indices->Size(); jj++) + vertices.Resize(mesh->vertices.Size()); + for (unsigned j = 0; j < mesh->vertices.Size(); j++) { - int j = (*indices)[jj]; int ox = int(mesh->vertices[j].X * 16.f) - cposx; int oy = int(mesh->vertices[j].Y * -16.f) - cposy; int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11); int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11); vertices[j] = { x1 / 4096.f, y1 / 4096.f, mesh->texcoords[j].X, mesh->texcoords[j].Y }; } + +#ifdef _DEBUG + // visualize the triangulator being used. + if (sections2PerSector[i][0]->geomflags & NoEarcut) light.r = light.b = 80; +#endif + twod->AddPoly(tileGetTexture(picnum, true), vertices.Data(), vertices.Size(), (unsigned*)indices->Data(), indices->Size(), translation, light, + LegacyRenderStyles[STYLE_Translucent], windowxy1.x, windowxy1.y, windowxy2.x + 1, windowxy2.y + 1); } - - int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal); - setgotpic(picnum); - twod->AddPoly(tileGetTexture(picnum, true), vertices.Data(), vertices.Size(), nullptr, 0, translation, shadeToLight(sector[i].floorshade), - LegacyRenderStyles[STYLE_Translucent], windowxy1.x, windowxy1.y, windowxy2.x + 1, windowxy2.y + 1); - - } qsort(floorsprites.Data(), floorsprites.Size(), sizeof(spritetype*), [](const void* a, const void* b) { diff --git a/source/core/rendering/hw_sections2.h b/source/core/rendering/hw_sections2.h index 0575ac378..ea11fcbd9 100644 --- a/source/core/rendering/hw_sections2.h +++ b/source/core/rendering/hw_sections2.h @@ -28,7 +28,9 @@ struct Section2Loop struct Section2 { - int flags; + uint8_t flags; + uint8_t dirty; + uint8_t geomflags; unsigned index; sectortype* sector; // this uses a memory arena for storage, so use TArrayView instead of TArray diff --git a/source/core/sectorgeometry.cpp b/source/core/sectorgeometry.cpp index 169d9ef19..00944a53e 100644 --- a/source/core/sectorgeometry.cpp +++ b/source/core/sectorgeometry.cpp @@ -233,13 +233,13 @@ static int OutlineToFloat(Outline& outl, FOutline& polygon) for (unsigned j = 0; j < outl[i].Size(); j++) { float X = RenderX(outl[i][j].x); - float Y = RenderX(outl[i][j].y); - 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. + float Y = RenderY(outl[i][j].y); + 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 -1; - } + } polygon[i][j] = { X, Y }; } } @@ -257,7 +257,8 @@ ETriangulateResult TriangulateOutlineEarcut(const FOutline& polygon, int count, // Sections are already validated so we can assume that the data is well defined here. auto indices = mapbox::earcut(polygon); - if (indices.size() < 3 * (count + polygon.size() * 2 - 2)) + size_t numtriangles = count + (polygon.size() - 1) * 2 - 2; // accout for the extra connections needed to turn the polygon into s single loop. + if (indices.size() < numtriangles * 3) { // this means that full triangulation failed. return ETriangulateResult::Failed; @@ -284,10 +285,11 @@ ETriangulateResult TriangulateOutlineEarcut(const FOutline& polygon, int count, // Try to triangulate a given outline with libtess2. // //========================================================================== +FMemArena tessArena(100000); ETriangulateResult TriangulateOutlineLibtess(const FOutline& polygon, int count, TArray& points, TArray& indicesOut) { - FMemArena tessArena(100000); + tessArena.FreeAll(); auto poolAlloc = [](void* userData, unsigned int size) -> void* { @@ -309,13 +311,14 @@ ETriangulateResult TriangulateOutlineLibtess(const FOutline& polygon, int count, if (!tess) return ETriangulateResult::Failed; - //tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, 1); + tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, 0); + tessSetOption(tess, TESS_REVERSE_CONTOURS, 1); // Add contours. for (auto& loop : polygon) tessAddContour(tess, 2, &loop.data()->first, (int)sizeof(*loop.data()), (int)loop.size()); - int result = tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, 3, 2, 0); + int result = tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, 3, 2, nullptr); if (!result) { tessDeleteTess(tess); @@ -326,16 +329,16 @@ ETriangulateResult TriangulateOutlineLibtess(const FOutline& polygon, int count, const int* vinds = tessGetVertexIndices(tess); const int* elems = tessGetElements(tess); const int nverts = tessGetVertexCount(tess); - const int nelems = tessGetElementCount(tess); + const int nelems = tessGetElementCount(tess) * 3; // an 'element' here is a full triangle, not a single vertex like in OpenGL... points.Resize(nverts); indicesOut.Resize(nelems); for (int i = 0; i < nverts; i++) - { + { points[i] = { verts[i * 2], verts[i * 2 + 1] }; - } + } for (int i = 0; i < nelems; i++) - { + { indicesOut[i] = elems[i]; } return ETriangulateResult::Ok; @@ -347,6 +350,7 @@ ETriangulateResult TriangulateOutlineLibtess(const FOutline& polygon, int count, // //========================================================================== +#if 0 ETriangulateResult TriangulateOutlineNodeBuild(const FOutline& polygon, int count, TArray& points, TArray& indicesOut) { TArray vertexes(count, true); @@ -412,6 +416,7 @@ ETriangulateResult TriangulateOutlineNodeBuild(const FOutline& polygon, int coun } return ETriangulateResult::Ok; } +#endif //========================================================================== // @@ -434,9 +439,9 @@ bool SectionGeometry::ValidateSection(Section2* section, int plane) sec->floorypan_ == compare->floorypan_ && sec->firstWall()->pos == sdata.poscompare[0] && sec->firstWall()->point2Wall()->pos == sdata.poscompare2[0] && - !(sdata.dirty & EDirty::FloorDirty) && sdata.planes[plane].vertices.Size() ) return true; + !(section->dirty & EDirty::FloorDirty) && sdata.planes[plane].vertices.Size() ) return true; - sdata.dirty &= EDirty::FloorDirty; + section->dirty &= EDirty::FloorDirty; } else { @@ -447,9 +452,9 @@ bool SectionGeometry::ValidateSection(Section2* section, int plane) sec->ceilingypan_ == compare->ceilingypan_ && sec->firstWall()->pos == sdata.poscompare[1] && sec->firstWall()->point2Wall()->pos == sdata.poscompare2[1] && - !(sdata.dirty & EDirty::CeilingDirty) && sdata.planes[1].vertices.Size()) return true; + !(section->dirty & EDirty::CeilingDirty) && sdata.planes[1].vertices.Size()) return true; - sdata.dirty &= ~EDirty::CeilingDirty; + section->dirty &= ~EDirty::CeilingDirty; } *compare = *sec; sdata.poscompare[plane] = sec->firstWall()->pos; @@ -480,17 +485,20 @@ bool SectionGeometry::CreateMesh(Section2* section) { result = TriangulateOutlineEarcut(foutline, count, sdata.meshVertices, sdata.meshIndices); } - if (result == ETriangulateResult::Failed && !(section->flags & NoLibtess)) + if (result == ETriangulateResult::Failed && !(section->geomflags & NoLibtess)) { - section->flags |= NoEarcut; + section->geomflags |= NoEarcut; result = TriangulateOutlineLibtess(foutline, count, sdata.meshVertices, sdata.meshIndices); } +#if 0 if (result == ETriangulateResult::Failed) { - section->flags |= NoLibtess; + section->geomflags |= NoLibtess; result = TriangulateOutlineNodeBuild(foutline, count, sdata.meshVertices, meshIndices); } - section->flags &= ~EDirty::GeometryDirty; +#endif + + section->dirty &= ~EDirty::GeometryDirty; return true; } @@ -521,7 +529,7 @@ void SectionGeometry::CreatePlaneMesh(Section2* section, int plane, const FVecto auto& pt = entry.vertices[i]; auto& tc = entry.texcoords[i]; - pt.XY() = org; + pt.X = org.X; pt.Y = org.Y; PlanesAtPoint(sectorp, (pt.X * 16), (pt.Y * -16), plane ? &pt.Z : nullptr, !plane ? &pt.Z : nullptr); tc = uvcalc.GetUV(int(pt.X * 16.), int(pt.Y * -16.), pt.Z); } @@ -540,7 +548,7 @@ void SectionGeometry::MarkDirty(sectortype* sector) { for (auto section : sections2PerSector[sectnum(sector)]) { - data[section->index].dirty = sector->dirty; + section->dirty = sector->dirty; } sector->dirty = 0; } @@ -556,12 +564,12 @@ SectionGeometryPlane* SectionGeometry::get(Section2* section, int plane, const F if (!section || section->index >= data.Size()) return nullptr; auto sectp = section->sector; if (sectp->dirty) MarkDirty(sectp); - if (data[section->index].dirty & EDirty::GeometryDirty) + if (section->dirty & EDirty::GeometryDirty) { bool res = CreateMesh(section); if (!res) { - section->flags &= ~EDirty::GeometryDirty; // sector is in an invalid state, so pretend the old setup is still valid. Happens in some SW maps. + section->dirty &= ~EDirty::GeometryDirty; // sector is in an invalid state, so pretend the old setup is still valid. Happens in some SW maps. } } if (!ValidateSection(section, plane)) diff --git a/source/core/sectorgeometry.h b/source/core/sectorgeometry.h index bcfe8d044..a1af5a159 100644 --- a/source/core/sectorgeometry.h +++ b/source/core/sectorgeometry.h @@ -67,8 +67,6 @@ struct SectionGeometryData vec2_t poscompare[2] = {}; vec2_t poscompare2[2] = {}; FVector3 normal[2]; - int dirty; - int flags; }; class SectionGeometry