Initial Commit
This commit is contained in:
143
openspec/changes/enterprise-gaming-mixamo/proposal.md
Normal file
143
openspec/changes/enterprise-gaming-mixamo/proposal.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# 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
|
||||
|
||||
```ts
|
||||
// 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```text
|
||||
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`.
|
||||
Reference in New Issue
Block a user