optimize method
dynamic
optimize()
Implementation
optimize() {
// times or values may be shared with other tracks, so overwriting is unsafe
var times = AnimationUtils.arraySlice(this.times),
values = AnimationUtils.arraySlice(this.values),
stride = getValueSize(),
smoothInterpolation = getInterpolation() == InterpolateSmooth,
lastIndex = times.length - 1;
var writeIndex = 1;
for (var i = 1; i < lastIndex; ++i) {
var keep = false;
var time = times[i];
var timeNext = times[i + 1];
// remove adjacent keyframes scheduled at the same time
if (time != timeNext && (i != 1 || time != times[0])) {
if (!smoothInterpolation) {
// remove unnecessary keyframes same as their neighbors
var offset = i * stride,
offsetP = offset - stride,
offsetN = offset + stride;
for (var j = 0; j != stride; ++j) {
var value = values[offset + j];
if (value != values[offsetP + j] || value != values[offsetN + j]) {
keep = true;
break;
}
}
} else {
keep = true;
}
}
// in-place compaction
if (keep) {
if (i != writeIndex) {
times[writeIndex] = times[i];
var readOffset = i * stride, writeOffset = writeIndex * stride;
for (var j = 0; j != stride; ++j) {
values[writeOffset + j] = values[readOffset + j];
}
}
++writeIndex;
}
}
// flush last keyframe (compaction looks ahead)
if (lastIndex > 0) {
times[writeIndex] = times[lastIndex];
for (var readOffset = lastIndex * stride,
writeOffset = writeIndex * stride,
j = 0;
j != stride;
++j) {
values[writeOffset + j] = values[readOffset + j];
}
++writeIndex;
}
if (writeIndex != times.length) {
this.times = AnimationUtils.arraySlice(times, 0, writeIndex);
this.values =
AnimationUtils.arraySlice(values, 0, (writeIndex * stride).toInt());
} else {
this.times = times;
this.values = values;
}
return this;
}