Skip to content

Commit

Permalink
v0.0.2 - IK Rigs & Animations
Browse files Browse the repository at this point in the history
  • Loading branch information
sketchpunk committed Dec 31, 2021
1 parent b752728 commit e425618
Show file tree
Hide file tree
Showing 24 changed files with 2,221 additions and 28 deletions.
32 changes: 12 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@


### Character Animation Library ###
This project focus is to allow animating 3D character in web application, games, metaverses, etc that are rendered in WebGL / WebGPU. Some of the big goals is to create something that is independent from any rendering engine while trying to be more collaborative in its design the betterment of the web. The biggest inspiration for me and one of the main goals is to achieve something similar to Ubisoft's GDC Talk & Demo of their IK Rigs animation system.

I like to look at this as being the IMGUI of Character Animations :)
This project is working toward a complete character skinning & animation library for the web. First most, this library is focused on being independent from any rendering engine with examples of how to use it in webgl based engines like threejs. The one big focus is recreating the IK Rig & IK Animations type system that was demoed several years ago from Ubisoft's GDC talk on IK Rigs. With many game engines like Unity and Unreal developing their own IK Rig like systems, this project helps fill the void for web based engines like threejs, babylon, etc. Hopefully with enough help we can create something just as good as the big boys, maybe even better since its free & open source.

### Setup ###

Expand Down Expand Up @@ -53,6 +51,9 @@ App.add( mesh );
* Bone Springs ( Rotation & Translation )
* Basic Animator based on Tracks
* Basic Animation Retargeting for similar skeletal meshes
* IK Rigs - Basic Biped
* IK Animation Retargeting using IK Rigs
* IK Solvers - Aim/SwingTwist, SwingTwistEnds, Limb
* GLTF2 Asset Parsing for cherry picking what you need to load.
* Several examples using ThreeJS for rendering
* Some extra fun examples like converting animations to Data Textures
Expand All @@ -61,13 +62,16 @@ App.add( mesh );

---
## Future Plans ##
- [ ] Rebuilding IK Rigs as a new version for this project
- [ ] Port over my Single Pass IK Solvers ( Aim, Limb, Z, Piston, Arc, ArcSin, Trapezoid, Spring )
- [ ] Rebuild IK Animation Retargeting for this project
- [ ] Complete FullBody IK Prototype
- [x] Rewrite IK Rigs
- [x] Port over starting IK Solvers ( Aim / SwingTwist, Limb, SwingTwistEnds )
- [x] Rewrite IK Animation Retargeting
- [ ] Port over extra single pass IK Solvers ( Z, Piston, Arc, ArcSin, Trapezoid, Spring )
- [ ] Create an implementation of FABIK
- [ ] Create solver based on Catenary Curve
- [ ] Port over Trianglution Solver ( Alternative to CCD )
- [ ] Port over Natural CCD ( Extended version of CCD )
- [ ] Create an implementation of FABIK
- [x] Complete FullBody IK Prototype
- [ ] Revisit FullBody IK, Make it mores stable & user friendly
- [ ] Figure out how to implement VRIK
- [ ] Bone Slots / Attachments
- [ ] Actions or State Machine based Animator
Expand All @@ -94,15 +98,3 @@ There are some things I've been wanting for my prototyping for awhile. Here's a
* Something that looks nice & blends well together, doesn't look choppy
* Walk, Run, Idle, Crawl, Jump. Maybe Flying & Swimming
* Prefer not to be baked

* `IK Bot`
* **Purpose** : Something to use for procedural generation & animation prototyping. Having the arm/leg made as pieces can allow me to create chains of various sizes procedurally to play with various IK solvers.
* **Inspiration** : https://twitter.com/WokkieG/status/1429130029422743561?s=20
* **Thoughs** :
* Round Robot so its easy to just place limbs anywhere and really play with things
* Instead of arms, create two types of "Bones" that can be connected in chains. One with a ball joint, the other with a hinge joint. This can help with demoing future constraints prototypes
* Ball joint base for connecting chain to the round body
* Some sort of Hand or Feet part to attach at the end of the chain
* Does not need to be skinned or textured
* Some hard edges in the design would be cool

84 changes: 84 additions & 0 deletions examples/threejs/005_ikrig.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title></head><body>
<script type="module">

//#region IMPORTS
import Starter, { THREE } from './_lib/Starter.js';
import ShapePointsMesh from './_lib/ShapePointsMesh.js';
import DynLineMesh from './_lib/DynLineMesh.js';

import { Gltf2 } from './_lib/UtilGltf2.js';
import UtilArm from './_lib/UtilArm.js';

import { BipedRig } from '../../src/ikrig/index';
//#endregion

//#region MAIN
let App;
let debug = {};
let Ref = {};

function onRender( dt=0, et=0 ){}

window.addEventListener( "load", async _=>{
App = new Starter( { webgl2:true, grid:true } );
App.setCamera( 0, 20, 4, [0,0.8,0] );
//App.onRender = onRender;

App.add( ( debug.pnt = new ShapePointsMesh() ) );
App.add( ( debug.ln = new DynLineMesh() ) );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const gltf = await Gltf2.fetch( '../_res/models/nabba/nabba.gltf' );
const arm = UtilArm.armFromGltf( gltf ); // Armature Setup Boiler Plate Abstracted
const boneView = UtilArm.newBoneView( arm ); // BoneView for 3JS Boiler Plate Abstracted
const mesh = UtilArm.skinMtxMesh( gltf, arm ); // Create a Skinned Mesh for 3JS Boiler Plate Abstracted
const pose = arm.newPose(); // Working Pose to save IK Results

App.add( boneView );
App.add( mesh );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const rig = new BipedRig();
rig.autoRig( arm );

// When Skinning BindPose is not a TPose, Need to create or set it
// somehow, then use that to load the rig
// createOrLoad_TPose( pose );
// pose.updateWorld();
// rig.bindPose( pose );
// rig.useSolversForRetarget( pose );

// BUT if The Skin BindPose is a TPose, Can get away using Armature instead of pose.
rig.bindPose( arm ); // Late Binding of TPose for the chains: Rigs only work with TPoses
rig.useSolversForRetarget( arm ); // Use Default Solvers for known chains, Should Happen After Bind

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const apos = [ 0.3, 0.6, -0.1 ];
const lpos = [ 0.2, 0.1, 0.1 ];
debug.pnt.add( apos, 0x00ff00, 1 );
debug.pnt.add( lpos, 0x00ffff, 1 );

// Set Solvers with IK Data
rig.armL.solver.setTargetPos( apos ).setTargetPole( [0,0,-1] );
rig.legL.solver.setTargetPos( lpos ).setTargetPole( [0.5,0,0.5] );
rig.footL.solver.setTargetDir( [0,0,1], [0,1,0] );
rig.spine.solver.setEndDir( [0,1,0], [0,0,1] ).setEndDir( [0,1,0], [0.5,0,0.5] );
rig.head.solver.setTargetDir( [0,0.5,0.5], [0,1,0] );

rig.hip.solver
.setMovePos( [0,-0.3,0], false )
.setTargetDir( [-0.5,0,0.5], [0,1,0] );

rig.resolveToPose( pose, debug ); // Run All Solvers, Store Results in a Pose
boneView.updateFromPose( pose.updateWorld() ); // Update BoneView with new Pose
arm.updateSkinFromPose( pose ); // Update Skinned Mesh with new Pose

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
App.render();
});
//#endregion

</script>
</body></html>
Loading

0 comments on commit e425618

Please sign in to comment.