@awayjs/graphics
Version:
AwayJS graphics classes
133 lines (132 loc) • 6.01 kB
JavaScript
import { __extends } from "tslib";
import { VertexAnimationMode } from './data/VertexAnimationMode';
import { AnimatorBase } from './AnimatorBase';
/**
* Provides an interface for assigning vertex-based animation data sets to entity-based entity objects
* and controlling the various available states of animation through an interative playhead that can be
* automatically updated or manually triggered.
*/
var VertexAnimator = /** @class */ (function (_super) {
__extends(VertexAnimator, _super);
/**
* Creates a new <code>VertexAnimator</code> object.
*
* @param vertexAnimationSet The animation data set containing the vertex animations used by the animator.
*/
function VertexAnimator(vertexAnimationSet) {
var _this = _super.call(this, vertexAnimationSet) || this;
_this._poses = new Array();
_this._weights = new Float32Array([1, 0, 0, 0]);
_this._vertexAnimationSet = vertexAnimationSet;
return _this;
}
/**
* @inheritDoc
*/
VertexAnimator.prototype.clone = function () {
return new VertexAnimator(this._vertexAnimationSet);
};
/**
* Plays a sequence with a given name. If the sequence is not found, it may not be loaded yet, and it will retry every frame.
* @param sequenceName The name of the clip to be played.
*/
VertexAnimator.prototype.play = function (name, transition, offset) {
if (transition === void 0) { transition = null; }
if (offset === void 0) { offset = NaN; }
if (this._pActiveAnimationName == name)
return;
this._pActiveAnimationName = name;
//TODO: implement transitions in vertex animator
if (!this._pAnimationSet.hasAnimation(name))
throw new Error('Animation root node ' + name + ' not found!');
this._pActiveNode = this._pAnimationSet.getAnimation(name);
this._pActiveState = this.getAnimationState(this._pActiveNode);
if (this.updatePosition) {
//update straight away to reset position deltas
this._pActiveState.update(this._pAbsoluteTime);
this._pActiveState.positionDelta;
}
this._activeVertexState = this._pActiveState;
this.start();
//apply a time offset if specified
if (!isNaN(offset))
this.reset(name, offset);
};
/**
* @inheritDoc
*/
VertexAnimator.prototype._pUpdateDeltaTime = function (dt) {
_super.prototype._pUpdateDeltaTime.call(this, dt);
var geometryFlag = false;
if (this._poses[0] != this._activeVertexState.currentElements) {
this._poses[0] = this._activeVertexState.currentElements;
geometryFlag = true;
}
if (this._poses[1] != this._activeVertexState.nextElements)
this._poses[1] = this._activeVertexState.nextElements;
this._weights[0] = 1 - (this._weights[1] = this._activeVertexState.blendWeight);
if (geometryFlag)
this.invalidateElements();
};
/**
* @inheritDoc
*/
VertexAnimator.prototype.setRenderState = function (shader, renderable) {
// todo: add code for when running on cpu
// this type of animation can only be IRenderable
var shape = renderable.shape;
var elements = renderable.stageElements.elements;
// if no poses defined, set temp data
if (!this._poses.length) {
this.setNullPose(shader, elements);
return;
}
var animationRegisterData = shader.animationRegisterData;
var i;
var len = this._vertexAnimationSet.numPoses;
shader.setVertexConstFromArray(animationRegisterData.weightsIndex, this._weights);
if (this._vertexAnimationSet.blendMode == VertexAnimationMode.ABSOLUTE)
i = 1;
else
i = 0;
var stageElements;
var k = 0;
for (; i < len; ++i) {
elements = (this._poses[i] || shape.elements);
stageElements = elements.getAbstraction(shader.stage);
stageElements._indexMappings = shape.elements.getAbstraction(shader.stage).getIndexMappings();
stageElements.activateVertexBufferVO(animationRegisterData.poseIndices[k++], elements.positions);
if (shader.normalDependencies > 0)
stageElements.activateVertexBufferVO(animationRegisterData.poseIndices[k++], elements.normals);
}
};
VertexAnimator.prototype.setNullPose = function (shader, elements) {
var animationRegisterData = shader.animationRegisterData;
shader.setVertexConstFromArray(animationRegisterData.weightsIndex, this._weights);
var stageElements = elements.getAbstraction(shader.stage);
var k = 0;
if (this._vertexAnimationSet.blendMode == VertexAnimationMode.ABSOLUTE) {
var len = this._vertexAnimationSet.numPoses;
for (var i = 1; i < len; ++i) {
stageElements.activateVertexBufferVO(animationRegisterData.poseIndices[k++], elements.positions);
if (shader.normalDependencies > 0)
stageElements.activateVertexBufferVO(animationRegisterData.poseIndices[k++], elements.normals);
}
}
// todo: set temp data for additive?
};
/**
* Verifies if the animation will be used on cpu. Needs to be true for all passes for a material to be able to use it on gpu.
* Needs to be called if gpu code is potentially required.
*/
VertexAnimator.prototype.testGPUCompatibility = function (shader) {
};
VertexAnimator.prototype.getRenderableElements = function (renderState, sourceElements) {
if (this._vertexAnimationSet.blendMode == VertexAnimationMode.ABSOLUTE && this._poses.length)
return this._poses[0] || sourceElements;
//nothing to do here
return sourceElements;
};
return VertexAnimator;
}(AnimatorBase));
export { VertexAnimator };