From 759320b189fe97796baa66c294ca400797f8d94f Mon Sep 17 00:00:00 2001 From: RaveYard <29225776+MrRaveYard@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:30:57 +0200 Subject: [PATCH] CPU tracelight portal fix --- .../rendering/hwrenderer/data/hw_levelmesh.h | 46 +++++++++++++++++-- src/rendering/hwrenderer/doom_levelmesh.h | 8 +--- .../hwrenderer/scene/hw_spritelight.cpp | 2 +- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index 9a3648c63..bd9b7555c 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -199,10 +199,50 @@ public: FVector3 SunColor = FVector3(0.0f, 0.0f, 0.0f); uint16_t LightmapSampleDistance = 16; - bool Trace(const FVector3& start, FVector3 direction, float maxDist) + LevelMeshSurface* Trace(const FVector3& start, FVector3 direction, float maxDist) { - FVector3 end = start + direction * std::max(maxDist - 10.0f, 0.0f); - return !TriangleMeshShape::find_any_hit(Collision.get(), start, end); + maxDist = std::max(maxDist - 10.0f, 0.0f); + + FVector3 origin = start; + FVector3 end; + + auto collision = Collision.get(); + + LevelMeshSurface* hitSurface = nullptr; + + while (true) + { + end = origin + direction * maxDist; + + auto hit = TriangleMeshShape::find_first_hit(collision, origin, end); + + if (hit.triangle < 0) + { + return nullptr; + } + + hitSurface = GetSurface(MeshSurfaceIndexes[hit.triangle]); + auto portal = hitSurface->portalIndex; + + if (!portal) + { + break; + } + + auto& transformation = 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 } void BuildSmoothingGroups() diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index 8205337e2..603a0f240 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -31,12 +31,8 @@ public: bool TraceSky(const FVector3& start, FVector3 direction, float dist) { FVector3 end = start + direction * dist; - TraceHit hit = TriangleMeshShape::find_first_hit(Collision.get(), start, end); - if (hit.fraction == 1.0f) - return true; - - int surfaceIndex = MeshSurfaceIndexes[hit.triangle]; - return Surfaces[surfaceIndex].bSky; + auto surface = Trace(start, direction, dist); + return surface && surface->bSky; } void UpdateLightLists() override; diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index c1cfd306f..dc2f3a3b3 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -74,7 +74,7 @@ public: } else { - bool traceResult = level.levelMesh->Trace(FVector3((float)light->Pos.X, (float)light->Pos.Y, (float)light->Pos.Z), FVector3(-L.X, -L.Y, -L.Z), dist); + bool traceResult = !level.levelMesh->Trace(FVector3((float)light->Pos.X, (float)light->Pos.Y, (float)light->Pos.Z), FVector3(-L.X, -L.Y, -L.Z), dist); Actor->StaticLightsTraceCache.Bits |= ((uint64_t)traceResult) << CurrentBit; CurrentBit++; return traceResult;