parseAnimation static method
dynamic
parseAnimation(
- dynamic animation,
- dynamic bones
Implementation
static parseAnimation(animation, bones) {
if (!animation) {
print('three.AnimationClip: No animation in JSONLoader data.');
return null;
}
addNonemptyTrack(String trackType, trackName, animationKeys, propertyName, destTracks) {
// only return track if there are actually keys.
if (animationKeys.length != 0) {
const times = [];
const values = [];
AnimationUtils.flattenJSON(animationKeys, times, values, propertyName);
// empty keys are filtered out, so check again
if (times.isNotEmpty) {
if (trackType == "VectorKeyframeTrack") {
destTracks.add(VectorKeyframeTrack(trackName, times, values, null));
} else if (trackType == "QuaternionKeyframeTrack") {
destTracks.add(QuaternionKeyframeTrack(trackName, times, values, null));
} else {
throw ("AnimationClip. addNonemptyTrack trackType: $trackType is not support ");
}
}
}
}
var tracks = <KeyframeTrack>[];
var clipName = animation.name ?? 'default';
var fps = animation.fps ?? 30;
var blendMode = animation.blendMode;
// automatic length determination in AnimationClip.
var duration = animation.length ?? -1;
var hierarchyTracks = animation.hierarchy ?? [];
for (var h = 0; h < hierarchyTracks.length; h++) {
var animationKeys = hierarchyTracks[h].keys;
// skip empty tracks
if (!animationKeys || animationKeys.length == 0) continue;
// process morph targets
if (animationKeys[0].morphTargets) {
// figure out all morph targets used in this track
var morphTargetNames = {};
int k;
for (k = 0; k < animationKeys.length; k++) {
if (animationKeys[k].morphTargets) {
for (var m = 0; m < animationKeys[k].morphTargets.length; m++) {
morphTargetNames[animationKeys[k].morphTargets[m]] = -1;
}
}
}
// create a track for each morph target with all zero
// morphTargetInfluences except for the keys in which
// the morphTarget is named.
// for ( var morphTargetName in morphTargetNames ) {
morphTargetNames.forEach((morphTargetName, value) {
List<num> times = [];
List<num> values = [];
for (var m = 0; m != animationKeys[k].morphTargets.length; ++m) {
var animationKey = animationKeys[k];
times.add(animationKey.time);
values.add((animationKey.morphTarget == morphTargetName) ? 1 : 0);
}
tracks.add(NumberKeyframeTrack('.morphTargetInfluence[$morphTargetName]', times, values, null));
});
duration = morphTargetNames.length * (fps ?? 1.0);
} else {
// ...assume skeletal animation
var boneName = '.bones[${bones[h].name}]';
addNonemptyTrack("VectorKeyframeTrack", '$boneName.position', animationKeys, 'pos', tracks);
addNonemptyTrack("QuaternionKeyframeTrack", '$boneName.quaternion', animationKeys, 'rot', tracks);
addNonemptyTrack("VectorKeyframeTrack", '$boneName.scale', animationKeys, 'scl', tracks);
}
}
if (tracks.isEmpty) {
return null;
}
var clip = AnimationClip(clipName, duration, tracks, blendMode);
return clip;
}