Animation.fromFlatbuffer constructor
Builds an Animation from a deserialized flatbuffer animation description.
Channels with missing or malformed keyframe data are skipped with
no error. Node references are resolved against sceneNodes to
recover the target name for each channel's BindKey.
Implementation
factory Animation.fromFlatbuffer(
fb.Animation animation,
List<Node> sceneNodes,
) {
List<AnimationChannel> channels = [];
for (fb.Channel fbChannel in animation.channels!) {
if (fbChannel.node < 0 ||
fbChannel.node >= sceneNodes.length ||
fbChannel.timeline == null) {
continue;
}
final outTimes = fbChannel.timeline!;
AnimationProperty outProperty;
PropertyResolver resolver;
// TODO(bdero): Why are the entries in the keyframe value arrays not
// contiguous in the flatbuffer? We should be able to get rid
// of the subloops below and just memcpy instead.
switch (fbChannel.keyframesType) {
case fb.KeyframesTypeId.TranslationKeyframes:
outProperty = AnimationProperty.translation;
fb.TranslationKeyframes? keyframes =
fbChannel.keyframes as fb.TranslationKeyframes?;
if (keyframes?.values == null) {
continue;
}
List<Vector3> outValues = [];
for (int i = 0; i < keyframes!.values!.length; i++) {
outValues.add(keyframes.values![i].toVector3());
}
resolver = PropertyResolver.makeTranslationTimeline(
outTimes,
outValues,
);
break;
case fb.KeyframesTypeId.RotationKeyframes:
outProperty = AnimationProperty.rotation;
fb.RotationKeyframes? keyframes =
fbChannel.keyframes as fb.RotationKeyframes?;
if (keyframes?.values == null) {
continue;
}
List<Quaternion> outValues = [];
for (int i = 0; i < keyframes!.values!.length; i++) {
outValues.add(keyframes.values![i].toQuaternion());
}
resolver = PropertyResolver.makeRotationTimeline(outTimes, outValues);
break;
case fb.KeyframesTypeId.ScaleKeyframes:
outProperty = AnimationProperty.scale;
fb.ScaleKeyframes? keyframes =
fbChannel.keyframes as fb.ScaleKeyframes?;
if (keyframes?.values == null) {
continue;
}
List<Vector3> outValues = [];
for (int i = 0; i < keyframes!.values!.length; i++) {
outValues.add(keyframes.values![i].toVector3());
}
resolver = PropertyResolver.makeScaleTimeline(outTimes, outValues);
break;
default:
continue;
}
final bindKey = BindKey(
nodeName: sceneNodes[fbChannel.node].name,
property: outProperty,
);
channels.add(AnimationChannel(bindTarget: bindKey, resolver: resolver));
}
return Animation(name: animation.name!.toString(), channels: channels);
}