diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c761f4dbb..9a1dd81a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1115,6 +1115,7 @@ set (PCH_SOURCES common/rendering/hwrenderer/data/hw_shadowmap.cpp common/rendering/hwrenderer/data/hw_shaderpatcher.cpp common/rendering/hwrenderer/data/hw_collision.cpp + common/rendering/hwrenderer/data/hw_levelmesh.cpp common/rendering/hwrenderer/data/hw_meshbuilder.cpp common/rendering/hwrenderer/data/hw_mesh.cpp common/rendering/hwrenderer/postprocessing/hw_postprocessshader.cpp diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp new file mode 100644 index 000000000..39ff02cc5 --- /dev/null +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -0,0 +1,190 @@ + +#include "hw_levelmesh.h" + +LevelMeshSurface* LevelMesh::Trace(const FVector3& start, FVector3 direction, float maxDist) +{ + maxDist = std::max(maxDist - 10.0f, 0.0f); + + FVector3 origin = start; + + LevelMeshSurface* hitSurface = nullptr; + + while (true) + { + FVector3 end = origin + direction * maxDist; + + TraceHit hit0 = TriangleMeshShape::find_first_hit(StaticMesh->Collision.get(), origin, end); + TraceHit hit1 = TriangleMeshShape::find_first_hit(DynamicMesh->Collision.get(), origin, end); + + LevelSubmesh* hitmesh = hit0.fraction < hit1.fraction ? StaticMesh.get() : DynamicMesh.get(); + TraceHit hit = hit0.fraction < hit1.fraction ? hit0 : hit1; + + if (hit.triangle < 0) + { + return nullptr; + } + + hitSurface = hitmesh->GetSurface(hitmesh->MeshSurfaceIndexes[hit.triangle]); + auto portal = hitSurface->portalIndex; + + if (!portal) + { + break; + } + + auto& transformation = hitmesh->Portals[portal]; + + auto travelDist = hit.fraction * maxDist + 2.0f; + if (travelDist >= maxDist) + { + break; + } + + origin = transformation.TransformPosition(origin + direction * travelDist); + direction = transformation.TransformRotation(direction); + maxDist -= travelDist; + } + + return hitSurface; // I hit something +} + +LevelMeshSurfaceStats LevelMesh::GatherSurfacePixelStats() +{ + LevelMeshSurfaceStats stats; + StaticMesh->GatherSurfacePixelStats(stats); + DynamicMesh->GatherSurfacePixelStats(stats); + return stats; +} + +///////////////////////////////////////////////////////////////////////////// + +LevelSubmesh::LevelSubmesh() +{ + // Default portal + LevelMeshPortal portal; + Portals.Push(portal); + + // Default empty mesh (we can't make it completely empty since vulkan doesn't like that) + float minval = -100001.0f; + float maxval = -100000.0f; + MeshVertices.Push({ minval, minval, minval }); + MeshVertices.Push({ maxval, minval, minval }); + MeshVertices.Push({ maxval, maxval, minval }); + MeshVertices.Push({ minval, minval, minval }); + MeshVertices.Push({ minval, maxval, minval }); + MeshVertices.Push({ maxval, maxval, minval }); + MeshVertices.Push({ minval, minval, maxval }); + MeshVertices.Push({ maxval, minval, maxval }); + MeshVertices.Push({ maxval, maxval, maxval }); + MeshVertices.Push({ minval, minval, maxval }); + MeshVertices.Push({ minval, maxval, maxval }); + MeshVertices.Push({ maxval, maxval, maxval }); + + MeshVertexUVs.Resize(MeshVertices.Size()); + + for (int i = 0; i < 3 * 4; i++) + MeshElements.Push(i); + + UpdateCollision(); +} + +void LevelSubmesh::UpdateCollision() +{ + Collision = std::make_unique(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size()); +} + +void LevelSubmesh::GatherSurfacePixelStats(LevelMeshSurfaceStats& stats) +{ + int count = GetSurfaceCount(); + for (int i = 0; i < count; ++i) + { + const auto* surface = GetSurface(i); + auto area = surface->Area(); + + stats.pixels.total += area; + + if (surface->needsUpdate) + { + stats.surfaces.dirty++; + stats.pixels.dirty += area; + } + if (surface->bSky) + { + stats.surfaces.sky++; + stats.pixels.sky += area; + } + } + stats.surfaces.total += count; +} + +void LevelSubmesh::BuildTileSurfaceLists() +{ + // Smoothing group surface is to be rendered with + TArray SmoothingGroups; + TArray SmoothingGroupIndexes(GetSurfaceCount()); + + for (int i = 0, count = GetSurfaceCount(); i < count; i++) + { + auto surface = GetSurface(i); + + // Is this surface in the same plane as an existing smoothing group? + int smoothingGroupIndex = -1; + + for (size_t j = 0; j < SmoothingGroups.Size(); j++) + { + if (surface->sectorGroup == SmoothingGroups[j].sectorGroup) + { + float direction = SmoothingGroups[j].plane.XYZ() | surface->plane.XYZ(); + if (direction >= 0.9999f && direction <= 1.001f) + { + auto point = (surface->plane.XYZ() * surface->plane.W); + auto planeDistance = (SmoothingGroups[j].plane.XYZ() | point) - SmoothingGroups[j].plane.W; + + float dist = std::abs(planeDistance); + if (dist <= 0.01f) + { + smoothingGroupIndex = (int)j; + break; + } + } + } + } + + // Surface is in a new plane. Create a smoothing group for it + if (smoothingGroupIndex == -1) + { + smoothingGroupIndex = SmoothingGroups.Size(); + + LevelMeshSmoothingGroup group; + group.plane = surface->plane; + group.sectorGroup = surface->sectorGroup; + SmoothingGroups.Push(group); + } + + SmoothingGroups[smoothingGroupIndex].surfaces.push_back(surface); + SmoothingGroupIndexes.Push(smoothingGroupIndex); + } + + for (int i = 0, count = GetSurfaceCount(); i < count; i++) + { + auto targetSurface = GetSurface(i); + targetSurface->tileSurfaces.Clear(); + for (LevelMeshSurface* surface : SmoothingGroups[SmoothingGroupIndexes[i]].surfaces) + { + FVector2 minUV = ToUV(surface->bounds.min, targetSurface); + FVector2 maxUV = ToUV(surface->bounds.max, targetSurface); + if (surface != targetSurface && (maxUV.X < 0.0f || maxUV.Y < 0.0f || minUV.X > 1.0f || minUV.Y > 1.0f)) + continue; // Bounding box not visible + + targetSurface->tileSurfaces.Push(surface); + } + } +} + +FVector2 LevelSubmesh::ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface) +{ + FVector3 localPos = vert - targetSurface->translateWorldToLocal; + float u = (1.0f + (localPos | targetSurface->projLocalToU)) / (targetSurface->AtlasTile.Width + 2); + float v = (1.0f + (localPos | targetSurface->projLocalToV)) / (targetSurface->AtlasTile.Height + 2); + return FVector2(u, v); +} diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index c4fdd66e5..5ee7ede8e 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -31,13 +31,13 @@ public: struct LevelMeshSurface { - int numVerts; - unsigned int startVertIndex; - unsigned int startUvIndex; - unsigned int startElementIndex; - unsigned int numElements; - FVector4 plane; - bool bSky; + int numVerts = 0; + unsigned int startVertIndex = 0; + unsigned int startUvIndex = 0; + unsigned int startElementIndex = 0; + unsigned int numElements = 0; + FVector4 plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f); + bool bSky = false; // Surface location in lightmap texture struct @@ -52,10 +52,6 @@ struct LevelMeshSurface // True if the surface needs to be rendered into the lightmap texture before it can be used bool needsUpdate = true; - // - // Required for internal lightmapper: - // - FTextureID texture = FNullTextureID(); float alpha = 1.0; @@ -70,15 +66,9 @@ struct LevelMeshSurface FVector3 projLocalToU = { 0.f, 0.f, 0.f }; FVector3 projLocalToV = { 0.f, 0.f, 0.f }; - // Smoothing group surface is to be rendered with - int smoothingGroupIndex = -1; - // Surfaces that are visible within the lightmap tile TArray tileSurfaces; - // - // Utility/Info - // uint32_t Area() const { return AtlasTile.Width * AtlasTile.Height; } // Light list location in the lightmapper GPU buffers @@ -181,35 +171,7 @@ struct LevelMeshSurfaceStats class LevelSubmesh { public: - LevelSubmesh() - { - // Default portal - LevelMeshPortal portal; - Portals.Push(portal); - - // Default empty mesh (we can't make it completely empty since vulkan doesn't like that) - float minval = -100001.0f; - float maxval = -100000.0f; - MeshVertices.Push({ minval, minval, minval }); - MeshVertices.Push({ maxval, minval, minval }); - MeshVertices.Push({ maxval, maxval, minval }); - MeshVertices.Push({ minval, minval, minval }); - MeshVertices.Push({ minval, maxval, minval }); - MeshVertices.Push({ maxval, maxval, minval }); - MeshVertices.Push({ minval, minval, maxval }); - MeshVertices.Push({ maxval, minval, maxval }); - MeshVertices.Push({ maxval, maxval, maxval }); - MeshVertices.Push({ minval, minval, maxval }); - MeshVertices.Push({ minval, maxval, maxval }); - MeshVertices.Push({ maxval, maxval, maxval }); - - MeshVertexUVs.Resize(MeshVertices.Size()); - - for (int i = 0; i < 3 * 4; i++) - MeshElements.Push(i); - - UpdateCollision(); - } + LevelSubmesh(); virtual ~LevelSubmesh() = default; @@ -236,105 +198,12 @@ public: uint32_t AtlasPixelCount() const { return uint32_t(LMTextureCount * LMTextureSize * LMTextureSize); } - void UpdateCollision() - { - Collision = std::make_unique(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size()); - } - - void GatherSurfacePixelStats(LevelMeshSurfaceStats& stats) - { - int count = GetSurfaceCount(); - for (int i = 0; i < count; ++i) - { - const auto* surface = GetSurface(i); - auto area = surface->Area(); - - stats.pixels.total += area; - - if (surface->needsUpdate) - { - stats.surfaces.dirty++; - stats.pixels.dirty += area; - } - if (surface->bSky) - { - stats.surfaces.sky++; - stats.pixels.sky += area; - } - } - stats.surfaces.total += count; - } - - void BuildSmoothingGroups() - { - TArray SmoothingGroups; - - for (int i = 0, count = GetSurfaceCount(); i < count; i++) - { - auto surface = GetSurface(i); - - // Is this surface in the same plane as an existing smoothing group? - int smoothingGroupIndex = -1; - - for (size_t j = 0; j < SmoothingGroups.Size(); j++) - { - if (surface->sectorGroup == SmoothingGroups[j].sectorGroup) - { - float direction = SmoothingGroups[j].plane.XYZ() | surface->plane.XYZ(); - if (direction >= 0.9999f && direction <= 1.001f) - { - auto point = (surface->plane.XYZ() * surface->plane.W); - auto planeDistance = (SmoothingGroups[j].plane.XYZ() | point) - SmoothingGroups[j].plane.W; - - float dist = std::abs(planeDistance); - if (dist <= 0.01f) - { - smoothingGroupIndex = (int)j; - break; - } - } - } - } - - // Surface is in a new plane. Create a smoothing group for it - if (smoothingGroupIndex == -1) - { - smoothingGroupIndex = SmoothingGroups.Size(); - - LevelMeshSmoothingGroup group; - group.plane = surface->plane; - group.sectorGroup = surface->sectorGroup; - SmoothingGroups.Push(group); - } - - SmoothingGroups[smoothingGroupIndex].surfaces.push_back(surface); - surface->smoothingGroupIndex = smoothingGroupIndex; - } - - for (int i = 0, count = GetSurfaceCount(); i < count; i++) - { - auto targetSurface = GetSurface(i); - targetSurface->tileSurfaces.Clear(); - for (LevelMeshSurface* surface : SmoothingGroups[targetSurface->smoothingGroupIndex].surfaces) - { - FVector2 minUV = ToUV(surface->bounds.min, targetSurface); - FVector2 maxUV = ToUV(surface->bounds.max, targetSurface); - if (surface != targetSurface && (maxUV.X < 0.0f || maxUV.Y < 0.0f || minUV.X > 1.0f || minUV.Y > 1.0f)) - continue; // Bounding box not visible - - targetSurface->tileSurfaces.Push(surface); - } - } - } + void UpdateCollision(); + void GatherSurfacePixelStats(LevelMeshSurfaceStats& stats); + void BuildTileSurfaceLists(); private: - FVector2 ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface) - { - FVector3 localPos = vert - targetSurface->translateWorldToLocal; - float u = (1.0f + (localPos | targetSurface->projLocalToU)) / (targetSurface->AtlasTile.Width + 2); - float v = (1.0f + (localPos | targetSurface->projLocalToV)) / (targetSurface->AtlasTile.Height + 2); - return FVector2(u, v); - } + FVector2 ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface); }; class LevelMesh @@ -347,62 +216,11 @@ public: virtual int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) { return 0; } - LevelMeshSurfaceStats GatherSurfacePixelStats() - { - LevelMeshSurfaceStats stats; - StaticMesh->GatherSurfacePixelStats(stats); - DynamicMesh->GatherSurfacePixelStats(stats); - return stats; - } + LevelMeshSurface* Trace(const FVector3& start, FVector3 direction, float maxDist); + + LevelMeshSurfaceStats GatherSurfacePixelStats(); // Map defaults FVector3 SunDirection = FVector3(0.0f, 0.0f, -1.0f); FVector3 SunColor = FVector3(0.0f, 0.0f, 0.0f); - - LevelMeshSurface* Trace(const FVector3& start, FVector3 direction, float maxDist) - { - maxDist = std::max(maxDist - 10.0f, 0.0f); - - FVector3 origin = start; - - LevelMeshSurface* hitSurface = nullptr; - - while (true) - { - FVector3 end = origin + direction * maxDist; - - TraceHit hit0 = TriangleMeshShape::find_first_hit(StaticMesh->Collision.get(), origin, end); - TraceHit hit1 = TriangleMeshShape::find_first_hit(DynamicMesh->Collision.get(), origin, end); - - LevelSubmesh* hitmesh = hit0.fraction < hit1.fraction ? StaticMesh.get() : DynamicMesh.get(); - TraceHit hit = hit0.fraction < hit1.fraction ? hit0 : hit1; - - if (hit.triangle < 0) - { - return nullptr; - } - - hitSurface = hitmesh->GetSurface(hitmesh->MeshSurfaceIndexes[hit.triangle]); - auto portal = hitSurface->portalIndex; - - if (!portal) - { - break; - } - - auto& transformation = hitmesh->Portals[portal]; - - auto travelDist = hit.fraction * maxDist + 2.0f; - if (travelDist >= maxDist) - { - break; - } - - origin = transformation.TransformPosition(origin + direction * travelDist); - direction = transformation.TransformRotation(direction); - maxDist -= travelDist; - } - - return hitSurface; // I hit something - } }; diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 9482ba741..d11a52e6d 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -10,6 +10,9 @@ #include "common/rendering/vulkan/accelstructs/vk_lightmap.h" #include +VSMatrix GetPlaneTextureRotationMatrix(FGameTexture* gltexture, const sector_t* sector, int plane); +void GetTexCoordInfo(FGameTexture* tex, FTexCoordInfo* tci, side_t* side, int texpos); + static bool RequireLevelMesh() { if (level.levelMesh) @@ -88,7 +91,6 @@ void PrintSurfaceInfo(const DoomLevelMeshSurface* surface) Printf(" Sample dimension: %d\n", surface->sampleDimension); Printf(" Needs update?: %d\n", surface->needsUpdate); Printf(" Sector group: %d\n", surface->sectorGroup); - Printf(" Smoothing group: %d\n", surface->smoothingGroupIndex); Printf(" Texture: '%s' (id=%d)\n", gameTexture ? gameTexture->GetName().GetChars() : "", surface->texture.GetIndex()); Printf(" Alpha: %f\n", surface->alpha); } @@ -134,6 +136,135 @@ CCMD(surfaceinfo) EXTERN_CVAR(Float, lm_scale); +///////////////////////////////////////////////////////////////////////////// + +DoomLevelMesh::DoomLevelMesh(FLevelLocals& doomMap) +{ + SunColor = doomMap.SunColor; // TODO keep only one copy? + SunDirection = doomMap.SunDirection; + + StaticMesh = std::make_unique(); + DynamicMesh = std::make_unique(); + + static_cast(StaticMesh.get())->CreateStatic(doomMap); + static_cast(DynamicMesh.get())->CreateDynamic(doomMap); +} + +void DoomLevelMesh::BeginFrame(FLevelLocals& doomMap) +{ + static_cast(DynamicMesh.get())->UpdateDynamic(doomMap); +} + +bool DoomLevelMesh::TraceSky(const FVector3& start, FVector3 direction, float dist) +{ + FVector3 end = start + direction * dist; + auto surface = Trace(start, direction, dist); + return surface && surface->bSky; +} + +void DoomLevelMesh::PackLightmapAtlas() +{ + static_cast(StaticMesh.get())->PackLightmapAtlas(); +} + +void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) +{ + static_cast(StaticMesh.get())->BindLightmapSurfacesToGeometry(doomMap); + + // Runtime helper + for (auto& surface : static_cast(StaticMesh.get())->Surfaces) + { + if (surface.ControlSector) + { + if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING) + { + XFloorToSurface[surface.Subsector->sector].Push(&surface); + } + else if (surface.Type == ST_MIDDLESIDE) + { + XFloorToSurfaceSides[surface.ControlSector].Push(&surface); + } + } + } +} + +void DoomLevelMesh::DisableLightmaps() +{ + static_cast(StaticMesh.get())->DisableLightmaps(); +} + +void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilename) const +{ + static_cast(StaticMesh.get())->DumpMesh(objFilename, mtlFilename); +} + +int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) +{ + const DoomLevelMeshSurface* doomsurf = static_cast(surface); + + FLightNode* node = nullptr; + if (doomsurf->Type == ST_FLOOR || doomsurf->Type == ST_CEILING) + { + node = doomsurf->Subsector->section->lighthead; + } + else if (doomsurf->Type == ST_MIDDLESIDE || doomsurf->Type == ST_UPPERSIDE || doomsurf->Type == ST_LOWERSIDE) + { + node = doomsurf->Side->lighthead; + } + if (!node) + return 0; + + int listpos = 0; + while (node && listpos < listMaxSize) + { + FDynamicLight* light = node->lightsource; + if (light && light->Trace()) + { + DVector3 pos = light->Pos; //light->PosRelative(portalgroup); + + LevelMeshLight& meshlight = list[listpos++]; + meshlight.Origin = { (float)pos.X, (float)pos.Y, (float)pos.Z }; + meshlight.RelativeOrigin = meshlight.Origin; + meshlight.Radius = (float)light->GetRadius(); + meshlight.Intensity = (float)light->target->Alpha; + if (light->IsSpot()) + { + meshlight.InnerAngleCos = (float)light->pSpotInnerAngle->Cos(); + meshlight.OuterAngleCos = (float)light->pSpotOuterAngle->Cos(); + + DAngle negPitch = -*light->pPitch; + DAngle Angle = light->target->Angles.Yaw; + double xzLen = negPitch.Cos(); + meshlight.SpotDir.X = float(-Angle.Cos() * xzLen); + meshlight.SpotDir.Y = float(-Angle.Sin() * xzLen); + meshlight.SpotDir.Z = float(-negPitch.Sin()); + } + else + { + meshlight.InnerAngleCos = -1.0f; + meshlight.OuterAngleCos = -1.0f; + meshlight.SpotDir.X = 0.0f; + meshlight.SpotDir.Y = 0.0f; + meshlight.SpotDir.Z = 0.0f; + } + meshlight.Color.X = light->GetRed() * (1.0f / 255.0f); + meshlight.Color.Y = light->GetGreen() * (1.0f / 255.0f); + meshlight.Color.Z = light->GetBlue() * (1.0f / 255.0f); + + if (light->Sector) + meshlight.SectorGroup = static_cast(StaticMesh.get())->sectorGroup[light->Sector->Index()]; + else + meshlight.SectorGroup = 0; + } + + node = node->nextLight; + } + + return listpos; +} + +///////////////////////////////////////////////////////////////////////////// + void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) { MeshVertices.Clear(); @@ -155,6 +286,7 @@ void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) CreateIndexes(); SetupLightmapUvs(doomMap); + BuildTileSurfaceLists(); UpdateCollision(); } @@ -236,26 +368,10 @@ void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap) CreateIndexes(); SetupLightmapUvs(doomMap); + BuildTileSurfaceLists(); UpdateCollision(); } -DoomLevelMesh::DoomLevelMesh(FLevelLocals &doomMap) -{ - SunColor = doomMap.SunColor; // TODO keep only one copy? - SunDirection = doomMap.SunDirection; - - StaticMesh = std::make_unique(); - DynamicMesh = std::make_unique(); - - static_cast(StaticMesh.get())->CreateStatic(doomMap); - static_cast(DynamicMesh.get())->CreateDynamic(doomMap); -} - -void DoomLevelMesh::BeginFrame(FLevelLocals& doomMap) -{ - static_cast(DynamicMesh.get())->UpdateDynamic(doomMap); -} - void DoomLevelSubmesh::BuildSectorGroups(const FLevelLocals& doomMap) { int groupIndex = 0; @@ -415,71 +531,6 @@ void DoomLevelSubmesh::CreatePortals() } } -int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) -{ - const DoomLevelMeshSurface* doomsurf = static_cast(surface); - - FLightNode* node = nullptr; - if (doomsurf->Type == ST_FLOOR || doomsurf->Type == ST_CEILING) - { - node = doomsurf->Subsector->section->lighthead; - } - else if (doomsurf->Type == ST_MIDDLESIDE || doomsurf->Type == ST_UPPERSIDE || doomsurf->Type == ST_LOWERSIDE) - { - node = doomsurf->Side->lighthead; - } - if (!node) - return 0; - - int listpos = 0; - while (node && listpos < listMaxSize) - { - FDynamicLight* light = node->lightsource; - if (light && light->Trace()) - { - DVector3 pos = light->Pos; //light->PosRelative(portalgroup); - - LevelMeshLight& meshlight = list[listpos++]; - meshlight.Origin = { (float)pos.X, (float)pos.Y, (float)pos.Z }; - meshlight.RelativeOrigin = meshlight.Origin; - meshlight.Radius = (float)light->GetRadius(); - meshlight.Intensity = (float)light->target->Alpha; - if (light->IsSpot()) - { - meshlight.InnerAngleCos = (float)light->pSpotInnerAngle->Cos(); - meshlight.OuterAngleCos = (float)light->pSpotOuterAngle->Cos(); - - DAngle negPitch = -*light->pPitch; - DAngle Angle = light->target->Angles.Yaw; - double xzLen = negPitch.Cos(); - meshlight.SpotDir.X = float(-Angle.Cos() * xzLen); - meshlight.SpotDir.Y = float(-Angle.Sin() * xzLen); - meshlight.SpotDir.Z = float(-negPitch.Sin()); - } - else - { - meshlight.InnerAngleCos = -1.0f; - meshlight.OuterAngleCos = -1.0f; - meshlight.SpotDir.X = 0.0f; - meshlight.SpotDir.Y = 0.0f; - meshlight.SpotDir.Z = 0.0f; - } - meshlight.Color.X = light->GetRed() * (1.0f / 255.0f); - meshlight.Color.Y = light->GetGreen() * (1.0f / 255.0f); - meshlight.Color.Z = light->GetBlue() * (1.0f / 255.0f); - - if (light->Sector) - meshlight.SectorGroup = static_cast(StaticMesh.get())->sectorGroup[light->Sector->Index()]; - else - meshlight.SectorGroup = 0; - } - - node = node->nextLight; - } - - return listpos; -} - void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) { // You have no idea how long this took me to figure out... @@ -1262,8 +1313,6 @@ void DoomLevelSubmesh::SetupLightmapUvs(FLevelLocals& doomMap) BuildSurfaceParams(LMTextureSize, LMTextureSize, surface); } - BuildSmoothingGroups(); - CreateSurfaceTextureUVs(doomMap); } @@ -1469,12 +1518,6 @@ void DoomLevelSubmesh::BuildSurfaceParams(int lightMapTextureWidth, int lightMap surface.AtlasTile.Height = height; } -// hw_flats.cpp -VSMatrix GetPlaneTextureRotationMatrix(FGameTexture* gltexture, const sector_t* sector, int plane); - -// hw_walls.cpp -void GetTexCoordInfo(FGameTexture* tex, FTexCoordInfo* tci, side_t* side, int texpos); - void DoomLevelSubmesh::CreateSurfaceTextureUVs(FLevelLocals& doomMap) { auto toUv = [](const DoomLevelMeshSurface* targetSurface, FVector3 vert) { diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index d1e68b235..1a04af9cd 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -7,7 +7,6 @@ #include "r_defs.h" #include "bounds.h" #include - #include typedef dp::rect_pack::RectPacker RectPacker; @@ -27,12 +26,12 @@ enum DoomLevelMeshSurfaceType struct DoomLevelMeshSurface : public LevelMeshSurface { DoomLevelMeshSurfaceType Type = ST_UNKNOWN; - int TypeIndex; + int TypeIndex = 0; subsector_t* Subsector = nullptr; side_t* Side = nullptr; sector_t* ControlSector = nullptr; - float* TexCoords; + float* TexCoords = nullptr; }; class DoomLevelSubmesh : public LevelSubmesh @@ -133,52 +132,14 @@ class DoomLevelMesh : public LevelMesh public: DoomLevelMesh(FLevelLocals &doomMap); - void BeginFrame(FLevelLocals& doomMap); - - bool TraceSky(const FVector3& start, FVector3 direction, float dist) - { - FVector3 end = start + direction * dist; - auto surface = Trace(start, direction, dist); - return surface && surface->bSky; - } - int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) override; - void PackLightmapAtlas() - { - static_cast(StaticMesh.get())->PackLightmapAtlas(); - } - - void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) - { - static_cast(StaticMesh.get())->BindLightmapSurfacesToGeometry(doomMap); - - // Runtime helper - for (auto& surface : static_cast(StaticMesh.get())->Surfaces) - { - if (surface.ControlSector) - { - if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING) - { - XFloorToSurface[surface.Subsector->sector].Push(&surface); - } - else if (surface.Type == ST_MIDDLESIDE) - { - XFloorToSurfaceSides[surface.ControlSector].Push(&surface); - } - } - } - } - - void DisableLightmaps() - { - static_cast(StaticMesh.get())->DisableLightmaps(); - } - - void DumpMesh(const FString& objFilename, const FString& mtlFilename) const - { - static_cast(StaticMesh.get())->DumpMesh(objFilename, mtlFilename); - } + 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; // To do: remove these. Use ffloors on flats and sides to find the 3d surfaces as that is both faster and culls better TMap> XFloorToSurface;