Skip to content

Commit

Permalink
Add blendFactor support to CCDIKSolver (#30415)
Browse files Browse the repository at this point in the history
Added ability to control IK influence through blend factors:
- Global blendFactor in update() method
- Per-chain blendFactor in updateOne() method
- Default value of 1.0 maintains backward compatibility
  • Loading branch information
anishwij authored Jan 31, 2025
1 parent 73019ad commit 88062ed
Showing 1 changed file with 52 additions and 4 deletions.
56 changes: 52 additions & 4 deletions examples/jsm/animation/CCDIKSolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,39 @@ class CCDIKSolver {
this.mesh = mesh;
this.iks = iks;

this._initialQuaternions = [];
this._workingQuaternion = new Quaternion();

for ( const ik of iks ) {

const chainQuats = [];
for ( let i = 0; i < ik.links.length; i ++ ) {

chainQuats.push( new Quaternion() );

}

this._initialQuaternions.push( chainQuats );

}

this._valid();

}

/**
* Update all IK bones.
*
* @param {number} [globalBlendFactor=1.0] - Blend factor applied if an IK chain doesn't have its own .blendFactor.
* @return {CCDIKSolver}
*/
update() {
update( globalBlendFactor = 1.0 ) {

const iks = this.iks;

for ( let i = 0, il = iks.length; i < il; i ++ ) {

this.updateOne( iks[ i ] );
this.updateOne( iks[ i ], globalBlendFactor );

}

Expand All @@ -84,11 +101,15 @@ class CCDIKSolver {
* Update one IK bone
*
* @param {Object} ik parameter
* @param {number} [overrideBlend=1.0] - If the ik object does not define .blendFactor, this value is used.
* @return {CCDIKSolver}
*/
updateOne( ik ) {
updateOne( ik, overrideBlend = 1.0 ) {

const chainBlend = ik.blendFactor !== undefined ? ik.blendFactor : overrideBlend;
const bones = this.mesh.skeleton.bones;
const chainIndex = this.iks.indexOf( ik );
const initialQuaternions = this._initialQuaternions[ chainIndex ];

// for reference overhead reduction in loop
const math = Math;
Expand All @@ -103,6 +124,17 @@ class CCDIKSolver {
const links = ik.links;
const iteration = ik.iteration !== undefined ? ik.iteration : 1;

if ( chainBlend < 1.0 ) {

for ( let j = 0; j < links.length; j ++ ) {

const linkIndex = links[ j ].index;
initialQuaternions[ j ].copy( bones[ linkIndex ].quaternion );

}

}

for ( let i = 0; i < iteration; i ++ ) {

let rotated = false;
Expand Down Expand Up @@ -205,7 +237,23 @@ class CCDIKSolver {

}

return this;
if ( chainBlend < 1.0 ) {

for ( let j = 0; j < links.length; j ++ ) {

const linkIndex = links[ j ].index;
const link = bones[ linkIndex ];

this._workingQuaternion.copy( initialQuaternions[ j ] ).slerp( link.quaternion, chainBlend );

link.quaternion.copy( this._workingQuaternion );
link.updateMatrixWorld( true );

}

}

return this;

}

Expand Down

0 comments on commit 88062ed

Please sign in to comment.