mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-12-25 20:33:50 +01:00
252 lines
5.2 KiB
JavaScript
Executable File
252 lines
5.2 KiB
JavaScript
Executable File
/**
|
|
* @author Tony Parisi / http://www.tonyparisi.com/
|
|
*/
|
|
|
|
THREE.glTFAnimator = ( function () {
|
|
|
|
var animators = [];
|
|
|
|
return {
|
|
add : function(animator)
|
|
{
|
|
animators.push(animator);
|
|
},
|
|
|
|
remove: function(animator)
|
|
{
|
|
|
|
var i = animators.indexOf(animator);
|
|
|
|
if ( i !== -1 ) {
|
|
animators.splice( i, 1 );
|
|
}
|
|
},
|
|
|
|
update : function()
|
|
{
|
|
for (i = 0; i < animators.length; i ++)
|
|
{
|
|
animators[i].update();
|
|
}
|
|
},
|
|
};
|
|
})();
|
|
|
|
// Construction/initialization
|
|
THREE.glTFAnimation = function(interps)
|
|
{
|
|
this.running = false;
|
|
this.loop = false;
|
|
this.duration = 0;
|
|
this.startTime = 0;
|
|
this.interps = [];
|
|
|
|
if (interps)
|
|
{
|
|
this.createInterpolators(interps);
|
|
}
|
|
}
|
|
|
|
THREE.glTFAnimation.prototype.createInterpolators = function(interps)
|
|
{
|
|
var i, len = interps.length;
|
|
for (i = 0; i < len; i ++)
|
|
{
|
|
var interp = new THREE.glTFInterpolator(interps[i]);
|
|
this.interps.push(interp);
|
|
this.duration = Math.max(this.duration, interp.duration);
|
|
}
|
|
}
|
|
|
|
// Start/stop
|
|
THREE.glTFAnimation.prototype.play = function()
|
|
{
|
|
if (this.running)
|
|
return;
|
|
|
|
this.startTime = Date.now();
|
|
this.running = true;
|
|
THREE.glTFAnimator.add(this);
|
|
}
|
|
|
|
THREE.glTFAnimation.prototype.stop = function()
|
|
{
|
|
this.running = false;
|
|
THREE.glTFAnimator.remove(this);
|
|
}
|
|
|
|
// Update - drive key frame evaluation
|
|
THREE.glTFAnimation.prototype.update = function()
|
|
{
|
|
if (!this.running)
|
|
return;
|
|
|
|
var now = Date.now();
|
|
var deltat = (now - this.startTime) / 1000;
|
|
var t = deltat % this.duration;
|
|
var nCycles = Math.floor(deltat / this.duration);
|
|
|
|
if (nCycles >= 1 && !this.loop)
|
|
{
|
|
this.running = false;
|
|
var i, len = this.interps.length;
|
|
for (i = 0; i < len; i ++)
|
|
{
|
|
this.interps[i].interp(this.duration);
|
|
}
|
|
this.stop();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
var i, len = this.interps.length;
|
|
for (i = 0; i < len; i ++)
|
|
{
|
|
this.interps[i].interp(t);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Interpolator class
|
|
//Construction/initialization
|
|
THREE.glTFInterpolator = function(param)
|
|
{
|
|
this.keys = param.keys;
|
|
this.values = param.values;
|
|
this.count = param.count;
|
|
this.type = param.type;
|
|
this.path = param.path;
|
|
this.isRot = false;
|
|
|
|
var node = param.target;
|
|
node.updateMatrix();
|
|
node.matrixAutoUpdate = true;
|
|
this.targetNode = node;
|
|
|
|
switch (param.path) {
|
|
case "translation" :
|
|
this.target = node.position;
|
|
this.originalValue = node.position.clone();
|
|
break;
|
|
case "rotation" :
|
|
this.target = node.quaternion;
|
|
this.originalValue = node.quaternion.clone();
|
|
this.isRot = true;
|
|
break;
|
|
case "scale" :
|
|
this.target = node.scale;
|
|
this.originalValue = node.scale.clone();
|
|
break;
|
|
}
|
|
|
|
this.duration = this.keys[this.count - 1];
|
|
|
|
this.vec1 = new THREE.Vector3;
|
|
this.vec2 = new THREE.Vector3;
|
|
this.vec3 = new THREE.Vector3;
|
|
this.quat1 = new THREE.Quaternion;
|
|
this.quat2 = new THREE.Quaternion;
|
|
this.quat3 = new THREE.Quaternion;
|
|
}
|
|
|
|
//Interpolation and tweening methods
|
|
THREE.glTFInterpolator.prototype.interp = function(t)
|
|
{
|
|
var i, j;
|
|
if (t == this.keys[0])
|
|
{
|
|
if (this.isRot) {
|
|
this.quat3.set(this.values[0], this.values[1], this.values[2], this.values[3]);
|
|
}
|
|
else {
|
|
this.vec3.set(this.values[0], this.values[1], this.values[2]);
|
|
}
|
|
}
|
|
else if (t < this.keys[0])
|
|
{
|
|
if (this.isRot) {
|
|
this.quat1.set(this.originalValue.x,
|
|
this.originalValue.y,
|
|
this.originalValue.z,
|
|
this.originalValue.w);
|
|
this.quat2.set(this.values[0],
|
|
this.values[1],
|
|
this.values[2],
|
|
this.values[3]);
|
|
THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, t / this.keys[0]);
|
|
}
|
|
else {
|
|
this.vec3.set(this.originalValue.x,
|
|
this.originalValue.y,
|
|
this.originalValue.z);
|
|
this.vec2.set(this.values[0],
|
|
this.values[1],
|
|
this.values[2]);
|
|
|
|
this.vec3.lerp(this.vec2, t / this.keys[0]);
|
|
}
|
|
}
|
|
else if (t >= this.keys[this.count - 1])
|
|
{
|
|
if (this.isRot) {
|
|
this.quat3.set(this.values[(this.count - 1) * 4],
|
|
this.values[(this.count - 1) * 4 + 1],
|
|
this.values[(this.count - 1) * 4 + 2],
|
|
this.values[(this.count - 1) * 4 + 3]);
|
|
}
|
|
else {
|
|
this.vec3.set(this.values[(this.count - 1) * 3],
|
|
this.values[(this.count - 1) * 3 + 1],
|
|
this.values[(this.count - 1) * 3 + 2]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < this.count - 1; i ++)
|
|
{
|
|
var key1 = this.keys[i];
|
|
var key2 = this.keys[i + 1];
|
|
|
|
if (t >= key1 && t <= key2)
|
|
{
|
|
if (this.isRot) {
|
|
this.quat1.set(this.values[i * 4],
|
|
this.values[i * 4 + 1],
|
|
this.values[i * 4 + 2],
|
|
this.values[i * 4 + 3]);
|
|
this.quat2.set(this.values[(i + 1) * 4],
|
|
this.values[(i + 1) * 4 + 1],
|
|
this.values[(i + 1) * 4 + 2],
|
|
this.values[(i + 1) * 4 + 3]);
|
|
THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, (t - key1) / (key2 - key1));
|
|
}
|
|
else {
|
|
this.vec3.set(this.values[i * 3],
|
|
this.values[i * 3 + 1],
|
|
this.values[i * 3 + 2]);
|
|
this.vec2.set(this.values[(i + 1) * 3],
|
|
this.values[(i + 1) * 3 + 1],
|
|
this.values[(i + 1) * 3 + 2]);
|
|
|
|
this.vec3.lerp(this.vec2, (t - key1) / (key2 - key1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.target)
|
|
{
|
|
this.copyValue(this.target);
|
|
}
|
|
}
|
|
|
|
THREE.glTFInterpolator.prototype.copyValue = function(target) {
|
|
|
|
if (this.isRot) {
|
|
target.copy(this.quat3);
|
|
}
|
|
else {
|
|
target.copy(this.vec3);
|
|
}
|
|
}
|