diff --git a/Exercise Library/Abdominal/frames/frame-1.svg b/Exercise Library/Abdominal/frames/frame-1.svg index 6ec8e41..aadcd30 100644 --- a/Exercise Library/Abdominal/frames/frame-1.svg +++ b/Exercise Library/Abdominal/frames/frame-1.svg @@ -1,11 +1,11 @@ Abdominal - - + + - - + + diff --git a/Exercise Library/Abdominal/frames/frame-2.svg b/Exercise Library/Abdominal/frames/frame-2.svg index b336ec9..97a4c09 100644 --- a/Exercise Library/Abdominal/frames/frame-2.svg +++ b/Exercise Library/Abdominal/frames/frame-2.svg @@ -1,11 +1,11 @@ Abdominal - - + + - - + + diff --git a/Exercise Library/Abdominal/motion.json b/Exercise Library/Abdominal/motion.json index f41fc49..8f96651 100644 --- a/Exercise Library/Abdominal/motion.json +++ b/Exercise Library/Abdominal/motion.json @@ -4,11 +4,11 @@ "working": ["spine"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[120, 128], [114, 62]], "w": 8}, - {"kind": "line", "pts": [[106, 130], [150, 130]], "w": 8}, + {"kind": "line", "pts": [[120, 128], [114, 62]], "w": 8, "depth": 7}, + {"kind": "line", "pts": [[106, 130], [150, 130]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[122, 132], [122, 150]], "w": 4}, - {"kind": "line", "pts": [[102, 150], [150, 150]], "w": 4}, - {"kind": "line", "pts": [[156, 149], [190, 149]], "w": 5} + {"kind": "line", "pts": [[102, 150], [150, 150]], "w": 4, "depth": 5}, + {"kind": "line", "pts": [[156, 149], [190, 149]], "w": 5, "depth": 6} ]}, {"type": "pad", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 14, "w": 6} ], diff --git a/Exercise Library/Abdominal/preview.gif b/Exercise Library/Abdominal/preview.gif index 71b5b34..3eeba54 100644 Binary files a/Exercise Library/Abdominal/preview.gif and b/Exercise Library/Abdominal/preview.gif differ diff --git a/Exercise Library/Abdominal/visual.svg b/Exercise Library/Abdominal/visual.svg index b336ec9..97a4c09 100644 --- a/Exercise Library/Abdominal/visual.svg +++ b/Exercise Library/Abdominal/visual.svg @@ -1,11 +1,11 @@ Abdominal - - + + - - + + diff --git a/Exercise Library/Abductor/frames/frame-1.svg b/Exercise Library/Abductor/frames/frame-1.svg index e01cdd7..83d571d 100644 --- a/Exercise Library/Abductor/frames/frame-1.svg +++ b/Exercise Library/Abductor/frames/frame-1.svg @@ -1,8 +1,8 @@ Abductor - - + + diff --git a/Exercise Library/Abductor/frames/frame-2.svg b/Exercise Library/Abductor/frames/frame-2.svg index 11d270b..6784061 100644 --- a/Exercise Library/Abductor/frames/frame-2.svg +++ b/Exercise Library/Abductor/frames/frame-2.svg @@ -1,8 +1,8 @@ Abductor - - + + diff --git a/Exercise Library/Abductor/motion.json b/Exercise Library/Abductor/motion.json index ee56697..e8db4c0 100644 --- a/Exercise Library/Abductor/motion.json +++ b/Exercise Library/Abductor/motion.json @@ -5,8 +5,8 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "rect", "x": 152, "y": 56, "w": 16, "h": 72, "r": 5}, - {"kind": "rect", "x": 130, "y": 126, "w": 60, "h": 10, "r": 3}, + {"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6}, + {"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12}, {"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6} ]}, {"type": "pad", "at": ["knee_r"], "angle": 90, "halfLen": 13, "w": 6}, diff --git a/Exercise Library/Abductor/preview.gif b/Exercise Library/Abductor/preview.gif index 4905e72..d27f921 100644 Binary files a/Exercise Library/Abductor/preview.gif and b/Exercise Library/Abductor/preview.gif differ diff --git a/Exercise Library/Abductor/visual.svg b/Exercise Library/Abductor/visual.svg index 11d270b..6784061 100644 --- a/Exercise Library/Abductor/visual.svg +++ b/Exercise Library/Abductor/visual.svg @@ -1,8 +1,8 @@ Abductor - - + + diff --git a/Exercise Library/Adductor/frames/frame-1.svg b/Exercise Library/Adductor/frames/frame-1.svg index 13116ee..7be524d 100644 --- a/Exercise Library/Adductor/frames/frame-1.svg +++ b/Exercise Library/Adductor/frames/frame-1.svg @@ -1,8 +1,8 @@ Adductor - - + + diff --git a/Exercise Library/Adductor/frames/frame-2.svg b/Exercise Library/Adductor/frames/frame-2.svg index 8616e78..7b4b5fb 100644 --- a/Exercise Library/Adductor/frames/frame-2.svg +++ b/Exercise Library/Adductor/frames/frame-2.svg @@ -1,8 +1,8 @@ Adductor - - + + diff --git a/Exercise Library/Adductor/motion.json b/Exercise Library/Adductor/motion.json index 6ffbf73..05f0126 100644 --- a/Exercise Library/Adductor/motion.json +++ b/Exercise Library/Adductor/motion.json @@ -5,8 +5,8 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "rect", "x": 152, "y": 56, "w": 16, "h": 72, "r": 5}, - {"kind": "rect", "x": 130, "y": 126, "w": 60, "h": 10, "r": 3}, + {"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6}, + {"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12}, {"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6} ]}, {"type": "pad", "at": ["knee_r"], "angle": 90, "halfLen": 13, "w": 6}, diff --git a/Exercise Library/Adductor/preview.gif b/Exercise Library/Adductor/preview.gif index 40919c8..29c5083 100644 Binary files a/Exercise Library/Adductor/preview.gif and b/Exercise Library/Adductor/preview.gif differ diff --git a/Exercise Library/Adductor/visual.svg b/Exercise Library/Adductor/visual.svg index 8616e78..7b4b5fb 100644 --- a/Exercise Library/Adductor/visual.svg +++ b/Exercise Library/Adductor/visual.svg @@ -1,8 +1,8 @@ Adductor - - + + diff --git a/Exercise Library/Arm Curl/frames/frame-1.svg b/Exercise Library/Arm Curl/frames/frame-1.svg index dd39282..d91f517 100644 --- a/Exercise Library/Arm Curl/frames/frame-1.svg +++ b/Exercise Library/Arm Curl/frames/frame-1.svg @@ -1,8 +1,8 @@ Arm Curl - - + + diff --git a/Exercise Library/Arm Curl/frames/frame-2.svg b/Exercise Library/Arm Curl/frames/frame-2.svg index df9b48a..7eb824d 100644 --- a/Exercise Library/Arm Curl/frames/frame-2.svg +++ b/Exercise Library/Arm Curl/frames/frame-2.svg @@ -1,8 +1,8 @@ Arm Curl - - + + diff --git a/Exercise Library/Arm Curl/motion.json b/Exercise Library/Arm Curl/motion.json index 23eb200..211ab99 100644 --- a/Exercise Library/Arm Curl/motion.json +++ b/Exercise Library/Arm Curl/motion.json @@ -4,8 +4,8 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 134], [150, 134]], "w": 8}, - {"kind": "line", "pts": [[136, 52], [164, 70]], "w": 8}, + {"kind": "line", "pts": [[116, 134], [150, 134]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[136, 52], [164, 70]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[164, 70], [164, 128]], "w": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 6} diff --git a/Exercise Library/Arm Curl/preview.gif b/Exercise Library/Arm Curl/preview.gif index fb46a70..12b9afc 100644 Binary files a/Exercise Library/Arm Curl/preview.gif and b/Exercise Library/Arm Curl/preview.gif differ diff --git a/Exercise Library/Arm Curl/visual.svg b/Exercise Library/Arm Curl/visual.svg index df9b48a..7eb824d 100644 --- a/Exercise Library/Arm Curl/visual.svg +++ b/Exercise Library/Arm Curl/visual.svg @@ -1,8 +1,8 @@ Arm Curl - - + + diff --git a/Exercise Library/Calfs/frames/frame-1.svg b/Exercise Library/Calfs/frames/frame-1.svg index cb158c8..ec1b41e 100644 --- a/Exercise Library/Calfs/frames/frame-1.svg +++ b/Exercise Library/Calfs/frames/frame-1.svg @@ -1,10 +1,10 @@ Calfs - + - - + + diff --git a/Exercise Library/Calfs/frames/frame-2.svg b/Exercise Library/Calfs/frames/frame-2.svg index a37332d..6541bd2 100644 --- a/Exercise Library/Calfs/frames/frame-2.svg +++ b/Exercise Library/Calfs/frames/frame-2.svg @@ -1,10 +1,10 @@ Calfs - + - - + + diff --git a/Exercise Library/Calfs/motion.json b/Exercise Library/Calfs/motion.json index 0dc1341..8982bb9 100644 --- a/Exercise Library/Calfs/motion.json +++ b/Exercise Library/Calfs/motion.json @@ -4,10 +4,10 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[124, 126], [158, 124]], "w": 9}, + {"kind": "line", "pts": [[124, 126], [158, 124]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[138, 128], [138, 150]], "w": 5}, - {"kind": "line", "pts": [[120, 150], [156, 150]], "w": 5}, - {"kind": "rect", "x": 198, "y": 147, "w": 34, "h": 6, "r": 1}, + {"kind": "line", "pts": [[120, 150], [156, 150]], "w": 5, "depth": 5}, + {"kind": "line", "pts": [[201, 150], [229, 150]], "w": 6, "depth": 7}, {"kind": "line", "pts": [[183, 62], [183, 122]], "w": 4}, {"kind": "line", "pts": [[164, 76], [183, 76]], "w": 3, "color": "prop"} ]}, diff --git a/Exercise Library/Calfs/preview.gif b/Exercise Library/Calfs/preview.gif index 2c2c443..5db2bba 100644 Binary files a/Exercise Library/Calfs/preview.gif and b/Exercise Library/Calfs/preview.gif differ diff --git a/Exercise Library/Calfs/visual.svg b/Exercise Library/Calfs/visual.svg index a37332d..6541bd2 100644 --- a/Exercise Library/Calfs/visual.svg +++ b/Exercise Library/Calfs/visual.svg @@ -1,10 +1,10 @@ Calfs - + - - + + diff --git a/Exercise Library/Chest Press/frames/frame-1.svg b/Exercise Library/Chest Press/frames/frame-1.svg index da7e3a8..0ae71a8 100644 --- a/Exercise Library/Chest Press/frames/frame-1.svg +++ b/Exercise Library/Chest Press/frames/frame-1.svg @@ -1,10 +1,10 @@ Chest Press - - + + - + diff --git a/Exercise Library/Chest Press/frames/frame-2.svg b/Exercise Library/Chest Press/frames/frame-2.svg index 1f6f46c..7ac4115 100644 --- a/Exercise Library/Chest Press/frames/frame-2.svg +++ b/Exercise Library/Chest Press/frames/frame-2.svg @@ -1,10 +1,10 @@ Chest Press - - + + - + diff --git a/Exercise Library/Chest Press/motion.json b/Exercise Library/Chest Press/motion.json index 2369b0a..93f8fca 100644 --- a/Exercise Library/Chest Press/motion.json +++ b/Exercise Library/Chest Press/motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[114, 132], [86, 40]], "w": 8}, - {"kind": "line", "pts": [[106, 133], [146, 133]], "w": 8}, + {"kind": "line", "pts": [[114, 132], [86, 40]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[106, 133], [146, 133]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[122, 135], [122, 151]], "w": 5}, - {"kind": "line", "pts": [[108, 151], [138, 151]], "w": 4} + {"kind": "line", "pts": [[108, 151], [138, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 8} ], diff --git a/Exercise Library/Chest Press/preview.gif b/Exercise Library/Chest Press/preview.gif index b0eb3b9..c097605 100644 Binary files a/Exercise Library/Chest Press/preview.gif and b/Exercise Library/Chest Press/preview.gif differ diff --git a/Exercise Library/Chest Press/visual.svg b/Exercise Library/Chest Press/visual.svg index 1f6f46c..7ac4115 100644 --- a/Exercise Library/Chest Press/visual.svg +++ b/Exercise Library/Chest Press/visual.svg @@ -1,10 +1,10 @@ Chest Press - - + + - + diff --git a/Exercise Library/Lat Pull Down/frames/frame-1.svg b/Exercise Library/Lat Pull Down/frames/frame-1.svg index e28b024..77e1f20 100644 --- a/Exercise Library/Lat Pull Down/frames/frame-1.svg +++ b/Exercise Library/Lat Pull Down/frames/frame-1.svg @@ -1,7 +1,7 @@ Lat Pull Down - + diff --git a/Exercise Library/Lat Pull Down/frames/frame-2.svg b/Exercise Library/Lat Pull Down/frames/frame-2.svg index 5368fb5..c7ef21f 100644 --- a/Exercise Library/Lat Pull Down/frames/frame-2.svg +++ b/Exercise Library/Lat Pull Down/frames/frame-2.svg @@ -1,7 +1,7 @@ Lat Pull Down - + diff --git a/Exercise Library/Lat Pull Down/motion.json b/Exercise Library/Lat Pull Down/motion.json index 78202df..e0b24ca 100644 --- a/Exercise Library/Lat Pull Down/motion.json +++ b/Exercise Library/Lat Pull Down/motion.json @@ -4,7 +4,7 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[126, 130], [162, 130]], "w": 8}, + {"kind": "line", "pts": [[126, 130], [162, 130]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[144, 132], [144, 150]], "w": 5}, {"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"} ]}, diff --git a/Exercise Library/Lat Pull Down/preview.gif b/Exercise Library/Lat Pull Down/preview.gif index b14b6f3..0e72dee 100644 Binary files a/Exercise Library/Lat Pull Down/preview.gif and b/Exercise Library/Lat Pull Down/preview.gif differ diff --git a/Exercise Library/Lat Pull Down/visual.svg b/Exercise Library/Lat Pull Down/visual.svg index 5368fb5..c7ef21f 100644 --- a/Exercise Library/Lat Pull Down/visual.svg +++ b/Exercise Library/Lat Pull Down/visual.svg @@ -1,7 +1,7 @@ Lat Pull Down - + diff --git a/Exercise Library/Leg Curl/frames/frame-1.svg b/Exercise Library/Leg Curl/frames/frame-1.svg index 9d3afe7..680ad19 100644 --- a/Exercise Library/Leg Curl/frames/frame-1.svg +++ b/Exercise Library/Leg Curl/frames/frame-1.svg @@ -1,12 +1,12 @@ Leg Curl - - - + + + - + diff --git a/Exercise Library/Leg Curl/frames/frame-2.svg b/Exercise Library/Leg Curl/frames/frame-2.svg index 3317dfd..3563402 100644 --- a/Exercise Library/Leg Curl/frames/frame-2.svg +++ b/Exercise Library/Leg Curl/frames/frame-2.svg @@ -1,12 +1,12 @@ Leg Curl - - - + + + - + diff --git a/Exercise Library/Leg Curl/motion.json b/Exercise Library/Leg Curl/motion.json index c82136d..11cb940 100644 --- a/Exercise Library/Leg Curl/motion.json +++ b/Exercise Library/Leg Curl/motion.json @@ -4,12 +4,12 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9}, - {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9}, - {"kind": "line", "pts": [[130, 105], [158, 106]], "w": 7}, + {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[130, 105], [158, 106]], "w": 7, "depth": 7}, {"kind": "line", "pts": [[108, 126], [108, 150]], "w": 5}, {"kind": "line", "pts": [[160, 124], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5}, + {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5, "depth": 5}, {"kind": "circle", "c": [114, 90], "r": 3.5, "fill": true, "color": "prop"} ]}, {"type": "roller", "at": ["foot_r", "foot_l"], "side": -1, "r": 5, "back": 3} diff --git a/Exercise Library/Leg Curl/preview.gif b/Exercise Library/Leg Curl/preview.gif index 69e07cc..cc73dc7 100644 Binary files a/Exercise Library/Leg Curl/preview.gif and b/Exercise Library/Leg Curl/preview.gif differ diff --git a/Exercise Library/Leg Curl/visual.svg b/Exercise Library/Leg Curl/visual.svg index 3317dfd..3563402 100644 --- a/Exercise Library/Leg Curl/visual.svg +++ b/Exercise Library/Leg Curl/visual.svg @@ -1,12 +1,12 @@ Leg Curl - - - + + + - + diff --git a/Exercise Library/Leg Extension/frames/frame-1.svg b/Exercise Library/Leg Extension/frames/frame-1.svg index 200de12..f5d713e 100644 --- a/Exercise Library/Leg Extension/frames/frame-1.svg +++ b/Exercise Library/Leg Extension/frames/frame-1.svg @@ -1,11 +1,11 @@ Leg Extension - - + + - + diff --git a/Exercise Library/Leg Extension/frames/frame-2.svg b/Exercise Library/Leg Extension/frames/frame-2.svg index b79a653..be42fe5 100644 --- a/Exercise Library/Leg Extension/frames/frame-2.svg +++ b/Exercise Library/Leg Extension/frames/frame-2.svg @@ -1,11 +1,11 @@ Leg Extension - - + + - + diff --git a/Exercise Library/Leg Extension/motion.json b/Exercise Library/Leg Extension/motion.json index afcbadf..7762e35 100644 --- a/Exercise Library/Leg Extension/motion.json +++ b/Exercise Library/Leg Extension/motion.json @@ -4,11 +4,11 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9}, - {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9}, + {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[108, 126], [108, 150]], "w": 5}, {"kind": "line", "pts": [[160, 124], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5}, + {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5, "depth": 5}, {"kind": "circle", "c": [114, 90], "r": 3.5, "fill": true, "color": "prop"} ]}, {"type": "roller", "at": ["foot_r", "foot_l"], "side": 1, "r": 5, "back": 7} diff --git a/Exercise Library/Leg Extension/preview.gif b/Exercise Library/Leg Extension/preview.gif index eef14fa..06ac716 100644 Binary files a/Exercise Library/Leg Extension/preview.gif and b/Exercise Library/Leg Extension/preview.gif differ diff --git a/Exercise Library/Leg Extension/visual.svg b/Exercise Library/Leg Extension/visual.svg index b79a653..be42fe5 100644 --- a/Exercise Library/Leg Extension/visual.svg +++ b/Exercise Library/Leg Extension/visual.svg @@ -1,11 +1,11 @@ Leg Extension - - + + - + diff --git a/Exercise Library/Leg Press/frames/frame-1.svg b/Exercise Library/Leg Press/frames/frame-1.svg index b95fdb0..1684b42 100644 --- a/Exercise Library/Leg Press/frames/frame-1.svg +++ b/Exercise Library/Leg Press/frames/frame-1.svg @@ -1,10 +1,10 @@ Leg Press - - + + - + diff --git a/Exercise Library/Leg Press/frames/frame-2.svg b/Exercise Library/Leg Press/frames/frame-2.svg index eb0f2a9..52ac48d 100644 --- a/Exercise Library/Leg Press/frames/frame-2.svg +++ b/Exercise Library/Leg Press/frames/frame-2.svg @@ -1,10 +1,10 @@ Leg Press - - + + - + diff --git a/Exercise Library/Leg Press/motion.json b/Exercise Library/Leg Press/motion.json index 78ee2e0..69430de 100644 --- a/Exercise Library/Leg Press/motion.json +++ b/Exercise Library/Leg Press/motion.json @@ -4,10 +4,10 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9}, - {"kind": "line", "pts": [[126, 127], [156, 122]], "w": 9}, + {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[126, 127], [156, 122]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[138, 130], [138, 150]], "w": 5}, - {"kind": "line", "pts": [[118, 150], [158, 150]], "w": 5}, + {"kind": "line", "pts": [[118, 150], [158, 150]], "w": 5, "depth": 5}, {"kind": "line", "pts": [[142, 90], [142, 78]], "w": 3}, {"kind": "circle", "c": [142, 77], "r": 3.5, "fill": true, "color": "prop"} ]}, diff --git a/Exercise Library/Leg Press/preview.gif b/Exercise Library/Leg Press/preview.gif index 7550326..9dae3b2 100644 Binary files a/Exercise Library/Leg Press/preview.gif and b/Exercise Library/Leg Press/preview.gif differ diff --git a/Exercise Library/Leg Press/visual.svg b/Exercise Library/Leg Press/visual.svg index eb0f2a9..52ac48d 100644 --- a/Exercise Library/Leg Press/visual.svg +++ b/Exercise Library/Leg Press/visual.svg @@ -1,10 +1,10 @@ Leg Press - - + + - + diff --git a/Exercise Library/Rotary/frames/frame-1.svg b/Exercise Library/Rotary/frames/frame-1.svg index 7d9391f..befe3e2 100644 --- a/Exercise Library/Rotary/frames/frame-1.svg +++ b/Exercise Library/Rotary/frames/frame-1.svg @@ -1,9 +1,9 @@ Rotary - + - + diff --git a/Exercise Library/Rotary/frames/frame-2.svg b/Exercise Library/Rotary/frames/frame-2.svg index 0993ca3..0fb1a97 100644 --- a/Exercise Library/Rotary/frames/frame-2.svg +++ b/Exercise Library/Rotary/frames/frame-2.svg @@ -1,9 +1,9 @@ Rotary - + - + diff --git a/Exercise Library/Rotary/motion.json b/Exercise Library/Rotary/motion.json index 9f2bd89..740d9b8 100644 --- a/Exercise Library/Rotary/motion.json +++ b/Exercise Library/Rotary/motion.json @@ -5,9 +5,9 @@ "working": ["spine"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[138, 130], [182, 130]], "w": 8}, + {"kind": "line", "pts": [[138, 130], [182, 130]], "w": 8, "depth": 10}, {"kind": "line", "pts": [[160, 132], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[144, 150], [176, 150]], "w": 5} + {"kind": "line", "pts": [[144, 150], [176, 150]], "w": 5, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 14} ], diff --git a/Exercise Library/Rotary/preview.gif b/Exercise Library/Rotary/preview.gif index 42e1f74..059daef 100644 Binary files a/Exercise Library/Rotary/preview.gif and b/Exercise Library/Rotary/preview.gif differ diff --git a/Exercise Library/Rotary/visual.svg b/Exercise Library/Rotary/visual.svg index 7d9391f..befe3e2 100644 --- a/Exercise Library/Rotary/visual.svg +++ b/Exercise Library/Rotary/visual.svg @@ -1,9 +1,9 @@ Rotary - + - + diff --git a/Exercise Library/SYSTEM.md b/Exercise Library/SYSTEM.md index 64b2953..c2d0eb1 100644 --- a/Exercise Library/SYSTEM.md +++ b/Exercise Library/SYSTEM.md @@ -132,8 +132,8 @@ scale drawings of the machine. ```json "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9}, - {"kind": "rect", "x": 54, "y": 104, "w": 40, "h": 8, "r": 3}, + {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14}, {"kind": "circle", "c": [142, 77], "r": 3.5, "fill": true, "color": "prop"} ]}, {"type": "cable", "from": [190, 8], "to": ["hand_r", "hand_l"]}, @@ -143,23 +143,37 @@ scale drawings of the machine. ] ``` -- **`scene`** — static shapes in canvas coordinates: `line` (polyline, stroke - width `w`), `circle` (`fill: false` for an outline), `rect` (filled, corner - radius `r`). A shape may set `"color": "prop"` to use the darker - attached-item gray (e.g. a fixed handle the hands rest on). Scene shapes - are view-locked billboards — they don't rotate with `--orbit`. -- **`cable`** — a thin line from a fixed anchor `from` to a moving joint `to`; - the machine's pulley line. +Props are authored in the authored view but have **world-space 3D form**: +under an orbiting camera the whole equipment layer rotates about the +world-vertical axis through the root anchor, exactly like the figure and the +mat. Everything resolves in the *authored* view — scene points, cable +anchors, bar angles, pad perpendiculars, roller offsets — and the resolved +constructs are then rotated; joint-attached items keep following the rotated +figure's hands and feet, so equipment stays welded to the body. At the +authored yaw nothing moves, so the authored look is exact. + +- **`scene`** — static shapes: `line` (polyline, stroke width `w`) and + `circle` (`fill: false` for an outline). Points are canvas `[x, y]` (or + `[x, y, z]` where needed); a shape-level `"z"` sets its depth plane + (positive toward the camera), and a line with `"depth"` is a **slab** — + extruded that half-width through its plane, it stays a plain line edge-on + and opens into a swept quad as the camera orbits (seats, backrests, + platforms). A shape may set `"color": "prop"` to use the darker + attached-item gray (e.g. a fixed handle the hands rest on). +- **`cable`** — a thin line from a fixed anchor `from` (`[x, y]` or + `[x, y, z]`) to a moving joint `to`; the machine's pulley line. - **`bar` / `dumbbell` / `pad`** — a segment centered on the joint(s) in `at` (a single joint, or the midpoint of a list). Joints are the extremities (`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 (`["knee_r", "foot_r"]`). - `bar` lies at a fixed world `angle` (default 0 = horizontal — in side view a - two-handed bar is drawn horizontal by convention); `dumbbell` and `pad` - default to perpendicular to the lower bone (forearm/shin), or take an - explicit `angle`. `plateR` puts filled discs on both ends (dumbbells default - to 4.5). A prop whose limb is hidden that frame simply isn't drawn. + `bar` lies at a fixed authored-view `angle` (default 0 = horizontal — in + side view a two-handed bar is drawn horizontal by convention); `dumbbell` + and `pad` default to perpendicular to the lower bone (forearm/shin), or + take an explicit `angle`. Under orbit the segment rotates with the scene + and foreshortens naturally. `plateR` puts filled discs on both ends + (dumbbells default to 4.5). A prop whose limb is hidden that frame simply + isn't drawn. - **`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 it presses — a leg extension's instep roller (`side: 1`), a leg curl's @@ -179,6 +193,7 @@ python3 render.py --figure=female # render with another skeleton profile python3 render.py --flip # view from the other side (camera + 180°) python3 render.py --strict # fail on any ROM violation, listing each python3 render.py --export # bake app resources into Workouts/Resources/ExerciseMotions +python3 render.py --fixtures # regenerate WorkoutsTests/Fixtures/figure-fixtures.json ``` `render.py` needs only Pillow (for GIFs/sheets; the SVGs have no dependency). @@ -192,6 +207,8 @@ the `--export` copies ship: `skeleton.json` plus uniquely-named and the exercise-library reference screen (`ExerciseInfo.swift` parses the info pages). The in-app solver is a line-for-line port of `kinematics.py`, held to it by `WorkoutsTests/Fixtures/figure-fixtures.json` — projected -geometry snapshots the Swift solver must reproduce; regenerate them alongside -any pipeline change. Re-run `python3 render.py --export` after editing any -motion or info page; the library stays the source of truth. +geometry snapshots (figure and prop primitives, including orbit-presentation +samples) the Swift solver must reproduce; regenerate with +`python3 render.py --fixtures` alongside any pipeline change. Re-run +`python3 render.py --export` after editing any motion or info page; the +library stays the source of truth. diff --git a/Exercise Library/Seated Row/frames/frame-1.svg b/Exercise Library/Seated Row/frames/frame-1.svg index b925a5f..9135fbf 100644 --- a/Exercise Library/Seated Row/frames/frame-1.svg +++ b/Exercise Library/Seated Row/frames/frame-1.svg @@ -1,9 +1,9 @@ Seated Row - - - + + + diff --git a/Exercise Library/Seated Row/frames/frame-2.svg b/Exercise Library/Seated Row/frames/frame-2.svg index 420c339..452ee05 100644 --- a/Exercise Library/Seated Row/frames/frame-2.svg +++ b/Exercise Library/Seated Row/frames/frame-2.svg @@ -1,9 +1,9 @@ Seated Row - - - + + + diff --git a/Exercise Library/Seated Row/motion.json b/Exercise Library/Seated Row/motion.json index dfeae9c..a25215e 100644 --- a/Exercise Library/Seated Row/motion.json +++ b/Exercise Library/Seated Row/motion.json @@ -4,9 +4,9 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[122, 132], [156, 132]], "w": 8}, - {"kind": "line", "pts": [[159, 46], [157, 96]], "w": 8}, - {"kind": "line", "pts": [[176, 150], [206, 150]], "w": 5} + {"kind": "line", "pts": [[122, 132], [156, 132]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[159, 46], [157, 96]], "w": 8, "depth": 7}, + {"kind": "line", "pts": [[176, 150], [206, 150]], "w": 5, "depth": 6} ]}, {"type": "cable", "from": [244, 120], "to": ["hand_r", "hand_l"]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 7} diff --git a/Exercise Library/Seated Row/preview.gif b/Exercise Library/Seated Row/preview.gif index 5941330..23f314c 100644 Binary files a/Exercise Library/Seated Row/preview.gif and b/Exercise Library/Seated Row/preview.gif differ diff --git a/Exercise Library/Seated Row/visual.svg b/Exercise Library/Seated Row/visual.svg index 420c339..452ee05 100644 --- a/Exercise Library/Seated Row/visual.svg +++ b/Exercise Library/Seated Row/visual.svg @@ -1,9 +1,9 @@ Seated Row - - - + + + diff --git a/Exercise Library/Shoulder Press/frames/frame-1.svg b/Exercise Library/Shoulder Press/frames/frame-1.svg index 5b72aa8..412cbbd 100644 --- a/Exercise Library/Shoulder Press/frames/frame-1.svg +++ b/Exercise Library/Shoulder Press/frames/frame-1.svg @@ -1,10 +1,10 @@ Shoulder Press - - + + - + diff --git a/Exercise Library/Shoulder Press/frames/frame-2.svg b/Exercise Library/Shoulder Press/frames/frame-2.svg index 8942caa..07abe43 100644 --- a/Exercise Library/Shoulder Press/frames/frame-2.svg +++ b/Exercise Library/Shoulder Press/frames/frame-2.svg @@ -1,10 +1,10 @@ Shoulder Press - - + + - + diff --git a/Exercise Library/Shoulder Press/motion.json b/Exercise Library/Shoulder Press/motion.json index 17bf2c6..3c256a1 100644 --- a/Exercise Library/Shoulder Press/motion.json +++ b/Exercise Library/Shoulder Press/motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 140], [88, 50]], "w": 8}, - {"kind": "line", "pts": [[110, 141], [148, 141]], "w": 8}, + {"kind": "line", "pts": [[116, 140], [88, 50]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[110, 141], [148, 141]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5}, - {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4} + {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} ], diff --git a/Exercise Library/Shoulder Press/preview.gif b/Exercise Library/Shoulder Press/preview.gif index 885d6f5..b9af810 100644 Binary files a/Exercise Library/Shoulder Press/preview.gif and b/Exercise Library/Shoulder Press/preview.gif differ diff --git a/Exercise Library/Shoulder Press/visual.svg b/Exercise Library/Shoulder Press/visual.svg index 8942caa..07abe43 100644 --- a/Exercise Library/Shoulder Press/visual.svg +++ b/Exercise Library/Shoulder Press/visual.svg @@ -1,10 +1,10 @@ Shoulder Press - - + + - + diff --git a/Exercise Library/Tricep Press/frames/frame-1.svg b/Exercise Library/Tricep Press/frames/frame-1.svg index a23007e..e638ff5 100644 --- a/Exercise Library/Tricep Press/frames/frame-1.svg +++ b/Exercise Library/Tricep Press/frames/frame-1.svg @@ -1,10 +1,10 @@ Tricep Press - - + + - + diff --git a/Exercise Library/Tricep Press/frames/frame-2.svg b/Exercise Library/Tricep Press/frames/frame-2.svg index bdd8b2c..da99f72 100644 --- a/Exercise Library/Tricep Press/frames/frame-2.svg +++ b/Exercise Library/Tricep Press/frames/frame-2.svg @@ -1,10 +1,10 @@ Tricep Press - - + + - + diff --git a/Exercise Library/Tricep Press/motion.json b/Exercise Library/Tricep Press/motion.json index bf77781..1002dc6 100644 --- a/Exercise Library/Tricep Press/motion.json +++ b/Exercise Library/Tricep Press/motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 134], [92, 42]], "w": 8}, - {"kind": "line", "pts": [[108, 135], [146, 135]], "w": 8}, + {"kind": "line", "pts": [[116, 134], [92, 42]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[108, 135], [146, 135]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[124, 137], [124, 151]], "w": 5}, - {"kind": "line", "pts": [[110, 151], [140, 151]], "w": 4} + {"kind": "line", "pts": [[110, 151], [140, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 6} ], diff --git a/Exercise Library/Tricep Press/preview.gif b/Exercise Library/Tricep Press/preview.gif index b041c74..8c4402a 100644 Binary files a/Exercise Library/Tricep Press/preview.gif and b/Exercise Library/Tricep Press/preview.gif differ diff --git a/Exercise Library/Tricep Press/visual.svg b/Exercise Library/Tricep Press/visual.svg index bdd8b2c..da99f72 100644 --- a/Exercise Library/Tricep Press/visual.svg +++ b/Exercise Library/Tricep Press/visual.svg @@ -1,10 +1,10 @@ Tricep Press - - + + - + diff --git a/Exercise Library/contact-sheet.png b/Exercise Library/contact-sheet.png index fc6cabd..b195a76 100644 Binary files a/Exercise Library/contact-sheet.png and b/Exercise Library/contact-sheet.png differ diff --git a/Exercise Library/render.py b/Exercise Library/render.py index 8e4ba3a..44bbb37 100644 --- a/Exercise Library/render.py +++ b/Exercise Library/render.py @@ -13,9 +13,11 @@ Outputs per exercise: frames/frame-N.svg, preview.gif (tweened, looping), visual.svg (the primary frame). `--sheet` writes contact-sheet.png of every key frame; `--demo` writes demo-sheet.png showing rig customizations (body profiles, flipped camera, theme); `--orbit` writes orbit.gif per named -exercise (the camera sweeps 360 degrees while the motion loops). `--export` -instead bakes each motion down to the legacy planar schema consumed by the -in-app SwiftUI renderer. SVGs need no dependencies; GIFs/sheets need Pillow. +exercise (the camera sweeps 360 degrees while the motion loops — props +rotate with the figure). `--export` copies the app's bundled resources +verbatim; `--fixtures` regenerates the projected-geometry snapshots pinning +the in-app Swift solver to this pipeline. SVGs need no dependencies; +GIFs/sheets need Pillow. """ import copy @@ -227,24 +229,35 @@ def timeline(norms, fps=20): # figure in the recessive equipment gray; joint-attached items (`bar`, # `dumbbell`, `pad`) draw over the limbs in the darker prop gray, following # the resolved hand/foot positions frame by frame. +# +# Props have world-space 3D form: everything is authored (and resolved) in the +# authored view — scene points and cable anchors carry an optional depth `z` +# (+ toward the camera), a scene line an optional `depth` extrusion half-width +# that makes it a slab — then rotated about the world-vertical axis through +# the root anchor for the orbiting presentation, exactly like the figure and +# the mat. Positions that follow the figure (joint anchors) come from the +# *rotated* geometry; fixed points, directions, and offsets (scene shapes, +# cable anchors, bar angles, pad perpendiculars, roller offsets) resolve in +# the *authored* view and rotate — never recompute them in the rotated view. def flip_props(props, width): - """Mirror the props horizontally, matching the flipped camera. Joint- - attached props follow the mirrored limbs automatically; only fixed - coordinates and world angles need mirroring.""" + """Mirror the props horizontally, matching the flipped camera (which views + from the opposite side, so authored depths flip sign too). Joint-attached + props follow the mirrored limbs automatically; only fixed coordinates, + depths, and world angles need mirroring.""" def fx(p): - return [width - p[0], p[1]] + return [width - p[0], p[1], -p[2]] if len(p) > 2 else [width - p[0], p[1]] out = [] for prop in props: p = json.loads(json.dumps(prop)) if p["type"] == "scene": for s in p["shapes"]: + if "z" in s: + s["z"] = -s["z"] if s["kind"] == "line": s["pts"] = [fx(pt) for pt in s["pts"]] elif s["kind"] == "circle": s["c"] = fx(s["c"]) - elif s["kind"] == "rect": - s["x"] = width - s["x"] - s["w"] elif p["type"] == "cable": p["from"] = fx(p["from"]) elif p["type"] in ("bar", "pad") and "angle" in p: @@ -255,6 +268,16 @@ def flip_props(props, width): return out +def prop_rotation(pitch, yaw_offset): + """View-space rotation carrying authored-view prop geometry to the camera + `yaw_offset` degrees past the authored yaw: a rotation about the world- + vertical axis through the root anchor, conjugated by the camera elevation. + The identity at offset 0, so the authored view stays bit-exact.""" + if yaw_offset == 0: + return K.IDENTITY + return K.chain(K.rot_x(pitch), K.rot_y(-yaw_offset), K.rot_x(-pitch)) + + def joint_points(geo, ref): """Resolve a joint ref — `"hand_r"`, `"knee_l"`, or a midpoint list like `["knee_r", "foot_r"]` — to (point, unit direction of the bone ending at @@ -275,45 +298,90 @@ def joint_points(geo, ref): sum(p[1] for p in pts) / len(pts)), direction) -def resolve_props(props, geo): - """Props -> drawable primitives for one frame: (background, foreground).""" +def resolve_props(props, geo, anchor, rot=K.IDENTITY, auth_geo=None): + """Props -> drawable primitives for one frame: (background, foreground). + + `geo` is the frame's drawn (possibly orbit-rotated) geometry, `auth_geo` + the same frame at the authored camera (defaults to `geo`), `anchor` the + frame's root canvas anchor, and `rot` the `prop_rotation` between them. + Joint positions come from `geo`; everything authored — scene points, + cable anchors, bar angles, pad perpendiculars, roller offsets — resolves + against `auth_geo` and rotates through `rot`. + """ + auth = auth_geo if auth_geo is not None else geo + + def place(pt, z=0.0): + """Authored canvas point (+ depth toward the camera) -> drawn canvas.""" + v = K.mvec(rot, (pt[0] - anchor[0], anchor[1] - pt[1], z)) + return (anchor[0] + v[0], anchor[1] - v[1]) + + def swing(vec, z=0.0): + """Authored canvas-space direction/offset -> drawn canvas (y-down).""" + v = K.mvec(rot, (vec[0], -vec[1], z)) + return (v[0], -v[1]) + bg, fg = [], [] for p in props or []: t = p["type"] if t == "scene": for s in p["shapes"]: - bg.append(dict(s, color=s.get("color", "equipment"))) + color = s.get("color", "equipment") + z = s.get("z", 0.0) + if s["kind"] == "line": + depth = s.get("depth", 0.0) + pts = [(pt[0], pt[1], z + (pt[2] if len(pt) > 2 else 0.0)) + for pt in s["pts"]] + if depth: + # An extruded slab: the polyline swept through +/-depth, + # filled and outlined so it degenerates to the plain + # line whenever the sweep collapses edge-on. + quad = ([place(pt, pt[2] + depth) for pt in pts] + + [place(pt, pt[2] - depth) for pt in reversed(pts)]) + bg.append({"kind": "poly", "pts": [list(q) for q in quad], + "w": s.get("w", 4), "color": color}) + else: + bg.append({"kind": "line", + "pts": [list(place(pt, pt[2])) for pt in pts], + "w": s.get("w", 4), "color": color}) + elif s["kind"] == "circle": + bg.append({"kind": "circle", "c": list(place(s["c"], z)), + "r": s["r"], "fill": s.get("fill", False), + "w": s.get("w", 3), "color": color}) elif t == "cable": end, _ = joint_points(geo, p["to"]) if end: - bg.append({"kind": "line", "pts": [list(p["from"]), list(end)], + start = place(p["from"], p["from"][2] if len(p["from"]) > 2 else 0.0) + bg.append({"kind": "line", "pts": [list(start), list(end)], "w": p.get("w", 2), "color": "equipment"}) elif t == "roller": # A machine roller pad seen end-on: a disc riding the limb's lower # bone near the joint, on the `side` (+1/-1) of the bone it presses. - c, d = joint_points(geo, p["at"]) - if not c: + # The offset resolves along the authored-view bone, then rotates. + c, _ = joint_points(geo, p["at"]) + _, d = joint_points(auth, p["at"]) + if not c or not d: continue r = p.get("r", 5) back = p.get("back", 0) side = p.get("side", 1) px, py = d[1] * side, -d[0] * side - center = (c[0] - d[0] * back + px * (r + 3), - c[1] - d[1] * back + py * (r + 3)) - fg.append({"kind": "circle", "c": list(center), "r": r, + off = swing((-d[0] * back + px * (r + 3), -d[1] * back + py * (r + 3))) + fg.append({"kind": "circle", "c": [c[0] + off[0], c[1] + off[1]], "r": r, "fill": True, "color": "prop"}) elif t in ("bar", "dumbbell", "pad"): - c, d = joint_points(geo, p["at"]) - if not c: + c, _ = joint_points(geo, p["at"]) + _, d = joint_points(auth, p["at"]) + if not c or not d: continue if t == "bar" or "angle" in p: - ux, uy = dirv(p.get("angle", 0)) # fixed world angle + axis = dirv(p.get("angle", 0)) # fixed authored-view angle else: - ux, uy = -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 h = p.get("halfLen", {"bar": 24, "dumbbell": 7, "pad": 8}[t]) a = (c[0] - ux * h, c[1] - uy * h) b = (c[0] + ux * h, c[1] + uy * h) - fg.append({"kind": "line", "pts": [a, b], + fg.append({"kind": "line", "pts": [list(a), list(b)], "w": p.get("w", {"bar": 4, "dumbbell": 3, "pad": 7}[t]), "color": "prop"}) plate = p.get("plateR", 4.5 if t == "dumbbell" else 0) @@ -332,6 +400,11 @@ def svg_prims(prims, colors): d = "M " + " L ".join(f"{x:.1f} {y:.1f}" for x, y in p["pts"]) lines.append(f' ') + elif p["kind"] == "poly": + d = "M " + " L ".join(f"{x:.1f} {y:.1f}" for x, y in p["pts"]) + " Z" + lines.append(f' ') elif p["kind"] == "circle": cx, cy = p["c"] if p.get("fill"): @@ -339,17 +412,17 @@ def svg_prims(prims, colors): else: lines.append(f' ') - elif p["kind"] == "rect": - lines.append(f' ') return lines def draw_prims(d, prims, colors, scale): for p in prims: color = colors[p["color"]] - if p["kind"] == "line": + if p["kind"] in ("line", "poly"): pts = [(x * scale, y * scale) for x, y in p["pts"]] + if p["kind"] == "poly": + d.polygon(pts, fill=color) + pts = pts + pts[:1] w = p.get("w", 4) * scale d.line(pts, fill=color, width=w, joint="curve") for x, y in (pts[0], pts[-1]): @@ -362,10 +435,6 @@ def draw_prims(d, prims, colors, scale): else: d.ellipse([cx - r, cy - r, cx + r, cy + r], outline=color, width=p.get("w", 3) * scale) - elif p["kind"] == "rect": - x, y = p["x"] * scale, p["y"] * scale - d.rounded_rectangle([x, y, x + p["w"] * scale, y + p["h"] * scale], - radius=p.get("r", 2) * scale, fill=color) # ------------------------------------------------------------------- drawing @@ -400,8 +469,8 @@ def quad_points(p0, ctrl, p2, n=24): return pts -def svg_for_frame(name, geo, order, shade, working, colors, props=None): - bg, fg = resolve_props(props, geo) +def svg_for_frame(name, geo, order, shade, working, colors, prims=((), ())): + bg, fg = prims w, h = CANVAS parts = [f'', f' {name}', @@ -443,10 +512,10 @@ def svg_for_frame(name, geo, order, shade, working, colors, props=None): return "\n".join(parts) + "\n" -def draw_geo(geo, order, shade, working, colors, scale=2, font=None, props=None): +def draw_geo(geo, order, shade, working, colors, scale=2, font=None, prims=((), ())): from PIL import Image, ImageDraw - bg, fg = resolve_props(props, geo) + bg, fg = prims w, h = CANVAS[0] * scale, CANVAS[1] * scale img = Image.new("RGB", (w, h), "white") d = ImageDraw.Draw(img) @@ -545,21 +614,21 @@ def render_exercise(folder, figure="neutral", flip=False, strict=False): return geo, order, shade resolved = [] - key_geos = [] + key_cells = [] for nf in norms: out, geo, order, shade = frame_geometry(nf, prof, cam, flip, pitch, mat) for limb in hide: geo.pop(limb, None) resolved.append(out) - key_geos.append((geo, order, shade)) + key_cells.append((geo, order, shade, resolve_props(props, geo, nf["root"]["pos"]))) frames_dir = folder / "frames" frames_dir.mkdir(exist_ok=True) for old in frames_dir.glob("frame-*.svg"): old.unlink() colors = PALETTES["default"] - svgs = [svg_for_frame(motion["name"], geo, order, shade, working, colors, props) - for geo, order, shade in key_geos] + svgs = [svg_for_frame(motion["name"], geo, order, shade, working, colors, prims) + for geo, order, shade, prims in key_cells] for i, svg in enumerate(svgs, start=1): (frames_dir / f"frame-{i}.svg").write_text(svg) (folder / "visual.svg").write_text(svgs[motion.get("primary", 1) - 1]) @@ -569,7 +638,8 @@ def render_exercise(folder, figure="neutral", flip=False, strict=False): imgs = [] for nf in timeline(resolved): geo, order, shade = geometry(nf) - imgs.append(draw_geo(geo, order, shade, working, colors, font=font, props=props)) + prims = resolve_props(props, geo, nf["root"]["pos"]) + 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:], duration=50, loop=0) print(f" {motion['name']}: {len(svgs)} frames, preview.gif") @@ -578,29 +648,34 @@ def render_exercise(folder, figure="neutral", flip=False, strict=False): def render_orbit(folder, figure="neutral"): - """A full-turn demo: the camera sweeps 360 degrees while the motion loops. - Scene props are view-locked billboards, so orbit shines on prop-free - motions (bodyweight exercises).""" + """An orbiting demo of what the app shows: the camera sweeps 360 degrees + while the motion loops (or swings a `camera.sweep` pendulum when the + motion authors one). Props rotate with the figure about the root anchor.""" motion = load_motion(folder) working = set(motion.get("working", [])) hide = set(motion.get("hide", [])) norms, prof, cam, pitch, props = prepare(motion, figure) resolved = [frame_geometry(nf, prof, cam, pitch=pitch)[0] for nf in norms] mat = mat_bounds(norms, prof, cam, pitch) + sweep = motion.get("camera", {}).get("sweep") font = legend_font() colors = PALETTES["default"] ticks = timeline(resolved) imgs = [] for i, nf in enumerate(ticks): - yaw = cam + 360.0 * i / len(ticks) + off = (sweep * math.sin(2 * math.pi * i / len(ticks)) if sweep + else 360.0 * i / len(ticks)) # Pins are canvas targets in the AUTHORED view: resolve the pose there, - # then rotate the posed body - never re-pin in the rotated view. - posed, _, _, _ = frame_geometry(nf, prof, cam, pitch=pitch) + # then rotate the posed body - never re-pin in the rotated view. The + # authored-view geometry also feeds the props' directions and offsets. + posed, auth_geo, _, _ = frame_geometry(nf, prof, cam, pitch=pitch) posed["pins"] = {} - _, geo, order, shade = frame_geometry(posed, prof, yaw, pitch=pitch, mat=mat) + _, geo, order, shade = frame_geometry(posed, prof, cam + off, pitch=pitch, mat=mat) for limb in hide: geo.pop(limb, None) - imgs.append(draw_geo(geo, order, shade, working, colors, font=font, props=props)) + prims = resolve_props(props, geo, nf["root"]["pos"], + prop_rotation(pitch, off), auth_geo) + 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:], duration=50, loop=0) print(f" {motion['name']}: orbit.gif ({len(imgs)} frames)") @@ -618,9 +693,10 @@ def contact_sheet(folders, figure="neutral", out=None): _, geo, order, shade = frame_geometry(nf, prof, cam, pitch=pitch, mat=mat) for limb in hide: geo.pop(limb, None) + prims = resolve_props(props, geo, nf["root"]["pos"]) cells.append((f"{motion['name']} {i}/{len(norms)}", draw_geo(geo, order, shade, working, PALETTES["default"], - font=font, props=props))) + font=font, prims=prims))) save_sheet(cells, Path(out) if out else LIB / "contact-sheet.png") @@ -644,9 +720,10 @@ def demo_sheet(folder): _, geo, order, shade = frame_geometry(norms[idx], prof, cam, flip, pitch, mat) for limb in hide: geo.pop(limb, None) + prims = resolve_props(props, geo, norms[idx]["root"]["pos"]) cells.append((f"{motion['name']} — {label}", draw_geo(geo, order, shade, working, PALETTES[palette], - font=font, props=props))) + font=font, prims=prims))) save_sheet(cells, LIB / "demo-sheet.png", cols=3) @@ -689,6 +766,62 @@ def export_app_resources(folders): print(f" exported skeleton.json -> {out}") +def write_fixtures(folders): + """Regenerate `WorkoutsTests/Fixtures/figure-fixtures.json` — the projected + geometry snapshots that pin the Swift solver to this pipeline: per exercise + and key frame the draw order, shading, spine, head, nose, and limb chains, + plus a mid-tween sample and (for a spread of prop flavors) orbit samples + taken through the presentation path — resolve at the authored camera, clear + the pins, rotate the posed body — with the resolved prop primitives.""" + ORBIT_SAMPLED = {"Bird Dog", "Lat Pull Down", "Leg Extension", "Abductor"} + OFFSETS = (37.0, 180.0) + T = 0.5 + + def sample(geo, order, shade, prims=None): + out = {"order": order, "shade": shade, + "spine": [list(p) for p in geo["spine"]], + "head": list(geo["head"])} + if "nose" in geo: + out["nose"] = [list(geo["nose"][0]), list(geo["nose"][1])] + for limb in K.LIMBS: + out[limb] = [list(p) for p in geo[limb]] + if prims is not None: + out["props"] = {"bg": prims[0], "fg": prims[1]} + return out + + exercises = [] + for folder in folders: + motion = load_motion(folder) + norms, prof, cam, pitch, props = prepare(motion, "neutral") + resolved, frames = [], [] + for nf in norms: + out, geo, order, shade = frame_geometry(nf, prof, cam) + resolved.append(out) + frames.append(sample(geo, order, shade)) + mid = K.lerp_frames(resolved[0], resolved[1], ease(T)) + _, geo, order, shade = frame_geometry(mid, prof, cam) + entry = {"name": motion["name"], "camera": cam, "frames": frames, + "tween": {"t": T, "sample": sample(geo, order, shade)}} + if motion["name"] in ORBIT_SAMPLED: + anchor = norms[0]["root"]["pos"] + posed, auth_geo, _, _ = frame_geometry(norms[0], prof, cam) + posed["pins"] = {} + orbit = [] + for off in OFFSETS: + _, geo, order, shade = frame_geometry(posed, prof, cam + off) + prims = resolve_props(props, geo, anchor, + prop_rotation(CAMERA_PITCH, off), auth_geo) + orbit.append({"yaw": cam + off, + "sample": sample(geo, order, shade, prims)}) + entry["orbit"] = orbit + exercises.append(entry) + + out_path = LIB.parent / "WorkoutsTests" / "Fixtures" / "figure-fixtures.json" + out_path.write_text(json.dumps( + {"profile": "neutral", "pitch": CAMERA_PITCH, "exercises": exercises})) + print(f" {out_path.name} ({len(exercises)} exercises)") + + def main(): flags = [a for a in sys.argv[1:] if a.startswith("--")] names = [a for a in sys.argv[1:] if not a.startswith("--")] @@ -704,6 +837,9 @@ def main(): if "--export" in flags: export_app_resources(folders) return + if "--fixtures" in flags: + write_fixtures(folders) + return if "--orbit" in flags: for folder in folders: render_orbit(folder, figure=figure) diff --git a/Workouts/ExerciseFigure/ExerciseFigureView.swift b/Workouts/ExerciseFigure/ExerciseFigureView.swift index 77386bc..319a5dd 100644 --- a/Workouts/ExerciseFigure/ExerciseFigureView.swift +++ b/Workouts/ExerciseFigure/ExerciseFigureView.swift @@ -46,11 +46,12 @@ struct FigureAnimation { /// describes one authored viewpoint, so machines keep their fixed camera. var orbits: Bool { props.isEmpty && hide.isEmpty } - /// Drawable geometry at `time`, with limbs listed in `hide` dropped so neither they - /// nor any prop riding them are drawn. + /// Drawable geometry at `time` — the figure plus the resolved equipment layers — + /// with limbs listed in `hide` dropped so neither they nor any prop riding them + /// are drawn. func geometry(at time: Double) -> FigureGeometry { let yaw = orbits ? 360 * (time / Self.orbitPeriod) : 0 - var geo = timeline.geometry(at: time, yawOffset: yaw) + var geo = timeline.geometry(at: time, yawOffset: yaw, props: props) for name in hide { if let limb = FigureLimb(rawValue: name) { geo.limbs[limb] = nil } } @@ -121,14 +122,14 @@ struct ExerciseFigureView: View { } // Equipment behind the figure: scene shapes and cables. - drawBackgroundProps(&ctx, geo) + drawProps(&ctx, geo.propsBackground) // Parts far-to-near. The head paints last (opaque), preceded by the joint-attached // equipment so bars/pads sit over the limbs but behind the face. for part in geo.order { switch part { case "head": - drawAttachedProps(&ctx, geo) + drawProps(&ctx, geo.propsForeground) drawHead(&ctx, geo) case "spine": drawSpine(&ctx, geo) @@ -164,132 +165,39 @@ struct ExerciseFigureView: View { // MARK: Props - /// Prop joint refs → (limb, chain index): extremities are index 2, mid joints - /// (elbows/knees) index 1, so equipment can ride either joint. Kept 1:1 with - /// the reference renderer's `JOINT_LIMB` (legs now end in a foot bone, so a foot - /// prop rides the ankle at index 2). - private static let propJoints: [String: (limb: FigureLimb, index: Int)] = [ - "hand_r": (.armR, 2), "elbow_r": (.armR, 1), - "hand_l": (.armL, 2), "elbow_l": (.armL, 1), - "foot_r": (.legR, 2), "knee_r": (.legR, 1), - "foot_l": (.legL, 2), "knee_l": (.legL, 1), - ] - - /// The joint point a prop follows (plus the unit direction of the bone ending - /// at the first joint, for perpendicular items). Nil when any referenced limb - /// isn't drawn this frame. - private func jointAnchor(_ geo: FigureGeometry, _ ref: PropJointRef) -> (point: CGPoint, direction: CGVector)? { - var points: [CGPoint] = [] - var direction: CGVector? - for name in ref.names { - guard let joint = Self.propJoints[name], - let chain = geo.limbs[joint.limb], chain.count > joint.index else { return nil } - let a = chain[joint.index - 1] - let b = chain[joint.index] - points.append(b) - if direction == nil { - let d = max(hypot(b.x - a.x, b.y - a.y), 1) - direction = CGVector(dx: (b.x - a.x) / d, dy: (b.y - a.y) / d) - } - } - guard let direction, !points.isEmpty else { return nil } - let center = CGPoint(x: points.reduce(0) { $0 + $1.x } / CGFloat(points.count), - y: points.reduce(0) { $0 + $1.y } / CGFloat(points.count)) - return (center, direction) - } - - private func drawBackgroundProps(_ ctx: inout GraphicsContext, _ geo: FigureGeometry) { - for prop in figure.props { - switch prop.type { - case "scene": - for shape in prop.shapes ?? [] { drawSceneShape(&ctx, shape) } - case "cable": - guard let from = prop.from, from.count == 2, let to = prop.to, - let anchor = jointAnchor(geo, to) else { continue } - stroke(&ctx, [CGPoint(x: from[0], y: from[1]), anchor.point], - color: .figureEquipment, width: prop.w ?? 2) - default: - break - } - } - } - - /// Bars sit at a fixed world angle (default horizontal); dumbbells and pads - /// default to perpendicular to the lower bone. Kept 1:1 with the reference - /// renderer's `resolve_props` — change them in lockstep. - private func drawAttachedProps(_ ctx: inout GraphicsContext, _ geo: FigureGeometry) { - for prop in figure.props { - if prop.type == "roller" { - drawRoller(&ctx, geo, prop) - continue - } - let defaults: (halfLen: Double, width: Double, plateR: Double) - switch prop.type { - case "bar": defaults = (24, 4, 0) - case "dumbbell": defaults = (7, 3, 4.5) - case "pad": defaults = (8, 7, 0) - default: continue - } - guard let at = prop.at, let anchor = jointAnchor(geo, at) else { continue } - let axis: CGVector - if prop.type == "bar" || prop.angle != nil { - axis = MotionSolver.direction(prop.angle ?? 0) - } else { - axis = CGVector(dx: -anchor.direction.dy, dy: anchor.direction.dx) - } - let h = prop.halfLen ?? defaults.halfLen - let a = CGPoint(x: anchor.point.x - axis.dx * h, y: anchor.point.y - axis.dy * h) - let b = CGPoint(x: anchor.point.x + axis.dx * h, y: anchor.point.y + axis.dy * h) - stroke(&ctx, [a, b], color: .figureProp, width: prop.w ?? defaults.width) - let plateR = prop.plateR ?? defaults.plateR - if plateR > 0 { - for end in [a, b] { - let rect = CGRect(x: end.x - plateR, y: end.y - plateR, - width: 2 * plateR, height: 2 * plateR) - ctx.fill(Path(ellipseIn: rect), with: .color(.figureProp)) + /// Draws one resolved equipment layer. The solver hands back ready canvas + /// primitives (`MotionSolver.resolveProps`, kept 1:1 with the reference + /// renderer); the view only maps inks to the adaptive palette. + private func drawProps(_ ctx: inout GraphicsContext, _ prims: [PropPrimitive]) { + for prim in prims { + switch prim { + case .line(let points, let width, let ink): + stroke(&ctx, points, color: color(for: ink), width: width) + case .poly(let points, let width, let ink): + // An extruded scene slab: filled and outlined, so it degenerates + // to the plain line whenever the sweep collapses edge-on. + guard let first = points.first else { continue } + var path = Path() + path.addLines(points) + path.addLine(to: first) + path.closeSubpath() + ctx.fill(path, with: .color(color(for: ink))) + ctx.stroke(path, with: .color(color(for: ink)), + style: StrokeStyle(lineWidth: width, lineCap: .round, lineJoin: .round)) + case .circle(let center, let radius, let width, let fill, let ink): + let rect = CGRect(x: center.x - radius, y: center.y - radius, + width: 2 * radius, height: 2 * radius) + if fill { + ctx.fill(Path(ellipseIn: rect), with: .color(color(for: ink))) + } else { + ctx.stroke(Path(ellipseIn: rect), with: .color(color(for: ink)), lineWidth: width) } } } } - /// A machine roller pad seen end-on: a disc riding the limb's lower bone near the - /// joint, on the `side` (+1/−1) of the bone it presses. Kept 1:1 with the reference - /// renderer's `resolve_props`. - private func drawRoller(_ ctx: inout GraphicsContext, _ geo: FigureGeometry, _ prop: MotionProp) { - guard let at = prop.at, let anchor = jointAnchor(geo, at) else { return } - let r = prop.r ?? 5 - let back = prop.back ?? 0 - let side = prop.side ?? 1 - let px = anchor.direction.dy * side, py = -anchor.direction.dx * side - let center = CGPoint(x: anchor.point.x - anchor.direction.dx * back + px * (r + 3), - y: anchor.point.y - anchor.direction.dy * back + py * (r + 3)) - let rect = CGRect(x: center.x - r, y: center.y - r, width: 2 * r, height: 2 * r) - ctx.fill(Path(ellipseIn: rect), with: .color(.figureProp)) - } - - private func drawSceneShape(_ ctx: inout GraphicsContext, _ shape: PropSceneShape) { - let color: Color = shape.color == "prop" ? .figureProp : .figureEquipment - switch shape.kind { - case "line": - guard let pts = shape.pts else { return } - stroke(&ctx, pts.compactMap { $0.count == 2 ? CGPoint(x: $0[0], y: $0[1]) : nil }, - color: color, width: shape.w ?? 4) - case "circle": - guard let c = shape.c, c.count == 2, let r = shape.r else { return } - let rect = CGRect(x: c[0] - r, y: c[1] - r, width: 2 * r, height: 2 * r) - if shape.fill ?? true { - ctx.fill(Path(ellipseIn: rect), with: .color(color)) - } else { - ctx.stroke(Path(ellipseIn: rect), with: .color(color), lineWidth: shape.w ?? 3) - } - case "rect": - guard let x = shape.x, let y = shape.y, let w = shape.w, let h = shape.h else { return } - let path = Path(roundedRect: CGRect(x: x, y: y, width: w, height: h), - cornerRadius: shape.r ?? 2) - ctx.fill(path, with: .color(color)) - default: - break - } + private func color(for ink: PropInk) -> Color { + ink == .prop ? .figureProp : .figureEquipment } /// Near parts take the dark ink, far parts the light one; working parts swap for the diff --git a/Workouts/ExerciseFigure/ExerciseMotion.swift b/Workouts/ExerciseFigure/ExerciseMotion.swift index aeeefe7..c610d80 100644 --- a/Workouts/ExerciseFigure/ExerciseMotion.swift +++ b/Workouts/ExerciseFigure/ExerciseMotion.swift @@ -140,20 +140,22 @@ enum PropJointRef: Codable { } } -/// One static shape of a `scene` prop, in canvas coordinates. +/// One static shape of a `scene` prop, authored in canvas coordinates in the +/// authored view, with world-space 3D form for the orbiting presentation. struct PropSceneShape: Codable { - let kind: String // "line" | "circle" | "rect" - /// line: polyline points; `w` is the stroke width. + let kind: String // "line" | "circle" + /// line: polyline points, `[x, y]` or `[x, y, z]`; `w` is the stroke width. let pts: [[Double]]? let w: Double? /// circle: center + radius; `fill` false draws an outline. let c: [Double]? let r: Double? let fill: Bool? - /// rect: origin + size (`w`/`h`), corner radius `r`; always filled. - let x: Double? - let y: Double? - let h: Double? + /// The shape's depth plane (+ toward the camera in the authored view). + let z: Double? + /// Extrusion half-width: a line with `depth` is a slab (a seat, a platform) + /// that opens into a swept quad as the camera orbits. + let depth: Double? /// Optional palette override: `"prop"` for the darker attached-item gray. let color: String? } @@ -164,7 +166,7 @@ struct MotionProp: Codable { let type: String // "scene" | "cable" | "bar" | "dumbbell" | "pad" | "roller" /// scene: the static shapes. let shapes: [PropSceneShape]? - /// cable: fixed anchor `[x, y]` → moving joint `to`. + /// cable: fixed anchor `[x, y]` or `[x, y, z]` → moving joint `to`. let from: [Double]? let to: PropJointRef? /// bar/dumbbell/pad: the joint(s) the item is centered on. diff --git a/Workouts/ExerciseFigure/MotionSolver.swift b/Workouts/ExerciseFigure/MotionSolver.swift index 92af64a..d67f949 100644 --- a/Workouts/ExerciseFigure/MotionSolver.swift +++ b/Workouts/ExerciseFigure/MotionSolver.swift @@ -150,6 +150,25 @@ struct NormalizedFrame { /// the far member draws light, behind, and nudged by the readability offset. enum Shade { case near, far } +/// The two equipment inks: recessive `equipment` gray for scene shapes and cables +/// behind the figure, darker `prop` gray for joint-attached items over the limbs. +enum PropInk { + case equipment, prop + + init(_ name: String?) { self = name == "prop" ? .prop : .equipment } +} + +/// One resolved equipment drawing primitive, in canvas coordinates — the shape the +/// prop layer reduces to for a single frame (mirroring the reference renderer's +/// `resolve_props` output; kept 1:1, change them in lockstep). +enum PropPrimitive { + case line(points: [CGPoint], width: Double, ink: PropInk) + /// A closed, filled, outlined polygon — an extruded scene slab. Degenerates to + /// the plain line whenever the sweep collapses edge-on (the authored view). + case poly(points: [CGPoint], width: Double, ink: PropInk) + case circle(center: CGPoint, radius: Double, width: Double, fill: Bool, ink: PropInk) +} + /// A pose resolved to drawable canvas points (plus the depth-sorted draw order and /// per-limb shading the view needs). struct FigureGeometry { @@ -171,6 +190,10 @@ struct FigureGeometry { /// Parts far-to-near, `"head"` always last (`"spine"`, `"arm_r"`, … then `"head"`). var order: [String] var shade: [FigureLimb: Shade] + /// The equipment layer resolved for this frame: scene shapes and cables drawn + /// behind the figure, joint-attached items drawn over the limbs (before the head). + var propsBackground: [PropPrimitive] = [] + var propsForeground: [PropPrimitive] = [] } /// FK output in view space (x right, y up, z toward the camera; origin at the root). @@ -500,6 +523,160 @@ enum MotionSolver { floor: floor, limbs: limbs, order: order, shade: shade) return (resolved, geo) } + + // MARK: Props + + /// Prop joint refs → (limb, chain index): extremities are index 2, mid joints + /// (elbows/knees) index 1, so equipment can ride either joint. Kept 1:1 with + /// the reference renderer's `JOINT_LIMB` (legs end in a foot bone, so a foot + /// prop rides the ankle at index 2). + private static let propJoints: [String: (limb: FigureLimb, index: Int)] = [ + "hand_r": (.armR, 2), "elbow_r": (.armR, 1), + "hand_l": (.armL, 2), "elbow_l": (.armL, 1), + "foot_r": (.legR, 2), "knee_r": (.legR, 1), + "foot_l": (.legL, 2), "knee_l": (.legL, 1), + ] + + /// The joint point a prop follows (plus the unit direction of the bone ending + /// at the first joint, for perpendicular items). Nil when any referenced limb + /// isn't drawn this frame. + private static func jointAnchor(_ geo: FigureGeometry, _ ref: PropJointRef) -> (point: CGPoint, direction: CGVector)? { + var points: [CGPoint] = [] + var direction: CGVector? + for name in ref.names { + guard let joint = propJoints[name], + let chain = geo.limbs[joint.limb], chain.count > joint.index else { return nil } + let a = chain[joint.index - 1] + let b = chain[joint.index] + points.append(b) + if direction == nil { + let d = max(hypot(b.x - a.x, b.y - a.y), 1) + direction = CGVector(dx: (b.x - a.x) / d, dy: (b.y - a.y) / d) + } + } + guard let direction, !points.isEmpty else { return nil } + let center = CGPoint(x: points.reduce(0) { $0 + $1.x } / CGFloat(points.count), + y: points.reduce(0) { $0 + $1.y } / CGFloat(points.count)) + return (center, direction) + } + + /// View-space rotation carrying authored-view prop geometry to the camera + /// `yawOffset` degrees past the authored yaw: a rotation about the world-vertical + /// axis through the root anchor, conjugated by the camera elevation. Nil (the + /// identity) at offset 0, so the authored view stays bit-exact. + static func propRotation(pitch: Double, yawOffset: Double) -> Mat3? { + guard yawOffset != 0 else { return nil } + return Mat3.rotX(pitch).times(Mat3.rotY(-yawOffset)).times(Mat3.rotX(-pitch)) + } + + /// Props → drawable primitives for one frame: (background, foreground). + /// + /// `geo` is the frame's drawn (possibly orbit-rotated) geometry, `authored` the + /// same frame at the authored camera (pass `geo` itself when not orbiting), + /// `anchor` the frame's root canvas anchor, and `rotation` the `propRotation` + /// between them. Joint positions come from `geo`; everything authored — scene + /// points, cable anchors, bar angles, pad perpendiculars, roller offsets — + /// resolves against `authored` and rotates. Kept 1:1 with the reference + /// renderer's `resolve_props` — change them in lockstep. + static func resolveProps(_ props: [MotionProp], geo: FigureGeometry, authored: FigureGeometry, + anchor: CGPoint, rotation: Mat3?) -> (bg: [PropPrimitive], fg: [PropPrimitive]) { + /// Authored canvas point (+ depth toward the camera) → drawn canvas. + func place(_ x: Double, _ y: Double, _ z: Double) -> CGPoint { + guard let rotation else { return CGPoint(x: x, y: y) } + let v = rotation.apply(Vec3(x - anchor.x, anchor.y - y, z)) + return CGPoint(x: anchor.x + v.x, y: anchor.y - v.y) + } + /// Authored canvas-space direction/offset → drawn canvas (y-down). + func swing(_ vec: CGVector) -> CGVector { + guard let rotation else { return vec } + let v = rotation.apply(Vec3(vec.dx, -vec.dy, 0)) + return CGVector(dx: v.x, dy: -v.y) + } + + var bg: [PropPrimitive] = [] + var fg: [PropPrimitive] = [] + for prop in props { + switch prop.type { + case "scene": + for shape in prop.shapes ?? [] { + let ink = PropInk(shape.color) + let z = shape.z ?? 0 + switch shape.kind { + case "line": + guard let pts = shape.pts else { continue } + let lifted = pts.compactMap { pt -> (x: Double, y: Double, z: Double)? in + pt.count >= 2 ? (pt[0], pt[1], z + (pt.count > 2 ? pt[2] : 0)) : nil + } + if let depth = shape.depth, depth != 0 { + // An extruded slab: the polyline swept through ±depth, + // filled and outlined so it degenerates to the plain + // line whenever the sweep collapses edge-on. + let quad = lifted.map { place($0.x, $0.y, $0.z + depth) } + + lifted.reversed().map { place($0.x, $0.y, $0.z - depth) } + bg.append(.poly(points: quad, width: shape.w ?? 4, ink: ink)) + } else { + bg.append(.line(points: lifted.map { place($0.x, $0.y, $0.z) }, + width: shape.w ?? 4, ink: ink)) + } + case "circle": + guard let c = shape.c, c.count == 2, let r = shape.r else { continue } + bg.append(.circle(center: place(c[0], c[1], z), radius: r, + width: shape.w ?? 3, fill: shape.fill ?? false, ink: ink)) + default: + break + } + } + case "cable": + guard let from = prop.from, from.count >= 2, let to = prop.to, + let end = jointAnchor(geo, to) else { continue } + let start = place(from[0], from[1], from.count > 2 ? from[2] : 0) + bg.append(.line(points: [start, end.point], width: prop.w ?? 2, ink: .equipment)) + case "roller": + // A machine roller pad seen end-on: a disc riding the limb's lower + // bone near the joint, on the `side` (+1/−1) of the bone it presses. + // The offset resolves along the authored-view bone, then rotates. + guard let at = prop.at, let now = jointAnchor(geo, at), + let auth = jointAnchor(authored, at) else { continue } + let r = prop.r ?? 5 + let back = prop.back ?? 0 + let side = prop.side ?? 1 + let d = auth.direction + let px = d.dy * side, py = -d.dx * side + let off = swing(CGVector(dx: -d.dx * back + px * (r + 3), + dy: -d.dy * back + py * (r + 3))) + fg.append(.circle(center: CGPoint(x: now.point.x + off.dx, y: now.point.y + off.dy), + radius: r, width: 3, fill: true, ink: .prop)) + case "bar", "dumbbell", "pad": + let defaults: (halfLen: Double, width: Double, plateR: Double) = switch prop.type { + case "bar": (24, 4, 0) + case "dumbbell": (7, 3, 4.5) + default: (8, 7, 0) + } + guard let at = prop.at, let now = jointAnchor(geo, at), + let auth = jointAnchor(authored, at) else { continue } + let axis: CGVector + if prop.type == "bar" || prop.angle != nil { + axis = direction(prop.angle ?? 0) // fixed authored-view angle + } else { + axis = CGVector(dx: -auth.direction.dy, dy: auth.direction.dx) + } + let u = swing(axis) // foreshortens under orbit + let h = prop.halfLen ?? defaults.halfLen + 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) + fg.append(.line(points: [a, b], width: prop.w ?? defaults.width, ink: .prop)) + let plateR = prop.plateR ?? defaults.plateR + if plateR > 0 { + for end in [a, b] { + fg.append(.circle(center: end, radius: plateR, width: 3, fill: true, ink: .prop)) + } + } + default: + break + } + } + return (bg, fg) + } } /// The full looping animation for one motion: key frames resolved to anatomical angles, @@ -566,13 +743,28 @@ struct MotionTimeline { /// targets in the *authored* view, so the pose resolves there first and the posed /// body is then rotated; re-pinning in a rotated view would glue hands to screen /// points that no longer correspond to anything (arms visibly "stuck" mid-orbit). - func geometry(at time: Double, yawOffset: Double = 0) -> FigureGeometry { + /// `props` are resolved into the geometry's primitive layers the same way: joint + /// anchors follow the rotated figure, while authored constructs (scene points, + /// cable anchors, bar angles, pad perpendiculars) resolve in the authored view + /// and rotate about the root anchor's vertical axis. + func geometry(at time: Double, yawOffset: Double = 0, props: [MotionProp] = []) -> FigureGeometry { let frame = frame(at: time) - guard yawOffset != 0 else { - return MotionSolver.frameGeometry(frame, prof: profile, cam: cam, pitch: pitch, mat: mat).1 + var geo: FigureGeometry + let authored: FigureGeometry + if yawOffset == 0 { + geo = MotionSolver.frameGeometry(frame, prof: profile, cam: cam, pitch: pitch, mat: mat).1 + authored = geo + } else { + let (posedFrame, authoredGeo) = MotionSolver.frameGeometry(frame, prof: profile, cam: cam, pitch: pitch) + authored = authoredGeo + var posed = posedFrame + posed.pins = [:] + geo = MotionSolver.frameGeometry(posed, prof: profile, cam: cam + yawOffset, pitch: pitch, mat: mat).1 } - var posed = MotionSolver.frameGeometry(frame, prof: profile, cam: cam, pitch: pitch).0 - posed.pins = [:] - return MotionSolver.frameGeometry(posed, prof: profile, cam: cam + yawOffset, pitch: pitch, mat: mat).1 + guard !props.isEmpty else { return geo } + let rotation = MotionSolver.propRotation(pitch: pitch, yawOffset: yawOffset) + (geo.propsBackground, geo.propsForeground) = MotionSolver.resolveProps( + props, geo: geo, authored: authored, anchor: frame.rootPos, rotation: rotation) + return geo } } diff --git a/Workouts/Resources/ExerciseMotions/Abdominal.motion.json b/Workouts/Resources/ExerciseMotions/Abdominal.motion.json index f41fc49..8f96651 100644 --- a/Workouts/Resources/ExerciseMotions/Abdominal.motion.json +++ b/Workouts/Resources/ExerciseMotions/Abdominal.motion.json @@ -4,11 +4,11 @@ "working": ["spine"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[120, 128], [114, 62]], "w": 8}, - {"kind": "line", "pts": [[106, 130], [150, 130]], "w": 8}, + {"kind": "line", "pts": [[120, 128], [114, 62]], "w": 8, "depth": 7}, + {"kind": "line", "pts": [[106, 130], [150, 130]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[122, 132], [122, 150]], "w": 4}, - {"kind": "line", "pts": [[102, 150], [150, 150]], "w": 4}, - {"kind": "line", "pts": [[156, 149], [190, 149]], "w": 5} + {"kind": "line", "pts": [[102, 150], [150, 150]], "w": 4, "depth": 5}, + {"kind": "line", "pts": [[156, 149], [190, 149]], "w": 5, "depth": 6} ]}, {"type": "pad", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 14, "w": 6} ], diff --git a/Workouts/Resources/ExerciseMotions/Abductor.motion.json b/Workouts/Resources/ExerciseMotions/Abductor.motion.json index ee56697..e8db4c0 100644 --- a/Workouts/Resources/ExerciseMotions/Abductor.motion.json +++ b/Workouts/Resources/ExerciseMotions/Abductor.motion.json @@ -5,8 +5,8 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "rect", "x": 152, "y": 56, "w": 16, "h": 72, "r": 5}, - {"kind": "rect", "x": 130, "y": 126, "w": 60, "h": 10, "r": 3}, + {"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6}, + {"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12}, {"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6} ]}, {"type": "pad", "at": ["knee_r"], "angle": 90, "halfLen": 13, "w": 6}, diff --git a/Workouts/Resources/ExerciseMotions/Adductor.motion.json b/Workouts/Resources/ExerciseMotions/Adductor.motion.json index 6ffbf73..05f0126 100644 --- a/Workouts/Resources/ExerciseMotions/Adductor.motion.json +++ b/Workouts/Resources/ExerciseMotions/Adductor.motion.json @@ -5,8 +5,8 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "rect", "x": 152, "y": 56, "w": 16, "h": 72, "r": 5}, - {"kind": "rect", "x": 130, "y": 126, "w": 60, "h": 10, "r": 3}, + {"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6}, + {"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12}, {"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6} ]}, {"type": "pad", "at": ["knee_r"], "angle": 90, "halfLen": 13, "w": 6}, diff --git a/Workouts/Resources/ExerciseMotions/Arm Curl.motion.json b/Workouts/Resources/ExerciseMotions/Arm Curl.motion.json index 23eb200..211ab99 100644 --- a/Workouts/Resources/ExerciseMotions/Arm Curl.motion.json +++ b/Workouts/Resources/ExerciseMotions/Arm Curl.motion.json @@ -4,8 +4,8 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 134], [150, 134]], "w": 8}, - {"kind": "line", "pts": [[136, 52], [164, 70]], "w": 8}, + {"kind": "line", "pts": [[116, 134], [150, 134]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[136, 52], [164, 70]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[164, 70], [164, 128]], "w": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 6} diff --git a/Workouts/Resources/ExerciseMotions/Calfs.motion.json b/Workouts/Resources/ExerciseMotions/Calfs.motion.json index 0dc1341..8982bb9 100644 --- a/Workouts/Resources/ExerciseMotions/Calfs.motion.json +++ b/Workouts/Resources/ExerciseMotions/Calfs.motion.json @@ -4,10 +4,10 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[124, 126], [158, 124]], "w": 9}, + {"kind": "line", "pts": [[124, 126], [158, 124]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[138, 128], [138, 150]], "w": 5}, - {"kind": "line", "pts": [[120, 150], [156, 150]], "w": 5}, - {"kind": "rect", "x": 198, "y": 147, "w": 34, "h": 6, "r": 1}, + {"kind": "line", "pts": [[120, 150], [156, 150]], "w": 5, "depth": 5}, + {"kind": "line", "pts": [[201, 150], [229, 150]], "w": 6, "depth": 7}, {"kind": "line", "pts": [[183, 62], [183, 122]], "w": 4}, {"kind": "line", "pts": [[164, 76], [183, 76]], "w": 3, "color": "prop"} ]}, diff --git a/Workouts/Resources/ExerciseMotions/Chest Press.motion.json b/Workouts/Resources/ExerciseMotions/Chest Press.motion.json index 2369b0a..93f8fca 100644 --- a/Workouts/Resources/ExerciseMotions/Chest Press.motion.json +++ b/Workouts/Resources/ExerciseMotions/Chest Press.motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[114, 132], [86, 40]], "w": 8}, - {"kind": "line", "pts": [[106, 133], [146, 133]], "w": 8}, + {"kind": "line", "pts": [[114, 132], [86, 40]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[106, 133], [146, 133]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[122, 135], [122, 151]], "w": 5}, - {"kind": "line", "pts": [[108, 151], [138, 151]], "w": 4} + {"kind": "line", "pts": [[108, 151], [138, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 8} ], diff --git a/Workouts/Resources/ExerciseMotions/Lat Pull Down.motion.json b/Workouts/Resources/ExerciseMotions/Lat Pull Down.motion.json index 78202df..e0b24ca 100644 --- a/Workouts/Resources/ExerciseMotions/Lat Pull Down.motion.json +++ b/Workouts/Resources/ExerciseMotions/Lat Pull Down.motion.json @@ -4,7 +4,7 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[126, 130], [162, 130]], "w": 8}, + {"kind": "line", "pts": [[126, 130], [162, 130]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[144, 132], [144, 150]], "w": 5}, {"kind": "circle", "c": [272, 19], "r": 4, "fill": true, "color": "prop"} ]}, diff --git a/Workouts/Resources/ExerciseMotions/Leg Curl.motion.json b/Workouts/Resources/ExerciseMotions/Leg Curl.motion.json index c82136d..11cb940 100644 --- a/Workouts/Resources/ExerciseMotions/Leg Curl.motion.json +++ b/Workouts/Resources/ExerciseMotions/Leg Curl.motion.json @@ -4,12 +4,12 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9}, - {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9}, - {"kind": "line", "pts": [[130, 105], [158, 106]], "w": 7}, + {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[130, 105], [158, 106]], "w": 7, "depth": 7}, {"kind": "line", "pts": [[108, 126], [108, 150]], "w": 5}, {"kind": "line", "pts": [[160, 124], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5}, + {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5, "depth": 5}, {"kind": "circle", "c": [114, 90], "r": 3.5, "fill": true, "color": "prop"} ]}, {"type": "roller", "at": ["foot_r", "foot_l"], "side": -1, "r": 5, "back": 3} diff --git a/Workouts/Resources/ExerciseMotions/Leg Extension.motion.json b/Workouts/Resources/ExerciseMotions/Leg Extension.motion.json index afcbadf..7762e35 100644 --- a/Workouts/Resources/ExerciseMotions/Leg Extension.motion.json +++ b/Workouts/Resources/ExerciseMotions/Leg Extension.motion.json @@ -4,11 +4,11 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9}, - {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9}, + {"kind": "line", "pts": [[110, 122], [86, 48]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[104, 124], [166, 120]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[108, 126], [108, 150]], "w": 5}, {"kind": "line", "pts": [[160, 124], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5}, + {"kind": "line", "pts": [[104, 150], [166, 150]], "w": 5, "depth": 5}, {"kind": "circle", "c": [114, 90], "r": 3.5, "fill": true, "color": "prop"} ]}, {"type": "roller", "at": ["foot_r", "foot_l"], "side": 1, "r": 5, "back": 7} diff --git a/Workouts/Resources/ExerciseMotions/Leg Press.motion.json b/Workouts/Resources/ExerciseMotions/Leg Press.motion.json index 78ee2e0..69430de 100644 --- a/Workouts/Resources/ExerciseMotions/Leg Press.motion.json +++ b/Workouts/Resources/ExerciseMotions/Leg Press.motion.json @@ -4,10 +4,10 @@ "working": ["leg_r", "leg_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9}, - {"kind": "line", "pts": [[126, 127], [156, 122]], "w": 9}, + {"kind": "line", "pts": [[134, 123], [96, 36]], "w": 9, "depth": 8}, + {"kind": "line", "pts": [[126, 127], [156, 122]], "w": 9, "depth": 8}, {"kind": "line", "pts": [[138, 130], [138, 150]], "w": 5}, - {"kind": "line", "pts": [[118, 150], [158, 150]], "w": 5}, + {"kind": "line", "pts": [[118, 150], [158, 150]], "w": 5, "depth": 5}, {"kind": "line", "pts": [[142, 90], [142, 78]], "w": 3}, {"kind": "circle", "c": [142, 77], "r": 3.5, "fill": true, "color": "prop"} ]}, diff --git a/Workouts/Resources/ExerciseMotions/Rotary.motion.json b/Workouts/Resources/ExerciseMotions/Rotary.motion.json index 9f2bd89..740d9b8 100644 --- a/Workouts/Resources/ExerciseMotions/Rotary.motion.json +++ b/Workouts/Resources/ExerciseMotions/Rotary.motion.json @@ -5,9 +5,9 @@ "working": ["spine"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[138, 130], [182, 130]], "w": 8}, + {"kind": "line", "pts": [[138, 130], [182, 130]], "w": 8, "depth": 10}, {"kind": "line", "pts": [[160, 132], [160, 150]], "w": 5}, - {"kind": "line", "pts": [[144, 150], [176, 150]], "w": 5} + {"kind": "line", "pts": [[144, 150], [176, 150]], "w": 5, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 14} ], diff --git a/Workouts/Resources/ExerciseMotions/Seated Row.motion.json b/Workouts/Resources/ExerciseMotions/Seated Row.motion.json index dfeae9c..a25215e 100644 --- a/Workouts/Resources/ExerciseMotions/Seated Row.motion.json +++ b/Workouts/Resources/ExerciseMotions/Seated Row.motion.json @@ -4,9 +4,9 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[122, 132], [156, 132]], "w": 8}, - {"kind": "line", "pts": [[159, 46], [157, 96]], "w": 8}, - {"kind": "line", "pts": [[176, 150], [206, 150]], "w": 5} + {"kind": "line", "pts": [[122, 132], [156, 132]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[159, 46], [157, 96]], "w": 8, "depth": 7}, + {"kind": "line", "pts": [[176, 150], [206, 150]], "w": 5, "depth": 6} ]}, {"type": "cable", "from": [244, 120], "to": ["hand_r", "hand_l"]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 7} diff --git a/Workouts/Resources/ExerciseMotions/Shoulder Press.motion.json b/Workouts/Resources/ExerciseMotions/Shoulder Press.motion.json index 17bf2c6..3c256a1 100644 --- a/Workouts/Resources/ExerciseMotions/Shoulder Press.motion.json +++ b/Workouts/Resources/ExerciseMotions/Shoulder Press.motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 140], [88, 50]], "w": 8}, - {"kind": "line", "pts": [[110, 141], [148, 141]], "w": 8}, + {"kind": "line", "pts": [[116, 140], [88, 50]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[110, 141], [148, 141]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[126, 143], [126, 151]], "w": 5}, - {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4} + {"kind": "line", "pts": [[110, 151], [142, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10} ], diff --git a/Workouts/Resources/ExerciseMotions/Tricep Press.motion.json b/Workouts/Resources/ExerciseMotions/Tricep Press.motion.json index bf77781..1002dc6 100644 --- a/Workouts/Resources/ExerciseMotions/Tricep Press.motion.json +++ b/Workouts/Resources/ExerciseMotions/Tricep Press.motion.json @@ -4,10 +4,10 @@ "working": ["arm_r", "arm_l"], "props": [ {"type": "scene", "shapes": [ - {"kind": "line", "pts": [[116, 134], [92, 42]], "w": 8}, - {"kind": "line", "pts": [[108, 135], [146, 135]], "w": 8}, + {"kind": "line", "pts": [[116, 134], [92, 42]], "w": 8, "depth": 8}, + {"kind": "line", "pts": [[108, 135], [146, 135]], "w": 8, "depth": 8}, {"kind": "line", "pts": [[124, 137], [124, 151]], "w": 5}, - {"kind": "line", "pts": [[110, 151], [140, 151]], "w": 4} + {"kind": "line", "pts": [[110, 151], [140, 151]], "w": 4, "depth": 5} ]}, {"type": "bar", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 6} ], diff --git a/WorkoutsTests/ExerciseMotionTests.swift b/WorkoutsTests/ExerciseMotionTests.swift index 9894420..e07bfb7 100644 --- a/WorkoutsTests/ExerciseMotionTests.swift +++ b/WorkoutsTests/ExerciseMotionTests.swift @@ -114,7 +114,9 @@ struct ExerciseMotionTests { /// The projected-geometry ground truth: for every exercise and key frame, the draw /// order and near/far shading must match exactly and every point land within 0.5 px - /// of the reference, plus the mid-tween sample and (Bird Dog) two orbit-camera views. + /// of the reference, plus the mid-tween sample and orbit-camera views taken through + /// the presentation path — resolve at the authored camera, clear the pins, rotate + /// the posed body — with the equipment layer resolved into rotated primitives. @Test func figureFixturesMatchReference() throws { let bundle = Bundle(for: FigureFixtureMarker.self) let url = try #require( @@ -143,9 +145,20 @@ struct ExerciseMotionTests { expectMatch(MotionSolver.frameGeometry(mid, prof: profile, cam: cam).1, exercise.tween.sample, "\(exercise.name) tween") - for orbit in exercise.orbit ?? [] { - expectMatch(MotionSolver.frameGeometry(norms[0], prof: profile, cam: orbit.yaw).1, - orbit.sample, "\(exercise.name) orbit \(orbit.yaw)") + guard let orbits = exercise.orbit, !orbits.isEmpty else { continue } + let (posedFrame, authored) = MotionSolver.frameGeometry(norms[0], prof: profile, cam: cam) + var posed = posedFrame + posed.pins = [:] + for orbit in orbits { + let geo = MotionSolver.frameGeometry(posed, prof: profile, cam: orbit.yaw).1 + expectMatch(geo, orbit.sample, "\(exercise.name) orbit \(orbit.yaw)") + guard let propFixture = orbit.sample.props else { continue } + let rotation = MotionSolver.propRotation(pitch: fixtures.pitch, yawOffset: orbit.yaw - cam) + let (bg, fg) = MotionSolver.resolveProps( + resources.motion.props ?? [], geo: geo, authored: authored, + anchor: norms[0].rootPos, rotation: rotation) + expectPrims(bg, propFixture.bg, "\(exercise.name) orbit \(orbit.yaw) bg") + expectPrims(fg, propFixture.fg, "\(exercise.name) orbit \(orbit.yaw) fg") } } } @@ -158,6 +171,7 @@ private final class FigureFixtureMarker {} private struct FigureFixtures: Decodable { let profile: String + let pitch: Double let exercises: [FixtureExercise] } @@ -182,13 +196,30 @@ private struct FixtureSample: Decodable { let armL: [[Double]] let legR: [[Double]] let legL: [[Double]] + let props: FixtureProps? enum CodingKeys: String, CodingKey { - case order, shade, spine, head, nose + case order, shade, spine, head, nose, props case armR = "arm_r", armL = "arm_l", legR = "leg_r", legL = "leg_l" } } +private struct FixtureProps: Decodable { + let bg: [FixturePrim] + let fg: [FixturePrim] +} + +/// One reference prop primitive: a line/poly (`pts`) or a circle (`c` + `r`). +private struct FixturePrim: Decodable { + let kind: String + let pts: [[Double]]? + let c: [Double]? + let r: Double? + let w: Double? + let fill: Bool? + let color: String +} + private func expectClose(_ point: CGPoint, _ expected: [Double], _ label: String) { #expect(abs(Double(point.x) - expected[0]) < 0.5 && abs(Double(point.y) - expected[1]) < 0.5, "\(label): got (\(point.x), \(point.y)) expected \(expected)") @@ -227,3 +258,37 @@ private func expectMatch(_ geo: FigureGeometry, _ fixture: FixtureSample, _ labe expectChain(geo.limbs[.legR], fixture.legR, "\(label).leg_r") expectChain(geo.limbs[.legL], fixture.legL, "\(label).leg_l") } + +/// One resolved equipment layer against its reference: same primitive kinds and inks +/// in the same order, every point within 0.5 px, radii and widths matching. +private func expectPrims(_ prims: [PropPrimitive], _ fixtures: [FixturePrim], _ label: String) { + guard prims.count == fixtures.count else { + Issue.record("\(label): \(prims.count) primitives, expected \(fixtures.count)") + return + } + for (index, (prim, fixture)) in zip(prims, fixtures).enumerated() { + let tag = "\(label)[\(index)]" + switch prim { + case .line(let points, let width, let ink): + #expect(fixture.kind == "line", "\(tag) kind") + expectChain(points, fixture.pts ?? [], tag) + #expect(width == (fixture.w ?? 4), "\(tag) width") + expectInk(ink, fixture.color, tag) + case .poly(let points, let width, let ink): + #expect(fixture.kind == "poly", "\(tag) kind") + expectChain(points, fixture.pts ?? [], tag) + #expect(width == (fixture.w ?? 4), "\(tag) width") + expectInk(ink, fixture.color, tag) + case .circle(let center, let radius, _, let fill, let ink): + #expect(fixture.kind == "circle", "\(tag) kind") + expectClose(center, fixture.c ?? [], tag) + #expect(radius == fixture.r, "\(tag) radius") + #expect(fill == (fixture.fill ?? false), "\(tag) fill") + expectInk(ink, fixture.color, tag) + } + } +} + +private func expectInk(_ ink: PropInk, _ expected: String, _ label: String) { + #expect((ink == .prop ? "prop" : "equipment") == expected, "\(label) ink") +} diff --git a/WorkoutsTests/Fixtures/figure-fixtures.json b/WorkoutsTests/Fixtures/figure-fixtures.json index b56c80a..3665ed4 100644 --- a/WorkoutsTests/Fixtures/figure-fixtures.json +++ b/WorkoutsTests/Fixtures/figure-fixtures.json @@ -1 +1 @@ -{"profile": "neutral", "pitch": 10.0, "exercises": [{"name": "Abdominal", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [123.501, 83.316], [125.0, 42.394]], "head": [127.784, 22.89], "nose": [[137.69, 24.261], [144.621, 25.22]], "arm_r": [[125.0, 44.305], [153.596, 35.371], [155.0, 64.882]], "arm_l": [[130.909, 42.454], [159.516, 33.554], [161.0, 63.062]], "leg_r": [[128.0, 127.216], [171.174, 111.583], [168.0, 150.851], [178.965, 151.711]], "leg_l": [[133.909, 126.754], [176.354, 109.292], [172.0, 148.45], [182.935, 149.629]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [123.113, 76.738], [167.641, 57.71]], "head": [186.184, 50.331], "nose": [[193.667, 56.966], [198.869, 61.579]], "arm_r": [[167.641, 59.62], [195.9, 49.703], [190.0, 78.67]], "arm_l": [[173.55, 57.769], [201.814, 47.865], [196.0, 76.849]], "leg_r": [[128.0, 127.216], [171.174, 111.583], [168.0, 150.851], [178.965, 151.711]], "leg_l": [[133.909, 126.754], [176.354, 109.292], [172.0, 148.45], [182.935, 149.629]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [122.501, 81.31], [148.0, 46.225]], "head": [160.314, 30.704], "nose": [[169.401, 34.877], [175.745, 37.79]], "arm_r": [[148.0, 48.135], [177.477, 42.641], [172.5, 71.776]], "arm_l": [[153.909, 46.284], [183.389, 40.806], [178.5, 69.955]], "leg_r": [[128.0, 127.216], [171.174, 111.583], [168.0, 150.851], [178.965, 151.711]], "leg_l": [[133.909, 126.754], [176.354, 109.292], [172.0, 148.45], [182.935, 149.629]]}}}, {"name": "Abductor", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [147.394, 133.103], [145.105, 172.832], [143.922, 171.655]], "leg_l": [[167.0, 116.0], [172.606, 133.103], [174.895, 172.832], [176.078, 171.655]]}, {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [130.0, 130.923], [120.611, 169.762], [115.754, 168.124]], "leg_l": [[167.0, 116.0], [190.0, 130.923], [199.389, 169.762], [204.246, 168.124]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [138.404, 132.341], [132.445, 171.759], [129.364, 170.421]], "leg_l": [[167.0, 116.0], [181.596, 132.341], [187.555, 171.759], [190.636, 170.421]]}}}, {"name": "Adductor", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [130.0, 130.923], [120.611, 169.762], [115.754, 168.124]], "leg_l": [[167.0, 116.0], [190.0, 130.923], [199.389, 169.762], [204.246, 168.124]]}, {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [147.394, 133.103], [145.105, 172.832], [143.922, 171.655]], "leg_l": [[167.0, 116.0], [172.606, 133.103], [174.895, 172.832], [176.078, 171.655]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.161], [160.0, 32.291]], "head": [160.0, 12.595], "nose": null, "arm_r": [[149.0, 32.291], [139.729, 60.823], [131.328, 86.682]], "arm_l": [[171.0, 32.291], [180.271, 60.823], [188.672, 86.682]], "leg_r": [[153.0, 116.0], [138.404, 132.341], [132.445, 171.759], [129.364, 170.421]], "leg_l": [[167.0, 116.0], [181.596, 132.341], [187.555, 171.759], [190.636, 170.421]]}}}, {"name": "Arm Curl", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.786, 81.149], [134.43, 40.418]], "head": [137.214, 20.913], "nose": [[146.738, 23.961], [153.396, 26.091]], "arm_r": [[134.43, 42.328], [159.005, 59.274], [174.903, 84.329]], "arm_l": [[140.339, 40.477], [164.914, 57.423], [180.811, 82.478]], "leg_r": [[130.0, 125.216], [173.836, 111.486], [176.0, 150.821], [186.984, 150.235]], "leg_l": [[135.909, 124.754], [179.406, 110.016], [180.0, 149.404], [190.999, 149.243]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.786, 81.149], [134.43, 40.418]], "head": [137.214, 20.913], "nose": [[146.738, 23.961], [153.396, 26.091]], "arm_r": [[134.43, 42.328], [159.005, 59.274], [178.289, 36.642]], "arm_l": [[140.339, 40.477], [164.914, 57.423], [184.197, 34.791]], "leg_r": [[130.0, 125.216], [173.836, 111.486], [176.0, 150.821], [186.984, 150.235]], "leg_l": [[135.909, 124.754], [179.406, 110.016], [180.0, 149.404], [190.999, 149.243]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.786, 81.149], [134.43, 40.418]], "head": [137.214, 20.913], "nose": [[146.738, 23.961], [153.396, 26.091]], "arm_r": [[134.43, 42.328], [159.005, 59.274], [188.932, 61.335]], "arm_l": [[140.339, 40.477], [164.914, 57.423], [194.841, 59.484]], "leg_r": [[130.0, 125.216], [173.836, 111.486], [176.0, 150.821], [186.984, 150.235]], "leg_l": [[135.909, 124.754], [179.406, 110.016], [180.0, 149.404], [190.999, 149.243]]}}}, {"name": "Bird Dog", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.036, 99.298], [106.046, 92.905]], "head": [86.196, 95.305], "nose": [[77.108, 99.479], [70.764, 102.392]], "arm_r": [[111.955, 92.965], [115.931, 122.248], [111.0, 151.391]], "arm_l": [[106.046, 94.815], [110.072, 124.092], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.036, 99.298], [106.046, 92.905]], "head": [86.196, 95.305], "nose": [[76.527, 97.857], [69.765, 99.641]], "arm_r": [[111.955, 92.965], [115.931, 122.248], [111.0, 151.391]], "arm_l": [[106.046, 94.815], [77.681, 85.197], [49.315, 75.578]], "leg_r": [[195.909, 106.754], [240.341, 95.029], [278.978, 84.834], [286.049, 93.132]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.036, 99.298], [106.046, 92.905]], "head": [86.196, 95.305], "nose": [[77.108, 99.479], [70.764, 102.392]], "arm_r": [[111.955, 92.965], [115.931, 122.248], [111.0, 151.391]], "arm_l": [[106.046, 94.815], [110.072, 124.092], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}, {"order": ["leg_r", "arm_r", "spine", "arm_l", "leg_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.036, 99.298], [106.046, 92.905]], "head": [86.196, 95.305], "nose": [[76.527, 97.857], [69.765, 99.641]], "arm_r": [[111.955, 92.965], [83.59, 83.346], [55.224, 73.727]], "arm_l": [[106.046, 94.815], [110.072, 124.092], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [234.433, 95.491], [273.07, 85.295], [280.14, 93.594]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.036, 99.298], [106.046, 92.905]], "head": [86.196, 95.305], "nose": [[76.782, 98.68], [70.204, 101.037]], "arm_r": [[111.955, 92.965], [115.931, 122.248], [111.0, 151.391]], "arm_l": [[106.046, 94.815], [82.85, 113.55], [57.036, 128.604]], "leg_r": [[195.909, 106.754], [234.045, 132.086], [273.702, 126.944], [281.812, 134.263]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}}, "orbit": [{"yaw": 37.0, "sample": {"order": ["arm_r", "arm_l", "spine", "leg_r", "leg_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [155.687, 94.809], [122.952, 84.132]], "head": [107.098, 84.457], "nose": [[97.959, 88.517], [92.892, 90.767]], "arm_r": [[134.291, 84.179], [123.903, 111.896], [112.556, 139.245]], "arm_l": [[116.332, 85.657], [111.24, 114.773], [105.078, 143.687]], "leg_r": [[198.932, 106.602], [203.409, 152.152], [235.354, 156.332], [242.551, 163.487]], "leg_l": [[185.787, 106.971], [190.264, 152.52], [222.21, 156.7], [229.406, 163.855]]}}, {"yaw": 180.0, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[190.0, 106.0], [232.964, 99.298], [273.954, 92.905]], "head": [293.804, 95.305], "nose": [[302.892, 99.479], [309.236, 102.392]], "arm_r": [[273.954, 94.815], [246.072, 105.72], [217.953, 116.017]], "arm_l": [[279.862, 92.965], [251.531, 102.679], [222.99, 111.783]], "leg_r": [[190.0, 107.216], [184.394, 152.179], [144.394, 152.179], [135.383, 158.393]], "leg_l": [[195.909, 106.754], [190.303, 151.718], [150.303, 151.718], [141.292, 157.931]]}}]}, {"name": "Calfs", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.995, 76.013], [128.143, 35.161]], "head": [131.616, 15.764], "nose": [[141.468, 17.475], [148.362, 18.672]], "arm_r": [[128.143, 37.071], [155.658, 48.846], [166.0, 76.579]], "arm_l": [[134.052, 35.221], [161.853, 46.324], [170.0, 74.758]], "leg_r": [[140.0, 119.216], [185.998, 118.826], [212.0, 148.76], [218.69, 140.16]], "leg_l": [[145.909, 118.754], [191.871, 116.91], [216.0, 148.328], [223.202, 140.14]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.995, 76.013], [128.143, 35.161]], "head": [131.616, 15.764], "nose": [[141.468, 17.475], [148.362, 18.672]], "arm_r": [[128.143, 37.071], [155.658, 48.846], [166.0, 76.579]], "arm_l": [[134.052, 35.221], [161.853, 46.324], [170.0, 74.758]], "leg_r": [[140.0, 119.216], [185.175, 110.675], [212.0, 139.897], [222.04, 135.471]], "leg_l": [[145.909, 118.754], [190.801, 108.872], [216.0, 139.465], [226.266, 135.574]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.995, 76.013], [128.143, 35.161]], "head": [131.616, 15.764], "nose": [[141.468, 17.475], [148.362, 18.672]], "arm_r": [[128.143, 37.071], [155.658, 48.846], [166.0, 76.579]], "arm_l": [[134.052, 35.221], [161.853, 46.324], [170.0, 74.758]], "leg_r": [[140.0, 119.216], [185.76, 114.596], [212.0, 144.328], [220.669, 137.659]], "leg_l": [[145.909, 118.754], [191.504, 112.755], [216.0, 143.897], [225.037, 137.72]]}}}, {"name": "Cat-Cow", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [145.16, 123.58], [109.354, 94.413]], "head": [89.43, 96.13], "nose": [[79.806, 93.412], [73.077, 91.512]], "arm_r": [[115.262, 94.473], [120.88, 123.494], [111.0, 151.391]], "arm_l": [[109.354, 96.323], [114.968, 125.346], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [152.084, 74.855], [109.947, 96.703]], "head": [93.564, 108.0], "nose": [[86.439, 115.017], [81.489, 119.892]], "arm_r": [[115.855, 96.763], [124.559, 125.036], [111.0, 151.391]], "arm_l": [[109.947, 98.613], [118.631, 126.893], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.073, 98.952], [105.742, 95.058]], "head": [86.948, 101.795], "nose": [[77.258, 104.263], [70.481, 105.989]], "arm_r": [[111.651, 95.118], [120.47, 123.357], [111.0, 151.391]], "arm_l": [[105.742, 96.969], [114.561, 125.208], [105.0, 153.211]], "leg_r": [[195.909, 106.754], [201.515, 151.718], [241.515, 151.718], [250.526, 157.931]], "leg_l": [[190.0, 107.216], [195.606, 152.179], [235.606, 152.179], [244.617, 158.393]]}}}, {"name": "Chest Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.043, 80.733], [98.304, 40.178]], "head": [100.395, 20.589], "nose": [[110.358, 19.731], [117.331, 19.13]], "arm_r": [[98.304, 42.088], [93.095, 71.183], [116.076, 52.192]], "arm_l": [[104.213, 40.237], [99.004, 69.332], [121.985, 50.342]], "leg_r": [[116.0, 123.216], [160.688, 112.472], [158.0, 151.775], [168.975, 152.503]], "leg_l": [[121.909, 122.754], [166.389, 111.204], [162.0, 150.359], [172.934, 151.547]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.043, 80.733], [98.304, 40.178]], "head": [100.395, 20.589], "nose": [[110.358, 19.731], [117.331, 19.13]], "arm_r": [[98.304, 42.088], [128.14, 45.176], [157.249, 52.323]], "arm_l": [[104.213, 40.237], [134.049, 43.325], [163.158, 50.473]], "leg_r": [[116.0, 123.216], [160.688, 112.472], [158.0, 151.775], [168.975, 152.503]], "leg_l": [[121.909, 122.754], [166.389, 111.204], [162.0, 150.359], [172.934, 151.547]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.043, 80.733], [98.304, 40.178]], "head": [100.395, 20.589], "nose": [[110.358, 19.731], [117.331, 19.13]], "arm_r": [[98.304, 42.088], [116.359, 65.683], [145.59, 59.037]], "arm_l": [[104.213, 40.237], [122.267, 63.832], [151.499, 57.186]], "leg_r": [[116.0, 123.216], [160.688, 112.472], [158.0, 151.775], [168.975, 152.503]], "leg_l": [[121.909, 122.754], [166.389, 111.204], [162.0, 150.359], [172.934, 151.547]]}}}, {"name": "Dead Bug", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [100.0, 120.366], [100.0, 90.822]], "arm_l": [[105.909, 148.059], [105.909, 118.515], [105.909, 88.971]], "leg_r": [[185.0, 149.216], [205.165, 108.499], [244.557, 115.34], [246.468, 104.671]], "leg_l": [[190.909, 148.754], [211.074, 108.038], [250.466, 114.878], [252.376, 104.21]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [78.787, 129.019], [57.574, 108.128]], "arm_l": [[105.909, 148.059], [105.909, 118.515], [105.909, 88.971]], "leg_r": [[185.0, 149.216], [205.165, 108.499], [244.557, 115.34], [246.468, 104.671]], "leg_l": [[190.909, 148.754], [235.127, 136.267], [273.577, 125.409], [270.545, 114.996]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [100.0, 120.366], [100.0, 90.822]], "arm_l": [[105.909, 148.059], [105.909, 118.515], [105.909, 88.971]], "leg_r": [[185.0, 149.216], [205.165, 108.499], [244.557, 115.34], [246.468, 104.671]], "leg_l": [[190.909, 148.754], [211.074, 108.038], [250.466, 114.878], [252.376, 104.21]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [100.0, 120.366], [100.0, 90.822]], "arm_l": [[105.909, 148.059], [84.696, 127.169], [63.482, 106.278]], "leg_r": [[185.0, 149.216], [229.218, 136.729], [267.669, 125.871], [264.636, 115.458]], "leg_l": [[190.909, 148.754], [211.074, 108.038], [250.466, 114.878], [252.376, 104.21]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [88.519, 122.615], [77.039, 95.32]], "arm_l": [[105.909, 148.059], [105.909, 118.515], [105.909, 88.971]], "leg_r": [[185.0, 149.216], [205.165, 108.499], [244.557, 115.34], [246.468, 104.671]], "leg_l": [[190.909, 148.754], [226.147, 119.635], [266.092, 117.573], [265.516, 106.755]]}}}, {"name": "Hollow Body Hold", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [70.0, 149.91], [40.0, 149.91]], "arm_l": [[105.909, 148.059], [135.909, 148.059], [165.909, 148.059]], "leg_r": [[185.0, 149.216], [231.0, 149.216], [271.0, 149.216], [271.0, 138.383]], "leg_l": [[190.909, 148.754], [236.909, 148.754], [276.909, 148.754], [276.909, 137.921]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [140.587, 148.434], [102.768, 129.427]], "head": [87.448, 116.767], "nose": [[93.933, 109.155], [98.433, 103.874]], "arm_r": [[102.768, 131.337], [75.579, 118.851], [48.39, 106.365]], "arm_l": [[108.677, 129.486], [136.868, 139.591], [165.059, 149.696]], "leg_r": [[185.0, 149.216], [229.995, 139.797], [269.121, 131.607], [266.834, 121.011]], "leg_l": [[190.909, 148.754], [235.904, 139.335], [275.03, 131.145], [272.743, 120.549]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.269, 148.267], [100.697, 138.601]], "head": [82.721, 129.967], "nose": [[86.188, 120.587], [88.582, 114.109]], "arm_r": [[100.697, 140.511], [71.408, 134.117], [42.119, 127.722]], "arm_l": [[106.606, 138.661], [136.15, 143.791], [165.694, 148.921]], "leg_r": [[185.0, 149.216], [230.748, 144.48], [270.529, 140.363], [269.379, 129.589]], "leg_l": [[190.909, 148.754], [236.657, 144.019], [276.438, 139.901], [275.288, 129.128]]}}}, {"name": "Lat Pull Down", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.624, 79.248], [147.75, 38.349]], "head": [149.493, 18.728], "nose": [[155.287, 10.578], [159.302, 4.931]], "arm_r": [[147.75, 40.26], [174.771, 27.426], [194.0, 4.748]], "arm_l": [[153.658, 38.409], [181.607, 27.671], [198.0, 2.928]], "leg_r": [[150.0, 123.216], [194.414, 111.422], [193.0, 150.79], [203.993, 151.173]], "leg_l": [[155.909, 122.754], [200.077, 110.098], [197.0, 149.374], [207.967, 150.207]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.624, 79.248], [147.75, 38.349]], "head": [149.493, 18.728], "nose": [[158.186, 13.785], [164.248, 10.339]], "arm_r": [[147.75, 40.26], [171.723, 58.02], [194.0, 38.232]], "arm_l": [[153.658, 38.409], [176.752, 57.267], [198.0, 36.411]], "leg_r": [[150.0, 123.216], [194.414, 111.422], [193.0, 150.79], [203.993, 151.173]], "leg_l": [[155.909, 122.754], [200.077, 110.098], [197.0, 149.374], [207.967, 150.207]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.624, 79.248], [147.75, 38.349]], "head": [149.493, 18.728], "nose": [[156.917, 12.029], [162.078, 7.371]], "arm_r": [[147.75, 40.26], [177.186, 45.958], [194.0, 21.49]], "arm_l": [[153.658, 38.409], [182.861, 45.176], [198.0, 19.669]], "leg_r": [[150.0, 123.216], [194.414, 111.422], [193.0, 150.79], [203.993, 151.173]], "leg_l": [[155.909, 122.754], [200.077, 110.098], [197.0, 149.374], [207.967, 150.207]]}}}, {"name": "Leg Curl", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [203.204, 106.601], [202.436, 95.795]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [209.113, 106.14], [208.345, 95.333]]}, {"order": ["leg_l", "arm_l", "leg_r", "spine", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [159.815, 148.591], [170.773, 149.536]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [165.724, 148.13], [176.682, 149.074]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [191.338, 137.446], [199.183, 129.853]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [197.246, 136.984], [205.092, 129.391]]}}}, {"name": "Leg Extension", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [168.176, 148.448], [179.094, 147.128]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [174.085, 147.986], [185.003, 146.666]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [203.204, 106.601], [202.436, 95.795]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [209.113, 106.14], [208.345, 95.333]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.728, 76.19], [91.716, 36.447]], "head": [97.229, 17.514], "nose": [[106.643, 20.888], [113.221, 23.246]], "arm_r": [[91.716, 38.358], [99.481, 66.895], [114.481, 92.481]], "arm_l": [[97.625, 36.507], [105.39, 65.044], [120.39, 90.631]], "leg_r": [[118.0, 117.216], [163.301, 109.349], [194.166, 134.406], [201.163, 126.047]], "leg_l": [[123.909, 116.754], [169.21, 108.888], [200.075, 133.944], [207.072, 125.585]]}}}, {"name": "Leg Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.592, 78.084], [105.417, 39.589]], "head": [110.593, 20.564], "nose": [[120.262, 23.115], [127.023, 24.9]], "arm_r": [[105.417, 41.499], [113.181, 70.037], [141.372, 80.141]], "arm_l": [[111.325, 39.648], [119.09, 68.186], [147.281, 78.291]], "leg_r": [[140.0, 117.216], [157.129, 75.172], [185.0, 103.428], [192.89, 95.88]], "leg_l": [[145.909, 116.754], [161.7, 74.206], [189.0, 102.997], [197.04, 95.603]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.592, 78.084], [105.417, 39.589]], "head": [110.593, 20.564], "nose": [[120.262, 23.115], [127.023, 24.9]], "arm_r": [[105.417, 41.499], [113.181, 70.037], [141.372, 80.141]], "arm_l": [[111.325, 39.648], [119.09, 68.186], [147.281, 78.291]], "leg_r": [[140.0, 117.216], [180.564, 95.852], [220.0, 102.443], [221.84, 91.763]], "leg_l": [[145.909, 116.754], [185.065, 92.98], [224.0, 102.012], [226.522, 91.468]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.592, 78.084], [105.417, 39.589]], "head": [110.593, 20.564], "nose": [[120.262, 23.115], [127.023, 24.9]], "arm_r": [[105.417, 41.499], [113.181, 70.037], [141.372, 80.141]], "arm_l": [[111.325, 39.648], [119.09, 68.186], [147.281, 78.291]], "leg_r": [[140.0, 117.216], [168.724, 81.832], [202.5, 102.936], [208.393, 93.789]], "leg_l": [[145.909, 116.754], [173.379, 80.418], [206.5, 102.504], [212.668, 93.534]]}}}, {"name": "Leg Raises", "camera": 0.0, "frames": [{"order": ["arm_l", "spine", "leg_l", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [130.0, 149.91], [160.0, 149.91]], "arm_l": [[105.909, 148.059], [135.891, 149.091], [165.872, 150.122]], "leg_r": [[185.0, 149.216], [208.0, 109.984], [228.0, 75.869], [218.474, 70.452]], "leg_l": [[190.909, 148.754], [213.909, 109.522], [233.909, 75.407], [224.383, 69.991]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [130.0, 149.91], [160.0, 149.91]], "arm_l": [[105.909, 148.059], [135.891, 149.091], [165.872, 150.122]], "leg_r": [[185.0, 149.216], [230.552, 142.911], [270.163, 137.428], [268.632, 126.701]], "leg_l": [[190.909, 148.754], [236.461, 142.449], [276.072, 136.967], [274.541, 126.24]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.437, 143.905], "nose": [[80.437, 133.905], [80.437, 127.011]], "arm_r": [[100.0, 149.91], [130.0, 149.91], [160.0, 149.91]], "arm_l": [[105.909, 148.059], [135.891, 149.091], [165.872, 150.122]], "leg_r": [[185.0, 149.216], [223.136, 123.883], [256.297, 101.856], [250.146, 92.875]], "leg_l": [[190.909, 148.754], [229.045, 123.422], [262.206, 101.394], [256.055, 92.413]]}}}, {"name": "Plank", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[172.0, 114.0], [128.666, 117.734], [87.323, 121.296]], "head": [67.4, 123.012], "nose": [[58.706, 127.955], [52.644, 131.402]], "arm_r": [[93.232, 121.355], [93.232, 150.899], [63.232, 150.899]], "arm_l": [[87.323, 123.206], [87.323, 152.75], [57.323, 152.75]], "leg_r": [[177.909, 114.754], [204.293, 151.863], [244.293, 151.863], [244.293, 162.695]], "leg_l": [[172.0, 115.216], [198.385, 152.324], [238.385, 152.324], [238.385, 163.157]]}, {"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[168.0, 137.0], [125.161, 129.561], [84.291, 122.464]], "head": [64.595, 119.044], "nose": [[55.902, 123.987], [49.84, 127.433]], "arm_r": [[90.2, 122.524], [90.2, 152.068], [60.2, 152.068]], "arm_l": [[84.291, 124.374], [84.291, 153.919], [54.291, 153.919]], "leg_r": [[173.909, 137.754], [219.21, 145.621], [258.602, 152.461], [256.692, 163.129]], "leg_l": [[168.0, 138.216], [213.301, 146.082], [252.693, 152.922], [250.783, 163.591]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[170.0, 125.5], [126.541, 123.631], [85.081, 121.849]], "head": [65.1, 120.99], "nose": [[56.407, 125.932], [50.345, 129.379]], "arm_r": [[90.99, 121.908], [90.99, 151.452], [60.99, 151.452]], "arm_l": [[85.081, 123.759], [85.081, 153.303], [55.081, 153.303]], "leg_r": [[175.909, 126.254], [214.705, 150.594], [254.553, 154.028], [253.594, 164.819]], "leg_l": [[170.0, 126.716], [208.796, 151.056], [248.644, 154.489], [247.685, 165.281]]}}}, {"name": "Reverse Crunch", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[172.0, 148.0], [128.5, 148.0], [87.0, 148.0]], "head": [67.437, 143.905], "nose": [[67.437, 133.905], [67.437, 127.011]], "arm_r": [[87.0, 149.91], [117.0, 149.91], [147.0, 149.91]], "arm_l": [[92.909, 148.059], [122.891, 149.091], [152.872, 150.122]], "leg_r": [[172.0, 149.216], [164.012, 104.603], [201.6, 118.076], [205.362, 107.896]], "leg_l": [[177.909, 148.754], [169.921, 104.141], [207.509, 117.614], [211.271, 107.435]]}, {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[166.0, 136.0], [124.618, 154.243], [82.625, 143.355]], "head": [62.637, 144.043], "nose": [[62.637, 134.043], [62.637, 127.149]], "arm_r": [[82.625, 145.265], [112.511, 147.84], [142.397, 150.415]], "arm_l": [[88.534, 143.415], [118.516, 144.446], [148.497, 145.477]], "leg_r": [[166.0, 137.216], [146.56, 96.159], [185.952, 102.999], [187.862, 92.331]], "leg_l": [[171.909, 136.754], [152.468, 95.697], [191.861, 102.538], [193.771, 91.869]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[169.0, 142.0], [126.032, 151.193], [84.408, 145.723]], "head": [64.484, 144.007], "nose": [[64.484, 134.007], [64.484, 127.113]], "arm_r": [[84.408, 147.633], [114.379, 148.922], [144.351, 150.211]], "arm_l": [[90.317, 145.783], [120.298, 146.814], [150.28, 147.845]], "leg_r": [[169.0, 143.216], [155.168, 100.011], [193.805, 110.207], [196.652, 99.743]], "leg_l": [[174.909, 142.754], [161.076, 99.55], [199.713, 109.745], [202.56, 99.281]]}}}, {"name": "Rotary", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "leg_l", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.161], [160.0, 38.291]], "head": [160.0, 18.595], "nose": [[169.635, 21.273], [173.344, 22.304]], "arm_r": [[152.929, 39.755], [174.525, 53.006], [197.157, 61.434]], "arm_l": [[167.071, 36.828], [188.666, 50.079], [211.298, 58.507]], "leg_r": [[153.0, 122.0], [140.321, 135.664], [136.55, 175.476], [133.701, 174.968]], "leg_l": [[167.0, 122.0], [179.679, 135.664], [183.45, 175.476], [186.299, 174.968]]}, {"order": ["spine", "arm_r", "leg_l", "leg_r", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.161], [160.0, 38.291]], "head": [160.0, 18.595], "nose": [[150.365, 21.273], [146.656, 22.304]], "arm_r": [[152.929, 36.828], [131.334, 50.079], [108.702, 58.507]], "arm_l": [[167.071, 39.755], [145.475, 53.006], [122.843, 61.434]], "leg_r": [[153.0, 122.0], [140.321, 135.664], [136.55, 175.476], [133.701, 174.968]], "leg_l": [[167.0, 122.0], [179.679, 135.664], [183.45, 175.476], [186.299, 174.968]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "leg_l", "leg_r", "arm_l", "arm_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.161], [160.0, 38.291]], "head": [160.0, 18.595], "nose": null, "arm_r": [[149.0, 38.291], [149.0, 53.291], [149.0, 63.552]], "arm_l": [[171.0, 38.291], [171.0, 53.291], [171.0, 63.552]], "leg_r": [[153.0, 122.0], [140.321, 135.664], [136.55, 175.476], [133.701, 174.968]], "leg_l": [[167.0, 122.0], [179.679, 135.664], [183.45, 175.476], [186.299, 174.968]]}}}, {"name": "Seated Row", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.699, 79.201], [149.593, 38.855]], "head": [153.066, 19.458], "nose": [[163.029, 18.6], [170.002, 17.999]], "arm_r": [[149.593, 40.765], [170.108, 62.322], [200.0, 64.822]], "arm_l": [[155.502, 38.915], [174.012, 62.165], [204.0, 63.001]], "leg_r": [[140.0, 123.216], [183.885, 109.637], [188.0, 148.821], [198.942, 147.706]], "leg_l": [[145.909, 122.754], [189.433, 108.093], [192.0, 147.404], [202.977, 146.709]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.699, 79.201], [149.593, 38.855]], "head": [153.066, 19.458], "nose": [[163.029, 18.6], [170.002, 17.999]], "arm_r": [[149.593, 40.765], [130.28, 63.373], [158.0, 74.67]], "arm_l": [[155.502, 38.915], [134.829, 60.324], [162.0, 72.849]], "leg_r": [[140.0, 123.216], [183.885, 109.637], [188.0, 148.821], [198.942, 147.706]], "leg_l": [[145.909, 122.754], [189.433, 108.093], [192.0, 147.404], [202.977, 146.709]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.699, 79.201], [149.593, 38.855]], "head": [153.066, 19.458], "nose": [[163.029, 18.6], [170.002, 17.999]], "arm_r": [[149.593, 40.765], [149.005, 70.304], [179.0, 69.746]], "arm_l": [[155.502, 38.915], [153.003, 68.356], [183.0, 67.925]], "leg_r": [[140.0, 123.216], [183.885, 109.637], [188.0, 148.821], [198.942, 147.706]], "leg_l": [[145.909, 122.754], [189.433, 108.093], [192.0, 147.404], [202.977, 146.709]]}}}, {"name": "Shoulder Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.02, 90.377], [95.132, 50.074]], "head": [98.605, 30.677], "nose": [[108.511, 29.306], [115.443, 28.346]], "arm_r": [[95.132, 51.984], [110.132, 77.57], [110.132, 48.026]], "arm_l": [[101.041, 50.133], [116.041, 75.719], [116.041, 46.175]], "leg_r": [[120.0, 131.216], [161.917, 112.558], [164.0, 151.897], [174.985, 151.332]], "leg_l": [[125.909, 130.754], [167.351, 111.093], [168.0, 150.48], [178.999, 150.304]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.02, 90.377], [95.132, 50.074]], "head": [98.605, 30.677], "nose": [[108.511, 29.306], [115.443, 28.346]], "arm_r": [[95.132, 51.984], [112.766, 28.082], [137.036, 10.716]], "arm_l": [[101.041, 50.133], [118.675, 26.231], [142.945, 8.866]], "leg_r": [[120.0, 131.216], [161.917, 112.558], [164.0, 151.897], [174.985, 151.332]], "leg_l": [[125.909, 130.754], [167.351, 111.093], [168.0, 150.48], [178.999, 150.304]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.02, 90.377], [95.132, 50.074]], "head": [98.605, 30.677], "nose": [[108.511, 29.306], [115.443, 28.346]], "arm_r": [[95.132, 51.984], [125.091, 53.53], [138.711, 27.206]], "arm_l": [[101.041, 50.133], [131.0, 51.679], [144.62, 25.355]], "leg_r": [[120.0, 131.216], [161.917, 112.558], [164.0, 151.897], [174.985, 151.332]], "leg_l": [[125.909, 130.754], [167.351, 111.093], [168.0, 150.48], [178.999, 150.304]]}}}, {"name": "Side Plank", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 150.0], [132.629, 136.762], [93.16, 124.133]], "head": [74.139, 118.046], "nose": [[64.176, 117.188], [57.203, 116.587]], "arm_r": [[99.069, 124.192], [127.26, 134.297], [156.238, 141.943]], "arm_l": [[93.16, 126.043], [89.959, 155.418], [60.0, 153.88]], "leg_r": [[179.909, 150.754], [225.902, 151.545], [265.896, 152.232], [265.704, 163.063]], "leg_l": [[174.0, 151.216], [219.993, 152.006], [259.987, 152.694], [259.795, 163.525]]}, {"order": ["leg_r", "arm_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 137.0], [131.161, 129.561], [90.291, 122.464]], "head": [70.595, 119.044], "nose": [[60.595, 119.044], [53.595, 119.044]], "arm_r": [[96.2, 122.524], [101.41, 93.428], [106.619, 64.333]], "arm_l": [[90.291, 124.374], [89.999, 153.917], [60.0, 153.682]], "leg_r": [[179.909, 137.754], [225.21, 145.621], [264.602, 152.461], [262.692, 163.129]], "leg_l": [[174.0, 138.216], [219.301, 146.082], [258.693, 152.922], [256.783, 163.591]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_r", "arm_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 143.5], [131.792, 133.136], [91.525, 123.249]], "head": [72.119, 118.484], "nose": [[62.128, 118.055], [55.135, 117.754]], "arm_r": [[97.434, 123.309], [123.414, 108.536], [148.716, 92.662]], "arm_l": [[91.525, 125.159], [89.987, 154.665], [60.0, 153.781]], "leg_r": [[179.909, 144.254], [225.697, 148.596], [265.513, 152.372], [264.459, 163.155]], "leg_l": [[174.0, 144.716], [219.788, 149.057], [259.604, 152.833], [258.55, 163.616]]}}}, {"name": "Tricep Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.722, 81.925], [104.688, 41.337]], "head": [106.083, 21.689], "nose": [[116.03, 20.659], [122.991, 19.939]], "arm_r": [[104.688, 43.247], [94.678, 71.099], [124.0, 64.852]], "arm_l": [[110.597, 41.397], [98.506, 68.435], [128.0, 63.031]], "leg_r": [[118.0, 125.216], [162.267, 112.9], [156.0, 151.805], [166.864, 153.503]], "leg_l": [[123.909, 124.754], [167.985, 111.79], [160.0, 150.389], [170.779, 152.551]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.722, 81.925], [104.688, 41.337]], "head": [106.083, 21.689], "nose": [[116.03, 20.659], [122.991, 19.939]], "arm_r": [[104.688, 43.247], [109.666, 72.382], [124.0, 98.336]], "arm_l": [[110.597, 41.397], [113.172, 70.832], [128.0, 96.515]], "leg_r": [[118.0, 125.216], [162.267, 112.9], [156.0, 151.805], [166.864, 153.503]], "leg_l": [[123.909, 124.754], [167.985, 111.79], [160.0, 150.389], [170.779, 152.551]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.722, 81.925], [104.688, 41.337]], "head": [106.083, 21.689], "nose": [[116.03, 20.659], [122.991, 19.939]], "arm_r": [[104.688, 43.247], [95.816, 71.47], [124.0, 81.594]], "arm_l": [[110.597, 41.397], [100.045, 69.053], [128.0, 79.773]], "leg_r": [[118.0, 125.216], [162.267, 112.9], [156.0, 151.805], [166.864, 153.503]], "leg_l": [[123.909, 124.754], [167.985, 111.79], [160.0, 150.389], [170.779, 152.551]]}}}]} +{"profile": "neutral", "pitch": 10.0, "exercises": [{"name": "Abdominal", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [123.50070744350393, 83.31559451522868], [125.00047162900262, 42.39449550813546]], "head": [127.78393364820391, 22.89002207499297], "nose": [[137.6895074402238, 24.26100998553362], [144.6213839214148, 25.22042122738718]], "arm_r": [[125.00047162900262, 44.30462546247169], [153.5959458166933, 35.37057588667207], [155.0, 64.8824337615549]], "arm_l": [[130.90931814707588, 42.453981059823654], [159.51563713035878, 33.55366614061362], [160.99999999999997, 63.06171224414536]], "leg_r": [[128.0, 127.2155372436685], [171.17430886688956, 111.58284855334222], [168.0, 150.8509233159615], [178.9653082306577, 151.71059641116776]], "leg_l": [[133.90884651807326, 126.7540782623559], [176.35384130990658, 109.29150625391821], [172.0, 148.449771713863], [182.93464482641144, 149.6288883001427]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [123.11337415401846, 76.7383796324037], [167.64073825067507, 57.70967534760443]], "head": [186.18441534201082, 50.33136579709479], "nose": [[193.66654290527876, 56.965954490223126], [198.8685566836205, 61.57870955266287]], "arm_r": [[167.64073825067507, 59.61980530194066], [195.90006093783734, 49.70250854036303], [190.0, 78.66974230372583]], "arm_l": [[173.54958476874833, 57.76916089929262], [201.81359837899106, 47.864837419955926], [195.99999999999997, 76.84902078631627]], "leg_r": [[128.0, 127.2155372436685], [171.1743088668896, 111.58284855334223], [168.0, 150.8509233159615], [178.9653082306577, 151.71059641116778]], "leg_l": [[133.90884651807326, 126.7540782623559], [176.35384130990658, 109.29150625391821], [172.0, 148.449771713863], [182.93464482641144, 149.62888830014273]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[128.0, 126.0], [122.50068568111516, 81.31026966131319], [148.00041311155596, 46.22466606468976]], "head": [160.31364261806914, 30.70388407251191], "nose": [[169.4012247293501, 34.87711440053437], [175.74537923860663, 37.79049858562185]], "arm_r": [[148.00041311155596, 48.134796019025984], [177.4772385118675, 42.64130176976346], [172.5, 71.77608803264036]], "arm_l": [[153.90925962962922, 46.28415161637795], [183.38904849856343, 40.8061016600034], [178.49999999999997, 69.95536651523082]], "leg_r": [[128.0, 127.2155372436685], [171.17430886688956, 111.58284855334223], [168.0, 150.8509233159615], [178.96530823065774, 151.71059641116776]], "leg_l": [[133.90884651807326, 126.7540782623559], [176.35384130990658, 109.29150625391821], [172.0, 148.449771713863], [182.93464482641144, 149.62888830014273]]}}}, {"name": "Abductor", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [147.39401020336322, 133.10345930302373], [145.10544255919902, 172.83189963719428], [143.92179588176742, 171.6549669223465]], "leg_l": [[167.0, 116.0], [172.60598979663678, 133.10345930302373], [174.89455744080098, 172.83189963719428], [176.07820411823258, 171.6549669223465]]}, {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [130.0, 130.9232660108731], [120.61056874428219, 169.76167264761645], [115.7543569835581, 168.1244147020733]], "leg_l": [[167.0, 116.0], [190.0, 130.9232660108731], [199.38943125571782, 169.76167264761645], [204.24564301644193, 168.1244147020733]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [138.40398580536578, 132.34142152089595], [132.44536528849622, 171.75877049117304], [129.36356808016237, 170.42094139199114]], "leg_l": [[167.0, 116.0], [181.59601419463425, 132.34142152089595], [187.5546347115038, 171.75877049117304], [190.63643191983766, 170.42094139199114]]}}, "orbit": [{"yaw": 127.0, "sample": {"order": ["spine", "arm_r", "leg_r", "arm_l", "leg_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "nose": [[150.25538327938614, 14.840724837485546], [146.0426781173218, 15.811496044064228]], "arm_r": [[154.77104199355594, 32.327140292628755], [144.38560499931648, 59.71678856368911], [127.45898099051918, 84.10364976890271]], "arm_l": [[168.78499061052023, 33.440885896654606], [173.2070703112358, 62.76814640805501], [169.70061398975147, 88.91108067494635]], "leg_r": [[157.9655840337451, 116.45381562691817], [126.61174048168456, 131.4098395903588], [118.23109913779213, 170.5183789577097], [110.96489412668988, 168.85049407976638]], "leg_l": [[165.59044857033106, 116.73152857444055], [143.19089005938437, 132.85925017338457], [138.46571149104156, 172.44611886252008], [133.09011101583206, 171.0256258036004]], "props": {"bg": [{"kind": "poly", "pts": [[170.17558907270748, 64.59122072790889], [164.32336047718314, 120.25119531754564], [171.43542568533545, 120.66441958783159], [177.28765428085978, 65.00444499819484]], "w": 16, "color": "equipment"}, {"kind": "poly", "pts": [[131.35448580972135, 127.88309544322196], [171.286261312086, 133.1082995463687], [185.5103917283906, 133.9347480869406], [145.57861622602596, 128.70954398379385]], "w": 10, "color": "equipment"}, {"kind": "line", "pts": [[157.9099183587413, 135.8785623534417], [156.44686120986023, 149.79355600085088]], "w": 6, "color": "equipment"}], "fg": [{"kind": "line", "pts": [[125.25318741486642, 144.3309051200959], [127.97029354850271, 118.48877406062171]], "w": 6, "color": "prop"}, {"kind": "line", "pts": [[141.8323369925662, 145.78031570312166], [144.54944312620253, 119.93818464364746]], "w": 6, "color": "prop"}]}}}, {"yaw": 270.0, "sample": {"order": ["leg_l", "leg_r", "arm_l", "arm_r", "spine", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[171.0, 32.29134099396232], [180.27050983124843, 59.10236470334958], [188.67244508110866, 79.06508551601353]], "arm_l": [[149.0, 32.29134099396232], [139.72949016875157, 59.102364703349586], [131.3275549188913, 79.06508551601354]], "leg_r": [[167.0, 116.0], [172.60598979663678, 117.59341061272917], [174.89455744080098, 153.54028741485138], [176.07820411823258, 148.71567825347657]], "leg_l": [[153.0, 116.0], [147.39401020336322, 117.59341061272917], [145.10544255919902, 153.54028741485138], [143.9217958817674, 148.71567825347657]], "props": {"bg": [{"kind": "poly", "pts": [[160.0, 69.87214486573811], [160.0, 122.49493162974898], [160.0, 126.59917334965701], [160.0, 73.97638658564614]], "w": 16, "color": "equipment"}, {"kind": "poly", "pts": [[185.0, 125.9911475918806], [135.0, 125.9911475918806], [135.0, 134.19963103169664], [185.0, 134.19963103169664]], "w": 10, "color": "equipment"}, {"kind": "line", "pts": [[160.0, 134.79385241571816], [160.0, 147.9495491067209]], "w": 6, "color": "equipment"}], "fg": [{"kind": "line", "pts": [[172.60598979663678, 129.80941468294597], [172.60598979663678, 105.37740654251236]], "w": 6, "color": "prop"}, {"kind": "line", "pts": [[147.39401020336322, 129.80941468294597], [147.39401020336322, 105.37740654251236]], "w": 6, "color": "prop"}]}}}]}, {"name": "Adductor", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [130.0, 130.9232660108731], [120.61056874428219, 169.76167264761645], [115.7543569835581, 168.1244147020733]], "leg_l": [[167.0, 116.0], [190.0, 130.9232660108731], [199.38943125571782, 169.76167264761645], [204.24564301644193, 168.1244147020733]]}, {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [147.39401020336322, 133.10345930302373], [145.10544255919902, 172.83189963719428], [143.92179588176742, 171.6549669223465]], "leg_l": [[167.0, 116.0], [172.60598979663678, 133.10345930302373], [174.89455744080098, 172.83189963719428], [176.07820411823258, 171.6549669223465]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "arm_l", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 116.0], [160.0, 73.16086274396895], [160.0, 32.29134099396232]], "head": [160.0, 12.59518593371817], "arm_r": [[149.0, 32.29134099396232], [139.72949016875157, 60.82303648281693], [131.3275549188913, 86.68153428172431]], "arm_l": [[171.0, 32.29134099396232], [180.27050983124843, 60.82303648281693], [188.6724450811087, 86.68153428172431]], "leg_r": [[153.0, 116.0], [138.40398580536578, 132.34142152089595], [132.44536528849622, 171.75877049117304], [129.36356808016237, 170.42094139199114]], "leg_l": [[167.0, 116.0], [181.59601419463425, 132.34142152089595], [187.5546347115038, 171.75877049117304], [190.63643191983766, 170.42094139199114]]}}}, {"name": "Arm Curl", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.7861315886847, 81.14917968668395], [134.4304502554608, 40.41789305174976]], "head": [137.2139122746621, 20.913419618607264], "nose": [[146.73819953969002, 23.961033782707986], [153.3955951537561, 26.091290105818835]], "arm_r": [[134.4304502554608, 42.328023006085985], [159.00501158413056, 59.27389864999469], [174.90258951112673, 84.32882885065742]], "arm_l": [[140.33929677353407, 40.47737860343795], [164.91385810220382, 57.423254247346655], [180.8114360292, 82.47818444800937]], "leg_r": [[130.0, 125.2155372436685], [173.8364696761423, 111.48589278988837], [176.0, 150.82053882198593], [186.98389774627694, 150.2346069268626]], "leg_l": [[135.90884651807326, 124.7540782623559], [179.40646070778647, 110.0162218015468], [180.0, 149.4041949728996], [190.99878894026918, 149.24345139631006]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.7861315886847, 81.14917968668395], [134.4304502554608, 40.41789305174976]], "head": [137.2139122746621, 20.913419618607264], "nose": [[146.73819953969002, 23.961033782707986], [153.3955951537561, 26.091290105818835]], "arm_r": [[134.4304502554608, 42.328023006085985], [159.00501158413056, 59.27389864999469], [178.28863987472675, 36.64170344793001]], "arm_l": [[140.33929677353407, 40.47737860343795], [164.91385810220382, 57.423254247346655], [184.19748639280002, 34.791059045281976]], "leg_r": [[130.0, 125.2155372436685], [173.8364696761423, 111.48589278988837], [176.0, 150.82053882198593], [186.98389774627694, 150.2346069268626]], "leg_l": [[135.90884651807326, 124.7540782623559], [179.40646070778647, 110.0162218015468], [180.0, 149.4041949728996], [190.99878894026918, 149.24345139631006]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[130.0, 124.0], [130.7861315886847, 81.14917968668395], [134.4304502554608, 40.41789305174976]], "head": [137.2139122746621, 20.913419618607264], "nose": [[146.73819953969002, 23.961033782707986], [153.3955951537561, 26.091290105818835]], "arm_r": [[134.4304502554608, 42.328023006085985], [159.00501158413056, 59.27389864999469], [188.9319330919253, 61.334800134974905]], "arm_l": [[140.33929677353407, 40.47737860343795], [164.91385810220382, 57.423254247346655], [194.84077960999855, 59.48415573232686]], "leg_r": [[130.0, 125.2155372436685], [173.8364696761423, 111.48589278988837], [176.0, 150.82053882198593], [186.98389774627694, 150.2346069268626]], "leg_l": [[135.90884651807326, 124.7540782623559], [179.40646070778647, 110.0162218015468], [180.0, 149.4041949728996], [190.99878894026918, 149.24345139631006]]}}}, {"name": "Bird Dog", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.03555718411147, 99.29848248056776], [106.04649104941329, 92.90508070915538]], "head": [86.19556801658685, 95.30543819395331], "nose": [[77.1079859053059, 99.47866852197576], [70.76383139604934, 102.39205270706324]], "arm_r": [[111.95533756748654, 92.96456626084355], [115.93122267253811, 122.24819097380495], [111.0, 151.39056507548827]], "arm_l": [[106.04649104941329, 94.81521066349163], [110.07168565309334, 124.09230142764625], [105.0, 153.2112865928978]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471004, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.3925136662734]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.03555718411147, 99.29848248056776], [106.04649104941329, 92.90508070915538]], "head": [86.19556801658685, 95.30543819395331], "nose": [[76.52653951347901, 97.85688637216273], [69.76505872945553, 99.64109538787199]], "arm_r": [[111.95533756748654, 92.96456626084355], [115.93122267253811, 122.24819097380495], [111.0, 151.39056507548827]], "arm_l": [[106.04649104941329, 94.81521066349163], [77.6809337814338, 85.1965493841931], [49.31537651345428, 75.57788810489458]], "leg_r": [[195.90884651807326, 106.7540782623559], [240.3414345273704, 95.02927615912368], [278.9784675789331, 84.83379606935654], [286.04913128548503, 93.13226764344691]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.3925136662734]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.03555718411147, 99.29848248056776], [106.04649104941329, 92.90508070915538]], "head": [86.19556801658685, 95.30543819395331], "nose": [[77.1079859053059, 99.47866852197576], [70.76383139604934, 102.39205270706324]], "arm_r": [[111.95533756748654, 92.96456626084355], [115.93122267253811, 122.24819097380495], [111.0, 151.39056507548827]], "arm_l": [[106.04649104941329, 94.81521066349163], [110.07168565309334, 124.09230142764625], [105.0, 153.2112865928978]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471004, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.3925136662734]]}, {"order": ["leg_r", "arm_r", "spine", "arm_l", "leg_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.03555718411147, 99.29848248056776], [106.04649104941329, 92.90508070915538]], "head": [86.19556801658685, 95.30543819395331], "nose": [[76.52653951347901, 97.85688637216273], [69.76505872945553, 99.64109538787199]], "arm_r": [[111.95533756748654, 92.96456626084355], [83.58978029950704, 83.34590498154503], [55.22422303152753, 73.72724370224651]], "arm_l": [[106.04649104941329, 94.81521066349163], [110.07168565309334, 124.09230142764625], [105.0, 153.2112865928978]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471004, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [234.43258800929715, 95.49073514043629], [273.06962106085984, 85.29525505066914], [280.1402847674118, 93.59372662475951]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.03555718411147, 99.29848248056776], [106.04649104941329, 92.90508070915538]], "head": [86.19556801658685, 95.30543819395331], "nose": [[76.78202489248983, 98.67963526151854], [70.20417654698848, 101.0374038833528]], "arm_r": [[111.95533756748654, 92.96456626084355], [115.93122267253811, 122.24819097380495], [111.0, 151.39056507548827]], "arm_l": [[106.04649104941329, 94.81521066349163], [82.84966999647663, 113.55006179251055], [57.03634935368697, 128.60417717799652]], "leg_r": [[195.90884651807326, 106.7540782623559], [234.0445748556052, 132.08616357365625], [273.7023693105576, 126.9444353308775], [281.8124200154689, 134.26302654838682]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.3925136662734]]}}, "orbit": [{"yaw": 37.0, "sample": {"order": ["arm_r", "arm_l", "spine", "leg_r", "leg_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [155.68707029783513, 94.80852282274789], [122.95174655898823, 84.13159632031196]], "head": [107.09809451775733, 84.4574513154624], "nose": [[97.95900332573831, 88.5166399269906], [92.89233625341937, 90.7670340686228]], "arm_r": [[134.2907264664134, 84.17910359422488], [137.46600949517568, 113.87822453047738], [133.5277599609364, 142.5052657333192]], "arm_l": [[116.3317813043157, 85.65709393064989], [119.54644464966532, 115.35483396198678], [115.49601639130758, 143.94380727355005]], "leg_r": [[198.93171981481694, 106.60223367767217], [203.40886233537387, 152.15157118192892], [235.35428273726558, 156.3317344644463], [242.55052575493283, 163.48687425758854]], "leg_l": [[185.78729483793566, 106.97077120657869], [190.2644373584926, 152.52010871083542], [222.2098577603843, 156.7002719933528], [229.40610077805155, 163.85541178649504]], "props": {"bg": [], "fg": []}}}, {"yaw": 180.0, "sample": {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[190.0, 106.0], [232.96444281588853, 99.29848248056776], [273.9535089505867, 92.90508070915538]], "head": [293.80443198341317, 95.30543819395332], "nose": [[302.8920140946941, 99.47866852197578], [309.23616860395066, 102.39205270706326]], "arm_r": [[273.9535089505867, 94.81521066349163], [269.97762384553516, 124.09883537645301], [274.90884651807323, 153.24120947813634]], "arm_l": [[279.8623554686599, 92.96456626084357], [275.83716086497986, 122.2416570249982], [280.90884651807323, 151.36064219024973]], "leg_r": [[190.0, 107.2155372436685], [184.39401020336322, 152.17902593017354], [144.39401020336322, 152.17902593017354], [135.38333771618431, 158.39251366627337]], "leg_l": [[195.90884651807326, 106.7540782623559], [190.30285672143648, 151.7175669488609], [150.30285672143648, 151.7175669488609], [141.29218423425758, 157.93105468496077]], "props": {"bg": [], "fg": []}}}]}, {"name": "Calfs", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.9947902691037, 76.01258331473494], [128.14293290308055, 35.16126798294198]], "head": [131.61589645641916, 15.764341775082897], "nose": [[141.46845419959308, 17.475220472543253], [148.36210847067855, 18.672290974183092]], "arm_r": [[128.14293290308055, 37.071397937278206], [155.6576522621167, 48.84552396045507], [166.0, 76.57858882179907]], "arm_l": [[134.0517794211538, 35.22075353463017], [161.85257237368958, 46.324036719323196], [170.0, 74.75786730438953]], "leg_r": [[140.0, 119.2155372436685], [185.99829621354849, 118.82564110752023], [212.0, 148.75976983403476], [218.68954801152353, 140.16030879539852]], "leg_l": [[145.90884651807326, 118.7540782623559], [191.8707292881921, 116.9102687478058], [216.0, 148.32823373796066], [223.2019010505247, 140.1399483462988]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.9947902691037, 76.01258331473494], [128.14293290308055, 35.16126798294198]], "head": [131.61589645641916, 15.764341775082897], "nose": [[141.46845419959308, 17.475220472543253], [148.36210847067855, 18.672290974183092]], "arm_r": [[128.14293290308055, 37.071397937278206], [155.6576522621167, 48.84552396045507], [166.0, 76.57858882179907]], "arm_l": [[134.0517794211538, 35.22075353463017], [161.85257237368958, 46.324036719323196], [170.0, 74.75786730438953]], "leg_r": [[140.0, 119.2155372436685], [185.1751715569397, 110.6752678976193], [212.0, 139.89650005692488], [222.040000508351, 135.47051611931823]], "leg_l": [[145.90884651807326, 118.7540782623559], [190.80108243714875, 108.87222292080564], [216.0, 139.46496396085078], [226.26606991421917, 135.57431163727887]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 118.0], [130.9947902691037, 76.01258331473494], [128.14293290308055, 35.16126798294198]], "head": [131.61589645641916, 15.764341775082897], "nose": [[141.46845419959308, 17.475220472543253], [148.36210847067855, 18.672290974183092]], "arm_r": [[128.14293290308055, 37.071397937278206], [155.6576522621167, 48.84552396045507], [166.0, 76.57858882179907]], "arm_l": [[134.0517794211538, 35.22075353463017], [161.85257237368958, 46.324036719323196], [170.0, 74.75786730438953]], "leg_r": [[140.0, 119.2155372436685], [185.76022286869107, 114.59616916585809], [212.0, 144.3281349454798], [220.6686979213759, 137.6594754981849]], "leg_l": [[145.90884651807326, 118.7540782623559], [191.50375298446497, 112.75527283004915], [216.0, 143.8965988494057], [225.03661802939996, 137.7197628895158]]}}}, {"name": "Cat-Cow", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [145.1601730939384, 123.58044185519884], [109.35354598857317, 94.41322108943268]], "head": [89.42965202673827, 96.1298541129813], "nose": [[79.80600507406713, 93.4122413130513], [73.0771732024989, 91.51209267785273]], "arm_r": [[115.26239250664642, 94.47270664112087], [120.87972526065431, 123.49440084545728], [111.0, 151.39056507548827]], "arm_l": [[109.35354598857317, 96.32335104376892], [114.9679818582322, 125.3455889056239], [105.0, 153.2112865928978]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471004, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.3925136662734]]}, {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [152.08424735154603, 74.85543177687914], [109.94656592660422, 96.70312504123498]], "head": [93.56352504082439, 108.00037547050745], "nose": [[86.43854210873769, 115.01711390210609], [81.48879464043186, 119.89166358434622]], "arm_r": [[115.85541244467747, 96.76261059292317], [124.5590964138107, 125.03612878182669], [111.0, 151.39056507548827]], "arm_l": [[109.94656592660422, 98.61325499557122], [118.63058159288913, 126.89263803630388], [105.0, 153.2112865928978]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471004, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.39251366627337]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[190.0, 106.0], [147.07348578236468, 98.95228286813989], [105.7422999370209, 95.05845136735941]], "head": [86.94844752130274, 101.79493314402872], "nose": [[77.25780748643307, 104.26302870834161], [70.48077400378631, 105.98906189268591]], "arm_r": [[111.65114645509415, 95.1179369190476], [120.46983670889635, 123.3568712620384], [111.0, 151.39056507548824]], "arm_l": [[105.7422999370209, 96.96858132169565], [114.56083205483813, 125.20756355913188], [105.0, 153.21128659289778]], "leg_r": [[195.90884651807326, 106.7540782623559], [201.51483631471007, 151.7175669488609], [241.51483631471004, 151.7175669488609], [250.52550880188895, 157.93105468496077]], "leg_l": [[190.0, 107.2155372436685], [195.60598979663678, 152.17902593017354], [235.60598979663678, 152.17902593017354], [244.61666228381569, 158.39251366627337]]}}}, {"name": "Chest Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.04264946482697, 80.73349088839885], [98.30413502720322, 40.17760054359378]], "head": [100.39470429255628, 20.589343081612355], "nose": [[110.35779236721048, 19.730928253756097], [117.3311552538527, 19.130106695514076]], "arm_r": [[98.30413502720322, 42.08773049793001], [93.0946896971953, 71.18311980971865], [116.07602299076464, 52.19245316293397]], "arm_l": [[104.21298154527646, 40.237086095281974], [99.00353621526855, 69.3324754070706], [121.98486950883789, 50.341808760285936]], "leg_r": [[116.0, 123.2155372436685], [160.6875870401012, 112.47166989865372], [158.0, 151.77496208102255], [168.97514242459204, 152.5028201333689]], "leg_l": [[121.90884651807325, 122.7540782623559], [166.38862646620098, 111.20411892847166], [162.0, 150.35861823193625], [172.93359315614495, 151.5471554084083]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.04264946482697, 80.73349088839885], [98.30413502720322, 40.17760054359378]], "head": [100.39470429255628, 20.589343081612355], "nose": [[110.35779236721048, 19.730928253756097], [117.3311552538527, 19.130106695514076]], "arm_r": [[98.30413502720322, 42.08773049793001], [128.1397918882514, 45.17594372902312], [157.2486636765313, 52.323340481322006]], "arm_l": [[104.21298154527646, 40.237086095281974], [134.04863840632467, 43.32529932637508], [163.15751019460455, 50.47269607867397]], "leg_r": [[116.0, 123.2155372436685], [160.6875870401012, 112.47166989865372], [158.0, 151.77496208102255], [168.97514242459204, 152.5028201333689]], "leg_l": [[121.90884651807325, 122.7540782623559], [166.38862646620098, 111.20411892847166], [162.0, 150.35861823193625], [172.93359315614495, 151.5471554084083]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[116.0, 122.0], [104.04264946482697, 80.73349088839885], [98.30413502720322, 40.17760054359378]], "head": [100.39470429255628, 20.589343081612355], "nose": [[110.35779236721048, 19.730928253756097], [117.3311552538527, 19.130106695514076]], "arm_r": [[98.30413502720322, 42.08773049793001], [116.35858572176467, 65.68280376169301], [145.58968766532172, 59.036797490709745]], "arm_l": [[104.21298154527646, 40.237086095281974], [122.26743223983792, 63.83215935904497], [151.49853418339498, 57.18615308806171]], "leg_r": [[116.0, 123.2155372436685], [160.6875870401012, 112.47166989865372], [158.0, 151.77496208102255], [168.97514242459204, 152.5028201333689]], "leg_l": [[121.90884651807325, 122.7540782623559], [166.38862646620098, 111.20411892847166], [162.0, 150.35861823193625], [172.93359315614495, 151.5471554084083]]}}}, {"name": "Dead Bug", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [100.0, 120.36589736396999], [100.0, 90.82166477360374]], "arm_l": [[105.90884651807325, 148.05948555168817], [105.90884651807325, 118.51525296132193], [105.90884651807325, 88.97102037095569]], "leg_r": [[185.0, 149.2155372436685], [205.16507275229756, 108.4991273664634], [244.55738287278587, 115.33953023297677], [246.4675128271221, 104.67122081865428]], "leg_l": [[190.90884651807326, 148.7540782623559], [211.07391927037082, 108.03766838515077], [250.46622939085913, 114.87807125166415], [252.37635934519537, 104.20976183734166]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [78.78679656440357, 129.01920274473565], [57.57359312880715, 108.12827553513509]], "arm_l": [[105.90884651807325, 148.05948555168817], [105.90884651807325, 118.51525296132193], [105.90884651807325, 88.97102037095569]], "leg_r": [[185.0, 149.2155372436685], [205.16507275229756, 108.4991273664634], [244.55738287278587, 115.33953023297677], [246.4675128271221, 104.67122081865428]], "leg_l": [[190.90884651807326, 148.7540782623559], [235.12688453123593, 136.2673872310511], [273.57735236876863, 125.40939502991648], [270.5453414547817, 114.99615735074556]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [100.0, 120.36589736396999], [100.0, 90.82166477360374]], "arm_l": [[105.90884651807325, 148.05948555168817], [105.90884651807325, 118.51525296132193], [105.90884651807325, 88.97102037095569]], "leg_r": [[185.0, 149.2155372436685], [205.16507275229756, 108.4991273664634], [244.55738287278587, 115.33953023297677], [246.4675128271221, 104.67122081865428]], "leg_l": [[190.90884651807326, 148.7540782623559], [211.07391927037082, 108.03766838515077], [250.46622939085913, 114.87807125166415], [252.37635934519537, 104.20976183734166]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [100.0, 120.36589736396999], [100.0, 90.82166477360374]], "arm_l": [[105.90884651807325, 148.05948555168817], [84.69564308247682, 127.16855834208761], [63.482439646880394, 106.27763113248703]], "leg_r": [[185.0, 149.2155372436685], [229.21803801316267, 136.7288462123637], [267.6685058506954, 125.87085401122908], [264.63649493670846, 115.45761633205817]], "leg_l": [[190.90884651807326, 148.7540782623559], [211.07391927037082, 108.03766838515077], [250.46622939085913, 114.87807125166415], [252.37635934519537, 104.20976183734166]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [88.51949702904732, 122.61481816034394], [77.03899405809463, 95.31950636635166]], "arm_l": [[105.90884651807325, 148.05948555168817], [105.90884651807325, 118.51525296132193], [105.90884651807325, 88.97102037095569]], "leg_r": [[185.0, 149.2155372436685], [205.16507275229756, 108.4991273664634], [244.55738287278587, 115.33953023297677], [246.4675128271221, 104.67122081865428]], "leg_l": [[190.90884651807326, 148.7540782623559], [226.14689090154624, 119.63505607061941], [266.0920722917292, 117.57342185184505], [265.5163767730568, 106.755382661499]]}}}, {"name": "Hollow Body Hold", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [70.0, 149.9101299543362], [40.0, 149.9101299543362]], "arm_l": [[105.90884651807325, 148.05948555168817], [135.90884651807326, 148.05948555168817], [165.90884651807326, 148.05948555168817]], "leg_r": [[185.0, 149.2155372436685], [231.0, 149.2155372436685], [271.0, 149.2155372436685], [271.0, 138.38265196053422]], "leg_l": [[190.90884651807326, 148.7540782623559], [236.90884651807326, 148.7540782623559], [276.90884651807323, 148.7540782623559], [276.90884651807323, 137.92119297922162]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [140.58688278525045, 148.43364741865258], [102.76846842615609, 129.42694930442767]], "head": [87.44757956377653, 116.76650487323789], "nose": [[93.93309205085959, 109.15479496153674], [98.43260531866537, 103.8739494143883]], "arm_r": [[102.76846842615609, 131.3370792587639], [75.5792348150566, 118.85114703696041], [48.3900012039571, 106.3652148151569]], "arm_l": [[108.67731494422934, 129.48643485611586], [136.8680935678066, 139.5911575211198], [165.05887219138384, 149.69588018612376]], "leg_r": [[185.0, 149.2155372436685], [229.99478963375506, 139.79689717094502], [269.12069366310726, 131.60677536857676], [266.8336650641119, 121.01061461985441]], "leg_l": [[190.90884651807326, 148.7540782623559], [235.90363615182832, 139.3354381896324], [275.0295401811805, 131.14531638726413], [272.74251158218516, 120.54915563854179]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.26935782158634, 148.2668263271459], [100.6970043790406, 138.60132020497852]], "head": [82.72112345305727, 129.96709412388378], "nose": [[86.18778863202375, 120.58720966100572], [88.58192963530344, 114.10929361221746]], "arm_r": [[100.6970043790406, 140.51145015931476], [71.40812416544262, 134.11690786335836], [42.11924395184462, 127.72236556740197]], "arm_l": [[106.60585089711385, 138.6608057566667], [136.1500834874801, 143.79110790655173], [165.69431607784634, 148.92141005643677]], "leg_r": [[185.0, 149.2155372436685], [230.74800718694058, 144.48027695599242], [270.5288830016715, 140.36265931453494], [269.3790699057273, 129.58911771044515]], "leg_l": [[190.90884651807326, 148.7540782623559], [236.65685370501384, 144.01881797467982], [276.4377295197447, 139.90120033322233], [275.28791642380054, 129.12765872913255]]}}}, {"name": "Lat Pull Down", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.62433082233014, 79.24791483349992], [147.74955388155342, 38.34937572031629]], "head": [149.49266873650657, 18.728170476508154], "nose": [[155.28735587215587, 10.578225630072646], [159.30239092661319, 4.931274641291457]], "arm_r": [[147.74955388155342, 40.259505674652516], [174.77136716083461, 27.425922423252715], [194.0, 4.748391839859067]], "arm_l": [[153.6584003996267, 38.40886127200448], [181.60676431735172, 27.670890621268786], [198.0, 2.9276703224495346]], "leg_r": [[150.0, 123.2155372436685], [194.41395436835177, 111.42246307048075], [193.0, 150.79015432801035], [203.99312537163428, 151.17308446470886]], "leg_l": [[155.90884651807326, 122.7540782623559], [200.07727426166045, 110.09824525529687], [197.0, 149.373810478924], [207.96739988435445, 150.20720445545675]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.62433082233014, 79.24791483349992], [147.74955388155342, 38.34937572031629]], "head": [149.49266873650657, 18.728170476508154], "nose": [[158.18575082167658, 13.785466372427464], [164.24792864816766, 10.338639236884735]], "arm_r": [[147.74955388155342, 40.259505674652516], [171.72345780323056, 58.020259740573785], [194.0, 38.231855442274124]], "arm_l": [[153.6584003996267, 38.40886127200448], [176.75165320875354, 57.2673942535663], [198.0, 36.41113392486461]], "leg_r": [[150.0, 123.2155372436685], [194.41395436835177, 111.42246307048075], [193.0, 150.79015432801035], [203.99312537163428, 151.17308446470886]], "leg_l": [[155.90884651807326, 122.7540782623559], [200.07727426166045, 110.09824525529687], [197.0, 149.373810478924], [207.96739988435445, 150.20720445545675]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [146.62433082233014, 79.24791483349992], [147.74955388155342, 38.34937572031629]], "head": [149.49266873650657, 18.728170476508154], "nose": [[156.91670692063303, 12.028643848407304], [162.0776482783039, 7.371358528174099]], "arm_r": [[147.74955388155342, 40.259505674652516], [177.18620166864008, 45.95811146381125], [194.0, 21.49012364106659]], "arm_l": [[153.6584003996267, 38.40886127200448], [182.86086618586543, 45.17585880681934], [198.0, 19.66940212365707]], "leg_r": [[150.0, 123.2155372436685], [194.41395436835177, 111.42246307048075], [193.0, 150.79015432801035], [203.99312537163428, 151.17308446470886]], "leg_l": [[155.90884651807326, 122.7540782623559], [200.07727426166045, 110.09824525529687], [197.0, 149.373810478924], [207.96739988435445, 150.20720445545675]]}}, "orbit": [{"yaw": 37.0, "sample": {"order": ["spine", "leg_l", "arm_l", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[150.0, 122.0], [147.3040707245407, 78.89514362473935], [148.20271381636047, 38.114194914475945]], "head": [149.59482723761698, 18.67515228851495], "nose": [[154.82362622309998, 10.15108863498608], [158.03017579167425, 4.923725199021456]], "arm_r": [[141.58274856168794, 39.63969252481388], [163.16332819238937, 29.629999065841375], [178.51999718740836, 8.961939106629913]], "arm_l": [[159.54169372378558, 38.16170218838887], [181.8622495962053, 30.344449654035888], [194.95446973694257, 7.314389402273139]], "leg_r": [[145.78729483793566, 122.97077120657869], [181.25785593812145, 115.81913656544059], [180.12862176996924, 155.0390638196267], [188.90812205815823, 156.57082043229062]], "leg_l": [[158.93171981481694, 122.60223367767217], [194.20619463380368, 114.56218166811979], [191.74857413428708, 153.51615916977624], [200.50752913482114, 155.49569120384058]], "props": {"bg": [{"kind": "poly", "pts": [[125.25533829692662, 127.16784412500894], [154.00621665862917, 130.9299910792746], [163.4889702694989, 131.4809567729892], [134.73809190779636, 127.71880981872354]], "w": 8, "color": "equipment"}, {"kind": "line", "pts": [[144.1631461190869, 131.31225668434325], [142.28207264195407, 149.20296280244077]], "w": 5, "color": "equipment"}, {"kind": "circle", "c": [258.197452678252, 32.37490189145329], "r": 4, "fill": true, "w": 3, "color": "prop"}, {"kind": "line", "pts": [[258.197452678252, 32.37490189145329], [186.73723346217548, 8.138164254451526]], "w": 4, "color": "equipment"}], "fg": [{"kind": "line", "pts": [[167.56998122104045, 5.630066284941094], [205.9044857033105, 10.646262223961958]], "w": 4, "color": "prop"}]}}}, {"yaw": 180.0, "sample": {"order": ["leg_r", "leg_l", "spine", "arm_r", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[150.0, 122.0], [153.37566917766986, 79.24791483349992], [152.25044611844658, 38.34937572031629]], "head": [150.50733126349343, 18.728170476508154], "nose": [[144.71264412784413, 10.578225630072646], [140.69760907338681, 4.931274641291457]], "arm_r": [[158.15929263651984, 38.40886127200448], [131.13747935723865, 25.575278020604674], [111.90884651807325, 2.897747437211029]], "arm_l": [[152.25044611844658, 40.259505674652516], [124.30208220072154, 29.521535023916826], [107.90884651807326, 4.778314725097573]], "leg_r": [[155.90884651807326, 122.7540782623559], [111.49489214972148, 110.96100408916814], [112.90884651807325, 150.3286953466977], [101.91572114643897, 150.71162548339626]], "leg_l": [[150.0, 123.2155372436685], [105.83157225641283, 110.55970423660949], [108.90884651807326, 149.83526946023665], [97.94144663371881, 150.66866343676938]], "props": {"bg": [{"kind": "poly", "pts": [[174.0, 126.78137981968192], [138.0, 126.78137981968192], [138.0, 132.25370211289263], [174.0, 132.25370211289263]], "w": 8, "color": "equipment"}, {"kind": "line", "pts": [[156.0, 131.39692620785908], [156.0, 148.31139338200543]], "w": 5, "color": "equipment"}, {"kind": "circle", "c": [28.0, 25.21166005905144], "r": 4, "fill": true, "w": 3, "color": "prop"}, {"kind": "line", "pts": [[28.0, 25.21166005905144], [109.90884651807326, 3.838031081154301]], "w": 4, "color": "equipment"}], "fg": [{"kind": "line", "pts": [[133.90884651807326, 3.8380310811543006], [85.90884651807326, 3.8380310811543015]], "w": 4, "color": "prop"}]}}}]}, {"name": "Leg Curl", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [203.20371864895455, 106.60120530053786], [202.4363974377692, 95.79470838149437]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [209.1125651670278, 106.13974631922524], [208.34524395584245, 95.33324940018176]]}, {"order": ["leg_l", "arm_l", "leg_r", "spine", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [159.81492692865524, 148.59148443479444], [170.77306860766444, 149.53563259774617]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [165.7237734467285, 148.1300254534818], [176.6819151257377, 149.07417361643354]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [191.3375272105556, 137.44565683383726], [199.1832821512516, 129.8527871797909]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [197.24637372862887, 136.98419785252463], [205.09212866932486, 129.3913281984783]]}}}, {"name": "Leg Extension", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [168.17593037476746, 148.44775976153034], [179.093938042822, 147.12756314489147]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [174.08477689284072, 147.9863007802177], [185.00278456089526, 146.66610416357884]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [203.20371864895455, 106.60120530053786], [202.4363974377692, 95.79470838149437]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [209.1125651670278, 106.13974631922524], [208.34524395584245, 95.33324940018176]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [101.72808522765135, 76.19044808081628], [91.71636489268228, 36.44745235385585]], "head": [97.22911200902226, 17.51429293718145], "nose": [[106.64265513311928, 20.888490004746693], [113.22050347862063, 23.246258626580946]], "arm_r": [[91.71636489268228, 38.35758230819208], [99.4809362457579, 66.89511958511801], [114.4809362457579, 92.48117554369131]], "arm_l": [[97.62521141075553, 36.50693790554404], [105.38978276383115, 65.04447518246997], [120.38978276383115, 90.63053114104326]], "leg_r": [[118.0, 117.2155372436685], [163.30115663856157, 109.34907394717814], [194.16613997407038, 134.4056644612481], [201.16300039712578, 126.04674386776264]], "leg_l": [[123.90884651807325, 116.7540782623559], [169.21000315663483, 108.88761496586552], [200.07498649214364, 133.94420547993548], [207.07184691519905, 125.58528488645004]]}}, "orbit": [{"yaw": 37.0, "sample": {"order": ["arm_l", "spine", "arm_r", "leg_l", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 116.0], [105.00467104633924, 74.48996656412565], [97.00895567017038, 33.70070519368849]], "head": [101.4116312751903, 15.343650354052286], "nose": [[110.06318318500227, 20.358692682071943], [115.31648645342548, 23.403873307202012]], "arm_r": [[90.38899041549786, 35.22620280402643], [96.59005281836, 64.57516948281769], [108.5695854690694, 91.72878667233499]], "arm_l": [[108.34793557759552, 33.74821246760142], [114.54899798045767, 63.097179146392676], [126.52853063116706, 90.25079633590998]], "leg_r": [[113.78729483793566, 116.97077120657869], [149.9664071757056, 113.8384637009904], [153.85957458488554, 153.4465832699093], [162.57908320756252, 153.26736302257655]], "leg_l": [[126.93171981481694, 116.60223367767217], [163.11083215258688, 113.4699261720839], [167.00399956176682, 153.0780457410028], [175.7235081844438, 152.89882549367005]], "props": {"bg": [{"kind": "poly", "pts": [[106.24251462180918, 120.85205320267173], [94.80856445333131, 44.79327452542702], [104.29131806420105, 45.344240219141625], [115.72526823267891, 121.40301889638633]], "w": 9, "color": "equipment"}, {"kind": "poly", "pts": [[101.24169339739956, 122.2128849456383], [151.17511134858344, 124.7164255628519], [160.65786495945318, 125.2673912565665], [110.7244470082693, 122.7638506393529]], "w": 9, "color": "equipment"}, {"kind": "line", "pts": [[108.96860407889773, 124.8942403560915], [106.4605061093873, 148.74851518022155]], "w": 5, "color": "equipment"}, {"kind": "line", "pts": [[150.7066587654828, 128.34059638801995], [147.98955263184652, 154.18272744749413]], "w": 5, "color": "equipment"}, {"kind": "poly", "pts": [[100.30260356580132, 148.15832207268397], [149.81800518873348, 154.63757516058593], [155.74472619552708, 154.98192871915757], [106.22932457259492, 148.5026756312556]], "w": 5, "color": "equipment"}, {"kind": "circle", "c": [117.52256409344713, 89.73985261227406], "r": 3.5, "fill": true, "w": 3, "color": "prop"}], "fg": [{"kind": "circle", "c": [166.90947233550744, 146.11361907675857], "r": 5, "fill": true, "color": "prop"}]}}}, {"yaw": 180.0, "sample": {"order": ["leg_r", "arm_r", "leg_l", "spine", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[118.0, 116.0], [134.27191477234865, 76.19044808081628], [144.2836351073177, 36.44745235385585]], "head": [138.77088799097774, 17.51429293718145], "nose": [[129.35734486688074, 20.888490004746693], [122.77949652137937, 23.246258626580946]], "arm_r": [[150.19248162539097, 36.50693790554404], [142.42791027231536, 65.04447518246997], [127.42791027231534, 90.63053114104326]], "arm_l": [[144.2836351073177, 38.35758230819208], [136.5190637542421, 66.89511958511801], [121.5190637542421, 92.48117554369131]], "leg_r": [[123.90884651807325, 116.7540782623559], [78.60768987951168, 108.88761496586552], [73.73291614330579, 147.9863007802177], [62.81490847525124, 146.66610416357884]], "leg_l": [[118.0, 117.2155372436685], [72.69884336143843, 109.34907394717814], [67.82406962523254, 148.44775976153034], [56.90606195717799, 147.12756314489147]], "props": {"bg": [{"kind": "poly", "pts": [[126.0, 118.9019945781101], [150.0, 49.364740639952885], [150.0, 54.83706293316358], [126.0, 124.3743168713208]], "w": 9, "color": "equipment"}, {"kind": "poly", "pts": [[132.0, 120.78137981968192], [70.0, 117.02260933653828], [70.0, 122.49493162974898], [132.0, 126.25370211289261]], "w": 9, "color": "equipment"}, {"kind": "line", "pts": [[128.0, 125.39692620785908], [128.0, 147.9495491067209]], "w": 5, "color": "equipment"}, {"kind": "line", "pts": [[76.0, 123.51754096628727], [76.0, 147.9495491067209]], "w": 5, "color": "equipment"}, {"kind": "poly", "pts": [[132.0, 146.23944839009255], [70.0, 146.23944839009255], [70.0, 149.65964982334924], [132.0, 149.65964982334924]], "w": 5, "color": "equipment"}, {"kind": "circle", "c": [122.0, 91.56799185956638], "r": 3.5, "fill": true, "w": 3, "color": "prop"}], "fg": [{"kind": "circle", "c": [63.706002038882666, 140.75964282059232], "r": 5, "fill": true, "color": "prop"}]}}}]}, {"name": "Leg Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.59179949383865, 78.0835670547446], [105.41656376460136, 39.588898523569924]], "head": [110.59294466665177, 20.56387367228598], "nose": [[120.26197316975961, 23.115321850495402], [127.02345395378309, 24.899530866204653]], "arm_r": [[105.41656376460136, 41.49902847790615], [113.18113511767699, 70.03656575483208], [141.37191374125425, 80.14128841983603]], "arm_l": [[111.32541028267461, 39.648384075258114], [119.08998163575023, 68.18592135218404], [147.2807602593275, 78.29064401718799]], "leg_r": [[140.0, 117.2155372436685], [157.1292173153023, 75.17232014967723], [185.0, 103.4282287014976], [192.89024540879532, 95.88020391213522]], "leg_l": [[145.90884651807326, 116.7540782623559], [161.69967986127625, 74.2057150715518], [189.0, 102.9966926054235], [197.03965931177694, 95.60316169903263]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.59179949383865, 78.0835670547446], [105.41656376460136, 39.588898523569924]], "head": [110.59294466665177, 20.56387367228598], "nose": [[120.26197316975961, 23.115321850495402], [127.02345395378309, 24.899530866204653]], "arm_r": [[105.41656376460136, 41.49902847790615], [113.18113511767699, 70.03656575483208], [141.37191374125425, 80.14128841983603]], "arm_l": [[111.32541028267461, 39.648384075258114], [119.08998163575023, 68.18592135218404], [147.2807602593275, 78.29064401718799]], "leg_r": [[140.0, 117.2155372436685], [180.56387328382812, 95.8524219129624], [220.0, 102.44342094848537], [221.8404858503854, 91.76324503029944]], "leg_l": [[145.90884651807326, 116.7540782623559], [185.0654782344644, 92.98043985822271], [224.0, 102.0118848524113], [226.52196163749238, 91.46755465641775]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 116.0], [119.59179949383865, 78.0835670547446], [105.41656376460136, 39.588898523569924]], "head": [110.59294466665177, 20.56387367228598], "nose": [[120.26197316975961, 23.115321850495402], [127.02345395378309, 24.899530866204653]], "arm_r": [[105.41656376460136, 41.49902847790615], [113.18113511767699, 70.03656575483208], [141.37191374125425, 80.14128841983603]], "arm_l": [[111.32541028267461, 39.648384075258114], [119.08998163575023, 68.18592135218404], [147.2807602593275, 78.29064401718799]], "leg_r": [[140.0, 117.2155372436685], [168.72442575335768, 81.83218317512427], [202.5, 102.9358248249915], [208.39302981821828, 93.78865179534496]], "leg_l": [[145.90884651807326, 116.7540782623559], [173.37889429197503, 80.41752162098928], [206.5, 102.5042887289174], [212.66756005027608, 93.53436026427744]]}}}, {"name": "Leg Raises", "camera": 0.0, "frames": [{"order": ["arm_l", "spine", "leg_l", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [130.0, 149.91012995433624], [160.0, 149.91012995433624]], "arm_l": [[105.90884651807325, 148.05948555168817], [135.89057132864613, 149.09056439955359], [165.872296139219, 150.121643247419]], "leg_r": [[185.0, 149.2155372436685], [208.0, 109.98358477385614], [228.0, 75.8688434957584], [218.47372055837118, 70.45240085419125]], "leg_l": [[190.90884651807326, 148.7540782623559], [213.90884651807326, 109.5221257925435], [233.90884651807326, 75.4073845144458], [224.38256707644445, 69.99094187287865]]}, {"order": ["arm_l", "leg_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [130.0, 149.91012995433624], [160.0, 149.91012995433624]], "arm_l": [[105.90884651807325, 148.05948555168817], [135.89057132864613, 149.09056439955359], [165.872296139219, 150.121643247419]], "leg_r": [[185.0, 149.2155372436685], [230.55233116211224, 142.91083479720226], [270.163053911775, 137.42848484375332], [268.6321498012143, 126.70102445552496]], "leg_l": [[190.90884651807326, 148.7540782623559], [236.4611776801855, 142.44937581588962], [276.07190042984826, 136.96702586244072], [274.54099631928756, 126.23956547421233]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[185.0, 148.0], [141.5, 148.0], [100.0, 148.0]], "head": [80.43704798532389, 143.90493909881587], "nose": [[80.43704798532389, 133.90493909881587], [80.43704798532389, 127.01128482773042]], "arm_r": [[100.0, 149.91012995433624], [130.0, 149.91012995433624], [160.0, 149.91012995433624]], "arm_l": [[105.90884651807325, 148.05948555168817], [135.89057132864613, 149.09056439955359], [165.872296139219, 150.121643247419]], "leg_r": [[185.0, 149.2155372436685], [223.13572833753193, 123.88345193236816], [256.2972312397336, 101.85555166167222], [250.14610930155538, 92.87468274277532]], "leg_l": [[190.90884651807326, 148.7540782623559], [229.0445748556052, 123.42199295105556], [262.20607775780684, 101.39409268035959], [256.0549558196286, 92.41322376146272]]}}}, {"name": "Plank", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[172.0, 114.0], [128.6655306330091, 117.73367682621827], [87.32345066220162, 121.29569035008166]], "head": [67.39955670036672, 123.0123233736303], "nose": [[58.7064746151967, 127.95502747771098], [52.64429678870563, 131.4018546132537]], "arm_r": [[93.23229718027487, 121.35517590176984], [93.23229718027487, 150.89940849213608], [63.23229718027487, 150.89940849213608]], "arm_l": [[87.32345066220162, 123.2058203044179], [87.32345066220162, 152.75005289478415], [57.32345066220162, 152.75005289478415]], "leg_r": [[177.90884651807326, 114.7540782623559], [204.2933625902214, 151.86261333148943], [244.2933625902214, 151.86261333148943], [244.2933625902214, 162.69549861462372]], "leg_l": [[172.0, 115.2155372436685], [198.38451607214813, 152.32407231280206], [238.38451607214813, 152.32407231280206], [238.38451607214813, 163.15695759593632]]}, {"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[168.0, 137.0], [125.16086274396895, 129.56106188266668], [84.29134099396232, 122.46414390865907]], "head": [64.59518593371817, 119.04394247540239], "nose": [[55.90210384854815, 123.98664657948308], [49.839926022057085, 127.43347371502581]], "arm_r": [[90.20018751203557, 122.52362946034725], [90.20018751203557, 152.06786205071347], [60.20018751203557, 152.0678620507135]], "arm_l": [[84.29134099396232, 124.37427386299531], [84.29134099396232, 153.91850645336154], [54.29134099396232, 153.91850645336154]], "leg_r": [[173.90884651807326, 137.7540782623559], [219.21000315663483, 145.62054155884627], [258.60231327712313, 152.46094442535966], [256.6921833227869, 163.12925383968215]], "leg_l": [[168.0, 138.2155372436685], [213.30115663856157, 146.0820005401589], [252.6934667590499, 152.9224034066723], [250.78333680471366, 163.59071282099478]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[170.0, 125.5], [126.54140236118918, 123.63138307763239], [85.08090116554209, 121.84867957698282]], "head": [65.09993673390494, 120.9895453598023], "nose": [[56.40685464873492, 125.932249463883], [50.344676822243855, 129.37907659942573]], "arm_r": [[90.98974768361533, 121.908165128671], [90.98974768361533, 151.45239771903724], [60.989747683615334, 151.45239771903724]], "arm_l": [[85.08090116554209, 123.75880953131905], [85.08090116554209, 153.30304212168528], [55.08090116554209, 153.30304212168528]], "leg_r": [[175.90884651807326, 126.2540782623559], [214.704853025466, 150.59437198191316], [254.55264094913582, 154.0276380290104], [253.5939277789116, 164.81930091310488]], "leg_l": [[170.0, 126.7155372436685], [208.79600650739275, 151.05583096322576], [248.64379443106256, 154.489097010323], [247.68508126083833, 165.28075989441749]]}}}, {"name": "Reverse Crunch", "camera": 0.0, "frames": [{"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[172.0, 148.0], [128.5, 148.0], [87.0, 148.0]], "head": [67.43704798532389, 143.90493909881587], "nose": [[67.43704798532389, 133.90493909881587], [67.43704798532389, 127.01128482773042]], "arm_r": [[87.0, 149.91012995433624], [117.0, 149.91012995433624], [147.0, 149.91012995433624]], "arm_l": [[92.90884651807325, 148.05948555168817], [122.89057132864612, 149.09056439955359], [152.872296139219, 150.121643247419]], "leg_r": [[172.0, 149.2155372436685], [164.0121838273212, 104.60260696559263], [201.59988865875755, 118.07557051893123], [205.3621102353399, 107.89598815654968]], "leg_l": [[177.90884651807326, 148.7540782623559], [169.92103034539446, 104.14114798428001], [207.5087351768308, 117.61411153761861], [211.27095675341317, 107.43452917523706]]}, {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[166.0, 136.0], [124.61787286428175, 154.24267631947558], [82.62501214971675, 143.35521174704758]], "head": [62.63719560933484, 144.04259764562454], "nose": [[62.63719560933484, 134.04259764562454], [62.63719560933484, 127.14894337453909]], "arm_r": [[82.62501214971675, 145.26534170138382], [112.51085309246912, 147.84029123670675], [142.3966940352215, 150.41524077202968]], "arm_l": [[88.53385866779, 143.41469729873577], [118.51558347836287, 144.44577614660116], [148.49730828893578, 145.47685499446658]], "leg_r": [[166.0, 137.2155372436685], [146.5595599599278, 96.15874622037313], [185.95187008041614, 102.99914908688652], [187.86200003475238, 92.33083967256403]], "leg_l": [[171.90884651807326, 136.7540782623559], [152.46840647800107, 95.69728723906053], [191.8607165984894, 102.5376901055739], [193.77084655282565, 91.86938069125141]]}], "tween": {"t": 0.5, "sample": {"order": ["arm_l", "leg_l", "spine", "arm_r", "leg_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[169.0, 142.0], [126.03181909460824, 151.19312771952025], [84.40784565448814, 145.72317600490808]], "head": [64.48395169265324, 144.00654298135944], "nose": [[64.48395169265324, 134.00654298135944], [64.48395169265324, 127.11288871027399]], "arm_r": [[84.40784565448814, 147.6333059592443], [114.37929230194388, 148.92200728501507], [144.3507389493996, 150.21070861078584]], "arm_l": [[90.31669217256139, 145.78266155659625], [120.29841698313426, 146.81374040446167], [150.28014179370714, 147.84481925232706]], "leg_r": [[169.0, 143.2155372436685], [155.16753322280343, 100.01105626897177], [193.80456627436615, 110.20653635873893], [196.65157577049388, 99.74277269053276]], "leg_l": [[174.90884651807326, 142.7540782623559], [161.0763797408767, 99.54959728765917], [199.7134127924394, 109.74507737742633], [202.56042228856714, 99.28131370922014]]}}}, {"name": "Rotary", "camera": 90.0, "frames": [{"order": ["spine", "arm_l", "leg_l", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.16086274396895], [160.0, 38.29134099396232]], "head": [160.0, 18.59518593371817], "nose": [[169.63488735000612, 21.272674636344597], [173.34432219963855, 22.303508681644907]], "arm_r": [[152.92933629344807, 39.754585431116695], [174.52472560523668, 53.00593171303545], [197.15692080730136, 61.433928518814795]], "arm_l": [[167.07066370655193, 36.82809655680795], [188.66605301834056, 50.079442838726706], [211.29824822040524, 58.50743964450605]], "leg_r": [[153.0, 122.0], [140.32068163241803, 135.6641252039847], [136.5497405147205, 175.47598817361995], [133.7005822327046, 174.9683561722579]], "leg_l": [[167.0, 122.0], [179.67931836758197, 135.6641252039847], [183.4502594852795, 175.47598817361995], [186.2994177672954, 174.9683561722579]]}, {"order": ["spine", "arm_r", "leg_l", "leg_r", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.16086274396895], [160.0, 38.29134099396232]], "head": [160.0, 18.59518593371817], "nose": [[150.36511264999388, 21.272674636344597], [146.65567780036145, 22.30350868164491]], "arm_r": [[152.92933629344807, 36.82809655680795], [131.33394698165944, 50.079442838726706], [108.70175177959479, 58.50743964450605]], "arm_l": [[167.07066370655193, 39.754585431116695], [145.47527439476332, 53.00593171303545], [122.84307919269864, 61.433928518814795]], "leg_r": [[153.0, 122.0], [140.32068163241803, 135.6641252039847], [136.5497405147205, 175.47598817361995], [133.7005822327046, 174.9683561722579]], "leg_l": [[167.0, 122.0], [179.67931836758197, 135.6641252039847], [183.4502594852795, 175.47598817361995], [186.2994177672954, 174.9683561722579]]}], "tween": {"t": 0.5, "sample": {"order": ["spine", "leg_l", "leg_r", "arm_l", "arm_r", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[160.0, 122.0], [160.0, 79.16086274396895], [160.0, 38.29134099396232]], "head": [160.0, 18.59518593371817], "arm_r": [[149.0, 38.29134099396232], [149.0, 53.29134099396232], [149.0, 63.55194529373239]], "arm_l": [[171.0, 38.29134099396232], [171.0, 53.29134099396232], [171.0, 63.55194529373239]], "leg_r": [[153.0, 122.0], [140.32068163241803, 135.6641252039847], [136.5497405147205, 175.47598817361995], [133.7005822327046, 174.9683561722579]], "leg_l": [[167.0, 122.0], [179.67931836758197, 135.6641252039847], [183.4502594852795, 175.47598817361995], [186.2994177672954, 174.9683561722579]]}}}, {"name": "Seated Row", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.69891028706257, 79.2013101935184], [149.59296717847204, 38.855014516213274]], "head": [153.06593073181065, 19.458088308354192], "nose": [[163.02901880646485, 18.599673480497934], [170.00238169310705, 17.998851922255916]], "arm_r": [[149.59296717847204, 40.7651444705495], [170.10755873258697, 62.32212354359968], [200.0, 64.82166477360376]], "arm_l": [[155.5018136965453, 38.914500067901464], [174.0120238448619, 62.16456016148103], [204.0, 63.000943256194205]], "leg_r": [[140.0, 123.2155372436685], [183.8850455429191, 109.63722816102359], [188.0, 148.8205388219859], [198.94163850640507, 147.7061180825139]], "leg_l": [[145.90884651807326, 122.7540782623559], [189.43323013923415, 108.09307121777746], [192.0, 147.4041949728996], [202.97732933112334, 146.70905688665255]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.69891028706257, 79.2013101935184], [149.59296717847204, 38.855014516213274]], "head": [153.06593073181065, 19.458088308354192], "nose": [[163.02901880646485, 18.599673480497934], [170.00238169310705, 17.998851922255916]], "arm_r": [[149.59296717847204, 40.7651444705495], [130.27974637330342, 63.37285383528793], [158.0, 74.66974230372583]], "arm_l": [[155.5018136965453, 38.914500067901464], [134.82908862986338, 60.32446610131683], [162.0, 72.84902078631629]], "leg_r": [[140.0, 123.2155372436685], [183.8850455429191, 109.63722816102359], [188.0, 148.8205388219859], [198.94163850640507, 147.7061180825139]], "leg_l": [[145.90884651807326, 122.7540782623559], [189.43323013923415, 108.09307121777746], [192.0, 147.4041949728996], [202.97732933112334, 146.70905688665255]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[140.0, 122.0], [142.69891028706257, 79.2013101935184], [149.59296717847204, 38.855014516213274]], "head": [153.06593073181065, 19.458088308354192], "nose": [[163.02901880646485, 18.599673480497934], [170.00238169310705, 17.998851922255916]], "arm_r": [[149.59296717847204, 40.7651444705495], [149.00535132812342, 70.30370907354869], [179.0, 69.74570353866478]], "arm_l": [[155.5018136965453, 38.914500067901464], [153.0031939480439, 68.35608343607598], [182.99999999999997, 67.92498202125525]], "leg_r": [[140.0, 123.2155372436685], [183.8850455429191, 109.63722816102359], [188.0, 148.8205388219859], [198.94163850640507, 147.7061180825139]], "leg_l": [[145.90884651807326, 122.7540782623559], [189.43323013923415, 108.09307121777746], [192.0, 147.4041949728996], [202.97732933112334, 146.70905688665255]]}}}, {"name": "Shoulder Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.0200605630874, 90.37728052628361], [95.1324142218102, 50.073787462921175]], "head": [98.60537777514881, 30.676861255062093], "nose": [[108.5109515671687, 29.305873344521444], [115.4428280483597, 28.346462102667882]], "arm_r": [[95.1324142218102, 51.9839174172574], [110.1324142218102, 77.5699733758307], [110.1324142218102, 48.02574078546445]], "arm_l": [[101.04126073988344, 50.133273014609365], [116.04126073988344, 75.71932897318266], [116.04126073988344, 46.17509638281641]], "leg_r": [[120.0, 131.2155372436685], [161.917285943973, 112.5576236573147], [164.0, 151.89650005692488], [174.98507904390829, 151.3324549957621]], "leg_l": [[125.90884651807325, 130.7540782623559], [167.3506724370636, 111.09303668974187], [168.0, 150.48015620783858], [178.99855056415495, 150.3043039328269]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.0200605630874, 90.37728052628361], [95.1324142218102, 50.073787462921175]], "head": [98.60537777514881, 30.676861255062093], "nose": [[108.5109515671687, 29.305873344521444], [115.4428280483597, 28.346462102667882]], "arm_r": [[95.1324142218102, 51.9839174172574], [112.76597179058439, 28.082131165884945], [137.03648162183282, 10.716466958969022]], "arm_l": [[101.04126073988344, 50.133273014609365], [118.67481830865763, 26.231486763236905], [142.94532813990608, 8.865822556320984]], "leg_r": [[120.0, 131.2155372436685], [161.917285943973, 112.5576236573147], [164.0, 151.89650005692488], [174.98507904390829, 151.3324549957621]], "leg_l": [[125.90884651807325, 130.7540782623559], [167.3506724370636, 111.09303668974187], [168.0, 150.48015620783858], [178.99855056415495, 150.3043039328269]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[120.0, 130.0], [103.0200605630874, 90.37728052628361], [95.1324142218102, 50.073787462921175]], "head": [98.60537777514881, 30.676861255062093], "nose": [[108.5109515671687, 29.305873344521444], [115.4428280483597, 28.346462102667882]], "arm_r": [[95.1324142218102, 51.9839174172574], [125.09130026444741, 53.53014308133817], [138.71101525663383, 27.206039091183243]], "arm_l": [[101.04126073988344, 50.133273014609365], [131.00014678252066, 51.67949867869013], [144.6198617747071, 25.355394688535203]], "leg_r": [[120.0, 131.2155372436685], [161.917285943973, 112.5576236573147], [164.0, 151.89650005692488], [174.98507904390829, 151.3324549957621]], "leg_l": [[125.90884651807325, 130.7540782623559], [167.3506724370636, 111.09303668974187], [168.0, 150.48015620783858], [178.99855056415495, 150.3043039328269]]}}}, {"name": "Side Plank", "camera": 0.0, "frames": [{"order": ["arm_r", "leg_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 150.0], [132.6290415411608, 136.76197856352545], [93.16019611491195, 124.13260179079685]], "head": [74.13906578900888, 118.0461551533373], "nose": [[64.17597771435469, 117.18774032548103], [57.20261482771247, 116.58691876723901]], "arm_r": [[99.0690426329852, 124.19208734248504], [127.25982125656246, 134.296810007489], [156.2375960452345, 141.94342007481436]], "arm_l": [[93.16019611491195, 126.0427317451331], [89.95929250465917, 155.4183141839495], [60.0, 153.87974546036065]], "leg_r": [[179.90884651807326, 150.7540782623559], [225.90184049526727, 151.5446924600911], [265.8957483015229, 152.23218306681738], [265.70377183071275, 163.0634184490528]], "leg_l": [[174.0, 151.2155372436685], [219.992993977194, 152.00615144140374], [259.98690178344964, 152.69364204813002], [259.7949253126395, 163.52487743036542]]}, {"order": ["leg_r", "arm_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 137.0], [131.16086274396895, 129.56106188266668], [90.29134099396232, 122.46414390865907]], "head": [70.59518593371817, 119.04394247540239], "nose": [[60.59518593371817, 119.04394247540239], [53.59518593371817, 119.04394247540239]], "arm_r": [[96.20018751203557, 122.52362946034725], [101.40963284204348, 93.42824014855863], [106.61907817205139, 64.33285083677]], "arm_l": [[90.29134099396232, 124.37427386299531], [89.99905209869154, 153.91710417204732], [60.0, 153.68224624951935]], "leg_r": [[179.90884651807326, 137.7540782623559], [225.21000315663483, 145.62054155884627], [264.60231327712313, 152.46094442535966], [262.6921833227869, 163.12925383968215]], "leg_l": [[174.0, 138.2155372436685], [219.30115663856157, 146.0820005401589], [258.6934667590499, 152.9224034066723], [256.78333680471366, 163.59071282099478]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_r", "arm_r", "spine", "leg_l", "arm_l", "head"], "shade": {"arm_r": "far", "arm_l": "near", "leg_r": "far", "leg_l": "near"}, "spine": [[174.0, 143.5], [131.79213590699416, 133.13627470916663], [91.52486326654031, 123.24904253515317]], "head": [72.11894874102038, 118.48411136695391], "nose": [[62.128179926165075, 118.05453193528285], [55.13484237509207, 117.75383495926968]], "arm_r": [[97.43370978461355, 123.30852808684135], [123.41447189814672, 108.53641179165822], [148.7162152725333, 92.66230719194698]], "arm_l": [[91.52486326654031, 125.1591724894894], [89.98658163375015, 154.66454016997503], [59.999999999999986, 153.78099585494002]], "leg_r": [[179.90884651807326, 144.2540782623559], [225.6970716429635, 148.59600171041538], [265.5129195776506, 152.3715873174236], [264.45861629992817, 163.15460014560324]], "leg_l": [[174.0, 144.7155372436685], [219.78822512489023, 149.05746069172798], [259.6040730595774, 152.83304629873624], [258.54976978185493, 163.61605912691584]]}}}, {"name": "Tricep Press", "camera": 0.0, "frames": [{"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.72232766064437, 81.92461008445406], [104.68785811999925, 41.33721444350374]], "head": [106.08298759488176, 21.689038227061047], "nose": [[116.02984525543485, 20.659464198301396], [122.99149852301275, 19.93888111104634]], "arm_r": [[104.68785811999925, 43.24734439783997], [94.67819740520659, 71.09854849438184], [124.0, 64.85204926757933]], "arm_l": [[110.5967046380725, 41.39669999519193], [98.50612246687119, 68.43532854979176], [128.0, 63.03132775016979]], "leg_r": [[118.0, 125.2155372436685], [162.26738385552633, 112.89958304064265], [156.0, 151.8053465749981], [166.8641356033426, 153.50269283330525]], "leg_l": [[123.90884651807325, 124.7540782623559], [167.98485944606693, 111.78953829173301], [160.00000000000003, 150.38900272591184], [170.7786039325257, 152.55147938544167]]}, {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.72232766064437, 81.92461008445406], [104.68785811999925, 41.33721444350374]], "head": [106.08298759488176, 21.689038227061047], "nose": [[116.02984525543485, 20.659464198301396], [122.99149852301275, 19.93888111104634]], "arm_r": [[104.68785811999925, 43.24734439783997], [109.6655943384287, 72.38204819466002], [124.0, 98.3355128699944]], "arm_l": [[110.5967046380725, 41.39669999519193], [113.17159954067507, 70.83190879489234], [128.0, 96.51479135258487]], "leg_r": [[118.0, 125.2155372436685], [162.26738385552633, 112.89958304064265], [156.0, 151.8053465749981], [166.8641356033426, 153.50269283330525]], "leg_l": [[123.90884651807325, 124.7540782623559], [167.98485944606693, 111.78953829173301], [160.00000000000003, 150.38900272591184], [170.7786039325257, 152.55147938544167]]}], "tween": {"t": 0.5, "sample": {"order": ["leg_l", "arm_l", "spine", "leg_r", "arm_r", "head"], "shade": {"arm_r": "near", "arm_l": "far", "leg_r": "near", "leg_l": "far"}, "spine": [[118.0, 124.0], [109.72232766064437, 81.92461008445406], [104.68785811999925, 41.33721444350374]], "head": [106.08298759488176, 21.689038227061047], "nose": [[116.02984525543485, 20.659464198301396], [122.99149852301275, 19.93888111104634]], "arm_r": [[104.68785811999925, 43.24734439783997], [95.81620416576652, 71.47018477789757], [124.0, 81.59378106878685]], "arm_l": [[110.5967046380725, 41.39669999519193], [100.04454561797358, 69.05300441583627], [128.0, 79.77305955137733]], "leg_r": [[118.0, 125.2155372436685], [162.26738385552633, 112.89958304064265], [156.0, 151.8053465749981], [166.8641356033426, 153.50269283330525]], "leg_l": [[123.90884651807325, 124.7540782623559], [167.98485944606693, 111.78953829173301], [160.0, 150.38900272591184], [170.7786039325257, 152.5514793854417]]}}}]} \ No newline at end of file