Enhanced Inverse Kinematics solver for Three.js with biomechanical constraints and multi-axis bone support
p0qp0q-IK-Solver (pronounced "pock-pock") is a modified version of Three.js CCDIKSolver enhanced with:
- Swing-Twist Constraint System - Biomechanically accurate joint limits
- Multi-Axis Bone Support - Works with any bone orientation (X, Y, or Z primary axis)
- Scale-Aware Precision - Handles tiny models (0.01 scale) and huge models equally well
- Octahedral Bone Visualization - Professional-grade bone display (like Maya/Blender)
- Educational Features - Visual constraint feedback and joint limit displays
This solver is based on Three.js CCDIKSolver (MIT License)
- Original: https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/CCDIKSolver.js
- Copyright © 2010-2025 three.js authors
- Enhanced by Allen Partridge © 2025
Original CCDIKSolver:
rotationMin: new Vector3(0, 0, 0),
rotationMax: new Vector3(130, 0, 0) // Hardcoded X-axisp0qp0q-IK-Solver:
swingTwistConstraint: {
type: 'hinge', // Anatomical joint type
twistAxis: new Vector3(0, 1, 0), // Auto-detected or specified
twistMin: 0, // Radians (extension)
twistMax: degToRad(130), // Radians (flexion)
swingRadius: degToRad(5) // Radians (wiggle room)
}Works with bones oriented along ANY axis:
- Meshy3D models (X-axis knees)
- Mixamo models (Y-axis knees)
- Character Creator (Z-axis or inverted axes)
- Custom rigs (any orientation)
Auto-detects bone orientation and applies constraints to the correct axis.
Professional bone display system:
- Directional octahedral bones (show bone orientation)
- Joint spheres at connections
- Constraint arcs showing valid ranges
- Color-coded by bone type (red=hinge, blue=ball, green=universal)
npm install p0qp0q-ik-solver @p0qp0q/animation-utilsUse import maps in your HTML:
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
"@p0qp0q/animation-utils": "https://unpkg.com/@p0qp0q/animation-utils/src/index.js",
"p0qp0q-ik-solver": "./p0qp0q-IK-Solver.js"
}
}
</script>If you're developing both packages simultaneously:
# In p0qp0q-IK-Solver directory
mkdir -p node_modules/@p0qp0q
ln -sf ../../../p0qp0q-animation-utils node_modules/@p0qp0q/animation-utilsThis creates a local symlink so imports work during development.
import * as THREE from 'three';
import { P0qP0qIKSolver } from 'p0qp0q-ik-solver';
// Define IK chains with swing-twist constraints
const iks = [
{
target: targetBoneIndex,
effector: effectorBoneIndex,
links: [
{
index: hipBoneIndex
// Ball joint - no constraints yet (Phase 3)
},
{
index: kneeBoneIndex,
swingTwistConstraint: {
type: 'hinge',
twistAxis: new THREE.Vector3(0, 1, 0), // Auto-detected in Phase 3!
twistMin: 0, // No hyperextension
twistMax: THREE.MathUtils.degToRad(130), // Max flexion
swingRadius: THREE.MathUtils.degToRad(5) // ±5° wiggle
}
},
{
index: ankleBoneIndex
// Universal joint - Phase 3
}
]
}
];
// Create solver
const ikSolver = new P0qP0qIKSolver(skinnedMesh, iks);
// Update in animation loop
ikSolver.update();- Fork Three.js CCDIKSolver ✅
- Add scale-aware precision thresholds ✅ (Phase 1 complete!)
- Implement swing-twist constraint system (INSIDE solver loop!) ✅ (Phase 2 complete!)
- Multi-axis bone orientation support (Week 2) - Integration with BoneAxisDetector
- Octahedral bone visualization (Week 3) - Professional Maya/Blender-style bones
- Comprehensive test suite (Week 4)
- Documentation and examples (Week 5)
- npm package release (v1.0.0)
Current Phase: Phase 2 Complete - Swing-Twist Constraints Integrated! Target Release: Q1 2025 Status: Alpha (core features working, testing in progress)
Latest: October 7, 2025 - Swing-twist constraints now applied INSIDE solver loop (correct architecture!)
This is currently a solo project by Allen Partridge for Black Box Studios.
MIT License - See LICENSE for full text
Includes code from Three.js (MIT License) - See LICENSE-ThreeJS.txt
Allen Partridge (p0qp0q)
- GitHub: @increasinglyHuman
- Web: poqpoq.com
- Project: Black Box Animator
"pock-pock" - Easy to say, hard to forget 🎯