diff --git a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h index bf6e52302..fc06953aa 100644 --- a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h +++ b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h @@ -172,9 +172,9 @@ struct LightmapTile height = textureSize; } - Transform.TranslateWorldToLocal.X = uvMin.X * SampleDimension; - Transform.TranslateWorldToLocal.Y = uvMin.Y * SampleDimension; - Transform.TranslateWorldToLocal.Z = uvMin.Z * SampleDimension; + Transform.TranslateWorldToLocal.X = uvMin.X * SampleDimension + 0.1f; + Transform.TranslateWorldToLocal.Y = uvMin.Y * SampleDimension + 0.1f; + Transform.TranslateWorldToLocal.Z = uvMin.Z * SampleDimension + 0.1f; Transform.ProjLocalToU = tCoords[0]; Transform.ProjLocalToV = tCoords[1]; diff --git a/src/common/utility/m_bbox.h b/src/common/utility/m_bbox.h index 7f622a6ba..3a35b5828 100644 --- a/src/common/utility/m_bbox.h +++ b/src/common/utility/m_bbox.h @@ -50,6 +50,14 @@ public: m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX; } + void extend(double size) + { + m_Box[BOXTOP] += size; + m_Box[BOXLEFT] -= size; + m_Box[BOXRIGHT] += size; + m_Box[BOXBOTTOM] -= size; + } + // Returns a bounding box that encloses both bounding boxes FBoundingBox operator | (const FBoundingBox &box2) const { diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index d35cdd487..0dca16c30 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -1711,7 +1711,7 @@ struct subsector_t uint32_t numlines; uint16_t flags; short mapsection; - FBoundingBox bbox; // [DVR] For alternative space culling in orthographic projection with no fog of war + FBoundingBox bbox; // subsector related GL data int validcount; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index e52929cfc..0c651206b 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3568,13 +3568,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) P_Recalculate3DFloors(&sec); } - InitLevelMesh(map); - - UpdateVBOLightmap(*screen->RenderState(), Level->sectors); - - Level->aabbTree = new DoomLevelAABBTree(Level); - - // [DVR] Populate subsector->bbox for alternative space culling in orthographic projection with no fog of war + // Calculate subsector->bbox subsector_t* sub = &Level->subsectors[0]; seg_t* seg; for (unsigned int kk = 0; kk < Level->subsectors.Size(); kk++) @@ -3582,9 +3576,9 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) sub[kk].bbox.ClearBox(); unsigned int count = sub[kk].numlines; seg = sub[kk].firstline; - while(count--) + while (count--) { - if((seg->v1 != nullptr) && (seg->v2 != nullptr)) + if ((seg->v1 != nullptr) && (seg->v2 != nullptr)) { sub[kk].bbox.AddToBox(seg->v1->fPos()); sub[kk].bbox.AddToBox(seg->v2->fPos()); @@ -3593,5 +3587,11 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) } } + InitLevelMesh(map); + + UpdateVBOLightmap(*screen->RenderState(), Level->sectors); + + Level->aabbTree = new DoomLevelAABBTree(Level); + LevelMeshUpdater = Level->levelMesh; // Start tracking level changes } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index ee3cbf5fd..cb002d1cf 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -503,15 +503,47 @@ void DoomLevelMesh::BuildSideVisibilityLists(FLevelLocals& doomMap) void DoomLevelMesh::BuildSubsectorVisibilityLists(FLevelLocals& doomMap) { + TArray stack; VisibleSubsectors.resize(doomMap.subsectors.size()); for (size_t i = 0, count = VisibleSubsectors.size(); i < count; i++) { subsector_t* sub = &doomMap.subsectors[i]; + FBoundingBox bbox = sub->bbox; + bbox.extend(32.0); + + validcount++; // Always bake the subsector VisibleSubsectors[i].Push(i); + sub->validcount = validcount; + stack.Push(sub); - // To do: use sub->firstline to find neighbouring subsectors we want included in a tile bake + // Add neighbouring subsectors that touches the bounding box + while (stack.size() != 0) + { + sub = stack.Last(); + stack.Pop(); + + auto lines = sub->firstline; + uint32_t count = sub->numlines; + for (uint32_t j = 0; j < count; j++) + { + seg_t* partner = lines[j].PartnerSeg; + if (partner && partner->Subsector) + { + subsector_t* partnersub = partner->Subsector; + if (partnersub->validcount != validcount) + { + partnersub->validcount = validcount; + if (partnersub->bbox.CheckOverlap(bbox)) + { + stack.Push(partnersub); + VisibleSubsectors[i].Push(partnersub->Index()); + } + } + } + } + } } }