animation system updates... still not 100%
parent
14df05ab5b
commit
4d7ac34a8a
|
@ -64,7 +64,7 @@ GameLib.Clock.prototype.getDelta = function() {
|
|||
*/
|
||||
|
||||
if (delta > (1 / 30.0)) {
|
||||
console.log('clipped ' + (delta - (1/30.0)) + ' seconds - essentially lost time');
|
||||
// console.log('clipped ' + (delta - (1/30.0)) + ' seconds - essentially lost time');
|
||||
delta = (1 / 30.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* @param translationFn
|
||||
* @param scaleFn
|
||||
* @param blocking
|
||||
* @param applyToMeshWhenDone
|
||||
* @param parentMesh
|
||||
* @param parentEntity
|
||||
* @constructor
|
||||
|
@ -23,6 +24,7 @@ GameLib.D3.API.Animation = function (
|
|||
translationFn,
|
||||
scaleFn,
|
||||
blocking,
|
||||
applyToMeshWhenDone,
|
||||
parentMesh,
|
||||
parentEntity
|
||||
) {
|
||||
|
@ -71,6 +73,11 @@ GameLib.D3.API.Animation = function (
|
|||
}
|
||||
this.blocking = blocking;
|
||||
|
||||
if (GameLib.Utils.UndefinedOrNull(applyToMeshWhenDone)) {
|
||||
applyToMeshWhenDone = true;
|
||||
}
|
||||
this.applyToMeshWhenDone = applyToMeshWhenDone;
|
||||
|
||||
if (GameLib.Utils.UndefinedOrNull(parentMesh)) {
|
||||
parentMesh = null;
|
||||
}
|
||||
|
@ -102,6 +109,7 @@ GameLib.D3.API.Animation.FromObject = function(objectComponent) {
|
|||
objectComponent.translationFn,
|
||||
objectComponent.scaleFn,
|
||||
objectComponent.blocking,
|
||||
objectComponent.applyToMeshWhenDone,
|
||||
objectComponent.parentMesh,
|
||||
objectComponent.parentEntity
|
||||
);
|
||||
|
|
|
@ -31,6 +31,7 @@ GameLib.D3.Animation = function(
|
|||
apiAnimation.translationFn,
|
||||
apiAnimation.scaleFn,
|
||||
apiAnimation.blocking,
|
||||
apiAnimation.applyToMeshWhenDone,
|
||||
apiAnimation.parentMesh,
|
||||
apiAnimation.parentEntity
|
||||
);
|
||||
|
@ -39,6 +40,12 @@ GameLib.D3.Animation = function(
|
|||
|
||||
this.editor = null;
|
||||
|
||||
/**
|
||||
* This indicates whether an animation is currently in process - for blocking to take effect
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.inProcess = false;
|
||||
|
||||
GameLib.Component.call(
|
||||
this,
|
||||
GameLib.Component.COMPONENT_ANIMATION
|
||||
|
@ -159,6 +166,7 @@ GameLib.D3.Animation.prototype.toApiObject = function() {
|
|||
this.translationFn,
|
||||
this.scaleFn,
|
||||
this.blocking,
|
||||
this.applyToMeshWhenDone,
|
||||
GameLib.Utils.IdOrNull(this.parentMesh),
|
||||
GameLib.Utils.IdOrNull(this.parentEntity)
|
||||
);
|
||||
|
|
|
@ -486,15 +486,7 @@ GameLib.D3.Mesh.prototype.updateInstance = function() {
|
|||
}
|
||||
|
||||
if (this.updateRotationFromAxisAngle) {
|
||||
this.quaternion.axis.instance.x = this.quaternion.axis.x;
|
||||
this.quaternion.axis.instance.y = this.quaternion.axis.y;
|
||||
this.quaternion.axis.instance.z = this.quaternion.axis.z;
|
||||
this.quaternion.instance.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
|
||||
this.instance.quaternion.copy(this.quaternion.instance);
|
||||
this.quaternion.x = this.quaternion.instance.x;
|
||||
this.quaternion.y = this.quaternion.instance.y;
|
||||
this.quaternion.z = this.quaternion.instance.z;
|
||||
this.quaternion.w = this.quaternion.instance.w;
|
||||
this.updateInstanceRotationFromAxisAngle();
|
||||
} else {
|
||||
this.instance.quaternion.x = this.quaternion.x;
|
||||
this.instance.quaternion.y = this.quaternion.y;
|
||||
|
@ -809,11 +801,19 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) {
|
|||
instance.position.y = this.position.y;
|
||||
instance.position.z = this.position.z;
|
||||
|
||||
|
||||
instance.quaternion.x = this.quaternion.x;
|
||||
instance.quaternion.y = this.quaternion.y;
|
||||
instance.quaternion.z = this.quaternion.z;
|
||||
instance.quaternion.w = this.quaternion.w;
|
||||
instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
|
||||
instance.quaternion.setFromAxisAngle(
|
||||
new THREE.Vector3(
|
||||
this.quaternion.axis.x,
|
||||
this.quaternion.axis.y,
|
||||
this.quaternion.axis.z
|
||||
),
|
||||
this.quaternion.angle
|
||||
);
|
||||
|
||||
instance.scale.x = this.scale.x;
|
||||
instance.scale.y = this.scale.y;
|
||||
|
@ -937,6 +937,18 @@ GameLib.D3.Mesh.prototype.centerAroundOrigin = function() {
|
|||
this.updateInstance();
|
||||
};
|
||||
|
||||
GameLib.D3.Mesh.prototype.getDistanceFromCenter = function() {
|
||||
var position = this.instance.geometry.center();
|
||||
return new GameLib.Vector3(
|
||||
this.graphics,
|
||||
new GameLib.API.Vector3(
|
||||
position.x,
|
||||
position.y,
|
||||
position.z
|
||||
)
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies position, rotation and scale to the object vertice data, resets scale, rotation and sets position to origin.
|
||||
*/
|
||||
|
@ -949,29 +961,56 @@ GameLib.D3.Mesh.prototype.applyPositionRotationScale = function() {
|
|||
this.position.x = 0;
|
||||
this.position.y = 0;
|
||||
this.position.z = 0;
|
||||
this.instance.position.set(0,0,0);
|
||||
this.updateInstancePosition();
|
||||
|
||||
this.scale.x = 1;
|
||||
this.scale.y = 1;
|
||||
this.scale.z = 1;
|
||||
this.instance.scale.set(1,1,1);
|
||||
|
||||
this.quaternion.axis.x = 0;
|
||||
this.quaternion.axis.y = 0;
|
||||
this.quaternion.axis.z = 0;
|
||||
this.quaternion.axis.w = 1;
|
||||
this.quaternion.angle = 0;
|
||||
this.instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
|
||||
this.quaternion.x = this.instance.quaternion.x;
|
||||
this.quaternion.y = this.instance.quaternion.y;
|
||||
this.quaternion.z = this.instance.quaternion.z;
|
||||
this.quaternion.w = this.instance.quaternion.w;
|
||||
this.updateInstanceRotationFromAxisAngle(
|
||||
new GameLib.Vector3(
|
||||
this.graphics,
|
||||
new GameLib.API.Vector3(
|
||||
0,0,0
|
||||
)
|
||||
),
|
||||
0
|
||||
);
|
||||
|
||||
this.instance.updateMatrix();
|
||||
|
||||
this.updateVerticesFromGeometryInstance(this.instance.geometry);
|
||||
};
|
||||
|
||||
GameLib.D3.Mesh.prototype.updateInstanceRotationFromAxisAngle = function(axis, angle) {
|
||||
|
||||
if (GameLib.Utils.UndefinedOrNull(axis)) {
|
||||
axis = this.quaternion.axis;
|
||||
}
|
||||
|
||||
if (GameLib.Utils.UndefinedOrNull(angle)) {
|
||||
angle = this.quaternion.angle;
|
||||
}
|
||||
|
||||
this.quaternion.axis.instance.x = axis.x;
|
||||
this.quaternion.axis.instance.y = axis.y;
|
||||
this.quaternion.axis.instance.z = axis.z;
|
||||
this.quaternion.instance.setFromAxisAngle(this.quaternion.axis.instance, angle);
|
||||
this.instance.quaternion.copy(this.quaternion.instance);
|
||||
this.quaternion.x = this.quaternion.instance.x;
|
||||
this.quaternion.y = this.quaternion.instance.y;
|
||||
this.quaternion.z = this.quaternion.instance.z;
|
||||
this.quaternion.w = this.quaternion.instance.w;
|
||||
};
|
||||
|
||||
GameLib.D3.Mesh.prototype.updateInstancePosition = function() {
|
||||
this.position.instance.x = this.position.x;
|
||||
this.position.instance.y = this.position.y;
|
||||
this.position.instance.z = this.position.z;
|
||||
this.instance.position.copy(this.position.instance);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets all children components of this Mesh (all linked objects only - no object references i.e. string ids)
|
||||
|
|
|
@ -44,16 +44,29 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
targetAngle : mesh.quaternion.angle,
|
||||
angleIncrement : true,
|
||||
intermediateAngle : mesh.quaternion.angle,
|
||||
subscription : null
|
||||
subscription : null,
|
||||
inProcess : false,
|
||||
blocking : animation.blocking,
|
||||
callbacks : [],
|
||||
storedValues : []
|
||||
};
|
||||
|
||||
var getIntermediateAngle = function() {
|
||||
return mesh.animationObject.intermediateAngle;
|
||||
};
|
||||
|
||||
var getTargetAngle = function() {
|
||||
|
||||
if (mesh.animationObject.storedValues.length > 0) {
|
||||
return mesh.animationObject.storedValues[mesh.animationObject.storedValues.length - 1];
|
||||
}
|
||||
|
||||
return mesh.animationObject.targetAngle;
|
||||
};
|
||||
|
||||
var animateRotation = function(value) {
|
||||
|
||||
mesh.animationObject.intermediateAngle = value;
|
||||
mesh.animationObject.intermediateAngle += value;
|
||||
|
||||
var done = false;
|
||||
|
||||
|
@ -61,7 +74,7 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
/**
|
||||
* We are rotating upwards
|
||||
*/
|
||||
if (value >= mesh.animationObject.targetAngle) {
|
||||
if (mesh.animationObject.intermediateAngle >= mesh.animationObject.targetAngle) {
|
||||
/**
|
||||
* We need to stop
|
||||
*/
|
||||
|
@ -71,7 +84,7 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
/**
|
||||
* We are rotating downwards
|
||||
*/
|
||||
if (value <= mesh.animationObject.targetAngle) {
|
||||
if (mesh.animationObject.intermediateAngle <= mesh.animationObject.targetAngle) {
|
||||
/**
|
||||
* We need to stop
|
||||
*/
|
||||
|
@ -81,49 +94,67 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
|
||||
if (done) {
|
||||
|
||||
/**
|
||||
* We clamp to our target angle
|
||||
*/
|
||||
mesh.animationObject.intermediateAngle = mesh.animationObject.targetAngle;
|
||||
|
||||
/**
|
||||
* We limit our intermediate angle between values of -pi and pi
|
||||
*/
|
||||
while (mesh.animationObject.intermediateAngle > Math.PI) {
|
||||
mesh.animationObject.intermediateAngle -= (Math.PI * 2);
|
||||
}
|
||||
|
||||
while (mesh.animationObject.intermediateAngle < -(Math.PI)) {
|
||||
mesh.animationObject.intermediateAngle += (Math.PI * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* We apply our new intermediate angle to our target
|
||||
*/
|
||||
mesh.animationObject.targetAngle = mesh.animationObject.intermediateAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the actual rotation to the mesh
|
||||
*/
|
||||
mesh.updateInstanceRotationFromAxisAngle(mesh.quaternion.axis, mesh.animationObject.intermediateAngle);
|
||||
|
||||
/**
|
||||
* Check again if we are done, we need to do some additional work -
|
||||
*/
|
||||
if (done) {
|
||||
|
||||
if (!mesh.animationObject.subscription) {
|
||||
var message = 'mesh animation object subscription went missing for ';
|
||||
message += mesh.name + ': ';
|
||||
message += animation.name;
|
||||
console.warn(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop subscribing to before render events
|
||||
*/
|
||||
mesh.animationObject.subscription.remove();
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {null}
|
||||
*/
|
||||
mesh.animationObject.subscription = null;
|
||||
|
||||
/**
|
||||
* Start checking again for animation requests
|
||||
* For some meshes, when we are done with the animation, we want to apply
|
||||
* the current state of the mesh to the object data itself (i.e. update
|
||||
* its vertices etc)
|
||||
*/
|
||||
Object.defineProperty(
|
||||
mesh.quaternion,
|
||||
'angle',
|
||||
{
|
||||
'get' : getIntermediateAngle,
|
||||
'set' : animationCheck,
|
||||
'configurable' : true
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Set our target angle value
|
||||
*/
|
||||
mesh.animationObject.intermediateAngle = mesh.animationObject.targetAngle;
|
||||
|
||||
/**
|
||||
* Update our actual angle
|
||||
*/
|
||||
mesh.quaternion.angle = mesh.animationObject.targetAngle;
|
||||
|
||||
/**
|
||||
* Update our instance
|
||||
*/
|
||||
mesh.updateInstance();
|
||||
|
||||
if (animation.applyToMeshWhenDone) {
|
||||
/**
|
||||
* Now we say that our intermediate angle is zero, because we will apply our rotation
|
||||
* and this will prevent us from re-registering a new 'animationRender' event
|
||||
*/
|
||||
mesh.animationObject.targetAngle = 0;
|
||||
mesh.animationObject.intermediateAngle = 0;
|
||||
|
||||
/**
|
||||
|
@ -131,19 +162,71 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
*/
|
||||
mesh.applyPositionRotationScale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell our animation component that it is no longer in process...
|
||||
* @type {boolean}
|
||||
*/
|
||||
mesh.animationObject.inProcess = false;
|
||||
|
||||
// if (mesh.animationObject.callbacks.length > 0) {
|
||||
// var callback = mesh.animationObject.callbacks[0];
|
||||
// mesh.animationObject.callbacks.splice(0,1);
|
||||
// callback();
|
||||
// }
|
||||
|
||||
mesh.animationObject.storedValues = [];
|
||||
}
|
||||
};
|
||||
|
||||
var animationCheck = function(value) {
|
||||
var setTargetAngle = function(value) {
|
||||
|
||||
/**
|
||||
* Check if we have work to do
|
||||
*/
|
||||
if (mesh.animationObject.intermediateAngle === value) {
|
||||
|
||||
mesh.animationObject.inProcess = false;
|
||||
|
||||
/**
|
||||
* Nothing to do
|
||||
*/
|
||||
return;
|
||||
} else if (mesh.animationObject.intermediateAngle > value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have another animation in process
|
||||
*/
|
||||
if (mesh.animationObject.inProcess && mesh.animationObject.blocking) {
|
||||
|
||||
console.log('another animation is already in process');
|
||||
|
||||
GameLib.Utils.PushUnique(mesh.animationObject.storedValues, value);
|
||||
|
||||
// mesh.animationObject.callbacks.push(
|
||||
// function(__value) {
|
||||
// return function(){
|
||||
// mesh.quaternion.angle = __value;
|
||||
// }
|
||||
// }(value)
|
||||
// );
|
||||
|
||||
/**
|
||||
* Respond that our angle is actually our target angle (it will be that soon)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* We indicate that we now have an animation in process
|
||||
* @type {boolean}
|
||||
*/
|
||||
mesh.animationObject.inProcess = true;
|
||||
|
||||
/**
|
||||
* Ok - all good - lets start the animation
|
||||
*/
|
||||
if (mesh.animationObject.intermediateAngle > value) {
|
||||
/**
|
||||
* We will rotate towards by decrementing
|
||||
*/
|
||||
|
@ -161,19 +244,6 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
*/
|
||||
mesh.animationObject.targetAngle = value;
|
||||
|
||||
/**
|
||||
* Now override the setter again
|
||||
*/
|
||||
Object.defineProperty(
|
||||
mesh.quaternion,
|
||||
'angle',
|
||||
{
|
||||
'get' : getIntermediateAngle,
|
||||
'set' : animateRotation,
|
||||
'configurable' : true
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Now we subscribe to 'before render' events, and slowly increment the value
|
||||
* @type {{fn, remove}}
|
||||
|
@ -184,17 +254,11 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
|
||||
var increment = Math.abs(animation.rotationSpeed);
|
||||
|
||||
if (mesh.angleIncrement) {
|
||||
if (!mesh.animationObject.angleIncrement) {
|
||||
increment *= -1;
|
||||
}
|
||||
|
||||
mesh.quaternion.angle = (data.delta * increment) + mesh.animationObject.intermediateAngle;
|
||||
|
||||
var backup = mesh.updateRotationFromAxisAngle;
|
||||
|
||||
mesh.updateRotationFromAxisAngle = true;
|
||||
mesh.updateInstance();
|
||||
mesh.updateRotationFromAxisAngle = backup;
|
||||
animateRotation(data.delta * increment);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -208,8 +272,8 @@ GameLib.System.Animation.prototype.start = function() {
|
|||
mesh.quaternion,
|
||||
'angle',
|
||||
{
|
||||
'get' : getIntermediateAngle,
|
||||
'set' : animationCheck,
|
||||
'get' : getTargetAngle,
|
||||
'set' : setTargetAngle,
|
||||
'configurable' : true
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue