feat(client): 3D locomotion sandbox — character walks the live Gauntlet (T-1088)
New SR_LIVE sandbox scene: CharacterVisual composited in a 3D greybox world derived from server snapshots. Per-leg constant-velocity interpolation keyed to the stance throttle, 'server feet / client eyes' facing (wire octant while moving, client aim octant idle), cadence-synced gait state machine on AnimationPlayer custom blends, D-148 orthographic follow camera (-30deg default, T-cycle presets), sim-space grid shader, camera-side wall cutaway, accumulating never-evict tile store with four-state visibility tint. Additive seams only: InputMapper.facing_angle_provider (2D path unchanged), CharacterVisual.play_animation blend_time param + get_animation_player(). Visual harness gains per-scenario scene field + SR_AUTOPILOT input scripting. 210 new gdUnit assertions across five suites; verified live (230/230 total, clean smoke, screenshot at .cache/screenshots/locomotion_idle_live.png). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
shader_type spatial;
|
||||
render_mode diffuse_lambert, specular_disabled;
|
||||
|
||||
// T-1088 greybox floor (design §3.3) — sandbox-only.
|
||||
//
|
||||
// Per-instance visibility tint x world-space grid lines. The MultiMesh instance
|
||||
// color (use_colors, GreyboxWorld) arrives as the COLOR built-in and multiplies
|
||||
// albedo: white = Forward, 85% = Peripheral, 70% = BoundaryWall, dim cool grey =
|
||||
// Remembered (SandboxConstants.TINTS — §3.2).
|
||||
//
|
||||
// Grid: data is per-0.5 m subtile (D-066/D-222) but the floor must READ as 1 m
|
||||
// visual tiles (2x2 subtiles) — minor lines every 0.5 m (alpha 0.15), major
|
||||
// lines every 1.0 m (alpha 0.45). Lines are sampled in SIM space (u_sim_from_world
|
||||
// undoes the 45 deg WorldRoot rotation) so they land on tile edges; sampling raw
|
||||
// world space would draw the grid rotated 45 deg against the tiles. Continuous
|
||||
// across instances because sim space is shared. D-243's "voxel = 1 m" is
|
||||
// generation-cascade vocabulary — the 1 m visual tile exists ONLY as the major
|
||||
// lines here (§2).
|
||||
|
||||
uniform vec3 u_base_albedo : source_color = vec3(0.52, 0.54, 0.58);
|
||||
uniform vec3 u_line_albedo : source_color = vec3(0.10, 0.11, 0.14);
|
||||
uniform float u_minor_spacing_m = 0.5;
|
||||
uniform float u_major_spacing_m = 1.0;
|
||||
uniform float u_minor_alpha = 0.15;
|
||||
uniform float u_major_alpha = 0.45;
|
||||
uniform float u_line_half_width_m = 0.02;
|
||||
// World -> sim-space transform; set by GreyboxWorld from its own inverse global
|
||||
// transform so the grid rotates WITH the tiles under the WorldRoot 45 deg.
|
||||
uniform mat4 u_sim_from_world = mat4(1.0);
|
||||
|
||||
varying vec2 v_world_xz;
|
||||
|
||||
void vertex() {
|
||||
// MODEL_MATRIX folds in the per-instance MultiMesh transform (incl. WorldRoot
|
||||
// rotation); u_sim_from_world undoes the scene rotation back to sim axes.
|
||||
v_world_xz = (u_sim_from_world * MODEL_MATRIX * vec4(VERTEX, 1.0)).xz;
|
||||
}
|
||||
|
||||
// 1.0 on a grid line of the given spacing, 0.0 off it, one-fwidth AA edge.
|
||||
float line_mask(vec2 p, float spacing, float half_width) {
|
||||
vec2 dxy = abs(fract(p / spacing + 0.5) - 0.5) * spacing; // metres to nearest line
|
||||
float d = min(dxy.x, dxy.y);
|
||||
float aa = fwidth(d);
|
||||
return 1.0 - smoothstep(half_width - aa, half_width + aa, d);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
float minor = line_mask(v_world_xz, u_minor_spacing_m, u_line_half_width_m) * u_minor_alpha;
|
||||
float major = line_mask(v_world_xz, u_major_spacing_m, u_line_half_width_m) * u_major_alpha;
|
||||
float line_a = max(minor, major); // major wins where the grids coincide
|
||||
vec3 tinted = u_base_albedo * COLOR.rgb;
|
||||
// Line color is tinted too, so remembered/peripheral tiles keep dim lines.
|
||||
ALBEDO = mix(tinted, u_line_albedo * COLOR.rgb, line_a);
|
||||
ROUGHNESS = 1.0;
|
||||
}
|
||||
Reference in New Issue
Block a user