From 61abc6454ce6fbd413a5685e457e458e7630f217 Mon Sep 17 00:00:00 2001 From: Felix Herbst Date: Sat, 4 Jun 2022 23:31:46 +0200 Subject: [PATCH] GLTFLoader: some code to be accessible from extensions on parser --- examples/jsm/loaders/GLTFLoader.js | 224 ++++++++++++++++++----------- 1 file changed, 137 insertions(+), 87 deletions(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 0a11e7ec4cf11e..ce0ad94d77370f 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -3857,6 +3857,7 @@ class GLTFParser { loadAnimation( animationIndex ) { const json = this.json; + const parser = this; const animationDef = json.animations[ animationIndex ]; const animationName = animationDef.name ? animationDef.name : 'animation_' + animationIndex; @@ -3914,103 +3915,23 @@ class GLTFParser { if ( node === undefined ) continue; - node.updateMatrix(); - - let TypedKeyframeTrack; - - switch ( PATH_PROPERTIES[ target.path ] ) { - - case PATH_PROPERTIES.weights: - - TypedKeyframeTrack = NumberKeyframeTrack; - break; - - case PATH_PROPERTIES.rotation: - - TypedKeyframeTrack = QuaternionKeyframeTrack; - break; - - case PATH_PROPERTIES.position: - case PATH_PROPERTIES.scale: - default: - - TypedKeyframeTrack = VectorKeyframeTrack; - break; - - } - - const targetName = node.name ? node.name : node.uuid; - - const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear; - - const targetNames = []; - - if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { - - node.traverse( function ( object ) { - - if ( object.morphTargetInfluences ) { - - targetNames.push( object.name ? object.name : object.uuid ); - - } - - } ); - - } else { - - targetNames.push( targetName ); + if ( node.updateMatrix ) { - } - - let outputArray = outputAccessor.array; - - if ( outputAccessor.normalized ) { - - const scale = getNormalizedComponentScale( outputArray.constructor ); - const scaled = new Float32Array( outputArray.length ); - - for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) { - - scaled[ j ] = outputArray[ j ] * scale; - - } - - outputArray = scaled; + node.updateMatrix(); + node.matrixAutoUpdate = true; } - for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) { - - const track = new TypedKeyframeTrack( - targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], - inputAccessor.array, - outputArray, - interpolation - ); - - // Override interpolation with custom factory method. - if ( sampler.interpolation === 'CUBICSPLINE' ) { - - track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { + const createdTracks = parser._createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target ); - // A CUBICSPLINE keyframe in glTF has three output values for each input value, - // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() - // must be divided by three to get the interpolant's sampleSize argument. + if ( createdTracks ) { - const interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant; + for ( let k = 0; k < createdTracks.length; k ++ ) { - return new interpolantType( this.times, this.values, this.getValueSize() / 3, result ); - - }; - - // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants. - track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; + tracks.push( createdTracks[ k ] ); } - tracks.push( track ); - } } @@ -4341,6 +4262,135 @@ class GLTFParser { } + _createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target ) { + + const tracks = []; + + const targetName = node.name ? node.name : node.uuid; + + const targetNames = []; + + if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { + + node.traverse( function ( object ) { + + if ( object.morphTargetInfluences ) { + + targetNames.push( object.name ? object.name : object.uuid ); + + } + + } ); + + } else { + + targetNames.push( targetName ); + + } + + let TypedKeyframeTrack; + + switch ( PATH_PROPERTIES[ target.path ] ) { + + case PATH_PROPERTIES.weights: + + TypedKeyframeTrack = NumberKeyframeTrack; + break; + + case PATH_PROPERTIES.rotation: + + TypedKeyframeTrack = QuaternionKeyframeTrack; + break; + + case PATH_PROPERTIES.position: + case PATH_PROPERTIES.scale: + default: + switch ( outputAccessor.itemSize ) { + + case 1: + TypedKeyframeTrack = NumberKeyframeTrack; + break; + case 2: + case 3: + TypedKeyframeTrack = VectorKeyframeTrack; + break; + + } + + break; + + } + + const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear; + + const outputArray = this._getArrayFromAccessor( outputAccessor ); + + for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) { + + const track = new TypedKeyframeTrack( + targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], + inputAccessor.array, + outputArray, + interpolation + ); + + // Override interpolation with custom factory method. + if ( interpolation === 'CUBICSPLINE' ) { + + this._createCubicSplineTrackInterpolant( track ); + + } + + tracks.push( track ); + + } + + return tracks; + + } + + _getArrayFromAccessor( accessor ) { + + let outputArray = accessor.array; + + if ( accessor.normalized ) { + + const scale = getNormalizedComponentScale( outputArray.constructor ); + const scaled = new Float32Array( outputArray.length ); + + for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) { + + scaled[ j ] = outputArray[ j ] * scale; + + } + + outputArray = scaled; + + } + + return outputArray; + + } + + _createCubicSplineTrackInterpolant( track ) { + + track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { + + // A CUBICSPLINE keyframe in glTF has three output values for each input value, + // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() + // must be divided by three to get the interpolant's sampleSize argument. + + const interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant; + + return new interpolantType( this.times, this.values, this.getValueSize() / 3, result ); + + }; + + // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants. + track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; + + } + } /**