提交 30da0beb 编写于 作者: M Mr.doob

FBXLoader2: Refactored parseAnimations.

上级 8b04814c
......@@ -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<string, any>}} animationCurveNode
* @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} 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<string, any>}} animationCurveNode
* @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} 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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册