loadAnimation method
dynamic
loadAnimation(
- dynamic animationIndex
Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations @param {number} animationIndex @return {Promise
Implementation
loadAnimation(animationIndex) async {
var json = this.json;
Map<String, dynamic> animationDef = json["animations"][animationIndex];
List<Future> pendingNodes = [];
List<Future> pendingInputAccessors = [];
List<Future> pendingOutputAccessors = [];
List<Future> pendingSamplers = [];
List<Future> pendingTargets = [];
for (var i = 0, il = animationDef["channels"].length; i < il; i++) {
Map<String, dynamic> channel = animationDef["channels"][i];
Map<String, dynamic> sampler =
animationDef["samplers"][channel["sampler"]];
Map<String, dynamic> target = channel["target"];
var name = target["node"] != null
? target["node"]
: target["id"]; // NOTE: target.id is deprecated.
var input = animationDef["parameters"] != null
? animationDef["parameters"][sampler["input"]]
: sampler["input"];
var output = animationDef["parameters"] != null
? animationDef["parameters"][sampler["output"]]
: sampler["output"];
pendingNodes.add(this.getDependency('node', name));
pendingInputAccessors.add(this.getDependency('accessor', input));
pendingOutputAccessors.add(this.getDependency('accessor', output));
pendingSamplers.add(Future.sync(() => sampler));
pendingTargets.add(Future.sync(() => target));
}
final dependencies = await Future.wait([
Future.wait(pendingNodes),
Future.wait(pendingInputAccessors),
Future.wait(pendingOutputAccessors),
Future.wait(pendingSamplers),
Future.wait(pendingTargets)
]);
var nodes = dependencies[0];
var inputAccessors = dependencies[1];
var outputAccessors = dependencies[2];
var samplers = dependencies[3];
var targets = dependencies[4];
List<KeyframeTrack> tracks = [];
for (var i = 0, il = nodes.length; i < il; i++) {
var node = nodes[i];
var inputAccessor = inputAccessors[i];
var outputAccessor = outputAccessors[i];
Map<String, dynamic> sampler = samplers[i];
Map<String, dynamic> target = targets[i];
if (node == null) continue;
node.updateMatrix();
node.matrixAutoUpdate = true;
var typedKeyframeTrack =
TypedKeyframeTrack(PATH_PROPERTIES.getValue(target["path"]));
var targetName = node.name != null ? node.name : node.uuid;
var interpolation = sampler["interpolation"] != null
? INTERPOLATION[sampler["interpolation"]]
: InterpolateLinear;
var targetNames = [];
if (PATH_PROPERTIES.getValue(target["path"]) == PATH_PROPERTIES.weights) {
// Node may be a Group (glTF mesh with several primitives) or a Mesh.
node.traverse((object) {
if (object.morphTargetInfluences != null) {
targetNames.add(object.name != null ? object.name : object.uuid);
}
});
} else {
targetNames.add(targetName);
}
var outputArray = outputAccessor.array;
if (outputAccessor.normalized) {
var scale = getNormalizedComponentScale(outputArray.runtimeType);
var scaled = Float32List(outputArray.length);
for (var j = 0, jl = outputArray.length; j < jl; j++) {
scaled[j] = outputArray[j] * scale;
}
outputArray = scaled;
}
for (var j = 0, jl = targetNames.length; j < jl; j++) {
var track = typedKeyframeTrack.createTrack(
targetNames[j] + '.' + PATH_PROPERTIES.getValue(target["path"]),
inputAccessor.array,
outputArray,
interpolation);
// Override interpolation with custom factory method.
if (sampler["interpolation"] == 'CUBICSPLINE') {
track.createInterpolant = (result) {
// A CUBICSPLINE keyframe in glTF has three output values for each input value,
// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
// must be divided by three to get the interpolant's sampleSize argument.
return GLTFCubicSplineInterpolant(
track.times, track.values, track.getValueSize() / 3, result);
};
// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
// track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
// TODO
print(
"GLTFParser.loadAnimation isInterpolantFactoryMethodGLTFCubicSpline TODO ?? how to handle this case ??? ");
}
tracks.add(track);
}
}
var name = animationDef["name"] != null
? animationDef["name"]
: 'animation_${animationIndex}';
return new AnimationClip(name, -1, tracks);
}