fix: Scale and fit clothing attachments over body limbs to eliminate clipping
checkpoint / checkpoint (push) Successful in 6m11s

This commit is contained in:
2026-09-20 20:51:05 +00:00
parent 84b98e9b3a
commit a7de464e1f
12 changed files with 274 additions and 11 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+274 -11
View File
@@ -91,18 +91,7 @@ const ATTACHMENTS := {
"hair_mohawk_01": ["mohawk", Vector3(0, 0.10, 0.0), Color(0.90, 0.20, 0.35)],
"hair_ponytail_01": ["ponytail", Vector3(0, -0.22, 0.24), Color(0.45, 0.30, 0.15)],
"face_glasses_01": ["glasses", Vector3(0, 0.12, -0.07), Color(0.10, 0.10, 0.12)],
"chest_bandit_01": ["torso", Vector3(0, -0.12, 0.0), Color(0.55, 0.20, 0.20)],
"back_backpack_01": ["box", Vector3(0, -0.06, 0.28), Color(0.30, 0.35, 0.25)],
"pants_cargo_01": ["hips", Vector3(0, -0.04, 0.0), Color(0.30, 0.35, 0.45)],
"left_hand_glove_01": ["blob", Vector3(0, 0.0, 0.0), Color(0.15, 0.15, 0.18)],
"right_hand_glove_01": ["blob", Vector3(0, 0.0, 0.0), Color(0.15, 0.15, 0.18)],
"left_hand_wristband_01": ["band", Vector3(0, 0.02, 0.0), Color(0.95, 0.80, 0.15)],
"right_hand_wristband_01": ["band", Vector3(0, 0.02, 0.0), Color(0.95, 0.80, 0.15)],
"left_foot_boot_01": ["boot", Vector3(0, -0.02, -0.05), Color(0.12, 0.10, 0.09)],
"right_foot_boot_01": ["boot", Vector3(0, -0.02, -0.05), Color(0.12, 0.10, 0.09)],
"left_foot_sneaker_01": ["sneaker", Vector3(0, -0.02, -0.05), Color(0.85, 0.25, 0.25)],
"right_foot_sneaker_01": ["sneaker", Vector3(0, -0.02, -0.05), Color(0.85, 0.25, 0.25)],
"accessory_belt_01": ["belt", Vector3(0, 0.74, 0.0), Color(0.20, 0.18, 0.12)],
"accessory_necklace_01": ["necklace", Vector3(0, 1.34, -0.10), Color(0.85, 0.75, 0.20)],
}
@@ -118,6 +107,17 @@ func _initialize() -> void:
var spec: Array = ATTACHMENTS[id]
_gen_attachment(id, spec[0], spec[1], spec[2])
_gen_chest_bandit()
_gen_pants_cargo()
_gen_glove("left_hand_glove_01", 1.0)
_gen_glove("right_hand_glove_01", -1.0)
_gen_wristband("left_hand_wristband_01", 1.0)
_gen_wristband("right_hand_wristband_01", -1.0)
_gen_boot("left_foot_boot_01", 1.0)
_gen_boot("right_foot_boot_01", -1.0)
_gen_sneaker("left_foot_sneaker_01", 1.0)
_gen_sneaker("right_foot_sneaker_01", -1.0)
_gen_belt()
_gen_water_buffalo_hat()
print("\n%s" % ("DONE — all placeholder avatar GLBs written" if _fail == 0
@@ -402,6 +402,269 @@ func _gen_water_buffalo_hat() -> void:
root.free()
func _gen_chest_bandit() -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
# Main vest/shirt covering torso (torso is 0.90 x 0.80 x 0.46)
var vest := MeshInstance3D.new()
vest.name = "Vest"
var vest_mesh := BoxMesh.new()
vest_mesh.size = Vector3(0.94, 0.82, 0.50)
vest.mesh = vest_mesh
vest.position = Vector3(0.0, -0.16, 0.0) # Relative to Chest bone (Y=1.30, torso center Y=1.14)
var vest_mat := StandardMaterial3D.new()
vest_mat.albedo_color = Color(0.55, 0.20, 0.20) # Bandit crimson
vest_mat.roughness = 0.85
vest.material_override = vest_mat
root.add_child(vest)
# Collar trim at top
var collar := MeshInstance3D.new()
collar.name = "Collar"
var collar_mesh := BoxMesh.new()
collar_mesh.size = Vector3(0.96, 0.12, 0.52)
collar.mesh = collar_mesh
collar.position = Vector3(0.0, 0.20, 0.0)
var trim_mat := StandardMaterial3D.new()
trim_mat.albedo_color = Color(0.22, 0.16, 0.12) # Dark leather trim
trim_mat.roughness = 0.8
collar.material_override = trim_mat
root.add_child(collar)
# Bottom hem trim
var hem := MeshInstance3D.new()
hem.name = "Hem"
var hem_mesh := BoxMesh.new()
hem_mesh.size = Vector3(0.96, 0.08, 0.52)
hem.mesh = hem_mesh
hem.position = Vector3(0.0, -0.53, 0.0)
hem.material_override = trim_mat
root.add_child(hem)
_write_glb(root, "chest_bandit_01")
root.free()
func _gen_pants_cargo() -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
var pants_mat := StandardMaterial3D.new()
pants_mat.albedo_color = Color(0.28, 0.34, 0.44) # Cargo slate blue
pants_mat.roughness = 0.9
var pocket_mat := StandardMaterial3D.new()
pocket_mat.albedo_color = Color(0.20, 0.24, 0.32) # Dark pocket trim
pocket_mat.roughness = 0.9
# 1. Waist section (covering hips across both legs)
var waist := MeshInstance3D.new()
waist.name = "Waist"
var waist_mesh := BoxMesh.new()
waist_mesh.size = Vector3(0.86, 0.20, 0.50)
waist.mesh = waist_mesh
waist.position = Vector3(0.0, -0.06, 0.0) # Relative to Hips bone (Y=0.76)
waist.material_override = pants_mat
root.add_child(waist)
# 2. Left and Right Pant Legs (legs are 0.40 wide, 0.78 tall, 0.46 deep, centers X = +-0.21)
for side in [-1.0, 1.0]:
var sname := "Right" if side < 0.0 else "Left"
var leg := MeshInstance3D.new()
leg.name = "PantLeg_%s" % sname
var leg_mesh := BoxMesh.new()
leg_mesh.size = Vector3(0.44, 0.64, 0.50) # Covers down to ankle
leg.mesh = leg_mesh
leg.position = Vector3(side * 0.21, -0.34, 0.0)
leg.material_override = pants_mat
root.add_child(leg)
# Cargo pocket on outer side
var pocket := MeshInstance3D.new()
pocket.name = "Pocket_%s" % sname
var pocket_mesh := BoxMesh.new()
pocket_mesh.size = Vector3(0.08, 0.20, 0.24)
pocket.mesh = pocket_mesh
pocket.position = Vector3(side * 0.44, -0.32, 0.0)
pocket.material_override = pocket_mat
root.add_child(pocket)
_write_glb(root, "pants_cargo_01")
root.free()
func _gen_glove(id: String, side: float) -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
# Arm is width 0.34, depth 0.46. Bone X is at side * 0.60, arm center is at side * 0.57.
var x_off := -0.03 * side
var glove := MeshInstance3D.new()
glove.name = "GloveBody"
var glove_mesh := BoxMesh.new()
glove_mesh.size = Vector3(0.38, 0.28, 0.50)
glove.mesh = glove_mesh
glove.position = Vector3(x_off, -0.06, 0.0)
var glove_mat := StandardMaterial3D.new()
glove_mat.albedo_color = Color(0.15, 0.15, 0.18)
glove_mat.roughness = 0.85
glove.material_override = glove_mat
root.add_child(glove)
# Glove cuff at top
var cuff := MeshInstance3D.new()
cuff.name = "GloveCuff"
var cuff_mesh := BoxMesh.new()
cuff_mesh.size = Vector3(0.40, 0.06, 0.52)
cuff.mesh = cuff_mesh
cuff.position = Vector3(x_off, 0.08, 0.0)
var cuff_mat := StandardMaterial3D.new()
cuff_mat.albedo_color = Color(0.25, 0.24, 0.28)
cuff_mat.roughness = 0.7
cuff.material_override = cuff_mat
root.add_child(cuff)
_write_glb(root, id)
root.free()
func _gen_wristband(id: String, side: float) -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
var x_off := -0.03 * side
var band := MeshInstance3D.new()
band.name = "Wristband"
var band_mesh := BoxMesh.new()
band_mesh.size = Vector3(0.38, 0.12, 0.50)
band.mesh = band_mesh
band.position = Vector3(x_off, 0.02, 0.0)
var band_mat := StandardMaterial3D.new()
band_mat.albedo_color = Color(0.96, 0.82, 0.18)
band_mat.metallic = 0.8
band_mat.roughness = 0.25
band.material_override = band_mat
root.add_child(band)
_write_glb(root, id)
root.free()
func _gen_boot(id: String, side: float) -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
# Boot Upper (encases lower leg and extends forward to toe)
var boot := MeshInstance3D.new()
boot.name = "BootUpper"
var boot_mesh := BoxMesh.new()
boot_mesh.size = Vector3(0.44, 0.22, 0.58)
boot.mesh = boot_mesh
boot.position = Vector3(0.0, 0.06, 0.02)
var boot_mat := StandardMaterial3D.new()
boot_mat.albedo_color = Color(0.14, 0.11, 0.10) # Dark boot leather
boot_mat.roughness = 0.8
boot.material_override = boot_mat
root.add_child(boot)
# Boot Sole
var sole := MeshInstance3D.new()
sole.name = "BootSole"
var sole_mesh := BoxMesh.new()
sole_mesh.size = Vector3(0.46, 0.06, 0.60)
sole.mesh = sole_mesh
sole.position = Vector3(0.0, -0.03, 0.02)
var sole_mat := StandardMaterial3D.new()
sole_mat.albedo_color = Color(0.07, 0.07, 0.08) # Black rubber tread
sole_mat.roughness = 0.95
sole.material_override = sole_mat
root.add_child(sole)
_write_glb(root, id)
root.free()
func _gen_sneaker(id: String, side: float) -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
var sneaker_mat := StandardMaterial3D.new()
sneaker_mat.albedo_color = Color(0.85, 0.25, 0.25) # Sneaker red
sneaker_mat.roughness = 0.8
var white_mat := StandardMaterial3D.new()
white_mat.albedo_color = Color(0.92, 0.92, 0.92) # White rubber
white_mat.roughness = 0.85
# Sneaker Upper
var upper := MeshInstance3D.new()
upper.name = "SneakerUpper"
var upper_mesh := BoxMesh.new()
upper_mesh.size = Vector3(0.44, 0.18, 0.58)
upper.mesh = upper_mesh
upper.position = Vector3(0.0, 0.04, 0.02)
upper.material_override = sneaker_mat
root.add_child(upper)
# White Rubber Sole
var sole := MeshInstance3D.new()
sole.name = "SneakerSole"
var sole_mesh := BoxMesh.new()
sole_mesh.size = Vector3(0.46, 0.06, 0.60)
sole.mesh = sole_mesh
sole.position = Vector3(0.0, -0.03, 0.02)
sole.material_override = white_mat
root.add_child(sole)
# White Rubber Toe Cap
var toe := MeshInstance3D.new()
toe.name = "ToeCap"
var toe_mesh := BoxMesh.new()
toe_mesh.size = Vector3(0.44, 0.08, 0.14)
toe.mesh = toe_mesh
toe.position = Vector3(0.0, 0.01, -0.21)
toe.material_override = white_mat
root.add_child(toe)
_write_glb(root, id)
root.free()
func _gen_belt() -> void:
var root := Node3D.new()
root.name = "AttachmentRoot"
var belt := MeshInstance3D.new()
belt.name = "BeltStrap"
var belt_mesh := BoxMesh.new()
belt_mesh.size = Vector3(0.94, 0.10, 0.50)
belt.mesh = belt_mesh
belt.position = Vector3(0.0, 0.74, 0.0)
var belt_mat := StandardMaterial3D.new()
belt_mat.albedo_color = Color(0.20, 0.16, 0.12)
belt_mat.roughness = 0.8
belt.material_override = belt_mat
root.add_child(belt)
var buckle := MeshInstance3D.new()
buckle.name = "BeltBuckle"
var buckle_mesh := BoxMesh.new()
buckle_mesh.size = Vector3(0.14, 0.12, 0.04)
buckle.mesh = buckle_mesh
buckle.position = Vector3(0.0, 0.74, -0.26)
var buckle_mat := StandardMaterial3D.new()
buckle_mat.albedo_color = Color(0.96, 0.82, 0.18)
buckle_mat.metallic = 0.8
buckle_mat.roughness = 0.25
buckle.material_override = buckle_mat
root.add_child(buckle)
_write_glb(root, "accessory_belt_01")
root.free()
# ---------------------------------------------------------------------------
# GLB export
# ---------------------------------------------------------------------------