Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions packages/posecode-render/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ export interface ViewerOptions {
* skeleton, rebuilt to the character's exact proportions (see character.ts).
*/
characterUrl?: string;
/**
* Show the procedural figure while `characterUrl` loads. Defaults to true
* for embeds and offline-friendly consumers. Set false when a brief empty
* stage is preferable to flashing the procedural figure before the skinned
* character appears. The procedural figure is still revealed if loading
* fails, so the viewer never remains permanently blank.
*/
showProceduralWhileLoading?: boolean;
/**
* Mocap clip library: clip name (as written in a document's `clip "<name>"`
* directive) → FBX/GLB asset URL. When a loaded document names a clip found
Expand Down Expand Up @@ -174,6 +182,9 @@ export function createViewer(

let mannequin: Mannequin = buildMannequin();
enableShadows(mannequin.root);
if (opts.characterUrl && opts.showProceduralWhileLoading === false) {
setMannequinMeshesVisible(mannequin.root, false);
}
scene.add(mannequin.root);

// Skinned character layer (optional). While loading (and on failure) the
Expand Down Expand Up @@ -768,8 +779,9 @@ export function createViewer(
else char.sync(mannequin);
})
.catch(() => {
// Keep the procedural figure. Deliberately silent: an offline embed
// or a blocked CDN should degrade, not error.
// Reveal the fallback if it was hidden during loading. Deliberately
// silent: an offline embed or blocked CDN should degrade, not error.
setMannequinMeshesVisible(mannequin.root, true);
});
}

Expand All @@ -785,6 +797,12 @@ function enableShadows(root: THREE.Object3D): void {
});
}

function setMannequinMeshesVisible(root: THREE.Object3D, visible: boolean): void {
root.traverse((obj) => {
if ((obj as THREE.Mesh).isMesh) obj.visible = visible;
});
}

/** Free GPU resources for a discarded subtree (prop set swapped on reload). */
function disposeTree(root: THREE.Object3D): void {
root.traverse((obj) => {
Expand Down
52 changes: 52 additions & 0 deletions playground/public/content-theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
:root{--bg:#0b0c0d;--panel:#111315;--panel-2:#171a1d;--border:#292d30;--border-2:#3a3f43;
--text:#f2f1eb;--text-2:#aaa9a2;--muted:#74746f;--accent:#d4ff3f;
--accent-ink:#0b0c0d;--accent-line:rgba(212,255,63,.42);--radius:3px}
body{background:var(--bg);color:var(--text)}
.wrap{max-width:1180px;padding-left:28px;padding-right:28px}
header.site-nav{position:sticky;top:0;z-index:10;margin-bottom:0;padding:18px 0;
background:rgba(11,12,13,.94);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
nav.links{gap:24px}
main{padding-top:clamp(54px,8vw,96px);padding-bottom:80px}
.eyebrow{color:var(--text-2);margin-bottom:16px}
h1{max-width:13ch;font-size:clamp(46px,7vw,82px);letter-spacing:-.055em;line-height:.94;
margin-bottom:24px;text-wrap:balance}
h2{font-size:clamp(24px,3vw,34px);letter-spacing:-.035em;margin:58px 0 18px}
p{max-width:760px;font-size:16px;margin-bottom:18px}
code{border-radius:2px}
pre.code-block{background:#0e1011;border-radius:2px;padding:20px 22px}
.card{border-radius:0;background:transparent}
.btn{background:var(--accent);border-radius:3px;padding:12px 19px}
.btn:hover{filter:none;transform:translateY(-1px)}
.steps{gap:0;border-top:1px solid var(--border)}
.steps li{border:0;border-bottom:1px solid var(--border);border-radius:0;padding:20px 0;background:transparent}
.chip-list{gap:0;border-top:1px solid var(--border);border-left:1px solid var(--border)}
.chip-list a{background:transparent;border:0;border-right:1px solid var(--border);
border-bottom:1px solid var(--border);border-radius:0;padding:8px 13px}
.chip-list a:hover{color:var(--bg);background:var(--text);border-color:var(--border)}
.domain-group{margin:64px 0 0}
.move-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:0;border-top:1px solid var(--border);
border-left:1px solid var(--border)}
.move-card{display:flex;min-height:126px;flex-direction:column;justify-content:space-between;
border:0;border-right:1px solid var(--border);border-bottom:1px solid var(--border);border-radius:0;
padding:19px 20px;background:transparent}
.move-card:hover{background:var(--text);border-color:var(--border)}
.move-card .mc-name{font-size:16px;letter-spacing:-.2px}
.move-card .mc-meta{font-family:var(--mono);font-size:10.5px;margin-top:16px}
.move-card:hover .mc-name{color:var(--bg)}
.move-card:hover .mc-meta{color:#555853}
footer.site-footer{padding:34px 0 48px}
@media(max-width:820px){
nav.links a:nth-child(n+4){display:none}
.move-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:600px){
.wrap{padding-left:18px;padding-right:18px}
header.site-nav{padding:14px 0}
nav.links{gap:14px}
nav.links a:nth-child(n+3){display:none}
main{padding-top:48px}
h1{font-size:clamp(44px,14vw,62px)}
.move-grid{grid-template-columns:1fr}
.move-card{min-height:104px}
.domain-group{margin-top:48px}
}
1 change: 1 addition & 0 deletions playground/public/llm-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />

<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/arm-circles.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Arm circles","description":"How to do the arm circles (warm-up): 3 phases targeting the deltoids, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Up & forward","text":"Sweep the arms up and forward"},{"@type":"HowToStep","name":"Out to sides","text":"Open the arms out wide to the sides"},{"@type":"HowToStep","name":"Down & round","text":"Lower and continue the circle back to the start"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/bent-over-row.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Bent-over row","description":"How to do the bent-over row (fitness): 4 phases targeting the lats, body weight, intermediate level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Set the hinge","text":"Hinge to a flat back, let the arms hang straight down"},{"@type":"HowToStep","name":"Row","text":"Drive the elbows up past the ribs, squeeze the shoulder blades"},{"@type":"HowToStep","name":"Lower","text":"Lower the bar under control, keep the back flat"},{"@type":"HowToStep","name":"Stand","text":"Stand up tall between sets"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/biceps.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Biceps curl","description":"How to do the biceps curl (fitness): 2 phases targeting the biceps, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Curl","text":"Curl up, keep the elbows tucked at your sides"},{"@type":"HowToStep","name":"Lower","text":"Lower under control: don't swing"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/bicycle-crunch.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Bicycle crunch","description":"How to do the bicycle crunch (fitness): 4 phases targeting the obliques, body weight, intermediate level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Set","text":"Hands by the ears, knees over the hips, shoulders lifted"},{"@type":"HowToStep","name":"Right to left","text":"Right elbow toward the left knee; the right leg extends long"},{"@type":"HowToStep","name":"Left to right","text":"Switch: left elbow toward the right knee"},{"@type":"HowToStep","name":"Center","text":"Return to center, knees stacked over the hips"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/bow.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Standing bow","description":"How to do the standing bow (martial arts): 2 phases targeting the hamstrings, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Bow","text":"Hinge forward from the hips into a respectful bow, back flat"},{"@type":"HowToStep","name":"Rise","text":"Return smoothly to standing"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/box-squat.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Box squat","description":"How to do the box squat (fitness): 2 phases targeting the quadriceps, chair, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Sit back","text":"Push the hips back and sit lightly onto the box"},{"@type":"HowToStep","name":"Stand","text":"Drive up to standing without bouncing off the box"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/box-step-taps.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Box step taps","description":"How to do the box step taps (warm-up): 4 phases targeting the hip flexors, box, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Right tap","text":"Tap the right foot lightly on top of the box"},{"@type":"HowToStep","name":"Right down","text":"Return the right foot to the floor"},{"@type":"HowToStep","name":"Left tap","text":"Tap the left foot on the box"},{"@type":"HowToStep","name":"Left down","text":"Back to the floor: keep a light, quick rhythm"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/box-step.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Box step","description":"How to do the box step (dance): 4 phases targeting the full body, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Step forward-right","text":"Step the right foot forward and out to the corner"},{"@type":"HowToStep","name":"Close the feet","text":"Bring the left foot to meet it, standing tall on the corner"},{"@type":"HowToStep","name":"Step back-left","text":"Step the left foot back to the start on the diagonal"},{"@type":"HowToStep","name":"Close home","text":"Close the feet together, back home and ready to repeat"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/calf-raise.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Single-leg calf raise","description":"How to do the single-leg calf raise (fitness): 2 phases targeting the calves, body weight, intermediate level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Rise","text":"Balance on the right foot and rise onto the ball of the foot"},{"@type":"HowToStep","name":"Lower","text":"Lower the right heel slowly under control"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/chair.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Chair pose","description":"How to do the chair pose (yoga): 2 phases targeting the quadriceps, body weight, intermediate level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Sink","text":"Sit the hips back and down, reach the arms overhead"},{"@type":"HowToStep","name":"Rise","text":"Press through the feet to stand, arms float down"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/chasse.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Chassé","description":"How to do the chassé (dance): 4 phases targeting the full body, body weight, intermediate level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Reach & push","text":"Reach the lead foot out and push off to travel sideways"},{"@type":"HowToStep","name":"Gallop close","text":"Chase the trailing foot to the lead: feet meet in the air"},{"@type":"HowToStep","name":"Reach & push back","text":"Change direction and travel back the other way"},{"@type":"HowToStep","name":"Gallop home","text":"Close home, ready to chassé again"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/chest-opener.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Chest opener","description":"How to do the chest opener (desk & posture): 2 phases targeting the pectorals, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Open","text":"Reach the arms back and lift the chest: open the front line"},{"@type":"HowToStep","name":"Release","text":"Return to neutral, ribs stacked over the hips"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/cobra.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Cobra","description":"How to do the cobra (yoga): 2 phases targeting the spinal erectors, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Lift","text":"Press the palms into the floor and lift the chest, shoulders rolling back"},{"@type":"HowToStep","name":"Lower","text":"Lower the chest back to the floor with control"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/cross-body-reach.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Cross-body reach","description":"How to do the cross-body reach (physiotherapy): 4 phases targeting the obliques, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Reach across right","text":"Pull the right arm across the chest toward the left shoulder"},{"@type":"HowToStep","name":"Return","text":"Release back to center"},{"@type":"HowToStep","name":"Reach across left","text":"Pull the left arm across the chest toward the right shoulder"},{"@type":"HowToStep","name":"Center","text":"Return to center"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
1 change: 1 addition & 0 deletions playground/public/moves/crunch.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
footer.site-footer p{font-size:12.5px;color:var(--muted);margin:0 0 6px;max-width:70ch}
@media(max-width:600px){.wrap{padding:0 18px}}
</style>
<link rel="stylesheet" href="/content-theme.css" />
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"How to do a Crunch","description":"How to do the crunch (fitness): 3 phases targeting the abdominals, body weight, beginner level. Animated 3D guide generated from Posecode, a text-to-motion language for LLMs.","step":[{"@type":"HowToStep","name":"Set up","text":"Set up"},{"@type":"HowToStep","name":"Curl up","text":"Curl the shoulders off the floor, ribs toward the hips"},{"@type":"HowToStep","name":"Lower","text":"Lower the upper back down with control"}]}</script>
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
Expand Down
Loading
Loading