From debc58a0b0d7c65ed51b8e9c49e4c77c634a7100 Mon Sep 17 00:00:00 2001 From: 0b5vr <0b5vr@0b5vr.com> Date: Fri, 16 Jan 2026 17:21:58 +0900 Subject: [PATCH 1/2] feat: support `/nodes/{}/weights/{}` - control individual morph weights See: https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc#4-core-pointers --- src/GLTFLoaderAnimationPointer.js | 40 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/GLTFLoaderAnimationPointer.js b/src/GLTFLoaderAnimationPointer.js index 56a9f64..735c51d 100644 --- a/src/GLTFLoaderAnimationPointer.js +++ b/src/GLTFLoaderAnimationPointer.js @@ -247,23 +247,29 @@ export class GLTFAnimationPointerExtension { const pathStartNode = path.substring( 0, pathIndexNode ); targetProperty = path.substring( pathIndexNode ); - switch ( targetProperty ) { - - case 'translation': - targetProperty = 'position'; - break; - case 'rotation': - targetProperty = 'quaternion'; - break; - case 'scale': - targetProperty = 'scale'; - break; - case 'weights': - targetProperty = 'morphTargetInfluences'; - break; - case "extensions/KHR_node_visibility/visible": - targetProperty = 'visible'; - break; + if ( targetProperty.startsWith( 'weights/' ) ) { + // `/nodes/{}/weights/{}` - control individual morph weights + const weightIndex = targetProperty.substring( 'weights/'.length ); + targetProperty = 'morphTargetInfluences[' + weightIndex + ']'; + } else { + switch ( targetProperty ) { + + case 'translation': + targetProperty = 'position'; + break; + case 'rotation': + targetProperty = 'quaternion'; + break; + case 'scale': + targetProperty = 'scale'; + break; + case 'weights': + targetProperty = 'morphTargetInfluences'; + break; + case "extensions/KHR_node_visibility/visible": + targetProperty = 'visible'; + break; + } } path = pathStartNode + targetProperty; From acec2bc1c562089d85161a976eb35b73b5e7c3c0 Mon Sep 17 00:00:00 2001 From: 0b5vr <0b5vr@0b5vr.com> Date: Fri, 16 Jan 2026 17:44:05 +0900 Subject: [PATCH 2/2] feat: support `/nodes/{}/weights/{}` even with multi-material meshes (primitives) Utilized the existing code of the weights of multi-material meshes --- src/GLTFLoaderAnimationPointer.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/GLTFLoaderAnimationPointer.js b/src/GLTFLoaderAnimationPointer.js index 735c51d..aee5ded 100644 --- a/src/GLTFLoaderAnimationPointer.js +++ b/src/GLTFLoaderAnimationPointer.js @@ -391,8 +391,11 @@ export class GLTFAnimationPointerExtension { // specially handle the morphTargetInfluences property for multi-material meshes // in which case the target object is a Group and the children are the actual targets + // Note that there is also morphTargetInfluences[i] for individual morph targets // see NE-3311 - if ( parts[ 3 ] === 'morphTargetInfluences' ) { + if ( parts[ 3 ].startsWith( 'morphTargetInfluences' ) ) { + + const property = parts[ 3 ]; if ( node.type === 'Group' ) { @@ -405,7 +408,7 @@ export class GLTFAnimationPointerExtension { if ( ch instanceof SkinnedMesh && ch.morphTargetInfluences ) { parts[ 3 ] = ch.name; - parts[ 4 ] = 'morphTargetInfluences'; + parts[ 4 ] = property; __createTrack( this.parser ); }