提交 801124dc 编写于 作者: B Ben Houston

simplifying code in the clip-based animation system.

上级 43f821d8
......@@ -75,70 +75,44 @@ THREE.AnimationClip.prototype = {
};
THREE.AnimationClip.CreateMorphAnimationFromNames = function( morphTargetNames, duration ) {
THREE.AnimationClip.CreateFromMorphTargetSequence = function( name, morphTargetSequence, fps ) {
var numMorphTargets = morphTargetSequence.length;
var tracks = [];
var frameStep = duration / morphTargetNames.length;
for( var i = 0; i < morphTargetNames.length; i ++ ) {
for( var i = 0; i < numMorphTargets; i ++ ) {
var keys = [];
if( ( i - 1 ) >= 0 ) {
keys.push( { time: ( i - 1 ) * frameStep, value: 0 } );
}
keys.push( { time: i * frameStep, value: 1 } );
if( ( i + 1 ) <= morphTargetNames.length ) {
keys.push( { time: ( i + numMorphTargets - 1 ) % numMorphTargets, value: 0 } );
keys.push( { time: i, value: 1 } );
keys.push( { time: ( i + 1 ) % numMorphTargets, value: 0 } );
keys.push( { time: ( i + 1 ) * frameStep, value: 0 } );
keys.sort( THREE.KeyframeTrack.keyComparer );
// if there is a key at the first frame, duplicate it as the last frame as well for perfect loop.
if( keys[0].time === 0 ) {
keys.push( {
time: numMorphTargets,
value: keys[0].value
});
}
if( ( i - 1 ) < 0 ) {
keys.push( { time: ( morphTargetNames.length - 1 ) * frameStep, value: 0 } );
keys.push( { time: morphTargetNames.length * frameStep, value: 1 } );
}
var morphName = morphTargetNames[i];
var trackName = '.morphTargetInfluences[' + morphName + ']';
var track = new THREE.NumberKeyframeTrack( trackName, keys );
tracks.push( track );
tracks.push( new THREE.NumberKeyframeTrack( '.morphTargetInfluences[' + morphTargetSequence[i].name + ']', keys ) );
}
var clip = new THREE.AnimationClip( 'morphAnimation', duration, tracks );
return new THREE.AnimationClip( name, -1, tracks ).scale( 1.0 / fps );
return clip;
};
THREE.AnimationClip.CreateMorphAnimation = function( morphTargets, duration ) {
var morphTargetNames = [];
for( var i = 0; i < morphTargets.length; i ++ ) {
morphTargetNames.push( morphTargets[i].name );
}
return THREE.AnimationClip.CreateMorphAnimationFromNames( morphTargetNames, duration );
};
THREE.AnimationClip.FromImplicitMorphTargetAnimations = function( morphTargets, fps ) {
THREE.AnimationClip.CreateClipsFromMorphTargetSequences = function( morphTargets, fps ) {
var animations = {};
var animationsArray = [];
var animationToMorphTargets = {};
var pattern = /([a-z]+)_?(\d+)/;
// sort morph target names into animation groups based patterns like Walk_001, Walk_002, Run_001, Run_002
for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
var morphTarget = morphTargets[ i ];
......@@ -146,29 +120,24 @@ THREE.AnimationClip.FromImplicitMorphTargetAnimations = function( morphTargets,
if ( parts && parts.length > 1 ) {
var animationName = parts[ 1 ];
var name = parts[ 1 ];
var animation = animations[ animationName ];
if ( ! animation ) {
animations[ animationName ] = animation = { name: animationName, morphTargetNames: [] };
animationsArray.push( animation );
var animationToMorphTargets = animationToMorphTargets[ name ] || [];
if( ! animationToMorphTargets ) {
animationToMorphTargets = [];
}
animation.morphTargetNames.push( morphTarget.name );
animationToMorphTargets.push( morphTarget );
}
}
var clips = [];
for( var i = 0; i < animationsArray.length; i ++ ) {
var animation = animationsArray[i];
var clip = new THREE.AnimationClip.CreateMorphAnimationFromNames( animation.morphTargetNames, animation.morphTargetNames.length * fps );
clip.name = animation.name;
for( var name in animationToMorphTargets ) {
clips.push( clip );
clips.push( THREE.AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps ) );
}
return clips;
......@@ -178,57 +147,17 @@ THREE.AnimationClip.FromImplicitMorphTargetAnimations = function( morphTargets,
// parse the standard JSON format for clips
THREE.AnimationClip.parse = function( json ) {
optionalPrefix = optionalPrefix || "";
var name = json.name || "default";
var duration = json.duration || -1;
var fps = json.fps || 30;
var animationTracks = json.tracks || [];
var tracks = [];
for( var i = 0; i < animationTracks.length; i ++ ) {
for( var i = 0; i < json.tracks.length; i ++ ) {
var track = THREE.KeyframeTrack.parse( animationTracks[i] ).scale( 1 / fps );
tracks.push( track );
tracks.push( THREE.KeyframeTrack.parse( json.tracks[i] ).scale( 1.0 / json.fps ) );
}
if( tracks.length === 0 ) return null;
return new THREE.AnimationClip( name, duration, tracks );
return new THREE.AnimationClip( json.name, json.duration, tracks );
};
// parse the JSON format for THREE.Geometry clips
THREE.AnimationClip.parseGeometryClip = function( json ) {
var name = json.name || "default";
var duration = json.duration || -1;
var fps = json.fps || 30;
var animationTracks = json.tracks || [];
var tracks = [];
for( var i = 0; i < animationTracks.length; i ++ ) {
var track = THREE.KeyframeTrack.parse( animationTracks[i] ).scale( 1 / fps );
if( track.name.indexOf('morphTargets') >= 0 ) {
track.name = track.name.replace('morphTargets', 'morphTargetInfluences' );
}
if( track.name.indexOf('.') !== 0 ) {
track.name = '.' + track.name;
}
tracks.push( track );
}
if( tracks.length === 0 ) return null;
return new THREE.AnimationClip( name, duration, tracks );
};
// parse the old animation.hierarchy format
THREE.AnimationClip.parseAnimationHierarchy = function( animation, bones, nodeName ) {
......
......@@ -137,19 +137,11 @@ THREE.KeyframeTrack.prototype = {
Tracks with out of order keys should be considered to be invalid. - bhouston
sort: function() {
function keyComparator(key0, key1) {
return key0.time - key1.time;
};
return function() {
this.keys.sort( keyComparator );
return this;
this.keys.sort( THREE.KeyframeTrack.keyComparer );
}
return this;
}(),*/
},*/
// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
// One could eventually ensure that all key.values in a track are all of the same type (otherwise interpolation makes no sense.)
......@@ -238,6 +230,10 @@ THREE.KeyframeTrack.prototype = {
};
THREE.KeyframeTrack.keyComparer = function keyComparator(key0, key1) {
return key0.time - key1.time;
};
THREE.KeyframeTrack.parse = function( json ) {
if( json.type === undefined ) throw new Error( "track type undefined, can not parse" );
......
......@@ -439,7 +439,7 @@ THREE.JSONLoader.prototype = {
for( var i = 0; i < clips.length; i ++ ) {
var clip = THREE.AnimationClip.parseGeometryClip( clips[i] );
var clip = THREE.AnimationClip.parse( clips[i] );
if( clip ) geometry.clips.push( clip );
}
......
......@@ -633,9 +633,9 @@ THREE.ObjectLoader.prototype = {
// One will end up with a few named clips for the scene composed of merged tracks from individual nodes.
for( var i = 0; i < Math.min( 1, data.clips.length ); i ++ ) {
var dataTracks = data.clips[i].tracks;
var fpsToSeconds = ( data.clips[i].fps !== undefined ) ? ( 1.0 / data.clips[i].fps ) : 1.0;
var dataClips = data.clips[i];
var dataTracks = dataClips.tracks || [];
var fpsToSeconds = 1.0 / ( dataClips.fps || 30 );
for( var i = 0; i < dataTracks.length; i ++ ) {
......
......@@ -473,7 +473,7 @@ def animated_blend_shapes(mesh, options):
animCurves = animCurves.action.fcurves
for key in shp.key_blocks.keys()[1:]: # skip "Basis"
key_name = constants.MORPH_TARGETS+"["+key+"]"
key_name = ".morphTargetInfluences["+key+"]"
found_animation = False
data_path = 'key_blocks["'+key+'"].value'
values = []
......
......@@ -172,10 +172,10 @@ def __parse_tracked_vector(fcurves, start_index, nb_curves):
# trackable transform fields ( <output field>, <nb fcurve>, <type> )
TRACKABLE_FIELDS = {
"location": ( "position", 3, "vector3" ),
"scale": ( "scale", 3, "vector3" ),
"rotation_euler": ( "rotation", 3, "vector3" ),
"rotation_quaternion": ( "quaternion", 4, "quaternion" )
"location": ( ".position", 3, "vector3" ),
"scale": ( ".scale", 3, "vector3" ),
"rotation_euler": ( ".rotation", 3, "vector3" ),
"rotation_quaternion": ( ".quaternion", 4, "quaternion" )
}
@_object
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册