1. 程式人生 > >HREE.JS 根據起始幀將一個AnimationClip物件分割成多個AnimationClip

HREE.JS 根據起始幀將一個AnimationClip物件分割成多個AnimationClip

THREE.JS 根據起始幀將一個AnimationClip物件分割成多個AnimationClip


因為從3dsMax裡面匯出的模型只支援一個動畫,如果需要對多個動畫進行單獨控制的話就必須將其切割成多個AnimationClip物件,其實原理跟陣列擷取是一樣的。


/**
 *根據起始幀將當前動畫切割成多段動畫
 * @param clips 起始幀陣列[[起始幀,結束幀],[起始幀,結束幀]...]
 * @returns {Array} 擷取後的多段動畫
 */
THREE.AnimationClip.prototype.slice = function (clips) {
    
    var animations = [];
    var startTime = 0;
    var scope = this;
    
    clips.forEach(function (clip, index) {

        var tracks = [];
        scope.tracks.forEach(function (track_s) {

            var s = (track_s.constructor == THREE.VectorKeyframeTrack ? 3 : 4)

            //按起始幀擷取關鍵幀
            var times = track_s.times.toArray().concat([]).slice(clip[0], clip[1] + 1);
            var values = track_s.values.toArray().concat([]).slice(clip[0] * s, (clip[1] + 1) * s)

            if (times.length == 0) {
                times.push(0);
                values = track_s.values.toArray().concat([]);
            }

            //減去上一段動畫的結束時間,把起始時間歸零
            times.forEach(function (value, index) {
                times[index] -= startTime;
            });

            var track;
            if (track_s.constructor == THREE.VectorKeyframeTrack)
                track = new THREE.VectorKeyframeTrack(track_s.name, times, values);
            else if (track_s.constructor == THREE.QuaternionKeyframeTrack)
                track = new THREE.QuaternionKeyframeTrack(track_s.name, times, values);

            tracks.push(track);
        });

        var animation = new THREE.AnimationClip('Take_' + index, -1, tracks);
        animations.push(animation);

        startTime = animation.duration;
    });
    return animations;
}
Float32Array.prototype.toArray = function () {
    var array = [];
    for (var i = 0; i < this.length; i++)
        array.push(this[i]);
    return array;
}