feat: thinner cel outline + procedural model actually holds its weapon

Outline: the inverted-hull width was tuned when the look was heavier and
now reads as a thick marker stroke. Cut every call site to roughly a third
(characters 0.012 -> 0.004, level geometry 0.015 -> 0.005, Neon Alley's
size-scaled clamp 0.02..0.05 -> 0.007..0.018) plus the shader default, so
the ink line stays readable without fattening every silhouette.

Third-person weapon on HumanoidModel: the gun was parented to root_pivot at
a fixed (-0.15, 1.0, 0.4) — floating 40 cm off the chest while both arms
posed at it from a distance. Give the rig a real right-hand node at the end
of the forearm and hang the weapon there, so it travels with the arm. Its
aim is re-derived from the body each frame (hand_r_pivot's global basis is
copied from root_pivot), otherwise the barrel would swing around with the
arm animation. The hold pose is retuned to match: right elbow tucked at the
ribs with a level forearm, left arm crossing to the handguard.

_seat_weapon_in_hand() slides each weapon along its own barrel axis so a
plausible grip lands in the fist regardless of where the artist left the
model origin. It measures with MeshInstance3D.get_aabb(), not
mesh.get_aabb() — the FBX gun parts are skinned, so the Mesh resource still
carries bind-pose bounds tens of metres across.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Nicholas Butzke
2026-07-21 17:32:37 -04:00
co-authored by Claude Opus 4.8
parent 9f60982416
commit af8c9831c9
5 changed files with 78 additions and 31 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ static func spawn_bolt(scene: Node, origin: Vector3, target: Vector3,
core.mesh = core_mesh
core.rotation.x = deg_to_rad(90) # orient capsule along Z
core.position = Vector3(0, 0, -0.55) # tail sits at the origin
core.material_overlay = LevelMaterials.outline(0.012)
core.material_overlay = LevelMaterials.outline(0.004)
tracer.add_child(core)
tracer.position = origin