mirror of
https://github.com/ZDoom/Raze.git
synced 2025-05-30 17:01:03 +00:00
- make SectionGeometry create some data.
This commit is contained in:
parent
ca19c265f8
commit
411e3e6f9c
5 changed files with 128 additions and 23 deletions
|
@ -19,4 +19,5 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr)
|
||||||
delete zr;
|
delete zr;
|
||||||
};
|
};
|
||||||
return zcr;
|
return zcr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -679,7 +679,7 @@ nexti:;
|
||||||
// calculate the rest.
|
// calculate the rest.
|
||||||
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);
|
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());
|
entry.texcoords.Resize(entry.vertices.Size());
|
||||||
for (unsigned i = 0; i < entry.vertices.Size(); i++)
|
for (unsigned i = 0; i < entry.vertices.Size(); i++)
|
||||||
|
|
|
@ -98,17 +98,17 @@ void HWFlat::MakeVertices()
|
||||||
bool canvas = texture->isHardwareCanvas();
|
bool canvas = texture->isHardwareCanvas();
|
||||||
if (Sprite == nullptr)
|
if (Sprite == nullptr)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (section != nullptr)
|
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;
|
auto vp = ret.first;
|
||||||
float base = (plane == 0 ? sec->floorz : sec->ceilingz) * (1 / -256.f);
|
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& pt = mesh->vertices[ii];
|
||||||
auto& uv = mesh->texcoords[ii];
|
auto& uv = mesh->texcoords[ii];
|
||||||
vp->SetVertex(pt.X, base + pt.Z, pt.Y);
|
vp->SetVertex(pt.X, base + pt.Z, pt.Y);
|
||||||
|
@ -116,10 +116,9 @@ void HWFlat::MakeVertices()
|
||||||
vp++;
|
vp++;
|
||||||
}
|
}
|
||||||
vertindex = ret.second;
|
vertindex = ret.second;
|
||||||
vertcount = mesh->indices.Size();
|
vertcount = pIndices->Size();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
auto mesh = sectorGeometry.get(oldsection, plane, geoofs);
|
auto mesh = sectorGeometry.get(oldsection, plane, geoofs);
|
||||||
if (!mesh) return;
|
if (!mesh) return;
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "nodebuilder/nodebuild.h"
|
#include "nodebuilder/nodebuild.h"
|
||||||
|
|
||||||
SectorGeometry sectorGeometry;
|
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);
|
int result = tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, 3, 2, 0);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
tessDeleteTess(tess);
|
tessDeleteTess(tess);
|
||||||
return ETriangulateResult::Failed;
|
return ETriangulateResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* verts = tessGetVertices(tess);
|
const float* verts = tessGetVertices(tess);
|
||||||
const int* vinds = tessGetVertexIndices(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 sec = section->sector;
|
||||||
auto& sdata = data[section->index];
|
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)
|
void SectionGeometry::MarkDirty(sectortype* sector)
|
||||||
{
|
{
|
||||||
for (auto section : sections2PerSector[sectnum(sector)])
|
for (auto section : sections2PerSector[sectnum(sector)])
|
||||||
{
|
{
|
||||||
data[section->index].dirty = sector->dirty;
|
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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,13 @@ enum GeomFlags
|
||||||
CeilingDone = 8,
|
CeilingDone = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using SectionGeometryPlane = SectorGeometryPlane;
|
||||||
|
|
||||||
struct SectionGeometryData
|
struct SectionGeometryData
|
||||||
{
|
{
|
||||||
SectorGeometryPlane planes[2];
|
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] = {};
|
sectortype compare[2] = {};
|
||||||
vec2_t poscompare[2] = {};
|
vec2_t poscompare[2] = {};
|
||||||
vec2_t poscompare2[2] = {};
|
vec2_t poscompare2[2] = {};
|
||||||
|
@ -69,22 +73,16 @@ struct SectionGeometryData
|
||||||
|
|
||||||
class SectionGeometry
|
class SectionGeometry
|
||||||
{
|
{
|
||||||
TArray<FVector2> meshVerts;
|
|
||||||
TArray<int> meshIndices;
|
|
||||||
TArray<SectionGeometryData> data;
|
TArray<SectionGeometryData> data;
|
||||||
|
|
||||||
bool ValidateSection(Section2* section, int plane, const FVector2& offset);
|
bool ValidateSection(Section2* section, int plane);
|
||||||
void MarkDirty(sectortype* sector);
|
void MarkDirty(sectortype* sector);
|
||||||
|
bool CreateMesh(Section2* section);
|
||||||
|
void CreatePlaneMesh(Section2* section, int plane, const FVector2& offset);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
SectionGeometryPlane* get(Section2* section, int plane, const FVector2& offset, TArray<int>** pIndices);
|
||||||
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];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SetSize(unsigned sectcount)
|
void SetSize(unsigned sectcount)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue