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
+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
# ---------------------------------------------------------------------------