diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 7702f68de..e0c136255 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -361,6 +361,12 @@ public: return v; } + float ReadFloat() + { + float v = 0.0f; + Read(&v, 4); + return v; + } friend class FileSystem; }; diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp index ae3f3f56e..b4a58345a 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -1,5 +1,6 @@ #include "hw_levelmesh.h" +#include "halffloat.h" LevelMesh::LevelMesh() { @@ -187,3 +188,105 @@ void LevelSubmesh::BuildTileSurfaceLists() } } } + +void LevelSubmesh::SetupTileTransforms() +{ + for (auto& tile : LightmapTiles) + { + tile.SetupTileTransform(LMTextureSize); + } +} + +void LevelSubmesh::PackLightmapAtlas(int lightmapStartIndex) +{ + std::vector sortedTiles; + sortedTiles.reserve(LightmapTiles.Size()); + + for (auto& tile : LightmapTiles) + { + sortedTiles.push_back(&tile); + } + + std::sort(sortedTiles.begin(), sortedTiles.end(), [](LightmapTile* a, LightmapTile* b) { return a->AtlasLocation.Height != b->AtlasLocation.Height ? a->AtlasLocation.Height > b->AtlasLocation.Height : a->AtlasLocation.Width > b->AtlasLocation.Width; }); + + RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0)); + + for (LightmapTile* tile : sortedTiles) + { + int sampleWidth = tile->AtlasLocation.Width; + int sampleHeight = tile->AtlasLocation.Height; + + auto result = packer.insert(sampleWidth, sampleHeight); + int x = result.pos.x, y = result.pos.y; + + tile->AtlasLocation.X = x; + tile->AtlasLocation.Y = y; + tile->AtlasLocation.ArrayIndex = lightmapStartIndex + (int)result.pageIndex; + } + + LMTextureCount = (int)packer.getNumPages(); + + // Calculate final texture coordinates + for (int i = 0, count = GetSurfaceCount(); i < count; i++) + { + auto surface = GetSurface(i); + if (surface->LightmapTileIndex >= 0) + { + const LightmapTile& tile = LightmapTiles[surface->LightmapTileIndex]; + for (int i = 0; i < surface->MeshLocation.NumVerts; i++) + { + auto& vertex = Mesh.Vertices[surface->MeshLocation.StartVertIndex + i]; + FVector2 uv = tile.ToUV(vertex.fPos(), (float)LMTextureSize); + vertex.lu = uv.X; + vertex.lv = uv.Y; + vertex.lindex = (float)tile.AtlasLocation.ArrayIndex; + } + } + } + +#if 0 // Debug atlas tile locations: + float colors[30] = + { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 0.5f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.0f, + 0.0f, 0.5f, 0.5f, + 0.5f, 0.0f, 0.5f + }; + LMTextureData.Resize(LMTextureSize * LMTextureSize * LMTextureCount * 3); + uint16_t* pixels = LMTextureData.Data(); + for (LightmapTile& tile : LightmapTiles) + { + tile.NeedsUpdate = false; + + int index = tile.Binding.TypeIndex; + float* color = colors + (index % 10) * 3; + + int x = tile.AtlasLocation.X; + int y = tile.AtlasLocation.Y; + int w = tile.AtlasLocation.Width; + int h = tile.AtlasLocation.Height; + for (int yy = y; yy < y + h; yy++) + { + uint16_t* line = pixels + tile.AtlasLocation.ArrayIndex * LMTextureSize * LMTextureSize + yy * LMTextureSize * 3; + for (int xx = x; xx < x + w; xx++) + { + float gray = (yy - y) / (float)h; + line[xx * 3] = floatToHalf(color[0] * gray); + line[xx * 3 + 1] = floatToHalf(color[1] * gray); + line[xx * 3 + 2] = floatToHalf(color[2] * gray); + } + } + } + for (int i = 0, count = GetSurfaceCount(); i < count; i++) + { + auto surface = GetSurface(i); + surface->AlwaysUpdate = false; + } +#endif +} diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index a62c8ff67..ed6426782 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -13,6 +13,9 @@ #include "hw_surfaceuniforms.h" #include +#include +typedef dp::rect_pack::RectPacker RectPacker; + struct LevelMeshTileStats; struct LevelSubmeshDrawRange @@ -61,9 +64,8 @@ public: void UpdateCollision(); void GatherTilePixelStats(LevelMeshTileStats& stats); void BuildTileSurfaceLists(); - -private: - FVector2 ToUV(const FVector3& vert, const LightmapTile* tile); + void SetupTileTransforms(); + void PackLightmapAtlas(int lightmapStartIndex); }; class LevelMesh diff --git a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h index faf188092..c65f9c038 100644 --- a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h +++ b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h @@ -69,4 +69,96 @@ struct LightmapTile float v = (AtlasLocation.Y + (localPos | Transform.ProjLocalToV)) / textureSize; return FVector2(u, v); } + + enum PlaneAxis + { + AXIS_YZ = 0, + AXIS_XZ, + AXIS_XY + }; + + static PlaneAxis BestAxis(const FVector4& p) + { + float na = fabs(float(p.X)); + float nb = fabs(float(p.Y)); + float nc = fabs(float(p.Z)); + + // figure out what axis the plane lies on + if (na >= nb && na >= nc) + { + return AXIS_YZ; + } + else if (nb >= na && nb >= nc) + { + return AXIS_XZ; + } + + return AXIS_XY; + } + + void SetupTileTransform(int textureSize) + { + BBox bounds = Bounds; + + // round off dimensions + FVector3 roundedSize; + for (int i = 0; i < 3; i++) + { + bounds.min[i] = SampleDimension * (floor(bounds.min[i] / SampleDimension) - 1); + bounds.max[i] = SampleDimension * (ceil(bounds.max[i] / SampleDimension) + 1); + roundedSize[i] = (bounds.max[i] - bounds.min[i]) / SampleDimension; + } + + FVector3 tCoords[2] = { FVector3(0.0f, 0.0f, 0.0f), FVector3(0.0f, 0.0f, 0.0f) }; + + PlaneAxis axis = BestAxis(Plane); + + int width; + int height; + switch (axis) + { + default: + case AXIS_YZ: + width = (int)roundedSize.Y; + height = (int)roundedSize.Z; + tCoords[0].Y = 1.0f / SampleDimension; + tCoords[1].Z = 1.0f / SampleDimension; + break; + + case AXIS_XZ: + width = (int)roundedSize.X; + height = (int)roundedSize.Z; + tCoords[0].X = 1.0f / SampleDimension; + tCoords[1].Z = 1.0f / SampleDimension; + break; + + case AXIS_XY: + width = (int)roundedSize.X; + height = (int)roundedSize.Y; + tCoords[0].X = 1.0f / SampleDimension; + tCoords[1].Y = 1.0f / SampleDimension; + break; + } + + // clamp width + if (width > textureSize - 2) + { + tCoords[0] *= ((float)(textureSize - 2) / (float)width); + width = (textureSize - 2); + } + + // clamp height + if (height > textureSize - 2) + { + tCoords[1] *= ((float)(textureSize - 2) / (float)height); + height = (textureSize - 2); + } + + Transform.TranslateWorldToLocal = bounds.min; + Transform.ProjLocalToU = tCoords[0]; + Transform.ProjLocalToV = tCoords[1]; + + AtlasLocation.Width = width; + AtlasLocation.Height = height; + } }; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 24a6090fa..fce403ba0 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3012,7 +3012,14 @@ void MapLoader::InitLevelMesh(MapData* map) Level->levelMesh = new DoomLevelMesh(*Level); // Lightmap binding/loading - LoadLightmap(map); + if (!LoadLightmap(map)) + { + if (Level->lightmaps) + { + Level->levelMesh->StaticMesh->SetupTileTransforms(); + Level->levelMesh->StaticMesh->PackLightmapAtlas(0); + } + } } bool MapLoader::LoadLightmap(MapData* map) @@ -3025,12 +3032,12 @@ bool MapLoader::LoadLightmap(MapData* map) return false; int version = fr.ReadInt32(); - if (version < 2) + if (version < 3) { Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); return false; } - else if (version != 2) + else if (version != 3) { Printf(PRINT_HIGH, "LoadLightmap: unsupported lightmap lump version\n"); return false; @@ -3038,14 +3045,13 @@ bool MapLoader::LoadLightmap(MapData* map) uint32_t numTiles = fr.ReadUInt32(); uint32_t numTexPixels = fr.ReadUInt32(); - uint32_t numTexCoords = fr.ReadUInt32(); // To do: remove from a future version of the format. We don't need this. if (developer >= 5) { - Printf("LoadLightmap: Tiles: %u, Pixels: %u, UVs: %u\n", numTiles, numTexPixels, numTexCoords); + Printf("LoadLightmap: Tiles: %u, Pixels: %u\n", numTiles, numTexPixels); } - if (numTiles == 0 || numTexCoords == 0 || numTexPixels == 0) + if (numTiles == 0 || numTexPixels == 0) return false; int errors = 0; @@ -3058,9 +3064,9 @@ bool MapLoader::LoadLightmap(MapData* map) uint32_t controlSector; // 0xFFFFFFFF is none uint16_t width, height; // in pixels uint32_t pixelsOffset; // offset in pixels array - uint32_t uvCount, uvOffset; - - DoomLevelMeshSurface* targetSurface; + FVector3 translateWorldToLocal; + FVector3 projLocalToU; + FVector3 projLocalToV; }; TArray tileEntries; @@ -3076,8 +3082,15 @@ bool MapLoader::LoadLightmap(MapData* map) entry.width = fr.ReadUInt16(); entry.height = fr.ReadUInt16(); entry.pixelsOffset = fr.ReadUInt32(); - entry.uvCount = fr.ReadUInt32(); - entry.uvOffset = fr.ReadUInt32(); + entry.translateWorldToLocal.X = fr.ReadFloat(); + entry.translateWorldToLocal.Y = fr.ReadFloat(); + entry.translateWorldToLocal.Z = fr.ReadFloat(); + entry.projLocalToU.X = fr.ReadFloat(); + entry.projLocalToU.Y = fr.ReadFloat(); + entry.projLocalToU.Z = fr.ReadFloat(); + entry.projLocalToV.X = fr.ReadFloat(); + entry.projLocalToV.Y = fr.ReadFloat(); + entry.projLocalToV.Z = fr.ReadFloat(); } // Load pixels @@ -3086,18 +3099,9 @@ bool MapLoader::LoadLightmap(MapData* map) uint8_t* data = (uint8_t*)&textureData[0]; fr.Read(data, numTexPixels * 3 * sizeof(uint16_t)); - // Load texture coordinates - // TArray zdrayUvs; - // zdrayUvs.Resize(numTexCoords); - // fr.Read(&zdrayUvs[0], numTexCoords * 2 * sizeof(float)); - auto submesh = Level->levelMesh->StaticMesh.get(); const auto textureSize = submesh->LMTextureSize; - // Start with empty lightmap textures - submesh->LMTextureData.Resize(submesh->LMTextureCount * textureSize * textureSize * 3); - memset(submesh->LMTextureData.Data(), 0, submesh->LMTextureData.Size() * sizeof(uint16_t)); - // Create lookup for finding tiles std::map levelTiles; for (LightmapTile& tile : submesh->LightmapTiles) @@ -3105,7 +3109,8 @@ bool MapLoader::LoadLightmap(MapData* map) levelTiles[tile.Binding] = &tile; } - // Bind tiles and copy their pixels to the texture + // Bind tiles and use the lump's tile transform + TArray> foundBindings; for (const TileEntry& entry : tileEntries) { LightmapTileBinding binding; @@ -3122,34 +3127,58 @@ bool MapLoader::LoadLightmap(MapData* map) continue; } - LightmapTile* tile = it->second; - - // To do: add transform info to the lump so that we can stretch the pixels as the lump lightmapper might be using fixed point coordinates that could cause alignment issues - - if (tile->AtlasLocation.Width != entry.width || tile->AtlasLocation.Height != entry.height) + if (entry.width == 0 || entry.height == 0) { if (errors < 10 && developer >= 1) - Printf("Lightmap tile size mismatch (type = %d, index = %d, control sector = %d)\n", entry.type, entry.typeIndex, entry.controlSector); + Printf("Invalid lightmap tile found (type = %d, index = %d, control sector = %d)\n", entry.type, entry.typeIndex, entry.controlSector); errors++; continue; } - const uint16_t* src = textureData.Data() + entry.pixelsOffset; + LightmapTile* tile = it->second; + + tile->AtlasLocation.Width = entry.width; + tile->AtlasLocation.Height = entry.height; + tile->Transform.TranslateWorldToLocal = entry.translateWorldToLocal; + tile->Transform.ProjLocalToU = entry.projLocalToU; + tile->Transform.ProjLocalToV = entry.projLocalToV; + tile->NeedsUpdate = false; + + foundBindings.Push({ &entry, tile }); + } + + // Setup the tile transform for any tile missing in the lump (shouldn't be any, but if there are we let the lightmapper bake them) + for (auto& tile : submesh->LightmapTiles) + { + if (tile.NeedsUpdate) + tile.SetupTileTransform(submesh->LMTextureSize); + } + + // Place all tiles in atlas textures + submesh->PackLightmapAtlas(0); + + // Start with empty lightmap textures + submesh->LMTextureData.Resize(submesh->LMTextureCount * textureSize * textureSize * 3); + memset(submesh->LMTextureData.Data(), 0, submesh->LMTextureData.Size() * sizeof(uint16_t)); + + // Copy tile pixels to the texture + for (auto& binding : foundBindings) + { + const TileEntry* entry = binding.first; + LightmapTile* tile = binding.second; + + const uint16_t* src = textureData.Data() + entry->pixelsOffset; uint16_t* dst = &submesh->LMTextureData[tile->AtlasLocation.ArrayIndex * textureSize * textureSize * 3]; + int destx = tile->AtlasLocation.X; + int desty = tile->AtlasLocation.Y; + int width = tile->AtlasLocation.Width; + int height = tile->AtlasLocation.Height; - int x = tile->AtlasLocation.X; - int y = tile->AtlasLocation.Y; - int w = tile->AtlasLocation.Width; - int h = tile->AtlasLocation.Height; - - for (int yy = 0; yy < w; yy++) + for (int yy = 0; yy < height; yy++) { - const uint16_t* srcline = src + yy * w * 3; - uint16_t* dstline = dst + (x + yy * textureSize) * 3; - for (int xx = 0, end = w * 3; xx < end; xx++) - { - dstline[xx] = srcline[xx]; - } + uint16_t* dstline = dst + (destx + (desty + yy) * textureSize) * 3; + const uint16_t* srcline = src + yy * (width * 3); + memcpy(dstline, srcline, width * 6); } tile->NeedsUpdate = false; diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 7ff6d8f9e..f03c2ec72 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -154,7 +154,12 @@ DoomLevelMesh::DoomLevelMesh(FLevelLocals& doomMap) void DoomLevelMesh::BeginFrame(FLevelLocals& doomMap) { - static_cast(DynamicMesh.get())->Update(doomMap, static_cast(StaticMesh.get())->LMTextureCount); + static_cast(DynamicMesh.get())->Update(doomMap); + if (doomMap.lightmaps) + { + DynamicMesh->SetupTileTransforms(); + DynamicMesh->PackLightmapAtlas(StaticMesh->LMTextureCount); + } } bool DoomLevelMesh::TraceSky(const FVector3& start, FVector3 direction, float dist) diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.cpp b/src/rendering/hwrenderer/doom_levelsubmesh.cpp index e50730845..71554da39 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelsubmesh.cpp @@ -7,7 +7,6 @@ #include "c_dispatch.h" #include "g_levellocals.h" #include "a_dynlight.h" -#include "halffloat.h" #include "hw_renderstate.h" #include "hw_vertexbuilder.h" #include "hwrenderer/scene/hw_drawstructs.h" @@ -32,12 +31,10 @@ DoomLevelSubmesh::DoomLevelSubmesh(DoomLevelMesh* mesh, FLevelLocals& doomMap, b SortIndexes(); BuildTileSurfaceLists(); UpdateCollision(); - if (doomMap.lightmaps) - PackLightmapAtlas(doomMap, 0); } } -void DoomLevelSubmesh::Update(FLevelLocals& doomMap, int lightmapStartIndex) +void DoomLevelSubmesh::Update(FLevelLocals& doomMap) { if (!StaticMesh) { @@ -49,9 +46,6 @@ void DoomLevelSubmesh::Update(FLevelLocals& doomMap, int lightmapStartIndex) SortIndexes(); BuildTileSurfaceLists(); UpdateCollision(); - - if (doomMap.lightmaps) - PackLightmapAtlas(doomMap, lightmapStartIndex); } } @@ -170,11 +164,6 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) state.SetRenderStyle(STYLE_Normal); } } - - for (auto& tile : LightmapTiles) - { - SetupTileTransform(LMTextureSize, LMTextureSize, tile); - } } void DoomLevelSubmesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, std::map& bindings, TArray& list, bool isSky, bool translucent) @@ -620,98 +609,6 @@ void DoomLevelSubmesh::SetSideLightmap(DoomLevelMeshSurface* surface) } } -void DoomLevelSubmesh::PackLightmapAtlas(FLevelLocals& doomMap, int lightmapStartIndex) -{ - std::vector sortedTiles; - sortedTiles.reserve(LightmapTiles.Size()); - - for (auto& tile : LightmapTiles) - { - sortedTiles.push_back(&tile); - } - - std::sort(sortedTiles.begin(), sortedTiles.end(), [](LightmapTile* a, LightmapTile* b) { return a->AtlasLocation.Height != b->AtlasLocation.Height ? a->AtlasLocation.Height > b->AtlasLocation.Height : a->AtlasLocation.Width > b->AtlasLocation.Width; }); - - RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0)); - - for (LightmapTile* tile : sortedTiles) - { - int sampleWidth = tile->AtlasLocation.Width; - int sampleHeight = tile->AtlasLocation.Height; - - auto result = packer.insert(sampleWidth, sampleHeight); - int x = result.pos.x, y = result.pos.y; - - tile->AtlasLocation.X = x; - tile->AtlasLocation.Y = y; - tile->AtlasLocation.ArrayIndex = lightmapStartIndex + (int)result.pageIndex; - } - - LMTextureCount = (int)packer.getNumPages(); - - // Calculate final texture coordinates - for (auto& surface : Surfaces) - { - if (surface.LightmapTileIndex >= 0) - { - const LightmapTile& tile = LightmapTiles[surface.LightmapTileIndex]; - for (int i = 0; i < surface.MeshLocation.NumVerts; i++) - { - auto& vertex = Mesh.Vertices[surface.MeshLocation.StartVertIndex + i]; - FVector2 uv = tile.ToUV(vertex.fPos(), (float)LMTextureSize); - vertex.lu = uv.X; - vertex.lv = uv.Y; - vertex.lindex = (float)tile.AtlasLocation.ArrayIndex; - } - } - } - -#if 0 // Debug atlas tile locations: - float colors[30] = - { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, - 0.0f, 1.0f, 1.0f, - 1.0f, 0.0f, 1.0f, - 0.5f, 0.0f, 0.0f, - 0.0f, 0.5f, 0.0f, - 0.5f, 0.5f, 0.0f, - 0.0f, 0.5f, 0.5f, - 0.5f, 0.0f, 0.5f - }; - LMTextureData.Resize(LMTextureSize * LMTextureSize * LMTextureCount * 3); - uint16_t* pixels = LMTextureData.Data(); - for (LightmapTile& tile : LightmapTiles) - { - tile.NeedsUpdate = false; - - int index = tile.Binding.TypeIndex; - float* color = colors + (index % 10) * 3; - - int x = tile.AtlasLocation.X; - int y = tile.AtlasLocation.Y; - int w = tile.AtlasLocation.Width; - int h = tile.AtlasLocation.Height; - for (int yy = y; yy < y + h; yy++) - { - uint16_t* line = pixels + tile.AtlasLocation.ArrayIndex * LMTextureSize * LMTextureSize + yy * LMTextureSize * 3; - for (int xx = x; xx < x + w; xx++) - { - float gray = (yy - y) / (float)h; - line[xx * 3] = floatToHalf(color[0] * gray); - line[xx * 3 + 1] = floatToHalf(color[1] * gray); - line[xx * 3 + 2] = floatToHalf(color[2] * gray); - } - } - } - for (DoomLevelMeshSurface& surf : Surfaces) - { - surf.AlwaysUpdate = false; - } -#endif -} - BBox DoomLevelSubmesh::GetBoundsFromSurface(const LevelMeshSurface& surface) const { BBox bounds; @@ -728,88 +625,3 @@ BBox DoomLevelSubmesh::GetBoundsFromSurface(const LevelMeshSurface& surface) con } return bounds; } - -DoomLevelSubmesh::PlaneAxis DoomLevelSubmesh::BestAxis(const FVector4& p) -{ - float na = fabs(float(p.X)); - float nb = fabs(float(p.Y)); - float nc = fabs(float(p.Z)); - - // figure out what axis the plane lies on - if (na >= nb && na >= nc) - { - return AXIS_YZ; - } - else if (nb >= na && nb >= nc) - { - return AXIS_XZ; - } - - return AXIS_XY; -} - -void DoomLevelSubmesh::SetupTileTransform(int lightMapTextureWidth, int lightMapTextureHeight, LightmapTile& tile) -{ - BBox bounds = tile.Bounds; - - // round off dimensions - FVector3 roundedSize; - for (int i = 0; i < 3; i++) - { - bounds.min[i] = tile.SampleDimension * (floor(bounds.min[i] / tile.SampleDimension) - 1); - bounds.max[i] = tile.SampleDimension * (ceil(bounds.max[i] / tile.SampleDimension) + 1); - roundedSize[i] = (bounds.max[i] - bounds.min[i]) / tile.SampleDimension; - } - - FVector3 tCoords[2] = { FVector3(0.0f, 0.0f, 0.0f), FVector3(0.0f, 0.0f, 0.0f) }; - - PlaneAxis axis = BestAxis(tile.Plane); - - int width; - int height; - switch (axis) - { - default: - case AXIS_YZ: - width = (int)roundedSize.Y; - height = (int)roundedSize.Z; - tCoords[0].Y = 1.0f / tile.SampleDimension; - tCoords[1].Z = 1.0f / tile.SampleDimension; - break; - - case AXIS_XZ: - width = (int)roundedSize.X; - height = (int)roundedSize.Z; - tCoords[0].X = 1.0f / tile.SampleDimension; - tCoords[1].Z = 1.0f / tile.SampleDimension; - break; - - case AXIS_XY: - width = (int)roundedSize.X; - height = (int)roundedSize.Y; - tCoords[0].X = 1.0f / tile.SampleDimension; - tCoords[1].Y = 1.0f / tile.SampleDimension; - break; - } - - // clamp width - if (width > lightMapTextureWidth - 2) - { - tCoords[0] *= ((float)(lightMapTextureWidth - 2) / (float)width); - width = (lightMapTextureWidth - 2); - } - - // clamp height - if (height > lightMapTextureHeight - 2) - { - tCoords[1] *= ((float)(lightMapTextureHeight - 2) / (float)height); - height = (lightMapTextureHeight - 2); - } - - tile.Transform.TranslateWorldToLocal = bounds.min; - tile.Transform.ProjLocalToU = tCoords[0]; - tile.Transform.ProjLocalToV = tCoords[1]; - - tile.AtlasLocation.Width = width; - tile.AtlasLocation.Height = height; -} diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.h b/src/rendering/hwrenderer/doom_levelsubmesh.h index df5386cb2..3bb3d8717 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.h +++ b/src/rendering/hwrenderer/doom_levelsubmesh.h @@ -7,12 +7,9 @@ #include "vectors.h" #include "r_defs.h" #include "bounds.h" -#include #include #include -typedef dp::rect_pack::RectPacker RectPacker; - struct FLevelLocals; struct FPolyObj; struct HWWallDispatcher; @@ -36,7 +33,7 @@ class DoomLevelSubmesh : public LevelSubmesh public: DoomLevelSubmesh(DoomLevelMesh* mesh, FLevelLocals& doomMap, bool staticMesh); - void Update(FLevelLocals& doomMap, int lightmapStartIndex); + void Update(FLevelLocals& doomMap); LevelMeshSurface* GetSurface(int index) override { return &Surfaces[index]; } unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const override { return (unsigned int)(ptrdiff_t)(static_cast(surface) - Surfaces.Data()); } @@ -61,19 +58,9 @@ private: void CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state, std::map& bindings, TArray& list, bool isSky = false); void LinkSurfaces(FLevelLocals& doomMap); - void PackLightmapAtlas(FLevelLocals& doomMap, int lightmapStartIndex); - enum PlaneAxis - { - AXIS_YZ = 0, - AXIS_XZ, - AXIS_XY - }; - - static PlaneAxis BestAxis(const FVector4& p); BBox GetBoundsFromSurface(const LevelMeshSurface& surface) const; - void SetupTileTransform(int lightMapTextureWidth, int lightMapTextureHeight, LightmapTile& tile); int AddSurfaceToTile(const DoomLevelMeshSurface& surf, std::map& bindings); int GetSampleDimension(const DoomLevelMeshSurface& surf);