2017-09-05 05:22:52 +02:00
|
|
|
/**
|
|
|
|
* System takes care of updating all the entities (based on their component data)
|
|
|
|
* @param apiSystem GameLib.API.System
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.System.Animation = function(
|
|
|
|
apiSystem
|
|
|
|
) {
|
|
|
|
GameLib.System.call(
|
|
|
|
this,
|
|
|
|
apiSystem
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.System.Animation.prototype = Object.create(GameLib.System.prototype);
|
|
|
|
GameLib.System.Animation.prototype.constructor = GameLib.System.Animation;
|
|
|
|
|
|
|
|
GameLib.System.Animation.prototype.start = function() {
|
2017-09-14 05:42:38 +02:00
|
|
|
|
|
|
|
GameLib.System.prototype.start.call(this);
|
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
this.animationEntities = GameLib.EntityManager.Instance.findEntities([GameLib.D3.Animation]);
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
this.animationEntities.map(
|
|
|
|
function(animationEntity) {
|
2017-09-14 05:42:38 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* Get all meshes and all animation components
|
|
|
|
*/
|
|
|
|
var meshComponents = animationEntity.getComponents(GameLib.D3.Mesh);
|
|
|
|
var animationComponents = animationEntity.getComponents(GameLib.D3.Animation);
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
animationComponents.map(function(animation){
|
2017-09-05 05:22:52 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
meshComponents.map(function(mesh){
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
if (animation.rotationSpeed) {
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* Back up the current property descriptor
|
|
|
|
*/
|
|
|
|
mesh.animationObject = {
|
|
|
|
backupAngleDescriptor : Object.getOwnPropertyDescriptor(mesh.quaternion, 'angle'),
|
|
|
|
targetAngle : mesh.quaternion.angle,
|
|
|
|
angleIncrement : true,
|
|
|
|
intermediateAngle : mesh.quaternion.angle,
|
|
|
|
subscription : null
|
|
|
|
};
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
var getIntermediateAngle = function() {
|
|
|
|
return mesh.animationObject.intermediateAngle;
|
|
|
|
};
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
var animateRotation = function(value) {
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
mesh.animationObject.intermediateAngle = value;
|
|
|
|
|
|
|
|
var done = false;
|
|
|
|
|
|
|
|
if (mesh.animationObject.angleIncrement) {
|
|
|
|
/**
|
|
|
|
* We are rotating upwards
|
|
|
|
*/
|
|
|
|
if (value >= mesh.animationObject.targetAngle) {
|
|
|
|
/**
|
|
|
|
* We need to stop
|
|
|
|
*/
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/**
|
|
|
|
* We are rotating downwards
|
|
|
|
*/
|
|
|
|
if (value <= mesh.animationObject.targetAngle) {
|
|
|
|
/**
|
|
|
|
* We need to stop
|
|
|
|
*/
|
|
|
|
done = true;
|
|
|
|
}
|
2017-09-14 10:50:09 +02:00
|
|
|
}
|
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
if (done) {
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* Stop subscribing to before render events
|
|
|
|
*/
|
|
|
|
mesh.animationObject.subscription.remove();
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @type {null}
|
|
|
|
*/
|
|
|
|
mesh.animationObject.subscription = null;
|
2017-09-14 10:50:09 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* Start checking again for animation requests
|
|
|
|
*/
|
|
|
|
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();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var animationCheck = function(value) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if we have work to do
|
|
|
|
*/
|
|
|
|
if (mesh.animationObject.intermediateAngle === value) {
|
|
|
|
/**
|
|
|
|
* Nothing to do
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
} else if (mesh.animationObject.intermediateAngle > value) {
|
|
|
|
/**
|
|
|
|
* We will rotate towards by decrementing
|
|
|
|
*/
|
|
|
|
mesh.animationObject.angleIncrement = false;
|
|
|
|
} else {
|
|
|
|
/**
|
|
|
|
* We will rotate towards by incrementing
|
|
|
|
*/
|
|
|
|
mesh.animationObject.angleIncrement = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We say what our target angle is - when we reach our target angle, we want
|
|
|
|
* to stop our animation
|
|
|
|
*/
|
|
|
|
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}}
|
|
|
|
*/
|
|
|
|
mesh.animationObject.subscription = GameLib.Event.Subscribe(
|
|
|
|
GameLib.Event.BEFORE_RENDER,
|
|
|
|
function(data) {
|
|
|
|
|
|
|
|
var increment = Math.abs(animation.rotationSpeed);
|
|
|
|
|
|
|
|
if (mesh.angleIncrement) {
|
|
|
|
increment *= -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
mesh.quaternion.angle = (data.delta * increment) + mesh.animationObject.intermediateAngle;
|
2017-09-14 05:42:38 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
var backup = mesh.updateRotationFromAxisAngle;
|
2017-09-14 05:42:38 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
mesh.updateRotationFromAxisAngle = true;
|
|
|
|
mesh.updateInstance();
|
|
|
|
mesh.updateRotationFromAxisAngle = backup;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override the property descriptor - to slowly increment the angle, but report back its
|
|
|
|
* target angle as its actual angle.
|
|
|
|
*/
|
|
|
|
Object.defineProperty(
|
|
|
|
mesh.quaternion,
|
|
|
|
'angle',
|
|
|
|
{
|
|
|
|
'get' : getIntermediateAngle,
|
|
|
|
'set' : animationCheck,
|
|
|
|
'configurable' : true
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
2017-09-14 05:42:38 +02:00
|
|
|
};
|
2017-09-05 05:22:52 +02:00
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* Stop Animation System
|
|
|
|
*/
|
2017-09-05 05:22:52 +02:00
|
|
|
GameLib.System.Animation.prototype.stop = function() {
|
2017-09-14 05:42:38 +02:00
|
|
|
|
|
|
|
GameLib.System.prototype.stop.call(this);
|
|
|
|
|
2017-09-17 19:12:45 +02:00
|
|
|
this.animationEntities = GameLib.EntityManager.Instance.findEntities([GameLib.D3.Animation]);
|
|
|
|
|
|
|
|
this.animationEntities.map(
|
|
|
|
function(animationEntity) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all meshes and all animation components
|
|
|
|
*/
|
|
|
|
var meshComponents = animationEntity.getComponents(GameLib.D3.Mesh);
|
|
|
|
var animationComponents = animationEntity.getComponents(GameLib.D3.Animation);
|
|
|
|
|
|
|
|
animationComponents.map(
|
|
|
|
function (animation) {
|
|
|
|
|
|
|
|
meshComponents.map(
|
|
|
|
function (mesh) {
|
|
|
|
|
|
|
|
if (animation.rotationSpeed) {
|
|
|
|
|
|
|
|
if (mesh.animationObject) {
|
|
|
|
|
|
|
|
if (mesh.animationObject.backupAngleDescriptor) {
|
|
|
|
Object.defineProperty(
|
|
|
|
mesh.quaternion,
|
|
|
|
'angle',
|
|
|
|
mesh.animationObject.backupAngleDescriptor
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mesh.animationObject.targetAngle) {
|
|
|
|
mesh.quaternion.angle = mesh.animationObject.targetAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mesh.animationObject.subscription) {
|
|
|
|
mesh.animationObject.subscription.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
delete mesh.animationObject;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
);
|
2017-09-05 05:22:52 +02:00
|
|
|
};
|
|
|
|
|