Move some code
This commit is contained in:
parent
f83ae7487f
commit
4f4d859fd9
5 changed files with 150 additions and 174 deletions
|
|
@ -2979,51 +2979,45 @@ void MapLoader::InitLevelMesh(MapData* map)
|
|||
Level->lightmaps = Level->lightmaps || *genlightmaps; // Allow lightmapping in non-lightmapped levels.
|
||||
}
|
||||
|
||||
// Levelmesh and lightmap binding/loading
|
||||
// Allocate room for surface arrays on sectors, sides and their 3D floors
|
||||
|
||||
unsigned int allSurfaces = 0;
|
||||
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
allSurfaces += 4 + Level->sides[i].sector->e->XFloor.ffloors.Size();
|
||||
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2;
|
||||
|
||||
Level->LMSurfaces.Resize(allSurfaces);
|
||||
memset(Level->LMSurfaces.Data(), 0, sizeof(DoomLevelMeshSurface*) * allSurfaces);
|
||||
|
||||
unsigned int offset = 0;
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
{
|
||||
auto& side = Level->sides[i];
|
||||
side.lightmap = &Level->LMSurfaces[offset];
|
||||
offset += 4 + side.sector->e->XFloor.ffloors.Size();
|
||||
}
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
{
|
||||
auto& subsector = Level->subsectors[i];
|
||||
unsigned int count = 1 + subsector.sector->e->XFloor.ffloors.Size();
|
||||
subsector.lightmap[0] = &Level->LMSurfaces[offset];
|
||||
subsector.lightmap[1] = &Level->LMSurfaces[offset + count];
|
||||
offset += count * 2;
|
||||
}
|
||||
|
||||
// Create the levelmesh
|
||||
Level->levelMesh = new DoomLevelMesh(*Level);
|
||||
|
||||
// Lightmap binding/loading
|
||||
if (Level->lightmaps)
|
||||
{
|
||||
if (!LoadLightmap(map))
|
||||
{
|
||||
Level->levelMesh->PackLightmapAtlas();
|
||||
}
|
||||
|
||||
// Allocate room for lightmap arrays on sectors, sides and their 3D floors
|
||||
|
||||
unsigned int allSurfaces = 0;
|
||||
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
allSurfaces += 4 + Level->sides[i].sector->e->XFloor.ffloors.Size();
|
||||
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2;
|
||||
|
||||
Level->LMSurfaces.Resize(allSurfaces);
|
||||
memset(Level->LMSurfaces.Data(), 0, sizeof(DoomLevelMeshSurface*) * allSurfaces);
|
||||
|
||||
unsigned int offset = 0;
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
{
|
||||
auto& side = Level->sides[i];
|
||||
int count = 4 + side.sector->e->XFloor.ffloors.Size();
|
||||
side.lightmap = TArrayView<DoomLevelMeshSurface*>(&Level->LMSurfaces[offset], count);
|
||||
offset += count;
|
||||
}
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
{
|
||||
auto& subsector = Level->subsectors[i];
|
||||
unsigned int count = 1 + subsector.sector->e->XFloor.ffloors.Size();
|
||||
subsector.lightmap[0] = TArrayView<DoomLevelMeshSurface*>(&Level->LMSurfaces[offset], count);
|
||||
subsector.lightmap[1] = TArrayView<DoomLevelMeshSurface*>(&Level->LMSurfaces[offset + count], count);
|
||||
offset += count * 2;
|
||||
}
|
||||
|
||||
Level->levelMesh->BindLightmapSurfacesToGeometry(*Level);
|
||||
}
|
||||
else
|
||||
{
|
||||
Level->levelMesh->DisableLightmaps();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,21 +167,6 @@ void DoomLevelMesh::PackLightmapAtlas()
|
|||
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->PackLightmapAtlas(0);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
||||
{
|
||||
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->BindLightmapSurfacesToGeometry(doomMap);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::DisableLightmaps()
|
||||
{
|
||||
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->DisableLightmaps();
|
||||
}
|
||||
|
||||
void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilename) const
|
||||
{
|
||||
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->DumpMesh(objFilename, mtlFilename);
|
||||
}
|
||||
|
||||
int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize)
|
||||
{
|
||||
const DoomLevelMeshSurface* doomsurf = static_cast<const DoomLevelMeshSurface*>(surface);
|
||||
|
|
@ -260,3 +245,114 @@ int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLi
|
|||
|
||||
return listpos;
|
||||
}
|
||||
|
||||
void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilename) const
|
||||
{
|
||||
DoomLevelSubmesh* submesh = static_cast<DoomLevelSubmesh*>(StaticMesh.get());
|
||||
|
||||
auto f = fopen(objFilename.GetChars(), "w");
|
||||
|
||||
fprintf(f, "# DoomLevelMesh debug export\n");
|
||||
fprintf(f, "# MeshVertices: %u, MeshElements: %u, Surfaces: %u\n", submesh->MeshVertices.Size(), submesh->MeshElements.Size(), submesh->Surfaces.Size());
|
||||
fprintf(f, "mtllib %s\n", mtlFilename.GetChars());
|
||||
|
||||
double scale = 1 / 10.0;
|
||||
|
||||
for (const auto& v : submesh->MeshVertices)
|
||||
{
|
||||
fprintf(f, "v %f %f %f\n", v.x * scale, v.y * scale, v.z * scale);
|
||||
}
|
||||
|
||||
for (const auto& v : submesh->MeshVertices)
|
||||
{
|
||||
fprintf(f, "vt %f %f\n", v.lu, v.lv);
|
||||
}
|
||||
|
||||
auto name = [](DoomLevelMeshSurfaceType type) -> const char* {
|
||||
switch (type)
|
||||
{
|
||||
case ST_CEILING:
|
||||
return "ceiling";
|
||||
case ST_FLOOR:
|
||||
return "floor";
|
||||
case ST_LOWERSIDE:
|
||||
return "lowerside";
|
||||
case ST_UPPERSIDE:
|
||||
return "upperside";
|
||||
case ST_MIDDLESIDE:
|
||||
return "middleside";
|
||||
case ST_UNKNOWN:
|
||||
return "unknown";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "error";
|
||||
};
|
||||
|
||||
|
||||
uint32_t lastSurfaceIndex = -1;
|
||||
|
||||
|
||||
bool useErrorMaterial = false;
|
||||
int highestUsedAtlasPage = -1;
|
||||
|
||||
for (unsigned i = 0, count = submesh->MeshElements.Size(); i + 2 < count; i += 3)
|
||||
{
|
||||
auto index = submesh->MeshSurfaceIndexes[i / 3];
|
||||
|
||||
if (index != lastSurfaceIndex)
|
||||
{
|
||||
lastSurfaceIndex = index;
|
||||
|
||||
if (unsigned(index) >= submesh->Surfaces.Size())
|
||||
{
|
||||
fprintf(f, "o Surface[%d] (bad index)\n", index);
|
||||
fprintf(f, "usemtl error\n");
|
||||
|
||||
useErrorMaterial = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& surface = submesh->Surfaces[index];
|
||||
fprintf(f, "o Surface[%d] %s %d%s\n", index, name(surface.Type), surface.TypeIndex, surface.bSky ? " sky" : "");
|
||||
fprintf(f, "usemtl lightmap%d\n", surface.AtlasTile.ArrayIndex);
|
||||
|
||||
if (surface.AtlasTile.ArrayIndex > highestUsedAtlasPage)
|
||||
{
|
||||
highestUsedAtlasPage = surface.AtlasTile.ArrayIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fprintf(f, "f %d %d %d\n", MeshElements[i] + 1, MeshElements[i + 1] + 1, MeshElements[i + 2] + 1);
|
||||
fprintf(f, "f %d/%d %d/%d %d/%d\n",
|
||||
submesh->MeshElements[i + 0] + 1, submesh->MeshElements[i + 0] + 1,
|
||||
submesh->MeshElements[i + 1] + 1, submesh->MeshElements[i + 1] + 1,
|
||||
submesh->MeshElements[i + 2] + 1, submesh->MeshElements[i + 2] + 1);
|
||||
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// material
|
||||
|
||||
f = fopen(mtlFilename.GetChars(), "w");
|
||||
|
||||
fprintf(f, "# DoomLevelMesh debug export\n");
|
||||
|
||||
if (useErrorMaterial)
|
||||
{
|
||||
fprintf(f, "# Surface indices that are referenced, but do not exists in the 'Surface' array\n");
|
||||
fprintf(f, "newmtl error\nKa 1 0 0\nKd 1 0 0\nKs 1 0 0\n");
|
||||
}
|
||||
|
||||
for (int page = 0; page <= highestUsedAtlasPage; ++page)
|
||||
{
|
||||
fprintf(f, "newmtl lightmap%d\n", page);
|
||||
fprintf(f, "Ka 1 1 1\nKd 1 1 1\nKs 0 0 0\n");
|
||||
fprintf(f, "map_Ka lightmap%d.png\n", page);
|
||||
fprintf(f, "map_Kd lightmap%d.png\n", page);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,5 @@ public:
|
|||
void BeginFrame(FLevelLocals& doomMap);
|
||||
bool TraceSky(const FVector3& start, FVector3 direction, float dist);
|
||||
void PackLightmapAtlas();
|
||||
void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap);
|
||||
void DisableLightmaps();
|
||||
void DumpMesh(const FString& objFilename, const FString& mtlFilename) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap)
|
|||
}
|
||||
|
||||
CreateSubsectorSurfaces(doomMap);
|
||||
LinkSurfaces(doomMap);
|
||||
|
||||
CreateIndexes();
|
||||
SetupLightmapUvs(doomMap);
|
||||
|
|
@ -79,13 +80,13 @@ void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap, int lightmapStartInd
|
|||
}
|
||||
}
|
||||
|
||||
LinkSurfaces(doomMap);
|
||||
CreateIndexes();
|
||||
SetupLightmapUvs(doomMap);
|
||||
BuildTileSurfaceLists();
|
||||
UpdateCollision();
|
||||
|
||||
PackLightmapAtlas(lightmapStartIndex);
|
||||
BindLightmapSurfacesToGeometry(doomMap);
|
||||
}
|
||||
|
||||
void DoomLevelSubmesh::CreateIndexes()
|
||||
|
|
@ -97,6 +98,7 @@ void DoomLevelSubmesh::CreateIndexes()
|
|||
unsigned int pos = s.startVertIndex;
|
||||
FFlatVertex* verts = &MeshVertices[pos];
|
||||
|
||||
s.Vertices = verts;
|
||||
s.startElementIndex = MeshElements.Size();
|
||||
s.numElements = 0;
|
||||
|
||||
|
|
@ -309,17 +311,12 @@ void DoomLevelSubmesh::CreatePortals()
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
||||
void DoomLevelSubmesh::LinkSurfaces(FLevelLocals& doomMap)
|
||||
{
|
||||
// Link surfaces
|
||||
for (auto& surface : Surfaces)
|
||||
{
|
||||
surface.Vertices = &MeshVertices[surface.startVertIndex];
|
||||
|
||||
if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING)
|
||||
{
|
||||
if (surface.Subsector->firstline && surface.Subsector->firstline->sidedef)
|
||||
surface.Subsector->firstline->sidedef->sector->HasLightmaps = true;
|
||||
SetSubsectorLightmap(&surface);
|
||||
}
|
||||
else
|
||||
|
|
@ -331,6 +328,9 @@ void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap)
|
|||
|
||||
void DoomLevelSubmesh::SetSubsectorLightmap(DoomLevelMeshSurface* surface)
|
||||
{
|
||||
if (surface->Subsector->firstline && surface->Subsector->firstline->sidedef)
|
||||
surface->Subsector->firstline->sidedef->sector->HasLightmaps = true;
|
||||
|
||||
if (!surface->ControlSector)
|
||||
{
|
||||
int index = surface->Type == ST_CEILING ? 1 : 0;
|
||||
|
|
@ -1148,118 +1148,9 @@ bool DoomLevelSubmesh::IsDegenerate(const FVector3 &v0, const FVector3 &v1, cons
|
|||
return crosslengthsqr <= 1.e-6f;
|
||||
}
|
||||
|
||||
void DoomLevelSubmesh::DumpMesh(const FString& objFilename, const FString& mtlFilename) const
|
||||
{
|
||||
auto f = fopen(objFilename.GetChars(), "w");
|
||||
|
||||
fprintf(f, "# DoomLevelMesh debug export\n");
|
||||
fprintf(f, "# MeshVertices: %u, MeshElements: %u, Surfaces: %u\n", MeshVertices.Size(), MeshElements.Size(), Surfaces.Size());
|
||||
fprintf(f, "mtllib %s\n", mtlFilename.GetChars());
|
||||
|
||||
double scale = 1 / 10.0;
|
||||
|
||||
for (const auto& v : MeshVertices)
|
||||
{
|
||||
fprintf(f, "v %f %f %f\n", v.x * scale, v.y * scale, v.z * scale);
|
||||
}
|
||||
|
||||
for (const auto& v : MeshVertices)
|
||||
{
|
||||
fprintf(f, "vt %f %f\n", v.lu, v.lv);
|
||||
}
|
||||
|
||||
auto name = [](DoomLevelMeshSurfaceType type) -> const char* {
|
||||
switch (type)
|
||||
{
|
||||
case ST_CEILING:
|
||||
return "ceiling";
|
||||
case ST_FLOOR:
|
||||
return "floor";
|
||||
case ST_LOWERSIDE:
|
||||
return "lowerside";
|
||||
case ST_UPPERSIDE:
|
||||
return "upperside";
|
||||
case ST_MIDDLESIDE:
|
||||
return "middleside";
|
||||
case ST_UNKNOWN:
|
||||
return "unknown";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "error";
|
||||
};
|
||||
|
||||
|
||||
uint32_t lastSurfaceIndex = -1;
|
||||
|
||||
|
||||
bool useErrorMaterial = false;
|
||||
int highestUsedAtlasPage = -1;
|
||||
|
||||
for (unsigned i = 0, count = MeshElements.Size(); i + 2 < count; i += 3)
|
||||
{
|
||||
auto index = MeshSurfaceIndexes[i / 3];
|
||||
|
||||
if(index != lastSurfaceIndex)
|
||||
{
|
||||
lastSurfaceIndex = index;
|
||||
|
||||
if (unsigned(index) >= Surfaces.Size())
|
||||
{
|
||||
fprintf(f, "o Surface[%d] (bad index)\n", index);
|
||||
fprintf(f, "usemtl error\n");
|
||||
|
||||
useErrorMaterial = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& surface = Surfaces[index];
|
||||
fprintf(f, "o Surface[%d] %s %d%s\n", index, name(surface.Type), surface.TypeIndex, surface.bSky ? " sky" : "");
|
||||
fprintf(f, "usemtl lightmap%d\n", surface.AtlasTile.ArrayIndex);
|
||||
|
||||
if (surface.AtlasTile.ArrayIndex > highestUsedAtlasPage)
|
||||
{
|
||||
highestUsedAtlasPage = surface.AtlasTile.ArrayIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fprintf(f, "f %d %d %d\n", MeshElements[i] + 1, MeshElements[i + 1] + 1, MeshElements[i + 2] + 1);
|
||||
fprintf(f, "f %d/%d %d/%d %d/%d\n",
|
||||
MeshElements[i + 0] + 1, MeshElements[i + 0] + 1,
|
||||
MeshElements[i + 1] + 1, MeshElements[i + 1] + 1,
|
||||
MeshElements[i + 2] + 1, MeshElements[i + 2] + 1);
|
||||
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// material
|
||||
|
||||
f = fopen(mtlFilename.GetChars(), "w");
|
||||
|
||||
fprintf(f, "# DoomLevelMesh debug export\n");
|
||||
|
||||
if (useErrorMaterial)
|
||||
{
|
||||
fprintf(f, "# Surface indices that are referenced, but do not exists in the 'Surface' array\n");
|
||||
fprintf(f, "newmtl error\nKa 1 0 0\nKd 1 0 0\nKs 1 0 0\n");
|
||||
}
|
||||
|
||||
for (int page = 0; page <= highestUsedAtlasPage; ++page)
|
||||
{
|
||||
fprintf(f, "newmtl lightmap%d\n", page);
|
||||
fprintf(f, "Ka 1 1 1\nKd 1 1 1\nKs 0 0 0\n");
|
||||
fprintf(f, "map_Ka lightmap%d.png\n", page);
|
||||
fprintf(f, "map_Kd lightmap%d.png\n", page);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void DoomLevelSubmesh::SetupLightmapUvs(FLevelLocals& doomMap)
|
||||
{
|
||||
LMTextureSize = 1024; // TODO cvar
|
||||
LMTextureSize = 1024;
|
||||
|
||||
for (auto& surface : Surfaces)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,13 +47,10 @@ public:
|
|||
unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const override { return (unsigned int)(ptrdiff_t)(static_cast<const DoomLevelMeshSurface*>(surface) - Surfaces.Data()); }
|
||||
int GetSurfaceCount() override { return Surfaces.Size(); }
|
||||
|
||||
void DumpMesh(const FString& objFilename, const FString& mtlFilename) const;
|
||||
|
||||
// Used by Maploader
|
||||
void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap);
|
||||
void LinkSurfaces(FLevelLocals& doomMap);
|
||||
void PackLightmapAtlas(int lightmapStartIndex);
|
||||
void CreatePortals();
|
||||
void DisableLightmaps() { /*Surfaces.Clear();*/ } // Temp hack that disables lightmapping
|
||||
|
||||
TArray<DoomLevelMeshSurface> Surfaces;
|
||||
TArray<int> sectorGroup; // index is sector, value is sectorGroup
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue