Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: CCDIKSolver with generic SkinnedMesh #23449

Merged
merged 11 commits into from
Apr 27, 2022
87 changes: 75 additions & 12 deletions docs/examples/en/animations/CCDIKSolver.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,94 @@ <h1>[name]</h1>

<p class="desc"> A solver for IK with <a href="https://sites.google.com/site/auraliusproject/ccd-algorithm"><em>CCD Algorithm</em></a>. <br /><br />
[name] solves Inverse Kinematics Problem with CCD Algorithm.
[name] is designed to work with [page:SkinnedMesh] loaded by [page:MMDLoader] but also can be used for generic [page:SkinnedMesh].
[name] is designed to work with [page:SkinnedMesh] but also can be used with [page:MMDLoader] or [page:GLTFLoader] skeleton.
</p>

<iframe id="scene" src="scenes/ccdiksolver-browser.html"></iframe>
abernier marked this conversation as resolved.
Show resolved Hide resolved

<h2>Code Example</h2>

<code>
let ikSolver;

// Load MMD resources and instantiate CCDIKSolver
new MMDLoader().load(
'models/mmd/miku.pmd',
function ( mesh ) {
//
// Bones hierarchy:
//
// root
// ├── bone0
// │ └── bone1
// │ └── bone2
// │ └── bone3
// └── target
//
// Positioned as follow on the cylinder:
//
// o <- target (y = 20)
//
// +----o----+ <- bone3 (y = 12)
// | |
// | o | <- bone2 (y = 4)
// | |
// | o | <- bone1 (y = -4)
// | |
// +----oo---+ <- root, bone0 (y = -12)
//

let bones = []

// "root"
let rootBone = new Bone();
rootBone.position.y = -12;
bones.push( rootBone );

// "bone0"
let prevBone = new Bone();
prevBone.position.y = 0;
rootBone.add( prevBone );
bones.push( prevBone );

// "bone1", "bone2", "bone3"
for ( let i = 1; i <= 3; i ++ ) {
const bone = new Bone();
bone.position.y = 8;
bones.push( bone );

prevBone.add( bone );
prevBone = bone;
}

// "target"
const targetBone = new Bone();
targetBone.position.y = 24 + 8
rootBone.add( targetBone );
bones.push( targetBone );

//
// skinned mesh
//

ikSolver = new CCDIKSolver( mesh, mesh.geometry.iks );
scene.add( mesh );
const mesh = new SkinnedMesh( geometry, material );
const skeleton = new Skeleton( bones );

mesh.add( bones[ 0 ] ); // "root" bone
mesh.bind( skeleton );

//
// ikSolver
//

const iks = [
{
target: 5, // "target"
effector: 4, // "bone3"
links: [ { index: 3 }, { index: 2 }, { index: 1 } ] // "bone2", "bone1", "bone0"
}
);
];
ikSolver = new CCDIKSolver( mesh, iks );

function render() {

animate(); // update bones
if ( ikSolver !== undefined ) ikSolver.update();
ikSolver?.update();
renderer.render( scene, camera );

}
</code>

Expand Down
91 changes: 77 additions & 14 deletions docs/examples/zh/animations/CCDIKSolver.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,94 @@ <h1>[name]</h1>

<p class="desc"> A solver for IK with <a href="https://sites.google.com/site/auraliusproject/ccd-algorithm"><em>CCD Algorithm</em></a>. <br /><br />
[name] solves Inverse Kinematics Problem with CCD Algorithm.
[name] is designed to work with [page:SkinnedMesh] loaded by [page:MMDLoader] but also can be used for generic [page:SkinnedMesh].
[name] is designed to work with [page:SkinnedMesh] but also can be used with [page:MMDLoader] or [page:GLTFLoader] skeleton.
</p>

<iframe id="scene" src="scenes/ccdiksolver-browser.html"></iframe>

<h2>代码示例</h2>

<code>
const ikSolver;
let ikSolver;

//
// Bones hierarchy:
//
// root
// ├── bone0
// │ └── bone1
// │ └── bone2
// │ └── bone3
// └── target
//
// Positioned as follow on the cylinder:
//
// o <- target (y = 20)
//
// +----o----+ <- bone3 (y = 12)
// | |
// | o | <- bone2 (y = 4)
// | |
// | o | <- bone1 (y = -4)
// | |
// +----oo---+ <- root, bone0 (y = -12)
//

let bones = []

// "root"
let rootBone = new Bone();
rootBone.position.y = -12;
bones.push( rootBone );

// "bone0"
let prevBone = new Bone();
prevBone.position.y = 0;
rootBone.add( prevBone );
bones.push( prevBone );

// "bone1", "bone2", "bone3"
for ( let i = 1; i <= 3; i ++ ) {
const bone = new Bone();
bone.position.y = 8;
bones.push( bone );

prevBone.add( bone );
prevBone = bone;
}

// "target"
const targetBone = new Bone();
targetBone.position.y = 24 + 8
rootBone.add( targetBone );
bones.push( targetBone );

//
// skinned mesh
//

// Load MMD resources and instantiate CCDIKSolver
new MMDLoader().load(
'models/mmd/miku.pmd',
function ( mesh ) {
const mesh = new SkinnedMesh( geometry, material );
const skeleton = new Skeleton( bones );

ikSolver = new CCDIKSolver( mesh, mesh.geometry.iks );
scene.add( mesh );
mesh.add( bones[ 0 ] ); // "root" bone
mesh.bind( skeleton );

//
// ikSolver
//

const iks = [
{
target: 5, // "target"
effector: 4, // "bone3"
links: [ { index: 3 }, { index: 2 }, { index: 1 } ] // "bone2", "bone1", "bone0"
}
);
];
ikSolver = new CCDIKSolver( mesh, iks );

function render() {

animate(); // update bones
if ( ikSolver !== undefined ) ikSolver.update();
ikSolver?.update();
renderer.render( scene, camera );

}
</code>

Expand Down Expand Up @@ -92,7 +155,7 @@ <h3>[method:CCDIKHelper createHelper]()</h3>

<h3>[method:this update]()</h3>
<p>
Update bones quaternion by solving CCD algorithm.
Update IK bones quaternion by solving CCD algorithm.
</p>

<h3>[method:this updateOne]( [param:Object ikParam] )</h3>
Expand Down
Loading