Add --dump-mesh option and improve LevelMesh::Export

This commit is contained in:
RaveYard 2022-06-24 20:36:13 +02:00
parent bbf4a71c1f
commit ce3060708d
4 changed files with 69 additions and 12 deletions

View file

@ -794,6 +794,18 @@ void FProcessor::BuildLightmaps()
LightmapMesh->CreateTextures(); LightmapMesh->CreateTextures();
} }
void FProcessor::DumpMesh()
{
if (LightmapMesh)
{
LightmapMesh->Export("levelmesh.obj");
}
else
{
printf("Error: no mesh to export\n");
}
}
void FProcessor::Write (FWadWriter &out) void FProcessor::Write (FWadWriter &out)
{ {
if (Level.NumLines() == 0 || Level.NumSides() == 0 || Level.NumSectors() == 0 || Level.NumVertices == 0) if (Level.NumLines() == 0 || Level.NumSides() == 0 || Level.NumSectors() == 0 || Level.NumVertices == 0)

View file

@ -59,6 +59,8 @@ public:
void BuildLightmaps(); void BuildLightmaps();
void Write(FWadWriter &out); void Write(FWadWriter &out);
void DumpMesh();
private: private:
void LoadUDMF(); void LoadUDMF();
void LoadThings(); void LoadThings();

View file

@ -977,6 +977,8 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile)
void LevelMesh::Export(std::string filename) void LevelMesh::Export(std::string filename)
{ {
printf("Exporting mesh \"%s\"\n", filename.c_str());
// This is so ugly! I had nothing to do with it! ;) // This is so ugly! I had nothing to do with it! ;)
std::string mtlfilename = filename; std::string mtlfilename = filename;
for (int i = 0; i < 3; i++) mtlfilename.pop_back(); for (int i = 0; i < 3; i++) mtlfilename.pop_back();
@ -986,14 +988,19 @@ void LevelMesh::Export(std::string filename)
TArray<vec2> outuv; TArray<vec2> outuv;
TArray<vec3> outnormal; TArray<vec3> outnormal;
TArray<int> outface; TArray<int> outface;
TArray<int> outLightmapId;
outvertices.Resize(MeshVertices.Size()); outvertices.Resize(MeshVertices.Size());
outuv.Resize(MeshVertices.Size()); outuv.Resize(MeshVertices.Size());
outnormal.Resize(MeshVertices.Size()); outnormal.Resize(MeshVertices.Size());
outLightmapId.Resize(MeshElements.Size() / 3);
for (unsigned int surfidx = 0; surfidx < MeshElements.Size() / 3; surfidx++) for (unsigned int surfidx = 0; surfidx < MeshElements.Size() / 3; surfidx++)
{ {
Surface* surface = surfaces[MeshSurfaces[surfidx]].get(); Surface* surface = surfaces[MeshSurfaces[surfidx]].get();
outLightmapId[surfidx] = surface->lightmapNum;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
int elementidx = surfidx * 3 + i; int elementidx = surfidx * 3 + i;
@ -1004,8 +1011,6 @@ void LevelMesh::Export(std::string filename)
outuv[vertexidx] = surface->lightmapCoords[uvindex]; outuv[vertexidx] = surface->lightmapCoords[uvindex];
outnormal[vertexidx] = surface->plane.Normal(); outnormal[vertexidx] = surface->plane.Normal();
outface.Push(vertexidx); outface.Push(vertexidx);
//surface->lightmapNum;
} }
} }
@ -1018,8 +1023,6 @@ void LevelMesh::Export(std::string filename)
buffer += mtlfilename; buffer += mtlfilename;
buffer += "\r\n"; buffer += "\r\n";
buffer += "usemtl Textured\r\n";
float scale = 0.01f; float scale = 0.01f;
for (unsigned int i = 0; i < outvertices.Size(); i++) for (unsigned int i = 0; i < outvertices.Size(); i++)
@ -1053,8 +1056,24 @@ void LevelMesh::Export(std::string filename)
buffer += "\r\n"; buffer += "\r\n";
} }
int prevLightmap = -1;
for (unsigned int i = 0; i < outface.Size(); i += 3) for (unsigned int i = 0; i < outface.Size(); i += 3)
{ {
if (prevLightmap != outLightmapId[i/3])
{
prevLightmap = outLightmapId[i/3];
if (prevLightmap < 0)
{
buffer += "usemtl lightmap_none\r\n";
}
else
{
buffer += "usemtl lightmap" + std::to_string(prevLightmap) + "\r\n";
}
}
std::string e0 = std::to_string(outface[i] + 1); std::string e0 = std::to_string(outface[i] + 1);
std::string e1 = std::to_string(outface[i + 1] + 1); std::string e1 = std::to_string(outface[i + 1] + 1);
std::string e2 = std::to_string(outface[i + 2] + 1); std::string e2 = std::to_string(outface[i + 2] + 1);
@ -1086,13 +1105,22 @@ void LevelMesh::Export(std::string filename)
fclose(file); fclose(file);
} }
std::string mtl = R"(newmtl Textured std::string mtl = "newtml lightmap_none\r\n"
Ka 1.000 1.000 1.000 "Ka 0 0 0\r\n"
Kd 1.000 1.000 1.000 "Kd 0 0 0\r\n"
Ks 0.000 0.000 0.000 "ks 0 0 0\r\n"
map_Ka lightmap0.png "map_Kd lightmap0.png\r\n";
map_Kd lightmap0.png
)"; for (int i = 0; i < textures.size(); i++)
{
mtl += "\r\nnewmtl lightmap" + std::to_string(i) + "\r\n";
mtl +=
"Ka 1 1 1\r\n"
"Kd 1 1 1\r\n"
"Ks 0 0 0\r\n";
mtl += "map_Ka lightmap" + std::to_string(i) + ".png\r\n";
mtl += "map_Kd lightmap" + std::to_string(i) + ".png\r\n";
}
file = fopen(mtlfilename.c_str(), "wb"); file = fopen(mtlfilename.c_str(), "wb");
if (file) if (file)
@ -1131,4 +1159,6 @@ void LevelMesh::Export(std::string filename)
PNGWriter::save("lightmap" + std::to_string(index++) + ".png", w, h, 8, buffer); PNGWriter::save("lightmap" + std::to_string(index++) + ".png", w, h, 8, buffer);
#endif #endif
} }
printf("Export complete\n");
} }

View file

@ -117,6 +117,7 @@ int NumThreads = 0;
int LMDims = 1024; int LMDims = 1024;
bool CPURaytrace = false; bool CPURaytrace = false;
bool VKDebug = false; bool VKDebug = false;
bool DumpMesh = false;
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -155,10 +156,11 @@ static option long_opts[] =
{"size", required_argument, 0, 'S'}, {"size", required_argument, 0, 'S'},
{"cpu-raytrace", no_argument, 0, 'C'}, {"cpu-raytrace", no_argument, 0, 'C'},
{"vkdebug", no_argument, 0, 'D'}, {"vkdebug", no_argument, 0, 'D'},
{"dump-mesh", no_argument, 0, 1004},
{0,0,0,0} {0,0,0,0}
}; };
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:S:CD"; static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:S:CD:";
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
@ -242,8 +244,15 @@ int main(int argc, char **argv)
builder.BuildNodes(); builder.BuildNodes();
builder.BuildLightmaps(); builder.BuildLightmaps();
builder.Write(outwad); builder.Write(outwad);
END_COUNTER(t2a, t2b, t2c, " %.3f seconds.\n") END_COUNTER(t2a, t2b, t2c, " %.3f seconds.\n")
if(DumpMesh)
{
printf("\n");
builder.DumpMesh();
}
lump = inwad.LumpAfterMap(lump); lump = inwad.LumpAfterMap(lump);
} }
else if (inwad.IsGLNodes(lump)) else if (inwad.IsGLNodes(lump))
@ -445,6 +454,9 @@ static void ParseArgs(int argc, char **argv)
case 'D': case 'D':
VKDebug = true; VKDebug = true;
break; break;
case 1004:
DumpMesh = true;
break;
case 1000: case 1000:
ShowUsage(); ShowUsage();
exit(0); exit(0);
@ -490,6 +502,7 @@ static void ShowUsage()
" -S, --size=NNN lightmap texture dimensions for width and height must be in powers of two (1, 2, 4, 8, 16, etc)\n" " -S, --size=NNN lightmap texture dimensions for width and height must be in powers of two (1, 2, 4, 8, 16, etc)\n"
" -C, --cpu-raytrace Use the CPU for ray tracing\n" " -C, --cpu-raytrace Use the CPU for ray tracing\n"
" -D, --vkdebug Print messages from the vulkan validation layer\n" " -D, --vkdebug Print messages from the vulkan validation layer\n"
" --dump-mesh Export level mesh and lightmaps for debugging\n"
" -w, --warn Show warning messages\n" " -w, --warn Show warning messages\n"
#if HAVE_TIMING #if HAVE_TIMING
" -t, --no-timing Suppress timing information\n" " -t, --no-timing Suppress timing information\n"