diff --git a/examples/js/loaders/FBXLoader2.js b/examples/js/loaders/FBXLoader2.js index 67f24a6e23fff21c01492e36836e8222468fd30e..407c0e84169aeb671865d80b884e1a06cb7403f0 100644 --- a/examples/js/loaders/FBXLoader2.js +++ b/examples/js/loaders/FBXLoader2.js @@ -1467,7 +1467,6 @@ var rawCurves = FBXTree.Objects.subNodes.AnimationCurve; var rawLayers = FBXTree.Objects.subNodes.AnimationLayer; var rawStacks = FBXTree.Objects.subNodes.AnimationStack; - var rawModels = FBXTree.Objects.subNodes.Model; /** * @type {{ @@ -2136,6 +2135,7 @@ */ var layer = []; var children = connections.get( parseInt( nodeID ) ).children; + for ( var childIndex = 0; childIndex < children.length; childIndex ++ ) { // Skip lockInfluenceWeights @@ -2167,8 +2167,8 @@ var layers = []; var children = connections.get( parseInt( nodeID ) ).children; - var maxTimeStamp = 0; - var minTimeStamp = Number.MAX_VALUE; + var timestamps = { max: 0, min: Number.MAX_VALUE }; + for ( var childIndex = 0; childIndex < children.length; ++ childIndex ) { var currentLayer = returnObject.layers[ children[ childIndex ].ID ]; @@ -2183,214 +2183,7 @@ if ( layer ) { - getCurveNodeMaxMinTimeStamps( layer ); - - } - - /** - * Sets the maxTimeStamp and minTimeStamp variables if it has timeStamps that are either larger or smaller - * than the max or min respectively. - * @param {{ - T: { - id: number, - attr: string, - internalID: number, - attrX: boolean, - attrY: boolean, - attrZ: boolean, - containerBoneID: number, - containerID: number, - curves: { - x: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - y: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - z: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - }, - }, - R: { - id: number, - attr: string, - internalID: number, - attrX: boolean, - attrY: boolean, - attrZ: boolean, - containerBoneID: number, - containerID: number, - curves: { - x: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - y: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - z: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - }, - }, - S: { - id: number, - attr: string, - internalID: number, - attrX: boolean, - attrY: boolean, - attrZ: boolean, - containerBoneID: number, - containerID: number, - curves: { - x: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - y: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - z: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - }, - }, - }} layer - */ - function getCurveNodeMaxMinTimeStamps( layer ) { - - /** - * Sets the maxTimeStamp and minTimeStamp if one of the curve's time stamps - * exceeds the maximum or minimum. - * @param {{ - x: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - y: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - }, - z: { - version: any, - id: number, - internalID: number, - times: number[], - values: number[], - attrFlag: number[], - attrData: number[], - } - }} curve - */ - function getCurveMaxMinTimeStamp( curve ) { - - /** - * Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum. - * @param {{times: number[]}} axis - */ - function getCurveAxisMaxMinTimeStamps( axis ) { - - maxTimeStamp = axis.times[ axis.times.length - 1 ] > maxTimeStamp ? axis.times[ axis.times.length - 1 ] : maxTimeStamp; - minTimeStamp = axis.times[ 0 ] < minTimeStamp ? axis.times[ 0 ] : minTimeStamp; - - } - - if ( curve.x ) { - - getCurveAxisMaxMinTimeStamps( curve.x ); - - } - if ( curve.y ) { - - getCurveAxisMaxMinTimeStamps( curve.y ); - - } - if ( curve.z ) { - - getCurveAxisMaxMinTimeStamps( curve.z ); - - } - - } - - if ( layer.R ) { - - getCurveMaxMinTimeStamp( layer.R.curves ); - - } - if ( layer.S ) { - - getCurveMaxMinTimeStamp( layer.S.curves ); - - } - if ( layer.T ) { - - getCurveMaxMinTimeStamp( layer.T.curves ); - - } + getCurveNodeMaxMinTimeStamps( layer, timestamps ); } @@ -2401,13 +2194,13 @@ } // Do we have an animation clip with actual length? - if ( maxTimeStamp > minTimeStamp ) { + if ( timestamps.max > timestamps.min ) { returnObject.stacks[ nodeID ] = { name: rawStacks[ nodeID ].attrName, layers: layers, - length: maxTimeStamp - minTimeStamp, - frames: ( maxTimeStamp - minTimeStamp ) * 30 + length: timestamps.max - timestamps.min, + frames: ( timestamps.max - timestamps.min ) * 30 }; } @@ -2416,142 +2209,351 @@ return returnObject; - /** - * @param {Object} FBXTree - * @param {{id: number, attrName: string, properties: Object}} animationCurveNode - * @param {Map} connections - * @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph - */ - function parseAnimationNode( FBXTree, animationCurveNode, connections, sceneGraph ) { - - var returnObject = { - /** - * @type {number} - */ - id: animationCurveNode.id, + } - /** - * @type {string} - */ - attr: animationCurveNode.attrName, + /** + * @param {Object} FBXTree + * @param {{id: number, attrName: string, properties: Object}} animationCurveNode + * @param {Map} connections + * @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph + */ + function parseAnimationNode( FBXTree, animationCurveNode, connections, sceneGraph ) { - /** - * @type {number} - */ - internalID: animationCurveNode.id, + var rawModels = FBXTree.Objects.subNodes.Model; - /** - * @type {boolean} - */ - attrX: false, + var returnObject = { + /** + * @type {number} + */ + id: animationCurveNode.id, - /** - * @type {boolean} - */ - attrY: false, + /** + * @type {string} + */ + attr: animationCurveNode.attrName, - /** - * @type {boolean} - */ - attrZ: false, + /** + * @type {number} + */ + internalID: animationCurveNode.id, - /** - * @type {number} - */ - containerBoneID: - 1, + /** + * @type {boolean} + */ + attrX: false, - /** - * @type {number} - */ - containerID: - 1, + /** + * @type {boolean} + */ + attrY: false, - curves: { - x: null, - y: null, - z: null - }, + /** + * @type {boolean} + */ + attrZ: false, - /** - * @type {number[]} - */ - preRotations: null - }; + /** + * @type {number} + */ + containerBoneID: - 1, - if ( returnObject.attr.match( /S|R|T/ ) ) { + /** + * @type {number} + */ + containerID: - 1, - for ( var attributeKey in animationCurveNode.properties ) { + curves: { + x: null, + y: null, + z: null + }, - if ( attributeKey.match( /X/ ) ) { + /** + * @type {number[]} + */ + preRotations: null + }; - returnObject.attrX = true; + if ( returnObject.attr.match( /S|R|T/ ) ) { - } - if ( attributeKey.match( /Y/ ) ) { + for ( var attributeKey in animationCurveNode.properties ) { - returnObject.attrY = true; + if ( attributeKey.match( /X/ ) ) { - } - if ( attributeKey.match( /Z/ ) ) { + returnObject.attrX = true; - returnObject.attrZ = true; + } + if ( attributeKey.match( /Y/ ) ) { - } + returnObject.attrY = true; } + if ( attributeKey.match( /Z/ ) ) { - } else { + returnObject.attrZ = true; - return null; + } } - var conns = connections.get( returnObject.id ); - var containerIndices = conns.parents; + } else { - for ( var containerIndicesIndex = containerIndices.length - 1; containerIndicesIndex >= 0; -- containerIndicesIndex ) { + return null; - var boneID = findIndex( sceneGraph.skeleton.bones, function ( bone ) { + } - return bone.FBX_ID === containerIndices[ containerIndicesIndex ].ID; + var conns = connections.get( returnObject.id ); + var containerIndices = conns.parents; - } ); - if ( boneID > - 1 ) { + for ( var containerIndicesIndex = containerIndices.length - 1; containerIndicesIndex >= 0; -- containerIndicesIndex ) { - returnObject.containerBoneID = boneID; - returnObject.containerID = containerIndices[ containerIndicesIndex ].ID; - var model = rawModels[ returnObject.containerID.toString() ]; - if ( 'PreRotation' in model.properties ) { + var boneID = findIndex( sceneGraph.skeleton.bones, function ( bone ) { - returnObject.preRotations = parseVector3( model.properties.PreRotation ).multiplyScalar( Math.PI / 180 ); + return bone.FBX_ID === containerIndices[ containerIndicesIndex ].ID; - } - break; + } ); + if ( boneID > - 1 ) { + + returnObject.containerBoneID = boneID; + returnObject.containerID = containerIndices[ containerIndicesIndex ].ID; + var model = rawModels[ returnObject.containerID.toString() ]; + if ( 'PreRotation' in model.properties ) { + + returnObject.preRotations = parseVector3( model.properties.PreRotation ).multiplyScalar( Math.PI / 180 ); } + break; } - return returnObject; + } + + return returnObject; + + } + + /** + * @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve + */ + function parseAnimationCurve( animationCurve ) { + + return { + version: null, + id: animationCurve.id, + internalID: animationCurve.id, + times: parseFloatArray( animationCurve.subNodes.KeyTime.properties.a ).map( convertFBXTimeToSeconds ), + values: parseFloatArray( animationCurve.subNodes.KeyValueFloat.properties.a ), + + attrFlag: parseIntArray( animationCurve.subNodes.KeyAttrFlags.properties.a ), + attrData: parseFloatArray( animationCurve.subNodes.KeyAttrDataFloat.properties.a ) + }; + + } + + /** + * Sets the maxTimeStamp and minTimeStamp variables if it has timeStamps that are either larger or smaller + * than the max or min respectively. + * @param {{ + T: { + id: number, + attr: string, + internalID: number, + attrX: boolean, + attrY: boolean, + attrZ: boolean, + containerBoneID: number, + containerID: number, + curves: { + x: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + y: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + z: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + }, + }, + R: { + id: number, + attr: string, + internalID: number, + attrX: boolean, + attrY: boolean, + attrZ: boolean, + containerBoneID: number, + containerID: number, + curves: { + x: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + y: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + z: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + }, + }, + S: { + id: number, + attr: string, + internalID: number, + attrX: boolean, + attrY: boolean, + attrZ: boolean, + containerBoneID: number, + containerID: number, + curves: { + x: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + y: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + z: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + }, + }, + }} layer + */ + function getCurveNodeMaxMinTimeStamps( layer, timestamps ) { + + if ( layer.R ) { + + getCurveMaxMinTimeStamp( layer.R.curves, timestamps ); } + if ( layer.S ) { - /** - * @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve - */ - function parseAnimationCurve( animationCurve ) { + getCurveMaxMinTimeStamp( layer.S.curves, timestamps ); - return { - version: null, - id: animationCurve.id, - internalID: animationCurve.id, - times: parseFloatArray( animationCurve.subNodes.KeyTime.properties.a ).map( convertFBXTimeToSeconds ), - values: parseFloatArray( animationCurve.subNodes.KeyValueFloat.properties.a ), - - attrFlag: parseIntArray( animationCurve.subNodes.KeyAttrFlags.properties.a ), - attrData: parseFloatArray( animationCurve.subNodes.KeyAttrDataFloat.properties.a ) - }; + } + if ( layer.T ) { + + getCurveMaxMinTimeStamp( layer.T.curves, timestamps ); + + } + + } + + /** + * Sets the maxTimeStamp and minTimeStamp if one of the curve's time stamps + * exceeds the maximum or minimum. + * @param {{ + x: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + y: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + }, + z: { + version: any, + id: number, + internalID: number, + times: number[], + values: number[], + attrFlag: number[], + attrData: number[], + } + }} curve + */ + function getCurveMaxMinTimeStamp( curve, timestamps ) { + + if ( curve.x ) { + + getCurveAxisMaxMinTimeStamps( curve.x, timestamps ); } + if ( curve.y ) { + + getCurveAxisMaxMinTimeStamps( curve.y, timestamps ); + + } + if ( curve.z ) { + + getCurveAxisMaxMinTimeStamps( curve.z, timestamps ); + + } + + } + + /** + * Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum. + * @param {{times: number[]}} axis + */ + function getCurveAxisMaxMinTimeStamps( axis, timestamps ) { + + timestamps.max = axis.times[ axis.times.length - 1 ] > timestamps.max ? axis.times[ axis.times.length - 1 ] : timestamps.max; + timestamps.min = axis.times[ 0 ] < timestamps.min ? axis.times[ 0 ] : timestamps.min; }