buildSkeleton method

Future<Skeleton> buildSkeleton(
  1. dynamic skeletons,
  2. dynamic joints
)

Implementation

Future<Skeleton> buildSkeleton( skeletons, joints ) async{
  final List<Map<String, dynamic>> boneData = [];
  final sortedBoneData = [];

  // a skeleton can have multiple root bones. collada expresses this
  // situtation with multiple "skeleton" tags per controller instance

  for (final skeleton in skeletons) {
    if ( hasNode( skeleton ) ) {
      final root = await getNode( skeleton );
      buildBoneHierarchy( root, joints, boneData );
    }
    else if ( hasVisualScene( skeleton ) ) {
      final visualScene = library['visualScenes']![ skeleton ];
      final children = visualScene.children;

      for (int j = 0; j < children.length; j ++ ) {
        final child = children[ j ];
        if ( child.type == 'JOINT' ) {
          final root = await getNode( child.id );
          buildBoneHierarchy( root, joints, boneData );
        }
      }
    }
    else {
      console.error( 'ColladaLoader: Unable to find root bone of skeleton with ID: $skeleton');
    }
  }

  // sort bone data (the order is defined in the corresponding controller)

  for (final joint in joints) {
    for (int j = 0; j < boneData.length; j ++ ) {
      final data = boneData[ j ];
      if ( data['bone'].name == joint['name'] ) {
        sortedBoneData.add(data);
        data['processed'] = true;
        break;
      }
    }
  }

  // add unprocessed bone data at the end of the list

  for (int i = 0; i < boneData.length; i ++ ) {
    final data = boneData[ i ];
    if ( data['processed'] == false ) {
      sortedBoneData.add( data );
      data['processed'] = true;
    }
  }

  // setup arrays for skeleton creation

  final List<Bone> bones = [];
  final List<Matrix4> boneInverses = [];

  for (int i = 0; i < sortedBoneData.length; i ++ ) {
    final data = sortedBoneData[ i ];
    bones.add( data['bone'] );
    boneInverses.add( data['boneInverse'] );
  }

  return Skeleton( bones, boneInverses );
}