- make SectionGeometry create some data.

This commit is contained in:
Christoph Oelckers 2021-12-12 18:07:19 +01:00
parent ca19c265f8
commit 411e3e6f9c
5 changed files with 128 additions and 23 deletions

View file

@ -20,3 +20,4 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr)
};
return zcr;
}

View file

@ -679,7 +679,7 @@ nexti:;
// calculate the rest.
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);
UVCalculator uvcalc(sectorp, plane, texture, offset);
UVCalculator1 uvcalc(sectorp, plane, texture, offset);
entry.texcoords.Resize(entry.vertices.Size());
for (unsigned i = 0; i < entry.vertices.Size(); i++)

View file

@ -98,17 +98,17 @@ void HWFlat::MakeVertices()
bool canvas = texture->isHardwareCanvas();
if (Sprite == nullptr)
{
#if 0
if (section != nullptr)
{
auto mesh = sectionGeometry.get(section, plane, geoofs);
TArray<int>* pIndices;
auto mesh = sectionGeometry.get(section, plane, geoofs, &pIndices);
auto ret = screen->mVertexData->AllocVertices(mesh->indices.Size());
auto ret = screen->mVertexData->AllocVertices(pIndices->Size());
auto vp = ret.first;
float base = (plane == 0 ? sec->floorz : sec->ceilingz) * (1 / -256.f);
for (unsigned i = 0; i < mesh->indices.Size(); i++)
for (unsigned i = 0; i < pIndices->Size(); i++)
{
auto ii = mesh->indicess[i];
auto ii = (*pIndices)[i];
auto& pt = mesh->vertices[ii];
auto& uv = mesh->texcoords[ii];
vp->SetVertex(pt.X, base + pt.Z, pt.Y);
@ -116,10 +116,9 @@ void HWFlat::MakeVertices()
vp++;
}
vertindex = ret.second;
vertcount = mesh->indices.Size();
vertcount = pIndices->Size();
}
else
#endif
{
auto mesh = sectorGeometry.get(oldsection, plane, geoofs);
if (!mesh) return;

View file

@ -45,6 +45,7 @@
#include "nodebuilder/nodebuild.h"
SectorGeometry sectorGeometry;
SectionGeometry sectionGeometry;
//==========================================================================
//
@ -316,10 +317,10 @@ ETriangulateResult TriangulateOutlineLibtess(const FOutline& polygon, int count,
int result = tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, 3, 2, 0);
if (!result)
{
{
tessDeleteTess(tess);
return ETriangulateResult::Failed;
}
}
const float* verts = tessGetVertices(tess);
const int* vinds = tessGetVertexIndices(tess);
@ -418,7 +419,7 @@ ETriangulateResult TriangulateOutlineNodeBuild(const FOutline& polygon, int coun
//
//==========================================================================
bool SectionGeometry::ValidateSection(Section2* section, int plane, const FVector2& offset)
bool SectionGeometry::ValidateSection(Section2* section, int plane)
{
auto sec = section->sector;
auto& sdata = data[section->index];
@ -457,10 +458,116 @@ bool SectionGeometry::ValidateSection(Section2* section, int plane, const FVecto
}
//==========================================================================
//
//
//
//==========================================================================
bool SectionGeometry::CreateMesh(Section2* section)
{
auto outline = BuildOutline(section);
FOutline foutline;
int count = OutlineToFloat(outline, foutline);
if (count == -1) return false; // gotta wait...
TArray<FVector2> meshVertices;
TArray<int> meshIndices;
ETriangulateResult result = ETriangulateResult::Failed;
auto& sdata = data[section->index];
if (!(section->flags & NoEarcut))
{
result = TriangulateOutlineEarcut(foutline, count, sdata.meshVertices, sdata.meshIndices);
}
if (result == ETriangulateResult::Failed && !(section->flags & NoLibtess))
{
section->flags |= NoEarcut;
result = TriangulateOutlineLibtess(foutline, count, sdata.meshVertices, sdata.meshIndices);
}
if (result == ETriangulateResult::Failed)
{
section->flags |= NoLibtess;
result = TriangulateOutlineNodeBuild(foutline, count, sdata.meshVertices, meshIndices);
}
section->flags &= ~EDirty::GeometryDirty;
return true;
}
//==========================================================================
//
// assumes that the geometry has already been validated.
//
//==========================================================================
void SectionGeometry::CreatePlaneMesh(Section2* section, int plane, const FVector2& offset)
{
auto sectorp = section->sector;
// calculate the rest.
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);
auto& sdata = data[section->index];
auto& entry = sdata.planes[plane];
int fz = sectorp->floorz, cz = sectorp->ceilingz;
sectorp->floorz = sectorp->ceilingz = 0;
UVCalculator uvcalc(sectorp, plane, texture, offset);
entry.vertices.Resize(sdata.meshVertices.Size());
entry.texcoords.Resize(entry.vertices.Size());
for (unsigned i = 0; i < entry.vertices.Size(); i++)
{
auto& org = sdata.meshVertices[i];
auto& pt = entry.vertices[i];
auto& tc = entry.texcoords[i];
pt.XY() = org;
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);
}
entry.normal = CalcNormal(sectorp, plane);
sectorp->floorz = fz;
sectorp->ceilingz = cz;
}
//==========================================================================
//
//
//
//==========================================================================
void SectionGeometry::MarkDirty(sectortype* sector)
{
for (auto section : sections2PerSector[sectnum(sector)])
{
data[section->index].dirty = sector->dirty;
}
sector->dirty = 0;
}
//==========================================================================
//
//
//
//==========================================================================
SectionGeometryPlane* SectionGeometry::get(Section2* section, int plane, const FVector2& offset, TArray<int>** pIndices)
{
if (!section || section->index >= data.Size()) return nullptr;
auto sectp = section->sector;
if (sectp->dirty) MarkDirty(sectp);
if (section->flags & 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.
}
}
if (!ValidateSection(section, plane))
{
CreatePlaneMesh(section, plane, offset);
}
*pIndices = &data[section->index].meshIndices;
return &data[section->index].planes[plane];
}

View file

@ -56,9 +56,13 @@ enum GeomFlags
CeilingDone = 8,
};
using SectionGeometryPlane = SectorGeometryPlane;
struct SectionGeometryData
{
SectorGeometryPlane planes[2];
TArray<FVector2> meshVertices; // flat vertices. Stored separately so that plane changes won't require completely new triangulation.
TArray<int> meshIndices;
sectortype compare[2] = {};
vec2_t poscompare[2] = {};
vec2_t poscompare2[2] = {};
@ -69,22 +73,16 @@ struct SectionGeometryData
class SectionGeometry
{
TArray<FVector2> meshVerts;
TArray<int> meshIndices;
TArray<SectionGeometryData> data;
bool ValidateSection(Section2* section, int plane, const FVector2& offset);
bool ValidateSection(Section2* section, int plane);
void MarkDirty(sectortype* sector);
bool CreateMesh(Section2* section);
void CreatePlaneMesh(Section2* section, int plane, const FVector2& offset);
public:
/*
SectionGeometryPlane* get(Section2* section, int plane, const FVector2& offset)
{
if (section->index >= data.Size()) return nullptr;
ValidateSector(section->index, plane, offset);
return &data[section->index].planes[plane];
}
*/
SectionGeometryPlane* get(Section2* section, int plane, const FVector2& offset, TArray<int>** pIndices);
void SetSize(unsigned sectcount)
{