parseAnimation static method

  1. @Deprecated('parseAnimation() is deprecated and will be removed with r185')
AnimationClip? parseAnimation(
  1. Map<String, dynamic>? animation,
  2. dynamic bones
)

Implementation

@Deprecated('parseAnimation() is deprecated and will be removed with r185')
static AnimationClip? parseAnimation(Map<String,dynamic>? animation, bones) {
  if (animation == null) {
    console.warning('AnimationClip: No animation in JsonLoader data.');
    return null;
  }

  void addNonemptyTrack(String trackType, String trackName, List<String> animationKeys, String propertyName, List<KeyframeTrack> destTracks) {
    // only return track if there are actually keys.
    if (animationKeys.isNotEmpty) {
      final List<double> times = [];
      final List<double> 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 ");
        }
      }
    }
  }

  final List<KeyframeTrack> tracks = [];

  String clipName = animation['name'] ?? 'default';
  int fps = animation['fps'] ?? 30;
  int blendMode = animation['blendMode'];

  // automatic length determination in AnimationClip.
  num duration = animation['length'] ?? -1;

  final hierarchyTracks = animation['hierarchy'] ?? [];

  for (int h = 0; h < hierarchyTracks.length; h++) {
    final 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
      final morphTargetNames = {};

      int k;

      for (k = 0; k < animationKeys.length; k++) {
        if (animationKeys[k].morphTargets) {
          for (int 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 ( String morphTargetName in morphTargetNames ) {
      morphTargetNames.forEach((morphTargetName, value) {
        List<num> times = [];
        List<num> values = [];

        for (int m = 0; m != animationKeys[k].morphTargets.length; ++m) {
          final 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;
    }
    else {
      // ...assume skeletal animation

      String 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;
  }

  AnimationClip clip = AnimationClip(clipName, duration, tracks, blendMode);

  return clip;
}