Skip to content

Commit cac0703

Browse files
committed
fix: aimBone parent resolver not working for some vrms
1 parent 4f96828 commit cac0703

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

src/core/extras/createVRMFactory.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,13 @@ export function createVRMFactory(glb, setupMaterial) {
314314
updateLocomotion(delta)
315315
}
316316
if (loco.gazeDir && (currentEmote ? currentEmote.gaze : true)) {
317-
aimBone('neck', 'upperChest', loco.gazeDir, delta, {
317+
aimBone('neck', loco.gazeDir, delta, {
318318
minAngle: -30,
319319
maxAngle: 30,
320320
smoothing: 0.4,
321321
weight: 0.5,
322322
})
323-
aimBone('head', 'neck', loco.gazeDir, delta, {
323+
aimBone('head', loco.gazeDir, delta, {
324324
minAngle: -30,
325325
maxAngle: 30,
326326
smoothing: 0.4,
@@ -337,6 +337,7 @@ export function createVRMFactory(glb, setupMaterial) {
337337
const aimBone = (() => {
338338
const smoothedRotations = new Map()
339339
const normalizedDir = new THREE.Vector3()
340+
const parentWorldMatrix = new THREE.Matrix4()
340341
const parentWorldRotationInverse = new THREE.Quaternion()
341342
const localDir = new THREE.Vector3()
342343
const currentAimDir = new THREE.Vector3()
@@ -350,7 +351,7 @@ export function createVRMFactory(glb, setupMaterial) {
350351
const targetRotation = new THREE.Quaternion()
351352
const restToTarget = new THREE.Quaternion()
352353

353-
return function aimBone(boneName, parentBoneName, targetDir, delta, options = {}) {
354+
return function aimBone(boneName, targetDir, delta, options = {}) {
354355
// default options
355356
const {
356357
aimAxis = AimAxis.NEG_Z,
@@ -362,8 +363,9 @@ export function createVRMFactory(glb, setupMaterial) {
362363
maxAngle = 180,
363364
} = options
364365
const bone = findBone(boneName)
365-
const parentBone = findBone(parentBoneName)
366-
if (!bone || !parentBone) return console.warn('aimBone: missing bone')
366+
const parentBone = glb.userData.vrm.humanoid.humanBones[boneName].node.parent
367+
if (!bone) return console.warn(`aimBone: missing bone (${boneName})`)
368+
if (!parentBone) return console.warn(`aimBone: no parent bone`)
367369
// get or create smoothed state for this bone
368370
const boneId = bone.uuid
369371
if (!smoothedRotations.has(boneId)) {
@@ -376,7 +378,7 @@ export function createVRMFactory(glb, setupMaterial) {
376378
// normalize target direction
377379
normalizedDir.copy(targetDir).normalize()
378380
// get parent's world matrix
379-
const parentWorldMatrix = getBoneTransform(parentBoneName)
381+
parentWorldMatrix.multiplyMatrices(vrm.scene.matrixWorld, parentBone.matrixWorld)
380382
// extract parent's world rotation
381383
parentWorldMatrix.decompose(v1, parentWorldRotationInverse, v2)
382384
parentWorldRotationInverse.invert()
@@ -450,14 +452,13 @@ export function createVRMFactory(glb, setupMaterial) {
450452

451453
// position target equivalent of aimBone()
452454
const aimBoneDir = new THREE.Vector3()
453-
function aimBoneAt(boneName, parentBoneName, targetPos, delta, options = {}) {
455+
function aimBoneAt(boneName, targetPos, delta, options = {}) {
454456
const bone = findBone(boneName)
455-
const parentBone = findBone(parentBoneName)
456-
if (!bone || !parentBone) return console.warn('aimBoneAt: missing bone')
457+
if (!bone) return console.warn(`aimBone: missing bone (${boneName})`)
457458
const boneWorldMatrix = getBoneTransform(boneName)
458459
const boneWorldPos = v1.setFromMatrixPosition(boneWorldMatrix)
459460
aimBoneDir.subVectors(targetPos, boneWorldPos).normalize()
460-
aimBone(boneName, parentBoneName, aimBoneDir, delta, options)
461+
aimBone(boneName, aimBoneDir, delta, options)
461462
}
462463

463464
// hooks.loader.load('emote', 'asset://rifle-aim.glb').then(emo => {

0 commit comments

Comments
 (0)