Files
2026-05-27 23:29:53 +01:00

3.8 KiB

OpenSpec Change: enterprise-gaming-mixamo

  • Change ID: enterprise-gaming-mixamo
  • Package: @suaveplan/mixamo
  • Category: gaming/rigs
  • Target path: gaming/rigs/mixamo
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/mixamo.md

Summary

Deliver @suaveplan/mixamo on the genesis branch from scratch at enterprise quality. The package provides Mixamo character utilities: skeleton normalisation (canonical bone name mapping), T-pose extraction, animation clip retargeting from Mixamo rig to arbitrary target skeletons, and root-motion extraction. These are pure math utilities with no Three.js dependency — the R3F integration layer lives in @suaveplan/r3f-animation. Genesis adds Zod schemas for bone maps and clip descriptors, structured errors, and 100% coverage.


Current-state audit (genesis)

Package does not exist on genesis yet — fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) MixamoError; MIXAMO.* codes
@suaveplan/types (workspace:^) Shared primitives
@suaveplan/bone-mapping (workspace:^) Skeleton detection and retargeting math
zod (catalog:forms) Bone map + clip schemas
@opentelemetry/api (catalog:observability) Retarget duration span

Public API surface

// Canonical Mixamo bone names → target bone names
const MIXAMO_BONE_NAMES: readonly string[]

function normalizeMixamoSkeleton(bones: BoneDescriptor[]): NormalizedSkeleton

interface NormalizedSkeleton {
  bones: BoneDescriptor[]
  boneIndexByName: Map<string, number>
  tPose: BonePose[]
}

interface BoneDescriptor {
  name: string
  parentIndex: number    // -1 for root
  localPosition: Vec3
  localRotation: Quat
}

interface BonePose {
  boneIndex: number
  position: Vec3
  rotation: Quat
}

// Animation clip
interface AnimationClip {
  name: string
  duration: number
  tracks: AnimationTrack[]
}

interface AnimationTrack {
  boneName: string
  times: Float32Array
  positions?: Float32Array   // xyz per keyframe
  rotations?: Float32Array   // xyzw per keyframe
}

function extractRootMotion(clip: AnimationClip, rootBoneName?: string): RootMotionData

interface RootMotionData {
  positions: Float32Array   // xyz per keyframe
  rotations: Float32Array   // xyzw per keyframe
  strippedClip: AnimationClip   // root motion removed from tracks
}

Error codes

type MixamoErrorCode =
  | 'MIXAMO_BONE_NOT_FOUND'
  | 'MIXAMO_INVALID_SKELETON'
  | 'MIXAMO_RETARGET_FAILED'
  | 'MIXAMO_CLIP_INVALID'

New additions for genesis

  1. Canonical bone map — 65-entry MIXAMO_BONE_NAMES table matching Adobe Mixamo's naming convention.
  2. T-pose extraction — derives rest pose from first frame of a T-pose clip or from bind pose.
  3. Root motion extraction — strips horizontal XZ translation and yaw from root track; returns both stripped clip and motion data.
  4. OTel — mixamo.normalise_duration_ms span; mixamo.retarget_duration_ms span.

File layout

gaming/rigs/mixamo/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    constants/
      index.ts         # MIXAMO_BONE_NAMES
    types/common.ts
    types/common.md
    core/
      normalise/
        normalise.ts
        normalise.md
        normalise.types.ts
        normalise.test.ts
        index.ts
      root-motion/
        root-motion.ts
        root-motion.md
        root-motion.types.ts
        root-motion.test.ts
        index.ts
  tests/
    integration.test.ts

Impact

Downstream: @suaveplan/r3f-animation uses normalizeMixamoSkeleton and extractRootMotion. Prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/bone-mapping.