makeClipAdditive method
dynamic
makeClipAdditive(
- AnimationClip targetClip, {
- int referenceFrame = 0,
- AnimationClip? referenceClip,
- int fps = 30,
Implementation
makeClipAdditive(AnimationClip targetClip,
{int referenceFrame = 0, AnimationClip? referenceClip, int fps = 30}) {
referenceClip ??= targetClip;
if (fps <= 0) fps = 30;
var numTracks = referenceClip.tracks.length;
var referenceTime = referenceFrame / fps;
// Make each track's values relative to the values at the reference frame
for (var i = 0; i < numTracks; ++i) {
var referenceTrack = referenceClip.tracks[i];
var referenceTrackType = referenceTrack.ValueTypeName;
// Skip this track if it's non-numeric
if (referenceTrackType == 'bool' || referenceTrackType == 'string') {
continue;
}
// Find the track in the target clip whose name and type matches the reference track
var targetTrack = targetClip.tracks.firstWhere((track) {
return track.name == referenceTrack.name &&
track.ValueTypeName == referenceTrackType;
});
if (targetTrack == null) continue;
var referenceOffset = 0;
var referenceValueSize = referenceTrack.getValueSize();
print("AnimationUtils isInterpolantFactoryMethodGLTFCubicSpline todo ");
// if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
// referenceOffset = referenceValueSize / 3;
// }
var targetOffset = 0;
var targetValueSize = targetTrack.getValueSize();
print("AnimationUtils isInterpolantFactoryMethodGLTFCubicSpline todo ");
// if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
// targetOffset = targetValueSize / 3;
// }
var lastIndex = referenceTrack.times.length - 1;
var referenceValue;
// Find the value to subtract out of the track
if (referenceTime <= referenceTrack.times[0]) {
// Reference frame is earlier than the first keyframe, so just use the first keyframe
var startIndex = referenceOffset;
var endIndex = referenceValueSize - referenceOffset;
referenceValue = AnimationUtils.arraySlice(
referenceTrack.values, startIndex, endIndex);
} else if (referenceTime >= referenceTrack.times[lastIndex]) {
// Reference frame is after the last keyframe, so just use the last keyframe
int startIndex =
(lastIndex * referenceValueSize + referenceOffset).toInt();
int endIndex =
(startIndex + referenceValueSize - referenceOffset).toInt();
referenceValue = AnimationUtils.arraySlice(
referenceTrack.values, startIndex, endIndex);
} else {
// Interpolate to the reference value
var interpolant = referenceTrack.createInterpolant!();
var startIndex = referenceOffset;
var endIndex = referenceValueSize - referenceOffset;
interpolant.evaluate(referenceTime);
referenceValue = AnimationUtils.arraySlice(
interpolant.resultBuffer, startIndex, endIndex);
}
// Conjugate the quaternion
if (referenceTrackType == 'quaternion') {
var referenceQuat =
Quaternion().fromArray(referenceValue).normalize().conjugate();
referenceQuat.toArray(referenceValue);
}
// Subtract the reference value from all of the track values
var numTimes = targetTrack.times.length;
for (var j = 0; j < numTimes; ++j) {
int valueStart = (j * targetValueSize + targetOffset).toInt();
if (referenceTrackType == 'quaternion') {
// Multiply the conjugate for quaternion track types
Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart,
referenceValue, 0, targetTrack.values, valueStart);
} else {
var valueEnd = targetValueSize - targetOffset * 2;
// Subtract each value for all other numeric track types
for (var k = 0; k < valueEnd; ++k) {
targetTrack.values[valueStart + k] -= referenceValue[k];
}
}
}
}
targetClip.blendMode = AdditiveAnimationBlendMode;
return targetClip;
}