Skip to content

Commit 56daa0f

Browse files
GWToolbox Botclaude
andcommitted
Danger Rings: share terrain-occlusion setting with in-game rendering
Danger Rings kept its own always-on "Occlude behind terrain" toggle. With occlusion on, the ring mesh is draped tight to the floor (z_lift 5), so the flat triangle chords between its 48 segments dip below the real terrain and fail the scene depth test - dropping arcs that shift as the camera rotates (the reported "incomplete circles depending on camera angle"). Remove the module's own occlude_behind_terrain boolean (and its duplicated z-near/z-far constants) and read the shared "In-game rendering" module's GetOccludeBehindTerrain()/GetDepthZNear()/GetDepthZFar() instead. That setting defaults off, so full circles draw by default, and occlusion is now configured in one place for all in-world overlays. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent f18f89b commit 56daa0f

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

GWToolboxdll/Modules/DangerRingsModule.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
#include <Utils/GameWorldCompositor.h>
1313
#include <Utils/SettingsRegistry.h>
1414
#include <Utils/TerrainDrape.h>
15+
#include <Widgets/Minimap/GameWorldRenderer.h>
1516

1617
namespace {
17-
constexpr float kZNear = 47.0f, kZFar = 100000.f; // must match GW's projection for occlusion to line up
1818
constexpr int kSegments = 48;
1919
constexpr int kMaxBuildsPerFrame = 4; // draping QueryAltitude budget: ~200 queries per ring build
2020

21-
bool occlude_behind_terrain = true;
21+
// Occlusion (whether the rings hide behind terrain, and the depth-projection planes it needs) is shared with
22+
// the "In-game rendering" module via GameWorldRenderer::GetOccludeBehindTerrain()/GetDepthZNear()/GetDepthZFar()
23+
// so it's configured in one place. It defaults off there: a ring draped tight to the floor otherwise self-
24+
// occludes against terrain it dips into between segments, dropping arcs that change with the camera angle.
2225
float render_max_distance = 5000.f;
2326
float fog_factor = 1.0f;
2427
float ring_thickness = 40.f;
@@ -149,7 +152,9 @@ void DangerRingsModule::DrawInWorld(IDirect3DDevice9* device)
149152

150153
IDirect3DStateBlock9* state_block = nullptr;
151154
if (device->CreateStateBlock(D3DSBT_ALL, &state_block) != D3D_OK) return;
152-
if (GameWorldCompositor::SetupPipeline(device, occlude_behind_terrain, kZNear, kZFar, render_max_distance, fog_factor)) {
155+
if (GameWorldCompositor::SetupPipeline(device, GameWorldRenderer::GetOccludeBehindTerrain(),
156+
GameWorldRenderer::GetDepthZNear(), GameWorldRenderer::GetDepthZFar(),
157+
render_max_distance, fog_factor)) {
153158
constexpr BOOL dotted_off[1] = {FALSE};
154159
device->SetPixelShaderConstantB(0, dotted_off, 1);
155160
device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, static_cast<UINT>(scratch.size() / 3), scratch.data(), sizeof(RingVertex));
@@ -160,7 +165,6 @@ void DangerRingsModule::DrawInWorld(IDirect3DDevice9* device)
160165

161166
void DangerRingsModule::RegisterSettings(ToolboxModule* module)
162167
{
163-
SettingsRegistry::RegisterField(module, "occlude_behind_terrain", &occlude_behind_terrain);
164168
SettingsRegistry::RegisterField(module, "render_max_distance", &render_max_distance);
165169
SettingsRegistry::RegisterField(module, "fog_factor", &fog_factor);
166170
SettingsRegistry::RegisterField(module, "ring_thickness", &ring_thickness);
@@ -199,7 +203,7 @@ void DangerRingsModule::DrawSettingsInternal()
199203
if (!GameWorldCompositor::IsActive())
200204
ImGui::TextColored(red, GameWorldCompositor::HasFailed() ? "In-world compositor FAILED to install." : "In-world compositor: not installed yet.");
201205

202-
if (ImGui::Checkbox("Occlude behind terrain", &occlude_behind_terrain)) meshes_dirty = true;
206+
ImGui::TextDisabled("Occlusion behind terrain follows the \"In-game rendering\" module's setting.");
203207
ImGui::DragFloat("Maximum render distance", &render_max_distance, 5.f, 10.f, 100000.f, "%.0f", ImGuiSliderFlags_AlwaysClamp);
204208
if (ImGui::DragFloat("Ring thickness", &ring_thickness, 1.f, 5.f, 500.f, "%.0f", ImGuiSliderFlags_AlwaysClamp)) meshes_dirty = true;
205209
if (ImGui::DragFloat("Rim opacity", &rim_opacity, 0.01f, 0.f, 1.f, "%.2f", ImGuiSliderFlags_AlwaysClamp)) meshes_dirty = true;

GWToolboxdll/Widgets/Minimap/GameWorldRenderer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,9 @@ void GameWorldRenderer::ClearNavmeshLines()
724724
const std::vector<GameWorldRenderer::BatchedLine>& GameWorldRenderer::GetNavmeshWorldMapLines() { return navmesh_worldmap_lines; }
725725
GW::Constants::MapID GameWorldRenderer::GetNavmeshWorldMapMapId() { return navmesh_worldmap_map; }
726726
float GameWorldRenderer::GetRenderMaxDistance() { return render_max_distance; }
727+
bool GameWorldRenderer::GetOccludeBehindTerrain() { return occlude_behind_terrain; }
728+
float GameWorldRenderer::GetDepthZNear() { return z_near; }
729+
float GameWorldRenderer::GetDepthZFar() { return z_far; }
727730

728731
void GameWorldRenderer::Terminate()
729732
{

GWToolboxdll/Widgets/Minimap/GameWorldRenderer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ class GameWorldRenderer : public ToolboxModule {
118118
// Max in-world render distance (game units) — the shared "Maximum render distance" for terrain overlays.
119119
static float GetRenderMaxDistance();
120120

121+
// Shared "Occlude behind terrain" configuration, so other in-world overlays (e.g. Danger Rings) test
122+
// against the scene depth buffer identically and occlusion is controlled from one place (these settings).
123+
static bool GetOccludeBehindTerrain();
124+
static float GetDepthZNear();
125+
static float GetDepthZFar();
126+
121127
private:
122128
static void RegisterSettings(ToolboxModule* module);
123129
static void OnSettingsLoaded();

0 commit comments

Comments
 (0)