I’ve modified the animation system to do this in my code, it isn’t possible with the base animation stuff.
I “think” that all you should need to do to include it in your project is to put this code somewhere and then set .startFrame
and .lastFrame
on your animation instance or skeleton (either should be fine).
pc.Skeleton.prototype.addTime = function(delta) {
if (this._animation !== null) {
this.firstFrame = this._animation.firstFrame !== undefined ? this._animation.firstFrame : this.firstFrame
this.lastFrame = this._animation.lastFrame !== undefined ? this._animation.lastFrame : this.lastFrame
this.last
var i;
var node, nodeName;
var keys, interpKey;
var k1, k2, alpha;
var nodes = this._animation._nodes;
var duration = this._animation.duration;
if (this._time === duration && !this.looping) {
return;
}
this._time += delta;
if (this._time > duration) {
this._time = this.looping ? 0.0 : duration;
for (i = 0;i < nodes.length;i++) {
node = nodes[i];
nodeName = node._name;
this._currKeyIndices[nodeName] = 0;
}
} else {
if (this._time < 0) {
this._time = this.looping ? duration : 0.0;
for (i = 0;i < nodes.length;i++) {
node = nodes[i];
nodeName = node._name;
this._currKeyIndices[nodeName] = node._keys.length - 2;
}
}
}
var offset = delta >= 0 ? 1 : -1;
var foundKey;
for (i = 0;i < nodes.length;i++) {
node = nodes[i];
nodeName = node._name;
keys = node._keys;
interpKey = this._interpolatedKeyDict[nodeName];
if(!interpKey) {
console.warn("No key", nodeName)
continue
}
foundKey = false;
const length = this.lastFrame ? (this.lastFrame - this.firstFrame) : keys.length
const start = this.firstFrame || 0
// If there's only a single key, just copy the key to the interpolated key...
const indices = this._currKeyIndices
if (keys.length !== 1) {
let startTime = keys[start].time
for (let currKeyIndex = indices[nodeName] || 0, count = 0, l = length - 1; count < l; count++, currKeyIndex = (currKeyIndex + offset + length) % length) {
k1 = keys[currKeyIndex + start];
k2 = keys[currKeyIndex + 1 + start];
if (k1.time - startTime <= this._time && k2.time-startTime >= this._time) {
alpha = (this._time - k1.time + startTime) / (k2.time - k1.time);
interpKey._pos.lerp(k1.position, k2.position, alpha);
interpKey._quat.slerp(k1.rotation, k2.rotation, alpha);
interpKey._scale.lerp(k1.scale, k2.scale, alpha);
interpKey._written = true;
this._currKeyIndices[nodeName] = currKeyIndex;
foundKey = true;
break;
}
}
}
if (keys.length === 1 || !foundKey && this._time === 0.0 && this.looping) {
interpKey._pos.copy(keys[0 + start].position);
interpKey._quat.copy(keys[0 + start].rotation);
interpKey._scale.copy(keys[0 + start].scale);
interpKey._written = true;
}
}
}
}