Move hand gear forward into the palm
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-02 19:33:42 +01:00
1 parent 7150bd7673
commit 58cf12fd1d
9 files changed
+45 -15

No files matched your search

+7
View File
@@ -179,6 +179,11 @@ const GEAR_OFFSETS := {
"lanyard": Vector3(0, 0, 0.04),
"firefighter_helmet": Vector3(0, 0.03, 0),
}
## Hand gear is authored around the wrist proxy. The palm sits ~4 cm in front
## of that origin, so without this offset the first phone/flashlight versions
## were partly buried inside the hand. Keep the grip axis and move the whole
## item forward into the open palm.
const HAND_ITEM_FORWARD := Vector3(0, 0, 0.04)
const GEAR_ATTACH := {
"cap": "head", "beanie": "head", "hood": "head", "sunglasses": "head",
"firefighter_helmet": "head",
@@ -746,6 +751,8 @@ func _attach_gear(gear_name: String) -> bool:
return false
if GEAR_OFFSETS.has(gear_name):
node.position += GEAR_OFFSETS[gear_name]
if str(GEAR_ATTACH[gear_name]) == "hand":
node.position += HAND_ITEM_FORWARD
_detail_nodes.append(node)
var ao := Materials.load_ao(BLENDER_GEAR_DIR + gear_name + "_ao.png")
for child in node.find_children("*", "MeshInstance3D", true, false):
+7 -1
View File
@@ -203,6 +203,9 @@ func test_library_gear_attaches_to_the_contract_points() -> bool:
var b := TestUtils.check(camera != null and camera.get_parent() is Node3D
and camera.get_parent().name == "Hand",
"hand gear attaches under the hand proxy")
var f := TestUtils.check(camera != null
and camera.position.z >= NpcAvatar.HAND_ITEM_FORWARD.z - 0.001,
"hand gear sits forward of the wrist proxy instead of inside the palm")
tourist.free()
var responder := _avatar(Rules.NpcType.RESPONDER, 12)
var helmet := responder.find_child("Gear_firefighter_helmet", true, false) as Node3D
@@ -213,10 +216,13 @@ func test_library_gear_attaches_to_the_contract_points() -> bool:
"firefighter helmet attaches to Rig/Head")
var d := TestUtils.check(tank != null and flashlight != null,
"responder gets SCBA tank and flashlight")
var g := TestUtils.check(flashlight != null
and flashlight.position.z >= NpcAvatar.HAND_ITEM_FORWARD.z - 0.001,
"flashlight uses the same forward grip offset")
var e2 := TestUtils.check(helmet != null and helmet.position.y > 0.02,
"the firefighter helmet clears the brow")
responder.free()
return a and b and c and d and e and e2
return a and b and c and d and e and e2 and f and g
## Horizontal bounds of a gear GLB in its attach-node space. The head/back
## contract is measured against the Blender fit report (head width 0.315 m,