Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69f4f11633 | ||
|
|
d1fa25629e | ||
|
|
359bb9a8c7 | ||
|
|
36576a023a | ||
|
|
c1ccfd6e72 | ||
|
|
27b8f9a249 | ||
|
|
d5a2c911a6 |
No files matched your search
@@ -4,6 +4,16 @@ All notable user-facing changes to Gig Line. The format follows
|
|||||||
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions use
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions use
|
||||||
Semantic Versioning.
|
Semantic Versioning.
|
||||||
|
|
||||||
|
## [0.9.8] — 2026-11-04
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Characters no longer detach at the wrist: the wrist and hand now track the same
|
||||||
|
bone, the hand was raised to meet the forearm, and the sleeve cuff follows the
|
||||||
|
hand instead of the elbow.
|
||||||
|
- Seated and walking poses no longer collapse the hip/thigh or pinch the knee:
|
||||||
|
the thigh and shin are rigid to their bones with a short blend at the knee.
|
||||||
|
|
||||||
## [0.9.7] — 2026-11-04
|
## [0.9.7] — 2026-11-04
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -71,8 +71,14 @@ an active track; ADR-0015 (CC0 / CC-BY with attribution) still governs every int
|
|||||||
Vision-reviewed: arms hang down and the silhouette + slot regions read, but the 1.63× arm warp
|
Vision-reviewed: arms hang down and the silhouette + slot regions read, but the 1.63× arm warp
|
||||||
distorts the deltoid/shoulder (spiky/warped), the decimated hands are blocky, and the slot
|
distorts the deltoid/shoulder (spiky/warped), the decimated hands are blocky, and the slot
|
||||||
boundaries are rough — these are the refinement steps below.
|
boundaries are rough — these are the refinement steps below.
|
||||||
- [ ] Re-run `inspect`/`audit`/`fit`/proportions and the 24-NPC budget after each intake; keep the
|
- [x] Head/hands/feet swap (`makehuman_final.py`): cut the decimated MakeHuman head/hands/feet and
|
||||||
procedural generator as the fallback until a MakeHuman variant ships.
|
joined the project's `_face`/`_hair`/`_hands_and_shoes`, then re-weighted/re-UV'd. Contract
|
||||||
|
passes: 6,407 / 8,000 tris, 6,651 / 8,000 verts, 14 bones, skinned, five slots, no issues.
|
||||||
|
Vision-reviewed: the head now reads as a realistic face, the hands as detailed fingers and
|
||||||
|
the shoes as attached. Remaining (manual retopology): a 1.63× arm-scale warp still distorts
|
||||||
|
the deltoid/shoulder, stray hand blobs linger at the hips, shirt/shirt seams are rough, and
|
||||||
|
the head-neck junction has a shadow gap. The procedural generator stays the shipped fallback
|
||||||
|
until these are cleaned in an editor session.
|
||||||
|
|
||||||
## 3D model and local map re-evaluation
|
## 3D model and local map re-evaluation
|
||||||
|
|
||||||
@@ -195,8 +201,11 @@ licence-free zone only.
|
|||||||
the open palm + forward offset; a finger-curl rig stays out of scope** — there are no finger
|
the open palm + forward offset; a finger-curl rig stays out of scope** — there are no finger
|
||||||
bones in the 13-bone contract, so a curl rig is a contract decision, not a modelling tidy-up.
|
bones in the 13-bone contract, so a curl rig is a contract decision, not a modelling tidy-up.
|
||||||
Recorded as ranked gap #6 (accept; revisit only if face work opens the budget).
|
Recorded as ranked gap #6 (accept; revisit only if face work opens the budget).
|
||||||
- [ ] Weights/pose: captured after the pose harness is fixed (see the top-level
|
- [x] Weights/pose evidence captured and vision-reviewed, and the P1s fixed: wrist/hand
|
||||||
**Fix the Rig pose harness** track); shoulder/hip/neck collapse remains unmeasured until then.
|
detachment (wrist + hand now 100% `Hand`, hand raised, sleeve cuff follows the hand),
|
||||||
|
hip/thigh collapse + knee pinch (thigh/shin rigid with a short knee blend). Vision-verified:
|
||||||
|
hip fix clean, knee crease minor residual. The guard hip-pouch clip and the residual knee
|
||||||
|
crease remain as 0.10.0 refinements.
|
||||||
- [x] UV/texel density: measured (64–122 px/m authored, 287–440 px/m effective fabric on the 4×
|
- [x] UV/texel density: measured (64–122 px/m authored, 287–440 px/m effective fabric on the 4×
|
||||||
repeat; table in `docs/3d-model-review.md`). Decision: **accept as-is** — the maps are
|
repeat; table in `docs/3d-model-review.md`). Decision: **accept as-is** — the maps are
|
||||||
neutral/runtime-tinted (not painted skin), so density controls only subtle weave/noise, and
|
neutral/runtime-tinted (not painted skin), so density controls only subtle weave/noise, and
|
||||||
@@ -879,12 +888,14 @@ variants, the four crowd-variety characters and the per-role pools — as a **pa
|
|||||||
- [x] Rig pose harness fixed and the weights/pose evidence captured (see the top track).
|
- [x] Rig pose harness fixed and the weights/pose evidence captured (see the top track).
|
||||||
- [x] Character work done: 12-character library, realistic face, crowd variants, per-role pools,
|
- [x] Character work done: 12-character library, realistic face, crowd variants, per-role pools,
|
||||||
24-NPC budget 6.94 ms (152,464 tris / 168 meshes).
|
24-NPC budget 6.94 ms (152,464 tris / 168 meshes).
|
||||||
- [ ] Run the full QA matrix and a local release build for 0.9.7; bump `config/version`, write the
|
- [x] QA + local build for 0.9.7: Godot 277/277, Python 161/161, audit 49 OK, fit/proportions
|
||||||
`CHANGELOG.md` entry, tag and publish per the Release Procedure.
|
12/12, release smoke matrix green, gallery 21/0, clean worktree build (Linux 172 MB,
|
||||||
|
Windows 206 MB, macOS 159 MB, Web 111 MB, HQ 266 MB), checksums verified, Linux binary
|
||||||
|
launches headless. Tagged `v0.9.7` (CI build/publish follows).
|
||||||
|
|
||||||
**Exit:** a 0.9.7 patch ships the 12-character library (face realism + crowd variety) with the
|
**Exit:** met — 0.9.7 ships the 12-character library (face realism + crowd variety) with the pose
|
||||||
pose harness fixed; the runtime contract is unchanged. The MakeHuman body and the map rebuild are
|
harness fixed; the runtime contract is unchanged. The MakeHuman body and the map rebuild are not
|
||||||
not in this patch.
|
in this patch (they target 0.10.0).
|
||||||
|
|
||||||
## Roadmap dependencies and risks
|
## Roadmap dependencies and risks
|
||||||
|
|
||||||
|
|||||||
@@ -466,8 +466,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5038,
|
"triangles": 5034,
|
||||||
"vertices": 4756
|
"vertices": 4607
|
||||||
},
|
},
|
||||||
"npc_coat": {
|
"npc_coat": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -507,8 +507,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 6030,
|
"triangles": 6046,
|
||||||
"vertices": 5802
|
"vertices": 5645
|
||||||
},
|
},
|
||||||
"npc_crowd_a": {
|
"npc_crowd_a": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -547,8 +547,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5200,
|
"triangles": 5284,
|
||||||
"vertices": 4734
|
"vertices": 4908
|
||||||
},
|
},
|
||||||
"npc_crowd_b": {
|
"npc_crowd_b": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -587,8 +587,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 4734,
|
"triangles": 4812,
|
||||||
"vertices": 4353
|
"vertices": 4550
|
||||||
},
|
},
|
||||||
"npc_crowd_c": {
|
"npc_crowd_c": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -627,8 +627,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5674,
|
"triangles": 5690,
|
||||||
"vertices": 5440
|
"vertices": 5510
|
||||||
},
|
},
|
||||||
"npc_crowd_d": {
|
"npc_crowd_d": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -667,8 +667,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5814,
|
"triangles": 5810,
|
||||||
"vertices": 5300
|
"vertices": 5444
|
||||||
},
|
},
|
||||||
"npc_dress": {
|
"npc_dress": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -706,8 +706,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5456,
|
"triangles": 5540,
|
||||||
"vertices": 5128
|
"vertices": 5073
|
||||||
},
|
},
|
||||||
"npc_firefighter": {
|
"npc_firefighter": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -747,8 +747,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5900,
|
"triangles": 5888,
|
||||||
"vertices": 5902
|
"vertices": 5785
|
||||||
},
|
},
|
||||||
"npc_guard": {
|
"npc_guard": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -791,8 +791,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5602,
|
"triangles": 5670,
|
||||||
"vertices": 5684
|
"vertices": 5671
|
||||||
},
|
},
|
||||||
"npc_hoodie": {
|
"npc_hoodie": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -832,8 +832,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5860,
|
"triangles": 5864,
|
||||||
"vertices": 5492
|
"vertices": 5325
|
||||||
},
|
},
|
||||||
"npc_jacket": {
|
"npc_jacket": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -873,8 +873,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5428,
|
"triangles": 5432,
|
||||||
"vertices": 5071
|
"vertices": 5225
|
||||||
},
|
},
|
||||||
"npc_vest": {
|
"npc_vest": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
@@ -914,8 +914,8 @@
|
|||||||
"accessory",
|
"accessory",
|
||||||
"hair"
|
"hair"
|
||||||
],
|
],
|
||||||
"triangles": 5536,
|
"triangles": 5532,
|
||||||
"vertices": 5375
|
"vertices": 5195
|
||||||
},
|
},
|
||||||
"palm_tree": {
|
"palm_tree": {
|
||||||
"bounds_godot": {
|
"bounds_godot": {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 60 KiB |
@@ -93,18 +93,18 @@ yet reviewed; this document is the place to fill it.
|
|||||||
| Character | Silhouette | Face @1.85 m | Hands/grip | Weights/pose | Cloth/hair | LOD | Verdict |
|
| Character | Silhouette | Face @1.85 m | Hands/grip | Weights/pose | Cloth/hair | LOD | Verdict |
|
||||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
| *(pose captured 2026-11-04: see "Pose evidence" below)* | | | | | | | |
|
| *(pose captured 2026-11-04: see "Pose evidence" below)* | | | | | | | |
|
||||||
| `npc_casual` | accept (0.9.4) | accept (face prototype) | accept (open palm) | captured (review pending) | accept | accept (two-quad impostor) | pending owner |
|
| `npc_casual` | accept (0.9.4) | accept (face prototype) | accept (open palm) | fixed (wrist/hand + hip/knee) | accept | accept (two-quad impostor) | pending owner |
|
||||||
| `npc_jacket` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_jacket` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_coat` | accept | accept (face prototype) | accept | captured (review pending) | accept (hem 0.76 stride) | accept | pending owner |
|
| `npc_coat` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (hem 0.76 stride) | accept | pending owner |
|
||||||
| `npc_vest` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_vest` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_dress` | accept; performer props dominate | accept (face prototype) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_dress` | accept; performer props dominate | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_hoodie` | accept (hooded criterion) | accept (lower face only) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_hoodie` | accept (hooded criterion) | accept (lower face only) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_firefighter` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_firefighter` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_guard` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | pending owner |
|
| `npc_guard` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
|
||||||
| `npc_crowd_a` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | crowd prototype |
|
| `npc_crowd_a` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | crowd prototype |
|
||||||
| `npc_crowd_b` | accept | accept (face prototype) | accept | captured (review pending) | accept (beard) | accept | crowd prototype |
|
| `npc_crowd_b` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (beard) | accept | crowd prototype |
|
||||||
| `npc_crowd_c` | accept | accept (face prototype) | accept | captured (review pending) | accept (coat hem) | accept | crowd prototype |
|
| `npc_crowd_c` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (coat hem) | accept | crowd prototype |
|
||||||
| `npc_crowd_d` | accept | accept (face prototype) | accept | captured (review pending) | accept | accept | crowd prototype |
|
| `npc_crowd_d` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | crowd prototype |
|
||||||
|
|
||||||
### Gear (18)
|
### Gear (18)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ config_version=5
|
|||||||
|
|
||||||
config/name="Gig Line"
|
config/name="Gig Line"
|
||||||
config/description="Workplace security simulation about observation, access verification, and proportionate escalation."
|
config/description="Workplace security simulation about observation, access verification, and proportionate escalation."
|
||||||
config/version="0.9.7"
|
config/version="0.9.8"
|
||||||
run/main_scene="res://scenes/main.tscn"
|
run/main_scene="res://scenes/main.tscn"
|
||||||
config/features=PackedStringArray("4.7", "GL Compatibility")
|
config/features=PackedStringArray("4.7", "GL Compatibility")
|
||||||
|
|
||||||
|
|||||||
@@ -566,7 +566,7 @@ def _skin_body(spec):
|
|||||||
((0.20 * s * w, 0, 1.37), 0.080 * t * sleeve, 0.074 * t * sleeve), # shoulder
|
((0.20 * s * w, 0, 1.37), 0.080 * t * sleeve, 0.074 * t * sleeve), # shoulder
|
||||||
((0.27 * s * w, 0, 1.23), 0.058 * t * sleeve, 0.058 * t * sleeve), # upper arm
|
((0.27 * s * w, 0, 1.23), 0.058 * t * sleeve, 0.058 * t * sleeve), # upper arm
|
||||||
((0.275 * s * w, 0.005, 1.06), 0.046 * t * sleeve, 0.048 * t * sleeve), # elbow
|
((0.275 * s * w, 0.005, 1.06), 0.046 * t * sleeve, 0.048 * t * sleeve), # elbow
|
||||||
((0.275 * s * w, -0.01, 0.80), 0.034 * t, 0.030 * t), # wrist
|
((0.275 * s * w, -0.01, 0.78), 0.034 * t, 0.030 * t), # wrist
|
||||||
]
|
]
|
||||||
edges += [(3, base), (base, base + 1), (base + 1, base + 2), (base + 2, base + 3)]
|
edges += [(3, base), (base, base + 1), (base + 1, base + 2), (base + 2, base + 3)]
|
||||||
hb = len(nodes)
|
hb = len(nodes)
|
||||||
@@ -666,13 +666,27 @@ def _auto_weights(obj, layout, rigid=None):
|
|||||||
groups[bone].add([v.index], 1.0, "REPLACE")
|
groups[bone].add([v.index], 1.0, "REPLACE")
|
||||||
continue
|
continue
|
||||||
if abs(p.x) > 0.19 and p.z > 0.74 and p.z < 1.42:
|
if abs(p.x) > 0.19 and p.z > 0.74 and p.z < 1.42:
|
||||||
allowed = ["Spine", f"Shoulder{side}", f"Elbow{side}", f"Hand{side}"]
|
if p.z < 0.82:
|
||||||
if abs(p.x) > 0.23:
|
# Wrist: track the Hand bone fully so the forearm-end moves with
|
||||||
allowed.remove("Spine")
|
# the rigid hand (the old Hand+Elbow blend left a visible gap at
|
||||||
|
# the wrist when the hand rotated).
|
||||||
|
allowed = [f"Hand{side}"]
|
||||||
|
else:
|
||||||
|
allowed = ["Spine", f"Shoulder{side}", f"Elbow{side}", f"Hand{side}"]
|
||||||
|
if abs(p.x) > 0.23:
|
||||||
|
allowed.remove("Spine")
|
||||||
elif p.z < 0.80:
|
elif p.z < 0.80:
|
||||||
allowed = ["Hips", f"Hip{side}", f"Knee{side}"]
|
# Legs: keep the shin rigid to the knee and the thigh rigid to the
|
||||||
if p.z < 0.66:
|
# hip, with a short blend only at the knee joint, so deep flexion
|
||||||
allowed.remove("Hips")
|
# (seated) no longer collapses the thigh or pinches the knee.
|
||||||
|
if p.z < 0.28:
|
||||||
|
allowed = [f"Knee{side}"]
|
||||||
|
elif p.z < 0.34:
|
||||||
|
allowed = [f"Hip{side}", f"Knee{side}"]
|
||||||
|
elif p.z < 0.62:
|
||||||
|
allowed = [f"Hip{side}"]
|
||||||
|
else:
|
||||||
|
allowed = ["Hips", f"Hip{side}"]
|
||||||
elif p.z > 1.40:
|
elif p.z > 1.40:
|
||||||
allowed = ["Spine", "Neck", "Head"]
|
allowed = ["Spine", "Neck", "Head"]
|
||||||
else:
|
else:
|
||||||
@@ -848,26 +862,26 @@ def _hands_and_shoes(mats, spec):
|
|||||||
for s in (-1.0, 1.0):
|
for s in (-1.0, 1.0):
|
||||||
x = 0.275 * s * w
|
x = 0.275 * s * w
|
||||||
# Wider and shallower than the old ball: a palm, not a wrist knob.
|
# Wider and shallower than the old ball: a palm, not a wrist knob.
|
||||||
parts.append(sphere("Palm", 0.046, (x, -0.012, 0.742), skin, seg=10, rings=6,
|
parts.append(sphere("Palm", 0.046, (x, -0.012, 0.762), skin, seg=10, rings=6,
|
||||||
scale=(0.80, 0.62, 0.88)))
|
scale=(0.80, 0.62, 0.88)))
|
||||||
# Four bent, tapering fingers with rounded tips. The two segments keep
|
# Four bent, tapering fingers with rounded tips. The two segments keep
|
||||||
# the hand readable at conversation distance without adding a full
|
# the hand readable at conversation distance without adding a full
|
||||||
# finger skeleton; the outer fingers are slightly shorter.
|
# finger skeleton; the outer fingers are slightly shorter.
|
||||||
for index, offset in enumerate((-0.024, -0.008, 0.008, 0.024)):
|
for index, offset in enumerate((-0.024, -0.008, 0.008, 0.024)):
|
||||||
fx = x + offset * s
|
fx = x + offset * s
|
||||||
tip_z = (0.692, 0.681, 0.684, 0.694)[index]
|
tip_z = (0.712, 0.701, 0.704, 0.714)[index]
|
||||||
radius = 0.0115 if index in (1, 2) else 0.0105
|
radius = 0.0115 if index in (1, 2) else 0.0105
|
||||||
parts.append(tube("Finger", [(fx, -0.018, 0.758),
|
parts.append(tube("Finger", [(fx, -0.018, 0.778),
|
||||||
(fx, -0.030, 0.726),
|
(fx, -0.030, 0.746),
|
||||||
(fx, -0.042, tip_z)],
|
(fx, -0.042, tip_z)],
|
||||||
radius, skin, seg=6, caps=False))
|
radius, skin, seg=6, caps=False))
|
||||||
parts.append(sphere("Fingertip", radius, (fx, -0.042, tip_z), skin,
|
parts.append(sphere("Fingertip", radius, (fx, -0.042, tip_z), skin,
|
||||||
seg=6, rings=4))
|
seg=6, rings=4))
|
||||||
parts.append(tube("Thumb", [(x - 0.010 * s, -0.018, 0.758),
|
parts.append(tube("Thumb", [(x - 0.010 * s, -0.018, 0.778),
|
||||||
(x - 0.028 * s, -0.040, 0.740),
|
(x - 0.028 * s, -0.040, 0.760),
|
||||||
(x - 0.034 * s, -0.055, 0.718)],
|
(x - 0.034 * s, -0.055, 0.738)],
|
||||||
0.012, skin, seg=6, caps=False))
|
0.012, skin, seg=6, caps=False))
|
||||||
parts.append(sphere("ThumbTip", 0.012, (x - 0.034 * s, -0.055, 0.718), skin,
|
parts.append(sphere("ThumbTip", 0.012, (x - 0.034 * s, -0.055, 0.738), skin,
|
||||||
seg=6, rings=4))
|
seg=6, rings=4))
|
||||||
parts.append(box("Shoe", (0.10, 0.25, 0.075), (0.12 * s, -0.045, 0.04), shoe,
|
parts.append(box("Shoe", (0.10, 0.25, 0.075), (0.12 * s, -0.045, 0.04), shoe,
|
||||||
bevel=0.028, segs=1))
|
bevel=0.028, segs=1))
|
||||||
@@ -1012,7 +1026,9 @@ def build_character(name):
|
|||||||
return "Head" if p.z > 1.55 else "Neck"
|
return "Head" if p.z > 1.55 else "Neck"
|
||||||
side = "L" if p.x < 0 else "R"
|
side = "L" if p.x < 0 else "R"
|
||||||
if abs(p.x) > 0.26 and p.z > 0.8:
|
if abs(p.x) > 0.26 and p.z > 0.8:
|
||||||
return f"Elbow{side}"
|
# Sleeve: the cuff follows the hand, the upper sleeve the elbow,
|
||||||
|
# so the sleeve does not separate from the hand at the wrist.
|
||||||
|
return f"Hand{side}" if p.z < 1.06 else f"Elbow{side}"
|
||||||
if p.z < 0.25:
|
if p.z < 0.25:
|
||||||
return f"Knee{side}"
|
return f"Knee{side}"
|
||||||
return None
|
return None
|
||||||
|
|||||||