readSkeletonData method

SkeletonData readSkeletonData(
  1. Object object
)

Implementation

SkeletonData readSkeletonData(Object object) {
  final double scale = this.scale;
  final SkeletonData skeletonData = SkeletonData('');

  dynamic root;

  if (object is String) {
    root = json.decode(object);
  } else if (object is Map) {
    root = object;
  } else {
    throw ArgumentError('object must be a String or Map.');
  }

  // Skeleton
  if (root.containsKey('skeleton')) {
    final dynamic skeletonMap = root['skeleton'];
    skeletonData
      ..hash = _getString(skeletonMap, 'hash')
      ..version = _getString(skeletonMap, 'spine')
      ..width = _getDouble(skeletonMap, 'width')
      ..height = _getDouble(skeletonMap, 'height')
      ..fps = _getDouble(skeletonMap, 'fps')
      ..imagesPath = _getString(skeletonMap, 'images');
  }

  // Bones
  if (root.containsKey('bones')) {
    for (int i = 0; i < root['bones'].length; i++) {
      final dynamic boneMap = root['bones'][i];

      BoneData? parent;
      final String parentName = _getString(boneMap, 'parent');
      if (parentName.isNotEmpty) {
        parent = skeletonData.findBone(parentName);
        if (parent == null) {
          throw StateError('Parent bone not found: $parentName');
        }
      }
      final BoneData data = BoneData(
          skeletonData.bones.length, _getString(boneMap, 'name'), parent)
        ..length = _getDouble(boneMap, 'length', 0.0) * scale
        ..x = _getDouble(boneMap, 'x', 0.0) * scale
        ..y = _getDouble(boneMap, 'y', 0.0) * scale
        ..rotation = _getDouble(boneMap, 'rotation', 0.0)
        ..scaleX = _getDouble(boneMap, 'scaleX', 1.0)
        ..scaleY = _getDouble(boneMap, 'scaleY', 1.0)
        ..shearX = _getDouble(boneMap, 'shearX', 0.0)
        ..shearY = _getDouble(boneMap, 'shearY', 0.0)
        ..transformMode = SkeletonJson.transformModeFromString(
            _getString(boneMap, 'transform', 'normal'));

      skeletonData.bones.add(data);
    }
  }

  // Slots.
  if (root.containsKey('slots')) {
    for (int i = 0; i < root['slots'].length; i++) {
      final dynamic slotMap = root['slots'][i];
      final String slotName = _getString(slotMap, 'name');
      final String boneName = _getString(slotMap, 'bone');
      final BoneData? boneData = skeletonData.findBone(boneName);
      if (boneData == null) {
        throw StateError('Slot bone not found: ' + boneName);
      }
      final SlotData data =
          SlotData(skeletonData.slots.length, slotName, boneData);

      final String color = _getString(slotMap, 'color');
      if (color.isNotEmpty) data.color.setFromString(color);

      final String dark = _getString(slotMap, 'dark');
      if (dark.isNotEmpty) {
        data.darkColor = Color(1.0, 1.0, 1.0, 1.0);
        data.darkColor!.setFromString(dark);
      }

      data
        ..attachmentName = _getString(slotMap, 'attachment')
        ..blendMode = SkeletonJson.blendModeFromString(
            _getString(slotMap, 'blend', 'normal'));
      skeletonData.slots.add(data);
    }
  }

  // IK constraints
  if (root.containsKey('ik')) {
    for (int i = 0; i < root['ik'].length; i++) {
      final dynamic constraintMap = root['ik'][i];
      final IkConstraintData data =
          IkConstraintData(_getString(constraintMap, 'name'))
            ..order = _getInt(constraintMap, 'order', 0);

      for (int j = 0; j < constraintMap['bones'].length; j++) {
        final String boneName = constraintMap['bones'][j];
        final BoneData? bone = skeletonData.findBone(boneName);
        if (bone == null) throw StateError('IK bone not found: ' + boneName);
        data.bones.add(bone);
      }

      final String targetName = _getString(constraintMap, 'target');
      data.target = skeletonData.findBone(targetName);
      if (data.target == null) {
        throw StateError('IK target bone not found: ' + targetName);
      }

      data
        ..bendDirection =
            _getBool(constraintMap, 'bendPositive', true) ? 1 : -1
        ..mix = _getDouble(constraintMap, 'mix', 1.0);

      skeletonData.ikConstraints.add(data);
    }
  }

  // Transform constraints.
  if (root.containsKey('transform')) {
    for (int i = 0; i < root['transform'].length; i++) {
      final dynamic constraintMap = root['transform'][i];
      final TransformConstraintData data =
          TransformConstraintData(_getString(constraintMap, 'name'))
            ..order = _getInt(constraintMap, 'order', 0);

      for (int j = 0; j < constraintMap['bones'].length; j++) {
        final String boneName = constraintMap['bones'][j]!;
        final BoneData? bone = skeletonData.findBone(boneName);
        if (bone == null) {
          throw StateError('Transform constraint bone not found: $boneName');
        }
        data.bones.add(bone);
      }

      final String targetName = _getString(constraintMap, 'target');
      data.target = skeletonData.findBone(targetName);
      if (data.target == null) {
        throw StateError(
            'Transform constraint target bone not found: $targetName');
      }

      data
        ..local = _getBool(constraintMap, 'local', false)
        ..relative = _getBool(constraintMap, 'relative', false)
        ..offsetRotation = _getDouble(constraintMap, 'rotation', 0.0)
        ..offsetX = _getDouble(constraintMap, 'x', 0.0) * scale
        ..offsetY = _getDouble(constraintMap, 'y', 0.0) * scale
        ..offsetScaleX = _getDouble(constraintMap, 'scaleX', 0.0)
        ..offsetScaleY = _getDouble(constraintMap, 'scaleY', 0.0)
        ..offsetShearY = _getDouble(constraintMap, 'shearY', 0.0)
        ..rotateMix = _getDouble(constraintMap, 'rotateMix', 1.0)
        ..translateMix = _getDouble(constraintMap, 'translateMix', 1.0)
        ..scaleMix = _getDouble(constraintMap, 'scaleMix', 1.0)
        ..shearMix = _getDouble(constraintMap, 'shearMix', 1.0);

      skeletonData.transformConstraints.add(data);
    }
  }

  // Path constraints.
  if (root.containsKey('path')) {
    for (int i = 0; i < root['path'].length; i++) {
      final dynamic constraintMap = root['path'][i];
      final PathConstraintData data =
          PathConstraintData(_getString(constraintMap, 'name'))
            ..order = _getInt(constraintMap, 'order', 0);

      for (int j = 0; j < constraintMap['bones'].length; j++) {
        final String boneName = constraintMap['bones'][j]!;
        final BoneData? bone = skeletonData.findBone(boneName);
        if (bone == null) {
          throw StateError('Transform constraint bone not found: $boneName');
        }
        data.bones.add(bone);
      }

      final String targetName = _getString(constraintMap, 'target');
      data.target = skeletonData.findSlot(targetName);
      if (data.target == null) {
        throw StateError('Path target slot not found: $targetName');
      }

      data
        ..positionMode = SkeletonJson.positionModeFromString(
            _getString(constraintMap, 'positionMode', 'percent'))
        ..spacingMode = SkeletonJson.spacingModeFromString(
            _getString(constraintMap, 'spacingMode', 'length'))
        ..rotateMode = SkeletonJson.rotateModeFromString(
            _getString(constraintMap, 'rotateMode', 'tangent'))
        ..offsetRotation = _getDouble(constraintMap, 'rotation', 0.0)
        ..position = _getDouble(constraintMap, 'position', 0.0);
      if (data.positionMode == PositionMode.fixed) {
        data.position = data.position * scale;
      }
      data.spacing = _getDouble(constraintMap, 'spacing', 0.0);
      if (data.spacingMode == SpacingMode.length ||
          data.spacingMode == SpacingMode.fixed) {
        data.spacing = data.spacing * scale;
      }
      data
        ..rotateMix = _getDouble(constraintMap, 'rotateMix', 1.0)
        ..translateMix = _getDouble(constraintMap, 'translateMix', 1.0);

      skeletonData.pathConstraints.add(data);
    }
  }

  // // Skins.
  if (root.containsKey('skins')) {
    dynamic skins = {};
    if (root['skins'] is List) {
      for (dynamic skin in root['skins']) {
        skins[skin['name']] = skin['attachments'];
      }
    } else {
      skins = root['skins'];
    }
    for (String skinName in skins.keys) {
      final dynamic skinMap = skins[skinName];
      final Skin skin = Skin(skinName);
      for (String slotName in skinMap.keys) {
        final int slotIndex = skeletonData.findSlotIndex(slotName);
        if (slotIndex == -1) throw StateError('Slot not found: $slotName');
        final dynamic slotMap = skinMap[slotName];
        for (String entryName in slotMap.keys) {
          final Attachment? attachment = readAttachment(
              slotMap[entryName], skin, slotIndex, entryName, skeletonData);
          if (attachment != null) {
            skin.addAttachment(slotIndex, entryName, attachment);
          }
        }
      }
      skeletonData.skins.add(skin);
      if (skin.name == 'default') skeletonData.defaultSkin = skin;
    }
  }

  // Linked meshes.
  final int n = linkedMeshes.length;
  for (int i = 0; i < n; i++) {
    final LinkedMesh linkedMesh = linkedMeshes[i];
    final Skin? skin = linkedMesh.skin.isEmpty
        ? skeletonData.defaultSkin
        : skeletonData.findSkin(linkedMesh.skin);
    if (skin == null) throw StateError('Skin not found: $linkedMesh.skin');
    final Attachment? parent =
        skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
    if (parent == null) {
      throw StateError('Parent mesh not found: $linkedMesh.parent');
    }
    linkedMesh.mesh.parentMesh = parent as MeshAttachment?;
    linkedMesh.mesh.updateUVs();
  }
  linkedMeshes.length = 0;

  // Events.
  if (root.containsKey('events')) {
    for (String eventName in root['events'].keys) {
      final dynamic eventMap = root['events'][eventName];
      final EventData data = EventData(eventName)
        ..intValue = _getInt(eventMap, 'int')
        ..floatValue = _getDouble(eventMap, 'float')
        ..stringValue = _getString(eventMap, 'string');
      skeletonData.events.add(data);
    }
  }

  // Animations.
  if (root.containsKey('animations')) {
    for (String animationName in root['animations'].keys) {
      final dynamic animationMap = root['animations'][animationName];
      readAnimation(animationMap, animationName, skeletonData);
    }
  }

  return skeletonData;
}