Give cross-body bars a true 3D axis and fix the goblet squat hold

The orbit was always a real camera orbit — figure and props share one
rigid rotation — but a bar's screen-space angle authored the wrong 3D
rod: the default horizontal encoded a rod along the body axis, so
barbells hovered fixed on screen and vanished at the head-on view
where they should span widest. Line props now take "axis": "z" (both
renderers in lockstep, fixture-pinned): the world left-right direction
projects through the camera pitch like the floor quad — end-on plates
in profile, full span face-on, swinging with the hands in between.
Applied to the ten cross-body bars; vertical handles were already
orbit-invariant.

Goblet Squat's hand pins sat so close to the shoulders that the
two-bone IK was degenerate, flipping between a chicken-wing and an
elbow-behind solve; re-pinned level with the shoulders so the elbows
tuck straight down through the whole rep.

Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
2026-07-08 12:49:35 -04:00
parent 60927b5d1f
commit fd2deaa9c7
79 changed files with 190 additions and 143 deletions
+8
View File
@@ -1,5 +1,13 @@
**July 2026** **July 2026**
Barbells and pull-up bars in the animated form guide now turn with the figure as the view circles, instead of hovering fixed on screen.
The goblet squat form guide now holds the weight at the chest with elbows tucked down, instead of flaring oddly.
Each set you complete is now recorded — adjust the reps or weight you actually did right from the rest screen.
The Weight Progression chart and workout volume now reflect what you actually lifted, not just the plan.
A Live Activity now shows your current exercise, set, and rest countdown on the Lock Screen and in the Dynamic Island. A Live Activity now shows your current exercise, set, and rest countdown on the Lock Screen and in the Dynamic Island.
Any exercise from the library can now be added mid-workout, planned from your last time doing it. Any exercise from the library can now be added mid-workout, planned from your last time doing it.
@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 164.1 90.9 L 160.0 90.4 L 160.0 91.3" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 164.1 90.9 L 160.0 90.4 L 160.0 91.3" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 160.0 90.4 Q 163.2 60.6 166.2 32.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 160.0 90.4 Q 163.2 60.6 166.2 32.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 166.2 33.5 L 182.9 46.1 L 164.2 36.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 166.2 33.5 L 182.9 46.1 L 164.2 36.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 147.4 36.0 L 183.8 36.0" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 165.6 32.8 L 165.6 39.1" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="147.4" cy="36.0" r="9.799999999999999" fill="#6b7180"/> <circle cx="165.6" cy="32.8" r="9.799999999999999" fill="#6b7180"/>
<circle cx="183.8" cy="36.0" r="9.799999999999999" fill="#6b7180"/> <circle cx="165.6" cy="39.1" r="9.799999999999999" fill="#6b7180"/>
<circle id="head" cx="168.2" cy="18.5" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="168.2" cy="18.5" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="175.2" y1="18.7" x2="180.1" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="175.2" y1="18.7" x2="180.1" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 134.0 121.7 L 129.9 121.2 L 129.9 122.1" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 134.0 121.7 L 129.9 121.2 L 129.9 122.1" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 129.9 121.2 Q 148.2 97.2 162.3 72.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 129.9 121.2 Q 148.2 97.2 162.3 72.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 162.3 73.4 L 183.0 70.2 L 162.1 68.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 162.3 73.4 L 183.0 70.2 L 162.1 68.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 145.3 68.1 L 181.7 68.1" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 163.5 65.0 L 163.5 71.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="145.3" cy="68.1" r="9.799999999999999" fill="#6b7180"/> <circle cx="163.5" cy="65.0" r="9.799999999999999" fill="#6b7180"/>
<circle cx="181.7" cy="68.1" r="9.799999999999999" fill="#6b7180"/> <circle cx="163.5" cy="71.3" r="9.799999999999999" fill="#6b7180"/>
<circle id="head" cx="170.5" cy="60.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="170.5" cy="60.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="177.5" y1="61.9" x2="182.3" y2="62.6" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="177.5" y1="61.9" x2="182.3" y2="62.6" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l"], "working": ["leg_r", "leg_l"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 14} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 14}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 157 KiB

+3 -3
View File
@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 134.0 121.7 L 129.9 121.2 L 129.9 122.1" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 134.0 121.7 L 129.9 121.2 L 129.9 122.1" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 129.9 121.2 Q 148.2 97.2 162.3 72.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 129.9 121.2 Q 148.2 97.2 162.3 72.1" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 162.3 73.4 L 183.0 70.2 L 162.1 68.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 162.3 73.4 L 183.0 70.2 L 162.1 68.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 145.3 68.1 L 181.7 68.1" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 163.5 65.0 L 163.5 71.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="145.3" cy="68.1" r="9.799999999999999" fill="#6b7180"/> <circle cx="163.5" cy="65.0" r="9.799999999999999" fill="#6b7180"/>
<circle cx="181.7" cy="68.1" r="9.799999999999999" fill="#6b7180"/> <circle cx="163.5" cy="71.3" r="9.799999999999999" fill="#6b7180"/>
<circle id="head" cx="170.5" cy="60.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="170.5" cy="60.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="177.5" y1="61.9" x2="182.3" y2="62.6" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="177.5" y1="61.9" x2="182.3" y2="62.6" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -11,9 +11,9 @@
<path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 65.0 117.9 L 91.6 131.7 L 93.0 102.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 65.0 117.9 L 91.6 131.7 L 93.0 102.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 69.0 101.2 L 121.0 101.2" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 95.0 96.7 L 95.0 105.8" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="69.0" cy="101.2" r="12" fill="#6b7180"/> <circle cx="95.0" cy="96.7" r="12" fill="#6b7180"/>
<circle cx="121.0" cy="101.2" r="12" fill="#6b7180"/> <circle cx="95.0" cy="105.8" r="12" fill="#6b7180"/>
<circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -11,9 +11,9 @@
<path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 65.0 117.9 L 60.6 88.7 L 67.0 59.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 65.0 117.9 L 60.6 88.7 L 67.0 59.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 43.0 58.9 L 95.0 58.9" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 69.0 54.4 L 69.0 63.4" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="43.0" cy="58.9" r="12" fill="#6b7180"/> <circle cx="69.0" cy="54.4" r="12" fill="#6b7180"/>
<circle cx="95.0" cy="58.9" r="12" fill="#6b7180"/> <circle cx="69.0" cy="63.4" r="12" fill="#6b7180"/>
<circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

+1 -1
View File
@@ -8,7 +8,7 @@
{"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4}, {"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4},
{"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4} {"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 156 KiB

+3 -3
View File
@@ -11,9 +11,9 @@
<path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 116.0 Q 106.5 116.0 65.0 116.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 117.2 L 195.3 109.3 L 196.0 148.7 L 206.9 147.6" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 65.0 117.9 L 91.6 131.7 L 93.0 102.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 65.0 117.9 L 91.6 131.7 L 93.0 102.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 69.0 101.2 L 121.0 101.2" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 95.0 96.7 L 95.0 105.8" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="69.0" cy="101.2" r="12" fill="#6b7180"/> <circle cx="95.0" cy="96.7" r="12" fill="#6b7180"/>
<circle cx="121.0" cy="101.2" r="12" fill="#6b7180"/> <circle cx="95.0" cy="105.8" r="12" fill="#6b7180"/>
<circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="45.2" cy="113.3" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="46.6" y1="103.4" x2="47.6" y2="96.5" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

+3 -3
View File
@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 116.5 109.1 L 112.4 108.6 L 112.4 109.5" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 116.5 109.1 L 112.4 108.6 L 112.4 109.5" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 112.4 108.6 Q 142.6 103.8 169.8 93.5" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 112.4 108.6 Q 142.6 103.8 169.8 93.5" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 169.8 94.8 L 164.3 114.8 L 158.1 134.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 169.8 94.8 L 164.3 114.8 L 158.1 134.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 141.4 133.7 L 177.8 133.7" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 159.6 130.6 L 159.6 136.9" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="141.4" cy="133.7" r="11.2" fill="#6b7180"/> <circle cx="159.6" cy="130.6" r="11.2" fill="#6b7180"/>
<circle cx="177.8" cy="133.7" r="11.2" fill="#6b7180"/> <circle cx="159.6" cy="136.9" r="11.2" fill="#6b7180"/>
<circle id="head" cx="183.4" cy="90.4" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="183.4" cy="90.4" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="190.4" y1="91.2" x2="195.3" y2="91.8" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="190.4" y1="91.2" x2="195.3" y2="91.8" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

+3 -3
View File
@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 157.1 90.9 L 153.0 90.4 L 153.0 91.3" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 90.9 L 153.0 90.4 L 153.0 91.3" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 153.0 90.4 Q 158.3 60.9 163.3 32.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 153.0 90.4 Q 158.3 60.9 163.3 32.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 163.3 34.0 L 167.6 54.3 L 160.7 73.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 163.3 34.0 L 167.6 54.3 L 160.7 73.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 143.9 73.2 L 180.3 73.2" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 162.1 70.0 L 162.1 76.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="143.9" cy="73.2" r="11.2" fill="#6b7180"/> <circle cx="162.1" cy="70.0" r="11.2" fill="#6b7180"/>
<circle cx="180.3" cy="73.2" r="11.2" fill="#6b7180"/> <circle cx="162.1" cy="76.3" r="11.2" fill="#6b7180"/>
<circle id="head" cx="166.2" cy="19.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="166.2" cy="19.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="173.2" y1="19.7" x2="178.1" y2="20.0" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="173.2" y1="19.7" x2="178.1" y2="20.0" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l", "spine"], "working": ["leg_r", "leg_l", "spine"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 16} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 16}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 167 KiB

+3 -3
View File
@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 116.5 109.1 L 112.4 108.6 L 112.4 109.5" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 116.5 109.1 L 112.4 108.6 L 112.4 109.5" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 112.4 108.6 Q 142.6 103.8 169.8 93.5" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 112.4 108.6 Q 142.6 103.8 169.8 93.5" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 169.8 94.8 L 164.3 114.8 L 158.1 134.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 169.8 94.8 L 164.3 114.8 L 158.1 134.6" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 141.4 133.7 L 177.8 133.7" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 159.6 130.6 L 159.6 136.9" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="141.4" cy="133.7" r="11.2" fill="#6b7180"/> <circle cx="159.6" cy="130.6" r="11.2" fill="#6b7180"/>
<circle cx="177.8" cy="133.7" r="11.2" fill="#6b7180"/> <circle cx="159.6" cy="136.9" r="11.2" fill="#6b7180"/>
<circle id="head" cx="183.4" cy="90.4" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="183.4" cy="90.4" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="190.4" y1="91.2" x2="195.3" y2="91.8" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="190.4" y1="91.2" x2="195.3" y2="91.8" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,16 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none">
<title>Goblet Squat</title> <title>Goblet Squat</title>
<path d="M 142.9 157.6 L 199.8 157.6 L 199.8 150.1 L 142.9 150.1 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/> <path d="M 142.9 157.6 L 197.4 157.6 L 197.4 150.1 L 142.9 150.1 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/>
<path id="leg_l" d="M 164.3 90.6 L 155.0 121.9 L 164.3 148.8 L 156.8 151.3" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_l" d="M 164.3 90.6 L 155.0 121.9 L 164.3 148.8 L 156.8 151.3" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 160.0 91.0 L 151.5 122.5 L 161.4 149.1 L 154.0 151.8" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 160.0 91.0 L 151.5 122.5 L 161.4 149.1 L 154.0 151.8" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_l" d="M 169.6 30.1 L 191.1 28.5 L 174.4 41.9" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_l" d="M 169.6 30.1 L 163.7 50.5 L 180.9 37.7" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="girdle" d="M 169.6 30.1 L 165.3 30.0 L 165.3 31.4" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="girdle" d="M 169.6 30.1 L 165.3 30.0 L 165.3 31.4" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="pelvisBar" d="M 164.3 90.6 L 160.0 90.1 L 160.0 91.0" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 164.3 90.6 L 160.0 90.1 L 160.0 91.0" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 160.0 90.1 Q 162.7 59.4 165.3 30.0" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 160.0 90.1 Q 162.7 59.4 165.3 30.0" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 165.3 31.4 L 186.7 28.1 L 171.5 43.2" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 165.3 31.4 L 161.1 52.3 L 178.0 39.0" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 173.0 48.3 L 173.0 36.8" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 179.4 44.1 L 179.4 32.6" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="173.0" cy="48.3" r="3.5999999999999996" fill="#6b7180"/> <circle cx="179.4" cy="44.1" r="3.5999999999999996" fill="#6b7180"/>
<circle cx="173.0" cy="36.8" r="3.5999999999999996" fill="#6b7180"/> <circle cx="179.4" cy="32.6" r="3.5999999999999996" fill="#6b7180"/>
<circle id="head" cx="167.1" cy="16.0" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/> <circle id="head" cx="167.1" cy="16.0" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/>
<line id="nose" x1="174.3" y1="16.1" x2="179.3" y2="16.2" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/> <line id="nose" x1="174.3" y1="16.1" x2="179.3" y2="16.2" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,16 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none">
<title>Goblet Squat</title> <title>Goblet Squat</title>
<path d="M 142.9 158.1 L 199.8 158.1 L 199.8 150.6 L 142.9 150.6 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/> <path d="M 142.9 158.1 L 197.4 158.1 L 197.4 150.6 L 142.9 150.6 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/>
<path id="leg_l" d="M 157.1 118.0 L 187.1 131.8 L 164.3 149.2 L 171.0 153.4" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_l" d="M 157.1 118.0 L 187.1 131.8 L 164.3 149.2 L 171.0 153.4" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_l" d="M 178.0 60.9 L 163.3 76.5 L 184.5 72.1" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_l" d="M 178.0 60.9 L 170.7 80.9 L 188.8 69.3" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 152.8 118.3 L 183.3 131.0 L 161.4 149.5 L 168.3 153.3" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 152.8 118.3 L 183.3 131.0 L 161.4 149.5 L 168.3 153.3" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="girdle" d="M 178.0 60.9 L 173.7 60.8 L 173.7 62.2" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="girdle" d="M 178.0 60.9 L 173.7 60.8 L 173.7 62.2" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="pelvisBar" d="M 157.1 118.0 L 152.8 117.4 L 152.8 118.3" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 118.0 L 152.8 117.4 L 152.8 118.3" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 152.8 117.4 Q 165.5 89.2 173.7 60.8" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 152.8 117.4 Q 165.5 89.2 173.7 60.8" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 173.7 62.2 L 160.8 79.3 L 181.6 73.4" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 173.7 62.2 L 168.2 82.8 L 185.9 70.6" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 183.0 78.5 L 183.0 67.0" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 187.4 75.7 L 187.4 64.2" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="183.0" cy="78.5" r="3.5999999999999996" fill="#6b7180"/> <circle cx="187.4" cy="75.7" r="3.5999999999999996" fill="#6b7180"/>
<circle cx="183.0" cy="67.0" r="3.5999999999999996" fill="#6b7180"/> <circle cx="187.4" cy="64.2" r="3.5999999999999996" fill="#6b7180"/>
<circle id="head" cx="179.1" cy="47.7" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/> <circle id="head" cx="179.1" cy="47.7" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/>
<line id="nose" x1="186.3" y1="48.2" x2="191.3" y2="48.5" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/> <line id="nose" x1="186.3" y1="48.2" x2="191.3" y2="48.5" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

+6 -6
View File
@@ -12,24 +12,24 @@
"root": {"pos": [160, 66], "pitch": 5}, "root": {"pos": [160, 66], "pitch": 5},
"spine": [0, 0], "spine": [0, 0],
"neck": 2, "head": -6, "neck": 2, "head": -6,
"shoulder_r": 38, "elbow_r": 125, "shoulder_r": 5, "elbow_r": 140,
"shoulder_l": 38, "elbow_l": 125, "shoulder_l": 5, "elbow_l": 140,
"hip_r": 5, "knee_r": 4, "ankle_r": 0, "hip_r": 5, "knee_r": 4, "ankle_r": 0,
"hip_l": 5, "knee_l": 4, "ankle_l": 0, "hip_l": 5, "knee_l": 4, "ankle_l": 0,
"pins": {"foot_r": [162, 148], "foot_l": [166, 150], "pins": {"foot_r": [162, 148], "foot_l": [166, 150],
"hand_r": [176, -2], "hand_l": [180, 0]} "hand_r": [185, -8], "hand_l": [189, -6]}
}, },
{ {
"hold": 0.4, "tween": 1.0, "hold": 0.4, "tween": 1.0,
"root": {"pos": [150, 104], "pitch": 22}, "root": {"pos": [150, 104], "pitch": 22},
"spine": [0, -4], "spine": [0, -4],
"neck": 4, "head": -18, "neck": 4, "head": -18,
"shoulder_r": 46, "elbow_r": 120, "shoulder_r": 15, "elbow_r": 135,
"shoulder_l": 46, "elbow_l": 120, "shoulder_l": 15, "elbow_l": 135,
"hip_r": 96, "knee_r": 116, "ankle_r": 20, "hip_r": 96, "knee_r": 116, "ankle_r": 20,
"hip_l": 96, "knee_l": 116, "ankle_l": 20, "hip_l": 96, "knee_l": 116, "ankle_l": 20,
"pins": {"foot_r": [162, 148], "foot_l": [166, 150], "pins": {"foot_r": [162, 148], "foot_l": [166, 150],
"hand_r": [190, 40], "hand_l": [194, 42]} "hand_r": [196, 36], "hand_l": [200, 38]}
} }
] ]
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

+6 -6
View File
@@ -1,16 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180" fill="none">
<title>Goblet Squat</title> <title>Goblet Squat</title>
<path d="M 142.9 158.1 L 199.8 158.1 L 199.8 150.6 L 142.9 150.6 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/> <path d="M 142.9 158.1 L 197.4 158.1 L 197.4 150.6 L 142.9 150.6 Z" fill="none" stroke="#b9bec9" stroke-width="2.16" stroke-linejoin="round"/>
<path id="leg_l" d="M 157.1 118.0 L 187.1 131.8 L 164.3 149.2 L 171.0 153.4" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_l" d="M 157.1 118.0 L 187.1 131.8 L 164.3 149.2 L 171.0 153.4" stroke="#86cfc5" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_l" d="M 178.0 60.9 L 163.3 76.5 L 184.5 72.1" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_l" d="M 178.0 60.9 L 170.7 80.9 L 188.8 69.3" stroke="#a9afba" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 152.8 118.3 L 183.3 131.0 L 161.4 149.5 L 168.3 153.3" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 152.8 118.3 L 183.3 131.0 L 161.4 149.5 L 168.3 153.3" stroke="#0d9488" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="girdle" d="M 178.0 60.9 L 173.7 60.8 L 173.7 62.2" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="girdle" d="M 178.0 60.9 L 173.7 60.8 L 173.7 62.2" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="pelvisBar" d="M 157.1 118.0 L 152.8 117.4 L 152.8 118.3" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 118.0 L 152.8 117.4 L 152.8 118.3" stroke="#3a3f4b" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 152.8 117.4 Q 165.5 89.2 173.7 60.8" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 152.8 117.4 Q 165.5 89.2 173.7 60.8" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 173.7 62.2 L 160.8 79.3 L 181.6 73.4" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 173.7 62.2 L 168.2 82.8 L 185.9 70.6" stroke="#3a3f4b" stroke-width="4.32" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 183.0 78.5 L 183.0 67.0" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 187.4 75.7 L 187.4 64.2" stroke="#6b7180" stroke-width="2.16" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="183.0" cy="78.5" r="3.5999999999999996" fill="#6b7180"/> <circle cx="187.4" cy="75.7" r="3.5999999999999996" fill="#6b7180"/>
<circle cx="183.0" cy="67.0" r="3.5999999999999996" fill="#6b7180"/> <circle cx="187.4" cy="64.2" r="3.5999999999999996" fill="#6b7180"/>
<circle id="head" cx="179.1" cy="47.7" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/> <circle id="head" cx="179.1" cy="47.7" r="7.199999999999999" fill="white" stroke="#3a3f4b" stroke-width="4.32"/>
<line id="nose" x1="186.3" y1="48.2" x2="191.3" y2="48.5" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/> <line id="nose" x1="186.3" y1="48.2" x2="191.3" y2="48.5" stroke="#3a3f4b" stroke-width="2.88" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -10,9 +10,9 @@
<path id="spine" d="M 150.0 136.0 Q 107.3 127.0 69.3 110.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 136.0 Q 107.3 127.0 69.3 110.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 137.2 L 187.9 111.6 L 203.0 148.0 L 212.8 143.1" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 137.2 L 187.9 111.6 L 203.0 148.0 L 212.8 143.1" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 69.3 112.1 L 99.3 112.3 L 124.0 129.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 69.3 112.1 L 99.3 112.3 L 124.0 129.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 100.0 128.1 L 152.0 128.1" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 126.0 123.6 L 126.0 132.7" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="100.0" cy="128.1" r="13" fill="#6b7180"/> <circle cx="126.0" cy="123.6" r="13" fill="#6b7180"/>
<circle cx="152.0" cy="128.1" r="13" fill="#6b7180"/> <circle cx="126.0" cy="132.7" r="13" fill="#6b7180"/>
<circle id="head" cx="60.2" cy="92.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="60.2" cy="92.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="68.8" y1="87.6" x2="74.8" y2="84.0" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="68.8" y1="87.6" x2="74.8" y2="84.0" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -10,9 +10,9 @@
<path id="spine" d="M 152.0 114.0 Q 108.5 114.0 67.1 111.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 152.0 114.0 Q 108.5 114.0 67.1 111.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 152.0 115.2 L 197.5 108.7 L 203.0 147.7 L 213.7 145.3" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 152.0 115.2 L 197.5 108.7 L 203.0 147.7 L 213.7 145.3" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 67.1 113.0 L 96.5 107.4 L 126.0 113.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 67.1 113.0 L 96.5 107.4 L 126.0 113.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 102.0 112.0 L 154.0 112.0" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 128.0 107.5 L 128.0 116.6" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="102.0" cy="112.0" r="13" fill="#6b7180"/> <circle cx="128.0" cy="107.5" r="13" fill="#6b7180"/>
<circle cx="154.0" cy="112.0" r="13" fill="#6b7180"/> <circle cx="128.0" cy="116.6" r="13" fill="#6b7180"/>
<circle id="head" cx="54.5" cy="95.8" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="54.5" cy="95.8" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="61.8" y1="89.0" x2="67.0" y2="84.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="61.8" y1="89.0" x2="67.0" y2="84.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

+1 -1
View File
@@ -7,7 +7,7 @@
{"kind": "line", "pts": [[50, 122], [88, 122]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[50, 122], [88, 122]], "w": 9, "depth": 8},
{"kind": "line", "pts": [[68, 127], [68, 150]], "w": 5} {"kind": "line", "pts": [[68, 127], [68, 150]], "w": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 KiB

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 162 KiB

+3 -3
View File
@@ -10,9 +10,9 @@
<path id="spine" d="M 152.0 114.0 Q 108.5 114.0 67.1 111.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 152.0 114.0 Q 108.5 114.0 67.1 111.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 152.0 115.2 L 197.5 108.7 L 203.0 147.7 L 213.7 145.3" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 152.0 115.2 L 197.5 108.7 L 203.0 147.7 L 213.7 145.3" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 67.1 113.0 L 96.5 107.4 L 126.0 113.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 67.1 113.0 L 96.5 107.4 L 126.0 113.0" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 102.0 112.0 L 154.0 112.0" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 128.0 107.5 L 128.0 116.6" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="102.0" cy="112.0" r="13" fill="#6b7180"/> <circle cx="128.0" cy="107.5" r="13" fill="#6b7180"/>
<circle cx="154.0" cy="112.0" r="13" fill="#6b7180"/> <circle cx="128.0" cy="116.6" r="13" fill="#6b7180"/>
<circle id="head" cx="54.5" cy="95.8" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="54.5" cy="95.8" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="61.8" y1="89.0" x2="67.0" y2="84.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="61.8" y1="89.0" x2="67.0" y2="84.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -11,9 +11,9 @@
<path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 105.3 72.1 L 130.3 77.2 L 114.1 57.8" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 105.3 72.1 L 130.3 77.2 L 114.1 57.8" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 93.7 57.0 L 137.9 57.0" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 115.8 53.2 L 115.8 60.9" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="93.7" cy="57.0" r="10.2" fill="#6b7180"/> <circle cx="115.8" cy="53.2" r="10.2" fill="#6b7180"/>
<circle cx="137.9" cy="57.0" r="10.2" fill="#6b7180"/> <circle cx="115.8" cy="60.9" r="10.2" fill="#6b7180"/>
<circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/> <circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/>
<line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/> <line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -11,9 +11,9 @@
<path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 105.3 72.1 L 112.7 48.0 L 107.3 23.5" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 105.3 72.1 L 112.7 48.0 L 107.3 23.5" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 86.9 22.7 L 131.1 22.7" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 109.0 18.9 L 109.0 26.6" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="86.9" cy="22.7" r="10.2" fill="#6b7180"/> <circle cx="109.0" cy="18.9" r="10.2" fill="#6b7180"/>
<circle cx="131.1" cy="22.7" r="10.2" fill="#6b7180"/> <circle cx="109.0" cy="26.6" r="10.2" fill="#6b7180"/>
<circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/> <circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/>
<line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/> <line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -9,7 +9,7 @@
{"kind": "line", "pts": [[140, 130], [166, 127]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[140, 130], [166, 127]], "w": 8, "depth": 8},
{"kind": "line", "pts": [[152, 133], [152, 150]], "w": 5} {"kind": "line", "pts": [[152, 133], [152, 150]], "w": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 158 KiB

@@ -11,9 +11,9 @@
<path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 149.8 126.5 Q 127.0 97.8 105.3 70.4" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 149.8 127.5 L 187.2 116.2 L 192.3 149.3 L 201.4 147.1" stroke="#3a3f4b" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 105.3 72.1 L 130.3 77.2 L 114.1 57.8" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 105.3 72.1 L 130.3 77.2 L 114.1 57.8" stroke="#0d9488" stroke-width="5.1" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 93.7 57.0 L 137.9 57.0" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 115.8 53.2 L 115.8 60.9" stroke="#6b7180" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="93.7" cy="57.0" r="10.2" fill="#6b7180"/> <circle cx="115.8" cy="53.2" r="10.2" fill="#6b7180"/>
<circle cx="137.9" cy="57.0" r="10.2" fill="#6b7180"/> <circle cx="115.8" cy="60.9" r="10.2" fill="#6b7180"/>
<circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/> <circle id="head" cx="99.5" cy="54.7" r="8.5" fill="white" stroke="#3a3f4b" stroke-width="5.1"/>
<line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/> <line id="nose" x1="107.3" y1="51.3" x2="112.7" y2="48.9" stroke="#3a3f4b" stroke-width="3.4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -12,7 +12,7 @@
<path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 147.7 40.3 L 174.8 27.4 L 194.0 4.7" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 147.7 40.3 L 174.8 27.4 L 194.0 4.7" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 172.0 3.8 L 220.0 3.8" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 196.0 -0.3 L 196.0 8.0" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="155.3" y1="10.6" x2="159.3" y2="4.9" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="155.3" y1="10.6" x2="159.3" y2="4.9" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -12,7 +12,7 @@
<path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 147.7 40.3 L 171.7 58.0 L 194.0 38.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 147.7 40.3 L 171.7 58.0 L 194.0 38.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 172.0 37.3 L 220.0 37.3" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 196.0 33.2 L 196.0 41.5" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="158.2" y1="13.8" x2="164.2" y2="10.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="158.2" y1="13.8" x2="164.2" y2="10.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

+1 -1
View File
@@ -9,7 +9,7 @@
{"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"} {"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"}
]}, ]},
{"type": "cable", "from": [272, 19], "to": ["hand_r", "hand_l"], "w": 4}, {"type": "cable", "from": [272, 19], "to": ["hand_r", "hand_l"], "w": 4},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 24} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 24}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 160 KiB

+1 -1
View File
@@ -12,7 +12,7 @@
<path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 150.0 122.0 Q 146.6 79.2 147.7 38.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 150.0 123.2 L 194.4 111.4 L 193.0 150.8 L 204.0 151.2" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 147.7 40.3 L 171.7 58.0 L 194.0 38.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 147.7 40.3 L 171.7 58.0 L 194.0 38.2" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 172.0 37.3 L 220.0 37.3" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 196.0 33.2 L 196.0 41.5" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="149.5" cy="18.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="158.2" y1="13.8" x2="164.2" y2="10.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="158.2" y1="13.8" x2="164.2" y2="10.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

+1 -1
View File
@@ -8,7 +8,7 @@
<path id="spine" d="M 157.2 114.9 Q 157.2 84.9 157.2 56.3" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 157.2 114.9 Q 157.2 84.9 157.2 56.3" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_l" d="M 161.3 56.3 L 160.4 35.7 L 158.6 15.1" stroke="#86cfc5" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_l" d="M 161.3 56.3 L 160.4 35.7 L 158.6 15.1" stroke="#86cfc5" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 157.2 57.6 L 156.1 37.0 L 155.8 16.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 157.2 57.6 L 156.1 37.0 L 155.8 16.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 140.4 15.7 L 174.0 15.7" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 157.2 12.8 L 157.2 18.6" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="157.7" cy="42.5" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="157.7" cy="42.5" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="164.7" y1="42.0" x2="169.6" y2="41.7" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="164.7" y1="42.0" x2="169.6" y2="41.7" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

+1 -1
View File
@@ -8,7 +8,7 @@
<path id="pelvisBar" d="M 161.3 93.0 L 157.2 92.5 L 157.2 93.4" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 161.3 93.0 L 157.2 92.5 L 157.2 93.4" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 157.2 92.5 Q 157.2 62.5 157.2 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 157.2 92.5 Q 157.2 62.5 157.2 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 157.2 35.2 L 175.0 24.3 L 155.8 15.9" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 157.2 35.2 L 175.0 24.3 L 155.8 15.9" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 140.4 15.3 L 174.0 15.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 157.2 12.4 L 157.2 18.2" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="158.2" cy="20.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="158.2" cy="20.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="165.1" y1="19.4" x2="170.0" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="165.1" y1="19.4" x2="170.0" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["arm_r", "arm_l"], "working": ["arm_r", "arm_l"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 24} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 24}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 131 KiB

+1 -1
View File
@@ -8,7 +8,7 @@
<path id="pelvisBar" d="M 161.3 93.0 L 157.2 92.5 L 157.2 93.4" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 161.3 93.0 L 157.2 92.5 L 157.2 93.4" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 157.2 92.5 Q 157.2 62.5 157.2 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 157.2 92.5 Q 157.2 62.5 157.2 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 157.2 35.2 L 175.0 24.3 L 155.8 15.9" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 157.2 35.2 L 175.0 24.3 L 155.8 15.9" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 140.4 15.3 L 174.0 15.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 157.2 12.4 L 157.2 18.2" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="158.2" cy="20.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="158.2" cy="20.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="165.1" y1="19.4" x2="170.0" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="165.1" y1="19.4" x2="170.0" y2="18.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 115.1 110.5 L 111.0 110.0 L 111.0 110.9" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 115.1 110.5 L 111.0 110.0 L 111.0 110.9" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 111.0 110.0 Q 139.9 100.1 164.9 85.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 111.0 110.0 Q 139.9 100.1 164.9 85.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 164.9 86.6 L 165.3 107.3 L 164.9 128.0" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 164.9 86.6 L 165.3 107.3 L 164.9 128.0" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 148.2 127.3 L 184.6 127.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 166.4 124.2 L 166.4 130.5" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="148.2" cy="127.3" r="9.1" fill="#6b7180"/> <circle cx="166.4" cy="124.2" r="9.1" fill="#6b7180"/>
<circle cx="184.6" cy="127.3" r="9.1" fill="#6b7180"/> <circle cx="166.4" cy="130.5" r="9.1" fill="#6b7180"/>
<circle id="head" cx="177.8" cy="79.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="177.8" cy="79.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="184.7" y1="80.5" x2="189.6" y2="80.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="184.7" y1="80.5" x2="189.6" y2="80.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 162.7 90.9 L 158.6 90.4 L 158.6 91.3" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 162.7 90.9 L 158.6 90.4 L 158.6 91.3" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 158.6 90.4 Q 163.9 60.9 168.9 32.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 158.6 90.4 Q 163.9 60.9 168.9 32.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 168.9 34.0 L 173.2 54.3 L 166.3 73.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 168.9 34.0 L 173.2 54.3 L 166.3 73.8" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 149.5 73.2 L 185.9 73.2" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 167.7 70.0 L 167.7 76.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="149.5" cy="73.2" r="9.1" fill="#6b7180"/> <circle cx="167.7" cy="70.0" r="9.1" fill="#6b7180"/>
<circle cx="185.9" cy="73.2" r="9.1" fill="#6b7180"/> <circle cx="167.7" cy="76.3" r="9.1" fill="#6b7180"/>
<circle id="head" cx="171.8" cy="19.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="171.8" cy="19.2" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="178.8" y1="19.7" x2="183.7" y2="20.0" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="178.8" y1="19.7" x2="183.7" y2="20.0" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l", "spine"], "working": ["leg_r", "leg_l", "spine"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 173 KiB

@@ -8,9 +8,9 @@
<path id="pelvisBar" d="M 115.1 110.5 L 111.0 110.0 L 111.0 110.9" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 115.1 110.5 L 111.0 110.0 L 111.0 110.9" stroke="#0d9488" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 111.0 110.0 Q 139.9 100.1 164.9 85.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 111.0 110.0 Q 139.9 100.1 164.9 85.3" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 164.9 86.6 L 165.3 107.3 L 164.9 128.0" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 164.9 86.6 L 165.3 107.3 L 164.9 128.0" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 148.2 127.3 L 184.6 127.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 166.4 124.2 L 166.4 130.5" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="148.2" cy="127.3" r="9.1" fill="#6b7180"/> <circle cx="166.4" cy="124.2" r="9.1" fill="#6b7180"/>
<circle cx="184.6" cy="127.3" r="9.1" fill="#6b7180"/> <circle cx="166.4" cy="130.5" r="9.1" fill="#6b7180"/>
<circle id="head" cx="177.8" cy="79.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="177.8" cy="79.9" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="184.7" y1="80.5" x2="189.6" y2="80.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="184.7" y1="80.5" x2="189.6" y2="80.9" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

+15 -6
View File
@@ -179,12 +179,21 @@ authored yaw nothing moves, so the authored look is exact.
(`hand_r`, `foot_l`, …) plus the mid joints (`elbow_r`, `knee_l`, …), so a (`hand_r`, `foot_l`, …) plus the mid joints (`elbow_r`, `knee_l`, …), so a
machine pad can ride a knee (`["knee_r", "knee_l"]`) or span a shin machine pad can ride a knee (`["knee_r", "knee_l"]`) or span a shin
(`["knee_r", "foot_r"]`). (`["knee_r", "foot_r"]`).
`bar` lies at a fixed authored-view `angle` (default 0 = horizontal — in `bar` lies at a fixed authored-view `angle` (default 0 = horizontal);
side view a two-handed bar is drawn horizontal by convention); `dumbbell` `dumbbell` and `pad` default to perpendicular to the lower bone
and `pad` default to perpendicular to the lower bone (forearm/shin), or (forearm/shin), or take an explicit `angle`. Under orbit the segment
take an explicit `angle`. Under orbit the segment rotates with the scene rotates with the scene and foreshortens naturally. `plateR` puts filled
and foreshortens naturally. `plateR` puts filled discs on both ends discs on both ends (dumbbells default to 4.5).
(dumbbells default to 4.5). A cross-body rod — a barbell, pull-up bar, or any grip that really runs
left-right *through* both hands — should instead set `"axis": "z"`
(superseding `angle`): its world-space direction projects through the
camera elevation like the floor quad, so in a profile view it reads
end-on (plates nearly concentric, seen from slightly above), opens to
its full span face-on, and swings with the figure in between. A fixed
screen-space `angle` can't do this — it keeps the rod glued to the
authored direction while the body turns under it. Vertical handles
(`angle: 90`) don't need it: a world-vertical rod is unchanged by a yaw
orbit.
- **`roller`** — a machine roller pad seen end-on: a filled disc riding the - **`roller`** — a machine roller pad seen end-on: a filled disc riding the
limb's lower bone near the joint in `at`, on the `side` (+1/1) of the bone limb's lower bone near the joint in `at`, on the `side` (+1/1) of the bone
it presses — a leg extension's instep roller (`side: 1`), a leg curl's it presses — a leg extension's instep roller (`side: 1`), a leg curl's
@@ -12,7 +12,7 @@
<path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 95.1 52.0 L 110.1 77.6 L 110.1 48.0" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 95.1 52.0 L 110.1 77.6 L 110.1 48.0" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 103.1 47.1 L 123.1 47.1" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 113.1 45.4 L 113.1 48.8" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -12,7 +12,7 @@
<path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 95.1 52.0 L 112.8 28.1 L 133.6 6.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 95.1 52.0 L 112.8 28.1 L 133.6 6.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 126.6 5.9 L 146.6 5.9" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 136.6 4.2 L 136.6 7.6" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

+1 -1
View File
@@ -9,7 +9,7 @@
{"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5}, {"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5},
{"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5} {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 10}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 168 KiB

+1 -1
View File
@@ -12,7 +12,7 @@
<path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 120.0 130.0 Q 103.0 90.4 95.1 50.1" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="leg_r" d="M 120.0 131.2 L 161.9 112.6 L 164.0 151.9 L 175.0 151.3" stroke="#3a3f4b" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 95.1 52.0 L 112.8 28.1 L 133.6 6.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 95.1 52.0 L 112.8 28.1 L 133.6 6.8" stroke="#0d9488" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 126.6 5.9 L 146.6 5.9" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 136.6 4.2 L 136.6 7.6" stroke="#6b7180" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/> <circle id="head" cx="98.6" cy="30.7" r="10" fill="white" stroke="#3a3f4b" stroke-width="6"/>
<line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/> <line id="nose" x1="108.5" y1="29.3" x2="115.4" y2="28.3" stroke="#3a3f4b" stroke-width="4" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -10,7 +10,7 @@
<path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 162.3 35.3 L 151.5 53.0 L 168.4 40.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 162.3 35.3 L 151.5 53.0 L 168.4 40.7" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 162.8 40.1 L 176.8 40.1" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 169.8 38.9 L 169.8 41.3" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -10,7 +10,7 @@
<path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 162.3 35.3 L 158.8 55.7 L 165.6 75.2" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 162.3 35.3 L 158.8 55.7 L 165.6 75.2" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 160.0 74.6 L 174.0 74.6" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 167.0 73.4 L 167.0 75.8" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -8,7 +8,7 @@
{"kind": "circle", "c": [186, -58], "r": 4, "fill": true, "color": "prop"} {"kind": "circle", "c": [186, -58], "r": 4, "fill": true, "color": "prop"}
]}, ]},
{"type": "cable", "from": [186, -58], "to": ["hand_r", "hand_l"], "w": 3}, {"type": "cable", "from": [186, -58], "to": ["hand_r", "hand_l"], "w": 3},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 10}
], ],
"frames": [ "frames": [
{ {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 121 KiB

+1 -1
View File
@@ -10,7 +10,7 @@
<path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> <path id="pelvisBar" d="M 157.1 92.3 L 153.0 91.8 L 153.0 92.7" stroke="#3a3f4b" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="spine" d="M 153.0 91.8 Q 156.7 62.0 162.3 33.9" stroke="#3a3f4b" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="arm_r" d="M 162.3 35.3 L 158.8 55.7 L 165.6 75.2" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/> <path id="arm_r" d="M 162.3 35.3 L 158.8 55.7 L 165.6 75.2" stroke="#0d9488" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 160.0 74.6 L 174.0 74.6" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/> <path d="M 167.0 73.4 L 167.0 75.8" stroke="#6b7180" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/> <circle id="head" cx="166.2" cy="20.7" r="7.0" fill="white" stroke="#3a3f4b" stroke-width="4.2"/>
<line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/> <line id="nose" x1="173.1" y1="21.6" x2="177.9" y2="22.3" stroke="#3a3f4b" stroke-width="2.8" stroke-linecap="round"/>
<g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180"> <g font-family="-apple-system, Helvetica, sans-serif" font-size="11" fill="#6b7180">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 KiB

After

Width:  |  Height:  |  Size: 844 KiB

+21 -9
View File
@@ -340,7 +340,7 @@ def joint_points(geo, ref):
sum(p[1] for p in pts) / len(pts)), direction) sum(p[1] for p in pts) / len(pts)), direction)
def resolve_props(props, geo, anchor, rot=K.IDENTITY, auth_geo=None): def resolve_props(props, geo, anchor, rot=K.IDENTITY, auth_geo=None, pitch=CAMERA_PITCH):
"""Props -> drawable primitives for one frame: (background, foreground). """Props -> drawable primitives for one frame: (background, foreground).
`geo` is the frame's drawn (possibly orbit-rotated) geometry, `auth_geo` `geo` is the frame's drawn (possibly orbit-rotated) geometry, `auth_geo`
@@ -348,7 +348,9 @@ def resolve_props(props, geo, anchor, rot=K.IDENTITY, auth_geo=None):
frame's root canvas anchor, and `rot` the `prop_rotation` between them. frame's root canvas anchor, and `rot` the `prop_rotation` between them.
Joint positions come from `geo`; everything authored — scene points, Joint positions come from `geo`; everything authored — scene points,
cable anchors, bar angles, pad perpendiculars, roller offsets — resolves cable anchors, bar angles, pad perpendiculars, roller offsets — resolves
against `auth_geo` and rotates through `rot`. against `auth_geo` and rotates through `rot`. `pitch` is the camera
elevation, needed by `axis` props whose world-space direction projects
through it (like the floor quad).
""" """
auth = auth_geo if auth_geo is not None else geo auth = auth_geo if auth_geo is not None else geo
@@ -415,11 +417,21 @@ def resolve_props(props, geo, anchor, rot=K.IDENTITY, auth_geo=None):
_, d = joint_points(auth, p["at"]) _, d = joint_points(auth, p["at"])
if not c or not d: if not c or not d:
continue continue
if t == "bar" or "angle" in p: if p.get("axis") == "z":
# A cross-body rod (barbell, pull-up bar): its true 3D axis is
# the world left-right axis, projected through the camera
# elevation like the floor quad — a small vertical sliver
# end-on in a profile view (the plates read nearly concentric,
# seen from slightly above), full span face-on, swinging with
# the figure in between, symmetric at 0 and 180.
pr = math.radians(pitch)
ux, uy = swing((0.0, math.sin(pr)), math.cos(pr))
elif t == "bar" or "angle" in p:
axis = dirv(p.get("angle", 0)) # fixed authored-view angle axis = dirv(p.get("angle", 0)) # fixed authored-view angle
ux, uy = swing(axis) # foreshortens under orbit
else: else:
axis = (-d[1], d[0]) # perpendicular to the lower bone axis = (-d[1], d[0]) # perpendicular to the lower bone
ux, uy = swing(axis) # foreshortens under orbit ux, uy = swing(axis)
h = p.get("halfLen", {"bar": 24, "dumbbell": 7, "pad": 8}[t]) h = p.get("halfLen", {"bar": 24, "dumbbell": 7, "pad": 8}[t])
a = (c[0] - ux * h, c[1] - uy * h) a = (c[0] - ux * h, c[1] - uy * h)
b = (c[0] + ux * h, c[1] + uy * h) b = (c[0] + ux * h, c[1] + uy * h)
@@ -662,7 +674,7 @@ def render_exercise(folder, figure="neutral", flip=False, strict=False):
for nf in norms: for nf in norms:
out, geo, order, shade = frame_geometry(nf, prof, cam, flip, pitch, mat) out, geo, order, shade = frame_geometry(nf, prof, cam, flip, pitch, mat)
resolved.append(out) resolved.append(out)
prims = resolve_props(props, geo, nf["root"]["pos"]) prims = resolve_props(props, geo, nf["root"]["pos"], pitch=pitch)
geo, prims = apply_zoom(geo, prims, zoom) geo, prims = apply_zoom(geo, prims, zoom)
key_cells.append((geo, order, shade, prims)) key_cells.append((geo, order, shade, prims))
@@ -682,7 +694,7 @@ def render_exercise(folder, figure="neutral", flip=False, strict=False):
imgs = [] imgs = []
for nf in timeline(resolved): for nf in timeline(resolved):
geo, order, shade = geometry(nf) geo, order, shade = geometry(nf)
prims = resolve_props(props, geo, nf["root"]["pos"]) prims = resolve_props(props, geo, nf["root"]["pos"], pitch=pitch)
geo, prims = apply_zoom(geo, prims, zoom) geo, prims = apply_zoom(geo, prims, zoom)
imgs.append(draw_geo(geo, order, shade, working, colors, font=font, prims=prims)) imgs.append(draw_geo(geo, order, shade, working, colors, font=font, prims=prims))
imgs[0].save(folder / "preview.gif", save_all=True, append_images=imgs[1:], imgs[0].save(folder / "preview.gif", save_all=True, append_images=imgs[1:],
@@ -716,7 +728,7 @@ def render_orbit(folder, figure="neutral"):
posed["pins"] = {} posed["pins"] = {}
_, geo, order, shade = frame_geometry(posed, prof, cam + off, pitch=pitch, mat=mat) _, geo, order, shade = frame_geometry(posed, prof, cam + off, pitch=pitch, mat=mat)
prims = resolve_props(props, geo, nf["root"]["pos"], prims = resolve_props(props, geo, nf["root"]["pos"],
prop_rotation(pitch, off), auth_geo) prop_rotation(pitch, off), auth_geo, pitch=pitch)
geo, prims = apply_zoom(geo, prims, zoom) geo, prims = apply_zoom(geo, prims, zoom)
imgs.append(draw_geo(geo, order, shade, working, colors, font=font, prims=prims)) imgs.append(draw_geo(geo, order, shade, working, colors, font=font, prims=prims))
imgs[0].save(folder / "orbit.gif", save_all=True, append_images=imgs[1:], imgs[0].save(folder / "orbit.gif", save_all=True, append_images=imgs[1:],
@@ -734,7 +746,7 @@ def contact_sheet(folders, figure="neutral", out=None):
mat = mat_bounds(norms, prof, cam, pitch) mat = mat_bounds(norms, prof, cam, pitch)
for i, nf in enumerate(norms, start=1): for i, nf in enumerate(norms, start=1):
_, geo, order, shade = frame_geometry(nf, prof, cam, pitch=pitch, mat=mat) _, geo, order, shade = frame_geometry(nf, prof, cam, pitch=pitch, mat=mat)
prims = resolve_props(props, geo, nf["root"]["pos"]) prims = resolve_props(props, geo, nf["root"]["pos"], pitch=pitch)
geo, prims = apply_zoom(geo, prims, zoom) geo, prims = apply_zoom(geo, prims, zoom)
cells.append((f"{motion['name']} {i}/{len(norms)}", cells.append((f"{motion['name']} {i}/{len(norms)}",
draw_geo(geo, order, shade, working, PALETTES["default"], draw_geo(geo, order, shade, working, PALETTES["default"],
@@ -760,7 +772,7 @@ def demo_sheet(folder):
norms, prof, cam, pitch, props, zoom = prepare(motion, figure, flip) norms, prof, cam, pitch, props, zoom = prepare(motion, figure, flip)
mat = mat_bounds(norms, prof, cam, pitch) mat = mat_bounds(norms, prof, cam, pitch)
_, geo, order, shade = frame_geometry(norms[idx], prof, cam, flip, pitch, mat) _, geo, order, shade = frame_geometry(norms[idx], prof, cam, flip, pitch, mat)
prims = resolve_props(props, geo, norms[idx]["root"]["pos"]) prims = resolve_props(props, geo, norms[idx]["root"]["pos"], pitch=pitch)
geo, prims = apply_zoom(geo, prims, zoom) geo, prims = apply_zoom(geo, prims, zoom)
cells.append((f"{motion['name']}{label}", cells.append((f"{motion['name']}{label}",
draw_geo(geo, order, shade, working, PALETTES[palette], draw_geo(geo, order, shade, working, PALETTES[palette],
@@ -178,6 +178,10 @@ struct MotionProp: Codable {
/// Fixed world angle (degrees, y-up). Default: bars are horizontal; /// Fixed world angle (degrees, y-up). Default: bars are horizontal;
/// dumbbells/pads sit perpendicular to the lower bone. /// dumbbells/pads sit perpendicular to the lower bone.
let angle: Double? let angle: Double?
/// True 3D axis, superseding `angle`: `"z"` marks a cross-body rod
/// (barbell, pull-up bar) whose projection foreshortens naturally
/// end-on in a profile view, full span face-on.
let axis: String?
let halfLen: Double? let halfLen: Double?
let w: Double? let w: Double?
/// End-disc radius (dumbbell plates default 4.5; bars none). /// End-disc radius (dumbbell plates default 4.5; bars none).
+23 -9
View File
@@ -576,10 +576,13 @@ enum MotionSolver {
/// `anchor` the frame's root canvas anchor, and `rotation` the `propRotation` /// `anchor` the frame's root canvas anchor, and `rotation` the `propRotation`
/// between them. Joint positions come from `geo`; everything authored scene /// between them. Joint positions come from `geo`; everything authored scene
/// points, cable anchors, bar angles, pad perpendiculars, roller offsets /// points, cable anchors, bar angles, pad perpendiculars, roller offsets
/// resolves against `authored` and rotates. Kept 1:1 with the reference /// resolves against `authored` and rotates. `pitch` is the camera elevation,
/// renderer's `resolve_props` change them in lockstep. /// needed by `axis` props whose world-space direction projects through it
/// (like the floor quad). Kept 1:1 with the reference renderer's
/// `resolve_props` change them in lockstep.
static func resolveProps(_ props: [MotionProp], geo: FigureGeometry, authored: FigureGeometry, static func resolveProps(_ props: [MotionProp], geo: FigureGeometry, authored: FigureGeometry,
anchor: CGPoint, rotation: Mat3?) -> (bg: [PropPrimitive], fg: [PropPrimitive]) { anchor: CGPoint, rotation: Mat3?,
pitch: Double = MotionSolver.defaultPitch) -> (bg: [PropPrimitive], fg: [PropPrimitive]) {
/// Authored canvas point (+ depth toward the camera) drawn canvas. /// Authored canvas point (+ depth toward the camera) drawn canvas.
func place(_ x: Double, _ y: Double, _ z: Double) -> CGPoint { func place(_ x: Double, _ y: Double, _ z: Double) -> CGPoint {
guard let rotation else { return CGPoint(x: x, y: y) } guard let rotation else { return CGPoint(x: x, y: y) }
@@ -654,13 +657,23 @@ enum MotionSolver {
} }
guard let at = prop.at, let now = jointAnchor(geo, at), guard let at = prop.at, let now = jointAnchor(geo, at),
let auth = jointAnchor(authored, at) else { continue } let auth = jointAnchor(authored, at) else { continue }
let axis: CGVector let u: CGVector
if prop.type == "bar" || prop.angle != nil { if prop.axis == "z" {
axis = direction(prop.angle ?? 0) // fixed authored-view angle // A cross-body rod (barbell, pull-up bar): its true 3D axis
// is the world left-right axis, projected through the camera
// elevation like the floor quad a small vertical sliver
// end-on in a profile view (the plates read nearly
// concentric, seen from slightly above), full span face-on,
// swinging with the figure in between, symmetric at 0 and 180.
let pr = pitch * .pi / 180
let axis = Vec3(0, -sin(pr), cos(pr))
let v = rotation?.apply(axis) ?? axis
u = CGVector(dx: v.x, dy: -v.y)
} else if prop.type == "bar" || prop.angle != nil {
u = swing(direction(prop.angle ?? 0)) // fixed authored-view angle, foreshortens under orbit
} else { } else {
axis = CGVector(dx: -auth.direction.dy, dy: auth.direction.dx) u = swing(CGVector(dx: -auth.direction.dy, dy: auth.direction.dx))
} }
let u = swing(axis) // foreshortens under orbit
let h = prop.halfLen ?? defaults.halfLen let h = prop.halfLen ?? defaults.halfLen
let a = CGPoint(x: now.point.x - u.dx * h, y: now.point.y - u.dy * h) let a = CGPoint(x: now.point.x - u.dx * h, y: now.point.y - u.dy * h)
let b = CGPoint(x: now.point.x + u.dx * h, y: now.point.y + u.dy * h) let b = CGPoint(x: now.point.x + u.dx * h, y: now.point.y + u.dy * h)
@@ -764,7 +777,8 @@ struct MotionTimeline {
guard !props.isEmpty else { return geo } guard !props.isEmpty else { return geo }
let rotation = MotionSolver.propRotation(pitch: pitch, yawOffset: yawOffset) let rotation = MotionSolver.propRotation(pitch: pitch, yawOffset: yawOffset)
(geo.propsBackground, geo.propsForeground) = MotionSolver.resolveProps( (geo.propsBackground, geo.propsForeground) = MotionSolver.resolveProps(
props, geo: geo, authored: authored, anchor: frame.rootPos, rotation: rotation) props, geo: geo, authored: authored, anchor: frame.rootPos, rotation: rotation,
pitch: pitch)
return geo return geo
} }
} }
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l"], "working": ["leg_r", "leg_l"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 14} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 14}
], ],
"frames": [ "frames": [
{ {
@@ -8,7 +8,7 @@
{"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4}, {"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4},
{"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4} {"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
], ],
"frames": [ "frames": [
{ {
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l", "spine"], "working": ["leg_r", "leg_l", "spine"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 16} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 16}
], ],
"frames": [ "frames": [
{ {
@@ -12,24 +12,24 @@
"root": {"pos": [160, 66], "pitch": 5}, "root": {"pos": [160, 66], "pitch": 5},
"spine": [0, 0], "spine": [0, 0],
"neck": 2, "head": -6, "neck": 2, "head": -6,
"shoulder_r": 38, "elbow_r": 125, "shoulder_r": 5, "elbow_r": 140,
"shoulder_l": 38, "elbow_l": 125, "shoulder_l": 5, "elbow_l": 140,
"hip_r": 5, "knee_r": 4, "ankle_r": 0, "hip_r": 5, "knee_r": 4, "ankle_r": 0,
"hip_l": 5, "knee_l": 4, "ankle_l": 0, "hip_l": 5, "knee_l": 4, "ankle_l": 0,
"pins": {"foot_r": [162, 148], "foot_l": [166, 150], "pins": {"foot_r": [162, 148], "foot_l": [166, 150],
"hand_r": [176, -2], "hand_l": [180, 0]} "hand_r": [185, -8], "hand_l": [189, -6]}
}, },
{ {
"hold": 0.4, "tween": 1.0, "hold": 0.4, "tween": 1.0,
"root": {"pos": [150, 104], "pitch": 22}, "root": {"pos": [150, 104], "pitch": 22},
"spine": [0, -4], "spine": [0, -4],
"neck": 4, "head": -18, "neck": 4, "head": -18,
"shoulder_r": 46, "elbow_r": 120, "shoulder_r": 15, "elbow_r": 135,
"shoulder_l": 46, "elbow_l": 120, "shoulder_l": 15, "elbow_l": 135,
"hip_r": 96, "knee_r": 116, "ankle_r": 20, "hip_r": 96, "knee_r": 116, "ankle_r": 20,
"hip_l": 96, "knee_l": 116, "ankle_l": 20, "hip_l": 96, "knee_l": 116, "ankle_l": 20,
"pins": {"foot_r": [162, 148], "foot_l": [166, 150], "pins": {"foot_r": [162, 148], "foot_l": [166, 150],
"hand_r": [190, 40], "hand_l": [194, 42]} "hand_r": [196, 36], "hand_l": [200, 38]}
} }
] ]
} }
@@ -7,7 +7,7 @@
{"kind": "line", "pts": [[50, 122], [88, 122]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[50, 122], [88, 122]], "w": 9, "depth": 8},
{"kind": "line", "pts": [[68, 127], [68, 150]], "w": 5} {"kind": "line", "pts": [[68, 127], [68, 150]], "w": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
], ],
"frames": [ "frames": [
{ {
@@ -9,7 +9,7 @@
{"kind": "line", "pts": [[140, 130], [166, 127]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[140, 130], [166, 127]], "w": 8, "depth": 8},
{"kind": "line", "pts": [[152, 133], [152, 150]], "w": 5} {"kind": "line", "pts": [[152, 133], [152, 150]], "w": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
], ],
"frames": [ "frames": [
{ {
@@ -9,7 +9,7 @@
{"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"} {"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"}
]}, ]},
{"type": "cable", "from": [272, 19], "to": ["hand_r", "hand_l"], "w": 4}, {"type": "cable", "from": [272, 19], "to": ["hand_r", "hand_l"], "w": 4},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 24} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 24}
], ],
"frames": [ "frames": [
{ {
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["arm_r", "arm_l"], "working": ["arm_r", "arm_l"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 24} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 24}
], ],
"frames": [ "frames": [
{ {
@@ -4,7 +4,7 @@
"camera": {"zoom": 0.7}, "camera": {"zoom": 0.7},
"working": ["leg_r", "leg_l", "spine"], "working": ["leg_r", "leg_l", "spine"],
"props": [ "props": [
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
], ],
"frames": [ "frames": [
{ {
@@ -9,7 +9,7 @@
{"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5}, {"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5},
{"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5} {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5}
]}, ]},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 10}
], ],
"frames": [ "frames": [
{ {
@@ -8,7 +8,7 @@
{"kind": "circle", "c": [186, -58], "r": 4, "fill": true, "color": "prop"} {"kind": "circle", "c": [186, -58], "r": 4, "fill": true, "color": "prop"}
]}, ]},
{"type": "cable", "from": [186, -58], "to": ["hand_r", "hand_l"], "w": 3}, {"type": "cable", "from": [186, -58], "to": ["hand_r", "hand_l"], "w": 3},
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} {"type": "bar", "axis": "z", "at": ["hand_r", "hand_l"], "halfLen": 10}
], ],
"frames": [ "frames": [
{ {
+2 -2
View File
@@ -131,7 +131,7 @@ struct ExerciseMotionTests {
bundle.url(forResource: "figure-fixtures", withExtension: "json"), bundle.url(forResource: "figure-fixtures", withExtension: "json"),
"figure-fixtures.json must be bundled as a WorkoutsTests resource (see project.yml)") "figure-fixtures.json must be bundled as a WorkoutsTests resource (see project.yml)")
let fixtures = try JSONDecoder().decode(FigureFixtures.self, from: Data(contentsOf: url)) let fixtures = try JSONDecoder().decode(FigureFixtures.self, from: Data(contentsOf: url))
#expect(fixtures.exercises.count == 47) #expect(fixtures.exercises.count == 64)
for exercise in fixtures.exercises { for exercise in fixtures.exercises {
let resources = try #require(ExerciseMotionLibrary.resources(for: exercise.name), let resources = try #require(ExerciseMotionLibrary.resources(for: exercise.name),
@@ -164,7 +164,7 @@ struct ExerciseMotionTests {
let rotation = MotionSolver.propRotation(pitch: fixtures.pitch, yawOffset: orbit.yaw - cam) let rotation = MotionSolver.propRotation(pitch: fixtures.pitch, yawOffset: orbit.yaw - cam)
let (bg, fg) = MotionSolver.resolveProps( let (bg, fg) = MotionSolver.resolveProps(
resources.motion.props ?? [], geo: geo, authored: authored, resources.motion.props ?? [], geo: geo, authored: authored,
anchor: norms[0].rootPos, rotation: rotation) anchor: norms[0].rootPos, rotation: rotation, pitch: fixtures.pitch)
expectPrims(bg, propFixture.bg, "\(exercise.name) orbit \(orbit.yaw) bg") expectPrims(bg, propFixture.bg, "\(exercise.name) orbit \(orbit.yaw) bg")
expectPrims(fg, propFixture.fg, "\(exercise.name) orbit \(orbit.yaw) fg") expectPrims(fg, propFixture.fg, "\(exercise.name) orbit \(orbit.yaw) fg")
} }
File diff suppressed because one or more lines are too long