/*
* Copyright (c) 2014 Gwennael Buchet
*
* License/Terms of Use
*
* Permission is hereby granted, free of charge and for the term of intellectual property rights on the Software, to any
* person obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, modify
* and propagate free of charge, anywhere in the world, all or part of the Software subject to the following mandatory
* conditions:
*
* • The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* Any failure to comply with the above shall automatically terminate the license and be construed as a breach of these
* Terms of Use causing significant harm to Gwennael Buchet.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of Gwennael Buchet shall not be used in advertising or otherwise to promote
* the use or other dealings in this Software without prior written authorization from Gwennael Buchet.
*
* These Terms of Use are subject to French law.
*/
/**
* @module
* @class CGSGInterpolatorTCB
* @extends {CGSGInterpolator}
* @constructor
* @author Gwennael Buchet (gwennael.buchet@gmail.com)
*/
var CGSGInterpolatorTCB = CGSGInterpolator.extend(
{
initialize : function() {
},
/**
* @method compute
* @param keys {Array} Array of all the animation keys
* @param steps {Array} Array of steps between 2 keys. steps.length = keys.length - 1.
* @return {Array} Array of {x, y} object corresponding to all the points in the curve
*/
compute : function(keys, steps) {
//TODO : compute TCB from the in and out tangents
var len = keys.length - 1;
var k = new CGSGKeyFrame(len, {x : keys[len].value.x, y : keys[len].value.y});
k.userData = {t : 0, c : 0, b : 0};
keys.push(k);
len = keys.length;
var i;
var values = [];
for (i = 0 ; i < len - 1 ; i++) {
if (i == 0) {
values = values.concat(this._interpolate(
keys[i],
keys[i],
keys[i + 1],
keys[i + 2],
keys[i].userData.t, keys[i].userData.c, keys[i].userData.b,
steps[i]
));
}
else if (i + 2 < len) {
values = values.concat(this._interpolate(
keys[i - 1],
keys[i],
keys[i + 1],
keys[i + 2],
keys[i].userData.t, keys[i].userData.c, keys[i].userData.b,
steps[i]
));
}
else if (i + 1 < len) {
values = values.concat(this._interpolate(
keys[i - 1],
keys[i],
keys[i + 1],
keys[0], //0
keys[i].userData.t, keys[i].userData.c, keys[i].userData.b,
steps[i]
));
}
else {
values = values.concat(this._interpolate(
keys[i - 1],
keys[i],
keys[0], //0
keys[1], //1
keys[i].userData.t, keys[i].userData.c, keys[i].userData.b,
steps[i]
));
}
}
var lk = keys[len - 2];
values.push({x : lk.value.x, y : lk.value.y});
keys.pop();
return values;
},
/**
* @method _interpolate
* @param p1
* @param p2
* @param p3
* @param p4
* @param t
* @param c
* @param b
* @param steps
* @private
* @return {Array}
*/
_interpolate : function(p1, p2, p3, p4, t, c, b, steps) {
var t1 = new CGSGVector2D(p1.value.x, p1.value.y);
var t2 = new CGSGVector2D(p2.value.x, p2.value.y);
var t3 = new CGSGVector2D(p3.value.x, p3.value.y);
var t4 = new CGSGVector2D(p4.value.x, p4.value.y);
var px = p2.value.x, py = p2.value.y;
var s, h1, h2, h3, h4;
var TDix, TDiy, TSix, TSiy, ppx, ppy;
var values = [];
for (var i = 0 ; i < steps ; i++) {
s = i / steps;
h1 = 2 * Math.pow(s, 3.0) - 3 * Math.pow(s, 2.0) + 1;
h2 = -2 * Math.pow(s, 3.0) + 3 * Math.pow(s, 2);
h3 = Math.pow(s, 3.0) - 2 * Math.pow(s, 2.0) + s;
h4 = Math.pow(s, 3.0) - Math.pow(s, 2);
TDix =
(1 - t) * (1 + c) * (1 + b) * (t2.x - t1.x) / 2.0 + (1 - t) * (1 - c) * (1 - b) * (t3.x - t2.x) / 2.0;
TDiy =
(1 - t) * (1 + c) * (1 + b) * (t2.y - t1.y) / 2.0 + (1 - t) * (1 - c) * (1 - b) * (t3.y - t2.y) / 2.0;
TSix =
(1 - t) * (1 - c) * (1 + b) * (t3.x - t2.x) / 2.0 + (1 - t) * (1 + c) * (1 - b) * (t4.x - t3.x) / 2.0;
TSiy =
(1 - t) * (1 - c) * (1 + b) * (t3.y - t2.y) / 2.0 + (1 - t) * (1 + c) * (1 - b) * (t4.y - t3.y) / 2;
ppx = h1 * t2.x + h2 * t3.x + h3 * TDix + h4 * TSix;
ppy = h1 * t2.y + h2 * t3.y + h3 * TDiy + h4 * TSiy;
values.push({x : ppx, y : ppy});
px = ppx;
py = ppy;
}
return values;
}
}
);