diff --git a/src/level/level.cpp b/src/level/level.cpp index bfccdc7..df38a54 100644 --- a/src/level/level.cpp +++ b/src/level/level.cpp @@ -794,6 +794,18 @@ void FProcessor::BuildLightmaps() LightmapMesh->CreateTextures(); } +void FProcessor::DumpMesh() +{ + if (LightmapMesh) + { + LightmapMesh->Export("levelmesh.obj"); + } + else + { + printf("Error: no mesh to export\n"); + } +} + void FProcessor::Write (FWadWriter &out) { if (Level.NumLines() == 0 || Level.NumSides() == 0 || Level.NumSectors() == 0 || Level.NumVertices == 0) diff --git a/src/level/level.h b/src/level/level.h index b9f2453..2431917 100644 --- a/src/level/level.h +++ b/src/level/level.h @@ -59,6 +59,8 @@ public: void BuildLightmaps(); void Write(FWadWriter &out); + void DumpMesh(); + private: void LoadUDMF(); void LoadThings(); diff --git a/src/lightmap/levelmesh.cpp b/src/lightmap/levelmesh.cpp index 8f2dcb6..d4cc656 100644 --- a/src/lightmap/levelmesh.cpp +++ b/src/lightmap/levelmesh.cpp @@ -977,6 +977,8 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile) 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! ;) std::string mtlfilename = filename; for (int i = 0; i < 3; i++) mtlfilename.pop_back(); @@ -986,14 +988,19 @@ void LevelMesh::Export(std::string filename) TArray outuv; TArray outnormal; TArray outface; + TArray outLightmapId; outvertices.Resize(MeshVertices.Size()); outuv.Resize(MeshVertices.Size()); outnormal.Resize(MeshVertices.Size()); + outLightmapId.Resize(MeshElements.Size() / 3); for (unsigned int surfidx = 0; surfidx < MeshElements.Size() / 3; surfidx++) { Surface* surface = surfaces[MeshSurfaces[surfidx]].get(); + + outLightmapId[surfidx] = surface->lightmapNum; + for (int i = 0; i < 3; i++) { int elementidx = surfidx * 3 + i; @@ -1004,8 +1011,6 @@ void LevelMesh::Export(std::string filename) outuv[vertexidx] = surface->lightmapCoords[uvindex]; outnormal[vertexidx] = surface->plane.Normal(); outface.Push(vertexidx); - - //surface->lightmapNum; } } @@ -1018,8 +1023,6 @@ void LevelMesh::Export(std::string filename) buffer += mtlfilename; buffer += "\r\n"; - buffer += "usemtl Textured\r\n"; - float scale = 0.01f; for (unsigned int i = 0; i < outvertices.Size(); i++) @@ -1053,8 +1056,24 @@ void LevelMesh::Export(std::string filename) buffer += "\r\n"; } + int prevLightmap = -1; + 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 e1 = std::to_string(outface[i + 1] + 1); std::string e2 = std::to_string(outface[i + 2] + 1); @@ -1086,13 +1105,22 @@ void LevelMesh::Export(std::string filename) fclose(file); } - std::string mtl = R"(newmtl Textured - Ka 1.000 1.000 1.000 - Kd 1.000 1.000 1.000 - Ks 0.000 0.000 0.000 - map_Ka lightmap0.png - map_Kd lightmap0.png -)"; + std::string mtl = "newtml lightmap_none\r\n" + "Ka 0 0 0\r\n" + "Kd 0 0 0\r\n" + "ks 0 0 0\r\n" + "map_Kd lightmap0.png\r\n"; + + 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"); if (file) @@ -1131,4 +1159,6 @@ void LevelMesh::Export(std::string filename) PNGWriter::save("lightmap" + std::to_string(index++) + ".png", w, h, 8, buffer); #endif } + + printf("Export complete\n"); } diff --git a/src/main.cpp b/src/main.cpp index 0b5f918..008ca4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -117,6 +117,7 @@ int NumThreads = 0; int LMDims = 1024; bool CPURaytrace = false; bool VKDebug = false; +bool DumpMesh = false; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -155,10 +156,11 @@ static option long_opts[] = {"size", required_argument, 0, 'S'}, {"cpu-raytrace", no_argument, 0, 'C'}, {"vkdebug", no_argument, 0, 'D'}, + {"dump-mesh", no_argument, 0, 1004}, {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 -------------------------------------------------------------------- @@ -242,8 +244,15 @@ int main(int argc, char **argv) builder.BuildNodes(); builder.BuildLightmaps(); builder.Write(outwad); + END_COUNTER(t2a, t2b, t2c, " %.3f seconds.\n") + if(DumpMesh) + { + printf("\n"); + builder.DumpMesh(); + } + lump = inwad.LumpAfterMap(lump); } else if (inwad.IsGLNodes(lump)) @@ -445,6 +454,9 @@ static void ParseArgs(int argc, char **argv) case 'D': VKDebug = true; break; + case 1004: + DumpMesh = true; + break; case 1000: ShowUsage(); 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" " -C, --cpu-raytrace Use the CPU for ray tracing\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" #if HAVE_TIMING " -t, --no-timing Suppress timing information\n"