Skip to content

Commit

Permalink
Merge pull request #1353 from pixiv/fix-humanoid
Browse files Browse the repository at this point in the history
fix: Normalized bones now respect non humanoid parent rotations
  • Loading branch information
0b5vr authored Jan 19, 2024
2 parents 8affe37 + 80f46b3 commit f85cb36
Showing 1 changed file with 11 additions and 13 deletions.
24 changes: 11 additions & 13 deletions packages/three-vrm-core/src/humanoid/VRMHumanoidRig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ export class VRMHumanoidRig extends VRMRig {
const root = new THREE.Object3D();
root.name = 'VRMHumanoidRig';

// store boneWorldPositions and boneWorldRotations
// store boneWorldPositions, boneWorldRotations, and parentWorldRotations
const boneWorldPositions: { [boneName in VRMHumanBoneName]?: THREE.Vector3 } = {};
const boneWorldRotations: { [boneName in VRMHumanBoneName]?: THREE.Quaternion } = {};
const boneRotations: { [boneName in VRMHumanBoneName]?: THREE.Quaternion } = {};
const parentWorldRotations: { [boneName in VRMHumanBoneName]?: THREE.Quaternion } = {};

VRMHumanBoneList.forEach((boneName) => {
const boneNode = modelRig.getBoneNode(boneName);
Expand All @@ -39,12 +40,14 @@ export class VRMHumanoidRig extends VRMRig {
boneWorldPositions[boneName] = boneWorldPosition;
boneWorldRotations[boneName] = boneWorldRotation;
boneRotations[boneName] = boneNode.quaternion.clone();

const parentWorldRotation = new THREE.Quaternion();
boneNode.parent?.matrixWorld.decompose(_v3A, parentWorldRotation, _v3A);
parentWorldRotations[boneName] = parentWorldRotation;
}
});

// build rig hierarchy + store parentWorldRotations
const parentWorldRotations: { [boneName in VRMHumanBoneName]?: THREE.Quaternion } = {};

const rigBones: Partial<VRMHumanBones> = {};
VRMHumanBoneList.forEach((boneName) => {
const boneNode = modelRig.getBoneNode(boneName);
Expand All @@ -54,15 +57,13 @@ export class VRMHumanoidRig extends VRMRig {

// see the nearest parent position
let currentBoneName: VRMHumanBoneName | null = boneName;
let parentWorldPosition: THREE.Vector3 | undefined;
let parentWorldRotation: THREE.Quaternion | undefined;
while (parentWorldPosition == null) {
let parentBoneWorldPosition: THREE.Vector3 | undefined;
while (parentBoneWorldPosition == null) {
currentBoneName = VRMHumanBoneParentMap[currentBoneName];
if (currentBoneName == null) {
break;
}
parentWorldPosition = boneWorldPositions[currentBoneName];
parentWorldRotation = boneWorldRotations[currentBoneName];
parentBoneWorldPosition = boneWorldPositions[currentBoneName];
}

// add to hierarchy
Expand All @@ -73,14 +74,11 @@ export class VRMHumanoidRig extends VRMRig {

parentRigBoneNode.add(rigBoneNode);
rigBoneNode.position.copy(boneWorldPosition);
if (parentWorldPosition) {
rigBoneNode.position.sub(parentWorldPosition);
if (parentBoneWorldPosition) {
rigBoneNode.position.sub(parentBoneWorldPosition);
}

rigBones[boneName] = { node: rigBoneNode };

// store parentWorldRotation
parentWorldRotations[boneName] = parentWorldRotation ?? new THREE.Quaternion();
}
});

Expand Down

0 comments on commit f85cb36

Please sign in to comment.