animation system updates... still not 100%

beta.r3js.org
-=yb4f310 2017-09-18 15:39:40 +02:00
parent 14df05ab5b
commit 4d7ac34a8a
5 changed files with 205 additions and 86 deletions

View File

@ -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);
}

View File

@ -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
);

View File

@ -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)
);

View File

@ -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.
*/
@ -947,31 +959,58 @@ GameLib.D3.Mesh.prototype.applyPositionRotationScale = function() {
this.instance.geometry.applyMatrix(this.instance.matrix);
this.position.x = 0;
this.position.y = 0;
this.position.z = 0;
this.instance.position.set(0,0,0);
this.position.y = 0;
this.position.z = 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)

View File

@ -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,69 +94,139 @@ 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
}
);
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;
/**
* Apply our position, rotation and scale to the mesh
*/
mesh.applyPositionRotationScale();
}
/**
* Set our target angle value
* Tell our animation component that it is no longer in process...
* @type {boolean}
*/
mesh.animationObject.intermediateAngle = mesh.animationObject.targetAngle;
mesh.animationObject.inProcess = false;
/**
* Update our actual angle
*/
mesh.quaternion.angle = mesh.animationObject.targetAngle;
// if (mesh.animationObject.callbacks.length > 0) {
// var callback = mesh.animationObject.callbacks[0];
// mesh.animationObject.callbacks.splice(0,1);
// callback();
// }
/**
* Update our instance
*/
mesh.updateInstance();
/**
* 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.intermediateAngle = 0;
/**
* Apply our position, rotation and scale to the mesh
*/
mesh.applyPositionRotationScale();
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
}
);