Skip to content

Latest commit

 

History

History
99 lines (78 loc) · 3.8 KB

File metadata and controls

99 lines (78 loc) · 3.8 KB

posecode-render

Renders a posecode-parser IR as an animated 3D human figure with Three.js: forward kinematics plus ground-lock CCD IK, live in the browser at 60fps. Pass characterUrl to show a realistic skinned character (any Mixamo-rigged GLB); without it — or while it loads, or if it fails — a procedural athletic figure renders instead, so the scene is never blank. Either way, a capsule self-collision pass keeps limbs from passing through the body.

Part of Posecode: a kinematic-motion protocol LLMs can write, rendered as text-to-motion 3D animation.

Install

npm install posecode-render posecode-parser three

Usage

import { parse } from "posecode-parser";
import { createViewer } from "posecode-render";

const canvas = document.querySelector("canvas")!;
const viewer = createViewer(canvas, {
  autoRotate: false,
  // Metric grid, load origin, live +Z facing arrow, and authored travel path.
  // Enabled by default; disable it for a clean presentation-only embed.
  floorGuide: true,
  // Optional: realistic skinned character (Mixamo bone naming). Omit both
  // characterUrl and characterUrls for the zero-asset procedural figure.
  characterUrl: "https://posecode.org/models/xbot.glb",
  // Alternative to characterUrl: pick from the optional `avatar` directive.
  // Documents without one use the `humanoid` entry. A selector absent from the
  // map (or any load failure) falls back to the procedural figure. Ignored
  // when characterUrl is set.
  // characterUrls: {
  //   humanoid: "https://posecode.org/models/xbot.glb",
  //   avatar1: "https://posecode.org/models/xbot.glb",
  //   avatar2: "https://posecode.org/models/avatar2.glb",
  //   avatar3: "https://posecode.org/models/avatar3.glb",
  // },
});

const { ir } = parse(myPosecodeSource);
if (ir) {
  viewer.load(ir);
  viewer.setLoop(true);
  viewer.play();
}

viewer.onPhase(({ phaseName, cue }) => {
  console.log(phaseName, cue);
});

const floor = viewer.getFloorGuideInfo();
console.log(floor?.gridStepMetres, floor?.hasTravel, floor?.waypoints);

const solverWarnings = viewer
  .getConstraintDiagnostics()
  .filter((diagnostic) => !diagnostic.pass);
console.log(solverWarnings);

cue is optional display-only coaching text. It never changes the pose, timing, range checks, contacts, or collision solving.

Constraint diagnostics name visible heel/toe contact errors, sole tilt, grounding-versus-ankle-ROM conflicts, and residual overlaps from the renderer's bounded self-collision pairs. They measure the post-solver procedural driver, before optional skinned-character or mocap surface reconciliation, and report outcomes without changing the authored motion.

UniMate constraint interchange

Use buildUniMateConstraintManifest() to turn a validated IR into a JSON-safe sparse key-pose schedule for a rig-aware UniMate adapter:

import { buildUniMateConstraintManifest } from "posecode-render";

const manifest = buildUniMateConstraintManifest(ir, { fps: 30 });

The manifest preserves named phase endpoints, root intent, Mixamo bone bindings, and contact constraints. It deliberately stops before UniMate's normalized motion tensor because that conversion requires the destination rig's rest geometry and the selected checkpoint's normalization statistics. See the integration note for the bridge boundary and acceptance test.

No GPU, no diffusion model: generation is a fraction of a cent of text, and rendering is plain forward kinematics.

License

AGPL-3.0-only. A separate commercial license is available for closed-source product use; see commercial licensing.