Skip to content

Commit

Permalink
Merge pull request #12 from 0b5vr/improve
Browse files Browse the repository at this point in the history
fix: Improve chest detection algorithm
  • Loading branch information
0b5vr authored Feb 15, 2024
2 parents cbc7cdc + 47f25a9 commit 8d99a3d
Showing 1 changed file with 31 additions and 3 deletions.
34 changes: 31 additions & 3 deletions src/lib/bvh-converter/mapSkeletonToVRM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ function objectBFS(
return null;
}

/**
* Traverse descendants of given object.
* It will return an array of object that the given evaluation function returns `true`.
*
* It will perform breadth first search.
*/
function objectTraverseFilter(
root: THREE.Object3D,
fn: (obj: THREE.Object3D) => boolean | void
): THREE.Object3D[] {
const result: THREE.Object3D[] = [];

root.traverse((obj) => {
if (fn(obj)) {
result.push(obj);
}
});

return result;
}

/**
* Traverse ancestors of given object.
* Once the given function returns `true`, it stops the traversal operation and returns the object.
Expand Down Expand Up @@ -346,10 +367,17 @@ export function mapSkeletonToVRM(root: THREE.Bone): Map<VRMHumanBoneName, THREE.
}
result.set('hips', hips as THREE.Bone);

// find chest candidate - the first descendant of the hips which has three children
const chestCand = objectBFS(hips, (obj) => {
// find chest candidate - descendants of the hips which has three or more children
const chestCands = objectTraverseFilter(hips, (obj) => {
return obj !== hips && obj.children.length >= 3;
}) as THREE.Bone;
}) as THREE.Bone[];
const chestCand = pickByProbability(
chestCands,
[
{ func: (obj) => evaluatorName(obj, 'upperchest'), weight: 1.0 },
{ func: (obj) => evaluatorName(obj, 'chest'), weight: 1.0 },
]
);
if (chestCand == null) {
throw new Error('Cannot find chest.');
}
Expand Down

0 comments on commit 8d99a3d

Please sign in to comment.