feat(ui): debug overlay + refined input controls

Adds the first on-screen HUD for the dev client plus today's mouse-control
refinements. Also lands yesterday's scenery-alignment changes that were
left uncommitted in the working tree.

Overlay:
- BitmapFont rasterizes a system TTF via StbTrueTypeSharp into a 512x512
  R8 atlas at startup (Consolas on Windows, DejaVu/Menlo fallbacks)
- TextRenderer batches 2D quads in screen-space with ortho projection;
  one shader + two draw calls (rect then text) for panel backgrounds
  under glyphs
- DebugOverlay composes info / stats / compass / help panels on top of
  the 3D scene; toggles via F1/F4/F5/F6; transient toasts for key events
- DebugLineRenderer and its shaders (carried over from the scenery work)
  are properly committed in this commit

Controls:
- Per-mode mouse sensitivity (Chase 0.15, Fly 1.0, Orbit 1.0); F8/F9 to
  adjust the active mode multiplicatively (x1.2)
- Hold RMB to free-orbit the chase camera around the player; release
  stays at the new angle (no snap-back)
- Mouse-wheel zooms chase distance between 2m and 40m
- Chase pitch widened to [-0.7, 1.4] so mouse-Y tilts both ways from
  the default neutral angle

Scenery alignment (carried from yesterday's session):
- ShadowObjectRegistry AllEntriesForDebug + Scale field
- SceneryGenerator uses ACViewer's OnRoad polygon test + baseLoc +
  set_heading rotation
- BSPQuery dispatchers accept localToWorld so normals/offsets transform
  correctly per part
- TransitionTypes.CylinderCollision rewritten with wall-slide + push-out
- PhysicsDataCache caches visual-mesh AABB for scenery that lacks
  physics Setup bounds
This commit is contained in:
Erik 2026-04-17 18:45:38 +02:00
parent 6b4e7569a3
commit ff325abd7b
20 changed files with 2734 additions and 268 deletions

View file

@ -0,0 +1,7 @@
#version 430 core
in vec3 vColor;
out vec4 FragColor;
void main() {
FragColor = vec4(vColor, 1.0);
}

View file

@ -0,0 +1,13 @@
#version 430 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
uniform mat4 uView;
uniform mat4 uProjection;
out vec3 vColor;
void main() {
vColor = aColor;
gl_Position = uProjection * uView * vec4(aPos, 1.0);
}

View file

@ -0,0 +1,18 @@
#version 430 core
in vec2 vUv;
in vec4 vColor;
out vec4 FragColor;
uniform sampler2D uTex;
uniform int uUseTexture;
void main() {
if (uUseTexture != 0) {
// Font atlas is a single-channel R8 texture; red = coverage alpha.
float coverage = texture(uTex, vUv).r;
FragColor = vec4(vColor.rgb, vColor.a * coverage);
} else {
FragColor = vColor;
}
if (FragColor.a < 0.005) discard;
}

View file

@ -0,0 +1,19 @@
#version 430 core
layout(location = 0) in vec2 aPos; // screen pixels, origin top-left
layout(location = 1) in vec2 aUv;
layout(location = 2) in vec4 aColor;
uniform vec2 uScreenSize;
out vec2 vUv;
out vec4 vColor;
void main() {
// Convert pixel coords (origin top-left, +Y down) to NDC (origin center, +Y up).
vec2 ndc = vec2(
aPos.x / uScreenSize.x * 2.0 - 1.0,
1.0 - aPos.y / uScreenSize.y * 2.0);
gl_Position = vec4(ndc, 0.0, 1.0);
vUv = aUv;
vColor = aColor;
}