design: skinned equipment parts with bone mapping (Tim t1027u)
@@ -573,3 +573,13 @@ When a single render or **Render Alles** reaches its end (done, failed or cancel
573
573
## Decision 2026-11-07 (Tim t1026u): window icon under Wayland comes only from the installed desktop entry
574
574
575
575
Investigated the Wayland "W" titlebar icon on KDE. The window sends `xdg_toplevel.set_app_id("paperdoll-renderer")` (checked with `WAYLAND_DEBUG` under headless Weston 14), and the v0.1.2 `.deb` (and so the AUR package) installs `paperdoll-renderer.desktop` (`Icon=` and `StartupWMClass=paperdoll-renderer`) plus all hicolor sizes. Wayland has no core way for a client to send its own window icon. The `with_icon` bitmap is used on X11 and Windows only; winit 0.30 does not implement `xdg-toplevel-icon-v1`. KWin therefore takes the icon from the desktop entry named after the app id, and shows the generic Wayland logo when none is installed. A binary that was built or unpacked without a package (`target/release`, AppImage, zip) gets the icon after `--install-desktop`. No code change; the README states this explicitly. If winit gains `xdg-toplevel-icon-v1`, revisit sending the bitmap directly.
576
577
## Decision 2026-11-08 (Tim t1027u): equipment with its own skeleton maps bones to the character
578
579
**Add part** still starts by choosing the model. A model without a skeleton (OBJ, unskinned FBX) keeps the current flow: choose one character bone, with one position/rotation. A glTF/GLB or FBX model that has a skin is imported as a *skinned part*: its skeleton (bone names, parents and rest-world matrices) is stored, and each vertex is assigned rigidly to its dominant bone (highest skin weight). The vertex is stored in that bone's rest space, after rest-pose linear blend skinning. Equipment stays rigid per bone: no blending between bones, no deformation.
580
581
Per sex, every equipment bone can be linked to one character bone (at least one link is required to render; the rest is optional). Each link has its own position (XYZ) and rotation (degrees XYZ, Rz·Ry·Rx), relative to the character bone. A newly made link gets the offset that keeps the equipment bone exactly where it sits in the model's rest pose, relative to the character bone's rest pose, so a model made for the same character fits at once. An unlinked bone follows its nearest linked ancestor rigidly (keeping its rest offset to that ancestor). A bone without a linked ancestor follows the first link.
582
583
Automatic filling links equipment bones to character bones by name: (1) exact name, case-insensitive; (2) equal after normalising: lowercase, strip namespace/armature prefixes (`mixamorig:`, `Armature|`, everything up to the last `:` or `|`, `bip01`, `def-`), strip numeric suffixes (`.001`, `_01`, `1`), and fold side markers (`L`/`R`/`left`/`right` as prefix or suffix, `LeftArm`) into one side tag; (3) partial: same side, and one normalised name contains the other (at least 3 characters). The best score wins; ties go to the first character bone. Auto-fill only fills unlinked bones; manual links are kept.
584
585
Storage: equipment bindings already live in the `.ppe` preset, which the `.ppd` lists; the `.ppd` only stores the preset paths, so the `.ppd` schema is unchanged. The `.ppe` container goes from version 1 to 2 (new optional fields: the part skeleton, the bone of each mesh, and per-sex bone links). Version 1 files load as rigid parts (migration) and are written as version 2 on the next save. Renders and the live preview use the same layer function, so both show the mapping.
@@ -573,3 +573,13 @@ When a single render or **Render Alles** reaches its end (done, failed or cancel573
## Decision 2026-11-07 (Tim t1026u): window icon under Wayland comes only from the installed desktop entry573
## Decision 2026-11-07 (Tim t1026u): window icon under Wayland comes only from the installed desktop entry574
574
575
Investigated the Wayland "W" titlebar icon on KDE. The window sends `xdg_toplevel.set_app_id("paperdoll-renderer")` (checked with `WAYLAND_DEBUG` under headless Weston 14), and the v0.1.2 `.deb` (and so the AUR package) installs `paperdoll-renderer.desktop` (`Icon=` and `StartupWMClass=paperdoll-renderer`) plus all hicolor sizes. Wayland has no core way for a client to send its own window icon. The `with_icon` bitmap is used on X11 and Windows only; winit 0.30 does not implement `xdg-toplevel-icon-v1`. KWin therefore takes the icon from the desktop entry named after the app id, and shows the generic Wayland logo when none is installed. A binary that was built or unpacked without a package (`target/release`, AppImage, zip) gets the icon after `--install-desktop`. No code change; the README states this explicitly. If winit gains `xdg-toplevel-icon-v1`, revisit sending the bitmap directly.575
Investigated the Wayland "W" titlebar icon on KDE. The window sends `xdg_toplevel.set_app_id("paperdoll-renderer")` (checked with `WAYLAND_DEBUG` under headless Weston 14), and the v0.1.2 `.deb` (and so the AUR package) installs `paperdoll-renderer.desktop` (`Icon=` and `StartupWMClass=paperdoll-renderer`) plus all hicolor sizes. Wayland has no core way for a client to send its own window icon. The `with_icon` bitmap is used on X11 and Windows only; winit 0.30 does not implement `xdg-toplevel-icon-v1`. KWin therefore takes the icon from the desktop entry named after the app id, and shows the generic Wayland logo when none is installed. A binary that was built or unpacked without a package (`target/release`, AppImage, zip) gets the icon after `--install-desktop`. No code change; the README states this explicitly. If winit gains `xdg-toplevel-icon-v1`, revisit sending the bitmap directly.576
577
## Decision 2026-11-08 (Tim t1027u): equipment with its own skeleton maps bones to the character578
579
**Add part** still starts by choosing the model. A model without a skeleton (OBJ, unskinned FBX) keeps the current flow: choose one character bone, with one position/rotation. A glTF/GLB or FBX model that has a skin is imported as a *skinned part*: its skeleton (bone names, parents and rest-world matrices) is stored, and each vertex is assigned rigidly to its dominant bone (highest skin weight). The vertex is stored in that bone's rest space, after rest-pose linear blend skinning. Equipment stays rigid per bone: no blending between bones, no deformation.580
581
Per sex, every equipment bone can be linked to one character bone (at least one link is required to render; the rest is optional). Each link has its own position (XYZ) and rotation (degrees XYZ, Rz·Ry·Rx), relative to the character bone. A newly made link gets the offset that keeps the equipment bone exactly where it sits in the model's rest pose, relative to the character bone's rest pose, so a model made for the same character fits at once. An unlinked bone follows its nearest linked ancestor rigidly (keeping its rest offset to that ancestor). A bone without a linked ancestor follows the first link.582
583
Automatic filling links equipment bones to character bones by name: (1) exact name, case-insensitive; (2) equal after normalising: lowercase, strip namespace/armature prefixes (`mixamorig:`, `Armature|`, everything up to the last `:` or `|`, `bip01`, `def-`), strip numeric suffixes (`.001`, `_01`, `1`), and fold side markers (`L`/`R`/`left`/`right` as prefix or suffix, `LeftArm`) into one side tag; (3) partial: same side, and one normalised name contains the other (at least 3 characters). The best score wins; ties go to the first character bone. Auto-fill only fills unlinked bones; manual links are kept.584
585
Storage: equipment bindings already live in the `.ppe` preset, which the `.ppd` lists; the `.ppd` only stores the preset paths, so the `.ppd` schema is unchanged. The `.ppe` container goes from version 1 to 2 (new optional fields: the part skeleton, the bone of each mesh, and per-sex bone links). Version 1 files load as rigid parts (migration) and are written as version 2 on the next save. Renders and the live preview use the same layer function, so both show the mapping.