diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 000000000..18d6dbe86
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,136 @@
+//var gulp = require('gulp');
+//var browserify = require('browserify');
+//var source = require('vinyl-source-stream');
+//
+
+
+//var gulp = require('gulp');
+//var glob = require('glob');
+//var browserify = require('browserify');
+//var source = require('vinyl-source-stream');
+//
+//gulp.task('browserify', function(){
+// var testFiles = glob.sync('./build/away/**/*.js');
+// return browserify({
+// debug: true,
+// entries: testFiles,
+// paths: ['./build/away']
+// })
+// .bundle()
+// .pipe(source('away.js'))
+// .pipe(gulp.dest('./build'));
+//});
+//
+//gulp.task('default', ['browserify']);
+
+var concat = require('gulp-concat');
+var gulp = require('gulp');
+var changed = require('gulp-changed');
+var glob = require('glob');
+var path = require('path');
+var browserify = require('browserify');
+var source = require('vinyl-source-stream');
+var map = require('vinyl-map');
+var exorcist = require('exorcist');
+var sourcemaps = require('gulp-sourcemaps');
+
+var typescript = require('gulp-typescript');
+
+//var project = {
+// declaration: true,
+// sourcemap: true,
+// noResolve: false,
+// target: 'ES5',
+// module: 'commonjs'
+//};
+//
+//gulp.task('compile', function() {
+// return gulp.src(['./lib/**/*.ts'])
+// //.pipe(changed('./out/', {extension:'.js', hasChanged: changed.compareLastModifiedTime}))
+// .pipe(tsc(project))
+// .pipe(gulp.dest('out/'));
+//});
+//
+//gulp.task('watch', ['scripts'], function() {
+// gulp.watch('lib/**/*.ts', ['scripts']);
+//});
+
+gulp.task('compile', function() {
+ var tsProject = typescript.createProject({
+ declarationFiles: true,
+ noExternalResolve: true,
+ target: 'ES5',
+ module: 'commonjs'
+ });
+
+ var ambientWrap = map(function(code, filename) {
+ code = code.toString();
+ code = 'declare module "' + path.relative('../', filename.slice(0,-5)) + '" {\n\t'
+ + code.split('declare ').join('').split('\n').join('\n\t') + "\n"
+ + '}';
+ return code;
+ });
+
+ var tsResult = gulp.src(['./lib/**/*.ts', './node_modules/awayjs-**/build/*.d.ts'])
+ .pipe(sourcemaps.init())
+ .pipe(typescript(tsProject));
+
+ tsResult.dts
+ .pipe(ambientWrap)
+ .pipe(concat('awayjs-renderergl.d.ts'))
+ .pipe(gulp.dest('./build'));
+
+ return tsResult.js
+ .pipe(sourcemaps.write())
+ .pipe(gulp.dest('./lib'));
+});
+
+gulp.task('watch', ['package'], function() {
+ gulp.watch('./lib/**/*.ts', ['package']);
+});
+
+gulp.task('package', ['compile'], function(callback){
+ var b = browserify({
+ debug: true,
+ paths: ['../']
+ });
+
+ glob('./node_modules/awayjs-**/lib/**/*.js', {}, function (error, files) {
+ files.forEach(function (file) {
+ b.external(file);
+ });
+ });
+
+ glob('./lib/**/*.js', {}, function (error, files) {
+
+ files.forEach(function (file) {
+ b.require(file, {expose:path.relative('../', file.slice(0,-3))});
+ });
+
+ b.bundle()
+ .pipe(exorcist('./build/awayjs-renderergl.js.map'))
+ .pipe(source('awayjs-renderergl.js'))
+ .pipe(gulp.dest('./build'))
+ .on('end', callback);
+ });
+});
+
+
+gulp.task('tests', function () {
+
+ var tsProject = typescript.createProject({
+ declarationFiles: true,
+ noExternalResolve: true,
+ target: 'ES5',
+ module: 'commonjs'
+ });
+
+ var tsResult = gulp.src(['./tests/**/*.ts', './node_modules/awayjs-**/build/*.d.ts', './build/awayjs-renderergl.d.ts'])
+ //.pipe(changed('./tests', {extension:'.js', hasChanged: changed.compareLastModifiedTime}))
+ .pipe(sourcemaps.init())
+ .pipe(typescript(tsProject));
+
+ return tsResult.js
+ .pipe(sourcemaps.write())
+ .pipe(gulp.dest('./tests'));
+});
\ No newline at end of file
diff --git a/lib/animators/ParticleAnimationSet.js b/lib/animators/ParticleAnimationSet.js
new file mode 100755
index 000000000..1a9d0484f
--- /dev/null
+++ b/lib/animators/ParticleAnimationSet.js
@@ -0,0 +1,301 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+var AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+var AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+var ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+var ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleTimeNode = require("awayjs-renderergl/lib/animators/nodes/ParticleTimeNode");
+/**
+ * The animation data set used by particle-based animators, containing particle animation data.
+ *
+ * @see away.animators.ParticleAnimator
+ */
+var ParticleAnimationSet = (function (_super) {
+ __extends(ParticleAnimationSet, _super);
+ /**
+ * Creates a new ParticleAnimationSet
+ *
+ * @param [optional] usesDuration Defines whether the animation set uses the duration
data in its static properties to determine how long a particle is visible for. Defaults to false.
+ * @param [optional] usesLooping Defines whether the animation set uses a looping timeframe for each particle determined by the startTime
, duration
and delay
data in its static properties function. Defaults to false. Requires usesDuration
to be true.
+ * @param [optional] usesDelay Defines whether the animation set uses the delay
data in its static properties to determine how long a particle is hidden for. Defaults to false. Requires usesLooping
to be true.
+ */
+ function ParticleAnimationSet(usesDuration, usesLooping, usesDelay) {
+ if (usesDuration === void 0) { usesDuration = false; }
+ if (usesLooping === void 0) { usesLooping = false; }
+ if (usesDelay === void 0) { usesDelay = false; }
+ _super.call(this);
+ this._animationSubGeometries = new Object();
+ this._particleNodes = new Array();
+ this._localDynamicNodes = new Array();
+ this._localStaticNodes = new Array();
+ this._totalLenOfOneVertex = 0;
+ //automatically add a particle time node to the set
+ this.addAnimation(this._timeNode = new ParticleTimeNode(usesDuration, usesLooping, usesDelay));
+ }
+ Object.defineProperty(ParticleAnimationSet.prototype, "particleNodes", {
+ /**
+ * Returns a vector of the particle animation nodes contained within the set.
+ */
+ get: function () {
+ return this._particleNodes;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.addAnimation = function (node) {
+ var i /*int*/;
+ var n = node;
+ n._iProcessAnimationSetting(this);
+ if (n.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ n._iDataOffset = this._totalLenOfOneVertex;
+ this._totalLenOfOneVertex += n.dataLength;
+ this._localStaticNodes.push(n);
+ }
+ else if (n.mode == ParticlePropertiesMode.LOCAL_DYNAMIC)
+ this._localDynamicNodes.push(n);
+ for (i = this._particleNodes.length - 1; i >= 0; i--) {
+ if (this._particleNodes[i].priority <= n.priority)
+ break;
+ }
+ this._particleNodes.splice(i + 1, 0, n);
+ _super.prototype.addAnimation.call(this, node);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.activate = function (shaderObject, stage) {
+ // this._iAnimationRegisterCache = pass.animationRegisterCache;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.deactivate = function (shaderObject, stage) {
+ // var context:IContextStageGL = stage.context;
+ // var offset:number /*int*/ = this._iAnimationRegisterCache.vertexAttributesOffset;
+ // var used:number /*int*/ = this._iAnimationRegisterCache.numUsedStreams;
+ // for (var i:number /*int*/ = offset; i < used; i++)
+ // context.setVertexBufferAt(i, null);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.getAGALVertexCode = function (shaderObject) {
+ //grab animationRegisterCache from the materialpassbase or create a new one if the first time
+ this._iAnimationRegisterCache = shaderObject.animationRegisterCache;
+ if (this._iAnimationRegisterCache == null)
+ this._iAnimationRegisterCache = shaderObject.animationRegisterCache = new AnimationRegisterCache(shaderObject.profile);
+ //reset animationRegisterCache
+ this._iAnimationRegisterCache.vertexConstantOffset = shaderObject.numUsedVertexConstants;
+ this._iAnimationRegisterCache.vertexAttributesOffset = shaderObject.numUsedStreams;
+ this._iAnimationRegisterCache.varyingsOffset = shaderObject.numUsedVaryings;
+ this._iAnimationRegisterCache.fragmentConstantOffset = shaderObject.numUsedFragmentConstants;
+ this._iAnimationRegisterCache.hasUVNode = this.hasUVNode;
+ this._iAnimationRegisterCache.needVelocity = this.needVelocity;
+ this._iAnimationRegisterCache.hasBillboard = this.hasBillboard;
+ this._iAnimationRegisterCache.sourceRegisters = shaderObject.animatableAttributes;
+ this._iAnimationRegisterCache.targetRegisters = shaderObject.animationTargetRegisters;
+ this._iAnimationRegisterCache.needFragmentAnimation = shaderObject.usesFragmentAnimation;
+ this._iAnimationRegisterCache.needUVAnimation = !shaderObject.usesUVTransform;
+ this._iAnimationRegisterCache.hasColorAddNode = this.hasColorAddNode;
+ this._iAnimationRegisterCache.hasColorMulNode = this.hasColorMulNode;
+ this._iAnimationRegisterCache.reset();
+ var code = "";
+ code += this._iAnimationRegisterCache.getInitCode();
+ var node;
+ var i /*int*/;
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority < ParticleAnimationSet.POST_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+ code += this._iAnimationRegisterCache.getCombinationCode();
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority >= ParticleAnimationSet.POST_PRIORITY && node.priority < ParticleAnimationSet.COLOR_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+ code += this._iAnimationRegisterCache.initColorRegisters();
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority >= ParticleAnimationSet.COLOR_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+ code += this._iAnimationRegisterCache.getColorPassCode();
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.getAGALUVCode = function (shaderObject) {
+ var code = "";
+ if (this.hasUVNode) {
+ this._iAnimationRegisterCache.setUVSourceAndTarget(shaderObject.uvSource, shaderObject.uvTarget);
+ code += "mov " + this._iAnimationRegisterCache.uvTarget + ".xy," + this._iAnimationRegisterCache.uvAttribute.toString() + "\n";
+ var node;
+ for (var i = 0; i < this._particleNodes.length; i++)
+ node = this._particleNodes[i];
+ code += node.getAGALUVCode(shaderObject, this._iAnimationRegisterCache);
+ code += "mov " + this._iAnimationRegisterCache.uvVar.toString() + "," + this._iAnimationRegisterCache.uvTarget + ".xy\n";
+ }
+ else
+ code += "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.getAGALFragmentCode = function (shaderObject, shadedTarget) {
+ return this._iAnimationRegisterCache.getColorCombinationCode(shadedTarget);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.doneAGALCode = function (shaderObject) {
+ this._iAnimationRegisterCache.setDataLength();
+ //set vertexZeroConst,vertexOneConst,vertexTwoConst
+ this._iAnimationRegisterCache.setVertexConst(this._iAnimationRegisterCache.vertexZeroConst.index, 0, 1, 2, 0);
+ };
+ Object.defineProperty(ParticleAnimationSet.prototype, "usesCPU", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimationSet.prototype.cancelGPUCompatibility = function () {
+ };
+ ParticleAnimationSet.prototype.dispose = function () {
+ for (var key in this._animationSubGeometries)
+ this._animationSubGeometries[key].dispose();
+ _super.prototype.dispose.call(this);
+ };
+ ParticleAnimationSet.prototype.getAnimationSubGeometry = function (subMesh) {
+ var mesh = subMesh.parentMesh;
+ var animationSubGeometry = (mesh.shareAnimationGeometry) ? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+ if (animationSubGeometry)
+ return animationSubGeometry;
+ this._iGenerateAnimationSubGeometries(mesh);
+ return (mesh.shareAnimationGeometry) ? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+ };
+ /** @private */
+ ParticleAnimationSet.prototype._iGenerateAnimationSubGeometries = function (mesh) {
+ if (this.initParticleFunc == null)
+ throw (new Error("no initParticleFunc set"));
+ var geometry = mesh.geometry;
+ if (!geometry)
+ throw (new Error("Particle animation can only be performed on a ParticleGeometry object"));
+ var i /*int*/, j /*int*/, k /*int*/;
+ var animationSubGeometry;
+ var newAnimationSubGeometry = false;
+ var subGeometry;
+ var subMesh;
+ var localNode;
+ for (i = 0; i < mesh.subMeshes.length; i++) {
+ subMesh = mesh.subMeshes[i];
+ subGeometry = subMesh.subGeometry;
+ if (mesh.shareAnimationGeometry) {
+ animationSubGeometry = this._animationSubGeometries[subGeometry.id];
+ if (animationSubGeometry)
+ continue;
+ }
+ animationSubGeometry = new AnimationSubGeometry();
+ if (mesh.shareAnimationGeometry)
+ this._animationSubGeometries[subGeometry.id] = animationSubGeometry;
+ else
+ this._animationSubGeometries[subMesh.id] = animationSubGeometry;
+ newAnimationSubGeometry = true;
+ //create the vertexData vector that will be used for local node data
+ animationSubGeometry.createVertexData(subGeometry.numVertices, this._totalLenOfOneVertex);
+ }
+ if (!newAnimationSubGeometry)
+ return;
+ var particles = geometry.particles;
+ var particlesLength = particles.length;
+ var numParticles = geometry.numParticles;
+ var particleProperties = new ParticleProperties();
+ var particle;
+ var oneDataLen /*int*/;
+ var oneDataOffset /*int*/;
+ var counterForVertex /*int*/;
+ var counterForOneData /*int*/;
+ var oneData;
+ var numVertices /*uint*/;
+ var vertexData;
+ var vertexLength /*uint*/;
+ var startingOffset /*uint*/;
+ var vertexOffset /*uint*/;
+ //default values for particle param
+ particleProperties.total = numParticles;
+ particleProperties.startTime = 0;
+ particleProperties.duration = 1000;
+ particleProperties.delay = 0.1;
+ i = 0;
+ j = 0;
+ while (i < numParticles) {
+ particleProperties.index = i;
+ //call the init on the particle parameters
+ this.initParticleFunc.call(this.initParticleScope, particleProperties);
+ for (k = 0; k < this._localStaticNodes.length; k++)
+ this._localStaticNodes[k]._iGeneratePropertyOfOneParticle(particleProperties);
+ while (j < particlesLength && (particle = particles[j]).particleIndex == i) {
+ for (k = 0; k < mesh.subMeshes.length; k++) {
+ subMesh = mesh.subMeshes[k];
+ if (subMesh.subGeometry == particle.subGeometry) {
+ animationSubGeometry = (mesh.shareAnimationGeometry) ? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+ break;
+ }
+ }
+ numVertices = particle.numVertices;
+ vertexData = animationSubGeometry.vertexData;
+ vertexLength = numVertices * this._totalLenOfOneVertex;
+ startingOffset = animationSubGeometry.numProcessedVertices * this._totalLenOfOneVertex;
+ for (k = 0; k < this._localStaticNodes.length; k++) {
+ localNode = this._localStaticNodes[k];
+ oneData = localNode.oneData;
+ oneDataLen = localNode.dataLength;
+ oneDataOffset = startingOffset + localNode._iDataOffset;
+ for (counterForVertex = 0; counterForVertex < vertexLength; counterForVertex += this._totalLenOfOneVertex) {
+ vertexOffset = oneDataOffset + counterForVertex;
+ for (counterForOneData = 0; counterForOneData < oneDataLen; counterForOneData++)
+ vertexData[vertexOffset + counterForOneData] = oneData[counterForOneData];
+ }
+ }
+ //store particle properties if they need to be retreived for dynamic local nodes
+ if (this._localDynamicNodes.length)
+ animationSubGeometry.animationParticles.push(new ParticleAnimationData(i, particleProperties.startTime, particleProperties.duration, particleProperties.delay, particle));
+ animationSubGeometry.numProcessedVertices += numVertices;
+ //next index
+ j++;
+ }
+ //next particle
+ i++;
+ }
+ };
+ /**
+ * Property used by particle nodes that require compilation at the end of the shader
+ */
+ ParticleAnimationSet.POST_PRIORITY = 9;
+ /**
+ * Property used by particle nodes that require color compilation
+ */
+ ParticleAnimationSet.COLOR_PRIORITY = 18;
+ return ParticleAnimationSet;
+})(AnimationSetBase);
+module.exports = ParticleAnimationSet;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9wYXJ0aWNsZWFuaW1hdGlvbnNldC50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUFuaW1hdGlvblNldCIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmNvbnN0cnVjdG9yIiwiUGFydGljbGVBbmltYXRpb25TZXQucGFydGljbGVOb2RlcyIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmFkZEFuaW1hdGlvbiIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmFjdGl2YXRlIiwiUGFydGljbGVBbmltYXRpb25TZXQuZGVhY3RpdmF0ZSIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVBbmltYXRpb25TZXQuZ2V0QUdBTFVWQ29kZSIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmdldEFHQUxGcmFnbWVudENvZGUiLCJQYXJ0aWNsZUFuaW1hdGlvblNldC5kb25lQUdBTENvZGUiLCJQYXJ0aWNsZUFuaW1hdGlvblNldC51c2VzQ1BVIiwiUGFydGljbGVBbmltYXRpb25TZXQuY2FuY2VsR1BVQ29tcGF0aWJpbGl0eSIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0LmRpc3Bvc2UiLCJQYXJ0aWNsZUFuaW1hdGlvblNldC5nZXRBbmltYXRpb25TdWJHZW9tZXRyeSIsIlBhcnRpY2xlQW5pbWF0aW9uU2V0Ll9pR2VuZXJhdGVBbmltYXRpb25TdWJHZW9tZXRyaWVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLGdCQUFnQixXQUFlLCtDQUErQyxDQUFDLENBQUM7QUFFdkYsSUFBTyxzQkFBc0IsV0FBYSwwREFBMEQsQ0FBQyxDQUFDO0FBSXRHLElBQU8sb0JBQW9CLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUN0RyxJQUFPLHFCQUFxQixXQUFhLDREQUE0RCxDQUFDLENBQUM7QUFDdkcsSUFBTyxrQkFBa0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBQ2xHLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUd6RyxJ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O1FBQ3pEQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO1FBQy9EQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO1FBQy9EQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLGVBQWVBLEdBQUdBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDbEZBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsZUFBZUEsR0FBR0EsWUFBWUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQTtRQUN0RkEsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxxQkFBcUJBLEdBQUdBLFlBQVlBLENBQUNBLHFCQUFxQkEsQ0FBQ0E7UUFDekZBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsZUFBZUEsR0FBR0EsQ0FBQ0EsWUFBWUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDOUVBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDckVBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDckVBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0E7UUFFdENBLElBQUlBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBRXJCQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLFdBQVdBLEVBQUVBLENBQUNBO1FBRXBEQSxJQUFJQSxJQUFxQkEsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBRXJCQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUNqREEsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDOUJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLG9CQUFvQkEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7Z0JBQ3REQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFlBQVlBLEVBQUVBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsQ0FBQ0E7UUFDOUVBLENBQUNBO1FBRURBLElBQUlBLElBQUlBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxDQUFDQTtRQUUzREEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFDakRBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzlCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxJQUFJQSxvQkFBb0JBLENBQUNBLGFBQWFBLElBQUlBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLG9CQUFvQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0E7Z0JBQzlHQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFlBQVlBLEVBQUVBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsQ0FBQ0E7UUFDOUVBLENBQUNBO1FBRURBLElBQUlBLElBQUlBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxDQUFDQTtRQUUzREEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEs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SUFBSUEscUJBQXFCQSxDQUFDQSxDQUFDQSxFQUFFQSxrQkFBa0JBLENBQUNBLFNBQVNBLEVBQUVBLGtCQUFrQkEsQ0FBQ0EsUUFBUUEsRUFBRUEsa0JBQWtCQSxDQUFDQSxLQUFLQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFFM0tBLG9CQUFvQkEsQ0FBQ0Esb0JBQW9CQSxJQUFJQSxXQUFXQSxDQUFDQTtnQkFFekRBLEFBQ0FBLFlBRFlBO2dCQUNaQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUNMQSxDQUFDQTtZQUVEQSxBQUNBQSxlQURlQTtZQUNmQSxDQUFDQSxFQUFFQSxDQUFDQTtRQUNMQSxDQUFDQTtJQUNGQSxDQUFDQTtJQXpYRGQ7O09BRUdBO0lBQ1dBLGtDQUFhQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFFL0NBOztPQUVHQTtJQUNXQSxtQ0FBY0EsR0FBa0JBLEVBQUVBLENBQUNBO0lBa1hsREEsMkJBQUNBO0FBQURBLENBbFlBLEFBa1lDQSxFQWxZa0MsZ0JBQWdCLEVBa1lsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSUFuaW1hdGlvblNldFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL0lBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgQW5pbWF0aW9uTm9kZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9hbmltYXRvcnMvbm9kZXMvQW5pbWF0aW9uTm9kZUJhc2VcIik7XG5pbXBvcnQgSVN1Yk1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvSVN1Yk1lc2hcIik7XG5pbXBvcnQgU3ViR2VvbWV0cnlCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvU3ViR2VvbWV0cnlCYXNlXCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5cbmltcG9ydCBBbmltYXRpb25TZXRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0aW9uU2V0QmFzZVwiKTtcbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5cbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uRGF0YVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZUFuaW1hdGlvbkRhdGFcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZURhdGFcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVEYXRhXCIpO1xuaW1wb3J0IFBhcnRpY2xlTm9kZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU5vZGVCYXNlXCIpO1xuaW1wb3J0IFBhcnRpY2xlVGltZU5vZGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVRpbWVOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlR2VvbWV0cnlcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2NvcmUvYmFzZS9QYXJ0aWNsZUdlb21ldHJ5XCIpO1xuXG4vKipcbiAqIFRoZSBhbmltYXRpb24gZGF0YSBzZXQgdXNlZCBieSBwYXJ0aWNsZS1iYXNlZCBhbmltYXRvcnMsIGNvbnRhaW5pbmcgcGFydGljbGUgYW5pbWF0aW9uIGRhdGEuXG4gKlxuICogQHNlZSBhd2F5LmFuaW1hdG9ycy5QYXJ0aWNsZUFuaW1hdG9yXG4gKi9cbmNsYXNzIFBhcnRpY2xlQW5pbWF0aW9uU2V0IGV4dGVuZHMgQW5pbWF0aW9uU2V0QmFzZSBpbXBsZW1lbnRzIElBbmltYXRpb25TZXRcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTtcblxuXHQvL2FsbCBvdGhlciBub2RlcyBkZXBlbmRlbnQgb24gaXRcblx0cHJpdmF0ZSBfdGltZU5vZGU6UGFydGljbGVUaW1lTm9kZTtcblxuXHQvKipcblx0ICogUHJvcGVydHkgdXNlZCBieSBwYXJ0aWNsZSBub2RlcyB0aGF0IHJlcXVpcmUgY29tcGlsYXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgc2hhZGVyXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIFBPU1RfUFJJT1JJVFk6bnVtYmVyIC8qaW50Ki8gPSA5O1xuXG5cdC8qKlxuXHQgKiBQcm9wZXJ0eSB1c2VkIGJ5IHBhcnRpY2xlIG5vZGVzIHRoYXQgcmVxdWlyZSBjb2xvciBjb21waWxhdGlvblxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBDT0xPUl9QUklPUklUWTpudW1iZXIgLyppbnQqLyA9IDE4O1xuXG5cdHByaXZhdGUgX2FuaW1hdGlvblN1Ykdlb21ldHJpZXM6T2JqZWN0ID0gbmV3IE9iamVjdCgpO1xuXHRwcml2YXRlIF9wYXJ0aWNsZU5vZGVzOkFycmF5PFBhcnRpY2xlTm9kZUJhc2U+ID0gbmV3IEFycmF5PFBhcnRpY2xlTm9kZUJhc2U+KCk7XG5cdHByaXZhdGUgX2xvY2FsRHluYW1pY05vZGVzOkFycmF5PFBhcnRpY2xlTm9kZUJhc2U+ID0gbmV3IEFycmF5PFBhcnRpY2xlTm9kZUJhc2U+KCk7XG5cdHByaXZhdGUgX2xvY2FsU3RhdGljTm9kZXM6QXJyYXk8UGFydGljbGVOb2RlQmFzZT4gPSBuZXcgQXJyYXk8UGFydGljbGVOb2RlQmFzZT4oKTtcblx0cHJpdmF0ZSBfdG90YWxMZW5PZk9uZVZlcnRleDpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0Ly9zZXQgdHJ1ZSBpZiBoYXMgYW4gbm9kZSB3aGljaCB3aWxsIGNoYW5nZSBVVlxuXHRwdWJsaWMgaGFzVVZOb2RlOmJvb2xlYW47XG5cdC8vc2V0IGlmIHRoZSBvdGhlciBub2RlcyBuZWVkIHRvIGFjY2VzcyB0aGUgdmVsb2NpdHlcblx0cHVibGljIG5lZWRWZWxvY2l0eTpib29sZWFuO1xuXHQvL3NldCBpZiBoYXMgYSBiaWxsYm9hcmQgbm9kZS5cblx0cHVibGljIGhhc0JpbGxib2FyZDpib29sZWFuO1xuXHQvL3NldCBpZiBoYXMgYW4gbm9kZSB3aGljaCB3aWxsIGFwcGx5IGNvbG9yIG11bHRpcGxlIG9wZXJhdGlvblxuXHRwdWJsaWMgaGFzQ29sb3JNdWxOb2RlOmJvb2xlYW47XG5cdC8vc2V0IGlmIGhhcyBhbiBub2RlIHdoaWNoIHdpbGwgYXBwbHkgY29sb3IgYWRkIG9wZXJhdGlvblxuXHRwdWJsaWMgaGFzQ29sb3JBZGROb2RlOmJvb2xlYW47XG5cblx0LyoqXG5cdCAqIEluaXRpYWxpc2VyIGZ1bmN0aW9uIGZvciBzdGF0aWMgcGFydGljbGUgcHJvcGVydGllcy4gTmVlZHMgdG8gcmVmZXJlbmNlIGEgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm1hdFxuXHQgKlxuXHQgKiA8Y29kZT5cblx0ICogaW5pdFBhcnRpY2xlRnVuYyhwcm9wOlBhcnRpY2xlUHJvcGVydGllcylcblx0ICoge1xuXHQgKiBcdFx0Ly9jb2RlIGZvciBzZXR0aW5ncyBsb2NhbCBwcm9wZXJ0aWVzXG5cdCAqIH1cblx0ICogPC9jb2RlPlxuXHQgKlxuXHQgKiBBc2lkZSBmcm9tIHNldHRpbmcgYW55IHByb3BlcnRpZXMgcmVxdWlyZWQgaW4gcGFydGljbGUgYW5pbWF0aW9uIG5vZGVzIHVzaW5nIGxvY2FsIHN0YXRpYyBwcm9wZXJ0aWVzLCB0aGUgaW5pdFBhcnRpY2xlRnVuYyBmdW5jdGlvblxuXHQgKiBpcyByZXF1aXJlZCB0byB0aW1lIG5vZGUgcmVxdWlyZW1lbnRzIGFzIHRoZXkgbWF5IGJlIG5lZWRlZC4gVGhlc2UgcHJvcGVydGllcyBvbiB0aGUgUGFydGljbGVQcm9wZXJ0aWVzIG9iamVjdCBjYW4gaW5jbHVkZVxuXHQgKiA8Y29kZT5zdGFydFRpbWU8L2NvZGU+LCA8Y29kZT5kdXJhdGlvbjwvY29kZT4gYW5kIDxjb2RlPmRlbGF5PC9jb2RlPi4gVGhlIHVzZSBvZiB0aGVzZSBwcm9wZXJ0aWVzIGlzIGRldGVybWluZWQgYnkgdGhlIHNldHRpbmdcblx0ICogYXJndW1lbnRzIHBhc3NlZCBpbiB0aGUgY29uc3RydWN0b3Igb2YgdGhlIHBhcnRpY2xlIGFuaW1hdGlvbiBzZXQuIEJ5IGRlZmF1bHQsIG9ubHkgdGhlIDxjb2RlPnN0YXJ0VGltZTwvY29kZT4gcHJvcGVydHkgaXMgcmVxdWlyZWQuXG5cdCAqL1xuXHRwdWJsaWMgaW5pdFBhcnRpY2xlRnVuYzpGdW5jdGlvbjtcblxuXHQvKipcblx0ICogSW5pdGlhbGlzZXIgZnVuY3Rpb24gc2NvcGUgZm9yIHN0YXRpYyBwYXJ0aWNsZSBwcm9wZXJ0aWVzXG5cdCAqL1xuXHRwdWJsaWMgaW5pdFBhcnRpY2xlU2NvcGU6T2JqZWN0O1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlQW5pbWF0aW9uU2V0PC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzRHVyYXRpb24gICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBhbmltYXRpb24gc2V0IHVzZXMgdGhlIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBkYXRhIGluIGl0cyBzdGF0aWMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgaG93IGxvbmcgYSBwYXJ0aWNsZSBpcyB2aXNpYmxlIGZvci4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNMb29waW5nICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIGFuaW1hdGlvbiBzZXQgdXNlcyBhIGxvb3BpbmcgdGltZWZyYW1lIGZvciBlYWNoIHBhcnRpY2xlIGRldGVybWluZWQgYnkgdGhlIDxjb2RlPnN0YXJ0VGltZTwvY29kZT4sIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBhbmQgPGNvZGU+ZGVsYXk8L2NvZGU+IGRhdGEgaW4gaXRzIHN0YXRpYyBwcm9wZXJ0aWVzIGZ1bmN0aW9uLiBEZWZhdWx0cyB0byBmYWxzZS4gUmVxdWlyZXMgPGNvZGU+dXNlc0R1cmF0aW9uPC9jb2RlPiB0byBiZSB0cnVlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzRGVsYXkgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBhbmltYXRpb24gc2V0IHVzZXMgdGhlIDxjb2RlPmRlbGF5PC9jb2RlPiBkYXRhIGluIGl0cyBzdGF0aWMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgaG93IGxvbmcgYSBwYXJ0aWNsZSBpcyBoaWRkZW4gZm9yLiBEZWZhdWx0cyB0byBmYWxzZS4gUmVxdWlyZXMgPGNvZGU+dXNlc0xvb3Bpbmc8L2NvZGU+IHRvIGJlIHRydWUuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih1c2VzRHVyYXRpb246Ym9vbGVhbiA9IGZhbHNlLCB1c2VzTG9vcGluZzpib29sZWFuID0gZmFsc2UsIHVzZXNEZWxheTpib29sZWFuID0gZmFsc2UpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0Ly9hdXRvbWF0aWNhbGx5IGFkZCBhIHBhcnRpY2xlIHRpbWUgbm9kZSB0byB0aGUgc2V0XG5cdFx0dGhpcy5hZGRBbmltYXRpb24odGhpcy5fdGltZU5vZGUgPSBuZXcgUGFydGljbGVUaW1lTm9kZSh1c2VzRHVyYXRpb24sIHVzZXNMb29waW5nLCB1c2VzRGVsYXkpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgdmVjdG9yIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZXMgY29udGFpbmVkIHdpdGhpbiB0aGUgc2V0LlxuXHQgKi9cblx0cHVibGljIGdldCBwYXJ0aWNsZU5vZGVzKCk6QXJyYXk8UGFydGljbGVOb2RlQmFzZT5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9wYXJ0aWNsZU5vZGVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgYWRkQW5pbWF0aW9uKG5vZGU6QW5pbWF0aW9uTm9kZUJhc2UpXG5cdHtcblx0XHR2YXIgaTpudW1iZXIgLyppbnQqLztcblx0XHR2YXIgbjpQYXJ0aWNsZU5vZGVCYXNlID0gPFBhcnRpY2xlTm9kZUJhc2U+IG5vZGU7XG5cdFx0bi5faVByb2Nlc3NBbmltYXRpb25TZXR0aW5nKHRoaXMpO1xuXHRcdGlmIChuLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpIHtcblx0XHRcdG4uX2lEYXRhT2Zmc2V0ID0gdGhpcy5fdG90YWxMZW5PZk9uZVZlcnRleDtcblx0XHRcdHRoaXMuX3RvdGFsTGVuT2ZPbmVWZXJ0ZXggKz0gbi5kYXRhTGVuZ3RoO1xuXHRcdFx0dGhpcy5fbG9jYWxTdGF0aWNOb2Rlcy5wdXNoKG4pO1xuXHRcdH0gZWxzZSBpZiAobi5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfRFlOQU1JQylcblx0XHRcdHRoaXMuX2xvY2FsRHluYW1pY05vZGVzLnB1c2gobik7XG5cblx0XHRmb3IgKGkgPSB0aGlzLl9wYXJ0aWNsZU5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0XHRpZiAodGhpcy5fcGFydGljbGVOb2Rlc1tpXS5wcmlvcml0eSA8PSBuLnByaW9yaXR5KVxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHR0aGlzLl9wYXJ0aWNsZU5vZGVzLnNwbGljZShpICsgMSwgMCwgbik7XG5cblx0XHRzdXBlci5hZGRBbmltYXRpb24obm9kZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBhY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc3RhZ2U6U3RhZ2UpXG5cdHtcbi8vXHRcdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUgPSBwYXNzLmFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkZWFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBzdGFnZTpTdGFnZSlcblx0e1xuLy9cdFx0XHR2YXIgY29udGV4dDpJQ29udGV4dFN0YWdlR0wgPSA8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0O1xuLy9cdFx0XHR2YXIgb2Zmc2V0Om51bWJlciAvKmludCovID0gdGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4QXR0cmlidXRlc09mZnNldDtcbi8vXHRcdFx0dmFyIHVzZWQ6bnVtYmVyIC8qaW50Ki8gPSB0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5udW1Vc2VkU3RyZWFtcztcbi8vXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IG9mZnNldDsgaSA8IHVzZWQ7IGkrKylcbi8vXHRcdFx0XHRjb250ZXh0LnNldFZlcnRleEJ1ZmZlckF0KGksIG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UpOnN0cmluZ1xuXHR7XG5cdFx0Ly9ncmFiIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUgZnJvbSB0aGUgbWF0ZXJpYWxwYXNzYmFzZSBvciBjcmVhdGUgYSBuZXcgb25lIGlmIHRoZSBmaXJzdCB0aW1lXG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUgPSBzaGFkZXJPYmplY3QuYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTtcblxuXHRcdGlmICh0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSA9PSBudWxsKVxuXHRcdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUgPSBzaGFkZXJPYmplY3QuYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSA9IG5ldyBBbmltYXRpb25SZWdpc3RlckNhY2hlKHNoYWRlck9iamVjdC5wcm9maWxlKTtcblxuXHRcdC8vcmVzZXQgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVxuXHRcdHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleENvbnN0YW50T2Zmc2V0ID0gc2hhZGVyT2JqZWN0Lm51bVVzZWRWZXJ0ZXhDb25zdGFudHM7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4QXR0cmlidXRlc09mZnNldCA9IHNoYWRlck9iamVjdC5udW1Vc2VkU3RyZWFtcztcblx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52YXJ5aW5nc09mZnNldCA9IHNoYWRlck9iamVjdC5udW1Vc2VkVmFyeWluZ3M7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZnJhZ21lbnRDb25zdGFudE9mZnNldCA9IHNoYWRlck9iamVjdC5udW1Vc2VkRnJhZ21lbnRDb25zdGFudHM7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuaGFzVVZOb2RlID0gdGhpcy5oYXNVVk5vZGU7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFZlbG9jaXR5ID0gdGhpcy5uZWVkVmVsb2NpdHk7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuaGFzQmlsbGJvYXJkID0gdGhpcy5oYXNCaWxsYm9hcmQ7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc291cmNlUmVnaXN0ZXJzID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzO1xuXHRcdHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnRhcmdldFJlZ2lzdGVycyA9IHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnM7XG5cdFx0dGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZEZyYWdtZW50QW5pbWF0aW9uID0gc2hhZGVyT2JqZWN0LnVzZXNGcmFnbWVudEFuaW1hdGlvbjtcblx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5uZWVkVVZBbmltYXRpb24gPSAhc2hhZGVyT2JqZWN0LnVzZXNVVlRyYW5zZm9ybTtcblx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5oYXNDb2xvckFkZE5vZGUgPSB0aGlzLmhhc0NvbG9yQWRkTm9kZTtcblx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5oYXNDb2xvck11bE5vZGUgPSB0aGlzLmhhc0NvbG9yTXVsTm9kZTtcblx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZXNldCgpO1xuXG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblxuXHRcdGNvZGUgKz0gdGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0SW5pdENvZGUoKTtcblxuXHRcdHZhciBub2RlOlBhcnRpY2xlTm9kZUJhc2U7XG5cdFx0dmFyIGk6bnVtYmVyIC8qaW50Ki87XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgdGhpcy5fcGFydGljbGVOb2Rlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0bm9kZSA9IHRoaXMuX3BhcnRpY2xlTm9kZXNbaV07XG5cdFx0XHRpZiAobm9kZS5wcmlvcml0eSA8IFBhcnRpY2xlQW5pbWF0aW9uU2V0LlBPU1RfUFJJT1JJVFkpXG5cdFx0XHRcdGNvZGUgKz0gbm9kZS5nZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3QsIHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlKTtcblx0XHR9XG5cblx0XHRjb2RlICs9IHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLmdldENvbWJpbmF0aW9uQ29kZSgpO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHRoaXMuX3BhcnRpY2xlTm9kZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG5vZGUgPSB0aGlzLl9wYXJ0aWNsZU5vZGVzW2ldO1xuXHRcdFx0aWYgKG5vZGUucHJpb3JpdHkgPj0gUGFydGljbGVBbmltYXRpb25TZXQuUE9TVF9QUklPUklUWSAmJiBub2RlLnByaW9yaXR5IDwgUGFydGljbGVBbmltYXRpb25TZXQuQ09MT1JfUFJJT1JJVFkpXG5cdFx0XHRcdGNvZGUgKz0gbm9kZS5nZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3QsIHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlKTtcblx0XHR9XG5cblx0XHRjb2RlICs9IHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLmluaXRDb2xvclJlZ2lzdGVycygpO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHRoaXMuX3BhcnRpY2xlTm9kZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG5vZGUgPSB0aGlzLl9wYXJ0aWNsZU5vZGVzW2ldO1xuXHRcdFx0aWYgKG5vZGUucHJpb3JpdHkgPj0gUGFydGljbGVBbmltYXRpb25TZXQuQ09MT1JfUFJJT1JJVFkpXG5cdFx0XHRcdGNvZGUgKz0gbm9kZS5nZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3QsIHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlKTtcblx0XHR9XG5cdFx0Y29kZSArPSB0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRDb2xvclBhc3NDb2RlKCk7XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVVZDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0aWYgKHRoaXMuaGFzVVZOb2RlKSB7XG5cdFx0XHR0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRVVlNvdXJjZUFuZFRhcmdldChzaGFkZXJPYmplY3QudXZTb3VyY2UsIHNoYWRlck9iamVjdC51dlRhcmdldCk7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudXZUYXJnZXQgKyBcIi54eSxcIiArIHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnV2QXR0cmlidXRlLnRvU3RyaW5nKCkgKyBcIlxcblwiO1xuXHRcdFx0dmFyIG5vZGU6UGFydGljbGVOb2RlQmFzZTtcblx0XHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IHRoaXMuX3BhcnRpY2xlTm9kZXMubGVuZ3RoOyBpKyspXG5cdFx0XHRcdG5vZGUgPSB0aGlzLl9wYXJ0aWNsZU5vZGVzW2ldO1xuXHRcdFx0XHRjb2RlICs9IG5vZGUuZ2V0QUdBTFVWQ29kZShzaGFkZXJPYmplY3QsIHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlKTtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS51dlZhci50b1N0cmluZygpICsgXCIsXCIgKyB0aGlzLl9pQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS51dlRhcmdldCArIFwiLnh5XFxuXCI7XG5cdFx0fSBlbHNlXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgc2hhZGVyT2JqZWN0LnV2VGFyZ2V0ICsgXCIsXCIgKyBzaGFkZXJPYmplY3QudXZTb3VyY2UgKyBcIlxcblwiO1xuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc2hhZGVkVGFyZ2V0OnN0cmluZyk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0Q29sb3JDb21iaW5hdGlvbkNvZGUoc2hhZGVkVGFyZ2V0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRvbmVBR0FMQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSlcblx0e1xuXHRcdHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnNldERhdGFMZW5ndGgoKTtcblxuXHRcdC8vc2V0IHZlcnRleFplcm9Db25zdCx2ZXJ0ZXhPbmVDb25zdCx2ZXJ0ZXhUd29Db25zdFxuXHRcdHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KHRoaXMuX2lBbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdC5pbmRleCwgMCwgMSwgMiwgMCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXQgdXNlc0NQVSgpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGNhbmNlbEdQVUNvbXBhdGliaWxpdHkoKVxuXHR7XG5cblx0fVxuXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdGZvciAodmFyIGtleSBpbiB0aGlzLl9hbmltYXRpb25TdWJHZW9tZXRyaWVzKVxuXHRcdFx0KDxBbmltYXRpb25TdWJHZW9tZXRyeT4gdGhpcy5fYW5pbWF0aW9uU3ViR2VvbWV0cmllc1trZXldKS5kaXNwb3NlKCk7XG5cblx0XHRzdXBlci5kaXNwb3NlKCk7XG5cdH1cblxuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3ViR2VvbWV0cnkoc3ViTWVzaDpJU3ViTWVzaClcblx0e1xuXHRcdHZhciBtZXNoOk1lc2ggPSBzdWJNZXNoLnBhcmVudE1lc2g7XG5cdFx0dmFyIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5ID0gKG1lc2guc2hhcmVBbmltYXRpb25HZW9tZXRyeSk/IHRoaXMuX2FuaW1hdGlvblN1Ykdlb21ldHJpZXNbc3ViTWVzaC5zdWJHZW9tZXRyeS5pZF0gOiB0aGlzLl9hbmltYXRpb25TdWJHZW9tZXRyaWVzW3N1Yk1lc2guaWRdO1xuXG5cdFx0aWYgKGFuaW1hdGlvblN1Ykdlb21ldHJ5KVxuXHRcdFx0cmV0dXJuIGFuaW1hdGlvblN1Ykdlb21ldHJ5O1xuXG5cdFx0dGhpcy5faUdlbmVyYXRlQW5pbWF0aW9uU3ViR2VvbWV0cmllcyhtZXNoKTtcblxuXHRcdHJldHVybiAobWVzaC5zaGFyZUFuaW1hdGlvbkdlb21ldHJ5KT8gdGhpcy5fYW5pbWF0aW9uU3ViR2VvbWV0cmllc1tzdWJNZXNoLnN1Ykdlb21ldHJ5LmlkXSA6IHRoaXMuX2FuaW1hdGlvblN1Ykdlb21ldHJpZXNbc3ViTWVzaC5pZF07XG5cdH1cblxuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZUFuaW1hdGlvblN1Ykdlb21ldHJpZXMobWVzaDpNZXNoKVxuXHR7XG5cdFx0aWYgKHRoaXMuaW5pdFBhcnRpY2xlRnVuYyA9PSBudWxsKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwibm8gaW5pdFBhcnRpY2xlRnVuYyBzZXRcIikpO1xuXG5cdFx0dmFyIGdlb21ldHJ5OlBhcnRpY2xlR2VvbWV0cnkgPSA8UGFydGljbGVHZW9tZXRyeT4gbWVzaC5nZW9tZXRyeTtcblxuXHRcdGlmICghZ2VvbWV0cnkpXG5cdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJQYXJ0aWNsZSBhbmltYXRpb24gY2FuIG9ubHkgYmUgcGVyZm9ybWVkIG9uIGEgUGFydGljbGVHZW9tZXRyeSBvYmplY3RcIikpO1xuXG5cdFx0dmFyIGk6bnVtYmVyIC8qaW50Ki8sIGo6bnVtYmVyIC8qaW50Ki8sIGs6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5O1xuXHRcdHZhciBuZXdBbmltYXRpb25TdWJHZW9tZXRyeTpib29sZWFuID0gZmFsc2U7XG5cdFx0dmFyIHN1Ykdlb21ldHJ5OlN1Ykdlb21ldHJ5QmFzZTtcblx0XHR2YXIgc3ViTWVzaDpJU3ViTWVzaDtcblx0XHR2YXIgbG9jYWxOb2RlOlBhcnRpY2xlTm9kZUJhc2U7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgbWVzaC5zdWJNZXNoZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHN1Yk1lc2ggPSBtZXNoLnN1Yk1lc2hlc1tpXTtcblx0XHRcdHN1Ykdlb21ldHJ5ID0gc3ViTWVzaC5zdWJHZW9tZXRyeTtcblx0XHRcdGlmIChtZXNoLnNoYXJlQW5pbWF0aW9uR2VvbWV0cnkpIHtcblx0XHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkgPSB0aGlzLl9hbmltYXRpb25TdWJHZW9tZXRyaWVzW3N1Ykdlb21ldHJ5LmlkXTtcblxuXHRcdFx0XHRpZiAoYW5pbWF0aW9uU3ViR2VvbWV0cnkpXG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5ID0gbmV3IEFuaW1hdGlvblN1Ykdlb21ldHJ5KCk7XG5cblx0XHRcdGlmIChtZXNoLnNoYXJlQW5pbWF0aW9uR2VvbWV0cnkpXG5cdFx0XHRcdHRoaXMuX2FuaW1hdGlvblN1Ykdlb21ldHJpZXNbc3ViR2VvbWV0cnkuaWRdID0gYW5pbWF0aW9uU3ViR2VvbWV0cnk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHRoaXMuX2FuaW1hdGlvblN1Ykdlb21ldHJpZXNbc3ViTWVzaC5pZF0gPSBhbmltYXRpb25TdWJHZW9tZXRyeTtcblxuXHRcdFx0bmV3QW5pbWF0aW9uU3ViR2VvbWV0cnkgPSB0cnVlO1xuXG5cdFx0XHQvL2NyZWF0ZSB0aGUgdmVydGV4RGF0YSB2ZWN0b3IgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIGxvY2FsIG5vZGUgZGF0YVxuXHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuY3JlYXRlVmVydGV4RGF0YShzdWJHZW9tZXRyeS5udW1WZXJ0aWNlcywgdGhpcy5fdG90YWxMZW5PZk9uZVZlcnRleCk7XG5cdFx0fVxuXG5cdFx0aWYgKCFuZXdBbmltYXRpb25TdWJHZW9tZXRyeSlcblx0XHRcdHJldHVybjtcblxuXHRcdHZhciBwYXJ0aWNsZXM6QXJyYXk8UGFydGljbGVEYXRhPiA9IGdlb21ldHJ5LnBhcnRpY2xlcztcblx0XHR2YXIgcGFydGljbGVzTGVuZ3RoOm51bWJlciAvKnVpbnQqLyA9IHBhcnRpY2xlcy5sZW5ndGg7XG5cdFx0dmFyIG51bVBhcnRpY2xlczpudW1iZXIgLyp1aW50Ki8gPSBnZW9tZXRyeS5udW1QYXJ0aWNsZXM7XG5cdFx0dmFyIHBhcnRpY2xlUHJvcGVydGllczpQYXJ0aWNsZVByb3BlcnRpZXMgPSBuZXcgUGFydGljbGVQcm9wZXJ0aWVzKCk7XG5cdFx0dmFyIHBhcnRpY2xlOlBhcnRpY2xlRGF0YTtcblxuXHRcdHZhciBvbmVEYXRhTGVuOm51bWJlciAvKmludCovO1xuXHRcdHZhciBvbmVEYXRhT2Zmc2V0Om51bWJlciAvKmludCovO1xuXHRcdHZhciBjb3VudGVyRm9yVmVydGV4Om51bWJlciAvKmludCovO1xuXHRcdHZhciBjb3VudGVyRm9yT25lRGF0YTpudW1iZXIgLyppbnQqLztcblx0XHR2YXIgb25lRGF0YTpBcnJheTxudW1iZXI+O1xuXHRcdHZhciBudW1WZXJ0aWNlczpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIHZlcnRleERhdGE6QXJyYXk8bnVtYmVyPjtcblx0XHR2YXIgdmVydGV4TGVuZ3RoOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgc3RhcnRpbmdPZmZzZXQ6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciB2ZXJ0ZXhPZmZzZXQ6bnVtYmVyIC8qdWludCovO1xuXG5cdFx0Ly9kZWZhdWx0IHZhbHVlcyBmb3IgcGFydGljbGUgcGFyYW1cblx0XHRwYXJ0aWNsZVByb3BlcnRpZXMudG90YWwgPSBudW1QYXJ0aWNsZXM7XG5cdFx0cGFydGljbGVQcm9wZXJ0aWVzLnN0YXJ0VGltZSA9IDA7XG5cdFx0cGFydGljbGVQcm9wZXJ0aWVzLmR1cmF0aW9uID0gMTAwMDtcblx0XHRwYXJ0aWNsZVByb3BlcnRpZXMuZGVsYXkgPSAwLjE7XG5cblx0XHRpID0gMDtcblx0XHRqID0gMDtcblx0XHR3aGlsZSAoaSA8IG51bVBhcnRpY2xlcykge1xuXHRcdFx0cGFydGljbGVQcm9wZXJ0aWVzLmluZGV4ID0gaTtcblxuXHRcdFx0Ly9jYWxsIHRoZSBpbml0IG9uIHRoZSBwYXJ0aWNsZSBwYXJhbWV0ZXJzXG5cdFx0XHR0aGlzLmluaXRQYXJ0aWNsZUZ1bmMuY2FsbCh0aGlzLmluaXRQYXJ0aWNsZVNjb3BlLCBwYXJ0aWNsZVByb3BlcnRpZXMpO1xuXG5cdFx0XHQvL2NyZWF0ZSB0aGUgbmV4dCBzZXQgb2Ygbm9kZSBwcm9wZXJ0aWVzIGZvciB0aGUgcGFydGljbGVcblx0XHRcdGZvciAoayA9IDA7IGsgPCB0aGlzLl9sb2NhbFN0YXRpY05vZGVzLmxlbmd0aDsgaysrKVxuXHRcdFx0XHR0aGlzLl9sb2NhbFN0YXRpY05vZGVzW2tdLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUocGFydGljbGVQcm9wZXJ0aWVzKTtcblxuXHRcdFx0Ly9sb29wIHRocm91Z2ggYWxsIHBhcnRpY2xlIGRhdGEgZm9yIHRoZSBjdXJlbnQgcGFydGljbGVcblx0XHRcdHdoaWxlIChqIDwgcGFydGljbGVzTGVuZ3RoICYmIChwYXJ0aWNsZSA9IHBhcnRpY2xlc1tqXSkucGFydGljbGVJbmRleCA9PSBpKSB7XG5cdFx0XHRcdC8vZmluZCB0aGUgdGFyZ2V0IGFuaW1hdGlvblN1Ykdlb21ldHJ5XG5cdFx0XHRcdGZvciAoayA9IDA7IGsgPCBtZXNoLnN1Yk1lc2hlcy5sZW5ndGg7IGsrKykge1xuXHRcdFx0XHRcdHN1Yk1lc2ggPSBtZXNoLnN1Yk1lc2hlc1trXTtcblx0XHRcdFx0XHRpZiAoc3ViTWVzaC5zdWJHZW9tZXRyeSA9PSBwYXJ0aWNsZS5zdWJHZW9tZXRyeSkge1xuXHRcdFx0XHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkgPSAobWVzaC5zaGFyZUFuaW1hdGlvbkdlb21ldHJ5KT8gdGhpcy5fYW5pbWF0aW9uU3ViR2VvbWV0cmllc1tzdWJNZXNoLnN1Ykdlb21ldHJ5LmlkXSA6IHRoaXMuX2FuaW1hdGlvblN1Ykdlb21ldHJpZXNbc3ViTWVzaC5pZF07XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0bnVtVmVydGljZXMgPSBwYXJ0aWNsZS5udW1WZXJ0aWNlcztcblx0XHRcdFx0dmVydGV4RGF0YSA9IGFuaW1hdGlvblN1Ykdlb21ldHJ5LnZlcnRleERhdGE7XG5cdFx0XHRcdHZlcnRleExlbmd0aCA9IG51bVZlcnRpY2VzKnRoaXMuX3RvdGFsTGVuT2ZPbmVWZXJ0ZXg7XG5cdFx0XHRcdHN0YXJ0aW5nT2Zmc2V0ID0gYW5pbWF0aW9uU3ViR2VvbWV0cnkubnVtUHJvY2Vzc2VkVmVydGljZXMqdGhpcy5fdG90YWxMZW5PZk9uZVZlcnRleDtcblxuXHRcdFx0XHQvL2xvb3AgdGhyb3VnaCBlYWNoIHN0YXRpYyBsb2NhbCBub2RlIGluIHRoZSBhbmltYXRpb24gc2V0XG5cdFx0XHRcdGZvciAoayA9IDA7IGsgPCB0aGlzLl9sb2NhbFN0YXRpY05vZGVzLmxlbmd0aDsgaysrKSB7XG5cdFx0XHRcdFx0bG9jYWxOb2RlID0gdGhpcy5fbG9jYWxTdGF0aWNOb2Rlc1trXTtcblx0XHRcdFx0XHRvbmVEYXRhID0gbG9jYWxOb2RlLm9uZURhdGE7XG5cdFx0XHRcdFx0b25lRGF0YUxlbiA9IGxvY2FsTm9kZS5kYXRhTGVuZ3RoO1xuXHRcdFx0XHRcdG9uZURhdGFPZmZzZXQgPSBzdGFydGluZ09mZnNldCArIGxvY2FsTm9kZS5faURhdGFPZmZzZXQ7XG5cblx0XHRcdFx0XHQvL2xvb3AgdGhyb3VnaCBlYWNoIHZlcnRleCBzZXQgaW4gdGhlIHZlcnRleCBkYXRhXG5cdFx0XHRcdFx0Zm9yIChjb3VudGVyRm9yVmVydGV4ID0gMDsgY291bnRlckZvclZlcnRleCA8IHZlcnRleExlbmd0aDsgY291bnRlckZvclZlcnRleCArPSB0aGlzLl90b3RhbExlbk9mT25lVmVydGV4KSB7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhPZmZzZXQgPSBvbmVEYXRhT2Zmc2V0ICsgY291bnRlckZvclZlcnRleDtcblxuXHRcdFx0XHRcdFx0Ly9hZGQgdGhlIGRhdGEgZm9yIHRoZSBsb2NhbCBub2RlIHRvIHRoZSB2ZXJ0ZXggZGF0YVxuXHRcdFx0XHRcdFx0Zm9yIChjb3VudGVyRm9yT25lRGF0YSA9IDA7IGNvdW50ZXJGb3JPbmVEYXRhIDwgb25lRGF0YUxlbjsgY291bnRlckZvck9uZURhdGErKylcblx0XHRcdFx0XHRcdFx0dmVydGV4RGF0YVt2ZXJ0ZXhPZmZzZXQgKyBjb3VudGVyRm9yT25lRGF0YV0gPSBvbmVEYXRhW2NvdW50ZXJGb3JPbmVEYXRhXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vc3RvcmUgcGFydGljbGUgcHJvcGVydGllcyBpZiB0aGV5IG5lZWQgdG8gYmUgcmV0cmVpdmVkIGZvciBkeW5hbWljIGxvY2FsIG5vZGVzXG5cdFx0XHRcdGlmICh0aGlzLl9sb2NhbER5bmFtaWNOb2Rlcy5sZW5ndGgpXG5cdFx0XHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuYW5pbWF0aW9uUGFydGljbGVzLnB1c2gobmV3IFBhcnRpY2xlQW5pbWF0aW9uRGF0YShpLCBwYXJ0aWNsZVByb3BlcnRpZXMuc3RhcnRUaW1lLCBwYXJ0aWNsZVByb3BlcnRpZXMuZHVyYXRpb24sIHBhcnRpY2xlUHJvcGVydGllcy5kZWxheSwgcGFydGljbGUpKTtcblxuXHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5udW1Qcm9jZXNzZWRWZXJ0aWNlcyArPSBudW1WZXJ0aWNlcztcblxuXHRcdFx0XHQvL25leHQgaW5kZXhcblx0XHRcdFx0aisrO1xuXHRcdFx0fVxuXG5cdFx0XHQvL25leHQgcGFydGljbGVcblx0XHRcdGkrKztcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVBbmltYXRpb25TZXQ7Il19
\ No newline at end of file
diff --git a/lib/animators/ParticleAnimationSet.ts b/lib/animators/ParticleAnimationSet.ts
new file mode 100644
index 000000000..d4d51f476
--- /dev/null
+++ b/lib/animators/ParticleAnimationSet.ts
@@ -0,0 +1,415 @@
+import IAnimationSet = require("awayjs-core/lib/animators/IAnimationSet");
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+import ISubMesh = require("awayjs-core/lib/core/base/ISubMesh");
+import SubGeometryBase = require("awayjs-core/lib/core/base/SubGeometryBase");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+
+import AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleData = require("awayjs-renderergl/lib/animators/data/ParticleData");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleTimeNode = require("awayjs-renderergl/lib/animators/nodes/ParticleTimeNode");
+import ParticleGeometry = require("awayjs-renderergl/lib/core/base/ParticleGeometry");
+
+/**
+ * The animation data set used by particle-based animators, containing particle animation data.
+ *
+ * @see away.animators.ParticleAnimator
+ */
+class ParticleAnimationSet extends AnimationSetBase implements IAnimationSet
+{
+ /** @private */
+ public _iAnimationRegisterCache:AnimationRegisterCache;
+
+ //all other nodes dependent on it
+ private _timeNode:ParticleTimeNode;
+
+ /**
+ * Property used by particle nodes that require compilation at the end of the shader
+ */
+ public static POST_PRIORITY:number /*int*/ = 9;
+
+ /**
+ * Property used by particle nodes that require color compilation
+ */
+ public static COLOR_PRIORITY:number /*int*/ = 18;
+
+ private _animationSubGeometries:Object = new Object();
+ private _particleNodes:Array = new Array();
+ private _localDynamicNodes:Array = new Array();
+ private _localStaticNodes:Array = new Array();
+ private _totalLenOfOneVertex:number /*int*/ = 0;
+
+ //set true if has an node which will change UV
+ public hasUVNode:boolean;
+ //set if the other nodes need to access the velocity
+ public needVelocity:boolean;
+ //set if has a billboard node.
+ public hasBillboard:boolean;
+ //set if has an node which will apply color multiple operation
+ public hasColorMulNode:boolean;
+ //set if has an node which will apply color add operation
+ public hasColorAddNode:boolean;
+
+ /**
+ * Initialiser function for static particle properties. Needs to reference a with the following format
+ *
+ *
+ * initParticleFunc(prop:ParticleProperties)
+ * {
+ * //code for settings local properties
+ * }
+ *
+ *
+ * Aside from setting any properties required in particle animation nodes using local static properties, the initParticleFunc function
+ * is required to time node requirements as they may be needed. These properties on the ParticleProperties object can include
+ * startTime
, duration
and delay
. The use of these properties is determined by the setting
+ * arguments passed in the constructor of the particle animation set. By default, only the startTime
property is required.
+ */
+ public initParticleFunc:Function;
+
+ /**
+ * Initialiser function scope for static particle properties
+ */
+ public initParticleScope:Object;
+
+ /**
+ * Creates a new ParticleAnimationSet
+ *
+ * @param [optional] usesDuration Defines whether the animation set uses the duration
data in its static properties to determine how long a particle is visible for. Defaults to false.
+ * @param [optional] usesLooping Defines whether the animation set uses a looping timeframe for each particle determined by the startTime
, duration
and delay
data in its static properties function. Defaults to false. Requires usesDuration
to be true.
+ * @param [optional] usesDelay Defines whether the animation set uses the delay
data in its static properties to determine how long a particle is hidden for. Defaults to false. Requires usesLooping
to be true.
+ */
+ constructor(usesDuration:boolean = false, usesLooping:boolean = false, usesDelay:boolean = false)
+ {
+ super();
+
+ //automatically add a particle time node to the set
+ this.addAnimation(this._timeNode = new ParticleTimeNode(usesDuration, usesLooping, usesDelay));
+ }
+
+ /**
+ * Returns a vector of the particle animation nodes contained within the set.
+ */
+ public get particleNodes():Array
+ {
+ return this._particleNodes;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public addAnimation(node:AnimationNodeBase)
+ {
+ var i:number /*int*/;
+ var n:ParticleNodeBase = node;
+ n._iProcessAnimationSetting(this);
+ if (n.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ n._iDataOffset = this._totalLenOfOneVertex;
+ this._totalLenOfOneVertex += n.dataLength;
+ this._localStaticNodes.push(n);
+ } else if (n.mode == ParticlePropertiesMode.LOCAL_DYNAMIC)
+ this._localDynamicNodes.push(n);
+
+ for (i = this._particleNodes.length - 1; i >= 0; i--) {
+ if (this._particleNodes[i].priority <= n.priority)
+ break;
+ }
+
+ this._particleNodes.splice(i + 1, 0, n);
+
+ super.addAnimation(node);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public activate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+// this._iAnimationRegisterCache = pass.animationRegisterCache;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public deactivate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+// var context:IContextStageGL = stage.context;
+// var offset:number /*int*/ = this._iAnimationRegisterCache.vertexAttributesOffset;
+// var used:number /*int*/ = this._iAnimationRegisterCache.numUsedStreams;
+// for (var i:number /*int*/ = offset; i < used; i++)
+// context.setVertexBufferAt(i, null);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase):string
+ {
+ //grab animationRegisterCache from the materialpassbase or create a new one if the first time
+ this._iAnimationRegisterCache = shaderObject.animationRegisterCache;
+
+ if (this._iAnimationRegisterCache == null)
+ this._iAnimationRegisterCache = shaderObject.animationRegisterCache = new AnimationRegisterCache(shaderObject.profile);
+
+ //reset animationRegisterCache
+ this._iAnimationRegisterCache.vertexConstantOffset = shaderObject.numUsedVertexConstants;
+ this._iAnimationRegisterCache.vertexAttributesOffset = shaderObject.numUsedStreams;
+ this._iAnimationRegisterCache.varyingsOffset = shaderObject.numUsedVaryings;
+ this._iAnimationRegisterCache.fragmentConstantOffset = shaderObject.numUsedFragmentConstants;
+ this._iAnimationRegisterCache.hasUVNode = this.hasUVNode;
+ this._iAnimationRegisterCache.needVelocity = this.needVelocity;
+ this._iAnimationRegisterCache.hasBillboard = this.hasBillboard;
+ this._iAnimationRegisterCache.sourceRegisters = shaderObject.animatableAttributes;
+ this._iAnimationRegisterCache.targetRegisters = shaderObject.animationTargetRegisters;
+ this._iAnimationRegisterCache.needFragmentAnimation = shaderObject.usesFragmentAnimation;
+ this._iAnimationRegisterCache.needUVAnimation = !shaderObject.usesUVTransform;
+ this._iAnimationRegisterCache.hasColorAddNode = this.hasColorAddNode;
+ this._iAnimationRegisterCache.hasColorMulNode = this.hasColorMulNode;
+ this._iAnimationRegisterCache.reset();
+
+ var code:string = "";
+
+ code += this._iAnimationRegisterCache.getInitCode();
+
+ var node:ParticleNodeBase;
+ var i:number /*int*/;
+
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority < ParticleAnimationSet.POST_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+
+ code += this._iAnimationRegisterCache.getCombinationCode();
+
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority >= ParticleAnimationSet.POST_PRIORITY && node.priority < ParticleAnimationSet.COLOR_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+
+ code += this._iAnimationRegisterCache.initColorRegisters();
+
+ for (i = 0; i < this._particleNodes.length; i++) {
+ node = this._particleNodes[i];
+ if (node.priority >= ParticleAnimationSet.COLOR_PRIORITY)
+ code += node.getAGALVertexCode(shaderObject, this._iAnimationRegisterCache);
+ }
+ code += this._iAnimationRegisterCache.getColorPassCode();
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase):string
+ {
+ var code:string = "";
+ if (this.hasUVNode) {
+ this._iAnimationRegisterCache.setUVSourceAndTarget(shaderObject.uvSource, shaderObject.uvTarget);
+ code += "mov " + this._iAnimationRegisterCache.uvTarget + ".xy," + this._iAnimationRegisterCache.uvAttribute.toString() + "\n";
+ var node:ParticleNodeBase;
+ for (var i:number /*uint*/ = 0; i < this._particleNodes.length; i++)
+ node = this._particleNodes[i];
+ code += node.getAGALUVCode(shaderObject, this._iAnimationRegisterCache);
+ code += "mov " + this._iAnimationRegisterCache.uvVar.toString() + "," + this._iAnimationRegisterCache.uvTarget + ".xy\n";
+ } else
+ code += "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALFragmentCode(shaderObject:ShaderObjectBase, shadedTarget:string):string
+ {
+ return this._iAnimationRegisterCache.getColorCombinationCode(shadedTarget);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public doneAGALCode(shaderObject:ShaderObjectBase)
+ {
+ this._iAnimationRegisterCache.setDataLength();
+
+ //set vertexZeroConst,vertexOneConst,vertexTwoConst
+ this._iAnimationRegisterCache.setVertexConst(this._iAnimationRegisterCache.vertexZeroConst.index, 0, 1, 2, 0);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get usesCPU():boolean
+ {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public cancelGPUCompatibility()
+ {
+
+ }
+
+ public dispose()
+ {
+ for (var key in this._animationSubGeometries)
+ ( this._animationSubGeometries[key]).dispose();
+
+ super.dispose();
+ }
+
+ public getAnimationSubGeometry(subMesh:ISubMesh)
+ {
+ var mesh:Mesh = subMesh.parentMesh;
+ var animationSubGeometry:AnimationSubGeometry = (mesh.shareAnimationGeometry)? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+
+ if (animationSubGeometry)
+ return animationSubGeometry;
+
+ this._iGenerateAnimationSubGeometries(mesh);
+
+ return (mesh.shareAnimationGeometry)? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+ }
+
+
+ /** @private */
+ public _iGenerateAnimationSubGeometries(mesh:Mesh)
+ {
+ if (this.initParticleFunc == null)
+ throw(new Error("no initParticleFunc set"));
+
+ var geometry:ParticleGeometry = mesh.geometry;
+
+ if (!geometry)
+ throw(new Error("Particle animation can only be performed on a ParticleGeometry object"));
+
+ var i:number /*int*/, j:number /*int*/, k:number /*int*/;
+ var animationSubGeometry:AnimationSubGeometry;
+ var newAnimationSubGeometry:boolean = false;
+ var subGeometry:SubGeometryBase;
+ var subMesh:ISubMesh;
+ var localNode:ParticleNodeBase;
+
+ for (i = 0; i < mesh.subMeshes.length; i++) {
+ subMesh = mesh.subMeshes[i];
+ subGeometry = subMesh.subGeometry;
+ if (mesh.shareAnimationGeometry) {
+ animationSubGeometry = this._animationSubGeometries[subGeometry.id];
+
+ if (animationSubGeometry)
+ continue;
+ }
+
+ animationSubGeometry = new AnimationSubGeometry();
+
+ if (mesh.shareAnimationGeometry)
+ this._animationSubGeometries[subGeometry.id] = animationSubGeometry;
+ else
+ this._animationSubGeometries[subMesh.id] = animationSubGeometry;
+
+ newAnimationSubGeometry = true;
+
+ //create the vertexData vector that will be used for local node data
+ animationSubGeometry.createVertexData(subGeometry.numVertices, this._totalLenOfOneVertex);
+ }
+
+ if (!newAnimationSubGeometry)
+ return;
+
+ var particles:Array = geometry.particles;
+ var particlesLength:number /*uint*/ = particles.length;
+ var numParticles:number /*uint*/ = geometry.numParticles;
+ var particleProperties:ParticleProperties = new ParticleProperties();
+ var particle:ParticleData;
+
+ var oneDataLen:number /*int*/;
+ var oneDataOffset:number /*int*/;
+ var counterForVertex:number /*int*/;
+ var counterForOneData:number /*int*/;
+ var oneData:Array;
+ var numVertices:number /*uint*/;
+ var vertexData:Array;
+ var vertexLength:number /*uint*/;
+ var startingOffset:number /*uint*/;
+ var vertexOffset:number /*uint*/;
+
+ //default values for particle param
+ particleProperties.total = numParticles;
+ particleProperties.startTime = 0;
+ particleProperties.duration = 1000;
+ particleProperties.delay = 0.1;
+
+ i = 0;
+ j = 0;
+ while (i < numParticles) {
+ particleProperties.index = i;
+
+ //call the init on the particle parameters
+ this.initParticleFunc.call(this.initParticleScope, particleProperties);
+
+ //create the next set of node properties for the particle
+ for (k = 0; k < this._localStaticNodes.length; k++)
+ this._localStaticNodes[k]._iGeneratePropertyOfOneParticle(particleProperties);
+
+ //loop through all particle data for the curent particle
+ while (j < particlesLength && (particle = particles[j]).particleIndex == i) {
+ //find the target animationSubGeometry
+ for (k = 0; k < mesh.subMeshes.length; k++) {
+ subMesh = mesh.subMeshes[k];
+ if (subMesh.subGeometry == particle.subGeometry) {
+ animationSubGeometry = (mesh.shareAnimationGeometry)? this._animationSubGeometries[subMesh.subGeometry.id] : this._animationSubGeometries[subMesh.id];
+ break;
+ }
+ }
+ numVertices = particle.numVertices;
+ vertexData = animationSubGeometry.vertexData;
+ vertexLength = numVertices*this._totalLenOfOneVertex;
+ startingOffset = animationSubGeometry.numProcessedVertices*this._totalLenOfOneVertex;
+
+ //loop through each static local node in the animation set
+ for (k = 0; k < this._localStaticNodes.length; k++) {
+ localNode = this._localStaticNodes[k];
+ oneData = localNode.oneData;
+ oneDataLen = localNode.dataLength;
+ oneDataOffset = startingOffset + localNode._iDataOffset;
+
+ //loop through each vertex set in the vertex data
+ for (counterForVertex = 0; counterForVertex < vertexLength; counterForVertex += this._totalLenOfOneVertex) {
+ vertexOffset = oneDataOffset + counterForVertex;
+
+ //add the data for the local node to the vertex data
+ for (counterForOneData = 0; counterForOneData < oneDataLen; counterForOneData++)
+ vertexData[vertexOffset + counterForOneData] = oneData[counterForOneData];
+ }
+
+ }
+
+ //store particle properties if they need to be retreived for dynamic local nodes
+ if (this._localDynamicNodes.length)
+ animationSubGeometry.animationParticles.push(new ParticleAnimationData(i, particleProperties.startTime, particleProperties.duration, particleProperties.delay, particle));
+
+ animationSubGeometry.numProcessedVertices += numVertices;
+
+ //next index
+ j++;
+ }
+
+ //next particle
+ i++;
+ }
+ }
+}
+
+export = ParticleAnimationSet;
\ No newline at end of file
diff --git a/lib/animators/ParticleAnimator.js b/lib/animators/ParticleAnimator.js
new file mode 100755
index 000000000..dc03af739
--- /dev/null
+++ b/lib/animators/ParticleAnimator.js
@@ -0,0 +1,128 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+var ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+var AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+/**
+ * Provides an interface for assigning paricle-based animation data sets to mesh-based entity objects
+ * and controlling the various available states of animation through an interative playhead that can be
+ * automatically updated or manually triggered.
+ *
+ * Requires that the containing geometry of the parent mesh is particle geometry
+ *
+ * @see away.base.ParticleGeometry
+ */
+var ParticleAnimator = (function (_super) {
+ __extends(ParticleAnimator, _super);
+ /**
+ * Creates a new ParticleAnimator
object.
+ *
+ * @param particleAnimationSet The animation data set containing the particle animations used by the animator.
+ */
+ function ParticleAnimator(particleAnimationSet) {
+ _super.call(this, particleAnimationSet);
+ this._animationParticleStates = new Array();
+ this._animatorParticleStates = new Array();
+ this._timeParticleStates = new Array();
+ this._totalLenOfOneVertex = 0;
+ this._animatorSubGeometries = new Object();
+ this._particleAnimationSet = particleAnimationSet;
+ var state;
+ var node;
+ for (var i = 0; i < this._particleAnimationSet.particleNodes.length; i++) {
+ node = this._particleAnimationSet.particleNodes[i];
+ state = this.getAnimationState(node);
+ if (node.mode == ParticlePropertiesMode.LOCAL_DYNAMIC) {
+ this._animatorParticleStates.push(state);
+ node._iDataOffset = this._totalLenOfOneVertex;
+ this._totalLenOfOneVertex += node.dataLength;
+ }
+ else {
+ this._animationParticleStates.push(state);
+ }
+ if (state.needUpdateTime)
+ this._timeParticleStates.push(state);
+ }
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype.clone = function () {
+ return new ParticleAnimator(this._particleAnimationSet);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype.setRenderState = function (shaderObject, renderable, stage, camera, vertexConstantOffset /*int*/, vertexStreamOffset /*int*/) {
+ var animationRegisterCache = this._particleAnimationSet._iAnimationRegisterCache;
+ var subMesh = renderable.subMesh;
+ var state;
+ var i;
+ if (!subMesh)
+ throw (new Error("Must be subMesh"));
+ //process animation sub geometries
+ var animationSubGeometry = this._particleAnimationSet.getAnimationSubGeometry(subMesh);
+ for (i = 0; i < this._animationParticleStates.length; i++)
+ this._animationParticleStates[i].setRenderState(stage, renderable, animationSubGeometry, animationRegisterCache, camera);
+ //process animator subgeometries
+ var animatorSubGeometry = this.getAnimatorSubGeometry(subMesh);
+ for (i = 0; i < this._animatorParticleStates.length; i++)
+ this._animatorParticleStates[i].setRenderState(stage, renderable, animatorSubGeometry, animationRegisterCache, camera);
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, animationRegisterCache.vertexConstantOffset, animationRegisterCache.vertexConstantData, animationRegisterCache.numVertexConstant);
+ if (animationRegisterCache.numFragmentConstant > 0)
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, animationRegisterCache.fragmentConstantOffset, animationRegisterCache.fragmentConstantData, animationRegisterCache.numFragmentConstant);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype.testGPUCompatibility = function (shaderObject) {
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype.start = function () {
+ _super.prototype.start.call(this);
+ for (var i = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].offset(this._pAbsoluteTime);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype._pUpdateDeltaTime = function (dt) {
+ this._pAbsoluteTime += dt;
+ for (var i = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].update(this._pAbsoluteTime);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAnimator.prototype.resetTime = function (offset) {
+ if (offset === void 0) { offset = 0; }
+ for (var i = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].offset(this._pAbsoluteTime + offset);
+ this.update(this.time);
+ };
+ ParticleAnimator.prototype.dispose = function () {
+ for (var key in this._animatorSubGeometries)
+ this._animatorSubGeometries[key].dispose();
+ };
+ ParticleAnimator.prototype.getAnimatorSubGeometry = function (subMesh) {
+ if (!this._animatorParticleStates.length)
+ return;
+ var subGeometry = subMesh.subGeometry;
+ var animatorSubGeometry = this._animatorSubGeometries[subGeometry.id] = new AnimationSubGeometry();
+ //create the vertexData vector that will be used for local state data
+ animatorSubGeometry.createVertexData(subGeometry.numVertices, this._totalLenOfOneVertex);
+ //pass the particles data to the animator subGeometry
+ animatorSubGeometry.animationParticles = this._particleAnimationSet.getAnimationSubGeometry(subMesh).animationParticles;
+ };
+ return ParticleAnimator;
+})(AnimatorBase);
+module.exports = ParticleAnimator;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9wYXJ0aWNsZWFuaW1hdG9yLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlQW5pbWF0b3IiLCJQYXJ0aWNsZUFuaW1hdG9yLmNvbnN0cnVjdG9yIiwiUGFydGljbGVBbmltYXRvci5jbG9uZSIsIlBhcnRpY2xlQW5pbWF0b3Iuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZUFuaW1hdG9yLnRlc3RHUFVDb21wYXRpYmlsaXR5IiwiUGFydGljbGVBbmltYXRvci5zdGFydCIsIlBhcnRpY2xlQW5pbWF0b3IuX3BVcGRhdGVEZWx0YVRpbWUiLCJQYXJ0aWNsZUFuaW1hdG9yLnJlc2V0VGltZSIsIlBhcnRpY2xlQW5pbWF0b3IuZGlzcG9zZSIsIlBhcnRpY2xlQW5pbWF0b3IuZ2V0QW5pbWF0b3JTdWJHZW9tZXRyeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBSUEsSUFBTyxZQUFZLFdBQWdCLDJDQUEyQyxDQUFDLENBQUM7QUFLaEYsSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBS2pHLElBQU8sb0JBQW9CLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUV0RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFJekcsQUFTQTs7Ozs7Ozs7R0FERztJQUNHLGdCQUFnQjtJQUFTQSxVQUF6QkEsZ0JBQWdCQSxVQUFxQkE7SUFVMUNBOzs7O09BSUdBO0lBQ0hBLFNBZktBLGdCQUFnQkEsQ0FlVEEsb0JBQXlDQTtRQUVwREMsa0JBQU1BLG9CQUFvQkEsQ0FBQ0EsQ0FBQ0E7UUFickJBLDZCQUF3QkEsR0FBNEJBLElBQUlBLEtBQUtBLEVBQXFCQSxDQUFDQTtRQUNuRkEsNEJBQXVCQSxHQUE0QkEsSUFBSUEsS0FBS0EsRUFBcUJBLENBQUNBO1FBQ2xGQSx3QkFBbUJBLEdBQTRCQSxJQUFJQSxLQUFLQSxFQUFxQkEsQ0FBQ0E7UUFDOUVBLHlCQUFvQkEsR0FBbUJBLENBQUNBLENBQUNBO1FBQ3pDQSwyQkFBc0JBLEdBQVVBLElBQUlB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LEdBQWRBO1FBRUNRLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLElBQUlBLElBQUlBLENBQUNBLHNCQUFzQkEsQ0FBQ0E7WUFDbkJBLElBQUlBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsR0FBR0EsQ0FBRUEsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7SUFDdEVBLENBQUNBO0lBRU9SLGlEQUFzQkEsR0FBOUJBLFVBQStCQSxPQUFnQkE7UUFFOUNTLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7WUFDeENBLE1BQU1BLENBQUNBO1FBRVJBLElBQUlBLFdBQVdBLEdBQW1CQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUN0REEsSUFBSUEsbUJBQW1CQSxHQUF3QkEsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxXQUFXQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxvQkFBb0JBLEVBQUVBLENBQUNBO1FBRXhIQSxBQUNBQSxxRUFEcUVBO1FBQ3JFQSxtQkFBbUJBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsRUFBRUEsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxDQUFDQTtRQUV6RkEsQUFDQUEscURBRHFEQTtRQUNyREEsbUJBQW1CQSxDQUFDQSxrQkFBa0JBLEdBQUdBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxrQkFBa0JBLENBQUNBO0lBQ3pIQSxDQUFDQTtJQUNGVCx1QkFBQ0E7QUFBREEsQ0ExSUEsQUEwSUNBLEVBMUk4QixZQUFZLEVBMEkxQztBQUVELEFBQTBCLGlCQUFqQixnQkFBZ0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvUGFydGljbGVBbmltYXRvci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBJU3ViTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9JU3ViTWVzaFwiKTtcbmltcG9ydCBTdWJHZW9tZXRyeUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9TdWJHZW9tZXRyeUJhc2VcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJNZXNoUmVuZGVyYWJsZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1RyaWFuZ2xlU3ViTWVzaFJlbmRlcmFibGVcIik7XG5pbXBvcnQgQ29udGV4dEdMUHJvZ3JhbVR5cGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMUHJvZ3JhbVR5cGVcIik7XG5pbXBvcnQgSUNvbnRleHRTdGFnZUdMXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvSUNvbnRleHRTdGFnZUdMXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZUFuaW1hdGlvbkRhdGFcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVBbmltYXRpb25EYXRhXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVTdGF0ZUJhc2VcIik7XG5cbi8qKlxuICogUHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBhc3NpZ25pbmcgcGFyaWNsZS1iYXNlZCBhbmltYXRpb24gZGF0YSBzZXRzIHRvIG1lc2gtYmFzZWQgZW50aXR5IG9iamVjdHNcbiAqIGFuZCBjb250cm9sbGluZyB0aGUgdmFyaW91cyBhdmFpbGFibGUgc3RhdGVzIG9mIGFuaW1hdGlvbiB0aHJvdWdoIGFuIGludGVyYXRpdmUgcGxheWhlYWQgdGhhdCBjYW4gYmVcbiAqIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCBvciBtYW51YWxseSB0cmlnZ2VyZWQuXG4gKlxuICogUmVxdWlyZXMgdGhhdCB0aGUgY29udGFpbmluZyBnZW9tZXRyeSBvZiB0aGUgcGFyZW50IG1lc2ggaXMgcGFydGljbGUgZ2VvbWV0cnlcbiAqXG4gKiBAc2VlIGF3YXkuYmFzZS5QYXJ0aWNsZUdlb21ldHJ5XG4gKi9cbmNsYXNzIFBhcnRpY2xlQW5pbWF0b3IgZXh0ZW5kcyBBbmltYXRvckJhc2VcbntcblxuXHRwcml2YXRlIF9wYXJ0aWNsZUFuaW1hdGlvblNldDpQYXJ0aWNsZUFuaW1hdGlvblNldDtcblx0cHJpdmF0ZSBfYW5pbWF0aW9uUGFydGljbGVTdGF0ZXM6QXJyYXk8UGFydGljbGVTdGF0ZUJhc2U+ID0gbmV3IEFycmF5PFBhcnRpY2xlU3RhdGVCYXNlPigpO1xuXHRwcml2YXRlIF9hbmltYXRvclBhcnRpY2xlU3RhdGVzOkFycmF5PFBhcnRpY2xlU3RhdGVCYXNlPiA9IG5ldyBBcnJheTxQYXJ0aWNsZVN0YXRlQmFzZT4oKTtcblx0cHJpdmF0ZSBfdGltZVBhcnRpY2xlU3RhdGVzOkFycmF5PFBhcnRpY2xlU3RhdGVCYXNlPiA9IG5ldyBBcnJheTxQYXJ0aWNsZVN0YXRlQmFzZT4oKTtcblx0cHJpdmF0ZSBfdG90YWxMZW5PZk9uZVZlcnRleDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRwcml2YXRlIF9hbmltYXRvclN1Ykdlb21ldHJpZXM6T2JqZWN0ID0gbmV3IE9iamVjdCgpO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlQW5pbWF0b3I8L2NvZGU+IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHBhcnRpY2xlQW5pbWF0aW9uU2V0IFRoZSBhbmltYXRpb24gZGF0YSBzZXQgY29udGFpbmluZyB0aGUgcGFydGljbGUgYW5pbWF0aW9ucyB1c2VkIGJ5IHRoZSBhbmltYXRvci5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHBhcnRpY2xlQW5pbWF0aW9uU2V0OlBhcnRpY2xlQW5pbWF0aW9uU2V0KVxuXHR7XG5cdFx0c3VwZXIocGFydGljbGVBbmltYXRpb25TZXQpO1xuXHRcdHRoaXMuX3BhcnRpY2xlQW5pbWF0aW9uU2V0ID0gcGFydGljbGVBbmltYXRpb25TZXQ7XG5cblx0XHR2YXIgc3RhdGU6UGFydGljbGVTdGF0ZUJhc2U7XG5cdFx0dmFyIG5vZGU6UGFydGljbGVOb2RlQmFzZTtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IHRoaXMuX3BhcnRpY2xlQW5pbWF0aW9uU2V0LnBhcnRpY2xlTm9kZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG5vZGUgPSB0aGlzLl9wYXJ0aWNsZUFuaW1hdGlvblNldC5wYXJ0aWNsZU5vZGVzW2ldO1xuXHRcdFx0c3RhdGUgPSA8UGFydGljbGVTdGF0ZUJhc2U+IHRoaXMuZ2V0QW5pbWF0aW9uU3RhdGUobm9kZSk7XG5cdFx0XHRpZiAobm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfRFlOQU1JQykge1xuXHRcdFx0XHR0aGlzLl9hbmltYXRvclBhcnRpY2xlU3RhdGVzLnB1c2goc3RhdGUpO1xuXHRcdFx0XHRub2RlLl9pRGF0YU9mZnNldCA9IHRoaXMuX3RvdGFsTGVuT2ZPbmVWZXJ0ZXg7XG5cdFx0XHRcdHRoaXMuX3RvdGFsTGVuT2ZPbmVWZXJ0ZXggKz0gbm9kZS5kYXRhTGVuZ3RoO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5fYW5pbWF0aW9uUGFydGljbGVTdGF0ZXMucHVzaChzdGF0ZSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoc3RhdGUubmVlZFVwZGF0ZVRpbWUpXG5cdFx0XHRcdHRoaXMuX3RpbWVQYXJ0aWNsZVN0YXRlcy5wdXNoKHN0YXRlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBjbG9uZSgpOkFuaW1hdG9yQmFzZVxuXHR7XG5cdFx0cmV0dXJuIG5ldyBQYXJ0aWNsZUFuaW1hdG9yKHRoaXMuX3BhcnRpY2xlQW5pbWF0aW9uU2V0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSwgdmVydGV4Q29uc3RhbnRPZmZzZXQ6bnVtYmVyIC8qaW50Ki8sIHZlcnRleFN0cmVhbU9mZnNldDpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdHZhciBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUgPSB0aGlzLl9wYXJ0aWNsZUFuaW1hdGlvblNldC5faUFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU7XG5cblx0XHR2YXIgc3ViTWVzaDpJU3ViTWVzaCA9ICg8VHJpYW5nbGVTdWJNZXNoUmVuZGVyYWJsZT4gcmVuZGVyYWJsZSkuc3ViTWVzaDtcblx0XHR2YXIgc3RhdGU6UGFydGljbGVTdGF0ZUJhc2U7XG5cdFx0dmFyIGk6bnVtYmVyO1xuXG5cdFx0aWYgKCFzdWJNZXNoKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwiTXVzdCBiZSBzdWJNZXNoXCIpKTtcblxuXHRcdC8vcHJvY2VzcyBhbmltYXRpb24gc3ViIGdlb21ldHJpZXNcblx0XHR2YXIgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnkgPSB0aGlzLl9wYXJ0aWNsZUFuaW1hdGlvblNldC5nZXRBbmltYXRpb25TdWJHZW9tZXRyeShzdWJNZXNoKTtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCB0aGlzLl9hbmltYXRpb25QYXJ0aWNsZVN0YXRlcy5sZW5ndGg7IGkrKylcblx0XHRcdHRoaXMuX2FuaW1hdGlvblBhcnRpY2xlU3RhdGVzW2ldLnNldFJlbmRlclN0YXRlKHN0YWdlLCByZW5kZXJhYmxlLCBhbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhKTtcblxuXHRcdC8vcHJvY2VzcyBhbmltYXRvciBzdWJnZW9tZXRyaWVzXG5cdFx0dmFyIGFuaW1hdG9yU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnkgPSB0aGlzLmdldEFuaW1hdG9yU3ViR2VvbWV0cnkoc3ViTWVzaCk7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgdGhpcy5fYW5pbWF0b3JQYXJ0aWNsZVN0YXRlcy5sZW5ndGg7IGkrKylcblx0XHRcdHRoaXMuX2FuaW1hdG9yUGFydGljbGVTdGF0ZXNbaV0uc2V0UmVuZGVyU3RhdGUoc3RhZ2UsIHJlbmRlcmFibGUsIGFuaW1hdG9yU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYSk7XG5cblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21BcnJheShDb250ZXh0R0xQcm9ncmFtVHlwZS5WRVJURVgsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4Q29uc3RhbnRPZmZzZXQsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4Q29uc3RhbnREYXRhLCBhbmltYXRpb25SZWdpc3RlckNhY2hlLm51bVZlcnRleENvbnN0YW50KTtcblxuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLm51bUZyYWdtZW50Q29uc3RhbnQgPiAwKVxuXHRcdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLnNldFByb2dyYW1Db25zdGFudHNGcm9tQXJyYXkoQ29udGV4dEdMUHJvZ3JhbVR5cGUuRlJBR01FTlQsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZnJhZ21lbnRDb25zdGFudE9mZnNldCwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5mcmFnbWVudENvbnN0YW50RGF0YSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5udW1GcmFnbWVudENvbnN0YW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHRlc3RHUFVDb21wYXRpYmlsaXR5KHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKVxuXHR7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHN0YXJ0KClcblx0e1xuXHRcdHN1cGVyLnN0YXJ0KCk7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCB0aGlzLl90aW1lUGFydGljbGVTdGF0ZXMubGVuZ3RoOyBpKyspXG5cdFx0XHR0aGlzLl90aW1lUGFydGljbGVTdGF0ZXNbaV0ub2Zmc2V0KHRoaXMuX3BBYnNvbHV0ZVRpbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVEZWx0YVRpbWUoZHQ6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fcEFic29sdXRlVGltZSArPSBkdDtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IHRoaXMuX3RpbWVQYXJ0aWNsZVN0YXRlcy5sZW5ndGg7IGkrKylcblx0XHRcdHRoaXMuX3RpbWVQYXJ0aWNsZVN0YXRlc1tpXS51cGRhdGUodGhpcy5fcEFic29sdXRlVGltZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyByZXNldFRpbWUob2Zmc2V0Om51bWJlciAvKmludCovID0gMClcblx0e1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IHRoaXMuX3RpbWVQYXJ0aWNsZVN0YXRlcy5sZW5ndGg7IGkrKylcblx0XHRcdHRoaXMuX3RpbWVQYXJ0aWNsZVN0YXRlc1tpXS5vZmZzZXQodGhpcy5fcEFic29sdXRlVGltZSArIG9mZnNldCk7XG5cdFx0dGhpcy51cGRhdGUodGhpcy50aW1lKTtcblx0fVxuXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdGZvciAodmFyIGtleSBpbiB0aGlzLl9hbmltYXRvclN1Ykdlb21ldHJpZXMpXG5cdFx0XHQoPEFuaW1hdGlvblN1Ykdlb21ldHJ5PiB0aGlzLl9hbmltYXRvclN1Ykdlb21ldHJpZXNba2V5XSkuZGlzcG9zZSgpO1xuXHR9XG5cblx0cHJpdmF0ZSBnZXRBbmltYXRvclN1Ykdlb21ldHJ5KHN1Yk1lc2g6SVN1Yk1lc2gpOkFuaW1hdGlvblN1Ykdlb21ldHJ5XG5cdHtcblx0XHRpZiAoIXRoaXMuX2FuaW1hdG9yUGFydGljbGVTdGF0ZXMubGVuZ3RoKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dmFyIHN1Ykdlb21ldHJ5OlN1Ykdlb21ldHJ5QmFzZSA9IHN1Yk1lc2guc3ViR2VvbWV0cnk7XG5cdFx0dmFyIGFuaW1hdG9yU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnkgPSB0aGlzLl9hbmltYXRvclN1Ykdlb21ldHJpZXNbc3ViR2VvbWV0cnkuaWRdID0gbmV3IEFuaW1hdGlvblN1Ykdlb21ldHJ5KCk7XG5cblx0XHQvL2NyZWF0ZSB0aGUgdmVydGV4RGF0YSB2ZWN0b3IgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIGxvY2FsIHN0YXRlIGRhdGFcblx0XHRhbmltYXRvclN1Ykdlb21ldHJ5LmNyZWF0ZVZlcnRleERhdGEoc3ViR2VvbWV0cnkubnVtVmVydGljZXMsIHRoaXMuX3RvdGFsTGVuT2ZPbmVWZXJ0ZXgpO1xuXG5cdFx0Ly9wYXNzIHRoZSBwYXJ0aWNsZXMgZGF0YSB0byB0aGUgYW5pbWF0b3Igc3ViR2VvbWV0cnlcblx0XHRhbmltYXRvclN1Ykdlb21ldHJ5LmFuaW1hdGlvblBhcnRpY2xlcyA9IHRoaXMuX3BhcnRpY2xlQW5pbWF0aW9uU2V0LmdldEFuaW1hdGlvblN1Ykdlb21ldHJ5KHN1Yk1lc2gpLmFuaW1hdGlvblBhcnRpY2xlcztcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZUFuaW1hdG9yOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/ParticleAnimator.ts b/lib/animators/ParticleAnimator.ts
new file mode 100644
index 000000000..25e389fbc
--- /dev/null
+++ b/lib/animators/ParticleAnimator.ts
@@ -0,0 +1,170 @@
+import ISubMesh = require("awayjs-core/lib/core/base/ISubMesh");
+import SubGeometryBase = require("awayjs-core/lib/core/base/SubGeometryBase");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import TriangleSubMeshRenderable = require("awayjs-stagegl/lib/core/pool/TriangleSubMeshRenderable");
+import ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * Provides an interface for assigning paricle-based animation data sets to mesh-based entity objects
+ * and controlling the various available states of animation through an interative playhead that can be
+ * automatically updated or manually triggered.
+ *
+ * Requires that the containing geometry of the parent mesh is particle geometry
+ *
+ * @see away.base.ParticleGeometry
+ */
+class ParticleAnimator extends AnimatorBase
+{
+
+ private _particleAnimationSet:ParticleAnimationSet;
+ private _animationParticleStates:Array = new Array();
+ private _animatorParticleStates:Array = new Array();
+ private _timeParticleStates:Array = new Array();
+ private _totalLenOfOneVertex:number /*uint*/ = 0;
+ private _animatorSubGeometries:Object = new Object();
+
+ /**
+ * Creates a new ParticleAnimator
object.
+ *
+ * @param particleAnimationSet The animation data set containing the particle animations used by the animator.
+ */
+ constructor(particleAnimationSet:ParticleAnimationSet)
+ {
+ super(particleAnimationSet);
+ this._particleAnimationSet = particleAnimationSet;
+
+ var state:ParticleStateBase;
+ var node:ParticleNodeBase;
+
+ for (var i:number = 0; i < this._particleAnimationSet.particleNodes.length; i++) {
+ node = this._particleAnimationSet.particleNodes[i];
+ state = this.getAnimationState(node);
+ if (node.mode == ParticlePropertiesMode.LOCAL_DYNAMIC) {
+ this._animatorParticleStates.push(state);
+ node._iDataOffset = this._totalLenOfOneVertex;
+ this._totalLenOfOneVertex += node.dataLength;
+ } else {
+ this._animationParticleStates.push(state);
+ }
+ if (state.needUpdateTime)
+ this._timeParticleStates.push(state);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public clone():AnimatorBase
+ {
+ return new ParticleAnimator(this._particleAnimationSet);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(shaderObject:ShaderObjectBase, renderable:RenderableBase, stage:Stage, camera:Camera, vertexConstantOffset:number /*int*/, vertexStreamOffset:number /*int*/)
+ {
+ var animationRegisterCache:AnimationRegisterCache = this._particleAnimationSet._iAnimationRegisterCache;
+
+ var subMesh:ISubMesh = ( renderable).subMesh;
+ var state:ParticleStateBase;
+ var i:number;
+
+ if (!subMesh)
+ throw(new Error("Must be subMesh"));
+
+ //process animation sub geometries
+ var animationSubGeometry:AnimationSubGeometry = this._particleAnimationSet.getAnimationSubGeometry(subMesh);
+
+ for (i = 0; i < this._animationParticleStates.length; i++)
+ this._animationParticleStates[i].setRenderState(stage, renderable, animationSubGeometry, animationRegisterCache, camera);
+
+ //process animator subgeometries
+ var animatorSubGeometry:AnimationSubGeometry = this.getAnimatorSubGeometry(subMesh);
+
+ for (i = 0; i < this._animatorParticleStates.length; i++)
+ this._animatorParticleStates[i].setRenderState(stage, renderable, animatorSubGeometry, animationRegisterCache, camera);
+
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, animationRegisterCache.vertexConstantOffset, animationRegisterCache.vertexConstantData, animationRegisterCache.numVertexConstant);
+
+ if (animationRegisterCache.numFragmentConstant > 0)
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, animationRegisterCache.fragmentConstantOffset, animationRegisterCache.fragmentConstantData, animationRegisterCache.numFragmentConstant);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public testGPUCompatibility(shaderObject:ShaderObjectBase)
+ {
+
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public start()
+ {
+ super.start();
+
+ for (var i:number = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].offset(this._pAbsoluteTime);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateDeltaTime(dt:number)
+ {
+ this._pAbsoluteTime += dt;
+
+ for (var i:number = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].update(this._pAbsoluteTime);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public resetTime(offset:number /*int*/ = 0)
+ {
+ for (var i:number = 0; i < this._timeParticleStates.length; i++)
+ this._timeParticleStates[i].offset(this._pAbsoluteTime + offset);
+ this.update(this.time);
+ }
+
+ public dispose()
+ {
+ for (var key in this._animatorSubGeometries)
+ ( this._animatorSubGeometries[key]).dispose();
+ }
+
+ private getAnimatorSubGeometry(subMesh:ISubMesh):AnimationSubGeometry
+ {
+ if (!this._animatorParticleStates.length)
+ return;
+
+ var subGeometry:SubGeometryBase = subMesh.subGeometry;
+ var animatorSubGeometry:AnimationSubGeometry = this._animatorSubGeometries[subGeometry.id] = new AnimationSubGeometry();
+
+ //create the vertexData vector that will be used for local state data
+ animatorSubGeometry.createVertexData(subGeometry.numVertices, this._totalLenOfOneVertex);
+
+ //pass the particles data to the animator subGeometry
+ animatorSubGeometry.animationParticles = this._particleAnimationSet.getAnimationSubGeometry(subMesh).animationParticles;
+ }
+}
+
+export = ParticleAnimator;
\ No newline at end of file
diff --git a/lib/animators/SkeletonAnimationSet.js b/lib/animators/SkeletonAnimationSet.js
new file mode 100755
index 000000000..e780a1a9f
--- /dev/null
+++ b/lib/animators/SkeletonAnimationSet.js
@@ -0,0 +1,103 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+/**
+ * The animation data set used by skeleton-based animators, containing skeleton animation data.
+ *
+ * @see away.animators.SkeletonAnimator
+ */
+var SkeletonAnimationSet = (function (_super) {
+ __extends(SkeletonAnimationSet, _super);
+ /**
+ * Creates a new SkeletonAnimationSet
object.
+ *
+ * @param jointsPerVertex Sets the amount of skeleton joints that can be linked to a single vertex via skinned weight values. For GPU-base animation, the maximum allowed value is 4. Defaults to 4.
+ */
+ function SkeletonAnimationSet(jointsPerVertex) {
+ if (jointsPerVertex === void 0) { jointsPerVertex = 4; }
+ _super.call(this);
+ this._jointsPerVertex = jointsPerVertex;
+ }
+ Object.defineProperty(SkeletonAnimationSet.prototype, "jointsPerVertex", {
+ /**
+ * Returns the amount of skeleton joints that can be linked to a single vertex via skinned weight values. For GPU-base animation, the
+ * maximum allowed value is 4.
+ */
+ get: function () {
+ return this._jointsPerVertex;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.getAGALVertexCode = function (shaderObject) {
+ var len = shaderObject.animatableAttributes.length;
+ var indexOffset0 = shaderObject.numUsedVertexConstants;
+ var indexOffset1 = indexOffset0 + 1;
+ var indexOffset2 = indexOffset0 + 2;
+ var indexStream = "va" + shaderObject.numUsedStreams;
+ var weightStream = "va" + (shaderObject.numUsedStreams + 1);
+ var indices = [indexStream + ".x", indexStream + ".y", indexStream + ".z", indexStream + ".w"];
+ var weights = [weightStream + ".x", weightStream + ".y", weightStream + ".z", weightStream + ".w"];
+ var temp1 = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var temp2 = this._pFindTempReg(shaderObject.animationTargetRegisters, temp1);
+ var dot = "dp4";
+ var code = "";
+ for (var i = 0; i < len; ++i) {
+ var src = shaderObject.animatableAttributes[i];
+ for (var j = 0; j < this._jointsPerVertex; ++j) {
+ code += dot + " " + temp1 + ".x, " + src + ", vc[" + indices[j] + "+" + indexOffset0 + "]\n" + dot + " " + temp1 + ".y, " + src + ", vc[" + indices[j] + "+" + indexOffset1 + "]\n" + dot + " " + temp1 + ".z, " + src + ", vc[" + indices[j] + "+" + indexOffset2 + "]\n" + "mov " + temp1 + ".w, " + src + ".w\n" + "mul " + temp1 + ", " + temp1 + ", " + weights[j] + "\n"; // apply weight
+ // add or mov to target. Need to write to a temp reg first, because an output can be a target
+ if (j == 0)
+ code += "mov " + temp2 + ", " + temp1 + "\n";
+ else
+ code += "add " + temp2 + ", " + temp2 + ", " + temp1 + "\n";
+ }
+ // switch to dp3 once positions have been transformed, from now on, it should only be vectors instead of points
+ dot = "dp3";
+ code += "mov " + shaderObject.animationTargetRegisters[i] + ", " + temp2 + "\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.activate = function (shaderObject, stage) {
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.deactivate = function (shaderObject, stage) {
+ // var streamOffset:number /*uint*/ = pass.numUsedStreams;
+ // var context:IContextStageGL = stage.context;
+ // context.setVertexBufferAt(streamOffset, null);
+ // context.setVertexBufferAt(streamOffset + 1, null);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.getAGALFragmentCode = function (shaderObject, shadedTarget) {
+ return "";
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.getAGALUVCode = function (shaderObject) {
+ return "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimationSet.prototype.doneAGALCode = function (shaderObject) {
+ };
+ return SkeletonAnimationSet;
+})(AnimationSetBase);
+module.exports = SkeletonAnimationSet;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9za2VsZXRvbmFuaW1hdGlvbnNldC50cyJdLCJuYW1lcyI6WyJTa2VsZXRvbkFuaW1hdGlvblNldCIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmNvbnN0cnVjdG9yIiwiU2tlbGV0b25BbmltYXRpb25TZXQuam9pbnRzUGVyVmVydGV4IiwiU2tlbGV0b25BbmltYXRpb25TZXQuZ2V0QUdBTFZlcnRleENvZGUiLCJTa2VsZXRvbkFuaW1hdGlvblNldC5hY3RpdmF0ZSIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmRlYWN0aXZhdGUiLCJTa2VsZXRvbkFuaW1hdGlvblNldC5nZXRBR0FMRnJhZ21lbnRDb2RlIiwiU2tlbGV0b25BbmltYXRpb25TZXQuZ2V0QUdBTFVWQ29kZSIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmRvbmVBR0FMQ29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUEsSUFBTyxnQkFBZ0IsV0FBZSwrQ0FBK0MsQ0FBQyxDQUFDO0FBSXZGLEFBS0E7Ozs7R0FERztJQUNHLG9CQUFvQjtJQUFTQSxVQUE3QkEsb0JBQW9CQSxVQUF5QkE7SUFhbERBOzs7O09BSUdBO0lBQ0hBLFNBbEJLQSxvQkFBb0JBLENBa0JiQSxlQUFtQ0E7UUFBbkNDLCtCQUFtQ0EsR0FBbkNBLG1CQUFtQ0E7UUFFOUNBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLGVBQWVBLENBQUNBO0lBQ3pDQSxDQUFDQTtJQWZERCxzQkFBV0EsaURBQWVBO1FBSjFCQTs7O1dBR0dBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7UUFDOUJBLENBQUNBOzs7T0FBQUY7SUFjREE7O09BRUdBO0lBQ0lBLGdEQUFpQkEsR0FBeEJBLFVBQXlCQSxZQUE2QkE7UUFFckRHLElBQUlBLEdBQUdBLEdBQW1CQSxZQUFZQSxDQUFDQSxvQkFBb0JBLENBQUNBLE1BQU1BLENBQUNBO1FBRW5FQSxJQUFJQSxZQUFZ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QUFuQkEsVUFBb0JBLFlBQTZCQTtJQUdqRFEsQ0FBQ0E7SUFDRlIsMkJBQUNBO0FBQURBLENBN0dBLEFBNkdDQSxFQTdHa0MsZ0JBQWdCLEVBNkdsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvU2tlbGV0b25BbmltYXRpb25TZXQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSUFuaW1hdGlvblNldFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL0lBbmltYXRpb25TZXRcIik7XG5cbmltcG9ydCBBbmltYXRpb25TZXRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0aW9uU2V0QmFzZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcblxuLyoqXG4gKiBUaGUgYW5pbWF0aW9uIGRhdGEgc2V0IHVzZWQgYnkgc2tlbGV0b24tYmFzZWQgYW5pbWF0b3JzLCBjb250YWluaW5nIHNrZWxldG9uIGFuaW1hdGlvbiBkYXRhLlxuICpcbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuU2tlbGV0b25BbmltYXRvclxuICovXG5jbGFzcyBTa2VsZXRvbkFuaW1hdGlvblNldCBleHRlbmRzIEFuaW1hdGlvblNldEJhc2UgaW1wbGVtZW50cyBJQW5pbWF0aW9uU2V0XG57XG5cdHByaXZhdGUgX2pvaW50c1BlclZlcnRleDpudW1iZXIgLyp1aW50Ki87XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGFtb3VudCBvZiBza2VsZXRvbiBqb2ludHMgdGhhdCBjYW4gYmUgbGlua2VkIHRvIGEgc2luZ2xlIHZlcnRleCB2aWEgc2tpbm5lZCB3ZWlnaHQgdmFsdWVzLiBGb3IgR1BVLWJhc2UgYW5pbWF0aW9uLCB0aGVcblx0ICogbWF4aW11bSBhbGxvd2VkIHZhbHVlIGlzIDQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGpvaW50c1BlclZlcnRleCgpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2pvaW50c1BlclZlcnRleDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlNrZWxldG9uQW5pbWF0aW9uU2V0PC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBqb2ludHNQZXJWZXJ0ZXggU2V0cyB0aGUgYW1vdW50IG9mIHNrZWxldG9uIGpvaW50cyB0aGF0IGNhbiBiZSBsaW5rZWQgdG8gYSBzaW5nbGUgdmVydGV4IHZpYSBza2lubmVkIHdlaWdodCB2YWx1ZXMuIEZvciBHUFUtYmFzZSBhbmltYXRpb24sIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUgaXMgNC4gRGVmYXVsdHMgdG8gNC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGpvaW50c1BlclZlcnRleDpudW1iZXIgLyp1aW50Ki8gPSA0KVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX2pvaW50c1BlclZlcnRleCA9IGpvaW50c1BlclZlcnRleDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzLmxlbmd0aDtcblxuXHRcdHZhciBpbmRleE9mZnNldDA6bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0Lm51bVVzZWRWZXJ0ZXhDb25zdGFudHM7XG5cdFx0dmFyIGluZGV4T2Zmc2V0MTpudW1iZXIgLyp1aW50Ki8gPSBpbmRleE9mZnNldDAgKyAxO1xuXHRcdHZhciBpbmRleE9mZnNldDI6bnVtYmVyIC8qdWludCovID0gaW5kZXhPZmZzZXQwICsgMjtcblx0XHR2YXIgaW5kZXhTdHJlYW06c3RyaW5nID0gXCJ2YVwiICsgc2hhZGVyT2JqZWN0Lm51bVVzZWRTdHJlYW1zO1xuXHRcdHZhciB3ZWlnaHRTdHJlYW06c3RyaW5nID0gXCJ2YVwiICsgKHNoYWRlck9iamVjdC5udW1Vc2VkU3RyZWFtcyArIDEpO1xuXHRcdHZhciBpbmRpY2VzOkFycmF5PHN0cmluZz4gPSBbIGluZGV4U3RyZWFtICsgXCIueFwiLCBpbmRleFN0cmVhbSArIFwiLnlcIiwgaW5kZXhTdHJlYW0gKyBcIi56XCIsIGluZGV4U3RyZWFtICsgXCIud1wiIF07XG5cdFx0dmFyIHdlaWdodHM6QXJyYXk8c3RyaW5nPiA9IFsgd2VpZ2h0U3RyZWFtICsgXCIueFwiLCB3ZWlnaHRTdHJlYW0gKyBcIi55XCIsIHdlaWdodFN0cmVhbSArIFwiLnpcIiwgd2VpZ2h0U3RyZWFtICsgXCIud1wiIF07XG5cdFx0dmFyIHRlbXAxOnN0cmluZyA9IHRoaXMuX3BGaW5kVGVtcFJlZyhzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzKTtcblx0XHR2YXIgdGVtcDI6c3RyaW5nID0gdGhpcy5fcEZpbmRUZW1wUmVnKHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnMsIHRlbXAxKTtcblx0XHR2YXIgZG90OnN0cmluZyA9IFwiZHA0XCI7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cblx0XHRcdHZhciBzcmM6c3RyaW5nID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzW2ldO1xuXG5cdFx0XHRmb3IgKHZhciBqOm51bWJlciAvKnVpbnQqLyA9IDA7IGogPCB0aGlzLl9qb2ludHNQZXJWZXJ0ZXg7ICsraikge1xuXHRcdFx0XHRjb2RlICs9IGRvdCArIFwiIFwiICsgdGVtcDEgKyBcIi54LCBcIiArIHNyYyArIFwiLCB2Y1tcIiArIGluZGljZXNbal0gKyBcIitcIiArIGluZGV4T2Zmc2V0MCArIFwiXVxcblwiICtcblx0XHRcdFx0XHRkb3QgKyBcIiBcIiArIHRlbXAxICsgXCIueSwgXCIgKyBzcmMgKyBcIiwgdmNbXCIgKyBpbmRpY2VzW2pdICsgXCIrXCIgKyBpbmRleE9mZnNldDEgKyBcIl1cXG5cIiArXG5cdFx0XHRcdFx0ZG90ICsgXCIgXCIgKyB0ZW1wMSArIFwiLnosIFwiICsgc3JjICsgXCIsIHZjW1wiICsgaW5kaWNlc1tqXSArIFwiK1wiICsgaW5kZXhPZmZzZXQyICsgXCJdXFxuXCIgK1xuXHRcdFx0XHRcdFwibW92IFwiICsgdGVtcDEgKyBcIi53LCBcIiArIHNyYyArIFwiLndcXG5cIiArXG5cdFx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wMSArIFwiLCBcIiArIHRlbXAxICsgXCIsIFwiICsgd2VpZ2h0c1tqXSArIFwiXFxuXCI7IC8vIGFwcGx5IHdlaWdodFxuXG5cdFx0XHRcdC8vIGFkZCBvciBtb3YgdG8gdGFyZ2V0LiBOZWVkIHRvIHdyaXRlIHRvIGEgdGVtcCByZWcgZmlyc3QsIGJlY2F1c2UgYW4gb3V0cHV0IGNhbiBiZSBhIHRhcmdldFxuXHRcdFx0XHRpZiAoaiA9PSAwKVxuXHRcdFx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMiArIFwiLCBcIiArIHRlbXAxICsgXCJcXG5cIjsgZWxzZVxuXHRcdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0ZW1wMiArIFwiLCBcIiArIHRlbXAyICsgXCIsIFwiICsgdGVtcDEgKyBcIlxcblwiO1xuXHRcdFx0fVxuXHRcdFx0Ly8gc3dpdGNoIHRvIGRwMyBvbmNlIHBvc2l0aW9ucyBoYXZlIGJlZW4gdHJhbnNmb3JtZWQsIGZyb20gbm93IG9uLCBpdCBzaG91bGQgb25seSBiZSB2ZWN0b3JzIGluc3RlYWQgb2YgcG9pbnRzXG5cdFx0XHRkb3QgPSBcImRwM1wiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnNbaV0gKyBcIiwgXCIgKyB0ZW1wMiArIFwiXFxuXCI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBhY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRlYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIHN0YWdlOlN0YWdlKVxuXHR7XG4vL1x0XHRcdHZhciBzdHJlYW1PZmZzZXQ6bnVtYmVyIC8qdWludCovID0gcGFzcy5udW1Vc2VkU3RyZWFtcztcbi8vXHRcdFx0dmFyIGNvbnRleHQ6SUNvbnRleHRTdGFnZUdMID0gPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dDtcbi8vXHRcdFx0Y29udGV4dC5zZXRWZXJ0ZXhCdWZmZXJBdChzdHJlYW1PZmZzZXQsIG51bGwpO1xuLy9cdFx0XHRjb250ZXh0LnNldFZlcnRleEJ1ZmZlckF0KHN0cmVhbU9mZnNldCArIDEsIG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc2hhZGVkVGFyZ2V0OnN0cmluZyk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIFwibW92IFwiICsgc2hhZGVyT2JqZWN0LnV2VGFyZ2V0ICsgXCIsXCIgKyBzaGFkZXJPYmplY3QudXZTb3VyY2UgKyBcIlxcblwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZG9uZUFHQUxDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKVxuXHR7XG5cblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkFuaW1hdGlvblNldDsiXX0=
\ No newline at end of file
diff --git a/lib/animators/SkeletonAnimationSet.ts b/lib/animators/SkeletonAnimationSet.ts
new file mode 100644
index 000000000..c14fd07cd
--- /dev/null
+++ b/lib/animators/SkeletonAnimationSet.ts
@@ -0,0 +1,123 @@
+import IAnimationSet = require("awayjs-core/lib/animators/IAnimationSet");
+
+import AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+/**
+ * The animation data set used by skeleton-based animators, containing skeleton animation data.
+ *
+ * @see away.animators.SkeletonAnimator
+ */
+class SkeletonAnimationSet extends AnimationSetBase implements IAnimationSet
+{
+ private _jointsPerVertex:number /*uint*/;
+
+ /**
+ * Returns the amount of skeleton joints that can be linked to a single vertex via skinned weight values. For GPU-base animation, the
+ * maximum allowed value is 4.
+ */
+ public get jointsPerVertex():number /*uint*/
+ {
+ return this._jointsPerVertex;
+ }
+
+ /**
+ * Creates a new SkeletonAnimationSet
object.
+ *
+ * @param jointsPerVertex Sets the amount of skeleton joints that can be linked to a single vertex via skinned weight values. For GPU-base animation, the maximum allowed value is 4. Defaults to 4.
+ */
+ constructor(jointsPerVertex:number /*uint*/ = 4)
+ {
+ super();
+
+ this._jointsPerVertex = jointsPerVertex;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase):string
+ {
+ var len:number /*uint*/ = shaderObject.animatableAttributes.length;
+
+ var indexOffset0:number /*uint*/ = shaderObject.numUsedVertexConstants;
+ var indexOffset1:number /*uint*/ = indexOffset0 + 1;
+ var indexOffset2:number /*uint*/ = indexOffset0 + 2;
+ var indexStream:string = "va" + shaderObject.numUsedStreams;
+ var weightStream:string = "va" + (shaderObject.numUsedStreams + 1);
+ var indices:Array = [ indexStream + ".x", indexStream + ".y", indexStream + ".z", indexStream + ".w" ];
+ var weights:Array = [ weightStream + ".x", weightStream + ".y", weightStream + ".z", weightStream + ".w" ];
+ var temp1:string = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var temp2:string = this._pFindTempReg(shaderObject.animationTargetRegisters, temp1);
+ var dot:string = "dp4";
+ var code:string = "";
+
+ for (var i:number /*uint*/ = 0; i < len; ++i) {
+
+ var src:string = shaderObject.animatableAttributes[i];
+
+ for (var j:number /*uint*/ = 0; j < this._jointsPerVertex; ++j) {
+ code += dot + " " + temp1 + ".x, " + src + ", vc[" + indices[j] + "+" + indexOffset0 + "]\n" +
+ dot + " " + temp1 + ".y, " + src + ", vc[" + indices[j] + "+" + indexOffset1 + "]\n" +
+ dot + " " + temp1 + ".z, " + src + ", vc[" + indices[j] + "+" + indexOffset2 + "]\n" +
+ "mov " + temp1 + ".w, " + src + ".w\n" +
+ "mul " + temp1 + ", " + temp1 + ", " + weights[j] + "\n"; // apply weight
+
+ // add or mov to target. Need to write to a temp reg first, because an output can be a target
+ if (j == 0)
+ code += "mov " + temp2 + ", " + temp1 + "\n"; else
+ code += "add " + temp2 + ", " + temp2 + ", " + temp1 + "\n";
+ }
+ // switch to dp3 once positions have been transformed, from now on, it should only be vectors instead of points
+ dot = "dp3";
+ code += "mov " + shaderObject.animationTargetRegisters[i] + ", " + temp2 + "\n";
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public activate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public deactivate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+// var streamOffset:number /*uint*/ = pass.numUsedStreams;
+// var context:IContextStageGL = stage.context;
+// context.setVertexBufferAt(streamOffset, null);
+// context.setVertexBufferAt(streamOffset + 1, null);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALFragmentCode(shaderObject:ShaderObjectBase, shadedTarget:string):string
+ {
+ return "";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase):string
+ {
+ return "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public doneAGALCode(shaderObject:ShaderObjectBase)
+ {
+
+ }
+}
+
+export = SkeletonAnimationSet;
\ No newline at end of file
diff --git a/lib/animators/SkeletonAnimator.js b/lib/animators/SkeletonAnimator.js
new file mode 100755
index 000000000..6b1010575
--- /dev/null
+++ b/lib/animators/SkeletonAnimator.js
@@ -0,0 +1,533 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+var SubGeometryEvent = require("awayjs-core/lib/events/SubGeometryEvent");
+var AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+var ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+/**
+ * Provides an interface for assigning skeleton-based animation data sets to mesh-based entity objects
+ * and controlling the various available states of animation through an interative playhead that can be
+ * automatically updated or manually triggered.
+ */
+var SkeletonAnimator = (function (_super) {
+ __extends(SkeletonAnimator, _super);
+ /**
+ * Creates a new SkeletonAnimator
object.
+ *
+ * @param skeletonAnimationSet The animation data set containing the skeleton animations used by the animator.
+ * @param skeleton The skeleton object used for calculating the resulting global matrices for transforming skinned mesh data.
+ * @param forceCPU Optional value that only allows the animator to perform calculation on the CPU. Defaults to false.
+ */
+ function SkeletonAnimator(animationSet, skeleton, forceCPU) {
+ var _this = this;
+ if (forceCPU === void 0) { forceCPU = false; }
+ _super.call(this, animationSet);
+ this._globalPose = new SkeletonPose();
+ this._morphedSubGeometry = new Object();
+ this._morphedSubGeometryDirty = new Object();
+ this._skeleton = skeleton;
+ this._forceCPU = forceCPU;
+ this._jointsPerVertex = animationSet.jointsPerVertex;
+ this._numJoints = this._skeleton.numJoints;
+ this._globalMatrices = new Array(this._numJoints * 12);
+ var j = 0;
+ for (var i = 0; i < this._numJoints; ++i) {
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ }
+ this._onTransitionCompleteDelegate = function (event) { return _this.onTransitionComplete(event); };
+ this._onIndicesUpdateDelegate = function (event) { return _this.onIndicesUpdate(event); };
+ this._onVerticesUpdateDelegate = function (event) { return _this.onVerticesUpdate(event); };
+ }
+ Object.defineProperty(SkeletonAnimator.prototype, "globalMatrices", {
+ /**
+ * returns the calculated global matrices of the current skeleton pose.
+ *
+ * @see #globalPose
+ */
+ get: function () {
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+ return this._globalMatrices;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonAnimator.prototype, "globalPose", {
+ /**
+ * returns the current skeleton pose output from the animator.
+ *
+ * @see away.animators.data.SkeletonPose
+ */
+ get: function () {
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+ return this._globalPose;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonAnimator.prototype, "skeleton", {
+ /**
+ * Returns the skeleton object in use by the animator - this defines the number and heirarchy of joints used by the
+ * skinned geoemtry to which skeleon animator is applied.
+ */
+ get: function () {
+ return this._skeleton;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonAnimator.prototype, "forceCPU", {
+ /**
+ * Indicates whether the skeleton animator is disabled by default for GPU rendering, something that allows the animator to perform calculation on the GPU.
+ * Defaults to false.
+ */
+ get: function () {
+ return this._forceCPU;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonAnimator.prototype, "useCondensedIndices", {
+ /**
+ * Offers the option of enabling GPU accelerated animation on skeletons larger than 32 joints
+ * by condensing the number of joint index values required per mesh. Only applicable to
+ * skeleton animations that utilise more than one mesh object. Defaults to false.
+ */
+ get: function () {
+ return this._useCondensedIndices;
+ },
+ set: function (value) {
+ this._useCondensedIndices = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimator.prototype.clone = function () {
+ /* The cast to SkeletonAnimationSet should never fail, as _animationSet can only be set
+ through the constructor, which will only accept a SkeletonAnimationSet. */
+ return new SkeletonAnimator(this._pAnimationSet, this._skeleton, this._forceCPU);
+ };
+ /**
+ * Plays an animation state registered with the given name in the animation data set.
+ *
+ * @param name The data set name of the animation state to be played.
+ * @param transition An optional transition object that determines how the animator will transition from the currently active animation state.
+ * @param offset An option offset time (in milliseconds) that resets the state's internal clock to the absolute time of the animator plus the offset value. Required for non-looping animation states.
+ */
+ SkeletonAnimator.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;
+ if (!this._pAnimationSet.hasAnimation(name))
+ throw new Error("Animation root node " + name + " not found!");
+ if (transition && this._pActiveNode) {
+ //setup the transition
+ this._pActiveNode = transition.getAnimationNode(this, this._pActiveNode, this._pAnimationSet.getAnimation(name), this._pAbsoluteTime);
+ this._pActiveNode.addEventListener(AnimationStateEvent.TRANSITION_COMPLETE, this._onTransitionCompleteDelegate);
+ }
+ else
+ 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._activeSkeletonState = this._pActiveState;
+ this.start();
+ //apply a time offset if specified
+ if (!isNaN(offset))
+ this.reset(name, offset);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimator.prototype.setRenderState = function (shaderObject, renderable, stage, camera, vertexConstantOffset /*int*/, vertexStreamOffset /*int*/) {
+ // do on request of globalProperties
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+ var subGeometry = renderable.subMesh.subGeometry;
+ subGeometry.useCondensedIndices = this._useCondensedIndices;
+ if (this._useCondensedIndices) {
+ // using a condensed data set
+ this.updateCondensedMatrices(subGeometry.condensedIndexLookUp, subGeometry.numCondensedJoints);
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._condensedMatrices, subGeometry.numCondensedJoints * 3);
+ }
+ else {
+ if (this._pAnimationSet.usesCPU) {
+ if (this._morphedSubGeometryDirty[subGeometry.id])
+ this.morphSubGeometry(renderable, subGeometry);
+ return;
+ }
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._globalMatrices, this._numJoints * 3);
+ }
+ stage.context.activateBuffer(vertexStreamOffset, renderable.getVertexData(TriangleSubGeometry.JOINT_INDEX_DATA), renderable.getVertexOffset(TriangleSubGeometry.JOINT_INDEX_DATA), renderable.JOINT_INDEX_FORMAT);
+ stage.context.activateBuffer(vertexStreamOffset + 1, renderable.getVertexData(TriangleSubGeometry.JOINT_WEIGHT_DATA), renderable.getVertexOffset(TriangleSubGeometry.JOINT_WEIGHT_DATA), renderable.JOINT_WEIGHT_FORMAT);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonAnimator.prototype.testGPUCompatibility = function (shaderObject) {
+ if (!this._useCondensedIndices && (this._forceCPU || this._jointsPerVertex > 4 || shaderObject.numUsedVertexConstants + this._numJoints * 3 > 128))
+ this._pAnimationSet.cancelGPUCompatibility();
+ };
+ /**
+ * Applies the calculated time delta to the active animation state node or state transition object.
+ */
+ SkeletonAnimator.prototype._pUpdateDeltaTime = function (dt) {
+ _super.prototype._pUpdateDeltaTime.call(this, dt);
+ //invalidate pose matrices
+ this._globalPropertiesDirty = true;
+ //trigger geometry invalidation if using CPU animation
+ if (this._pAnimationSet.usesCPU)
+ for (var key in this._morphedSubGeometryDirty)
+ this._morphedSubGeometryDirty[key] = true;
+ };
+ SkeletonAnimator.prototype.updateCondensedMatrices = function (condensedIndexLookUp /*uint*/, numJoints /*uint*/) {
+ var i = 0, j = 0;
+ var len /*uint*/;
+ var srcIndex /*uint*/;
+ this._condensedMatrices = new Array();
+ do {
+ srcIndex = condensedIndexLookUp[i] * 4;
+ len = srcIndex + 12;
+ while (srcIndex < len)
+ this._condensedMatrices[j++] = this._globalMatrices[srcIndex++];
+ } while (++i < numJoints);
+ };
+ SkeletonAnimator.prototype.updateGlobalProperties = function () {
+ this._globalPropertiesDirty = false;
+ //get global pose
+ this.localToGlobalPose(this._activeSkeletonState.getSkeletonPose(this._skeleton), this._globalPose, this._skeleton);
+ // convert pose to matrix
+ var mtxOffset = 0;
+ var globalPoses = this._globalPose.jointPoses;
+ var raw;
+ var ox, oy, oz, ow;
+ var xy2, xz2, xw2;
+ var yz2, yw2, zw2;
+ var n11, n12, n13;
+ var n21, n22, n23;
+ var n31, n32, n33;
+ var m11, m12, m13, m14;
+ var m21, m22, m23, m24;
+ var m31, m32, m33, m34;
+ var joints = this._skeleton.joints;
+ var pose;
+ var quat;
+ var vec;
+ var t;
+ for (var i = 0; i < this._numJoints; ++i) {
+ pose = globalPoses[i];
+ quat = pose.orientation;
+ vec = pose.translation;
+ ox = quat.x;
+ oy = quat.y;
+ oz = quat.z;
+ ow = quat.w;
+ xy2 = (t = 2.0 * ox) * oy;
+ xz2 = t * oz;
+ xw2 = t * ow;
+ yz2 = (t = 2.0 * oy) * oz;
+ yw2 = t * ow;
+ zw2 = 2.0 * oz * ow;
+ yz2 = 2.0 * oy * oz;
+ yw2 = 2.0 * oy * ow;
+ zw2 = 2.0 * oz * ow;
+ ox *= ox;
+ oy *= oy;
+ oz *= oz;
+ ow *= ow;
+ n11 = (t = ox - oy) - oz + ow;
+ n12 = xy2 - zw2;
+ n13 = xz2 + yw2;
+ n21 = xy2 + zw2;
+ n22 = -t - oz + ow;
+ n23 = yz2 - xw2;
+ n31 = xz2 - yw2;
+ n32 = yz2 + xw2;
+ n33 = -ox - oy + oz + ow;
+ // prepend inverse bind pose
+ raw = joints[i].inverseBindPose;
+ m11 = raw[0];
+ m12 = raw[4];
+ m13 = raw[8];
+ m14 = raw[12];
+ m21 = raw[1];
+ m22 = raw[5];
+ m23 = raw[9];
+ m24 = raw[13];
+ m31 = raw[2];
+ m32 = raw[6];
+ m33 = raw[10];
+ m34 = raw[14];
+ this._globalMatrices[mtxOffset] = n11 * m11 + n12 * m21 + n13 * m31;
+ this._globalMatrices[mtxOffset + 1] = n11 * m12 + n12 * m22 + n13 * m32;
+ this._globalMatrices[mtxOffset + 2] = n11 * m13 + n12 * m23 + n13 * m33;
+ this._globalMatrices[mtxOffset + 3] = n11 * m14 + n12 * m24 + n13 * m34 + vec.x;
+ this._globalMatrices[mtxOffset + 4] = n21 * m11 + n22 * m21 + n23 * m31;
+ this._globalMatrices[mtxOffset + 5] = n21 * m12 + n22 * m22 + n23 * m32;
+ this._globalMatrices[mtxOffset + 6] = n21 * m13 + n22 * m23 + n23 * m33;
+ this._globalMatrices[mtxOffset + 7] = n21 * m14 + n22 * m24 + n23 * m34 + vec.y;
+ this._globalMatrices[mtxOffset + 8] = n31 * m11 + n32 * m21 + n33 * m31;
+ this._globalMatrices[mtxOffset + 9] = n31 * m12 + n32 * m22 + n33 * m32;
+ this._globalMatrices[mtxOffset + 10] = n31 * m13 + n32 * m23 + n33 * m33;
+ this._globalMatrices[mtxOffset + 11] = n31 * m14 + n32 * m24 + n33 * m34 + vec.z;
+ mtxOffset = mtxOffset + 12;
+ }
+ };
+ SkeletonAnimator.prototype.getRenderableSubGeometry = function (renderable, sourceSubGeometry) {
+ this._morphedSubGeometryDirty[sourceSubGeometry.id] = true;
+ //early out for GPU animations
+ if (!this._pAnimationSet.usesCPU)
+ return sourceSubGeometry;
+ var targetSubGeometry;
+ if (!(targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id])) {
+ //not yet stored
+ targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id] = sourceSubGeometry.clone();
+ //turn off auto calculations on the morphed geometry
+ targetSubGeometry.autoDeriveNormals = false;
+ targetSubGeometry.autoDeriveTangents = false;
+ targetSubGeometry.autoDeriveUVs = false;
+ //add event listeners for any changes in UV values on the source geometry
+ sourceSubGeometry.addEventListener(SubGeometryEvent.INDICES_UPDATED, this._onIndicesUpdateDelegate);
+ sourceSubGeometry.addEventListener(SubGeometryEvent.VERTICES_UPDATED, this._onVerticesUpdateDelegate);
+ }
+ return targetSubGeometry;
+ };
+ /**
+ * If the animation can't be performed on GPU, transform vertices manually
+ * @param subGeom The subgeometry containing the weights and joint index data per vertex.
+ * @param pass The material pass for which we need to transform the vertices
+ */
+ SkeletonAnimator.prototype.morphSubGeometry = function (renderable, sourceSubGeometry) {
+ this._morphedSubGeometryDirty[sourceSubGeometry.id] = false;
+ var sourcePositions = sourceSubGeometry.positions;
+ var sourceNormals = sourceSubGeometry.vertexNormals;
+ var sourceTangents = sourceSubGeometry.vertexTangents;
+ var jointIndices = sourceSubGeometry.jointIndices;
+ var jointWeights = sourceSubGeometry.jointWeights;
+ var targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id];
+ var targetPositions = targetSubGeometry.positions;
+ var targetNormals = targetSubGeometry.vertexNormals;
+ var targetTangents = targetSubGeometry.vertexTangents;
+ var index = 0;
+ var j = 0;
+ var k /*uint*/;
+ var vx, vy, vz;
+ var nx, ny, nz;
+ var tx, ty, tz;
+ var len = sourcePositions.length;
+ var weight;
+ var vertX, vertY, vertZ;
+ var normX, normY, normZ;
+ var tangX, tangY, tangZ;
+ var m11, m12, m13, m14;
+ var m21, m22, m23, m24;
+ var m31, m32, m33, m34;
+ while (index < len) {
+ vertX = sourcePositions[index];
+ vertY = sourcePositions[index + 1];
+ vertZ = sourcePositions[index + 2];
+ normX = sourceNormals[index];
+ normY = sourceNormals[index + 1];
+ normZ = sourceNormals[index + 2];
+ tangX = sourceTangents[index];
+ tangY = sourceTangents[index + 1];
+ tangZ = sourceTangents[index + 2];
+ vx = 0;
+ vy = 0;
+ vz = 0;
+ nx = 0;
+ ny = 0;
+ nz = 0;
+ tx = 0;
+ ty = 0;
+ tz = 0;
+ k = 0;
+ while (k < this._jointsPerVertex) {
+ weight = jointWeights[j];
+ if (weight > 0) {
+ // implicit /3*12 (/3 because indices are multiplied by 3 for gpu matrix access, *12 because it's the matrix size)
+ var mtxOffset = jointIndices[j++] << 2;
+ m11 = this._globalMatrices[mtxOffset];
+ m12 = this._globalMatrices[mtxOffset + 1];
+ m13 = this._globalMatrices[mtxOffset + 2];
+ m14 = this._globalMatrices[mtxOffset + 3];
+ m21 = this._globalMatrices[mtxOffset + 4];
+ m22 = this._globalMatrices[mtxOffset + 5];
+ m23 = this._globalMatrices[mtxOffset + 6];
+ m24 = this._globalMatrices[mtxOffset + 7];
+ m31 = this._globalMatrices[mtxOffset + 8];
+ m32 = this._globalMatrices[mtxOffset + 9];
+ m33 = this._globalMatrices[mtxOffset + 10];
+ m34 = this._globalMatrices[mtxOffset + 11];
+ vx += weight * (m11 * vertX + m12 * vertY + m13 * vertZ + m14);
+ vy += weight * (m21 * vertX + m22 * vertY + m23 * vertZ + m24);
+ vz += weight * (m31 * vertX + m32 * vertY + m33 * vertZ + m34);
+ nx += weight * (m11 * normX + m12 * normY + m13 * normZ);
+ ny += weight * (m21 * normX + m22 * normY + m23 * normZ);
+ nz += weight * (m31 * normX + m32 * normY + m33 * normZ);
+ tx += weight * (m11 * tangX + m12 * tangY + m13 * tangZ);
+ ty += weight * (m21 * tangX + m22 * tangY + m23 * tangZ);
+ tz += weight * (m31 * tangX + m32 * tangY + m33 * tangZ);
+ ++k;
+ }
+ else {
+ j += (this._jointsPerVertex - k);
+ k = this._jointsPerVertex;
+ }
+ }
+ targetPositions[index] = vx;
+ targetPositions[index + 1] = vy;
+ targetPositions[index + 2] = vz;
+ targetNormals[index] = nx;
+ targetNormals[index + 1] = ny;
+ targetNormals[index + 2] = nz;
+ targetTangents[index] = tx;
+ targetTangents[index + 1] = ty;
+ targetTangents[index + 2] = tz;
+ index += 3;
+ }
+ targetSubGeometry.updatePositions(targetPositions);
+ targetSubGeometry.updateVertexNormals(targetNormals);
+ targetSubGeometry.updateVertexTangents(targetTangents);
+ };
+ /**
+ * Converts a local hierarchical skeleton pose to a global pose
+ * @param targetPose The SkeletonPose object that will contain the global pose.
+ * @param skeleton The skeleton containing the joints, and as such, the hierarchical data to transform to global poses.
+ */
+ SkeletonAnimator.prototype.localToGlobalPose = function (sourcePose, targetPose, skeleton) {
+ var globalPoses = targetPose.jointPoses;
+ var globalJointPose;
+ var joints = skeleton.joints;
+ var len = sourcePose.numJointPoses;
+ var jointPoses = sourcePose.jointPoses;
+ var parentIndex /*int*/;
+ var joint;
+ var parentPose;
+ var pose;
+ var or;
+ var tr;
+ var t;
+ var q;
+ var x1, y1, z1, w1;
+ var x2, y2, z2, w2;
+ var x3, y3, z3;
+ // :s
+ if (globalPoses.length != len)
+ globalPoses.length = len;
+ for (var i = 0; i < len; ++i) {
+ globalJointPose = globalPoses[i];
+ if (globalJointPose == null)
+ globalJointPose = globalPoses[i] = new JointPose();
+ joint = joints[i];
+ parentIndex = joint.parentIndex;
+ pose = jointPoses[i];
+ q = globalJointPose.orientation;
+ t = globalJointPose.translation;
+ if (parentIndex < 0) {
+ tr = pose.translation;
+ or = pose.orientation;
+ q.x = or.x;
+ q.y = or.y;
+ q.z = or.z;
+ q.w = or.w;
+ t.x = tr.x;
+ t.y = tr.y;
+ t.z = tr.z;
+ }
+ else {
+ // append parent pose
+ parentPose = globalPoses[parentIndex];
+ // rotate point
+ or = parentPose.orientation;
+ tr = pose.translation;
+ x2 = or.x;
+ y2 = or.y;
+ z2 = or.z;
+ w2 = or.w;
+ x3 = tr.x;
+ y3 = tr.y;
+ z3 = tr.z;
+ w1 = -x2 * x3 - y2 * y3 - z2 * z3;
+ x1 = w2 * x3 + y2 * z3 - z2 * y3;
+ y1 = w2 * y3 - x2 * z3 + z2 * x3;
+ z1 = w2 * z3 + x2 * y3 - y2 * x3;
+ // append parent translation
+ tr = parentPose.translation;
+ t.x = -w1 * x2 + x1 * w2 - y1 * z2 + z1 * y2 + tr.x;
+ t.y = -w1 * y2 + x1 * z2 + y1 * w2 - z1 * x2 + tr.y;
+ t.z = -w1 * z2 - x1 * y2 + y1 * x2 + z1 * w2 + tr.z;
+ // append parent orientation
+ x1 = or.x;
+ y1 = or.y;
+ z1 = or.z;
+ w1 = or.w;
+ or = pose.orientation;
+ x2 = or.x;
+ y2 = or.y;
+ z2 = or.z;
+ w2 = or.w;
+ q.w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2;
+ q.x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2;
+ q.y = w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2;
+ q.z = w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2;
+ }
+ }
+ };
+ SkeletonAnimator.prototype.onTransitionComplete = function (event) {
+ if (event.type == AnimationStateEvent.TRANSITION_COMPLETE) {
+ event.animationNode.removeEventListener(AnimationStateEvent.TRANSITION_COMPLETE, this._onTransitionCompleteDelegate);
+ //if this is the current active state transition, revert control to the active node
+ if (this._pActiveState == event.animationState) {
+ this._pActiveNode = this._pAnimationSet.getAnimation(this._pActiveAnimationName);
+ this._pActiveState = this.getAnimationState(this._pActiveNode);
+ this._activeSkeletonState = this._pActiveState;
+ }
+ }
+ };
+ SkeletonAnimator.prototype.onIndicesUpdate = function (event) {
+ var subGeometry = event.target;
+ this._morphedSubGeometry[subGeometry.id].updateIndices(subGeometry.indices);
+ };
+ SkeletonAnimator.prototype.onVerticesUpdate = function (event) {
+ var subGeometry = event.target;
+ var morphGeometry = this._morphedSubGeometry[subGeometry.id];
+ switch (event.dataType) {
+ case TriangleSubGeometry.UV_DATA:
+ morphGeometry.updateUVs(subGeometry.uvs);
+ case TriangleSubGeometry.SECONDARY_UV_DATA:
+ morphGeometry.updateUVs(subGeometry.secondaryUVs);
+ }
+ };
+ return SkeletonAnimator;
+})(AnimatorBase);
+module.exports = SkeletonAnimator;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9za2VsZXRvbmFuaW1hdG9yLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uQW5pbWF0b3IiLCJTa2VsZXRvbkFuaW1hdG9yLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25BbmltYXRvci5nbG9iYWxNYXRyaWNlcyIsIlNrZWxldG9uQW5pbWF0b3IuZ2xvYmFsUG9zZSIsIlNrZWxldG9uQW5pbWF0b3Iuc2tlbGV0b24iLCJTa2VsZXRvbkFuaW1hdG9yLmZvcmNlQ1BVIiwiU2tlbGV0b25BbmltYXRvci51c2VDb25kZW5zZWRJbmRpY2VzIiwiU2tlbGV0b25BbmltYXRvci5jbG9uZSIsIlNrZWxldG9uQW5pbWF0b3IucGxheSIsIlNrZWxldG9uQW5pbWF0b3Iuc2V0UmVuZGVyU3RhdGUiLCJTa2VsZXRvbkFuaW1hdG9yLnRlc3RHUFVDb21wYXRpYmlsaXR5IiwiU2tlbGV0b25BbmltYXRvci5fcFVwZGF0ZURlbHRhVGltZSIsIlNrZWxldG9uQW5pbWF0b3IudXBkYXRlQ29uZGVuc2VkTWF0cmljZXMiLCJTa2VsZXRvbkFuaW1hdG9yLnVwZGF0ZUdsb2JhbFByb3BlcnRpZXMiLCJTa2VsZXRvbkFuaW1hdG9yLmdldFJlbmRlcmFibGVTdWJHZW9tZXRyeSIsIlNrZWxldG9uQW5pbWF0b3IubW9ycGhTdWJHZW9tZXRyeSIsIlNrZWxldG9uQW5pbWF0b3IubG9jYWxUb0dsb2JhbFBvc2UiLCJTa2VsZXRvbkFuaW1hdG9yLm9uVHJhbnNpdGlvbkNvbXBsZXRlIiwiU2tlbGV0b25BbmltYXRvci5vbkluZGljZXNVcGRhdGUiLCJTa2VsZXRvbkFuaW1hdG9yLm9uVmVydGljZXNVcGRhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLElBQU8sbUJBQW1CLFdBQWMsK0NBQStDLENBQUMsQ0FBQztBQUt6RixJQUFPLGdCQUFnQixXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFFakYsSUFBTyxZQUFZLFdBQWdCLDJDQUEyQyxDQUFDLENBQUM7QUFJaEYsSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBS2pHLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBR2xGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBR3hGLElBQU8sbUJBQW1CLFdBQWMsa0RBQWtELENBQUMsQ0FBQztBQUU1RixBQUtBOzs7O0dBREc7SUFDRyxnQkFBZ0I7SUFBU0EsVUFBekJBLGdCQUFnQkEsVUFBcUJBO0lBK0UxQ0E7Ozs7OztPQU1HQTtJQUNIQSxTQXRGS0EsZ0JBQWdCQSxDQXNGVEEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxRQUF3QkE7UUF0RjNGQyxpQkFxbEJDQTtRQS9ma0VBLHdCQUF3QkEsR0FBeEJBLGdCQUF3QkE7UUFFekZBLGtCQUFNQSxZQUFZQSxDQUFDQSxDQUFDQTtRQXJGYkEsZ0JBQVdBLEdBQWdCQSxJQUFJQSxZQUFZQSxFQUFFQSxDQUFDQTtRQUc5Q0Esd0JBQW1CQSxHQUFVQSxJQUFJQSxNQUFNQSxFQUFFQSxDQUFDQTtRQUMxQ0EsNkJBQXdCQSxHQUFVQSxJQUFJQSxNQUFNQSxFQUFFQSxDQUFDQTtRQW1GdERBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLFFBQVFBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUMxQkEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxZQUFZQSxDQUFDQSxlQUFlQSxDQUFDQTtRQUVyREEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDM0NBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLEtBQUtBLENBQVNBLElBQUlBLENBQUNBLFVBQVVBLEdBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBRTdEQSxJQUFJQSxDQUFDQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7UUFDekJBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUMxREEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDOUJBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDOUJBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDOUJBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDOUJBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUMvQkEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsNkJBQTZC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QUNBLEVBQUVBLENBQUNBO1lBQ3RCQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQTtZQUNYQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQTtZQUNYQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQTtZQUN0QkEsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDWEEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsRUFBRUEsR0FBQ0EsRUFBRUEsQ0FBQ0E7WUFFaEJBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEVBQUVBLEdBQUNBLEVBQUVBLENBQUNBO1lBQ2hCQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxDQUFDQTtZQUNoQkEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsRUFBRUEsR0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDaEJBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBQ1RBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBQ1RBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBQ1RBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBRVRBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBO1lBQzlCQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQTtZQUNoQkEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0E7WUFDaEJBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBO1lBQ2hCQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQTtZQUNuQkEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0E7WUFDaEJBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBO1lBQ2hCQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQTtZQUNoQkEsR0FBR0EsR0FBR0EsQ0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7WUFFekJBLEFBQ0FBLDRCQUQ0QkE7WUFDNUJBLEdBQUdBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBLGVBQWVBLENBQUNBO1lBQ2hDQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUNkQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUNkQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNiQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUNkQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUVkQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtZQUM5REEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7WUFDbEVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO1lBQ2xFQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMxRUEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7WUFDbEVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO1lBQ2xFQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtZQUNsRUEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0Es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QUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMUNBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUMxQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzFDQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMUNBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUMxQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7b0JBQzNDQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQTtvQkFDM0NBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBO29CQUN2REEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDdkRBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLENBQUNBLENBQUNBO29CQUNqREEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtvQkFDakRBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLENBQUNBLENBQUNBO29CQUNqREEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtvQkFDakRBLEVBQUVBLENBQUNBLENBQUNBO2dCQUNMQSxDQUFDQTtnQkFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7b0JBQ1BBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBO2dCQUMzQkEsQ0FBQ0E7WUFDRkEsQ0FBQ0E7WUFFREEsZUFBZUEsQ0FBQ0EsS0FBS0Es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cERBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xCQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUNoQ0EsSUFBSUEsR0FBR0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFckJBLENBQUNBLEdBQUdBLGVBQWVBLENBQUNBLFdBQVdBLENBQUNBO1lBQ2hDQSxDQUFDQSxHQUFHQSxlQUFlQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUVoQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsV0FBV0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JCQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDdEJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO2dCQUN0QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1hBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNYQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDWEEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1hBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNYQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDWEEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDWkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ1BBLEFBQ0FBLHFCQURxQkE7Z0JBQ3JCQSxVQUFVQSxHQUFHQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtnQkFFdENBLEFBQ0FBLGVBRGVBO2dCQUNmQSxFQUFFQSxHQUFHQSxVQUFVQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDNUJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO2dCQUN0QkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRVZBLEVBQUVBLEdBQUdBLENBQUNBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLENBQUNBO2dCQUM1QkEsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsQ0FBQ0E7Z0JBQzNCQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxDQUFDQTtnQkFDM0JBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLENBQUNBO2dCQUUzQkEsQUFDQUEsNEJBRDRCQTtnQkFDNUJBLEVBQUVBLEdBQUdBLFVBQVVBLENBQUNBLFdBQVdBLENBQUNBO2dCQUM1QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzVDQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDNUNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUU1Q0EsQUFDQUEsNEJBRDRCQTtnQkFDNUJBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDdEJBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUVWQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFH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Q0FBQyIsImZpbGUiOiJhbmltYXRvcnMvU2tlbGV0b25BbmltYXRvci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBJU3ViTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9JU3ViTWVzaFwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL1RyaWFuZ2xlU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJNZXNoXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJNZXNoXCIpO1xuaW1wb3J0IFF1YXRlcm5pb25cdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1F1YXRlcm5pb25cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuaW1wb3J0IFN1Ykdlb21ldHJ5RXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9TdWJHZW9tZXRyeUV2ZW50XCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvVHJpYW5nbGVTdWJNZXNoUmVuZGVyYWJsZVwiKTtcbmltcG9ydCBDb250ZXh0R0xQcm9ncmFtVHlwZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xQcm9ncmFtVHlwZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5cbmltcG9ydCBTa2VsZXRvbkFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9Ta2VsZXRvbkFuaW1hdGlvblNldFwiKTtcbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Kb2ludFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25Kb2ludFwiKTtcbmltcG9ydCBTa2VsZXRvblBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25Qb3NlXCIpO1xuaW1wb3J0IElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcIik7XG5pbXBvcnQgSUFuaW1hdGlvblRyYW5zaXRpb25cdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvdHJhbnNpdGlvbnMvSUFuaW1hdGlvblRyYW5zaXRpb25cIik7XG5pbXBvcnQgQW5pbWF0aW9uU3RhdGVFdmVudFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2V2ZW50cy9BbmltYXRpb25TdGF0ZUV2ZW50XCIpO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgYXNzaWduaW5nIHNrZWxldG9uLWJhc2VkIGFuaW1hdGlvbiBkYXRhIHNldHMgdG8gbWVzaC1iYXNlZCBlbnRpdHkgb2JqZWN0c1xuICogYW5kIGNvbnRyb2xsaW5nIHRoZSB2YXJpb3VzIGF2YWlsYWJsZSBzdGF0ZXMgb2YgYW5pbWF0aW9uIHRocm91Z2ggYW4gaW50ZXJhdGl2ZSBwbGF5aGVhZCB0aGF0IGNhbiBiZVxuICogYXV0b21hdGljYWxseSB1cGRhdGVkIG9yIG1hbnVhbGx5IHRyaWdnZXJlZC5cbiAqL1xuY2xhc3MgU2tlbGV0b25BbmltYXRvciBleHRlbmRzIEFuaW1hdG9yQmFzZVxue1xuXHRwcml2YXRlIF9nbG9iYWxNYXRyaWNlczpBcnJheTxudW1iZXI+O1xuXHRwcml2YXRlIF9nbG9iYWxQb3NlOlNrZWxldG9uUG9zZSA9IG5ldyBTa2VsZXRvblBvc2UoKTtcblx0cHJpdmF0ZSBfZ2xvYmFsUHJvcGVydGllc0RpcnR5OmJvb2xlYW47XG5cdHByaXZhdGUgX251bUpvaW50czpudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX21vcnBoZWRTdWJHZW9tZXRyeTpPYmplY3QgPSBuZXcgT2JqZWN0KCk7XG5cdHByaXZhdGUgX21vcnBoZWRTdWJHZW9tZXRyeURpcnR5Ok9iamVjdCA9IG5ldyBPYmplY3QoKTtcblx0cHJpdmF0ZSBfY29uZGVuc2VkTWF0cmljZXM6QXJyYXk8bnVtYmVyPjtcblxuXHRwcml2YXRlIF9za2VsZXRvbjpTa2VsZXRvbjtcblx0cHJpdmF0ZSBfZm9yY2VDUFU6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfdXNlQ29uZGVuc2VkSW5kaWNlczpib29sZWFuO1xuXHRwcml2YXRlIF9qb2ludHNQZXJWZXJ0ZXg6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9hY3RpdmVTa2VsZXRvblN0YXRlOklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXHRwcml2YXRlIF9vblRyYW5zaXRpb25Db21wbGV0ZURlbGVnYXRlOihldmVudDpBbmltYXRpb25TdGF0ZUV2ZW50KSA9PiB2b2lkO1xuXG5cdHByaXZhdGUgX29uSW5kaWNlc1VwZGF0ZURlbGVnYXRlOihldmVudDpTdWJHZW9tZXRyeUV2ZW50KSA9PiB2b2lkO1xuXHRwcml2YXRlIF9vblZlcnRpY2VzVXBkYXRlRGVsZWdhdGU6KGV2ZW50OlN1Ykdlb21ldHJ5RXZlbnQpID0+IHZvaWQ7XG5cblx0LyoqXG5cdCAqIHJldHVybnMgdGhlIGNhbGN1bGF0ZWQgZ2xvYmFsIG1hdHJpY2VzIG9mIHRoZSBjdXJyZW50IHNrZWxldG9uIHBvc2UuXG5cdCAqXG5cdCAqIEBzZWUgI2dsb2JhbFBvc2Vcblx0ICovXG5cdHB1YmxpYyBnZXQgZ2xvYmFsTWF0cmljZXMoKTpBcnJheTxudW1iZXI+XG5cdHtcblx0XHRpZiAodGhpcy5fZ2xvYmFsUHJvcGVydGllc0RpcnR5KVxuXHRcdFx0dGhpcy51cGRhdGVHbG9iYWxQcm9wZXJ0aWVzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fZ2xvYmFsTWF0cmljZXM7XG5cdH1cblxuXHQvKipcblx0ICogcmV0dXJucyB0aGUgY3VycmVudCBza2VsZXRvbiBwb3NlIG91dHB1dCBmcm9tIHRoZSBhbmltYXRvci5cblx0ICpcblx0ICogQHNlZSBhd2F5LmFuaW1hdG9ycy5kYXRhLlNrZWxldG9uUG9zZVxuXHQgKi9cblx0cHVibGljIGdldCBnbG9iYWxQb3NlKCk6U2tlbGV0b25Qb3NlXG5cdHtcblx0XHRpZiAodGhpcy5fZ2xvYmFsUHJvcGVydGllc0RpcnR5KVxuXHRcdFx0dGhpcy51cGRhdGVHbG9iYWxQcm9wZXJ0aWVzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fZ2xvYmFsUG9zZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBza2VsZXRvbiBvYmplY3QgaW4gdXNlIGJ5IHRoZSBhbmltYXRvciAtIHRoaXMgZGVmaW5lcyB0aGUgbnVtYmVyIGFuZCBoZWlyYXJjaHkgb2Ygam9pbnRzIHVzZWQgYnkgdGhlXG5cdCAqIHNraW5uZWQgZ2VvZW10cnkgdG8gd2hpY2ggc2tlbGVvbiBhbmltYXRvciBpcyBhcHBsaWVkLlxuXHQgKi9cblx0cHVibGljIGdldCBza2VsZXRvbigpOlNrZWxldG9uXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc2tlbGV0b247XG5cdH1cblxuXHQvKipcblx0ICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNrZWxldG9uIGFuaW1hdG9yIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQgZm9yIEdQVSByZW5kZXJpbmcsIHNvbWV0aGluZyB0aGF0IGFsbG93cyB0aGUgYW5pbWF0b3IgdG8gcGVyZm9ybSBjYWxjdWxhdGlvbiBvbiB0aGUgR1BVLlxuXHQgKiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgZm9yY2VDUFUoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZm9yY2VDUFU7XG5cdH1cblxuXHQvKipcblx0ICogT2ZmZXJzIHRoZSBvcHRpb24gb2YgZW5hYmxpbmcgR1BVIGFjY2VsZXJhdGVkIGFuaW1hdGlvbiBvbiBza2VsZXRvbnMgbGFyZ2VyIHRoYW4gMzIgam9pbnRzXG5cdCAqIGJ5IGNvbmRlbnNpbmcgdGhlIG51bWJlciBvZiBqb2ludCBpbmRleCB2YWx1ZXMgcmVxdWlyZWQgcGVyIG1lc2guIE9ubHkgYXBwbGljYWJsZSB0b1xuXHQgKiBza2VsZXRvbiBhbmltYXRpb25zIHRoYXQgdXRpbGlzZSBtb3JlIHRoYW4gb25lIG1lc2ggb2JqZWN0LiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgdXNlQ29uZGVuc2VkSW5kaWNlcygpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiB0aGlzLl91c2VDb25kZW5zZWRJbmRpY2VzO1xuXHR9XG5cblx0cHVibGljIHNldCB1c2VDb25kZW5zZWRJbmRpY2VzKHZhbHVlOmJvb2xlYW4pXG5cdHtcblx0XHR0aGlzLl91c2VDb25kZW5zZWRJbmRpY2VzID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvbkFuaW1hdG9yPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBza2VsZXRvbkFuaW1hdGlvblNldCBUaGUgYW5pbWF0aW9uIGRhdGEgc2V0IGNvbnRhaW5pbmcgdGhlIHNrZWxldG9uIGFuaW1hdGlvbnMgdXNlZCBieSB0aGUgYW5pbWF0b3IuXG5cdCAqIEBwYXJhbSBza2VsZXRvbiBUaGUgc2tlbGV0b24gb2JqZWN0IHVzZWQgZm9yIGNhbGN1bGF0aW5nIHRoZSByZXN1bHRpbmcgZ2xvYmFsIG1hdHJpY2VzIGZvciB0cmFuc2Zvcm1pbmcgc2tpbm5lZCBtZXNoIGRhdGEuXG5cdCAqIEBwYXJhbSBmb3JjZUNQVSBPcHRpb25hbCB2YWx1ZSB0aGF0IG9ubHkgYWxsb3dzIHRoZSBhbmltYXRvciB0byBwZXJmb3JtIGNhbGN1bGF0aW9uIG9uIHRoZSBDUFUuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoYW5pbWF0aW9uU2V0OlNrZWxldG9uQW5pbWF0aW9uU2V0LCBza2VsZXRvbjpTa2VsZXRvbiwgZm9yY2VDUFU6Ym9vbGVhbiA9IGZhbHNlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0aW9uU2V0KTtcblxuXHRcdHRoaXMuX3NrZWxldG9uID0gc2tlbGV0b247XG5cdFx0dGhpcy5fZm9yY2VDUFUgPSBmb3JjZUNQVTtcblx0XHR0aGlzLl9qb2ludHNQZXJWZXJ0ZXggPSBhbmltYXRpb25TZXQuam9pbnRzUGVyVmVydGV4O1xuXG5cdFx0dGhpcy5fbnVtSm9pbnRzID0gdGhpcy5fc2tlbGV0b24ubnVtSm9pbnRzO1xuXHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5fbnVtSm9pbnRzKjEyKTtcblxuXHRcdHZhciBqOm51bWJlciAvKmludCovID0gMDtcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKnVpbnQqLyA9IDA7IGkgPCB0aGlzLl9udW1Kb2ludHM7ICsraSkge1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbaisrXSA9IDE7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1tqKytdID0gMDtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW2orK10gPSAwO1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbaisrXSA9IDA7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1tqKytdID0gMDtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW2orK10gPSAxO1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbaisrXSA9IDA7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1tqKytdID0gMDtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW2orK10gPSAwO1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbaisrXSA9IDA7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1tqKytdID0gMTtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW2orK10gPSAwO1xuXHRcdH1cblxuXHRcdHRoaXMuX29uVHJhbnNpdGlvbkNvbXBsZXRlRGVsZWdhdGUgPSAoZXZlbnQ6QW5pbWF0aW9uU3RhdGVFdmVudCkgPT4gdGhpcy5vblRyYW5zaXRpb25Db21wbGV0ZShldmVudCk7XG5cdFx0dGhpcy5fb25JbmRpY2VzVXBkYXRlRGVsZWdhdGUgPSAoZXZlbnQ6U3ViR2VvbWV0cnlFdmVudCkgPT4gdGhpcy5vbkluZGljZXNVcGRhdGUoZXZlbnQpO1xuXHRcdHRoaXMuX29uVmVydGljZXNVcGRhdGVEZWxlZ2F0ZSA9IChldmVudDpTdWJHZW9tZXRyeUV2ZW50KSA9PiB0aGlzLm9uVmVydGljZXNVcGRhdGUoZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgY2xvbmUoKTpBbmltYXRvckJhc2Vcblx0e1xuXHRcdC8qIFRoZSBjYXN0IHRvIFNrZWxldG9uQW5pbWF0aW9uU2V0IHNob3VsZCBuZXZlciBmYWlsLCBhcyBfYW5pbWF0aW9uU2V0IGNhbiBvbmx5IGJlIHNldFxuXHRcdCB0aHJvdWdoIHRoZSBjb25zdHJ1Y3Rvciwgd2hpY2ggd2lsbCBvbmx5IGFjY2VwdCBhIFNrZWxldG9uQW5pbWF0aW9uU2V0LiAqL1xuXHRcdHJldHVybiBuZXcgU2tlbGV0b25BbmltYXRvcig8U2tlbGV0b25BbmltYXRpb25TZXQ+IHRoaXMuX3BBbmltYXRpb25TZXQsIHRoaXMuX3NrZWxldG9uLCB0aGlzLl9mb3JjZUNQVSk7XG5cdH1cblxuXHQvKipcblx0ICogUGxheXMgYW4gYW5pbWF0aW9uIHN0YXRlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBpbiB0aGUgYW5pbWF0aW9uIGRhdGEgc2V0LlxuXHQgKlxuXHQgKiBAcGFyYW0gbmFtZSBUaGUgZGF0YSBzZXQgbmFtZSBvZiB0aGUgYW5pbWF0aW9uIHN0YXRlIHRvIGJlIHBsYXllZC5cblx0ICogQHBhcmFtIHRyYW5zaXRpb24gQW4gb3B0aW9uYWwgdHJhbnNpdGlvbiBvYmplY3QgdGhhdCBkZXRlcm1pbmVzIGhvdyB0aGUgYW5pbWF0b3Igd2lsbCB0cmFuc2l0aW9uIGZyb20gdGhlIGN1cnJlbnRseSBhY3RpdmUgYW5pbWF0aW9uIHN0YXRlLlxuXHQgKiBAcGFyYW0gb2Zmc2V0IEFuIG9wdGlvbiBvZmZzZXQgdGltZSAoaW4gbWlsbGlzZWNvbmRzKSB0aGF0IHJlc2V0cyB0aGUgc3RhdGUncyBpbnRlcm5hbCBjbG9jayB0byB0aGUgYWJzb2x1dGUgdGltZSBvZiB0aGUgYW5pbWF0b3IgcGx1cyB0aGUgb2Zmc2V0IHZhbHVlLiBSZXF1aXJlZCBmb3Igbm9uLWxvb3BpbmcgYW5pbWF0aW9uIHN0YXRlcy5cblx0ICovXG5cdHB1YmxpYyBwbGF5KG5hbWU6c3RyaW5nLCB0cmFuc2l0aW9uOklBbmltYXRpb25UcmFuc2l0aW9uID0gbnVsbCwgb2Zmc2V0Om51bWJlciA9IE5hTilcblx0e1xuXHRcdGlmICh0aGlzLl9wQWN0aXZlQW5pbWF0aW9uTmFtZSA9PSBuYW1lKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5fcEFjdGl2ZUFuaW1hdGlvbk5hbWUgPSBuYW1lO1xuXG5cdFx0aWYgKCF0aGlzLl9wQW5pbWF0aW9uU2V0Lmhhc0FuaW1hdGlvbihuYW1lKSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkFuaW1hdGlvbiByb290IG5vZGUgXCIgKyBuYW1lICsgXCIgbm90IGZvdW5kIVwiKTtcblxuXHRcdGlmICh0cmFuc2l0aW9uICYmIHRoaXMuX3BBY3RpdmVOb2RlKSB7XG5cdFx0XHQvL3NldHVwIHRoZSB0cmFuc2l0aW9uXG5cdFx0XHR0aGlzLl9wQWN0aXZlTm9kZSA9IHRyYW5zaXRpb24uZ2V0QW5pbWF0aW9uTm9kZSh0aGlzLCB0aGlzLl9wQWN0aXZlTm9kZSwgdGhpcy5fcEFuaW1hdGlvblNldC5nZXRBbmltYXRpb24obmFtZSksIHRoaXMuX3BBYnNvbHV0ZVRpbWUpO1xuXHRcdFx0dGhpcy5fcEFjdGl2ZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcihBbmltYXRpb25TdGF0ZUV2ZW50LlRSQU5TSVRJT05fQ09NUExFVEUsIHRoaXMuX29uVHJhbnNpdGlvbkNvbXBsZXRlRGVsZWdhdGUpO1xuXHRcdH0gZWxzZVxuXHRcdFx0dGhpcy5fcEFjdGl2ZU5vZGUgPSB0aGlzLl9wQW5pbWF0aW9uU2V0LmdldEFuaW1hdGlvbihuYW1lKTtcblxuXHRcdHRoaXMuX3BBY3RpdmVTdGF0ZSA9IHRoaXMuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcy5fcEFjdGl2ZU5vZGUpO1xuXG5cdFx0aWYgKHRoaXMudXBkYXRlUG9zaXRpb24pIHtcblx0XHRcdC8vdXBkYXRlIHN0cmFpZ2h0IGF3YXkgdG8gcmVzZXQgcG9zaXRpb24gZGVsdGFzXG5cdFx0XHR0aGlzLl9wQWN0aXZlU3RhdGUudXBkYXRlKHRoaXMuX3BBYnNvbHV0ZVRpbWUpO1xuXHRcdFx0dGhpcy5fcEFjdGl2ZVN0YXRlLnBvc2l0aW9uRGVsdGE7XG5cdFx0fVxuXG5cdFx0dGhpcy5fYWN0aXZlU2tlbGV0b25TdGF0ZSA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gdGhpcy5fcEFjdGl2ZVN0YXRlO1xuXG5cdFx0dGhpcy5zdGFydCgpO1xuXG5cdFx0Ly9hcHBseSBhIHRpbWUgb2Zmc2V0IGlmIHNwZWNpZmllZFxuXHRcdGlmICghaXNOYU4ob2Zmc2V0KSlcblx0XHRcdHRoaXMucmVzZXQobmFtZSwgb2Zmc2V0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSwgdmVydGV4Q29uc3RhbnRPZmZzZXQ6bnVtYmVyIC8qaW50Ki8sIHZlcnRleFN0cmVhbU9mZnNldDpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdC8vIGRvIG9uIHJlcXVlc3Qgb2YgZ2xvYmFsUHJvcGVydGllc1xuXHRcdGlmICh0aGlzLl9nbG9iYWxQcm9wZXJ0aWVzRGlydHkpXG5cdFx0XHR0aGlzLnVwZGF0ZUdsb2JhbFByb3BlcnRpZXMoKTtcblxuXHRcdHZhciBzdWJHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5ID0gPFRyaWFuZ2xlU3ViR2VvbWV0cnk+ICg8VHJpYW5nbGVTdWJNZXNoPiAoPFRyaWFuZ2xlU3ViTWVzaFJlbmRlcmFibGU+IHJlbmRlcmFibGUpLnN1Yk1lc2gpLnN1Ykdlb21ldHJ5O1xuXG5cdFx0c3ViR2VvbWV0cnkudXNlQ29uZGVuc2VkSW5kaWNlcyA9IHRoaXMuX3VzZUNvbmRlbnNlZEluZGljZXM7XG5cblx0XHRpZiAodGhpcy5fdXNlQ29uZGVuc2VkSW5kaWNlcykge1xuXHRcdFx0Ly8gdXNpbmcgYSBjb25kZW5zZWQgZGF0YSBzZXRcblx0XHRcdHRoaXMudXBkYXRlQ29uZGVuc2VkTWF0cmljZXMoc3ViR2VvbWV0cnkuY29uZGVuc2VkSW5kZXhMb29rVXAsIHN1Ykdlb21ldHJ5Lm51bUNvbmRlbnNlZEpvaW50cyk7XG5cdFx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21BcnJheShDb250ZXh0R0xQcm9ncmFtVHlwZS5WRVJURVgsIHZlcnRleENvbnN0YW50T2Zmc2V0LCB0aGlzLl9jb25kZW5zZWRNYXRyaWNlcywgc3ViR2VvbWV0cnkubnVtQ29uZGVuc2VkSm9pbnRzKjMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5fcEFuaW1hdGlvblNldC51c2VzQ1BVKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9tb3JwaGVkU3ViR2VvbWV0cnlEaXJ0eVtzdWJHZW9tZXRyeS5pZF0pXG5cdFx0XHRcdFx0dGhpcy5tb3JwaFN1Ykdlb21ldHJ5KDxUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlPiByZW5kZXJhYmxlLCBzdWJHZW9tZXRyeSk7XG5cblx0XHRcdFx0cmV0dXJuXG5cdFx0XHR9XG5cdFx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21BcnJheShDb250ZXh0R0xQcm9ncmFtVHlwZS5WRVJURVgsIHZlcnRleENvbnN0YW50T2Zmc2V0LCB0aGlzLl9nbG9iYWxNYXRyaWNlcywgdGhpcy5fbnVtSm9pbnRzKjMpO1xuXHRcdH1cblxuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZUJ1ZmZlcih2ZXJ0ZXhTdHJlYW1PZmZzZXQsIHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LkpPSU5UX0lOREVYX0RBVEEpLCByZW5kZXJhYmxlLmdldFZlcnRleE9mZnNldChUcmlhbmdsZVN1Ykdlb21ldHJ5LkpPSU5UX0lOREVYX0RBVEEpLCByZW5kZXJhYmxlLkpPSU5UX0lOREVYX0ZPUk1BVCk7XG5cdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlQnVmZmVyKHZlcnRleFN0cmVhbU9mZnNldCArIDEsIHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LkpPSU5UX1dFSUdIVF9EQVRBKSwgcmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5KT0lOVF9XRUlHSFRfREFUQSksIHJlbmRlcmFibGUuSk9JTlRfV0VJR0hUX0ZPUk1BVCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyB0ZXN0R1BVQ29tcGF0aWJpbGl0eShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSlcblx0e1xuXHRcdGlmICghdGhpcy5fdXNlQ29uZGVuc2VkSW5kaWNlcyAmJiAodGhpcy5fZm9yY2VDUFUgfHwgdGhpcy5fam9pbnRzUGVyVmVydGV4ID4gNCB8fCBzaGFkZXJPYmplY3QubnVtVXNlZFZlcnRleENvbnN0YW50cyArIHRoaXMuX251bUpvaW50cyozID4gMTI4KSlcblx0XHRcdHRoaXMuX3BBbmltYXRpb25TZXQuY2FuY2VsR1BVQ29tcGF0aWJpbGl0eSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGxpZXMgdGhlIGNhbGN1bGF0ZWQgdGltZSBkZWx0YSB0byB0aGUgYWN0aXZlIGFuaW1hdGlvbiBzdGF0ZSBub2RlIG9yIHN0YXRlIHRyYW5zaXRpb24gb2JqZWN0LlxuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlRGVsdGFUaW1lKGR0Om51bWJlcilcblx0e1xuXHRcdHN1cGVyLl9wVXBkYXRlRGVsdGFUaW1lKGR0KTtcblxuXHRcdC8vaW52YWxpZGF0ZSBwb3NlIG1hdHJpY2VzXG5cdFx0dGhpcy5fZ2xvYmFsUHJvcGVydGllc0RpcnR5ID0gdHJ1ZTtcblxuXHRcdC8vdHJpZ2dlciBnZW9tZXRyeSBpbnZhbGlkYXRpb24gaWYgdXNpbmcgQ1BVIGFuaW1hdGlvblxuXHRcdGlmICh0aGlzLl9wQW5pbWF0aW9uU2V0LnVzZXNDUFUpXG5cdFx0XHRmb3IgKHZhciBrZXkgaW4gdGhpcy5fbW9ycGhlZFN1Ykdlb21ldHJ5RGlydHkpXG5cdFx0XHRcdHRoaXMuX21vcnBoZWRTdWJHZW9tZXRyeURpcnR5W2tleV0gPSB0cnVlO1xuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVDb25kZW5zZWRNYXRyaWNlcyhjb25kZW5zZWRJbmRleExvb2tVcDpBcnJheTxudW1iZXI+IC8qdWludCovLCBudW1Kb2ludHM6bnVtYmVyIC8qdWludCovKVxuXHR7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovID0gMCwgajpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBzcmNJbmRleDpudW1iZXIgLyp1aW50Ki87XG5cblx0XHR0aGlzLl9jb25kZW5zZWRNYXRyaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cblx0XHRkbyB7XG5cdFx0XHRzcmNJbmRleCA9IGNvbmRlbnNlZEluZGV4TG9va1VwW2ldKjQ7XG5cdFx0XHRsZW4gPSBzcmNJbmRleCArIDEyO1xuXHRcdFx0Ly8gY29weSBpbnRvIGNvbmRlbnNlZFxuXHRcdFx0d2hpbGUgKHNyY0luZGV4IDwgbGVuKVxuXHRcdFx0XHR0aGlzLl9jb25kZW5zZWRNYXRyaWNlc1tqKytdID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbc3JjSW5kZXgrK107XG5cdFx0fSB3aGlsZSAoKytpIDwgbnVtSm9pbnRzKTtcblx0fVxuXG5cdHByaXZhdGUgdXBkYXRlR2xvYmFsUHJvcGVydGllcygpXG5cdHtcblx0XHR0aGlzLl9nbG9iYWxQcm9wZXJ0aWVzRGlydHkgPSBmYWxzZTtcblxuXHRcdC8vZ2V0IGdsb2JhbCBwb3NlXG5cdFx0dGhpcy5sb2NhbFRvR2xvYmFsUG9zZSh0aGlzLl9hY3RpdmVTa2VsZXRvblN0YXRlLmdldFNrZWxldG9uUG9zZSh0aGlzLl9za2VsZXRvbiksIHRoaXMuX2dsb2JhbFBvc2UsIHRoaXMuX3NrZWxldG9uKTtcblxuXHRcdC8vIGNvbnZlcnQgcG9zZSB0byBtYXRyaXhcblx0XHR2YXIgbXR4T2Zmc2V0Om51bWJlciAvKnVpbnQqLyA9IDA7XG5cdFx0dmFyIGdsb2JhbFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9nbG9iYWxQb3NlLmpvaW50UG9zZXM7XG5cdFx0dmFyIHJhdzpBcnJheTxudW1iZXI+O1xuXHRcdHZhciBveDpudW1iZXIsIG95Om51bWJlciwgb3o6bnVtYmVyLCBvdzpudW1iZXI7XG5cdFx0dmFyIHh5MjpudW1iZXIsIHh6MjpudW1iZXIsIHh3MjpudW1iZXI7XG5cdFx0dmFyIHl6MjpudW1iZXIsIHl3MjpudW1iZXIsIHp3MjpudW1iZXI7XG5cdFx0dmFyIG4xMTpudW1iZXIsIG4xMjpudW1iZXIsIG4xMzpudW1iZXI7XG5cdFx0dmFyIG4yMTpudW1iZXIsIG4yMjpudW1iZXIsIG4yMzpudW1iZXI7XG5cdFx0dmFyIG4zMTpudW1iZXIsIG4zMjpudW1iZXIsIG4zMzpudW1iZXI7XG5cdFx0dmFyIG0xMTpudW1iZXIsIG0xMjpudW1iZXIsIG0xMzpudW1iZXIsIG0xNDpudW1iZXI7XG5cdFx0dmFyIG0yMTpudW1iZXIsIG0yMjpudW1iZXIsIG0yMzpudW1iZXIsIG0yNDpudW1iZXI7XG5cdFx0dmFyIG0zMTpudW1iZXIsIG0zMjpudW1iZXIsIG0zMzpudW1iZXIsIG0zNDpudW1iZXI7XG5cdFx0dmFyIGpvaW50czpBcnJheTxTa2VsZXRvbkpvaW50PiA9IHRoaXMuX3NrZWxldG9uLmpvaW50cztcblx0XHR2YXIgcG9zZTpKb2ludFBvc2U7XG5cdFx0dmFyIHF1YXQ6UXVhdGVybmlvbjtcblx0XHR2YXIgdmVjOlZlY3RvcjNEO1xuXHRcdHZhciB0Om51bWJlcjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IHRoaXMuX251bUpvaW50czsgKytpKSB7XG5cdFx0XHRwb3NlID0gZ2xvYmFsUG9zZXNbaV07XG5cdFx0XHRxdWF0ID0gcG9zZS5vcmllbnRhdGlvbjtcblx0XHRcdHZlYyA9IHBvc2UudHJhbnNsYXRpb247XG5cdFx0XHRveCA9IHF1YXQueDtcblx0XHRcdG95ID0gcXVhdC55O1xuXHRcdFx0b3ogPSBxdWF0Lno7XG5cdFx0XHRvdyA9IHF1YXQudztcblxuXHRcdFx0eHkyID0gKHQgPSAyLjAqb3gpKm95O1xuXHRcdFx0eHoyID0gdCpvejtcblx0XHRcdHh3MiA9IHQqb3c7XG5cdFx0XHR5ejIgPSAodCA9IDIuMCpveSkqb3o7XG5cdFx0XHR5dzIgPSB0Km93O1xuXHRcdFx0encyID0gMi4wKm96Km93O1xuXG5cdFx0XHR5ejIgPSAyLjAqb3kqb3o7XG5cdFx0XHR5dzIgPSAyLjAqb3kqb3c7XG5cdFx0XHR6dzIgPSAyLjAqb3oqb3c7XG5cdFx0XHRveCAqPSBveDtcblx0XHRcdG95ICo9IG95O1xuXHRcdFx0b3ogKj0gb3o7XG5cdFx0XHRvdyAqPSBvdztcblxuXHRcdFx0bjExID0gKHQgPSBveCAtIG95KSAtIG96ICsgb3c7XG5cdFx0XHRuMTIgPSB4eTIgLSB6dzI7XG5cdFx0XHRuMTMgPSB4ejIgKyB5dzI7XG5cdFx0XHRuMjEgPSB4eTIgKyB6dzI7XG5cdFx0XHRuMjIgPSAtdCAtIG96ICsgb3c7XG5cdFx0XHRuMjMgPSB5ejIgLSB4dzI7XG5cdFx0XHRuMzEgPSB4ejIgLSB5dzI7XG5cdFx0XHRuMzIgPSB5ejIgKyB4dzI7XG5cdFx0XHRuMzMgPSAtb3ggLSBveSArIG96ICsgb3c7XG5cblx0XHRcdC8vIHByZXBlbmQgaW52ZXJzZSBiaW5kIHBvc2Vcblx0XHRcdHJhdyA9IGpvaW50c1tpXS5pbnZlcnNlQmluZFBvc2U7XG5cdFx0XHRtMTEgPSByYXdbMF07XG5cdFx0XHRtMTIgPSByYXdbNF07XG5cdFx0XHRtMTMgPSByYXdbOF07XG5cdFx0XHRtMTQgPSByYXdbMTJdO1xuXHRcdFx0bTIxID0gcmF3WzFdO1xuXHRcdFx0bTIyID0gcmF3WzVdO1xuXHRcdFx0bTIzID0gcmF3WzldO1xuXHRcdFx0bTI0ID0gcmF3WzEzXTtcblx0XHRcdG0zMSA9IHJhd1syXTtcblx0XHRcdG0zMiA9IHJhd1s2XTtcblx0XHRcdG0zMyA9IHJhd1sxMF07XG5cdFx0XHRtMzQgPSByYXdbMTRdO1xuXG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1ttdHhPZmZzZXRdID0gbjExKm0xMSArIG4xMiptMjEgKyBuMTMqbTMxO1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgMV0gPSBuMTEqbTEyICsgbjEyKm0yMiArIG4xMyptMzI7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1ttdHhPZmZzZXQgKyAyXSA9IG4xMSptMTMgKyBuMTIqbTIzICsgbjEzKm0zMztcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldCArIDNdID0gbjExKm0xNCArIG4xMiptMjQgKyBuMTMqbTM0ICsgdmVjLng7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1ttdHhPZmZzZXQgKyA0XSA9IG4yMSptMTEgKyBuMjIqbTIxICsgbjIzKm0zMTtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldCArIDVdID0gbjIxKm0xMiArIG4yMiptMjIgKyBuMjMqbTMyO1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgNl0gPSBuMjEqbTEzICsgbjIyKm0yMyArIG4yMyptMzM7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1ttdHhPZmZzZXQgKyA3XSA9IG4yMSptMTQgKyBuMjIqbTI0ICsgbjIzKm0zNCArIHZlYy55O1xuXHRcdFx0dGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgOF0gPSBuMzEqbTExICsgbjMyKm0yMSArIG4zMyptMzE7XG5cdFx0XHR0aGlzLl9nbG9iYWxNYXRyaWNlc1ttdHhPZmZzZXQgKyA5XSA9IG4zMSptMTIgKyBuMzIqbTIyICsgbjMzKm0zMjtcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldCArIDEwXSA9IG4zMSptMTMgKyBuMzIqbTIzICsgbjMzKm0zMztcblx0XHRcdHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldCArIDExXSA9IG4zMSptMTQgKyBuMzIqbTI0ICsgbjMzKm0zNCArIHZlYy56O1xuXG5cdFx0XHRtdHhPZmZzZXQgPSBtdHhPZmZzZXQgKyAxMjtcblx0XHR9XG5cdH1cblxuXG5cdHB1YmxpYyBnZXRSZW5kZXJhYmxlU3ViR2VvbWV0cnkocmVuZGVyYWJsZTpUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlLCBzb3VyY2VTdWJHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5KTpUcmlhbmdsZVN1Ykdlb21ldHJ5XG5cdHtcblx0XHR0aGlzLl9tb3JwaGVkU3ViR2VvbWV0cnlEaXJ0eVtzb3VyY2VTdWJHZW9tZXRyeS5pZF0gPSB0cnVlO1xuXG5cdFx0Ly9lYXJseSBvdXQgZm9yIEdQVSBhbmltYXRpb25zXG5cdFx0aWYgKCF0aGlzLl9wQW5pbWF0aW9uU2V0LnVzZXNDUFUpXG5cdFx0XHRyZXR1cm4gc291cmNlU3ViR2VvbWV0cnk7XG5cblx0XHR2YXIgdGFyZ2V0U3ViR2VvbWV0cnk6VHJpYW5nbGVTdWJHZW9tZXRyeTtcblxuXHRcdGlmICghKHRhcmdldFN1Ykdlb21ldHJ5ID0gdGhpcy5fbW9ycGhlZFN1Ykdlb21ldHJ5W3NvdXJjZVN1Ykdlb21ldHJ5LmlkXSkpIHtcblx0XHRcdC8vbm90IHlldCBzdG9yZWRcblx0XHRcdHRhcmdldFN1Ykdlb21ldHJ5ID0gdGhpcy5fbW9ycGhlZFN1Ykdlb21ldHJ5W3NvdXJjZVN1Ykdlb21ldHJ5LmlkXSA9IHNvdXJjZVN1Ykdlb21ldHJ5LmNsb25lKCk7XG5cdFx0XHQvL3R1cm4gb2ZmIGF1dG8gY2FsY3VsYXRpb25zIG9uIHRoZSBtb3JwaGVkIGdlb21ldHJ5XG5cdFx0XHR0YXJnZXRTdWJHZW9tZXRyeS5hdXRvRGVyaXZlTm9ybWFscyA9IGZhbHNlO1xuXHRcdFx0dGFyZ2V0U3ViR2VvbWV0cnkuYXV0b0Rlcml2ZVRhbmdlbnRzID0gZmFsc2U7XG5cdFx0XHR0YXJnZXRTdWJHZW9tZXRyeS5hdXRvRGVyaXZlVVZzID0gZmFsc2U7XG5cdFx0XHQvL2FkZCBldmVudCBsaXN0ZW5lcnMgZm9yIGFueSBjaGFuZ2VzIGluIFVWIHZhbHVlcyBvbiB0aGUgc291cmNlIGdlb21ldHJ5XG5cdFx0XHRzb3VyY2VTdWJHZW9tZXRyeS5hZGRFdmVudExpc3RlbmVyKFN1Ykdlb21ldHJ5RXZlbnQuSU5ESUNFU19VUERBVEVELCB0aGlzLl9vbkluZGljZXNVcGRhdGVEZWxlZ2F0ZSk7XG5cdFx0XHRzb3VyY2VTdWJHZW9tZXRyeS5hZGRFdmVudExpc3RlbmVyKFN1Ykdlb21ldHJ5RXZlbnQuVkVSVElDRVNfVVBEQVRFRCwgdGhpcy5fb25WZXJ0aWNlc1VwZGF0ZURlbGVnYXRlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGFyZ2V0U3ViR2VvbWV0cnk7XG5cdH1cblxuXHQvKipcblx0ICogSWYgdGhlIGFuaW1hdGlvbiBjYW4ndCBiZSBwZXJmb3JtZWQgb24gR1BVLCB0cmFuc2Zvcm0gdmVydGljZXMgbWFudWFsbHlcblx0ICogQHBhcmFtIHN1Ykdlb20gVGhlIHN1Ymdlb21ldHJ5IGNvbnRhaW5pbmcgdGhlIHdlaWdodHMgYW5kIGpvaW50IGluZGV4IGRhdGEgcGVyIHZlcnRleC5cblx0ICogQHBhcmFtIHBhc3MgVGhlIG1hdGVyaWFsIHBhc3MgZm9yIHdoaWNoIHdlIG5lZWQgdG8gdHJhbnNmb3JtIHRoZSB2ZXJ0aWNlc1xuXHQgKi9cblx0cHVibGljIG1vcnBoU3ViR2VvbWV0cnkocmVuZGVyYWJsZTpUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlLCBzb3VyY2VTdWJHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5KVxuXHR7XG5cdFx0dGhpcy5fbW9ycGhlZFN1Ykdlb21ldHJ5RGlydHlbc291cmNlU3ViR2VvbWV0cnkuaWRdID0gZmFsc2U7XG5cblx0XHR2YXIgc291cmNlUG9zaXRpb25zOkFycmF5PG51bWJlcj4gPSBzb3VyY2VTdWJHZW9tZXRyeS5wb3NpdGlvbnM7XG5cdFx0dmFyIHNvdXJjZU5vcm1hbHM6QXJyYXk8bnVtYmVyPiA9IHNvdXJjZVN1Ykdlb21ldHJ5LnZlcnRleE5vcm1hbHM7XG5cdFx0dmFyIHNvdXJjZVRhbmdlbnRzOkFycmF5PG51bWJlcj4gPSBzb3VyY2VTdWJHZW9tZXRyeS52ZXJ0ZXhUYW5nZW50cztcblxuXHRcdHZhciBqb2ludEluZGljZXM6QXJyYXk8bnVtYmVyPiA9IHNvdXJjZVN1Ykdlb21ldHJ5LmpvaW50SW5kaWNlcztcblx0XHR2YXIgam9pbnRXZWlnaHRzOkFycmF5PG51bWJlcj4gPSBzb3VyY2VTdWJHZW9tZXRyeS5qb2ludFdlaWdodHM7XG5cblx0XHR2YXIgdGFyZ2V0U3ViR2VvbWV0cnkgPSB0aGlzLl9tb3JwaGVkU3ViR2VvbWV0cnlbc291cmNlU3ViR2VvbWV0cnkuaWRdO1xuXG5cdFx0dmFyIHRhcmdldFBvc2l0aW9uczpBcnJheTxudW1iZXI+ID0gdGFyZ2V0U3ViR2VvbWV0cnkucG9zaXRpb25zO1xuXHRcdHZhciB0YXJnZXROb3JtYWxzOkFycmF5PG51bWJlcj4gPSB0YXJnZXRTdWJHZW9tZXRyeS52ZXJ0ZXhOb3JtYWxzO1xuXHRcdHZhciB0YXJnZXRUYW5nZW50czpBcnJheTxudW1iZXI+ID0gdGFyZ2V0U3ViR2VvbWV0cnkudmVydGV4VGFuZ2VudHM7XG5cblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qdWludCovID0gMDtcblx0XHR2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRcdHZhciBrOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgdng6bnVtYmVyLCB2eTpudW1iZXIsIHZ6Om51bWJlcjtcblx0XHR2YXIgbng6bnVtYmVyLCBueTpudW1iZXIsIG56Om51bWJlcjtcblx0XHR2YXIgdHg6bnVtYmVyLCB0eTpudW1iZXIsIHR6Om51bWJlcjtcblx0XHR2YXIgbGVuOm51bWJlciAvKmludCovID0gc291cmNlUG9zaXRpb25zLmxlbmd0aDtcblx0XHR2YXIgd2VpZ2h0Om51bWJlcjtcblx0XHR2YXIgdmVydFg6bnVtYmVyLCB2ZXJ0WTpudW1iZXIsIHZlcnRaOm51bWJlcjtcblx0XHR2YXIgbm9ybVg6bnVtYmVyLCBub3JtWTpudW1iZXIsIG5vcm1aOm51bWJlcjtcblx0XHR2YXIgdGFuZ1g6bnVtYmVyLCB0YW5nWTpudW1iZXIsIHRhbmdaOm51bWJlcjtcblx0XHR2YXIgbTExOm51bWJlciwgbTEyOm51bWJlciwgbTEzOm51bWJlciwgbTE0Om51bWJlcjtcblx0XHR2YXIgbTIxOm51bWJlciwgbTIyOm51bWJlciwgbTIzOm51bWJlciwgbTI0Om51bWJlcjtcblx0XHR2YXIgbTMxOm51bWJlciwgbTMyOm51bWJlciwgbTMzOm51bWJlciwgbTM0Om51bWJlcjtcblxuXHRcdHdoaWxlIChpbmRleCA8IGxlbikge1xuXHRcdFx0dmVydFggPSBzb3VyY2VQb3NpdGlvbnNbaW5kZXhdO1xuXHRcdFx0dmVydFkgPSBzb3VyY2VQb3NpdGlvbnNbaW5kZXggKyAxXTtcblx0XHRcdHZlcnRaID0gc291cmNlUG9zaXRpb25zW2luZGV4ICsgMl07XG5cdFx0XHRub3JtWCA9IHNvdXJjZU5vcm1hbHNbaW5kZXhdO1xuXHRcdFx0bm9ybVkgPSBzb3VyY2VOb3JtYWxzW2luZGV4ICsgMV07XG5cdFx0XHRub3JtWiA9IHNvdXJjZU5vcm1hbHNbaW5kZXggKyAyXTtcblx0XHRcdHRhbmdYID0gc291cmNlVGFuZ2VudHNbaW5kZXhdO1xuXHRcdFx0dGFuZ1kgPSBzb3VyY2VUYW5nZW50c1tpbmRleCArIDFdO1xuXHRcdFx0dGFuZ1ogPSBzb3VyY2VUYW5nZW50c1tpbmRleCArIDJdO1xuXHRcdFx0dnggPSAwO1xuXHRcdFx0dnkgPSAwO1xuXHRcdFx0dnogPSAwO1xuXHRcdFx0bnggPSAwO1xuXHRcdFx0bnkgPSAwO1xuXHRcdFx0bnogPSAwO1xuXHRcdFx0dHggPSAwO1xuXHRcdFx0dHkgPSAwO1xuXHRcdFx0dHogPSAwO1xuXHRcdFx0ayA9IDA7XG5cdFx0XHR3aGlsZSAoayA8IHRoaXMuX2pvaW50c1BlclZlcnRleCkge1xuXHRcdFx0XHR3ZWlnaHQgPSBqb2ludFdlaWdodHNbal07XG5cdFx0XHRcdGlmICh3ZWlnaHQgPiAwKSB7XG5cdFx0XHRcdFx0Ly8gaW1wbGljaXQgLzMqMTIgKC8zIGJlY2F1c2UgaW5kaWNlcyBhcmUgbXVsdGlwbGllZCBieSAzIGZvciBncHUgbWF0cml4IGFjY2VzcywgKjEyIGJlY2F1c2UgaXQncyB0aGUgbWF0cml4IHNpemUpXG5cdFx0XHRcdFx0dmFyIG10eE9mZnNldDpudW1iZXIgLyp1aW50Ki8gPSBqb2ludEluZGljZXNbaisrXSA8PCAyO1xuXHRcdFx0XHRcdG0xMSA9IHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldF07XG5cdFx0XHRcdFx0bTEyID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgMV07XG5cdFx0XHRcdFx0bTEzID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgMl07XG5cdFx0XHRcdFx0bTE0ID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgM107XG5cdFx0XHRcdFx0bTIxID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgNF07XG5cdFx0XHRcdFx0bTIyID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgNV07XG5cdFx0XHRcdFx0bTIzID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgNl07XG5cdFx0XHRcdFx0bTI0ID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgN107XG5cdFx0XHRcdFx0bTMxID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgOF07XG5cdFx0XHRcdFx0bTMyID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgOV07XG5cdFx0XHRcdFx0bTMzID0gdGhpcy5fZ2xvYmFsTWF0cmljZXNbbXR4T2Zmc2V0ICsgMTBdO1xuXHRcdFx0XHRcdG0zNCA9IHRoaXMuX2dsb2JhbE1hdHJpY2VzW210eE9mZnNldCArIDExXTtcblx0XHRcdFx0XHR2eCArPSB3ZWlnaHQqKG0xMSp2ZXJ0WCArIG0xMip2ZXJ0WSArIG0xMyp2ZXJ0WiArIG0xNCk7XG5cdFx0XHRcdFx0dnkgKz0gd2VpZ2h0KihtMjEqdmVydFggKyBtMjIqdmVydFkgKyBtMjMqdmVydFogKyBtMjQpO1xuXHRcdFx0XHRcdHZ6ICs9IHdlaWdodCoobTMxKnZlcnRYICsgbTMyKnZlcnRZICsgbTMzKnZlcnRaICsgbTM0KTtcblx0XHRcdFx0XHRueCArPSB3ZWlnaHQqKG0xMSpub3JtWCArIG0xMipub3JtWSArIG0xMypub3JtWik7XG5cdFx0XHRcdFx0bnkgKz0gd2VpZ2h0KihtMjEqbm9ybVggKyBtMjIqbm9ybVkgKyBtMjMqbm9ybVopO1xuXHRcdFx0XHRcdG56ICs9IHdlaWdodCoobTMxKm5vcm1YICsgbTMyKm5vcm1ZICsgbTMzKm5vcm1aKTtcblx0XHRcdFx0XHR0eCArPSB3ZWlnaHQqKG0xMSp0YW5nWCArIG0xMip0YW5nWSArIG0xMyp0YW5nWik7XG5cdFx0XHRcdFx0dHkgKz0gd2VpZ2h0KihtMjEqdGFuZ1ggKyBtMjIqdGFuZ1kgKyBtMjMqdGFuZ1opO1xuXHRcdFx0XHRcdHR6ICs9IHdlaWdodCoobTMxKnRhbmdYICsgbTMyKnRhbmdZICsgbTMzKnRhbmdaKTtcblx0XHRcdFx0XHQrK2s7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aiArPSAodGhpcy5fam9pbnRzUGVyVmVydGV4IC0gayk7XG5cdFx0XHRcdFx0ayA9IHRoaXMuX2pvaW50c1BlclZlcnRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR0YXJnZXRQb3NpdGlvbnNbaW5kZXhdID0gdng7XG5cdFx0XHR0YXJnZXRQb3NpdGlvbnNbaW5kZXggKyAxXSA9IHZ5O1xuXHRcdFx0dGFyZ2V0UG9zaXRpb25zW2luZGV4ICsgMl0gPSB2ejtcblx0XHRcdHRhcmdldE5vcm1hbHNbaW5kZXhdID0gbng7XG5cdFx0XHR0YXJnZXROb3JtYWxzW2luZGV4ICsgMV0gPSBueTtcblx0XHRcdHRhcmdldE5vcm1hbHNbaW5kZXggKyAyXSA9IG56O1xuXHRcdFx0dGFyZ2V0VGFuZ2VudHNbaW5kZXhdID0gdHg7XG5cdFx0XHR0YXJnZXRUYW5nZW50c1tpbmRleCArIDFdID0gdHk7XG5cdFx0XHR0YXJnZXRUYW5nZW50c1tpbmRleCArIDJdID0gdHo7XG5cblx0XHRcdGluZGV4ICs9IDM7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0U3ViR2VvbWV0cnkudXBkYXRlUG9zaXRpb25zKHRhcmdldFBvc2l0aW9ucyk7XG5cdFx0dGFyZ2V0U3ViR2VvbWV0cnkudXBkYXRlVmVydGV4Tm9ybWFscyh0YXJnZXROb3JtYWxzKTtcblx0XHR0YXJnZXRTdWJHZW9tZXRyeS51cGRhdGVWZXJ0ZXhUYW5nZW50cyh0YXJnZXRUYW5nZW50cyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBsb2NhbCBoaWVyYXJjaGljYWwgc2tlbGV0b24gcG9zZSB0byBhIGdsb2JhbCBwb3NlXG5cdCAqIEBwYXJhbSB0YXJnZXRQb3NlIFRoZSBTa2VsZXRvblBvc2Ugb2JqZWN0IHRoYXQgd2lsbCBjb250YWluIHRoZSBnbG9iYWwgcG9zZS5cblx0ICogQHBhcmFtIHNrZWxldG9uIFRoZSBza2VsZXRvbiBjb250YWluaW5nIHRoZSBqb2ludHMsIGFuZCBhcyBzdWNoLCB0aGUgaGllcmFyY2hpY2FsIGRhdGEgdG8gdHJhbnNmb3JtIHRvIGdsb2JhbCBwb3Nlcy5cblx0ICovXG5cdHByaXZhdGUgbG9jYWxUb0dsb2JhbFBvc2Uoc291cmNlUG9zZTpTa2VsZXRvblBvc2UsIHRhcmdldFBvc2U6U2tlbGV0b25Qb3NlLCBza2VsZXRvbjpTa2VsZXRvbilcblx0e1xuXHRcdHZhciBnbG9iYWxQb3NlczpBcnJheTxKb2ludFBvc2U+ID0gdGFyZ2V0UG9zZS5qb2ludFBvc2VzO1xuXHRcdHZhciBnbG9iYWxKb2ludFBvc2U6Sm9pbnRQb3NlO1xuXHRcdHZhciBqb2ludHM6QXJyYXk8U2tlbGV0b25Kb2ludD4gPSBza2VsZXRvbi5qb2ludHM7XG5cdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki8gPSBzb3VyY2VQb3NlLm51bUpvaW50UG9zZXM7XG5cdFx0dmFyIGpvaW50UG9zZXM6QXJyYXk8Sm9pbnRQb3NlPiA9IHNvdXJjZVBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgcGFyZW50SW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIGpvaW50OlNrZWxldG9uSm9pbnQ7XG5cdFx0dmFyIHBhcmVudFBvc2U6Sm9pbnRQb3NlO1xuXHRcdHZhciBwb3NlOkpvaW50UG9zZTtcblx0XHR2YXIgb3I6UXVhdGVybmlvbjtcblx0XHR2YXIgdHI6VmVjdG9yM0Q7XG5cdFx0dmFyIHQ6VmVjdG9yM0Q7XG5cdFx0dmFyIHE6UXVhdGVybmlvbjtcblxuXHRcdHZhciB4MTpudW1iZXIsIHkxOm51bWJlciwgejE6bnVtYmVyLCB3MTpudW1iZXI7XG5cdFx0dmFyIHgyOm51bWJlciwgeTI6bnVtYmVyLCB6MjpudW1iZXIsIHcyOm51bWJlcjtcblx0XHR2YXIgeDM6bnVtYmVyLCB5MzpudW1iZXIsIHozOm51bWJlcjtcblxuXHRcdC8vIDpzXG5cdFx0aWYgKGdsb2JhbFBvc2VzLmxlbmd0aCAhPSBsZW4pXG5cdFx0XHRnbG9iYWxQb3Nlcy5sZW5ndGggPSBsZW47XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciAvKnVpbnQqLyA9IDA7IGkgPCBsZW47ICsraSkge1xuXHRcdFx0Z2xvYmFsSm9pbnRQb3NlID0gZ2xvYmFsUG9zZXNbaV07XG5cblx0XHRcdGlmIChnbG9iYWxKb2ludFBvc2UgPT0gbnVsbClcblx0XHRcdFx0Z2xvYmFsSm9pbnRQb3NlID0gZ2xvYmFsUG9zZXNbaV0gPSBuZXcgSm9pbnRQb3NlKCk7XG5cblx0XHRcdGpvaW50ID0gam9pbnRzW2ldO1xuXHRcdFx0cGFyZW50SW5kZXggPSBqb2ludC5wYXJlbnRJbmRleDtcblx0XHRcdHBvc2UgPSBqb2ludFBvc2VzW2ldO1xuXG5cdFx0XHRxID0gZ2xvYmFsSm9pbnRQb3NlLm9yaWVudGF0aW9uO1xuXHRcdFx0dCA9IGdsb2JhbEpvaW50UG9zZS50cmFuc2xhdGlvbjtcblxuXHRcdFx0aWYgKHBhcmVudEluZGV4IDwgMCkge1xuXHRcdFx0XHR0ciA9IHBvc2UudHJhbnNsYXRpb247XG5cdFx0XHRcdG9yID0gcG9zZS5vcmllbnRhdGlvbjtcblx0XHRcdFx0cS54ID0gb3IueDtcblx0XHRcdFx0cS55ID0gb3IueTtcblx0XHRcdFx0cS56ID0gb3Iuejtcblx0XHRcdFx0cS53ID0gb3Iudztcblx0XHRcdFx0dC54ID0gdHIueDtcblx0XHRcdFx0dC55ID0gdHIueTtcblx0XHRcdFx0dC56ID0gdHIuejtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIGFwcGVuZCBwYXJlbnQgcG9zZVxuXHRcdFx0XHRwYXJlbnRQb3NlID0gZ2xvYmFsUG9zZXNbcGFyZW50SW5kZXhdO1xuXG5cdFx0XHRcdC8vIHJvdGF0ZSBwb2ludFxuXHRcdFx0XHRvciA9IHBhcmVudFBvc2Uub3JpZW50YXRpb247XG5cdFx0XHRcdHRyID0gcG9zZS50cmFuc2xhdGlvbjtcblx0XHRcdFx0eDIgPSBvci54O1xuXHRcdFx0XHR5MiA9IG9yLnk7XG5cdFx0XHRcdHoyID0gb3Iuejtcblx0XHRcdFx0dzIgPSBvci53O1xuXHRcdFx0XHR4MyA9IHRyLng7XG5cdFx0XHRcdHkzID0gdHIueTtcblx0XHRcdFx0ejMgPSB0ci56O1xuXG5cdFx0XHRcdHcxID0gLXgyKngzIC0geTIqeTMgLSB6Mip6Mztcblx0XHRcdFx0eDEgPSB3Mip4MyArIHkyKnozIC0gejIqeTM7XG5cdFx0XHRcdHkxID0gdzIqeTMgLSB4Mip6MyArIHoyKngzO1xuXHRcdFx0XHR6MSA9IHcyKnozICsgeDIqeTMgLSB5Mip4MztcblxuXHRcdFx0XHQvLyBhcHBlbmQgcGFyZW50IHRyYW5zbGF0aW9uXG5cdFx0XHRcdHRyID0gcGFyZW50UG9zZS50cmFuc2xhdGlvbjtcblx0XHRcdFx0dC54ID0gLXcxKngyICsgeDEqdzIgLSB5MSp6MiArIHoxKnkyICsgdHIueDtcblx0XHRcdFx0dC55ID0gLXcxKnkyICsgeDEqejIgKyB5MSp3MiAtIHoxKngyICsgdHIueTtcblx0XHRcdFx0dC56ID0gLXcxKnoyIC0geDEqeTIgKyB5MSp4MiArIHoxKncyICsgdHIuejtcblxuXHRcdFx0XHQvLyBhcHBlbmQgcGFyZW50IG9yaWVudGF0aW9uXG5cdFx0XHRcdHgxID0gb3IueDtcblx0XHRcdFx0eTEgPSBvci55O1xuXHRcdFx0XHR6MSA9IG9yLno7XG5cdFx0XHRcdHcxID0gb3Iudztcblx0XHRcdFx0b3IgPSBwb3NlLm9yaWVudGF0aW9uO1xuXHRcdFx0XHR4MiA9IG9yLng7XG5cdFx0XHRcdHkyID0gb3IueTtcblx0XHRcdFx0ejIgPSBvci56O1xuXHRcdFx0XHR3MiA9IG9yLnc7XG5cblx0XHRcdFx0cS53ID0gdzEqdzIgLSB4MSp4MiAtIHkxKnkyIC0gejEqejI7XG5cdFx0XHRcdHEueCA9IHcxKngyICsgeDEqdzIgKyB5MSp6MiAtIHoxKnkyO1xuXHRcdFx0XHRxLnkgPSB3MSp5MiAtIHgxKnoyICsgeTEqdzIgKyB6MSp4Mjtcblx0XHRcdFx0cS56ID0gdzEqejIgKyB4MSp5MiAtIHkxKngyICsgejEqdzI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBvblRyYW5zaXRpb25Db21wbGV0ZShldmVudDpBbmltYXRpb25TdGF0ZUV2ZW50KVxuXHR7XG5cdFx0aWYgKGV2ZW50LnR5cGUgPT0gQW5pbWF0aW9uU3RhdGVFdmVudC5UUkFOU0lUSU9OX0NPTVBMRVRFKSB7XG5cdFx0XHRldmVudC5hbmltYXRpb25Ob2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoQW5pbWF0aW9uU3RhdGVFdmVudC5UUkFOU0lUSU9OX0NPTVBMRVRFLCB0aGlzLl9vblRyYW5zaXRpb25Db21wbGV0ZURlbGVnYXRlKTtcblx0XHRcdC8vaWYgdGhpcyBpcyB0aGUgY3VycmVudCBhY3RpdmUgc3RhdGUgdHJhbnNpdGlvbiwgcmV2ZXJ0IGNvbnRyb2wgdG8gdGhlIGFjdGl2ZSBub2RlXG5cdFx0XHRpZiAodGhpcy5fcEFjdGl2ZVN0YXRlID09IGV2ZW50LmFuaW1hdGlvblN0YXRlKSB7XG5cdFx0XHRcdHRoaXMuX3BBY3RpdmVOb2RlID0gdGhpcy5fcEFuaW1hdGlvblNldC5nZXRBbmltYXRpb24odGhpcy5fcEFjdGl2ZUFuaW1hdGlvbk5hbWUpO1xuXHRcdFx0XHR0aGlzLl9wQWN0aXZlU3RhdGUgPSB0aGlzLmdldEFuaW1hdGlvblN0YXRlKHRoaXMuX3BBY3RpdmVOb2RlKTtcblx0XHRcdFx0dGhpcy5fYWN0aXZlU2tlbGV0b25TdGF0ZSA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gdGhpcy5fcEFjdGl2ZVN0YXRlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgb25JbmRpY2VzVXBkYXRlKGV2ZW50OlN1Ykdlb21ldHJ5RXZlbnQpXG5cdHtcblx0XHR2YXIgc3ViR2VvbWV0cnk6VHJpYW5nbGVTdWJHZW9tZXRyeSA9IDxUcmlhbmdsZVN1Ykdlb21ldHJ5PiBldmVudC50YXJnZXQ7XG5cblx0XHQoPFRyaWFuZ2xlU3ViR2VvbWV0cnk+IHRoaXMuX21vcnBoZWRTdWJHZW9tZXRyeVtzdWJHZW9tZXRyeS5pZF0pLnVwZGF0ZUluZGljZXMoc3ViR2VvbWV0cnkuaW5kaWNlcyk7XG5cdH1cblxuXHRwcml2YXRlIG9uVmVydGljZXNVcGRhdGUoZXZlbnQ6U3ViR2VvbWV0cnlFdmVudClcblx0e1xuXHRcdHZhciBzdWJHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5ID0gPFRyaWFuZ2xlU3ViR2VvbWV0cnk+IGV2ZW50LnRhcmdldDtcblx0XHR2YXIgbW9ycGhHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5ID0gPFRyaWFuZ2xlU3ViR2VvbWV0cnk+IHRoaXMuX21vcnBoZWRTdWJHZW9tZXRyeVtzdWJHZW9tZXRyeS5pZF07XG5cblx0XHRzd2l0Y2goZXZlbnQuZGF0YVR5cGUpIHtcblx0XHRcdGNhc2UgVHJpYW5nbGVTdWJHZW9tZXRyeS5VVl9EQVRBOlxuXHRcdFx0XHRtb3JwaEdlb21ldHJ5LnVwZGF0ZVVWcyhzdWJHZW9tZXRyeS51dnMpO1xuXHRcdFx0Y2FzZSBUcmlhbmdsZVN1Ykdlb21ldHJ5LlNFQ09OREFSWV9VVl9EQVRBOlxuXHRcdFx0XHRtb3JwaEdlb21ldHJ5LnVwZGF0ZVVWcyhzdWJHZW9tZXRyeS5zZWNvbmRhcnlVVnMpO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkFuaW1hdG9yOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/SkeletonAnimator.ts b/lib/animators/SkeletonAnimator.ts
new file mode 100644
index 000000000..00e827b8d
--- /dev/null
+++ b/lib/animators/SkeletonAnimator.ts
@@ -0,0 +1,630 @@
+import ISubMesh = require("awayjs-core/lib/core/base/ISubMesh");
+import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+import TriangleSubMesh = require("awayjs-core/lib/core/base/TriangleSubMesh");
+import Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+import SubGeometryEvent = require("awayjs-core/lib/events/SubGeometryEvent");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import TriangleSubMeshRenderable = require("awayjs-stagegl/lib/core/pool/TriangleSubMeshRenderable");
+import ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import SkeletonAnimationSet = require("awayjs-renderergl/lib/animators/SkeletonAnimationSet");
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+import IAnimationTransition = require("awayjs-renderergl/lib/animators/transitions/IAnimationTransition");
+import AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+
+/**
+ * Provides an interface for assigning skeleton-based animation data sets to mesh-based entity objects
+ * and controlling the various available states of animation through an interative playhead that can be
+ * automatically updated or manually triggered.
+ */
+class SkeletonAnimator extends AnimatorBase
+{
+ private _globalMatrices:Array;
+ private _globalPose:SkeletonPose = new SkeletonPose();
+ private _globalPropertiesDirty:boolean;
+ private _numJoints:number /*uint*/;
+ private _morphedSubGeometry:Object = new Object();
+ private _morphedSubGeometryDirty:Object = new Object();
+ private _condensedMatrices:Array;
+
+ private _skeleton:Skeleton;
+ private _forceCPU:boolean;
+ private _useCondensedIndices:boolean;
+ private _jointsPerVertex:number /*uint*/;
+ private _activeSkeletonState:ISkeletonAnimationState;
+ private _onTransitionCompleteDelegate:(event:AnimationStateEvent) => void;
+
+ private _onIndicesUpdateDelegate:(event:SubGeometryEvent) => void;
+ private _onVerticesUpdateDelegate:(event:SubGeometryEvent) => void;
+
+ /**
+ * returns the calculated global matrices of the current skeleton pose.
+ *
+ * @see #globalPose
+ */
+ public get globalMatrices():Array
+ {
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+
+ return this._globalMatrices;
+ }
+
+ /**
+ * returns the current skeleton pose output from the animator.
+ *
+ * @see away.animators.data.SkeletonPose
+ */
+ public get globalPose():SkeletonPose
+ {
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+
+ return this._globalPose;
+ }
+
+ /**
+ * Returns the skeleton object in use by the animator - this defines the number and heirarchy of joints used by the
+ * skinned geoemtry to which skeleon animator is applied.
+ */
+ public get skeleton():Skeleton
+ {
+ return this._skeleton;
+ }
+
+ /**
+ * Indicates whether the skeleton animator is disabled by default for GPU rendering, something that allows the animator to perform calculation on the GPU.
+ * Defaults to false.
+ */
+ public get forceCPU():boolean
+ {
+ return this._forceCPU;
+ }
+
+ /**
+ * Offers the option of enabling GPU accelerated animation on skeletons larger than 32 joints
+ * by condensing the number of joint index values required per mesh. Only applicable to
+ * skeleton animations that utilise more than one mesh object. Defaults to false.
+ */
+ public get useCondensedIndices():boolean
+ {
+ return this._useCondensedIndices;
+ }
+
+ public set useCondensedIndices(value:boolean)
+ {
+ this._useCondensedIndices = value;
+ }
+
+ /**
+ * Creates a new SkeletonAnimator
object.
+ *
+ * @param skeletonAnimationSet The animation data set containing the skeleton animations used by the animator.
+ * @param skeleton The skeleton object used for calculating the resulting global matrices for transforming skinned mesh data.
+ * @param forceCPU Optional value that only allows the animator to perform calculation on the CPU. Defaults to false.
+ */
+ constructor(animationSet:SkeletonAnimationSet, skeleton:Skeleton, forceCPU:boolean = false)
+ {
+ super(animationSet);
+
+ this._skeleton = skeleton;
+ this._forceCPU = forceCPU;
+ this._jointsPerVertex = animationSet.jointsPerVertex;
+
+ this._numJoints = this._skeleton.numJoints;
+ this._globalMatrices = new Array(this._numJoints*12);
+
+ var j:number /*int*/ = 0;
+ for (var i:number /*uint*/ = 0; i < this._numJoints; ++i) {
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 0;
+ this._globalMatrices[j++] = 1;
+ this._globalMatrices[j++] = 0;
+ }
+
+ this._onTransitionCompleteDelegate = (event:AnimationStateEvent) => this.onTransitionComplete(event);
+ this._onIndicesUpdateDelegate = (event:SubGeometryEvent) => this.onIndicesUpdate(event);
+ this._onVerticesUpdateDelegate = (event:SubGeometryEvent) => this.onVerticesUpdate(event);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public clone():AnimatorBase
+ {
+ /* The cast to SkeletonAnimationSet should never fail, as _animationSet can only be set
+ through the constructor, which will only accept a SkeletonAnimationSet. */
+ return new SkeletonAnimator( this._pAnimationSet, this._skeleton, this._forceCPU);
+ }
+
+ /**
+ * Plays an animation state registered with the given name in the animation data set.
+ *
+ * @param name The data set name of the animation state to be played.
+ * @param transition An optional transition object that determines how the animator will transition from the currently active animation state.
+ * @param offset An option offset time (in milliseconds) that resets the state's internal clock to the absolute time of the animator plus the offset value. Required for non-looping animation states.
+ */
+ public play(name:string, transition:IAnimationTransition = null, offset:number = NaN)
+ {
+ if (this._pActiveAnimationName == name)
+ return;
+
+ this._pActiveAnimationName = name;
+
+ if (!this._pAnimationSet.hasAnimation(name))
+ throw new Error("Animation root node " + name + " not found!");
+
+ if (transition && this._pActiveNode) {
+ //setup the transition
+ this._pActiveNode = transition.getAnimationNode(this, this._pActiveNode, this._pAnimationSet.getAnimation(name), this._pAbsoluteTime);
+ this._pActiveNode.addEventListener(AnimationStateEvent.TRANSITION_COMPLETE, this._onTransitionCompleteDelegate);
+ } else
+ 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._activeSkeletonState = this._pActiveState;
+
+ this.start();
+
+ //apply a time offset if specified
+ if (!isNaN(offset))
+ this.reset(name, offset);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(shaderObject:ShaderObjectBase, renderable:RenderableBase, stage:Stage, camera:Camera, vertexConstantOffset:number /*int*/, vertexStreamOffset:number /*int*/)
+ {
+ // do on request of globalProperties
+ if (this._globalPropertiesDirty)
+ this.updateGlobalProperties();
+
+ var subGeometry:TriangleSubGeometry = ( ( renderable).subMesh).subGeometry;
+
+ subGeometry.useCondensedIndices = this._useCondensedIndices;
+
+ if (this._useCondensedIndices) {
+ // using a condensed data set
+ this.updateCondensedMatrices(subGeometry.condensedIndexLookUp, subGeometry.numCondensedJoints);
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._condensedMatrices, subGeometry.numCondensedJoints*3);
+ } else {
+ if (this._pAnimationSet.usesCPU) {
+ if (this._morphedSubGeometryDirty[subGeometry.id])
+ this.morphSubGeometry( renderable, subGeometry);
+
+ return
+ }
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._globalMatrices, this._numJoints*3);
+ }
+
+ ( stage.context).activateBuffer(vertexStreamOffset, renderable.getVertexData(TriangleSubGeometry.JOINT_INDEX_DATA), renderable.getVertexOffset(TriangleSubGeometry.JOINT_INDEX_DATA), renderable.JOINT_INDEX_FORMAT);
+ ( stage.context).activateBuffer(vertexStreamOffset + 1, renderable.getVertexData(TriangleSubGeometry.JOINT_WEIGHT_DATA), renderable.getVertexOffset(TriangleSubGeometry.JOINT_WEIGHT_DATA), renderable.JOINT_WEIGHT_FORMAT);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public testGPUCompatibility(shaderObject:ShaderObjectBase)
+ {
+ if (!this._useCondensedIndices && (this._forceCPU || this._jointsPerVertex > 4 || shaderObject.numUsedVertexConstants + this._numJoints*3 > 128))
+ this._pAnimationSet.cancelGPUCompatibility();
+ }
+
+ /**
+ * Applies the calculated time delta to the active animation state node or state transition object.
+ */
+ public _pUpdateDeltaTime(dt:number)
+ {
+ super._pUpdateDeltaTime(dt);
+
+ //invalidate pose matrices
+ this._globalPropertiesDirty = true;
+
+ //trigger geometry invalidation if using CPU animation
+ if (this._pAnimationSet.usesCPU)
+ for (var key in this._morphedSubGeometryDirty)
+ this._morphedSubGeometryDirty[key] = true;
+ }
+
+ private updateCondensedMatrices(condensedIndexLookUp:Array /*uint*/, numJoints:number /*uint*/)
+ {
+ var i:number /*uint*/ = 0, j:number /*uint*/ = 0;
+ var len:number /*uint*/;
+ var srcIndex:number /*uint*/;
+
+ this._condensedMatrices = new Array();
+
+ do {
+ srcIndex = condensedIndexLookUp[i]*4;
+ len = srcIndex + 12;
+ // copy into condensed
+ while (srcIndex < len)
+ this._condensedMatrices[j++] = this._globalMatrices[srcIndex++];
+ } while (++i < numJoints);
+ }
+
+ private updateGlobalProperties()
+ {
+ this._globalPropertiesDirty = false;
+
+ //get global pose
+ this.localToGlobalPose(this._activeSkeletonState.getSkeletonPose(this._skeleton), this._globalPose, this._skeleton);
+
+ // convert pose to matrix
+ var mtxOffset:number /*uint*/ = 0;
+ var globalPoses:Array = this._globalPose.jointPoses;
+ var raw:Array;
+ var ox:number, oy:number, oz:number, ow:number;
+ var xy2:number, xz2:number, xw2:number;
+ var yz2:number, yw2:number, zw2:number;
+ var n11:number, n12:number, n13:number;
+ var n21:number, n22:number, n23:number;
+ var n31:number, n32:number, n33:number;
+ var m11:number, m12:number, m13:number, m14:number;
+ var m21:number, m22:number, m23:number, m24:number;
+ var m31:number, m32:number, m33:number, m34:number;
+ var joints:Array = this._skeleton.joints;
+ var pose:JointPose;
+ var quat:Quaternion;
+ var vec:Vector3D;
+ var t:number;
+
+ for (var i:number /*uint*/ = 0; i < this._numJoints; ++i) {
+ pose = globalPoses[i];
+ quat = pose.orientation;
+ vec = pose.translation;
+ ox = quat.x;
+ oy = quat.y;
+ oz = quat.z;
+ ow = quat.w;
+
+ xy2 = (t = 2.0*ox)*oy;
+ xz2 = t*oz;
+ xw2 = t*ow;
+ yz2 = (t = 2.0*oy)*oz;
+ yw2 = t*ow;
+ zw2 = 2.0*oz*ow;
+
+ yz2 = 2.0*oy*oz;
+ yw2 = 2.0*oy*ow;
+ zw2 = 2.0*oz*ow;
+ ox *= ox;
+ oy *= oy;
+ oz *= oz;
+ ow *= ow;
+
+ n11 = (t = ox - oy) - oz + ow;
+ n12 = xy2 - zw2;
+ n13 = xz2 + yw2;
+ n21 = xy2 + zw2;
+ n22 = -t - oz + ow;
+ n23 = yz2 - xw2;
+ n31 = xz2 - yw2;
+ n32 = yz2 + xw2;
+ n33 = -ox - oy + oz + ow;
+
+ // prepend inverse bind pose
+ raw = joints[i].inverseBindPose;
+ m11 = raw[0];
+ m12 = raw[4];
+ m13 = raw[8];
+ m14 = raw[12];
+ m21 = raw[1];
+ m22 = raw[5];
+ m23 = raw[9];
+ m24 = raw[13];
+ m31 = raw[2];
+ m32 = raw[6];
+ m33 = raw[10];
+ m34 = raw[14];
+
+ this._globalMatrices[mtxOffset] = n11*m11 + n12*m21 + n13*m31;
+ this._globalMatrices[mtxOffset + 1] = n11*m12 + n12*m22 + n13*m32;
+ this._globalMatrices[mtxOffset + 2] = n11*m13 + n12*m23 + n13*m33;
+ this._globalMatrices[mtxOffset + 3] = n11*m14 + n12*m24 + n13*m34 + vec.x;
+ this._globalMatrices[mtxOffset + 4] = n21*m11 + n22*m21 + n23*m31;
+ this._globalMatrices[mtxOffset + 5] = n21*m12 + n22*m22 + n23*m32;
+ this._globalMatrices[mtxOffset + 6] = n21*m13 + n22*m23 + n23*m33;
+ this._globalMatrices[mtxOffset + 7] = n21*m14 + n22*m24 + n23*m34 + vec.y;
+ this._globalMatrices[mtxOffset + 8] = n31*m11 + n32*m21 + n33*m31;
+ this._globalMatrices[mtxOffset + 9] = n31*m12 + n32*m22 + n33*m32;
+ this._globalMatrices[mtxOffset + 10] = n31*m13 + n32*m23 + n33*m33;
+ this._globalMatrices[mtxOffset + 11] = n31*m14 + n32*m24 + n33*m34 + vec.z;
+
+ mtxOffset = mtxOffset + 12;
+ }
+ }
+
+
+ public getRenderableSubGeometry(renderable:TriangleSubMeshRenderable, sourceSubGeometry:TriangleSubGeometry):TriangleSubGeometry
+ {
+ this._morphedSubGeometryDirty[sourceSubGeometry.id] = true;
+
+ //early out for GPU animations
+ if (!this._pAnimationSet.usesCPU)
+ return sourceSubGeometry;
+
+ var targetSubGeometry:TriangleSubGeometry;
+
+ if (!(targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id])) {
+ //not yet stored
+ targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id] = sourceSubGeometry.clone();
+ //turn off auto calculations on the morphed geometry
+ targetSubGeometry.autoDeriveNormals = false;
+ targetSubGeometry.autoDeriveTangents = false;
+ targetSubGeometry.autoDeriveUVs = false;
+ //add event listeners for any changes in UV values on the source geometry
+ sourceSubGeometry.addEventListener(SubGeometryEvent.INDICES_UPDATED, this._onIndicesUpdateDelegate);
+ sourceSubGeometry.addEventListener(SubGeometryEvent.VERTICES_UPDATED, this._onVerticesUpdateDelegate);
+ }
+
+ return targetSubGeometry;
+ }
+
+ /**
+ * If the animation can't be performed on GPU, transform vertices manually
+ * @param subGeom The subgeometry containing the weights and joint index data per vertex.
+ * @param pass The material pass for which we need to transform the vertices
+ */
+ public morphSubGeometry(renderable:TriangleSubMeshRenderable, sourceSubGeometry:TriangleSubGeometry)
+ {
+ this._morphedSubGeometryDirty[sourceSubGeometry.id] = false;
+
+ var sourcePositions:Array = sourceSubGeometry.positions;
+ var sourceNormals:Array = sourceSubGeometry.vertexNormals;
+ var sourceTangents:Array = sourceSubGeometry.vertexTangents;
+
+ var jointIndices:Array = sourceSubGeometry.jointIndices;
+ var jointWeights:Array = sourceSubGeometry.jointWeights;
+
+ var targetSubGeometry = this._morphedSubGeometry[sourceSubGeometry.id];
+
+ var targetPositions:Array = targetSubGeometry.positions;
+ var targetNormals:Array = targetSubGeometry.vertexNormals;
+ var targetTangents:Array = targetSubGeometry.vertexTangents;
+
+ var index:number /*uint*/ = 0;
+ var j:number /*uint*/ = 0;
+ var k:number /*uint*/;
+ var vx:number, vy:number, vz:number;
+ var nx:number, ny:number, nz:number;
+ var tx:number, ty:number, tz:number;
+ var len:number /*int*/ = sourcePositions.length;
+ var weight:number;
+ var vertX:number, vertY:number, vertZ:number;
+ var normX:number, normY:number, normZ:number;
+ var tangX:number, tangY:number, tangZ:number;
+ var m11:number, m12:number, m13:number, m14:number;
+ var m21:number, m22:number, m23:number, m24:number;
+ var m31:number, m32:number, m33:number, m34:number;
+
+ while (index < len) {
+ vertX = sourcePositions[index];
+ vertY = sourcePositions[index + 1];
+ vertZ = sourcePositions[index + 2];
+ normX = sourceNormals[index];
+ normY = sourceNormals[index + 1];
+ normZ = sourceNormals[index + 2];
+ tangX = sourceTangents[index];
+ tangY = sourceTangents[index + 1];
+ tangZ = sourceTangents[index + 2];
+ vx = 0;
+ vy = 0;
+ vz = 0;
+ nx = 0;
+ ny = 0;
+ nz = 0;
+ tx = 0;
+ ty = 0;
+ tz = 0;
+ k = 0;
+ while (k < this._jointsPerVertex) {
+ weight = jointWeights[j];
+ if (weight > 0) {
+ // implicit /3*12 (/3 because indices are multiplied by 3 for gpu matrix access, *12 because it's the matrix size)
+ var mtxOffset:number /*uint*/ = jointIndices[j++] << 2;
+ m11 = this._globalMatrices[mtxOffset];
+ m12 = this._globalMatrices[mtxOffset + 1];
+ m13 = this._globalMatrices[mtxOffset + 2];
+ m14 = this._globalMatrices[mtxOffset + 3];
+ m21 = this._globalMatrices[mtxOffset + 4];
+ m22 = this._globalMatrices[mtxOffset + 5];
+ m23 = this._globalMatrices[mtxOffset + 6];
+ m24 = this._globalMatrices[mtxOffset + 7];
+ m31 = this._globalMatrices[mtxOffset + 8];
+ m32 = this._globalMatrices[mtxOffset + 9];
+ m33 = this._globalMatrices[mtxOffset + 10];
+ m34 = this._globalMatrices[mtxOffset + 11];
+ vx += weight*(m11*vertX + m12*vertY + m13*vertZ + m14);
+ vy += weight*(m21*vertX + m22*vertY + m23*vertZ + m24);
+ vz += weight*(m31*vertX + m32*vertY + m33*vertZ + m34);
+ nx += weight*(m11*normX + m12*normY + m13*normZ);
+ ny += weight*(m21*normX + m22*normY + m23*normZ);
+ nz += weight*(m31*normX + m32*normY + m33*normZ);
+ tx += weight*(m11*tangX + m12*tangY + m13*tangZ);
+ ty += weight*(m21*tangX + m22*tangY + m23*tangZ);
+ tz += weight*(m31*tangX + m32*tangY + m33*tangZ);
+ ++k;
+ } else {
+ j += (this._jointsPerVertex - k);
+ k = this._jointsPerVertex;
+ }
+ }
+
+ targetPositions[index] = vx;
+ targetPositions[index + 1] = vy;
+ targetPositions[index + 2] = vz;
+ targetNormals[index] = nx;
+ targetNormals[index + 1] = ny;
+ targetNormals[index + 2] = nz;
+ targetTangents[index] = tx;
+ targetTangents[index + 1] = ty;
+ targetTangents[index + 2] = tz;
+
+ index += 3;
+ }
+
+ targetSubGeometry.updatePositions(targetPositions);
+ targetSubGeometry.updateVertexNormals(targetNormals);
+ targetSubGeometry.updateVertexTangents(targetTangents);
+ }
+
+ /**
+ * Converts a local hierarchical skeleton pose to a global pose
+ * @param targetPose The SkeletonPose object that will contain the global pose.
+ * @param skeleton The skeleton containing the joints, and as such, the hierarchical data to transform to global poses.
+ */
+ private localToGlobalPose(sourcePose:SkeletonPose, targetPose:SkeletonPose, skeleton:Skeleton)
+ {
+ var globalPoses:Array = targetPose.jointPoses;
+ var globalJointPose:JointPose;
+ var joints:Array = skeleton.joints;
+ var len:number /*uint*/ = sourcePose.numJointPoses;
+ var jointPoses:Array = sourcePose.jointPoses;
+ var parentIndex:number /*int*/;
+ var joint:SkeletonJoint;
+ var parentPose:JointPose;
+ var pose:JointPose;
+ var or:Quaternion;
+ var tr:Vector3D;
+ var t:Vector3D;
+ var q:Quaternion;
+
+ var x1:number, y1:number, z1:number, w1:number;
+ var x2:number, y2:number, z2:number, w2:number;
+ var x3:number, y3:number, z3:number;
+
+ // :s
+ if (globalPoses.length != len)
+ globalPoses.length = len;
+
+ for (var i:number /*uint*/ = 0; i < len; ++i) {
+ globalJointPose = globalPoses[i];
+
+ if (globalJointPose == null)
+ globalJointPose = globalPoses[i] = new JointPose();
+
+ joint = joints[i];
+ parentIndex = joint.parentIndex;
+ pose = jointPoses[i];
+
+ q = globalJointPose.orientation;
+ t = globalJointPose.translation;
+
+ if (parentIndex < 0) {
+ tr = pose.translation;
+ or = pose.orientation;
+ q.x = or.x;
+ q.y = or.y;
+ q.z = or.z;
+ q.w = or.w;
+ t.x = tr.x;
+ t.y = tr.y;
+ t.z = tr.z;
+ } else {
+ // append parent pose
+ parentPose = globalPoses[parentIndex];
+
+ // rotate point
+ or = parentPose.orientation;
+ tr = pose.translation;
+ x2 = or.x;
+ y2 = or.y;
+ z2 = or.z;
+ w2 = or.w;
+ x3 = tr.x;
+ y3 = tr.y;
+ z3 = tr.z;
+
+ w1 = -x2*x3 - y2*y3 - z2*z3;
+ x1 = w2*x3 + y2*z3 - z2*y3;
+ y1 = w2*y3 - x2*z3 + z2*x3;
+ z1 = w2*z3 + x2*y3 - y2*x3;
+
+ // append parent translation
+ tr = parentPose.translation;
+ t.x = -w1*x2 + x1*w2 - y1*z2 + z1*y2 + tr.x;
+ t.y = -w1*y2 + x1*z2 + y1*w2 - z1*x2 + tr.y;
+ t.z = -w1*z2 - x1*y2 + y1*x2 + z1*w2 + tr.z;
+
+ // append parent orientation
+ x1 = or.x;
+ y1 = or.y;
+ z1 = or.z;
+ w1 = or.w;
+ or = pose.orientation;
+ x2 = or.x;
+ y2 = or.y;
+ z2 = or.z;
+ w2 = or.w;
+
+ q.w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
+ q.x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
+ q.y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
+ q.z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
+ }
+ }
+ }
+
+ private onTransitionComplete(event:AnimationStateEvent)
+ {
+ if (event.type == AnimationStateEvent.TRANSITION_COMPLETE) {
+ event.animationNode.removeEventListener(AnimationStateEvent.TRANSITION_COMPLETE, this._onTransitionCompleteDelegate);
+ //if this is the current active state transition, revert control to the active node
+ if (this._pActiveState == event.animationState) {
+ this._pActiveNode = this._pAnimationSet.getAnimation(this._pActiveAnimationName);
+ this._pActiveState = this.getAnimationState(this._pActiveNode);
+ this._activeSkeletonState = this._pActiveState;
+ }
+ }
+ }
+
+ private onIndicesUpdate(event:SubGeometryEvent)
+ {
+ var subGeometry:TriangleSubGeometry = event.target;
+
+ ( this._morphedSubGeometry[subGeometry.id]).updateIndices(subGeometry.indices);
+ }
+
+ private onVerticesUpdate(event:SubGeometryEvent)
+ {
+ var subGeometry:TriangleSubGeometry = event.target;
+ var morphGeometry:TriangleSubGeometry = this._morphedSubGeometry[subGeometry.id];
+
+ switch(event.dataType) {
+ case TriangleSubGeometry.UV_DATA:
+ morphGeometry.updateUVs(subGeometry.uvs);
+ case TriangleSubGeometry.SECONDARY_UV_DATA:
+ morphGeometry.updateUVs(subGeometry.secondaryUVs);
+ }
+ }
+}
+
+export = SkeletonAnimator;
\ No newline at end of file
diff --git a/lib/animators/VertexAnimationSet.js b/lib/animators/VertexAnimationSet.js
new file mode 100755
index 000000000..9b4d340c6
--- /dev/null
+++ b/lib/animators/VertexAnimationSet.js
@@ -0,0 +1,164 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+var VertexAnimationMode = require("awayjs-renderergl/lib/animators/data/VertexAnimationMode");
+/**
+ * The animation data set used by vertex-based animators, containing vertex animation state data.
+ *
+ * @see VertexAnimator
+ */
+var VertexAnimationSet = (function (_super) {
+ __extends(VertexAnimationSet, _super);
+ /**
+ * Returns whether or not normal data is used in last set GPU pass of the vertex shader.
+ */
+ // public get useNormals():boolean
+ // {
+ // return this._uploadNormals;
+ // }
+ /**
+ * Creates a new VertexAnimationSet
object.
+ *
+ * @param numPoses The number of poses made available at once to the GPU animation code.
+ * @param blendMode Optional value for setting the animation mode of the vertex animator object.
+ *
+ * @see away3d.animators.data.VertexAnimationMode
+ */
+ function VertexAnimationSet(numPoses, blendMode) {
+ if (numPoses === void 0) { numPoses = 2; }
+ if (blendMode === void 0) { blendMode = "absolute"; }
+ _super.call(this);
+ this._numPoses = numPoses;
+ this._blendMode = blendMode;
+ }
+ Object.defineProperty(VertexAnimationSet.prototype, "numPoses", {
+ /**
+ * Returns the number of poses made available at once to the GPU animation code.
+ */
+ get: function () {
+ return this._numPoses;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(VertexAnimationSet.prototype, "blendMode", {
+ /**
+ * Returns the active blend mode of the vertex animator object.
+ */
+ get: function () {
+ return this._blendMode;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.getAGALVertexCode = function (shaderObject) {
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE)
+ return this.getAbsoluteAGALCode(shaderObject);
+ else
+ return this.getAdditiveAGALCode(shaderObject);
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.activate = function (shaderObject, stage) {
+ // var uID:number = pass._iUniqueId;
+ // this._uploadNormals = this._useNormals[uID];
+ // this._uploadTangents = this._useTangents[uID];
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.deactivate = function (shaderObject, stage) {
+ // var uID:number = pass._iUniqueId;
+ // var index:number /*uint*/ = this._streamIndices[uID];
+ // var context:IContextStageGL = stage.context;
+ // context.setVertexBufferAt(index, null);
+ // if (this._uploadNormals)
+ // context.setVertexBufferAt(index + 1, null);
+ // if (this._uploadTangents)
+ // context.setVertexBufferAt(index + 2, null);
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.getAGALFragmentCode = function (shaderObject, shadedTarget) {
+ return "";
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.getAGALUVCode = function (shaderObject) {
+ return "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimationSet.prototype.doneAGALCode = function (shaderObject) {
+ };
+ /**
+ * Generates the vertex AGAL code for absolute blending.
+ */
+ VertexAnimationSet.prototype.getAbsoluteAGALCode = function (shaderObject) {
+ var code = "";
+ var temp1 = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var temp2 = this._pFindTempReg(shaderObject.animationTargetRegisters, temp1);
+ var regs = new Array("x", "y", "z", "w");
+ var len = shaderObject.animatableAttributes.length;
+ var constantReg = "vc" + shaderObject.numUsedVertexConstants;
+ if (len > 2)
+ len = 2;
+ var streamIndex = shaderObject.numUsedStreams;
+ for (var i = 0; i < len; ++i) {
+ code += "mul " + temp1 + ", " + shaderObject.animatableAttributes[i] + ", " + constantReg + "." + regs[0] + "\n";
+ for (var j = 1; j < this._numPoses; ++j) {
+ code += "mul " + temp2 + ", va" + streamIndex + ", " + constantReg + "." + regs[j] + "\n";
+ if (j < this._numPoses - 1)
+ code += "add " + temp1 + ", " + temp1 + ", " + temp2 + "\n";
+ ++streamIndex;
+ }
+ code += "add " + shaderObject.animationTargetRegisters[i] + ", " + temp1 + ", " + temp2 + "\n";
+ }
+ // add code for bitangents if tangents are used
+ if (shaderObject.tangentDependencies > 0 || shaderObject.outputsNormals) {
+ code += "dp3 " + temp1 + ".x, " + shaderObject.animatableAttributes[2] + ", " + shaderObject.animationTargetRegisters[1] + "\n" + "mul " + temp1 + ", " + shaderObject.animationTargetRegisters[1] + ", " + temp1 + ".x\n" + "sub " + shaderObject.animationTargetRegisters[2] + ", " + shaderObject.animationTargetRegisters[2] + ", " + temp1 + "\n";
+ }
+ return code;
+ };
+ /**
+ * Generates the vertex AGAL code for additive blending.
+ */
+ VertexAnimationSet.prototype.getAdditiveAGALCode = function (shaderObject) {
+ var code = "";
+ var len = shaderObject.animatableAttributes.length;
+ var regs = ["x", "y", "z", "w"];
+ var temp1 = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var k /*uint*/;
+ var streamIndex = shaderObject.numUsedStreams;
+ if (len > 2)
+ len = 2;
+ code += "mov " + shaderObject.animationTargetRegisters[0] + ", " + shaderObject.animatableAttributes[0] + "\n";
+ if (shaderObject.normalDependencies > 0)
+ code += "mov " + shaderObject.animationTargetRegisters[1] + ", " + shaderObject.animatableAttributes[1] + "\n";
+ for (var i = 0; i < len; ++i) {
+ for (var j = 0; j < this._numPoses; ++j) {
+ code += "mul " + temp1 + ", va" + (streamIndex + k) + ", vc" + shaderObject.numUsedVertexConstants + "." + regs[j] + "\n" + "add " + shaderObject.animationTargetRegisters[i] + ", " + shaderObject.animationTargetRegisters[i] + ", " + temp1 + "\n";
+ k++;
+ }
+ }
+ if (shaderObject.tangentDependencies > 0 || shaderObject.outputsNormals) {
+ code += "dp3 " + temp1 + ".x, " + shaderObject.animatableAttributes[2] + ", " + shaderObject.animationTargetRegisters[1] + "\n" + "mul " + temp1 + ", " + shaderObject.animationTargetRegisters[1] + ", " + temp1 + ".x\n" + "sub " + shaderObject.animationTargetRegisters[2] + ", " + shaderObject.animatableAttributes[2] + ", " + temp1 + "\n";
+ }
+ return code;
+ };
+ return VertexAnimationSet;
+})(AnimationSetBase);
+module.exports = VertexAnimationSet;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy92ZXJ0ZXhhbmltYXRpb25zZXQudHMiXSwibmFtZXMiOlsiVmVydGV4QW5pbWF0aW9uU2V0IiwiVmVydGV4QW5pbWF0aW9uU2V0LmNvbnN0cnVjdG9yIiwiVmVydGV4QW5pbWF0aW9uU2V0Lm51bVBvc2VzIiwiVmVydGV4QW5pbWF0aW9uU2V0LmJsZW5kTW9kZSIsIlZlcnRleEFuaW1hdGlvblNldC5nZXRBR0FMVmVydGV4Q29kZSIsIlZlcnRleEFuaW1hdGlvblNldC5hY3RpdmF0ZSIsIlZlcnRleEFuaW1hdGlvblNldC5kZWFjdGl2YXRlIiwiVmVydGV4QW5pbWF0aW9uU2V0LmdldEFHQUxGcmFnbWVudENvZGUiLCJWZXJ0ZXhBbmltYXRpb25TZXQuZ2V0QUdBTFVWQ29kZSIsIlZlcnRleEFuaW1hdGlvblNldC5kb25lQUdBTENvZGUiLCJWZXJ0ZXhBbmltYXRpb25TZXQuZ2V0QWJzb2x1dGVBR0FMQ29kZSIsIlZlcnRleEFuaW1hdGlvblNldC5nZXRBZGRpdGl2ZUFHQUxDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQSxJQUFPLGdCQUFnQixXQUFlLCtDQUErQyxDQUFDLENBQUM7QUFJdkYsSUFBTyxtQkFBbUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRXBHLEFBS0E7Ozs7R0FERztJQUNHLGtCQUFrQjtJQUFTQSxVQUEzQkEsa0JBQWtCQSxVQUF5QkE7SUFxQmhEQTs7T0FFR0E7SUFDSkEsbUNBQW1DQTtJQUNuQ0EsS0FBS0E7SUFDTEEsZ0NBQWdDQTtJQUNoQ0EsS0FBS0E7SUFFSkE7Ozs7Ozs7T0FPR0E7SUFDSEEsU0FyQ0tBLGtCQUFrQkEsQ0FxQ1hBLFFBQTRCQSxFQUFFQSxTQUE2QkE7UUFBM0RDLHdCQUE0QkEsR0FBNUJBLFlBQTRCQTtRQUFFQSx5QkFBNkJBLEdBQTdCQSxzQkFBNkJBO1FBRXRFQSxpQkFBT0EsQ0FBQ0E7UUFDUkEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDMUJBLElBQUlB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QUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUM5Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsR0FBR0EsWUFBWUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxHQUFHQSxXQUFXQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUVqSEEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBbUJBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBO2dCQUN6REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsV0FBV0EsR0FBR0EsSUFBSUEsR0FBR0EsV0FBV0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBRTFGQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDMUJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO2dCQUU3REEsRUFBRUEsV0FBV0EsQ0FBQ0E7WUFDZkEsQ0FBQ0E7WUFFREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNoR0EsQ0FBQ0E7UUFFREEsQUFD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QkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL1ZlcnRleEFuaW1hdGlvblNldC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBJQW5pbWF0aW9uU2V0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9hbmltYXRvcnMvSUFuaW1hdGlvblNldFwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblNldEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRpb25TZXRCYXNlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuXG5pbXBvcnQgVmVydGV4QW5pbWF0aW9uTW9kZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1ZlcnRleEFuaW1hdGlvbk1vZGVcIik7XG5cbi8qKlxuICogVGhlIGFuaW1hdGlvbiBkYXRhIHNldCB1c2VkIGJ5IHZlcnRleC1iYXNlZCBhbmltYXRvcnMsIGNvbnRhaW5pbmcgdmVydGV4IGFuaW1hdGlvbiBzdGF0ZSBkYXRhLlxuICpcbiAqIEBzZWUgVmVydGV4QW5pbWF0b3JcbiAqL1xuY2xhc3MgVmVydGV4QW5pbWF0aW9uU2V0IGV4dGVuZHMgQW5pbWF0aW9uU2V0QmFzZSBpbXBsZW1lbnRzIElBbmltYXRpb25TZXRcbntcblx0cHJpdmF0ZSBfbnVtUG9zZXM6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9ibGVuZE1vZGU6c3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcG9zZXMgbWFkZSBhdmFpbGFibGUgYXQgb25jZSB0byB0aGUgR1BVIGFuaW1hdGlvbiBjb2RlLlxuXHQgKi9cblx0cHVibGljIGdldCBudW1Qb3NlcygpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX251bVBvc2VzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGFjdGl2ZSBibGVuZCBtb2RlIG9mIHRoZSB2ZXJ0ZXggYW5pbWF0b3Igb2JqZWN0LlxuXHQgKi9cblx0cHVibGljIGdldCBibGVuZE1vZGUoKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLl9ibGVuZE1vZGU7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCBub3JtYWwgZGF0YSBpcyB1c2VkIGluIGxhc3Qgc2V0IEdQVSBwYXNzIG9mIHRoZSB2ZXJ0ZXggc2hhZGVyLlxuXHQgKi9cbi8vXHRcdHB1YmxpYyBnZXQgdXNlTm9ybWFscygpOmJvb2xlYW5cbi8vXHRcdHtcbi8vXHRcdFx0cmV0dXJuIHRoaXMuX3VwbG9hZE5vcm1hbHM7XG4vL1x0XHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+VmVydGV4QW5pbWF0aW9uU2V0PC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBudW1Qb3NlcyBUaGUgbnVtYmVyIG9mIHBvc2VzIG1hZGUgYXZhaWxhYmxlIGF0IG9uY2UgdG8gdGhlIEdQVSBhbmltYXRpb24gY29kZS5cblx0ICogQHBhcmFtIGJsZW5kTW9kZSBPcHRpb25hbCB2YWx1ZSBmb3Igc2V0dGluZyB0aGUgYW5pbWF0aW9uIG1vZGUgb2YgdGhlIHZlcnRleCBhbmltYXRvciBvYmplY3QuXG5cdCAqXG5cdCAqIEBzZWUgYXdheTNkLmFuaW1hdG9ycy5kYXRhLlZlcnRleEFuaW1hdGlvbk1vZGVcblx0ICovXG5cdGNvbnN0cnVjdG9yKG51bVBvc2VzOm51bWJlciAvKnVpbnQqLyA9IDIsIGJsZW5kTW9kZTpzdHJpbmcgPSBcImFic29sdXRlXCIpXG5cdHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMuX251bVBvc2VzID0gbnVtUG9zZXM7XG5cdFx0dGhpcy5fYmxlbmRNb2RlID0gYmxlbmRNb2RlO1xuXG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSk6c3RyaW5nXG5cdHtcblx0XHRpZiAodGhpcy5fYmxlbmRNb2RlID09IFZlcnRleEFuaW1hdGlvbk1vZGUuQUJTT0xVVEUpXG5cdFx0XHRyZXR1cm4gdGhpcy5nZXRBYnNvbHV0ZUFHQUxDb2RlKHNoYWRlck9iamVjdCk7XG5cdFx0ZWxzZVxuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0QWRkaXRpdmVBR0FMQ29kZShzaGFkZXJPYmplY3QpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIHN0YWdlOlN0YWdlKVxuXHR7XG4vL1x0XHRcdHZhciB1SUQ6bnVtYmVyID0gcGFzcy5faVVuaXF1ZUlkO1xuLy9cdFx0XHR0aGlzLl91cGxvYWROb3JtYWxzID0gPGJvb2xlYW4+IHRoaXMuX3VzZU5vcm1hbHNbdUlEXTtcbi8vXHRcdFx0dGhpcy5fdXBsb2FkVGFuZ2VudHMgPSA8Ym9vbGVhbj4gdGhpcy5fdXNlVGFuZ2VudHNbdUlEXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRlYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIHN0YWdlOlN0YWdlKVxuXHR7XG4vL1x0XHRcdHZhciB1SUQ6bnVtYmVyID0gcGFzcy5faVVuaXF1ZUlkO1xuLy9cdFx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qdWludCovID0gdGhpcy5fc3RyZWFtSW5kaWNlc1t1SURdO1xuLy9cdFx0XHR2YXIgY29udGV4dDpJQ29udGV4dFN0YWdlR0wgPSA8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0O1xuLy9cdFx0XHRjb250ZXh0LnNldFZlcnRleEJ1ZmZlckF0KGluZGV4LCBudWxsKTtcbi8vXHRcdFx0aWYgKHRoaXMuX3VwbG9hZE5vcm1hbHMpXG4vL1x0XHRcdFx0Y29udGV4dC5zZXRWZXJ0ZXhCdWZmZXJBdChpbmRleCArIDEsIG51bGwpO1xuLy9cdFx0XHRpZiAodGhpcy5fdXBsb2FkVGFuZ2VudHMpXG4vL1x0XHRcdFx0Y29udGV4dC5zZXRWZXJ0ZXhCdWZmZXJBdChpbmRleCArIDIsIG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc2hhZGVkVGFyZ2V0OnN0cmluZyk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIFwibW92IFwiICsgc2hhZGVyT2JqZWN0LnV2VGFyZ2V0ICsgXCIsXCIgKyBzaGFkZXJPYmplY3QudXZTb3VyY2UgKyBcIlxcblwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZG9uZUFHQUxDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKVxuXHR7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBHZW5lcmF0ZXMgdGhlIHZlcnRleCBBR0FMIGNvZGUgZm9yIGFic29sdXRlIGJsZW5kaW5nLlxuXHQgKi9cblx0cHJpdmF0ZSBnZXRBYnNvbHV0ZUFHQUxDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIHRlbXAxOnN0cmluZyA9IHRoaXMuX3BGaW5kVGVtcFJlZyhzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzKTtcblx0XHR2YXIgdGVtcDI6c3RyaW5nID0gdGhpcy5fcEZpbmRUZW1wUmVnKHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnMsIHRlbXAxKTtcblx0XHR2YXIgcmVnczpBcnJheTxzdHJpbmc+ID0gbmV3IEFycmF5PHN0cmluZz4oXCJ4XCIsIFwieVwiLCBcInpcIiwgXCJ3XCIpO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzLmxlbmd0aDtcblx0XHR2YXIgY29uc3RhbnRSZWc6c3RyaW5nID0gXCJ2Y1wiICsgc2hhZGVyT2JqZWN0Lm51bVVzZWRWZXJ0ZXhDb25zdGFudHM7XG5cblx0XHRpZiAobGVuID4gMilcblx0XHRcdGxlbiA9IDI7XG5cdFx0dmFyIHN0cmVhbUluZGV4Om51bWJlciAvKnVpbnQqLyA9IHNoYWRlck9iamVjdC5udW1Vc2VkU3RyZWFtcztcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcDEgKyBcIiwgXCIgKyBzaGFkZXJPYmplY3QuYW5pbWF0YWJsZUF0dHJpYnV0ZXNbaV0gKyBcIiwgXCIgKyBjb25zdGFudFJlZyArIFwiLlwiICsgcmVnc1swXSArIFwiXFxuXCI7XG5cblx0XHRcdGZvciAodmFyIGo6bnVtYmVyIC8qdWludCovID0gMTsgaiA8IHRoaXMuX251bVBvc2VzOyArK2opIHtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAyICsgXCIsIHZhXCIgKyBzdHJlYW1JbmRleCArIFwiLCBcIiArIGNvbnN0YW50UmVnICsgXCIuXCIgKyByZWdzW2pdICsgXCJcXG5cIjtcblxuXHRcdFx0XHRpZiAoaiA8IHRoaXMuX251bVBvc2VzIC0gMSlcblx0XHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdGVtcDEgKyBcIiwgXCIgKyB0ZW1wMSArIFwiLCBcIiArIHRlbXAyICsgXCJcXG5cIjtcblxuXHRcdFx0XHQrK3N0cmVhbUluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1tpXSArIFwiLCBcIiArIHRlbXAxICsgXCIsIFwiICsgdGVtcDIgKyBcIlxcblwiO1xuXHRcdH1cblxuXHRcdC8vIGFkZCBjb2RlIGZvciBiaXRhbmdlbnRzIGlmIHRhbmdlbnRzIGFyZSB1c2VkXG5cdFx0aWYgKHNoYWRlck9iamVjdC50YW5nZW50RGVwZW5kZW5jaWVzID4gMCB8fCBzaGFkZXJPYmplY3Qub3V0cHV0c05vcm1hbHMpIHtcblx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyB0ZW1wMSArIFwiLngsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzWzJdICsgXCIsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1sxXSArIFwiXFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAxICsgXCIsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1sxXSArIFwiLCBcIiArIHRlbXAxICsgXCIueFxcblwiICtcblx0XHRcdFx0XCJzdWIgXCIgKyBzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzWzJdICsgXCIsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1syXSArIFwiLCBcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHR9XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogR2VuZXJhdGVzIHRoZSB2ZXJ0ZXggQUdBTCBjb2RlIGZvciBhZGRpdGl2ZSBibGVuZGluZy5cblx0ICovXG5cdHByaXZhdGUgZ2V0QWRkaXRpdmVBR0FMQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzLmxlbmd0aDtcblx0XHR2YXIgcmVnczpBcnJheTxzdHJpbmc+ID0gW1wieFwiLCBcInlcIiwgXCJ6XCIsIFwid1wiXTtcblx0XHR2YXIgdGVtcDE6c3RyaW5nID0gdGhpcy5fcEZpbmRUZW1wUmVnKHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnMpO1xuXHRcdHZhciBrOm51bWJlciAvKnVpbnQqLztcblxuXHRcdHZhciBzdHJlYW1JbmRleDpudW1iZXIgLyp1aW50Ki8gPSBzaGFkZXJPYmplY3QubnVtVXNlZFN0cmVhbXM7XG5cblx0XHRpZiAobGVuID4gMilcblx0XHRcdGxlbiA9IDI7XG5cblx0XHRjb2RlICs9IFwibW92ICBcIiArIHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnNbMF0gKyBcIiwgXCIgKyBzaGFkZXJPYmplY3QuYW5pbWF0YWJsZUF0dHJpYnV0ZXNbMF0gKyBcIlxcblwiO1xuXHRcdGlmIChzaGFkZXJPYmplY3Qubm9ybWFsRGVwZW5kZW5jaWVzID4gMClcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzWzFdICsgXCIsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzWzFdICsgXCJcXG5cIjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cdFx0XHRmb3IgKHZhciBqOm51bWJlciAvKnVpbnQqLyA9IDA7IGogPCB0aGlzLl9udW1Qb3NlczsgKytqKSB7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ZW1wMSArIFwiLCB2YVwiICsgKHN0cmVhbUluZGV4ICsgaykgKyBcIiwgdmNcIiArIHNoYWRlck9iamVjdC5udW1Vc2VkVmVydGV4Q29uc3RhbnRzICsgXCIuXCIgKyByZWdzW2pdICsgXCJcXG5cIiArXG5cdFx0XHRcdFx0XCJhZGQgXCIgKyBzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzW2ldICsgXCIsIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1tpXSArIFwiLCBcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHRcdFx0aysrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChzaGFkZXJPYmplY3QudGFuZ2VudERlcGVuZGVuY2llcyA+IDAgfHwgc2hhZGVyT2JqZWN0Lm91dHB1dHNOb3JtYWxzKSB7XG5cdFx0XHRjb2RlICs9IFwiZHAzIFwiICsgdGVtcDEgKyBcIi54LCBcIiArIHNoYWRlck9iamVjdC5hbmltYXRhYmxlQXR0cmlidXRlc1syXSArIFwiLCBcIiArIHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnNbMV0gKyBcIlxcblwiICtcblx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wMSArIFwiLCBcIiArIHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnNbMV0gKyBcIiwgXCIgKyB0ZW1wMSArIFwiLnhcXG5cIiArXG5cdFx0XHRcdFwic3ViIFwiICsgc2hhZGVyT2JqZWN0LmFuaW1hdGlvblRhcmdldFJlZ2lzdGVyc1syXSArIFwiLCBcIiArIHNoYWRlck9iamVjdC5hbmltYXRhYmxlQXR0cmlidXRlc1syXSArIFwiLCBcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBWZXJ0ZXhBbmltYXRpb25TZXQ7Il19
\ No newline at end of file
diff --git a/lib/animators/VertexAnimationSet.ts b/lib/animators/VertexAnimationSet.ts
new file mode 100644
index 000000000..ed8d8385c
--- /dev/null
+++ b/lib/animators/VertexAnimationSet.ts
@@ -0,0 +1,197 @@
+import IAnimationSet = require("awayjs-core/lib/animators/IAnimationSet");
+
+import AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import VertexAnimationMode = require("awayjs-renderergl/lib/animators/data/VertexAnimationMode");
+
+/**
+ * The animation data set used by vertex-based animators, containing vertex animation state data.
+ *
+ * @see VertexAnimator
+ */
+class VertexAnimationSet extends AnimationSetBase implements IAnimationSet
+{
+ private _numPoses:number /*uint*/;
+ private _blendMode:string;
+
+ /**
+ * Returns the number of poses made available at once to the GPU animation code.
+ */
+ public get numPoses():number /*uint*/
+ {
+ return this._numPoses;
+ }
+
+ /**
+ * Returns the active blend mode of the vertex animator object.
+ */
+ public get blendMode():string
+ {
+ return this._blendMode;
+ }
+
+ /**
+ * Returns whether or not normal data is used in last set GPU pass of the vertex shader.
+ */
+// public get useNormals():boolean
+// {
+// return this._uploadNormals;
+// }
+
+ /**
+ * Creates a new VertexAnimationSet
object.
+ *
+ * @param numPoses The number of poses made available at once to the GPU animation code.
+ * @param blendMode Optional value for setting the animation mode of the vertex animator object.
+ *
+ * @see away3d.animators.data.VertexAnimationMode
+ */
+ constructor(numPoses:number /*uint*/ = 2, blendMode:string = "absolute")
+ {
+ super();
+ this._numPoses = numPoses;
+ this._blendMode = blendMode;
+
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase):string
+ {
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE)
+ return this.getAbsoluteAGALCode(shaderObject);
+ else
+ return this.getAdditiveAGALCode(shaderObject);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public activate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+// var uID:number = pass._iUniqueId;
+// this._uploadNormals = this._useNormals[uID];
+// this._uploadTangents = this._useTangents[uID];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public deactivate(shaderObject:ShaderObjectBase, stage:Stage)
+ {
+// var uID:number = pass._iUniqueId;
+// var index:number /*uint*/ = this._streamIndices[uID];
+// var context:IContextStageGL = stage.context;
+// context.setVertexBufferAt(index, null);
+// if (this._uploadNormals)
+// context.setVertexBufferAt(index + 1, null);
+// if (this._uploadTangents)
+// context.setVertexBufferAt(index + 2, null);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALFragmentCode(shaderObject:ShaderObjectBase, shadedTarget:string):string
+ {
+ return "";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase):string
+ {
+ return "mov " + shaderObject.uvTarget + "," + shaderObject.uvSource + "\n";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public doneAGALCode(shaderObject:ShaderObjectBase)
+ {
+
+ }
+
+ /**
+ * Generates the vertex AGAL code for absolute blending.
+ */
+ private getAbsoluteAGALCode(shaderObject:ShaderObjectBase):string
+ {
+ var code:string = "";
+ var temp1:string = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var temp2:string = this._pFindTempReg(shaderObject.animationTargetRegisters, temp1);
+ var regs:Array = new Array("x", "y", "z", "w");
+ var len:number /*uint*/ = shaderObject.animatableAttributes.length;
+ var constantReg:string = "vc" + shaderObject.numUsedVertexConstants;
+
+ if (len > 2)
+ len = 2;
+ var streamIndex:number /*uint*/ = shaderObject.numUsedStreams;
+
+ for (var i:number /*uint*/ = 0; i < len; ++i) {
+ code += "mul " + temp1 + ", " + shaderObject.animatableAttributes[i] + ", " + constantReg + "." + regs[0] + "\n";
+
+ for (var j:number /*uint*/ = 1; j < this._numPoses; ++j) {
+ code += "mul " + temp2 + ", va" + streamIndex + ", " + constantReg + "." + regs[j] + "\n";
+
+ if (j < this._numPoses - 1)
+ code += "add " + temp1 + ", " + temp1 + ", " + temp2 + "\n";
+
+ ++streamIndex;
+ }
+
+ code += "add " + shaderObject.animationTargetRegisters[i] + ", " + temp1 + ", " + temp2 + "\n";
+ }
+
+ // add code for bitangents if tangents are used
+ if (shaderObject.tangentDependencies > 0 || shaderObject.outputsNormals) {
+ code += "dp3 " + temp1 + ".x, " + shaderObject.animatableAttributes[2] + ", " + shaderObject.animationTargetRegisters[1] + "\n" +
+ "mul " + temp1 + ", " + shaderObject.animationTargetRegisters[1] + ", " + temp1 + ".x\n" +
+ "sub " + shaderObject.animationTargetRegisters[2] + ", " + shaderObject.animationTargetRegisters[2] + ", " + temp1 + "\n";
+ }
+ return code;
+ }
+
+ /**
+ * Generates the vertex AGAL code for additive blending.
+ */
+ private getAdditiveAGALCode(shaderObject:ShaderObjectBase):string
+ {
+ var code:string = "";
+ var len:number /*uint*/ = shaderObject.animatableAttributes.length;
+ var regs:Array = ["x", "y", "z", "w"];
+ var temp1:string = this._pFindTempReg(shaderObject.animationTargetRegisters);
+ var k:number /*uint*/;
+
+ var streamIndex:number /*uint*/ = shaderObject.numUsedStreams;
+
+ if (len > 2)
+ len = 2;
+
+ code += "mov " + shaderObject.animationTargetRegisters[0] + ", " + shaderObject.animatableAttributes[0] + "\n";
+ if (shaderObject.normalDependencies > 0)
+ code += "mov " + shaderObject.animationTargetRegisters[1] + ", " + shaderObject.animatableAttributes[1] + "\n";
+
+ for (var i:number /*uint*/ = 0; i < len; ++i) {
+ for (var j:number /*uint*/ = 0; j < this._numPoses; ++j) {
+ code += "mul " + temp1 + ", va" + (streamIndex + k) + ", vc" + shaderObject.numUsedVertexConstants + "." + regs[j] + "\n" +
+ "add " + shaderObject.animationTargetRegisters[i] + ", " + shaderObject.animationTargetRegisters[i] + ", " + temp1 + "\n";
+ k++;
+ }
+ }
+
+ if (shaderObject.tangentDependencies > 0 || shaderObject.outputsNormals) {
+ code += "dp3 " + temp1 + ".x, " + shaderObject.animatableAttributes[2] + ", " + shaderObject.animationTargetRegisters[1] + "\n" +
+ "mul " + temp1 + ", " + shaderObject.animationTargetRegisters[1] + ", " + temp1 + ".x\n" +
+ "sub " + shaderObject.animationTargetRegisters[2] + ", " + shaderObject.animatableAttributes[2] + ", " + temp1 + "\n";
+ }
+
+ return code;
+ }
+}
+
+export = VertexAnimationSet;
\ No newline at end of file
diff --git a/lib/animators/VertexAnimator.js b/lib/animators/VertexAnimator.js
new file mode 100755
index 000000000..3d7573ded
--- /dev/null
+++ b/lib/animators/VertexAnimator.js
@@ -0,0 +1,144 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+var AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+var VertexDataPool = require("awayjs-stagegl/lib/core/pool/VertexDataPool");
+var ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+var VertexAnimationMode = require("awayjs-renderergl/lib/animators/data/VertexAnimationMode");
+/**
+ * Provides an interface for assigning vertex-based animation data sets to mesh-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 = (function (_super) {
+ __extends(VertexAnimator, _super);
+ /**
+ * Creates a new VertexAnimator
object.
+ *
+ * @param vertexAnimationSet The animation data set containing the vertex animations used by the animator.
+ */
+ function VertexAnimator(vertexAnimationSet) {
+ _super.call(this, vertexAnimationSet);
+ this._poses = new Array();
+ this._weights = Array(1, 0, 0, 0);
+ this._vertexAnimationSet = vertexAnimationSet;
+ this._numPoses = vertexAnimationSet.numPoses;
+ this._blendMode = vertexAnimationSet.blendMode;
+ }
+ /**
+ * @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.currentGeometry) {
+ this._poses[0] = this._activeVertexState.currentGeometry;
+ geometryFlag = true;
+ }
+ if (this._poses[1] != this._activeVertexState.nextGeometry) {
+ this._poses[1] = this._activeVertexState.nextGeometry;
+ geometryFlag = true;
+ }
+ this._weights[0] = 1 - (this._weights[1] = this._activeVertexState.blendWeight);
+ if (geometryFlag) {
+ //invalidate meshes
+ var mesh;
+ var len = this._pOwners.length;
+ for (var i = 0; i < len; i++) {
+ mesh = this._pOwners[i];
+ mesh._iInvalidateRenderableGeometries();
+ }
+ }
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexAnimator.prototype.setRenderState = function (shaderObject, renderable, stage, camera, vertexConstantOffset /*int*/, vertexStreamOffset /*int*/) {
+ // todo: add code for when running on cpu
+ // if no poses defined, set temp data
+ if (!this._poses.length) {
+ this.setNullPose(shaderObject, renderable, stage, vertexConstantOffset, vertexStreamOffset);
+ return;
+ }
+ // this type of animation can only be SubMesh
+ var subMesh = renderable.subMesh;
+ var subGeom;
+ var i /*uint*/;
+ var len = this._numPoses;
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._weights, 1);
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE)
+ i = 1;
+ else
+ i = 0;
+ for (; i < len; ++i) {
+ subGeom = this._poses[i].subGeometries[subMesh._iIndex] || subMesh.subGeometry;
+ stage.context.activateBuffer(vertexStreamOffset++, VertexDataPool.getItem(subGeom, renderable.getIndexData(), TriangleSubGeometry.POSITION_DATA), subGeom.getOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ if (shaderObject.normalDependencies > 0)
+ stage.context.activateBuffer(vertexStreamOffset++, VertexDataPool.getItem(subGeom, renderable.getIndexData(), TriangleSubGeometry.NORMAL_DATA), subGeom.getOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT);
+ }
+ };
+ VertexAnimator.prototype.setNullPose = function (shaderObject, renderable, stage, vertexConstantOffset /*int*/, vertexStreamOffset /*int*/) {
+ stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._weights, 1);
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE) {
+ var len = this._numPoses;
+ for (var i = 1; i < len; ++i) {
+ stage.context.activateBuffer(vertexStreamOffset++, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ if (shaderObject.normalDependencies > 0)
+ stage.context.activateBuffer(vertexStreamOffset++, renderable.getVertexData(TriangleSubGeometry.NORMAL_DATA), renderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT);
+ }
+ }
+ // 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 (shaderObject) {
+ };
+ VertexAnimator.prototype.getRenderableSubGeometry = function (renderable, sourceSubGeometry) {
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE && this._poses.length)
+ return this._poses[0].subGeometries[renderable.subMesh._iIndex] || sourceSubGeometry;
+ //nothing to do here
+ return sourceSubGeometry;
+ };
+ return VertexAnimator;
+})(AnimatorBase);
+module.exports = VertexAnimator;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy92ZXJ0ZXhhbmltYXRvci50cyJdLCJuYW1lcyI6WyJWZXJ0ZXhBbmltYXRvciIsIlZlcnRleEFuaW1hdG9yLmNvbnN0cnVjdG9yIiwiVmVydGV4QW5pbWF0b3IuY2xvbmUiLCJWZXJ0ZXhBbmltYXRvci5wbGF5IiwiVmVydGV4QW5pbWF0b3IuX3BVcGRhdGVEZWx0YVRpbWUiLCJWZXJ0ZXhBbmltYXRvci5zZXRSZW5kZXJTdGF0ZSIsIlZlcnRleEFuaW1hdG9yLnNldE51bGxQb3NlIiwiVmVydGV4QW5pbWF0b3IudGVzdEdQVUNvbXBhdGliaWxpdHkiLCJWZXJ0ZXhBbmltYXRvci5nZXRSZW5kZXJhYmxlU3ViR2VvbWV0cnkiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLElBQU8sbUJBQW1CLFdBQWMsK0NBQStDLENBQUMsQ0FBQztBQUt6RixJQUFPLFlBQVksV0FBZ0IsMkNBQTJDLENBQUMsQ0FBQztBQUloRixJQUFPLGNBQWMsV0FBZSw2Q0FBNkMsQ0FBQyxDQUFDO0FBQ25GLElBQU8sb0JBQW9CLFdBQWMsc0RBQXNELENBQUMsQ0FBQztBQUtqRyxJQUFPLG1CQUFtQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFJcEcsQUFLQTs7OztHQURHO0lBQ0csY0FBYztJQUFTQSxVQUF2QkEsY0FBY0EsVUFBcUJBO0lBU3hDQTs7OztPQUlHQTtJQUNIQSxTQWRLQSxjQUFjQSxDQWNQQSxrQkFBcUNBO1FBRWhEQyxrQkFBTUEsa0JBQWtCQSxDQUFDQSxDQUFDQTtRQWJuQkEsV0FBTUEsR0FBbUJBLElBQUlBLEtBQUtBLEVBQVlBLENBQUNBO1FBQy9DQSxhQUFRQSxHQUFpQkEsS0FBS0EsQ0FBU0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFjMURBLElBQUlBLENBQUNBLG1CQUFtQkEsR0FBR0Esa0JBQWtCQSxDQUFDQTtRQUM5Q0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0Esa0JBQWtCQSxD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Q0FBQ0EsYUFBYUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsSUFBSUEsaUJBQWlCQSxDQUFDQTtRQUU1R0EsQUFDQUEsb0JBRG9CQTtRQUNwQkEsTUFBTUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQTtJQUMxQkEsQ0FBQ0E7SUFDRlIscUJBQUNBO0FBQURBLENBdEtBLEFBc0tDQSxFQXRLNEIsWUFBWSxFQXNLeEM7QUFFRCxBQUF3QixpQkFBZixjQUFjLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL1ZlcnRleEFuaW1hdG9yLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEdlb21ldHJ5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0dlb21ldHJ5XCIpO1xuaW1wb3J0IFN1Ykdlb21ldHJ5QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL1N1Ykdlb21ldHJ5QmFzZVwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL1RyaWFuZ2xlU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJNZXNoXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJNZXNoXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcbmltcG9ydCBNZXNoXHRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJNZXNoUmVuZGVyYWJsZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1RyaWFuZ2xlU3ViTWVzaFJlbmRlcmFibGVcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBWZXJ0ZXhEYXRhUG9vbFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1ZlcnRleERhdGFQb29sXCIpO1xuaW1wb3J0IENvbnRleHRHTFByb2dyYW1UeXBlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFByb2dyYW1UeXBlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcblxuaW1wb3J0IFZlcnRleEFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9WZXJ0ZXhBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgVmVydGV4QW5pbWF0aW9uTW9kZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1ZlcnRleEFuaW1hdGlvbk1vZGVcIik7XG5pbXBvcnQgSVZlcnRleEFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVZlcnRleEFuaW1hdGlvblN0YXRlXCIpO1xuaW1wb3J0IElBbmltYXRpb25UcmFuc2l0aW9uXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3RyYW5zaXRpb25zL0lBbmltYXRpb25UcmFuc2l0aW9uXCIpO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgYXNzaWduaW5nIHZlcnRleC1iYXNlZCBhbmltYXRpb24gZGF0YSBzZXRzIHRvIG1lc2gtYmFzZWQgZW50aXR5IG9iamVjdHNcbiAqIGFuZCBjb250cm9sbGluZyB0aGUgdmFyaW91cyBhdmFpbGFibGUgc3RhdGVzIG9mIGFuaW1hdGlvbiB0aHJvdWdoIGFuIGludGVyYXRpdmUgcGxheWhlYWQgdGhhdCBjYW4gYmVcbiAqIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCBvciBtYW51YWxseSB0cmlnZ2VyZWQuXG4gKi9cbmNsYXNzIFZlcnRleEFuaW1hdG9yIGV4dGVuZHMgQW5pbWF0b3JCYXNlXG57XG5cdHByaXZhdGUgX3ZlcnRleEFuaW1hdGlvblNldDpWZXJ0ZXhBbmltYXRpb25TZXQ7XG5cdHByaXZhdGUgX3Bvc2VzOkFycmF5PEdlb21ldHJ5PiA9IG5ldyBBcnJheTxHZW9tZXRyeT4oKTtcblx0cHJpdmF0ZSBfd2VpZ2h0czpBcnJheTxudW1iZXI+ID0gQXJyYXk8bnVtYmVyPigxLCAwLCAwLCAwKTtcblx0cHJpdmF0ZSBfbnVtUG9zZXM6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9ibGVuZE1vZGU6c3RyaW5nO1xuXHRwcml2YXRlIF9hY3RpdmVWZXJ0ZXhTdGF0ZTpJVmVydGV4QW5pbWF0aW9uU3RhdGU7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+VmVydGV4QW5pbWF0b3I8L2NvZGU+IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHZlcnRleEFuaW1hdGlvblNldCBUaGUgYW5pbWF0aW9uIGRhdGEgc2V0IGNvbnRhaW5pbmcgdGhlIHZlcnRleCBhbmltYXRpb25zIHVzZWQgYnkgdGhlIGFuaW1hdG9yLlxuXHQgKi9cblx0Y29uc3RydWN0b3IodmVydGV4QW5pbWF0aW9uU2V0OlZlcnRleEFuaW1hdGlvblNldClcblx0e1xuXHRcdHN1cGVyKHZlcnRleEFuaW1hdGlvblNldCk7XG5cblx0XHR0aGlzLl92ZXJ0ZXhBbmltYXRpb25TZXQgPSB2ZXJ0ZXhBbmltYXRpb25TZXQ7XG5cdFx0dGhpcy5fbnVtUG9zZXMgPSB2ZXJ0ZXhBbmltYXRpb25TZXQubnVtUG9zZXM7XG5cdFx0dGhpcy5fYmxlbmRNb2RlID0gdmVydGV4QW5pbWF0aW9uU2V0LmJsZW5kTW9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGNsb25lKCk6QW5pbWF0b3JCYXNlXG5cdHtcblx0XHRyZXR1cm4gbmV3IFZlcnRleEFuaW1hdG9yKHRoaXMuX3ZlcnRleEFuaW1hdGlvblNldCk7XG5cdH1cblxuXHQvKipcblx0ICogUGxheXMgYSBzZXF1ZW5jZSB3aXRoIGEgZ2l2ZW4gbmFtZS4gSWYgdGhlIHNlcXVlbmNlIGlzIG5vdCBmb3VuZCwgaXQgbWF5IG5vdCBiZSBsb2FkZWQgeWV0LCBhbmQgaXQgd2lsbCByZXRyeSBldmVyeSBmcmFtZS5cblx0ICogQHBhcmFtIHNlcXVlbmNlTmFtZSBUaGUgbmFtZSBvZiB0aGUgY2xpcCB0byBiZSBwbGF5ZWQuXG5cdCAqL1xuXHRwdWJsaWMgcGxheShuYW1lOnN0cmluZywgdHJhbnNpdGlvbjpJQW5pbWF0aW9uVHJhbnNpdGlvbiA9IG51bGwsIG9mZnNldDpudW1iZXIgPSBOYU4pXG5cdHtcblx0XHRpZiAodGhpcy5fcEFjdGl2ZUFuaW1hdGlvbk5hbWUgPT0gbmFtZSlcblx0XHRcdHJldHVybjtcblxuXHRcdHRoaXMuX3BBY3RpdmVBbmltYXRpb25OYW1lID0gbmFtZTtcblxuXHRcdC8vVE9ETzogaW1wbGVtZW50IHRyYW5zaXRpb25zIGluIHZlcnRleCBhbmltYXRvclxuXG5cdFx0aWYgKCF0aGlzLl9wQW5pbWF0aW9uU2V0Lmhhc0FuaW1hdGlvbihuYW1lKSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkFuaW1hdGlvbiByb290IG5vZGUgXCIgKyBuYW1lICsgXCIgbm90IGZvdW5kIVwiKTtcblxuXHRcdHRoaXMuX3BBY3RpdmVOb2RlID0gdGhpcy5fcEFuaW1hdGlvblNldC5nZXRBbmltYXRpb24obmFtZSk7XG5cblx0XHR0aGlzLl9wQWN0aXZlU3RhdGUgPSB0aGlzLmdldEFuaW1hdGlvblN0YXRlKHRoaXMuX3BBY3RpdmVOb2RlKTtcblxuXHRcdGlmICh0aGlzLnVwZGF0ZVBvc2l0aW9uKSB7XG5cdFx0XHQvL3VwZGF0ZSBzdHJhaWdodCBhd2F5IHRvIHJlc2V0IHBvc2l0aW9uIGRlbHRhc1xuXHRcdFx0dGhpcy5fcEFjdGl2ZVN0YXRlLnVwZGF0ZSh0aGlzLl9wQWJzb2x1dGVUaW1lKTtcblx0XHRcdHRoaXMuX3BBY3RpdmVTdGF0ZS5wb3NpdGlvbkRlbHRhO1xuXHRcdH1cblxuXHRcdHRoaXMuX2FjdGl2ZVZlcnRleFN0YXRlID0gPElWZXJ0ZXhBbmltYXRpb25TdGF0ZT4gdGhpcy5fcEFjdGl2ZVN0YXRlO1xuXG5cdFx0dGhpcy5zdGFydCgpO1xuXG5cdFx0Ly9hcHBseSBhIHRpbWUgb2Zmc2V0IGlmIHNwZWNpZmllZFxuXHRcdGlmICghaXNOYU4ob2Zmc2V0KSlcblx0XHRcdHRoaXMucmVzZXQobmFtZSwgb2Zmc2V0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlRGVsdGFUaW1lKGR0Om51bWJlcilcblx0e1xuXHRcdHN1cGVyLl9wVXBkYXRlRGVsdGFUaW1lKGR0KTtcblxuXHRcdHZhciBnZW9tZXRyeUZsYWc6Ym9vbGVhbiA9IGZhbHNlO1xuXG5cdFx0aWYgKHRoaXMuX3Bvc2VzWzBdICE9IHRoaXMuX2FjdGl2ZVZlcnRleFN0YXRlLmN1cnJlbnRHZW9tZXRyeSkge1xuXHRcdFx0dGhpcy5fcG9zZXNbMF0gPSB0aGlzLl9hY3RpdmVWZXJ0ZXhTdGF0ZS5jdXJyZW50R2VvbWV0cnk7XG5cdFx0XHRnZW9tZXRyeUZsYWcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9wb3Nlc1sxXSAhPSB0aGlzLl9hY3RpdmVWZXJ0ZXhTdGF0ZS5uZXh0R2VvbWV0cnkpIHtcblx0XHRcdHRoaXMuX3Bvc2VzWzFdID0gdGhpcy5fYWN0aXZlVmVydGV4U3RhdGUubmV4dEdlb21ldHJ5O1xuXHRcdFx0Z2VvbWV0cnlGbGFnID0gdHJ1ZTtcblx0XHR9XG5cblx0XHR0aGlzLl93ZWlnaHRzWzBdID0gMSAtICh0aGlzLl93ZWlnaHRzWzFdID0gdGhpcy5fYWN0aXZlVmVydGV4U3RhdGUuYmxlbmRXZWlnaHQpO1xuXG5cdFx0aWYgKGdlb21ldHJ5RmxhZykge1xuXHRcdFx0Ly9pbnZhbGlkYXRlIG1lc2hlc1xuXHRcdFx0dmFyIG1lc2g6TWVzaDtcblx0XHRcdHZhciBsZW46bnVtYmVyID0gdGhpcy5fcE93bmVycy5sZW5ndGg7XG5cdFx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRtZXNoID0gdGhpcy5fcE93bmVyc1tpXTtcblx0XHRcdFx0bWVzaC5faUludmFsaWRhdGVSZW5kZXJhYmxlR2VvbWV0cmllcygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSwgdmVydGV4Q29uc3RhbnRPZmZzZXQ6bnVtYmVyIC8qaW50Ki8sIHZlcnRleFN0cmVhbU9mZnNldDpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdC8vIHRvZG86IGFkZCBjb2RlIGZvciB3aGVuIHJ1bm5pbmcgb24gY3B1XG5cblx0XHQvLyBpZiBubyBwb3NlcyBkZWZpbmVkLCBzZXQgdGVtcCBkYXRhXG5cdFx0aWYgKCF0aGlzLl9wb3Nlcy5sZW5ndGgpIHtcblx0XHRcdHRoaXMuc2V0TnVsbFBvc2Uoc2hhZGVyT2JqZWN0LCByZW5kZXJhYmxlLCBzdGFnZSwgdmVydGV4Q29uc3RhbnRPZmZzZXQsIHZlcnRleFN0cmVhbU9mZnNldCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcyB0eXBlIG9mIGFuaW1hdGlvbiBjYW4gb25seSBiZSBTdWJNZXNoXG5cdFx0dmFyIHN1Yk1lc2g6VHJpYW5nbGVTdWJNZXNoID0gPFRyaWFuZ2xlU3ViTWVzaD4gKDxUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlPiByZW5kZXJhYmxlKS5zdWJNZXNoO1xuXHRcdHZhciBzdWJHZW9tOlN1Ykdlb21ldHJ5QmFzZTtcblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9udW1Qb3NlcztcblxuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbUFycmF5KENvbnRleHRHTFByb2dyYW1UeXBlLlZFUlRFWCwgdmVydGV4Q29uc3RhbnRPZmZzZXQsIHRoaXMuX3dlaWdodHMsIDEpO1xuXG5cdFx0aWYgKHRoaXMuX2JsZW5kTW9kZSA9PSBWZXJ0ZXhBbmltYXRpb25Nb2RlLkFCU09MVVRFKVxuXHRcdFx0aSA9IDE7XG5cdFx0ZWxzZVxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKDsgaSA8IGxlbjsgKytpKSB7XG5cdFx0XHRzdWJHZW9tID0gdGhpcy5fcG9zZXNbaV0uc3ViR2VvbWV0cmllc1tzdWJNZXNoLl9pSW5kZXhdIHx8IHN1Yk1lc2guc3ViR2VvbWV0cnk7XG5cblx0XHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZUJ1ZmZlcih2ZXJ0ZXhTdHJlYW1PZmZzZXQrKywgVmVydGV4RGF0YVBvb2wuZ2V0SXRlbShzdWJHZW9tLCByZW5kZXJhYmxlLmdldEluZGV4RGF0YSgpLCBUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLCBzdWJHZW9tLmdldE9mZnNldChUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLCBUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0ZPUk1BVCk7XG5cblx0XHRcdGlmIChzaGFkZXJPYmplY3Qubm9ybWFsRGVwZW5kZW5jaWVzID4gMClcblx0XHRcdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlQnVmZmVyKHZlcnRleFN0cmVhbU9mZnNldCsrLCBWZXJ0ZXhEYXRhUG9vbC5nZXRJdGVtKHN1Ykdlb20sIHJlbmRlcmFibGUuZ2V0SW5kZXhEYXRhKCksIFRyaWFuZ2xlU3ViR2VvbWV0cnkuTk9STUFMX0RBVEEpLCBzdWJHZW9tLmdldE9mZnNldChUcmlhbmdsZVN1Ykdlb21ldHJ5Lk5PUk1BTF9EQVRBKSwgVHJpYW5nbGVTdWJHZW9tZXRyeS5OT1JNQUxfRk9STUFUKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHNldE51bGxQb3NlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgdmVydGV4Q29uc3RhbnRPZmZzZXQ6bnVtYmVyIC8qaW50Ki8sIHZlcnRleFN0cmVhbU9mZnNldDpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbUFycmF5KENvbnRleHRHTFByb2dyYW1UeXBlLlZFUlRFWCwgdmVydGV4Q29uc3RhbnRPZmZzZXQsIHRoaXMuX3dlaWdodHMsIDEpO1xuXG5cdFx0aWYgKHRoaXMuX2JsZW5kTW9kZSA9PSBWZXJ0ZXhBbmltYXRpb25Nb2RlLkFCU09MVVRFKSB7XG5cdFx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX251bVBvc2VzO1xuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAxOyBpIDwgbGVuOyArK2kpIHtcblx0XHRcdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlQnVmZmVyKHZlcnRleFN0cmVhbU9mZnNldCsrLCByZW5kZXJhYmxlLmdldFZlcnRleERhdGEoVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9EQVRBKSwgcmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9EQVRBKSwgVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9GT1JNQVQpO1xuXG5cdFx0XHRcdGlmIChzaGFkZXJPYmplY3Qubm9ybWFsRGVwZW5kZW5jaWVzID4gMClcblx0XHRcdFx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVCdWZmZXIodmVydGV4U3RyZWFtT2Zmc2V0KyssIHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5Lk5PUk1BTF9EQVRBKSwgcmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5OT1JNQUxfREFUQSksIFRyaWFuZ2xlU3ViR2VvbWV0cnkuTk9STUFMX0ZPUk1BVCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIHRvZG86IHNldCB0ZW1wIGRhdGEgZm9yIGFkZGl0aXZlP1xuXHR9XG5cblx0LyoqXG5cdCAqIFZlcmlmaWVzIGlmIHRoZSBhbmltYXRpb24gd2lsbCBiZSB1c2VkIG9uIGNwdS4gTmVlZHMgdG8gYmUgdHJ1ZSBmb3IgYWxsIHBhc3NlcyBmb3IgYSBtYXRlcmlhbCB0byBiZSBhYmxlIHRvIHVzZSBpdCBvbiBncHUuXG5cdCAqIE5lZWRzIHRvIGJlIGNhbGxlZCBpZiBncHUgY29kZSBpcyBwb3RlbnRpYWxseSByZXF1aXJlZC5cblx0ICovXG5cdHB1YmxpYyB0ZXN0R1BVQ29tcGF0aWJpbGl0eShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSlcblx0e1xuXHR9XG5cblx0cHVibGljIGdldFJlbmRlcmFibGVTdWJHZW9tZXRyeShyZW5kZXJhYmxlOlRyaWFuZ2xlU3ViTWVzaFJlbmRlcmFibGUsIHNvdXJjZVN1Ykdlb21ldHJ5OlRyaWFuZ2xlU3ViR2VvbWV0cnkpOlRyaWFuZ2xlU3ViR2VvbWV0cnlcblx0e1xuXHRcdGlmICh0aGlzLl9ibGVuZE1vZGUgPT0gVmVydGV4QW5pbWF0aW9uTW9kZS5BQlNPTFVURSAmJiB0aGlzLl9wb3Nlcy5sZW5ndGgpXG5cdFx0XHRyZXR1cm4gPFRyaWFuZ2xlU3ViR2VvbWV0cnk+IHRoaXMuX3Bvc2VzWzBdLnN1Ykdlb21ldHJpZXNbcmVuZGVyYWJsZS5zdWJNZXNoLl9pSW5kZXhdIHx8IHNvdXJjZVN1Ykdlb21ldHJ5O1xuXG5cdFx0Ly9ub3RoaW5nIHRvIGRvIGhlcmVcblx0XHRyZXR1cm4gc291cmNlU3ViR2VvbWV0cnk7XG5cdH1cbn1cblxuZXhwb3J0ID0gVmVydGV4QW5pbWF0b3I7Il19
\ No newline at end of file
diff --git a/lib/animators/VertexAnimator.ts b/lib/animators/VertexAnimator.ts
new file mode 100644
index 000000000..e713fa7b7
--- /dev/null
+++ b/lib/animators/VertexAnimator.ts
@@ -0,0 +1,195 @@
+import Geometry = require("awayjs-core/lib/core/base/Geometry");
+import SubGeometryBase = require("awayjs-core/lib/core/base/SubGeometryBase");
+import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+import TriangleSubMesh = require("awayjs-core/lib/core/base/TriangleSubMesh");
+import Camera = require("awayjs-core/lib/entities/Camera");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import TriangleSubMeshRenderable = require("awayjs-stagegl/lib/core/pool/TriangleSubMeshRenderable");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import VertexDataPool = require("awayjs-stagegl/lib/core/pool/VertexDataPool");
+import ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import VertexAnimationSet = require("awayjs-renderergl/lib/animators/VertexAnimationSet");
+import VertexAnimationMode = require("awayjs-renderergl/lib/animators/data/VertexAnimationMode");
+import IVertexAnimationState = require("awayjs-renderergl/lib/animators/states/IVertexAnimationState");
+import IAnimationTransition = require("awayjs-renderergl/lib/animators/transitions/IAnimationTransition");
+
+/**
+ * Provides an interface for assigning vertex-based animation data sets to mesh-based entity objects
+ * and controlling the various available states of animation through an interative playhead that can be
+ * automatically updated or manually triggered.
+ */
+class VertexAnimator extends AnimatorBase
+{
+ private _vertexAnimationSet:VertexAnimationSet;
+ private _poses:Array = new Array();
+ private _weights:Array = Array(1, 0, 0, 0);
+ private _numPoses:number /*uint*/;
+ private _blendMode:string;
+ private _activeVertexState:IVertexAnimationState;
+
+ /**
+ * Creates a new VertexAnimator
object.
+ *
+ * @param vertexAnimationSet The animation data set containing the vertex animations used by the animator.
+ */
+ constructor(vertexAnimationSet:VertexAnimationSet)
+ {
+ super(vertexAnimationSet);
+
+ this._vertexAnimationSet = vertexAnimationSet;
+ this._numPoses = vertexAnimationSet.numPoses;
+ this._blendMode = vertexAnimationSet.blendMode;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public clone():AnimatorBase
+ {
+ 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.
+ */
+ public play(name:string, transition:IAnimationTransition = null, offset:number = 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
+ */
+ public _pUpdateDeltaTime(dt:number)
+ {
+ super._pUpdateDeltaTime(dt);
+
+ var geometryFlag:boolean = false;
+
+ if (this._poses[0] != this._activeVertexState.currentGeometry) {
+ this._poses[0] = this._activeVertexState.currentGeometry;
+ geometryFlag = true;
+ }
+
+ if (this._poses[1] != this._activeVertexState.nextGeometry) {
+ this._poses[1] = this._activeVertexState.nextGeometry;
+ geometryFlag = true;
+ }
+
+ this._weights[0] = 1 - (this._weights[1] = this._activeVertexState.blendWeight);
+
+ if (geometryFlag) {
+ //invalidate meshes
+ var mesh:Mesh;
+ var len:number = this._pOwners.length;
+ for (var i:number = 0; i < len; i++) {
+ mesh = this._pOwners[i];
+ mesh._iInvalidateRenderableGeometries();
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(shaderObject:ShaderObjectBase, renderable:RenderableBase, stage:Stage, camera:Camera, vertexConstantOffset:number /*int*/, vertexStreamOffset:number /*int*/)
+ {
+ // todo: add code for when running on cpu
+
+ // if no poses defined, set temp data
+ if (!this._poses.length) {
+ this.setNullPose(shaderObject, renderable, stage, vertexConstantOffset, vertexStreamOffset);
+ return;
+ }
+
+ // this type of animation can only be SubMesh
+ var subMesh:TriangleSubMesh = ( renderable).subMesh;
+ var subGeom:SubGeometryBase;
+ var i:number /*uint*/;
+ var len:number /*uint*/ = this._numPoses;
+
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._weights, 1);
+
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE)
+ i = 1;
+ else
+ i = 0;
+
+ for (; i < len; ++i) {
+ subGeom = this._poses[i].subGeometries[subMesh._iIndex] || subMesh.subGeometry;
+
+ ( stage.context).activateBuffer(vertexStreamOffset++, VertexDataPool.getItem(subGeom, renderable.getIndexData(), TriangleSubGeometry.POSITION_DATA), subGeom.getOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+
+ if (shaderObject.normalDependencies > 0)
+ ( stage.context).activateBuffer(vertexStreamOffset++, VertexDataPool.getItem(subGeom, renderable.getIndexData(), TriangleSubGeometry.NORMAL_DATA), subGeom.getOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT);
+ }
+ }
+
+ private setNullPose(shaderObject:ShaderObjectBase, renderable:RenderableBase, stage:Stage, vertexConstantOffset:number /*int*/, vertexStreamOffset:number /*int*/)
+ {
+ ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, vertexConstantOffset, this._weights, 1);
+
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE) {
+ var len:number /*uint*/ = this._numPoses;
+ for (var i:number /*uint*/ = 1; i < len; ++i) {
+ ( stage.context).activateBuffer(vertexStreamOffset++, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+
+ if (shaderObject.normalDependencies > 0)
+ ( stage.context).activateBuffer(vertexStreamOffset++, renderable.getVertexData(TriangleSubGeometry.NORMAL_DATA), renderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT);
+ }
+ }
+ // 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.
+ */
+ public testGPUCompatibility(shaderObject:ShaderObjectBase)
+ {
+ }
+
+ public getRenderableSubGeometry(renderable:TriangleSubMeshRenderable, sourceSubGeometry:TriangleSubGeometry):TriangleSubGeometry
+ {
+ if (this._blendMode == VertexAnimationMode.ABSOLUTE && this._poses.length)
+ return this._poses[0].subGeometries[renderable.subMesh._iIndex] || sourceSubGeometry;
+
+ //nothing to do here
+ return sourceSubGeometry;
+ }
+}
+
+export = VertexAnimator;
\ No newline at end of file
diff --git a/lib/animators/data/AnimationSubGeometry.js b/lib/animators/data/AnimationSubGeometry.js
new file mode 100755
index 000000000..8ed4d8fd5
--- /dev/null
+++ b/lib/animators/data/AnimationSubGeometry.js
@@ -0,0 +1,73 @@
+/**
+ * ...
+ */
+var AnimationSubGeometry = (function () {
+ function AnimationSubGeometry() {
+ this._pVertexBuffer = new Array(8);
+ this._pBufferContext = new Array(8);
+ this._pBufferDirty = new Array(8);
+ this.numProcessedVertices = 0;
+ this.previousTime = Number.NEGATIVE_INFINITY;
+ this.animationParticles = new Array();
+ for (var i = 0; i < 8; i++)
+ this._pBufferDirty[i] = true;
+ this._iUniqueId = AnimationSubGeometry.SUBGEOM_ID_COUNT++;
+ }
+ AnimationSubGeometry.prototype.createVertexData = function (numVertices /*uint*/, totalLenOfOneVertex /*uint*/) {
+ this._numVertices = numVertices;
+ this._totalLenOfOneVertex = totalLenOfOneVertex;
+ this._pVertexData = new Array(numVertices * totalLenOfOneVertex);
+ };
+ AnimationSubGeometry.prototype.activateVertexBuffer = function (index /*int*/, bufferOffset /*int*/, stage, format) {
+ var contextIndex = stage.stageIndex;
+ var context = stage.context;
+ var buffer = this._pVertexBuffer[contextIndex];
+ if (!buffer || this._pBufferContext[contextIndex] != context) {
+ buffer = this._pVertexBuffer[contextIndex] = context.createVertexBuffer(this._numVertices, this._totalLenOfOneVertex);
+ this._pBufferContext[contextIndex] = context;
+ this._pBufferDirty[contextIndex] = true;
+ }
+ if (this._pBufferDirty[contextIndex]) {
+ buffer.uploadFromArray(this._pVertexData, 0, this._numVertices);
+ this._pBufferDirty[contextIndex] = false;
+ }
+ context.setVertexBufferAt(index, buffer, bufferOffset, format);
+ };
+ AnimationSubGeometry.prototype.dispose = function () {
+ while (this._pVertexBuffer.length) {
+ var vertexBuffer = this._pVertexBuffer.pop();
+ if (vertexBuffer)
+ vertexBuffer.dispose();
+ }
+ };
+ AnimationSubGeometry.prototype.invalidateBuffer = function () {
+ for (var i = 0; i < 8; i++)
+ this._pBufferDirty[i] = true;
+ };
+ Object.defineProperty(AnimationSubGeometry.prototype, "vertexData", {
+ get: function () {
+ return this._pVertexData;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationSubGeometry.prototype, "numVertices", {
+ get: function () {
+ return this._numVertices;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationSubGeometry.prototype, "totalLenOfOneVertex", {
+ get: function () {
+ return this._totalLenOfOneVertex;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ AnimationSubGeometry.SUBGEOM_ID_COUNT = 0;
+ return AnimationSubGeometry;
+})();
+module.exports = AnimationSubGeometry;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL2FuaW1hdGlvbnN1Ymdlb21ldHJ5LnRzIl0sIm5hbWVzIjpbIkFuaW1hdGlvblN1Ykdlb21ldHJ5IiwiQW5pbWF0aW9uU3ViR2VvbWV0cnkuY29uc3RydWN0b3IiLCJBbmltYXRpb25TdWJHZW9tZXRyeS5jcmVhdGVWZXJ0ZXhEYXRhIiwiQW5pbWF0aW9uU3ViR2VvbWV0cnkuYWN0aXZhdGVWZXJ0ZXhCdWZmZXIiLCJBbmltYXRpb25TdWJHZW9tZXRyeS5kaXNwb3NlIiwiQW5pbWF0aW9uU3ViR2VvbWV0cnkuaW52YWxpZGF0ZUJ1ZmZlciIsIkFuaW1hdGlvblN1Ykdlb21ldHJ5LnZlcnRleERhdGEiLCJBbmltYXRpb25TdWJHZW9tZXRyeS5udW1WZXJ0aWNlcyIsIkFuaW1hdGlvblN1Ykdlb21ldHJ5LnRvdGFsTGVuT2ZPbmVWZXJ0ZXgiXSwibWFwcGluZ3MiOiJBQU1BLEFBR0E7O0dBREc7SUFDRyxvQkFBb0I7SUEyQnpCQSxTQTNCS0Esb0JBQW9CQTtRQU1sQkMsbUJBQWNBLEdBQXdCQSxJQUFJQSxLQUFLQSxDQUFnQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDbEVBLG9CQUFlQSxHQUEwQkEsSUFBSUEsS0FBS0EsQ0FBa0JBLENBQUNBLENBQUNBLENBQUNBO1FBQ3ZFQSxrQkFBYUEsR0FBa0JBLElBQUlBLEtBQUtBLENBQVVBLENBQUNBLENBQUNBLENBQUNBO1FBTXJEQSx5QkFBb0JBLEdBQWtCQSxDQUFDQSxDQUFDQTtRQUV4Q0EsaUJBQVlBLEdBQVVBLE1BQU1BLENBQUNBLGlCQUFpQkEsQ0FBQ0E7UUFFL0NBLHVCQUFrQkEsR0FBZ0NBLElBQUlBLEtBQUtBLEVBQXlCQSxDQUFDQTtRQVczRkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBa0JBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBO1lBQ3hDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxD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Qy9CQSxDQUFDQTtJQUVETCxzQkFBV0EsNENBQVVBO2FBQXJCQTtZQUVDTSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQTtRQUMxQkEsQ0FBQ0E7OztPQUFBTjtJQUVEQSxzQkFBV0EsNkNBQVdBO2FBQXRCQTtZQUVDTyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQTtRQUMxQkEsQ0FBQ0E7OztPQUFBUDtJQUVEQSxzQkFBV0EscURBQW1CQTthQUE5QkE7WUFFQ1EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUNsQ0EsQ0FBQ0E7OztPQUFBUjtJQXZGYUEscUNBQWdCQSxHQUFVQSxDQUFDQSxDQUFDQTtJQXdGM0NBLDJCQUFDQTtBQUFEQSxDQTFGQSxBQTBGQ0EsSUFBQTtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgSVZlcnRleEJ1ZmZlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lWZXJ0ZXhCdWZmZXJcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdGlvbkRhdGFcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVBbmltYXRpb25EYXRhXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBBbmltYXRpb25TdWJHZW9tZXRyeVxue1xuXHRwdWJsaWMgc3RhdGljIFNVQkdFT01fSURfQ09VTlQ6bnVtYmVyID0gMDtcblxuXHRwdWJsaWMgX3BWZXJ0ZXhEYXRhOkFycmF5PG51bWJlcj47XG5cblx0cHVibGljIF9wVmVydGV4QnVmZmVyOkFycmF5PElWZXJ0ZXhCdWZmZXI+ID0gbmV3IEFycmF5PElWZXJ0ZXhCdWZmZXI+KDgpO1xuXHRwdWJsaWMgX3BCdWZmZXJDb250ZXh0OkFycmF5PElDb250ZXh0U3RhZ2VHTD4gPSBuZXcgQXJyYXk8SUNvbnRleHRTdGFnZUdMPig4KTtcblx0cHVibGljIF9wQnVmZmVyRGlydHk6QXJyYXk8Ym9vbGVhbj4gPSBuZXcgQXJyYXk8Ym9vbGVhbj4oOCk7XG5cblx0cHJpdmF0ZSBfbnVtVmVydGljZXM6bnVtYmVyIC8qdWludCovO1xuXG5cdHByaXZhdGUgX3RvdGFsTGVuT2ZPbmVWZXJ0ZXg6bnVtYmVyIC8qdWludCovO1xuXG5cdHB1YmxpYyBudW1Qcm9jZXNzZWRWZXJ0aWNlczpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0cHVibGljIHByZXZpb3VzVGltZTpudW1iZXIgPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cblx0cHVibGljIGFuaW1hdGlvblBhcnRpY2xlczpBcnJheTxQYXJ0aWNsZUFuaW1hdGlvbkRhdGE+ID0gbmV3IEFycmF5PFBhcnRpY2xlQW5pbWF0aW9uRGF0YT4oKTtcblxuXHQvKipcblx0ICogQW4gaWQgZm9yIHRoaXMgYW5pbWF0aW9uIHN1Ymdlb21ldHJ5LCB1c2VkIHRvIGlkZW50aWZ5IGFuaW1hdGlvbiBzdWJnZW9tZXRyaWVzIHdoZW4gdXNpbmcgYW5pbWF0aW9uIHNldHMuXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRwdWJsaWMgX2lVbmlxdWVJZDpudW1iZXI7Ly9BcmNhbmVcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IDg7IGkrKylcblx0XHRcdHRoaXMuX3BCdWZmZXJEaXJ0eVtpXSA9IHRydWU7XG5cblx0XHR0aGlzLl9pVW5pcXVlSWQgPSBBbmltYXRpb25TdWJHZW9tZXRyeS5TVUJHRU9NX0lEX0NPVU5UKys7XG5cdH1cblxuXHRwdWJsaWMgY3JlYXRlVmVydGV4RGF0YShudW1WZXJ0aWNlczpudW1iZXIgLyp1aW50Ki8sIHRvdGFsTGVuT2ZPbmVWZXJ0ZXg6bnVtYmVyIC8qdWludCovKVxuXHR7XG5cdFx0dGhpcy5fbnVtVmVydGljZXMgPSBudW1WZXJ0aWNlcztcblx0XHR0aGlzLl90b3RhbExlbk9mT25lVmVydGV4ID0gdG90YWxMZW5PZk9uZVZlcnRleDtcblx0XHR0aGlzLl9wVmVydGV4RGF0YSA9IG5ldyBBcnJheTxudW1iZXI+KG51bVZlcnRpY2VzKnRvdGFsTGVuT2ZPbmVWZXJ0ZXgpO1xuXHR9XG5cblx0cHVibGljIGFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4Om51bWJlciAvKmludCovLCBidWZmZXJPZmZzZXQ6bnVtYmVyIC8qaW50Ki8sIHN0YWdlOlN0YWdlLCBmb3JtYXQ6c3RyaW5nKVxuXHR7XG5cdFx0dmFyIGNvbnRleHRJbmRleDpudW1iZXIgLyppbnQqLyA9IHN0YWdlLnN0YWdlSW5kZXg7XG5cdFx0dmFyIGNvbnRleHQ6SUNvbnRleHRTdGFnZUdMID0gPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dDtcblxuXHRcdHZhciBidWZmZXI6SVZlcnRleEJ1ZmZlciA9IHRoaXMuX3BWZXJ0ZXhCdWZmZXJbY29udGV4dEluZGV4XTtcblx0XHRpZiAoIWJ1ZmZlciB8fCB0aGlzLl9wQnVmZmVyQ29udGV4dFtjb250ZXh0SW5kZXhdICE9IGNvbnRleHQpIHtcblx0XHRcdGJ1ZmZlciA9IHRoaXMuX3BWZXJ0ZXhCdWZmZXJbY29udGV4dEluZGV4XSA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMuX251bVZlcnRpY2VzLCB0aGlzLl90b3RhbExlbk9mT25lVmVydGV4KTtcblx0XHRcdHRoaXMuX3BCdWZmZXJDb250ZXh0W2NvbnRleHRJbmRleF0gPSBjb250ZXh0O1xuXHRcdFx0dGhpcy5fcEJ1ZmZlckRpcnR5W2NvbnRleHRJbmRleF0gPSB0cnVlO1xuXHRcdH1cblx0XHRpZiAodGhpcy5fcEJ1ZmZlckRpcnR5W2NvbnRleHRJbmRleF0pIHtcblx0XHRcdGJ1ZmZlci51cGxvYWRGcm9tQXJyYXkodGhpcy5fcFZlcnRleERhdGEsIDAsIHRoaXMuX251bVZlcnRpY2VzKTtcblx0XHRcdHRoaXMuX3BCdWZmZXJEaXJ0eVtjb250ZXh0SW5kZXhdID0gZmFsc2U7XG5cdFx0fVxuXHRcdGNvbnRleHQuc2V0VmVydGV4QnVmZmVyQXQoaW5kZXgsIGJ1ZmZlciwgYnVmZmVyT2Zmc2V0LCBmb3JtYXQpO1xuXHR9XG5cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cdFx0d2hpbGUgKHRoaXMuX3BWZXJ0ZXhCdWZmZXIubGVuZ3RoKSB7XG5cdFx0XHR2YXIgdmVydGV4QnVmZmVyOklWZXJ0ZXhCdWZmZXIgPSB0aGlzLl9wVmVydGV4QnVmZmVyLnBvcCgpXG5cblx0XHRcdGlmICh2ZXJ0ZXhCdWZmZXIpXG5cdFx0XHRcdHZlcnRleEJ1ZmZlci5kaXNwb3NlKCk7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGludmFsaWRhdGVCdWZmZXIoKVxuXHR7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCA4OyBpKyspXG5cdFx0XHR0aGlzLl9wQnVmZmVyRGlydHlbaV0gPSB0cnVlO1xuXHR9XG5cblx0cHVibGljIGdldCB2ZXJ0ZXhEYXRhKCk6QXJyYXk8bnVtYmVyPlxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3BWZXJ0ZXhEYXRhO1xuXHR9XG5cblx0cHVibGljIGdldCBudW1WZXJ0aWNlcygpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX251bVZlcnRpY2VzO1xuXHR9XG5cblx0cHVibGljIGdldCB0b3RhbExlbk9mT25lVmVydGV4KCk6bnVtYmVyIC8qdWludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdG90YWxMZW5PZk9uZVZlcnRleDtcblx0fVxufVxuXG5leHBvcnQgPSBBbmltYXRpb25TdWJHZW9tZXRyeTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/data/AnimationSubGeometry.ts b/lib/animators/data/AnimationSubGeometry.ts
new file mode 100644
index 000000000..76b6c7e7e
--- /dev/null
+++ b/lib/animators/data/AnimationSubGeometry.ts
@@ -0,0 +1,102 @@
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import IVertexBuffer = require("awayjs-stagegl/lib/core/stagegl/IVertexBuffer");
+
+import ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+
+/**
+ * ...
+ */
+class AnimationSubGeometry
+{
+ public static SUBGEOM_ID_COUNT:number = 0;
+
+ public _pVertexData:Array;
+
+ public _pVertexBuffer:Array = new Array(8);
+ public _pBufferContext:Array = new Array(8);
+ public _pBufferDirty:Array = new Array(8);
+
+ private _numVertices:number /*uint*/;
+
+ private _totalLenOfOneVertex:number /*uint*/;
+
+ public numProcessedVertices:number /*int*/ = 0;
+
+ public previousTime:number = Number.NEGATIVE_INFINITY;
+
+ public animationParticles:Array = new Array();
+
+ /**
+ * An id for this animation subgeometry, used to identify animation subgeometries when using animation sets.
+ *
+ * @private
+ */
+ public _iUniqueId:number;//Arcane
+
+ constructor()
+ {
+ for (var i:number /*int*/ = 0; i < 8; i++)
+ this._pBufferDirty[i] = true;
+
+ this._iUniqueId = AnimationSubGeometry.SUBGEOM_ID_COUNT++;
+ }
+
+ public createVertexData(numVertices:number /*uint*/, totalLenOfOneVertex:number /*uint*/)
+ {
+ this._numVertices = numVertices;
+ this._totalLenOfOneVertex = totalLenOfOneVertex;
+ this._pVertexData = new Array(numVertices*totalLenOfOneVertex);
+ }
+
+ public activateVertexBuffer(index:number /*int*/, bufferOffset:number /*int*/, stage:Stage, format:string)
+ {
+ var contextIndex:number /*int*/ = stage.stageIndex;
+ var context:IContextStageGL = stage.context;
+
+ var buffer:IVertexBuffer = this._pVertexBuffer[contextIndex];
+ if (!buffer || this._pBufferContext[contextIndex] != context) {
+ buffer = this._pVertexBuffer[contextIndex] = context.createVertexBuffer(this._numVertices, this._totalLenOfOneVertex);
+ this._pBufferContext[contextIndex] = context;
+ this._pBufferDirty[contextIndex] = true;
+ }
+ if (this._pBufferDirty[contextIndex]) {
+ buffer.uploadFromArray(this._pVertexData, 0, this._numVertices);
+ this._pBufferDirty[contextIndex] = false;
+ }
+ context.setVertexBufferAt(index, buffer, bufferOffset, format);
+ }
+
+ public dispose()
+ {
+ while (this._pVertexBuffer.length) {
+ var vertexBuffer:IVertexBuffer = this._pVertexBuffer.pop()
+
+ if (vertexBuffer)
+ vertexBuffer.dispose();
+ }
+ }
+
+ public invalidateBuffer()
+ {
+ for (var i:number /*int*/ = 0; i < 8; i++)
+ this._pBufferDirty[i] = true;
+ }
+
+ public get vertexData():Array
+ {
+ return this._pVertexData;
+ }
+
+ public get numVertices():number /*uint*/
+ {
+ return this._numVertices;
+ }
+
+ public get totalLenOfOneVertex():number /*uint*/
+ {
+ return this._totalLenOfOneVertex;
+ }
+}
+
+export = AnimationSubGeometry;
\ No newline at end of file
diff --git a/lib/animators/data/ColorSegmentPoint.js b/lib/animators/data/ColorSegmentPoint.js
new file mode 100755
index 000000000..33f0b70cd
--- /dev/null
+++ b/lib/animators/data/ColorSegmentPoint.js
@@ -0,0 +1,27 @@
+var ColorSegmentPoint = (function () {
+ function ColorSegmentPoint(life, color) {
+ //0= 1)
+ throw (new Error("life exceeds range (0,1)"));
+ this._life = life;
+ this._color = color;
+ }
+ Object.defineProperty(ColorSegmentPoint.prototype, "color", {
+ get: function () {
+ return this._color;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ColorSegmentPoint.prototype, "life", {
+ get: function () {
+ return this._life;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return ColorSegmentPoint;
+})();
+module.exports = ColorSegmentPoint;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL2NvbG9yc2VnbWVudHBvaW50LnRzIl0sIm5hbWVzIjpbIkNvbG9yU2VnbWVudFBvaW50IiwiQ29sb3JTZWdtZW50UG9pbnQuY29uc3RydWN0b3IiLCJDb2xvclNlZ21lbnRQb2ludC5jb2xvciIsIkNvbG9yU2VnbWVudFBvaW50LmxpZmUiXSwibWFwcGluZ3MiOiJBQUVBLElBQU0saUJBQWlCO0lBS3RCQSxTQUxLQSxpQkFBaUJBLENBS1ZBLElBQVdBLEVBQUVBLEtBQW9CQTtRQUU1Q0MsQUFDQUEsVUFEVUE7UUFDVkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsSUFBSUEsQ0FBQ0EsSUFBSUEsSUFBSUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDMUJBLE1BQUtBLENBQUNBLElBQUlBLEtBQUtBLENBQUNBLDBCQUEwQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDOUNBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1FBQ2xCQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxLQUFLQSxDQUFDQTtJQUNyQkEsQ0FBQ0E7SUFFREQsc0JBQVdBLG9DQUFLQTthQUFoQkE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDcEJBLENBQUNBOzs7T0FBQUY7SUFFREEsc0JBQVdBLG1DQUFJQTthQUFmQTtZQUVDRyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUNuQkEsQ0FBQ0E7OztPQUFBSDtJQUVGQSx3QkFBQ0E7QUFBREEsQ0F4QkEsQUF3QkNBLElBQUE7QUFFRCxBQUEyQixpQkFBbEIsaUJBQWlCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL2RhdGEvQ29sb3JTZWdtZW50UG9pbnQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29sb3JUcmFuc2Zvcm1cdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Db2xvclRyYW5zZm9ybVwiKTtcblxuY2xhc3MgQ29sb3JTZWdtZW50UG9pbnRcbntcblx0cHJpdmF0ZSBfY29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdHByaXZhdGUgX2xpZmU6bnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKGxpZmU6bnVtYmVyLCBjb2xvcjpDb2xvclRyYW5zZm9ybSlcblx0e1xuXHRcdC8vMDxsaWZlPDFcblx0XHRpZiAobGlmZSA8PSAwIHx8IGxpZmUgPj0gMSlcblx0XHRcdHRocm93KG5ldyBFcnJvcihcImxpZmUgZXhjZWVkcyByYW5nZSAoMCwxKVwiKSk7XG5cdFx0dGhpcy5fbGlmZSA9IGxpZmU7XG5cdFx0dGhpcy5fY29sb3IgPSBjb2xvcjtcblx0fVxuXG5cdHB1YmxpYyBnZXQgY29sb3IoKTpDb2xvclRyYW5zZm9ybVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2NvbG9yO1xuXHR9XG5cblx0cHVibGljIGdldCBsaWZlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fbGlmZTtcblx0fVxuXG59XG5cbmV4cG9ydCA9IENvbG9yU2VnbWVudFBvaW50OyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/data/ColorSegmentPoint.ts b/lib/animators/data/ColorSegmentPoint.ts
new file mode 100644
index 000000000..025641855
--- /dev/null
+++ b/lib/animators/data/ColorSegmentPoint.ts
@@ -0,0 +1,29 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+
+class ColorSegmentPoint
+{
+ private _color:ColorTransform;
+ private _life:number;
+
+ constructor(life:number, color:ColorTransform)
+ {
+ //0= 1)
+ throw(new Error("life exceeds range (0,1)"));
+ this._life = life;
+ this._color = color;
+ }
+
+ public get color():ColorTransform
+ {
+ return this._color;
+ }
+
+ public get life():number
+ {
+ return this._life;
+ }
+
+}
+
+export = ColorSegmentPoint;
\ No newline at end of file
diff --git a/lib/animators/data/JointPose.js b/lib/animators/data/JointPose.js
new file mode 100755
index 000000000..aca5b0415
--- /dev/null
+++ b/lib/animators/data/JointPose.js
@@ -0,0 +1,57 @@
+var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+var Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+/**
+ * Contains transformation data for a skeleton joint, used for skeleton animation.
+ *
+ * @see away.animation.Skeleton
+ * @see away.animation.SkeletonJoint
+ *
+ * todo: support (uniform) scale
+ */
+var JointPose = (function () {
+ function JointPose() {
+ /**
+ * The rotation of the pose stored as a quaternion
+ */
+ this.orientation = new Quaternion();
+ /**
+ * The translation of the pose
+ */
+ this.translation = new Vector3D();
+ }
+ /**
+ * Converts the transformation to a Matrix3D representation.
+ *
+ * @param target An optional target matrix to store the transformation. If not provided, it will create a new instance.
+ * @return The transformation matrix of the pose.
+ */
+ JointPose.prototype.toMatrix3D = function (target) {
+ if (target === void 0) { target = null; }
+ if (target == null)
+ target = new Matrix3D();
+ this.orientation.toMatrix3D(target);
+ target.appendTranslation(this.translation.x, this.translation.y, this.translation.z);
+ return target;
+ };
+ /**
+ * Copies the transformation data from a source pose object into the existing pose object.
+ *
+ * @param pose The source pose to copy from.
+ */
+ JointPose.prototype.copyFrom = function (pose) {
+ var or = pose.orientation;
+ var tr = pose.translation;
+ this.orientation.x = or.x;
+ this.orientation.y = or.y;
+ this.orientation.z = or.z;
+ this.orientation.w = or.w;
+ this.translation.x = tr.x;
+ this.translation.y = tr.y;
+ this.translation.z = tr.z;
+ };
+ return JointPose;
+})();
+module.exports = JointPose;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL2pvaW50cG9zZS50cyJdLCJuYW1lcyI6WyJKb2ludFBvc2UiLCJKb2ludFBvc2UuY29uc3RydWN0b3IiLCJKb2ludFBvc2UudG9NYXRyaXgzRCIsIkpvaW50UG9zZS5jb3B5RnJvbSJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFDdEUsSUFBTyxVQUFVLFdBQWdCLHNDQUFzQyxDQUFDLENBQUM7QUFDekUsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFFdEUsQUFRQTs7Ozs7OztHQURHO0lBQ0csU0FBUztJQWlCZEEsU0FqQktBLFNBQVNBO1FBT2RDOztXQUVHQTtRQUNJQSxnQkFBV0EsR0FBY0EsSUFBSUEsVUFBVUEsRUFBRUEsQ0FBQ0E7UUFFakRBOztXQUVHQTtRQUNJQSxnQkFBV0EsR0FBWUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFLN0NBLENBQUNBO0lBRUREOzs7OztPQUtHQTtJQUNJQSw4QkFBVUEsR0FBakJBLFVBQWtCQSxNQUFzQkE7UUFBdEJFLHNCQUFzQkEsR0FBdEJBLGFBQXNCQTtRQUV2Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsSUFBSUEsSUFBSUEsQ0FBQ0E7WUFDbEJBLE1BQU1BLEdBQUdBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1FBRXpCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxVQUFVQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQTtRQUNwQ0EsTUFBTUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNyRkEsTUFBTUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7SUFDZkEsQ0FBQ0E7SUFFREY7Ozs7T0FJR0E7SUFDSUEsNEJBQVFBLEdBQWZBLFVBQWdCQSxJQUFjQTtRQUU3QkcsSUFBSUEsRUFBRUEsR0FBY0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDckNBLElBQUlBLEVBQUVBLEdBQVlBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBQ25DQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMxQkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMxQkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUMzQkEsQ0FBQ0E7SUFDRkgsZ0JBQUNBO0FBQURBLENBdkRBLEFBdURDQSxJQUFBO0FBRUQsQUFBbUIsaUJBQVYsU0FBUyxDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9kYXRhL0pvaW50UG9zZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBRdWF0ZXJuaW9uXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9RdWF0ZXJuaW9uXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG4vKipcbiAqIENvbnRhaW5zIHRyYW5zZm9ybWF0aW9uIGRhdGEgZm9yIGEgc2tlbGV0b24gam9pbnQsIHVzZWQgZm9yIHNrZWxldG9uIGFuaW1hdGlvbi5cbiAqXG4gKiBAc2VlIGF3YXkuYW5pbWF0aW9uLlNrZWxldG9uXG4gKiBAc2VlIGF3YXkuYW5pbWF0aW9uLlNrZWxldG9uSm9pbnRcbiAqXG4gKiB0b2RvOiBzdXBwb3J0ICh1bmlmb3JtKSBzY2FsZVxuICovXG5jbGFzcyBKb2ludFBvc2Vcbntcblx0LyoqXG5cdCAqIFRoZSBuYW1lIG9mIHRoZSBqb2ludCB0byB3aGljaCB0aGUgcG9zZSBpcyBhc3NvY2lhdGVkXG5cdCAqL1xuXHRwdWJsaWMgbmFtZTpzdHJpbmc7IC8vIGludGVudGlvbiBpcyB0aGF0IHRoaXMgc2hvdWxkIGJlIHVzZWQgb25seSBhdCBsb2FkIHRpbWUsIG5vdCBpbiB0aGUgbWFpbiBsb29wXG5cblx0LyoqXG5cdCAqIFRoZSByb3RhdGlvbiBvZiB0aGUgcG9zZSBzdG9yZWQgYXMgYSBxdWF0ZXJuaW9uXG5cdCAqL1xuXHRwdWJsaWMgb3JpZW50YXRpb246UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cblx0LyoqXG5cdCAqIFRoZSB0cmFuc2xhdGlvbiBvZiB0aGUgcG9zZVxuXHQgKi9cblx0cHVibGljIHRyYW5zbGF0aW9uOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEKCk7XG5cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgdHJhbnNmb3JtYXRpb24gdG8gYSBNYXRyaXgzRCByZXByZXNlbnRhdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHRhcmdldCBBbiBvcHRpb25hbCB0YXJnZXQgbWF0cml4IHRvIHN0b3JlIHRoZSB0cmFuc2Zvcm1hdGlvbi4gSWYgbm90IHByb3ZpZGVkLCBpdCB3aWxsIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZS5cblx0ICogQHJldHVybiBUaGUgdHJhbnNmb3JtYXRpb24gbWF0cml4IG9mIHRoZSBwb3NlLlxuXHQgKi9cblx0cHVibGljIHRvTWF0cml4M0QodGFyZ2V0Ok1hdHJpeDNEID0gbnVsbCk6TWF0cml4M0Rcblx0e1xuXHRcdGlmICh0YXJnZXQgPT0gbnVsbClcblx0XHRcdHRhcmdldCA9IG5ldyBNYXRyaXgzRCgpO1xuXG5cdFx0dGhpcy5vcmllbnRhdGlvbi50b01hdHJpeDNEKHRhcmdldCk7XG5cdFx0dGFyZ2V0LmFwcGVuZFRyYW5zbGF0aW9uKHRoaXMudHJhbnNsYXRpb24ueCwgdGhpcy50cmFuc2xhdGlvbi55LCB0aGlzLnRyYW5zbGF0aW9uLnopO1xuXHRcdHJldHVybiB0YXJnZXQ7XG5cdH1cblxuXHQvKipcblx0ICogQ29waWVzIHRoZSB0cmFuc2Zvcm1hdGlvbiBkYXRhIGZyb20gYSBzb3VyY2UgcG9zZSBvYmplY3QgaW50byB0aGUgZXhpc3RpbmcgcG9zZSBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBwb3NlIFRoZSBzb3VyY2UgcG9zZSB0byBjb3B5IGZyb20uXG5cdCAqL1xuXHRwdWJsaWMgY29weUZyb20ocG9zZTpKb2ludFBvc2UpXG5cdHtcblx0XHR2YXIgb3I6UXVhdGVybmlvbiA9IHBvc2Uub3JpZW50YXRpb247XG5cdFx0dmFyIHRyOlZlY3RvcjNEID0gcG9zZS50cmFuc2xhdGlvbjtcblx0XHR0aGlzLm9yaWVudGF0aW9uLnggPSBvci54O1xuXHRcdHRoaXMub3JpZW50YXRpb24ueSA9IG9yLnk7XG5cdFx0dGhpcy5vcmllbnRhdGlvbi56ID0gb3Iuejtcblx0XHR0aGlzLm9yaWVudGF0aW9uLncgPSBvci53O1xuXHRcdHRoaXMudHJhbnNsYXRpb24ueCA9IHRyLng7XG5cdFx0dGhpcy50cmFuc2xhdGlvbi55ID0gdHIueTtcblx0XHR0aGlzLnRyYW5zbGF0aW9uLnogPSB0ci56O1xuXHR9XG59XG5cbmV4cG9ydCA9IEpvaW50UG9zZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/data/JointPose.ts b/lib/animators/data/JointPose.ts
new file mode 100644
index 000000000..2d25bf3e1
--- /dev/null
+++ b/lib/animators/data/JointPose.ts
@@ -0,0 +1,70 @@
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+/**
+ * Contains transformation data for a skeleton joint, used for skeleton animation.
+ *
+ * @see away.animation.Skeleton
+ * @see away.animation.SkeletonJoint
+ *
+ * todo: support (uniform) scale
+ */
+class JointPose
+{
+ /**
+ * The name of the joint to which the pose is associated
+ */
+ public name:string; // intention is that this should be used only at load time, not in the main loop
+
+ /**
+ * The rotation of the pose stored as a quaternion
+ */
+ public orientation:Quaternion = new Quaternion();
+
+ /**
+ * The translation of the pose
+ */
+ public translation:Vector3D = new Vector3D();
+
+ constructor()
+ {
+
+ }
+
+ /**
+ * Converts the transformation to a Matrix3D representation.
+ *
+ * @param target An optional target matrix to store the transformation. If not provided, it will create a new instance.
+ * @return The transformation matrix of the pose.
+ */
+ public toMatrix3D(target:Matrix3D = null):Matrix3D
+ {
+ if (target == null)
+ target = new Matrix3D();
+
+ this.orientation.toMatrix3D(target);
+ target.appendTranslation(this.translation.x, this.translation.y, this.translation.z);
+ return target;
+ }
+
+ /**
+ * Copies the transformation data from a source pose object into the existing pose object.
+ *
+ * @param pose The source pose to copy from.
+ */
+ public copyFrom(pose:JointPose)
+ {
+ var or:Quaternion = pose.orientation;
+ var tr:Vector3D = pose.translation;
+ this.orientation.x = or.x;
+ this.orientation.y = or.y;
+ this.orientation.z = or.z;
+ this.orientation.w = or.w;
+ this.translation.x = tr.x;
+ this.translation.y = tr.y;
+ this.translation.z = tr.z;
+ }
+}
+
+export = JointPose;
\ No newline at end of file
diff --git a/lib/animators/data/ParticleAnimationData.js b/lib/animators/data/ParticleAnimationData.js
new file mode 100755
index 000000000..cceceeab9
--- /dev/null
+++ b/lib/animators/data/ParticleAnimationData.js
@@ -0,0 +1,18 @@
+/**
+ * ...
+ */
+var ParticleAnimationData = (function () {
+ function ParticleAnimationData(index /*uint*/, startTime, duration, delay, particle) {
+ this.index = index;
+ this.startTime = startTime;
+ this.totalTime = duration + delay;
+ this.duration = duration;
+ this.delay = delay;
+ this.startVertexIndex = particle.startVertexIndex;
+ this.numVertices = particle.numVertices;
+ }
+ return ParticleAnimationData;
+})();
+module.exports = ParticleAnimationData;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3BhcnRpY2xlYW5pbWF0aW9uZGF0YS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUFuaW1hdGlvbkRhdGEiLCJQYXJ0aWNsZUFuaW1hdGlvbkRhdGEuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUVBLEFBR0E7O0dBREc7SUFDRyxxQkFBcUI7SUFVMUJBLFNBVktBLHFCQUFxQkEsQ0FVZEEsS0FBS0EsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsU0FBZ0JBLEVBQUVBLFFBQWVBLEVBQUVBLEtBQVlBLEVBQUVBLFFBQXFCQTtRQUV4R0MsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDbkJBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLFNBQVNBLENBQUNBO1FBQzNCQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUNsQ0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDekJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLENBQUNBO1FBQ25CQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLFFBQVFBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7UUFDbERBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLFFBQVFBLENBQUNBLFdBQVdBLENBQUNBO0lBQ3pDQSxDQUFDQTtJQUNGRCw0QkFBQ0E7QUFBREEsQ0FwQkEsQUFvQkNBLElBQUE7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL2RhdGEvUGFydGljbGVBbmltYXRpb25EYXRhLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnRpY2xlRGF0YVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZURhdGFcIik7XG5cbi8qKlxuICogLi4uXG4gKi9cbmNsYXNzIFBhcnRpY2xlQW5pbWF0aW9uRGF0YVxue1xuXHRwdWJsaWMgaW5kZXg6bnVtYmVyIC8qdWludCovO1xuXHRwdWJsaWMgc3RhcnRUaW1lOm51bWJlcjtcblx0cHVibGljIHRvdGFsVGltZTpudW1iZXI7XG5cdHB1YmxpYyBkdXJhdGlvbjpudW1iZXI7XG5cdHB1YmxpYyBkZWxheTpudW1iZXI7XG5cdHB1YmxpYyBzdGFydFZlcnRleEluZGV4Om51bWJlciAvKnVpbnQqLztcblx0cHVibGljIG51bVZlcnRpY2VzOm51bWJlciAvKnVpbnQqLztcblxuXHRjb25zdHJ1Y3RvcihpbmRleDpudW1iZXIgLyp1aW50Ki8sIHN0YXJ0VGltZTpudW1iZXIsIGR1cmF0aW9uOm51bWJlciwgZGVsYXk6bnVtYmVyLCBwYXJ0aWNsZTpQYXJ0aWNsZURhdGEpXG5cdHtcblx0XHR0aGlzLmluZGV4ID0gaW5kZXg7XG5cdFx0dGhpcy5zdGFydFRpbWUgPSBzdGFydFRpbWU7XG5cdFx0dGhpcy50b3RhbFRpbWUgPSBkdXJhdGlvbiArIGRlbGF5O1xuXHRcdHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcblx0XHR0aGlzLmRlbGF5ID0gZGVsYXk7XG5cdFx0dGhpcy5zdGFydFZlcnRleEluZGV4ID0gcGFydGljbGUuc3RhcnRWZXJ0ZXhJbmRleDtcblx0XHR0aGlzLm51bVZlcnRpY2VzID0gcGFydGljbGUubnVtVmVydGljZXM7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVBbmltYXRpb25EYXRhOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/data/ParticleAnimationData.ts b/lib/animators/data/ParticleAnimationData.ts
new file mode 100644
index 000000000..c18940adb
--- /dev/null
+++ b/lib/animators/data/ParticleAnimationData.ts
@@ -0,0 +1,28 @@
+import ParticleData = require("awayjs-renderergl/lib/animators/data/ParticleData");
+
+/**
+ * ...
+ */
+class ParticleAnimationData
+{
+ public index:number /*uint*/;
+ public startTime:number;
+ public totalTime:number;
+ public duration:number;
+ public delay:number;
+ public startVertexIndex:number /*uint*/;
+ public numVertices:number /*uint*/;
+
+ constructor(index:number /*uint*/, startTime:number, duration:number, delay:number, particle:ParticleData)
+ {
+ this.index = index;
+ this.startTime = startTime;
+ this.totalTime = duration + delay;
+ this.duration = duration;
+ this.delay = delay;
+ this.startVertexIndex = particle.startVertexIndex;
+ this.numVertices = particle.numVertices;
+ }
+}
+
+export = ParticleAnimationData;
\ No newline at end of file
diff --git a/lib/animators/data/ParticleData.js b/lib/animators/data/ParticleData.js
new file mode 100755
index 000000000..c4eee1032
--- /dev/null
+++ b/lib/animators/data/ParticleData.js
@@ -0,0 +1,8 @@
+var ParticleData = (function () {
+ function ParticleData() {
+ }
+ return ParticleData;
+})();
+module.exports = ParticleData;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3BhcnRpY2xlZGF0YS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZURhdGEiLCJQYXJ0aWNsZURhdGEuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUVBLElBQU0sWUFBWTtJQUFsQkEsU0FBTUEsWUFBWUE7SUFNbEJDLENBQUNBO0lBQURELG1CQUFDQTtBQUFEQSxDQU5BLEFBTUNBLElBQUE7QUFFRCxBQUFxQixpQkFBWixZQUFZLENBQUEiLCJmaWxlIjoiYW5pbWF0b3JzL2RhdGEvUGFydGljbGVEYXRhLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcblxuY2xhc3MgUGFydGljbGVEYXRhXG57XG5cdHB1YmxpYyBwYXJ0aWNsZUluZGV4Om51bWJlciAvKnVpbnQqLztcblx0cHVibGljIG51bVZlcnRpY2VzOm51bWJlciAvKnVpbnQqLztcblx0cHVibGljIHN0YXJ0VmVydGV4SW5kZXg6bnVtYmVyIC8qdWludCovO1xuXHRwdWJsaWMgc3ViR2VvbWV0cnk6VHJpYW5nbGVTdWJHZW9tZXRyeTtcbn1cblxuZXhwb3J0ID0gUGFydGljbGVEYXRhIl19
\ No newline at end of file
diff --git a/lib/animators/data/ParticleData.ts b/lib/animators/data/ParticleData.ts
new file mode 100644
index 000000000..5ec3c84b1
--- /dev/null
+++ b/lib/animators/data/ParticleData.ts
@@ -0,0 +1,11 @@
+import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+
+class ParticleData
+{
+ public particleIndex:number /*uint*/;
+ public numVertices:number /*uint*/;
+ public startVertexIndex:number /*uint*/;
+ public subGeometry:TriangleSubGeometry;
+}
+
+export = ParticleData
\ No newline at end of file
diff --git a/lib/animators/data/ParticleProperties.js b/lib/animators/data/ParticleProperties.js
new file mode 100755
index 000000000..8a516840a
--- /dev/null
+++ b/lib/animators/data/ParticleProperties.js
@@ -0,0 +1,12 @@
+/**
+ * Dynamic class for holding the local properties of a particle, used for processing the static properties
+ * of particles in the particle animation set before beginning upload to the GPU.
+ */
+var ParticleProperties = (function () {
+ function ParticleProperties() {
+ }
+ return ParticleProperties;
+})();
+module.exports = ParticleProperties;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3BhcnRpY2xlcHJvcGVydGllcy50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVByb3BlcnRpZXMiLCJQYXJ0aWNsZVByb3BlcnRpZXMuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUFBLEFBSUE7OztHQURHO0lBQ0csa0JBQWtCO0lBQXhCQSxTQUFNQSxrQkFBa0JBO0lBOEJ4QkMsQ0FBQ0E7SUFBREQseUJBQUNBO0FBQURBLENBOUJBLEFBOEJDQSxJQUFBO0FBRUQsQUFBNEIsaUJBQW5CLGtCQUFrQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRHluYW1pYyBjbGFzcyBmb3IgaG9sZGluZyB0aGUgbG9jYWwgcHJvcGVydGllcyBvZiBhIHBhcnRpY2xlLCB1c2VkIGZvciBwcm9jZXNzaW5nIHRoZSBzdGF0aWMgcHJvcGVydGllc1xuICogb2YgcGFydGljbGVzIGluIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gc2V0IGJlZm9yZSBiZWdpbm5pbmcgdXBsb2FkIHRvIHRoZSBHUFUuXG4gKi9cbmNsYXNzIFBhcnRpY2xlUHJvcGVydGllc1xue1xuXHQvKipcblx0ICogVGhlIGluZGV4IG9mIHRoZSBjdXJyZW50IHBhcnRpY2xlIGJlaW5nIHNldC5cblx0ICovXG5cdHB1YmxpYyBpbmRleDpudW1iZXIgLyp1aW50Ki87XG5cblx0LyoqXG5cdCAqIFRoZSB0b3RhbCBudW1iZXIgb2YgcGFydGljbGVzIGJlaW5nIHByb2Nlc3NlZCBieSB0aGUgcGFydGljbGUgYW5pbWF0aW9uIHNldC5cblx0ICovXG5cdHB1YmxpYyB0b3RhbDpudW1iZXIgLyp1aW50Ki87XG5cblx0LyoqXG5cdCAqIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBwYXJ0aWNsZS5cblx0ICovXG5cdHB1YmxpYyBzdGFydFRpbWU6bnVtYmVyO1xuXG5cdC8qKlxuXHQgKiBUaGUgZHVyYXRpb24gb2YgdGhlIHBhcnRpY2xlLCBhbiBvcHRpb25hbCB2YWx1ZSB1c2VkIHdoZW4gdGhlIHBhcnRpY2xlIGFuaWFtdGlvbiBzZXQgc2V0dGluZ3MgZm9yIDxjb2RlPnVzZUR1cmF0aW9uPC9jb2RlPiBhcmUgZW5hYmxlZCBpbiB0aGUgY29uc3RydWN0b3IuXG5cdCAqXG5cdCAqIEBzZWUgYXdheS5hbmltYXRvcnMuUGFydGljbGVBbmltYXRpb25TZXRcblx0ICovXG5cdHB1YmxpYyBkdXJhdGlvbjpudW1iZXI7XG5cblx0LyoqXG5cdCAqIFRoZSBkZWxheSBiZXR3ZWVuIGN5Y2xlcyBvZiB0aGUgcGFydGljbGUsIGFuIG9wdGlvbmFsIHZhbHVlIHVzZWQgd2hlbiB0aGUgcGFydGljbGUgYW5pYW10aW9uIHNldCBzZXR0aW5ncyBmb3IgPGNvZGU+dXNlTG9vcGluZzwvY29kZT4gYW5kICA8Y29kZT51c2VEZWxheTwvY29kZT4gYXJlIGVuYWJsZWQgaW4gdGhlIGNvbnN0cnVjdG9yLlxuXHQgKlxuXHQgKiBAc2VlIGF3YXkuYW5pbWF0b3JzLlBhcnRpY2xlQW5pbWF0aW9uU2V0XG5cdCAqL1xuXHRwdWJsaWMgZGVsYXk6bnVtYmVyO1xufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVByb3BlcnRpZXM7Il19
\ No newline at end of file
diff --git a/lib/animators/data/ParticleProperties.ts b/lib/animators/data/ParticleProperties.ts
new file mode 100644
index 000000000..3da259b93
--- /dev/null
+++ b/lib/animators/data/ParticleProperties.ts
@@ -0,0 +1,37 @@
+/**
+ * Dynamic class for holding the local properties of a particle, used for processing the static properties
+ * of particles in the particle animation set before beginning upload to the GPU.
+ */
+class ParticleProperties
+{
+ /**
+ * The index of the current particle being set.
+ */
+ public index:number /*uint*/;
+
+ /**
+ * The total number of particles being processed by the particle animation set.
+ */
+ public total:number /*uint*/;
+
+ /**
+ * The start time of the particle.
+ */
+ public startTime:number;
+
+ /**
+ * The duration of the particle, an optional value used when the particle aniamtion set settings for useDuration
are enabled in the constructor.
+ *
+ * @see away.animators.ParticleAnimationSet
+ */
+ public duration:number;
+
+ /**
+ * The delay between cycles of the particle, an optional value used when the particle aniamtion set settings for useLooping
and useDelay
are enabled in the constructor.
+ *
+ * @see away.animators.ParticleAnimationSet
+ */
+ public delay:number;
+}
+
+export = ParticleProperties;
\ No newline at end of file
diff --git a/lib/animators/data/ParticlePropertiesMode.js b/lib/animators/data/ParticlePropertiesMode.js
new file mode 100755
index 000000000..dba8dcbdd
--- /dev/null
+++ b/lib/animators/data/ParticlePropertiesMode.js
@@ -0,0 +1,23 @@
+/**
+ * Options for setting the properties mode of a particle animation node.
+ */
+var ParticlePropertiesMode = (function () {
+ function ParticlePropertiesMode() {
+ }
+ /**
+ * Mode that defines the particle node as acting on global properties (ie. the properties set in the node constructor or the corresponding animation state).
+ */
+ ParticlePropertiesMode.GLOBAL = 0;
+ /**
+ * Mode that defines the particle node as acting on local static properties (ie. the properties of particles set in the initialising on the animation set).
+ */
+ ParticlePropertiesMode.LOCAL_STATIC = 1;
+ /**
+ * Mode that defines the particle node as acting on local dynamic properties (ie. the properties of the particles set in the corresponding animation state).
+ */
+ ParticlePropertiesMode.LOCAL_DYNAMIC = 2;
+ return ParticlePropertiesMode;
+})();
+module.exports = ParticlePropertiesMode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3BhcnRpY2xlcHJvcGVydGllc21vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVQcm9wZXJ0aWVzTW9kZSIsIlBhcnRpY2xlUHJvcGVydGllc01vZGUuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUFBLEFBR0E7O0dBREc7SUFDRyxzQkFBc0I7SUFBNUJBLFNBQU1BLHNCQUFzQkE7SUFnQjVCQyxDQUFDQTtJQWRBRDs7T0FFR0E7SUFDV0EsNkJBQU1BLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUV6Q0E7O09BRUdBO0lBQ1dBLG1DQUFZQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUFFL0NBOztPQUVHQTtJQUNXQSxvQ0FBYUEsR0FBbUJBLENBQUNBLENBQUNBO0lBQ2pEQSw2QkFBQ0E7QUFBREEsQ0FoQkEsQUFnQkNBLElBQUE7QUFFRCxBQUFnQyxpQkFBdkIsc0JBQXNCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3B0aW9ucyBmb3Igc2V0dGluZyB0aGUgcHJvcGVydGllcyBtb2RlIG9mIGEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUuXG4gKi9cbmNsYXNzIFBhcnRpY2xlUHJvcGVydGllc01vZGVcbntcblx0LyoqXG5cdCAqIE1vZGUgdGhhdCBkZWZpbmVzIHRoZSBwYXJ0aWNsZSBub2RlIGFzIGFjdGluZyBvbiBnbG9iYWwgcHJvcGVydGllcyAoaWUuIHRoZSBwcm9wZXJ0aWVzIHNldCBpbiB0aGUgbm9kZSBjb25zdHJ1Y3RvciBvciB0aGUgY29ycmVzcG9uZGluZyBhbmltYXRpb24gc3RhdGUpLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBHTE9CQUw6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHQvKipcblx0ICogTW9kZSB0aGF0IGRlZmluZXMgdGhlIHBhcnRpY2xlIG5vZGUgYXMgYWN0aW5nIG9uIGxvY2FsIHN0YXRpYyBwcm9wZXJ0aWVzIChpZS4gdGhlIHByb3BlcnRpZXMgb2YgcGFydGljbGVzIHNldCBpbiB0aGUgaW5pdGlhbGlzaW5nIG9uIHRoZSBhbmltYXRpb24gc2V0KS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgTE9DQUxfU1RBVElDOm51bWJlciAvKnVpbnQqLyA9IDE7XG5cblx0LyoqXG5cdCAqIE1vZGUgdGhhdCBkZWZpbmVzIHRoZSBwYXJ0aWNsZSBub2RlIGFzIGFjdGluZyBvbiBsb2NhbCBkeW5hbWljIHByb3BlcnRpZXMgKGllLiB0aGUgcHJvcGVydGllcyBvZiB0aGUgcGFydGljbGVzIHNldCBpbiB0aGUgY29ycmVzcG9uZGluZyBhbmltYXRpb24gc3RhdGUpLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBMT0NBTF9EWU5BTUlDOm51bWJlciAvKnVpbnQqLyA9IDI7XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlUHJvcGVydGllc01vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/data/ParticlePropertiesMode.ts b/lib/animators/data/ParticlePropertiesMode.ts
new file mode 100644
index 000000000..a623bc964
--- /dev/null
+++ b/lib/animators/data/ParticlePropertiesMode.ts
@@ -0,0 +1,22 @@
+/**
+ * Options for setting the properties mode of a particle animation node.
+ */
+class ParticlePropertiesMode
+{
+ /**
+ * Mode that defines the particle node as acting on global properties (ie. the properties set in the node constructor or the corresponding animation state).
+ */
+ public static GLOBAL:number /*uint*/ = 0;
+
+ /**
+ * Mode that defines the particle node as acting on local static properties (ie. the properties of particles set in the initialising on the animation set).
+ */
+ public static LOCAL_STATIC:number /*uint*/ = 1;
+
+ /**
+ * Mode that defines the particle node as acting on local dynamic properties (ie. the properties of the particles set in the corresponding animation state).
+ */
+ public static LOCAL_DYNAMIC:number /*uint*/ = 2;
+}
+
+export = ParticlePropertiesMode;
\ No newline at end of file
diff --git a/lib/animators/data/Skeleton.js b/lib/animators/data/Skeleton.js
new file mode 100755
index 000000000..e56e1d692
--- /dev/null
+++ b/lib/animators/data/Skeleton.js
@@ -0,0 +1,94 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AssetType = require("awayjs-core/lib/core/library/AssetType");
+var NamedAssetBase = require("awayjs-core/lib/core/library/NamedAssetBase");
+/**
+ * A Skeleton object is a hierarchical grouping of joint objects that can be used for skeletal animation.
+ *
+ * @see away.animators.SkeletonJoint
+ */
+var Skeleton = (function (_super) {
+ __extends(Skeleton, _super);
+ /**
+ * Creates a new Skeleton
object
+ */
+ function Skeleton() {
+ _super.call(this);
+ // in the long run, it might be a better idea to not store Joint objects, but keep all data in Vectors, that we can upload easily?
+ this.joints = new Array();
+ }
+ Object.defineProperty(Skeleton.prototype, "numJoints", {
+ /**
+ * The total number of joints in the skeleton.
+ */
+ get: function () {
+ return this.joints.length;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Returns the joint object in the skeleton with the given name, otherwise returns a null object.
+ *
+ * @param jointName The name of the joint object to be found.
+ * @return The joint object with the given name.
+ *
+ * @see #joints
+ */
+ Skeleton.prototype.jointFromName = function (jointName) {
+ var jointIndex = this.jointIndexFromName(jointName);
+ if (jointIndex != -1)
+ return this.joints[jointIndex];
+ else
+ return null;
+ };
+ /**
+ * Returns the joint index, given the joint name. -1 is returned if the joint name is not found.
+ *
+ * @param jointName The name of the joint object to be found.
+ * @return The index of the joint object in the joints Array
+ *
+ * @see #joints
+ */
+ Skeleton.prototype.jointIndexFromName = function (jointName) {
+ // this is implemented as a linear search, rather than a possibly
+ // more optimal method (Dictionary lookup, for example) because:
+ // a) it is assumed that it will be called once for each joint
+ // b) it is assumed that it will be called only during load, and not during main loop
+ // c) maintaining a dictionary (for safety) would dictate an interface to access SkeletonJoints,
+ // rather than direct array access. this would be sub-optimal.
+ var jointIndex /*int*/;
+ var joint;
+ for (var i /*int*/; i < this.joints.length; i++) {
+ joint = this.joints[i];
+ if (joint.name == jointName)
+ return jointIndex;
+ jointIndex++;
+ }
+ return -1;
+ };
+ /**
+ * @inheritDoc
+ */
+ Skeleton.prototype.dispose = function () {
+ this.joints.length = 0;
+ };
+ Object.defineProperty(Skeleton.prototype, "assetType", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return AssetType.SKELETON;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return Skeleton;
+})(NamedAssetBase);
+module.exports = Skeleton;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3NrZWxldG9uLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uIiwiU2tlbGV0b24uY29uc3RydWN0b3IiLCJTa2VsZXRvbi5udW1Kb2ludHMiLCJTa2VsZXRvbi5qb2ludEZyb21OYW1lIiwiU2tlbGV0b24uam9pbnRJbmRleEZyb21OYW1lIiwiU2tlbGV0b24uZGlzcG9zZSIsIlNrZWxldG9uLmFzc2V0VHlwZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUEsSUFBTyxTQUFTLFdBQWdCLHdDQUF3QyxDQUFDLENBQUM7QUFFMUUsSUFBTyxjQUFjLFdBQWUsNkNBQTZDLENBQUMsQ0FBQztBQUVuRixBQUtBOzs7O0dBREc7SUFDRyxRQUFRO0lBQVNBLFVBQWpCQSxRQUFRQSxVQUF1QkE7SUFpQnBDQTs7T0FFR0E7SUFDSEEsU0FwQktBLFFBQVFBO1FBc0JaQyxpQkFBT0EsQ0FBQ0E7UUFFUkEsQUFDQUEsa0lBRGtJQTtRQUNsSUEsSUFBSUEsQ0FBQ0EsTUFBTUEsR0FBR0EsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBO0lBQzFDQSxDQUFDQTtJQWRERCxzQkFBV0EsK0JBQVNBO1FBSHBCQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDM0JBLENBQUNBOzs7T0FBQUY7SUFhREE7Ozs7Ozs7T0FPR0E7SUFDSUEsZ0NBQWFBLEdBQXBCQSxVQUFxQkEsU0FBZ0JBO1FBRXBDRyxJQUFJQSxVQUFVQSxHQUFrQkEsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUNuRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsVUFBVUEsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDcEJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLFVBQVVBLENBQUNBLENBQUNBO1FBQUNBLElBQUlBO1lBQ3BDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNkQSxDQUFDQTtJQUVESDs7Ozs7OztPQU9HQTtJQUNJQSxxQ0FBa0JBLEdBQXpCQSxVQUEwQkEsU0FBZ0JBO1FBRXpDSSxBQU1BQSxpRUFOaUVBO1FBQ2pFQSxnRUFBZ0VBO1FBQ2hFQSw4REFBOERBO1FBQzlEQSxxRkFBcUZBO1FBQ3JGQSxnR0FBZ0dBO1FBQ2hHQSxrRUFBa0VBO1lBQzlEQSxVQUFVQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUM5QkEsSUFBSUEsS0FBbUJBLENBQUNBO1FBQ3hCQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUN4REEsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLElBQUlBLElBQUlBLFNBQVNBLENBQUNBO2dCQUMzQkEsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7WUFDbkJBLFVBQVVBLEVBQUVBLENBQUNBO1FBQ2RBLENBQUNBO1FBRURBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO0lBQ1hBLENBQUNBO0lBRURKOztPQUVHQTtJQUNJQSwwQkFBT0EsR0FBZEE7UUFFQ0ssSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBS0RMLHNCQUFXQSwrQkFBU0E7UUFIcEJBOztXQUVHQTthQUNIQTtZQUVDTSxNQUFNQSxDQUFDQSxTQUFTQSxDQUFDQSxRQUFRQSxDQUFDQTtRQUMzQkEsQ0FBQ0E7OztPQUFBTjtJQUNGQSxlQUFDQTtBQUFEQSxDQXZGQSxBQXVGQ0EsRUF2RnNCLGNBQWMsRUF1RnBDO0FBRUQsQUFBa0IsaUJBQVQsUUFBUSxDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9kYXRhL1NrZWxldG9uLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFNrZWxldG9uSm9pbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uSm9pbnRcIik7XG5cbmltcG9ydCBBc3NldFR5cGVcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0VHlwZVwiKTtcbmltcG9ydCBJQXNzZXRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IE5hbWVkQXNzZXRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvTmFtZWRBc3NldEJhc2VcIik7XG5cbi8qKlxuICogQSBTa2VsZXRvbiBvYmplY3QgaXMgYSBoaWVyYXJjaGljYWwgZ3JvdXBpbmcgb2Ygam9pbnQgb2JqZWN0cyB0aGF0IGNhbiBiZSB1c2VkIGZvciBza2VsZXRhbCBhbmltYXRpb24uXG4gKlxuICogQHNlZSBhd2F5LmFuaW1hdG9ycy5Ta2VsZXRvbkpvaW50XG4gKi9cbmNsYXNzIFNrZWxldG9uIGV4dGVuZHMgTmFtZWRBc3NldEJhc2UgaW1wbGVtZW50cyBJQXNzZXRcbntcblx0LyoqXG5cdCAqIEEgZmxhdCBsaXN0IG9mIGpvaW50IG9iamVjdHMgdGhhdCBjb21wcmlzZSB0aGUgc2tlbGV0b24uIEV2ZXJ5IGpvaW50IGV4Y2VwdCBmb3IgdGhlIHJvb3QgaGFzIGEgcGFyZW50SW5kZXhcblx0ICogcHJvcGVydHkgdGhhdCBpcyBhbiBpbmRleCBpbnRvIHRoaXMgbGlzdC5cblx0ICogQSBjaGlsZCBqb2ludCBzaG91bGQgYWx3YXlzIGhhdmUgYSBoaWdoZXIgaW5kZXggdGhhbiBpdHMgcGFyZW50LlxuXHQgKi9cblx0cHVibGljIGpvaW50czpBcnJheTxTa2VsZXRvbkpvaW50PjtcblxuXHQvKipcblx0ICogVGhlIHRvdGFsIG51bWJlciBvZiBqb2ludHMgaW4gdGhlIHNrZWxldG9uLlxuXHQgKi9cblx0cHVibGljIGdldCBudW1Kb2ludHMoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLmpvaW50cy5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvbjwvY29kZT4gb2JqZWN0XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0Ly8gaW4gdGhlIGxvbmcgcnVuLCBpdCBtaWdodCBiZSBhIGJldHRlciBpZGVhIHRvIG5vdCBzdG9yZSBKb2ludCBvYmplY3RzLCBidXQga2VlcCBhbGwgZGF0YSBpbiBWZWN0b3JzLCB0aGF0IHdlIGNhbiB1cGxvYWQgZWFzaWx5P1xuXHRcdHRoaXMuam9pbnRzID0gbmV3IEFycmF5PFNrZWxldG9uSm9pbnQ+KCk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgam9pbnQgb2JqZWN0IGluIHRoZSBza2VsZXRvbiB3aXRoIHRoZSBnaXZlbiBuYW1lLCBvdGhlcndpc2UgcmV0dXJucyBhIG51bGwgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gam9pbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBqb2ludCBvYmplY3QgdG8gYmUgZm91bmQuXG5cdCAqIEByZXR1cm4gVGhlIGpvaW50IG9iamVjdCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuXHQgKlxuXHQgKiBAc2VlICNqb2ludHNcblx0ICovXG5cdHB1YmxpYyBqb2ludEZyb21OYW1lKGpvaW50TmFtZTpzdHJpbmcpOlNrZWxldG9uSm9pbnRcblx0e1xuXHRcdHZhciBqb2ludEluZGV4Om51bWJlciAvKmludCovID0gdGhpcy5qb2ludEluZGV4RnJvbU5hbWUoam9pbnROYW1lKTtcblx0XHRpZiAoam9pbnRJbmRleCAhPSAtMSlcblx0XHRcdHJldHVybiB0aGlzLmpvaW50c1tqb2ludEluZGV4XTsgZWxzZVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgam9pbnQgaW5kZXgsIGdpdmVuIHRoZSBqb2ludCBuYW1lLiAtMSBpcyByZXR1cm5lZCBpZiB0aGUgam9pbnQgbmFtZSBpcyBub3QgZm91bmQuXG5cdCAqXG5cdCAqIEBwYXJhbSBqb2ludE5hbWUgVGhlIG5hbWUgb2YgdGhlIGpvaW50IG9iamVjdCB0byBiZSBmb3VuZC5cblx0ICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGpvaW50IG9iamVjdCBpbiB0aGUgam9pbnRzIEFycmF5XG5cdCAqXG5cdCAqIEBzZWUgI2pvaW50c1xuXHQgKi9cblx0cHVibGljIGpvaW50SW5kZXhGcm9tTmFtZShqb2ludE5hbWU6c3RyaW5nKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0Ly8gdGhpcyBpcyBpbXBsZW1lbnRlZCBhcyBhIGxpbmVhciBzZWFyY2gsIHJhdGhlciB0aGFuIGEgcG9zc2libHlcblx0XHQvLyBtb3JlIG9wdGltYWwgbWV0aG9kIChEaWN0aW9uYXJ5IGxvb2t1cCwgZm9yIGV4YW1wbGUpIGJlY2F1c2U6XG5cdFx0Ly8gYSkgaXQgaXMgYXNzdW1lZCB0aGF0IGl0IHdpbGwgYmUgY2FsbGVkIG9uY2UgZm9yIGVhY2ggam9pbnRcblx0XHQvLyBiKSBpdCBpcyBhc3N1bWVkIHRoYXQgaXQgd2lsbCBiZSBjYWxsZWQgb25seSBkdXJpbmcgbG9hZCwgYW5kIG5vdCBkdXJpbmcgbWFpbiBsb29wXG5cdFx0Ly8gYykgbWFpbnRhaW5pbmcgYSBkaWN0aW9uYXJ5IChmb3Igc2FmZXR5KSB3b3VsZCBkaWN0YXRlIGFuIGludGVyZmFjZSB0byBhY2Nlc3MgU2tlbGV0b25Kb2ludHMsXG5cdFx0Ly8gICAgcmF0aGVyIHRoYW4gZGlyZWN0IGFycmF5IGFjY2Vzcy4gIHRoaXMgd291bGQgYmUgc3ViLW9wdGltYWwuXG5cdFx0dmFyIGpvaW50SW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIGpvaW50OlNrZWxldG9uSm9pbnQ7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLzsgaSA8IHRoaXMuam9pbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRqb2ludCA9IHRoaXMuam9pbnRzW2ldO1xuXHRcdFx0aWYgKGpvaW50Lm5hbWUgPT0gam9pbnROYW1lKVxuXHRcdFx0XHRyZXR1cm4gam9pbnRJbmRleDtcblx0XHRcdGpvaW50SW5kZXgrKztcblx0XHR9XG5cblx0XHRyZXR1cm4gLTE7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdHRoaXMuam9pbnRzLmxlbmd0aCA9IDA7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXQgYXNzZXRUeXBlKCk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gQXNzZXRUeXBlLlNLRUxFVE9OO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNrZWxldG9uOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/data/Skeleton.ts b/lib/animators/data/Skeleton.ts
new file mode 100644
index 000000000..61bcfff38
--- /dev/null
+++ b/lib/animators/data/Skeleton.ts
@@ -0,0 +1,101 @@
+import SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint");
+
+import AssetType = require("awayjs-core/lib/core/library/AssetType");
+import IAsset = require("awayjs-core/lib/core/library/IAsset");
+import NamedAssetBase = require("awayjs-core/lib/core/library/NamedAssetBase");
+
+/**
+ * A Skeleton object is a hierarchical grouping of joint objects that can be used for skeletal animation.
+ *
+ * @see away.animators.SkeletonJoint
+ */
+class Skeleton extends NamedAssetBase implements IAsset
+{
+ /**
+ * A flat list of joint objects that comprise the skeleton. Every joint except for the root has a parentIndex
+ * property that is an index into this list.
+ * A child joint should always have a higher index than its parent.
+ */
+ public joints:Array;
+
+ /**
+ * The total number of joints in the skeleton.
+ */
+ public get numJoints():number /*uint*/
+ {
+ return this.joints.length;
+ }
+
+ /**
+ * Creates a new Skeleton
object
+ */
+ constructor()
+ {
+ super();
+
+ // in the long run, it might be a better idea to not store Joint objects, but keep all data in Vectors, that we can upload easily?
+ this.joints = new Array();
+ }
+
+ /**
+ * Returns the joint object in the skeleton with the given name, otherwise returns a null object.
+ *
+ * @param jointName The name of the joint object to be found.
+ * @return The joint object with the given name.
+ *
+ * @see #joints
+ */
+ public jointFromName(jointName:string):SkeletonJoint
+ {
+ var jointIndex:number /*int*/ = this.jointIndexFromName(jointName);
+ if (jointIndex != -1)
+ return this.joints[jointIndex]; else
+ return null;
+ }
+
+ /**
+ * Returns the joint index, given the joint name. -1 is returned if the joint name is not found.
+ *
+ * @param jointName The name of the joint object to be found.
+ * @return The index of the joint object in the joints Array
+ *
+ * @see #joints
+ */
+ public jointIndexFromName(jointName:string):number /*int*/
+ {
+ // this is implemented as a linear search, rather than a possibly
+ // more optimal method (Dictionary lookup, for example) because:
+ // a) it is assumed that it will be called once for each joint
+ // b) it is assumed that it will be called only during load, and not during main loop
+ // c) maintaining a dictionary (for safety) would dictate an interface to access SkeletonJoints,
+ // rather than direct array access. this would be sub-optimal.
+ var jointIndex:number /*int*/;
+ var joint:SkeletonJoint;
+ for (var i:number /*int*/; i < this.joints.length; i++) {
+ joint = this.joints[i];
+ if (joint.name == jointName)
+ return jointIndex;
+ jointIndex++;
+ }
+
+ return -1;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public dispose()
+ {
+ this.joints.length = 0;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get assetType():string
+ {
+ return AssetType.SKELETON;
+ }
+}
+
+export = Skeleton;
\ No newline at end of file
diff --git a/lib/animators/data/SkeletonJoint.js b/lib/animators/data/SkeletonJoint.js
new file mode 100755
index 000000000..8e0c24473
--- /dev/null
+++ b/lib/animators/data/SkeletonJoint.js
@@ -0,0 +1,22 @@
+/**
+ * A value obect representing a single joint in a skeleton object.
+ *
+ * @see away.animators.Skeleton
+ */
+var SkeletonJoint = (function () {
+ /**
+ * Creates a new SkeletonJoint
object
+ */
+ function SkeletonJoint() {
+ /**
+ * The index of the parent joint in the skeleton's joints vector.
+ *
+ * @see away.animators.Skeleton#joints
+ */
+ this.parentIndex = -1;
+ }
+ return SkeletonJoint;
+})();
+module.exports = SkeletonJoint;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3NrZWxldG9uam9pbnQudHMiXSwibmFtZXMiOlsiU2tlbGV0b25Kb2ludCIsIlNrZWxldG9uSm9pbnQuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUFBLEFBS0E7Ozs7R0FERztJQUNHLGFBQWE7SUFtQmxCQTs7T0FFR0E7SUFDSEEsU0F0QktBLGFBQWFBO1FBRWxCQzs7OztXQUlHQTtRQUNJQSxnQkFBV0EsR0FBa0JBLENBQUNBLENBQUNBLENBQUNBO0lBaUJ2Q0EsQ0FBQ0E7SUFDRkQsb0JBQUNBO0FBQURBLENBekJBLEFBeUJDQSxJQUFBO0FBRUQsQUFBdUIsaUJBQWQsYUFBYSxDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9kYXRhL1NrZWxldG9uSm9pbnQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgdmFsdWUgb2JlY3QgcmVwcmVzZW50aW5nIGEgc2luZ2xlIGpvaW50IGluIGEgc2tlbGV0b24gb2JqZWN0LlxuICpcbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuU2tlbGV0b25cbiAqL1xuY2xhc3MgU2tlbGV0b25Kb2ludFxue1xuXHQvKipcblx0ICogVGhlIGluZGV4IG9mIHRoZSBwYXJlbnQgam9pbnQgaW4gdGhlIHNrZWxldG9uJ3Mgam9pbnRzIHZlY3Rvci5cblx0ICpcblx0ICogQHNlZSBhd2F5LmFuaW1hdG9ycy5Ta2VsZXRvbiNqb2ludHNcblx0ICovXG5cdHB1YmxpYyBwYXJlbnRJbmRleDpudW1iZXIgLyppbnQqLyA9IC0xO1xuXG5cdC8qKlxuXHQgKiBUaGUgbmFtZSBvZiB0aGUgam9pbnRcblx0ICovXG5cdHB1YmxpYyBuYW1lOnN0cmluZzsgLy8gaW50ZW50aW9uIGlzIHRoYXQgdGhpcyBzaG91bGQgYmUgdXNlZCBvbmx5IGF0IGxvYWQgdGltZSwgbm90IGluIHRoZSBtYWluIGxvb3BcblxuXHQvKipcblx0ICogVGhlIGludmVyc2UgYmluZCBwb3NlIG1hdHJpeCwgYXMgcmF3IGRhdGEsIHVzZWQgdG8gdHJhbnNmb3JtIHZlcnRpY2VzIHRvIGJpbmQgam9pbnQgc3BhY2UgaW4gcHJlcGFyYXRpb24gZm9yIHRyYW5zZm9ybWF0aW9uIHVzaW5nIHRoZSBqb2ludCBtYXRyaXguXG5cdCAqL1xuXHRwdWJsaWMgaW52ZXJzZUJpbmRQb3NlOkFycmF5PG51bWJlcj47XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+U2tlbGV0b25Kb2ludDwvY29kZT4gb2JqZWN0XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkpvaW50OyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/data/SkeletonJoint.ts b/lib/animators/data/SkeletonJoint.ts
new file mode 100644
index 000000000..a02a3dc8c
--- /dev/null
+++ b/lib/animators/data/SkeletonJoint.ts
@@ -0,0 +1,33 @@
+/**
+ * A value obect representing a single joint in a skeleton object.
+ *
+ * @see away.animators.Skeleton
+ */
+class SkeletonJoint
+{
+ /**
+ * The index of the parent joint in the skeleton's joints vector.
+ *
+ * @see away.animators.Skeleton#joints
+ */
+ public parentIndex:number /*int*/ = -1;
+
+ /**
+ * The name of the joint
+ */
+ public name:string; // intention is that this should be used only at load time, not in the main loop
+
+ /**
+ * The inverse bind pose matrix, as raw data, used to transform vertices to bind joint space in preparation for transformation using the joint matrix.
+ */
+ public inverseBindPose:Array;
+
+ /**
+ * Creates a new SkeletonJoint
object
+ */
+ constructor()
+ {
+ }
+}
+
+export = SkeletonJoint;
\ No newline at end of file
diff --git a/lib/animators/data/SkeletonPose.js b/lib/animators/data/SkeletonPose.js
new file mode 100755
index 000000000..73f924129
--- /dev/null
+++ b/lib/animators/data/SkeletonPose.js
@@ -0,0 +1,113 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var AssetType = require("awayjs-core/lib/core/library/AssetType");
+var NamedAssetBase = require("awayjs-core/lib/core/library/NamedAssetBase");
+/**
+ * A collection of pose objects, determining the pose for an entire skeleton.
+ * The jointPoses
vector object corresponds to a skeleton's joints
vector object, however, there is no
+ * reference to a skeleton's instance, since several skeletons can be influenced by the same pose (eg: animation
+ * clips are added to any animator with a valid skeleton)
+ *
+ * @see away.animators.Skeleton
+ * @see away.animators.JointPose
+ */
+var SkeletonPose = (function (_super) {
+ __extends(SkeletonPose, _super);
+ /**
+ * Creates a new SkeletonPose
object.
+ */
+ function SkeletonPose() {
+ _super.call(this);
+ this.jointPoses = new Array();
+ }
+ Object.defineProperty(SkeletonPose.prototype, "numJointPoses", {
+ /**
+ * The total number of joint poses in the skeleton pose.
+ */
+ get: function () {
+ return this.jointPoses.length;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonPose.prototype, "assetType", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return AssetType.SKELETON_POSE;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Returns the joint pose object with the given joint name, otherwise returns a null object.
+ *
+ * @param jointName The name of the joint object whose pose is to be found.
+ * @return The pose object with the given joint name.
+ */
+ SkeletonPose.prototype.jointPoseFromName = function (jointName) {
+ var jointPoseIndex = this.jointPoseIndexFromName(jointName);
+ if (jointPoseIndex != -1)
+ return this.jointPoses[jointPoseIndex];
+ else
+ return null;
+ };
+ /**
+ * Returns the pose index, given the joint name. -1 is returned if the joint name is not found in the pose.
+ *
+ * @param The name of the joint object whose pose is to be found.
+ * @return The index of the pose object in the jointPoses Array
+ *
+ * @see #jointPoses
+ */
+ SkeletonPose.prototype.jointPoseIndexFromName = function (jointName) {
+ // this is implemented as a linear search, rather than a possibly
+ // more optimal method (Dictionary lookup, for example) because:
+ // a) it is assumed that it will be called once for each joint
+ // b) it is assumed that it will be called only during load, and not during main loop
+ // c) maintaining a dictionary (for safety) would dictate an interface to access JointPoses,
+ // rather than direct array access. this would be sub-optimal.
+ var jointPoseIndex /*int*/;
+ var jointPose;
+ for (var i /*uint*/; i < this.jointPoses.length; i++) {
+ jointPose = this.jointPoses[i];
+ if (jointPose.name == jointName)
+ return jointPoseIndex;
+ jointPoseIndex++;
+ }
+ return -1;
+ };
+ /**
+ * Creates a copy of the SkeletonPose
object, with a dulpicate of its component joint poses.
+ *
+ * @return SkeletonPose
+ */
+ SkeletonPose.prototype.clone = function () {
+ var clone = new SkeletonPose();
+ var numJointPoses = this.jointPoses.length;
+ for (var i = 0; i < numJointPoses; i++) {
+ var cloneJointPose = new JointPose();
+ var thisJointPose = this.jointPoses[i];
+ cloneJointPose.name = thisJointPose.name;
+ cloneJointPose.copyFrom(thisJointPose);
+ clone.jointPoses[i] = cloneJointPose;
+ }
+ return clone;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonPose.prototype.dispose = function () {
+ this.jointPoses.length = 0;
+ };
+ return SkeletonPose;
+})(NamedAssetBase);
+module.exports = SkeletonPose;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3NrZWxldG9ucG9zZS50cyJdLCJuYW1lcyI6WyJTa2VsZXRvblBvc2UiLCJTa2VsZXRvblBvc2UuY29uc3RydWN0b3IiLCJTa2VsZXRvblBvc2UubnVtSm9pbnRQb3NlcyIsIlNrZWxldG9uUG9zZS5hc3NldFR5cGUiLCJTa2VsZXRvblBvc2Uuam9pbnRQb3NlRnJvbU5hbWUiLCJTa2VsZXRvblBvc2Uuam9pbnRQb3NlSW5kZXhGcm9tTmFtZSIsIlNrZWxldG9uUG9zZS5jbG9uZSIsIlNrZWxldG9uUG9zZS5kaXNwb3NlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFNBQVMsV0FBZ0IsZ0RBQWdELENBQUMsQ0FBQztBQUVsRixJQUFPLFNBQVMsV0FBZ0Isd0NBQXdDLENBQUMsQ0FBQztBQUUxRSxJQUFPLGNBQWMsV0FBZSw2Q0FBNkMsQ0FBQyxDQUFDO0FBRW5GLEFBU0E7Ozs7Ozs7O0dBREc7SUFDRyxZQUFZO0lBQVNBLFVBQXJCQSxZQUFZQSxVQUF1QkE7SUFpQnhDQTs7T0FFR0E7SUFDSEEsU0FwQktBLFlBQVlBO1FBc0JoQkMsaUJBQU9BLENBQUNBO1FBRVJBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLEtBQUtBLEVBQWFBLENBQUNBO0lBQzFDQSxDQUFDQTtJQWJERCxzQkFBV0EsdUNBQWFBO1FBSHhCQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDL0JBLENBQUNBOzs7T0FBQUY7SUFlREEsc0JBQVdBLG1DQUFTQTtRQUhwQkE7O1dBRUdBO2FBQ0hBO1lBRUNHLE1BQU1BLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLENBQUNBO1FBQ2hDQSxDQUFDQTs7O09BQUFIO0lBRURBOzs7OztPQUtHQTtJQUNJQSx3Q0FBaUJBLEdBQXhCQSxVQUF5QkEsU0FBZ0JBO1FBRXhDSSxJQUFJQSxjQUFjQSxHQUFrQkEsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUMzRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsY0FBY0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeEJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBO1FBQUNBLElBQUlBO1lBQzVDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNkQSxDQUFDQTtJQUVESjs7Ozs7OztPQU9HQTtJQUNJQSw2Q0FBc0JBLEdBQTdCQSxVQUE4QkEsU0FBZ0JBO1FBRTdDSyxBQU1BQSxpRUFOaUVBO1FBQ2pFQSxnRUFBZ0VBO1FBQ2hFQSw4REFBOERBO1FBQzlEQSxxRkFBcUZBO1FBQ3JGQSw0RkFBNEZBO1FBQzVGQSxrRUFBa0VBO1lBQzlEQSxjQUFjQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUNsQ0EsSUFBSUEsU0FBbUJBLENBQUNBO1FBQ3hCQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUM3REEsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLEVBQUVBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBLElBQUlBLElBQUlBLFNBQVNBLENBQUNBO2dCQUMvQkEsTUFBTUEsQ0FBQ0EsY0FBY0EsQ0FBQ0E7WUFDdkJBLGNBQWNBLEVBQUVBLENBQUNBO1FBQ2xCQSxDQUFDQTtRQUVEQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUNYQSxDQUFDQTtJQUVETDs7OztPQUlHQTtJQUNJQSw0QkFBS0EsR0FBWkE7UUFFQ00sSUFBSUEsS0FBS0EsR0FBZ0JBLElBQUlBLFlBQVlBLEVBQUVBLENBQUNBO1FBQzVDQSxJQUFJQSxhQUFhQSxHQUFtQkEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDM0RBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxhQUFhQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUN4REEsSUFBSUEsY0FBY0EsR0FBYUEsSUFBSUEsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFDL0NBLElBQUlBLGFBQWFBLEdBQWFBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2pEQSxjQUFjQSxDQUFDQSxJQUFJQSxHQUFHQSxhQUFhQSxDQUFDQSxJQUFJQSxDQUFDQTtZQUN6Q0EsY0FBY0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0E7WUFDdkNBLEtBQUtBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLGNBQWNBLENBQUNBO1FBQ3RDQSxDQUFDQTtRQUNEQSxNQUFNQSxDQUFDQSxLQUFLQSxDQUFDQTtJQUNkQSxDQUFDQTtJQUVETjs7T0FFR0E7SUFDSUEsOEJBQU9BLEdBQWRBO1FBRUNPLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLE1BQU1BLEdBQUdBLENBQUNBLENBQUNBO0lBQzVCQSxDQUFDQTtJQUNGUCxtQkFBQ0E7QUFBREEsQ0F2R0EsQUF1R0NBLEVBdkcwQixjQUFjLEVBdUd4QztBQUVELEFBQXNCLGlCQUFiLFlBQVksQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvZGF0YS9Ta2VsZXRvblBvc2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSm9pbnRQb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0pvaW50UG9zZVwiKTtcblxuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9JQXNzZXRcIik7XG5pbXBvcnQgTmFtZWRBc3NldEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9OYW1lZEFzc2V0QmFzZVwiKTtcblxuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgcG9zZSBvYmplY3RzLCBkZXRlcm1pbmluZyB0aGUgcG9zZSBmb3IgYW4gZW50aXJlIHNrZWxldG9uLlxuICogVGhlIDxjb2RlPmpvaW50UG9zZXM8L2NvZGU+IHZlY3RvciBvYmplY3QgY29ycmVzcG9uZHMgdG8gYSBza2VsZXRvbidzIDxjb2RlPmpvaW50czwvY29kZT4gdmVjdG9yIG9iamVjdCwgaG93ZXZlciwgdGhlcmUgaXMgbm9cbiAqIHJlZmVyZW5jZSB0byBhIHNrZWxldG9uJ3MgaW5zdGFuY2UsIHNpbmNlIHNldmVyYWwgc2tlbGV0b25zIGNhbiBiZSBpbmZsdWVuY2VkIGJ5IHRoZSBzYW1lIHBvc2UgKGVnOiBhbmltYXRpb25cbiAqIGNsaXBzIGFyZSBhZGRlZCB0byBhbnkgYW5pbWF0b3Igd2l0aCBhIHZhbGlkIHNrZWxldG9uKVxuICpcbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuU2tlbGV0b25cbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuSm9pbnRQb3NlXG4gKi9cbmNsYXNzIFNrZWxldG9uUG9zZSBleHRlbmRzIE5hbWVkQXNzZXRCYXNlIGltcGxlbWVudHMgSUFzc2V0XG57XG5cdC8qKlxuXHQgKiBBIGZsYXQgbGlzdCBvZiBwb3NlIG9iamVjdHMgdGhhdCBjb21wcmlzZSB0aGUgc2tlbGV0b24gcG9zZS4gVGhlIHBvc2UgaW5kaWNlcyBjb3JyZXNwb25kIHRvIHRoZSB0YXJnZXQgc2tlbGV0b24ncyBqb2ludCBpbmRpY2VzLlxuXHQgKlxuXHQgKiBAc2VlIGF3YXkuYW5pbWF0b3JzLlNrZWxldG9uI2pvaW50c1xuXHQgKi9cblx0cHVibGljIGpvaW50UG9zZXM6QXJyYXk8Sm9pbnRQb3NlPjtcblxuXHQvKipcblx0ICogVGhlIHRvdGFsIG51bWJlciBvZiBqb2ludCBwb3NlcyBpbiB0aGUgc2tlbGV0b24gcG9zZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgbnVtSm9pbnRQb3NlcygpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuam9pbnRQb3Nlcy5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvblBvc2U8L2NvZGU+IG9iamVjdC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLmpvaW50UG9zZXMgPSBuZXcgQXJyYXk8Sm9pbnRQb3NlPigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGFzc2V0VHlwZSgpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIEFzc2V0VHlwZS5TS0VMRVRPTl9QT1NFO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGpvaW50IHBvc2Ugb2JqZWN0IHdpdGggdGhlIGdpdmVuIGpvaW50IG5hbWUsIG90aGVyd2lzZSByZXR1cm5zIGEgbnVsbCBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBqb2ludE5hbWUgVGhlIG5hbWUgb2YgdGhlIGpvaW50IG9iamVjdCB3aG9zZSBwb3NlIGlzIHRvIGJlIGZvdW5kLlxuXHQgKiBAcmV0dXJuIFRoZSBwb3NlIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBqb2ludCBuYW1lLlxuXHQgKi9cblx0cHVibGljIGpvaW50UG9zZUZyb21OYW1lKGpvaW50TmFtZTpzdHJpbmcpOkpvaW50UG9zZVxuXHR7XG5cdFx0dmFyIGpvaW50UG9zZUluZGV4Om51bWJlciAvKmludCovID0gdGhpcy5qb2ludFBvc2VJbmRleEZyb21OYW1lKGpvaW50TmFtZSk7XG5cdFx0aWYgKGpvaW50UG9zZUluZGV4ICE9IC0xKVxuXHRcdFx0cmV0dXJuIHRoaXMuam9pbnRQb3Nlc1tqb2ludFBvc2VJbmRleF07IGVsc2Vcblx0XHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHBvc2UgaW5kZXgsIGdpdmVuIHRoZSBqb2ludCBuYW1lLiAtMSBpcyByZXR1cm5lZCBpZiB0aGUgam9pbnQgbmFtZSBpcyBub3QgZm91bmQgaW4gdGhlIHBvc2UuXG5cdCAqXG5cdCAqIEBwYXJhbSBUaGUgbmFtZSBvZiB0aGUgam9pbnQgb2JqZWN0IHdob3NlIHBvc2UgaXMgdG8gYmUgZm91bmQuXG5cdCAqIEByZXR1cm4gVGhlIGluZGV4IG9mIHRoZSBwb3NlIG9iamVjdCBpbiB0aGUgam9pbnRQb3NlcyBBcnJheVxuXHQgKlxuXHQgKiBAc2VlICNqb2ludFBvc2VzXG5cdCAqL1xuXHRwdWJsaWMgam9pbnRQb3NlSW5kZXhGcm9tTmFtZShqb2ludE5hbWU6c3RyaW5nKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0Ly8gdGhpcyBpcyBpbXBsZW1lbnRlZCBhcyBhIGxpbmVhciBzZWFyY2gsIHJhdGhlciB0aGFuIGEgcG9zc2libHlcblx0XHQvLyBtb3JlIG9wdGltYWwgbWV0aG9kIChEaWN0aW9uYXJ5IGxvb2t1cCwgZm9yIGV4YW1wbGUpIGJlY2F1c2U6XG5cdFx0Ly8gYSkgaXQgaXMgYXNzdW1lZCB0aGF0IGl0IHdpbGwgYmUgY2FsbGVkIG9uY2UgZm9yIGVhY2ggam9pbnRcblx0XHQvLyBiKSBpdCBpcyBhc3N1bWVkIHRoYXQgaXQgd2lsbCBiZSBjYWxsZWQgb25seSBkdXJpbmcgbG9hZCwgYW5kIG5vdCBkdXJpbmcgbWFpbiBsb29wXG5cdFx0Ly8gYykgbWFpbnRhaW5pbmcgYSBkaWN0aW9uYXJ5IChmb3Igc2FmZXR5KSB3b3VsZCBkaWN0YXRlIGFuIGludGVyZmFjZSB0byBhY2Nlc3MgSm9pbnRQb3Nlcyxcblx0XHQvLyAgICByYXRoZXIgdGhhbiBkaXJlY3QgYXJyYXkgYWNjZXNzLiAgdGhpcyB3b3VsZCBiZSBzdWItb3B0aW1hbC5cblx0XHR2YXIgam9pbnRQb3NlSW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIGpvaW50UG9zZTpKb2ludFBvc2U7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki87IGkgPCB0aGlzLmpvaW50UG9zZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGpvaW50UG9zZSA9IHRoaXMuam9pbnRQb3Nlc1tpXTtcblx0XHRcdGlmIChqb2ludFBvc2UubmFtZSA9PSBqb2ludE5hbWUpXG5cdFx0XHRcdHJldHVybiBqb2ludFBvc2VJbmRleDtcblx0XHRcdGpvaW50UG9zZUluZGV4Kys7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoZSA8Y29kZT5Ta2VsZXRvblBvc2U8L2NvZGU+IG9iamVjdCwgd2l0aCBhIGR1bHBpY2F0ZSBvZiBpdHMgY29tcG9uZW50IGpvaW50IHBvc2VzLlxuXHQgKlxuXHQgKiBAcmV0dXJuIFNrZWxldG9uUG9zZVxuXHQgKi9cblx0cHVibGljIGNsb25lKCk6U2tlbGV0b25Qb3NlXG5cdHtcblx0XHR2YXIgY2xvbmU6U2tlbGV0b25Qb3NlID0gbmV3IFNrZWxldG9uUG9zZSgpO1xuXHRcdHZhciBudW1Kb2ludFBvc2VzOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuam9pbnRQb3Nlcy5sZW5ndGg7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwOyBpIDwgbnVtSm9pbnRQb3NlczsgaSsrKSB7XG5cdFx0XHR2YXIgY2xvbmVKb2ludFBvc2U6Sm9pbnRQb3NlID0gbmV3IEpvaW50UG9zZSgpO1xuXHRcdFx0dmFyIHRoaXNKb2ludFBvc2U6Sm9pbnRQb3NlID0gdGhpcy5qb2ludFBvc2VzW2ldO1xuXHRcdFx0Y2xvbmVKb2ludFBvc2UubmFtZSA9IHRoaXNKb2ludFBvc2UubmFtZTtcblx0XHRcdGNsb25lSm9pbnRQb3NlLmNvcHlGcm9tKHRoaXNKb2ludFBvc2UpO1xuXHRcdFx0Y2xvbmUuam9pbnRQb3Nlc1tpXSA9IGNsb25lSm9pbnRQb3NlO1xuXHRcdH1cblx0XHRyZXR1cm4gY2xvbmU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdHRoaXMuam9pbnRQb3Nlcy5sZW5ndGggPSAwO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNrZWxldG9uUG9zZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/data/SkeletonPose.ts b/lib/animators/data/SkeletonPose.ts
new file mode 100644
index 000000000..3223a3d31
--- /dev/null
+++ b/lib/animators/data/SkeletonPose.ts
@@ -0,0 +1,121 @@
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+
+import AssetType = require("awayjs-core/lib/core/library/AssetType");
+import IAsset = require("awayjs-core/lib/core/library/IAsset");
+import NamedAssetBase = require("awayjs-core/lib/core/library/NamedAssetBase");
+
+/**
+ * A collection of pose objects, determining the pose for an entire skeleton.
+ * The jointPoses
vector object corresponds to a skeleton's joints
vector object, however, there is no
+ * reference to a skeleton's instance, since several skeletons can be influenced by the same pose (eg: animation
+ * clips are added to any animator with a valid skeleton)
+ *
+ * @see away.animators.Skeleton
+ * @see away.animators.JointPose
+ */
+class SkeletonPose extends NamedAssetBase implements IAsset
+{
+ /**
+ * A flat list of pose objects that comprise the skeleton pose. The pose indices correspond to the target skeleton's joint indices.
+ *
+ * @see away.animators.Skeleton#joints
+ */
+ public jointPoses:Array;
+
+ /**
+ * The total number of joint poses in the skeleton pose.
+ */
+ public get numJointPoses():number /*uint*/
+ {
+ return this.jointPoses.length;
+ }
+
+ /**
+ * Creates a new SkeletonPose
object.
+ */
+ constructor()
+ {
+ super();
+
+ this.jointPoses = new Array();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get assetType():string
+ {
+ return AssetType.SKELETON_POSE;
+ }
+
+ /**
+ * Returns the joint pose object with the given joint name, otherwise returns a null object.
+ *
+ * @param jointName The name of the joint object whose pose is to be found.
+ * @return The pose object with the given joint name.
+ */
+ public jointPoseFromName(jointName:string):JointPose
+ {
+ var jointPoseIndex:number /*int*/ = this.jointPoseIndexFromName(jointName);
+ if (jointPoseIndex != -1)
+ return this.jointPoses[jointPoseIndex]; else
+ return null;
+ }
+
+ /**
+ * Returns the pose index, given the joint name. -1 is returned if the joint name is not found in the pose.
+ *
+ * @param The name of the joint object whose pose is to be found.
+ * @return The index of the pose object in the jointPoses Array
+ *
+ * @see #jointPoses
+ */
+ public jointPoseIndexFromName(jointName:string):number /*int*/
+ {
+ // this is implemented as a linear search, rather than a possibly
+ // more optimal method (Dictionary lookup, for example) because:
+ // a) it is assumed that it will be called once for each joint
+ // b) it is assumed that it will be called only during load, and not during main loop
+ // c) maintaining a dictionary (for safety) would dictate an interface to access JointPoses,
+ // rather than direct array access. this would be sub-optimal.
+ var jointPoseIndex:number /*int*/;
+ var jointPose:JointPose;
+ for (var i:number /*uint*/; i < this.jointPoses.length; i++) {
+ jointPose = this.jointPoses[i];
+ if (jointPose.name == jointName)
+ return jointPoseIndex;
+ jointPoseIndex++;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Creates a copy of the SkeletonPose
object, with a dulpicate of its component joint poses.
+ *
+ * @return SkeletonPose
+ */
+ public clone():SkeletonPose
+ {
+ var clone:SkeletonPose = new SkeletonPose();
+ var numJointPoses:number /*uint*/ = this.jointPoses.length;
+ for (var i:number /*uint*/ = 0; i < numJointPoses; i++) {
+ var cloneJointPose:JointPose = new JointPose();
+ var thisJointPose:JointPose = this.jointPoses[i];
+ cloneJointPose.name = thisJointPose.name;
+ cloneJointPose.copyFrom(thisJointPose);
+ clone.jointPoses[i] = cloneJointPose;
+ }
+ return clone;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public dispose()
+ {
+ this.jointPoses.length = 0;
+ }
+}
+
+export = SkeletonPose;
\ No newline at end of file
diff --git a/lib/animators/data/VertexAnimationMode.js b/lib/animators/data/VertexAnimationMode.js
new file mode 100755
index 000000000..c83fbda70
--- /dev/null
+++ b/lib/animators/data/VertexAnimationMode.js
@@ -0,0 +1,21 @@
+/**
+ * Options for setting the animation mode of a vertex animator object.
+ *
+ * @see away.animators.VertexAnimator
+ */
+var VertexAnimationMode = (function () {
+ function VertexAnimationMode() {
+ }
+ /**
+ * Animation mode that adds all outputs from active vertex animation state to form the current vertex animation pose.
+ */
+ VertexAnimationMode.ADDITIVE = "additive";
+ /**
+ * Animation mode that picks the output from a single vertex animation state to form the current vertex animation pose.
+ */
+ VertexAnimationMode.ABSOLUTE = "absolute";
+ return VertexAnimationMode;
+})();
+module.exports = VertexAnimationMode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9kYXRhL3ZlcnRleGFuaW1hdGlvbm1vZGUudHMiXSwibmFtZXMiOlsiVmVydGV4QW5pbWF0aW9uTW9kZSIsIlZlcnRleEFuaW1hdGlvbk1vZGUuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiJBQUFBLEFBS0E7Ozs7R0FERztJQUNHLG1CQUFtQjtJQUF6QkEsU0FBTUEsbUJBQW1CQTtJQVd6QkMsQ0FBQ0E7SUFUQUQ7O09BRUdBO0lBQ1dBLDRCQUFRQSxHQUFVQSxVQUFVQSxDQUFDQTtJQUUzQ0E7O09BRUdBO0lBQ1dBLDRCQUFRQSxHQUFVQSxVQUFVQSxDQUFDQTtJQUM1Q0EsMEJBQUNBO0FBQURBLENBWEEsQUFXQ0EsSUFBQTtBQUVELEFBQTZCLGlCQUFwQixtQkFBbUIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvZGF0YS9WZXJ0ZXhBbmltYXRpb25Nb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBPcHRpb25zIGZvciBzZXR0aW5nIHRoZSBhbmltYXRpb24gbW9kZSBvZiBhIHZlcnRleCBhbmltYXRvciBvYmplY3QuXG4gKlxuICogQHNlZSBhd2F5LmFuaW1hdG9ycy5WZXJ0ZXhBbmltYXRvclxuICovXG5jbGFzcyBWZXJ0ZXhBbmltYXRpb25Nb2RlXG57XG5cdC8qKlxuXHQgKiBBbmltYXRpb24gbW9kZSB0aGF0IGFkZHMgYWxsIG91dHB1dHMgZnJvbSBhY3RpdmUgdmVydGV4IGFuaW1hdGlvbiBzdGF0ZSB0byBmb3JtIHRoZSBjdXJyZW50IHZlcnRleCBhbmltYXRpb24gcG9zZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgQURESVRJVkU6c3RyaW5nID0gXCJhZGRpdGl2ZVwiO1xuXG5cdC8qKlxuXHQgKiBBbmltYXRpb24gbW9kZSB0aGF0IHBpY2tzIHRoZSBvdXRwdXQgZnJvbSBhIHNpbmdsZSB2ZXJ0ZXggYW5pbWF0aW9uIHN0YXRlIHRvIGZvcm0gdGhlIGN1cnJlbnQgdmVydGV4IGFuaW1hdGlvbiBwb3NlLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBBQlNPTFVURTpzdHJpbmcgPSBcImFic29sdXRlXCI7XG59XG5cbmV4cG9ydCA9IFZlcnRleEFuaW1hdGlvbk1vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/data/VertexAnimationMode.ts b/lib/animators/data/VertexAnimationMode.ts
new file mode 100644
index 000000000..c188e10a3
--- /dev/null
+++ b/lib/animators/data/VertexAnimationMode.ts
@@ -0,0 +1,19 @@
+/**
+ * Options for setting the animation mode of a vertex animator object.
+ *
+ * @see away.animators.VertexAnimator
+ */
+class VertexAnimationMode
+{
+ /**
+ * Animation mode that adds all outputs from active vertex animation state to form the current vertex animation pose.
+ */
+ public static ADDITIVE:string = "additive";
+
+ /**
+ * Animation mode that picks the output from a single vertex animation state to form the current vertex animation pose.
+ */
+ public static ABSOLUTE:string = "absolute";
+}
+
+export = VertexAnimationMode;
\ No newline at end of file
diff --git a/lib/animators/nodes/AnimationClipNodeBase.js b/lib/animators/nodes/AnimationClipNodeBase.js
new file mode 100755
index 000000000..279920229
--- /dev/null
+++ b/lib/animators/nodes/AnimationClipNodeBase.js
@@ -0,0 +1,116 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+/**
+ * Provides an abstract base class for nodes with time-based animation data in an animation blend tree.
+ */
+var AnimationClipNodeBase = (function (_super) {
+ __extends(AnimationClipNodeBase, _super);
+ /**
+ * Creates a new AnimationClipNodeBase
object.
+ */
+ function AnimationClipNodeBase() {
+ _super.call(this);
+ this._pLooping = true;
+ this._pTotalDuration = 0;
+ this._pStitchDirty = true;
+ this._pStitchFinalFrame = false;
+ this._pNumFrames = 0;
+ this._pDurations = new Array();
+ /*uint*/
+ this._pTotalDelta = new Vector3D();
+ this.fixedFrameRate = true;
+ }
+ Object.defineProperty(AnimationClipNodeBase.prototype, "looping", {
+ /**
+ * Determines whether the contents of the animation node have looping characteristics enabled.
+ */
+ get: function () {
+ return this._pLooping;
+ },
+ set: function (value) {
+ if (this._pLooping == value)
+ return;
+ this._pLooping = value;
+ this._pStitchDirty = true;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipNodeBase.prototype, "stitchFinalFrame", {
+ /**
+ * Defines if looping content blends the final frame of animation data with the first (true) or works on the
+ * assumption that both first and last frames are identical (false). Defaults to false.
+ */
+ get: function () {
+ return this._pStitchFinalFrame;
+ },
+ set: function (value) {
+ if (this._pStitchFinalFrame == value)
+ return;
+ this._pStitchFinalFrame = value;
+ this._pStitchDirty = true;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipNodeBase.prototype, "totalDuration", {
+ get: function () {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+ return this._pTotalDuration;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipNodeBase.prototype, "totalDelta", {
+ get: function () {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+ return this._pTotalDelta;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipNodeBase.prototype, "lastFrame", {
+ get: function () {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+ return this._pLastFrame;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipNodeBase.prototype, "durations", {
+ /**
+ * Returns a vector of time values representing the duration (in milliseconds) of each animation frame in the clip.
+ */
+ get: function () {
+ return this._pDurations;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Updates the node's final frame stitch state.
+ *
+ * @see #stitchFinalFrame
+ */
+ AnimationClipNodeBase.prototype._pUpdateStitch = function () {
+ this._pStitchDirty = false;
+ this._pLastFrame = (this._pStitchFinalFrame) ? this._pNumFrames : this._pNumFrames - 1;
+ this._pTotalDuration = 0;
+ this._pTotalDelta.x = 0;
+ this._pTotalDelta.y = 0;
+ this._pTotalDelta.z = 0;
+ };
+ return AnimationClipNodeBase;
+})(AnimationNodeBase);
+module.exports = AnimationClipNodeBase;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9hbmltYXRpb25jbGlwbm9kZWJhc2UudHMiXSwibmFtZXMiOlsiQW5pbWF0aW9uQ2xpcE5vZGVCYXNlIiwiQW5pbWF0aW9uQ2xpcE5vZGVCYXNlLmNvbnN0cnVjdG9yIiwiQW5pbWF0aW9uQ2xpcE5vZGVCYXNlLmxvb3BpbmciLCJBbmltYXRpb25DbGlwTm9kZUJhc2Uuc3RpdGNoRmluYWxGcmFtZSIsIkFuaW1hdGlvbkNsaXBOb2RlQmFzZS50b3RhbER1cmF0aW9uIiwiQW5pbWF0aW9uQ2xpcE5vZGVCYXNlLnRvdGFsRGVsdGEiLCJBbmltYXRpb25DbGlwTm9kZUJhc2UubGFzdEZyYW1lIiwiQW5pbWF0aW9uQ2xpcE5vZGVCYXNlLmR1cmF0aW9ucyIsIkFuaW1hdGlvbkNsaXBOb2RlQmFzZS5fcFVwZGF0ZVN0aXRjaCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxpQkFBaUIsV0FBYyxtREFBbUQsQ0FBQyxDQUFDO0FBQzNGLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBRXRFLEFBR0E7O0dBREc7SUFDRyxxQkFBcUI7SUFBU0EsVUFBOUJBLHFCQUFxQkEsVUFBMEJBO0lBcUZwREE7O09BRUdBO0lBQ0hBLFNBeEZLQSxxQkFBcUJBO1FBMEZ6QkMsaUJBQU9BLENBQUNBO1FBeEZGQSxjQUFTQSxHQUFXQSxJQUFJQSxDQUFDQTtRQUN6QkEsb0JBQWVBLEdBQW1CQSxDQUFDQSxDQUFDQTtRQUdwQ0Esa0JBQWFBLEdBQVdBLElBQUlBLENBQUNBO1FBQzdCQSx1QkFBa0JBLEdBQVdBLEtBQUtBLENBQUNBO1FBQ25DQSxnQkFBV0EsR0FBbUJBLENBQUNBLENBQUNBO1FBRWhDQSxnQkFBV0EsR0FBaUJBLElBQUlBLEtBQUtBLEVBQVVBLENBQUNBO1FBQ3ZEQSxRQUFRQTtRQUNEQSxpQkFBWUEsR0FBWUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7UUFFdkNBLG1CQUFjQSxHQUFXQSxJQUFJQSxDQUFDQTtJQTZF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Q2xpcE5vZGVCYXNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIG5vZGVzIHdpdGggdGltZS1iYXNlZCBhbmltYXRpb24gZGF0YSBpbiBhbiBhbmltYXRpb24gYmxlbmQgdHJlZS5cbiAqL1xuY2xhc3MgQW5pbWF0aW9uQ2xpcE5vZGVCYXNlIGV4dGVuZHMgQW5pbWF0aW9uTm9kZUJhc2Vcbntcblx0cHVibGljIF9wTG9vcGluZzpib29sZWFuID0gdHJ1ZTtcblx0cHVibGljIF9wVG90YWxEdXJhdGlvbjpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRwdWJsaWMgX3BMYXN0RnJhbWU6bnVtYmVyIC8qdWludCovO1xuXG5cdHB1YmxpYyBfcFN0aXRjaERpcnR5OmJvb2xlYW4gPSB0cnVlO1xuXHRwdWJsaWMgX3BTdGl0Y2hGaW5hbEZyYW1lOmJvb2xlYW4gPSBmYWxzZTtcblx0cHVibGljIF9wTnVtRnJhbWVzOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0cHVibGljIF9wRHVyYXRpb25zOkFycmF5PG51bWJlcj4gPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHQvKnVpbnQqL1xuXHRwdWJsaWMgX3BUb3RhbERlbHRhOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEKCk7XG5cblx0cHVibGljIGZpeGVkRnJhbWVSYXRlOmJvb2xlYW4gPSB0cnVlO1xuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNvbnRlbnRzIG9mIHRoZSBhbmltYXRpb24gbm9kZSBoYXZlIGxvb3BpbmcgY2hhcmFjdGVyaXN0aWNzIGVuYWJsZWQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGxvb3BpbmcoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcExvb3Bpbmc7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGxvb3BpbmcodmFsdWU6Ym9vbGVhbilcblx0e1xuXHRcdGlmICh0aGlzLl9wTG9vcGluZyA9PSB2YWx1ZSlcblx0XHRcdHJldHVybjtcblxuXHRcdHRoaXMuX3BMb29waW5nID0gdmFsdWU7XG5cblx0XHR0aGlzLl9wU3RpdGNoRGlydHkgPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmluZXMgaWYgbG9vcGluZyBjb250ZW50IGJsZW5kcyB0aGUgZmluYWwgZnJhbWUgb2YgYW5pbWF0aW9uIGRhdGEgd2l0aCB0aGUgZmlyc3QgKHRydWUpIG9yIHdvcmtzIG9uIHRoZVxuXHQgKiBhc3N1bXB0aW9uIHRoYXQgYm90aCBmaXJzdCBhbmQgbGFzdCBmcmFtZXMgYXJlIGlkZW50aWNhbCAoZmFsc2UpLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgc3RpdGNoRmluYWxGcmFtZSgpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9wU3RpdGNoRmluYWxGcmFtZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgc3RpdGNoRmluYWxGcmFtZSh2YWx1ZTpib29sZWFuKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3BTdGl0Y2hGaW5hbEZyYW1lID09IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5fcFN0aXRjaEZpbmFsRnJhbWUgPSB2YWx1ZTtcblxuXHRcdHRoaXMuX3BTdGl0Y2hEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHRwdWJsaWMgZ2V0IHRvdGFsRHVyYXRpb24oKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdGlmICh0aGlzLl9wU3RpdGNoRGlydHkpXG5cdFx0XHR0aGlzLl9wVXBkYXRlU3RpdGNoKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fcFRvdGFsRHVyYXRpb247XG5cdH1cblxuXHRwdWJsaWMgZ2V0IHRvdGFsRGVsdGEoKTpWZWN0b3IzRFxuXHR7XG5cdFx0aWYgKHRoaXMuX3BTdGl0Y2hEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVTdGl0Y2goKTtcblxuXHRcdHJldHVybiB0aGlzLl9wVG90YWxEZWx0YTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgbGFzdEZyYW1lKCk6bnVtYmVyIC8qdWludCovXG5cdHtcblx0XHRpZiAodGhpcy5fcFN0aXRjaERpcnR5KVxuXHRcdFx0dGhpcy5fcFVwZGF0ZVN0aXRjaCgpO1xuXG5cdFx0cmV0dXJuIHRoaXMuX3BMYXN0RnJhbWU7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhIHZlY3RvciBvZiB0aW1lIHZhbHVlcyByZXByZXNlbnRpbmcgdGhlIGR1cmF0aW9uIChpbiBtaWxsaXNlY29uZHMpIG9mIGVhY2ggYW5pbWF0aW9uIGZyYW1lIGluIHRoZSBjbGlwLlxuXHQgKi9cblx0cHVibGljIGdldCBkdXJhdGlvbnMoKTpBcnJheTxudW1iZXI+IC8qdWludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcER1cmF0aW9ucztcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPkFuaW1hdGlvbkNsaXBOb2RlQmFzZTwvY29kZT4gb2JqZWN0LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBub2RlJ3MgZmluYWwgZnJhbWUgc3RpdGNoIHN0YXRlLlxuXHQgKlxuXHQgKiBAc2VlICNzdGl0Y2hGaW5hbEZyYW1lXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVTdGl0Y2goKVxuXHR7XG5cdFx0dGhpcy5fcFN0aXRjaERpcnR5ID0gZmFsc2U7XG5cblx0XHR0aGlzLl9wTGFzdEZyYW1lID0gKHRoaXMuX3BTdGl0Y2hGaW5hbEZyYW1lKT8gdGhpcy5fcE51bUZyYW1lcyA6IHRoaXMuX3BOdW1GcmFtZXMgLSAxO1xuXG5cdFx0dGhpcy5fcFRvdGFsRHVyYXRpb24gPSAwO1xuXHRcdHRoaXMuX3BUb3RhbERlbHRhLnggPSAwO1xuXHRcdHRoaXMuX3BUb3RhbERlbHRhLnkgPSAwO1xuXHRcdHRoaXMuX3BUb3RhbERlbHRhLnogPSAwO1xuXHR9XG59XG5cbmV4cG9ydCA9IEFuaW1hdGlvbkNsaXBOb2RlQmFzZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/AnimationClipNodeBase.ts b/lib/animators/nodes/AnimationClipNodeBase.ts
new file mode 100644
index 000000000..a6933746a
--- /dev/null
+++ b/lib/animators/nodes/AnimationClipNodeBase.ts
@@ -0,0 +1,118 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+/**
+ * Provides an abstract base class for nodes with time-based animation data in an animation blend tree.
+ */
+class AnimationClipNodeBase extends AnimationNodeBase
+{
+ public _pLooping:boolean = true;
+ public _pTotalDuration:number /*uint*/ = 0;
+ public _pLastFrame:number /*uint*/;
+
+ public _pStitchDirty:boolean = true;
+ public _pStitchFinalFrame:boolean = false;
+ public _pNumFrames:number /*uint*/ = 0;
+
+ public _pDurations:Array = new Array();
+ /*uint*/
+ public _pTotalDelta:Vector3D = new Vector3D();
+
+ public fixedFrameRate:boolean = true;
+
+ /**
+ * Determines whether the contents of the animation node have looping characteristics enabled.
+ */
+ public get looping():boolean
+ {
+ return this._pLooping;
+ }
+
+ public set looping(value:boolean)
+ {
+ if (this._pLooping == value)
+ return;
+
+ this._pLooping = value;
+
+ this._pStitchDirty = true;
+ }
+
+ /**
+ * Defines if looping content blends the final frame of animation data with the first (true) or works on the
+ * assumption that both first and last frames are identical (false). Defaults to false.
+ */
+ public get stitchFinalFrame():boolean
+ {
+ return this._pStitchFinalFrame;
+ }
+
+ public set stitchFinalFrame(value:boolean)
+ {
+ if (this._pStitchFinalFrame == value)
+ return;
+
+ this._pStitchFinalFrame = value;
+
+ this._pStitchDirty = true;
+ }
+
+ public get totalDuration():number /*uint*/
+ {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+
+ return this._pTotalDuration;
+ }
+
+ public get totalDelta():Vector3D
+ {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+
+ return this._pTotalDelta;
+ }
+
+ public get lastFrame():number /*uint*/
+ {
+ if (this._pStitchDirty)
+ this._pUpdateStitch();
+
+ return this._pLastFrame;
+ }
+
+ /**
+ * Returns a vector of time values representing the duration (in milliseconds) of each animation frame in the clip.
+ */
+ public get durations():Array /*uint*/
+ {
+ return this._pDurations;
+ }
+
+ /**
+ * Creates a new AnimationClipNodeBase
object.
+ */
+ constructor()
+ {
+ super();
+ }
+
+ /**
+ * Updates the node's final frame stitch state.
+ *
+ * @see #stitchFinalFrame
+ */
+ public _pUpdateStitch()
+ {
+ this._pStitchDirty = false;
+
+ this._pLastFrame = (this._pStitchFinalFrame)? this._pNumFrames : this._pNumFrames - 1;
+
+ this._pTotalDuration = 0;
+ this._pTotalDelta.x = 0;
+ this._pTotalDelta.y = 0;
+ this._pTotalDelta.z = 0;
+ }
+}
+
+export = AnimationClipNodeBase;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleAccelerationNode.js b/lib/animators/nodes/ParticleAccelerationNode.js
new file mode 100755
index 000000000..5b4c1adfd
--- /dev/null
+++ b/lib/animators/nodes/ParticleAccelerationNode.js
@@ -0,0 +1,73 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleAccelerationState = require("awayjs-renderergl/lib/animators/states/ParticleAccelerationState");
+/**
+ * A particle animation node used to apply a constant acceleration vector to the motion of a particle.
+ */
+var ParticleAccelerationNode = (function (_super) {
+ __extends(ParticleAccelerationNode, _super);
+ /**
+ * Creates a new ParticleAccelerationNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] acceleration Defines the default acceleration vector of the node, used when in global mode.
+ */
+ function ParticleAccelerationNode(mode /*uint*/, acceleration) {
+ if (acceleration === void 0) { acceleration = null; }
+ _super.call(this, "ParticleAcceleration", mode, 3);
+ this._pStateClass = ParticleAccelerationState;
+ this._acceleration = acceleration || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleAccelerationNode.prototype.pGetAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var accelerationValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleAccelerationState.ACCELERATION_INDEX, accelerationValue.index);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var code = "mul " + temp + "," + animationRegisterCache.vertexTime + "," + accelerationValue + "\n";
+ if (animationRegisterCache.needVelocity) {
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ code += "mul " + temp2 + "," + temp + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + temp2 + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+ animationRegisterCache.removeVertexTempUsage(temp);
+ code += "mul " + temp + "," + temp + "," + animationRegisterCache.vertexTime + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + temp + "," + animationRegisterCache.positionTarget + ".xyz\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAccelerationNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleAccelerationNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var tempAcceleration = param[ParticleAccelerationNode.ACCELERATION_VECTOR3D];
+ if (!tempAcceleration)
+ throw new Error("there is no " + ParticleAccelerationNode.ACCELERATION_VECTOR3D + " in param!");
+ this._pOneData[0] = tempAcceleration.x / 2;
+ this._pOneData[1] = tempAcceleration.y / 2;
+ this._pOneData[2] = tempAcceleration.z / 2;
+ };
+ /**
+ * Reference for acceleration node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the direction of acceleration on the particle.
+ */
+ ParticleAccelerationNode.ACCELERATION_VECTOR3D = "AccelerationVector3D";
+ return ParticleAccelerationNode;
+})(ParticleNodeBase);
+module.exports = ParticleAccelerationNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWFjY2VsZXJhdGlvbm5vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlIiwiUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlLnBHZXRBR0FMVmVydGV4Q29kZSIsIlBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZS5faUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQVF0RSxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8seUJBQXlCLFdBQVksa0VBQWtFLENBQUMsQ0FBQztBQUVoSCxBQUdBOztHQURHO0lBQ0csd0JBQXdCO0lBQVNBLFVBQWpDQSx3QkFBd0JBLFVBQXlCQTtJQVd0REE7Ozs7O09BS0dBO0lBQ0hBLFNBakJLQSx3QkFBd0JBLENBaUJqQkEsSUFBSUEsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsWUFBNEJBO1FBQTVCQyw0QkFBNEJBLEdBQTVCQSxtQkFBNEJBO1FBRTdEQSxrQkFBTUEsc0JBQXNCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUV2Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EseUJBQXlCQSxDQUFDQTtRQUU5Q0EsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsWUFBWUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDckRBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSxxREFBa0JBLEdBQXpCQSxVQUEwQkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFckdFLElBQUlB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Q0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsZ0JBQWdCQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQTtJQUMxQ0EsQ0FBQ0E7SUFsRURKOzs7T0FHR0E7SUFDV0EsOENBQXFCQSxHQUFVQSxzQkFBc0JBLENBQUNBO0lBK0RyRUEsK0JBQUNBO0FBQURBLENBeEVBLEFBd0VDQSxFQXhFc0MsZ0JBQWdCLEVBd0V0RDtBQUVELEFBQWtDLGlCQUF6Qix3QkFBd0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZUFjY2VsZXJhdGlvblN0YXRlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlQWNjZWxlcmF0aW9uU3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB1c2VkIHRvIGFwcGx5IGEgY29uc3RhbnQgYWNjZWxlcmF0aW9uIHZlY3RvciB0byB0aGUgbW90aW9uIG9mIGEgcGFydGljbGUuXG4gKi9cbmNsYXNzIFBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfYWNjZWxlcmF0aW9uOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIGFjY2VsZXJhdGlvbiBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5WZWN0b3IzRDwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZGlyZWN0aW9uIG9mIGFjY2VsZXJhdGlvbiBvbiB0aGUgcGFydGljbGUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIEFDQ0VMRVJBVElPTl9WRUNUT1IzRDpzdHJpbmcgPSBcIkFjY2VsZXJhdGlvblZlY3RvcjNEXCI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVBY2NlbGVyYXRpb25Ob2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gYWNjZWxlcmF0aW9uICAgIERlZmluZXMgdGhlIGRlZmF1bHQgYWNjZWxlcmF0aW9uIHZlY3RvciBvZiB0aGUgbm9kZSwgdXNlZCB3aGVuIGluIGdsb2JhbCBtb2RlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobW9kZTpudW1iZXIgLyp1aW50Ki8sIGFjY2VsZXJhdGlvbjpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlQWNjZWxlcmF0aW9uXCIsIG1vZGUsIDMpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBQYXJ0aWNsZUFjY2VsZXJhdGlvblN0YXRlO1xuXG5cdFx0dGhpcy5fYWNjZWxlcmF0aW9uID0gYWNjZWxlcmF0aW9uIHx8IG5ldyBWZWN0b3IzRCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgcEdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGFjY2VsZXJhdGlvblZhbHVlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCkgOiBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZS5BQ0NFTEVSQVRJT05fSU5ERVgsIGFjY2VsZXJhdGlvblZhbHVlLmluZGV4KTtcblxuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXModGVtcCwgMSk7XG5cblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIm11bCBcIiArIHRlbXAgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgYWNjZWxlcmF0aW9uVmFsdWUgKyBcIlxcblwiO1xuXG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFZlbG9jaXR5KSB7XG5cdFx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAyICsgXCIsXCIgKyB0ZW1wICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFR3b0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlbG9jaXR5VGFyZ2V0ICsgXCIueHl6LFwiICsgdGVtcDIgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlbG9jaXR5VGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0fVxuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIixcIiArIHRlbXAgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXosXCIgKyB0ZW1wICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnBvc2l0aW9uVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlQWNjZWxlcmF0aW9uU3RhdGVcblx0e1xuXHRcdHJldHVybiA8UGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlKHBhcmFtOlBhcnRpY2xlUHJvcGVydGllcylcblx0e1xuXHRcdHZhciB0ZW1wQWNjZWxlcmF0aW9uOlZlY3RvcjNEID0gcGFyYW1bUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlLkFDQ0VMRVJBVElPTl9WRUNUT1IzRF07XG5cdFx0aWYgKCF0ZW1wQWNjZWxlcmF0aW9uKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZUFjY2VsZXJhdGlvbk5vZGUuQUNDRUxFUkFUSU9OX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpO1xuXG5cdFx0dGhpcy5fcE9uZURhdGFbMF0gPSB0ZW1wQWNjZWxlcmF0aW9uLngvMjtcblx0XHR0aGlzLl9wT25lRGF0YVsxXSA9IHRlbXBBY2NlbGVyYXRpb24ueS8yO1xuXHRcdHRoaXMuX3BPbmVEYXRhWzJdID0gdGVtcEFjY2VsZXJhdGlvbi56LzI7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleAccelerationNode.ts b/lib/animators/nodes/ParticleAccelerationNode.ts
new file mode 100644
index 000000000..06894ea4f
--- /dev/null
+++ b/lib/animators/nodes/ParticleAccelerationNode.ts
@@ -0,0 +1,90 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleAccelerationState = require("awayjs-renderergl/lib/animators/states/ParticleAccelerationState");
+
+/**
+ * A particle animation node used to apply a constant acceleration vector to the motion of a particle.
+ */
+class ParticleAccelerationNode extends ParticleNodeBase
+{
+ /** @private */
+ public _acceleration:Vector3D;
+
+ /**
+ * Reference for acceleration node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the direction of acceleration on the particle.
+ */
+ public static ACCELERATION_VECTOR3D:string = "AccelerationVector3D";
+
+ /**
+ * Creates a new ParticleAccelerationNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] acceleration Defines the default acceleration vector of the node, used when in global mode.
+ */
+ constructor(mode:number /*uint*/, acceleration:Vector3D = null)
+ {
+ super("ParticleAcceleration", mode, 3);
+
+ this._pStateClass = ParticleAccelerationState;
+
+ this._acceleration = acceleration || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public pGetAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var accelerationValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleAccelerationState.ACCELERATION_INDEX, accelerationValue.index);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+
+ var code:string = "mul " + temp + "," + animationRegisterCache.vertexTime + "," + accelerationValue + "\n";
+
+ if (animationRegisterCache.needVelocity) {
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ code += "mul " + temp2 + "," + temp + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + temp2 + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+ animationRegisterCache.removeVertexTempUsage(temp);
+
+ code += "mul " + temp + "," + temp + "," + animationRegisterCache.vertexTime + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + temp + "," + animationRegisterCache.positionTarget + ".xyz\n";
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleAccelerationState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var tempAcceleration:Vector3D = param[ParticleAccelerationNode.ACCELERATION_VECTOR3D];
+ if (!tempAcceleration)
+ throw new Error("there is no " + ParticleAccelerationNode.ACCELERATION_VECTOR3D + " in param!");
+
+ this._pOneData[0] = tempAcceleration.x/2;
+ this._pOneData[1] = tempAcceleration.y/2;
+ this._pOneData[2] = tempAcceleration.z/2;
+ }
+}
+
+export = ParticleAccelerationNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleBezierCurveNode.js b/lib/animators/nodes/ParticleBezierCurveNode.js
new file mode 100755
index 000000000..5600fb9f9
--- /dev/null
+++ b/lib/animators/nodes/ParticleBezierCurveNode.js
@@ -0,0 +1,105 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleBezierCurveState = require("awayjs-renderergl/lib/animators/states/ParticleBezierCurveState");
+/**
+ * A particle animation node used to control the position of a particle over time along a bezier curve.
+ */
+var ParticleBezierCurveNode = (function (_super) {
+ __extends(ParticleBezierCurveNode, _super);
+ /**
+ * Creates a new ParticleBezierCurveNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] controlPoint Defines the default control point of the node, used when in global mode.
+ * @param [optional] endPoint Defines the default end point of the node, used when in global mode.
+ */
+ function ParticleBezierCurveNode(mode /*uint*/, controlPoint, endPoint) {
+ if (controlPoint === void 0) { controlPoint = null; }
+ if (endPoint === void 0) { endPoint = null; }
+ _super.call(this, "ParticleBezierCurve", mode, 6);
+ this._pStateClass = ParticleBezierCurveState;
+ this._iControlPoint = controlPoint || new Vector3D();
+ this._iEndPoint = endPoint || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleBezierCurveNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var controlValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleBezierCurveState.BEZIER_CONTROL_INDEX, controlValue.index);
+ var endValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleBezierCurveState.BEZIER_END_INDEX, endValue.index);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ var rev_time = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var time_2 = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var time_temp = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ var distance = new ShaderRegisterElement(temp2.regName, temp2.index);
+ animationRegisterCache.removeVertexTempUsage(temp);
+ var code = "";
+ code += "sub " + rev_time + "," + animationRegisterCache.vertexOneConst + "," + animationRegisterCache.vertexLife + "\n";
+ code += "mul " + time_2 + "," + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexLife + "\n";
+ code += "mul " + time_temp + "," + animationRegisterCache.vertexLife + "," + rev_time + "\n";
+ code += "mul " + time_temp + "," + time_temp + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "mul " + distance + ".xyz," + time_temp + "," + controlValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "mul " + distance + ".xyz," + time_2 + "," + endValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ if (animationRegisterCache.needVelocity) {
+ code += "mul " + time_2 + "," + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sub " + time_temp + "," + animationRegisterCache.vertexOneConst + "," + time_2 + "\n";
+ code += "mul " + time_temp + "," + animationRegisterCache.vertexTwoConst + "," + time_temp + "\n";
+ code += "mul " + distance + ".xyz," + controlValue + "," + time_temp + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "mul " + distance + ".xyz," + endValue + "," + time_2 + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleBezierCurveNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleBezierCurveNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var bezierControl = param[ParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3D];
+ if (!bezierControl)
+ throw new Error("there is no " + ParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3D + " in param!");
+ var bezierEnd = param[ParticleBezierCurveNode.BEZIER_END_VECTOR3D];
+ if (!bezierEnd)
+ throw new Error("there is no " + ParticleBezierCurveNode.BEZIER_END_VECTOR3D + " in param!");
+ this._pOneData[0] = bezierControl.x;
+ this._pOneData[1] = bezierControl.y;
+ this._pOneData[2] = bezierControl.z;
+ this._pOneData[3] = bezierEnd.x;
+ this._pOneData[4] = bezierEnd.y;
+ this._pOneData[5] = bezierEnd.z;
+ };
+ /**
+ * Reference for bezier curve node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the control point position (0, 1, 2) of the curve.
+ */
+ ParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3D = "BezierControlVector3D";
+ /**
+ * Reference for bezier curve node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the end point position (0, 1, 2) of the curve.
+ */
+ ParticleBezierCurveNode.BEZIER_END_VECTOR3D = "BezierEndVector3D";
+ return ParticleBezierCurveNode;
+})(ParticleNodeBase);
+module.exports = ParticleBezierCurveNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWJlemllcmN1cnZlbm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUJlemllckN1cnZlTm9kZSIsIlBhcnRpY2xlQmV6aWVyQ3VydmVOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVCZXppZXJDdXJ2ZU5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZUJlemllckN1cnZlTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlQmV6aWVyQ3VydmVOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sd0JBQXdCLFdBQWEsaUVBQWlFLENBQUMsQ0FBQztBQUUvRyxBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQXlCQTtJQW1CckRBOzs7Ozs7T0FNR0E7SUFDSEEsU0ExQktBLHVCQUF1QkEsQ0EwQmhCQSxJQUFJQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxZQUE0QkEsRUFBRUEsUUFBd0JBO1FBQXREQyw0QkFBNEJBLEdBQTVCQSxtQkFBNEJBO1FBQUVBLHdCQUF3QkEsR0FBeEJBLGVBQXdCQTtRQUV2RkEsa0JBQU1BLHFCQUFxQkEsRUFBRUEsSUFBSUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFdENBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLHdCQUF3QkEsQ0FBQ0E7UUFFN0NBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFlBQVlBLElBQUlBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1FBQ3JEQSxJQUFJ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YW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlQmV6aWVyQ3VydmVOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZUJlemllckN1cnZlU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZUJlemllckN1cnZlU3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB1c2VkIHRvIGNvbnRyb2wgdGhlIHBvc2l0aW9uIG9mIGEgcGFydGljbGUgb3ZlciB0aW1lIGFsb25nIGEgYmV6aWVyIGN1cnZlLlxuICovXG5jbGFzcyBQYXJ0aWNsZUJlemllckN1cnZlTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUNvbnRyb2xQb2ludDpWZWN0b3IzRDtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUVuZFBvaW50OlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIGJlemllciBjdXJ2ZSBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5WZWN0b3IzRDwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29udHJvbCBwb2ludCBwb3NpdGlvbiAoMCwgMSwgMikgb2YgdGhlIGN1cnZlLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBCRVpJRVJfQ09OVFJPTF9WRUNUT1IzRDpzdHJpbmcgPSBcIkJlemllckNvbnRyb2xWZWN0b3IzRFwiO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIGJlemllciBjdXJ2ZSBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5WZWN0b3IzRDwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZW5kIHBvaW50IHBvc2l0aW9uICgwLCAxLCAyKSBvZiB0aGUgY3VydmUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIEJFWklFUl9FTkRfVkVDVE9SM0Q6c3RyaW5nID0gXCJCZXppZXJFbmRWZWN0b3IzRFwiO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlQmV6aWVyQ3VydmVOb2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gY29udHJvbFBvaW50ICAgIERlZmluZXMgdGhlIGRlZmF1bHQgY29udHJvbCBwb2ludCBvZiB0aGUgbm9kZSwgdXNlZCB3aGVuIGluIGdsb2JhbCBtb2RlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBlbmRQb2ludCAgICAgICAgRGVmaW5lcyB0aGUgZGVmYXVsdCBlbmQgcG9pbnQgb2YgdGhlIG5vZGUsIHVzZWQgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCBjb250cm9sUG9pbnQ6VmVjdG9yM0QgPSBudWxsLCBlbmRQb2ludDpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlQmV6aWVyQ3VydmVcIiwgbW9kZSwgNik7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZTtcblxuXHRcdHRoaXMuX2lDb250cm9sUG9pbnQgPSBjb250cm9sUG9pbnQgfHwgbmV3IFZlY3RvcjNEKCk7XG5cdFx0dGhpcy5faUVuZFBvaW50ID0gZW5kUG9pbnQgfHwgbmV3IFZlY3RvcjNEKCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb250cm9sVmFsdWU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gKHRoaXMuX3BNb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKT8gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUuQkVaSUVSX0NPTlRST0xfSU5ERVgsIGNvbnRyb2xWYWx1ZS5pbmRleCk7XG5cblx0XHR2YXIgZW5kVmFsdWU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gKHRoaXMuX3BNb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKT8gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUuQkVaSUVSX0VORF9JTkRFWCwgZW5kVmFsdWUuaW5kZXgpO1xuXG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdHZhciByZXZfdGltZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMCk7XG5cdFx0dmFyIHRpbWVfMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMSk7XG5cdFx0dmFyIHRpbWVfdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMik7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdHZhciB0ZW1wMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGRpc3RhbmNlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcDIucmVnTmFtZSwgdGVtcDIuaW5kZXgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHRjb2RlICs9IFwic3ViIFwiICsgcmV2X3RpbWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRpbWVfMiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhMaWZlICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleExpZmUgKyBcIlxcblwiO1xuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRpbWVfdGVtcCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhMaWZlICsgXCIsXCIgKyByZXZfdGltZSArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRpbWVfdGVtcCArIFwiLFwiICsgdGltZV90ZW1wICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFR3b0NvbnN0ICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgZGlzdGFuY2UgKyBcIi54eXosXCIgKyB0aW1lX3RlbXAgKyBcIixcIiArIGNvbnRyb2xWYWx1ZSArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXosXCIgKyBkaXN0YW5jZSArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgZGlzdGFuY2UgKyBcIi54eXosXCIgKyB0aW1lXzIgKyBcIixcIiArIGVuZFZhbHVlICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5eixcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5elxcblwiO1xuXG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFZlbG9jaXR5KSB7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGltZV8yICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleExpZmUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VHdvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHRpbWVfdGVtcCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiLFwiICsgdGltZV8yICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aW1lX3RlbXAgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VHdvQ29uc3QgKyBcIixcIiArIHRpbWVfdGVtcCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgZGlzdGFuY2UgKyBcIi54eXosXCIgKyBjb250cm9sVmFsdWUgKyBcIixcIiArIHRpbWVfdGVtcCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5eixcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgZW5kVmFsdWUgKyBcIixcIiArIHRpbWVfMiArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5eixcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5elxcblwiO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpQYXJ0aWNsZUJlemllckN1cnZlU3RhdGVcblx0e1xuXHRcdHJldHVybiA8UGFydGljbGVCZXppZXJDdXJ2ZVN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUocGFyYW06UGFydGljbGVQcm9wZXJ0aWVzKVxuXHR7XG5cdFx0dmFyIGJlemllckNvbnRyb2w6VmVjdG9yM0QgPSBwYXJhbVtQYXJ0aWNsZUJlemllckN1cnZlTm9kZS5CRVpJRVJfQ09OVFJPTF9WRUNUT1IzRF07XG5cdFx0aWYgKCFiZXppZXJDb250cm9sKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZUJlemllckN1cnZlTm9kZS5CRVpJRVJfQ09OVFJPTF9WRUNUT1IzRCArIFwiIGluIHBhcmFtIVwiKTtcblxuXHRcdHZhciBiZXppZXJFbmQ6VmVjdG9yM0QgPSBwYXJhbVtQYXJ0aWNsZUJlemllckN1cnZlTm9kZS5CRVpJRVJfRU5EX1ZFQ1RPUjNEXTtcblx0XHRpZiAoIWJlemllckVuZClcblx0XHRcdHRocm93IG5ldyBFcnJvcihcInRoZXJlIGlzIG5vIFwiICsgUGFydGljbGVCZXppZXJDdXJ2ZU5vZGUuQkVaSUVSX0VORF9WRUNUT1IzRCArIFwiIGluIHBhcmFtIVwiKTtcblxuXHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gYmV6aWVyQ29udHJvbC54O1xuXHRcdHRoaXMuX3BPbmVEYXRhWzFdID0gYmV6aWVyQ29udHJvbC55O1xuXHRcdHRoaXMuX3BPbmVEYXRhWzJdID0gYmV6aWVyQ29udHJvbC56O1xuXHRcdHRoaXMuX3BPbmVEYXRhWzNdID0gYmV6aWVyRW5kLng7XG5cdFx0dGhpcy5fcE9uZURhdGFbNF0gPSBiZXppZXJFbmQueTtcblx0XHR0aGlzLl9wT25lRGF0YVs1XSA9IGJlemllckVuZC56O1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlQmV6aWVyQ3VydmVOb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleBezierCurveNode.ts b/lib/animators/nodes/ParticleBezierCurveNode.ts
new file mode 100644
index 000000000..fffadb4ba
--- /dev/null
+++ b/lib/animators/nodes/ParticleBezierCurveNode.ts
@@ -0,0 +1,126 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleBezierCurveState = require("awayjs-renderergl/lib/animators/states/ParticleBezierCurveState");
+
+/**
+ * A particle animation node used to control the position of a particle over time along a bezier curve.
+ */
+class ParticleBezierCurveNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iControlPoint:Vector3D;
+ /** @private */
+ public _iEndPoint:Vector3D;
+
+ /**
+ * Reference for bezier curve node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the control point position (0, 1, 2) of the curve.
+ */
+ public static BEZIER_CONTROL_VECTOR3D:string = "BezierControlVector3D";
+
+ /**
+ * Reference for bezier curve node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the end point position (0, 1, 2) of the curve.
+ */
+ public static BEZIER_END_VECTOR3D:string = "BezierEndVector3D";
+
+ /**
+ * Creates a new ParticleBezierCurveNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] controlPoint Defines the default control point of the node, used when in global mode.
+ * @param [optional] endPoint Defines the default end point of the node, used when in global mode.
+ */
+ constructor(mode:number /*uint*/, controlPoint:Vector3D = null, endPoint:Vector3D = null)
+ {
+ super("ParticleBezierCurve", mode, 6);
+
+ this._pStateClass = ParticleBezierCurveState;
+
+ this._iControlPoint = controlPoint || new Vector3D();
+ this._iEndPoint = endPoint || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var controlValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleBezierCurveState.BEZIER_CONTROL_INDEX, controlValue.index);
+
+ var endValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleBezierCurveState.BEZIER_END_INDEX, endValue.index);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var rev_time:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var time_2:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var time_temp:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var distance:ShaderRegisterElement = new ShaderRegisterElement(temp2.regName, temp2.index);
+ animationRegisterCache.removeVertexTempUsage(temp);
+
+ var code:string = "";
+ code += "sub " + rev_time + "," + animationRegisterCache.vertexOneConst + "," + animationRegisterCache.vertexLife + "\n";
+ code += "mul " + time_2 + "," + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexLife + "\n";
+
+ code += "mul " + time_temp + "," + animationRegisterCache.vertexLife + "," + rev_time + "\n";
+ code += "mul " + time_temp + "," + time_temp + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "mul " + distance + ".xyz," + time_temp + "," + controlValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "mul " + distance + ".xyz," + time_2 + "," + endValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+
+ if (animationRegisterCache.needVelocity) {
+ code += "mul " + time_2 + "," + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sub " + time_temp + "," + animationRegisterCache.vertexOneConst + "," + time_2 + "\n";
+ code += "mul " + time_temp + "," + animationRegisterCache.vertexTwoConst + "," + time_temp + "\n";
+ code += "mul " + distance + ".xyz," + controlValue + "," + time_temp + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "mul " + distance + ".xyz," + endValue + "," + time_2 + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleBezierCurveState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var bezierControl:Vector3D = param[ParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3D];
+ if (!bezierControl)
+ throw new Error("there is no " + ParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3D + " in param!");
+
+ var bezierEnd:Vector3D = param[ParticleBezierCurveNode.BEZIER_END_VECTOR3D];
+ if (!bezierEnd)
+ throw new Error("there is no " + ParticleBezierCurveNode.BEZIER_END_VECTOR3D + " in param!");
+
+ this._pOneData[0] = bezierControl.x;
+ this._pOneData[1] = bezierControl.y;
+ this._pOneData[2] = bezierControl.z;
+ this._pOneData[3] = bezierEnd.x;
+ this._pOneData[4] = bezierEnd.y;
+ this._pOneData[5] = bezierEnd.z;
+ }
+}
+
+export = ParticleBezierCurveNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleBillboardNode.js b/lib/animators/nodes/ParticleBillboardNode.js
new file mode 100755
index 000000000..4042e0be2
--- /dev/null
+++ b/lib/animators/nodes/ParticleBillboardNode.js
@@ -0,0 +1,58 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleBillboardState = require("awayjs-renderergl/lib/animators/states/ParticleBillboardState");
+/**
+ * A particle animation node that controls the rotation of a particle to always face the camera.
+ */
+var ParticleBillboardNode = (function (_super) {
+ __extends(ParticleBillboardNode, _super);
+ /**
+ * Creates a new ParticleBillboardNode
+ */
+ function ParticleBillboardNode(billboardAxis) {
+ if (billboardAxis === void 0) { billboardAxis = null; }
+ _super.call(this, "ParticleBillboard", ParticlePropertiesMode.GLOBAL, 0, 4);
+ this._pStateClass = ParticleBillboardState;
+ this._iBillboardAxis = billboardAxis;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleBillboardNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var rotationMatrixRegister = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleBillboardState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ var code = "m33 " + temp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + "," + rotationMatrixRegister + "\n" + "mov " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+ var shaderRegisterElement;
+ for (var i = 0; i < animationRegisterCache.rotationRegisters.length; i++) {
+ shaderRegisterElement = animationRegisterCache.rotationRegisters[i];
+ code += "m33 " + temp + ".xyz," + shaderRegisterElement + "," + rotationMatrixRegister + "\n" + "mov " + shaderRegisterElement + ".xyz," + shaderRegisterElement + "\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleBillboardNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleBillboardNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ particleAnimationSet.hasBillboard = true;
+ };
+ return ParticleBillboardNode;
+})(ParticleNodeBase);
+module.exports = ParticleBillboardNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWJpbGxib2FyZG5vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVCaWxsYm9hcmROb2RlIiwiUGFydGljbGVCaWxsYm9hcmROb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVCaWxsYm9hcmROb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVCaWxsYm9hcmROb2RlLmdldEFuaW1hdGlvblN0YXRlIiwiUGFydGljbGVCaWxsYm9hcmROb2RlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7OztBQVNBLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxzQkFBc0IsV0FBYSwrREFBK0QsQ0FBQyxDQUFDO0FBRTNHLEFBR0E7O0dBREc7SUFDRyxxQkFBcUI7SUFBU0EsVUFBOUJBLHFCQUFxQkEsVUFBeUJBO0lBS25EQTs7T0FFR0E7SUFDSEEsU0FSS0EscUJBQXFCQSxDQVFkQSxhQUE2QkE7UUFBN0JDLDZCQUE2QkEsR0FBN0JBLG9CQUE2QkE7UUFFeENBLGtCQUFNQSxtQkFBbUJBLEVBQUVBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFaEVBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLHNCQUFzQkEsQ0FBQ0E7UUFFM0NBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLGFBQWFBLENBQUNBO0lBQ3RDQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsaURBQWlCQSxHQUF4QkEsVUFBeUJBLFlBQTZCQSxFQUFFQSxzQkFBNkNBO1FBRXBHRSxJQUFJQSxzQkFBc0JBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFDbEdBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxzQkFBc0JBLENBQUNBLFlBQVlBLEVBQUVBLHNCQUFzQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDakhBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUMvQ0Esc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO1FBQy9DQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFFL0NBLElBQUlBLElBQUlBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFFbEZBLElBQUlBLElBQUlBLEdBQVVBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLEdBQUdBLElBQUlBLEdBQ3ZIQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFFbkZBLElBQUlBLHFCQUEyQ0EsQ0FBQ0E7UUFDaERBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxzQkFBc0JBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFDMUZBLHFCQUFxQkEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3BFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxxQkFBcUJBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsR0FBR0EsSUFBSUEsR0FDM0ZBLE1BQU1BLEdBQUdBLHFCQUFxQkEsR0FBR0EsT0FBT0EsR0FBR0EscUJBQXFCQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzRUEsQ0FBQ0E7UUFFREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFREY7O09BRUdBO0lBQ0lBLGlEQUFpQkEsR0FBeEJBLFVBQXlCQSxRQUFxQkE7UUFFN0NHLE1BQU1BLENBQTBCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ2xFQSxDQUFDQTtJQUVESDs7T0FFR0E7SUFDSUEseURBQXlCQSxHQUFoQ0EsVUFBaUNBLG9CQUF5Q0E7UUFFekVJLG9CQUFvQkEsQ0FBQ0EsWUFBWUEsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBQ0ZKLDRCQUFDQTtBQUFEQSxDQTFEQSxBQTBEQ0EsRUExRG1DLGdCQUFnQixFQTBEbkQ7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlQmlsbGJvYXJkTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uU2V0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0aW9uU2V0XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVCaWxsYm9hcmRTdGF0ZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlQmlsbGJvYXJkU3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB0aGF0IGNvbnRyb2xzIHRoZSByb3RhdGlvbiBvZiBhIHBhcnRpY2xlIHRvIGFsd2F5cyBmYWNlIHRoZSBjYW1lcmEuXG4gKi9cbmNsYXNzIFBhcnRpY2xlQmlsbGJvYXJkTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUJpbGxib2FyZEF4aXM6VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVCaWxsYm9hcmROb2RlPC9jb2RlPlxuXHQgKi9cblx0Y29uc3RydWN0b3IoYmlsbGJvYXJkQXhpczpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlQmlsbGJvYXJkXCIsIFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMLCAwLCA0KTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVCaWxsYm9hcmRTdGF0ZTtcblxuXHRcdHRoaXMuX2lCaWxsYm9hcmRBeGlzID0gYmlsbGJvYXJkQXhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHJvdGF0aW9uTWF0cml4UmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVCaWxsYm9hcmRTdGF0ZS5NQVRSSVhfSU5ERVgsIHJvdGF0aW9uTWF0cml4UmVnaXN0ZXIuaW5kZXgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJtMzMgXCIgKyB0ZW1wICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLFwiICsgcm90YXRpb25NYXRyaXhSZWdpc3RlciArIFwiXFxuXCIgK1xuXHRcdFx0XHRcdFx0ICBcIm1vdiBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyB0ZW1wICsgXCJcXG5cIjtcblxuXHRcdHZhciBzaGFkZXJSZWdpc3RlckVsZW1lbnQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV07XG5cdFx0XHRjb2RlICs9IFwibTMzIFwiICsgdGVtcCArIFwiLnh5eixcIiArIHNoYWRlclJlZ2lzdGVyRWxlbWVudCArIFwiLFwiICsgcm90YXRpb25NYXRyaXhSZWdpc3RlciArIFwiXFxuXCIgK1xuXHRcdFx0XHRcdFwibW92IFwiICsgc2hhZGVyUmVnaXN0ZXJFbGVtZW50ICsgXCIueHl6LFwiICsgc2hhZGVyUmVnaXN0ZXJFbGVtZW50ICsgXCJcXG5cIjtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFuaW1hdGlvblN0YXRlKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSk6UGFydGljbGVCaWxsYm9hcmRTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZUJpbGxib2FyZFN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmcocGFydGljbGVBbmltYXRpb25TZXQ6UGFydGljbGVBbmltYXRpb25TZXQpXG5cdHtcblx0XHRwYXJ0aWNsZUFuaW1hdGlvblNldC5oYXNCaWxsYm9hcmQgPSB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlQmlsbGJvYXJkTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleBillboardNode.ts b/lib/animators/nodes/ParticleBillboardNode.ts
new file mode 100644
index 000000000..b8db77ea3
--- /dev/null
+++ b/lib/animators/nodes/ParticleBillboardNode.ts
@@ -0,0 +1,77 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleBillboardState = require("awayjs-renderergl/lib/animators/states/ParticleBillboardState");
+
+/**
+ * A particle animation node that controls the rotation of a particle to always face the camera.
+ */
+class ParticleBillboardNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iBillboardAxis:Vector3D;
+
+ /**
+ * Creates a new ParticleBillboardNode
+ */
+ constructor(billboardAxis:Vector3D = null)
+ {
+ super("ParticleBillboard", ParticlePropertiesMode.GLOBAL, 0, 4);
+
+ this._pStateClass = ParticleBillboardState;
+
+ this._iBillboardAxis = billboardAxis;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var rotationMatrixRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleBillboardState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+
+ var code:string = "m33 " + temp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + "," + rotationMatrixRegister + "\n" +
+ "mov " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+
+ var shaderRegisterElement:ShaderRegisterElement;
+ for (var i:number /*uint*/ = 0; i < animationRegisterCache.rotationRegisters.length; i++) {
+ shaderRegisterElement = animationRegisterCache.rotationRegisters[i];
+ code += "m33 " + temp + ".xyz," + shaderRegisterElement + "," + rotationMatrixRegister + "\n" +
+ "mov " + shaderRegisterElement + ".xyz," + shaderRegisterElement + "\n";
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleBillboardState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ particleAnimationSet.hasBillboard = true;
+ }
+}
+
+export = ParticleBillboardNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleColorNode.js b/lib/animators/nodes/ParticleColorNode.js
new file mode 100755
index 000000000..e667d1d3d
--- /dev/null
+++ b/lib/animators/nodes/ParticleColorNode.js
@@ -0,0 +1,178 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleColorState = require("awayjs-renderergl/lib/animators/states/ParticleColorState");
+/**
+ * A particle animation node used to control the color variation of a particle over time.
+ */
+var ParticleColorNode = (function (_super) {
+ __extends(ParticleColorNode, _super);
+ /**
+ * Creates a new ParticleColorNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesMultiplier Defines whether the node uses multiplier data in the shader for its color transformations. Defaults to true.
+ * @param [optional] usesOffset Defines whether the node uses offset data in the shader for its color transformations. Defaults to true.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of the animation independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the cycle rotation of the particle. Defaults to false.
+ * @param [optional] startColor Defines the default start color transform of the node, when in global mode.
+ * @param [optional] endColor Defines the default end color transform of the node, when in global mode.
+ * @param [optional] cycleDuration Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ function ParticleColorNode(mode /*uint*/, usesMultiplier, usesOffset, usesCycle, usesPhase, startColor, endColor, cycleDuration, cyclePhase) {
+ if (usesMultiplier === void 0) { usesMultiplier = true; }
+ if (usesOffset === void 0) { usesOffset = true; }
+ if (usesCycle === void 0) { usesCycle = false; }
+ if (usesPhase === void 0) { usesPhase = false; }
+ if (startColor === void 0) { startColor = null; }
+ if (endColor === void 0) { endColor = null; }
+ if (cycleDuration === void 0) { cycleDuration = 1; }
+ if (cyclePhase === void 0) { cyclePhase = 0; }
+ _super.call(this, "ParticleColor", mode, (usesMultiplier && usesOffset) ? 16 : 8, ParticleAnimationSet.COLOR_PRIORITY);
+ this._pStateClass = ParticleColorState;
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+ this._iStartColor = startColor || new ColorTransform();
+ this._iEndColor = endColor || new ColorTransform();
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleColorNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ if (this._iUsesCycle) {
+ var cycleConst = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.CYCLE_INDEX, cycleConst.index);
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var sin = animationRegisterCache.getFreeVertexSingleTemp();
+ animationRegisterCache.removeVertexTempUsage(temp);
+ code += "mul " + sin + "," + animationRegisterCache.vertexTime + "," + cycleConst + ".x\n";
+ if (this._iUsesPhase)
+ code += "add " + sin + "," + sin + "," + cycleConst + ".y\n";
+ code += "sin " + sin + "," + sin + "\n";
+ }
+ if (this._iUsesMultiplier) {
+ var startMultiplierValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ var deltaMultiplierValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.START_MULTIPLIER_INDEX, startMultiplierValue.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.DELTA_MULTIPLIER_INDEX, deltaMultiplierValue.index);
+ code += "mul " + temp + "," + deltaMultiplierValue + "," + (this._iUsesCycle ? sin : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + temp + "," + startMultiplierValue + "\n";
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + temp + "," + animationRegisterCache.colorMulTarget + "\n";
+ }
+ if (this._iUsesOffset) {
+ var startOffsetValue = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC) ? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+ var deltaOffsetValue = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC) ? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.START_OFFSET_INDEX, startOffsetValue.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.DELTA_OFFSET_INDEX, deltaOffsetValue.index);
+ code += "mul " + temp + "," + deltaOffsetValue + "," + (this._iUsesCycle ? sin : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + temp + "," + startOffsetValue + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + temp + "," + animationRegisterCache.colorAddTarget + "\n";
+ }
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleColorNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleColorNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleColorNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var startColor = param[ParticleColorNode.COLOR_START_COLORTRANSFORM];
+ if (!startColor)
+ throw (new Error("there is no " + ParticleColorNode.COLOR_START_COLORTRANSFORM + " in param!"));
+ var endColor = param[ParticleColorNode.COLOR_END_COLORTRANSFORM];
+ if (!endColor)
+ throw (new Error("there is no " + ParticleColorNode.COLOR_END_COLORTRANSFORM + " in param!"));
+ var i = 0;
+ if (!this._iUsesCycle) {
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = startColor.redMultiplier;
+ this._pOneData[i++] = startColor.greenMultiplier;
+ this._pOneData[i++] = startColor.blueMultiplier;
+ this._pOneData[i++] = startColor.alphaMultiplier;
+ this._pOneData[i++] = endColor.redMultiplier - startColor.redMultiplier;
+ this._pOneData[i++] = endColor.greenMultiplier - startColor.greenMultiplier;
+ this._pOneData[i++] = endColor.blueMultiplier - startColor.blueMultiplier;
+ this._pOneData[i++] = endColor.alphaMultiplier - startColor.alphaMultiplier;
+ }
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = startColor.redOffset / 255;
+ this._pOneData[i++] = startColor.greenOffset / 255;
+ this._pOneData[i++] = startColor.blueOffset / 255;
+ this._pOneData[i++] = startColor.alphaOffset / 255;
+ this._pOneData[i++] = (endColor.redOffset - startColor.redOffset) / 255;
+ this._pOneData[i++] = (endColor.greenOffset - startColor.greenOffset) / 255;
+ this._pOneData[i++] = (endColor.blueOffset - startColor.blueOffset) / 255;
+ this._pOneData[i++] = (endColor.alphaOffset - startColor.alphaOffset) / 255;
+ }
+ }
+ else {
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = (startColor.redMultiplier + endColor.redMultiplier) / 2;
+ this._pOneData[i++] = (startColor.greenMultiplier + endColor.greenMultiplier) / 2;
+ this._pOneData[i++] = (startColor.blueMultiplier + endColor.blueMultiplier) / 2;
+ this._pOneData[i++] = (startColor.alphaMultiplier + endColor.alphaMultiplier) / 2;
+ this._pOneData[i++] = (startColor.redMultiplier - endColor.redMultiplier) / 2;
+ this._pOneData[i++] = (startColor.greenMultiplier - endColor.greenMultiplier) / 2;
+ this._pOneData[i++] = (startColor.blueMultiplier - endColor.blueMultiplier) / 2;
+ this._pOneData[i++] = (startColor.alphaMultiplier - endColor.alphaMultiplier) / 2;
+ }
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = (startColor.redOffset + endColor.redOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.greenOffset + endColor.greenOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.blueOffset + endColor.blueOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.alphaOffset + endColor.alphaOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.redOffset - endColor.redOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.greenOffset - endColor.greenOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.blueOffset - endColor.blueOffset) / (255 * 2);
+ this._pOneData[i++] = (startColor.alphaOffset - endColor.alphaOffset) / (255 * 2);
+ }
+ }
+ };
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the start color transform applied to the particle.
+ */
+ ParticleColorNode.COLOR_START_COLORTRANSFORM = "ColorStartColorTransform";
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the end color transform applied to the particle.
+ */
+ ParticleColorNode.COLOR_END_COLORTRANSFORM = "ColorEndColorTransform";
+ return ParticleColorNode;
+})(ParticleNodeBase);
+module.exports = ParticleColorNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWNvbG9ybm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUNvbG9yTm9kZSIsIlBhcnRpY2xlQ29sb3JOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVDb2xvck5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZUNvbG9yTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlQ29sb3JOb2RlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciLCJQYXJ0aWNsZUNvbG9yTm9kZS5faUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLGNBQWMsV0FBZSwwQ0FBMEMsQ0FBQyxDQUFDO0FBUWhGLElBQU8sb0JBQW9CLFdBQWMsc0RBQXNELENBQUMsQ0FBQztBQUVqRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csaUJBQWlCO0lBQVNBLFVBQTFCQSxpQkFBaUJBLFVBQXlCQTtJQWdDL0NBOzs7Ozs7Ozs7Ozs7T0FZR0E7SUFDSEEsU0E3Q0tBLGlCQUFpQkEsQ0E2Q1ZBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLGNBQTZCQSxFQUFFQSxVQUF5QkEsRUFBRUEsU0FBeUJBLEVBQUVBLFNBQXlCQSxFQUFFQSxVQUFnQ0EsRUFBRUEsUUFBOEJBLEVBQUVBLGFBQXdCQSxFQUFFQSxVQUFxQkE7UUFBak9DLDhCQUE2QkEsR0FBN0JBLHFCQUE2QkE7UUFBRUEsMEJBQXlCQSxHQUF6QkEsaUJBQXlCQTtRQUFFQSx5QkFBeUJBLEdBQXpCQSxpQkFBeUJBO1FBQUVBLHlCQUF5QkEsR0FBekJBLGlCQUF5QkE7UUFBRUEsMEJBQWdDQSxHQUFoQ0EsaUJBQWdDQTtR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QUFDQSxjQUFjQSxDQUFDQTtnQkFDMUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFFBQVFBLENBQUNBLGVBQWVBLEdBQUdBLFVBQVVBLENBQUNBLGVBQWVBLENBQUNBO1lBQzdFQSxDQUFDQTtZQUVEQSxBQUNBQSxRQURRQTtZQUNSQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDdkJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFVBQVVBLENBQUNBLFNBQVNBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUMvQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsVUFBVUEsQ0FBQ0EsV0FBV0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQ2pEQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxVQUFVQSxDQUFDQSxVQUFVQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDaERBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFVBQVVBLENBQUNBLFdBQVdBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUNqREEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsU0FBU0EsR0FBR0EsVUFBVUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQ3RFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxRQUFRQSxDQUFDQSxXQUFXQSxHQUFHQSxVQUFVQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDMUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFFBQVFBLENBQUNBLFVBQVVBLEdBQUdBLFVBQVVBLENBQUNBLFVBQVVBLENBQUNBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUN4RUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsV0FBV0EsR0FBR0EsVUFBVUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7WUFDM0VBLENBQUNBO1FBQ0ZBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLEFBQ0FBLFlBRFlBO1lBQ1pBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzNCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxVQUFVQSxDQUFDQSxhQUFhQSxHQUFHQSxRQUFRQSxDQUFDQSxhQUFhQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQTtnQkFDNUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLGVBQWVBLEdBQUdBLFFBQVFBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLENBQUNBLENBQUNBO2dCQUNoRkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsY0FBY0EsR0FBR0EsUUFBUUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzlFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxVQUFVQSxDQUFDQSxlQUFlQSxHQUFHQSxRQUFRQSxDQUFDQSxlQUFlQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQTtnQkFDaEZBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLGFBQWFBLEdBQUdBLFFBQVFBLENBQUNBLGFBQWFBLENBQUNBLEdBQUNBLENBQUNBLENBQUNBO2dCQUM1RUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsZUFBZUEsR0FBR0EsUUFBUUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2hGQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxVQUFVQSxDQUFDQSxjQUFjQSxHQUFHQSxRQUFRQSxDQUFDQSxjQUFjQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQTtnQkFDOUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLGVBQWVBLEdBQUdBLFFBQVFBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLENBQUNBLENBQUNBO1lBQ2pGQSxDQUFDQTtZQUVEQSxBQUNBQSxRQURRQTtZQUNSQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDdkJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLFNBQVNBLEdBQUdBLFFBQVFBLENBQUNBLFNBQVNBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUMxRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsV0FBV0EsR0FBR0EsUUFBUUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzlFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxVQUFVQSxDQUFDQSxVQUFVQSxHQUFHQSxRQUFRQSxDQUFDQSxVQUFVQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDNUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLFdBQVdBLEdBQUdBLFFBQVFBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUM5RUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsU0FBU0EsR0FBR0EsUUFBUUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxVQUFVQSxDQUFDQSxXQUFXQSxHQUFHQSxRQUFRQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDOUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLFVBQVVBLENBQUNBLFVBQVVBLEdBQUdBLFFBQVFBLENBQUNBLFVBQVVBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUM1RUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsV0FBV0EsR0FBR0EsUUFBUUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0VBLENBQUNBO1FBQ0ZBLENBQUNBO0lBRUZBLENBQUNBO0lBbkxETDs7O09BR0dBO0lBQ1dBLDRDQUEwQkEsR0FBVUEsMEJBQTBCQSxDQUFDQTtJQUU3RUE7OztPQUdHQTtJQUNXQSwwQ0FBd0JBLEdBQVVBLHdCQUF3QkEsQ0FBQ0E7SUEwSzFFQSx3QkFBQ0E7QUFBREEsQ0F4TUEsQUF3TUNBLEVBeE0rQixnQkFBZ0IsRUF3TS9DO0FBRUQsQUFBMkIsaUJBQWxCLGlCQUFpQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZUNvbG9yTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDb2xvclRyYW5zZm9ybVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL0NvbG9yVHJhbnNmb3JtXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZUNvbG9yU3RhdGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlQ29sb3JTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gY29udHJvbCB0aGUgY29sb3IgdmFyaWF0aW9uIG9mIGEgcGFydGljbGUgb3ZlciB0aW1lLlxuICovXG5jbGFzcyBQYXJ0aWNsZUNvbG9yTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0Ly9kZWZhdWx0IHZhbHVlcyB1c2VkIHdoZW4gY3JlYXRpbmcgc3RhdGVzXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc09mZnNldDpib29sZWFuO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc0N5Y2xlOmJvb2xlYW47XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzUGhhc2U6Ym9vbGVhbjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVN0YXJ0Q29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lFbmRDb2xvcjpDb2xvclRyYW5zZm9ybTtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUN5Y2xlRHVyYXRpb246bnVtYmVyO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pQ3ljbGVQaGFzZTpudW1iZXI7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3IgY29sb3Igbm9kZSBwcm9wZXJ0aWVzIG9uIGEgc2luZ2xlIHBhcnRpY2xlICh3aGVuIGluIGxvY2FsIHByb3BlcnR5IG1vZGUpLlxuXHQgKiBFeHBlY3RzIGEgPGNvZGU+Q29sb3JUcmFuc2Zvcm08L2NvZGU+IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHN0YXJ0IGNvbG9yIHRyYW5zZm9ybSBhcHBsaWVkIHRvIHRoZSBwYXJ0aWNsZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgQ09MT1JfU1RBUlRfQ09MT1JUUkFOU0ZPUk06c3RyaW5nID0gXCJDb2xvclN0YXJ0Q29sb3JUcmFuc2Zvcm1cIjtcblxuXHQvKipcblx0ICogUmVmZXJlbmNlIGZvciBjb2xvciBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5Db2xvclRyYW5zZm9ybTwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZW5kIGNvbG9yIHRyYW5zZm9ybSBhcHBsaWVkIHRvIHRoZSBwYXJ0aWNsZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgQ09MT1JfRU5EX0NPTE9SVFJBTlNGT1JNOnN0cmluZyA9IFwiQ29sb3JFbmRDb2xvclRyYW5zZm9ybVwiO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlQ29sb3JOb2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdXNlc011bHRpcGxpZXIgIERlZmluZXMgd2hldGhlciB0aGUgbm9kZSB1c2VzIG11bHRpcGxpZXIgZGF0YSBpbiB0aGUgc2hhZGVyIGZvciBpdHMgY29sb3IgdHJhbnNmb3JtYXRpb25zLiBEZWZhdWx0cyB0byB0cnVlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzT2Zmc2V0ICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBub2RlIHVzZXMgb2Zmc2V0IGRhdGEgaW4gdGhlIHNoYWRlciBmb3IgaXRzIGNvbG9yIHRyYW5zZm9ybWF0aW9ucy4gRGVmYXVsdHMgdG8gdHJ1ZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdXNlc0N5Y2xlICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbm9kZSB1c2VzIHRoZSA8Y29kZT5jeWNsZUR1cmF0aW9uPC9jb2RlPiBwcm9wZXJ0eSBpbiB0aGUgc2hhZGVyIHRvIGNhbGN1bGF0ZSB0aGUgcGVyaW9kIG9mIHRoZSBhbmltYXRpb24gaW5kZXBlbmRlbnQgb2YgcGFydGljbGUgZHVyYXRpb24uIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzUGhhc2UgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBub2RlIHVzZXMgdGhlIDxjb2RlPmN5Y2xlUGhhc2U8L2NvZGU+IHByb3BlcnR5IGluIHRoZSBzaGFkZXIgdG8gY2FsY3VsYXRlIGEgc3RhcnRpbmcgb2Zmc2V0IHRvIHRoZSBjeWNsZSByb3RhdGlvbiBvZiB0aGUgcGFydGljbGUuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBzdGFydENvbG9yICAgICAgRGVmaW5lcyB0aGUgZGVmYXVsdCBzdGFydCBjb2xvciB0cmFuc2Zvcm0gb2YgdGhlIG5vZGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIGVuZENvbG9yICAgICAgICBEZWZpbmVzIHRoZSBkZWZhdWx0IGVuZCBjb2xvciB0cmFuc2Zvcm0gb2YgdGhlIG5vZGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIGN5Y2xlRHVyYXRpb24gICBEZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluIHNlY29uZHMsIHVzZWQgYXMgYSBwZXJpb2QgaW5kZXBlbmRlbnQgb2YgcGFydGljbGUgZHVyYXRpb24gd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gY3ljbGVQaGFzZSAgICAgIERlZmluZXMgdGhlIHBoYXNlIG9mIHRoZSBjeWNsZSBpbiBkZWdyZWVzLCB1c2VkIGFzIHRoZSBzdGFydGluZyBvZmZzZXQgb2YgdGhlIGN5Y2xlIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDAuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihtb2RlOm51bWJlciAvKnVpbnQqLywgdXNlc011bHRpcGxpZXI6Ym9vbGVhbiA9IHRydWUsIHVzZXNPZmZzZXQ6Ym9vbGVhbiA9IHRydWUsIHVzZXNDeWNsZTpib29sZWFuID0gZmFsc2UsIHVzZXNQaGFzZTpib29sZWFuID0gZmFsc2UsIHN0YXJ0Q29sb3I6Q29sb3JUcmFuc2Zvcm0gPSBudWxsLCBlbmRDb2xvcjpDb2xvclRyYW5zZm9ybSA9IG51bGwsIGN5Y2xlRHVyYXRpb246bnVtYmVyID0gMSwgY3ljbGVQaGFzZTpudW1iZXIgPSAwKVxuXHR7XG5cdFx0c3VwZXIoXCJQYXJ0aWNsZUNvbG9yXCIsIG1vZGUsICh1c2VzTXVsdGlwbGllciAmJiB1c2VzT2Zmc2V0KT8gMTYgOiA4LCBQYXJ0aWNsZUFuaW1hdGlvblNldC5DT0xPUl9QUklPUklUWSk7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFBhcnRpY2xlQ29sb3JTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzTXVsdGlwbGllciA9IHVzZXNNdWx0aXBsaWVyO1xuXHRcdHRoaXMuX2lVc2VzT2Zmc2V0ID0gdXNlc09mZnNldDtcblx0XHR0aGlzLl9pVXNlc0N5Y2xlID0gdXNlc0N5Y2xlO1xuXHRcdHRoaXMuX2lVc2VzUGhhc2UgPSB1c2VzUGhhc2U7XG5cblx0XHR0aGlzLl9pU3RhcnRDb2xvciA9IHN0YXJ0Q29sb3IgfHwgbmV3IENvbG9yVHJhbnNmb3JtKCk7XG5cdFx0dGhpcy5faUVuZENvbG9yID0gZW5kQ29sb3IgfHwgbmV3IENvbG9yVHJhbnNmb3JtKCk7XG5cdFx0dGhpcy5faUN5Y2xlRHVyYXRpb24gPSBjeWNsZUR1cmF0aW9uO1xuXHRcdHRoaXMuX2lDeWNsZVBoYXNlID0gY3ljbGVQaGFzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5uZWVkRnJhZ21lbnRBbmltYXRpb24pIHtcblx0XHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblxuXHRcdFx0aWYgKHRoaXMuX2lVc2VzQ3ljbGUpIHtcblx0XHRcdFx0dmFyIGN5Y2xlQ29uc3Q6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlQ29sb3JTdGF0ZS5DWUNMRV9JTkRFWCwgY3ljbGVDb25zdC5pbmRleCk7XG5cblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdFx0XHR2YXIgc2luOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFNpbmdsZVRlbXAoKTtcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcCk7XG5cblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyBjeWNsZUNvbnN0ICsgXCIueFxcblwiO1xuXG5cdFx0XHRcdGlmICh0aGlzLl9pVXNlc1BoYXNlKVxuXHRcdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBzaW4gKyBcIixcIiArIHNpbiArIFwiLFwiICsgY3ljbGVDb25zdCArIFwiLnlcXG5cIjtcblxuXHRcdFx0XHRjb2RlICs9IFwic2luIFwiICsgc2luICsgXCIsXCIgKyBzaW4gKyBcIlxcblwiO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5faVVzZXNNdWx0aXBsaWVyKSB7XG5cdFx0XHRcdHZhciBzdGFydE11bHRpcGxpZXJWYWx1ZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0XHRcdHZhciBkZWx0YU11bHRpcGxpZXJWYWx1ZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlQ29sb3JTdGF0ZS5TVEFSVF9NVUxUSVBMSUVSX0lOREVYLCBzdGFydE11bHRpcGxpZXJWYWx1ZS5pbmRleCk7XG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZUNvbG9yU3RhdGUuREVMVEFfTVVMVElQTElFUl9JTkRFWCwgZGVsdGFNdWx0aXBsaWVyVmFsdWUuaW5kZXgpO1xuXG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ZW1wICsgXCIsXCIgKyBkZWx0YU11bHRpcGxpZXJWYWx1ZSArIFwiLFwiICsgKHRoaXMuX2lVc2VzQ3ljbGU/IHNpbiA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSkgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdGVtcCArIFwiLFwiICsgdGVtcCArIFwiLFwiICsgc3RhcnRNdWx0aXBsaWVyVmFsdWUgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5jb2xvck11bFRhcmdldCArIFwiLFwiICsgdGVtcCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5jb2xvck11bFRhcmdldCArIFwiXFxuXCI7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9pVXNlc09mZnNldCkge1xuXHRcdFx0XHR2YXIgc3RhcnRPZmZzZXRWYWx1ZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRcdHZhciBkZWx0YU9mZnNldFZhbHVlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQyk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblxuXHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVDb2xvclN0YXRlLlNUQVJUX09GRlNFVF9JTkRFWCwgc3RhcnRPZmZzZXRWYWx1ZS5pbmRleCk7XG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZUNvbG9yU3RhdGUuREVMVEFfT0ZGU0VUX0lOREVYLCBkZWx0YU9mZnNldFZhbHVlLmluZGV4KTtcblxuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcCArIFwiLFwiICsgZGVsdGFPZmZzZXRWYWx1ZSArIFwiLFwiICsgKHRoaXMuX2lVc2VzQ3ljbGU/IHNpbiA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSkgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdGVtcCArIFwiLFwiICsgdGVtcCArIFwiLFwiICsgc3RhcnRPZmZzZXRWYWx1ZSArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yQWRkVGFyZ2V0ICsgXCIsXCIgKyB0ZW1wICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yQWRkVGFyZ2V0ICsgXCJcXG5cIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFuaW1hdGlvblN0YXRlKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSk6UGFydGljbGVDb2xvclN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFBhcnRpY2xlQ29sb3JTdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVByb2Nlc3NBbmltYXRpb25TZXR0aW5nKHBhcnRpY2xlQW5pbWF0aW9uU2V0OlBhcnRpY2xlQW5pbWF0aW9uU2V0KVxuXHR7XG5cdFx0aWYgKHRoaXMuX2lVc2VzTXVsdGlwbGllcilcblx0XHRcdHBhcnRpY2xlQW5pbWF0aW9uU2V0Lmhhc0NvbG9yTXVsTm9kZSA9IHRydWU7XG5cdFx0aWYgKHRoaXMuX2lVc2VzT2Zmc2V0KVxuXHRcdFx0cGFydGljbGVBbmltYXRpb25TZXQuaGFzQ29sb3JBZGROb2RlID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUocGFyYW06UGFydGljbGVQcm9wZXJ0aWVzKVxuXHR7XG5cdFx0dmFyIHN0YXJ0Q29sb3I6Q29sb3JUcmFuc2Zvcm0gPSBwYXJhbVtQYXJ0aWNsZUNvbG9yTm9kZS5DT0xPUl9TVEFSVF9DT0xPUlRSQU5TRk9STV07XG5cdFx0aWYgKCFzdGFydENvbG9yKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZUNvbG9yTm9kZS5DT0xPUl9TVEFSVF9DT0xPUlRSQU5TRk9STSArIFwiIGluIHBhcmFtIVwiKSk7XG5cblx0XHR2YXIgZW5kQ29sb3I6Q29sb3JUcmFuc2Zvcm0gPSBwYXJhbVtQYXJ0aWNsZUNvbG9yTm9kZS5DT0xPUl9FTkRfQ09MT1JUUkFOU0ZPUk1dO1xuXHRcdGlmICghZW5kQ29sb3IpXG5cdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJ0aGVyZSBpcyBubyBcIiArIFBhcnRpY2xlQ29sb3JOb2RlLkNPTE9SX0VORF9DT0xPUlRSQU5TRk9STSArIFwiIGluIHBhcmFtIVwiKSk7XG5cblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdFx0aWYgKCF0aGlzLl9pVXNlc0N5Y2xlKSB7XG5cdFx0XHQvL211bHRpcGxpZXJcblx0XHRcdGlmICh0aGlzLl9pVXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IucmVkTXVsdGlwbGllcjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IuZ3JlZW5NdWx0aXBsaWVyO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gc3RhcnRDb2xvci5ibHVlTXVsdGlwbGllcjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IuYWxwaGFNdWx0aXBsaWVyO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gZW5kQ29sb3IucmVkTXVsdGlwbGllciAtIHN0YXJ0Q29sb3IucmVkTXVsdGlwbGllcjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IGVuZENvbG9yLmdyZWVuTXVsdGlwbGllciAtIHN0YXJ0Q29sb3IuZ3JlZW5NdWx0aXBsaWVyO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gZW5kQ29sb3IuYmx1ZU11bHRpcGxpZXIgLSBzdGFydENvbG9yLmJsdWVNdWx0aXBsaWVyO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gZW5kQ29sb3IuYWxwaGFNdWx0aXBsaWVyIC0gc3RhcnRDb2xvci5hbHBoYU11bHRpcGxpZXI7XG5cdFx0XHR9XG5cblx0XHRcdC8vb2Zmc2V0XG5cdFx0XHRpZiAodGhpcy5faVVzZXNPZmZzZXQpIHtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IucmVkT2Zmc2V0LzI1NTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IuZ3JlZW5PZmZzZXQvMjU1O1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gc3RhcnRDb2xvci5ibHVlT2Zmc2V0LzI1NTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IHN0YXJ0Q29sb3IuYWxwaGFPZmZzZXQvMjU1O1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKGVuZENvbG9yLnJlZE9mZnNldCAtIHN0YXJ0Q29sb3IucmVkT2Zmc2V0KS8yNTU7XG5cdFx0XHRcdHRoaXMuX3BPbmVEYXRhW2krK10gPSAoZW5kQ29sb3IuZ3JlZW5PZmZzZXQgLSBzdGFydENvbG9yLmdyZWVuT2Zmc2V0KS8yNTU7XG5cdFx0XHRcdHRoaXMuX3BPbmVEYXRhW2krK10gPSAoZW5kQ29sb3IuYmx1ZU9mZnNldCAtIHN0YXJ0Q29sb3IuYmx1ZU9mZnNldCkvMjU1O1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKGVuZENvbG9yLmFscGhhT2Zmc2V0IC0gc3RhcnRDb2xvci5hbHBoYU9mZnNldCkvMjU1O1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL211bHRpcGxpZXJcblx0XHRcdGlmICh0aGlzLl9pVXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLnJlZE11bHRpcGxpZXIgKyBlbmRDb2xvci5yZWRNdWx0aXBsaWVyKS8yO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuZ3JlZW5NdWx0aXBsaWVyICsgZW5kQ29sb3IuZ3JlZW5NdWx0aXBsaWVyKS8yO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIgKyBlbmRDb2xvci5ibHVlTXVsdGlwbGllcikvMjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLmFscGhhTXVsdGlwbGllciArIGVuZENvbG9yLmFscGhhTXVsdGlwbGllcikvMjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLnJlZE11bHRpcGxpZXIgLSBlbmRDb2xvci5yZWRNdWx0aXBsaWVyKS8yO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuZ3JlZW5NdWx0aXBsaWVyIC0gZW5kQ29sb3IuZ3JlZW5NdWx0aXBsaWVyKS8yO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIgLSBlbmRDb2xvci5ibHVlTXVsdGlwbGllcikvMjtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLmFscGhhTXVsdGlwbGllciAtIGVuZENvbG9yLmFscGhhTXVsdGlwbGllcikvMjtcblx0XHRcdH1cblxuXHRcdFx0Ly9vZmZzZXRcblx0XHRcdGlmICh0aGlzLl9pVXNlc09mZnNldCkge1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IucmVkT2Zmc2V0ICsgZW5kQ29sb3IucmVkT2Zmc2V0KS8oMjU1KjIpO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuZ3JlZW5PZmZzZXQgKyBlbmRDb2xvci5ncmVlbk9mZnNldCkvKDI1NSoyKTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLmJsdWVPZmZzZXQgKyBlbmRDb2xvci5ibHVlT2Zmc2V0KS8oMjU1KjIpO1xuXHRcdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gKHN0YXJ0Q29sb3IuYWxwaGFPZmZzZXQgKyBlbmRDb2xvci5hbHBoYU9mZnNldCkvKDI1NSoyKTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLnJlZE9mZnNldCAtIGVuZENvbG9yLnJlZE9mZnNldCkvKDI1NSoyKTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLmdyZWVuT2Zmc2V0IC0gZW5kQ29sb3IuZ3JlZW5PZmZzZXQpLygyNTUqMik7XG5cdFx0XHRcdHRoaXMuX3BPbmVEYXRhW2krK10gPSAoc3RhcnRDb2xvci5ibHVlT2Zmc2V0IC0gZW5kQ29sb3IuYmx1ZU9mZnNldCkvKDI1NSoyKTtcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IChzdGFydENvbG9yLmFscGhhT2Zmc2V0IC0gZW5kQ29sb3IuYWxwaGFPZmZzZXQpLygyNTUqMik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVDb2xvck5vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleColorNode.ts b/lib/animators/nodes/ParticleColorNode.ts
new file mode 100644
index 000000000..eb792beec
--- /dev/null
+++ b/lib/animators/nodes/ParticleColorNode.ts
@@ -0,0 +1,220 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleColorState = require("awayjs-renderergl/lib/animators/states/ParticleColorState");
+
+/**
+ * A particle animation node used to control the color variation of a particle over time.
+ */
+class ParticleColorNode extends ParticleNodeBase
+{
+ //default values used when creating states
+ /** @private */
+ public _iUsesMultiplier:boolean;
+ /** @private */
+ public _iUsesOffset:boolean;
+ /** @private */
+ public _iUsesCycle:boolean;
+ /** @private */
+ public _iUsesPhase:boolean;
+ /** @private */
+ public _iStartColor:ColorTransform;
+ /** @private */
+ public _iEndColor:ColorTransform;
+ /** @private */
+ public _iCycleDuration:number;
+ /** @private */
+ public _iCyclePhase:number;
+
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the start color transform applied to the particle.
+ */
+ public static COLOR_START_COLORTRANSFORM:string = "ColorStartColorTransform";
+
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the end color transform applied to the particle.
+ */
+ public static COLOR_END_COLORTRANSFORM:string = "ColorEndColorTransform";
+
+ /**
+ * Creates a new ParticleColorNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesMultiplier Defines whether the node uses multiplier data in the shader for its color transformations. Defaults to true.
+ * @param [optional] usesOffset Defines whether the node uses offset data in the shader for its color transformations. Defaults to true.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of the animation independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the cycle rotation of the particle. Defaults to false.
+ * @param [optional] startColor Defines the default start color transform of the node, when in global mode.
+ * @param [optional] endColor Defines the default end color transform of the node, when in global mode.
+ * @param [optional] cycleDuration Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ constructor(mode:number /*uint*/, usesMultiplier:boolean = true, usesOffset:boolean = true, usesCycle:boolean = false, usesPhase:boolean = false, startColor:ColorTransform = null, endColor:ColorTransform = null, cycleDuration:number = 1, cyclePhase:number = 0)
+ {
+ super("ParticleColor", mode, (usesMultiplier && usesOffset)? 16 : 8, ParticleAnimationSet.COLOR_PRIORITY);
+
+ this._pStateClass = ParticleColorState;
+
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+
+ this._iStartColor = startColor || new ColorTransform();
+ this._iEndColor = endColor || new ColorTransform();
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+
+ if (this._iUsesCycle) {
+ var cycleConst:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.CYCLE_INDEX, cycleConst.index);
+
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var sin:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+ animationRegisterCache.removeVertexTempUsage(temp);
+
+ code += "mul " + sin + "," + animationRegisterCache.vertexTime + "," + cycleConst + ".x\n";
+
+ if (this._iUsesPhase)
+ code += "add " + sin + "," + sin + "," + cycleConst + ".y\n";
+
+ code += "sin " + sin + "," + sin + "\n";
+ }
+
+ if (this._iUsesMultiplier) {
+ var startMultiplierValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ var deltaMultiplierValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.START_MULTIPLIER_INDEX, startMultiplierValue.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.DELTA_MULTIPLIER_INDEX, deltaMultiplierValue.index);
+
+ code += "mul " + temp + "," + deltaMultiplierValue + "," + (this._iUsesCycle? sin : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + temp + "," + startMultiplierValue + "\n";
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + temp + "," + animationRegisterCache.colorMulTarget + "\n";
+ }
+
+ if (this._iUsesOffset) {
+ var startOffsetValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC)? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+ var deltaOffsetValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC)? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.START_OFFSET_INDEX, startOffsetValue.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleColorState.DELTA_OFFSET_INDEX, deltaOffsetValue.index);
+
+ code += "mul " + temp + "," + deltaOffsetValue + "," + (this._iUsesCycle? sin : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + temp + "," + startOffsetValue + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + temp + "," + animationRegisterCache.colorAddTarget + "\n";
+ }
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleColorState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var startColor:ColorTransform = param[ParticleColorNode.COLOR_START_COLORTRANSFORM];
+ if (!startColor)
+ throw(new Error("there is no " + ParticleColorNode.COLOR_START_COLORTRANSFORM + " in param!"));
+
+ var endColor:ColorTransform = param[ParticleColorNode.COLOR_END_COLORTRANSFORM];
+ if (!endColor)
+ throw(new Error("there is no " + ParticleColorNode.COLOR_END_COLORTRANSFORM + " in param!"));
+
+ var i:number /*uint*/ = 0;
+
+ if (!this._iUsesCycle) {
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = startColor.redMultiplier;
+ this._pOneData[i++] = startColor.greenMultiplier;
+ this._pOneData[i++] = startColor.blueMultiplier;
+ this._pOneData[i++] = startColor.alphaMultiplier;
+ this._pOneData[i++] = endColor.redMultiplier - startColor.redMultiplier;
+ this._pOneData[i++] = endColor.greenMultiplier - startColor.greenMultiplier;
+ this._pOneData[i++] = endColor.blueMultiplier - startColor.blueMultiplier;
+ this._pOneData[i++] = endColor.alphaMultiplier - startColor.alphaMultiplier;
+ }
+
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = startColor.redOffset/255;
+ this._pOneData[i++] = startColor.greenOffset/255;
+ this._pOneData[i++] = startColor.blueOffset/255;
+ this._pOneData[i++] = startColor.alphaOffset/255;
+ this._pOneData[i++] = (endColor.redOffset - startColor.redOffset)/255;
+ this._pOneData[i++] = (endColor.greenOffset - startColor.greenOffset)/255;
+ this._pOneData[i++] = (endColor.blueOffset - startColor.blueOffset)/255;
+ this._pOneData[i++] = (endColor.alphaOffset - startColor.alphaOffset)/255;
+ }
+ } else {
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = (startColor.redMultiplier + endColor.redMultiplier)/2;
+ this._pOneData[i++] = (startColor.greenMultiplier + endColor.greenMultiplier)/2;
+ this._pOneData[i++] = (startColor.blueMultiplier + endColor.blueMultiplier)/2;
+ this._pOneData[i++] = (startColor.alphaMultiplier + endColor.alphaMultiplier)/2;
+ this._pOneData[i++] = (startColor.redMultiplier - endColor.redMultiplier)/2;
+ this._pOneData[i++] = (startColor.greenMultiplier - endColor.greenMultiplier)/2;
+ this._pOneData[i++] = (startColor.blueMultiplier - endColor.blueMultiplier)/2;
+ this._pOneData[i++] = (startColor.alphaMultiplier - endColor.alphaMultiplier)/2;
+ }
+
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = (startColor.redOffset + endColor.redOffset)/(255*2);
+ this._pOneData[i++] = (startColor.greenOffset + endColor.greenOffset)/(255*2);
+ this._pOneData[i++] = (startColor.blueOffset + endColor.blueOffset)/(255*2);
+ this._pOneData[i++] = (startColor.alphaOffset + endColor.alphaOffset)/(255*2);
+ this._pOneData[i++] = (startColor.redOffset - endColor.redOffset)/(255*2);
+ this._pOneData[i++] = (startColor.greenOffset - endColor.greenOffset)/(255*2);
+ this._pOneData[i++] = (startColor.blueOffset - endColor.blueOffset)/(255*2);
+ this._pOneData[i++] = (startColor.alphaOffset - endColor.alphaOffset)/(255*2);
+ }
+ }
+
+ }
+}
+
+export = ParticleColorNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleFollowNode.js b/lib/animators/nodes/ParticleFollowNode.js
new file mode 100755
index 000000000..ad964cac1
--- /dev/null
+++ b/lib/animators/nodes/ParticleFollowNode.js
@@ -0,0 +1,127 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleFollowState = require("awayjs-renderergl/lib/animators/states/ParticleFollowState");
+/**
+ * A particle animation node used to create a follow behaviour on a particle system.
+ */
+var ParticleFollowNode = (function (_super) {
+ __extends(ParticleFollowNode, _super);
+ /**
+ * Creates a new ParticleFollowNode
+ *
+ * @param [optional] usesPosition Defines wehether the individual particle reacts to the position of the target.
+ * @param [optional] usesRotation Defines wehether the individual particle reacts to the rotation of the target.
+ * @param [optional] smooth Defines wehether the state calculate the interpolated value.
+ */
+ function ParticleFollowNode(usesPosition, usesRotation, smooth) {
+ if (usesPosition === void 0) { usesPosition = true; }
+ if (usesRotation === void 0) { usesRotation = true; }
+ if (smooth === void 0) { smooth = false; }
+ _super.call(this, "ParticleFollow", ParticlePropertiesMode.LOCAL_DYNAMIC, (usesPosition && usesRotation) ? 6 : 3, ParticleAnimationSet.POST_PRIORITY);
+ this._pStateClass = ParticleFollowState;
+ this._iUsesPosition = usesPosition;
+ this._iUsesRotation = usesRotation;
+ this._iSmooth = smooth;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleFollowNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ //TODO: use Quaternion to implement this function
+ var code = "";
+ if (this._iUsesRotation) {
+ var rotationAttribute = animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleFollowState.FOLLOW_ROTATION_INDEX, rotationAttribute.index);
+ var temp1 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3 = animationRegisterCache.getFreeVertexVectorTemp();
+ var temp4;
+ if (animationRegisterCache.hasBillboard) {
+ animationRegisterCache.addVertexTempUsages(temp3, 1);
+ temp4 = animationRegisterCache.getFreeVertexVectorTemp();
+ }
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+ if (animationRegisterCache.hasBillboard)
+ animationRegisterCache.removeVertexTempUsage(temp3);
+ var len = animationRegisterCache.rotationRegisters.length;
+ var i /*int*/;
+ //x axis
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "sin " + temp3 + ".y," + rotationAttribute + ".x\n";
+ code += "cos " + temp3 + ".z," + rotationAttribute + ".x\n";
+ code += "mov " + temp2 + ".x," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".z\n";
+ code += "neg " + temp2 + ".z," + temp3 + ".y\n";
+ if (animationRegisterCache.hasBillboard)
+ code += "m33 " + temp4 + ".xyz," + animationRegisterCache.positionTarget + ".xyz," + temp1 + "\n";
+ else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+ //y axis
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "cos " + temp1 + ".x," + rotationAttribute + ".y\n";
+ code += "sin " + temp1 + ".z," + rotationAttribute + ".y\n";
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "neg " + temp3 + ".x," + temp1 + ".z\n";
+ code += "mov " + temp3 + ".z," + temp1 + ".x\n";
+ if (animationRegisterCache.hasBillboard)
+ code += "m33 " + temp4 + ".xyz," + temp4 + ".xyz," + temp1 + "\n";
+ else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+ //z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "sin " + temp2 + ".x," + rotationAttribute + ".z\n";
+ code += "cos " + temp2 + ".y," + rotationAttribute + ".z\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp2 + ".y\n";
+ code += "neg " + temp1 + ".y," + temp2 + ".x\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+ if (animationRegisterCache.hasBillboard) {
+ code += "m33 " + temp4 + ".xyz," + temp4 + ".xyz," + temp1 + "\n";
+ code += "sub " + temp4 + ".xyz," + temp4 + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp4 + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ }
+ else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+ }
+ if (this._iUsesPosition) {
+ var positionAttribute = animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleFollowState.FOLLOW_POSITION_INDEX, positionAttribute.index);
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + positionAttribute + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleFollowNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ return ParticleFollowNode;
+})(ParticleNodeBase);
+module.exports = ParticleFollowNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWZvbGxvd25vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVGb2xsb3dOb2RlIiwiUGFydGljbGVGb2xsb3dOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVGb2xsb3dOb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVGb2xsb3dOb2RlLmdldEFuaW1hdGlvblN0YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFPQSxJQUFPLG9CQUFvQixXQUFjLHNEQUFzRCxDQUFDLENBQUM7QUFFakcsSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBQ3pHLElBQU8sZ0JBQWdCLFdBQWUsd0RBQXdELENBQUMsQ0FBQztBQUNoRyxJQUFPLG1CQUFtQixXQUFjLDREQUE0RCxDQUFDLENBQUM7QUFFdEcsQUFHQTs7R0FERztJQUNHLGtCQUFrQjtJQUFTQSxVQUEzQkEsa0JBQWtCQSxVQUF5QkE7SUFXaERBOzs7Ozs7T0FNR0E7SUFDSEEsU0FsQktBLGtCQUFrQkEsQ0FrQlhBLFlBQTJCQSxFQUFFQSxZQUEyQkEsRUFBRUEsTUFBc0JBO1FBQWhGQyw0QkFBMkJBLEdBQTNCQSxtQkFBMkJBO1FBQUVBLDRCQUEyQkEsR0FBM0JBLG1CQUEyQkE7UUFBRUEsc0JBQXNCQSxHQUF0QkEsY0FBc0JBO1FBRTNGQSxrQkFBTUEsZ0JBQWdCQSxFQUFFQSxzQkFBc0JBLENBQUNBLGFBQWFBLEVBQUVBLENBQUNBLFlBQVlBLElBQUlBLFlBQVlBLENBQUNBLEdBQUVBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLG9CQUFvQkEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0E7UUFFeklBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLG1CQUFtQkEsQ0FBQ0E7UUFFeENBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFlBQVlBLENBQUNBO1FBQ25DQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxZQUFZQSxDQUFDQTtRQUNuQ0EsSUFBSUEsQ0FB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LEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLEdBQUdBLEVBQUVBLENBQUNBLEVBQUVBO29CQUN2QkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM1SUEsQ0FBQ0E7WUFFREEsQUFDQUEsUUFEUUE7WUFDUkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM3RUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsaUJBQWlCQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM1REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsaUJBQWlCQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM1REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM3RUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDaERBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBO1lBQ2hEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQzdFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO1lBRTlFQSxFQUFFQSxDQUFDQSxDQUFDQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBO2dCQUN6Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsT0FBT0EsR0FBR0EsS0FBS0EsR0FBR0EsT0FBT0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ2xFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUN0R0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUNuSkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ1BBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsT0FBT0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQzlJQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxDQUFDQSxFQUFFQTtvQkFDdkJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDNUlBLENBQUNBO1FBRUZBLENBQUNBO1FBRURBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3pCQSxJQUFJQSxpQkFBaUJBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7WUFDOUZBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxtQkFBbUJBLENBQUNBLHFCQUFxQkEsRUFBRUEsaUJBQWlCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUNsSEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE9BQU9BLEdBQUdBLGlCQUFpQkEsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLFFBQVFBLENBQUNBO1FBQzNKQSxDQUFDQTtRQUVEQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVERjs7T0FFR0E7SUFDSUEsOENBQWlCQSxHQUF4QkEsVUFBeUJBLFFBQXFCQTtRQUU3Q0csTUFBTUEsQ0FBdUJBLFFBQVFBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDL0RBLENBQUNBO0lBQ0ZILHlCQUFDQTtBQUFEQSxDQXZJQSxBQXVJQ0EsRUF2SWdDLGdCQUFnQixFQXVJaEQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlRm9sbG93Tm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uU2V0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0aW9uU2V0XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVGb2xsb3dTdGF0ZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVGb2xsb3dTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gY3JlYXRlIGEgZm9sbG93IGJlaGF2aW91ciBvbiBhIHBhcnRpY2xlIHN5c3RlbS5cbiAqL1xuY2xhc3MgUGFydGljbGVGb2xsb3dOb2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc1Bvc2l0aW9uOmJvb2xlYW47XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVVzZXNSb3RhdGlvbjpib29sZWFuO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lTbW9vdGg6Ym9vbGVhbjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QYXJ0aWNsZUZvbGxvd05vZGU8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNQb3NpdGlvbiAgICAgRGVmaW5lcyB3ZWhldGhlciB0aGUgaW5kaXZpZHVhbCBwYXJ0aWNsZSByZWFjdHMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNSb3RhdGlvbiAgICAgRGVmaW5lcyB3ZWhldGhlciB0aGUgaW5kaXZpZHVhbCBwYXJ0aWNsZSByZWFjdHMgdG8gdGhlIHJvdGF0aW9uIG9mIHRoZSB0YXJnZXQuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHNtb290aCAgICAgRGVmaW5lcyB3ZWhldGhlciB0aGUgc3RhdGUgY2FsY3VsYXRlIHRoZSBpbnRlcnBvbGF0ZWQgdmFsdWUuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih1c2VzUG9zaXRpb246Ym9vbGVhbiA9IHRydWUsIHVzZXNSb3RhdGlvbjpib29sZWFuID0gdHJ1ZSwgc21vb3RoOmJvb2xlYW4gPSBmYWxzZSlcblx0e1xuXHRcdHN1cGVyKFwiUGFydGljbGVGb2xsb3dcIiwgUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9EWU5BTUlDLCAodXNlc1Bvc2l0aW9uICYmIHVzZXNSb3RhdGlvbik/IDYgOiAzLCBQYXJ0aWNsZUFuaW1hdGlvblNldC5QT1NUX1BSSU9SSVRZKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVGb2xsb3dTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzUG9zaXRpb24gPSB1c2VzUG9zaXRpb247XG5cdFx0dGhpcy5faVVzZXNSb3RhdGlvbiA9IHVzZXNSb3RhdGlvbjtcblx0XHR0aGlzLl9pU21vb3RoID0gc21vb3RoO1xuXG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdC8vVE9ETzogdXNlIFF1YXRlcm5pb24gdG8gaW1wbGVtZW50IHRoaXMgZnVuY3Rpb25cblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdGlmICh0aGlzLl9pVXNlc1JvdGF0aW9uKSB7XG5cdFx0XHR2YXIgcm90YXRpb25BdHRyaWJ1dGU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVGb2xsb3dTdGF0ZS5GT0xMT1dfUk9UQVRJT05fSU5ERVgsIHJvdGF0aW9uQXR0cmlidXRlLmluZGV4KTtcblxuXHRcdFx0dmFyIHRlbXAxOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuYWRkVmVydGV4VGVtcFVzYWdlcyh0ZW1wMSwgMSk7XG5cdFx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAyLCAxKTtcblx0XHRcdHZhciB0ZW1wMzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cblx0XHRcdHZhciB0ZW1wNDpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5oYXNCaWxsYm9hcmQpIHtcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAzLCAxKTtcblx0XHRcdFx0dGVtcDQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0XHR9XG5cblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXAxKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXAyKTtcblx0XHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZClcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcDMpO1xuXG5cdFx0XHR2YXIgbGVuOm51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVycy5sZW5ndGg7XG5cdFx0XHR2YXIgaTpudW1iZXIgLyppbnQqLztcblxuXHRcdFx0Ly94IGF4aXNcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAxICsgXCIueCxcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAzICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwic2luIFwiICsgdGVtcDMgKyBcIi55LFwiICsgcm90YXRpb25BdHRyaWJ1dGUgKyBcIi54XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiY29zIFwiICsgdGVtcDMgKyBcIi56LFwiICsgcm90YXRpb25BdHRyaWJ1dGUgKyBcIi54XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDIgKyBcIi54LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueSxcIiArIHRlbXAzICsgXCIuelxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5lZyBcIiArIHRlbXAyICsgXCIueixcIiArIHRlbXAzICsgXCIueVxcblwiO1xuXG5cdFx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5oYXNCaWxsYm9hcmQpXG5cdFx0XHRcdGNvZGUgKz0gXCJtMzMgXCIgKyB0ZW1wNCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXosXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgdGVtcDEgKyBcIlxcblwiO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG5cdFx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIsXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8veSBheGlzXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDEgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJjb3MgXCIgKyB0ZW1wMSArIFwiLngsXCIgKyByb3RhdGlvbkF0dHJpYnV0ZSArIFwiLnlcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJzaW4gXCIgKyB0ZW1wMSArIFwiLnosXCIgKyByb3RhdGlvbkF0dHJpYnV0ZSArIFwiLnlcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueSxcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAzICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgdGVtcDMgKyBcIi54LFwiICsgdGVtcDEgKyBcIi56XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDMgKyBcIi56LFwiICsgdGVtcDEgKyBcIi54XFxuXCI7XG5cblx0XHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZClcblx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIHRlbXA0ICsgXCIueHl6LFwiICsgdGVtcDQgKyBcIi54eXosXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgdGVtcDEgKyBcIlxcblwiO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG5cdFx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIsXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8veiBheGlzXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDIgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJzaW4gXCIgKyB0ZW1wMiArIFwiLngsXCIgKyByb3RhdGlvbkF0dHJpYnV0ZSArIFwiLnpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJjb3MgXCIgKyB0ZW1wMiArIFwiLnksXCIgKyByb3RhdGlvbkF0dHJpYnV0ZSArIFwiLnpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAxICsgXCIueCxcIiArIHRlbXAyICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5lZyBcIiArIHRlbXAxICsgXCIueSxcIiArIHRlbXAyICsgXCIueFxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAzICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDMgKyBcIi56LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiXFxuXCI7XG5cblx0XHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZCkge1xuXHRcdFx0XHRjb2RlICs9IFwibTMzIFwiICsgdGVtcDQgKyBcIi54eXosXCIgKyB0ZW1wNCArIFwiLnh5eixcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHRlbXA0ICsgXCIueHl6LFwiICsgdGVtcDQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnBvc2l0aW9uVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgdGVtcDQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb2RlICs9IFwibTMzIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcblx0XHRcdFx0XHRjb2RlICs9IFwibTMzIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIixcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9pVXNlc1Bvc2l0aW9uKSB7XG5cdFx0XHR2YXIgcG9zaXRpb25BdHRyaWJ1dGU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVGb2xsb3dTdGF0ZS5GT0xMT1dfUE9TSVRJT05fSU5ERVgsIHBvc2l0aW9uQXR0cmlidXRlLmluZGV4KTtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgcG9zaXRpb25BdHRyaWJ1dGUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFuaW1hdGlvblN0YXRlKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSk6UGFydGljbGVGb2xsb3dTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZUZvbGxvd1N0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZUZvbGxvd05vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleFollowNode.ts b/lib/animators/nodes/ParticleFollowNode.ts
new file mode 100644
index 000000000..c4cb793e8
--- /dev/null
+++ b/lib/animators/nodes/ParticleFollowNode.ts
@@ -0,0 +1,154 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleFollowState = require("awayjs-renderergl/lib/animators/states/ParticleFollowState");
+
+/**
+ * A particle animation node used to create a follow behaviour on a particle system.
+ */
+class ParticleFollowNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesPosition:boolean;
+
+ /** @private */
+ public _iUsesRotation:boolean;
+
+ /** @private */
+ public _iSmooth:boolean;
+
+ /**
+ * Creates a new ParticleFollowNode
+ *
+ * @param [optional] usesPosition Defines wehether the individual particle reacts to the position of the target.
+ * @param [optional] usesRotation Defines wehether the individual particle reacts to the rotation of the target.
+ * @param [optional] smooth Defines wehether the state calculate the interpolated value.
+ */
+ constructor(usesPosition:boolean = true, usesRotation:boolean = true, smooth:boolean = false)
+ {
+ super("ParticleFollow", ParticlePropertiesMode.LOCAL_DYNAMIC, (usesPosition && usesRotation)? 6 : 3, ParticleAnimationSet.POST_PRIORITY);
+
+ this._pStateClass = ParticleFollowState;
+
+ this._iUsesPosition = usesPosition;
+ this._iUsesRotation = usesRotation;
+ this._iSmooth = smooth;
+
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ //TODO: use Quaternion to implement this function
+ var code:string = "";
+ if (this._iUsesRotation) {
+ var rotationAttribute:ShaderRegisterElement = animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleFollowState.FOLLOW_ROTATION_INDEX, rotationAttribute.index);
+
+ var temp1:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+
+ var temp4:ShaderRegisterElement;
+ if (animationRegisterCache.hasBillboard) {
+ animationRegisterCache.addVertexTempUsages(temp3, 1);
+ temp4 = animationRegisterCache.getFreeVertexVectorTemp();
+ }
+
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+ if (animationRegisterCache.hasBillboard)
+ animationRegisterCache.removeVertexTempUsage(temp3);
+
+ var len:number /*int*/ = animationRegisterCache.rotationRegisters.length;
+ var i:number /*int*/;
+
+ //x axis
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "sin " + temp3 + ".y," + rotationAttribute + ".x\n";
+ code += "cos " + temp3 + ".z," + rotationAttribute + ".x\n";
+ code += "mov " + temp2 + ".x," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".z\n";
+ code += "neg " + temp2 + ".z," + temp3 + ".y\n";
+
+ if (animationRegisterCache.hasBillboard)
+ code += "m33 " + temp4 + ".xyz," + animationRegisterCache.positionTarget + ".xyz," + temp1 + "\n";
+ else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+
+ //y axis
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "cos " + temp1 + ".x," + rotationAttribute + ".y\n";
+ code += "sin " + temp1 + ".z," + rotationAttribute + ".y\n";
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "neg " + temp3 + ".x," + temp1 + ".z\n";
+ code += "mov " + temp3 + ".z," + temp1 + ".x\n";
+
+ if (animationRegisterCache.hasBillboard)
+ code += "m33 " + temp4 + ".xyz," + temp4 + ".xyz," + temp1 + "\n";
+ else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+
+ //z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "sin " + temp2 + ".x," + rotationAttribute + ".z\n";
+ code += "cos " + temp2 + ".y," + rotationAttribute + ".z\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp2 + ".y\n";
+ code += "neg " + temp1 + ".y," + temp2 + ".x\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+
+ if (animationRegisterCache.hasBillboard) {
+ code += "m33 " + temp4 + ".xyz," + temp4 + ".xyz," + temp1 + "\n";
+ code += "sub " + temp4 + ".xyz," + temp4 + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp4 + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ } else {
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+
+ }
+
+ if (this._iUsesPosition) {
+ var positionAttribute:ShaderRegisterElement = animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleFollowState.FOLLOW_POSITION_INDEX, positionAttribute.index);
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + positionAttribute + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleFollowState
+ {
+ return animator.getAnimationState(this);
+ }
+}
+
+export = ParticleFollowNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleInitialColorNode.js b/lib/animators/nodes/ParticleInitialColorNode.js
new file mode 100755
index 000000000..fd68cbe37
--- /dev/null
+++ b/lib/animators/nodes/ParticleInitialColorNode.js
@@ -0,0 +1,87 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleInitialColorState = require("awayjs-renderergl/lib/animators/states/ParticleInitialColorState");
+/**
+ *
+ */
+var ParticleInitialColorNode = (function (_super) {
+ __extends(ParticleInitialColorNode, _super);
+ function ParticleInitialColorNode(mode /*uint*/, usesMultiplier, usesOffset, initialColor) {
+ if (usesMultiplier === void 0) { usesMultiplier = true; }
+ if (usesOffset === void 0) { usesOffset = false; }
+ if (initialColor === void 0) { initialColor = null; }
+ _super.call(this, "ParticleInitialColor", mode, (usesMultiplier && usesOffset) ? 8 : 4, ParticleAnimationSet.COLOR_PRIORITY);
+ this._pStateClass = ParticleInitialColorState;
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iInitialColor = initialColor || new ColorTransform();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleInitialColorNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+ if (this._iUsesMultiplier) {
+ var multiplierValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleInitialColorState.MULTIPLIER_INDEX, multiplierValue.index);
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + multiplierValue + "," + animationRegisterCache.colorMulTarget + "\n";
+ }
+ if (this._iUsesOffset) {
+ var offsetValue = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC) ? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleInitialColorState.OFFSET_INDEX, offsetValue.index);
+ code += "add " + animationRegisterCache.colorAddTarget + "," + offsetValue + "," + animationRegisterCache.colorAddTarget + "\n";
+ }
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleInitialColorNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleInitialColorNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var initialColor = param[ParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORM];
+ if (!initialColor)
+ throw (new Error("there is no " + ParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORM + " in param!"));
+ var i = 0;
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = initialColor.redMultiplier;
+ this._pOneData[i++] = initialColor.greenMultiplier;
+ this._pOneData[i++] = initialColor.blueMultiplier;
+ this._pOneData[i++] = initialColor.alphaMultiplier;
+ }
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = initialColor.redOffset / 255;
+ this._pOneData[i++] = initialColor.greenOffset / 255;
+ this._pOneData[i++] = initialColor.blueOffset / 255;
+ this._pOneData[i++] = initialColor.alphaOffset / 255;
+ }
+ };
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the color transform applied to the particle.
+ */
+ ParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORM = "ColorInitialColorTransform";
+ return ParticleInitialColorNode;
+})(ParticleNodeBase);
+module.exports = ParticleInitialColorNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZWluaXRpYWxjb2xvcm5vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVJbml0aWFsQ29sb3JOb2RlIiwiUGFydGljbGVJbml0aWFsQ29sb3JOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVJbml0aWFsQ29sb3JOb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVJbml0aWFsQ29sb3JOb2RlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciLCJQYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUuX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxjQUFjLFdBQWUsMENBQTBDLENBQUMsQ0FBQztBQVFoRixJQUFPLG9CQUFvQixXQUFjLHNEQUFzRCxDQUFDLENBQUM7QUFFakcsSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBQ3pHLElBQU8sZ0JBQWdCLFdBQWUsd0RBQXdELENBQUMsQ0FBQztBQUNoRyxJQUFPLHlCQUF5QixXQUFZLGtFQUFrRSxDQUFDLENBQUM7QUFFaEgsQUFHQTs7R0FERztJQUNHLHdCQUF3QjtJQUFTQSxVQUFqQ0Esd0JBQXdCQSxVQUF5QkE7SUFnQnREQSxTQWhCS0Esd0JBQXdCQSxDQWdCakJBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLGNBQTZCQSxFQUFFQSxVQUEwQkEsRUFBRUEsWUFBa0NBO1FBQTdGQyw4QkFBNkJBLEdBQTdCQSxxQkFBNkJBO1FBQUVBLDBCQUEwQkEsR0FBMUJBLGtCQUEwQkE7UUFBRUEsNEJBQWtDQSxHQUFsQ0EsbUJBQWtDQTtRQUU5SEEsa0JBQU1BLHNCQUFzQkEsRUFBRUEsSUFBSUEsRUFBRUEsQ0FBQ0EsY0FBY0EsSUFBSUEsVUFBVUEsQ0FBQ0EsR0FBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsb0JBQW9CQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUVoSEEsSUFB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QUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFlBQVlBLENBQUNBLFdBQVdBLEdBQUNBLEdBQUdBLENBQUNBO1FBQ3BEQSxDQUFDQTtJQUVGQSxDQUFDQTtJQWhGREo7OztPQUdHQTtJQUNXQSxxREFBNEJBLEdBQVVBLDRCQUE0QkEsQ0FBQ0E7SUE4RWxGQSwrQkFBQ0E7QUFBREEsQ0E1RkEsQUE0RkNBLEVBNUZzQyxnQkFBZ0IsRUE0RnREO0FBRUQsQUFBa0MsaUJBQXpCLHdCQUF3QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29sb3JUcmFuc2Zvcm1cdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Db2xvclRyYW5zZm9ybVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uU2V0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0aW9uU2V0XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZUluaXRpYWxDb2xvclN0YXRlXCIpO1xuXG4vKipcbiAqXG4gKi9cbmNsYXNzIFBhcnRpY2xlSW5pdGlhbENvbG9yTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0Ly9kZWZhdWx0IHZhbHVlcyB1c2VkIHdoZW4gY3JlYXRpbmcgc3RhdGVzXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc09mZnNldDpib29sZWFuO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pSW5pdGlhbENvbG9yOkNvbG9yVHJhbnNmb3JtO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIGNvbG9yIG5vZGUgcHJvcGVydGllcyBvbiBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPkNvbG9yVHJhbnNmb3JtPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjb2xvciB0cmFuc2Zvcm0gYXBwbGllZCB0byB0aGUgcGFydGljbGUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIENPTE9SX0lOSVRJQUxfQ09MT1JUUkFOU0ZPUk06c3RyaW5nID0gXCJDb2xvckluaXRpYWxDb2xvclRyYW5zZm9ybVwiO1xuXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCB1c2VzTXVsdGlwbGllcjpib29sZWFuID0gdHJ1ZSwgdXNlc09mZnNldDpib29sZWFuID0gZmFsc2UsIGluaXRpYWxDb2xvcjpDb2xvclRyYW5zZm9ybSA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlSW5pdGlhbENvbG9yXCIsIG1vZGUsICh1c2VzTXVsdGlwbGllciAmJiB1c2VzT2Zmc2V0KT8gOCA6IDQsIFBhcnRpY2xlQW5pbWF0aW9uU2V0LkNPTE9SX1BSSU9SSVRZKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzTXVsdGlwbGllciA9IHVzZXNNdWx0aXBsaWVyO1xuXHRcdHRoaXMuX2lVc2VzT2Zmc2V0ID0gdXNlc09mZnNldDtcblx0XHR0aGlzLl9pSW5pdGlhbENvbG9yID0gaW5pdGlhbENvbG9yIHx8IG5ldyBDb2xvclRyYW5zZm9ybSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLm5lZWRGcmFnbWVudEFuaW1hdGlvbikge1xuXG5cdFx0XHRpZiAodGhpcy5faVVzZXNNdWx0aXBsaWVyKSB7XG5cdFx0XHRcdHZhciBtdWx0aXBsaWVyVmFsdWU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gKHRoaXMuX3BNb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKT8gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpO1xuXHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZS5NVUxUSVBMSUVSX0lOREVYLCBtdWx0aXBsaWVyVmFsdWUuaW5kZXgpO1xuXG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yTXVsVGFyZ2V0ICsgXCIsXCIgKyBtdWx0aXBsaWVyVmFsdWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuY29sb3JNdWxUYXJnZXQgKyBcIlxcblwiO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5faVVzZXNPZmZzZXQpIHtcblx0XHRcdFx0dmFyIG9mZnNldFZhbHVlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQyk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlSW5pdGlhbENvbG9yU3RhdGUuT0ZGU0VUX0lOREVYLCBvZmZzZXRWYWx1ZS5pbmRleCk7XG5cblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuY29sb3JBZGRUYXJnZXQgKyBcIixcIiArIG9mZnNldFZhbHVlICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yQWRkVGFyZ2V0ICsgXCJcXG5cIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmcocGFydGljbGVBbmltYXRpb25TZXQ6UGFydGljbGVBbmltYXRpb25TZXQpXG5cdHtcblx0XHRpZiAodGhpcy5faVVzZXNNdWx0aXBsaWVyKVxuXHRcdFx0cGFydGljbGVBbmltYXRpb25TZXQuaGFzQ29sb3JNdWxOb2RlID0gdHJ1ZTtcblx0XHRpZiAodGhpcy5faVVzZXNPZmZzZXQpXG5cdFx0XHRwYXJ0aWNsZUFuaW1hdGlvblNldC5oYXNDb2xvckFkZE5vZGUgPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZShwYXJhbTpQYXJ0aWNsZVByb3BlcnRpZXMpXG5cdHtcblx0XHR2YXIgaW5pdGlhbENvbG9yOkNvbG9yVHJhbnNmb3JtID0gcGFyYW1bUGFydGljbGVJbml0aWFsQ29sb3JOb2RlLkNPTE9SX0lOSVRJQUxfQ09MT1JUUkFOU0ZPUk1dO1xuXHRcdGlmICghaW5pdGlhbENvbG9yKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUuQ09MT1JfSU5JVElBTF9DT0xPUlRSQU5TRk9STSArIFwiIGluIHBhcmFtIVwiKSk7XG5cblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdFx0Ly9tdWx0aXBsaWVyXG5cdFx0aWYgKHRoaXMuX2lVc2VzTXVsdGlwbGllcikge1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IGluaXRpYWxDb2xvci5yZWRNdWx0aXBsaWVyO1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IGluaXRpYWxDb2xvci5ncmVlbk11bHRpcGxpZXI7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gaW5pdGlhbENvbG9yLmJsdWVNdWx0aXBsaWVyO1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbaSsrXSA9IGluaXRpYWxDb2xvci5hbHBoYU11bHRpcGxpZXI7XG5cdFx0fVxuXHRcdC8vb2Zmc2V0XG5cdFx0aWYgKHRoaXMuX2lVc2VzT2Zmc2V0KSB7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gaW5pdGlhbENvbG9yLnJlZE9mZnNldC8yNTU7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gaW5pdGlhbENvbG9yLmdyZWVuT2Zmc2V0LzI1NTtcblx0XHRcdHRoaXMuX3BPbmVEYXRhW2krK10gPSBpbml0aWFsQ29sb3IuYmx1ZU9mZnNldC8yNTU7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVtpKytdID0gaW5pdGlhbENvbG9yLmFscGhhT2Zmc2V0LzI1NTtcblx0XHR9XG5cblx0fVxuXG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlSW5pdGlhbENvbG9yTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleInitialColorNode.ts b/lib/animators/nodes/ParticleInitialColorNode.ts
new file mode 100644
index 000000000..2f480d5ef
--- /dev/null
+++ b/lib/animators/nodes/ParticleInitialColorNode.ts
@@ -0,0 +1,112 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleInitialColorState = require("awayjs-renderergl/lib/animators/states/ParticleInitialColorState");
+
+/**
+ *
+ */
+class ParticleInitialColorNode extends ParticleNodeBase
+{
+ //default values used when creating states
+ /** @private */
+ public _iUsesMultiplier:boolean;
+ /** @private */
+ public _iUsesOffset:boolean;
+ /** @private */
+ public _iInitialColor:ColorTransform;
+
+ /**
+ * Reference for color node properties on a single particle (when in local property mode).
+ * Expects a ColorTransform
object representing the color transform applied to the particle.
+ */
+ public static COLOR_INITIAL_COLORTRANSFORM:string = "ColorInitialColorTransform";
+
+ constructor(mode:number /*uint*/, usesMultiplier:boolean = true, usesOffset:boolean = false, initialColor:ColorTransform = null)
+ {
+ super("ParticleInitialColor", mode, (usesMultiplier && usesOffset)? 8 : 4, ParticleAnimationSet.COLOR_PRIORITY);
+
+ this._pStateClass = ParticleInitialColorState;
+
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iInitialColor = initialColor || new ColorTransform();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+
+ if (this._iUsesMultiplier) {
+ var multiplierValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleInitialColorState.MULTIPLIER_INDEX, multiplierValue.index);
+
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + multiplierValue + "," + animationRegisterCache.colorMulTarget + "\n";
+ }
+
+ if (this._iUsesOffset) {
+ var offsetValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.LOCAL_STATIC)? animationRegisterCache.getFreeVertexAttribute() : animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleInitialColorState.OFFSET_INDEX, offsetValue.index);
+
+ code += "add " + animationRegisterCache.colorAddTarget + "," + offsetValue + "," + animationRegisterCache.colorAddTarget + "\n";
+ }
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var initialColor:ColorTransform = param[ParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORM];
+ if (!initialColor)
+ throw(new Error("there is no " + ParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORM + " in param!"));
+
+ var i:number /*uint*/ = 0;
+
+ //multiplier
+ if (this._iUsesMultiplier) {
+ this._pOneData[i++] = initialColor.redMultiplier;
+ this._pOneData[i++] = initialColor.greenMultiplier;
+ this._pOneData[i++] = initialColor.blueMultiplier;
+ this._pOneData[i++] = initialColor.alphaMultiplier;
+ }
+ //offset
+ if (this._iUsesOffset) {
+ this._pOneData[i++] = initialColor.redOffset/255;
+ this._pOneData[i++] = initialColor.greenOffset/255;
+ this._pOneData[i++] = initialColor.blueOffset/255;
+ this._pOneData[i++] = initialColor.alphaOffset/255;
+ }
+
+ }
+
+}
+
+export = ParticleInitialColorNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleNodeBase.js b/lib/animators/nodes/ParticleNodeBase.js
new file mode 100755
index 000000000..da6d7d6ff
--- /dev/null
+++ b/lib/animators/nodes/ParticleNodeBase.js
@@ -0,0 +1,127 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+/**
+ * Provides an abstract base class for particle animation nodes.
+ */
+var ParticleNodeBase = (function (_super) {
+ __extends(ParticleNodeBase, _super);
+ /**
+ * Creates a new ParticleNodeBase
object.
+ *
+ * @param name Defines the generic name of the particle animation node.
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param dataLength Defines the length of the data used by the node when in LOCAL_STATIC
mode.
+ * @param [optional] priority the priority of the particle animation node, used to order the agal generated in a particle animation set. Defaults to 1.
+ */
+ function ParticleNodeBase(name, mode /*uint*/, dataLength /*uint*/, priority) {
+ if (priority === void 0) { priority = 1; }
+ _super.call(this);
+ this._pDataLength = 3;
+ name = name + ParticleNodeBase.MODES[mode];
+ this.name = name;
+ this._pMode = mode;
+ this._priority = priority;
+ this._pDataLength = dataLength;
+ this._pOneData = new Array(this._pDataLength);
+ }
+ Object.defineProperty(ParticleNodeBase.prototype, "mode", {
+ /**
+ * Returns the property mode of the particle animation node. Typically set in the node constructor
+ *
+ * @see away.animators.ParticlePropertiesMode
+ */
+ get: function () {
+ return this._pMode;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleNodeBase.prototype, "priority", {
+ /**
+ * Returns the priority of the particle animation node, used to order the agal generated in a particle animation set. Set automatically on instantiation.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #getAGALVertexCode
+ */
+ get: function () {
+ return this._priority;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleNodeBase.prototype, "dataLength", {
+ /**
+ * Returns the length of the data used by the node when in LOCAL_STATIC
mode. Used to generate the local static data of the particle animation set.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #getAGALVertexCode
+ */
+ get: function () {
+ return this._pDataLength;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleNodeBase.prototype, "oneData", {
+ /**
+ * Returns the generated data vector of the node after one particle pass during the generation of all local static data of the particle animation set.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #generatePropertyOfOneParticle
+ */
+ get: function () {
+ return this._pOneData;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Returns the AGAL code of the particle animation node for use in the vertex shader.
+ */
+ ParticleNodeBase.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ return "";
+ };
+ /**
+ * Returns the AGAL code of the particle animation node for use in the fragment shader.
+ */
+ ParticleNodeBase.prototype.getAGALFragmentCode = function (shaderObject, animationRegisterCache) {
+ return "";
+ };
+ /**
+ * Returns the AGAL code of the particle animation node for use in the fragment shader when UV coordinates are required.
+ */
+ ParticleNodeBase.prototype.getAGALUVCode = function (shaderObject, animationRegisterCache) {
+ return "";
+ };
+ /**
+ * Called internally by the particle animation set when assigning the set of static properties originally defined by the initParticleFunc of the set.
+ *
+ * @see away.animators.ParticleAnimationSet#initParticleFunc
+ */
+ ParticleNodeBase.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ };
+ /**
+ * Called internally by the particle animation set when determining the requirements of the particle animation node AGAL.
+ */
+ ParticleNodeBase.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ };
+ //modes alias
+ ParticleNodeBase.GLOBAL = 'Global';
+ ParticleNodeBase.LOCAL_STATIC = 'LocalStatic';
+ ParticleNodeBase.LOCAL_DYNAMIC = 'LocalDynamic';
+ //modes list
+ ParticleNodeBase.MODES = {
+ 0: ParticleNodeBase.GLOBAL,
+ 1: ParticleNodeBase.LOCAL_STATIC,
+ 2: ParticleNodeBase.LOCAL_DYNAMIC
+ };
+ return ParticleNodeBase;
+})(AnimationNodeBase);
+module.exports = ParticleNodeBase;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZW5vZGViYXNlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlTm9kZUJhc2UiLCJQYXJ0aWNsZU5vZGVCYXNlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVOb2RlQmFzZS5tb2RlIiwiUGFydGljbGVOb2RlQmFzZS5wcmlvcml0eSIsIlBhcnRpY2xlTm9kZUJhc2UuZGF0YUxlbmd0aCIsIlBhcnRpY2xlTm9kZUJhc2Uub25lRGF0YSIsIlBhcnRpY2xlTm9kZUJhc2UuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZU5vZGVCYXNlLmdldEFHQUxGcmFnbWVudENvZGUiLCJQYXJ0aWNsZU5vZGVCYXNlLmdldEFHQUxVVkNvZGUiLCJQYXJ0aWNsZU5vZGVCYXNlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiLCJQYXJ0aWNsZU5vZGVCYXNlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8saUJBQWlCLFdBQWMsbURBQW1ELENBQUMsQ0FBQztBQVEzRixBQUdBOztHQURHO0lBQ0csZ0JBQWdCO0lBQVNBLFVBQXpCQSxnQkFBZ0JBLFVBQTBCQTtJQWtFL0NBOzs7Ozs7O09BT0dBO0lBQ0hBLFNBMUVLQSxnQkFBZ0JBLENBMEVUQSxJQUFXQSxFQUFFQSxJQUFJQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxVQUFVQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxRQUEyQkE7UUFBM0JDLHdCQUEyQkEsR0FBM0JBLFlBQTJCQTtRQUVyR0EsaUJBQU9BLENBQUNBO1FBdkVGQSxpQkFBWUEsR0FBbUJBLENBQUNBLENBQUNBO1FBeUV2Q0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsZ0JBQWdCQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUUzQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDakJBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBO1FBQ25CQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUMxQkEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsVUFBVUEsQ0FBQ0E7UUFFL0JBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLEtBQUtBLENBQVNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBO0lBQ3ZEQSxDQUFDQTtJQTFEREQsc0JBQVdBLGtDQUFJQTtRQUxmQTs7OztXQUlHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQTtRQUNwQkEsQ0FBQ0E7OztPQUFBRjtJQVFEQSxzQkFBV0Esc0NBQVFBO1FBTm5CQTs7Ozs7V0FLR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDdkJBLENBQUNBOzs7T0FBQUg7SUFRREEsc0JBQVdBLHdDQUFVQTtRQU5yQkE7Ozs7O1dBS0dBO2FBQ0hBO1lBRUNJLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO1FBQzFCQSxDQUFDQTs7O09BQUFKO0lBUURBLHNCQUFXQSxxQ0FBT0E7UUFObEJBOzs7OztXQUtHQTthQUNIQTtZQUVDSyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN2QkEsQ0FBQ0E7OztPQUFBTDtJQXdCREE7O09BRUdBO0lBQ0lBLDRDQUFpQkEsR0FBeEJBLFVBQXlCQSxZQUE2QkEsRUFBRUEsc0JBQTZDQTtRQUVwR00sTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7SUFDWEEsQ0FBQ0E7SUFFRE47O09BRUdBO0lBQ0lBLDhDQUFtQkEsR0FBMUJBLFVBQTJCQSxZQUE2QkEsRUFBRUEsc0JBQTZDQTtRQUV0R08sTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7SUFDWEEsQ0FBQ0E7SUFFRFA7O09BRUdBO0lBQ0lBLHdDQUFhQSxHQUFwQkEsVUFBcUJBLFlBQTZCQSxFQUFFQSxzQkFBNkNBO1FBRWhHUSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQTtJQUNYQSxDQUFDQTtJQUVEUjs7OztPQUlHQTtJQUNJQSwwREFBK0JBLEdBQXRDQSxVQUF1Q0EsS0FBd0JBO0lBRy9EUyxDQUFDQTtJQUVEVDs7T0FFR0E7SUFDSUEsb0RBQXlCQSxHQUFoQ0EsVUFBaUNBLG9CQUF5Q0E7SUFHMUVVLENBQUNBO0lBdEhEVixhQUFhQTtJQUNFQSx1QkFBTUEsR0FBVUEsUUFBUUEsQ0FBQ0E7SUFDekJBLDZCQUFZQSxHQUFVQSxhQUFhQSxDQUFDQTtJQUNwQ0EsOEJBQWFBLEdBQVVBLGNBQWNBLENBQUNBO0lBRXJEQSxZQUFZQTtJQUNHQSxzQkFBS0EsR0FDcEJBO1FBQ0NBLENBQUNBLEVBQUNBLGdCQUFnQkEsQ0FBQ0EsTUFBTUE7UUFDekJBLENBQUNBLEVBQUNBLGdCQUFnQkEsQ0FBQ0EsWUFBWUE7UUFDL0JBLENBQUNBLEVBQUNBLGdCQUFnQkEsQ0FBQ0EsYUFBYUE7S0FDaENBLENBQUNBO0lBNEdIQSx1QkFBQ0E7QUFBREEsQ0FqSUEsQUFpSUNBLEVBakk4QixpQkFBaUIsRUFpSS9DO0FBRUQsQUFBMEIsaUJBQWpCLGdCQUFnQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU5vZGVCYXNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIHBhcnRpY2xlIGFuaW1hdGlvbiBub2Rlcy5cbiAqL1xuY2xhc3MgUGFydGljbGVOb2RlQmFzZSBleHRlbmRzIEFuaW1hdGlvbk5vZGVCYXNlXG57XG5cdHByaXZhdGUgX3ByaW9yaXR5Om51bWJlciAvKmludCovO1xuXG5cdHB1YmxpYyBfcE1vZGU6bnVtYmVyIC8qdWludCovO1xuXHRwdWJsaWMgX3BEYXRhTGVuZ3RoOm51bWJlciAvKnVpbnQqLyA9IDM7XG5cdHB1YmxpYyBfcE9uZURhdGE6QXJyYXk8bnVtYmVyPjtcblxuXHRwdWJsaWMgX2lEYXRhT2Zmc2V0Om51bWJlciAvKnVpbnQqLztcblxuXHQvL21vZGVzIGFsaWFzXG5cdHByaXZhdGUgc3RhdGljIEdMT0JBTDpzdHJpbmcgPSAnR2xvYmFsJztcblx0cHJpdmF0ZSBzdGF0aWMgTE9DQUxfU1RBVElDOnN0cmluZyA9ICdMb2NhbFN0YXRpYyc7XG5cdHByaXZhdGUgc3RhdGljIExPQ0FMX0RZTkFNSUM6c3RyaW5nID0gJ0xvY2FsRHluYW1pYyc7XG5cblx0Ly9tb2RlcyBsaXN0XG5cdHByaXZhdGUgc3RhdGljIE1PREVTOk9iamVjdCA9XG5cdHtcblx0XHQwOlBhcnRpY2xlTm9kZUJhc2UuR0xPQkFMLFxuXHRcdDE6UGFydGljbGVOb2RlQmFzZS5MT0NBTF9TVEFUSUMsXG5cdFx0MjpQYXJ0aWNsZU5vZGVCYXNlLkxPQ0FMX0RZTkFNSUNcblx0fTtcblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgcHJvcGVydHkgbW9kZSBvZiB0aGUgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUuIFR5cGljYWxseSBzZXQgaW4gdGhlIG5vZGUgY29uc3RydWN0b3Jcblx0ICpcblx0ICogQHNlZSBhd2F5LmFuaW1hdG9ycy5QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG1vZGUoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9wTW9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBwcmlvcml0eSBvZiB0aGUgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUsIHVzZWQgdG8gb3JkZXIgdGhlIGFnYWwgZ2VuZXJhdGVkIGluIGEgcGFydGljbGUgYW5pbWF0aW9uIHNldC4gU2V0IGF1dG9tYXRpY2FsbHkgb24gaW5zdGFudGlhdGlvbi5cblx0ICpcblx0ICogQHNlZSBhd2F5LmFuaW1hdG9ycy5QYXJ0aWNsZUFuaW1hdGlvblNldFxuXHQgKiBAc2VlICNnZXRBR0FMVmVydGV4Q29kZVxuXHQgKi9cblx0cHVibGljIGdldCBwcmlvcml0eSgpOm51bWJlciAvKmludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcHJpb3JpdHk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIHVzZWQgYnkgdGhlIG5vZGUgd2hlbiBpbiA8Y29kZT5MT0NBTF9TVEFUSUM8L2NvZGU+IG1vZGUuIFVzZWQgdG8gZ2VuZXJhdGUgdGhlIGxvY2FsIHN0YXRpYyBkYXRhIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gc2V0LlxuXHQgKlxuXHQgKiBAc2VlIGF3YXkuYW5pbWF0b3JzLlBhcnRpY2xlQW5pbWF0aW9uU2V0XG5cdCAqIEBzZWUgI2dldEFHQUxWZXJ0ZXhDb2RlXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGRhdGFMZW5ndGgoKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3BEYXRhTGVuZ3RoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGdlbmVyYXRlZCBkYXRhIHZlY3RvciBvZiB0aGUgbm9kZSBhZnRlciBvbmUgcGFydGljbGUgcGFzcyBkdXJpbmcgdGhlIGdlbmVyYXRpb24gb2YgYWxsIGxvY2FsIHN0YXRpYyBkYXRhIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gc2V0LlxuXHQgKlxuXHQgKiBAc2VlIGF3YXkuYW5pbWF0b3JzLlBhcnRpY2xlQW5pbWF0aW9uU2V0XG5cdCAqIEBzZWUgI2dlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG9uZURhdGEoKTpBcnJheTxudW1iZXI+XG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcE9uZURhdGE7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QYXJ0aWNsZU5vZGVCYXNlPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSAgICAgICAgICAgICAgIG5hbWUgICAgICAgICAgICBEZWZpbmVzIHRoZSBnZW5lcmljIG5hbWUgb2YgdGhlIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlLlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgICAgICAgICAgICAgZGF0YUxlbmd0aCAgICAgIERlZmluZXMgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSB1c2VkIGJ5IHRoZSBub2RlIHdoZW4gaW4gPGNvZGU+TE9DQUxfU1RBVElDPC9jb2RlPiBtb2RlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBwcmlvcml0eSAgICAgICAgdGhlIHByaW9yaXR5IG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSwgdXNlZCB0byBvcmRlciB0aGUgYWdhbCBnZW5lcmF0ZWQgaW4gYSBwYXJ0aWNsZSBhbmltYXRpb24gc2V0LiBEZWZhdWx0cyB0byAxLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobmFtZTpzdHJpbmcsIG1vZGU6bnVtYmVyIC8qdWludCovLCBkYXRhTGVuZ3RoOm51bWJlciAvKnVpbnQqLywgcHJpb3JpdHk6bnVtYmVyIC8qaW50Ki8gPSAxKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdG5hbWUgPSBuYW1lICsgUGFydGljbGVOb2RlQmFzZS5NT0RFU1ttb2RlXTtcblxuXHRcdHRoaXMubmFtZSA9IG5hbWU7XG5cdFx0dGhpcy5fcE1vZGUgPSBtb2RlO1xuXHRcdHRoaXMuX3ByaW9yaXR5ID0gcHJpb3JpdHk7XG5cdFx0dGhpcy5fcERhdGFMZW5ndGggPSBkYXRhTGVuZ3RoO1xuXG5cdFx0dGhpcy5fcE9uZURhdGEgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLl9wRGF0YUxlbmd0aCk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgQUdBTCBjb2RlIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSBmb3IgdXNlIGluIHRoZSB2ZXJ0ZXggc2hhZGVyLlxuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgQUdBTCBjb2RlIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSBmb3IgdXNlIGluIHRoZSBmcmFnbWVudCBzaGFkZXIuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIEFHQUwgY29kZSBvZiB0aGUgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgZm9yIHVzZSBpbiB0aGUgZnJhZ21lbnQgc2hhZGVyIHdoZW4gVVYgY29vcmRpbmF0ZXMgYXJlIHJlcXVpcmVkLlxuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgaW50ZXJuYWxseSBieSB0aGUgcGFydGljbGUgYW5pbWF0aW9uIHNldCB3aGVuIGFzc2lnbmluZyB0aGUgc2V0IG9mIHN0YXRpYyBwcm9wZXJ0aWVzIG9yaWdpbmFsbHkgZGVmaW5lZCBieSB0aGUgaW5pdFBhcnRpY2xlRnVuYyBvZiB0aGUgc2V0LlxuXHQgKlxuXHQgKiBAc2VlIGF3YXkuYW5pbWF0b3JzLlBhcnRpY2xlQW5pbWF0aW9uU2V0I2luaXRQYXJ0aWNsZUZ1bmNcblx0ICovXG5cdHB1YmxpYyBfaUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlKHBhcmFtOlBhcnRpY2xlUHJvcGVydGllcylcblx0e1xuXG5cdH1cblxuXHQvKipcblx0ICogQ2FsbGVkIGludGVybmFsbHkgYnkgdGhlIHBhcnRpY2xlIGFuaW1hdGlvbiBzZXQgd2hlbiBkZXRlcm1pbmluZyB0aGUgcmVxdWlyZW1lbnRzIG9mIHRoZSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSBBR0FMLlxuXHQgKi9cblx0cHVibGljIF9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmcocGFydGljbGVBbmltYXRpb25TZXQ6UGFydGljbGVBbmltYXRpb25TZXQpXG5cdHtcblxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlTm9kZUJhc2U7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleNodeBase.ts b/lib/animators/nodes/ParticleNodeBase.ts
new file mode 100644
index 000000000..4bdf0a66c
--- /dev/null
+++ b/lib/animators/nodes/ParticleNodeBase.ts
@@ -0,0 +1,143 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+
+/**
+ * Provides an abstract base class for particle animation nodes.
+ */
+class ParticleNodeBase extends AnimationNodeBase
+{
+ private _priority:number /*int*/;
+
+ public _pMode:number /*uint*/;
+ public _pDataLength:number /*uint*/ = 3;
+ public _pOneData:Array;
+
+ public _iDataOffset:number /*uint*/;
+
+ //modes alias
+ private static GLOBAL:string = 'Global';
+ private static LOCAL_STATIC:string = 'LocalStatic';
+ private static LOCAL_DYNAMIC:string = 'LocalDynamic';
+
+ //modes list
+ private static MODES:Object =
+ {
+ 0:ParticleNodeBase.GLOBAL,
+ 1:ParticleNodeBase.LOCAL_STATIC,
+ 2:ParticleNodeBase.LOCAL_DYNAMIC
+ };
+
+ /**
+ * Returns the property mode of the particle animation node. Typically set in the node constructor
+ *
+ * @see away.animators.ParticlePropertiesMode
+ */
+ public get mode():number /*uint*/
+ {
+ return this._pMode;
+ }
+
+ /**
+ * Returns the priority of the particle animation node, used to order the agal generated in a particle animation set. Set automatically on instantiation.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #getAGALVertexCode
+ */
+ public get priority():number /*int*/
+ {
+ return this._priority;
+ }
+
+ /**
+ * Returns the length of the data used by the node when in LOCAL_STATIC
mode. Used to generate the local static data of the particle animation set.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #getAGALVertexCode
+ */
+ public get dataLength():number /*int*/
+ {
+ return this._pDataLength;
+ }
+
+ /**
+ * Returns the generated data vector of the node after one particle pass during the generation of all local static data of the particle animation set.
+ *
+ * @see away.animators.ParticleAnimationSet
+ * @see #generatePropertyOfOneParticle
+ */
+ public get oneData():Array
+ {
+ return this._pOneData;
+ }
+
+ /**
+ * Creates a new ParticleNodeBase
object.
+ *
+ * @param name Defines the generic name of the particle animation node.
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param dataLength Defines the length of the data used by the node when in LOCAL_STATIC
mode.
+ * @param [optional] priority the priority of the particle animation node, used to order the agal generated in a particle animation set. Defaults to 1.
+ */
+ constructor(name:string, mode:number /*uint*/, dataLength:number /*uint*/, priority:number /*int*/ = 1)
+ {
+ super();
+
+ name = name + ParticleNodeBase.MODES[mode];
+
+ this.name = name;
+ this._pMode = mode;
+ this._priority = priority;
+ this._pDataLength = dataLength;
+
+ this._pOneData = new Array(this._pDataLength);
+ }
+
+ /**
+ * Returns the AGAL code of the particle animation node for use in the vertex shader.
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ return "";
+ }
+
+ /**
+ * Returns the AGAL code of the particle animation node for use in the fragment shader.
+ */
+ public getAGALFragmentCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ return "";
+ }
+
+ /**
+ * Returns the AGAL code of the particle animation node for use in the fragment shader when UV coordinates are required.
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ return "";
+ }
+
+ /**
+ * Called internally by the particle animation set when assigning the set of static properties originally defined by the initParticleFunc of the set.
+ *
+ * @see away.animators.ParticleAnimationSet#initParticleFunc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+
+ }
+
+ /**
+ * Called internally by the particle animation set when determining the requirements of the particle animation node AGAL.
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+
+ }
+}
+
+export = ParticleNodeBase;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleOrbitNode.js b/lib/animators/nodes/ParticleOrbitNode.js
new file mode 100755
index 000000000..09530b120
--- /dev/null
+++ b/lib/animators/nodes/ParticleOrbitNode.js
@@ -0,0 +1,130 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleOrbitState = require("awayjs-renderergl/lib/animators/states/ParticleOrbitState");
+/**
+ * A particle animation node used to control the position of a particle over time around a circular orbit.
+ */
+var ParticleOrbitNode = (function (_super) {
+ __extends(ParticleOrbitNode, _super);
+ /**
+ * Creates a new ParticleOrbitNode
object.
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesEulers Defines whether the node uses the eulers
property in the shader to calculate a rotation on the orbit. Defaults to true.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of the orbit independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the cycle rotation of the particle. Defaults to false.
+ * @param [optional] radius Defines the radius of the orbit when in global mode. Defaults to 100.
+ * @param [optional] cycleDuration Defines the duration of the orbit in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the phase of the orbit in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ * @param [optional] eulers Defines the euler rotation in degrees, applied to the orientation of the orbit when in global mode.
+ */
+ function ParticleOrbitNode(mode /*uint*/, usesEulers, usesCycle, usesPhase, radius, cycleDuration, cyclePhase, eulers) {
+ if (usesEulers === void 0) { usesEulers = true; }
+ if (usesCycle === void 0) { usesCycle = false; }
+ if (usesPhase === void 0) { usesPhase = false; }
+ if (radius === void 0) { radius = 100; }
+ if (cycleDuration === void 0) { cycleDuration = 1; }
+ if (cyclePhase === void 0) { cyclePhase = 0; }
+ if (eulers === void 0) { eulers = null; }
+ var len = 3;
+ if (usesPhase)
+ len++;
+ _super.call(this, "ParticleOrbit", mode, len);
+ this._pStateClass = ParticleOrbitState;
+ this._iUsesEulers = usesEulers;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+ this._iRadius = radius;
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ this._iEulers = eulers || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleOrbitNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var orbitRegister = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleOrbitState.ORBIT_INDEX, orbitRegister.index);
+ var eulersMatrixRegister = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleOrbitState.EULERS_INDEX, eulersMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ var temp1 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var distance = new ShaderRegisterElement(temp1.regName, temp1.index);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ var cos = new ShaderRegisterElement(temp2.regName, temp2.index, 0);
+ var sin = new ShaderRegisterElement(temp2.regName, temp2.index, 1);
+ var degree = new ShaderRegisterElement(temp2.regName, temp2.index, 2);
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ var code = "";
+ if (this._iUsesCycle) {
+ code += "mul " + degree + "," + animationRegisterCache.vertexTime + "," + orbitRegister + ".y\n";
+ if (this._iUsesPhase)
+ code += "add " + degree + "," + degree + "," + orbitRegister + ".w\n";
+ }
+ else
+ code += "mul " + degree + "," + animationRegisterCache.vertexLife + "," + orbitRegister + ".y\n";
+ code += "cos " + cos + "," + degree + "\n";
+ code += "sin " + sin + "," + degree + "\n";
+ code += "mul " + distance + ".x," + cos + "," + orbitRegister + ".x\n";
+ code += "mul " + distance + ".y," + sin + "," + orbitRegister + ".x\n";
+ code += "mov " + distance + ".wz" + animationRegisterCache.vertexZeroConst + "\n";
+ if (this._iUsesEulers)
+ code += "m44 " + distance + "," + distance + "," + eulersMatrixRegister + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ if (animationRegisterCache.needVelocity) {
+ code += "neg " + distance + ".x," + sin + "\n";
+ code += "mov " + distance + ".y," + cos + "\n";
+ code += "mov " + distance + ".zw," + animationRegisterCache.vertexZeroConst + "\n";
+ if (this._iUsesEulers)
+ code += "m44 " + distance + "," + distance + "," + eulersMatrixRegister + "\n";
+ code += "mul " + distance + "," + distance + "," + orbitRegister + ".z\n";
+ code += "div " + distance + "," + distance + "," + orbitRegister + ".y\n";
+ if (!this._iUsesCycle)
+ code += "div " + distance + "," + distance + "," + animationRegisterCache.vertexLife + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleOrbitNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleOrbitNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ //Vector3D.x is radius, Vector3D.y is cycle duration, Vector3D.z is phase
+ var orbit = param[ParticleOrbitNode.ORBIT_VECTOR3D];
+ if (!orbit)
+ throw new Error("there is no " + ParticleOrbitNode.ORBIT_VECTOR3D + " in param!");
+ this._pOneData[0] = orbit.x;
+ if (this._iUsesCycle && orbit.y <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._pOneData[1] = Math.PI * 2 / (!this._iUsesCycle ? 1 : orbit.y);
+ this._pOneData[2] = orbit.x * Math.PI * 2;
+ if (this._iUsesPhase)
+ this._pOneData[3] = orbit.z * Math.PI / 180;
+ };
+ /**
+ * Reference for orbit node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the radius (x), cycle speed (y) and cycle phase (z) of the motion on the particle.
+ */
+ ParticleOrbitNode.ORBIT_VECTOR3D = "OrbitVector3D";
+ return ParticleOrbitNode;
+})(ParticleNodeBase);
+module.exports = ParticleOrbitNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZW9yYml0bm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZU9yYml0Tm9kZSIsIlBhcnRpY2xlT3JiaXROb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVPcmJpdE5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZU9yYml0Tm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlT3JiaXROb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csaUJBQWlCO0lBQVNBLFVBQTFCQSxpQkFBaUJBLFVBQXlCQTtJQTBCL0NBOzs7Ozs7Ozs7OztPQVdHQTtJQUNIQSxTQXRDS0EsaUJBQWlCQSxDQXNDVkEsSUFBSUEsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsVUFBeUJBLEVBQUVBLFNBQXlCQSxFQUFFQSxTQUF5QkEsRUFBRUEsTUFBbUJBLEVBQUVBLGFBQXdCQSxFQUFFQSxVQUFxQkEsRUFBRUEsTUFBc0JBO1FBQTdLQywwQkFBeUJBLEdBQXpCQSxpQkFBeUJBO1FBQUVBLHlCQUF5QkEsR0FBekJBLGlCQUF5QkE7UUFBRUEseUJBQXlCQSxHQUF6QkEsaUJBQXlCQTtRQUFFQSxzQkFBbUJBLEdBQW5CQSxZQUFtQkE7UUFBRUEsNkJBQXdCQSxHQUF4QkEsaUJBQXdCQTtRQUFFQSwwQkFBcUJBLEdBQXJCQSxjQUFxQkE7UUFBRUEsc0JBQXNCQSxHQUF0QkEsYUFBc0JBO1FBRTlNQSxJQUFJQSxHQUFHQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7UUFDM0JBLEVBQUVBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBO1lBQ2JBLEdBQUdBLEVBQUVBLENBQUNBO1FBQ1BBLGtCQUFNQSxlQUFlQSxFQUFFQSxJQUFJQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVsQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0Esa0JBQWtCQSxDQUFDQTtRQUV2Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsVUFBVUEsQ0FBQ0E7UUFDL0JBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLFNBQVNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxTQUFTQSxDQUFDQTtRQUU3QkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFDdkJBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLGFBQWFBLENBQUNBO1FBQ3JDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxVQUFVQSxDQUFDQTtRQUMvQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSw2Q0FBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLGFBQWFBLEdBQXlCQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxJQUFJQSxzQkFBc0JBLENBQUNBLE1BQU1BLENBQUNBLEdBQUVBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxHQUFHQSxzQkFBc0JBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7UUFDM0xBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxrQkFBa0JBLENBQUNBLFdBQVdBLEVBQUVBLGFBQWFBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBRW5HQSxJQUFJQSxvQkFBb0JBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFDaEdBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxrQkFBa0JBLENBQUNBLFlBQVlBLEVBQUVBLG9CQUFvQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDM0dBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUMvQ0Esc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO1FBQy9DQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFFL0NBLElBQUlBLEtBQUtBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDbkZBLHNCQUFzQkEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNyREEsSUFBSUEsUUFBUUEsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsRUFBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFFM0ZBLElBQUlBLEtBQUtBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDbkZBLElBQUlBLEdBQUdBLEdBQXlCQSxJQUFJQSxxQkFBcUJBLENBQUNBLEtBQUtBLENBQUNBLE9BQU9BLEVBQUVBLEtBQUtBLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQ3pGQSxJQUFJQSxHQUFHQSxHQUF5QkEsSUFBSUEscUJBQXFCQSxDQUFDQSxLQUFLQSxDQUFDQSxPQUFPQSxFQUFFQSxLQUFLQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN6RkEsSUFBSUEsTUFBTUEsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsRUFBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUZBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUVwREEsSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFFckJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1lBRWpHQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDcEJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBQ3hFQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUNMQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBRWxHQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzQ0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0NBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBQ3ZFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxhQUFhQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUN2RUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsS0FBS0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNsRkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0E7WUFDckJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLG9CQUFvQkEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDaEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsT0FBT0EsR0FBR0EsUUFBUUEsR0FBR0EsT0FBT0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUV6SUEsRUFBRUEsQ0FBQ0EsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDL0NBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO1lBQy9DQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQ25GQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQTtnQkFDckJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLG9CQUFvQkEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDaEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1lBQzFFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxhQUFhQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUMxRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7Z0JBQ3JCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBO1lBQzdGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsT0FBT0EsR0FBR0EsUUFBUUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDMUlBLENBQUNBO1FBQ0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURGOztPQUVHQTtJQUNJQSw2Q0FBaUJBLEdBQXhCQSxVQUF5QkEsUUFBcUJBO1FBRTdDRyxNQUFNQSxDQUFzQkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUM5REEsQ0FBQ0E7SUFFREg7O09BRUdBO0lBQ0lBLDJEQUErQkEsR0FBdENBLFVBQXVDQSxLQUF3QkE7UUFFOURJLEFBQ0FBLHlFQUR5RUE7WUFDckVBLEtBQUtBLEdBQVlBLEtBQUtBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFDN0RBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBO1lBQ1ZBLE1BQU1BLElBQUlBLEtBQUtBLENBQUNBLGNBQWNBLEdBQUdBLGlCQUFpQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsWUFBWUEsQ0FBQ0EsQ0FBQ0E7UUFFbkZBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQzVCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxJQUFJQSxLQUFLQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNwQ0EsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsOENBQThDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNsRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBRUEsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDL0RBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLENBQUNBLENBQUNBO1FBQ3RDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUNwQkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsR0FBR0EsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBeEhESjs7O09BR0dBO0lBQ1dBLGdDQUFjQSxHQUFVQSxlQUFlQSxDQUFDQTtJQXFIdkRBLHdCQUFDQTtBQUFEQSxDQTdJQSxBQTZJQ0EsRUE3SStCLGdCQUFnQixFQTZJL0M7QUFFRCxBQUEyQixpQkFBbEIsaUJBQWlCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlT3JiaXROb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU9yYml0U3RhdGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlT3JiaXRTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gY29udHJvbCB0aGUgcG9zaXRpb24gb2YgYSBwYXJ0aWNsZSBvdmVyIHRpbWUgYXJvdW5kIGEgY2lyY3VsYXIgb3JiaXQuXG4gKi9cbmNsYXNzIFBhcnRpY2xlT3JiaXROb2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc0V1bGVyczpib29sZWFuO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzQ3ljbGU6Ym9vbGVhbjtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc1BoYXNlOmJvb2xlYW47XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVJhZGl1czpudW1iZXI7XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lDeWNsZUR1cmF0aW9uOm51bWJlcjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUN5Y2xlUGhhc2U6bnVtYmVyO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pRXVsZXJzOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIG9yYml0IG5vZGUgcHJvcGVydGllcyBvbiBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPlZlY3RvcjNEPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSByYWRpdXMgKHgpLCBjeWNsZSBzcGVlZCAoeSkgYW5kIGN5Y2xlIHBoYXNlICh6KSBvZiB0aGUgbW90aW9uIG9uIHRoZSBwYXJ0aWNsZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgT1JCSVRfVkVDVE9SM0Q6c3RyaW5nID0gXCJPcmJpdFZlY3RvcjNEXCI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVPcmJpdE5vZGU8L2NvZGU+IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtICAgICAgICAgICAgICAgbW9kZSAgICAgICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbW9kZSBvZiBvcGVyYXRpb24gYWN0cyBvbiBsb2NhbCBwcm9wZXJ0aWVzIG9mIGEgcGFydGljbGUgb3IgZ2xvYmFsIHByb3BlcnRpZXMgb2YgdGhlIG5vZGUuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNFdWxlcnMgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIG5vZGUgdXNlcyB0aGUgPGNvZGU+ZXVsZXJzPC9jb2RlPiBwcm9wZXJ0eSBpbiB0aGUgc2hhZGVyIHRvIGNhbGN1bGF0ZSBhIHJvdGF0aW9uIG9uIHRoZSBvcmJpdC4gRGVmYXVsdHMgdG8gdHJ1ZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdXNlc0N5Y2xlICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbm9kZSB1c2VzIHRoZSA8Y29kZT5jeWNsZUR1cmF0aW9uPC9jb2RlPiBwcm9wZXJ0eSBpbiB0aGUgc2hhZGVyIHRvIGNhbGN1bGF0ZSB0aGUgcGVyaW9kIG9mIHRoZSBvcmJpdCBpbmRlcGVuZGVudCBvZiBwYXJ0aWNsZSBkdXJhdGlvbi4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNQaGFzZSAgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIG5vZGUgdXNlcyB0aGUgPGNvZGU+Y3ljbGVQaGFzZTwvY29kZT4gcHJvcGVydHkgaW4gdGhlIHNoYWRlciB0byBjYWxjdWxhdGUgYSBzdGFydGluZyBvZmZzZXQgdG8gdGhlIGN5Y2xlIHJvdGF0aW9uIG9mIHRoZSBwYXJ0aWNsZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHJhZGl1cyAgICAgICAgICBEZWZpbmVzIHRoZSByYWRpdXMgb2YgdGhlIG9yYml0IHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEwMC5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gY3ljbGVEdXJhdGlvbiAgIERlZmluZXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBvcmJpdCBpbiBzZWNvbmRzLCB1c2VkIGFzIGEgcGVyaW9kIGluZGVwZW5kZW50IG9mIHBhcnRpY2xlIGR1cmF0aW9uIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIGN5Y2xlUGhhc2UgICAgICBEZWZpbmVzIHRoZSBwaGFzZSBvZiB0aGUgb3JiaXQgaW4gZGVncmVlcywgdXNlZCBhcyB0aGUgc3RhcnRpbmcgb2Zmc2V0IG9mIHRoZSBjeWNsZSB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAwLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBldWxlcnMgICAgICAgICAgRGVmaW5lcyB0aGUgZXVsZXIgcm90YXRpb24gaW4gZGVncmVlcywgYXBwbGllZCB0byB0aGUgb3JpZW50YXRpb24gb2YgdGhlIG9yYml0IHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihtb2RlOm51bWJlciAvKnVpbnQqLywgdXNlc0V1bGVyczpib29sZWFuID0gdHJ1ZSwgdXNlc0N5Y2xlOmJvb2xlYW4gPSBmYWxzZSwgdXNlc1BoYXNlOmJvb2xlYW4gPSBmYWxzZSwgcmFkaXVzOm51bWJlciA9IDEwMCwgY3ljbGVEdXJhdGlvbjpudW1iZXIgPSAxLCBjeWNsZVBoYXNlOm51bWJlciA9IDAsIGV1bGVyczpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHR2YXIgbGVuOm51bWJlciAvKmludCovID0gMztcblx0XHRpZiAodXNlc1BoYXNlKVxuXHRcdFx0bGVuKys7XG5cdFx0c3VwZXIoXCJQYXJ0aWNsZU9yYml0XCIsIG1vZGUsIGxlbik7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFBhcnRpY2xlT3JiaXRTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzRXVsZXJzID0gdXNlc0V1bGVycztcblx0XHR0aGlzLl9pVXNlc0N5Y2xlID0gdXNlc0N5Y2xlO1xuXHRcdHRoaXMuX2lVc2VzUGhhc2UgPSB1c2VzUGhhc2U7XG5cblx0XHR0aGlzLl9pUmFkaXVzID0gcmFkaXVzO1xuXHRcdHRoaXMuX2lDeWNsZUR1cmF0aW9uID0gY3ljbGVEdXJhdGlvbjtcblx0XHR0aGlzLl9pQ3ljbGVQaGFzZSA9IGN5Y2xlUGhhc2U7XG5cdFx0dGhpcy5faUV1bGVycyA9IGV1bGVycyB8fCBuZXcgVmVjdG9yM0QoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIG9yYml0UmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gKHRoaXMuX3BNb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKT8gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZU9yYml0U3RhdGUuT1JCSVRfSU5ERVgsIG9yYml0UmVnaXN0ZXIuaW5kZXgpO1xuXG5cdFx0dmFyIGV1bGVyc01hdHJpeFJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlT3JiaXRTdGF0ZS5FVUxFUlNfSU5ERVgsIGV1bGVyc01hdHJpeFJlZ2lzdGVyLmluZGV4KTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblxuXHRcdHZhciB0ZW1wMTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAxLCAxKTtcblx0XHR2YXIgZGlzdGFuY2U6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh0ZW1wMS5yZWdOYW1lLCB0ZW1wMS5pbmRleCk7XG5cblx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdHZhciBjb3M6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh0ZW1wMi5yZWdOYW1lLCB0ZW1wMi5pbmRleCwgMCk7XG5cdFx0dmFyIHNpbjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAyLnJlZ05hbWUsIHRlbXAyLmluZGV4LCAxKTtcblx0XHR2YXIgZGVncmVlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcDIucmVnTmFtZSwgdGVtcDIuaW5kZXgsIDIpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXAxKTtcblxuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cblx0XHRpZiAodGhpcy5faVVzZXNDeWNsZSkge1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGRlZ3JlZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyBvcmJpdFJlZ2lzdGVyICsgXCIueVxcblwiO1xuXG5cdFx0XHRpZiAodGhpcy5faVVzZXNQaGFzZSlcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGRlZ3JlZSArIFwiLFwiICsgZGVncmVlICsgXCIsXCIgKyBvcmJpdFJlZ2lzdGVyICsgXCIud1xcblwiO1xuXHRcdH0gZWxzZVxuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGRlZ3JlZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhMaWZlICsgXCIsXCIgKyBvcmJpdFJlZ2lzdGVyICsgXCIueVxcblwiO1xuXG5cdFx0Y29kZSArPSBcImNvcyBcIiArIGNvcyArIFwiLFwiICsgZGVncmVlICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwic2luIFwiICsgc2luICsgXCIsXCIgKyBkZWdyZWUgKyBcIlxcblwiO1xuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBkaXN0YW5jZSArIFwiLngsXCIgKyBjb3MgKyBcIixcIiArIG9yYml0UmVnaXN0ZXIgKyBcIi54XFxuXCI7XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIGRpc3RhbmNlICsgXCIueSxcIiArIHNpbiArIFwiLFwiICsgb3JiaXRSZWdpc3RlciArIFwiLnhcXG5cIjtcblx0XHRjb2RlICs9IFwibW92IFwiICsgZGlzdGFuY2UgKyBcIi53elwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdGlmICh0aGlzLl9pVXNlc0V1bGVycylcblx0XHRcdGNvZGUgKz0gXCJtNDQgXCIgKyBkaXN0YW5jZSArIFwiLFwiICsgZGlzdGFuY2UgKyBcIixcIiArIGV1bGVyc01hdHJpeFJlZ2lzdGVyICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5eixcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5elxcblwiO1xuXG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFZlbG9jaXR5KSB7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgZGlzdGFuY2UgKyBcIi54LFwiICsgc2luICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBkaXN0YW5jZSArIFwiLnksXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIGRpc3RhbmNlICsgXCIuencsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRpZiAodGhpcy5faVVzZXNFdWxlcnMpXG5cdFx0XHRcdGNvZGUgKz0gXCJtNDQgXCIgKyBkaXN0YW5jZSArIFwiLFwiICsgZGlzdGFuY2UgKyBcIixcIiArIGV1bGVyc01hdHJpeFJlZ2lzdGVyICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBkaXN0YW5jZSArIFwiLFwiICsgZGlzdGFuY2UgKyBcIixcIiArIG9yYml0UmVnaXN0ZXIgKyBcIi56XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiZGl2IFwiICsgZGlzdGFuY2UgKyBcIixcIiArIGRpc3RhbmNlICsgXCIsXCIgKyBvcmJpdFJlZ2lzdGVyICsgXCIueVxcblwiO1xuXHRcdFx0aWYgKCF0aGlzLl9pVXNlc0N5Y2xlKVxuXHRcdFx0XHRjb2RlICs9IFwiZGl2IFwiICsgZGlzdGFuY2UgKyBcIixcIiArIGRpc3RhbmNlICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleExpZmUgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVsb2NpdHlUYXJnZXQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlbG9jaXR5VGFyZ2V0ICsgXCIueHl6LFwiICsgZGlzdGFuY2UgKyBcIi54eXpcXG5cIjtcblx0XHR9XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlT3JiaXRTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZU9yYml0U3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZShwYXJhbTpQYXJ0aWNsZVByb3BlcnRpZXMpXG5cdHtcblx0XHQvL1ZlY3RvcjNELnggaXMgcmFkaXVzLCBWZWN0b3IzRC55IGlzIGN5Y2xlIGR1cmF0aW9uLCBWZWN0b3IzRC56IGlzIHBoYXNlXG5cdFx0dmFyIG9yYml0OlZlY3RvcjNEID0gcGFyYW1bUGFydGljbGVPcmJpdE5vZGUuT1JCSVRfVkVDVE9SM0RdO1xuXHRcdGlmICghb3JiaXQpXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ0aGVyZSBpcyBubyBcIiArIFBhcnRpY2xlT3JiaXROb2RlLk9SQklUX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpO1xuXG5cdFx0dGhpcy5fcE9uZURhdGFbMF0gPSBvcmJpdC54O1xuXHRcdGlmICh0aGlzLl9pVXNlc0N5Y2xlICYmIG9yYml0LnkgPD0gMClcblx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHR0aGlzLl9wT25lRGF0YVsxXSA9IE1hdGguUEkqMi8oIXRoaXMuX2lVc2VzQ3ljbGU/IDEgOiBvcmJpdC55KTtcblx0XHR0aGlzLl9wT25lRGF0YVsyXSA9IG9yYml0LngqTWF0aC5QSSoyO1xuXHRcdGlmICh0aGlzLl9pVXNlc1BoYXNlKVxuXHRcdFx0dGhpcy5fcE9uZURhdGFbM10gPSBvcmJpdC56Kk1hdGguUEkvMTgwO1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlT3JiaXROb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleOrbitNode.ts b/lib/animators/nodes/ParticleOrbitNode.ts
new file mode 100644
index 000000000..f56e8c6cc
--- /dev/null
+++ b/lib/animators/nodes/ParticleOrbitNode.ts
@@ -0,0 +1,159 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleOrbitState = require("awayjs-renderergl/lib/animators/states/ParticleOrbitState");
+
+/**
+ * A particle animation node used to control the position of a particle over time around a circular orbit.
+ */
+class ParticleOrbitNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesEulers:boolean;
+
+ /** @private */
+ public _iUsesCycle:boolean;
+
+ /** @private */
+ public _iUsesPhase:boolean;
+
+ /** @private */
+ public _iRadius:number;
+ /** @private */
+ public _iCycleDuration:number;
+ /** @private */
+ public _iCyclePhase:number;
+ /** @private */
+ public _iEulers:Vector3D;
+
+ /**
+ * Reference for orbit node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the radius (x), cycle speed (y) and cycle phase (z) of the motion on the particle.
+ */
+ public static ORBIT_VECTOR3D:string = "OrbitVector3D";
+
+ /**
+ * Creates a new ParticleOrbitNode
object.
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesEulers Defines whether the node uses the eulers
property in the shader to calculate a rotation on the orbit. Defaults to true.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of the orbit independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the cycle rotation of the particle. Defaults to false.
+ * @param [optional] radius Defines the radius of the orbit when in global mode. Defaults to 100.
+ * @param [optional] cycleDuration Defines the duration of the orbit in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the phase of the orbit in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ * @param [optional] eulers Defines the euler rotation in degrees, applied to the orientation of the orbit when in global mode.
+ */
+ constructor(mode:number /*uint*/, usesEulers:boolean = true, usesCycle:boolean = false, usesPhase:boolean = false, radius:number = 100, cycleDuration:number = 1, cyclePhase:number = 0, eulers:Vector3D = null)
+ {
+ var len:number /*int*/ = 3;
+ if (usesPhase)
+ len++;
+ super("ParticleOrbit", mode, len);
+
+ this._pStateClass = ParticleOrbitState;
+
+ this._iUsesEulers = usesEulers;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+
+ this._iRadius = radius;
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ this._iEulers = eulers || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var orbitRegister:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleOrbitState.ORBIT_INDEX, orbitRegister.index);
+
+ var eulersMatrixRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleOrbitState.EULERS_INDEX, eulersMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+
+ var temp1:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var distance:ShaderRegisterElement = new ShaderRegisterElement(temp1.regName, temp1.index);
+
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var cos:ShaderRegisterElement = new ShaderRegisterElement(temp2.regName, temp2.index, 0);
+ var sin:ShaderRegisterElement = new ShaderRegisterElement(temp2.regName, temp2.index, 1);
+ var degree:ShaderRegisterElement = new ShaderRegisterElement(temp2.regName, temp2.index, 2);
+ animationRegisterCache.removeVertexTempUsage(temp1);
+
+ var code:string = "";
+
+ if (this._iUsesCycle) {
+ code += "mul " + degree + "," + animationRegisterCache.vertexTime + "," + orbitRegister + ".y\n";
+
+ if (this._iUsesPhase)
+ code += "add " + degree + "," + degree + "," + orbitRegister + ".w\n";
+ } else
+ code += "mul " + degree + "," + animationRegisterCache.vertexLife + "," + orbitRegister + ".y\n";
+
+ code += "cos " + cos + "," + degree + "\n";
+ code += "sin " + sin + "," + degree + "\n";
+ code += "mul " + distance + ".x," + cos + "," + orbitRegister + ".x\n";
+ code += "mul " + distance + ".y," + sin + "," + orbitRegister + ".x\n";
+ code += "mov " + distance + ".wz" + animationRegisterCache.vertexZeroConst + "\n";
+ if (this._iUsesEulers)
+ code += "m44 " + distance + "," + distance + "," + eulersMatrixRegister + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+
+ if (animationRegisterCache.needVelocity) {
+ code += "neg " + distance + ".x," + sin + "\n";
+ code += "mov " + distance + ".y," + cos + "\n";
+ code += "mov " + distance + ".zw," + animationRegisterCache.vertexZeroConst + "\n";
+ if (this._iUsesEulers)
+ code += "m44 " + distance + "," + distance + "," + eulersMatrixRegister + "\n";
+ code += "mul " + distance + "," + distance + "," + orbitRegister + ".z\n";
+ code += "div " + distance + "," + distance + "," + orbitRegister + ".y\n";
+ if (!this._iUsesCycle)
+ code += "div " + distance + "," + distance + "," + animationRegisterCache.vertexLife + "\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz\n";
+ }
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleOrbitState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ //Vector3D.x is radius, Vector3D.y is cycle duration, Vector3D.z is phase
+ var orbit:Vector3D = param[ParticleOrbitNode.ORBIT_VECTOR3D];
+ if (!orbit)
+ throw new Error("there is no " + ParticleOrbitNode.ORBIT_VECTOR3D + " in param!");
+
+ this._pOneData[0] = orbit.x;
+ if (this._iUsesCycle && orbit.y <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._pOneData[1] = Math.PI*2/(!this._iUsesCycle? 1 : orbit.y);
+ this._pOneData[2] = orbit.x*Math.PI*2;
+ if (this._iUsesPhase)
+ this._pOneData[3] = orbit.z*Math.PI/180;
+ }
+}
+
+export = ParticleOrbitNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleOscillatorNode.js b/lib/animators/nodes/ParticleOscillatorNode.js
new file mode 100755
index 000000000..e67ce1a21
--- /dev/null
+++ b/lib/animators/nodes/ParticleOscillatorNode.js
@@ -0,0 +1,85 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleOscillatorState = require("awayjs-renderergl/lib/animators/states/ParticleOscillatorState");
+/**
+ * A particle animation node used to control the position of a particle over time using simple harmonic motion.
+ */
+var ParticleOscillatorNode = (function (_super) {
+ __extends(ParticleOscillatorNode, _super);
+ /**
+ * Creates a new ParticleOscillatorNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] oscillator Defines the default oscillator axis (x, y, z) and cycleDuration (w) of the node, used when in global mode.
+ */
+ function ParticleOscillatorNode(mode /*uint*/, oscillator) {
+ if (oscillator === void 0) { oscillator = null; }
+ _super.call(this, "ParticleOscillator", mode, 4);
+ this._pStateClass = ParticleOscillatorState;
+ this._iOscillator = oscillator || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleOscillatorNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var oscillatorRegister = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleOscillatorState.OSCILLATOR_INDEX, oscillatorRegister.index);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ var dgree = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var sin = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var cos = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ var distance = new ShaderRegisterElement(temp2.regName, temp2.index);
+ animationRegisterCache.removeVertexTempUsage(temp);
+ var code = "";
+ code += "mul " + dgree + "," + animationRegisterCache.vertexTime + "," + oscillatorRegister + ".w\n";
+ code += "sin " + sin + "," + dgree + "\n";
+ code += "mul " + distance + ".xyz," + sin + "," + oscillatorRegister + ".xyz\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ if (animationRegisterCache.needVelocity) {
+ code += "cos " + cos + "," + dgree + "\n";
+ code += "mul " + distance + ".xyz," + cos + "," + oscillatorRegister + ".xyz\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleOscillatorNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleOscillatorNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ //(Vector3D.x,Vector3D.y,Vector3D.z) is oscillator axis, Vector3D.w is oscillator cycle duration
+ var drift = param[ParticleOscillatorNode.OSCILLATOR_VECTOR3D];
+ if (!drift)
+ throw (new Error("there is no " + ParticleOscillatorNode.OSCILLATOR_VECTOR3D + " in param!"));
+ this._pOneData[0] = drift.x;
+ this._pOneData[1] = drift.y;
+ this._pOneData[2] = drift.z;
+ if (drift.w <= 0)
+ throw (new Error("the cycle duration must greater than zero"));
+ this._pOneData[3] = Math.PI * 2 / drift.w;
+ };
+ /**
+ * Reference for ocsillator node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the axis (x,y,z) and cycle speed (w) of the motion on the particle.
+ */
+ ParticleOscillatorNode.OSCILLATOR_VECTOR3D = "OscillatorVector3D";
+ return ParticleOscillatorNode;
+})(ParticleNodeBase);
+module.exports = ParticleOscillatorNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZW9zY2lsbGF0b3Jub2RlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlT3NjaWxsYXRvck5vZGUiLCJQYXJ0aWNsZU9zY2lsbGF0b3JOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVPc2NpbGxhdG9yTm9kZS5nZXRBR0FMVmVydGV4Q29kZSIsIlBhcnRpY2xlT3NjaWxsYXRvck5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiLCJQYXJ0aWNsZU9zY2lsbGF0b3JOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sdUJBQXVCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUU3RyxBQUdBOztHQURHO0lBQ0csc0JBQXNCO0lBQVNBLFVBQS9CQSxzQkFBc0JBLFVBQXlCQTtJQVdwREE7Ozs7O09BS0dBO0lBQ0hBLFNBakJLQSxzQkFBc0JBLENBaUJmQSxJQUFJQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxVQUEwQkE7UUFBMUJDLDBCQUEwQkEsR0FBMUJBLGlCQUEwQkE7UUFFM0RBLGtCQUFNQSxvQkFBb0JBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBRXJDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSx1QkFBdUJBLENBQUNBO1FBRTVDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxVQUFVQSxJQUFJQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtJQUNsREEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLGtEQUFpQkEsR0FBeEJBLFVBQXlCQSxZQUE2QkEsRUFBRUEsc0JBQTZDQTtRQUVwR0UsSUFBSUEsa0JBQWtCQSxHQUF5QkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsSUFBSUEsc0JBQXNCQSxDQUFDQSxNQUFNQSxDQUFDQSxHQUFFQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxzQkFBc0JBLEVBQUVBLENBQUNBO1FBQ2hNQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsRUFBRUEsdUJBQXVCQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLGtCQUFrQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDbEhBLElBQUlBLElBQUlBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDbEZBLElBQUlBLEtBQUtBLEdBQXlCQSxJQUFJQSxxQkFBcUJBLENBQUNBLElBQUlBLENBQUNBLE9BQU9BLEVBQUVBLElBQUlBLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQ3pGQSxJQUFJQSxHQUFHQSxHQUF5QkEsSUFBSUEscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxFQUFFQSxJQUFJQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN2RkEsSUFBSUEsR0FBR0EsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsRUFBRUEsSUFBSUEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDdkZBLHNCQUFzQkEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNwREEsSUFBSUEsS0FBS0EsR0FBeUJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUNuRkEsSUFBSUEsUUFBUUEsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsRUFBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDM0ZBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUVuREEsSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsVUFBVUEsR0FBR0EsR0FBR0EsR0FBR0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUNyR0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDMUNBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE9BQU9BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLGtCQUFrQkEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDaEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsT0FBT0EsR0FBR0EsUUFBUUEsR0FBR0EsT0FBT0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUV6SUEsRUFBRUEsQ0FBQ0EsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDMUNBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE9BQU9BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLGtCQUFrQkEsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFDaEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsT0FBT0EsR0FBR0EsUUFBUUEsR0FBR0EsT0FBT0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUMxSUEsQ0FBQ0E7UUFFREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFREY7O09BRUdBO0lBQ0lBLGtEQUFpQkEsR0FBeEJBLFVBQXlCQSxRQUFxQkE7UUFFN0NHLE1BQU1BLENBQTJCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ25FQSxDQUFDQTtJQUVESDs7T0FFR0E7SUFDSUEsZ0VBQStCQSxHQUF0Q0EsVUFBdUNBLEtBQXdCQTtRQUU5REksQUFDQUEsZ0dBRGdHQTtZQUM1RkEsS0FBS0EsR0FBWUEsS0FBS0EsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxtQkFBbUJBLENBQUNBLENBQUNBO1FBQ3ZFQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQTtZQUNWQSxNQUFLQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSxjQUFjQSxHQUFHQSxzQkFBc0JBLENBQUNBLG1CQUFtQkEsR0FBR0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFOUZBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM1QkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ2hCQSxNQUFLQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSwyQ0FBMkNBLENBQUNBLENBQUNBLENBQUNBO1FBQy9EQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFDQSxDQUFDQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUN2Q0EsQ0FBQ0E7SUE1RURKOzs7T0FHR0E7SUFDV0EsMENBQW1CQSxHQUFVQSxvQkFBb0JBLENBQUNBO0lBeUVqRUEsNkJBQUNBO0FBQURBLENBbEZBLEFBa0ZDQSxFQWxGb0MsZ0JBQWdCLEVBa0ZwRDtBQUVELEFBQWdDLGlCQUF2QixzQkFBc0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVPc2NpbGxhdG9yTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVPc2NpbGxhdG9yU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gY29udHJvbCB0aGUgcG9zaXRpb24gb2YgYSBwYXJ0aWNsZSBvdmVyIHRpbWUgdXNpbmcgc2ltcGxlIGhhcm1vbmljIG1vdGlvbi5cbiAqL1xuY2xhc3MgUGFydGljbGVPc2NpbGxhdG9yTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaU9zY2lsbGF0b3I6VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3Igb2NzaWxsYXRvciBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5WZWN0b3IzRDwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgYXhpcyAoeCx5LHopIGFuZCBjeWNsZSBzcGVlZCAodykgb2YgdGhlIG1vdGlvbiBvbiB0aGUgcGFydGljbGUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIE9TQ0lMTEFUT1JfVkVDVE9SM0Q6c3RyaW5nID0gXCJPc2NpbGxhdG9yVmVjdG9yM0RcIjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QYXJ0aWNsZU9zY2lsbGF0b3JOb2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gb3NjaWxsYXRvciAgICAgIERlZmluZXMgdGhlIGRlZmF1bHQgb3NjaWxsYXRvciBheGlzICh4LCB5LCB6KSBhbmQgY3ljbGVEdXJhdGlvbiAodykgb2YgdGhlIG5vZGUsIHVzZWQgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCBvc2NpbGxhdG9yOlZlY3RvcjNEID0gbnVsbClcblx0e1xuXHRcdHN1cGVyKFwiUGFydGljbGVPc2NpbGxhdG9yXCIsIG1vZGUsIDQpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZTtcblxuXHRcdHRoaXMuX2lPc2NpbGxhdG9yID0gb3NjaWxsYXRvciB8fCBuZXcgVmVjdG9yM0QoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIG9zY2lsbGF0b3JSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlT3NjaWxsYXRvclN0YXRlLk9TQ0lMTEFUT1JfSU5ERVgsIG9zY2lsbGF0b3JSZWdpc3Rlci5pbmRleCk7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdHZhciBkZ3JlZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMCk7XG5cdFx0dmFyIHNpbjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMSk7XG5cdFx0dmFyIGNvczpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMik7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdHZhciB0ZW1wMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGRpc3RhbmNlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcDIucmVnTmFtZSwgdGVtcDIuaW5kZXgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgZGdyZWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgb3NjaWxsYXRvclJlZ2lzdGVyICsgXCIud1xcblwiO1xuXHRcdGNvZGUgKz0gXCJzaW4gXCIgKyBzaW4gKyBcIixcIiArIGRncmVlICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgZGlzdGFuY2UgKyBcIi54eXosXCIgKyBzaW4gKyBcIixcIiArIG9zY2lsbGF0b3JSZWdpc3RlciArIFwiLnh5elxcblwiO1xuXHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnBvc2l0aW9uVGFyZ2V0ICsgXCIueHl6LFwiICsgZGlzdGFuY2UgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnBvc2l0aW9uVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cblx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5uZWVkVmVsb2NpdHkpIHtcblx0XHRcdGNvZGUgKz0gXCJjb3MgXCIgKyBjb3MgKyBcIixcIiArIGRncmVlICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBkaXN0YW5jZSArIFwiLnh5eixcIiArIGNvcyArIFwiLFwiICsgb3NjaWxsYXRvclJlZ2lzdGVyICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5eixcIiArIGRpc3RhbmNlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5elxcblwiO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlKHBhcmFtOlBhcnRpY2xlUHJvcGVydGllcylcblx0e1xuXHRcdC8vKFZlY3RvcjNELngsVmVjdG9yM0QueSxWZWN0b3IzRC56KSBpcyBvc2NpbGxhdG9yIGF4aXMsIFZlY3RvcjNELncgaXMgb3NjaWxsYXRvciBjeWNsZSBkdXJhdGlvblxuXHRcdHZhciBkcmlmdDpWZWN0b3IzRCA9IHBhcmFtW1BhcnRpY2xlT3NjaWxsYXRvck5vZGUuT1NDSUxMQVRPUl9WRUNUT1IzRF07XG5cdFx0aWYgKCFkcmlmdClcblx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZXJlIGlzIG5vIFwiICsgUGFydGljbGVPc2NpbGxhdG9yTm9kZS5PU0NJTExBVE9SX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpKTtcblxuXHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gZHJpZnQueDtcblx0XHR0aGlzLl9wT25lRGF0YVsxXSA9IGRyaWZ0Lnk7XG5cdFx0dGhpcy5fcE9uZURhdGFbMl0gPSBkcmlmdC56O1xuXHRcdGlmIChkcmlmdC53IDw9IDApXG5cdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJ0aGUgY3ljbGUgZHVyYXRpb24gbXVzdCBncmVhdGVyIHRoYW4gemVyb1wiKSk7XG5cdFx0dGhpcy5fcE9uZURhdGFbM10gPSBNYXRoLlBJKjIvZHJpZnQudztcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZU9zY2lsbGF0b3JOb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleOscillatorNode.ts b/lib/animators/nodes/ParticleOscillatorNode.ts
new file mode 100644
index 000000000..f6fb73a2b
--- /dev/null
+++ b/lib/animators/nodes/ParticleOscillatorNode.ts
@@ -0,0 +1,100 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleOscillatorState = require("awayjs-renderergl/lib/animators/states/ParticleOscillatorState");
+
+/**
+ * A particle animation node used to control the position of a particle over time using simple harmonic motion.
+ */
+class ParticleOscillatorNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iOscillator:Vector3D;
+
+ /**
+ * Reference for ocsillator node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the axis (x,y,z) and cycle speed (w) of the motion on the particle.
+ */
+ public static OSCILLATOR_VECTOR3D:string = "OscillatorVector3D";
+
+ /**
+ * Creates a new ParticleOscillatorNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] oscillator Defines the default oscillator axis (x, y, z) and cycleDuration (w) of the node, used when in global mode.
+ */
+ constructor(mode:number /*uint*/, oscillator:Vector3D = null)
+ {
+ super("ParticleOscillator", mode, 4);
+
+ this._pStateClass = ParticleOscillatorState;
+
+ this._iOscillator = oscillator || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var oscillatorRegister:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleOscillatorState.OSCILLATOR_INDEX, oscillatorRegister.index);
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var dgree:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var sin:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var cos:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var distance:ShaderRegisterElement = new ShaderRegisterElement(temp2.regName, temp2.index);
+ animationRegisterCache.removeVertexTempUsage(temp);
+
+ var code:string = "";
+ code += "mul " + dgree + "," + animationRegisterCache.vertexTime + "," + oscillatorRegister + ".w\n";
+ code += "sin " + sin + "," + dgree + "\n";
+ code += "mul " + distance + ".xyz," + sin + "," + oscillatorRegister + ".xyz\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+
+ if (animationRegisterCache.needVelocity) {
+ code += "cos " + cos + "," + dgree + "\n";
+ code += "mul " + distance + ".xyz," + cos + "," + oscillatorRegister + ".xyz\n";
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + distance + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ }
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleOscillatorState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ //(Vector3D.x,Vector3D.y,Vector3D.z) is oscillator axis, Vector3D.w is oscillator cycle duration
+ var drift:Vector3D = param[ParticleOscillatorNode.OSCILLATOR_VECTOR3D];
+ if (!drift)
+ throw(new Error("there is no " + ParticleOscillatorNode.OSCILLATOR_VECTOR3D + " in param!"));
+
+ this._pOneData[0] = drift.x;
+ this._pOneData[1] = drift.y;
+ this._pOneData[2] = drift.z;
+ if (drift.w <= 0)
+ throw(new Error("the cycle duration must greater than zero"));
+ this._pOneData[3] = Math.PI*2/drift.w;
+ }
+}
+
+export = ParticleOscillatorNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticlePositionNode.js b/lib/animators/nodes/ParticlePositionNode.js
new file mode 100755
index 000000000..1c99e8232
--- /dev/null
+++ b/lib/animators/nodes/ParticlePositionNode.js
@@ -0,0 +1,62 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticlePositionState = require("awayjs-renderergl/lib/animators/states/ParticlePositionState");
+/**
+ * A particle animation node used to set the starting position of a particle.
+ */
+var ParticlePositionNode = (function (_super) {
+ __extends(ParticlePositionNode, _super);
+ /**
+ * Creates a new ParticlePositionNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] position Defines the default position of the particle when in global mode. Defaults to 0,0,0.
+ */
+ function ParticlePositionNode(mode /*uint*/, position) {
+ if (position === void 0) { position = null; }
+ _super.call(this, "ParticlePosition", mode, 3);
+ this._pStateClass = ParticlePositionState;
+ this._iPosition = position || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticlePositionNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var positionAttribute = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticlePositionState.POSITION_INDEX, positionAttribute.index);
+ return "add " + animationRegisterCache.positionTarget + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticlePositionNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticlePositionNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var offset = param[ParticlePositionNode.POSITION_VECTOR3D];
+ if (!offset)
+ throw (new Error("there is no " + ParticlePositionNode.POSITION_VECTOR3D + " in param!"));
+ this._pOneData[0] = offset.x;
+ this._pOneData[1] = offset.y;
+ this._pOneData[2] = offset.z;
+ };
+ /**
+ * Reference for position node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing position of the particle.
+ */
+ ParticlePositionNode.POSITION_VECTOR3D = "PositionVector3D";
+ return ParticlePositionNode;
+})(ParticleNodeBase);
+module.exports = ParticlePositionNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXBvc2l0aW9ubm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVBvc2l0aW9uTm9kZSIsIlBhcnRpY2xlUG9zaXRpb25Ob2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVQb3NpdGlvbk5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZVBvc2l0aW9uTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlUG9zaXRpb25Ob2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBUXRFLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxxQkFBcUIsV0FBYSw4REFBOEQsQ0FBQyxDQUFDO0FBRXpHLEFBR0E7O0dBREc7SUFDRyxvQkFBb0I7SUFBU0EsVUFBN0JBLG9CQUFvQkEsVUFBeUJBO0lBV2xEQTs7Ozs7T0FLR0E7SUFDSEEsU0FqQktBLG9CQUFvQkEsQ0FpQmJBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFFBQXdCQTtRQUF4QkMsd0JBQXdCQSxHQUF4QkEsZUFBd0JBO1FBRXpEQSxrQkFBTUEsa0JBQWtCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVuQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EscUJBQXFCQSxDQUFDQTtRQUUxQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsUUFBUUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDOUNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSxnREFBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLGlCQUFpQkEsR0FBeUJBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLElBQUlBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsR0FBRUEsc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esc0JBQXNCQSxFQUFFQSxDQUFDQTtRQUMvTEEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLEVBQUVBLHFCQUFxQkEsQ0FBQ0EsY0FBY0EsRUFBRUEsaUJBQWlCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUU3R0EsTUFBTUEsQ0FBQ0EsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxPQUFPQSxHQUFHQSxpQkFBaUJBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsUUFBUUEsQ0FBQ0E7SUFDbEpBLENBQUNBO0lBRURGOztPQUVHQTtJQUNJQSxnREFBaUJBLEdBQXhCQSxVQUF5QkEsUUFBcUJBO1FBRTdDRyxNQUFNQSxDQUF5QkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUNqRUEsQ0FBQ0E7SUFFREg7O09BRUdBO0lBQ0lBLDhEQUErQkEsR0FBdENBLFVBQXVDQSxLQUF3QkE7UUFFOURJLElBQUlBLE1BQU1BLEdBQVlBLEtBQUtBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQTtRQUNwRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7WUFDWEEsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0Esb0JBQW9CQSxDQUFDQSxpQkFBaUJBLEdBQUdBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBO1FBRTFGQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM3QkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBO0lBQzlCQSxDQUFDQTtJQXBEREo7OztPQUdHQTtJQUNXQSxzQ0FBaUJBLEdBQVVBLGtCQUFrQkEsQ0FBQ0E7SUFpRDdEQSwyQkFBQ0E7QUFBREEsQ0ExREEsQUEwRENBLEVBMURrQyxnQkFBZ0IsRUEwRGxEO0FBRUQsQUFBOEIsaUJBQXJCLG9CQUFvQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVBvc2l0aW9uTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVQb3NpdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVQb3NpdGlvblN0YXRlXCIpO1xuXG4vKipcbiAqIEEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgdXNlZCB0byBzZXQgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIG9mIGEgcGFydGljbGUuXG4gKi9cbmNsYXNzIFBhcnRpY2xlUG9zaXRpb25Ob2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pUG9zaXRpb246VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3IgcG9zaXRpb24gbm9kZSBwcm9wZXJ0aWVzIG9uIGEgc2luZ2xlIHBhcnRpY2xlICh3aGVuIGluIGxvY2FsIHByb3BlcnR5IG1vZGUpLlxuXHQgKiBFeHBlY3RzIGEgPGNvZGU+VmVjdG9yM0Q8L2NvZGU+IG9iamVjdCByZXByZXNlbnRpbmcgcG9zaXRpb24gb2YgdGhlIHBhcnRpY2xlLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBQT1NJVElPTl9WRUNUT1IzRDpzdHJpbmcgPSBcIlBvc2l0aW9uVmVjdG9yM0RcIjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QYXJ0aWNsZVBvc2l0aW9uTm9kZTwvY29kZT5cblx0ICpcblx0ICogQHBhcmFtICAgICAgICAgICAgICAgbW9kZSAgICAgICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbW9kZSBvZiBvcGVyYXRpb24gYWN0cyBvbiBsb2NhbCBwcm9wZXJ0aWVzIG9mIGEgcGFydGljbGUgb3IgZ2xvYmFsIHByb3BlcnRpZXMgb2YgdGhlIG5vZGUuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHBvc2l0aW9uICAgICAgICBEZWZpbmVzIHRoZSBkZWZhdWx0IHBvc2l0aW9uIG9mIHRoZSBwYXJ0aWNsZSB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAwLDAsMC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCBwb3NpdGlvbjpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlUG9zaXRpb25cIiwgbW9kZSwgMyk7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFBhcnRpY2xlUG9zaXRpb25TdGF0ZTtcblxuXHRcdHRoaXMuX2lQb3NpdGlvbiA9IHBvc2l0aW9uIHx8IG5ldyBWZWN0b3IzRCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgcG9zaXRpb25BdHRyaWJ1dGU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gKHRoaXMuX3BNb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKT8gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKSA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleEF0dHJpYnV0ZSgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZVBvc2l0aW9uU3RhdGUuUE9TSVRJT05fSU5ERVgsIHBvc2l0aW9uQXR0cmlidXRlLmluZGV4KTtcblxuXHRcdHJldHVybiBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXosXCIgKyBwb3NpdGlvbkF0dHJpYnV0ZSArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFuaW1hdGlvblN0YXRlKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSk6UGFydGljbGVQb3NpdGlvblN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFBhcnRpY2xlUG9zaXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlKHBhcmFtOlBhcnRpY2xlUHJvcGVydGllcylcblx0e1xuXHRcdHZhciBvZmZzZXQ6VmVjdG9yM0QgPSBwYXJhbVtQYXJ0aWNsZVBvc2l0aW9uTm9kZS5QT1NJVElPTl9WRUNUT1IzRF07XG5cdFx0aWYgKCFvZmZzZXQpXG5cdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJ0aGVyZSBpcyBubyBcIiArIFBhcnRpY2xlUG9zaXRpb25Ob2RlLlBPU0lUSU9OX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpKTtcblxuXHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gb2Zmc2V0Lng7XG5cdFx0dGhpcy5fcE9uZURhdGFbMV0gPSBvZmZzZXQueTtcblx0XHR0aGlzLl9wT25lRGF0YVsyXSA9IG9mZnNldC56O1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlUG9zaXRpb25Ob2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticlePositionNode.ts b/lib/animators/nodes/ParticlePositionNode.ts
new file mode 100644
index 000000000..e811771a6
--- /dev/null
+++ b/lib/animators/nodes/ParticlePositionNode.ts
@@ -0,0 +1,76 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticlePositionState = require("awayjs-renderergl/lib/animators/states/ParticlePositionState");
+
+/**
+ * A particle animation node used to set the starting position of a particle.
+ */
+class ParticlePositionNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iPosition:Vector3D;
+
+ /**
+ * Reference for position node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing position of the particle.
+ */
+ public static POSITION_VECTOR3D:string = "PositionVector3D";
+
+ /**
+ * Creates a new ParticlePositionNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] position Defines the default position of the particle when in global mode. Defaults to 0,0,0.
+ */
+ constructor(mode:number /*uint*/, position:Vector3D = null)
+ {
+ super("ParticlePosition", mode, 3);
+
+ this._pStateClass = ParticlePositionState;
+
+ this._iPosition = position || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var positionAttribute:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticlePositionState.POSITION_INDEX, positionAttribute.index);
+
+ return "add " + animationRegisterCache.positionTarget + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticlePositionState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var offset:Vector3D = param[ParticlePositionNode.POSITION_VECTOR3D];
+ if (!offset)
+ throw(new Error("there is no " + ParticlePositionNode.POSITION_VECTOR3D + " in param!"));
+
+ this._pOneData[0] = offset.x;
+ this._pOneData[1] = offset.y;
+ this._pOneData[2] = offset.z;
+ }
+}
+
+export = ParticlePositionNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotateToHeadingNode.js b/lib/animators/nodes/ParticleRotateToHeadingNode.js
new file mode 100755
index 000000000..dd7a1619c
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotateToHeadingNode.js
@@ -0,0 +1,163 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleRotateToHeadingState = require("awayjs-renderergl/lib/animators/states/ParticleRotateToHeadingState");
+/**
+ * A particle animation node used to control the rotation of a particle to match its heading vector.
+ */
+var ParticleRotateToHeadingNode = (function (_super) {
+ __extends(ParticleRotateToHeadingNode, _super);
+ /**
+ * Creates a new ParticleBillboardNode
+ */
+ function ParticleRotateToHeadingNode() {
+ _super.call(this, "ParticleRotateToHeading", ParticlePropertiesMode.GLOBAL, 0, 3);
+ this._pStateClass = ParticleRotateToHeadingState;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToHeadingNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ var len = animationRegisterCache.rotationRegisters.length;
+ var i /*int*/;
+ if (animationRegisterCache.hasBillboard) {
+ var temp1 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3 = animationRegisterCache.getFreeVertexVectorTemp();
+ var rotationMatrixRegister = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToHeadingState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+ //process the velocity
+ code += "m33 " + temp1 + ".xyz," + animationRegisterCache.velocityTarget + ".xyz," + rotationMatrixRegister + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".xy," + temp1 + ".xy\n";
+ code += "nrm " + temp3 + ".xyz," + temp3 + ".xyz\n";
+ //temp3.x=cos,temp3.y=sin
+ //only process z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".x," + temp3 + ".y\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".x\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp3 + ".x\n";
+ code += "neg " + temp1 + ".y," + temp3 + ".y\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+ else {
+ var nrmVel = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmVel, 1);
+ var xAxis = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(xAxis, 1);
+ var R = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(R, 1);
+ var R_rev = animationRegisterCache.getFreeVertexVectorTemp();
+ var cos = new ShaderRegisterElement(R.regName, R.index, 3);
+ var sin = new ShaderRegisterElement(R_rev.regName, R_rev.index, 3);
+ var cos2 = new ShaderRegisterElement(nrmVel.regName, nrmVel.index, 3);
+ var tempSingle = sin;
+ animationRegisterCache.removeVertexTempUsage(nrmVel);
+ animationRegisterCache.removeVertexTempUsage(xAxis);
+ animationRegisterCache.removeVertexTempUsage(R);
+ code += "mov " + xAxis + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + xAxis + ".yz," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmVel + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "dp3 " + cos2 + "," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + xAxis + ".xyz," + nrmVel + ".xyz\n";
+ code += "nrm " + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ //use R as temp to judge if nrm is (0,0,0).
+ //if nrm is (0,0,0) ,change it to (0,0,1).
+ code += "dp3 " + R + ".x," + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "sge " + R + ".x," + animationRegisterCache.vertexZeroConst + "," + R + ".x\n";
+ code += "add " + nrmVel + ".z," + R + ".x," + nrmVel + ".z\n";
+ code += "add " + tempSingle + "," + cos2 + "," + animationRegisterCache.vertexOneConst + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + cos + "," + tempSingle + "\n";
+ code += "sub " + tempSingle + "," + animationRegisterCache.vertexOneConst + "," + cos2 + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + sin + "," + tempSingle + "\n";
+ code += "mul " + R + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ //use cos as R.w
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ //use cos as R_rev.w
+ //nrmVel and xAxis are used as temp register
+ code += "crs " + nrmVel + ".xyz," + R + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ //use cos as R.w
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + R + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + R + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ //code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," +R_rev + ".w\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + R + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ for (i = 0; i < len; i++) {
+ //just repeat the calculate above
+ //because of the limited registers, no need to optimise
+ code += "mov " + xAxis + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + xAxis + ".yz," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmVel + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "dp3 " + cos2 + "," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + xAxis + ".xyz," + nrmVel + ".xyz\n";
+ code += "nrm " + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "dp3 " + R + ".x," + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "sge " + R + ".x," + animationRegisterCache.vertexZeroConst + "," + R + ".x\n";
+ code += "add " + nrmVel + ".z," + R + ".x," + nrmVel + ".z\n";
+ code += "add " + tempSingle + "," + cos2 + "," + animationRegisterCache.vertexOneConst + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + cos + "," + tempSingle + "\n";
+ code += "sub " + tempSingle + "," + animationRegisterCache.vertexOneConst + "," + cos2 + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + sin + "," + tempSingle + "\n";
+ code += "mul " + R + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + R + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + R + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + R + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + R + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ }
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToHeadingNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToHeadingNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ particleAnimationSet.needVelocity = true;
+ };
+ return ParticleRotateToHeadingNode;
+})(ParticleNodeBase);
+module.exports = ParticleRotateToHeadingNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXJvdGF0ZXRvaGVhZGluZ25vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlIiwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlLmdldEFuaW1hdGlvblN0YXRlIiwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7OztBQUtBLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUkzRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sNEJBQTRCLFdBQVkscUVBQXFFLENBQUMsQ0FBQztBQUV0SCxBQUdBOztHQURHO0lBQ0csMkJBQTJCO0lBQVNBLFVBQXBDQSwyQkFBMkJBLFVBQXlCQTtJQUV6REE7O09BRUdBO0lBQ0hBLFNBTEtBLDJCQUEyQkE7UUFPL0JDLGtCQUFNQSx5QkFBeUJBLEVBQUVBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFdEVBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLDRCQUE0QkEsQ0FBQ0E7SUFDbERBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSx1REFBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBQ3JCQSxJQUFJQSxHQUFHQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLE1BQU1BLENBQUNBO1FBQ3pFQSxJQUFJQSxDQUFD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R0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ25FQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxPQUFPQSxHQUFHQSxDQUFDQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxRQUFRQSxDQUFDQTtnQkFDOURBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUNyRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE9BQU9BLEdBQUdBLENBQUNBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLFFBQVFBLENBQUNBO1lBQ3pHQSxDQUFDQTtRQUVGQSxDQUFDQTtRQUNEQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVERjs7T0FFR0E7SUFDSUEsdURBQWlCQSxHQUF4QkEsVUFBeUJBLFFBQXFCQTtRQUU3Q0csTUFBTUEsQ0FBZ0NBLFFBQVFBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDeEVBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSwrREFBeUJBLEdBQWhDQSxVQUFpQ0Esb0JBQXlDQTtRQUV6RUksb0JBQW9CQSxDQUFDQSxZQUFZQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUMxQ0EsQ0FBQ0E7SUFDRkosa0NBQUNBO0FBQURBLENBOUtBLEFBOEtDQSxFQTlLeUMsZ0JBQWdCLEVBOEt6RDtBQUVELEFBQXFDLGlCQUE1QiwyQkFBMkIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ1N0YXRlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlUm90YXRlVG9IZWFkaW5nU3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB1c2VkIHRvIGNvbnRyb2wgdGhlIHJvdGF0aW9uIG9mIGEgcGFydGljbGUgdG8gbWF0Y2ggaXRzIGhlYWRpbmcgdmVjdG9yLlxuICovXG5jbGFzcyBQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ05vZGUgZXh0ZW5kcyBQYXJ0aWNsZU5vZGVCYXNlXG57XG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlQmlsbGJvYXJkTm9kZTwvY29kZT5cblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHN1cGVyKFwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdcIiwgUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwsIDAsIDMpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ1N0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzLmxlbmd0aDtcblx0XHR2YXIgaTpudW1iZXIgLyppbnQqLztcblx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5oYXNCaWxsYm9hcmQpIHtcblx0XHRcdHZhciB0ZW1wMTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXModGVtcDEsIDEpO1xuXHRcdFx0dmFyIHRlbXAyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuYWRkVmVydGV4VGVtcFVzYWdlcyh0ZW1wMiwgMSk7XG5cdFx0XHR2YXIgdGVtcDM6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXG5cdFx0XHR2YXIgcm90YXRpb25NYXRyaXhSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlUm90YXRlVG9IZWFkaW5nU3RhdGUuTUFUUklYX0lOREVYLCByb3RhdGlvbk1hdHJpeFJlZ2lzdGVyLmluZGV4KTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblxuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcDEpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcDIpO1xuXG5cdFx0XHQvL3Byb2Nlc3MgdGhlIHZlbG9jaXR5XG5cdFx0XHRjb2RlICs9IFwibTMzIFwiICsgdGVtcDEgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlbG9jaXR5VGFyZ2V0ICsgXCIueHl6LFwiICsgcm90YXRpb25NYXRyaXhSZWdpc3RlciArIFwiXFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMyArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAzICsgXCIueHksXCIgKyB0ZW1wMSArIFwiLnh5XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibnJtIFwiICsgdGVtcDMgKyBcIi54eXosXCIgKyB0ZW1wMyArIFwiLnh5elxcblwiO1xuXG5cdFx0XHQvL3RlbXAzLng9Y29zLHRlbXAzLnk9c2luXG5cdFx0XHQvL29ubHkgcHJvY2VzcyB6IGF4aXNcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueCxcIiArIHRlbXAzICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueSxcIiArIHRlbXAzICsgXCIueFxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAxICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDEgKyBcIi54LFwiICsgdGVtcDMgKyBcIi54XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgdGVtcDEgKyBcIi55LFwiICsgdGVtcDMgKyBcIi55XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDMgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMyArIFwiLnosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtMzMgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcblx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIsXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciBucm1WZWw6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKG5ybVZlbCwgMSk7XG5cblx0XHRcdHZhciB4QXhpczpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXMoeEF4aXMsIDEpO1xuXG5cdFx0XHR2YXIgUjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXMoUiwgMSk7XG5cdFx0XHR2YXIgUl9yZXY6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0dmFyIGNvczpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KFIucmVnTmFtZSwgUi5pbmRleCwgMyk7XG5cdFx0XHR2YXIgc2luOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQoUl9yZXYucmVnTmFtZSwgUl9yZXYuaW5kZXgsIDMpO1xuXHRcdFx0dmFyIGNvczI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudChucm1WZWwucmVnTmFtZSwgbnJtVmVsLmluZGV4LCAzKTtcblx0XHRcdHZhciB0ZW1wU2luZ2xlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHNpbjtcblxuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UobnJtVmVsKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKHhBeGlzKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucmVtb3ZlVmVydGV4VGVtcFVzYWdlKFIpO1xuXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgeEF4aXMgKyBcIi54LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgeEF4aXMgKyBcIi55eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblxuXHRcdFx0Y29kZSArPSBcIm5ybSBcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVsb2NpdHlUYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyBjb3MyICsgXCIsXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyB4QXhpcyArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcImNycyBcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibnJtIFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIueHl6XFxuXCI7XG5cdFx0XHQvL3VzZSBSIGFzIHRlbXAgdG8ganVkZ2UgaWYgbnJtIGlzICgwLDAsMCkuXG5cdFx0XHQvL2lmIG5ybSBpcyAoMCwwLDApICxjaGFuZ2UgaXQgdG8gKDAsMCwxKS5cblx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyBSICsgXCIueCxcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcInNnZSBcIiArIFIgKyBcIi54LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIixcIiArIFIgKyBcIi54XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgbnJtVmVsICsgXCIueixcIiArIFIgKyBcIi54LFwiICsgbnJtVmVsICsgXCIuelxcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgY29zMiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiZGl2IFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUd29Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwic3F0IFwiICsgY29zICsgXCIsXCIgKyB0ZW1wU2luZ2xlICsgXCJcXG5cIjtcblxuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIixcIiArIGNvczIgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcImRpdiBcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VHdvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcInNxdCBcIiArIHNpbiArIFwiLFwiICsgdGVtcFNpbmdsZSArIFwiXFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueHl6LFwiICsgc2luICsgXCIsXCIgKyBucm1WZWwgKyBcIi54eXpcXG5cIjtcblxuXHRcdFx0Ly91c2UgY29zIGFzIFIud1xuXG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUl9yZXYgKyBcIi54eXosXCIgKyBzaW4gKyBcIixcIiArIG5ybVZlbCArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5lZyBcIiArIFJfcmV2ICsgXCIueHl6LFwiICsgUl9yZXYgKyBcIi54eXpcXG5cIjtcblxuXHRcdFx0Ly91c2UgY29zIGFzIFJfcmV2LndcblxuXHRcdFx0Ly9ucm1WZWwgYW5kIHhBeGlzIGFyZSB1c2VkIGFzIHRlbXAgcmVnaXN0ZXJcblx0XHRcdGNvZGUgKz0gXCJjcnMgXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBSICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5elxcblwiO1xuXG5cdFx0XHQvL3VzZSBjb3MgYXMgUi53XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBjb3MgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyB4QXhpcyArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcImRwMyBcIiArIHhBeGlzICsgXCIudyxcIiArIFIgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgbnJtVmVsICsgXCIudyxcIiArIHhBeGlzICsgXCIud1xcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwiY3JzIFwiICsgUiArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cdFx0XHQvL2NvZGUgKz0gXCJtdWwgXCIgKyB4QXhpcyArIFwiLnh5encsXCIgKyBucm1WZWwgKyBcIi54eXp3LFwiICtSX3JldiArIFwiLndcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB4QXhpcyArIFwiLnh5encsXCIgKyBucm1WZWwgKyBcIi54eXp3LFwiICsgY29zICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBSICsgXCIueHl6LFwiICsgUiArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBucm1WZWwgKyBcIi53LFwiICsgUl9yZXYgKyBcIi54eXpcXG5cIjtcblxuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBSICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXpcXG5cIjtcblxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdC8vanVzdCByZXBlYXQgdGhlIGNhbGN1bGF0ZSBhYm92ZVxuXHRcdFx0XHQvL2JlY2F1c2Ugb2YgdGhlIGxpbWl0ZWQgcmVnaXN0ZXJzLCBubyBuZWVkIHRvIG9wdGltaXNlXG5cdFx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB4QXhpcyArIFwiLngsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHhBeGlzICsgXCIueXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJucm0gXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlbG9jaXR5VGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyBjb3MyICsgXCIsXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyB4QXhpcyArIFwiLnh5elxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiY3JzIFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBucm1WZWwgKyBcIi54eXpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm5ybSBcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5elxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiZHAzIFwiICsgUiArIFwiLngsXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBucm1WZWwgKyBcIi54eXpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcInNnZSBcIiArIFIgKyBcIi54LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIixcIiArIFIgKyBcIi54XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBucm1WZWwgKyBcIi56LFwiICsgUiArIFwiLngsXCIgKyBucm1WZWwgKyBcIi56XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0ZW1wU2luZ2xlICsgXCIsXCIgKyBjb3MyICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcImRpdiBcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VHdvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwic3F0IFwiICsgY29zICsgXCIsXCIgKyB0ZW1wU2luZ2xlICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHRlbXBTaW5nbGUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIixcIiArIGNvczIgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiZGl2IFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUd29Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJzcXQgXCIgKyBzaW4gKyBcIixcIiArIHRlbXBTaW5nbGUgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUiArIFwiLnh5eixcIiArIHNpbiArIFwiLFwiICsgbnJtVmVsICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSX3JldiArIFwiLnh5eixcIiArIHNpbiArIFwiLFwiICsgbnJtVmVsICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJuZWcgXCIgKyBSX3JldiArIFwiLnh5eixcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJjcnMgXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBSICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLnh5elxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBjb3MgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyB4QXhpcyArIFwiLncsXCIgKyBSICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLnh5elxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibmVnIFwiICsgbnJtVmVsICsgXCIudyxcIiArIHhBeGlzICsgXCIud1xcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiY3JzIFwiICsgUiArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB4QXhpcyArIFwiLnh5encsXCIgKyBucm1WZWwgKyBcIi54eXp3LFwiICsgY29zICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIFIgKyBcIi54eXosXCIgKyBSICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHhBeGlzICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIudyxcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIueHl6LFwiICsgUiArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0XHR9XG5cblx0XHR9XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlUm90YXRlVG9IZWFkaW5nU3RhdGVcblx0e1xuXHRcdHJldHVybiA8UGFydGljbGVSb3RhdGVUb0hlYWRpbmdTdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVByb2Nlc3NBbmltYXRpb25TZXR0aW5nKHBhcnRpY2xlQW5pbWF0aW9uU2V0OlBhcnRpY2xlQW5pbWF0aW9uU2V0KVxuXHR7XG5cdFx0cGFydGljbGVBbmltYXRpb25TZXQubmVlZFZlbG9jaXR5ID0gdHJ1ZTtcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ05vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotateToHeadingNode.ts b/lib/animators/nodes/ParticleRotateToHeadingNode.ts
new file mode 100644
index 000000000..f9ee42d93
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotateToHeadingNode.ts
@@ -0,0 +1,193 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleRotateToHeadingState = require("awayjs-renderergl/lib/animators/states/ParticleRotateToHeadingState");
+
+/**
+ * A particle animation node used to control the rotation of a particle to match its heading vector.
+ */
+class ParticleRotateToHeadingNode extends ParticleNodeBase
+{
+ /**
+ * Creates a new ParticleBillboardNode
+ */
+ constructor()
+ {
+ super("ParticleRotateToHeading", ParticlePropertiesMode.GLOBAL, 0, 3);
+
+ this._pStateClass = ParticleRotateToHeadingState;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+ var len:number /*int*/ = animationRegisterCache.rotationRegisters.length;
+ var i:number /*int*/;
+ if (animationRegisterCache.hasBillboard) {
+ var temp1:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+
+ var rotationMatrixRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToHeadingState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+
+ //process the velocity
+ code += "m33 " + temp1 + ".xyz," + animationRegisterCache.velocityTarget + ".xyz," + rotationMatrixRegister + "\n";
+
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".xy," + temp1 + ".xy\n";
+ code += "nrm " + temp3 + ".xyz," + temp3 + ".xyz\n";
+
+ //temp3.x=cos,temp3.y=sin
+ //only process z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".x," + temp3 + ".y\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".x\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp3 + ".x\n";
+ code += "neg " + temp1 + ".y," + temp3 + ".y\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ } else {
+ var nrmVel:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmVel, 1);
+
+ var xAxis:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(xAxis, 1);
+
+ var R:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(R, 1);
+ var R_rev:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var cos:ShaderRegisterElement = new ShaderRegisterElement(R.regName, R.index, 3);
+ var sin:ShaderRegisterElement = new ShaderRegisterElement(R_rev.regName, R_rev.index, 3);
+ var cos2:ShaderRegisterElement = new ShaderRegisterElement(nrmVel.regName, nrmVel.index, 3);
+ var tempSingle:ShaderRegisterElement = sin;
+
+ animationRegisterCache.removeVertexTempUsage(nrmVel);
+ animationRegisterCache.removeVertexTempUsage(xAxis);
+ animationRegisterCache.removeVertexTempUsage(R);
+
+ code += "mov " + xAxis + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + xAxis + ".yz," + animationRegisterCache.vertexZeroConst + "\n";
+
+ code += "nrm " + nrmVel + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "dp3 " + cos2 + "," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + xAxis + ".xyz," + nrmVel + ".xyz\n";
+ code += "nrm " + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ //use R as temp to judge if nrm is (0,0,0).
+ //if nrm is (0,0,0) ,change it to (0,0,1).
+ code += "dp3 " + R + ".x," + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "sge " + R + ".x," + animationRegisterCache.vertexZeroConst + "," + R + ".x\n";
+ code += "add " + nrmVel + ".z," + R + ".x," + nrmVel + ".z\n";
+
+ code += "add " + tempSingle + "," + cos2 + "," + animationRegisterCache.vertexOneConst + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + cos + "," + tempSingle + "\n";
+
+ code += "sub " + tempSingle + "," + animationRegisterCache.vertexOneConst + "," + cos2 + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + sin + "," + tempSingle + "\n";
+
+ code += "mul " + R + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+
+ //use cos as R.w
+
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+
+ //use cos as R_rev.w
+
+ //nrmVel and xAxis are used as temp register
+ code += "crs " + nrmVel + ".xyz," + R + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+
+ //use cos as R.w
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + R + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+
+ code += "crs " + R + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ //code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," +R_rev + ".w\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + R + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+
+ for (i = 0; i < len; i++) {
+ //just repeat the calculate above
+ //because of the limited registers, no need to optimise
+ code += "mov " + xAxis + ".x," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mov " + xAxis + ".yz," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmVel + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ code += "dp3 " + cos2 + "," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + xAxis + ".xyz," + nrmVel + ".xyz\n";
+ code += "nrm " + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "dp3 " + R + ".x," + nrmVel + ".xyz," + nrmVel + ".xyz\n";
+ code += "sge " + R + ".x," + animationRegisterCache.vertexZeroConst + "," + R + ".x\n";
+ code += "add " + nrmVel + ".z," + R + ".x," + nrmVel + ".z\n";
+ code += "add " + tempSingle + "," + cos2 + "," + animationRegisterCache.vertexOneConst + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + cos + "," + tempSingle + "\n";
+ code += "sub " + tempSingle + "," + animationRegisterCache.vertexOneConst + "," + cos2 + "\n";
+ code += "div " + tempSingle + "," + tempSingle + "," + animationRegisterCache.vertexTwoConst + "\n";
+ code += "sqt " + sin + "," + tempSingle + "\n";
+ code += "mul " + R + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + R + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + R + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + R + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + R + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".xyz," + R + ".xyz," + xAxis + ".xyz\n";
+ }
+
+ }
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleRotateToHeadingState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ particleAnimationSet.needVelocity = true;
+ }
+}
+
+export = ParticleRotateToHeadingNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotateToPositionNode.js b/lib/animators/nodes/ParticleRotateToPositionNode.js
new file mode 100755
index 000000000..5773a1764
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotateToPositionNode.js
@@ -0,0 +1,182 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleRotateToPositionState = require("awayjs-renderergl/lib/animators/states/ParticleRotateToPositionState");
+/**
+ * A particle animation node used to control the rotation of a particle to face to a position
+ */
+var ParticleRotateToPositionNode = (function (_super) {
+ __extends(ParticleRotateToPositionNode, _super);
+ /**
+ * Creates a new ParticleRotateToPositionNode
+ */
+ function ParticleRotateToPositionNode(mode /*uint*/, position) {
+ if (position === void 0) { position = null; }
+ _super.call(this, "ParticleRotateToPosition", mode, 3, 3);
+ this._pStateClass = ParticleRotateToPositionState;
+ this._iPosition = position || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToPositionNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var positionAttribute = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToPositionState.POSITION_INDEX, positionAttribute.index);
+ var code = "";
+ var len = animationRegisterCache.rotationRegisters.length;
+ var i /*int*/;
+ if (animationRegisterCache.hasBillboard) {
+ var temp1 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2 = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3 = animationRegisterCache.getFreeVertexVectorTemp();
+ var rotationMatrixRegister = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToPositionState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+ //process the position
+ code += "sub " + temp1 + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "m33 " + temp1 + ".xyz," + temp1 + ".xyz," + rotationMatrixRegister + "\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".xy," + temp1 + ".xy\n";
+ code += "nrm " + temp3 + ".xyz," + temp3 + ".xyz\n";
+ //temp3.x=cos,temp3.y=sin
+ //only process z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".x," + temp3 + ".y\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".x\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp3 + ".x\n";
+ code += "neg " + temp1 + ".y," + temp3 + ".y\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ }
+ else {
+ var nrmDirection = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmDirection, 1);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var cos = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var sin = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var o_temp = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ var tempSingle = new ShaderRegisterElement(temp.regName, temp.index, 3);
+ var R = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(R, 1);
+ animationRegisterCache.removeVertexTempUsage(nrmDirection);
+ animationRegisterCache.removeVertexTempUsage(temp);
+ animationRegisterCache.removeVertexTempUsage(R);
+ code += "sub " + nrmDirection + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "mov " + sin + "," + nrmDirection + ".y\n";
+ code += "mul " + cos + "," + sin + "," + sin + "\n";
+ code += "sub " + cos + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "sqt " + cos + "," + cos + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".y\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".y\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "sub " + animationRegisterCache.scaleAndRotateTarget + ".y," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".z," + R + ".z," + R + ".w\n";
+ code += "abs " + R + ".y," + nrmDirection + ".y\n";
+ code += "sge " + R + ".z," + R + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mul " + R + ".x," + R + ".y," + nrmDirection + ".y\n";
+ //judgu if nrmDirection=(0,1,0);
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "dp3 " + sin + "," + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sge " + tempSingle + "," + animationRegisterCache.vertexZeroConst + "," + sin + "\n";
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sub " + sin + "," + animationRegisterCache.vertexOneConst + "," + tempSingle + "\n";
+ code += "mul " + sin + "," + sin + "," + nrmDirection + ".x\n";
+ code += "mov " + cos + "," + nrmDirection + ".z\n";
+ code += "neg " + cos + "," + cos + "\n";
+ code += "sub " + o_temp + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "mul " + o_temp + "," + R + ".x," + tempSingle + "\n";
+ code += "add " + cos + "," + cos + "," + o_temp + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".x\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".x\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "sub " + animationRegisterCache.scaleAndRotateTarget + ".x," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".z," + R + ".z," + R + ".w\n";
+ for (i = 0; i < len; i++) {
+ //just repeat the calculate above
+ //because of the limited registers, no need to optimise
+ code += "sub " + nrmDirection + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "mov " + sin + "," + nrmDirection + ".y\n";
+ code += "mul " + cos + "," + sin + "," + sin + "\n";
+ code += "sub " + cos + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "sqt " + cos + "," + cos + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".y\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".y\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "sub " + animationRegisterCache.rotationRegisters[i] + ".y," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".z," + R + ".z," + R + ".w\n";
+ code += "abs " + R + ".y," + nrmDirection + ".y\n";
+ code += "sge " + R + ".z," + R + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mul " + R + ".x," + R + ".y," + nrmDirection + ".y\n";
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "dp3 " + sin + "," + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sge " + tempSingle + "," + animationRegisterCache.vertexZeroConst + "," + sin + "\n";
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sub " + sin + "," + animationRegisterCache.vertexOneConst + "," + tempSingle + "\n";
+ code += "mul " + sin + "," + sin + "," + nrmDirection + ".x\n";
+ code += "mov " + cos + "," + nrmDirection + ".z\n";
+ code += "neg " + cos + "," + cos + "\n";
+ code += "sub " + o_temp + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "mul " + o_temp + "," + R + ".x," + tempSingle + "\n";
+ code += "add " + cos + "," + cos + "," + o_temp + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".x\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".x\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "sub " + animationRegisterCache.rotationRegisters[i] + ".x," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".z," + R + ".z," + R + ".w\n";
+ }
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToPositionNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotateToPositionNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var offset = param[ParticleRotateToPositionNode.POSITION_VECTOR3D];
+ if (!offset)
+ throw (new Error("there is no " + ParticleRotateToPositionNode.POSITION_VECTOR3D + " in param!"));
+ this._pOneData[0] = offset.x;
+ this._pOneData[1] = offset.y;
+ this._pOneData[2] = offset.z;
+ };
+ /**
+ * Reference for the position the particle will rotate to face for a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the position that the particle must face.
+ */
+ ParticleRotateToPositionNode.POSITION_VECTOR3D = "RotateToPositionVector3D";
+ return ParticleRotateToPositionNode;
+})(ParticleNodeBase);
+module.exports = ParticleRotateToPositionNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXJvdGF0ZXRvcG9zaXRpb25ub2RlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUiLCJQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZS5nZXRBR0FMVmVydGV4Q29kZSIsIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiLCJQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sNkJBQTZCLFdBQVcsc0VBQXNFLENBQUMsQ0FBQztBQUV2SCxBQUdBOztHQURHO0lBQ0csNEJBQTRCO0lBQVNBLFVBQXJDQSw0QkFBNEJBLFVBQXlCQTtJQVcxREE7O09BRUdBO0lBQ0hBLFNBZEtBLDRCQUE0QkEsQ0FjckJBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFFBQXdCQTtRQUF4QkMsd0JBQXdCQSxHQUF4QkEsZUFBd0JBO1FBRXpEQSxrQkFBTUEsMEJBQTBCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU5Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsNkJBQTZCQSxDQUFDQTtRQUVsREEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsUUFBUUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDOUNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSx3REFBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLGlCQUFpQkEsR0FBeUJBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLElBQUlBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsR0FBRUEsc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esc0JBQXNCQSxFQUFFQSxDQUFDQTtRQUMvTEEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLEVBQUVBLDZCQUE2QkEsQ0FBQ0EsY0FBY0EsRUFBRUEsaUJBQWlCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUVySEEsSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLEdBQUdBLEdBQWtCQSxzQkFBc0JBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDekVBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3JCQSxFQUFFQSxDQUFDQSxDQUFDQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBO1lBQ3pDQSxJQUFJQSxLQUFLQSxHQUF5QkEsc0JBQXNCQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1lBQ25GQSxzQkFBc0JBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDckRBLElBQUlBLEtBQUtBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7WUFDbkZBLHNCQUFzQkEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNyREEsSUFBSUEsS0FBS0EsR0FBeUJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtZQUVuRkEsSUFBSUEsc0JBQXNCQSxHQUF5QkEsc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO1lBQ2xHQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsRUFBRUEsNkJBQTZCQSxDQUFDQSxZQUFZQSxFQUFFQSxzQkFBc0JBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1lBQ3hIQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7WUFDL0NBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtZQUMvQ0Esc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO1lBRS9DQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7WUFDcERBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUVwREEsQUFDQUEsc0JBRHNCQTtZQUN0QkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsT0FBT0EsR0FBR0EsaUJBQWlCQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLENBQUNBO1lBQ2xIQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLEdBQUdBLElBQUlBLENBQUNBO1lBRW5GQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQzdFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxDQUFDQTtZQUNsREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsT0FBT0EsR0FBR0EsS0FBS0EsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFFcERBLEFBRUFBLHlCQUZ5QkE7WUFDekJBLHFCQUFxQkE7WUFDckJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDN0VBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBO1lBQ2hEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxLQUFLQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUNoREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM3RUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDaERBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBO1lBQ2hEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQzdFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO1lBQzlFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsT0FBT0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1lBQzlJQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxDQUFDQSxFQUFFQTtnQkFDdkJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDNUlBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLElBQUlBLFlBQVlBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7WUFDMUZBLHNCQUFzQkEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUU1REEsSUFBSUEsSUFBSUEsR0FBeUJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtZQUNsRkEsc0JBQXNCQSxDQUFDQSxtQkFBbUJBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1lBQ3BEQSxJQUFJQSxHQUFHQSxHQUF5QkEsSUFBSUEscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxFQUFFQSxJQUFJQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN2RkEsSUFBSUEsR0FBR0EsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsRUFBRUEsSUFBSUEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkZBLElBQUlBLE1BQU1BLEdBQXlCQSxJQUFJQSxxQkFBcUJBLENBQUNBLElBQUlBLENBQUNBLE9BQU9BLEVBQUVBLElBQUlBLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1lBQzFGQSxJQUFJQSxVQUFVQSxHQUF5QkEsSUFBSUEscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxFQUFFQSxJQUFJQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUU5RkEsSUFBSUEsQ0FBQ0EsR0FBeUJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtZQUMvRUEsc0JBQXNCQSxDQUFDQSxtQkFBbUJBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1lBRWpEQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0E7WUFDM0RBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNuREEsc0JBQXNCQSxDQUFDQSxxQkFBcUJBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBRWhEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxPQUFPQSxHQUFHQSxpQkFBaUJBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFDekhBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLEdBQUdBLE9BQU9BLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLENBQUNBO1lBRWxFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUNuREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDcERBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO1lBRXhDQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE1BQU1BLENBQUNBO1lBQzlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO1lBRTlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUNuREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFL0RBLEFBQ0FBLGdDQURnQ0E7WUFDaENBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLEdBQUdBLEtBQUtBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLFlBQVlBLEdBQUdBLE9BQU9BLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLENBQUNBO1lBQzlFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO1lBRTlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQ3RGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxPQUFPQSxHQUFHQSxZQUFZQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUVsRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM3RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFL0RBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLFlBQVlBLEdBQUdBLE1BQU1BLENBQUNBO1lBQ25EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN6RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDOURBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBO1lBRXZEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE1BQU1BLENBQUNBO1lBQzlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO1lBRTlGQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtnQkFDMUJBLEFBRUFBLGlDQUZpQ0E7Z0JBQ2pDQSx1REFBdURBO2dCQUN2REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsaUJBQWlCQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUN6SEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsWUFBWUEsR0FBR0EsUUFBUUEsQ0FBQ0E7Z0JBQ2xFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtnQkFDbkRBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUNwREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7Z0JBQ25EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7Z0JBQy9EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsWUFBWUEsR0FBR0EsUUFBUUEsQ0FBQ0E7Z0JBQzlFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsS0FBS0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLEdBQUdBLE9BQU9BLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUNsRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDN0ZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdB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QTtRQUVsR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUM5QkEsQ0FBQ0E7SUE5TERKOzs7T0FHR0E7SUFDV0EsOENBQWlCQSxHQUFVQSwwQkFBMEJBLENBQUNBO0lBMkxyRUEsbUNBQUNBO0FBQURBLENBcE1BLEFBb01DQSxFQXBNMEMsZ0JBQWdCLEVBb00xRDtBQUVELEFBQXNDLGlCQUE3Qiw0QkFBNEIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGVcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlXCIpO1xuXG4vKipcbiAqIEEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgdXNlZCB0byBjb250cm9sIHRoZSByb3RhdGlvbiBvZiBhIHBhcnRpY2xlIHRvIGZhY2UgdG8gYSBwb3NpdGlvblxuICovXG5jbGFzcyBQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pUG9zaXRpb246VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3IgdGhlIHBvc2l0aW9uIHRoZSBwYXJ0aWNsZSB3aWxsIHJvdGF0ZSB0byBmYWNlIGZvciBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPlZlY3RvcjNEPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBwb3NpdGlvbiB0aGF0IHRoZSBwYXJ0aWNsZSBtdXN0IGZhY2UuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIFBPU0lUSU9OX1ZFQ1RPUjNEOnN0cmluZyA9IFwiUm90YXRlVG9Qb3NpdGlvblZlY3RvcjNEXCI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZTwvY29kZT5cblx0ICovXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCBwb3NpdGlvbjpWZWN0b3IzRCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblwiLCBtb2RlLCAzLCAzKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGU7XG5cblx0XHR0aGlzLl9pUG9zaXRpb24gPSBwb3NpdGlvbiB8fCBuZXcgVmVjdG9yM0QoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHBvc2l0aW9uQXR0cmlidXRlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCkgOiBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGUuUE9TSVRJT05fSU5ERVgsIHBvc2l0aW9uQXR0cmlidXRlLmluZGV4KTtcblxuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIGxlbjpudW1iZXIgLyppbnQqLyA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnMubGVuZ3RoO1xuXHRcdHZhciBpOm51bWJlciAvKmludCovO1xuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZCkge1xuXHRcdFx0dmFyIHRlbXAxOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuYWRkVmVydGV4VGVtcFVzYWdlcyh0ZW1wMSwgMSk7XG5cdFx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAyLCAxKTtcblx0XHRcdHZhciB0ZW1wMzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cblx0XHRcdHZhciByb3RhdGlvbk1hdHJpeFJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGUuTUFUUklYX0lOREVYLCByb3RhdGlvbk1hdHJpeFJlZ2lzdGVyLmluZGV4KTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblxuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcDEpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcDIpO1xuXG5cdFx0XHQvL3Byb2Nlc3MgdGhlIHBvc2l0aW9uXG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgdGVtcDEgKyBcIi54eXosXCIgKyBwb3NpdGlvbkF0dHJpYnV0ZSArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtMzMgXCIgKyB0ZW1wMSArIFwiLnh5eixcIiArIHRlbXAxICsgXCIueHl6LFwiICsgcm90YXRpb25NYXRyaXhSZWdpc3RlciArIFwiXFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMyArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAzICsgXCIueHksXCIgKyB0ZW1wMSArIFwiLnh5XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibnJtIFwiICsgdGVtcDMgKyBcIi54eXosXCIgKyB0ZW1wMyArIFwiLnh5elxcblwiO1xuXG5cdFx0XHQvL3RlbXAzLng9Y29zLHRlbXAzLnk9c2luXG5cdFx0XHQvL29ubHkgcHJvY2VzcyB6IGF4aXNcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueCxcIiArIHRlbXAzICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAyICsgXCIueSxcIiArIHRlbXAzICsgXCIueFxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHRlbXAxICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDEgKyBcIi54LFwiICsgdGVtcDMgKyBcIi54XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgdGVtcDEgKyBcIi55LFwiICsgdGVtcDMgKyBcIi55XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGVtcDMgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMyArIFwiLnosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtMzMgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIHRlbXAxICsgXCJcXG5cIjtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcblx0XHRcdFx0Y29kZSArPSBcIm0zMyBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIsXCIgKyB0ZW1wMSArIFwiXFxuXCI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciBucm1EaXJlY3Rpb246U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKG5ybURpcmVjdGlvbiwgMSk7XG5cblx0XHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuYWRkVmVydGV4VGVtcFVzYWdlcyh0ZW1wLCAxKTtcblx0XHRcdHZhciBjb3M6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh0ZW1wLnJlZ05hbWUsIHRlbXAuaW5kZXgsIDApO1xuXHRcdFx0dmFyIHNpbjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMSk7XG5cdFx0XHR2YXIgb190ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcC5yZWdOYW1lLCB0ZW1wLmluZGV4LCAyKTtcblx0XHRcdHZhciB0ZW1wU2luZ2xlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcC5yZWdOYW1lLCB0ZW1wLmluZGV4LCAzKTtcblxuXHRcdFx0dmFyIFI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKFIsIDEpO1xuXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnJlbW92ZVZlcnRleFRlbXBVc2FnZShucm1EaXJlY3Rpb24pO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnJlbW92ZVZlcnRleFRlbXBVc2FnZShSKTtcblxuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5eixcIiArIHBvc2l0aW9uQXR0cmlidXRlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5ybSBcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5eixcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5elxcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgc2luICsgXCIsXCIgKyBucm1EaXJlY3Rpb24gKyBcIi55XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgY29zICsgXCIsXCIgKyBzaW4gKyBcIixcIiArIHNpbiArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcInNxdCBcIiArIGNvcyArIFwiLFwiICsgY29zICsgXCJcXG5cIjtcblxuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi54LFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi55LFwiICsgc2luICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIuelxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi56LFwiICsgc2luICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi53LFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIuelxcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnksXCIgKyBSICsgXCIueCxcIiArIFIgKyBcIi55XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnosXCIgKyBSICsgXCIueixcIiArIFIgKyBcIi53XFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJhYnMgXCIgKyBSICsgXCIueSxcIiArIG5ybURpcmVjdGlvbiArIFwiLnlcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJzZ2UgXCIgKyBSICsgXCIueixcIiArIFIgKyBcIi55LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUiArIFwiLngsXCIgKyBSICsgXCIueSxcIiArIG5ybURpcmVjdGlvbiArIFwiLnlcXG5cIjtcblxuXHRcdFx0Ly9qdWRndSBpZiBucm1EaXJlY3Rpb249KDAsMSwwKTtcblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBucm1EaXJlY3Rpb24gKyBcIi55LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcImRwMyBcIiArIHNpbiArIFwiLFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6LFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwic2dlIFwiICsgdGVtcFNpbmdsZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIixcIiArIHNpbiArIFwiXFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBucm1EaXJlY3Rpb24gKyBcIi55LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5ybSBcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5eixcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5elxcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgc2luICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCIsXCIgKyB0ZW1wU2luZ2xlICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBzaW4gKyBcIixcIiArIHNpbiArIFwiLFwiICsgbnJtRGlyZWN0aW9uICsgXCIueFxcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgY29zICsgXCIsXCIgKyBucm1EaXJlY3Rpb24gKyBcIi56XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibmVnIFwiICsgY29zICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIG9fdGVtcCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiLFwiICsgY29zICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBvX3RlbXAgKyBcIixcIiArIFIgKyBcIi54LFwiICsgdGVtcFNpbmdsZSArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgY29zICsgXCIsXCIgKyBjb3MgKyBcIixcIiArIG9fdGVtcCArIFwiXFxuXCI7XG5cblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueCxcIiArIGNvcyArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnhcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueSxcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueixcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnhcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIudyxcIiArIGNvcyArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnpcXG5cIjtcblxuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54LFwiICsgUiArIFwiLngsXCIgKyBSICsgXCIueVxcblwiO1xuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi56LFwiICsgUiArIFwiLnosXCIgKyBSICsgXCIud1xcblwiO1xuXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdFx0Ly9qdXN0IHJlcGVhdCB0aGUgY2FsY3VsYXRlIGFib3ZlXG5cdFx0XHRcdC8vYmVjYXVzZSBvZiB0aGUgbGltaXRlZCByZWdpc3RlcnMsIG5vIG5lZWQgdG8gb3B0aW1pc2Vcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIG5ybURpcmVjdGlvbiArIFwiLnh5eixcIiArIHBvc2l0aW9uQXR0cmlidXRlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5elxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibnJtIFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6LFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBzaW4gKyBcIixcIiArIG5ybURpcmVjdGlvbiArIFwiLnlcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGNvcyArIFwiLFwiICsgc2luICsgXCIsXCIgKyBzaW4gKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwic3ViIFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleE9uZUNvbnN0ICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwic3F0IFwiICsgY29zICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUiArIFwiLngsXCIgKyBjb3MgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi55XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueSxcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLnpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi56LFwiICsgc2luICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIueVxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUiArIFwiLncsXCIgKyBjb3MgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi56XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIueSxcIiArIFIgKyBcIi54LFwiICsgUiArIFwiLnlcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi56LFwiICsgUiArIFwiLnosXCIgKyBSICsgXCIud1xcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiYWJzIFwiICsgUiArIFwiLnksXCIgKyBucm1EaXJlY3Rpb24gKyBcIi55XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJzZ2UgXCIgKyBSICsgXCIueixcIiArIFIgKyBcIi55LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueCxcIiArIFIgKyBcIi55LFwiICsgbnJtRGlyZWN0aW9uICsgXCIueVxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibW92IFwiICsgbnJtRGlyZWN0aW9uICsgXCIueSxcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcImRwMyBcIiArIHNpbiArIFwiLFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6LFwiICsgbnJtRGlyZWN0aW9uICsgXCIueHl6XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJzZ2UgXCIgKyB0ZW1wU2luZ2xlICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiLFwiICsgc2luICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIG5ybURpcmVjdGlvbiArIFwiLnksXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJucm0gXCIgKyBucm1EaXJlY3Rpb24gKyBcIi54eXosXCIgKyBucm1EaXJlY3Rpb24gKyBcIi54eXpcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhPbmVDb25zdCArIFwiLFwiICsgdGVtcFNpbmdsZSArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBzaW4gKyBcIixcIiArIHNpbiArIFwiLFwiICsgbnJtRGlyZWN0aW9uICsgXCIueFxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibW92IFwiICsgY29zICsgXCIsXCIgKyBucm1EaXJlY3Rpb24gKyBcIi56XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJuZWcgXCIgKyBjb3MgKyBcIixcIiArIGNvcyArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyBvX3RlbXAgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4T25lQ29uc3QgKyBcIixcIiArIGNvcyArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBvX3RlbXAgKyBcIixcIiArIFIgKyBcIi54LFwiICsgdGVtcFNpbmdsZSArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBjb3MgKyBcIixcIiArIGNvcyArIFwiLFwiICsgb190ZW1wICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi54LFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIueFxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUiArIFwiLnksXCIgKyBzaW4gKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi56XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSICsgXCIueixcIiArIHNpbiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLnhcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIFIgKyBcIi53LFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIuelxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwic3ViIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiLngsXCIgKyBSICsgXCIueCxcIiArIFIgKyBcIi55XFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIueixcIiArIFIgKyBcIi56LFwiICsgUiArIFwiLndcXG5cIjtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUocGFyYW06UGFydGljbGVQcm9wZXJ0aWVzKVxuXHR7XG5cdFx0dmFyIG9mZnNldDpWZWN0b3IzRCA9IHBhcmFtW1BhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUuUE9TSVRJT05fVkVDVE9SM0RdO1xuXHRcdGlmICghb2Zmc2V0KVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLlBPU0lUSU9OX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpKTtcblxuXHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gb2Zmc2V0Lng7XG5cdFx0dGhpcy5fcE9uZURhdGFbMV0gPSBvZmZzZXQueTtcblx0XHR0aGlzLl9wT25lRGF0YVsyXSA9IG9mZnNldC56O1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotateToPositionNode.ts b/lib/animators/nodes/ParticleRotateToPositionNode.ts
new file mode 100644
index 000000000..a897510c8
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotateToPositionNode.ts
@@ -0,0 +1,214 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleRotateToPositionState = require("awayjs-renderergl/lib/animators/states/ParticleRotateToPositionState");
+
+/**
+ * A particle animation node used to control the rotation of a particle to face to a position
+ */
+class ParticleRotateToPositionNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iPosition:Vector3D;
+
+ /**
+ * Reference for the position the particle will rotate to face for a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the position that the particle must face.
+ */
+ public static POSITION_VECTOR3D:string = "RotateToPositionVector3D";
+
+ /**
+ * Creates a new ParticleRotateToPositionNode
+ */
+ constructor(mode:number /*uint*/, position:Vector3D = null)
+ {
+ super("ParticleRotateToPosition", mode, 3, 3);
+
+ this._pStateClass = ParticleRotateToPositionState;
+
+ this._iPosition = position || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var positionAttribute:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToPositionState.POSITION_INDEX, positionAttribute.index);
+
+ var code:string = "";
+ var len:number /*int*/ = animationRegisterCache.rotationRegisters.length;
+ var i:number /*int*/;
+ if (animationRegisterCache.hasBillboard) {
+ var temp1:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp1, 1);
+ var temp2:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp2, 1);
+ var temp3:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+
+ var rotationMatrixRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotateToPositionState.MATRIX_INDEX, rotationMatrixRegister.index);
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.getFreeVertexConstant();
+
+ animationRegisterCache.removeVertexTempUsage(temp1);
+ animationRegisterCache.removeVertexTempUsage(temp2);
+
+ //process the position
+ code += "sub " + temp1 + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "m33 " + temp1 + ".xyz," + temp1 + ".xyz," + rotationMatrixRegister + "\n";
+
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".xy," + temp1 + ".xy\n";
+ code += "nrm " + temp3 + ".xyz," + temp3 + ".xyz\n";
+
+ //temp3.x=cos,temp3.y=sin
+ //only process z axis
+ code += "mov " + temp2 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp2 + ".x," + temp3 + ".y\n";
+ code += "mov " + temp2 + ".y," + temp3 + ".x\n";
+ code += "mov " + temp1 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp1 + ".x," + temp3 + ".x\n";
+ code += "neg " + temp1 + ".y," + temp3 + ".y\n";
+ code += "mov " + temp3 + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mov " + temp3 + ".z," + animationRegisterCache.vertexOneConst + "\n";
+ code += "m33 " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp1 + "\n";
+ for (i = 0; i < len; i++)
+ code += "m33 " + animationRegisterCache.rotationRegisters[i] + ".xyz," + animationRegisterCache.rotationRegisters[i] + "," + temp1 + "\n";
+ } else {
+ var nrmDirection:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmDirection, 1);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var cos:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var sin:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ var o_temp:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ var tempSingle:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 3);
+
+ var R:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(R, 1);
+
+ animationRegisterCache.removeVertexTempUsage(nrmDirection);
+ animationRegisterCache.removeVertexTempUsage(temp);
+ animationRegisterCache.removeVertexTempUsage(R);
+
+ code += "sub " + nrmDirection + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+
+ code += "mov " + sin + "," + nrmDirection + ".y\n";
+ code += "mul " + cos + "," + sin + "," + sin + "\n";
+ code += "sub " + cos + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "sqt " + cos + "," + cos + "\n";
+
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".y\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".y\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+
+ code += "sub " + animationRegisterCache.scaleAndRotateTarget + ".y," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".z," + R + ".z," + R + ".w\n";
+
+ code += "abs " + R + ".y," + nrmDirection + ".y\n";
+ code += "sge " + R + ".z," + R + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mul " + R + ".x," + R + ".y," + nrmDirection + ".y\n";
+
+ //judgu if nrmDirection=(0,1,0);
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "dp3 " + sin + "," + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sge " + tempSingle + "," + animationRegisterCache.vertexZeroConst + "," + sin + "\n";
+
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+
+ code += "sub " + sin + "," + animationRegisterCache.vertexOneConst + "," + tempSingle + "\n";
+ code += "mul " + sin + "," + sin + "," + nrmDirection + ".x\n";
+
+ code += "mov " + cos + "," + nrmDirection + ".z\n";
+ code += "neg " + cos + "," + cos + "\n";
+ code += "sub " + o_temp + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "mul " + o_temp + "," + R + ".x," + tempSingle + "\n";
+ code += "add " + cos + "," + cos + "," + o_temp + "\n";
+
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".x\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.scaleAndRotateTarget + ".x\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".z\n";
+
+ code += "sub " + animationRegisterCache.scaleAndRotateTarget + ".x," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".z," + R + ".z," + R + ".w\n";
+
+ for (i = 0; i < len; i++) {
+ //just repeat the calculate above
+ //because of the limited registers, no need to optimise
+ code += "sub " + nrmDirection + ".xyz," + positionAttribute + ".xyz," + animationRegisterCache.positionTarget + ".xyz\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "mov " + sin + "," + nrmDirection + ".y\n";
+ code += "mul " + cos + "," + sin + "," + sin + "\n";
+ code += "sub " + cos + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "sqt " + cos + "," + cos + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".y\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".y\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "sub " + animationRegisterCache.rotationRegisters[i] + ".y," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".z," + R + ".z," + R + ".w\n";
+ code += "abs " + R + ".y," + nrmDirection + ".y\n";
+ code += "sge " + R + ".z," + R + ".y," + animationRegisterCache.vertexOneConst + "\n";
+ code += "mul " + R + ".x," + R + ".y," + nrmDirection + ".y\n";
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "dp3 " + sin + "," + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sge " + tempSingle + "," + animationRegisterCache.vertexZeroConst + "," + sin + "\n";
+ code += "mov " + nrmDirection + ".y," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "nrm " + nrmDirection + ".xyz," + nrmDirection + ".xyz\n";
+ code += "sub " + sin + "," + animationRegisterCache.vertexOneConst + "," + tempSingle + "\n";
+ code += "mul " + sin + "," + sin + "," + nrmDirection + ".x\n";
+ code += "mov " + cos + "," + nrmDirection + ".z\n";
+ code += "neg " + cos + "," + cos + "\n";
+ code += "sub " + o_temp + "," + animationRegisterCache.vertexOneConst + "," + cos + "\n";
+ code += "mul " + o_temp + "," + R + ".x," + tempSingle + "\n";
+ code += "add " + cos + "," + cos + "," + o_temp + "\n";
+ code += "mul " + R + ".x," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".x\n";
+ code += "mul " + R + ".y," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "mul " + R + ".z," + sin + "," + animationRegisterCache.rotationRegisters[i] + ".x\n";
+ code += "mul " + R + ".w," + cos + "," + animationRegisterCache.rotationRegisters[i] + ".z\n";
+ code += "sub " + animationRegisterCache.rotationRegisters[i] + ".x," + R + ".x," + R + ".y\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + ".z," + R + ".z," + R + ".w\n";
+ }
+ }
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleRotateToPositionState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var offset:Vector3D = param[ParticleRotateToPositionNode.POSITION_VECTOR3D];
+ if (!offset)
+ throw(new Error("there is no " + ParticleRotateToPositionNode.POSITION_VECTOR3D + " in param!"));
+
+ this._pOneData[0] = offset.x;
+ this._pOneData[1] = offset.y;
+ this._pOneData[2] = offset.z;
+ }
+}
+
+export = ParticleRotateToPositionNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotationalVelocityNode.js b/lib/animators/nodes/ParticleRotationalVelocityNode.js
new file mode 100755
index 000000000..12e3f615d
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotationalVelocityNode.js
@@ -0,0 +1,127 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleRotationalVelocityState = require("awayjs-renderergl/lib/animators/states/ParticleRotationalVelocityState");
+/**
+ * A particle animation node used to set the starting rotational velocity of a particle.
+ */
+var ParticleRotationalVelocityNode = (function (_super) {
+ __extends(ParticleRotationalVelocityNode, _super);
+ /**
+ * Creates a new ParticleRotationalVelocityNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ */
+ function ParticleRotationalVelocityNode(mode /*uint*/, rotationalVelocity) {
+ if (rotationalVelocity === void 0) { rotationalVelocity = null; }
+ _super.call(this, "ParticleRotationalVelocity", mode, 4);
+ this._pStateClass = ParticleRotationalVelocityState;
+ this._iRotationalVelocity = rotationalVelocity || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleRotationalVelocityNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var rotationRegister = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotationalVelocityState.ROTATIONALVELOCITY_INDEX, rotationRegister.index);
+ var nrmVel = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmVel, 1);
+ var xAxis = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(xAxis, 1);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var Rtemp = new ShaderRegisterElement(temp.regName, temp.index);
+ var R_rev = animationRegisterCache.getFreeVertexVectorTemp();
+ R_rev = new ShaderRegisterElement(R_rev.regName, R_rev.index);
+ var cos = new ShaderRegisterElement(Rtemp.regName, Rtemp.index, 3);
+ var sin = new ShaderRegisterElement(R_rev.regName, R_rev.index, 3);
+ animationRegisterCache.removeVertexTempUsage(nrmVel);
+ animationRegisterCache.removeVertexTempUsage(xAxis);
+ animationRegisterCache.removeVertexTempUsage(temp);
+ var code = "";
+ code += "mov " + nrmVel + ".xyz," + rotationRegister + ".xyz\n";
+ code += "mov " + nrmVel + ".w," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mul " + cos + "," + animationRegisterCache.vertexTime + "," + rotationRegister + ".w\n";
+ code += "sin " + sin + "," + cos + "\n";
+ code += "cos " + cos + "," + cos + "\n";
+ code += "mul " + Rtemp + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ //nrmVel and xAxis are used as temp register
+ code += "crs " + nrmVel + ".xyz," + Rtemp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + Rtemp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + Rtemp + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ //use cos as R_rev.w
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + Rtemp + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ var len = animationRegisterCache.rotationRegisters.length;
+ for (var i = 0; i < len; i++) {
+ code += "mov " + nrmVel + ".xyz," + rotationRegister + ".xyz\n";
+ code += "mov " + nrmVel + ".w," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mul " + cos + "," + animationRegisterCache.vertexTime + "," + rotationRegister + ".w\n";
+ code += "sin " + sin + "," + cos + "\n";
+ code += "cos " + cos + "," + cos + "\n";
+ code += "mul " + Rtemp + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + Rtemp + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.rotationRegisters[i] + "\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + Rtemp + ".xyz," + animationRegisterCache.rotationRegisters[i] + "\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + Rtemp + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + Rtemp + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + "," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotationalVelocityNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotationalVelocityNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ //(Vector3d.x,Vector3d.y,Vector3d.z) is rotation axis,Vector3d.w is cycle duration
+ var rotate = param[ParticleRotationalVelocityNode.ROTATIONALVELOCITY_VECTOR3D];
+ if (!rotate)
+ throw (new Error("there is no " + ParticleRotationalVelocityNode.ROTATIONALVELOCITY_VECTOR3D + " in param!"));
+ if (rotate.length <= 0)
+ rotate.z = 1; //set the default direction
+ else
+ rotate.normalize();
+ this._pOneData[0] = rotate.x;
+ this._pOneData[1] = rotate.y;
+ this._pOneData[2] = rotate.z;
+ if (rotate.w <= 0)
+ throw (new Error("the cycle duration must greater than zero"));
+ // it's used as angle/2 in agal
+ this._pOneData[3] = Math.PI / rotate.w;
+ };
+ /**
+ * Reference for rotational velocity node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the rotational velocity around an axis of the particle.
+ */
+ ParticleRotationalVelocityNode.ROTATIONALVELOCITY_VECTOR3D = "RotationalVelocityVector3D";
+ return ParticleRotationalVelocityNode;
+})(ParticleNodeBase);
+module.exports = ParticleRotationalVelocityNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXJvdGF0aW9uYWx2ZWxvY2l0eW5vZGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlLmdldEFuaW1hdGlvblN0YXRlIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sK0JBQStCLFdBQVcsd0VBQXdFLENBQUMsQ0FBQztBQUUzSCxBQUdBOztHQURHO0lBQ0csOEJBQThCO0lBQVNBLFVBQXZDQSw4QkFBOEJBLFVBQXlCQTtJQVc1REE7Ozs7T0FJR0E7SUFDSEEsU0FoQktBLDhCQUE4QkEsQ0FnQnZCQSxJQUFJQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxrQkFBa0NBO1FBQWxDQyxrQ0FBa0NBLEdBQWxDQSx5QkFBa0NBO1FBRW5FQSxrQkFBTUEsNEJBQTRCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU3Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsK0JBQStCQSxDQUFDQTtRQUVwREEsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxrQkFBa0JBLElBQUlBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO0lBQ2xFQSxD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LENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBO0lBQ3RDQSxDQUFDQTtJQXBJREo7OztPQUdHQTtJQUNXQSwwREFBMkJBLEdBQVVBLDRCQUE0QkEsQ0FBQ0E7SUFpSWpGQSxxQ0FBQ0E7QUFBREEsQ0ExSUEsQUEwSUNBLEVBMUk0QyxnQkFBZ0IsRUEwSTVEO0FBRUQsQUFBd0MsaUJBQS9CLDhCQUE4QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlTm9kZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU5vZGVCYXNlXCIpO1xuaW1wb3J0IFBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGVcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB1c2VkIHRvIHNldCB0aGUgc3RhcnRpbmcgcm90YXRpb25hbCB2ZWxvY2l0eSBvZiBhIHBhcnRpY2xlLlxuICovXG5jbGFzcyBQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUgZXh0ZW5kcyBQYXJ0aWNsZU5vZGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lSb3RhdGlvbmFsVmVsb2NpdHk6VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3Igcm90YXRpb25hbCB2ZWxvY2l0eSBub2RlIHByb3BlcnRpZXMgb24gYSBzaW5nbGUgcGFydGljbGUgKHdoZW4gaW4gbG9jYWwgcHJvcGVydHkgbW9kZSkuXG5cdCAqIEV4cGVjdHMgYSA8Y29kZT5WZWN0b3IzRDwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcm90YXRpb25hbCB2ZWxvY2l0eSBhcm91bmQgYW4gYXhpcyBvZiB0aGUgcGFydGljbGUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIFJPVEFUSU9OQUxWRUxPQ0lUWV9WRUNUT1IzRDpzdHJpbmcgPSBcIlJvdGF0aW9uYWxWZWxvY2l0eVZlY3RvcjNEXCI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKG1vZGU6bnVtYmVyIC8qdWludCovLCByb3RhdGlvbmFsVmVsb2NpdHk6VmVjdG9yM0QgPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIoXCJQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eVwiLCBtb2RlLCA0KTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZTtcblxuXHRcdHRoaXMuX2lSb3RhdGlvbmFsVmVsb2NpdHkgPSByb3RhdGlvbmFsVmVsb2NpdHkgfHwgbmV3IFZlY3RvcjNEKCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHZhciByb3RhdGlvblJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCkgOiBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZS5ST1RBVElPTkFMVkVMT0NJVFlfSU5ERVgsIHJvdGF0aW9uUmVnaXN0ZXIuaW5kZXgpO1xuXG5cdFx0dmFyIG5ybVZlbDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKG5ybVZlbCwgMSk7XG5cblx0XHR2YXIgeEF4aXM6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuYWRkVmVydGV4VGVtcFVzYWdlcyh4QXhpcywgMSk7XG5cblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5hZGRWZXJ0ZXhUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdHZhciBSdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCk7XG5cdFx0dmFyIFJfcmV2OlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHRSX3JldiA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQoUl9yZXYucmVnTmFtZSwgUl9yZXYuaW5kZXgpO1xuXG5cdFx0dmFyIGNvczpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KFJ0ZW1wLnJlZ05hbWUsIFJ0ZW1wLmluZGV4LCAzKTtcblx0XHR2YXIgc2luOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQoUl9yZXYucmVnTmFtZSwgUl9yZXYuaW5kZXgsIDMpO1xuXG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UobnJtVmVsKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnJlbW92ZVZlcnRleFRlbXBVc2FnZSh4QXhpcyk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcCk7XG5cblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdGNvZGUgKz0gXCJtb3YgXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyByb3RhdGlvblJlZ2lzdGVyICsgXCIueHl6XFxuXCI7XG5cdFx0Y29kZSArPSBcIm1vdiBcIiArIG5ybVZlbCArIFwiLncsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cblx0XHRjb2RlICs9IFwibXVsIFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFRpbWUgKyBcIixcIiArIHJvdGF0aW9uUmVnaXN0ZXIgKyBcIi53XFxuXCI7XG5cblx0XHRjb2RlICs9IFwic2luIFwiICsgc2luICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdGNvZGUgKz0gXCJjb3MgXCIgKyBjb3MgKyBcIixcIiArIGNvcyArIFwiXFxuXCI7XG5cblx0XHRjb2RlICs9IFwibXVsIFwiICsgUnRlbXAgKyBcIi54eXosXCIgKyBzaW4gKyBcIixcIiArIG5ybVZlbCArIFwiLnh5elxcblwiO1xuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIFJfcmV2ICsgXCIueHl6LFwiICsgc2luICsgXCIsXCIgKyBucm1WZWwgKyBcIi54eXpcXG5cIjtcblx0XHRjb2RlICs9IFwibmVnIFwiICsgUl9yZXYgKyBcIi54eXosXCIgKyBSX3JldiArIFwiLnh5elxcblwiO1xuXG5cdFx0Ly9ucm1WZWwgYW5kIHhBeGlzIGFyZSB1c2VkIGFzIHRlbXAgcmVnaXN0ZXJcblx0XHRjb2RlICs9IFwiY3JzIFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgUnRlbXAgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cblx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBjb3MgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXpcXG5cIjtcblx0XHRjb2RlICs9IFwiYWRkIFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXpcXG5cIjtcblx0XHRjb2RlICs9IFwiZHAzIFwiICsgeEF4aXMgKyBcIi53LFwiICsgUnRlbXAgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6XFxuXCI7XG5cdFx0Y29kZSArPSBcIm5lZyBcIiArIG5ybVZlbCArIFwiLncsXCIgKyB4QXhpcyArIFwiLndcXG5cIjtcblxuXHRcdGNvZGUgKz0gXCJjcnMgXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cblx0XHQvL3VzZSBjb3MgYXMgUl9yZXYud1xuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB4QXhpcyArIFwiLnh5encsXCIgKyBucm1WZWwgKyBcIi54eXp3LFwiICsgY29zICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwiYWRkIFwiICsgUnRlbXAgKyBcIi54eXosXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHhBeGlzICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIudyxcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cblx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIFJ0ZW1wICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXpcXG5cIjtcblxuXHRcdHZhciBsZW46bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzLmxlbmd0aDtcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRjb2RlICs9IFwibW92IFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgcm90YXRpb25SZWdpc3RlciArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIG5ybVZlbCArIFwiLncsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgY29zICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFRpbWUgKyBcIixcIiArIHJvdGF0aW9uUmVnaXN0ZXIgKyBcIi53XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwic2luIFwiICsgc2luICsgXCIsXCIgKyBjb3MgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcImNvcyBcIiArIGNvcyArIFwiLFwiICsgY29zICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIHNpbiArIFwiLFwiICsgbnJtVmVsICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgUl9yZXYgKyBcIi54eXosXCIgKyBzaW4gKyBcIixcIiArIG5ybVZlbCArIFwiLnh5elxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5lZyBcIiArIFJfcmV2ICsgXCIueHl6LFwiICsgUl9yZXYgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJjcnMgXCIgKyBucm1WZWwgKyBcIi54eXosXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB4QXhpcyArIFwiLnh5eixcIiArIGNvcyArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yb3RhdGlvblJlZ2lzdGVyc1tpXSArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgbnJtVmVsICsgXCIueHl6LFwiICsgeEF4aXMgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJkcDMgXCIgKyB4QXhpcyArIFwiLncsXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucm90YXRpb25SZWdpc3RlcnNbaV0gKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm5lZyBcIiArIG5ybVZlbCArIFwiLncsXCIgKyB4QXhpcyArIFwiLndcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJjcnMgXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIG5ybVZlbCArIFwiLnh5eixcIiArIFJfcmV2ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXp3LFwiICsgbnJtVmVsICsgXCIueHl6dyxcIiArIGNvcyArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgUnRlbXAgKyBcIi54eXosXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgeEF4aXMgKyBcIi54eXosXCIgKyBucm1WZWwgKyBcIi53LFwiICsgUl9yZXYgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnJvdGF0aW9uUmVnaXN0ZXJzW2ldICsgXCIsXCIgKyBSdGVtcCArIFwiLnh5eixcIiArIHhBeGlzICsgXCIueHl6XFxuXCI7XG5cdFx0fVxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eVN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZShwYXJhbTpQYXJ0aWNsZVByb3BlcnRpZXMpXG5cdHtcblx0XHQvLyhWZWN0b3IzZC54LFZlY3RvcjNkLnksVmVjdG9yM2QueikgaXMgcm90YXRpb24gYXhpcyxWZWN0b3IzZC53IGlzIGN5Y2xlIGR1cmF0aW9uXG5cdFx0dmFyIHJvdGF0ZTpWZWN0b3IzRCA9IHBhcmFtW1BhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5Tm9kZS5ST1RBVElPTkFMVkVMT0NJVFlfVkVDVE9SM0RdO1xuXHRcdGlmICghcm90YXRlKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUuUk9UQVRJT05BTFZFTE9DSVRZX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpKTtcblxuXHRcdGlmIChyb3RhdGUubGVuZ3RoIDw9IDApXG5cdFx0XHRyb3RhdGUueiA9IDE7IC8vc2V0IHRoZSBkZWZhdWx0IGRpcmVjdGlvblxuXHRcdGVsc2Vcblx0XHRcdHJvdGF0ZS5ub3JtYWxpemUoKTtcblxuXHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gcm90YXRlLng7XG5cdFx0dGhpcy5fcE9uZURhdGFbMV0gPSByb3RhdGUueTtcblx0XHR0aGlzLl9wT25lRGF0YVsyXSA9IHJvdGF0ZS56O1xuXHRcdGlmIChyb3RhdGUudyA8PSAwKVxuXHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlIGN5Y2xlIGR1cmF0aW9uIG11c3QgZ3JlYXRlciB0aGFuIHplcm9cIikpO1xuXHRcdC8vIGl0J3MgdXNlZCBhcyBhbmdsZS8yIGluIGFnYWxcblx0XHR0aGlzLl9wT25lRGF0YVszXSA9IE1hdGguUEkvcm90YXRlLnc7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleRotationalVelocityNode.ts b/lib/animators/nodes/ParticleRotationalVelocityNode.ts
new file mode 100644
index 000000000..551851617
--- /dev/null
+++ b/lib/animators/nodes/ParticleRotationalVelocityNode.ts
@@ -0,0 +1,156 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleRotationalVelocityState = require("awayjs-renderergl/lib/animators/states/ParticleRotationalVelocityState");
+
+/**
+ * A particle animation node used to set the starting rotational velocity of a particle.
+ */
+class ParticleRotationalVelocityNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iRotationalVelocity:Vector3D;
+
+ /**
+ * Reference for rotational velocity node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the rotational velocity around an axis of the particle.
+ */
+ public static ROTATIONALVELOCITY_VECTOR3D:string = "RotationalVelocityVector3D";
+
+ /**
+ * Creates a new ParticleRotationalVelocityNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ */
+ constructor(mode:number /*uint*/, rotationalVelocity:Vector3D = null)
+ {
+ super("ParticleRotationalVelocity", mode, 4);
+
+ this._pStateClass = ParticleRotationalVelocityState;
+
+ this._iRotationalVelocity = rotationalVelocity || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var rotationRegister:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleRotationalVelocityState.ROTATIONALVELOCITY_INDEX, rotationRegister.index);
+
+ var nrmVel:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(nrmVel, 1);
+
+ var xAxis:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(xAxis, 1);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(temp, 1);
+ var Rtemp:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index);
+ var R_rev:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ R_rev = new ShaderRegisterElement(R_rev.regName, R_rev.index);
+
+ var cos:ShaderRegisterElement = new ShaderRegisterElement(Rtemp.regName, Rtemp.index, 3);
+ var sin:ShaderRegisterElement = new ShaderRegisterElement(R_rev.regName, R_rev.index, 3);
+
+ animationRegisterCache.removeVertexTempUsage(nrmVel);
+ animationRegisterCache.removeVertexTempUsage(xAxis);
+ animationRegisterCache.removeVertexTempUsage(temp);
+
+ var code:string = "";
+ code += "mov " + nrmVel + ".xyz," + rotationRegister + ".xyz\n";
+ code += "mov " + nrmVel + ".w," + animationRegisterCache.vertexZeroConst + "\n";
+
+ code += "mul " + cos + "," + animationRegisterCache.vertexTime + "," + rotationRegister + ".w\n";
+
+ code += "sin " + sin + "," + cos + "\n";
+ code += "cos " + cos + "," + cos + "\n";
+
+ code += "mul " + Rtemp + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+
+ //nrmVel and xAxis are used as temp register
+ code += "crs " + nrmVel + ".xyz," + Rtemp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + Rtemp + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+
+ code += "crs " + Rtemp + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+
+ //use cos as R_rev.w
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + Rtemp + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+
+ code += "add " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+
+ var len:number /*int*/ = animationRegisterCache.rotationRegisters.length;
+ for (var i:number /*int*/ = 0; i < len; i++) {
+ code += "mov " + nrmVel + ".xyz," + rotationRegister + ".xyz\n";
+ code += "mov " + nrmVel + ".w," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mul " + cos + "," + animationRegisterCache.vertexTime + "," + rotationRegister + ".w\n";
+ code += "sin " + sin + "," + cos + "\n";
+ code += "cos " + cos + "," + cos + "\n";
+ code += "mul " + Rtemp + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "mul " + R_rev + ".xyz," + sin + "," + nrmVel + ".xyz\n";
+ code += "neg " + R_rev + ".xyz," + R_rev + ".xyz\n";
+ code += "crs " + nrmVel + ".xyz," + Rtemp + ".xyz," + animationRegisterCache.rotationRegisters[i] + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + cos + "," + animationRegisterCache.rotationRegisters[i] + "\n";
+ code += "add " + nrmVel + ".xyz," + nrmVel + ".xyz," + xAxis + ".xyz\n";
+ code += "dp3 " + xAxis + ".w," + Rtemp + ".xyz," + animationRegisterCache.rotationRegisters[i] + "\n";
+ code += "neg " + nrmVel + ".w," + xAxis + ".w\n";
+ code += "crs " + Rtemp + ".xyz," + nrmVel + ".xyz," + R_rev + ".xyz\n";
+ code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," + cos + "\n";
+ code += "add " + Rtemp + ".xyz," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ code += "mul " + xAxis + ".xyz," + nrmVel + ".w," + R_rev + ".xyz\n";
+ code += "add " + animationRegisterCache.rotationRegisters[i] + "," + Rtemp + ".xyz," + xAxis + ".xyz\n";
+ }
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleRotationalVelocityState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ //(Vector3d.x,Vector3d.y,Vector3d.z) is rotation axis,Vector3d.w is cycle duration
+ var rotate:Vector3D = param[ParticleRotationalVelocityNode.ROTATIONALVELOCITY_VECTOR3D];
+ if (!rotate)
+ throw(new Error("there is no " + ParticleRotationalVelocityNode.ROTATIONALVELOCITY_VECTOR3D + " in param!"));
+
+ if (rotate.length <= 0)
+ rotate.z = 1; //set the default direction
+ else
+ rotate.normalize();
+
+ this._pOneData[0] = rotate.x;
+ this._pOneData[1] = rotate.y;
+ this._pOneData[2] = rotate.z;
+ if (rotate.w <= 0)
+ throw(new Error("the cycle duration must greater than zero"));
+ // it's used as angle/2 in agal
+ this._pOneData[3] = Math.PI/rotate.w;
+ }
+}
+
+export = ParticleRotationalVelocityNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleScaleNode.js b/lib/animators/nodes/ParticleScaleNode.js
new file mode 100755
index 000000000..e2c40f83e
--- /dev/null
+++ b/lib/animators/nodes/ParticleScaleNode.js
@@ -0,0 +1,95 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleScaleState = require("awayjs-renderergl/lib/animators/states/ParticleScaleState");
+/**
+ * A particle animation node used to control the scale variation of a particle over time.
+ */
+var ParticleScaleNode = (function (_super) {
+ __extends(ParticleScaleNode, _super);
+ /**
+ * Creates a new ParticleScaleNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of animation independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the animation cycle. Defaults to false.
+ * @param [optional] minScale Defines the default min scale transform of the node, when in global mode. Defaults to 1.
+ * @param [optional] maxScale Defines the default max color transform of the node, when in global mode. Defaults to 1.
+ * @param [optional] cycleDuration Defines the default duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the default phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ function ParticleScaleNode(mode /*uint*/, usesCycle, usesPhase, minScale, maxScale, cycleDuration, cyclePhase) {
+ if (minScale === void 0) { minScale = 1; }
+ if (maxScale === void 0) { maxScale = 1; }
+ if (cycleDuration === void 0) { cycleDuration = 1; }
+ if (cyclePhase === void 0) { cyclePhase = 0; }
+ _super.call(this, "ParticleScale", mode, (usesCycle && usesPhase) ? 4 : ((usesCycle || usesPhase) ? 3 : 2), 3);
+ this._pStateClass = ParticleScaleState;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+ this._iMinScale = minScale;
+ this._iMaxScale = maxScale;
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleScaleNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ var temp = animationRegisterCache.getFreeVertexSingleTemp();
+ var scaleRegister = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleScaleState.SCALE_INDEX, scaleRegister.index);
+ if (this._iUsesCycle) {
+ code += "mul " + temp + "," + animationRegisterCache.vertexTime + "," + scaleRegister + ".z\n";
+ if (this._iUsesPhase)
+ code += "add " + temp + "," + temp + "," + scaleRegister + ".w\n";
+ code += "sin " + temp + "," + temp + "\n";
+ }
+ code += "mul " + temp + "," + scaleRegister + ".y," + ((this._iUsesCycle) ? temp : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + scaleRegister + ".x," + temp + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleScaleNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleScaleNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var scale = param[ParticleScaleNode.SCALE_VECTOR3D];
+ if (!scale)
+ throw (new Error("there is no " + ParticleScaleNode.SCALE_VECTOR3D + " in param!"));
+ if (this._iUsesCycle) {
+ this._pOneData[0] = (scale.x + scale.y) / 2;
+ this._pOneData[1] = Math.abs(scale.x - scale.y) / 2;
+ if (scale.z <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._pOneData[2] = Math.PI * 2 / scale.z;
+ if (this._iUsesPhase)
+ this._pOneData[3] = scale.w * Math.PI / 180;
+ }
+ else {
+ this._pOneData[0] = scale.x;
+ this._pOneData[1] = scale.y - scale.x;
+ }
+ };
+ /**
+ * Reference for scale node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
representing the min scale (x), max scale(y), optional cycle speed (z) and phase offset (w) applied to the particle.
+ */
+ ParticleScaleNode.SCALE_VECTOR3D = "ScaleVector3D";
+ return ParticleScaleNode;
+})(ParticleNodeBase);
+module.exports = ParticleScaleNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXNjYWxlbm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVNjYWxlTm9kZSIsIlBhcnRpY2xlU2NhbGVOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVTY2FsZU5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZVNjYWxlTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlU2NhbGVOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVFBLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxrQkFBa0IsV0FBYywyREFBMkQsQ0FBQyxDQUFDO0FBRXBHLEFBR0E7O0dBREc7SUFDRyxpQkFBaUI7SUFBU0EsVUFBMUJBLGlCQUFpQkEsVUFBeUJBO0lBdUIvQ0E7Ozs7Ozs7Ozs7T0FVR0E7SUFDSEEsU0FsQ0tBLGlCQUFpQkEsQ0FrQ1ZBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFNBQWlCQSxFQUFFQSxTQUFpQkEsRUFBRUEsUUFBbUJBLEVBQUVBLFFBQW1CQSxFQUFFQSxhQUF3QkEsRUFBRUEsVUFBcUJBO1FBQXpGQyx3QkFBbUJBLEdBQW5CQSxZQUFtQkE7UUFBRUEsd0JBQW1CQSxHQUFuQkEsWUFBbUJBO1FBQUVBLDZCQUF3QkEsR0FBeEJBLGlCQUF3QkE7UUFBRUEsMEJBQXFCQSxHQUFyQkEsY0FBcUJBO1FBRWhLQSxrQkFBTUEsZUFBZUEsRUFBRUEsSUFBSUEsRUFBRUEsQ0FBQ0EsU0FBU0EsSUFBSUEsU0FBU0EsQ0FBQ0EsR0FBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsU0FBU0EsSUFBSUEsU0FBU0EsQ0FBQ0EsR0FBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFakdBLElB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WUEsS0FBS0EsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUM3REEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0E7WUFDVkEsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsaUJBQWlCQSxDQUFDQSxjQUFjQSxHQUFHQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVwRkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdEJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLENBQUNBLENBQUNBO1lBQzFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxHQUFHQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQTtZQUNsREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ2hCQSxNQUFLQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSw4Q0FBOENBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFDQSxDQUFDQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN0Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7Z0JBQ3BCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFDQSxHQUFHQSxDQUFDQTtRQUMxQ0EsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDUEEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDNUJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQ3ZDQSxDQUFDQTtJQUNGQSxDQUFDQTtJQXhGREo7OztPQUdHQTtJQUNXQSxnQ0FBY0EsR0FBVUEsZUFBZUEsQ0FBQ0E7SUFxRnZEQSx3QkFBQ0E7QUFBREEsQ0ExR0EsQUEwR0NBLEVBMUcrQixnQkFBZ0IsRUEwRy9DO0FBRUQsQUFBMkIsaUJBQWxCLGlCQUFpQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVNjYWxlTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVTY2FsZVN0YXRlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVNjYWxlU3RhdGVcIik7XG5cbi8qKlxuICogQSBwYXJ0aWNsZSBhbmltYXRpb24gbm9kZSB1c2VkIHRvIGNvbnRyb2wgdGhlIHNjYWxlIHZhcmlhdGlvbiBvZiBhIHBhcnRpY2xlIG92ZXIgdGltZS5cbiAqL1xuY2xhc3MgUGFydGljbGVTY2FsZU5vZGUgZXh0ZW5kcyBQYXJ0aWNsZU5vZGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzQ3ljbGU6Ym9vbGVhbjtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc1BoYXNlOmJvb2xlYW47XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaU1pblNjYWxlOm51bWJlcjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaU1heFNjYWxlOm51bWJlcjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUN5Y2xlRHVyYXRpb246bnVtYmVyO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pQ3ljbGVQaGFzZTpudW1iZXI7XG5cblx0LyoqXG5cdCAqIFJlZmVyZW5jZSBmb3Igc2NhbGUgbm9kZSBwcm9wZXJ0aWVzIG9uIGEgc2luZ2xlIHBhcnRpY2xlICh3aGVuIGluIGxvY2FsIHByb3BlcnR5IG1vZGUpLlxuXHQgKiBFeHBlY3RzIGEgPGNvZGU+VmVjdG9yM0Q8L2NvZGU+IHJlcHJlc2VudGluZyB0aGUgbWluIHNjYWxlICh4KSwgbWF4IHNjYWxlKHkpLCBvcHRpb25hbCBjeWNsZSBzcGVlZCAoeikgYW5kIHBoYXNlIG9mZnNldCAodykgYXBwbGllZCB0byB0aGUgcGFydGljbGUuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIFNDQUxFX1ZFQ1RPUjNEOnN0cmluZyA9IFwiU2NhbGVWZWN0b3IzRFwiO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlU2NhbGVOb2RlPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgICAgICAgICAgICBtb2RlICAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBtb2RlIG9mIG9wZXJhdGlvbiBhY3RzIG9uIGxvY2FsIHByb3BlcnRpZXMgb2YgYSBwYXJ0aWNsZSBvciBnbG9iYWwgcHJvcGVydGllcyBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdXNlc0N5Y2xlICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbm9kZSB1c2VzIHRoZSA8Y29kZT5jeWNsZUR1cmF0aW9uPC9jb2RlPiBwcm9wZXJ0eSBpbiB0aGUgc2hhZGVyIHRvIGNhbGN1bGF0ZSB0aGUgcGVyaW9kIG9mIGFuaW1hdGlvbiBpbmRlcGVuZGVudCBvZiBwYXJ0aWNsZSBkdXJhdGlvbi4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHVzZXNQaGFzZSAgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIG5vZGUgdXNlcyB0aGUgPGNvZGU+Y3ljbGVQaGFzZTwvY29kZT4gcHJvcGVydHkgaW4gdGhlIHNoYWRlciB0byBjYWxjdWxhdGUgYSBzdGFydGluZyBvZmZzZXQgdG8gdGhlIGFuaW1hdGlvbiBjeWNsZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIG1pblNjYWxlICAgICAgICBEZWZpbmVzIHRoZSBkZWZhdWx0IG1pbiBzY2FsZSB0cmFuc2Zvcm0gb2YgdGhlIG5vZGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIG1heFNjYWxlICAgICAgICBEZWZpbmVzIHRoZSBkZWZhdWx0IG1heCBjb2xvciB0cmFuc2Zvcm0gb2YgdGhlIG5vZGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIGN5Y2xlRHVyYXRpb24gICBEZWZpbmVzIHRoZSBkZWZhdWx0IGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gaW4gc2Vjb25kcywgdXNlZCBhcyBhIHBlcmlvZCBpbmRlcGVuZGVudCBvZiBwYXJ0aWNsZSBkdXJhdGlvbiB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBjeWNsZVBoYXNlICAgICAgRGVmaW5lcyB0aGUgZGVmYXVsdCBwaGFzZSBvZiB0aGUgY3ljbGUgaW4gZGVncmVlcywgdXNlZCBhcyB0aGUgc3RhcnRpbmcgb2Zmc2V0IG9mIHRoZSBjeWNsZSB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAwLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobW9kZTpudW1iZXIgLyp1aW50Ki8sIHVzZXNDeWNsZTpib29sZWFuLCB1c2VzUGhhc2U6Ym9vbGVhbiwgbWluU2NhbGU6bnVtYmVyID0gMSwgbWF4U2NhbGU6bnVtYmVyID0gMSwgY3ljbGVEdXJhdGlvbjpudW1iZXIgPSAxLCBjeWNsZVBoYXNlOm51bWJlciA9IDApXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlU2NhbGVcIiwgbW9kZSwgKHVzZXNDeWNsZSAmJiB1c2VzUGhhc2UpPyA0IDogKCh1c2VzQ3ljbGUgfHwgdXNlc1BoYXNlKT8gMyA6IDIpLCAzKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVTY2FsZVN0YXRlO1xuXG5cdFx0dGhpcy5faVVzZXNDeWNsZSA9IHVzZXNDeWNsZTtcblx0XHR0aGlzLl9pVXNlc1BoYXNlID0gdXNlc1BoYXNlO1xuXG5cdFx0dGhpcy5faU1pblNjYWxlID0gbWluU2NhbGU7XG5cdFx0dGhpcy5faU1heFNjYWxlID0gbWF4U2NhbGU7XG5cdFx0dGhpcy5faUN5Y2xlRHVyYXRpb24gPSBjeWNsZUR1cmF0aW9uO1xuXHRcdHRoaXMuX2lDeWNsZVBoYXNlID0gY3ljbGVQaGFzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhTaW5nbGVUZW1wKCk7XG5cblx0XHR2YXIgc2NhbGVSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlU2NhbGVTdGF0ZS5TQ0FMRV9JTkRFWCwgc2NhbGVSZWdpc3Rlci5pbmRleCk7XG5cblx0XHRpZiAodGhpcy5faVVzZXNDeWNsZSkge1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgc2NhbGVSZWdpc3RlciArIFwiLnpcXG5cIjtcblxuXHRcdFx0aWYgKHRoaXMuX2lVc2VzUGhhc2UpXG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0ZW1wICsgXCIsXCIgKyB0ZW1wICsgXCIsXCIgKyBzY2FsZVJlZ2lzdGVyICsgXCIud1xcblwiO1xuXG5cdFx0XHRjb2RlICs9IFwic2luIFwiICsgdGVtcCArIFwiLFwiICsgdGVtcCArIFwiXFxuXCI7XG5cdFx0fVxuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIixcIiArIHNjYWxlUmVnaXN0ZXIgKyBcIi55LFwiICsgKCh0aGlzLl9pVXNlc0N5Y2xlKT8gdGVtcCA6IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSkgKyBcIlxcblwiO1xuXHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0ZW1wICsgXCIsXCIgKyBzY2FsZVJlZ2lzdGVyICsgXCIueCxcIiArIHRlbXAgKyBcIlxcblwiO1xuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIHRlbXAgKyBcIlxcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlU2NhbGVTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZVNjYWxlU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZShwYXJhbTpQYXJ0aWNsZVByb3BlcnRpZXMpXG5cdHtcblx0XHR2YXIgc2NhbGU6VmVjdG9yM0QgPSBwYXJhbVtQYXJ0aWNsZVNjYWxlTm9kZS5TQ0FMRV9WRUNUT1IzRF07XG5cdFx0aWYgKCFzY2FsZSlcblx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZXJlIGlzIG5vIFwiICsgUGFydGljbGVTY2FsZU5vZGUuU0NBTEVfVkVDVE9SM0QgKyBcIiBpbiBwYXJhbSFcIikpO1xuXG5cdFx0aWYgKHRoaXMuX2lVc2VzQ3ljbGUpIHtcblx0XHRcdHRoaXMuX3BPbmVEYXRhWzBdID0gKHNjYWxlLnggKyBzY2FsZS55KS8yO1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbMV0gPSBNYXRoLmFicyhzY2FsZS54IC0gc2NhbGUueSkvMjtcblx0XHRcdGlmIChzY2FsZS56IDw9IDApXG5cdFx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHRcdHRoaXMuX3BPbmVEYXRhWzJdID0gTWF0aC5QSSoyL3NjYWxlLno7XG5cdFx0XHRpZiAodGhpcy5faVVzZXNQaGFzZSlcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbM10gPSBzY2FsZS53Kk1hdGguUEkvMTgwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVswXSA9IHNjYWxlLng7XG5cdFx0XHR0aGlzLl9wT25lRGF0YVsxXSA9IHNjYWxlLnkgLSBzY2FsZS54O1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVNjYWxlTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleScaleNode.ts b/lib/animators/nodes/ParticleScaleNode.ts
new file mode 100644
index 000000000..f150cef24
--- /dev/null
+++ b/lib/animators/nodes/ParticleScaleNode.ts
@@ -0,0 +1,124 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleScaleState = require("awayjs-renderergl/lib/animators/states/ParticleScaleState");
+
+/**
+ * A particle animation node used to control the scale variation of a particle over time.
+ */
+class ParticleScaleNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesCycle:boolean;
+
+ /** @private */
+ public _iUsesPhase:boolean;
+
+ /** @private */
+ public _iMinScale:number;
+ /** @private */
+ public _iMaxScale:number;
+ /** @private */
+ public _iCycleDuration:number;
+ /** @private */
+ public _iCyclePhase:number;
+
+ /**
+ * Reference for scale node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
representing the min scale (x), max scale(y), optional cycle speed (z) and phase offset (w) applied to the particle.
+ */
+ public static SCALE_VECTOR3D:string = "ScaleVector3D";
+
+ /**
+ * Creates a new ParticleScaleNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] usesCycle Defines whether the node uses the cycleDuration
property in the shader to calculate the period of animation independent of particle duration. Defaults to false.
+ * @param [optional] usesPhase Defines whether the node uses the cyclePhase
property in the shader to calculate a starting offset to the animation cycle. Defaults to false.
+ * @param [optional] minScale Defines the default min scale transform of the node, when in global mode. Defaults to 1.
+ * @param [optional] maxScale Defines the default max color transform of the node, when in global mode. Defaults to 1.
+ * @param [optional] cycleDuration Defines the default duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the default phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ constructor(mode:number /*uint*/, usesCycle:boolean, usesPhase:boolean, minScale:number = 1, maxScale:number = 1, cycleDuration:number = 1, cyclePhase:number = 0)
+ {
+ super("ParticleScale", mode, (usesCycle && usesPhase)? 4 : ((usesCycle || usesPhase)? 3 : 2), 3);
+
+ this._pStateClass = ParticleScaleState;
+
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+
+ this._iMinScale = minScale;
+ this._iMaxScale = maxScale;
+ this._iCycleDuration = cycleDuration;
+ this._iCyclePhase = cyclePhase;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+
+ var scaleRegister:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleScaleState.SCALE_INDEX, scaleRegister.index);
+
+ if (this._iUsesCycle) {
+ code += "mul " + temp + "," + animationRegisterCache.vertexTime + "," + scaleRegister + ".z\n";
+
+ if (this._iUsesPhase)
+ code += "add " + temp + "," + temp + "," + scaleRegister + ".w\n";
+
+ code += "sin " + temp + "," + temp + "\n";
+ }
+
+ code += "mul " + temp + "," + scaleRegister + ".y," + ((this._iUsesCycle)? temp : animationRegisterCache.vertexLife) + "\n";
+ code += "add " + temp + "," + scaleRegister + ".x," + temp + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleScaleState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var scale:Vector3D = param[ParticleScaleNode.SCALE_VECTOR3D];
+ if (!scale)
+ throw(new Error("there is no " + ParticleScaleNode.SCALE_VECTOR3D + " in param!"));
+
+ if (this._iUsesCycle) {
+ this._pOneData[0] = (scale.x + scale.y)/2;
+ this._pOneData[1] = Math.abs(scale.x - scale.y)/2;
+ if (scale.z <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._pOneData[2] = Math.PI*2/scale.z;
+ if (this._iUsesPhase)
+ this._pOneData[3] = scale.w*Math.PI/180;
+ } else {
+ this._pOneData[0] = scale.x;
+ this._pOneData[1] = scale.y - scale.x;
+ }
+ }
+}
+
+export = ParticleScaleNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleSegmentedColorNode.js b/lib/animators/nodes/ParticleSegmentedColorNode.js
new file mode 100755
index 000000000..edfa4092e
--- /dev/null
+++ b/lib/animators/nodes/ParticleSegmentedColorNode.js
@@ -0,0 +1,151 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleSegmentedColorState = require("awayjs-renderergl/lib/animators/states/ParticleSegmentedColorState");
+/**
+ *
+ */
+var ParticleSegmentedColorNode = (function (_super) {
+ __extends(ParticleSegmentedColorNode, _super);
+ function ParticleSegmentedColorNode(usesMultiplier, usesOffset, numSegmentPoint /*int*/, startColor, endColor, segmentPoints) {
+ //because of the stage3d register limitation, it only support the global mode
+ _super.call(this, "ParticleSegmentedColor", ParticlePropertiesMode.GLOBAL, 0, ParticleAnimationSet.COLOR_PRIORITY);
+ this._pStateClass = ParticleSegmentedColorState;
+ if (numSegmentPoint > 4)
+ throw (new Error("the numSegmentPoint must be less or equal 4"));
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iNumSegmentPoint = numSegmentPoint;
+ this._iStartColor = startColor;
+ this._iEndColor = endColor;
+ this._iSegmentPoints = segmentPoints;
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleSegmentedColorNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleSegmentedColorNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+ var accMultiplierColor;
+ //var accOffsetColor:ShaderRegisterElement;
+ if (this._iUsesMultiplier) {
+ accMultiplierColor = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(accMultiplierColor, 1);
+ }
+ var tempColor = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(tempColor, 1);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ var accTime = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var tempTime = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ if (this._iUsesMultiplier)
+ animationRegisterCache.removeVertexTempUsage(accMultiplierColor);
+ animationRegisterCache.removeVertexTempUsage(tempColor);
+ //for saving all the life values (at most 4)
+ var lifeTimeRegister = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.TIME_DATA_INDEX, lifeTimeRegister.index);
+ var i /*int*/;
+ var startMulValue;
+ var deltaMulValues;
+ if (this._iUsesMultiplier) {
+ startMulValue = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.START_MULTIPLIER_INDEX, startMulValue.index);
+ deltaMulValues = new Array();
+ for (i = 0; i < this._iNumSegmentPoint + 1; i++)
+ deltaMulValues.push(animationRegisterCache.getFreeVertexConstant());
+ }
+ var startOffsetValue;
+ var deltaOffsetValues;
+ if (this._iUsesOffset) {
+ startOffsetValue = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.START_OFFSET_INDEX, startOffsetValue.index);
+ deltaOffsetValues = new Array();
+ for (i = 0; i < this._iNumSegmentPoint + 1; i++)
+ deltaOffsetValues.push(animationRegisterCache.getFreeVertexConstant());
+ }
+ if (this._iUsesMultiplier)
+ code += "mov " + accMultiplierColor + "," + startMulValue + "\n";
+ if (this._iUsesOffset)
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + startOffsetValue + "\n";
+ for (i = 0; i < this._iNumSegmentPoint; i++) {
+ switch (i) {
+ case 0:
+ code += "min " + tempTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ break;
+ case 1:
+ code += "sub " + accTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".y\n";
+ break;
+ case 2:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".y\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".z\n";
+ break;
+ case 3:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".z\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".w\n";
+ break;
+ }
+ if (this._iUsesMultiplier) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaMulValues[i] + "\n";
+ code += "add " + accMultiplierColor + "," + accMultiplierColor + "," + tempColor + "\n";
+ }
+ if (this._iUsesOffset) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaOffsetValues[i] + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + tempColor + "\n";
+ }
+ }
+ //for the last segment:
+ if (this._iNumSegmentPoint == 0)
+ tempTime = animationRegisterCache.vertexLife;
+ else {
+ switch (this._iNumSegmentPoint) {
+ case 1:
+ code += "sub " + accTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ break;
+ case 2:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".y\n";
+ break;
+ case 3:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".z\n";
+ break;
+ case 4:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".w\n";
+ break;
+ }
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ }
+ if (this._iUsesMultiplier) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaMulValues[this._iNumSegmentPoint] + "\n";
+ code += "add " + accMultiplierColor + "," + accMultiplierColor + "," + tempColor + "\n";
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + animationRegisterCache.colorMulTarget + "," + accMultiplierColor + "\n";
+ }
+ if (this._iUsesOffset) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaOffsetValues[this._iNumSegmentPoint] + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + tempColor + "\n";
+ }
+ }
+ return code;
+ };
+ return ParticleSegmentedColorNode;
+})(ParticleNodeBase);
+module.exports = ParticleSegmentedColorNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXNlZ21lbnRlZGNvbG9ybm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVNlZ21lbnRlZENvbG9yTm9kZSIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGUuX2lQcm9jZXNzQW5pbWF0aW9uU2V0dGluZyIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlLmdldEFHQUxWZXJ0ZXhDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLHFCQUFxQixXQUFhLGdFQUFnRSxDQUFDLENBQUM7QUFFM0csSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBR2pHLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTywyQkFBMkIsV0FBWSxvRUFBb0UsQ0FBQyxDQUFDO0FBRXBILEFBR0E7O0dBREc7SUFDRywwQkFBMEI7SUFBU0EsVUFBbkNBLDBCQUEwQkEsVUFBeUJBO0lBZXhEQSxTQWZLQSwwQkFBMEJBLENBZW5CQSxjQUFzQkEsRUFBRUEsVUFBa0JBLEVBQUVBLGVBQWVBLENBQVFBLE9BQURBLEFBQVFBLEVBQUVBLFVBQXlCQSxFQUFFQSxRQUF1QkEsRUFBRUEsYUFBc0NBO1FBRWpMQyxBQUNBQSw2RUFENkVBO1FBQzdFQSxrQkFBTUEsd0JBQXdCQSxFQUFFQSxzQkFBc0JBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLG9CQUFvQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFdkdBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLDJCQUEyQkEsQ0FBQ0E7UUFFaERBLEVBQUVBLENBQUNBLENBQUNBLGVBQWVBLEdBQUdBLENBQUNBLENBQUNBO1lBQ3ZCQSxNQUFLQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSw2Q0FB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QSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBO29CQUNoQ0EsS0FBS0EsQ0FBQ0E7d0JBQ0xBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE9BQU9BLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsVUFBVUEsR0FBR0EsR0FBR0EsR0FBR0EsZ0JBQWdCQSxHQUFHQSxNQUFNQSxDQUFDQTt3QkFDckdBLEtBQUtBLENBQUNBO29CQUNQQSxLQUFLQSxDQUFDQTt3QkFDTEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsZ0JBQWdCQSxHQUFHQSxNQUFNQSxDQUFDQTt3QkFDM0VBLEtBQUtBLENBQUNBO29CQUNQQSxLQUFLQSxDQUFDQTt3QkFDTEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsZ0JBQWdCQSxHQUFHQSxNQUFNQSxDQUFDQTt3QkFDM0VBLEtBQUtBLENBQUNBO29CQUNQQSxLQUFLQSxDQUFDQTt3QkFDTEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0EsZ0JBQWdCQSxHQUFHQSxNQUFNQSxDQUFDQTt3QkFDM0VBLEtBQUtBLENBQUNBO2dCQUNSQSxDQUFDQTtnQkFDREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUNqR0EsQ0FBQ0E7WUFDREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDM0JBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUdBLGNBQWNBLENBQUNBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ2xHQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxrQkFBa0JBLEdBQUdBLEdBQUdBLEdBQUdBLGtCQUFrQkEsR0FBR0EsR0FBR0EsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ3hGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsR0FBR0EsR0FBR0Esa0JBQWtCQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN4SUEsQ0FBQ0E7WUFDREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3ZCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxHQUFHQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ3JHQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsR0FBR0EsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDL0hBLENBQUNBO1FBRUZBLENBQUNBO1FBQ0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRUZILGlDQUFDQTtBQUFEQSxDQXJLQSxBQXFLQ0EsRUFyS3dDLGdCQUFnQixFQXFLeEQ7QUFFRCxBQUFvQyxpQkFBM0IsMEJBQTBCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbG9yVHJhbnNmb3JtXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vQ29sb3JUcmFuc2Zvcm1cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdGlvblNldFwiKTtcbmltcG9ydCBDb2xvclNlZ21lbnRQb2ludFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0NvbG9yU2VnbWVudFBvaW50XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZVwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBQYXJ0aWNsZVNlZ21lbnRlZENvbG9yTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVVzZXNNdWx0aXBsaWVyOmJvb2xlYW47XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzT2Zmc2V0OmJvb2xlYW47XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lTdGFydENvbG9yOkNvbG9yVHJhbnNmb3JtO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pRW5kQ29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lOdW1TZWdtZW50UG9pbnQ6bnVtYmVyIC8qaW50Ki87XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lTZWdtZW50UG9pbnRzOkFycmF5PENvbG9yU2VnbWVudFBvaW50PjtcblxuXHRjb25zdHJ1Y3Rvcih1c2VzTXVsdGlwbGllcjpib29sZWFuLCB1c2VzT2Zmc2V0OmJvb2xlYW4sIG51bVNlZ21lbnRQb2ludDpudW1iZXIgLyppbnQqLywgc3RhcnRDb2xvcjpDb2xvclRyYW5zZm9ybSwgZW5kQ29sb3I6Q29sb3JUcmFuc2Zvcm0sIHNlZ21lbnRQb2ludHM6QXJyYXk8Q29sb3JTZWdtZW50UG9pbnQ+KVxuXHR7XG5cdFx0Ly9iZWNhdXNlIG9mIHRoZSBzdGFnZTNkIHJlZ2lzdGVyIGxpbWl0YXRpb24sIGl0IG9ubHkgc3VwcG9ydCB0aGUgZ2xvYmFsIG1vZGVcblx0XHRzdXBlcihcIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JcIiwgUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwsIDAsIFBhcnRpY2xlQW5pbWF0aW9uU2V0LkNPTE9SX1BSSU9SSVRZKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlO1xuXG5cdFx0aWYgKG51bVNlZ21lbnRQb2ludCA+IDQpXG5cdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJ0aGUgbnVtU2VnbWVudFBvaW50IG11c3QgYmUgbGVzcyBvciBlcXVhbCA0XCIpKTtcblx0XHR0aGlzLl9pVXNlc011bHRpcGxpZXIgPSB1c2VzTXVsdGlwbGllcjtcblx0XHR0aGlzLl9pVXNlc09mZnNldCA9IHVzZXNPZmZzZXQ7XG5cdFx0dGhpcy5faU51bVNlZ21lbnRQb2ludCA9IG51bVNlZ21lbnRQb2ludDtcblx0XHR0aGlzLl9pU3RhcnRDb2xvciA9IHN0YXJ0Q29sb3I7XG5cdFx0dGhpcy5faUVuZENvbG9yID0gZW5kQ29sb3I7XG5cdFx0dGhpcy5faVNlZ21lbnRQb2ludHMgPSBzZWdtZW50UG9pbnRzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lQcm9jZXNzQW5pbWF0aW9uU2V0dGluZyhwYXJ0aWNsZUFuaW1hdGlvblNldDpQYXJ0aWNsZUFuaW1hdGlvblNldClcblx0e1xuXHRcdGlmICh0aGlzLl9pVXNlc011bHRpcGxpZXIpXG5cdFx0XHRwYXJ0aWNsZUFuaW1hdGlvblNldC5oYXNDb2xvck11bE5vZGUgPSB0cnVlO1xuXHRcdGlmICh0aGlzLl9pVXNlc09mZnNldClcblx0XHRcdHBhcnRpY2xlQW5pbWF0aW9uU2V0Lmhhc0NvbG9yQWRkTm9kZSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZEZyYWdtZW50QW5pbWF0aW9uKSB7XG5cdFx0XHR2YXIgYWNjTXVsdGlwbGllckNvbG9yOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0XHRcdC8vdmFyIGFjY09mZnNldENvbG9yOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0XHRcdGlmICh0aGlzLl9pVXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0YWNjTXVsdGlwbGllckNvbG9yID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXMoYWNjTXVsdGlwbGllckNvbG9yLCAxKTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIHRlbXBDb2xvcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLmFkZFZlcnRleFRlbXBVc2FnZXModGVtcENvbG9yLCAxKTtcblxuXHRcdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFx0dmFyIGFjY1RpbWU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh0ZW1wLnJlZ05hbWUsIHRlbXAuaW5kZXgsIDApO1xuXHRcdFx0dmFyIHRlbXBUaW1lOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcC5yZWdOYW1lLCB0ZW1wLmluZGV4LCAxKTtcblxuXHRcdFx0aWYgKHRoaXMuX2lVc2VzTXVsdGlwbGllcilcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UoYWNjTXVsdGlwbGllckNvbG9yKTtcblxuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5yZW1vdmVWZXJ0ZXhUZW1wVXNhZ2UodGVtcENvbG9yKTtcblxuXHRcdFx0Ly9mb3Igc2F2aW5nIGFsbCB0aGUgbGlmZSB2YWx1ZXMgKGF0IG1vc3QgNClcblx0XHRcdHZhciBsaWZlVGltZVJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLlRJTUVfREFUQV9JTkRFWCwgbGlmZVRpbWVSZWdpc3Rlci5pbmRleCk7XG5cblx0XHRcdHZhciBpOm51bWJlciAvKmludCovO1xuXG5cdFx0XHR2YXIgc3RhcnRNdWxWYWx1ZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFx0XHR2YXIgZGVsdGFNdWxWYWx1ZXM6QXJyYXk8U2hhZGVyUmVnaXN0ZXJFbGVtZW50Pjtcblx0XHRcdGlmICh0aGlzLl9pVXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0c3RhcnRNdWxWYWx1ZSA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuU1RBUlRfTVVMVElQTElFUl9JTkRFWCwgc3RhcnRNdWxWYWx1ZS5pbmRleCk7XG5cdFx0XHRcdGRlbHRhTXVsVmFsdWVzID0gbmV3IEFycmF5PFNoYWRlclJlZ2lzdGVyRWxlbWVudD4oKTtcblx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IHRoaXMuX2lOdW1TZWdtZW50UG9pbnQgKyAxOyBpKyspXG5cdFx0XHRcdFx0ZGVsdGFNdWxWYWx1ZXMucHVzaChhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpKTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIHN0YXJ0T2Zmc2V0VmFsdWU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdFx0dmFyIGRlbHRhT2Zmc2V0VmFsdWVzOkFycmF5PFNoYWRlclJlZ2lzdGVyRWxlbWVudD47XG5cdFx0XHRpZiAodGhpcy5faVVzZXNPZmZzZXQpIHtcblx0XHRcdFx0c3RhcnRPZmZzZXRWYWx1ZSA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0UmVnaXN0ZXJJbmRleCh0aGlzLCBQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuU1RBUlRfT0ZGU0VUX0lOREVYLCBzdGFydE9mZnNldFZhbHVlLmluZGV4KTtcblx0XHRcdFx0ZGVsdGFPZmZzZXRWYWx1ZXMgPSBuZXcgQXJyYXk8U2hhZGVyUmVnaXN0ZXJFbGVtZW50PigpO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgdGhpcy5faU51bVNlZ21lbnRQb2ludCArIDE7IGkrKylcblx0XHRcdFx0XHRkZWx0YU9mZnNldFZhbHVlcy5wdXNoKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCkpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5faVVzZXNNdWx0aXBsaWVyKVxuXHRcdFx0XHRjb2RlICs9IFwibW92IFwiICsgYWNjTXVsdGlwbGllckNvbG9yICsgXCIsXCIgKyBzdGFydE11bFZhbHVlICsgXCJcXG5cIjtcblx0XHRcdGlmICh0aGlzLl9pVXNlc09mZnNldClcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuY29sb3JBZGRUYXJnZXQgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuY29sb3JBZGRUYXJnZXQgKyBcIixcIiArIHN0YXJ0T2Zmc2V0VmFsdWUgKyBcIlxcblwiO1xuXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgdGhpcy5faU51bVNlZ21lbnRQb2ludDsgaSsrKSB7XG5cdFx0XHRcdHN3aXRjaCAoaSkge1xuXHRcdFx0XHRcdGNhc2UgMDpcblx0XHRcdFx0XHRcdGNvZGUgKz0gXCJtaW4gXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhMaWZlICsgXCIsXCIgKyBsaWZlVGltZVJlZ2lzdGVyICsgXCIueFxcblwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIGFjY1RpbWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSArIFwiLFwiICsgbGlmZVRpbWVSZWdpc3RlciArIFwiLnhcXG5cIjtcblx0XHRcdFx0XHRcdGNvZGUgKz0gXCJtYXggXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgYWNjVGltZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0XHRcdFx0Y29kZSArPSBcIm1pbiBcIiArIHRlbXBUaW1lICsgXCIsXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgbGlmZVRpbWVSZWdpc3RlciArIFwiLnlcXG5cIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgMjpcblx0XHRcdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyBhY2NUaW1lICsgXCIsXCIgKyBhY2NUaW1lICsgXCIsXCIgKyBsaWZlVGltZVJlZ2lzdGVyICsgXCIueVxcblwiO1xuXHRcdFx0XHRcdFx0Y29kZSArPSBcIm1heCBcIiArIHRlbXBUaW1lICsgXCIsXCIgKyBhY2NUaW1lICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0XHRcdFx0XHRjb2RlICs9IFwibWluIFwiICsgdGVtcFRpbWUgKyBcIixcIiArIHRlbXBUaW1lICsgXCIsXCIgKyBsaWZlVGltZVJlZ2lzdGVyICsgXCIuelxcblwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAzOlxuXHRcdFx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIGFjY1RpbWUgKyBcIixcIiArIGFjY1RpbWUgKyBcIixcIiArIGxpZmVUaW1lUmVnaXN0ZXIgKyBcIi56XFxuXCI7XG5cdFx0XHRcdFx0XHRjb2RlICs9IFwibWF4IFwiICsgdGVtcFRpbWUgKyBcIixcIiArIGFjY1RpbWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4WmVyb0NvbnN0ICsgXCJcXG5cIjtcblx0XHRcdFx0XHRcdGNvZGUgKz0gXCJtaW4gXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgdGVtcFRpbWUgKyBcIixcIiArIGxpZmVUaW1lUmVnaXN0ZXIgKyBcIi53XFxuXCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGhpcy5faVVzZXNNdWx0aXBsaWVyKSB7XG5cdFx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXBDb2xvciArIFwiLFwiICsgdGVtcFRpbWUgKyBcIixcIiArIGRlbHRhTXVsVmFsdWVzW2ldICsgXCJcXG5cIjtcblx0XHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYWNjTXVsdGlwbGllckNvbG9yICsgXCIsXCIgKyBhY2NNdWx0aXBsaWVyQ29sb3IgKyBcIixcIiArIHRlbXBDb2xvciArIFwiXFxuXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHRoaXMuX2lVc2VzT2Zmc2V0KSB7XG5cdFx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXBDb2xvciArIFwiLFwiICsgdGVtcFRpbWUgKyBcIixcIiArIGRlbHRhT2Zmc2V0VmFsdWVzW2ldICsgXCJcXG5cIjtcblx0XHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5jb2xvckFkZFRhcmdldCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5jb2xvckFkZFRhcmdldCArIFwiLFwiICsgdGVtcENvbG9yICsgXCJcXG5cIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvL2ZvciB0aGUgbGFzdCBzZWdtZW50OlxuXHRcdFx0aWYgKHRoaXMuX2lOdW1TZWdtZW50UG9pbnQgPT0gMClcblx0XHRcdFx0dGVtcFRpbWUgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleExpZmU7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0c3dpdGNoICh0aGlzLl9pTnVtU2VnbWVudFBvaW50KSB7XG5cdFx0XHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIGFjY1RpbWUgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSArIFwiLFwiICsgbGlmZVRpbWVSZWdpc3RlciArIFwiLnhcXG5cIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgMjpcblx0XHRcdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyBhY2NUaW1lICsgXCIsXCIgKyBhY2NUaW1lICsgXCIsXCIgKyBsaWZlVGltZVJlZ2lzdGVyICsgXCIueVxcblwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAzOlxuXHRcdFx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIGFjY1RpbWUgKyBcIixcIiArIGFjY1RpbWUgKyBcIixcIiArIGxpZmVUaW1lUmVnaXN0ZXIgKyBcIi56XFxuXCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIDQ6XG5cdFx0XHRcdFx0XHRjb2RlICs9IFwic3ViIFwiICsgYWNjVGltZSArIFwiLFwiICsgYWNjVGltZSArIFwiLFwiICsgbGlmZVRpbWVSZWdpc3RlciArIFwiLndcXG5cIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvZGUgKz0gXCJtYXggXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgYWNjVGltZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhaZXJvQ29uc3QgKyBcIlxcblwiO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuX2lVc2VzTXVsdGlwbGllcikge1xuXHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcENvbG9yICsgXCIsXCIgKyB0ZW1wVGltZSArIFwiLFwiICsgZGVsdGFNdWxWYWx1ZXNbdGhpcy5faU51bVNlZ21lbnRQb2ludF0gKyBcIlxcblwiO1xuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgYWNjTXVsdGlwbGllckNvbG9yICsgXCIsXCIgKyBhY2NNdWx0aXBsaWVyQ29sb3IgKyBcIixcIiArIHRlbXBDb2xvciArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yTXVsVGFyZ2V0ICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yTXVsVGFyZ2V0ICsgXCIsXCIgKyBhY2NNdWx0aXBsaWVyQ29sb3IgKyBcIlxcblwiO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuX2lVc2VzT2Zmc2V0KSB7XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ZW1wQ29sb3IgKyBcIixcIiArIHRlbXBUaW1lICsgXCIsXCIgKyBkZWx0YU9mZnNldFZhbHVlc1t0aGlzLl9pTnVtU2VnbWVudFBvaW50XSArIFwiXFxuXCI7XG5cdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yQWRkVGFyZ2V0ICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmNvbG9yQWRkVGFyZ2V0ICsgXCIsXCIgKyB0ZW1wQ29sb3IgKyBcIlxcblwiO1xuXHRcdFx0fVxuXG5cdFx0fVxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cbn1cblxuZXhwb3J0ID0gUGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleSegmentedColorNode.ts b/lib/animators/nodes/ParticleSegmentedColorNode.ts
new file mode 100644
index 000000000..edee40270
--- /dev/null
+++ b/lib/animators/nodes/ParticleSegmentedColorNode.ts
@@ -0,0 +1,186 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ColorSegmentPoint = require("awayjs-renderergl/lib/animators/data/ColorSegmentPoint");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleSegmentedColorState = require("awayjs-renderergl/lib/animators/states/ParticleSegmentedColorState");
+
+/**
+ *
+ */
+class ParticleSegmentedColorNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesMultiplier:boolean;
+ /** @private */
+ public _iUsesOffset:boolean;
+ /** @private */
+ public _iStartColor:ColorTransform;
+ /** @private */
+ public _iEndColor:ColorTransform;
+ /** @private */
+ public _iNumSegmentPoint:number /*int*/;
+ /** @private */
+ public _iSegmentPoints:Array;
+
+ constructor(usesMultiplier:boolean, usesOffset:boolean, numSegmentPoint:number /*int*/, startColor:ColorTransform, endColor:ColorTransform, segmentPoints:Array)
+ {
+ //because of the stage3d register limitation, it only support the global mode
+ super("ParticleSegmentedColor", ParticlePropertiesMode.GLOBAL, 0, ParticleAnimationSet.COLOR_PRIORITY);
+
+ this._pStateClass = ParticleSegmentedColorState;
+
+ if (numSegmentPoint > 4)
+ throw(new Error("the numSegmentPoint must be less or equal 4"));
+ this._iUsesMultiplier = usesMultiplier;
+ this._iUsesOffset = usesOffset;
+ this._iNumSegmentPoint = numSegmentPoint;
+ this._iStartColor = startColor;
+ this._iEndColor = endColor;
+ this._iSegmentPoints = segmentPoints;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ if (this._iUsesMultiplier)
+ particleAnimationSet.hasColorMulNode = true;
+ if (this._iUsesOffset)
+ particleAnimationSet.hasColorAddNode = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+ if (animationRegisterCache.needFragmentAnimation) {
+ var accMultiplierColor:ShaderRegisterElement;
+ //var accOffsetColor:ShaderRegisterElement;
+ if (this._iUsesMultiplier) {
+ accMultiplierColor = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(accMultiplierColor, 1);
+ }
+
+ var tempColor:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ animationRegisterCache.addVertexTempUsages(tempColor, 1);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var accTime:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var tempTime:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 1);
+
+ if (this._iUsesMultiplier)
+ animationRegisterCache.removeVertexTempUsage(accMultiplierColor);
+
+ animationRegisterCache.removeVertexTempUsage(tempColor);
+
+ //for saving all the life values (at most 4)
+ var lifeTimeRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.TIME_DATA_INDEX, lifeTimeRegister.index);
+
+ var i:number /*int*/;
+
+ var startMulValue:ShaderRegisterElement;
+ var deltaMulValues:Array;
+ if (this._iUsesMultiplier) {
+ startMulValue = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.START_MULTIPLIER_INDEX, startMulValue.index);
+ deltaMulValues = new Array();
+ for (i = 0; i < this._iNumSegmentPoint + 1; i++)
+ deltaMulValues.push(animationRegisterCache.getFreeVertexConstant());
+ }
+
+ var startOffsetValue:ShaderRegisterElement;
+ var deltaOffsetValues:Array;
+ if (this._iUsesOffset) {
+ startOffsetValue = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleSegmentedColorState.START_OFFSET_INDEX, startOffsetValue.index);
+ deltaOffsetValues = new Array();
+ for (i = 0; i < this._iNumSegmentPoint + 1; i++)
+ deltaOffsetValues.push(animationRegisterCache.getFreeVertexConstant());
+ }
+
+ if (this._iUsesMultiplier)
+ code += "mov " + accMultiplierColor + "," + startMulValue + "\n";
+ if (this._iUsesOffset)
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + startOffsetValue + "\n";
+
+ for (i = 0; i < this._iNumSegmentPoint; i++) {
+ switch (i) {
+ case 0:
+ code += "min " + tempTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ break;
+ case 1:
+ code += "sub " + accTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".y\n";
+ break;
+ case 2:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".y\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".z\n";
+ break;
+ case 3:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".z\n";
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "min " + tempTime + "," + tempTime + "," + lifeTimeRegister + ".w\n";
+ break;
+ }
+ if (this._iUsesMultiplier) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaMulValues[i] + "\n";
+ code += "add " + accMultiplierColor + "," + accMultiplierColor + "," + tempColor + "\n";
+ }
+ if (this._iUsesOffset) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaOffsetValues[i] + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + tempColor + "\n";
+ }
+ }
+
+ //for the last segment:
+ if (this._iNumSegmentPoint == 0)
+ tempTime = animationRegisterCache.vertexLife;
+ else {
+ switch (this._iNumSegmentPoint) {
+ case 1:
+ code += "sub " + accTime + "," + animationRegisterCache.vertexLife + "," + lifeTimeRegister + ".x\n";
+ break;
+ case 2:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".y\n";
+ break;
+ case 3:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".z\n";
+ break;
+ case 4:
+ code += "sub " + accTime + "," + accTime + "," + lifeTimeRegister + ".w\n";
+ break;
+ }
+ code += "max " + tempTime + "," + accTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ }
+ if (this._iUsesMultiplier) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaMulValues[this._iNumSegmentPoint] + "\n";
+ code += "add " + accMultiplierColor + "," + accMultiplierColor + "," + tempColor + "\n";
+ code += "mul " + animationRegisterCache.colorMulTarget + "," + animationRegisterCache.colorMulTarget + "," + accMultiplierColor + "\n";
+ }
+ if (this._iUsesOffset) {
+ code += "mul " + tempColor + "," + tempTime + "," + deltaOffsetValues[this._iNumSegmentPoint] + "\n";
+ code += "add " + animationRegisterCache.colorAddTarget + "," + animationRegisterCache.colorAddTarget + "," + tempColor + "\n";
+ }
+
+ }
+ return code;
+ }
+
+}
+
+export = ParticleSegmentedColorNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleSpriteSheetNode.js b/lib/animators/nodes/ParticleSpriteSheetNode.js
new file mode 100755
index 000000000..be805ce67
--- /dev/null
+++ b/lib/animators/nodes/ParticleSpriteSheetNode.js
@@ -0,0 +1,167 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleSpriteSheetState = require("awayjs-renderergl/lib/animators/states/ParticleSpriteSheetState");
+/**
+ * A particle animation node used when a spritesheet texture is required to animate the particle.
+ * NB: to enable use of this node, the repeat
property on the material has to be set to true.
+ */
+var ParticleSpriteSheetNode = (function (_super) {
+ __extends(ParticleSpriteSheetNode, _super);
+ /**
+ * Creates a new ParticleSpriteSheetNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] numColumns Defines the number of columns in the spritesheet, when in global mode. Defaults to 1.
+ * @param [optional] numRows Defines the number of rows in the spritesheet, when in global mode. Defaults to 1.
+ * @param [optional] cycleDuration Defines the default cycle duration in seconds, when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the default cycle phase, when in global mode. Defaults to 0.
+ * @param [optional] totalFrames Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows.
+ * @param [optional] looping Defines whether the spritesheet animation is set to loop indefinitely. Defaults to true.
+ */
+ function ParticleSpriteSheetNode(mode /*uint*/, usesCycle, usesPhase, numColumns, numRows, cycleDuration, cyclePhase, totalFrames) {
+ if (numColumns === void 0) { numColumns = 1; }
+ if (numRows === void 0) { numRows = 1; }
+ if (cycleDuration === void 0) { cycleDuration = 1; }
+ if (cyclePhase === void 0) { cyclePhase = 0; }
+ if (totalFrames === void 0) { totalFrames = Number.MAX_VALUE; }
+ _super.call(this, "ParticleSpriteSheet", mode, usesCycle ? (usesPhase ? 3 : 2) : 1, ParticleAnimationSet.POST_PRIORITY + 1);
+ this._pStateClass = ParticleSpriteSheetState;
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+ this._iNumColumns = numColumns;
+ this._iNumRows = numRows;
+ this._iCyclePhase = cyclePhase;
+ this._iCycleDuration = cycleDuration;
+ this._iTotalFrames = Math.min(totalFrames, numColumns * numRows);
+ }
+ Object.defineProperty(ParticleSpriteSheetNode.prototype, "numColumns", {
+ /**
+ * Defines the number of columns in the spritesheet, when in global mode. Defaults to 1. Read only.
+ */
+ get: function () {
+ return this._iNumColumns;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSpriteSheetNode.prototype, "numRows", {
+ /**
+ * Defines the number of rows in the spritesheet, when in global mode. Defaults to 1. Read only.
+ */
+ get: function () {
+ return this._iNumRows;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSpriteSheetNode.prototype, "totalFrames", {
+ /**
+ * Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows. Read only.
+ */
+ get: function () {
+ return this._iTotalFrames;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleSpriteSheetNode.prototype.getAGALUVCode = function (shaderObject, animationRegisterCache) {
+ //get 2 vc
+ var uvParamConst1 = animationRegisterCache.getFreeVertexConstant();
+ var uvParamConst2 = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_0, uvParamConst1.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_1, uvParamConst2.index);
+ var uTotal = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 0);
+ var uStep = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 1);
+ var vStep = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 2);
+ var uSpeed = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 0);
+ var cycle = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 1);
+ var phaseTime = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 2);
+ var temp = animationRegisterCache.getFreeVertexVectorTemp();
+ var time = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var vOffset = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ temp = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ var temp2 = new ShaderRegisterElement(temp.regName, temp.index, 3);
+ var u = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, 0);
+ var v = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, 1);
+ var code = "";
+ //scale uv
+ code += "mul " + u + "," + u + "," + uStep + "\n";
+ if (this._iNumRows > 1)
+ code += "mul " + v + "," + v + "," + vStep + "\n";
+ if (this._iUsesCycle) {
+ if (this._iUsesPhase)
+ code += "add " + time + "," + animationRegisterCache.vertexTime + "," + phaseTime + "\n";
+ else
+ code += "mov " + time + "," + animationRegisterCache.vertexTime + "\n";
+ code += "div " + time + "," + time + "," + cycle + "\n";
+ code += "frc " + time + "," + time + "\n";
+ code += "mul " + time + "," + time + "," + cycle + "\n";
+ code += "mul " + temp + "," + time + "," + uSpeed + "\n";
+ }
+ else
+ code += "mul " + temp.toString() + "," + animationRegisterCache.vertexLife + "," + uTotal + "\n";
+ if (this._iNumRows > 1) {
+ code += "frc " + temp2 + "," + temp + "\n";
+ code += "sub " + vOffset + "," + temp + "," + temp2 + "\n";
+ code += "mul " + vOffset + "," + vOffset + "," + vStep + "\n";
+ code += "add " + v + "," + v + "," + vOffset + "\n";
+ }
+ code += "div " + temp2 + "," + temp + "," + uStep + "\n";
+ code += "frc " + temp + "," + temp2 + "\n";
+ code += "sub " + temp2 + "," + temp2 + "," + temp + "\n";
+ code += "mul " + temp + "," + temp2 + "," + uStep + "\n";
+ if (this._iNumRows > 1)
+ code += "frc " + temp + "," + temp + "\n";
+ code += "add " + u + "," + u + "," + temp + "\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleSpriteSheetNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleSpriteSheetNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ particleAnimationSet.hasUVNode = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleSpriteSheetNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ if (this._iUsesCycle) {
+ var uvCycle = param[ParticleSpriteSheetNode.UV_VECTOR3D];
+ if (!uvCycle)
+ throw (new Error("there is no " + ParticleSpriteSheetNode.UV_VECTOR3D + " in param!"));
+ if (uvCycle.x <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ var uTotal = this._iTotalFrames / this._iNumColumns;
+ this._pOneData[0] = uTotal / uvCycle.x;
+ this._pOneData[1] = uvCycle.x;
+ if (this._iUsesPhase)
+ this._pOneData[2] = uvCycle.y;
+ }
+ };
+ /**
+ * Reference for spritesheet node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
representing the cycleDuration (x), optional phaseTime (y).
+ */
+ ParticleSpriteSheetNode.UV_VECTOR3D = "UVVector3D";
+ return ParticleSpriteSheetNode;
+})(ParticleNodeBase);
+module.exports = ParticleSpriteSheetNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXNwcml0ZXNoZWV0bm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZSIsIlBhcnRpY2xlU3ByaXRlU2hlZXROb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVTcHJpdGVTaGVldE5vZGUubnVtQ29sdW1ucyIsIlBhcnRpY2xlU3ByaXRlU2hlZXROb2RlLm51bVJvd3MiLCJQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS50b3RhbEZyYW1lcyIsIlBhcnRpY2xlU3ByaXRlU2hlZXROb2RlLmdldEFHQUxVVkNvZGUiLCJQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlU3ByaXRlU2hlZXROb2RlLl9pUHJvY2Vzc0FuaW1hdGlvblNldHRpbmciLCJQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5faUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFLQSxJQUFPLHFCQUFxQixXQUFhLGdFQUFnRSxDQUFDLENBQUM7QUFFM0csSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBRWpHLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyx3QkFBd0IsV0FBYSxpRUFBaUUsQ0FBQyxDQUFDO0FBRS9HLEFBSUE7OztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQXlCQTtJQWlEckRBOzs7Ozs7Ozs7O09BVUdBO0lBQ0hBLFNBNURLQSx1QkFBdUJBLENBNERoQkEsSUFBSUEsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsU0FBaUJBLEVBQUVBLFNBQWlCQSxFQUFFQSxVQUE2QkEsRUFBRUEsT0FBMkJBLEVBQUVBLGFBQXdCQSxFQUFFQSxVQUFxQkEsRUFBRUEsV0FBOENBO1FBQTNKQywwQkFB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QkEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDeEVBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1lBQ3hEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUMxQ0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDeERBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBO1FBQzFEQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUNMQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxFQUFFQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBO1FBRWxHQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN4QkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDM0NBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE9BQU9BLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1lBQzNEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxPQUFPQSxHQUFHQSxHQUFHQSxHQUFHQSxPQUFPQSxHQUFHQSxHQUFHQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM5REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDckRBLENBQUNBO1FBRURBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1FBQ3pEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxHQUFHQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzQ0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDekRBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO1FBRXpEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUN0QkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0NBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBO1FBRWpEQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEsbURBQWlCQSxHQUF4QkEsVUFBeUJBLFFBQXFCQTtRQUU3Q00sTUFBTUEsQ0FBNEJBLFFBQVFBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDcEVBLENBQUNBO0lBRUROOztPQUVHQTtJQUNJQSwyREFBeUJBLEdBQWhDQSxVQUFpQ0Esb0JBQXlDQTtRQUV6RU8sb0JBQW9CQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUN2Q0EsQ0FBQ0E7SUFFRFA7O09BRUdBO0lBQ0lBLGlFQUErQkEsR0FBdENBLFVBQXVDQSxLQUF3QkE7UUFFOURRLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RCQSxJQUFJQSxPQUFPQSxHQUFZQSxLQUFLQSxDQUFDQSx1QkFBdUJBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO1lBQ2xFQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxPQUFPQSxDQUFDQTtnQkFDWkEsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsdUJBQXVCQSxDQUFDQSxXQUFXQSxHQUFHQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN2RkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ2xCQSxNQUFLQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSw4Q0FBOENBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xFQSxJQUFJQSxNQUFNQSxHQUFVQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQTtZQUN6REEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDckNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBO1lBQzlCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDcEJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBO1FBQ2hDQSxDQUFDQTtJQUNGQSxDQUFDQTtJQTNKRFI7OztPQUdHQTtJQUNXQSxtQ0FBV0EsR0FBVUEsWUFBWUEsQ0FBQ0E7SUF3SmpEQSw4QkFBQ0E7QUFBREEsQ0EvS0EsQUErS0NBLEVBL0txQyxnQkFBZ0IsRUErS3JEO0FBRUQsQUFBaUMsaUJBQXhCLHVCQUF1QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uU2V0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0aW9uU2V0XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVTcHJpdGVTaGVldFN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVTcHJpdGVTaGVldFN0YXRlXCIpO1xuXG4vKipcbiAqIEEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgdXNlZCB3aGVuIGEgc3ByaXRlc2hlZXQgdGV4dHVyZSBpcyByZXF1aXJlZCB0byBhbmltYXRlIHRoZSBwYXJ0aWNsZS5cbiAqIE5COiB0byBlbmFibGUgdXNlIG9mIHRoaXMgbm9kZSwgdGhlIDxjb2RlPnJlcGVhdDwvY29kZT4gcHJvcGVydHkgb24gdGhlIG1hdGVyaWFsIGhhcyB0byBiZSBzZXQgdG8gdHJ1ZS5cbiAqL1xuY2xhc3MgUGFydGljbGVTcHJpdGVTaGVldE5vZGUgZXh0ZW5kcyBQYXJ0aWNsZU5vZGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzQ3ljbGU6Ym9vbGVhbjtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc1BoYXNlOmJvb2xlYW47XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVRvdGFsRnJhbWVzOm51bWJlciAvKmludCovO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pTnVtQ29sdW1uczpudW1iZXIgLyppbnQqLztcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaU51bVJvd3M6bnVtYmVyIC8qaW50Ki87XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lDeWNsZUR1cmF0aW9uOm51bWJlcjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUN5Y2xlUGhhc2U6bnVtYmVyO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIHNwcml0ZXNoZWV0IG5vZGUgcHJvcGVydGllcyBvbiBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPlZlY3RvcjNEPC9jb2RlPiByZXByZXNlbnRpbmcgdGhlIGN5Y2xlRHVyYXRpb24gKHgpLCBvcHRpb25hbCBwaGFzZVRpbWUgKHkpLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBVVl9WRUNUT1IzRDpzdHJpbmcgPSBcIlVWVmVjdG9yM0RcIjtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHNwcml0ZXNoZWV0LCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLiBSZWFkIG9ubHkuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG51bUNvbHVtbnMoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9pTnVtQ29sdW1ucztcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBudW1iZXIgb2Ygcm93cyBpbiB0aGUgc3ByaXRlc2hlZXQsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEuIFJlYWQgb25seS5cblx0ICovXG5cdHB1YmxpYyBnZXQgbnVtUm93cygpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2lOdW1Sb3dzO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIHRvdGFsIG51bWJlciBvZiBmcmFtZXMgdXNlZCBieSB0aGUgc3ByaXRlc2hlZXQsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIHRoZSBudW1iZXIgZGVmaW5lZCBieSBudW1Db2x1bW5zIGFuZCBudW1Sb3dzLiBSZWFkIG9ubHkuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHRvdGFsRnJhbWVzKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faVRvdGFsRnJhbWVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVTcHJpdGVTaGVldE5vZGU8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSAgICAgICAgICAgICAgIG1vZGUgICAgICAgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIG1vZGUgb2Ygb3BlcmF0aW9uIGFjdHMgb24gbG9jYWwgcHJvcGVydGllcyBvZiBhIHBhcnRpY2xlIG9yIGdsb2JhbCBwcm9wZXJ0aWVzIG9mIHRoZSBub2RlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBudW1Db2x1bW5zICAgICAgRGVmaW5lcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHNwcml0ZXNoZWV0LCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBudW1Sb3dzICAgICAgICAgRGVmaW5lcyB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gdGhlIHNwcml0ZXNoZWV0LCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBjeWNsZUR1cmF0aW9uICAgRGVmaW5lcyB0aGUgZGVmYXVsdCBjeWNsZSBkdXJhdGlvbiBpbiBzZWNvbmRzLCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBjeWNsZVBoYXNlICAgICAgRGVmaW5lcyB0aGUgZGVmYXVsdCBjeWNsZSBwaGFzZSwgd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMC5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdG90YWxGcmFtZXMgICAgIERlZmluZXMgdGhlIHRvdGFsIG51bWJlciBvZiBmcmFtZXMgdXNlZCBieSB0aGUgc3ByaXRlc2hlZXQsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIHRoZSBudW1iZXIgZGVmaW5lZCBieSBudW1Db2x1bW5zIGFuZCBudW1Sb3dzLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBsb29waW5nICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBzcHJpdGVzaGVldCBhbmltYXRpb24gaXMgc2V0IHRvIGxvb3AgaW5kZWZpbml0ZWx5LiBEZWZhdWx0cyB0byB0cnVlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobW9kZTpudW1iZXIgLyp1aW50Ki8sIHVzZXNDeWNsZTpib29sZWFuLCB1c2VzUGhhc2U6Ym9vbGVhbiwgbnVtQ29sdW1uczpudW1iZXIgLyppbnQqLyA9IDEsIG51bVJvd3M6bnVtYmVyIC8qdWludCovID0gMSwgY3ljbGVEdXJhdGlvbjpudW1iZXIgPSAxLCBjeWNsZVBoYXNlOm51bWJlciA9IDAsIHRvdGFsRnJhbWVzOm51bWJlciAvKnVpbnQqLyA9IE51bWJlci5NQVhfVkFMVUUpXG5cdHtcblx0XHRzdXBlcihcIlBhcnRpY2xlU3ByaXRlU2hlZXRcIiwgbW9kZSwgdXNlc0N5Y2xlPyAodXNlc1BoYXNlPyAzIDogMikgOiAxLCBQYXJ0aWNsZUFuaW1hdGlvblNldC5QT1NUX1BSSU9SSVRZICsgMSk7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzQ3ljbGUgPSB1c2VzQ3ljbGU7XG5cdFx0dGhpcy5faVVzZXNQaGFzZSA9IHVzZXNQaGFzZTtcblxuXHRcdHRoaXMuX2lOdW1Db2x1bW5zID0gbnVtQ29sdW1ucztcblx0XHR0aGlzLl9pTnVtUm93cyA9IG51bVJvd3M7XG5cdFx0dGhpcy5faUN5Y2xlUGhhc2UgPSBjeWNsZVBoYXNlO1xuXHRcdHRoaXMuX2lDeWNsZUR1cmF0aW9uID0gY3ljbGVEdXJhdGlvbjtcblx0XHR0aGlzLl9pVG90YWxGcmFtZXMgPSBNYXRoLm1pbih0b3RhbEZyYW1lcywgbnVtQ29sdW1ucypudW1Sb3dzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHQvL2dldCAyIHZjXG5cdFx0dmFyIHV2UGFyYW1Db25zdDE6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHR2YXIgdXZQYXJhbUNvbnN0MjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSAodGhpcy5fcE1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpPyBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpIDogYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4QXR0cmlidXRlKCk7XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZS5VVl9JTkRFWF8wLCB1dlBhcmFtQ29uc3QxLmluZGV4KTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVTcHJpdGVTaGVldFN0YXRlLlVWX0lOREVYXzEsIHV2UGFyYW1Db25zdDIuaW5kZXgpO1xuXG5cdFx0dmFyIHVUb3RhbDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHV2UGFyYW1Db25zdDEucmVnTmFtZSwgdXZQYXJhbUNvbnN0MS5pbmRleCwgMCk7XG5cdFx0dmFyIHVTdGVwOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodXZQYXJhbUNvbnN0MS5yZWdOYW1lLCB1dlBhcmFtQ29uc3QxLmluZGV4LCAxKTtcblx0XHR2YXIgdlN0ZXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh1dlBhcmFtQ29uc3QxLnJlZ05hbWUsIHV2UGFyYW1Db25zdDEuaW5kZXgsIDIpO1xuXG5cdFx0dmFyIHVTcGVlZDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHV2UGFyYW1Db25zdDIucmVnTmFtZSwgdXZQYXJhbUNvbnN0Mi5pbmRleCwgMCk7XG5cdFx0dmFyIGN5Y2xlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodXZQYXJhbUNvbnN0Mi5yZWdOYW1lLCB1dlBhcmFtQ29uc3QyLmluZGV4LCAxKTtcblx0XHR2YXIgcGhhc2VUaW1lOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodXZQYXJhbUNvbnN0Mi5yZWdOYW1lLCB1dlBhcmFtQ29uc3QyLmluZGV4LCAyKTtcblxuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFZlY3RvclRlbXAoKTtcblx0XHR2YXIgdGltZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMCk7XG5cdFx0dmFyIHZPZmZzZXQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gbmV3IFNoYWRlclJlZ2lzdGVyRWxlbWVudCh0ZW1wLnJlZ05hbWUsIHRlbXAuaW5kZXgsIDEpO1xuXHRcdHRlbXAgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KHRlbXAucmVnTmFtZSwgdGVtcC5pbmRleCwgMik7XG5cdFx0dmFyIHRlbXAyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQodGVtcC5yZWdOYW1lLCB0ZW1wLmluZGV4LCAzKTtcblxuXHRcdHZhciB1OlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS51dlRhcmdldC5yZWdOYW1lLCBhbmltYXRpb25SZWdpc3RlckNhY2hlLnV2VGFyZ2V0LmluZGV4LCAwKTtcblx0XHR2YXIgdjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBuZXcgU2hhZGVyUmVnaXN0ZXJFbGVtZW50KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudXZUYXJnZXQucmVnTmFtZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS51dlRhcmdldC5pbmRleCwgMSk7XG5cblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdC8vc2NhbGUgdXZcblx0XHRjb2RlICs9IFwibXVsIFwiICsgdSArIFwiLFwiICsgdSArIFwiLFwiICsgdVN0ZXAgKyBcIlxcblwiO1xuXHRcdGlmICh0aGlzLl9pTnVtUm93cyA+IDEpXG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdiArIFwiLFwiICsgdiArIFwiLFwiICsgdlN0ZXAgKyBcIlxcblwiO1xuXG5cdFx0aWYgKHRoaXMuX2lVc2VzQ3ljbGUpIHtcblx0XHRcdGlmICh0aGlzLl9pVXNlc1BoYXNlKVxuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdGltZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyBwaGFzZVRpbWUgKyBcIlxcblwiO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRjb2RlICs9IFwibW92IFwiICsgdGltZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJkaXYgXCIgKyB0aW1lICsgXCIsXCIgKyB0aW1lICsgXCIsXCIgKyBjeWNsZSArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiZnJjIFwiICsgdGltZSArIFwiLFwiICsgdGltZSArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGltZSArIFwiLFwiICsgdGltZSArIFwiLFwiICsgY3ljbGUgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIixcIiArIHRpbWUgKyBcIixcIiArIHVTcGVlZCArIFwiXFxuXCI7XG5cdFx0fSBlbHNlXG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcC50b1N0cmluZygpICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleExpZmUgKyBcIixcIiArIHVUb3RhbCArIFwiXFxuXCI7XG5cblx0XHRpZiAodGhpcy5faU51bVJvd3MgPiAxKSB7XG5cdFx0XHRjb2RlICs9IFwiZnJjIFwiICsgdGVtcDIgKyBcIixcIiArIHRlbXAgKyBcIlxcblwiO1xuXHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHZPZmZzZXQgKyBcIixcIiArIHRlbXAgKyBcIixcIiArIHRlbXAyICsgXCJcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB2T2Zmc2V0ICsgXCIsXCIgKyB2T2Zmc2V0ICsgXCIsXCIgKyB2U3RlcCArIFwiXFxuXCI7XG5cdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdiArIFwiLFwiICsgdiArIFwiLFwiICsgdk9mZnNldCArIFwiXFxuXCI7XG5cdFx0fVxuXG5cdFx0Y29kZSArPSBcImRpdiBcIiArIHRlbXAyICsgXCIsXCIgKyB0ZW1wICsgXCIsXCIgKyB1U3RlcCArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcImZyYyBcIiArIHRlbXAgKyBcIixcIiArIHRlbXAyICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwic3ViIFwiICsgdGVtcDIgKyBcIixcIiArIHRlbXAyICsgXCIsXCIgKyB0ZW1wICsgXCJcXG5cIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcCArIFwiLFwiICsgdGVtcDIgKyBcIixcIiArIHVTdGVwICsgXCJcXG5cIjtcblxuXHRcdGlmICh0aGlzLl9pTnVtUm93cyA+IDEpXG5cdFx0XHRjb2RlICs9IFwiZnJjIFwiICsgdGVtcCArIFwiLFwiICsgdGVtcCArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcImFkZCBcIiArIHUgKyBcIixcIiArIHUgKyBcIixcIiArIHRlbXAgKyBcIlxcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZVNwcml0ZVNoZWV0U3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lQcm9jZXNzQW5pbWF0aW9uU2V0dGluZyhwYXJ0aWNsZUFuaW1hdGlvblNldDpQYXJ0aWNsZUFuaW1hdGlvblNldClcblx0e1xuXHRcdHBhcnRpY2xlQW5pbWF0aW9uU2V0Lmhhc1VWTm9kZSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaUdlbmVyYXRlUHJvcGVydHlPZk9uZVBhcnRpY2xlKHBhcmFtOlBhcnRpY2xlUHJvcGVydGllcylcblx0e1xuXHRcdGlmICh0aGlzLl9pVXNlc0N5Y2xlKSB7XG5cdFx0XHR2YXIgdXZDeWNsZTpWZWN0b3IzRCA9IHBhcmFtW1BhcnRpY2xlU3ByaXRlU2hlZXROb2RlLlVWX1ZFQ1RPUjNEXTtcblx0XHRcdGlmICghdXZDeWNsZSlcblx0XHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlcmUgaXMgbm8gXCIgKyBQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5VVl9WRUNUT1IzRCArIFwiIGluIHBhcmFtIVwiKSk7XG5cdFx0XHRpZiAodXZDeWNsZS54IDw9IDApXG5cdFx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHRcdHZhciB1VG90YWw6bnVtYmVyID0gdGhpcy5faVRvdGFsRnJhbWVzL3RoaXMuX2lOdW1Db2x1bW5zO1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbMF0gPSB1VG90YWwvdXZDeWNsZS54O1xuXHRcdFx0dGhpcy5fcE9uZURhdGFbMV0gPSB1dkN5Y2xlLng7XG5cdFx0XHRpZiAodGhpcy5faVVzZXNQaGFzZSlcblx0XHRcdFx0dGhpcy5fcE9uZURhdGFbMl0gPSB1dkN5Y2xlLnk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlU3ByaXRlU2hlZXROb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleSpriteSheetNode.ts b/lib/animators/nodes/ParticleSpriteSheetNode.ts
new file mode 100644
index 000000000..d5b17daaf
--- /dev/null
+++ b/lib/animators/nodes/ParticleSpriteSheetNode.ts
@@ -0,0 +1,195 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleSpriteSheetState = require("awayjs-renderergl/lib/animators/states/ParticleSpriteSheetState");
+
+/**
+ * A particle animation node used when a spritesheet texture is required to animate the particle.
+ * NB: to enable use of this node, the repeat
property on the material has to be set to true.
+ */
+class ParticleSpriteSheetNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesCycle:boolean;
+
+ /** @private */
+ public _iUsesPhase:boolean;
+
+ /** @private */
+ public _iTotalFrames:number /*int*/;
+ /** @private */
+ public _iNumColumns:number /*int*/;
+ /** @private */
+ public _iNumRows:number /*int*/;
+ /** @private */
+ public _iCycleDuration:number;
+ /** @private */
+ public _iCyclePhase:number;
+
+ /**
+ * Reference for spritesheet node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
representing the cycleDuration (x), optional phaseTime (y).
+ */
+ public static UV_VECTOR3D:string = "UVVector3D";
+
+ /**
+ * Defines the number of columns in the spritesheet, when in global mode. Defaults to 1. Read only.
+ */
+ public get numColumns():number
+ {
+ return this._iNumColumns;
+ }
+
+ /**
+ * Defines the number of rows in the spritesheet, when in global mode. Defaults to 1. Read only.
+ */
+ public get numRows():number
+ {
+ return this._iNumRows;
+ }
+
+ /**
+ * Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows. Read only.
+ */
+ public get totalFrames():number
+ {
+ return this._iTotalFrames;
+ }
+
+ /**
+ * Creates a new ParticleSpriteSheetNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] numColumns Defines the number of columns in the spritesheet, when in global mode. Defaults to 1.
+ * @param [optional] numRows Defines the number of rows in the spritesheet, when in global mode. Defaults to 1.
+ * @param [optional] cycleDuration Defines the default cycle duration in seconds, when in global mode. Defaults to 1.
+ * @param [optional] cyclePhase Defines the default cycle phase, when in global mode. Defaults to 0.
+ * @param [optional] totalFrames Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows.
+ * @param [optional] looping Defines whether the spritesheet animation is set to loop indefinitely. Defaults to true.
+ */
+ constructor(mode:number /*uint*/, usesCycle:boolean, usesPhase:boolean, numColumns:number /*int*/ = 1, numRows:number /*uint*/ = 1, cycleDuration:number = 1, cyclePhase:number = 0, totalFrames:number /*uint*/ = Number.MAX_VALUE)
+ {
+ super("ParticleSpriteSheet", mode, usesCycle? (usesPhase? 3 : 2) : 1, ParticleAnimationSet.POST_PRIORITY + 1);
+
+ this._pStateClass = ParticleSpriteSheetState;
+
+ this._iUsesCycle = usesCycle;
+ this._iUsesPhase = usesPhase;
+
+ this._iNumColumns = numColumns;
+ this._iNumRows = numRows;
+ this._iCyclePhase = cyclePhase;
+ this._iCycleDuration = cycleDuration;
+ this._iTotalFrames = Math.min(totalFrames, numColumns*numRows);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ //get 2 vc
+ var uvParamConst1:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ var uvParamConst2:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_0, uvParamConst1.index);
+ animationRegisterCache.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_1, uvParamConst2.index);
+
+ var uTotal:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 0);
+ var uStep:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 1);
+ var vStep:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 2);
+
+ var uSpeed:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 0);
+ var cycle:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 1);
+ var phaseTime:ShaderRegisterElement = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 2);
+
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var time:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 0);
+ var vOffset:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 1);
+ temp = new ShaderRegisterElement(temp.regName, temp.index, 2);
+ var temp2:ShaderRegisterElement = new ShaderRegisterElement(temp.regName, temp.index, 3);
+
+ var u:ShaderRegisterElement = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, 0);
+ var v:ShaderRegisterElement = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, 1);
+
+ var code:string = "";
+ //scale uv
+ code += "mul " + u + "," + u + "," + uStep + "\n";
+ if (this._iNumRows > 1)
+ code += "mul " + v + "," + v + "," + vStep + "\n";
+
+ if (this._iUsesCycle) {
+ if (this._iUsesPhase)
+ code += "add " + time + "," + animationRegisterCache.vertexTime + "," + phaseTime + "\n";
+ else
+ code += "mov " + time + "," + animationRegisterCache.vertexTime + "\n";
+ code += "div " + time + "," + time + "," + cycle + "\n";
+ code += "frc " + time + "," + time + "\n";
+ code += "mul " + time + "," + time + "," + cycle + "\n";
+ code += "mul " + temp + "," + time + "," + uSpeed + "\n";
+ } else
+ code += "mul " + temp.toString() + "," + animationRegisterCache.vertexLife + "," + uTotal + "\n";
+
+ if (this._iNumRows > 1) {
+ code += "frc " + temp2 + "," + temp + "\n";
+ code += "sub " + vOffset + "," + temp + "," + temp2 + "\n";
+ code += "mul " + vOffset + "," + vOffset + "," + vStep + "\n";
+ code += "add " + v + "," + v + "," + vOffset + "\n";
+ }
+
+ code += "div " + temp2 + "," + temp + "," + uStep + "\n";
+ code += "frc " + temp + "," + temp2 + "\n";
+ code += "sub " + temp2 + "," + temp2 + "," + temp + "\n";
+ code += "mul " + temp + "," + temp2 + "," + uStep + "\n";
+
+ if (this._iNumRows > 1)
+ code += "frc " + temp + "," + temp + "\n";
+ code += "add " + u + "," + u + "," + temp + "\n";
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleSpriteSheetState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ particleAnimationSet.hasUVNode = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ if (this._iUsesCycle) {
+ var uvCycle:Vector3D = param[ParticleSpriteSheetNode.UV_VECTOR3D];
+ if (!uvCycle)
+ throw(new Error("there is no " + ParticleSpriteSheetNode.UV_VECTOR3D + " in param!"));
+ if (uvCycle.x <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ var uTotal:number = this._iTotalFrames/this._iNumColumns;
+ this._pOneData[0] = uTotal/uvCycle.x;
+ this._pOneData[1] = uvCycle.x;
+ if (this._iUsesPhase)
+ this._pOneData[2] = uvCycle.y;
+ }
+ }
+}
+
+export = ParticleSpriteSheetNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleTimeNode.js b/lib/animators/nodes/ParticleTimeNode.js
new file mode 100755
index 000000000..f19efe244
--- /dev/null
+++ b/lib/animators/nodes/ParticleTimeNode.js
@@ -0,0 +1,90 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleTimeState = require("awayjs-renderergl/lib/animators/states/ParticleTimeState");
+/**
+ * A particle animation node used as the base node for timekeeping inside a particle. Automatically added to a particle animation set on instatiation.
+ */
+var ParticleTimeNode = (function (_super) {
+ __extends(ParticleTimeNode, _super);
+ /**
+ * Creates a new ParticleTimeNode
+ *
+ * @param [optional] usesDuration Defines whether the node uses the duration
data in the static properties to determine how long a particle is visible for. Defaults to false.
+ * @param [optional] usesDelay Defines whether the node uses the delay
data in the static properties to determine how long a particle is hidden for. Defaults to false. Requires usesDuration
to be true.
+ * @param [optional] usesLooping Defines whether the node creates a looping timeframe for each particle determined by the startTime
, duration
and delay
data in the static properties function. Defaults to false. Requires usesLooping
to be true.
+ */
+ function ParticleTimeNode(usesDuration, usesLooping, usesDelay) {
+ if (usesDuration === void 0) { usesDuration = false; }
+ if (usesLooping === void 0) { usesLooping = false; }
+ if (usesDelay === void 0) { usesDelay = false; }
+ this._pStateClass = ParticleTimeState;
+ this._iUsesDuration = usesDuration;
+ this._iUsesLooping = usesLooping;
+ this._iUsesDelay = usesDelay;
+ _super.call(this, "ParticleTime", ParticlePropertiesMode.LOCAL_STATIC, 4, 0);
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleTimeNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var timeStreamRegister = animationRegisterCache.getFreeVertexAttribute(); //timeStreamRegister.x is start,timeStreamRegister.y is during time
+ animationRegisterCache.setRegisterIndex(this, ParticleTimeState.TIME_STREAM_INDEX, timeStreamRegister.index);
+ var timeConst = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleTimeState.TIME_CONSTANT_INDEX, timeConst.index);
+ var code = "";
+ code += "sub " + animationRegisterCache.vertexTime + "," + timeConst + "," + timeStreamRegister + ".x\n";
+ //if time=0,set the position to zero.
+ var temp = animationRegisterCache.getFreeVertexSingleTemp();
+ code += "sge " + temp + "," + animationRegisterCache.vertexTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+ if (this._iUsesDuration) {
+ if (this._iUsesLooping) {
+ var div = animationRegisterCache.getFreeVertexSingleTemp();
+ if (this._iUsesDelay) {
+ code += "div " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".z\n";
+ code += "frc " + div + "," + div + "\n";
+ code += "mul " + animationRegisterCache.vertexTime + "," + div + "," + timeStreamRegister + ".z\n";
+ code += "slt " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".y\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + div + "\n";
+ }
+ else {
+ code += "mul " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".w\n";
+ code += "frc " + div + "," + div + "\n";
+ code += "mul " + animationRegisterCache.vertexTime + "," + div + "," + timeStreamRegister + ".y\n";
+ }
+ }
+ else {
+ var sge = animationRegisterCache.getFreeVertexSingleTemp();
+ code += "sge " + sge + "," + timeStreamRegister + ".y," + animationRegisterCache.vertexTime + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + sge + "\n";
+ }
+ }
+ code += "mul " + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".w\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleTimeNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleTimeNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ this._pOneData[0] = param.startTime;
+ this._pOneData[1] = param.duration;
+ this._pOneData[2] = param.delay + param.duration;
+ this._pOneData[3] = 1 / param.duration;
+ };
+ return ParticleTimeNode;
+})(ParticleNodeBase);
+module.exports = ParticleTimeNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXRpbWVub2RlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlVGltZU5vZGUiLCJQYXJ0aWNsZVRpbWVOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVUaW1lTm9kZS5nZXRBR0FMVmVydGV4Q29kZSIsIlBhcnRpY2xlVGltZU5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiLCJQYXJ0aWNsZVRpbWVOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVFBLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxnQkFBZ0I7SUFBU0EsVUFBekJBLGdCQUFnQkEsVUFBeUJBO0lBUzlDQTs7Ozs7O09BTUdBO0lBQ0hBLFNBaEJLQSxnQkFBZ0JBLENBZ0JUQSxZQUE0QkEsRUFBRUEsV0FBMkJBLEVBQUVBLFNBQXlCQTtRQUFwRkMsNEJBQTRCQSxHQUE1QkEsb0JBQTRCQTtRQUFFQSwyQkFBMkJBLEdBQTNCQSxtQkFBMkJBO1FBQUVBLHlCQUF5QkEsR0FBekJBLGlCQUF5QkE7UUFFL0ZBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLGlCQUFpQkEsQ0FBQ0E7UUFFdENBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFlBQVlBLENBQUNBO1FBQ25DQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxXQUFXQSxDQUFDQTtRQUNqQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsU0FBU0EsQ0FBQ0E7UUFFN0JBLGtCQUFNQSxjQUFjQSxFQUFFQSxzQkFBc0JBLENBQUNBLFlBQVlBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO0lBQ2xFQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsNENB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QUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDN0RBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSwwREFBK0JBLEdBQXRDQSxVQUF1Q0EsS0FBd0JBO1FBRTlESSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUNwQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsUUFBUUEsQ0FBQ0E7UUFDbkNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLENBQUNBLFFBQVFBLENBQUNBO1FBQ2pEQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQTtJQUV0Q0EsQ0FBQ0E7SUFDRkosdUJBQUNBO0FBQURBLENBdEZBLEFBc0ZDQSxFQXRGOEIsZ0JBQWdCLEVBc0Y5QztBQUVELEFBQTBCLGlCQUFqQixnQkFBZ0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVUaW1lTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc1x0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc1wiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVUaW1lU3RhdGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlVGltZVN0YXRlXCIpO1xuXG4vKipcbiAqIEEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgdXNlZCBhcyB0aGUgYmFzZSBub2RlIGZvciB0aW1la2VlcGluZyBpbnNpZGUgYSBwYXJ0aWNsZS4gQXV0b21hdGljYWxseSBhZGRlZCB0byBhIHBhcnRpY2xlIGFuaW1hdGlvbiBzZXQgb24gaW5zdGF0aWF0aW9uLlxuICovXG5jbGFzcyBQYXJ0aWNsZVRpbWVOb2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc0R1cmF0aW9uOmJvb2xlYW47XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzRGVsYXk6Ym9vbGVhbjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVVzZXNMb29waW5nOmJvb2xlYW47XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UGFydGljbGVUaW1lTm9kZTwvY29kZT5cblx0ICpcblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gdXNlc0R1cmF0aW9uICAgIERlZmluZXMgd2hldGhlciB0aGUgbm9kZSB1c2VzIHRoZSA8Y29kZT5kdXJhdGlvbjwvY29kZT4gZGF0YSBpbiB0aGUgc3RhdGljIHByb3BlcnRpZXMgdG8gZGV0ZXJtaW5lIGhvdyBsb25nIGEgcGFydGljbGUgaXMgdmlzaWJsZSBmb3IuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzRGVsYXkgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBub2RlIHVzZXMgdGhlIDxjb2RlPmRlbGF5PC9jb2RlPiBkYXRhIGluIHRoZSBzdGF0aWMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgaG93IGxvbmcgYSBwYXJ0aWNsZSBpcyBoaWRkZW4gZm9yLiBEZWZhdWx0cyB0byBmYWxzZS4gUmVxdWlyZXMgPGNvZGU+dXNlc0R1cmF0aW9uPC9jb2RlPiB0byBiZSB0cnVlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSB1c2VzTG9vcGluZyAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSBub2RlIGNyZWF0ZXMgYSBsb29waW5nIHRpbWVmcmFtZSBmb3IgZWFjaCBwYXJ0aWNsZSBkZXRlcm1pbmVkIGJ5IHRoZSA8Y29kZT5zdGFydFRpbWU8L2NvZGU+LCA8Y29kZT5kdXJhdGlvbjwvY29kZT4gYW5kIDxjb2RlPmRlbGF5PC9jb2RlPiBkYXRhIGluIHRoZSBzdGF0aWMgcHJvcGVydGllcyBmdW5jdGlvbi4gRGVmYXVsdHMgdG8gZmFsc2UuIFJlcXVpcmVzIDxjb2RlPnVzZXNMb29waW5nPC9jb2RlPiB0byBiZSB0cnVlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IodXNlc0R1cmF0aW9uOmJvb2xlYW4gPSBmYWxzZSwgdXNlc0xvb3Bpbmc6Ym9vbGVhbiA9IGZhbHNlLCB1c2VzRGVsYXk6Ym9vbGVhbiA9IGZhbHNlKVxuXHR7XG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBQYXJ0aWNsZVRpbWVTdGF0ZTtcblxuXHRcdHRoaXMuX2lVc2VzRHVyYXRpb24gPSB1c2VzRHVyYXRpb247XG5cdFx0dGhpcy5faVVzZXNMb29waW5nID0gdXNlc0xvb3Bpbmc7XG5cdFx0dGhpcy5faVVzZXNEZWxheSA9IHVzZXNEZWxheTtcblxuXHRcdHN1cGVyKFwiUGFydGljbGVUaW1lXCIsIFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfU1RBVElDLCA0LCAwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHRpbWVTdHJlYW1SZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKTsgLy90aW1lU3RyZWFtUmVnaXN0ZXIueCBpcyBzdGFydO+8jHRpbWVTdHJlYW1SZWdpc3Rlci55IGlzIGR1cmluZyB0aW1lXG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRSZWdpc3RlckluZGV4KHRoaXMsIFBhcnRpY2xlVGltZVN0YXRlLlRJTUVfU1RSRUFNX0lOREVYLCB0aW1lU3RyZWFtUmVnaXN0ZXIuaW5kZXgpO1xuXHRcdHZhciB0aW1lQ29uc3Q6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVUaW1lU3RhdGUuVElNRV9DT05TVEFOVF9JTkRFWCwgdGltZUNvbnN0LmluZGV4KTtcblxuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0Y29kZSArPSBcInN1YiBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgdGltZUNvbnN0ICsgXCIsXCIgKyB0aW1lU3RyZWFtUmVnaXN0ZXIgKyBcIi54XFxuXCI7XG5cdFx0Ly9pZiB0aW1lPTAsc2V0IHRoZSBwb3NpdGlvbiB0byB6ZXJvLlxuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleFNpbmdsZVRlbXAoKTtcblx0XHRjb2RlICs9IFwic2dlIFwiICsgdGVtcCArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFplcm9Db25zdCArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgdGVtcCArIFwiXFxuXCI7XG5cdFx0aWYgKHRoaXMuX2lVc2VzRHVyYXRpb24pIHtcblx0XHRcdGlmICh0aGlzLl9pVXNlc0xvb3BpbmcpIHtcblx0XHRcdFx0dmFyIGRpdjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhTaW5nbGVUZW1wKCk7XG5cdFx0XHRcdGlmICh0aGlzLl9pVXNlc0RlbGF5KSB7XG5cdFx0XHRcdFx0Y29kZSArPSBcImRpdiBcIiArIGRpdiArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyB0aW1lU3RyZWFtUmVnaXN0ZXIgKyBcIi56XFxuXCI7XG5cdFx0XHRcdFx0Y29kZSArPSBcImZyYyBcIiArIGRpdiArIFwiLFwiICsgZGl2ICsgXCJcXG5cIjtcblx0XHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyBkaXYgKyBcIixcIiArIHRpbWVTdHJlYW1SZWdpc3RlciArIFwiLnpcXG5cIjtcblx0XHRcdFx0XHRjb2RlICs9IFwic2x0IFwiICsgZGl2ICsgXCIsXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnZlcnRleFRpbWUgKyBcIixcIiArIHRpbWVTdHJlYW1SZWdpc3RlciArIFwiLnlcXG5cIjtcblx0XHRcdFx0XHRjb2RlICs9IFwibXVsIFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zY2FsZUFuZFJvdGF0ZVRhcmdldCArIFwiLnh5eixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBkaXYgKyBcIlxcblwiO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBkaXYgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgdGltZVN0cmVhbVJlZ2lzdGVyICsgXCIud1xcblwiO1xuXHRcdFx0XHRcdGNvZGUgKz0gXCJmcmMgXCIgKyBkaXYgKyBcIixcIiArIGRpdiArIFwiXFxuXCI7XG5cdFx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgZGl2ICsgXCIsXCIgKyB0aW1lU3RyZWFtUmVnaXN0ZXIgKyBcIi55XFxuXCI7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHZhciBzZ2U6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4U2luZ2xlVGVtcCgpO1xuXHRcdFx0XHRjb2RlICs9IFwic2dlIFwiICsgc2dlICsgXCIsXCIgKyB0aW1lU3RyZWFtUmVnaXN0ZXIgKyBcIi55LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCJcXG5cIjtcblx0XHRcdFx0Y29kZSArPSBcIm11bCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2NhbGVBbmRSb3RhdGVUYXJnZXQgKyBcIi54eXosXCIgKyBhbmltYXRpb25SZWdpc3RlckNhY2hlLnNjYWxlQW5kUm90YXRlVGFyZ2V0ICsgXCIueHl6LFwiICsgc2dlICsgXCJcXG5cIjtcblx0XHRcdH1cblx0XHR9XG5cdFx0Y29kZSArPSBcIm11bCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4TGlmZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZXJ0ZXhUaW1lICsgXCIsXCIgKyB0aW1lU3RyZWFtUmVnaXN0ZXIgKyBcIi53XFxuXCI7XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlVGltZVN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFBhcnRpY2xlVGltZVN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUocGFyYW06UGFydGljbGVQcm9wZXJ0aWVzKVxuXHR7XG5cdFx0dGhpcy5fcE9uZURhdGFbMF0gPSBwYXJhbS5zdGFydFRpbWU7XG5cdFx0dGhpcy5fcE9uZURhdGFbMV0gPSBwYXJhbS5kdXJhdGlvbjtcblx0XHR0aGlzLl9wT25lRGF0YVsyXSA9IHBhcmFtLmRlbGF5ICsgcGFyYW0uZHVyYXRpb247XG5cdFx0dGhpcy5fcE9uZURhdGFbM10gPSAxL3BhcmFtLmR1cmF0aW9uO1xuXG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVUaW1lTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleTimeNode.ts b/lib/animators/nodes/ParticleTimeNode.ts
new file mode 100644
index 000000000..2a63b1f06
--- /dev/null
+++ b/lib/animators/nodes/ParticleTimeNode.ts
@@ -0,0 +1,104 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleTimeState = require("awayjs-renderergl/lib/animators/states/ParticleTimeState");
+
+/**
+ * A particle animation node used as the base node for timekeeping inside a particle. Automatically added to a particle animation set on instatiation.
+ */
+class ParticleTimeNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUsesDuration:boolean;
+ /** @private */
+ public _iUsesDelay:boolean;
+ /** @private */
+ public _iUsesLooping:boolean;
+
+ /**
+ * Creates a new ParticleTimeNode
+ *
+ * @param [optional] usesDuration Defines whether the node uses the duration
data in the static properties to determine how long a particle is visible for. Defaults to false.
+ * @param [optional] usesDelay Defines whether the node uses the delay
data in the static properties to determine how long a particle is hidden for. Defaults to false. Requires usesDuration
to be true.
+ * @param [optional] usesLooping Defines whether the node creates a looping timeframe for each particle determined by the startTime
, duration
and delay
data in the static properties function. Defaults to false. Requires usesLooping
to be true.
+ */
+ constructor(usesDuration:boolean = false, usesLooping:boolean = false, usesDelay:boolean = false)
+ {
+ this._pStateClass = ParticleTimeState;
+
+ this._iUsesDuration = usesDuration;
+ this._iUsesLooping = usesLooping;
+ this._iUsesDelay = usesDelay;
+
+ super("ParticleTime", ParticlePropertiesMode.LOCAL_STATIC, 4, 0);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var timeStreamRegister:ShaderRegisterElement = animationRegisterCache.getFreeVertexAttribute(); //timeStreamRegister.x is start,timeStreamRegister.y is during time
+ animationRegisterCache.setRegisterIndex(this, ParticleTimeState.TIME_STREAM_INDEX, timeStreamRegister.index);
+ var timeConst:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleTimeState.TIME_CONSTANT_INDEX, timeConst.index);
+
+ var code:string = "";
+ code += "sub " + animationRegisterCache.vertexTime + "," + timeConst + "," + timeStreamRegister + ".x\n";
+ //if time=0,set the position to zero.
+ var temp:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+ code += "sge " + temp + "," + animationRegisterCache.vertexTime + "," + animationRegisterCache.vertexZeroConst + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + temp + "\n";
+ if (this._iUsesDuration) {
+ if (this._iUsesLooping) {
+ var div:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+ if (this._iUsesDelay) {
+ code += "div " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".z\n";
+ code += "frc " + div + "," + div + "\n";
+ code += "mul " + animationRegisterCache.vertexTime + "," + div + "," + timeStreamRegister + ".z\n";
+ code += "slt " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".y\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + div + "\n";
+ } else {
+ code += "mul " + div + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".w\n";
+ code += "frc " + div + "," + div + "\n";
+ code += "mul " + animationRegisterCache.vertexTime + "," + div + "," + timeStreamRegister + ".y\n";
+ }
+ } else {
+ var sge:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+ code += "sge " + sge + "," + timeStreamRegister + ".y," + animationRegisterCache.vertexTime + "\n";
+ code += "mul " + animationRegisterCache.scaleAndRotateTarget + ".xyz," + animationRegisterCache.scaleAndRotateTarget + ".xyz," + sge + "\n";
+ }
+ }
+ code += "mul " + animationRegisterCache.vertexLife + "," + animationRegisterCache.vertexTime + "," + timeStreamRegister + ".w\n";
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleTimeState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ this._pOneData[0] = param.startTime;
+ this._pOneData[1] = param.duration;
+ this._pOneData[2] = param.delay + param.duration;
+ this._pOneData[3] = 1/param.duration;
+
+ }
+}
+
+export = ParticleTimeNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleUVNode.js b/lib/animators/nodes/ParticleUVNode.js
new file mode 100755
index 000000000..681c1a2c2
--- /dev/null
+++ b/lib/animators/nodes/ParticleUVNode.js
@@ -0,0 +1,123 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+var ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleUVState = require("awayjs-renderergl/lib/animators/states/ParticleUVState");
+/**
+ * A particle animation node used to control the UV offset and scale of a particle over time.
+ */
+var ParticleUVNode = (function (_super) {
+ __extends(ParticleUVNode, _super);
+ /**
+ * Creates a new ParticleTimeNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] cycle Defines whether the time track is in loop mode. Defaults to false.
+ * @param [optional] scale Defines whether the time track is in loop mode. Defaults to false.
+ * @param [optional] axis Defines whether the time track is in loop mode. Defaults to false.
+ */
+ function ParticleUVNode(mode /*uint*/, cycle, scale, axis) {
+ if (cycle === void 0) { cycle = 1; }
+ if (scale === void 0) { scale = 1; }
+ if (axis === void 0) { axis = "x"; }
+ //because of the stage3d register limitation, it only support the global mode
+ _super.call(this, "ParticleUV", ParticlePropertiesMode.GLOBAL, 4, ParticleAnimationSet.POST_PRIORITY + 1);
+ this._pStateClass = ParticleUVState;
+ this._cycle = cycle;
+ this._scale = scale;
+ this._axis = axis;
+ this.updateUVData();
+ }
+ Object.defineProperty(ParticleUVNode.prototype, "cycle", {
+ /**
+ *
+ */
+ get: function () {
+ return this._cycle;
+ },
+ set: function (value) {
+ this._cycle = value;
+ this.updateUVData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleUVNode.prototype, "scale", {
+ /**
+ *
+ */
+ get: function () {
+ return this._scale;
+ },
+ set: function (value) {
+ this._scale = value;
+ this.updateUVData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleUVNode.prototype, "axis", {
+ /**
+ *
+ */
+ get: function () {
+ return this._axis;
+ },
+ set: function (value) {
+ this._axis = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleUVNode.prototype.getAGALUVCode = function (shaderObject, animationRegisterCache) {
+ var code = "";
+ var uvConst = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleUVState.UV_INDEX, uvConst.index);
+ var axisIndex = this._axis == "x" ? 0 : (this._axis == "y" ? 1 : 2);
+ var target = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, axisIndex);
+ var sin = animationRegisterCache.getFreeVertexSingleTemp();
+ if (this._scale != 1)
+ code += "mul " + target + "," + target + "," + uvConst + ".y\n";
+ code += "mul " + sin + "," + animationRegisterCache.vertexTime + "," + uvConst + ".x\n";
+ code += "sin " + sin + "," + sin + "\n";
+ code += "add " + target + "," + target + "," + sin + "\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleUVNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ ParticleUVNode.prototype.updateUVData = function () {
+ this._iUvData = new Vector3D(Math.PI * 2 / this._cycle, this._scale, 0, 0);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleUVNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) {
+ particleAnimationSet.hasUVNode = true;
+ };
+ /**
+ *
+ */
+ ParticleUVNode.U_AXIS = "x";
+ /**
+ *
+ */
+ ParticleUVNode.V_AXIS = "y";
+ return ParticleUVNode;
+})(ParticleNodeBase);
+module.exports = ParticleUVNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXV2bm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVVWTm9kZSIsIlBhcnRpY2xlVVZOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVVVk5vZGUuY3ljbGUiLCJQYXJ0aWNsZVVWTm9kZS5zY2FsZSIsIlBhcnRpY2xlVVZOb2RlLmF4aXMiLCJQYXJ0aWNsZVVWTm9kZS5nZXRBR0FMVVZDb2RlIiwiUGFydGljbGVVVk5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiLCJQYXJ0aWNsZVVWTm9kZS51cGRhdGVVVkRhdGEiLCJQYXJ0aWNsZVVWTm9kZS5faVByb2Nlc3NBbmltYXRpb25TZXR0aW5nIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUt0RSxJQUFPLHFCQUFxQixXQUFhLGdFQUFnRSxDQUFDLENBQUM7QUFFM0csSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBRWpHLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxlQUFlLFdBQWUsd0RBQXdELENBQUMsQ0FBQztBQUUvRixBQUdBOztHQURHO0lBQ0csY0FBYztJQUFTQSxVQUF2QkEsY0FBY0EsVUFBeUJBO0lBbUI1Q0E7Ozs7Ozs7T0FPR0E7SUFDSEEsU0EzQktBLGNBQWNBLENBMkJQQSxJQUFJQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxLQUFnQkEsRUFBRUEsS0FBZ0JBLEVBQUVBLElBQWlCQTtRQUFyREMscUJBQWdCQSxHQUFoQkEsU0FBZ0JBO1FBQUVBLHFCQUFnQkEsR0FBaEJBLFNBQWdCQTtRQUFFQSxvQkFBaUJBLEdBQWpCQSxVQUFpQkE7UUFFdEZBLEFBQ0FBLDZFQUQ2RUE7UUFDN0VBLGtCQUFNQSxZQUFZQSxFQUFFQSxzQkFBc0JBLENBQUNBLE1BQU1BLEVBQUVBLENB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QUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUN4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFFMURBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURMOztPQUVHQTtJQUNJQSwwQ0FBaUJBLEdBQXhCQSxVQUF5QkEsUUFBcUJBO1FBRTdDTSxNQUFNQSxDQUFtQkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUMzREEsQ0FBQ0E7SUFFT04scUNBQVlBLEdBQXBCQTtRQUVDTyxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFDQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUN4RUEsQ0FBQ0E7SUFFRFA7O09BRUdBO0lBQ0lBLGtEQUF5QkEsR0FBaENBLFVBQWlDQSxvQkFBeUNBO1FBRXpFUSxvQkFBb0JBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBO0lBQ3ZDQSxDQUFDQTtJQTVIRFI7O09BRUdBO0lBQ1dBLHFCQUFNQSxHQUFVQSxHQUFHQSxDQUFDQTtJQUVsQ0E7O09BRUdBO0lBQ1dBLHFCQUFNQSxHQUFVQSxHQUFHQSxDQUFDQTtJQXFIbkNBLHFCQUFDQTtBQUFEQSxDQWxJQSxBQWtJQ0EsRUFsSTRCLGdCQUFnQixFQWtJNUM7QUFFRCxBQUF3QixpQkFBZixjQUFjLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlVVZOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVVWU3RhdGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVVVlN0YXRlXCIpO1xuXG4vKipcbiAqIEEgcGFydGljbGUgYW5pbWF0aW9uIG5vZGUgdXNlZCB0byBjb250cm9sIHRoZSBVViBvZmZzZXQgYW5kIHNjYWxlIG9mIGEgcGFydGljbGUgb3ZlciB0aW1lLlxuICovXG5jbGFzcyBQYXJ0aWNsZVVWTm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVV2RGF0YTpWZWN0b3IzRDtcblxuXHQvKipcblx0ICpcblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgVV9BWElTOnN0cmluZyA9IFwieFwiO1xuXG5cdC8qKlxuXHQgKlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBWX0FYSVM6c3RyaW5nID0gXCJ5XCI7XG5cblx0cHJpdmF0ZSBfY3ljbGU6bnVtYmVyO1xuXHRwcml2YXRlIF9zY2FsZTpudW1iZXI7XG5cdHByaXZhdGUgX2F4aXM6c3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBhcnRpY2xlVGltZU5vZGU8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSAgICAgICAgICAgICAgIG1vZGUgICAgICAgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIG1vZGUgb2Ygb3BlcmF0aW9uIGFjdHMgb24gbG9jYWwgcHJvcGVydGllcyBvZiBhIHBhcnRpY2xlIG9yIGdsb2JhbCBwcm9wZXJ0aWVzIG9mIHRoZSBub2RlLlxuXHQgKiBAcGFyYW0gICAgW29wdGlvbmFsXSBjeWNsZSAgICAgICAgICAgRGVmaW5lcyB3aGV0aGVyIHRoZSB0aW1lIHRyYWNrIGlzIGluIGxvb3AgbW9kZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHNjYWxlICAgICAgICAgICBEZWZpbmVzIHdoZXRoZXIgdGhlIHRpbWUgdHJhY2sgaXMgaW4gbG9vcCBtb2RlLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICogQHBhcmFtICAgIFtvcHRpb25hbF0gYXhpcyAgICAgICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgdGltZSB0cmFjayBpcyBpbiBsb29wIG1vZGUuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobW9kZTpudW1iZXIgLyp1aW50Ki8sIGN5Y2xlOm51bWJlciA9IDEsIHNjYWxlOm51bWJlciA9IDEsIGF4aXM6c3RyaW5nID0gXCJ4XCIpXG5cdHtcblx0XHQvL2JlY2F1c2Ugb2YgdGhlIHN0YWdlM2QgcmVnaXN0ZXIgbGltaXRhdGlvbiwgaXQgb25seSBzdXBwb3J0IHRoZSBnbG9iYWwgbW9kZVxuXHRcdHN1cGVyKFwiUGFydGljbGVVVlwiLCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCwgNCwgUGFydGljbGVBbmltYXRpb25TZXQuUE9TVF9QUklPUklUWSArIDEpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBQYXJ0aWNsZVVWU3RhdGU7XG5cblx0XHR0aGlzLl9jeWNsZSA9IGN5Y2xlO1xuXHRcdHRoaXMuX3NjYWxlID0gc2NhbGU7XG5cdFx0dGhpcy5fYXhpcyA9IGF4aXM7XG5cblx0XHR0aGlzLnVwZGF0ZVVWRGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGN5Y2xlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY3ljbGU7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGN5Y2xlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2N5Y2xlID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZVVWRGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHNjYWxlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc2NhbGU7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHNjYWxlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3NjYWxlID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZVVWRGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGF4aXMoKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLl9heGlzO1xuXHR9XG5cblx0cHVibGljIHNldCBheGlzKHZhbHVlOnN0cmluZylcblx0e1xuXHRcdHRoaXMuX2F4aXMgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXG5cdFx0dmFyIHV2Q29uc3Q6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVVVlN0YXRlLlVWX0lOREVYLCB1dkNvbnN0LmluZGV4KTtcblxuXHRcdHZhciBheGlzSW5kZXg6bnVtYmVyID0gdGhpcy5fYXhpcyA9PSBcInhcIj8gMCA6ICh0aGlzLl9heGlzID09IFwieVwiPyAxIDogMik7XG5cblx0XHR2YXIgdGFyZ2V0OlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IG5ldyBTaGFkZXJSZWdpc3RlckVsZW1lbnQoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS51dlRhcmdldC5yZWdOYW1lLCBhbmltYXRpb25SZWdpc3RlckNhY2hlLnV2VGFyZ2V0LmluZGV4LCBheGlzSW5kZXgpO1xuXG5cdFx0dmFyIHNpbjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhTaW5nbGVUZW1wKCk7XG5cblx0XHRpZiAodGhpcy5fc2NhbGUgIT0gMSlcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0YXJnZXQgKyBcIixcIiArIHRhcmdldCArIFwiLFwiICsgdXZDb25zdCArIFwiLnlcXG5cIjtcblxuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyBzaW4gKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgdXZDb25zdCArIFwiLnhcXG5cIjtcblx0XHRjb2RlICs9IFwic2luIFwiICsgc2luICsgXCIsXCIgKyBzaW4gKyBcIlxcblwiO1xuXHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0YXJnZXQgKyBcIixcIiArIHRhcmdldCArIFwiLFwiICsgc2luICsgXCJcXG5cIjtcblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpQYXJ0aWNsZVVWU3RhdGVcblx0e1xuXHRcdHJldHVybiA8UGFydGljbGVVVlN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdHByaXZhdGUgdXBkYXRlVVZEYXRhKClcblx0e1xuXHRcdHRoaXMuX2lVdkRhdGEgPSBuZXcgVmVjdG9yM0QoTWF0aC5QSSoyL3RoaXMuX2N5Y2xlLCB0aGlzLl9zY2FsZSwgMCwgMCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVByb2Nlc3NBbmltYXRpb25TZXR0aW5nKHBhcnRpY2xlQW5pbWF0aW9uU2V0OlBhcnRpY2xlQW5pbWF0aW9uU2V0KVxuXHR7XG5cdFx0cGFydGljbGVBbmltYXRpb25TZXQuaGFzVVZOb2RlID0gdHJ1ZTtcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVVWTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleUVNode.ts b/lib/animators/nodes/ParticleUVNode.ts
new file mode 100644
index 000000000..46064b972
--- /dev/null
+++ b/lib/animators/nodes/ParticleUVNode.ts
@@ -0,0 +1,149 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleAnimationSet = require("awayjs-renderergl/lib/animators/ParticleAnimationSet");
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleUVState = require("awayjs-renderergl/lib/animators/states/ParticleUVState");
+
+/**
+ * A particle animation node used to control the UV offset and scale of a particle over time.
+ */
+class ParticleUVNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iUvData:Vector3D;
+
+ /**
+ *
+ */
+ public static U_AXIS:string = "x";
+
+ /**
+ *
+ */
+ public static V_AXIS:string = "y";
+
+ private _cycle:number;
+ private _scale:number;
+ private _axis:string;
+
+ /**
+ * Creates a new ParticleTimeNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] cycle Defines whether the time track is in loop mode. Defaults to false.
+ * @param [optional] scale Defines whether the time track is in loop mode. Defaults to false.
+ * @param [optional] axis Defines whether the time track is in loop mode. Defaults to false.
+ */
+ constructor(mode:number /*uint*/, cycle:number = 1, scale:number = 1, axis:string = "x")
+ {
+ //because of the stage3d register limitation, it only support the global mode
+ super("ParticleUV", ParticlePropertiesMode.GLOBAL, 4, ParticleAnimationSet.POST_PRIORITY + 1);
+
+ this._pStateClass = ParticleUVState;
+
+ this._cycle = cycle;
+ this._scale = scale;
+ this._axis = axis;
+
+ this.updateUVData();
+ }
+
+ /**
+ *
+ */
+ public get cycle():number
+ {
+ return this._cycle;
+ }
+
+ public set cycle(value:number)
+ {
+ this._cycle = value;
+
+ this.updateUVData();
+ }
+
+ /**
+ *
+ */
+ public get scale():number
+ {
+ return this._scale;
+ }
+
+ public set scale(value:number)
+ {
+ this._scale = value;
+
+ this.updateUVData();
+ }
+
+ /**
+ *
+ */
+ public get axis():string
+ {
+ return this._axis;
+ }
+
+ public set axis(value:string)
+ {
+ this._axis = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALUVCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var code:string = "";
+
+ var uvConst:ShaderRegisterElement = animationRegisterCache.getFreeVertexConstant();
+ animationRegisterCache.setRegisterIndex(this, ParticleUVState.UV_INDEX, uvConst.index);
+
+ var axisIndex:number = this._axis == "x"? 0 : (this._axis == "y"? 1 : 2);
+
+ var target:ShaderRegisterElement = new ShaderRegisterElement(animationRegisterCache.uvTarget.regName, animationRegisterCache.uvTarget.index, axisIndex);
+
+ var sin:ShaderRegisterElement = animationRegisterCache.getFreeVertexSingleTemp();
+
+ if (this._scale != 1)
+ code += "mul " + target + "," + target + "," + uvConst + ".y\n";
+
+ code += "mul " + sin + "," + animationRegisterCache.vertexTime + "," + uvConst + ".x\n";
+ code += "sin " + sin + "," + sin + "\n";
+ code += "add " + target + "," + target + "," + sin + "\n";
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleUVState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ private updateUVData()
+ {
+ this._iUvData = new Vector3D(Math.PI*2/this._cycle, this._scale, 0, 0);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iProcessAnimationSetting(particleAnimationSet:ParticleAnimationSet)
+ {
+ particleAnimationSet.hasUVNode = true;
+ }
+}
+
+export = ParticleUVNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleVelocityNode.js b/lib/animators/nodes/ParticleVelocityNode.js
new file mode 100755
index 000000000..68ae3dad7
--- /dev/null
+++ b/lib/animators/nodes/ParticleVelocityNode.js
@@ -0,0 +1,68 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+var ParticleVelocityState = require("awayjs-renderergl/lib/animators/states/ParticleVelocityState");
+/**
+ * A particle animation node used to set the starting velocity of a particle.
+ */
+var ParticleVelocityNode = (function (_super) {
+ __extends(ParticleVelocityNode, _super);
+ /**
+ * Creates a new ParticleVelocityNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] velocity Defines the default velocity vector of the node, used when in global mode.
+ */
+ function ParticleVelocityNode(mode /*uint*/, velocity) {
+ if (velocity === void 0) { velocity = null; }
+ _super.call(this, "ParticleVelocity", mode, 3);
+ this._pStateClass = ParticleVelocityState;
+ this._iVelocity = velocity || new Vector3D();
+ }
+ /**
+ * @inheritDoc
+ */
+ ParticleVelocityNode.prototype.getAGALVertexCode = function (shaderObject, animationRegisterCache) {
+ var velocityValue = (this._pMode == ParticlePropertiesMode.GLOBAL) ? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleVelocityState.VELOCITY_INDEX, velocityValue.index);
+ var distance = animationRegisterCache.getFreeVertexVectorTemp();
+ var code = "";
+ code += "mul " + distance + "," + animationRegisterCache.vertexTime + "," + velocityValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + "," + animationRegisterCache.positionTarget + ".xyz\n";
+ if (animationRegisterCache.needVelocity)
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + velocityValue + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleVelocityNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleVelocityNode.prototype._iGeneratePropertyOfOneParticle = function (param) {
+ var _tempVelocity = param[ParticleVelocityNode.VELOCITY_VECTOR3D];
+ if (!_tempVelocity)
+ throw new Error("there is no " + ParticleVelocityNode.VELOCITY_VECTOR3D + " in param!");
+ this._pOneData[0] = _tempVelocity.x;
+ this._pOneData[1] = _tempVelocity.y;
+ this._pOneData[2] = _tempVelocity.z;
+ };
+ /**
+ * Reference for velocity node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the direction of movement on the particle.
+ */
+ ParticleVelocityNode.VELOCITY_VECTOR3D = "VelocityVector3D";
+ return ParticleVelocityNode;
+})(ParticleNodeBase);
+module.exports = ParticleVelocityNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXZlbG9jaXR5bm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVZlbG9jaXR5Tm9kZSIsIlBhcnRpY2xlVmVsb2NpdHlOb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVWZWxvY2l0eU5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZVZlbG9jaXR5Tm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlVmVsb2NpdHlOb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBUXRFLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN6RyxJQUFPLGdCQUFnQixXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFDaEcsSUFBTyxxQkFBcUIsV0FBYSw4REFBOEQsQ0FBQyxDQUFDO0FBRXpHLEFBR0E7O0dBREc7SUFDRyxvQkFBb0I7SUFBU0EsVUFBN0JBLG9CQUFvQkEsVUFBeUJBO0lBV2xEQTs7Ozs7T0FLR0E7SUFDSEEsU0FqQktBLG9CQUFvQkEsQ0FpQmJBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFFBQXdCQTtRQUF4QkMsd0JBQXdCQSxHQUF4QkEsZUFBd0JBO1FBRXpEQSxrQkFBTUEsa0JBQWtCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVuQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EscUJBQXFCQSxDQUFDQTtRQUUxQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsUUFBUUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDOUNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSxnREFBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLGFBQWFBLEdBQXlCQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxJQUFJQSxzQkFBc0JBLENBQUNBLE1BQU1BLENBQUNBLEdBQUVBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxHQUFHQSxzQkFBc0JBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7UUFDM0xBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxxQkFBcUJBLENBQUNBLGNBQWNBLEVBQUVBLGFBQWFBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBRXpHQSxJQUFJQSxRQUFRQSxHQUF5QkEsc0JBQXNCQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3RGQSxJQUFJQSxJQUFJQSxHQUFVQSxFQUFFQSxDQUFDQTtRQUNyQkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNqR0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxPQUFPQSxHQUFHQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLENBQUNBO1FBRXJJQSxFQUFFQSxDQUFDQSxDQUFDQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBO1lBQ3ZDQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLE9BQU9BLEdBQUdBLGFBQWFBLEdBQUdBLE9BQU9BLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFFL0lBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURGOztPQUVHQTtJQUNJQSxnREFBaUJBLEdBQXhCQSxVQUF5QkEsUUFBcUJBO1FBRTdDRyxNQUFNQSxDQUF5QkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUNqRUEsQ0FBQ0E7SUFFREg7O09BRUdBO0lBQ0lBLDhEQUErQkEsR0FBdENBLFVBQXVDQSxLQUF3QkE7UUFFOURJLElBQUlBLGFBQWFBLEdBQVlBLEtBQUtBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQTtRQUMzRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsYUFBYUEsQ0FBQ0E7WUFDbEJBLE1BQU1BLElBQUlBLEtBQUtBLENBQUNBLGNBQWNBLEdBQUdBLG9CQUFvQkEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxZQUFZQSxDQUFDQSxDQUFDQTtRQUV6RkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDcENBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBO1FBQ3BDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUNyQ0EsQ0FBQ0E7SUE1RERKOzs7T0FHR0E7SUFDV0Esc0NBQWlCQSxHQUFVQSxrQkFBa0JBLENBQUNBO0lBeUQ3REEsMkJBQUNBO0FBQURBLENBbEVBLEFBa0VDQSxFQWxFa0MsZ0JBQWdCLEVBa0VsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvUGFydGljbGVWZWxvY2l0eU5vZGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlTm9kZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU5vZGVCYXNlXCIpO1xuaW1wb3J0IFBhcnRpY2xlVmVsb2NpdHlTdGF0ZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlVmVsb2NpdHlTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gc2V0IHRoZSBzdGFydGluZyB2ZWxvY2l0eSBvZiBhIHBhcnRpY2xlLlxuICovXG5jbGFzcyBQYXJ0aWNsZVZlbG9jaXR5Tm9kZSBleHRlbmRzIFBhcnRpY2xlTm9kZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVZlbG9jaXR5OlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIHZlbG9jaXR5IG5vZGUgcHJvcGVydGllcyBvbiBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPlZlY3RvcjNEPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBkaXJlY3Rpb24gb2YgbW92ZW1lbnQgb24gdGhlIHBhcnRpY2xlLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBWRUxPQ0lUWV9WRUNUT1IzRDpzdHJpbmcgPSBcIlZlbG9jaXR5VmVjdG9yM0RcIjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QYXJ0aWNsZVZlbG9jaXR5Tm9kZTwvY29kZT5cblx0ICpcblx0ICogQHBhcmFtICAgICAgICAgICAgICAgbW9kZSAgICAgICAgICAgIERlZmluZXMgd2hldGhlciB0aGUgbW9kZSBvZiBvcGVyYXRpb24gYWN0cyBvbiBsb2NhbCBwcm9wZXJ0aWVzIG9mIGEgcGFydGljbGUgb3IgZ2xvYmFsIHByb3BlcnRpZXMgb2YgdGhlIG5vZGUuXG5cdCAqIEBwYXJhbSAgICBbb3B0aW9uYWxdIHZlbG9jaXR5ICAgICAgICBEZWZpbmVzIHRoZSBkZWZhdWx0IHZlbG9jaXR5IHZlY3RvciBvZiB0aGUgbm9kZSwgdXNlZCB3aGVuIGluIGdsb2JhbCBtb2RlLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobW9kZTpudW1iZXIgLyp1aW50Ki8sIHZlbG9jaXR5OlZlY3RvcjNEID0gbnVsbClcblx0e1xuXHRcdHN1cGVyKFwiUGFydGljbGVWZWxvY2l0eVwiLCBtb2RlLCAzKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gUGFydGljbGVWZWxvY2l0eVN0YXRlO1xuXG5cdFx0dGhpcy5faVZlbG9jaXR5ID0gdmVsb2NpdHkgfHwgbmV3IFZlY3RvcjNEKCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBR0FMVmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHZhciB2ZWxvY2l0eVZhbHVlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9ICh0aGlzLl9wTW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCk/IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCkgOiBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhBdHRyaWJ1dGUoKTtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFJlZ2lzdGVySW5kZXgodGhpcywgUGFydGljbGVWZWxvY2l0eVN0YXRlLlZFTE9DSVRZX0lOREVYLCB2ZWxvY2l0eVZhbHVlLmluZGV4KTtcblxuXHRcdHZhciBkaXN0YW5jZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgZGlzdGFuY2UgKyBcIixcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVydGV4VGltZSArIFwiLFwiICsgdmVsb2NpdHlWYWx1ZSArIFwiXFxuXCI7XG5cdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUucG9zaXRpb25UYXJnZXQgKyBcIi54eXosXCIgKyBkaXN0YW5jZSArIFwiLFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5wb3NpdGlvblRhcmdldCArIFwiLnh5elxcblwiO1xuXG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFZlbG9jaXR5KVxuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUudmVsb2NpdHlUYXJnZXQgKyBcIi54eXosXCIgKyB2ZWxvY2l0eVZhbHVlICsgXCIueHl6LFwiICsgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS52ZWxvY2l0eVRhcmdldCArIFwiLnh5elxcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlBhcnRpY2xlVmVsb2NpdHlTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxQYXJ0aWNsZVZlbG9jaXR5U3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZW5lcmF0ZVByb3BlcnR5T2ZPbmVQYXJ0aWNsZShwYXJhbTpQYXJ0aWNsZVByb3BlcnRpZXMpXG5cdHtcblx0XHR2YXIgX3RlbXBWZWxvY2l0eTpWZWN0b3IzRCA9IHBhcmFtW1BhcnRpY2xlVmVsb2NpdHlOb2RlLlZFTE9DSVRZX1ZFQ1RPUjNEXTtcblx0XHRpZiAoIV90ZW1wVmVsb2NpdHkpXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ0aGVyZSBpcyBubyBcIiArIFBhcnRpY2xlVmVsb2NpdHlOb2RlLlZFTE9DSVRZX1ZFQ1RPUjNEICsgXCIgaW4gcGFyYW0hXCIpO1xuXG5cdFx0dGhpcy5fcE9uZURhdGFbMF0gPSBfdGVtcFZlbG9jaXR5Lng7XG5cdFx0dGhpcy5fcE9uZURhdGFbMV0gPSBfdGVtcFZlbG9jaXR5Lnk7XG5cdFx0dGhpcy5fcE9uZURhdGFbMl0gPSBfdGVtcFZlbG9jaXR5Lno7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVWZWxvY2l0eU5vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/ParticleVelocityNode.ts b/lib/animators/nodes/ParticleVelocityNode.ts
new file mode 100644
index 000000000..3bdaf33fc
--- /dev/null
+++ b/lib/animators/nodes/ParticleVelocityNode.ts
@@ -0,0 +1,84 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+
+import ParticleProperties = require("awayjs-renderergl/lib/animators/data/ParticleProperties");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleVelocityState = require("awayjs-renderergl/lib/animators/states/ParticleVelocityState");
+
+/**
+ * A particle animation node used to set the starting velocity of a particle.
+ */
+class ParticleVelocityNode extends ParticleNodeBase
+{
+ /** @private */
+ public _iVelocity:Vector3D;
+
+ /**
+ * Reference for velocity node properties on a single particle (when in local property mode).
+ * Expects a Vector3D
object representing the direction of movement on the particle.
+ */
+ public static VELOCITY_VECTOR3D:string = "VelocityVector3D";
+
+ /**
+ * Creates a new ParticleVelocityNode
+ *
+ * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node.
+ * @param [optional] velocity Defines the default velocity vector of the node, used when in global mode.
+ */
+ constructor(mode:number /*uint*/, velocity:Vector3D = null)
+ {
+ super("ParticleVelocity", mode, 3);
+
+ this._pStateClass = ParticleVelocityState;
+
+ this._iVelocity = velocity || new Vector3D();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAGALVertexCode(shaderObject:ShaderObjectBase, animationRegisterCache:AnimationRegisterCache):string
+ {
+ var velocityValue:ShaderRegisterElement = (this._pMode == ParticlePropertiesMode.GLOBAL)? animationRegisterCache.getFreeVertexConstant() : animationRegisterCache.getFreeVertexAttribute();
+ animationRegisterCache.setRegisterIndex(this, ParticleVelocityState.VELOCITY_INDEX, velocityValue.index);
+
+ var distance:ShaderRegisterElement = animationRegisterCache.getFreeVertexVectorTemp();
+ var code:string = "";
+ code += "mul " + distance + "," + animationRegisterCache.vertexTime + "," + velocityValue + "\n";
+ code += "add " + animationRegisterCache.positionTarget + ".xyz," + distance + "," + animationRegisterCache.positionTarget + ".xyz\n";
+
+ if (animationRegisterCache.needVelocity)
+ code += "add " + animationRegisterCache.velocityTarget + ".xyz," + velocityValue + ".xyz," + animationRegisterCache.velocityTarget + ".xyz\n";
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):ParticleVelocityState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _iGeneratePropertyOfOneParticle(param:ParticleProperties)
+ {
+ var _tempVelocity:Vector3D = param[ParticleVelocityNode.VELOCITY_VECTOR3D];
+ if (!_tempVelocity)
+ throw new Error("there is no " + ParticleVelocityNode.VELOCITY_VECTOR3D + " in param!");
+
+ this._pOneData[0] = _tempVelocity.x;
+ this._pOneData[1] = _tempVelocity.y;
+ this._pOneData[2] = _tempVelocity.z;
+ }
+}
+
+export = ParticleVelocityNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonBinaryLERPNode.js b/lib/animators/nodes/SkeletonBinaryLERPNode.js
new file mode 100755
index 000000000..ab9ae20ca
--- /dev/null
+++ b/lib/animators/nodes/SkeletonBinaryLERPNode.js
@@ -0,0 +1,31 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+var SkeletonBinaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonBinaryLERPState");
+/**
+ * A skeleton animation node that uses two animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+var SkeletonBinaryLERPNode = (function (_super) {
+ __extends(SkeletonBinaryLERPNode, _super);
+ /**
+ * Creates a new SkeletonBinaryLERPNode
object.
+ */
+ function SkeletonBinaryLERPNode() {
+ _super.call(this);
+ this._pStateClass = SkeletonBinaryLERPState;
+ }
+ /**
+ * @inheritDoc
+ */
+ SkeletonBinaryLERPNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ return SkeletonBinaryLERPNode;
+})(AnimationNodeBase);
+module.exports = SkeletonBinaryLERPNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9za2VsZXRvbmJpbmFyeWxlcnBub2RlLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uQmluYXJ5TEVSUE5vZGUiLCJTa2VsZXRvbkJpbmFyeUxFUlBOb2RlLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25CaW5hcnlMRVJQTm9kZS5nZXRBbmltYXRpb25TdGF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxpQkFBaUIsV0FBYyxtREFBbUQsQ0FBQyxDQUFDO0FBSzNGLElBQU8sdUJBQXVCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUU3RyxBQUdBOztHQURHO0lBQ0csc0JBQXNCO0lBQVNBLFVBQS9CQSxzQkFBc0JBLFVBQTBCQTtJQVlyREE7O09BRUdBO0lBQ0hBLFNBZktBLHNCQUFzQkE7UUFpQjFCQyxpQkFBT0EsQ0FBQ0E7UUFFUkEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsdUJBQXVCQSxDQUFDQTtJQUM3Q0EsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLGtEQUFpQkEsR0FBeEJBLFVBQXlCQSxRQUFxQkE7UUFFN0NFLE1BQU1BLENBQTJCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ25FQSxDQUFDQTtJQUNGRiw2QkFBQ0E7QUFBREEsQ0E3QkEsQUE2QkNBLEVBN0JvQyxpQkFBaUIsRUE2QnJEO0FBRUQsQUFBZ0MsaUJBQXZCLHNCQUFzQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkJpbmFyeUxFUlBOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1NrZWxldG9uQmluYXJ5TEVSUFN0YXRlXCIpO1xuXG4vKipcbiAqIEEgc2tlbGV0b24gYW5pbWF0aW9uIG5vZGUgdGhhdCB1c2VzIHR3byBhbmltYXRpb24gbm9kZSBpbnB1dHMgdG8gYmxlbmQgYSBsaW5lcmFseSBpbnRlcnBvbGF0ZWQgb3V0cHV0IG9mIGEgc2tlbGV0b24gcG9zZS5cbiAqL1xuY2xhc3MgU2tlbGV0b25CaW5hcnlMRVJQTm9kZSBleHRlbmRzIEFuaW1hdGlvbk5vZGVCYXNlXG57XG5cdC8qKlxuXHQgKiBEZWZpbmVzIGlucHV0IG5vZGUgQSB0byB1c2UgZm9yIHRoZSBibGVuZGVkIG91dHB1dC5cblx0ICovXG5cdHB1YmxpYyBpbnB1dEE6QW5pbWF0aW9uTm9kZUJhc2U7XG5cblx0LyoqXG5cdCAqIERlZmluZXMgaW5wdXQgbm9kZSBCIHRvIHVzZSBmb3IgdGhlIGJsZW5kZWQgb3V0cHV0LlxuXHQgKi9cblx0cHVibGljIGlucHV0QjpBbmltYXRpb25Ob2RlQmFzZTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvbkJpbmFyeUxFUlBOb2RlPC9jb2RlPiBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFuaW1hdGlvblN0YXRlKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSk6U2tlbGV0b25CaW5hcnlMRVJQU3RhdGVcblx0e1xuXHRcdHJldHVybiA8U2tlbGV0b25CaW5hcnlMRVJQU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNrZWxldG9uQmluYXJ5TEVSUE5vZGU7Il19
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonBinaryLERPNode.ts b/lib/animators/nodes/SkeletonBinaryLERPNode.ts
new file mode 100644
index 000000000..c32d30f4a
--- /dev/null
+++ b/lib/animators/nodes/SkeletonBinaryLERPNode.ts
@@ -0,0 +1,42 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonBinaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonBinaryLERPState");
+
+/**
+ * A skeleton animation node that uses two animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+class SkeletonBinaryLERPNode extends AnimationNodeBase
+{
+ /**
+ * Defines input node A to use for the blended output.
+ */
+ public inputA:AnimationNodeBase;
+
+ /**
+ * Defines input node B to use for the blended output.
+ */
+ public inputB:AnimationNodeBase;
+
+ /**
+ * Creates a new SkeletonBinaryLERPNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = SkeletonBinaryLERPState;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):SkeletonBinaryLERPState
+ {
+ return animator.getAnimationState(this);
+ }
+}
+
+export = SkeletonBinaryLERPNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonClipNode.js b/lib/animators/nodes/SkeletonClipNode.js
new file mode 100755
index 000000000..abe097500
--- /dev/null
+++ b/lib/animators/nodes/SkeletonClipNode.js
@@ -0,0 +1,85 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationClipNodeBase = require("awayjs-renderergl/lib/animators/nodes/AnimationClipNodeBase");
+var SkeletonClipState = require("awayjs-renderergl/lib/animators/states/SkeletonClipState");
+/**
+ * A skeleton animation node containing time-based animation data as individual skeleton poses.
+ */
+var SkeletonClipNode = (function (_super) {
+ __extends(SkeletonClipNode, _super);
+ /**
+ * Creates a new SkeletonClipNode
object.
+ */
+ function SkeletonClipNode() {
+ _super.call(this);
+ this._frames = new Array();
+ /**
+ * Determines whether to use SLERP equations (true) or LERP equations (false) in the calculation
+ * of the output skeleton pose. Defaults to false.
+ */
+ this.highQuality = false;
+ this._pStateClass = SkeletonClipState;
+ }
+ Object.defineProperty(SkeletonClipNode.prototype, "frames", {
+ /**
+ * Returns a vector of skeleton poses representing the pose of each animation frame in the clip.
+ */
+ get: function () {
+ return this._frames;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Adds a skeleton pose frame to the internal timeline of the animation node.
+ *
+ * @param skeletonPose The skeleton pose object to add to the timeline of the node.
+ * @param duration The specified duration of the frame in milliseconds.
+ */
+ SkeletonClipNode.prototype.addFrame = function (skeletonPose, duration /*number /*uint*/) {
+ this._frames.push(skeletonPose);
+ this._pDurations.push(duration);
+ this._pNumFrames = this._pDurations.length;
+ this._pStitchDirty = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonClipNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonClipNode.prototype._pUpdateStitch = function () {
+ _super.prototype._pUpdateStitch.call(this);
+ var i = this._pNumFrames - 1;
+ var p1, p2, delta;
+ while (i--) {
+ this._pTotalDuration += this._pDurations[i];
+ p1 = this._frames[i].jointPoses[0].translation;
+ p2 = this._frames[i + 1].jointPoses[0].translation;
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ if (this._pStitchFinalFrame || !this._pLooping) {
+ this._pTotalDuration += this._pDurations[this._pNumFrames - 1];
+ p1 = this._frames[0].jointPoses[0].translation;
+ p2 = this._frames[1].jointPoses[0].translation;
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ };
+ return SkeletonClipNode;
+})(AnimationClipNodeBase);
+module.exports = SkeletonClipNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9za2VsZXRvbmNsaXBub2RlLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uQ2xpcE5vZGUiLCJTa2VsZXRvbkNsaXBOb2RlLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25DbGlwTm9kZS5mcmFtZXMiLCJTa2VsZXRvbkNsaXBOb2RlLmFkZEZyYW1lIiwiU2tlbGV0b25DbGlwTm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlNrZWxldG9uQ2xpcE5vZGUuX3BVcGRhdGVTdGl0Y2giXSwibWFwcGluZ3MiOiI7Ozs7OztBQUtBLElBQU8scUJBQXFCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUN4RyxJQUFPLGlCQUFpQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFFbEcsQUFHQTs7R0FERztJQUNHLGdCQUFnQjtJQUFTQSxVQUF6QkEsZ0JBQWdCQSxVQUE4QkE7SUFrQm5EQTs7T0FFR0E7SUFDSEEsU0FyQktBLGdCQUFnQkE7UUF1QnBCQyxpQkFBT0EsQ0FBQ0E7UUFyQkRBLFlBQU9BLEdBQXVCQSxJQUFJQSxLQUFLQSxFQUFnQkEsQ0FBQ0E7UUFFaEVBOzs7V0FHR0E7UUFDSUEsZ0JBQVdBLEdBQVdBLEtBQUtBLENBQUNBO1FBaUJsQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsaUJBQWlCQSxDQUFDQTtJQUN2Q0EsQ0FBQ0E7SUFiREQsc0JBQVdBLG9DQUFNQTtRQUhqQkE7O1dBRUdBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBO1FBQ3JCQSxDQUFDQTs7O09BQUFGO0lBWURBOzs7OztPQUtHQTtJQUNJQSxtQ0FBUUEsR0FBZkEsVUFBZ0JBLFlBQXlCQSxFQUFFQSxRQUFRQSxDQUFRQSxpQkFBREEsQUFBa0JBO1FBRTNFRyxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQTtRQUNoQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsUUFB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QkFBZ0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvU2tlbGV0b25DbGlwTm9kZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuXG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBBbmltYXRpb25DbGlwTm9kZUJhc2VcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbkNsaXBOb2RlQmFzZVwiKTtcbmltcG9ydCBTa2VsZXRvbkNsaXBTdGF0ZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvU2tlbGV0b25DbGlwU3RhdGVcIik7XG5cbi8qKlxuICogQSBza2VsZXRvbiBhbmltYXRpb24gbm9kZSBjb250YWluaW5nIHRpbWUtYmFzZWQgYW5pbWF0aW9uIGRhdGEgYXMgaW5kaXZpZHVhbCBza2VsZXRvbiBwb3Nlcy5cbiAqL1xuY2xhc3MgU2tlbGV0b25DbGlwTm9kZSBleHRlbmRzIEFuaW1hdGlvbkNsaXBOb2RlQmFzZVxue1xuXHRwcml2YXRlIF9mcmFtZXM6QXJyYXk8U2tlbGV0b25Qb3NlPiA9IG5ldyBBcnJheTxTa2VsZXRvblBvc2U+KCk7XG5cblx0LyoqXG5cdCAqIERldGVybWluZXMgd2hldGhlciB0byB1c2UgU0xFUlAgZXF1YXRpb25zICh0cnVlKSBvciBMRVJQIGVxdWF0aW9ucyAoZmFsc2UpIGluIHRoZSBjYWxjdWxhdGlvblxuXHQgKiBvZiB0aGUgb3V0cHV0IHNrZWxldG9uIHBvc2UuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKi9cblx0cHVibGljIGhpZ2hRdWFsaXR5OmJvb2xlYW4gPSBmYWxzZTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIHZlY3RvciBvZiBza2VsZXRvbiBwb3NlcyByZXByZXNlbnRpbmcgdGhlIHBvc2Ugb2YgZWFjaCBhbmltYXRpb24gZnJhbWUgaW4gdGhlIGNsaXAuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGZyYW1lcygpOkFycmF5PFNrZWxldG9uUG9zZT5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9mcmFtZXM7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvbkNsaXBOb2RlPC9jb2RlPiBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0dGhpcy5fcFN0YXRlQ2xhc3MgPSBTa2VsZXRvbkNsaXBTdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgc2tlbGV0b24gcG9zZSBmcmFtZSB0byB0aGUgaW50ZXJuYWwgdGltZWxpbmUgb2YgdGhlIGFuaW1hdGlvbiBub2RlLlxuXHQgKlxuXHQgKiBAcGFyYW0gc2tlbGV0b25Qb3NlIFRoZSBza2VsZXRvbiBwb3NlIG9iamVjdCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lIG9mIHRoZSBub2RlLlxuXHQgKiBAcGFyYW0gZHVyYXRpb24gVGhlIHNwZWNpZmllZCBkdXJhdGlvbiBvZiB0aGUgZnJhbWUgaW4gbWlsbGlzZWNvbmRzLlxuXHQgKi9cblx0cHVibGljIGFkZEZyYW1lKHNrZWxldG9uUG9zZTpTa2VsZXRvblBvc2UsIGR1cmF0aW9uOm51bWJlciAvKm51bWJlciAvKnVpbnQqLylcblx0e1xuXHRcdHRoaXMuX2ZyYW1lcy5wdXNoKHNrZWxldG9uUG9zZSk7XG5cdFx0dGhpcy5fcER1cmF0aW9ucy5wdXNoKGR1cmF0aW9uKTtcblxuXHRcdHRoaXMuX3BOdW1GcmFtZXMgPSB0aGlzLl9wRHVyYXRpb25zLmxlbmd0aDtcblxuXHRcdHRoaXMuX3BTdGl0Y2hEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlNrZWxldG9uQ2xpcFN0YXRlXG5cdHtcblx0XHRyZXR1cm4gPFNrZWxldG9uQ2xpcFN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlU3RpdGNoKClcblx0e1xuXHRcdHN1cGVyLl9wVXBkYXRlU3RpdGNoKCk7XG5cblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wTnVtRnJhbWVzIC0gMTtcblx0XHR2YXIgcDE6VmVjdG9yM0QsIHAyOlZlY3RvcjNELCBkZWx0YTpWZWN0b3IzRDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHR0aGlzLl9wVG90YWxEdXJhdGlvbiArPSB0aGlzLl9wRHVyYXRpb25zW2ldO1xuXHRcdFx0cDEgPSB0aGlzLl9mcmFtZXNbaV0uam9pbnRQb3Nlc1swXS50cmFuc2xhdGlvbjtcblx0XHRcdHAyID0gdGhpcy5fZnJhbWVzW2kgKyAxXS5qb2ludFBvc2VzWzBdLnRyYW5zbGF0aW9uO1xuXHRcdFx0ZGVsdGEgPSBwMi5zdWJ0cmFjdChwMSk7XG5cdFx0XHR0aGlzLl9wVG90YWxEZWx0YS54ICs9IGRlbHRhLng7XG5cdFx0XHR0aGlzLl9wVG90YWxEZWx0YS55ICs9IGRlbHRhLnk7XG5cdFx0XHR0aGlzLl9wVG90YWxEZWx0YS56ICs9IGRlbHRhLno7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3BTdGl0Y2hGaW5hbEZyYW1lIHx8ICF0aGlzLl9wTG9vcGluZykge1xuXHRcdFx0dGhpcy5fcFRvdGFsRHVyYXRpb24gKz0gdGhpcy5fcER1cmF0aW9uc1t0aGlzLl9wTnVtRnJhbWVzIC0gMV07XG5cdFx0XHRwMSA9IHRoaXMuX2ZyYW1lc1swXS5qb2ludFBvc2VzWzBdLnRyYW5zbGF0aW9uO1xuXHRcdFx0cDIgPSB0aGlzLl9mcmFtZXNbMV0uam9pbnRQb3Nlc1swXS50cmFuc2xhdGlvbjtcblx0XHRcdGRlbHRhID0gcDIuc3VidHJhY3QocDEpO1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueCArPSBkZWx0YS54O1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueSArPSBkZWx0YS55O1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueiArPSBkZWx0YS56O1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkNsaXBOb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonClipNode.ts b/lib/animators/nodes/SkeletonClipNode.ts
new file mode 100644
index 000000000..daee39fdd
--- /dev/null
+++ b/lib/animators/nodes/SkeletonClipNode.ts
@@ -0,0 +1,95 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import AnimationClipNodeBase = require("awayjs-renderergl/lib/animators/nodes/AnimationClipNodeBase");
+import SkeletonClipState = require("awayjs-renderergl/lib/animators/states/SkeletonClipState");
+
+/**
+ * A skeleton animation node containing time-based animation data as individual skeleton poses.
+ */
+class SkeletonClipNode extends AnimationClipNodeBase
+{
+ private _frames:Array = new Array();
+
+ /**
+ * Determines whether to use SLERP equations (true) or LERP equations (false) in the calculation
+ * of the output skeleton pose. Defaults to false.
+ */
+ public highQuality:boolean = false;
+
+ /**
+ * Returns a vector of skeleton poses representing the pose of each animation frame in the clip.
+ */
+ public get frames():Array
+ {
+ return this._frames;
+ }
+
+ /**
+ * Creates a new SkeletonClipNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = SkeletonClipState;
+ }
+
+ /**
+ * Adds a skeleton pose frame to the internal timeline of the animation node.
+ *
+ * @param skeletonPose The skeleton pose object to add to the timeline of the node.
+ * @param duration The specified duration of the frame in milliseconds.
+ */
+ public addFrame(skeletonPose:SkeletonPose, duration:number /*number /*uint*/)
+ {
+ this._frames.push(skeletonPose);
+ this._pDurations.push(duration);
+
+ this._pNumFrames = this._pDurations.length;
+
+ this._pStitchDirty = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):SkeletonClipState
+ {
+ return animator.getAnimationState(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateStitch()
+ {
+ super._pUpdateStitch();
+
+ var i:number /*uint*/ = this._pNumFrames - 1;
+ var p1:Vector3D, p2:Vector3D, delta:Vector3D;
+ while (i--) {
+ this._pTotalDuration += this._pDurations[i];
+ p1 = this._frames[i].jointPoses[0].translation;
+ p2 = this._frames[i + 1].jointPoses[0].translation;
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+
+ if (this._pStitchFinalFrame || !this._pLooping) {
+ this._pTotalDuration += this._pDurations[this._pNumFrames - 1];
+ p1 = this._frames[0].jointPoses[0].translation;
+ p2 = this._frames[1].jointPoses[0].translation;
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ }
+}
+
+export = SkeletonClipNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonDifferenceNode.js b/lib/animators/nodes/SkeletonDifferenceNode.js
new file mode 100755
index 000000000..46c8fd398
--- /dev/null
+++ b/lib/animators/nodes/SkeletonDifferenceNode.js
@@ -0,0 +1,31 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+var SkeletonDifferenceState = require("awayjs-renderergl/lib/animators/states/SkeletonDifferenceState");
+/**
+ * A skeleton animation node that uses a difference input pose with a base input pose to blend a linearly interpolated output of a skeleton pose.
+ */
+var SkeletonDifferenceNode = (function (_super) {
+ __extends(SkeletonDifferenceNode, _super);
+ /**
+ * Creates a new SkeletonAdditiveNode
object.
+ */
+ function SkeletonDifferenceNode() {
+ _super.call(this);
+ this._pStateClass = SkeletonDifferenceState;
+ }
+ /**
+ * @inheritDoc
+ */
+ SkeletonDifferenceNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ return SkeletonDifferenceNode;
+})(AnimationNodeBase);
+module.exports = SkeletonDifferenceNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9za2VsZXRvbmRpZmZlcmVuY2Vub2RlLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uRGlmZmVyZW5jZU5vZGUiLCJTa2VsZXRvbkRpZmZlcmVuY2VOb2RlLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25EaWZmZXJlbmNlTm9kZS5nZXRBbmltYXRpb25TdGF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxpQkFBaUIsV0FBYyxtREFBbUQsQ0FBQyxDQUFDO0FBSTNGLElBQU8sdUJBQXVCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUU3RyxBQUdBOztHQURHO0lBQ0csc0JBQXNCO0lBQVNBLFVBQS9CQSxzQkFBc0JBLFVBQTBCQTtJQVlyREE7O09BRUdBO0lBQ0hBLFNBZktBLHNCQUFzQkE7UUFpQjFCQyxpQkFBT0EsQ0FBQ0E7UUFFUkEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsdUJBQXVCQSxDQUFDQTtJQUM3Q0EsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLGtEQUFpQkEsR0FBeEJBLFVBQXlCQSxRQUFxQkE7UUFFN0NFLE1BQU1BLENBQTJCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ25FQSxDQUFDQTtJQUNGRiw2QkFBQ0E7QUFBREEsQ0E3QkEsQUE2QkNBLEVBN0JvQyxpQkFBaUIsRUE2QnJEO0FBRUQsQUFBK0IsaUJBQXRCLHNCQUFzQixDQUFBIiwiZmlsZSI6ImFuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkRpZmZlcmVuY2VOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1NrZWxldG9uRGlmZmVyZW5jZVN0YXRlXCIpO1xuXG4vKipcbiAqIEEgc2tlbGV0b24gYW5pbWF0aW9uIG5vZGUgdGhhdCB1c2VzIGEgZGlmZmVyZW5jZSBpbnB1dCBwb3NlIHdpdGggYSBiYXNlIGlucHV0IHBvc2UgdG8gYmxlbmQgYSBsaW5lYXJseSBpbnRlcnBvbGF0ZWQgb3V0cHV0IG9mIGEgc2tlbGV0b24gcG9zZS5cbiAqL1xuY2xhc3MgU2tlbGV0b25EaWZmZXJlbmNlTm9kZSBleHRlbmRzIEFuaW1hdGlvbk5vZGVCYXNlXG57XG5cdC8qKlxuXHQgKiBEZWZpbmVzIGEgYmFzZSBpbnB1dCBub2RlIHRvIHVzZSBmb3IgdGhlIGJsZW5kZWQgb3V0cHV0LlxuXHQgKi9cblx0cHVibGljIGJhc2VJbnB1dDpBbmltYXRpb25Ob2RlQmFzZTtcblxuXHQvKipcblx0ICogRGVmaW5lcyBhIGRpZmZlcmVuY2UgaW5wdXQgbm9kZSB0byB1c2UgZm9yIHRoZSBibGVuZGVkIG91dHB1dC5cblx0ICovXG5cdHB1YmxpYyBkaWZmZXJlbmNlSW5wdXQ6QW5pbWF0aW9uTm9kZUJhc2U7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+U2tlbGV0b25BZGRpdGl2ZU5vZGU8L2NvZGU+IG9iamVjdC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IFNrZWxldG9uRGlmZmVyZW5jZVN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcyk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2tlbGV0b25EaWZmZXJlbmNlTm9kZSJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonDifferenceNode.ts b/lib/animators/nodes/SkeletonDifferenceNode.ts
new file mode 100644
index 000000000..474430003
--- /dev/null
+++ b/lib/animators/nodes/SkeletonDifferenceNode.ts
@@ -0,0 +1,41 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonDifferenceState = require("awayjs-renderergl/lib/animators/states/SkeletonDifferenceState");
+
+/**
+ * A skeleton animation node that uses a difference input pose with a base input pose to blend a linearly interpolated output of a skeleton pose.
+ */
+class SkeletonDifferenceNode extends AnimationNodeBase
+{
+ /**
+ * Defines a base input node to use for the blended output.
+ */
+ public baseInput:AnimationNodeBase;
+
+ /**
+ * Defines a difference input node to use for the blended output.
+ */
+ public differenceInput:AnimationNodeBase;
+
+ /**
+ * Creates a new SkeletonAdditiveNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = SkeletonDifferenceState;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):SkeletonDifferenceState
+ {
+ return animator.getAnimationState(this);
+ }
+}
+
+export = SkeletonDifferenceNode
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonDirectionalNode.js b/lib/animators/nodes/SkeletonDirectionalNode.js
new file mode 100755
index 000000000..cb5105d92
--- /dev/null
+++ b/lib/animators/nodes/SkeletonDirectionalNode.js
@@ -0,0 +1,28 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+var SkeletonDirectionalState = require("awayjs-renderergl/lib/animators/states/SkeletonDirectionalState");
+/**
+ * A skeleton animation node that uses four directional input poses with an input direction to blend a linearly interpolated output of a skeleton pose.
+ */
+var SkeletonDirectionalNode = (function (_super) {
+ __extends(SkeletonDirectionalNode, _super);
+ function SkeletonDirectionalNode() {
+ _super.call(this);
+ this._pStateClass = SkeletonDirectionalState;
+ }
+ /**
+ * @inheritDoc
+ */
+ SkeletonDirectionalNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ return SkeletonDirectionalNode;
+})(AnimationNodeBase);
+module.exports = SkeletonDirectionalNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9za2VsZXRvbmRpcmVjdGlvbmFsbm9kZS50cyJdLCJuYW1lcyI6WyJTa2VsZXRvbkRpcmVjdGlvbmFsTm9kZSIsIlNrZWxldG9uRGlyZWN0aW9uYWxOb2RlLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25EaXJlY3Rpb25hbE5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8saUJBQWlCLFdBQWMsbURBQW1ELENBQUMsQ0FBQztBQUkzRixJQUFPLHdCQUF3QixXQUFhLGlFQUFpRSxDQUFDLENBQUM7QUFFL0csQUFHQTs7R0FERztJQUNHLHVCQUF1QjtJQUFTQSxVQUFoQ0EsdUJBQXVCQSxVQUEwQkE7SUFzQnREQSxTQXRCS0EsdUJBQXVCQTtRQXdCM0JDLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSx3QkFBd0JBLENBQUNBO0lBQzlDQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsbURBQWlCQSxHQUF4QkEsVUFBeUJBLFFBQXFCQTtRQUU3Q0UsTUFBTUEsQ0FBNEJBLFFBQVFBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDcEVBLENBQUNBO0lBRUZGLDhCQUFDQTtBQUFEQSxDQXJDQSxBQXFDQ0EsRUFyQ3FDLGlCQUFpQixFQXFDdEQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1NrZWxldG9uRGlyZWN0aW9uYWxOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9Ta2VsZXRvbkRpcmVjdGlvbmFsU3RhdGVcIik7XG5cbi8qKlxuICogQSBza2VsZXRvbiBhbmltYXRpb24gbm9kZSB0aGF0IHVzZXMgZm91ciBkaXJlY3Rpb25hbCBpbnB1dCBwb3NlcyB3aXRoIGFuIGlucHV0IGRpcmVjdGlvbiB0byBibGVuZCBhIGxpbmVhcmx5IGludGVycG9sYXRlZCBvdXRwdXQgb2YgYSBza2VsZXRvbiBwb3NlLlxuICovXG5jbGFzcyBTa2VsZXRvbkRpcmVjdGlvbmFsTm9kZSBleHRlbmRzIEFuaW1hdGlvbk5vZGVCYXNlXG57XG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBmb3J3YXJkIGNvbmZpZ3VyZWQgaW5wdXQgbm9kZSB0byB1c2UgZm9yIHRoZSBibGVuZGVkIG91dHB1dC5cblx0ICovXG5cdHB1YmxpYyBmb3J3YXJkOkFuaW1hdGlvbk5vZGVCYXNlO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBiYWNrd2FyZHMgY29uZmlndXJlZCBpbnB1dCBub2RlIHRvIHVzZSBmb3IgdGhlIGJsZW5kZWQgb3V0cHV0LlxuXHQgKi9cblx0cHVibGljIGJhY2t3YXJkOkFuaW1hdGlvbk5vZGVCYXNlO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBsZWZ0IGNvbmZpZ3VyZWQgaW5wdXQgbm9kZSB0byB1c2UgZm9yIHRoZSBibGVuZGVkIG91dHB1dC5cblx0ICovXG5cdHB1YmxpYyBsZWZ0OkFuaW1hdGlvbk5vZGVCYXNlO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSByaWdodCBjb25maWd1cmVkIGlucHV0IG5vZGUgdG8gdXNlIGZvciB0aGUgYmxlbmRlZCBvdXRwdXQuXG5cdCAqL1xuXHRwdWJsaWMgcmlnaHQ6QW5pbWF0aW9uTm9kZUJhc2U7XG5cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gU2tlbGV0b25EaXJlY3Rpb25hbFN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uU3RhdGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlKTpTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGVcblx0e1xuXHRcdHJldHVybiA8U2tlbGV0b25EaXJlY3Rpb25hbFN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzKTtcblx0fVxuXG59XG5cbmV4cG9ydCA9IFNrZWxldG9uRGlyZWN0aW9uYWxOb2RlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonDirectionalNode.ts b/lib/animators/nodes/SkeletonDirectionalNode.ts
new file mode 100644
index 000000000..a9bc8ced9
--- /dev/null
+++ b/lib/animators/nodes/SkeletonDirectionalNode.ts
@@ -0,0 +1,49 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonDirectionalState = require("awayjs-renderergl/lib/animators/states/SkeletonDirectionalState");
+
+/**
+ * A skeleton animation node that uses four directional input poses with an input direction to blend a linearly interpolated output of a skeleton pose.
+ */
+class SkeletonDirectionalNode extends AnimationNodeBase
+{
+ /**
+ * Defines the forward configured input node to use for the blended output.
+ */
+ public forward:AnimationNodeBase;
+
+ /**
+ * Defines the backwards configured input node to use for the blended output.
+ */
+ public backward:AnimationNodeBase;
+
+ /**
+ * Defines the left configured input node to use for the blended output.
+ */
+ public left:AnimationNodeBase;
+
+ /**
+ * Defines the right configured input node to use for the blended output.
+ */
+ public right:AnimationNodeBase;
+
+ constructor()
+ {
+ super();
+
+ this._pStateClass = SkeletonDirectionalState;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):SkeletonDirectionalState
+ {
+ return animator.getAnimationState(this);
+ }
+
+}
+
+export = SkeletonDirectionalNode;
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonNaryLERPNode.js b/lib/animators/nodes/SkeletonNaryLERPNode.js
new file mode 100755
index 000000000..ddb8604d0
--- /dev/null
+++ b/lib/animators/nodes/SkeletonNaryLERPNode.js
@@ -0,0 +1,61 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+var SkeletonNaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonNaryLERPState");
+/**
+ * A skeleton animation node that uses an n-dimensional array of animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+var SkeletonNaryLERPNode = (function (_super) {
+ __extends(SkeletonNaryLERPNode, _super);
+ /**
+ * Creates a new SkeletonNaryLERPNode
object.
+ */
+ function SkeletonNaryLERPNode() {
+ _super.call(this);
+ this._iInputs = new Array();
+ this._pStateClass = SkeletonNaryLERPState;
+ }
+ Object.defineProperty(SkeletonNaryLERPNode.prototype, "numInputs", {
+ get: function () {
+ return this._numInputs;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Returns an integer representing the input index of the given skeleton animation node.
+ *
+ * @param input The skeleton animation node for with the input index is requested.
+ */
+ SkeletonNaryLERPNode.prototype.getInputIndex = function (input) {
+ return this._iInputs.indexOf(input);
+ };
+ /**
+ * Returns the skeleton animation node object that resides at the given input index.
+ *
+ * @param index The input index for which the skeleton animation node is requested.
+ */
+ SkeletonNaryLERPNode.prototype.getInputAt = function (index /*uint*/) {
+ return this._iInputs[index];
+ };
+ /**
+ * Adds a new skeleton animation node input to the animation node.
+ */
+ SkeletonNaryLERPNode.prototype.addInput = function (input) {
+ this._iInputs[this._numInputs++] = input;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonNaryLERPNode.prototype.getAnimationState = function (animator) {
+ return animator.getAnimationState(this);
+ };
+ return SkeletonNaryLERPNode;
+})(AnimationNodeBase);
+module.exports = SkeletonNaryLERPNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9za2VsZXRvbm5hcnlsZXJwbm9kZS50cyJdLCJuYW1lcyI6WyJTa2VsZXRvbk5hcnlMRVJQTm9kZSIsIlNrZWxldG9uTmFyeUxFUlBOb2RlLmNvbnN0cnVjdG9yIiwiU2tlbGV0b25OYXJ5TEVSUE5vZGUubnVtSW5wdXRzIiwiU2tlbGV0b25OYXJ5TEVSUE5vZGUuZ2V0SW5wdXRJbmRleCIsIlNrZWxldG9uTmFyeUxFUlBOb2RlLmdldElucHV0QXQiLCJTa2VsZXRvbk5hcnlMRVJQTm9kZS5hZGRJbnB1dCIsIlNrZWxldG9uTmFyeUxFUlBOb2RlLmdldEFuaW1hdGlvblN0YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLGlCQUFpQixXQUFjLG1EQUFtRCxDQUFDLENBQUM7QUFJM0YsSUFBTyxxQkFBcUIsV0FBYSw4REFBOEQsQ0FBQyxDQUFDO0FBRXpHLEFBR0E7O0dBREc7SUFDRyxvQkFBb0I7SUFBU0EsVUFBN0JBLG9CQUFvQkEsVUFBMEJBO0lBV25EQTs7T0FFR0E7SUFDSEEsU0FkS0Esb0JBQW9CQTtRQWdCeEJDLGlCQUFPQSxDQUFDQTtRQWRGQSxhQUFRQSxHQUE0QkEsSUFBSUEsS0FBS0EsRUFBcUJBLENBQUNBO1FBZ0J6RUEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EscUJBQXFCQSxDQUFDQTtJQUMzQ0EsQ0FBQ0E7SUFiREQsc0JBQVdBLDJDQUFTQTthQUFwQkE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDeEJBLENBQUNBOzs7T0FBQUY7SUFZREE7Ozs7T0FJR0E7SUFDSUEsNENBQWFBLEdBQXBCQSxVQUFxQkEsS0FBdUJBO1FBRTNDRyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxPQUFPQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtJQUNyQ0EsQ0FBQ0E7SUFFREg7Ozs7T0FJR0E7SUFDSUEseUNBQVVBLEdBQWpCQSxVQUFrQkEsS0FBS0EsQ0FBUUEsUUFBREEsQUFBU0E7UUFFdENJLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO0lBQzdCQSxDQUFDQTtJQUVESjs7T0FFR0E7SUFDSUEsdUNBQVFBLEdBQWZBLFVBQWdCQSxLQUF1QkE7UUFFdENLLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBO0lBQzFDQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEsZ0RBQWlCQSxHQUF4QkEsVUFBeUJBLFFBQXFCQTtRQUU3Q00sTUFBTUEsQ0FBeUJBLFFBQVFBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDakVBLENBQUNBO0lBQ0ZOLDJCQUFDQTtBQUFEQSxDQXhEQSxBQXdEQ0EsRUF4RGtDLGlCQUFpQixFQXdEbkQ7QUFFRCxBQUE2QixpQkFBcEIsb0JBQW9CLENBQUEiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1NrZWxldG9uTmFyeUxFUlBOb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBTa2VsZXRvbk5hcnlMRVJQU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9Ta2VsZXRvbk5hcnlMRVJQU3RhdGVcIik7XG5cbi8qKlxuICogQSBza2VsZXRvbiBhbmltYXRpb24gbm9kZSB0aGF0IHVzZXMgYW4gbi1kaW1lbnNpb25hbCBhcnJheSBvZiBhbmltYXRpb24gbm9kZSBpbnB1dHMgdG8gYmxlbmQgYSBsaW5lcmFseSBpbnRlcnBvbGF0ZWQgb3V0cHV0IG9mIGEgc2tlbGV0b24gcG9zZS5cbiAqL1xuY2xhc3MgU2tlbGV0b25OYXJ5TEVSUE5vZGUgZXh0ZW5kcyBBbmltYXRpb25Ob2RlQmFzZVxue1xuXHRwdWJsaWMgX2lJbnB1dHM6QXJyYXk8QW5pbWF0aW9uTm9kZUJhc2U+ID0gbmV3IEFycmF5PEFuaW1hdGlvbk5vZGVCYXNlPigpO1xuXG5cdHByaXZhdGUgX251bUlucHV0czpudW1iZXIgLyp1aW50Ki87XG5cblx0cHVibGljIGdldCBudW1JbnB1dHMoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9udW1JbnB1dHM7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ta2VsZXRvbk5hcnlMRVJQTm9kZTwvY29kZT4gb2JqZWN0LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gU2tlbGV0b25OYXJ5TEVSUFN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIGlucHV0IGluZGV4IG9mIHRoZSBnaXZlbiBza2VsZXRvbiBhbmltYXRpb24gbm9kZS5cblx0ICpcblx0ICogQHBhcmFtIGlucHV0IFRoZSBza2VsZXRvbiBhbmltYXRpb24gbm9kZSBmb3Igd2l0aCB0aGUgaW5wdXQgaW5kZXggaXMgcmVxdWVzdGVkLlxuXHQgKi9cblx0cHVibGljIGdldElucHV0SW5kZXgoaW5wdXQ6QW5pbWF0aW9uTm9kZUJhc2UpOm51bWJlciAvKmludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faUlucHV0cy5pbmRleE9mKGlucHV0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBza2VsZXRvbiBhbmltYXRpb24gbm9kZSBvYmplY3QgdGhhdCByZXNpZGVzIGF0IHRoZSBnaXZlbiBpbnB1dCBpbmRleC5cblx0ICpcblx0ICogQHBhcmFtIGluZGV4IFRoZSBpbnB1dCBpbmRleCBmb3Igd2hpY2ggdGhlIHNrZWxldG9uIGFuaW1hdGlvbiBub2RlIGlzIHJlcXVlc3RlZC5cblx0ICovXG5cdHB1YmxpYyBnZXRJbnB1dEF0KGluZGV4Om51bWJlciAvKnVpbnQqLyk6QW5pbWF0aW9uTm9kZUJhc2Vcblx0e1xuXHRcdHJldHVybiB0aGlzLl9pSW5wdXRzW2luZGV4XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbmV3IHNrZWxldG9uIGFuaW1hdGlvbiBub2RlIGlucHV0IHRvIHRoZSBhbmltYXRpb24gbm9kZS5cblx0ICovXG5cdHB1YmxpYyBhZGRJbnB1dChpbnB1dDpBbmltYXRpb25Ob2RlQmFzZSlcblx0e1xuXHRcdHRoaXMuX2lJbnB1dHNbdGhpcy5fbnVtSW5wdXRzKytdID0gaW5wdXQ7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRBbmltYXRpb25TdGF0ZShhbmltYXRvcjpBbmltYXRvckJhc2UpOlNrZWxldG9uTmFyeUxFUlBTdGF0ZVxuXHR7XG5cdFx0cmV0dXJuIDxTa2VsZXRvbk5hcnlMRVJQU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNrZWxldG9uTmFyeUxFUlBOb2RlIl19
\ No newline at end of file
diff --git a/lib/animators/nodes/SkeletonNaryLERPNode.ts b/lib/animators/nodes/SkeletonNaryLERPNode.ts
new file mode 100644
index 000000000..4117de7fb
--- /dev/null
+++ b/lib/animators/nodes/SkeletonNaryLERPNode.ts
@@ -0,0 +1,68 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonNaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonNaryLERPState");
+
+/**
+ * A skeleton animation node that uses an n-dimensional array of animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+class SkeletonNaryLERPNode extends AnimationNodeBase
+{
+ public _iInputs:Array = new Array();
+
+ private _numInputs:number /*uint*/;
+
+ public get numInputs():number /*uint*/
+ {
+ return this._numInputs;
+ }
+
+ /**
+ * Creates a new SkeletonNaryLERPNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = SkeletonNaryLERPState;
+ }
+
+ /**
+ * Returns an integer representing the input index of the given skeleton animation node.
+ *
+ * @param input The skeleton animation node for with the input index is requested.
+ */
+ public getInputIndex(input:AnimationNodeBase):number /*int*/
+ {
+ return this._iInputs.indexOf(input);
+ }
+
+ /**
+ * Returns the skeleton animation node object that resides at the given input index.
+ *
+ * @param index The input index for which the skeleton animation node is requested.
+ */
+ public getInputAt(index:number /*uint*/):AnimationNodeBase
+ {
+ return this._iInputs[index];
+ }
+
+ /**
+ * Adds a new skeleton animation node input to the animation node.
+ */
+ public addInput(input:AnimationNodeBase)
+ {
+ this._iInputs[this._numInputs++] = input;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getAnimationState(animator:AnimatorBase):SkeletonNaryLERPState
+ {
+ return animator.getAnimationState(this);
+ }
+}
+
+export = SkeletonNaryLERPNode
\ No newline at end of file
diff --git a/lib/animators/nodes/VertexClipNode.js b/lib/animators/nodes/VertexClipNode.js
new file mode 100755
index 000000000..9a67e5a5c
--- /dev/null
+++ b/lib/animators/nodes/VertexClipNode.js
@@ -0,0 +1,79 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var AnimationClipNodeBase = require("awayjs-renderergl/lib/animators/nodes/AnimationClipNodeBase");
+var VertexClipState = require("awayjs-renderergl/lib/animators/states/VertexClipState");
+/**
+ * A vertex animation node containing time-based animation data as individual geometry obejcts.
+ */
+var VertexClipNode = (function (_super) {
+ __extends(VertexClipNode, _super);
+ /**
+ * Creates a new VertexClipNode
object.
+ */
+ function VertexClipNode() {
+ _super.call(this);
+ this._frames = new Array();
+ this._translations = new Array();
+ this._pStateClass = VertexClipState;
+ }
+ Object.defineProperty(VertexClipNode.prototype, "frames", {
+ /**
+ * Returns a vector of geometry frames representing the vertex values of each animation frame in the clip.
+ */
+ get: function () {
+ return this._frames;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Adds a geometry object to the internal timeline of the animation node.
+ *
+ * @param geometry The geometry object to add to the timeline of the node.
+ * @param duration The specified duration of the frame in milliseconds.
+ * @param translation The absolute translation of the frame, used in root delta calculations for mesh movement.
+ */
+ VertexClipNode.prototype.addFrame = function (geometry, duration /*uint*/, translation) {
+ if (translation === void 0) { translation = null; }
+ this._frames.push(geometry);
+ this._pDurations.push(duration);
+ this._translations.push(translation || new Vector3D());
+ this._pNumFrames = this._pDurations.length;
+ this._pStitchDirty = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexClipNode.prototype._pUpdateStitch = function () {
+ _super.prototype._pUpdateStitch.call(this);
+ var i = this._pNumFrames - 1;
+ var p1, p2, delta;
+ while (i--) {
+ this._pTotalDuration += this._pDurations[i];
+ p1 = this._translations[i];
+ p2 = this._translations[i + 1];
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ if (this._pNumFrames > 1 && (this._pStitchFinalFrame || !this._pLooping)) {
+ this._pTotalDuration += this._pDurations[this._pNumFrames - 1];
+ p1 = this._translations[0];
+ p2 = this._translations[1];
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ };
+ return VertexClipNode;
+})(AnimationClipNodeBase);
+module.exports = VertexClipNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy92ZXJ0ZXhjbGlwbm9kZS50cyJdLCJuYW1lcyI6WyJWZXJ0ZXhDbGlwTm9kZSIsIlZlcnRleENsaXBOb2RlLmNvbnN0cnVjdG9yIiwiVmVydGV4Q2xpcE5vZGUuZnJhbWVzIiwiVmVydGV4Q2xpcE5vZGUuYWRkRnJhbWUiLCJWZXJ0ZXhDbGlwTm9kZS5fcFVwZGF0ZVN0aXRjaCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFJdEUsSUFBTyxxQkFBcUIsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBQ3hHLElBQU8sZUFBZSxXQUFlLHdEQUF3RCxDQUFDLENBQUM7QUFFL0YsQUFHQTs7R0FERztJQUNHLGNBQWM7SUFBU0EsVUFBdkJBLGNBQWNBLFVBQThCQTtJQWFqREE7O09BRUdBO0lBQ0hBLFNBaEJLQSxjQUFjQTtRQWtCbEJDLGlCQUFPQSxDQUFDQTtRQWhCREEsWUFBT0EsR0FBbUJBLElBQUlBLEtBQUtBLEVBQVlBLENBQUNBO1FBQ2hEQSxrQkFBYUEsR0FBbUJBLElBQUlBLEtBQUtBLEVBQVlBLENBQUNBO1FBaUI3REEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsZUFBZUEsQ0FBQ0E7SUFDckNBLENBQUNBO0lBYkRELHNCQUFXQSxrQ0FBTUE7UUFIakJBOztXQUVHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQTtRQUNyQkEsQ0FBQ0E7OztPQUFBRjtJQVlEQTs7Ozs7O09BTUdBO0lBQ0lBLGlDQUFRQSxHQUFmQSxVQUFnQkEsUUFBaUJBLEVBQUVBLFFBQVFBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFdBQTJCQTtRQUEzQkcsMkJBQTJCQSxHQUEzQkEsa0JBQTJCQTtRQUV2RkEsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBO1FBQ2hDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxJQUFJQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUV2REEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFFM0NBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO0lBQzNCQSxDQUFDQTtJQUVESDs7T0FFR0E7SUFDSUEsdUNBQWNBLEdBQXJCQTtRQUVDSSxnQkFBS0EsQ0FBQ0EsY0FBY0EsV0FBRUEsQ0FBQ0E7UUFFdkJBLElBQUlBLENBQUNBLEdBQW1CQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUM3Q0EsSUFBSUEsRUFBV0EsRUFBRUEsRUFBV0EsRUFBRUEsS0FBY0EsQ0FBQ0E7UUFDN0NBLE9BQU9BLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQ1pBLElBQUlBLENBQUNBLGVBQWVBLElBQUlBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzVDQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMzQkEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLEtBQUtBLEdBQUdBLEVBQUVBLENBQUNBLFFBQVFBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ3hCQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMvQkEsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQ2hDQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxrQkFBa0JBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzFFQSxJQUFJQSxDQUFDQSxlQUFlQSxJQUFJQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMvREEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDM0JBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzNCQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQSxRQUFRQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUN4QkEsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1lBQy9CQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxJQUFJQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNoQ0EsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFDRkoscUJBQUNBO0FBQURBLENBdEVBLEFBc0VDQSxFQXRFNEIscUJBQXFCLEVBc0VqRDtBQUVELEFBQXdCLGlCQUFmLGNBQWMsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvbm9kZXMvVmVydGV4Q2xpcE5vZGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgR2VvbWV0cnlcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvR2VvbWV0cnlcIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvbkNsaXBOb2RlQmFzZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvQW5pbWF0aW9uQ2xpcE5vZGVCYXNlXCIpO1xuaW1wb3J0IFZlcnRleENsaXBTdGF0ZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9WZXJ0ZXhDbGlwU3RhdGVcIik7XG5cbi8qKlxuICogQSB2ZXJ0ZXggYW5pbWF0aW9uIG5vZGUgY29udGFpbmluZyB0aW1lLWJhc2VkIGFuaW1hdGlvbiBkYXRhIGFzIGluZGl2aWR1YWwgZ2VvbWV0cnkgb2JlamN0cy5cbiAqL1xuY2xhc3MgVmVydGV4Q2xpcE5vZGUgZXh0ZW5kcyBBbmltYXRpb25DbGlwTm9kZUJhc2Vcbntcblx0cHJpdmF0ZSBfZnJhbWVzOkFycmF5PEdlb21ldHJ5PiA9IG5ldyBBcnJheTxHZW9tZXRyeT4oKTtcblx0cHJpdmF0ZSBfdHJhbnNsYXRpb25zOkFycmF5PFZlY3RvcjNEPiA9IG5ldyBBcnJheTxWZWN0b3IzRD4oKTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIHZlY3RvciBvZiBnZW9tZXRyeSBmcmFtZXMgcmVwcmVzZW50aW5nIHRoZSB2ZXJ0ZXggdmFsdWVzIG9mIGVhY2ggYW5pbWF0aW9uIGZyYW1lIGluIHRoZSBjbGlwLlxuXHQgKi9cblx0cHVibGljIGdldCBmcmFtZXMoKTpBcnJheTxHZW9tZXRyeT5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9mcmFtZXM7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5WZXJ0ZXhDbGlwTm9kZTwvY29kZT4gb2JqZWN0LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX3BTdGF0ZUNsYXNzID0gVmVydGV4Q2xpcFN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBnZW9tZXRyeSBvYmplY3QgdG8gdGhlIGludGVybmFsIHRpbWVsaW5lIG9mIHRoZSBhbmltYXRpb24gbm9kZS5cblx0ICpcblx0ICogQHBhcmFtIGdlb21ldHJ5IFRoZSBnZW9tZXRyeSBvYmplY3QgdG8gYWRkIHRvIHRoZSB0aW1lbGluZSBvZiB0aGUgbm9kZS5cblx0ICogQHBhcmFtIGR1cmF0aW9uIFRoZSBzcGVjaWZpZWQgZHVyYXRpb24gb2YgdGhlIGZyYW1lIGluIG1pbGxpc2Vjb25kcy5cblx0ICogQHBhcmFtIHRyYW5zbGF0aW9uIFRoZSBhYnNvbHV0ZSB0cmFuc2xhdGlvbiBvZiB0aGUgZnJhbWUsIHVzZWQgaW4gcm9vdCBkZWx0YSBjYWxjdWxhdGlvbnMgZm9yIG1lc2ggbW92ZW1lbnQuXG5cdCAqL1xuXHRwdWJsaWMgYWRkRnJhbWUoZ2VvbWV0cnk6R2VvbWV0cnksIGR1cmF0aW9uOm51bWJlciAvKnVpbnQqLywgdHJhbnNsYXRpb246VmVjdG9yM0QgPSBudWxsKVxuXHR7XG5cdFx0dGhpcy5fZnJhbWVzLnB1c2goZ2VvbWV0cnkpO1xuXHRcdHRoaXMuX3BEdXJhdGlvbnMucHVzaChkdXJhdGlvbik7XG5cdFx0dGhpcy5fdHJhbnNsYXRpb25zLnB1c2godHJhbnNsYXRpb24gfHwgbmV3IFZlY3RvcjNEKCkpO1xuXG5cdFx0dGhpcy5fcE51bUZyYW1lcyA9IHRoaXMuX3BEdXJhdGlvbnMubGVuZ3RoO1xuXG5cdFx0dGhpcy5fcFN0aXRjaERpcnR5ID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlU3RpdGNoKClcblx0e1xuXHRcdHN1cGVyLl9wVXBkYXRlU3RpdGNoKCk7XG5cblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wTnVtRnJhbWVzIC0gMTtcblx0XHR2YXIgcDE6VmVjdG9yM0QsIHAyOlZlY3RvcjNELCBkZWx0YTpWZWN0b3IzRDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHR0aGlzLl9wVG90YWxEdXJhdGlvbiArPSB0aGlzLl9wRHVyYXRpb25zW2ldO1xuXHRcdFx0cDEgPSB0aGlzLl90cmFuc2xhdGlvbnNbaV07XG5cdFx0XHRwMiA9IHRoaXMuX3RyYW5zbGF0aW9uc1tpICsgMV07XG5cdFx0XHRkZWx0YSA9IHAyLnN1YnRyYWN0KHAxKTtcblx0XHRcdHRoaXMuX3BUb3RhbERlbHRhLnggKz0gZGVsdGEueDtcblx0XHRcdHRoaXMuX3BUb3RhbERlbHRhLnkgKz0gZGVsdGEueTtcblx0XHRcdHRoaXMuX3BUb3RhbERlbHRhLnogKz0gZGVsdGEuejtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcE51bUZyYW1lcyA+IDEgJiYgKHRoaXMuX3BTdGl0Y2hGaW5hbEZyYW1lIHx8ICF0aGlzLl9wTG9vcGluZykpIHtcblx0XHRcdHRoaXMuX3BUb3RhbER1cmF0aW9uICs9IHRoaXMuX3BEdXJhdGlvbnNbdGhpcy5fcE51bUZyYW1lcyAtIDFdO1xuXHRcdFx0cDEgPSB0aGlzLl90cmFuc2xhdGlvbnNbMF07XG5cdFx0XHRwMiA9IHRoaXMuX3RyYW5zbGF0aW9uc1sxXTtcblx0XHRcdGRlbHRhID0gcDIuc3VidHJhY3QocDEpO1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueCArPSBkZWx0YS54O1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueSArPSBkZWx0YS55O1xuXHRcdFx0dGhpcy5fcFRvdGFsRGVsdGEueiArPSBkZWx0YS56O1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBWZXJ0ZXhDbGlwTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/nodes/VertexClipNode.ts b/lib/animators/nodes/VertexClipNode.ts
new file mode 100644
index 000000000..655a77e9d
--- /dev/null
+++ b/lib/animators/nodes/VertexClipNode.ts
@@ -0,0 +1,84 @@
+import Geometry = require("awayjs-core/lib/core/base/Geometry");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import AnimationClipNodeBase = require("awayjs-renderergl/lib/animators/nodes/AnimationClipNodeBase");
+import VertexClipState = require("awayjs-renderergl/lib/animators/states/VertexClipState");
+
+/**
+ * A vertex animation node containing time-based animation data as individual geometry obejcts.
+ */
+class VertexClipNode extends AnimationClipNodeBase
+{
+ private _frames:Array = new Array();
+ private _translations:Array = new Array();
+
+ /**
+ * Returns a vector of geometry frames representing the vertex values of each animation frame in the clip.
+ */
+ public get frames():Array
+ {
+ return this._frames;
+ }
+
+ /**
+ * Creates a new VertexClipNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = VertexClipState;
+ }
+
+ /**
+ * Adds a geometry object to the internal timeline of the animation node.
+ *
+ * @param geometry The geometry object to add to the timeline of the node.
+ * @param duration The specified duration of the frame in milliseconds.
+ * @param translation The absolute translation of the frame, used in root delta calculations for mesh movement.
+ */
+ public addFrame(geometry:Geometry, duration:number /*uint*/, translation:Vector3D = null)
+ {
+ this._frames.push(geometry);
+ this._pDurations.push(duration);
+ this._translations.push(translation || new Vector3D());
+
+ this._pNumFrames = this._pDurations.length;
+
+ this._pStitchDirty = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateStitch()
+ {
+ super._pUpdateStitch();
+
+ var i:number /*uint*/ = this._pNumFrames - 1;
+ var p1:Vector3D, p2:Vector3D, delta:Vector3D;
+ while (i--) {
+ this._pTotalDuration += this._pDurations[i];
+ p1 = this._translations[i];
+ p2 = this._translations[i + 1];
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+
+ if (this._pNumFrames > 1 && (this._pStitchFinalFrame || !this._pLooping)) {
+ this._pTotalDuration += this._pDurations[this._pNumFrames - 1];
+ p1 = this._translations[0];
+ p2 = this._translations[1];
+ delta = p2.subtract(p1);
+ this._pTotalDelta.x += delta.x;
+ this._pTotalDelta.y += delta.y;
+ this._pTotalDelta.z += delta.z;
+ }
+ }
+}
+
+export = VertexClipNode;
\ No newline at end of file
diff --git a/lib/animators/states/AnimationClipState.js b/lib/animators/states/AnimationClipState.js
new file mode 100755
index 000000000..2ce335d40
--- /dev/null
+++ b/lib/animators/states/AnimationClipState.js
@@ -0,0 +1,152 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+var AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+/**
+ *
+ */
+var AnimationClipState = (function (_super) {
+ __extends(AnimationClipState, _super);
+ function AnimationClipState(animator, animationClipNode) {
+ _super.call(this, animator, animationClipNode);
+ this._pFramesDirty = true;
+ this._animationClipNode = animationClipNode;
+ }
+ Object.defineProperty(AnimationClipState.prototype, "blendWeight", {
+ /**
+ * Returns a fractional value between 0 and 1 representing the blending ratio of the current playhead position
+ * between the current frame (0) and next frame (1) of the animation.
+ *
+ * @see #currentFrame
+ * @see #nextFrame
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._pBlendWeight;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipState.prototype, "currentFrame", {
+ /**
+ * Returns the current frame of animation in the clip based on the internal playhead position.
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._pCurrentFrame;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationClipState.prototype, "nextFrame", {
+ /**
+ * Returns the next frame of animation in the clip based on the internal playhead position.
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._pNextFrame;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ AnimationClipState.prototype.update = function (time /*int*/) {
+ if (!this._animationClipNode.looping) {
+ if (time > this._pStartTime + this._animationClipNode.totalDuration)
+ time = this._pStartTime + this._animationClipNode.totalDuration;
+ else if (time < this._pStartTime)
+ time = this._pStartTime;
+ }
+ if (this._pTime == time - this._pStartTime)
+ return;
+ this._pUpdateTime(time);
+ };
+ /**
+ * @inheritDoc
+ */
+ AnimationClipState.prototype.phase = function (value) {
+ var time = value * this._animationClipNode.totalDuration + this._pStartTime;
+ if (this._pTime == time - this._pStartTime)
+ return;
+ this._pUpdateTime(time);
+ };
+ /**
+ * @inheritDoc
+ */
+ AnimationClipState.prototype._pUpdateTime = function (time /*int*/) {
+ this._pFramesDirty = true;
+ this._pTimeDir = (time - this._pStartTime > this._pTime) ? 1 : -1;
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * Updates the nodes internal playhead to determine the current and next animation frame, and the blendWeight between the two.
+ *
+ * @see #currentFrame
+ * @see #nextFrame
+ * @see #blendWeight
+ */
+ AnimationClipState.prototype._pUpdateFrames = function () {
+ this._pFramesDirty = false;
+ var looping = this._animationClipNode.looping;
+ var totalDuration = this._animationClipNode.totalDuration;
+ var lastFrame = this._animationClipNode.lastFrame;
+ var time = this._pTime;
+ //trace("time", time, totalDuration)
+ if (looping && (time >= totalDuration || time < 0)) {
+ time %= totalDuration;
+ if (time < 0)
+ time += totalDuration;
+ }
+ if (!looping && time >= totalDuration) {
+ this.notifyPlaybackComplete();
+ this._pCurrentFrame = lastFrame;
+ this._pNextFrame = lastFrame;
+ this._pBlendWeight = 0;
+ }
+ else if (!looping && time <= 0) {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 0;
+ this._pBlendWeight = 0;
+ }
+ else if (this._animationClipNode.fixedFrameRate) {
+ var t = time / totalDuration * lastFrame;
+ this._pCurrentFrame = Math.floor(t);
+ this._pBlendWeight = t - this._pCurrentFrame;
+ this._pNextFrame = this._pCurrentFrame + 1;
+ }
+ else {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 0;
+ var dur = 0, frameTime /*uint*/;
+ var durations = this._animationClipNode.durations;
+ do {
+ frameTime = dur;
+ dur += durations[this._pNextFrame];
+ this._pCurrentFrame = this._pNextFrame++;
+ } while (time > dur);
+ if (this._pCurrentFrame == lastFrame) {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 1;
+ }
+ this._pBlendWeight = (time - frameTime) / durations[this._pCurrentFrame];
+ }
+ };
+ AnimationClipState.prototype.notifyPlaybackComplete = function () {
+ if (this._animationStatePlaybackComplete == null)
+ this._animationStatePlaybackComplete = new AnimationStateEvent(AnimationStateEvent.PLAYBACK_COMPLETE, this._pAnimator, this, this._animationClipNode);
+ this._animationClipNode.dispatchEvent(this._animationStatePlaybackComplete);
+ };
+ return AnimationClipState;
+})(AnimationStateBase);
+module.exports = AnimationClipState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvYW5pbWF0aW9uY2xpcHN0YXRlLnRzIl0sIm5hbWVzIjpbIkFuaW1hdGlvbkNsaXBTdGF0ZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5jb25zdHJ1Y3RvciIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5ibGVuZFdlaWdodCIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5jdXJyZW50RnJhbWUiLCJBbmltYXRpb25DbGlwU3RhdGUubmV4dEZyYW1lIiwiQW5pbWF0aW9uQ2xpcFN0YXRlLnVwZGF0ZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5waGFzZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJBbmltYXRpb25DbGlwU3RhdGUuX3BVcGRhdGVGcmFtZXMiLCJBbmltYXRpb25DbGlwU3RhdGUubm90aWZ5UGxheWJhY2tDb21wbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsSUFBTyxrQkFBa0IsV0FBYywyREFBMkQsQ0FBQyxDQUFDO0FBQ3BHLElBQU8sbUJBQW1CLFdBQWMsa0RBQWtELENBQUMsQ0FBQztBQUU1RixBQUdBOztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTJCQTtJQWlEbERBLFNBakRLQSxrQkFBa0JBLENBaURYQSxRQUFxQkEsRUFBRUEsaUJBQXVDQTtRQUV6RUMsa0JBQU1BLFFBQVFBLEVBQUVBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0E7UUF6QzdCQSxrQkFBYUEsR0FBV0EsSUFBSUEsQ0FBQ0E7UUEyQ25DQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLGlCQUFpQkEsQ0FBQ0E7SUFDN0NBLENBQUNBO0lBbkNERCxzQkFBV0EsMkNBQVdBO1FBUHRCQTs7Ozs7O1dBTUdBO2FBQ0hBO1lBRUNFLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO2dCQUN0QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsRUFBRUEsQ0FBQ0E7WUFFdkJBLE1BQU1BLENBQUNBLElBQUlBLENB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Q0EsQ0FBQ0E7Z0JBQ3RDQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDeEJBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLENBQUNBLENBQUNBO1lBQ3RCQSxDQUFDQTtZQUVEQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxDQUFDQSxJQUFJQSxHQUFHQSxTQUFTQSxDQUFDQSxHQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUN4RUEsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFFT1IsbURBQXNCQSxHQUE5QkE7UUFFQ1MsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsK0JBQStCQSxJQUFJQSxJQUFJQSxDQUFDQTtZQUNoREEsSUFBSUEsQ0FBQ0EsK0JBQStCQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxJQUFJQSxFQUFFQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLENBQUNBO1FBRXZKQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLCtCQUErQkEsQ0FBQ0EsQ0FBQ0E7SUFDN0VBLENBQUNBO0lBQ0ZULHlCQUFDQTtBQUFEQSxDQXBLQSxBQW9LQ0EsRUFwS2dDLGtCQUFrQixFQW9LbEQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9BbmltYXRpb25DbGlwU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBBbmltYXRpb25DbGlwTm9kZUJhc2VcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbkNsaXBOb2RlQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25TdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL0FuaW1hdGlvblN0YXRlQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25TdGF0ZUV2ZW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvZXZlbnRzL0FuaW1hdGlvblN0YXRlRXZlbnRcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgQW5pbWF0aW9uQ2xpcFN0YXRlIGV4dGVuZHMgQW5pbWF0aW9uU3RhdGVCYXNlXG57XG5cdHByaXZhdGUgX2FuaW1hdGlvbkNsaXBOb2RlOkFuaW1hdGlvbkNsaXBOb2RlQmFzZTtcblx0cHJpdmF0ZSBfYW5pbWF0aW9uU3RhdGVQbGF5YmFja0NvbXBsZXRlOkFuaW1hdGlvblN0YXRlRXZlbnQ7XG5cdHB1YmxpYyBfcEJsZW5kV2VpZ2h0Om51bWJlcjtcblx0cHVibGljIF9wQ3VycmVudEZyYW1lOm51bWJlciAvKnVpbnQqLztcblx0cHVibGljIF9wTmV4dEZyYW1lOm51bWJlciAvKnVpbnQqLztcblxuXHRwdWJsaWMgX3BPbGRGcmFtZTpudW1iZXIgLyp1aW50Ki87XG5cdHB1YmxpYyBfcFRpbWVEaXI6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyBfcEZyYW1lc0RpcnR5OmJvb2xlYW4gPSB0cnVlO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZnJhY3Rpb25hbCB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEgcmVwcmVzZW50aW5nIHRoZSBibGVuZGluZyByYXRpbyBvZiB0aGUgY3VycmVudCBwbGF5aGVhZCBwb3NpdGlvblxuXHQgKiBiZXR3ZWVuIHRoZSBjdXJyZW50IGZyYW1lICgwKSBhbmQgbmV4dCBmcmFtZSAoMSkgb2YgdGhlIGFuaW1hdGlvbi5cblx0ICpcblx0ICogQHNlZSAjY3VycmVudEZyYW1lXG5cdCAqIEBzZWUgI25leHRGcmFtZVxuXHQgKi9cblx0cHVibGljIGdldCBibGVuZFdlaWdodCgpOm51bWJlclxuXHR7XG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHJldHVybiB0aGlzLl9wQmxlbmRXZWlnaHQ7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgY3VycmVudCBmcmFtZSBvZiBhbmltYXRpb24gaW4gdGhlIGNsaXAgYmFzZWQgb24gdGhlIGludGVybmFsIHBsYXloZWFkIHBvc2l0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldCBjdXJyZW50RnJhbWUoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdGlmICh0aGlzLl9wRnJhbWVzRGlydHkpXG5cdFx0XHR0aGlzLl9wVXBkYXRlRnJhbWVzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fcEN1cnJlbnRGcmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBuZXh0IGZyYW1lIG9mIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG5leHRGcmFtZSgpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHJldHVybiB0aGlzLl9wTmV4dEZyYW1lO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBhbmltYXRpb25DbGlwTm9kZTpBbmltYXRpb25DbGlwTm9kZUJhc2UpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgYW5pbWF0aW9uQ2xpcE5vZGUpO1xuXG5cdFx0dGhpcy5fYW5pbWF0aW9uQ2xpcE5vZGUgPSBhbmltYXRpb25DbGlwTm9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHVwZGF0ZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0aWYgKCF0aGlzLl9hbmltYXRpb25DbGlwTm9kZS5sb29waW5nKSB7XG5cdFx0XHRpZiAodGltZSA+IHRoaXMuX3BTdGFydFRpbWUgKyB0aGlzLl9hbmltYXRpb25DbGlwTm9kZS50b3RhbER1cmF0aW9uKVxuXHRcdFx0XHR0aW1lID0gdGhpcy5fcFN0YXJ0VGltZSArIHRoaXMuX2FuaW1hdGlvbkNsaXBOb2RlLnRvdGFsRHVyYXRpb247IGVsc2UgaWYgKHRpbWUgPCB0aGlzLl9wU3RhcnRUaW1lKVxuXHRcdFx0XHR0aW1lID0gdGhpcy5fcFN0YXJ0VGltZTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcFRpbWUgPT0gdGltZSAtIHRoaXMuX3BTdGFydFRpbWUpXG5cdFx0XHRyZXR1cm47XG5cblx0XHR0aGlzLl9wVXBkYXRlVGltZSh0aW1lKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHBoYXNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHZhciB0aW1lOm51bWJlciAvKmludCovID0gdmFsdWUqdGhpcy5fYW5pbWF0aW9uQ2xpcE5vZGUudG90YWxEdXJhdGlvbiArIHRoaXMuX3BTdGFydFRpbWU7XG5cblx0XHRpZiAodGhpcy5fcFRpbWUgPT0gdGltZSAtIHRoaXMuX3BTdGFydFRpbWUpXG5cdFx0XHRyZXR1cm47XG5cblx0XHR0aGlzLl9wVXBkYXRlVGltZSh0aW1lKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlVGltZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0dGhpcy5fcEZyYW1lc0RpcnR5ID0gdHJ1ZTtcblxuXHRcdHRoaXMuX3BUaW1lRGlyID0gKHRpbWUgLSB0aGlzLl9wU3RhcnRUaW1lID4gdGhpcy5fcFRpbWUpPyAxIDogLTE7XG5cblx0XHRzdXBlci5fcFVwZGF0ZVRpbWUodGltZSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgbm9kZXMgaW50ZXJuYWwgcGxheWhlYWQgdG8gZGV0ZXJtaW5lIHRoZSBjdXJyZW50IGFuZCBuZXh0IGFuaW1hdGlvbiBmcmFtZSwgYW5kIHRoZSBibGVuZFdlaWdodCBiZXR3ZWVuIHRoZSB0d28uXG5cdCAqXG5cdCAqIEBzZWUgI2N1cnJlbnRGcmFtZVxuXHQgKiBAc2VlICNuZXh0RnJhbWVcblx0ICogQHNlZSAjYmxlbmRXZWlnaHRcblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZUZyYW1lcygpXG5cdHtcblx0XHR0aGlzLl9wRnJhbWVzRGlydHkgPSBmYWxzZTtcblxuXHRcdHZhciBsb29waW5nOmJvb2xlYW4gPSB0aGlzLl9hbmltYXRpb25DbGlwTm9kZS5sb29waW5nO1xuXHRcdHZhciB0b3RhbER1cmF0aW9uOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX2FuaW1hdGlvbkNsaXBOb2RlLnRvdGFsRHVyYXRpb247XG5cdFx0dmFyIGxhc3RGcmFtZTpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9hbmltYXRpb25DbGlwTm9kZS5sYXN0RnJhbWU7XG5cdFx0dmFyIHRpbWU6bnVtYmVyIC8qaW50Ki8gPSB0aGlzLl9wVGltZTtcblxuXHRcdC8vdHJhY2UoXCJ0aW1lXCIsIHRpbWUsIHRvdGFsRHVyYXRpb24pXG5cdFx0aWYgKGxvb3BpbmcgJiYgKHRpbWUgPj0gdG90YWxEdXJhdGlvbiB8fCB0aW1lIDwgMCkpIHtcblx0XHRcdHRpbWUgJT0gdG90YWxEdXJhdGlvbjtcblx0XHRcdGlmICh0aW1lIDwgMClcblx0XHRcdFx0dGltZSArPSB0b3RhbER1cmF0aW9uO1xuXHRcdH1cblxuXHRcdGlmICghbG9vcGluZyAmJiB0aW1lID49IHRvdGFsRHVyYXRpb24pIHtcblx0XHRcdHRoaXMubm90aWZ5UGxheWJhY2tDb21wbGV0ZSgpO1xuXHRcdFx0dGhpcy5fcEN1cnJlbnRGcmFtZSA9IGxhc3RGcmFtZTtcblx0XHRcdHRoaXMuX3BOZXh0RnJhbWUgPSBsYXN0RnJhbWU7XG5cdFx0XHR0aGlzLl9wQmxlbmRXZWlnaHQgPSAwO1xuXHRcdH0gZWxzZSBpZiAoIWxvb3BpbmcgJiYgdGltZSA8PSAwKSB7XG5cdFx0XHR0aGlzLl9wQ3VycmVudEZyYW1lID0gMDtcblx0XHRcdHRoaXMuX3BOZXh0RnJhbWUgPSAwO1xuXHRcdFx0dGhpcy5fcEJsZW5kV2VpZ2h0ID0gMDtcblx0XHR9IGVsc2UgaWYgKHRoaXMuX2FuaW1hdGlvbkNsaXBOb2RlLmZpeGVkRnJhbWVSYXRlKSB7XG5cdFx0XHR2YXIgdDpudW1iZXIgPSB0aW1lL3RvdGFsRHVyYXRpb24qbGFzdEZyYW1lO1xuXHRcdFx0dGhpcy5fcEN1cnJlbnRGcmFtZSA9IE1hdGguZmxvb3IodCk7XG5cdFx0XHR0aGlzLl9wQmxlbmRXZWlnaHQgPSB0IC0gdGhpcy5fcEN1cnJlbnRGcmFtZTtcblx0XHRcdHRoaXMuX3BOZXh0RnJhbWUgPSB0aGlzLl9wQ3VycmVudEZyYW1lICsgMTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fcEN1cnJlbnRGcmFtZSA9IDA7XG5cdFx0XHR0aGlzLl9wTmV4dEZyYW1lID0gMDtcblxuXHRcdFx0dmFyIGR1cjpudW1iZXIgLyp1aW50Ki8gPSAwLCBmcmFtZVRpbWU6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0dmFyIGR1cmF0aW9uczpBcnJheTxudW1iZXI+IC8qdWludCovID0gdGhpcy5fYW5pbWF0aW9uQ2xpcE5vZGUuZHVyYXRpb25zO1xuXG5cdFx0XHRkbyB7XG5cdFx0XHRcdGZyYW1lVGltZSA9IGR1cjtcblx0XHRcdFx0ZHVyICs9IGR1cmF0aW9uc1t0aGlzLl9wTmV4dEZyYW1lXTtcblx0XHRcdFx0dGhpcy5fcEN1cnJlbnRGcmFtZSA9IHRoaXMuX3BOZXh0RnJhbWUrKztcblx0XHRcdH0gd2hpbGUgKHRpbWUgPiBkdXIpO1xuXG5cdFx0XHRpZiAodGhpcy5fcEN1cnJlbnRGcmFtZSA9PSBsYXN0RnJhbWUpIHtcblx0XHRcdFx0dGhpcy5fcEN1cnJlbnRGcmFtZSA9IDA7XG5cdFx0XHRcdHRoaXMuX3BOZXh0RnJhbWUgPSAxO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9wQmxlbmRXZWlnaHQgPSAodGltZSAtIGZyYW1lVGltZSkvZHVyYXRpb25zW3RoaXMuX3BDdXJyZW50RnJhbWVdO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgbm90aWZ5UGxheWJhY2tDb21wbGV0ZSgpXG5cdHtcblx0XHRpZiAodGhpcy5fYW5pbWF0aW9uU3RhdGVQbGF5YmFja0NvbXBsZXRlID09IG51bGwpXG5cdFx0XHR0aGlzLl9hbmltYXRpb25TdGF0ZVBsYXliYWNrQ29tcGxldGUgPSBuZXcgQW5pbWF0aW9uU3RhdGVFdmVudChBbmltYXRpb25TdGF0ZUV2ZW50LlBMQVlCQUNLX0NPTVBMRVRFLCB0aGlzLl9wQW5pbWF0b3IsIHRoaXMsIHRoaXMuX2FuaW1hdGlvbkNsaXBOb2RlKTtcblxuXHRcdHRoaXMuX2FuaW1hdGlvbkNsaXBOb2RlLmRpc3BhdGNoRXZlbnQodGhpcy5fYW5pbWF0aW9uU3RhdGVQbGF5YmFja0NvbXBsZXRlKTtcblx0fVxufVxuXG5leHBvcnQgPSBBbmltYXRpb25DbGlwU3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/AnimationClipState.ts b/lib/animators/states/AnimationClipState.ts
new file mode 100644
index 000000000..0b08e02cf
--- /dev/null
+++ b/lib/animators/states/AnimationClipState.ts
@@ -0,0 +1,176 @@
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import AnimationClipNodeBase = require("awayjs-renderergl/lib/animators/nodes/AnimationClipNodeBase");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+import AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+
+/**
+ *
+ */
+class AnimationClipState extends AnimationStateBase
+{
+ private _animationClipNode:AnimationClipNodeBase;
+ private _animationStatePlaybackComplete:AnimationStateEvent;
+ public _pBlendWeight:number;
+ public _pCurrentFrame:number /*uint*/;
+ public _pNextFrame:number /*uint*/;
+
+ public _pOldFrame:number /*uint*/;
+ public _pTimeDir:number /*int*/;
+ public _pFramesDirty:boolean = true;
+
+ /**
+ * Returns a fractional value between 0 and 1 representing the blending ratio of the current playhead position
+ * between the current frame (0) and next frame (1) of the animation.
+ *
+ * @see #currentFrame
+ * @see #nextFrame
+ */
+ public get blendWeight():number
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._pBlendWeight;
+ }
+
+ /**
+ * Returns the current frame of animation in the clip based on the internal playhead position.
+ */
+ public get currentFrame():number /*uint*/
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._pCurrentFrame;
+ }
+
+ /**
+ * Returns the next frame of animation in the clip based on the internal playhead position.
+ */
+ public get nextFrame():number /*uint*/
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._pNextFrame;
+ }
+
+ constructor(animator:AnimatorBase, animationClipNode:AnimationClipNodeBase)
+ {
+ super(animator, animationClipNode);
+
+ this._animationClipNode = animationClipNode;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public update(time:number /*int*/)
+ {
+ if (!this._animationClipNode.looping) {
+ if (time > this._pStartTime + this._animationClipNode.totalDuration)
+ time = this._pStartTime + this._animationClipNode.totalDuration; else if (time < this._pStartTime)
+ time = this._pStartTime;
+ }
+
+ if (this._pTime == time - this._pStartTime)
+ return;
+
+ this._pUpdateTime(time);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public phase(value:number)
+ {
+ var time:number /*int*/ = value*this._animationClipNode.totalDuration + this._pStartTime;
+
+ if (this._pTime == time - this._pStartTime)
+ return;
+
+ this._pUpdateTime(time);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateTime(time:number /*int*/)
+ {
+ this._pFramesDirty = true;
+
+ this._pTimeDir = (time - this._pStartTime > this._pTime)? 1 : -1;
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * Updates the nodes internal playhead to determine the current and next animation frame, and the blendWeight between the two.
+ *
+ * @see #currentFrame
+ * @see #nextFrame
+ * @see #blendWeight
+ */
+ public _pUpdateFrames()
+ {
+ this._pFramesDirty = false;
+
+ var looping:boolean = this._animationClipNode.looping;
+ var totalDuration:number /*uint*/ = this._animationClipNode.totalDuration;
+ var lastFrame:number /*uint*/ = this._animationClipNode.lastFrame;
+ var time:number /*int*/ = this._pTime;
+
+ //trace("time", time, totalDuration)
+ if (looping && (time >= totalDuration || time < 0)) {
+ time %= totalDuration;
+ if (time < 0)
+ time += totalDuration;
+ }
+
+ if (!looping && time >= totalDuration) {
+ this.notifyPlaybackComplete();
+ this._pCurrentFrame = lastFrame;
+ this._pNextFrame = lastFrame;
+ this._pBlendWeight = 0;
+ } else if (!looping && time <= 0) {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 0;
+ this._pBlendWeight = 0;
+ } else if (this._animationClipNode.fixedFrameRate) {
+ var t:number = time/totalDuration*lastFrame;
+ this._pCurrentFrame = Math.floor(t);
+ this._pBlendWeight = t - this._pCurrentFrame;
+ this._pNextFrame = this._pCurrentFrame + 1;
+ } else {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 0;
+
+ var dur:number /*uint*/ = 0, frameTime:number /*uint*/;
+ var durations:Array /*uint*/ = this._animationClipNode.durations;
+
+ do {
+ frameTime = dur;
+ dur += durations[this._pNextFrame];
+ this._pCurrentFrame = this._pNextFrame++;
+ } while (time > dur);
+
+ if (this._pCurrentFrame == lastFrame) {
+ this._pCurrentFrame = 0;
+ this._pNextFrame = 1;
+ }
+
+ this._pBlendWeight = (time - frameTime)/durations[this._pCurrentFrame];
+ }
+ }
+
+ private notifyPlaybackComplete()
+ {
+ if (this._animationStatePlaybackComplete == null)
+ this._animationStatePlaybackComplete = new AnimationStateEvent(AnimationStateEvent.PLAYBACK_COMPLETE, this._pAnimator, this, this._animationClipNode);
+
+ this._animationClipNode.dispatchEvent(this._animationStatePlaybackComplete);
+ }
+}
+
+export = AnimationClipState;
\ No newline at end of file
diff --git a/lib/animators/states/AnimationStateBase.js b/lib/animators/states/AnimationStateBase.js
new file mode 100755
index 000000000..48b269e10
--- /dev/null
+++ b/lib/animators/states/AnimationStateBase.js
@@ -0,0 +1,73 @@
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+/**
+ *
+ */
+var AnimationStateBase = (function () {
+ function AnimationStateBase(animator, animationNode) {
+ this._pRootDelta = new Vector3D();
+ this._pPositionDeltaDirty = true;
+ this._pStartTime = 0;
+ this._pAnimator = animator;
+ this._pAnimationNode = animationNode;
+ }
+ Object.defineProperty(AnimationStateBase.prototype, "positionDelta", {
+ /**
+ * Returns a 3d vector representing the translation delta of the animating entity for the current timestep of animation
+ */
+ get: function () {
+ if (this._pPositionDeltaDirty) {
+ this._pUpdatePositionDelta();
+ }
+ return this._pRootDelta;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Resets the start time of the node to a new value.
+ *
+ * @param startTime The absolute start time (in milliseconds) of the node's starting time.
+ */
+ AnimationStateBase.prototype.offset = function (startTime) {
+ this._pStartTime = startTime;
+ this._pPositionDeltaDirty = true;
+ };
+ /**
+ * Updates the configuration of the node to its current state.
+ *
+ * @param time The absolute time (in milliseconds) of the animator's play head position.
+ *
+ * @see AnimatorBase#update()
+ */
+ AnimationStateBase.prototype.update = function (time) {
+ if (this._pTime == time - this._pStartTime) {
+ return;
+ }
+ this._pUpdateTime(time);
+ };
+ /**
+ * Sets the animation phase of the node.
+ *
+ * @param value The phase value to use. 0 represents the beginning of an animation clip, 1 represents the end.
+ */
+ AnimationStateBase.prototype.phase = function (value) {
+ };
+ /**
+ * Updates the node's internal playhead position.
+ *
+ * @param time The local time (in milliseconds) of the node's playhead position.
+ */
+ AnimationStateBase.prototype._pUpdateTime = function (time) {
+ this._pTime = time - this._pStartTime;
+ this._pPositionDeltaDirty = true;
+ };
+ /**
+ * Updates the node's root delta position
+ */
+ AnimationStateBase.prototype._pUpdatePositionDelta = function () {
+ };
+ return AnimationStateBase;
+})();
+module.exports = AnimationStateBase;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvYW5pbWF0aW9uc3RhdGViYXNlLnRzIl0sIm5hbWVzIjpbIkFuaW1hdGlvblN0YXRlQmFzZSIsIkFuaW1hdGlvblN0YXRlQmFzZS5jb25zdHJ1Y3RvciIsIkFuaW1hdGlvblN0YXRlQmFzZS5wb3NpdGlvbkRlbHRhIiwiQW5pbWF0aW9uU3RhdGVCYXNlLm9mZnNldCIsIkFuaW1hdGlvblN0YXRlQmFzZS51cGRhdGUiLCJBbmltYXRpb25TdGF0ZUJhc2UucGhhc2UiLCJBbmltYXRpb25TdGF0ZUJhc2UuX3BVcGRhdGVUaW1lIiwiQW5pbWF0aW9uU3RhdGVCYXNlLl9wVXBkYXRlUG9zaXRpb25EZWx0YSJdLCJtYXBwaW5ncyI6IkFBQ0EsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFPdEUsQUFHQTs7R0FERztJQUNHLGtCQUFrQjtJQXdCdkJBLFNBeEJLQSxrQkFBa0JBLENBd0JYQSxRQUFxQkEsRUFBRUEsYUFBK0JBO1FBckIzREMsZ0JBQVdBLEdBQVlBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1FBQ3RDQSx5QkFBb0JBLEdBQVdBLElBQUlBLENBQUNBO1FBR3BDQSxnQkFBV0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7UUFtQjdCQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUMzQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsYUFBYUEsQ0FBQ0E7SUFDdENBLENBQUNBO0lBZkRELHNCQUFXQSw2Q0FBYUE7UUFIeEJBOztXQUVHQTthQUNIQTtZQUVDRSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxvQkFBb0JBLENBQUNBLENBQUNBLENBQUNBO2dCQUUvQkEsSUFBSUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtZQUM5QkEsQ0FBQ0E7WUFFREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFFekJBLENBQUNBOzs7T0FBQUY7SUFRREE7Ozs7T0FJR0E7SUFDSUEsbUNBQU1BLEdBQWJBLFVBQWNBLFNBQWdCQTtRQUU3QkcsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsU0FBU0EsQ0FBQ0E7UUFFN0JBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDbENBLENBQUNBO0lBRURIOzs7Ozs7T0FNR0E7SUFDSUEsbUNBQU1BLEdBQWJBLFVBQWNBLElBQVdBO1FBRXhCSSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxJQUFJQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUU1Q0EsTUFBTUEsQ0FBQ0E7UUFFUkEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFFekJBLENBQUNBO0lBRURKOzs7O09BSUdBO0lBQ0lBLGtDQUFLQSxHQUFaQSxVQUFhQSxLQUFZQTtJQUd6QkssQ0FBQ0E7SUFFREw7Ozs7T0FJR0E7SUFDSUEseUNBQVlBLEdBQW5CQSxVQUFvQkEsSUFBV0E7UUFFOUJNLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBRXRDQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLENBQUNBO0lBQ2xDQSxDQUFDQTtJQUVETjs7T0FFR0E7SUFDSUEsa0RBQXFCQSxHQUE1QkE7SUFFQU8sQ0FBQ0E7SUFDRlAseUJBQUNBO0FBQURBLENBekZBLEFBeUZDQSxJQUFBO0FBRUQsQUFBNEIsaUJBQW5CLGtCQUFrQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgSUFuaW1hdGlvblN0YXRlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL0lBbmltYXRpb25TdGF0ZVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblN0YXRlRXZlbnRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9ldmVudHMvQW5pbWF0aW9uU3RhdGVFdmVudFwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBBbmltYXRpb25TdGF0ZUJhc2UgaW1wbGVtZW50cyBJQW5pbWF0aW9uU3RhdGVcbntcblx0cHVibGljIF9wQW5pbWF0aW9uTm9kZTpBbmltYXRpb25Ob2RlQmFzZTtcblx0cHVibGljIF9wUm9vdERlbHRhOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEKCk7XG5cdHB1YmxpYyBfcFBvc2l0aW9uRGVsdGFEaXJ0eTpib29sZWFuID0gdHJ1ZTtcblxuXHRwdWJsaWMgX3BUaW1lOm51bWJlcjtcblx0cHVibGljIF9wU3RhcnRUaW1lOm51bWJlciA9IDA7XG5cdHB1YmxpYyBfcEFuaW1hdG9yOkFuaW1hdG9yQmFzZTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIDNkIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIHRyYW5zbGF0aW9uIGRlbHRhIG9mIHRoZSBhbmltYXRpbmcgZW50aXR5IGZvciB0aGUgY3VycmVudCB0aW1lc3RlcCBvZiBhbmltYXRpb25cblx0ICovXG5cdHB1YmxpYyBnZXQgcG9zaXRpb25EZWx0YSgpOlZlY3RvcjNEXG5cdHtcblx0XHRpZiAodGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSkge1xuXG5cdFx0XHR0aGlzLl9wVXBkYXRlUG9zaXRpb25EZWx0YSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLl9wUm9vdERlbHRhO1xuXG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpBbmltYXRvckJhc2UsIGFuaW1hdGlvbk5vZGU6QW5pbWF0aW9uTm9kZUJhc2UpXG5cdHtcblx0XHR0aGlzLl9wQW5pbWF0b3IgPSBhbmltYXRvcjtcblx0XHR0aGlzLl9wQW5pbWF0aW9uTm9kZSA9IGFuaW1hdGlvbk5vZGU7XG5cdH1cblxuXHQvKipcblx0ICogUmVzZXRzIHRoZSBzdGFydCB0aW1lIG9mIHRoZSBub2RlIHRvIGEgIG5ldyB2YWx1ZS5cblx0ICpcblx0ICogQHBhcmFtIHN0YXJ0VGltZSBUaGUgYWJzb2x1dGUgc3RhcnQgdGltZSAoaW4gbWlsbGlzZWNvbmRzKSBvZiB0aGUgbm9kZSdzIHN0YXJ0aW5nIHRpbWUuXG5cdCAqL1xuXHRwdWJsaWMgb2Zmc2V0KHN0YXJ0VGltZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9wU3RhcnRUaW1lID0gc3RhcnRUaW1lO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgbm9kZSB0byBpdHMgY3VycmVudCBzdGF0ZS5cblx0ICpcblx0ICogQHBhcmFtIHRpbWUgVGhlIGFic29sdXRlIHRpbWUgKGluIG1pbGxpc2Vjb25kcykgb2YgdGhlIGFuaW1hdG9yJ3MgcGxheSBoZWFkIHBvc2l0aW9uLlxuXHQgKlxuXHQgKiBAc2VlIEFuaW1hdG9yQmFzZSN1cGRhdGUoKVxuXHQgKi9cblx0cHVibGljIHVwZGF0ZSh0aW1lOm51bWJlcilcblx0e1xuXHRcdGlmICh0aGlzLl9wVGltZSA9PSB0aW1lIC0gdGhpcy5fcFN0YXJ0VGltZSkge1xuXG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHR0aGlzLl9wVXBkYXRlVGltZSh0aW1lKTtcblxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGFuaW1hdGlvbiBwaGFzZSBvZiB0aGUgbm9kZS5cblx0ICpcblx0ICogQHBhcmFtIHZhbHVlIFRoZSBwaGFzZSB2YWx1ZSB0byB1c2UuIDAgcmVwcmVzZW50cyB0aGUgYmVnaW5uaW5nIG9mIGFuIGFuaW1hdGlvbiBjbGlwLCAxIHJlcHJlc2VudHMgdGhlIGVuZC5cblx0ICovXG5cdHB1YmxpYyBwaGFzZSh2YWx1ZTpudW1iZXIpXG5cdHtcblxuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgdGhlIG5vZGUncyBpbnRlcm5hbCBwbGF5aGVhZCBwb3NpdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHRpbWUgVGhlIGxvY2FsIHRpbWUgKGluIG1pbGxpc2Vjb25kcykgb2YgdGhlIG5vZGUncyBwbGF5aGVhZCBwb3NpdGlvbi5cblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVRpbWUodGltZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9wVGltZSA9IHRpbWUgLSB0aGlzLl9wU3RhcnRUaW1lO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgbm9kZSdzIHJvb3QgZGVsdGEgcG9zaXRpb25cblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVBvc2l0aW9uRGVsdGEoKVxuXHR7XG5cdH1cbn1cblxuZXhwb3J0ID0gQW5pbWF0aW9uU3RhdGVCYXNlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/AnimationStateBase.ts b/lib/animators/states/AnimationStateBase.ts
new file mode 100644
index 000000000..f20f4b0f7
--- /dev/null
+++ b/lib/animators/states/AnimationStateBase.ts
@@ -0,0 +1,103 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import IAnimationState = require("awayjs-stagegl/lib/animators/states/IAnimationState");
+
+import AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+
+/**
+ *
+ */
+class AnimationStateBase implements IAnimationState
+{
+ public _pAnimationNode:AnimationNodeBase;
+ public _pRootDelta:Vector3D = new Vector3D();
+ public _pPositionDeltaDirty:boolean = true;
+
+ public _pTime:number;
+ public _pStartTime:number = 0;
+ public _pAnimator:AnimatorBase;
+
+ /**
+ * Returns a 3d vector representing the translation delta of the animating entity for the current timestep of animation
+ */
+ public get positionDelta():Vector3D
+ {
+ if (this._pPositionDeltaDirty) {
+
+ this._pUpdatePositionDelta();
+ }
+
+ return this._pRootDelta;
+
+ }
+
+ constructor(animator:AnimatorBase, animationNode:AnimationNodeBase)
+ {
+ this._pAnimator = animator;
+ this._pAnimationNode = animationNode;
+ }
+
+ /**
+ * Resets the start time of the node to a new value.
+ *
+ * @param startTime The absolute start time (in milliseconds) of the node's starting time.
+ */
+ public offset(startTime:number)
+ {
+ this._pStartTime = startTime;
+
+ this._pPositionDeltaDirty = true;
+ }
+
+ /**
+ * Updates the configuration of the node to its current state.
+ *
+ * @param time The absolute time (in milliseconds) of the animator's play head position.
+ *
+ * @see AnimatorBase#update()
+ */
+ public update(time:number)
+ {
+ if (this._pTime == time - this._pStartTime) {
+
+ return;
+
+ }
+
+ this._pUpdateTime(time);
+
+ }
+
+ /**
+ * Sets the animation phase of the node.
+ *
+ * @param value The phase value to use. 0 represents the beginning of an animation clip, 1 represents the end.
+ */
+ public phase(value:number)
+ {
+
+ }
+
+ /**
+ * Updates the node's internal playhead position.
+ *
+ * @param time The local time (in milliseconds) of the node's playhead position.
+ */
+ public _pUpdateTime(time:number)
+ {
+ this._pTime = time - this._pStartTime;
+
+ this._pPositionDeltaDirty = true;
+ }
+
+ /**
+ * Updates the node's root delta position
+ */
+ public _pUpdatePositionDelta()
+ {
+ }
+}
+
+export = AnimationStateBase;
\ No newline at end of file
diff --git a/lib/animators/states/ISkeletonAnimationState.js b/lib/animators/states/ISkeletonAnimationState.js
new file mode 100755
index 000000000..62ef01306
--- /dev/null
+++ b/lib/animators/states/ISkeletonAnimationState.js
@@ -0,0 +1,3 @@
+
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvaXNrZWxldG9uYW5pbWF0aW9uc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBYWlDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSUFuaW1hdGlvblN0YXRlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL0lBbmltYXRpb25TdGF0ZVwiKTtcblxuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcblxuaW50ZXJmYWNlIElTa2VsZXRvbkFuaW1hdGlvblN0YXRlIGV4dGVuZHMgSUFuaW1hdGlvblN0YXRlXG57XG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBvdXRwdXQgc2tlbGV0b24gcG9zZSBvZiB0aGUgYW5pbWF0aW9uIG5vZGUuXG5cdCAqL1xuXHRnZXRTa2VsZXRvblBvc2Uoc2tlbGV0b246U2tlbGV0b24pOlNrZWxldG9uUG9zZTtcbn1cblxuZXhwb3J0ID0gSVNrZWxldG9uQW5pbWF0aW9uU3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/ISkeletonAnimationState.ts b/lib/animators/states/ISkeletonAnimationState.ts
new file mode 100644
index 000000000..82040f79e
--- /dev/null
+++ b/lib/animators/states/ISkeletonAnimationState.ts
@@ -0,0 +1,14 @@
+import IAnimationState = require("awayjs-stagegl/lib/animators/states/IAnimationState");
+
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+
+interface ISkeletonAnimationState extends IAnimationState
+{
+ /**
+ * Returns the output skeleton pose of the animation node.
+ */
+ getSkeletonPose(skeleton:Skeleton):SkeletonPose;
+}
+
+export = ISkeletonAnimationState;
\ No newline at end of file
diff --git a/lib/animators/states/IVertexAnimationState.js b/lib/animators/states/IVertexAnimationState.js
new file mode 100755
index 000000000..49d48fa42
--- /dev/null
+++ b/lib/animators/states/IVertexAnimationState.js
@@ -0,0 +1,3 @@
+
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvaXZlcnRleGFuaW1hdGlvbnN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTRCK0IiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9JVmVydGV4QW5pbWF0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgR2VvbWV0cnlcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvR2VvbWV0cnlcIik7XG5cbmltcG9ydCBJQW5pbWF0aW9uU3RhdGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSUFuaW1hdGlvblN0YXRlXCIpO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgYW5pbWF0aW9uIG5vZGUgY2xhc3NlcyB0aGF0IGhvbGQgYW5pbWF0aW9uIGRhdGEgZm9yIHVzZSBpbiB0aGUgVmVydGV4IGFuaW1hdG9yIGNsYXNzLlxuICpcbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuVmVydGV4QW5pbWF0b3JcbiAqL1xuaW50ZXJmYWNlIElWZXJ0ZXhBbmltYXRpb25TdGF0ZSBleHRlbmRzIElBbmltYXRpb25TdGF0ZVxue1xuXHQvKipcblx0ICogUmV0dXJucyB0aGUgY3VycmVudCBnZW9tZXRyeSBmcmFtZSBvZiBhbmltYXRpb24gaW4gdGhlIGNsaXAgYmFzZWQgb24gdGhlIGludGVybmFsIHBsYXloZWFkIHBvc2l0aW9uLlxuXHQgKi9cblx0Y3VycmVudEdlb21ldHJ5Okdlb21ldHJ5OyAvL0dFVFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGdlb21ldHJ5IGZyYW1lIG9mIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRuZXh0R2VvbWV0cnk6R2VvbWV0cnk7IC8vR0VUXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBmcmFjdGlvbmFsIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIGJsZW5kaW5nIHJhdGlvIG9mIHRoZSBjdXJyZW50IHBsYXloZWFkIHBvc2l0aW9uXG5cdCAqIGJldHdlZW4gdGhlIGN1cnJlbnQgZ2VvbWV0cnkgZnJhbWUgKDApIGFuZCBuZXh0IGdlb21ldHJ5IGZyYW1lICgxKSBvZiB0aGUgYW5pbWF0aW9uLlxuXHQgKi9cblx0YmxlbmRXZWlnaHQ6bnVtYmVyOyAvL0dFVFxufVxuXG5leHBvcnQgPSBJVmVydGV4QW5pbWF0aW9uU3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/IVertexAnimationState.ts b/lib/animators/states/IVertexAnimationState.ts
new file mode 100644
index 000000000..d4fa66351
--- /dev/null
+++ b/lib/animators/states/IVertexAnimationState.ts
@@ -0,0 +1,29 @@
+import Geometry = require("awayjs-core/lib/core/base/Geometry");
+
+import IAnimationState = require("awayjs-stagegl/lib/animators/states/IAnimationState");
+
+/**
+ * Provides an interface for animation node classes that hold animation data for use in the Vertex animator class.
+ *
+ * @see away.animators.VertexAnimator
+ */
+interface IVertexAnimationState extends IAnimationState
+{
+ /**
+ * Returns the current geometry frame of animation in the clip based on the internal playhead position.
+ */
+ currentGeometry:Geometry; //GET
+
+ /**
+ * Returns the current geometry frame of animation in the clip based on the internal playhead position.
+ */
+ nextGeometry:Geometry; //GET
+
+ /**
+ * Returns a fractional value between 0 and 1 representing the blending ratio of the current playhead position
+ * between the current geometry frame (0) and next geometry frame (1) of the animation.
+ */
+ blendWeight:number; //GET
+}
+
+export = IVertexAnimationState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleAccelerationState.js b/lib/animators/states/ParticleAccelerationState.js
new file mode 100755
index 000000000..af38bdd47
--- /dev/null
+++ b/lib/animators/states/ParticleAccelerationState.js
@@ -0,0 +1,58 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleAccelerationState = (function (_super) {
+ __extends(ParticleAccelerationState, _super);
+ function ParticleAccelerationState(animator, particleAccelerationNode) {
+ _super.call(this, animator, particleAccelerationNode);
+ this._particleAccelerationNode = particleAccelerationNode;
+ this._acceleration = this._particleAccelerationNode._acceleration;
+ this.updateAccelerationData();
+ }
+ Object.defineProperty(ParticleAccelerationState.prototype, "acceleration", {
+ /**
+ * Defines the acceleration vector of the state, used when in global mode.
+ */
+ get: function () {
+ return this._acceleration;
+ },
+ set: function (value) {
+ this._acceleration.x = value.x;
+ this._acceleration.y = value.y;
+ this._acceleration.z = value.z;
+ this.updateAccelerationData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleAccelerationState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleAccelerationState.ACCELERATION_INDEX);
+ if (this._particleAccelerationNode.mode == ParticlePropertiesMode.LOCAL_STATIC)
+ animationSubGeometry.activateVertexBuffer(index, this._particleAccelerationNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ else
+ animationRegisterCache.setVertexConst(index, this._halfAcceleration.x, this._halfAcceleration.y, this._halfAcceleration.z);
+ };
+ ParticleAccelerationState.prototype.updateAccelerationData = function () {
+ if (this._particleAccelerationNode.mode == ParticlePropertiesMode.GLOBAL)
+ this._halfAcceleration = new Vector3D(this._acceleration.x / 2, this._acceleration.y / 2, this._acceleration.z / 2);
+ };
+ /** @private */
+ ParticleAccelerationState.ACCELERATION_INDEX = 0;
+ return ParticleAccelerationState;
+})(ParticleStateBase);
+module.exports = ParticleAccelerationState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVhY2NlbGVyYXRpb25zdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUFjY2VsZXJhdGlvblN0YXRlIiwiUGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlQWNjZWxlcmF0aW9uU3RhdGUuYWNjZWxlcmF0aW9uIiwiUGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZS5zZXRSZW5kZXJTdGF0ZSIsIlBhcnRpY2xlQWNjZWxlcmF0aW9uU3RhdGUudXBkYXRlQWNjZWxlcmF0aW9uRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFNdEUsSUFBTywyQkFBMkIsV0FBWSw2REFBNkQsQ0FBQyxDQUFDO0FBSTdHLElBQU8sc0JBQXNCLFdBQWEsNkRBQTZELENBQUMsQ0FBQztBQUV6RyxJQUFPLGlCQUFpQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFFbEcsQUFHQTs7R0FERztJQUNHLHlCQUF5QjtJQUFTQSxVQUFsQ0EseUJBQXlCQSxVQUEwQkE7SUEwQnhEQSxTQTFCS0EseUJBQXlCQSxDQTBCbEJBLFFBQXlCQSxFQUFFQSx3QkFBaURBO1FBRXZGQyxrQkFBTUEsUUFBUUEsRUFBRUEsd0JBQXdCQSxDQUFDQSxDQUFDQTtRQUUxQ0EsSUFBSUEsQ0FBQ0EseUJBQXlCQSxHQUFHQSx3QkFBd0JBLENBQUNBO1FBQzFEQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSx5QkFBeUJBLENBQUNBLGFBQWFBLENBQUNBO1FBRWxFQSxJQUFJQSxDQUFDQSxzQkFBc0JBLEVBQUVBLENBQUNBO0lBQy9CQSxDQUFDQTtJQXRCREQsc0JBQVdBLG1EQUFZQTtRQUh2QkE7O1dBRUdBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1FBQzNCQSxDQUFDQTthQUVERixVQUF3QkEsS0FBY0E7WUFFckNFLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1lBQy9CQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMvQkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFL0JBLElBQUlBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7UUFDL0JBLENBQUNBOzs7T0FUQUY7SUFxQkRBOztPQUVHQTtJQUNJQSxrREFBY0EsR0FBckJBLFVBQXNCQSxLQUFXQSxFQUFFQSxVQUF5QkEsRUFBRUEsb0JBQXlDQSxFQUFFQSxzQkFBNkNBLEVBQUVBLE1BQWFBO1FBRXBLRyxJQUFJQSxLQUFLQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLHlCQUF5QkEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxDQUFDQTtRQUV2SUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EseUJBQXlCQSxDQUFDQSxJQUFJQSxJQUFJQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBO1lBQzlFQSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsS0FBS0EsRUFBRUEsSUFBSUEsQ0FBQ0EseUJBQXlCQSxDQUFDQSxZQUFZQSxFQUFFQSxLQUFLQSxFQUFFQSwyQkFBMkJBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBO1FBQzNJQSxJQUFJQTtZQUNIQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO0lBQzdIQSxDQUFDQTtJQUVPSCwwREFBc0JBLEdBQTlCQTtRQUVDSSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSx5QkFBeUJBLENBQUNBLElBQUlBLElBQUlBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7WUFDeEVBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7SUFDaEhBLENBQUNBO0lBbkRESixlQUFlQTtJQUNEQSw0Q0FBa0JBLEdBQWtCQSxDQUFDQSxDQUFDQTtJQW1EckRBLGdDQUFDQTtBQUFEQSxDQXREQSxBQXNEQ0EsRUF0RHVDLGlCQUFpQixFQXNEeEQ7QUFFRCxBQUFtQyxpQkFBMUIseUJBQXlCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZUFjY2VsZXJhdGlvblN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdG9yXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVBY2NlbGVyYXRpb25Ob2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIEFDQ0VMRVJBVElPTl9JTkRFWDpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0cHJpdmF0ZSBfcGFydGljbGVBY2NlbGVyYXRpb25Ob2RlOlBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZTtcblx0cHJpdmF0ZSBfYWNjZWxlcmF0aW9uOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9oYWxmQWNjZWxlcmF0aW9uOlZlY3RvcjNEO1xuXHRcblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIGFjY2VsZXJhdGlvbiB2ZWN0b3Igb2YgdGhlIHN0YXRlLCB1c2VkIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGFjY2VsZXJhdGlvbigpOlZlY3RvcjNEXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYWNjZWxlcmF0aW9uO1xuXHR9XG5cdFxuXHRwdWJsaWMgc2V0IGFjY2VsZXJhdGlvbih2YWx1ZTpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMuX2FjY2VsZXJhdGlvbi54ID0gdmFsdWUueDtcblx0XHR0aGlzLl9hY2NlbGVyYXRpb24ueSA9IHZhbHVlLnk7XG5cdFx0dGhpcy5fYWNjZWxlcmF0aW9uLnogPSB2YWx1ZS56O1xuXG5cdFx0dGhpcy51cGRhdGVBY2NlbGVyYXRpb25EYXRhKCk7XG5cdH1cblx0XG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZTpQYXJ0aWNsZUFjY2VsZXJhdGlvbk5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVBY2NlbGVyYXRpb25Ob2RlKTtcblxuXHRcdHRoaXMuX3BhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZSA9IHBhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZTtcblx0XHR0aGlzLl9hY2NlbGVyYXRpb24gPSB0aGlzLl9wYXJ0aWNsZUFjY2VsZXJhdGlvbk5vZGUuX2FjY2VsZXJhdGlvbjtcblxuXHRcdHRoaXMudXBkYXRlQWNjZWxlcmF0aW9uRGF0YSgpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVBY2NlbGVyYXRpb25TdGF0ZS5BQ0NFTEVSQVRJT05fSU5ERVgpO1xuXHRcdFxuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZUFjY2VsZXJhdGlvbk5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQylcblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZUFjY2VsZXJhdGlvbk5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHRcdGVsc2Vcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoaW5kZXgsIHRoaXMuX2hhbGZBY2NlbGVyYXRpb24ueCwgdGhpcy5faGFsZkFjY2VsZXJhdGlvbi55LCB0aGlzLl9oYWxmQWNjZWxlcmF0aW9uLnopO1xuXHR9XG5cdFxuXHRwcml2YXRlIHVwZGF0ZUFjY2VsZXJhdGlvbkRhdGEoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlQWNjZWxlcmF0aW9uTm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKVxuXHRcdFx0dGhpcy5faGFsZkFjY2VsZXJhdGlvbiA9IG5ldyBWZWN0b3IzRCh0aGlzLl9hY2NlbGVyYXRpb24ueC8yLCB0aGlzLl9hY2NlbGVyYXRpb24ueS8yLCB0aGlzLl9hY2NlbGVyYXRpb24uei8yKTtcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZUFjY2VsZXJhdGlvblN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleAccelerationState.ts b/lib/animators/states/ParticleAccelerationState.ts
new file mode 100644
index 000000000..7a6a22516
--- /dev/null
+++ b/lib/animators/states/ParticleAccelerationState.ts
@@ -0,0 +1,74 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleAccelerationNode = require("awayjs-renderergl/lib/animators/nodes/ParticleAccelerationNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleAccelerationState extends ParticleStateBase
+{
+ /** @private */
+ public static ACCELERATION_INDEX:number /*int*/ = 0;
+
+ private _particleAccelerationNode:ParticleAccelerationNode;
+ private _acceleration:Vector3D;
+ private _halfAcceleration:Vector3D;
+
+ /**
+ * Defines the acceleration vector of the state, used when in global mode.
+ */
+ public get acceleration():Vector3D
+ {
+ return this._acceleration;
+ }
+
+ public set acceleration(value:Vector3D)
+ {
+ this._acceleration.x = value.x;
+ this._acceleration.y = value.y;
+ this._acceleration.z = value.z;
+
+ this.updateAccelerationData();
+ }
+
+ constructor(animator:ParticleAnimator, particleAccelerationNode:ParticleAccelerationNode)
+ {
+ super(animator, particleAccelerationNode);
+
+ this._particleAccelerationNode = particleAccelerationNode;
+ this._acceleration = this._particleAccelerationNode._acceleration;
+
+ this.updateAccelerationData();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleAccelerationState.ACCELERATION_INDEX);
+
+ if (this._particleAccelerationNode.mode == ParticlePropertiesMode.LOCAL_STATIC)
+ animationSubGeometry.activateVertexBuffer(index, this._particleAccelerationNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ else
+ animationRegisterCache.setVertexConst(index, this._halfAcceleration.x, this._halfAcceleration.y, this._halfAcceleration.z);
+ }
+
+ private updateAccelerationData()
+ {
+ if (this._particleAccelerationNode.mode == ParticlePropertiesMode.GLOBAL)
+ this._halfAcceleration = new Vector3D(this._acceleration.x/2, this._acceleration.y/2, this._acceleration.z/2);
+ }
+}
+
+export = ParticleAccelerationState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleBezierCurveState.js b/lib/animators/states/ParticleBezierCurveState.js
new file mode 100755
index 000000000..05490c2c2
--- /dev/null
+++ b/lib/animators/states/ParticleBezierCurveState.js
@@ -0,0 +1,67 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleBezierCurveState = (function (_super) {
+ __extends(ParticleBezierCurveState, _super);
+ function ParticleBezierCurveState(animator, particleBezierCurveNode) {
+ _super.call(this, animator, particleBezierCurveNode);
+ this._particleBezierCurveNode = particleBezierCurveNode;
+ this._controlPoint = this._particleBezierCurveNode._iControlPoint;
+ this._endPoint = this._particleBezierCurveNode._iEndPoint;
+ }
+ Object.defineProperty(ParticleBezierCurveState.prototype, "controlPoint", {
+ /**
+ * Defines the default control point of the node, used when in global mode.
+ */
+ get: function () {
+ return this._controlPoint;
+ },
+ set: function (value) {
+ this._controlPoint = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleBezierCurveState.prototype, "endPoint", {
+ /**
+ * Defines the default end point of the node, used when in global mode.
+ */
+ get: function () {
+ return this._endPoint;
+ },
+ set: function (value) {
+ this._endPoint = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleBezierCurveState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var controlIndex = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBezierCurveState.BEZIER_CONTROL_INDEX);
+ var endIndex = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBezierCurveState.BEZIER_END_INDEX);
+ if (this._particleBezierCurveNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(controlIndex, this._particleBezierCurveNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ animationSubGeometry.activateVertexBuffer(endIndex, this._particleBezierCurveNode._iDataOffset + 3, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ else {
+ animationRegisterCache.setVertexConst(controlIndex, this._controlPoint.x, this._controlPoint.y, this._controlPoint.z);
+ animationRegisterCache.setVertexConst(endIndex, this._endPoint.x, this._endPoint.y, this._endPoint.z);
+ }
+ };
+ /** @private */
+ ParticleBezierCurveState.BEZIER_CONTROL_INDEX = 0;
+ /** @private */
+ ParticleBezierCurveState.BEZIER_END_INDEX = 1;
+ return ParticleBezierCurveState;
+})(ParticleStateBase);
+module.exports = ParticleBezierCurveState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGViZXppZXJjdXJ2ZXN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZSIsIlBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZS5jb250cm9sUG9pbnQiLCJQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUuZW5kUG9pbnQiLCJQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUuc2V0UmVuZGVyU3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQU1BLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQUk3RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFFekcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyx3QkFBd0I7SUFBU0EsVUFBakNBLHdCQUF3QkEsVUFBMEJBO0lBc0N2REEsU0F0Q0tBLHdCQUF3QkEsQ0FzQ2pCQSxRQUF5QkEsRUFBRUEsdUJBQStDQTtRQUVyRkMsa0JBQU1BLFFBQVFBLEVBQUVBLHVCQUF1QkEsQ0FBQ0EsQ0FBQ0E7UUFFekNBLElBQUlBLENBQUNBLHdCQUF3QkEsR0FBR0EsdUJBQXVCQSxDQUFDQTtRQUN4REEsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUNsRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxVQUFVQSxDQUFDQTtJQUMzREEsQ0FBQ0E7SUE5QkRELHNCQUFXQSxrREFBWUE7UUFIdkJBOztXQUVHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUMzQkEsQ0FBQ0E7YUFFREYsVUFBd0JBLEtBQWNBO1lBRXJDRSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUM1QkEsQ0FBQ0E7OztPQUxBRjtJQVVEQSxzQkFBV0EsOENBQVFBO1FBSG5CQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDdkJBLENBQUNBO2FBRURILFVBQW9CQSxLQUFjQTtZQUVqQ0csSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDeEJBLENBQUNBOzs7T0FMQUg7SUFnQk1BLGlEQUFjQSxHQUFyQkEsVUFBc0JBLEtBQVdBLEVBQUVBLFVBQXlCQSxFQUFFQSxvQkFBeUNBLEVBQUVBLHNCQUE2Q0EsRUFBRUEsTUFBYUE7UUFFcEtJLElBQUlBLFlBQVlBLEdBQWtCQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsd0JBQXdCQSxDQUFDQSxvQkFBb0JBLENBQUNBLENBQUNBO1FBQy9JQSxJQUFJQSxRQUFRQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLHdCQUF3QkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxDQUFDQTtRQUV2SUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxJQUFJQSxJQUFJQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBO1lBQy9FQSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsWUFBWUEsRUFBRUEsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxZQUFZQSxFQUFFQSxLQUFLQSxFQUFFQSwyQkFBMkJBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBO1lBQ2hKQSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsUUFBUUEsRUFBRUEsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxZQUFZQSxHQUFHQSxDQUFDQSxFQUFFQSxLQUFLQSxFQUFFQSwyQkFBMkJBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBO1FBQ2pKQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLFlBQVlBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RIQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLFFBQVFBLEVBQUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ3ZHQSxDQUFDQTtJQUNGQSxDQUFDQTtJQXpEREosZUFBZUE7SUFDREEsNkNBQW9CQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFFdERBLGVBQWVBO0lBQ0RBLHlDQUFnQkEsR0FBa0JBLENBQUNBLENBQUNBO0lBc0RuREEsK0JBQUNBO0FBQURBLENBNURBLEFBNERDQSxFQTVEc0MsaUJBQWlCLEVBNER2RDtBQUVELEFBQWtDLGlCQUF6Qix3QkFBd0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZUJlemllckN1cnZlTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVCZXppZXJDdXJ2ZU5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUgZXh0ZW5kcyBQYXJ0aWNsZVN0YXRlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBCRVpJRVJfQ09OVFJPTF9JTkRFWDpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgQkVaSUVSX0VORF9JTkRFWDpudW1iZXIgLyppbnQqLyA9IDE7XG5cblx0cHJpdmF0ZSBfcGFydGljbGVCZXppZXJDdXJ2ZU5vZGU6UGFydGljbGVCZXppZXJDdXJ2ZU5vZGU7XG5cdHByaXZhdGUgX2NvbnRyb2xQb2ludDpWZWN0b3IzRDtcblx0cHJpdmF0ZSBfZW5kUG9pbnQ6VmVjdG9yM0Q7XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIGRlZmF1bHQgY29udHJvbCBwb2ludCBvZiB0aGUgbm9kZSwgdXNlZCB3aGVuIGluIGdsb2JhbCBtb2RlLlxuXHQgKi9cblx0cHVibGljIGdldCBjb250cm9sUG9pbnQoKTpWZWN0b3IzRFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2NvbnRyb2xQb2ludDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgY29udHJvbFBvaW50KHZhbHVlOlZlY3RvcjNEKVxuXHR7XG5cdFx0dGhpcy5fY29udHJvbFBvaW50ID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZGVmYXVsdCBlbmQgcG9pbnQgb2YgdGhlIG5vZGUsIHVzZWQgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgZW5kUG9pbnQoKTpWZWN0b3IzRFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2VuZFBvaW50O1xuXHR9XG5cblx0cHVibGljIHNldCBlbmRQb2ludCh2YWx1ZTpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMuX2VuZFBvaW50ID0gdmFsdWU7XG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpQYXJ0aWNsZUFuaW1hdG9yLCBwYXJ0aWNsZUJlemllckN1cnZlTm9kZTpQYXJ0aWNsZUJlemllckN1cnZlTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZUJlemllckN1cnZlTm9kZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZUJlemllckN1cnZlTm9kZSA9IHBhcnRpY2xlQmV6aWVyQ3VydmVOb2RlO1xuXHRcdHRoaXMuX2NvbnRyb2xQb2ludCA9IHRoaXMuX3BhcnRpY2xlQmV6aWVyQ3VydmVOb2RlLl9pQ29udHJvbFBvaW50O1xuXHRcdHRoaXMuX2VuZFBvaW50ID0gdGhpcy5fcGFydGljbGVCZXppZXJDdXJ2ZU5vZGUuX2lFbmRQb2ludDtcblx0fVxuXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHZhciBjb250cm9sSW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZS5CRVpJRVJfQ09OVFJPTF9JTkRFWCk7XG5cdFx0dmFyIGVuZEluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUJlemllckN1cnZlU3RhdGUuQkVaSUVSX0VORF9JTkRFWCk7XG5cblx0XHRpZiAodGhpcy5fcGFydGljbGVCZXppZXJDdXJ2ZU5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQykge1xuXHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuYWN0aXZhdGVWZXJ0ZXhCdWZmZXIoY29udHJvbEluZGV4LCB0aGlzLl9wYXJ0aWNsZUJlemllckN1cnZlTm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfMyk7XG5cdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihlbmRJbmRleCwgdGhpcy5fcGFydGljbGVCZXppZXJDdXJ2ZU5vZGUuX2lEYXRhT2Zmc2V0ICsgMywgc3RhZ2UsIENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdC5GTE9BVF8zKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChjb250cm9sSW5kZXgsIHRoaXMuX2NvbnRyb2xQb2ludC54LCB0aGlzLl9jb250cm9sUG9pbnQueSwgdGhpcy5fY29udHJvbFBvaW50LnopO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChlbmRJbmRleCwgdGhpcy5fZW5kUG9pbnQueCwgdGhpcy5fZW5kUG9pbnQueSwgdGhpcy5fZW5kUG9pbnQueik7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlQmV6aWVyQ3VydmVTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleBezierCurveState.ts b/lib/animators/states/ParticleBezierCurveState.ts
new file mode 100644
index 000000000..9dbb47880
--- /dev/null
+++ b/lib/animators/states/ParticleBezierCurveState.ts
@@ -0,0 +1,80 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleBezierCurveNode = require("awayjs-renderergl/lib/animators/nodes/ParticleBezierCurveNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleBezierCurveState extends ParticleStateBase
+{
+ /** @private */
+ public static BEZIER_CONTROL_INDEX:number /*int*/ = 0;
+
+ /** @private */
+ public static BEZIER_END_INDEX:number /*int*/ = 1;
+
+ private _particleBezierCurveNode:ParticleBezierCurveNode;
+ private _controlPoint:Vector3D;
+ private _endPoint:Vector3D;
+
+ /**
+ * Defines the default control point of the node, used when in global mode.
+ */
+ public get controlPoint():Vector3D
+ {
+ return this._controlPoint;
+ }
+
+ public set controlPoint(value:Vector3D)
+ {
+ this._controlPoint = value;
+ }
+
+ /**
+ * Defines the default end point of the node, used when in global mode.
+ */
+ public get endPoint():Vector3D
+ {
+ return this._endPoint;
+ }
+
+ public set endPoint(value:Vector3D)
+ {
+ this._endPoint = value;
+ }
+
+ constructor(animator:ParticleAnimator, particleBezierCurveNode:ParticleBezierCurveNode)
+ {
+ super(animator, particleBezierCurveNode);
+
+ this._particleBezierCurveNode = particleBezierCurveNode;
+ this._controlPoint = this._particleBezierCurveNode._iControlPoint;
+ this._endPoint = this._particleBezierCurveNode._iEndPoint;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var controlIndex:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBezierCurveState.BEZIER_CONTROL_INDEX);
+ var endIndex:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBezierCurveState.BEZIER_END_INDEX);
+
+ if (this._particleBezierCurveNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(controlIndex, this._particleBezierCurveNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ animationSubGeometry.activateVertexBuffer(endIndex, this._particleBezierCurveNode._iDataOffset + 3, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ } else {
+ animationRegisterCache.setVertexConst(controlIndex, this._controlPoint.x, this._controlPoint.y, this._controlPoint.z);
+ animationRegisterCache.setVertexConst(endIndex, this._endPoint.x, this._endPoint.y, this._endPoint.z);
+ }
+ }
+}
+
+export = ParticleBezierCurveState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleBillboardState.js b/lib/animators/states/ParticleBillboardState.js
new file mode 100755
index 000000000..58d8af9cc
--- /dev/null
+++ b/lib/animators/states/ParticleBillboardState.js
@@ -0,0 +1,76 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var MathConsts = require("awayjs-core/lib/core/geom/MathConsts");
+var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+var Orientation3D = require("awayjs-core/lib/core/geom/Orientation3D");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleBillboardState = (function (_super) {
+ __extends(ParticleBillboardState, _super);
+ /**
+ *
+ */
+ function ParticleBillboardState(animator, particleNode) {
+ _super.call(this, animator, particleNode);
+ this._matrix = new Matrix3D;
+ this._billboardAxis = particleNode._iBillboardAxis;
+ }
+ ParticleBillboardState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var comps;
+ if (this._billboardAxis) {
+ var pos = renderable.sourceEntity.sceneTransform.position;
+ var look = camera.sceneTransform.position.subtract(pos);
+ var right = look.crossProduct(this._billboardAxis);
+ right.normalize();
+ look = this.billboardAxis.crossProduct(right);
+ look.normalize();
+ //create a quick inverse projection matrix
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ comps = this._matrix.decompose(Orientation3D.AXIS_ANGLE);
+ this._matrix.copyColumnFrom(0, right);
+ this._matrix.copyColumnFrom(1, this.billboardAxis);
+ this._matrix.copyColumnFrom(2, look);
+ this._matrix.copyColumnFrom(3, pos);
+ this._matrix.appendRotation(-comps[1].w * MathConsts.RADIANS_TO_DEGREES, comps[1]);
+ }
+ else {
+ //create a quick inverse projection matrix
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+ //decompose using axis angle rotations
+ comps = this._matrix.decompose(Orientation3D.AXIS_ANGLE);
+ //recreate the matrix with just the rotation data
+ this._matrix.identity();
+ this._matrix.appendRotation(-comps[1].w * MathConsts.RADIANS_TO_DEGREES, comps[1]);
+ }
+ //set a new matrix transform constant
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBillboardState.MATRIX_INDEX), this._matrix);
+ };
+ Object.defineProperty(ParticleBillboardState.prototype, "billboardAxis", {
+ /**
+ * Defines the billboard axis.
+ */
+ get: function () {
+ return this.billboardAxis;
+ },
+ set: function (value) {
+ this.billboardAxis = value ? value.clone() : null;
+ if (this.billboardAxis)
+ this.billboardAxis.normalize();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /** @private */
+ ParticleBillboardState.MATRIX_INDEX = 0;
+ return ParticleBillboardState;
+})(ParticleStateBase);
+module.exports = ParticleBillboardState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGViaWxsYm9hcmRzdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUJpbGxib2FyZFN0YXRlIiwiUGFydGljbGVCaWxsYm9hcmRTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlQmlsbGJvYXJkU3RhdGUuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZUJpbGxib2FyZFN0YXRlLmJpbGxib2FyZEF4aXMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sVUFBVSxXQUFnQixzQ0FBc0MsQ0FBQyxDQUFDO0FBQ3pFLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBRXRFLElBQU8sYUFBYSxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFXOUUsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxzQkFBc0I7SUFBU0EsVUFBL0JBLHNCQUFzQkEsVUFBMEJBO0lBU3JEQTs7T0FFR0E7SUFDSEEsU0FaS0Esc0JBQXNCQSxDQVlmQSxRQUF5QkEsRUFBRUEsWUFBa0NBO1FBRXhFQyxrQkFBTUEsUUFBUUEsRUFBRUEsWUFBWUEsQ0FBQ0EsQ0FBQ0E7UUFUdkJBLFlBQU9BLEdBQVlBLElBQUlBLFFBQVFBLENBQUNBO1FBV3ZDQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxZQUFZQSxDQUFDQSxlQUFlQSxDQUFDQTtJQUNwREEsQ0FBQ0E7SUFFTUQsK0NBQWNBLEdBQXJCQSxVQUFzQkEsS0FBV0EsRUFBRUEsVUFBeUJBLEVBQUVBLG9CQUF5Q0EsRUFBRUEsc0JBQTZDQSxFQUFFQSxNQUFhQTtRQUVwS0UsSUFBSUEsS0FBcUJBLENBQUNBO1FBQzFCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6QkEsSUFBSUEsR0FBR0EsR0FBWUEsVUFBVUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsUUFBUUEsQ0FBQ0E7WUFDbkVBLElBQUlBLElBQUlBLEdBQVlBLE1BQU1BLENBQUNBLGNBQWNBLENBQUNBLFFBQVFBLENBQUNBLFFBQVFBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2pFQSxJQUFJQSxLQUFLQSxHQUFZQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtZQUM1REEsS0FBS0EsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFDbEJBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFlBQVlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1lBQzlDQSxJQUFJQSxDQUFDQSxTQUFTQSxFQUFFQSxDQUFDQTtZQUVqQkEsQUFDQUEsMENBRDBDQTtZQUMxQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7WUFDOURBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBO1lBQ3pEQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUN0Q0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0E7WUFDbkRBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO1lBQ3JDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNwQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsVUFBVUEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNsRkEsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDUEEsQUFDQUEsMENBRDBDQTtZQUMxQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7WUFDOURBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLE1BQU1BLENBQUNBLE1BQU1BLENBQUNBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0E7WUFFbERBLEFBQ0FBLHNDQURzQ0E7WUFDdENBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBO1lBRXpEQSxBQUNBQSxpREFEaURBO1lBQ2pEQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxRQUFRQSxFQUFFQSxDQUFDQTtZQUN4QkEsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsVUFBVUEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNsRkEsQ0FBQ0E7UUFFREEsQUFDQUEscUNBRHFDQTtRQUNyQ0Esc0JBQXNCQSxDQUFDQSx3QkFBd0JBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBO0lBQ25LQSxDQUFDQTtJQUtERixzQkFBV0EsaURBQWFBO1FBSHhCQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7UUFDM0JBLENBQUNBO2FBRURILFVBQXlCQSxLQUFjQTtZQUV0Q0csSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsS0FBS0EsR0FBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDakRBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO2dCQUN0QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0E7UUFDakNBLENBQUNBOzs7T0FQQUg7SUEzRERBLGVBQWVBO0lBQ0RBLG1DQUFZQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFtRS9DQSw2QkFBQ0E7QUFBREEsQ0F0RUEsQUFzRUNBLEVBdEVvQyxpQkFBaUIsRUFzRXJEO0FBRUQsQUFBZ0MsaUJBQXZCLHNCQUFzQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVCaWxsYm9hcmRTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNYXRoQ29uc3RzXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRoQ29uc3RzXCIpO1xuaW1wb3J0IE1hdHJpeDNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeDNEXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IE9yaWVudGF0aW9uM0RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9PcmllbnRhdGlvbjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdG9yXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgUGFydGljbGVCaWxsYm9hcmROb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZUJpbGxib2FyZE5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZUJpbGxib2FyZFN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgTUFUUklYX0lOREVYOm51bWJlciAvKmludCovID0gMDtcblxuXHRwcml2YXRlIF9tYXRyaXg6TWF0cml4M0QgPSBuZXcgTWF0cml4M0Q7XG5cblx0cHJpdmF0ZSBfYmlsbGJvYXJkQXhpczpWZWN0b3IzRDtcblxuXHQvKipcblx0ICpcblx0ICovXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlTm9kZTpQYXJ0aWNsZUJpbGxib2FyZE5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVOb2RlKTtcblxuXHRcdHRoaXMuX2JpbGxib2FyZEF4aXMgPSBwYXJ0aWNsZU5vZGUuX2lCaWxsYm9hcmRBeGlzO1xuXHR9XG5cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0dmFyIGNvbXBzOkFycmF5PFZlY3RvcjNEPjtcblx0XHRpZiAodGhpcy5fYmlsbGJvYXJkQXhpcykge1xuXHRcdFx0dmFyIHBvczpWZWN0b3IzRCA9IHJlbmRlcmFibGUuc291cmNlRW50aXR5LnNjZW5lVHJhbnNmb3JtLnBvc2l0aW9uO1xuXHRcdFx0dmFyIGxvb2s6VmVjdG9yM0QgPSBjYW1lcmEuc2NlbmVUcmFuc2Zvcm0ucG9zaXRpb24uc3VidHJhY3QocG9zKTtcblx0XHRcdHZhciByaWdodDpWZWN0b3IzRCA9IGxvb2suY3Jvc3NQcm9kdWN0KHRoaXMuX2JpbGxib2FyZEF4aXMpO1xuXHRcdFx0cmlnaHQubm9ybWFsaXplKCk7XG5cdFx0XHRsb29rID0gdGhpcy5iaWxsYm9hcmRBeGlzLmNyb3NzUHJvZHVjdChyaWdodCk7XG5cdFx0XHRsb29rLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHQvL2NyZWF0ZSBhIHF1aWNrIGludmVyc2UgcHJvamVjdGlvbiBtYXRyaXhcblx0XHRcdHRoaXMuX21hdHJpeC5jb3B5RnJvbShyZW5kZXJhYmxlLnNvdXJjZUVudGl0eS5zY2VuZVRyYW5zZm9ybSk7XG5cdFx0XHRjb21wcyA9IHRoaXMuX21hdHJpeC5kZWNvbXBvc2UoT3JpZW50YXRpb24zRC5BWElTX0FOR0xFKTtcblx0XHRcdHRoaXMuX21hdHJpeC5jb3B5Q29sdW1uRnJvbSgwLCByaWdodCk7XG5cdFx0XHR0aGlzLl9tYXRyaXguY29weUNvbHVtbkZyb20oMSwgdGhpcy5iaWxsYm9hcmRBeGlzKTtcblx0XHRcdHRoaXMuX21hdHJpeC5jb3B5Q29sdW1uRnJvbSgyLCBsb29rKTtcblx0XHRcdHRoaXMuX21hdHJpeC5jb3B5Q29sdW1uRnJvbSgzLCBwb3MpO1xuXHRcdFx0dGhpcy5fbWF0cml4LmFwcGVuZFJvdGF0aW9uKC1jb21wc1sxXS53Kk1hdGhDb25zdHMuUkFESUFOU19UT19ERUdSRUVTLCBjb21wc1sxXSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vY3JlYXRlIGEgcXVpY2sgaW52ZXJzZSBwcm9qZWN0aW9uIG1hdHJpeFxuXHRcdFx0dGhpcy5fbWF0cml4LmNvcHlGcm9tKHJlbmRlcmFibGUuc291cmNlRW50aXR5LnNjZW5lVHJhbnNmb3JtKTtcblx0XHRcdHRoaXMuX21hdHJpeC5hcHBlbmQoY2FtZXJhLmludmVyc2VTY2VuZVRyYW5zZm9ybSk7XG5cblx0XHRcdC8vZGVjb21wb3NlIHVzaW5nIGF4aXMgYW5nbGUgcm90YXRpb25zXG5cdFx0XHRjb21wcyA9IHRoaXMuX21hdHJpeC5kZWNvbXBvc2UoT3JpZW50YXRpb24zRC5BWElTX0FOR0xFKTtcblxuXHRcdFx0Ly9yZWNyZWF0ZSB0aGUgbWF0cml4IHdpdGgganVzdCB0aGUgcm90YXRpb24gZGF0YVxuXHRcdFx0dGhpcy5fbWF0cml4LmlkZW50aXR5KCk7XG5cdFx0XHR0aGlzLl9tYXRyaXguYXBwZW5kUm90YXRpb24oLWNvbXBzWzFdLncqTWF0aENvbnN0cy5SQURJQU5TX1RPX0RFR1JFRVMsIGNvbXBzWzFdKTtcblx0XHR9XG5cblx0XHQvL3NldCBhIG5ldyBtYXRyaXggdHJhbnNmb3JtIGNvbnN0YW50XG5cdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdEZyb21NYXRyaXgoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUJpbGxib2FyZFN0YXRlLk1BVFJJWF9JTkRFWCksIHRoaXMuX21hdHJpeCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgYmlsbGJvYXJkIGF4aXMuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGJpbGxib2FyZEF4aXMoKTpWZWN0b3IzRFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuYmlsbGJvYXJkQXhpcztcblx0fVxuXG5cdHB1YmxpYyBzZXQgYmlsbGJvYXJkQXhpcyh2YWx1ZTpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMuYmlsbGJvYXJkQXhpcyA9IHZhbHVlPyB2YWx1ZS5jbG9uZSgpIDogbnVsbDtcblx0XHRpZiAodGhpcy5iaWxsYm9hcmRBeGlzKVxuXHRcdFx0dGhpcy5iaWxsYm9hcmRBeGlzLm5vcm1hbGl6ZSgpO1xuXHR9XG5cbn1cblxuZXhwb3J0ID0gUGFydGljbGVCaWxsYm9hcmRTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleBillboardState.ts b/lib/animators/states/ParticleBillboardState.ts
new file mode 100644
index 000000000..12532272f
--- /dev/null
+++ b/lib/animators/states/ParticleBillboardState.ts
@@ -0,0 +1,92 @@
+import MathConsts = require("awayjs-core/lib/core/geom/MathConsts");
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Orientation3D = require("awayjs-core/lib/core/geom/Orientation3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleBillboardNode = require("awayjs-renderergl/lib/animators/nodes/ParticleBillboardNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleBillboardState extends ParticleStateBase
+{
+ /** @private */
+ public static MATRIX_INDEX:number /*int*/ = 0;
+
+ private _matrix:Matrix3D = new Matrix3D;
+
+ private _billboardAxis:Vector3D;
+
+ /**
+ *
+ */
+ constructor(animator:ParticleAnimator, particleNode:ParticleBillboardNode)
+ {
+ super(animator, particleNode);
+
+ this._billboardAxis = particleNode._iBillboardAxis;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var comps:Array;
+ if (this._billboardAxis) {
+ var pos:Vector3D = renderable.sourceEntity.sceneTransform.position;
+ var look:Vector3D = camera.sceneTransform.position.subtract(pos);
+ var right:Vector3D = look.crossProduct(this._billboardAxis);
+ right.normalize();
+ look = this.billboardAxis.crossProduct(right);
+ look.normalize();
+
+ //create a quick inverse projection matrix
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ comps = this._matrix.decompose(Orientation3D.AXIS_ANGLE);
+ this._matrix.copyColumnFrom(0, right);
+ this._matrix.copyColumnFrom(1, this.billboardAxis);
+ this._matrix.copyColumnFrom(2, look);
+ this._matrix.copyColumnFrom(3, pos);
+ this._matrix.appendRotation(-comps[1].w*MathConsts.RADIANS_TO_DEGREES, comps[1]);
+ } else {
+ //create a quick inverse projection matrix
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+
+ //decompose using axis angle rotations
+ comps = this._matrix.decompose(Orientation3D.AXIS_ANGLE);
+
+ //recreate the matrix with just the rotation data
+ this._matrix.identity();
+ this._matrix.appendRotation(-comps[1].w*MathConsts.RADIANS_TO_DEGREES, comps[1]);
+ }
+
+ //set a new matrix transform constant
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleBillboardState.MATRIX_INDEX), this._matrix);
+ }
+
+ /**
+ * Defines the billboard axis.
+ */
+ public get billboardAxis():Vector3D
+ {
+ return this.billboardAxis;
+ }
+
+ public set billboardAxis(value:Vector3D)
+ {
+ this.billboardAxis = value? value.clone() : null;
+ if (this.billboardAxis)
+ this.billboardAxis.normalize();
+ }
+
+}
+
+export = ParticleBillboardState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleColorState.js b/lib/animators/states/ParticleColorState.js
new file mode 100755
index 000000000..ca0e7cac3
--- /dev/null
+++ b/lib/animators/states/ParticleColorState.js
@@ -0,0 +1,160 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ * @author ...
+ */
+var ParticleColorState = (function (_super) {
+ __extends(ParticleColorState, _super);
+ function ParticleColorState(animator, particleColorNode) {
+ _super.call(this, animator, particleColorNode);
+ this._particleColorNode = particleColorNode;
+ this._usesMultiplier = this._particleColorNode._iUsesMultiplier;
+ this._usesOffset = this._particleColorNode._iUsesOffset;
+ this._usesCycle = this._particleColorNode._iUsesCycle;
+ this._usesPhase = this._particleColorNode._iUsesPhase;
+ this._startColor = this._particleColorNode._iStartColor;
+ this._endColor = this._particleColorNode._iEndColor;
+ this._cycleDuration = this._particleColorNode._iCycleDuration;
+ this._cyclePhase = this._particleColorNode._iCyclePhase;
+ this.updateColorData();
+ }
+ Object.defineProperty(ParticleColorState.prototype, "startColor", {
+ /**
+ * Defines the start color transform of the state, when in global mode.
+ */
+ get: function () {
+ return this._startColor;
+ },
+ set: function (value) {
+ this._startColor = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleColorState.prototype, "endColor", {
+ /**
+ * Defines the end color transform of the state, when in global mode.
+ */
+ get: function () {
+ return this._endColor;
+ },
+ set: function (value) {
+ this._endColor = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleColorState.prototype, "cycleDuration", {
+ /**
+ * Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._cycleDuration;
+ },
+ set: function (value) {
+ this._cycleDuration = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleColorState.prototype, "cyclePhase", {
+ /**
+ * Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ get: function () {
+ return this._cyclePhase;
+ },
+ set: function (value) {
+ this._cyclePhase = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleColorState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (animationRegisterCache.needFragmentAnimation) {
+ var dataOffset = this._particleColorNode._iDataOffset;
+ if (this._usesCycle)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.CYCLE_INDEX), this._cycleData.x, this._cycleData.y, this._cycleData.z, this._cycleData.w);
+ if (this._usesMultiplier) {
+ if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ }
+ else {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), this._startMultiplierData.x, this._startMultiplierData.y, this._startMultiplierData.z, this._startMultiplierData.w);
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), this._deltaMultiplierData.x, this._deltaMultiplierData.y, this._deltaMultiplierData.z, this._deltaMultiplierData.w);
+ }
+ }
+ if (this._usesOffset) {
+ if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ }
+ else {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), this._startOffsetData.x, this._startOffsetData.y, this._startOffsetData.z, this._startOffsetData.w);
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), this._deltaOffsetData.x, this._deltaOffsetData.y, this._deltaOffsetData.z, this._deltaOffsetData.w);
+ }
+ }
+ }
+ };
+ ParticleColorState.prototype.updateColorData = function () {
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._cycleData = new Vector3D(Math.PI * 2 / this._cycleDuration, this._cyclePhase * Math.PI / 180, 0, 0);
+ }
+ if (this._particleColorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesCycle) {
+ if (this._usesMultiplier) {
+ this._startMultiplierData = new Vector3D((this._startColor.redMultiplier + this._endColor.redMultiplier) / 2, (this._startColor.greenMultiplier + this._endColor.greenMultiplier) / 2, (this._startColor.blueMultiplier + this._endColor.blueMultiplier) / 2, (this._startColor.alphaMultiplier + this._endColor.alphaMultiplier) / 2);
+ this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier) / 2, (this._endColor.greenMultiplier - this._startColor.greenMultiplier) / 2, (this._endColor.blueMultiplier - this._startColor.blueMultiplier) / 2, (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier) / 2);
+ }
+ if (this._usesOffset) {
+ this._startOffsetData = new Vector3D((this._startColor.redOffset + this._endColor.redOffset) / (255 * 2), (this._startColor.greenOffset + this._endColor.greenOffset) / (255 * 2), (this._startColor.blueOffset + this._endColor.blueOffset) / (255 * 2), (this._startColor.alphaOffset + this._endColor.alphaOffset) / (255 * 2));
+ this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset) / (255 * 2), (this._endColor.greenOffset - this._startColor.greenOffset) / (255 * 2), (this._endColor.blueOffset - this._startColor.blueOffset) / (255 * 2), (this._endColor.alphaOffset - this._startColor.alphaOffset) / (255 * 2));
+ }
+ }
+ else {
+ if (this._usesMultiplier) {
+ this._startMultiplierData = new Vector3D(this._startColor.redMultiplier, this._startColor.greenMultiplier, this._startColor.blueMultiplier, this._startColor.alphaMultiplier);
+ this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier), (this._endColor.greenMultiplier - this._startColor.greenMultiplier), (this._endColor.blueMultiplier - this._startColor.blueMultiplier), (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier));
+ }
+ if (this._usesOffset) {
+ this._startOffsetData = new Vector3D(this._startColor.redOffset / 255, this._startColor.greenOffset / 255, this._startColor.blueOffset / 255, this._startColor.alphaOffset / 255);
+ this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset) / 255, (this._endColor.greenOffset - this._startColor.greenOffset) / 255, (this._endColor.blueOffset - this._startColor.blueOffset) / 255, (this._endColor.alphaOffset - this._startColor.alphaOffset) / 255);
+ }
+ }
+ }
+ };
+ /** @private */
+ ParticleColorState.START_MULTIPLIER_INDEX = 0;
+ /** @private */
+ ParticleColorState.DELTA_MULTIPLIER_INDEX = 1;
+ /** @private */
+ ParticleColorState.START_OFFSET_INDEX = 2;
+ /** @private */
+ ParticleColorState.DELTA_OFFSET_INDEX = 3;
+ /** @private */
+ ParticleColorState.CYCLE_INDEX = 4;
+ return ParticleColorState;
+})(ParticleStateBase);
+module.exports = ParticleColorState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVjb2xvcnN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlQ29sb3JTdGF0ZSIsIlBhcnRpY2xlQ29sb3JTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlQ29sb3JTdGF0ZS5zdGFydENvbG9yIiwiUGFydGljbGVDb2xvclN0YXRlLmVuZENvbG9yIiwiUGFydGljbGVDb2xvclN0YXRlLmN5Y2xlRHVyYXRpb24iLCJQYXJ0aWNsZUNvbG9yU3RhdGUuY3ljbGVQaGFzZSIsIlBhcnRpY2xlQ29sb3JTdGF0ZS5zZXRSZW5kZXJTdGF0ZSIsIlBhcnRpY2xlQ29sb3JTdGF0ZS51cGRhdGVDb2xvckRhdGEiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBTXRFLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQUk3RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFFekcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBSUE7OztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTBCQTtJQTRGakRBLFNBNUZLQSxrQkFBa0JBLENBNEZYQSxRQUF5QkEsRUFBRUEsaUJBQW1DQTtRQUV6RUMsa0JBQU1BLFFBQVFBLEVBQUVBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0E7UUFFbkNBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsaUJBQWlCQSxDQUFDQTtRQUM1Q0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1FBQ2hFQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLFlBQVlBLENBQUNBO1FBQ3hEQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JB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Q0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2hVQSxDQUFDQTtnQkFFREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3RCQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLElBQUlBLFFBQVFBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFVBQVVBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUNuVEEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxTQUFTQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxVQUFVQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDcFRBLENBQUNBO1lBQ0ZBLENBQUNBO1lBQUNBLElBQUlBLENBQUNBLENBQUNBO2dCQUNQQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMUJBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7b0JBQzlLQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLFFBQVFBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGFBQWFBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGVBQWVBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGNBQWNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4VEEsQ0FBQ0E7Z0JBRURBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO29CQUN0QkEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxTQUFTQSxHQUFDQSxHQUFHQSxFQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxHQUFDQSxHQUFHQSxFQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxVQUFVQSxHQUFDQSxHQUFHQSxFQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxHQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDMUtBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsVUFBVUEsQ0FBRUEsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JTQSxDQUFDQTtZQUNGQSxDQUFDQTtRQUNGQSxDQUFDQTtJQUNGQSxDQUFDQTtJQXpLRFAsZUFBZUE7SUFDREEseUNBQXNCQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUFFekRBLGVBQWVBO0lBQ0RBLHlDQUFzQkEsR0FBbUJBLENBQUNBLENBQUNBO0lBRXpEQSxlQUFlQTtJQUNEQSxxQ0FBa0JBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUVyREEsZUFBZUE7SUFDREEscUNBQWtCQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUFFckRBLGVBQWVBO0lBQ0RBLDhCQUFXQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUE2Si9DQSx5QkFBQ0E7QUFBREEsQ0E1S0EsQUE0S0NBLEVBNUtnQyxpQkFBaUIsRUE0S2pEO0FBRUQsQUFBNEIsaUJBQW5CLGtCQUFrQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVDb2xvclN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbG9yVHJhbnNmb3JtXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vQ29sb3JUcmFuc2Zvcm1cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVDb2xvck5vZGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVDb2xvck5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICogQGF1dGhvciAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVDb2xvclN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgU1RBUlRfTVVMVElQTElFUl9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIERFTFRBX01VTFRJUExJRVJfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBTVEFSVF9PRkZTRVRfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMjtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBERUxUQV9PRkZTRVRfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMztcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBDWUNMRV9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSA0O1xuXG5cdHByaXZhdGUgX3BhcnRpY2xlQ29sb3JOb2RlOlBhcnRpY2xlQ29sb3JOb2RlO1xuXHRwcml2YXRlIF91c2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzT2Zmc2V0OmJvb2xlYW47XG5cdHByaXZhdGUgX3VzZXNDeWNsZTpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzUGhhc2U6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfc3RhcnRDb2xvcjpDb2xvclRyYW5zZm9ybTtcblx0cHJpdmF0ZSBfZW5kQ29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdHByaXZhdGUgX2N5Y2xlRHVyYXRpb246bnVtYmVyO1xuXHRwcml2YXRlIF9jeWNsZVBoYXNlOm51bWJlcjtcblx0cHJpdmF0ZSBfY3ljbGVEYXRhOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9zdGFydE11bHRpcGxpZXJEYXRhOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9kZWx0YU11bHRpcGxpZXJEYXRhOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9zdGFydE9mZnNldERhdGE6VmVjdG9yM0Q7XG5cdHByaXZhdGUgX2RlbHRhT2Zmc2V0RGF0YTpWZWN0b3IzRDtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgc3RhcnQgY29sb3IgdHJhbnNmb3JtIG9mIHRoZSBzdGF0ZSwgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgc3RhcnRDb2xvcigpOkNvbG9yVHJhbnNmb3JtXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc3RhcnRDb2xvcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgc3RhcnRDb2xvcih2YWx1ZTpDb2xvclRyYW5zZm9ybSlcblx0e1xuXHRcdHRoaXMuX3N0YXJ0Q29sb3IgPSB2YWx1ZTtcblxuXHRcdHRoaXMudXBkYXRlQ29sb3JEYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZW5kIGNvbG9yIHRyYW5zZm9ybSBvZiB0aGUgc3RhdGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVuZENvbG9yKCk6Q29sb3JUcmFuc2Zvcm1cblx0e1xuXHRcdHJldHVybiB0aGlzLl9lbmRDb2xvcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgZW5kQ29sb3IodmFsdWU6Q29sb3JUcmFuc2Zvcm0pXG5cdHtcblx0XHR0aGlzLl9lbmRDb2xvciA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVDb2xvckRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluIHNlY29uZHMsIHVzZWQgYXMgYSBwZXJpb2QgaW5kZXBlbmRlbnQgb2YgcGFydGljbGUgZHVyYXRpb24gd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMS5cblx0ICovXG5cdHB1YmxpYyBnZXQgY3ljbGVEdXJhdGlvbigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N5Y2xlRHVyYXRpb247XG5cdH1cblxuXHRwdWJsaWMgc2V0IGN5Y2xlRHVyYXRpb24odmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fY3ljbGVEdXJhdGlvbiA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVDb2xvckRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBwaGFzZSBvZiB0aGUgY3ljbGUgaW4gZGVncmVlcywgdXNlZCBhcyB0aGUgc3RhcnRpbmcgb2Zmc2V0IG9mIHRoZSBjeWNsZSB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAwLlxuXHQgKi9cblx0cHVibGljIGdldCBjeWNsZVBoYXNlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY3ljbGVQaGFzZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgY3ljbGVQaGFzZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9jeWNsZVBoYXNlID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZUNvbG9yRGF0YSgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVDb2xvck5vZGU6UGFydGljbGVDb2xvck5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVDb2xvck5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVDb2xvck5vZGUgPSBwYXJ0aWNsZUNvbG9yTm9kZTtcblx0XHR0aGlzLl91c2VzTXVsdGlwbGllciA9IHRoaXMuX3BhcnRpY2xlQ29sb3JOb2RlLl9pVXNlc011bHRpcGxpZXI7XG5cdFx0dGhpcy5fdXNlc09mZnNldCA9IHRoaXMuX3BhcnRpY2xlQ29sb3JOb2RlLl9pVXNlc09mZnNldDtcblx0XHR0aGlzLl91c2VzQ3ljbGUgPSB0aGlzLl9wYXJ0aWNsZUNvbG9yTm9kZS5faVVzZXNDeWNsZTtcblx0XHR0aGlzLl91c2VzUGhhc2UgPSB0aGlzLl9wYXJ0aWNsZUNvbG9yTm9kZS5faVVzZXNQaGFzZTtcblx0XHR0aGlzLl9zdGFydENvbG9yID0gdGhpcy5fcGFydGljbGVDb2xvck5vZGUuX2lTdGFydENvbG9yO1xuXHRcdHRoaXMuX2VuZENvbG9yID0gdGhpcy5fcGFydGljbGVDb2xvck5vZGUuX2lFbmRDb2xvcjtcblx0XHR0aGlzLl9jeWNsZUR1cmF0aW9uID0gdGhpcy5fcGFydGljbGVDb2xvck5vZGUuX2lDeWNsZUR1cmF0aW9uO1xuXHRcdHRoaXMuX2N5Y2xlUGhhc2UgPSB0aGlzLl9wYXJ0aWNsZUNvbG9yTm9kZS5faUN5Y2xlUGhhc2U7XG5cblx0XHR0aGlzLnVwZGF0ZUNvbG9yRGF0YSgpO1xuXHR9XG5cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZEZyYWdtZW50QW5pbWF0aW9uKSB7XG5cdFx0XHR2YXIgZGF0YU9mZnNldDpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wYXJ0aWNsZUNvbG9yTm9kZS5faURhdGFPZmZzZXQ7XG5cdFx0XHRpZiAodGhpcy5fdXNlc0N5Y2xlKVxuXHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVDb2xvclN0YXRlLkNZQ0xFX0lOREVYKSwgdGhpcy5fY3ljbGVEYXRhLngsIHRoaXMuX2N5Y2xlRGF0YS55LCB0aGlzLl9jeWNsZURhdGEueiwgdGhpcy5fY3ljbGVEYXRhLncpO1xuXG5cdFx0XHRpZiAodGhpcy5fdXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0aWYgKHRoaXMuX3BhcnRpY2xlQ29sb3JOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpIHtcblx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlQ29sb3JTdGF0ZS5TVEFSVF9NVUxUSVBMSUVSX0lOREVYKSwgZGF0YU9mZnNldCwgc3RhZ2UsIENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdC5GTE9BVF80KTtcblx0XHRcdFx0XHRkYXRhT2Zmc2V0ICs9IDQ7XG5cdFx0XHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuYWN0aXZhdGVWZXJ0ZXhCdWZmZXIoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUNvbG9yU3RhdGUuREVMVEFfTVVMVElQTElFUl9JTkRFWCksIGRhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfNCk7XG5cdFx0XHRcdFx0ZGF0YU9mZnNldCArPSA0O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUNvbG9yU3RhdGUuU1RBUlRfTVVMVElQTElFUl9JTkRFWCksIHRoaXMuX3N0YXJ0TXVsdGlwbGllckRhdGEueCwgdGhpcy5fc3RhcnRNdWx0aXBsaWVyRGF0YS55LCB0aGlzLl9zdGFydE11bHRpcGxpZXJEYXRhLnosIHRoaXMuX3N0YXJ0TXVsdGlwbGllckRhdGEudyk7XG5cdFx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlQ29sb3JTdGF0ZS5ERUxUQV9NVUxUSVBMSUVSX0lOREVYKSwgdGhpcy5fZGVsdGFNdWx0aXBsaWVyRGF0YS54LCB0aGlzLl9kZWx0YU11bHRpcGxpZXJEYXRhLnksIHRoaXMuX2RlbHRhTXVsdGlwbGllckRhdGEueiwgdGhpcy5fZGVsdGFNdWx0aXBsaWVyRGF0YS53KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuX3VzZXNPZmZzZXQpIHtcblx0XHRcdFx0aWYgKHRoaXMuX3BhcnRpY2xlQ29sb3JOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpIHtcblx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlQ29sb3JTdGF0ZS5TVEFSVF9PRkZTRVRfSU5ERVgpLCBkYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzQpO1xuXHRcdFx0XHRcdGRhdGFPZmZzZXQgKz0gNDtcblx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlQ29sb3JTdGF0ZS5ERUxUQV9PRkZTRVRfSU5ERVgpLCBkYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzQpO1xuXHRcdFx0XHRcdGRhdGFPZmZzZXQgKz0gNDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVDb2xvclN0YXRlLlNUQVJUX09GRlNFVF9JTkRFWCksIHRoaXMuX3N0YXJ0T2Zmc2V0RGF0YS54LCB0aGlzLl9zdGFydE9mZnNldERhdGEueSwgdGhpcy5fc3RhcnRPZmZzZXREYXRhLnosIHRoaXMuX3N0YXJ0T2Zmc2V0RGF0YS53KTtcblx0XHRcdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVDb2xvclN0YXRlLkRFTFRBX09GRlNFVF9JTkRFWCksIHRoaXMuX2RlbHRhT2Zmc2V0RGF0YS54LCB0aGlzLl9kZWx0YU9mZnNldERhdGEueSwgdGhpcy5fZGVsdGFPZmZzZXREYXRhLnosIHRoaXMuX2RlbHRhT2Zmc2V0RGF0YS53KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgdXBkYXRlQ29sb3JEYXRhKClcblx0e1xuXHRcdGlmICh0aGlzLl91c2VzQ3ljbGUpIHtcblx0XHRcdGlmICh0aGlzLl9jeWNsZUR1cmF0aW9uIDw9IDApXG5cdFx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHRcdHRoaXMuX2N5Y2xlRGF0YSA9IG5ldyBWZWN0b3IzRChNYXRoLlBJKjIvdGhpcy5fY3ljbGVEdXJhdGlvbiwgdGhpcy5fY3ljbGVQaGFzZSpNYXRoLlBJLzE4MCwgMCwgMCk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZUNvbG9yTm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKSB7XG5cdFx0XHRpZiAodGhpcy5fdXNlc0N5Y2xlKSB7XG5cdFx0XHRcdGlmICh0aGlzLl91c2VzTXVsdGlwbGllcikge1xuXHRcdFx0XHRcdHRoaXMuX3N0YXJ0TXVsdGlwbGllckRhdGEgPSBuZXcgVmVjdG9yM0QoKHRoaXMuX3N0YXJ0Q29sb3IucmVkTXVsdGlwbGllciArIHRoaXMuX2VuZENvbG9yLnJlZE11bHRpcGxpZXIpLzIsICh0aGlzLl9zdGFydENvbG9yLmdyZWVuTXVsdGlwbGllciArIHRoaXMuX2VuZENvbG9yLmdyZWVuTXVsdGlwbGllcikvMiwgKHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIgKyB0aGlzLl9lbmRDb2xvci5ibHVlTXVsdGlwbGllcikvMiwgKHRoaXMuX3N0YXJ0Q29sb3IuYWxwaGFNdWx0aXBsaWVyICsgdGhpcy5fZW5kQ29sb3IuYWxwaGFNdWx0aXBsaWVyKS8yKTtcblx0XHRcdFx0XHR0aGlzLl9kZWx0YU11bHRpcGxpZXJEYXRhID0gbmV3IFZlY3RvcjNEKCh0aGlzLl9lbmRDb2xvci5yZWRNdWx0aXBsaWVyIC0gdGhpcy5fc3RhcnRDb2xvci5yZWRNdWx0aXBsaWVyKS8yLCAodGhpcy5fZW5kQ29sb3IuZ3JlZW5NdWx0aXBsaWVyIC0gdGhpcy5fc3RhcnRDb2xvci5ncmVlbk11bHRpcGxpZXIpLzIsICh0aGlzLl9lbmRDb2xvci5ibHVlTXVsdGlwbGllciAtIHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIpLzIsICh0aGlzLl9lbmRDb2xvci5hbHBoYU11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmFscGhhTXVsdGlwbGllcikvMik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodGhpcy5fdXNlc09mZnNldCkge1xuXHRcdFx0XHRcdHRoaXMuX3N0YXJ0T2Zmc2V0RGF0YSA9IG5ldyBWZWN0b3IzRCgodGhpcy5fc3RhcnRDb2xvci5yZWRPZmZzZXQgKyB0aGlzLl9lbmRDb2xvci5yZWRPZmZzZXQpLygyNTUqMiksICh0aGlzLl9zdGFydENvbG9yLmdyZWVuT2Zmc2V0ICsgdGhpcy5fZW5kQ29sb3IuZ3JlZW5PZmZzZXQpLygyNTUqMiksICh0aGlzLl9zdGFydENvbG9yLmJsdWVPZmZzZXQgKyB0aGlzLl9lbmRDb2xvci5ibHVlT2Zmc2V0KS8oMjU1KjIpLCAodGhpcy5fc3RhcnRDb2xvci5hbHBoYU9mZnNldCArIHRoaXMuX2VuZENvbG9yLmFscGhhT2Zmc2V0KS8oMjU1KjIpKTtcblx0XHRcdFx0XHR0aGlzLl9kZWx0YU9mZnNldERhdGEgPSBuZXcgVmVjdG9yM0QoKHRoaXMuX2VuZENvbG9yLnJlZE9mZnNldCAtIHRoaXMuX3N0YXJ0Q29sb3IucmVkT2Zmc2V0KS8oMjU1KjIpLCAodGhpcy5fZW5kQ29sb3IuZ3JlZW5PZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLmdyZWVuT2Zmc2V0KS8oMjU1KjIpLCAodGhpcy5fZW5kQ29sb3IuYmx1ZU9mZnNldCAtIHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU9mZnNldCkvKDI1NSoyKSwgKHRoaXMuX2VuZENvbG9yLmFscGhhT2Zmc2V0IC0gdGhpcy5fc3RhcnRDb2xvci5hbHBoYU9mZnNldCkvKDI1NSoyKSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICh0aGlzLl91c2VzTXVsdGlwbGllcikge1xuXHRcdFx0XHRcdHRoaXMuX3N0YXJ0TXVsdGlwbGllckRhdGEgPSBuZXcgVmVjdG9yM0QodGhpcy5fc3RhcnRDb2xvci5yZWRNdWx0aXBsaWVyLCB0aGlzLl9zdGFydENvbG9yLmdyZWVuTXVsdGlwbGllciwgdGhpcy5fc3RhcnRDb2xvci5ibHVlTXVsdGlwbGllciwgdGhpcy5fc3RhcnRDb2xvci5hbHBoYU11bHRpcGxpZXIpO1xuXHRcdFx0XHRcdHRoaXMuX2RlbHRhTXVsdGlwbGllckRhdGEgPSBuZXcgVmVjdG9yM0QoKHRoaXMuX2VuZENvbG9yLnJlZE11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLnJlZE11bHRpcGxpZXIpLCAodGhpcy5fZW5kQ29sb3IuZ3JlZW5NdWx0aXBsaWVyIC0gdGhpcy5fc3RhcnRDb2xvci5ncmVlbk11bHRpcGxpZXIpLCAodGhpcy5fZW5kQ29sb3IuYmx1ZU11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmJsdWVNdWx0aXBsaWVyKSwgKHRoaXMuX2VuZENvbG9yLmFscGhhTXVsdGlwbGllciAtIHRoaXMuX3N0YXJ0Q29sb3IuYWxwaGFNdWx0aXBsaWVyKSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodGhpcy5fdXNlc09mZnNldCkge1xuXHRcdFx0XHRcdHRoaXMuX3N0YXJ0T2Zmc2V0RGF0YSA9IG5ldyBWZWN0b3IzRCh0aGlzLl9zdGFydENvbG9yLnJlZE9mZnNldC8yNTUsIHRoaXMuX3N0YXJ0Q29sb3IuZ3JlZW5PZmZzZXQvMjU1LCB0aGlzLl9zdGFydENvbG9yLmJsdWVPZmZzZXQvMjU1LCB0aGlzLl9zdGFydENvbG9yLmFscGhhT2Zmc2V0LzI1NSk7XG5cdFx0XHRcdFx0dGhpcy5fZGVsdGFPZmZzZXREYXRhID0gbmV3IFZlY3RvcjNEKCh0aGlzLl9lbmRDb2xvci5yZWRPZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLnJlZE9mZnNldCkvMjU1LCAodGhpcy5fZW5kQ29sb3IuZ3JlZW5PZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLmdyZWVuT2Zmc2V0KS8yNTUsICh0aGlzLl9lbmRDb2xvci5ibHVlT2Zmc2V0IC0gdGhpcy5fc3RhcnRDb2xvci5ibHVlT2Zmc2V0ICkvMjU1LCAodGhpcy5fZW5kQ29sb3IuYWxwaGFPZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLmFscGhhT2Zmc2V0KS8yNTUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlQ29sb3JTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleColorState.ts b/lib/animators/states/ParticleColorState.ts
new file mode 100644
index 000000000..6e9fc2110
--- /dev/null
+++ b/lib/animators/states/ParticleColorState.ts
@@ -0,0 +1,194 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleColorNode = require("awayjs-renderergl/lib/animators/nodes/ParticleColorNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ * @author ...
+ */
+class ParticleColorState extends ParticleStateBase
+{
+ /** @private */
+ public static START_MULTIPLIER_INDEX:number /*uint*/ = 0;
+
+ /** @private */
+ public static DELTA_MULTIPLIER_INDEX:number /*uint*/ = 1;
+
+ /** @private */
+ public static START_OFFSET_INDEX:number /*uint*/ = 2;
+
+ /** @private */
+ public static DELTA_OFFSET_INDEX:number /*uint*/ = 3;
+
+ /** @private */
+ public static CYCLE_INDEX:number /*uint*/ = 4;
+
+ private _particleColorNode:ParticleColorNode;
+ private _usesMultiplier:boolean;
+ private _usesOffset:boolean;
+ private _usesCycle:boolean;
+ private _usesPhase:boolean;
+ private _startColor:ColorTransform;
+ private _endColor:ColorTransform;
+ private _cycleDuration:number;
+ private _cyclePhase:number;
+ private _cycleData:Vector3D;
+ private _startMultiplierData:Vector3D;
+ private _deltaMultiplierData:Vector3D;
+ private _startOffsetData:Vector3D;
+ private _deltaOffsetData:Vector3D;
+
+ /**
+ * Defines the start color transform of the state, when in global mode.
+ */
+ public get startColor():ColorTransform
+ {
+ return this._startColor;
+ }
+
+ public set startColor(value:ColorTransform)
+ {
+ this._startColor = value;
+
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the end color transform of the state, when in global mode.
+ */
+ public get endColor():ColorTransform
+ {
+ return this._endColor;
+ }
+
+ public set endColor(value:ColorTransform)
+ {
+ this._endColor = value;
+
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ public get cycleDuration():number
+ {
+ return this._cycleDuration;
+ }
+
+ public set cycleDuration(value:number)
+ {
+ this._cycleDuration = value;
+
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ public get cyclePhase():number
+ {
+ return this._cyclePhase;
+ }
+
+ public set cyclePhase(value:number)
+ {
+ this._cyclePhase = value;
+
+ this.updateColorData();
+ }
+
+ constructor(animator:ParticleAnimator, particleColorNode:ParticleColorNode)
+ {
+ super(animator, particleColorNode);
+
+ this._particleColorNode = particleColorNode;
+ this._usesMultiplier = this._particleColorNode._iUsesMultiplier;
+ this._usesOffset = this._particleColorNode._iUsesOffset;
+ this._usesCycle = this._particleColorNode._iUsesCycle;
+ this._usesPhase = this._particleColorNode._iUsesPhase;
+ this._startColor = this._particleColorNode._iStartColor;
+ this._endColor = this._particleColorNode._iEndColor;
+ this._cycleDuration = this._particleColorNode._iCycleDuration;
+ this._cyclePhase = this._particleColorNode._iCyclePhase;
+
+ this.updateColorData();
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (animationRegisterCache.needFragmentAnimation) {
+ var dataOffset:number /*uint*/ = this._particleColorNode._iDataOffset;
+ if (this._usesCycle)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.CYCLE_INDEX), this._cycleData.x, this._cycleData.y, this._cycleData.z, this._cycleData.w);
+
+ if (this._usesMultiplier) {
+ if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ } else {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), this._startMultiplierData.x, this._startMultiplierData.y, this._startMultiplierData.z, this._startMultiplierData.w);
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), this._deltaMultiplierData.x, this._deltaMultiplierData.y, this._deltaMultiplierData.z, this._deltaMultiplierData.w);
+ }
+ }
+ if (this._usesOffset) {
+ if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ } else {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), this._startOffsetData.x, this._startOffsetData.y, this._startOffsetData.z, this._startOffsetData.w);
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), this._deltaOffsetData.x, this._deltaOffsetData.y, this._deltaOffsetData.z, this._deltaOffsetData.w);
+ }
+ }
+ }
+ }
+
+ private updateColorData()
+ {
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._cycleData = new Vector3D(Math.PI*2/this._cycleDuration, this._cyclePhase*Math.PI/180, 0, 0);
+ }
+ if (this._particleColorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesCycle) {
+ if (this._usesMultiplier) {
+ this._startMultiplierData = new Vector3D((this._startColor.redMultiplier + this._endColor.redMultiplier)/2, (this._startColor.greenMultiplier + this._endColor.greenMultiplier)/2, (this._startColor.blueMultiplier + this._endColor.blueMultiplier)/2, (this._startColor.alphaMultiplier + this._endColor.alphaMultiplier)/2);
+ this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier)/2, (this._endColor.greenMultiplier - this._startColor.greenMultiplier)/2, (this._endColor.blueMultiplier - this._startColor.blueMultiplier)/2, (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier)/2);
+ }
+
+ if (this._usesOffset) {
+ this._startOffsetData = new Vector3D((this._startColor.redOffset + this._endColor.redOffset)/(255*2), (this._startColor.greenOffset + this._endColor.greenOffset)/(255*2), (this._startColor.blueOffset + this._endColor.blueOffset)/(255*2), (this._startColor.alphaOffset + this._endColor.alphaOffset)/(255*2));
+ this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset)/(255*2), (this._endColor.greenOffset - this._startColor.greenOffset)/(255*2), (this._endColor.blueOffset - this._startColor.blueOffset)/(255*2), (this._endColor.alphaOffset - this._startColor.alphaOffset)/(255*2));
+ }
+ } else {
+ if (this._usesMultiplier) {
+ this._startMultiplierData = new Vector3D(this._startColor.redMultiplier, this._startColor.greenMultiplier, this._startColor.blueMultiplier, this._startColor.alphaMultiplier);
+ this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier), (this._endColor.greenMultiplier - this._startColor.greenMultiplier), (this._endColor.blueMultiplier - this._startColor.blueMultiplier), (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier));
+ }
+
+ if (this._usesOffset) {
+ this._startOffsetData = new Vector3D(this._startColor.redOffset/255, this._startColor.greenOffset/255, this._startColor.blueOffset/255, this._startColor.alphaOffset/255);
+ this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset)/255, (this._endColor.greenOffset - this._startColor.greenOffset)/255, (this._endColor.blueOffset - this._startColor.blueOffset )/255, (this._endColor.alphaOffset - this._startColor.alphaOffset)/255);
+ }
+ }
+ }
+ }
+}
+
+export = ParticleColorState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleFollowState.js b/lib/animators/states/ParticleFollowState.js
new file mode 100755
index 000000000..239e227f8
--- /dev/null
+++ b/lib/animators/states/ParticleFollowState.js
@@ -0,0 +1,219 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var MathConsts = require("awayjs-core/lib/core/geom/MathConsts");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleFollowState = (function (_super) {
+ __extends(ParticleFollowState, _super);
+ function ParticleFollowState(animator, particleFollowNode) {
+ _super.call(this, animator, particleFollowNode, true);
+ this._targetPos = new Vector3D();
+ this._targetEuler = new Vector3D();
+ //temporary vector3D for calculation
+ this._temp = new Vector3D();
+ this._particleFollowNode = particleFollowNode;
+ this._smooth = particleFollowNode._iSmooth;
+ }
+ Object.defineProperty(ParticleFollowState.prototype, "followTarget", {
+ get: function () {
+ return this._followTarget;
+ },
+ set: function (value) {
+ this._followTarget = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleFollowState.prototype, "smooth", {
+ get: function () {
+ return this._smooth;
+ },
+ set: function (value) {
+ this._smooth = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleFollowState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (this._followTarget) {
+ if (this._particleFollowNode._iUsesPosition) {
+ this._targetPos.x = this._followTarget.transform.position.x / renderable.sourceEntity.scaleX;
+ this._targetPos.y = this._followTarget.transform.position.y / renderable.sourceEntity.scaleY;
+ this._targetPos.z = this._followTarget.transform.position.z / renderable.sourceEntity.scaleZ;
+ }
+ if (this._particleFollowNode._iUsesRotation) {
+ this._targetEuler.x = this._followTarget.rotationX;
+ this._targetEuler.y = this._followTarget.rotationY;
+ this._targetEuler.z = this._followTarget.rotationZ;
+ this._targetEuler.scaleBy(MathConsts.DEGREES_TO_RADIANS);
+ }
+ }
+ //initialization
+ if (!this._prePos)
+ this._prePos = this._targetPos.clone();
+ if (!this._preEuler)
+ this._preEuler = this._targetEuler.clone();
+ var currentTime = this._pTime / 1000;
+ var previousTime = animationSubGeometry.previousTime;
+ var deltaTime = currentTime - previousTime;
+ var needProcess = previousTime != currentTime;
+ if (this._particleFollowNode._iUsesPosition && this._particleFollowNode._iUsesRotation) {
+ if (needProcess)
+ this.processPositionAndRotation(currentTime, deltaTime, animationSubGeometry);
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset + 3, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ else if (this._particleFollowNode._iUsesPosition) {
+ if (needProcess)
+ this.processPosition(currentTime, deltaTime, animationSubGeometry);
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ else if (this._particleFollowNode._iUsesRotation) {
+ if (needProcess)
+ this.precessRotation(currentTime, deltaTime, animationSubGeometry);
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ this._prePos.copyFrom(this._targetPos);
+ this._targetEuler.copyFrom(this._targetEuler);
+ animationSubGeometry.previousTime = currentTime;
+ };
+ ParticleFollowState.prototype.processPosition = function (currentTime, deltaTime, animationSubGeometry) {
+ var data = animationSubGeometry.animationParticles;
+ var vertexData = animationSubGeometry.vertexData;
+ var changed = false;
+ var len = data.length;
+ var interpolatedPos;
+ var posVelocity;
+ if (this._smooth) {
+ posVelocity = this._prePos.subtract(this._targetPos);
+ posVelocity.scaleBy(1 / deltaTime);
+ }
+ else
+ interpolatedPos = this._targetPos;
+ for (var i = 0; i < len; i++) {
+ var k = (currentTime - data[i].startTime) / data[i].totalTime;
+ var t = (k - Math.floor(k)) * data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc = data[i].startVertexIndex * animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+ if (this._smooth) {
+ this._temp.copyFrom(posVelocity);
+ this._temp.scaleBy(t);
+ interpolatedPos = this._targetPos.add(this._temp);
+ }
+ if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z) {
+ changed = true;
+ for (var j = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedPos.x;
+ vertexData[inc++] = interpolatedPos.y;
+ vertexData[inc++] = interpolatedPos.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+ };
+ ParticleFollowState.prototype.precessRotation = function (currentTime, deltaTime, animationSubGeometry) {
+ var data = animationSubGeometry.animationParticles;
+ var vertexData = animationSubGeometry.vertexData;
+ var changed = false;
+ var len = data.length;
+ var interpolatedRotation;
+ var rotationVelocity;
+ if (this._smooth) {
+ rotationVelocity = this._preEuler.subtract(this._targetEuler);
+ rotationVelocity.scaleBy(1 / deltaTime);
+ }
+ else
+ interpolatedRotation = this._targetEuler;
+ for (var i = 0; i < len; i++) {
+ var k = (currentTime - data[i].startTime) / data[i].totalTime;
+ var t = (k - Math.floor(k)) * data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc = data[i].startVertexIndex * animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+ if (this._smooth) {
+ this._temp.copyFrom(rotationVelocity);
+ this._temp.scaleBy(t);
+ interpolatedRotation = this._targetEuler.add(this._temp);
+ }
+ if (vertexData[inc] != interpolatedRotation.x || vertexData[inc + 1] != interpolatedRotation.y || vertexData[inc + 2] != interpolatedRotation.z) {
+ changed = true;
+ for (var j = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedRotation.x;
+ vertexData[inc++] = interpolatedRotation.y;
+ vertexData[inc++] = interpolatedRotation.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+ };
+ ParticleFollowState.prototype.processPositionAndRotation = function (currentTime, deltaTime, animationSubGeometry) {
+ var data = animationSubGeometry.animationParticles;
+ var vertexData = animationSubGeometry.vertexData;
+ var changed = false;
+ var len = data.length;
+ var interpolatedPos;
+ var interpolatedRotation;
+ var posVelocity;
+ var rotationVelocity;
+ if (this._smooth) {
+ posVelocity = this._prePos.subtract(this._targetPos);
+ posVelocity.scaleBy(1 / deltaTime);
+ rotationVelocity = this._preEuler.subtract(this._targetEuler);
+ rotationVelocity.scaleBy(1 / deltaTime);
+ }
+ else {
+ interpolatedPos = this._targetPos;
+ interpolatedRotation = this._targetEuler;
+ }
+ for (var i = 0; i < len; i++) {
+ var k = (currentTime - data[i].startTime) / data[i].totalTime;
+ var t = (k - Math.floor(k)) * data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc = data[i].startVertexIndex * animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+ if (this._smooth) {
+ this._temp.copyFrom(posVelocity);
+ this._temp.scaleBy(t);
+ interpolatedPos = this._targetPos.add(this._temp);
+ this._temp.copyFrom(rotationVelocity);
+ this._temp.scaleBy(t);
+ interpolatedRotation = this._targetEuler.add(this._temp);
+ }
+ if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z || vertexData[inc + 3] != interpolatedRotation.x || vertexData[inc + 4] != interpolatedRotation.y || vertexData[inc + 5] != interpolatedRotation.z) {
+ changed = true;
+ for (var j = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedPos.x;
+ vertexData[inc++] = interpolatedPos.y;
+ vertexData[inc++] = interpolatedPos.z;
+ vertexData[inc++] = interpolatedRotation.x;
+ vertexData[inc++] = interpolatedRotation.y;
+ vertexData[inc++] = interpolatedRotation.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+ };
+ /** @private */
+ ParticleFollowState.FOLLOW_POSITION_INDEX = 0;
+ /** @private */
+ ParticleFollowState.FOLLOW_ROTATION_INDEX = 1;
+ return ParticleFollowState;
+})(ParticleStateBase);
+module.exports = ParticleFollowState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVmb2xsb3dzdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUZvbGxvd1N0YXRlIiwiUGFydGljbGVGb2xsb3dTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlRm9sbG93U3RhdGUuZm9sbG93VGFyZ2V0IiwiUGFydGljbGVGb2xsb3dTdGF0ZS5zbW9vdGgiLCJQYXJ0aWNsZUZvbGxvd1N0YXRlLnNldFJlbmRlclN0YXRlIiwiUGFydGljbGVGb2xsb3dTdGF0ZS5wcm9jZXNzUG9zaXRpb24iLCJQYXJ0aWNsZUZvbGxvd1N0YXRlLnByZWNlc3NSb3RhdGlvbiIsIlBhcnRpY2xlRm9sbG93U3RhdGUucHJvY2Vzc1Bvc2l0aW9uQW5kUm90YXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLElBQU8sVUFBVSxXQUFnQixzQ0FBc0MsQ0FBQyxDQUFDO0FBQ3pFLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBTXRFLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQU03RyxJQUFPLGlCQUFpQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFFbEcsQUFHQTs7R0FERztJQUNHLG1CQUFtQjtJQUFTQSxVQUE1QkEsbUJBQW1CQSxVQUEwQkE7SUFvQmxEQSxTQXBCS0EsbUJBQW1CQSxDQW9CWkEsUUFBeUJBLEVBQUVBLGtCQUFxQ0E7UUFFM0VDLGtCQUFNQSxRQUFRQSxFQUFFQSxrQkFBa0JBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO1FBWG5DQSxlQUFVQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtRQUNyQ0EsaUJBQVlBLEdBQVlBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1FBSy9DQSxvQ0FBb0NBO1FBQzVCQSxVQUFLQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtRQU12Q0EsSUFBSUEsQ0FBQ0EsbUJBQW1CQSxHQUFHQSxrQkFBa0JBLENBQUNBO1FBQzlDQSxJ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QkEsb0JBQW9CQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxHQUFHQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtnQkFDMURBLENBQUNBO2dCQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxVQUFVQSxDQUFDQSxHQUFHQSxDQUFDQSxJQUFJQSxlQUFlQSxDQUFDQSxDQUFDQSxJQUFJQSxVQUFVQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxJQUFJQSxlQUFlQSxDQUFDQSxDQUFDQSxJQUFJQSxVQUFVQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxJQUFJQSxlQUFlQSxDQUFDQSxDQUFDQSxJQUFJQSxVQUFVQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxJQUFJQSxvQkFBb0JBLENBQUNBLENBQUNBLElBQUlBLFVBQVVBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLElBQUlBLG9CQUFvQkEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsVUFBVUEsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsb0JBQW9CQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDclJBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBO29CQUNmQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFtQkEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsV0FBV0EsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7d0JBQzlEQSxVQUFVQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQTt3QkFDdENBLFVBQVVBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLGVBQWVBLENBQUNBLENBQUNBLENBQUNBO3dCQUN0Q0EsVUFBVUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7d0JBQ3RDQSxVQUFVQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxvQkFBb0JBLENBQUNBLENBQUNBLENBQUNBO3dCQUMzQ0EsVUFBVUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0Esb0JBQW9CQSxDQUFDQSxDQUFDQSxDQUFDQTt3QkFDM0NBLFVBQVVBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLG9CQUFvQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzVDQSxDQUFDQTtnQkFDRkEsQ0FBQ0E7WUFDRkEsQ0FBQ0E7UUFDRkEsQ0FBQ0E7UUFDREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsT0FBT0EsQ0FBQ0E7WUFDWEEsb0JBQW9CQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLENBQUNBO0lBQzFDQSxDQUFDQTtJQTdPRFAsZUFBZUE7SUFDREEseUNBQXFCQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUFFeERBLGVBQWVBO0lBQ0RBLHlDQUFxQkEsR0FBbUJBLENBQUNBLENBQUNBO0lBMk96REEsMEJBQUNBO0FBQURBLENBalBBLEFBaVBDQSxFQWpQaUMsaUJBQWlCLEVBaVBsRDtBQUVELEFBQTZCLGlCQUFwQixtQkFBbUIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlRm9sbG93U3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGlzcGxheU9iamVjdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0Rpc3BsYXlPYmplY3RcIik7XG5pbXBvcnQgTWF0aENvbnN0c1x0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0aENvbnN0c1wiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlQW5pbWF0aW9uRGF0YVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZUFuaW1hdGlvbkRhdGFcIik7XG5pbXBvcnQgUGFydGljbGVGb2xsb3dOb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlRm9sbG93Tm9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVTdGF0ZUJhc2VcIik7XG5cbi8qKlxuICogLi4uXG4gKi9cbmNsYXNzIFBhcnRpY2xlRm9sbG93U3RhdGUgZXh0ZW5kcyBQYXJ0aWNsZVN0YXRlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBGT0xMT1dfUE9TSVRJT05fSU5ERVg6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBGT0xMT1dfUk9UQVRJT05fSU5ERVg6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHRwcml2YXRlIF9wYXJ0aWNsZUZvbGxvd05vZGU6UGFydGljbGVGb2xsb3dOb2RlO1xuXHRwcml2YXRlIF9mb2xsb3dUYXJnZXQ6RGlzcGxheU9iamVjdDtcblxuXHRwcml2YXRlIF90YXJnZXRQb3M6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0cHJpdmF0ZSBfdGFyZ2V0RXVsZXI6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0cHJpdmF0ZSBfcHJlUG9zOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9wcmVFdWxlcjpWZWN0b3IzRDtcblx0cHJpdmF0ZSBfc21vb3RoOmJvb2xlYW47XG5cblx0Ly90ZW1wb3JhcnkgdmVjdG9yM0QgZm9yIGNhbGN1bGF0aW9uXG5cdHByaXZhdGUgX3RlbXA6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpQYXJ0aWNsZUFuaW1hdG9yLCBwYXJ0aWNsZUZvbGxvd05vZGU6UGFydGljbGVGb2xsb3dOb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHBhcnRpY2xlRm9sbG93Tm9kZSwgdHJ1ZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZUZvbGxvd05vZGUgPSBwYXJ0aWNsZUZvbGxvd05vZGU7XG5cdFx0dGhpcy5fc21vb3RoID0gcGFydGljbGVGb2xsb3dOb2RlLl9pU21vb3RoO1xuXHR9XG5cblx0cHVibGljIGdldCBmb2xsb3dUYXJnZXQoKTpEaXNwbGF5T2JqZWN0XG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZm9sbG93VGFyZ2V0O1xuXHR9XG5cblx0cHVibGljIHNldCBmb2xsb3dUYXJnZXQodmFsdWU6RGlzcGxheU9iamVjdClcblx0e1xuXHRcdHRoaXMuX2ZvbGxvd1RhcmdldCA9IHZhbHVlO1xuXHR9XG5cblx0cHVibGljIGdldCBzbW9vdGgoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc21vb3RoO1xuXHR9XG5cblx0cHVibGljIHNldCBzbW9vdGgodmFsdWU6Ym9vbGVhbilcblx0e1xuXHRcdHRoaXMuX3Ntb290aCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgc2V0UmVuZGVyU3RhdGUoc3RhZ2U6U3RhZ2UsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5LCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHRpZiAodGhpcy5fZm9sbG93VGFyZ2V0KSB7XG5cdFx0XHRpZiAodGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pVXNlc1Bvc2l0aW9uKSB7XG5cdFx0XHRcdHRoaXMuX3RhcmdldFBvcy54ID0gdGhpcy5fZm9sbG93VGFyZ2V0LnRyYW5zZm9ybS5wb3NpdGlvbi54L3JlbmRlcmFibGUuc291cmNlRW50aXR5LnNjYWxlWDtcblx0XHRcdFx0dGhpcy5fdGFyZ2V0UG9zLnkgPSB0aGlzLl9mb2xsb3dUYXJnZXQudHJhbnNmb3JtLnBvc2l0aW9uLnkvcmVuZGVyYWJsZS5zb3VyY2VFbnRpdHkuc2NhbGVZO1xuXHRcdFx0XHR0aGlzLl90YXJnZXRQb3MueiA9IHRoaXMuX2ZvbGxvd1RhcmdldC50cmFuc2Zvcm0ucG9zaXRpb24uei9yZW5kZXJhYmxlLnNvdXJjZUVudGl0eS5zY2FsZVo7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pVXNlc1JvdGF0aW9uKSB7XG5cdFx0XHRcdHRoaXMuX3RhcmdldEV1bGVyLnggPSB0aGlzLl9mb2xsb3dUYXJnZXQucm90YXRpb25YO1xuXHRcdFx0XHR0aGlzLl90YXJnZXRFdWxlci55ID0gdGhpcy5fZm9sbG93VGFyZ2V0LnJvdGF0aW9uWTtcblx0XHRcdFx0dGhpcy5fdGFyZ2V0RXVsZXIueiA9IHRoaXMuX2ZvbGxvd1RhcmdldC5yb3RhdGlvblo7XG5cdFx0XHRcdHRoaXMuX3RhcmdldEV1bGVyLnNjYWxlQnkoTWF0aENvbnN0cy5ERUdSRUVTX1RPX1JBRElBTlMpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHQvL2luaXRpYWxpemF0aW9uXG5cdFx0aWYgKCF0aGlzLl9wcmVQb3MpXG5cdFx0XHR0aGlzLl9wcmVQb3MgPSB0aGlzLl90YXJnZXRQb3MuY2xvbmUoKTtcblx0XHRpZiAoIXRoaXMuX3ByZUV1bGVyKVxuXHRcdFx0dGhpcy5fcHJlRXVsZXIgPSB0aGlzLl90YXJnZXRFdWxlci5jbG9uZSgpO1xuXG5cdFx0dmFyIGN1cnJlbnRUaW1lOm51bWJlciA9IHRoaXMuX3BUaW1lLzEwMDA7XG5cdFx0dmFyIHByZXZpb3VzVGltZTpudW1iZXIgPSBhbmltYXRpb25TdWJHZW9tZXRyeS5wcmV2aW91c1RpbWU7XG5cdFx0dmFyIGRlbHRhVGltZTpudW1iZXIgPSBjdXJyZW50VGltZSAtIHByZXZpb3VzVGltZTtcblxuXHRcdHZhciBuZWVkUHJvY2Vzczpib29sZWFuID0gcHJldmlvdXNUaW1lICE9IGN1cnJlbnRUaW1lO1xuXG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlRm9sbG93Tm9kZS5faVVzZXNQb3NpdGlvbiAmJiB0aGlzLl9wYXJ0aWNsZUZvbGxvd05vZGUuX2lVc2VzUm90YXRpb24pIHtcblx0XHRcdGlmIChuZWVkUHJvY2Vzcylcblx0XHRcdFx0dGhpcy5wcm9jZXNzUG9zaXRpb25BbmRSb3RhdGlvbihjdXJyZW50VGltZSwgZGVsdGFUaW1lLCBhbmltYXRpb25TdWJHZW9tZXRyeSk7XG5cblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVGb2xsb3dTdGF0ZS5GT0xMT1dfUE9TSVRJT05fSU5ERVgpLCB0aGlzLl9wYXJ0aWNsZUZvbGxvd05vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuYWN0aXZhdGVWZXJ0ZXhCdWZmZXIoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUZvbGxvd1N0YXRlLkZPTExPV19ST1RBVElPTl9JTkRFWCksIHRoaXMuX3BhcnRpY2xlRm9sbG93Tm9kZS5faURhdGFPZmZzZXQgKyAzLCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pVXNlc1Bvc2l0aW9uKSB7XG5cdFx0XHRpZiAobmVlZFByb2Nlc3MpXG5cdFx0XHRcdHRoaXMucHJvY2Vzc1Bvc2l0aW9uKGN1cnJlbnRUaW1lLCBkZWx0YVRpbWUsIGFuaW1hdGlvblN1Ykdlb21ldHJ5KTtcblxuXHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuYWN0aXZhdGVWZXJ0ZXhCdWZmZXIoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUZvbGxvd1N0YXRlLkZPTExPV19QT1NJVElPTl9JTkRFWCksIHRoaXMuX3BhcnRpY2xlRm9sbG93Tm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfMyk7XG5cdFx0fSBlbHNlIGlmICh0aGlzLl9wYXJ0aWNsZUZvbGxvd05vZGUuX2lVc2VzUm90YXRpb24pIHtcblx0XHRcdGlmIChuZWVkUHJvY2Vzcylcblx0XHRcdFx0dGhpcy5wcmVjZXNzUm90YXRpb24oY3VycmVudFRpbWUsIGRlbHRhVGltZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnkpO1xuXG5cdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlRm9sbG93U3RhdGUuRk9MTE9XX1JPVEFUSU9OX0lOREVYKSwgdGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pRGF0YU9mZnNldCwgc3RhZ2UsIENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdC5GTE9BVF8zKTtcblx0XHR9XG5cblx0XHR0aGlzLl9wcmVQb3MuY29weUZyb20odGhpcy5fdGFyZ2V0UG9zKTtcblx0XHR0aGlzLl90YXJnZXRFdWxlci5jb3B5RnJvbSh0aGlzLl90YXJnZXRFdWxlcik7XG5cdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkucHJldmlvdXNUaW1lID0gY3VycmVudFRpbWU7XG5cdH1cblxuXHRwcml2YXRlIHByb2Nlc3NQb3NpdGlvbihjdXJyZW50VGltZTpudW1iZXIsIGRlbHRhVGltZTpudW1iZXIsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5KVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8UGFydGljbGVBbmltYXRpb25EYXRhPiA9IGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFuaW1hdGlvblBhcnRpY2xlcztcblx0XHR2YXIgdmVydGV4RGF0YTpBcnJheTxudW1iZXI+ID0gYW5pbWF0aW9uU3ViR2VvbWV0cnkudmVydGV4RGF0YTtcblxuXHRcdHZhciBjaGFuZ2VkOmJvb2xlYW4gPSBmYWxzZTtcblx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLyA9IGRhdGEubGVuZ3RoO1xuXHRcdHZhciBpbnRlcnBvbGF0ZWRQb3M6VmVjdG9yM0Q7XG5cdFx0dmFyIHBvc1ZlbG9jaXR5OlZlY3RvcjNEO1xuXHRcdGlmICh0aGlzLl9zbW9vdGgpIHtcblx0XHRcdHBvc1ZlbG9jaXR5ID0gdGhpcy5fcHJlUG9zLnN1YnRyYWN0KHRoaXMuX3RhcmdldFBvcyk7XG5cdFx0XHRwb3NWZWxvY2l0eS5zY2FsZUJ5KDEvZGVsdGFUaW1lKTtcblx0XHR9IGVsc2Vcblx0XHRcdGludGVycG9sYXRlZFBvcyA9IHRoaXMuX3RhcmdldFBvcztcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKnVpbnQqLyA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0dmFyIGs6bnVtYmVyID0gKGN1cnJlbnRUaW1lIC0gZGF0YVtpXS5zdGFydFRpbWUpL2RhdGFbaV0udG90YWxUaW1lO1xuXHRcdFx0dmFyIHQ6bnVtYmVyID0gKGsgLSBNYXRoLmZsb29yKGspKSpkYXRhW2ldLnRvdGFsVGltZTtcblx0XHRcdGlmICh0IC0gZGVsdGFUaW1lIDw9IDApIHtcblx0XHRcdFx0dmFyIGluYzpudW1iZXIgLyppbnQqLyA9IGRhdGFbaV0uc3RhcnRWZXJ0ZXhJbmRleCphbmltYXRpb25TdWJHZW9tZXRyeS50b3RhbExlbk9mT25lVmVydGV4ICsgdGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pRGF0YU9mZnNldDtcblxuXHRcdFx0XHRpZiAodGhpcy5fc21vb3RoKSB7XG5cdFx0XHRcdFx0dGhpcy5fdGVtcC5jb3B5RnJvbShwb3NWZWxvY2l0eSk7XG5cdFx0XHRcdFx0dGhpcy5fdGVtcC5zY2FsZUJ5KHQpO1xuXHRcdFx0XHRcdGludGVycG9sYXRlZFBvcyA9IHRoaXMuX3RhcmdldFBvcy5hZGQodGhpcy5fdGVtcCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodmVydGV4RGF0YVtpbmNdICE9IGludGVycG9sYXRlZFBvcy54IHx8IHZlcnRleERhdGFbaW5jICsgMV0gIT0gaW50ZXJwb2xhdGVkUG9zLnkgfHwgdmVydGV4RGF0YVtpbmMgKyAyXSAhPSBpbnRlcnBvbGF0ZWRQb3Mueikge1xuXHRcdFx0XHRcdGNoYW5nZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGZvciAodmFyIGo6bnVtYmVyIC8qdWludCovID0gMDsgaiA8IGRhdGFbaV0ubnVtVmVydGljZXM7IGorKykge1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVtpbmMrK10gPSBpbnRlcnBvbGF0ZWRQb3MueDtcblx0XHRcdFx0XHRcdHZlcnRleERhdGFbaW5jKytdID0gaW50ZXJwb2xhdGVkUG9zLnk7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW2luYysrXSA9IGludGVycG9sYXRlZFBvcy56O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoY2hhbmdlZClcblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmludmFsaWRhdGVCdWZmZXIoKTtcblxuXHR9XG5cblx0cHJpdmF0ZSBwcmVjZXNzUm90YXRpb24oY3VycmVudFRpbWU6bnVtYmVyLCBkZWx0YVRpbWU6bnVtYmVyLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSlcblx0e1xuXHRcdHZhciBkYXRhOkFycmF5PFBhcnRpY2xlQW5pbWF0aW9uRGF0YT4gPSBhbmltYXRpb25TdWJHZW9tZXRyeS5hbmltYXRpb25QYXJ0aWNsZXM7XG5cdFx0dmFyIHZlcnRleERhdGE6QXJyYXk8bnVtYmVyPiA9IGFuaW1hdGlvblN1Ykdlb21ldHJ5LnZlcnRleERhdGE7XG5cblx0XHR2YXIgY2hhbmdlZDpib29sZWFuID0gZmFsc2U7XG5cdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki8gPSBkYXRhLmxlbmd0aDtcblxuXHRcdHZhciBpbnRlcnBvbGF0ZWRSb3RhdGlvbjpWZWN0b3IzRDtcblx0XHR2YXIgcm90YXRpb25WZWxvY2l0eTpWZWN0b3IzRDtcblxuXHRcdGlmICh0aGlzLl9zbW9vdGgpIHtcblx0XHRcdHJvdGF0aW9uVmVsb2NpdHkgPSB0aGlzLl9wcmVFdWxlci5zdWJ0cmFjdCh0aGlzLl90YXJnZXRFdWxlcik7XG5cdFx0XHRyb3RhdGlvblZlbG9jaXR5LnNjYWxlQnkoMS9kZWx0YVRpbWUpO1xuXHRcdH0gZWxzZVxuXHRcdFx0aW50ZXJwb2xhdGVkUm90YXRpb24gPSB0aGlzLl90YXJnZXRFdWxlcjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHR2YXIgazpudW1iZXIgPSAoY3VycmVudFRpbWUgLSBkYXRhW2ldLnN0YXJ0VGltZSkvZGF0YVtpXS50b3RhbFRpbWU7XG5cdFx0XHR2YXIgdDpudW1iZXIgPSAoayAtIE1hdGguZmxvb3IoaykpKmRhdGFbaV0udG90YWxUaW1lO1xuXHRcdFx0aWYgKHQgLSBkZWx0YVRpbWUgPD0gMCkge1xuXHRcdFx0XHR2YXIgaW5jOm51bWJlciAvKmludCovID0gZGF0YVtpXS5zdGFydFZlcnRleEluZGV4KmFuaW1hdGlvblN1Ykdlb21ldHJ5LnRvdGFsTGVuT2ZPbmVWZXJ0ZXggKyB0aGlzLl9wYXJ0aWNsZUZvbGxvd05vZGUuX2lEYXRhT2Zmc2V0O1xuXG5cdFx0XHRcdGlmICh0aGlzLl9zbW9vdGgpIHtcblx0XHRcdFx0XHR0aGlzLl90ZW1wLmNvcHlGcm9tKHJvdGF0aW9uVmVsb2NpdHkpO1xuXHRcdFx0XHRcdHRoaXMuX3RlbXAuc2NhbGVCeSh0KTtcblx0XHRcdFx0XHRpbnRlcnBvbGF0ZWRSb3RhdGlvbiA9IHRoaXMuX3RhcmdldEV1bGVyLmFkZCh0aGlzLl90ZW1wKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh2ZXJ0ZXhEYXRhW2luY10gIT0gaW50ZXJwb2xhdGVkUm90YXRpb24ueCB8fCB2ZXJ0ZXhEYXRhW2luYyArIDFdICE9IGludGVycG9sYXRlZFJvdGF0aW9uLnkgfHwgdmVydGV4RGF0YVtpbmMgKyAyXSAhPSBpbnRlcnBvbGF0ZWRSb3RhdGlvbi56KSB7XG5cdFx0XHRcdFx0Y2hhbmdlZCA9IHRydWU7XG5cdFx0XHRcdFx0Zm9yICh2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwOyBqIDwgZGF0YVtpXS5udW1WZXJ0aWNlczsgaisrKSB7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW2luYysrXSA9IGludGVycG9sYXRlZFJvdGF0aW9uLng7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW2luYysrXSA9IGludGVycG9sYXRlZFJvdGF0aW9uLnk7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW2luYysrXSA9IGludGVycG9sYXRlZFJvdGF0aW9uLno7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChjaGFuZ2VkKVxuXHRcdFx0YW5pbWF0aW9uU3ViR2VvbWV0cnkuaW52YWxpZGF0ZUJ1ZmZlcigpO1xuXG5cdH1cblxuXHRwcml2YXRlIHByb2Nlc3NQb3NpdGlvbkFuZFJvdGF0aW9uKGN1cnJlbnRUaW1lOm51bWJlciwgZGVsdGFUaW1lOm51bWJlciwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnkpXG5cdHtcblx0XHR2YXIgZGF0YTpBcnJheTxQYXJ0aWNsZUFuaW1hdGlvbkRhdGE+ID0gYW5pbWF0aW9uU3ViR2VvbWV0cnkuYW5pbWF0aW9uUGFydGljbGVzO1xuXHRcdHZhciB2ZXJ0ZXhEYXRhOkFycmF5PG51bWJlcj4gPSBhbmltYXRpb25TdWJHZW9tZXRyeS52ZXJ0ZXhEYXRhO1xuXG5cdFx0dmFyIGNoYW5nZWQ6Ym9vbGVhbiA9IGZhbHNlO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gZGF0YS5sZW5ndGg7XG5cblx0XHR2YXIgaW50ZXJwb2xhdGVkUG9zOlZlY3RvcjNEO1xuXHRcdHZhciBpbnRlcnBvbGF0ZWRSb3RhdGlvbjpWZWN0b3IzRDtcblxuXHRcdHZhciBwb3NWZWxvY2l0eTpWZWN0b3IzRDtcblx0XHR2YXIgcm90YXRpb25WZWxvY2l0eTpWZWN0b3IzRDtcblx0XHRpZiAodGhpcy5fc21vb3RoKSB7XG5cdFx0XHRwb3NWZWxvY2l0eSA9IHRoaXMuX3ByZVBvcy5zdWJ0cmFjdCh0aGlzLl90YXJnZXRQb3MpO1xuXHRcdFx0cG9zVmVsb2NpdHkuc2NhbGVCeSgxL2RlbHRhVGltZSk7XG5cdFx0XHRyb3RhdGlvblZlbG9jaXR5ID0gdGhpcy5fcHJlRXVsZXIuc3VidHJhY3QodGhpcy5fdGFyZ2V0RXVsZXIpO1xuXHRcdFx0cm90YXRpb25WZWxvY2l0eS5zY2FsZUJ5KDEvZGVsdGFUaW1lKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aW50ZXJwb2xhdGVkUG9zID0gdGhpcy5fdGFyZ2V0UG9zO1xuXHRcdFx0aW50ZXJwb2xhdGVkUm90YXRpb24gPSB0aGlzLl90YXJnZXRFdWxlcjtcblx0XHR9XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciAvKnVpbnQqLyA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0dmFyIGs6bnVtYmVyID0gKGN1cnJlbnRUaW1lIC0gZGF0YVtpXS5zdGFydFRpbWUpL2RhdGFbaV0udG90YWxUaW1lO1xuXHRcdFx0dmFyIHQ6bnVtYmVyID0gKGsgLSBNYXRoLmZsb29yKGspKSpkYXRhW2ldLnRvdGFsVGltZTtcblx0XHRcdGlmICh0IC0gZGVsdGFUaW1lIDw9IDApIHtcblx0XHRcdFx0dmFyIGluYzpudW1iZXIgLyppbnQqLyA9IGRhdGFbaV0uc3RhcnRWZXJ0ZXhJbmRleCphbmltYXRpb25TdWJHZW9tZXRyeS50b3RhbExlbk9mT25lVmVydGV4ICsgdGhpcy5fcGFydGljbGVGb2xsb3dOb2RlLl9pRGF0YU9mZnNldDtcblx0XHRcdFx0aWYgKHRoaXMuX3Ntb290aCkge1xuXHRcdFx0XHRcdHRoaXMuX3RlbXAuY29weUZyb20ocG9zVmVsb2NpdHkpO1xuXHRcdFx0XHRcdHRoaXMuX3RlbXAuc2NhbGVCeSh0KTtcblx0XHRcdFx0XHRpbnRlcnBvbGF0ZWRQb3MgPSB0aGlzLl90YXJnZXRQb3MuYWRkKHRoaXMuX3RlbXApO1xuXG5cdFx0XHRcdFx0dGhpcy5fdGVtcC5jb3B5RnJvbShyb3RhdGlvblZlbG9jaXR5KTtcblx0XHRcdFx0XHR0aGlzLl90ZW1wLnNjYWxlQnkodCk7XG5cdFx0XHRcdFx0aW50ZXJwb2xhdGVkUm90YXRpb24gPSB0aGlzLl90YXJnZXRFdWxlci5hZGQodGhpcy5fdGVtcCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodmVydGV4RGF0YVtpbmNdICE9IGludGVycG9sYXRlZFBvcy54IHx8IHZlcnRleERhdGFbaW5jICsgMV0gIT0gaW50ZXJwb2xhdGVkUG9zLnkgfHwgdmVydGV4RGF0YVtpbmMgKyAyXSAhPSBpbnRlcnBvbGF0ZWRQb3MueiB8fCB2ZXJ0ZXhEYXRhW2luYyArIDNdICE9IGludGVycG9sYXRlZFJvdGF0aW9uLnggfHwgdmVydGV4RGF0YVtpbmMgKyA0XSAhPSBpbnRlcnBvbGF0ZWRSb3RhdGlvbi55IHx8IHZlcnRleERhdGFbaW5jICsgNV0gIT0gaW50ZXJwb2xhdGVkUm90YXRpb24ueikge1xuXHRcdFx0XHRcdGNoYW5nZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGZvciAodmFyIGo6bnVtYmVyIC8qdWludCovID0gMDsgaiA8IGRhdGFbaV0ubnVtVmVydGljZXM7IGorKykge1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVtpbmMrK10gPSBpbnRlcnBvbGF0ZWRQb3MueDtcblx0XHRcdFx0XHRcdHZlcnRleERhdGFbaW5jKytdID0gaW50ZXJwb2xhdGVkUG9zLnk7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW2luYysrXSA9IGludGVycG9sYXRlZFBvcy56O1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVtpbmMrK10gPSBpbnRlcnBvbGF0ZWRSb3RhdGlvbi54O1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVtpbmMrK10gPSBpbnRlcnBvbGF0ZWRSb3RhdGlvbi55O1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVtpbmMrK10gPSBpbnRlcnBvbGF0ZWRSb3RhdGlvbi56O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoY2hhbmdlZClcblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmludmFsaWRhdGVCdWZmZXIoKTtcblx0fVxuXG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlRm9sbG93U3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/ParticleFollowState.ts b/lib/animators/states/ParticleFollowState.ts
new file mode 100644
index 000000000..64accfd26
--- /dev/null
+++ b/lib/animators/states/ParticleFollowState.ts
@@ -0,0 +1,263 @@
+import DisplayObject = require("awayjs-core/lib/core/base/DisplayObject");
+import MathConsts = require("awayjs-core/lib/core/geom/MathConsts");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+import ParticleFollowNode = require("awayjs-renderergl/lib/animators/nodes/ParticleFollowNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleFollowState extends ParticleStateBase
+{
+ /** @private */
+ public static FOLLOW_POSITION_INDEX:number /*uint*/ = 0;
+
+ /** @private */
+ public static FOLLOW_ROTATION_INDEX:number /*uint*/ = 1;
+
+ private _particleFollowNode:ParticleFollowNode;
+ private _followTarget:DisplayObject;
+
+ private _targetPos:Vector3D = new Vector3D();
+ private _targetEuler:Vector3D = new Vector3D();
+ private _prePos:Vector3D;
+ private _preEuler:Vector3D;
+ private _smooth:boolean;
+
+ //temporary vector3D for calculation
+ private _temp:Vector3D = new Vector3D();
+
+ constructor(animator:ParticleAnimator, particleFollowNode:ParticleFollowNode)
+ {
+ super(animator, particleFollowNode, true);
+
+ this._particleFollowNode = particleFollowNode;
+ this._smooth = particleFollowNode._iSmooth;
+ }
+
+ public get followTarget():DisplayObject
+ {
+ return this._followTarget;
+ }
+
+ public set followTarget(value:DisplayObject)
+ {
+ this._followTarget = value;
+ }
+
+ public get smooth():boolean
+ {
+ return this._smooth;
+ }
+
+ public set smooth(value:boolean)
+ {
+ this._smooth = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (this._followTarget) {
+ if (this._particleFollowNode._iUsesPosition) {
+ this._targetPos.x = this._followTarget.transform.position.x/renderable.sourceEntity.scaleX;
+ this._targetPos.y = this._followTarget.transform.position.y/renderable.sourceEntity.scaleY;
+ this._targetPos.z = this._followTarget.transform.position.z/renderable.sourceEntity.scaleZ;
+ }
+ if (this._particleFollowNode._iUsesRotation) {
+ this._targetEuler.x = this._followTarget.rotationX;
+ this._targetEuler.y = this._followTarget.rotationY;
+ this._targetEuler.z = this._followTarget.rotationZ;
+ this._targetEuler.scaleBy(MathConsts.DEGREES_TO_RADIANS);
+ }
+ }
+ //initialization
+ if (!this._prePos)
+ this._prePos = this._targetPos.clone();
+ if (!this._preEuler)
+ this._preEuler = this._targetEuler.clone();
+
+ var currentTime:number = this._pTime/1000;
+ var previousTime:number = animationSubGeometry.previousTime;
+ var deltaTime:number = currentTime - previousTime;
+
+ var needProcess:boolean = previousTime != currentTime;
+
+ if (this._particleFollowNode._iUsesPosition && this._particleFollowNode._iUsesRotation) {
+ if (needProcess)
+ this.processPositionAndRotation(currentTime, deltaTime, animationSubGeometry);
+
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset + 3, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ } else if (this._particleFollowNode._iUsesPosition) {
+ if (needProcess)
+ this.processPosition(currentTime, deltaTime, animationSubGeometry);
+
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ } else if (this._particleFollowNode._iUsesRotation) {
+ if (needProcess)
+ this.precessRotation(currentTime, deltaTime, animationSubGeometry);
+
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+
+ this._prePos.copyFrom(this._targetPos);
+ this._targetEuler.copyFrom(this._targetEuler);
+ animationSubGeometry.previousTime = currentTime;
+ }
+
+ private processPosition(currentTime:number, deltaTime:number, animationSubGeometry:AnimationSubGeometry)
+ {
+ var data:Array = animationSubGeometry.animationParticles;
+ var vertexData:Array = animationSubGeometry.vertexData;
+
+ var changed:boolean = false;
+ var len:number /*uint*/ = data.length;
+ var interpolatedPos:Vector3D;
+ var posVelocity:Vector3D;
+ if (this._smooth) {
+ posVelocity = this._prePos.subtract(this._targetPos);
+ posVelocity.scaleBy(1/deltaTime);
+ } else
+ interpolatedPos = this._targetPos;
+ for (var i:number /*uint*/ = 0; i < len; i++) {
+ var k:number = (currentTime - data[i].startTime)/data[i].totalTime;
+ var t:number = (k - Math.floor(k))*data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc:number /*int*/ = data[i].startVertexIndex*animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+
+ if (this._smooth) {
+ this._temp.copyFrom(posVelocity);
+ this._temp.scaleBy(t);
+ interpolatedPos = this._targetPos.add(this._temp);
+ }
+
+ if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z) {
+ changed = true;
+ for (var j:number /*uint*/ = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedPos.x;
+ vertexData[inc++] = interpolatedPos.y;
+ vertexData[inc++] = interpolatedPos.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+
+ }
+
+ private precessRotation(currentTime:number, deltaTime:number, animationSubGeometry:AnimationSubGeometry)
+ {
+ var data:Array = animationSubGeometry.animationParticles;
+ var vertexData:Array = animationSubGeometry.vertexData;
+
+ var changed:boolean = false;
+ var len:number /*uint*/ = data.length;
+
+ var interpolatedRotation:Vector3D;
+ var rotationVelocity:Vector3D;
+
+ if (this._smooth) {
+ rotationVelocity = this._preEuler.subtract(this._targetEuler);
+ rotationVelocity.scaleBy(1/deltaTime);
+ } else
+ interpolatedRotation = this._targetEuler;
+
+ for (var i:number /*uint*/ = 0; i < len; i++) {
+ var k:number = (currentTime - data[i].startTime)/data[i].totalTime;
+ var t:number = (k - Math.floor(k))*data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc:number /*int*/ = data[i].startVertexIndex*animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+
+ if (this._smooth) {
+ this._temp.copyFrom(rotationVelocity);
+ this._temp.scaleBy(t);
+ interpolatedRotation = this._targetEuler.add(this._temp);
+ }
+
+ if (vertexData[inc] != interpolatedRotation.x || vertexData[inc + 1] != interpolatedRotation.y || vertexData[inc + 2] != interpolatedRotation.z) {
+ changed = true;
+ for (var j:number /*uint*/ = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedRotation.x;
+ vertexData[inc++] = interpolatedRotation.y;
+ vertexData[inc++] = interpolatedRotation.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+
+ }
+
+ private processPositionAndRotation(currentTime:number, deltaTime:number, animationSubGeometry:AnimationSubGeometry)
+ {
+ var data:Array = animationSubGeometry.animationParticles;
+ var vertexData:Array = animationSubGeometry.vertexData;
+
+ var changed:boolean = false;
+ var len:number /*uint*/ = data.length;
+
+ var interpolatedPos:Vector3D;
+ var interpolatedRotation:Vector3D;
+
+ var posVelocity:Vector3D;
+ var rotationVelocity:Vector3D;
+ if (this._smooth) {
+ posVelocity = this._prePos.subtract(this._targetPos);
+ posVelocity.scaleBy(1/deltaTime);
+ rotationVelocity = this._preEuler.subtract(this._targetEuler);
+ rotationVelocity.scaleBy(1/deltaTime);
+ } else {
+ interpolatedPos = this._targetPos;
+ interpolatedRotation = this._targetEuler;
+ }
+
+ for (var i:number /*uint*/ = 0; i < len; i++) {
+ var k:number = (currentTime - data[i].startTime)/data[i].totalTime;
+ var t:number = (k - Math.floor(k))*data[i].totalTime;
+ if (t - deltaTime <= 0) {
+ var inc:number /*int*/ = data[i].startVertexIndex*animationSubGeometry.totalLenOfOneVertex + this._particleFollowNode._iDataOffset;
+ if (this._smooth) {
+ this._temp.copyFrom(posVelocity);
+ this._temp.scaleBy(t);
+ interpolatedPos = this._targetPos.add(this._temp);
+
+ this._temp.copyFrom(rotationVelocity);
+ this._temp.scaleBy(t);
+ interpolatedRotation = this._targetEuler.add(this._temp);
+ }
+
+ if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z || vertexData[inc + 3] != interpolatedRotation.x || vertexData[inc + 4] != interpolatedRotation.y || vertexData[inc + 5] != interpolatedRotation.z) {
+ changed = true;
+ for (var j:number /*uint*/ = 0; j < data[i].numVertices; j++) {
+ vertexData[inc++] = interpolatedPos.x;
+ vertexData[inc++] = interpolatedPos.y;
+ vertexData[inc++] = interpolatedPos.z;
+ vertexData[inc++] = interpolatedRotation.x;
+ vertexData[inc++] = interpolatedRotation.y;
+ vertexData[inc++] = interpolatedRotation.z;
+ }
+ }
+ }
+ }
+ if (changed)
+ animationSubGeometry.invalidateBuffer();
+ }
+
+}
+
+export = ParticleFollowState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleInitialColorState.js b/lib/animators/states/ParticleInitialColorState.js
new file mode 100755
index 000000000..ed230d146
--- /dev/null
+++ b/lib/animators/states/ParticleInitialColorState.js
@@ -0,0 +1,78 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+*
+*/
+var ParticleInitialColorState = (function (_super) {
+ __extends(ParticleInitialColorState, _super);
+ function ParticleInitialColorState(animator, particleInitialColorNode) {
+ _super.call(this, animator, particleInitialColorNode);
+ this._particleInitialColorNode = particleInitialColorNode;
+ this._usesMultiplier = particleInitialColorNode._iUsesMultiplier;
+ this._usesOffset = particleInitialColorNode._iUsesOffset;
+ this._initialColor = particleInitialColorNode._iInitialColor;
+ this.updateColorData();
+ }
+ Object.defineProperty(ParticleInitialColorState.prototype, "initialColor", {
+ /**
+ * Defines the initial color transform of the state, when in global mode.
+ */
+ get: function () {
+ return this._initialColor;
+ },
+ set: function (value) {
+ this._initialColor = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleInitialColorState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ // TODO: not used
+ renderable = renderable;
+ camera = camera;
+ if (animationRegisterCache.needFragmentAnimation) {
+ if (this._particleInitialColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ var dataOffset = this._particleInitialColorNode._iDataOffset;
+ if (this._usesMultiplier) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ }
+ if (this._usesOffset)
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ }
+ else {
+ if (this._usesMultiplier)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.MULTIPLIER_INDEX), this._multiplierData.x, this._multiplierData.y, this._multiplierData.z, this._multiplierData.w);
+ if (this._usesOffset)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.OFFSET_INDEX), this._offsetData.x, this._offsetData.y, this._offsetData.z, this._offsetData.w);
+ }
+ }
+ };
+ ParticleInitialColorState.prototype.updateColorData = function () {
+ if (this._particleInitialColorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesMultiplier)
+ this._multiplierData = new Vector3D(this._initialColor.redMultiplier, this._initialColor.greenMultiplier, this._initialColor.blueMultiplier, this._initialColor.alphaMultiplier);
+ if (this._usesOffset)
+ this._offsetData = new Vector3D(this._initialColor.redOffset / 255, this._initialColor.greenOffset / 255, this._initialColor.blueOffset / 255, this._initialColor.alphaOffset / 255);
+ }
+ };
+ /** @private */
+ ParticleInitialColorState.MULTIPLIER_INDEX = 0;
+ /** @private */
+ ParticleInitialColorState.OFFSET_INDEX = 1;
+ return ParticleInitialColorState;
+})(ParticleStateBase);
+module.exports = ParticleInitialColorState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVpbml0aWFsY29sb3JzdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUluaXRpYWxDb2xvclN0YXRlIiwiUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlSW5pdGlhbENvbG9yU3RhdGUuaW5pdGlhbENvbG9yIiwiUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZS5zZXRSZW5kZXJTdGF0ZSIsIlBhcnRpY2xlSW5pdGlhbENvbG9yU3RhdGUudXBkYXRlQ29sb3JEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQU10RSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztFQURFO0lBQ0kseUJBQXlCO0lBQVNBLFVBQWxDQSx5QkFBeUJBLFVBQTBCQTtJQWN4REEsU0FkS0EseUJBQXlCQSxDQWNsQkEsUUFBeUJBLEVBQUVBLHdCQUFpREE7UUFFdkZDLGtCQUFNQSxRQUFRQSxFQUFFQSx3QkFBd0JBLENBQUNBLENBQUNBO1FBRTFDQSxJQUFJQSxDQUFDQSx5QkFBeUJBLEdBQUdBLHdCQUF3QkEsQ0FBQ0E7UUFDMURBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLHdCQUF3QkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQTtRQUNqRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0Esd0JBQXdCQSxDQUFDQSxZQUFZQSxDQUFDQTtRQUN6REEsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0Esd0JBQXdCQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUU3REEsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBS0RELHNCQUFXQSxtREFBWUE7UUFI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b2xvclN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbG9yVHJhbnNmb3JtXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vQ29sb3JUcmFuc2Zvcm1cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVJbml0aWFsQ29sb3JOb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZUluaXRpYWxDb2xvck5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbipcbiovXG5jbGFzcyBQYXJ0aWNsZUluaXRpYWxDb2xvclN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgTVVMVElQTElFUl9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBPRkZTRVRfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHRwcml2YXRlIF9wYXJ0aWNsZUluaXRpYWxDb2xvck5vZGU6UGFydGljbGVJbml0aWFsQ29sb3JOb2RlO1xuXHRwcml2YXRlIF91c2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzT2Zmc2V0OmJvb2xlYW47XG5cdHByaXZhdGUgX2luaXRpYWxDb2xvcjpDb2xvclRyYW5zZm9ybTtcblx0cHJpdmF0ZSBfbXVsdGlwbGllckRhdGE6VmVjdG9yM0Q7XG5cdHByaXZhdGUgX29mZnNldERhdGE6VmVjdG9yM0Q7XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVJbml0aWFsQ29sb3JOb2RlOlBhcnRpY2xlSW5pdGlhbENvbG9yTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVJbml0aWFsQ29sb3JOb2RlID0gcGFydGljbGVJbml0aWFsQ29sb3JOb2RlO1xuXHRcdHRoaXMuX3VzZXNNdWx0aXBsaWVyID0gcGFydGljbGVJbml0aWFsQ29sb3JOb2RlLl9pVXNlc011bHRpcGxpZXI7XG5cdFx0dGhpcy5fdXNlc09mZnNldCA9IHBhcnRpY2xlSW5pdGlhbENvbG9yTm9kZS5faVVzZXNPZmZzZXQ7XG5cdFx0dGhpcy5faW5pdGlhbENvbG9yID0gcGFydGljbGVJbml0aWFsQ29sb3JOb2RlLl9pSW5pdGlhbENvbG9yO1xuXG5cdFx0dGhpcy51cGRhdGVDb2xvckRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBpbml0aWFsIGNvbG9yIHRyYW5zZm9ybSBvZiB0aGUgc3RhdGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGluaXRpYWxDb2xvcigpOkNvbG9yVHJhbnNmb3JtXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faW5pdGlhbENvbG9yO1xuXHR9XG5cblx0cHVibGljIHNldCBpbml0aWFsQ29sb3IodmFsdWU6Q29sb3JUcmFuc2Zvcm0pXG5cdHtcblx0XHR0aGlzLl9pbml0aWFsQ29sb3IgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0Ly8gVE9ETzogbm90IHVzZWRcblx0XHRyZW5kZXJhYmxlID0gcmVuZGVyYWJsZTtcblx0XHRjYW1lcmEgPSBjYW1lcmE7XG5cblx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5uZWVkRnJhZ21lbnRBbmltYXRpb24pIHtcblx0XHRcdGlmICh0aGlzLl9wYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQykge1xuXHRcdFx0XHR2YXIgZGF0YU9mZnNldDpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wYXJ0aWNsZUluaXRpYWxDb2xvck5vZGUuX2lEYXRhT2Zmc2V0O1xuXHRcdFx0XHRpZiAodGhpcy5fdXNlc011bHRpcGxpZXIpIHtcblx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlSW5pdGlhbENvbG9yU3RhdGUuTVVMVElQTElFUl9JTkRFWCksIGRhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfNCk7XG5cdFx0XHRcdFx0ZGF0YU9mZnNldCArPSA0O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh0aGlzLl91c2VzT2Zmc2V0KVxuXHRcdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVJbml0aWFsQ29sb3JTdGF0ZS5PRkZTRVRfSU5ERVgpLCBkYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKHRoaXMuX3VzZXNNdWx0aXBsaWVyKVxuXHRcdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZUluaXRpYWxDb2xvclN0YXRlLk1VTFRJUExJRVJfSU5ERVgpLCB0aGlzLl9tdWx0aXBsaWVyRGF0YS54LCB0aGlzLl9tdWx0aXBsaWVyRGF0YS55LCB0aGlzLl9tdWx0aXBsaWVyRGF0YS56LCB0aGlzLl9tdWx0aXBsaWVyRGF0YS53KTtcblx0XHRcdFx0aWYgKHRoaXMuX3VzZXNPZmZzZXQpXG5cdFx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlSW5pdGlhbENvbG9yU3RhdGUuT0ZGU0VUX0lOREVYKSwgdGhpcy5fb2Zmc2V0RGF0YS54LCB0aGlzLl9vZmZzZXREYXRhLnksIHRoaXMuX29mZnNldERhdGEueiwgdGhpcy5fb2Zmc2V0RGF0YS53KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZUNvbG9yRGF0YSgpXG5cdHtcblx0XHRpZiAodGhpcy5fcGFydGljbGVJbml0aWFsQ29sb3JOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpIHtcblx0XHRcdGlmICh0aGlzLl91c2VzTXVsdGlwbGllcilcblx0XHRcdFx0dGhpcy5fbXVsdGlwbGllckRhdGEgPSBuZXcgVmVjdG9yM0QodGhpcy5faW5pdGlhbENvbG9yLnJlZE11bHRpcGxpZXIsIHRoaXMuX2luaXRpYWxDb2xvci5ncmVlbk11bHRpcGxpZXIsIHRoaXMuX2luaXRpYWxDb2xvci5ibHVlTXVsdGlwbGllciwgdGhpcy5faW5pdGlhbENvbG9yLmFscGhhTXVsdGlwbGllcik7XG5cdFx0XHRpZiAodGhpcy5fdXNlc09mZnNldClcblx0XHRcdFx0dGhpcy5fb2Zmc2V0RGF0YSA9IG5ldyBWZWN0b3IzRCh0aGlzLl9pbml0aWFsQ29sb3IucmVkT2Zmc2V0LzI1NSwgdGhpcy5faW5pdGlhbENvbG9yLmdyZWVuT2Zmc2V0LzI1NSwgdGhpcy5faW5pdGlhbENvbG9yLmJsdWVPZmZzZXQvMjU1LCB0aGlzLl9pbml0aWFsQ29sb3IuYWxwaGFPZmZzZXQvMjU1KTtcblx0XHR9XG5cdH1cblxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZUluaXRpYWxDb2xvclN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleInitialColorState.ts b/lib/animators/states/ParticleInitialColorState.ts
new file mode 100644
index 000000000..55964ce92
--- /dev/null
+++ b/lib/animators/states/ParticleInitialColorState.ts
@@ -0,0 +1,97 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleInitialColorNode = require("awayjs-renderergl/lib/animators/nodes/ParticleInitialColorNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+*
+*/
+class ParticleInitialColorState extends ParticleStateBase
+{
+ /** @private */
+ public static MULTIPLIER_INDEX:number /*uint*/ = 0;
+ /** @private */
+ public static OFFSET_INDEX:number /*uint*/ = 1;
+
+ private _particleInitialColorNode:ParticleInitialColorNode;
+ private _usesMultiplier:boolean;
+ private _usesOffset:boolean;
+ private _initialColor:ColorTransform;
+ private _multiplierData:Vector3D;
+ private _offsetData:Vector3D;
+
+ constructor(animator:ParticleAnimator, particleInitialColorNode:ParticleInitialColorNode)
+ {
+ super(animator, particleInitialColorNode);
+
+ this._particleInitialColorNode = particleInitialColorNode;
+ this._usesMultiplier = particleInitialColorNode._iUsesMultiplier;
+ this._usesOffset = particleInitialColorNode._iUsesOffset;
+ this._initialColor = particleInitialColorNode._iInitialColor;
+
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the initial color transform of the state, when in global mode.
+ */
+ public get initialColor():ColorTransform
+ {
+ return this._initialColor;
+ }
+
+ public set initialColor(value:ColorTransform)
+ {
+ this._initialColor = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ // TODO: not used
+ renderable = renderable;
+ camera = camera;
+
+ if (animationRegisterCache.needFragmentAnimation) {
+ if (this._particleInitialColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ var dataOffset:number /*uint*/ = this._particleInitialColorNode._iDataOffset;
+ if (this._usesMultiplier) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.MULTIPLIER_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ dataOffset += 4;
+ }
+ if (this._usesOffset)
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.OFFSET_INDEX), dataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ } else {
+ if (this._usesMultiplier)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.MULTIPLIER_INDEX), this._multiplierData.x, this._multiplierData.y, this._multiplierData.z, this._multiplierData.w);
+ if (this._usesOffset)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleInitialColorState.OFFSET_INDEX), this._offsetData.x, this._offsetData.y, this._offsetData.z, this._offsetData.w);
+ }
+ }
+ }
+
+ private updateColorData()
+ {
+ if (this._particleInitialColorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesMultiplier)
+ this._multiplierData = new Vector3D(this._initialColor.redMultiplier, this._initialColor.greenMultiplier, this._initialColor.blueMultiplier, this._initialColor.alphaMultiplier);
+ if (this._usesOffset)
+ this._offsetData = new Vector3D(this._initialColor.redOffset/255, this._initialColor.greenOffset/255, this._initialColor.blueOffset/255, this._initialColor.alphaOffset/255);
+ }
+ }
+
+}
+
+export = ParticleInitialColorState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleOrbitState.js b/lib/animators/states/ParticleOrbitState.js
new file mode 100755
index 000000000..2386c8702
--- /dev/null
+++ b/lib/animators/states/ParticleOrbitState.js
@@ -0,0 +1,124 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleOrbitState = (function (_super) {
+ __extends(ParticleOrbitState, _super);
+ function ParticleOrbitState(animator, particleOrbitNode) {
+ _super.call(this, animator, particleOrbitNode);
+ this._particleOrbitNode = particleOrbitNode;
+ this._usesEulers = this._particleOrbitNode._iUsesEulers;
+ this._usesCycle = this._particleOrbitNode._iUsesCycle;
+ this._usesPhase = this._particleOrbitNode._iUsesPhase;
+ this._eulers = this._particleOrbitNode._iEulers;
+ this._radius = this._particleOrbitNode._iRadius;
+ this._cycleDuration = this._particleOrbitNode._iCycleDuration;
+ this._cyclePhase = this._particleOrbitNode._iCyclePhase;
+ this.updateOrbitData();
+ }
+ Object.defineProperty(ParticleOrbitState.prototype, "radius", {
+ /**
+ * Defines the radius of the orbit when in global mode. Defaults to 100.
+ */
+ get: function () {
+ return this._radius;
+ },
+ set: function (value) {
+ this._radius = value;
+ this.updateOrbitData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleOrbitState.prototype, "cycleDuration", {
+ /**
+ * Defines the duration of the orbit in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._cycleDuration;
+ },
+ set: function (value) {
+ this._cycleDuration = value;
+ this.updateOrbitData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleOrbitState.prototype, "cyclePhase", {
+ /**
+ * Defines the phase of the orbit in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ get: function () {
+ return this._cyclePhase;
+ },
+ set: function (value) {
+ this._cyclePhase = value;
+ this.updateOrbitData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleOrbitState.prototype, "eulers", {
+ /**
+ * Defines the euler rotation in degrees, applied to the orientation of the orbit when in global mode.
+ */
+ get: function () {
+ return this._eulers;
+ },
+ set: function (value) {
+ this._eulers = value;
+ this.updateOrbitData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleOrbitState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOrbitState.ORBIT_INDEX);
+ if (this._particleOrbitNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleOrbitNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleOrbitNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ else
+ animationRegisterCache.setVertexConst(index, this._orbitData.x, this._orbitData.y, this._orbitData.z, this._orbitData.w);
+ if (this._usesEulers)
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOrbitState.EULERS_INDEX), this._eulersMatrix);
+ };
+ ParticleOrbitState.prototype.updateOrbitData = function () {
+ if (this._usesEulers) {
+ this._eulersMatrix = new Matrix3D();
+ this._eulersMatrix.appendRotation(this._eulers.x, Vector3D.X_AXIS);
+ this._eulersMatrix.appendRotation(this._eulers.y, Vector3D.Y_AXIS);
+ this._eulersMatrix.appendRotation(this._eulers.z, Vector3D.Z_AXIS);
+ }
+ if (this._particleOrbitNode.mode == ParticlePropertiesMode.GLOBAL) {
+ this._orbitData = new Vector3D(this._radius, 0, this._radius * Math.PI * 2, this._cyclePhase * Math.PI / 180);
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._orbitData.y = Math.PI * 2 / this._cycleDuration;
+ }
+ else
+ this._orbitData.y = Math.PI * 2;
+ }
+ };
+ /** @private */
+ ParticleOrbitState.ORBIT_INDEX = 0;
+ /** @private */
+ ParticleOrbitState.EULERS_INDEX = 1;
+ return ParticleOrbitState;
+})(ParticleStateBase);
+module.exports = ParticleOrbitState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVvcmJpdHN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlT3JiaXRTdGF0ZSIsIlBhcnRpY2xlT3JiaXRTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlT3JiaXRTdGF0ZS5yYWRpdXMiLCJQYXJ0aWNsZU9yYml0U3RhdGUuY3ljbGVEdXJhdGlvbiIsIlBhcnRpY2xlT3JiaXRTdGF0ZS5jeWNsZVBoYXNlIiwiUGFydGljbGVPcmJpdFN0YXRlLmV1bGVycyIsIlBhcnRpY2xlT3JiaXRTdGF0ZS5zZXRSZW5kZXJTdGF0ZSIsIlBhcnRpY2xlT3JiaXRTdGF0ZS51cGRhdGVPcmJpdERhdGEiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3RFLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBTXRFLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQUk3RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFFekcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxrQkFBa0I7SUFBU0EsVUFBM0JBLGtCQUFrQkEsVUFBMEJBO0lBZ0ZqREEsU0FoRktBLGtCQUFrQkEsQ0FnRlhBLFFBQXlCQSxFQUFFQSxpQkFBbUNBO1FBRXpFQyxrQkFBTUEsUUFBUUEsRUFBRUEsaUJBQWlCQSxDQUFDQSxDQUFDQTtRQUVuQ0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxpQkFBaUJBLENBQUNBO1FBQzVDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLFlBQVlBLENBQUNBO1FBQ3hEQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLFdBQVdBLENBQUNBO1FBQ3REQSxJQUFJQSxDQUFDQSxV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QSxDQWpJQSxBQWlJQ0EsRUFqSWdDLGlCQUFpQixFQWlJakQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZU9yYml0U3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTWF0cml4M0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RcIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVPcmJpdE5vZGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVPcmJpdE5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZU9yYml0U3RhdGUgZXh0ZW5kcyBQYXJ0aWNsZVN0YXRlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBPUkJJVF9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIEVVTEVSU19JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAxO1xuXG5cdHByaXZhdGUgX3BhcnRpY2xlT3JiaXROb2RlOlBhcnRpY2xlT3JiaXROb2RlO1xuXHRwcml2YXRlIF91c2VzRXVsZXJzOmJvb2xlYW47XG5cdHByaXZhdGUgX3VzZXNDeWNsZTpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzUGhhc2U6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfcmFkaXVzOm51bWJlcjtcblx0cHJpdmF0ZSBfY3ljbGVEdXJhdGlvbjpudW1iZXI7XG5cdHByaXZhdGUgX2N5Y2xlUGhhc2U6bnVtYmVyO1xuXHRwcml2YXRlIF9ldWxlcnM6VmVjdG9yM0Q7XG5cdHByaXZhdGUgX29yYml0RGF0YTpWZWN0b3IzRDtcblx0cHJpdmF0ZSBfZXVsZXJzTWF0cml4Ok1hdHJpeDNEO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSByYWRpdXMgb2YgdGhlIG9yYml0IHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEwMC5cblx0ICovXG5cdHB1YmxpYyBnZXQgcmFkaXVzKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcmFkaXVzO1xuXHR9XG5cblx0cHVibGljIHNldCByYWRpdXModmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fcmFkaXVzID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZU9yYml0RGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBvcmJpdCBpbiBzZWNvbmRzLCB1c2VkIGFzIGEgcGVyaW9kIGluZGVwZW5kZW50IG9mIHBhcnRpY2xlIGR1cmF0aW9uIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIDEuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGN5Y2xlRHVyYXRpb24oKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9jeWNsZUR1cmF0aW9uO1xuXHR9XG5cblx0cHVibGljIHNldCBjeWNsZUR1cmF0aW9uKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2N5Y2xlRHVyYXRpb24gPSB2YWx1ZTtcblxuXHRcdHRoaXMudXBkYXRlT3JiaXREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgcGhhc2Ugb2YgdGhlIG9yYml0IGluIGRlZ3JlZXMsIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIG9mZnNldCBvZiB0aGUgY3ljbGUgd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMC5cblx0ICovXG5cdHB1YmxpYyBnZXQgY3ljbGVQaGFzZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N5Y2xlUGhhc2U7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGN5Y2xlUGhhc2UodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fY3ljbGVQaGFzZSA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVPcmJpdERhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBldWxlciByb3RhdGlvbiBpbiBkZWdyZWVzLCBhcHBsaWVkIHRvIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgb3JiaXQgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgZXVsZXJzKCk6VmVjdG9yM0Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl9ldWxlcnM7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGV1bGVycyh2YWx1ZTpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMuX2V1bGVycyA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVPcmJpdERhdGEoKTtcblxuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVPcmJpdE5vZGU6UGFydGljbGVPcmJpdE5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVPcmJpdE5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVPcmJpdE5vZGUgPSBwYXJ0aWNsZU9yYml0Tm9kZTtcblx0XHR0aGlzLl91c2VzRXVsZXJzID0gdGhpcy5fcGFydGljbGVPcmJpdE5vZGUuX2lVc2VzRXVsZXJzO1xuXHRcdHRoaXMuX3VzZXNDeWNsZSA9IHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLl9pVXNlc0N5Y2xlO1xuXHRcdHRoaXMuX3VzZXNQaGFzZSA9IHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLl9pVXNlc1BoYXNlO1xuXHRcdHRoaXMuX2V1bGVycyA9IHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLl9pRXVsZXJzO1xuXHRcdHRoaXMuX3JhZGl1cyA9IHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLl9pUmFkaXVzO1xuXHRcdHRoaXMuX2N5Y2xlRHVyYXRpb24gPSB0aGlzLl9wYXJ0aWNsZU9yYml0Tm9kZS5faUN5Y2xlRHVyYXRpb247XG5cdFx0dGhpcy5fY3ljbGVQaGFzZSA9IHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLl9pQ3ljbGVQaGFzZTtcblx0XHR0aGlzLnVwZGF0ZU9yYml0RGF0YSgpO1xuXHR9XG5cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZU9yYml0U3RhdGUuT1JCSVRfSU5ERVgpO1xuXG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlT3JiaXROb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpIHtcblx0XHRcdGlmICh0aGlzLl91c2VzUGhhc2UpXG5cdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZU9yYml0Tm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfNCk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZU9yYml0Tm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfMyk7XG5cdFx0fSBlbHNlXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl9vcmJpdERhdGEueCwgdGhpcy5fb3JiaXREYXRhLnksIHRoaXMuX29yYml0RGF0YS56LCB0aGlzLl9vcmJpdERhdGEudyk7XG5cblx0XHRpZiAodGhpcy5fdXNlc0V1bGVycylcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3RGcm9tTWF0cml4KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVPcmJpdFN0YXRlLkVVTEVSU19JTkRFWCksIHRoaXMuX2V1bGVyc01hdHJpeCk7XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZU9yYml0RGF0YSgpXG5cdHtcblx0XHRpZiAodGhpcy5fdXNlc0V1bGVycykge1xuXHRcdFx0dGhpcy5fZXVsZXJzTWF0cml4ID0gbmV3IE1hdHJpeDNEKCk7XG5cdFx0XHR0aGlzLl9ldWxlcnNNYXRyaXguYXBwZW5kUm90YXRpb24odGhpcy5fZXVsZXJzLngsIFZlY3RvcjNELlhfQVhJUyk7XG5cdFx0XHR0aGlzLl9ldWxlcnNNYXRyaXguYXBwZW5kUm90YXRpb24odGhpcy5fZXVsZXJzLnksIFZlY3RvcjNELllfQVhJUyk7XG5cdFx0XHR0aGlzLl9ldWxlcnNNYXRyaXguYXBwZW5kUm90YXRpb24odGhpcy5fZXVsZXJzLnosIFZlY3RvcjNELlpfQVhJUyk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZU9yYml0Tm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuR0xPQkFMKSB7XG5cdFx0XHR0aGlzLl9vcmJpdERhdGEgPSBuZXcgVmVjdG9yM0QodGhpcy5fcmFkaXVzLCAwLCB0aGlzLl9yYWRpdXMqTWF0aC5QSSoyLCB0aGlzLl9jeWNsZVBoYXNlKk1hdGguUEkvMTgwKTtcblx0XHRcdGlmICh0aGlzLl91c2VzQ3ljbGUpIHtcblx0XHRcdFx0aWYgKHRoaXMuX2N5Y2xlRHVyYXRpb24gPD0gMClcblx0XHRcdFx0XHR0aHJvdyhuZXcgRXJyb3IoXCJ0aGUgY3ljbGUgZHVyYXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyb1wiKSk7XG5cdFx0XHRcdHRoaXMuX29yYml0RGF0YS55ID0gTWF0aC5QSSoyL3RoaXMuX2N5Y2xlRHVyYXRpb247XG5cdFx0XHR9IGVsc2Vcblx0XHRcdFx0dGhpcy5fb3JiaXREYXRhLnkgPSBNYXRoLlBJKjI7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlT3JiaXRTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleOrbitState.ts b/lib/animators/states/ParticleOrbitState.ts
new file mode 100644
index 000000000..2153843f0
--- /dev/null
+++ b/lib/animators/states/ParticleOrbitState.ts
@@ -0,0 +1,150 @@
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleOrbitNode = require("awayjs-renderergl/lib/animators/nodes/ParticleOrbitNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleOrbitState extends ParticleStateBase
+{
+ /** @private */
+ public static ORBIT_INDEX:number /*uint*/ = 0;
+
+ /** @private */
+ public static EULERS_INDEX:number /*uint*/ = 1;
+
+ private _particleOrbitNode:ParticleOrbitNode;
+ private _usesEulers:boolean;
+ private _usesCycle:boolean;
+ private _usesPhase:boolean;
+ private _radius:number;
+ private _cycleDuration:number;
+ private _cyclePhase:number;
+ private _eulers:Vector3D;
+ private _orbitData:Vector3D;
+ private _eulersMatrix:Matrix3D;
+
+ /**
+ * Defines the radius of the orbit when in global mode. Defaults to 100.
+ */
+ public get radius():number
+ {
+ return this._radius;
+ }
+
+ public set radius(value:number)
+ {
+ this._radius = value;
+
+ this.updateOrbitData();
+ }
+
+ /**
+ * Defines the duration of the orbit in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ public get cycleDuration():number
+ {
+ return this._cycleDuration;
+ }
+
+ public set cycleDuration(value:number)
+ {
+ this._cycleDuration = value;
+
+ this.updateOrbitData();
+ }
+
+ /**
+ * Defines the phase of the orbit in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ public get cyclePhase():number
+ {
+ return this._cyclePhase;
+ }
+
+ public set cyclePhase(value:number)
+ {
+ this._cyclePhase = value;
+
+ this.updateOrbitData();
+ }
+
+ /**
+ * Defines the euler rotation in degrees, applied to the orientation of the orbit when in global mode.
+ */
+ public get eulers():Vector3D
+ {
+ return this._eulers;
+ }
+
+ public set eulers(value:Vector3D)
+ {
+ this._eulers = value;
+
+ this.updateOrbitData();
+
+ }
+
+ constructor(animator:ParticleAnimator, particleOrbitNode:ParticleOrbitNode)
+ {
+ super(animator, particleOrbitNode);
+
+ this._particleOrbitNode = particleOrbitNode;
+ this._usesEulers = this._particleOrbitNode._iUsesEulers;
+ this._usesCycle = this._particleOrbitNode._iUsesCycle;
+ this._usesPhase = this._particleOrbitNode._iUsesPhase;
+ this._eulers = this._particleOrbitNode._iEulers;
+ this._radius = this._particleOrbitNode._iRadius;
+ this._cycleDuration = this._particleOrbitNode._iCycleDuration;
+ this._cyclePhase = this._particleOrbitNode._iCyclePhase;
+ this.updateOrbitData();
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOrbitState.ORBIT_INDEX);
+
+ if (this._particleOrbitNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleOrbitNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleOrbitNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ } else
+ animationRegisterCache.setVertexConst(index, this._orbitData.x, this._orbitData.y, this._orbitData.z, this._orbitData.w);
+
+ if (this._usesEulers)
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOrbitState.EULERS_INDEX), this._eulersMatrix);
+ }
+
+ private updateOrbitData()
+ {
+ if (this._usesEulers) {
+ this._eulersMatrix = new Matrix3D();
+ this._eulersMatrix.appendRotation(this._eulers.x, Vector3D.X_AXIS);
+ this._eulersMatrix.appendRotation(this._eulers.y, Vector3D.Y_AXIS);
+ this._eulersMatrix.appendRotation(this._eulers.z, Vector3D.Z_AXIS);
+ }
+ if (this._particleOrbitNode.mode == ParticlePropertiesMode.GLOBAL) {
+ this._orbitData = new Vector3D(this._radius, 0, this._radius*Math.PI*2, this._cyclePhase*Math.PI/180);
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._orbitData.y = Math.PI*2/this._cycleDuration;
+ } else
+ this._orbitData.y = Math.PI*2;
+ }
+ }
+}
+
+export = ParticleOrbitState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleOscillatorState.js b/lib/animators/states/ParticleOscillatorState.js
new file mode 100755
index 000000000..987c0662e
--- /dev/null
+++ b/lib/animators/states/ParticleOscillatorState.js
@@ -0,0 +1,64 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleOscillatorState = (function (_super) {
+ __extends(ParticleOscillatorState, _super);
+ function ParticleOscillatorState(animator, particleOscillatorNode) {
+ _super.call(this, animator, particleOscillatorNode);
+ this._particleOscillatorNode = particleOscillatorNode;
+ this._oscillator = this._particleOscillatorNode._iOscillator;
+ this.updateOscillatorData();
+ }
+ Object.defineProperty(ParticleOscillatorState.prototype, "oscillator", {
+ /**
+ * Defines the default oscillator axis (x, y, z) and cycleDuration (w) of the state, used when in global mode.
+ */
+ get: function () {
+ return this._oscillator;
+ },
+ set: function (value) {
+ this._oscillator = value;
+ this.updateOscillatorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ParticleOscillatorState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOscillatorState.OSCILLATOR_INDEX);
+ if (this._particleOscillatorNode.mode == ParticlePropertiesMode.LOCAL_STATIC)
+ animationSubGeometry.activateVertexBuffer(index, this._particleOscillatorNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationRegisterCache.setVertexConst(index, this._oscillatorData.x, this._oscillatorData.y, this._oscillatorData.z, this._oscillatorData.w);
+ };
+ ParticleOscillatorState.prototype.updateOscillatorData = function () {
+ if (this._particleOscillatorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._oscillator.w <= 0)
+ throw (new Error("the cycle duration must greater than zero"));
+ if (this._oscillatorData == null)
+ this._oscillatorData = new Vector3D();
+ this._oscillatorData.x = this._oscillator.x;
+ this._oscillatorData.y = this._oscillator.y;
+ this._oscillatorData.z = this._oscillator.z;
+ this._oscillatorData.w = Math.PI * 2 / this._oscillator.w;
+ }
+ };
+ /** @private */
+ ParticleOscillatorState.OSCILLATOR_INDEX = 0;
+ return ParticleOscillatorState;
+})(ParticleStateBase);
+module.exports = ParticleOscillatorState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVvc2NpbGxhdG9yc3RhdGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVPc2NpbGxhdG9yU3RhdGUiLCJQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlT3NjaWxsYXRvclN0YXRlLm9zY2lsbGF0b3IiLCJQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZS5zZXRSZW5kZXJTdGF0ZSIsIlBhcnRpY2xlT3NjaWxsYXRvclN0YXRlLnVwZGF0ZU9zY2lsbGF0b3JEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQU10RSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQTBCQTtJQXdCdERBLFNBeEJLQSx1QkFBdUJBLENBd0JoQkEsUUFBeUJBLEVBQUVBLHNCQUE2Q0E7UUFFbkZDLGtCQUFNQSxRQUFRQSxFQUFFQSxzQkFBc0JBLENBQUNBLENBQUNBO1FBRXhDQSxJQUFJQSxDQUFDQSx1QkFBdUJBLEdBQUdBLHNCQUFzQkEsQ0FBQ0E7UUFDdERBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsWUFBWUEsQ0FBQ0E7UUFFN0RBLElBQUlBLENBQUNBLG9CQUFvQkEsRUFBRUEsQ0FBQ0E7SUFDN0JBLENBQUNBO0lBcEJERCxzQkFBV0EsK0NBQVVBO1FBSHJCQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDekJBLENBQUNBO2FBRURGLFVBQXNCQSxLQUFjQTtZQUVuQ0UsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0E7WUFFekJBLElBQUlBLENBQUNBLG9CQUFvQkEsRUFBRUEsQ0FBQ0E7UUFDN0JBLENBQUNBOzs7T0FQQUY7SUFtQkRBOztPQUVHQTtJQUNJQSxnREFBY0EsR0FBckJBLFVBQXNCQSxLQUFXQSxFQUFFQSxVQUF5QkEsRUFBRUEsb0JBQXlDQSxFQUFFQSxzQkFBNkNBLEVBQUVBLE1BQWFBO1FBRXBLRyxJQUFJQSxLQUFLQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLHVCQUF1QkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxDQUFDQTtRQUVuSUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxJQUFJQSxJQUFJQSxzQkFBc0JBLENBQUNBLFlBQVlBLENBQUNBO1lBQzVFQSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsS0FBS0EsRUFBRUEsSUFBSUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxZQUFZQSxFQUFFQSxLQUFLQSxFQUFFQSwyQkFBMkJBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBO1FBQ3pJQSxJQUFJQTtZQUNIQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO0lBQy9JQSxDQUFDQTtJQUVPSCxzREFBb0JBLEdBQTVCQTtRQUVDSSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSx1QkFBdUJBLENBQUNBLElBQUlBLElBQUlBLHNCQUFzQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeEVBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO2dCQUMzQkEsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsMkNBQTJDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUUvREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsSUFBSUEsSUFBSUEsQ0FBQ0E7Z0JBQ2hDQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtZQUV2Q0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDNUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO1lBQzVDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUM1Q0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDdkRBLENBQUNBO0lBQ0ZBLENBQUNBO0lBM0RESixlQUFlQTtJQUNEQSx3Q0FBZ0JBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQTJEcERBLDhCQUFDQTtBQUFEQSxDQTlEQSxBQThEQ0EsRUE5RHFDLGlCQUFpQixFQThEdEQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU9zY2lsbGF0b3JOb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU9zY2lsbGF0b3JOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVPc2NpbGxhdG9yU3RhdGUgZXh0ZW5kcyBQYXJ0aWNsZVN0YXRlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBPU0NJTExBVE9SX0lOREVYOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0cHJpdmF0ZSBfcGFydGljbGVPc2NpbGxhdG9yTm9kZTpQYXJ0aWNsZU9zY2lsbGF0b3JOb2RlO1xuXHRwcml2YXRlIF9vc2NpbGxhdG9yOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9vc2NpbGxhdG9yRGF0YTpWZWN0b3IzRDtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZGVmYXVsdCBvc2NpbGxhdG9yIGF4aXMgKHgsIHksIHopIGFuZCBjeWNsZUR1cmF0aW9uICh3KSBvZiB0aGUgc3RhdGUsIHVzZWQgd2hlbiBpbiBnbG9iYWwgbW9kZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgb3NjaWxsYXRvcigpOlZlY3RvcjNEXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fb3NjaWxsYXRvcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgb3NjaWxsYXRvcih2YWx1ZTpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMuX29zY2lsbGF0b3IgPSB2YWx1ZTtcblxuXHRcdHRoaXMudXBkYXRlT3NjaWxsYXRvckRhdGEoKTtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlT3NjaWxsYXRvck5vZGU6UGFydGljbGVPc2NpbGxhdG9yTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZU9zY2lsbGF0b3JOb2RlKTtcblxuXHRcdHRoaXMuX3BhcnRpY2xlT3NjaWxsYXRvck5vZGUgPSBwYXJ0aWNsZU9zY2lsbGF0b3JOb2RlO1xuXHRcdHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9wYXJ0aWNsZU9zY2lsbGF0b3JOb2RlLl9pT3NjaWxsYXRvcjtcblxuXHRcdHRoaXMudXBkYXRlT3NjaWxsYXRvckRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZU9zY2lsbGF0b3JTdGF0ZS5PU0NJTExBVE9SX0lOREVYKTtcblxuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZU9zY2lsbGF0b3JOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5MT0NBTF9TVEFUSUMpXG5cdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihpbmRleCwgdGhpcy5fcGFydGljbGVPc2NpbGxhdG9yTm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfNCk7XG5cdFx0ZWxzZVxuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChpbmRleCwgdGhpcy5fb3NjaWxsYXRvckRhdGEueCwgdGhpcy5fb3NjaWxsYXRvckRhdGEueSwgdGhpcy5fb3NjaWxsYXRvckRhdGEueiwgdGhpcy5fb3NjaWxsYXRvckRhdGEudyk7XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZU9zY2lsbGF0b3JEYXRhKClcblx0e1xuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZU9zY2lsbGF0b3JOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpIHtcblx0XHRcdGlmICh0aGlzLl9vc2NpbGxhdG9yLncgPD0gMClcblx0XHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlIGN5Y2xlIGR1cmF0aW9uIG11c3QgZ3JlYXRlciB0aGFuIHplcm9cIikpO1xuXG5cdFx0XHRpZiAodGhpcy5fb3NjaWxsYXRvckRhdGEgPT0gbnVsbClcblx0XHRcdFx0dGhpcy5fb3NjaWxsYXRvckRhdGEgPSBuZXcgVmVjdG9yM0QoKTtcblxuXHRcdFx0dGhpcy5fb3NjaWxsYXRvckRhdGEueCA9IHRoaXMuX29zY2lsbGF0b3IueDtcblx0XHRcdHRoaXMuX29zY2lsbGF0b3JEYXRhLnkgPSB0aGlzLl9vc2NpbGxhdG9yLnk7XG5cdFx0XHR0aGlzLl9vc2NpbGxhdG9yRGF0YS56ID0gdGhpcy5fb3NjaWxsYXRvci56O1xuXHRcdFx0dGhpcy5fb3NjaWxsYXRvckRhdGEudyA9IE1hdGguUEkqMi90aGlzLl9vc2NpbGxhdG9yLnc7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlT3NjaWxsYXRvclN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleOscillatorState.ts b/lib/animators/states/ParticleOscillatorState.ts
new file mode 100644
index 000000000..0ddbd5490
--- /dev/null
+++ b/lib/animators/states/ParticleOscillatorState.ts
@@ -0,0 +1,82 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleOscillatorNode = require("awayjs-renderergl/lib/animators/nodes/ParticleOscillatorNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleOscillatorState extends ParticleStateBase
+{
+ /** @private */
+ public static OSCILLATOR_INDEX:number /*uint*/ = 0;
+
+ private _particleOscillatorNode:ParticleOscillatorNode;
+ private _oscillator:Vector3D;
+ private _oscillatorData:Vector3D;
+
+ /**
+ * Defines the default oscillator axis (x, y, z) and cycleDuration (w) of the state, used when in global mode.
+ */
+ public get oscillator():Vector3D
+ {
+ return this._oscillator;
+ }
+
+ public set oscillator(value:Vector3D)
+ {
+ this._oscillator = value;
+
+ this.updateOscillatorData();
+ }
+
+ constructor(animator:ParticleAnimator, particleOscillatorNode:ParticleOscillatorNode)
+ {
+ super(animator, particleOscillatorNode);
+
+ this._particleOscillatorNode = particleOscillatorNode;
+ this._oscillator = this._particleOscillatorNode._iOscillator;
+
+ this.updateOscillatorData();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleOscillatorState.OSCILLATOR_INDEX);
+
+ if (this._particleOscillatorNode.mode == ParticlePropertiesMode.LOCAL_STATIC)
+ animationSubGeometry.activateVertexBuffer(index, this._particleOscillatorNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationRegisterCache.setVertexConst(index, this._oscillatorData.x, this._oscillatorData.y, this._oscillatorData.z, this._oscillatorData.w);
+ }
+
+ private updateOscillatorData()
+ {
+ if (this._particleOscillatorNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._oscillator.w <= 0)
+ throw(new Error("the cycle duration must greater than zero"));
+
+ if (this._oscillatorData == null)
+ this._oscillatorData = new Vector3D();
+
+ this._oscillatorData.x = this._oscillator.x;
+ this._oscillatorData.y = this._oscillator.y;
+ this._oscillatorData.z = this._oscillator.z;
+ this._oscillatorData.w = Math.PI*2/this._oscillator.w;
+ }
+ }
+}
+
+export = ParticleOscillatorState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticlePositionState.js b/lib/animators/states/ParticlePositionState.js
new file mode 100755
index 000000000..009a32b44
--- /dev/null
+++ b/lib/animators/states/ParticlePositionState.js
@@ -0,0 +1,62 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ * @author ...
+ */
+var ParticlePositionState = (function (_super) {
+ __extends(ParticlePositionState, _super);
+ function ParticlePositionState(animator, particlePositionNode) {
+ _super.call(this, animator, particlePositionNode);
+ this._particlePositionNode = particlePositionNode;
+ this._position = this._particlePositionNode._iPosition;
+ }
+ Object.defineProperty(ParticlePositionState.prototype, "position", {
+ /**
+ * Defines the position of the particle when in global mode. Defaults to 0,0,0.
+ */
+ get: function () {
+ return this._position;
+ },
+ set: function (value) {
+ this._position = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ *
+ */
+ ParticlePositionState.prototype.getPositions = function () {
+ return this._pDynamicProperties;
+ };
+ ParticlePositionState.prototype.setPositions = function (value) {
+ this._pDynamicProperties = value;
+ this._pDynamicPropertiesDirty = new Object();
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticlePositionState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (this._particlePositionNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticlePositionState.POSITION_INDEX);
+ if (this._particlePositionNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._position.x, this._position.y, this._position.z);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particlePositionNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ };
+ /** @private */
+ ParticlePositionState.POSITION_INDEX = 0;
+ return ParticlePositionState;
+})(ParticleStateBase);
+module.exports = ParticlePositionState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVwb3NpdGlvbnN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlUG9zaXRpb25TdGF0ZSIsIlBhcnRpY2xlUG9zaXRpb25TdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlUG9zaXRpb25TdGF0ZS5wb3NpdGlvbiIsIlBhcnRpY2xlUG9zaXRpb25TdGF0ZS5nZXRQb3NpdGlvbnMiLCJQYXJ0aWNsZVBvc2l0aW9uU3RhdGUuc2V0UG9zaXRpb25zIiwiUGFydGljbGVQb3NpdGlvblN0YXRlLnNldFJlbmRlclN0YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUlBOzs7R0FERztJQUNHLHFCQUFxQjtJQUFTQSxVQUE5QkEscUJBQXFCQSxVQUEwQkE7SUFvQ3BEQSxTQXBDS0EscUJBQXFCQSxDQW9DZEEsUUFBeUJBLEVBQUVBLG9CQUF5Q0E7UUFFL0VDLGtCQUFNQSxRQUFRQSxFQUFFQSxvQkFBb0JBLENBQUNBLENBQUNBO1FBRXRDQSxJQUFJQSxDQUFDQSxxQkFBcUJBLEdBQUdBLG9CQUFvQkEsQ0FBQ0E7UUFDbERBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7SUFDeERBLENBQUNBO0lBL0JERCxzQkFBV0EsMkNBQVFBO1FBSG5CQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDdkJBLENBQUNBO2FBRURGLFVBQW9CQSxLQUFjQTtZQUVqQ0UsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDeEJBLENBQUNBOzs7T0FMQUY7SUFPREE7O09BRUdBO0lBQ0lBLDRDQUFZQSxHQUFuQkE7UUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQTtJQUNqQ0EsQ0FBQ0E7SUFFTUgsNENBQVlBLEdBQW5CQSxVQUFvQkEsS0FBcUJBO1FBRXhDSSxJQUFJQSxDQUFDQSxtQkFBbUJBLEdBQUdBLEtBQUtBLENBQUNBO1FBRWpDQSxJQUFJQSxDQUFDQSx3QkFBd0JBLEdBQUdBLElBQUlBLE1BQU1BLEVBQUVBLENBQUNBO0lBQzlDQSxDQUFDQTtJQVVESjs7T0FFR0E7SUFDSUEsOENBQWNBLEdBQXJCQSxVQUFzQkEsS0FBV0EsRUFBRUEsVUFBeUJBLEVBQUVBLG9CQUF5Q0EsRUFBRUEsc0JBQTZDQSxFQUFFQSxNQUFhQTtRQUVwS0ssRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxJQUFJQSxJQUFJQSxzQkFBc0JBLENBQUNBLGFBQWFBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQTtZQUM5SUEsSUFBSUEsQ0FBQ0EseUJBQXlCQSxDQUFDQSxvQkFBb0JBLENBQUNBLENBQUNBO1FBRXREQSxJQUFJQSxLQUFLQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLHFCQUFxQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFL0hBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsSUFBSUEsc0JBQXNCQSxDQUFDQSxNQUFNQSxDQUFDQTtZQUNwRUEsc0JBQXNCQSxDQUFDQSxjQUFjQSxDQUFDQSxLQUFLQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNwR0EsSUFBSUE7WUFDSEEsb0JBQW9CQSxDQUFDQSxvQkFBb0JBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsWUFBWUEsRUFBRUEsS0FBS0EsRUFBRUEsMkJBQTJCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtJQUN4SUEsQ0FBQ0E7SUF4RERMLGVBQWVBO0lBQ0RBLG9DQUFjQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUF3RGxEQSw0QkFBQ0E7QUFBREEsQ0EzREEsQUEyRENBLEVBM0RtQyxpQkFBaUIsRUEyRHBEO0FBRUQsQUFBK0IsaUJBQXRCLHFCQUFxQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVQb3NpdGlvblN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdG9yXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlUG9zaXRpb25Ob2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlUG9zaXRpb25Ob2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqIEBhdXRob3IgLi4uXG4gKi9cbmNsYXNzIFBhcnRpY2xlUG9zaXRpb25TdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFBPU0lUSU9OX0lOREVYOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0cHJpdmF0ZSBfcGFydGljbGVQb3NpdGlvbk5vZGU6UGFydGljbGVQb3NpdGlvbk5vZGU7XG5cdHByaXZhdGUgX3Bvc2l0aW9uOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgcGFydGljbGUgd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMCwwLDAuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHBvc2l0aW9uKCk6VmVjdG9yM0Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl9wb3NpdGlvbjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgcG9zaXRpb24odmFsdWU6VmVjdG9yM0QpXG5cdHtcblx0XHR0aGlzLl9wb3NpdGlvbiA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0UG9zaXRpb25zKCk6QXJyYXk8VmVjdG9yM0Q+XG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzO1xuXHR9XG5cblx0cHVibGljIHNldFBvc2l0aW9ucyh2YWx1ZTpBcnJheTxWZWN0b3IzRD4pXG5cdHtcblx0XHR0aGlzLl9wRHluYW1pY1Byb3BlcnRpZXMgPSB2YWx1ZTtcblxuXHRcdHRoaXMuX3BEeW5hbWljUHJvcGVydGllc0RpcnR5ID0gbmV3IE9iamVjdCgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVQb3NpdGlvbk5vZGU6UGFydGljbGVQb3NpdGlvbk5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVQb3NpdGlvbk5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVQb3NpdGlvbk5vZGUgPSBwYXJ0aWNsZVBvc2l0aW9uTm9kZTtcblx0XHR0aGlzLl9wb3NpdGlvbiA9IHRoaXMuX3BhcnRpY2xlUG9zaXRpb25Ob2RlLl9pUG9zaXRpb247XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZVBvc2l0aW9uTm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfRFlOQU1JQyAmJiAhdGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzRGlydHlbYW5pbWF0aW9uU3ViR2VvbWV0cnkuX2lVbmlxdWVJZF0pXG5cdFx0XHR0aGlzLl9wVXBkYXRlRHluYW1pY1Byb3BlcnRpZXMoYW5pbWF0aW9uU3ViR2VvbWV0cnkpO1xuXG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVBvc2l0aW9uU3RhdGUuUE9TSVRJT05fSU5ERVgpO1xuXG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlUG9zaXRpb25Ob2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl9wb3NpdGlvbi54LCB0aGlzLl9wb3NpdGlvbi55LCB0aGlzLl9wb3NpdGlvbi56KTtcblx0XHRlbHNlXG5cdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihpbmRleCwgdGhpcy5fcGFydGljbGVQb3NpdGlvbk5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlUG9zaXRpb25TdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticlePositionState.ts b/lib/animators/states/ParticlePositionState.ts
new file mode 100644
index 000000000..885418c9f
--- /dev/null
+++ b/lib/animators/states/ParticlePositionState.ts
@@ -0,0 +1,80 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticlePositionNode = require("awayjs-renderergl/lib/animators/nodes/ParticlePositionNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ * @author ...
+ */
+class ParticlePositionState extends ParticleStateBase
+{
+ /** @private */
+ public static POSITION_INDEX:number /*uint*/ = 0;
+
+ private _particlePositionNode:ParticlePositionNode;
+ private _position:Vector3D;
+
+ /**
+ * Defines the position of the particle when in global mode. Defaults to 0,0,0.
+ */
+ public get position():Vector3D
+ {
+ return this._position;
+ }
+
+ public set position(value:Vector3D)
+ {
+ this._position = value;
+ }
+
+ /**
+ *
+ */
+ public getPositions():Array
+ {
+ return this._pDynamicProperties;
+ }
+
+ public setPositions(value:Array)
+ {
+ this._pDynamicProperties = value;
+
+ this._pDynamicPropertiesDirty = new Object();
+ }
+
+ constructor(animator:ParticleAnimator, particlePositionNode:ParticlePositionNode)
+ {
+ super(animator, particlePositionNode);
+
+ this._particlePositionNode = particlePositionNode;
+ this._position = this._particlePositionNode._iPosition;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (this._particlePositionNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticlePositionState.POSITION_INDEX);
+
+ if (this._particlePositionNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._position.x, this._position.y, this._position.z);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particlePositionNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+}
+
+export = ParticlePositionState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotateToHeadingState.js b/lib/animators/states/ParticleRotateToHeadingState.js
new file mode 100755
index 000000000..013d40eb3
--- /dev/null
+++ b/lib/animators/states/ParticleRotateToHeadingState.js
@@ -0,0 +1,31 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleRotateToHeadingState = (function (_super) {
+ __extends(ParticleRotateToHeadingState, _super);
+ function ParticleRotateToHeadingState(animator, particleNode) {
+ _super.call(this, animator, particleNode);
+ this._matrix = new Matrix3D();
+ }
+ ParticleRotateToHeadingState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (animationRegisterCache.hasBillboard) {
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToHeadingState.MATRIX_INDEX), this._matrix);
+ }
+ };
+ /** @private */
+ ParticleRotateToHeadingState.MATRIX_INDEX = 0;
+ return ParticleRotateToHeadingState;
+})(ParticleStateBase);
+module.exports = ParticleRotateToHeadingState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVyb3RhdGV0b2hlYWRpbmdzdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ1N0YXRlIiwiUGFydGljbGVSb3RhdGVUb0hlYWRpbmdTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlUm90YXRlVG9IZWFkaW5nU3RhdGUuc2V0UmVuZGVyU3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBV3RFLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztHQURHO0lBQ0csNEJBQTRCO0lBQVNBLFVBQXJDQSw0QkFBNEJBLFVBQTBCQTtJQU8zREEsU0FQS0EsNEJBQTRCQSxDQU9yQkEsUUFBeUJBLEVBQUVBLFlBQTZCQTtRQUVuRUMsa0JBQU1BLFFBQVFBLEVBQUVBLFlBQVlBLENBQUNBLENBQUNBO1FBSnZCQSxZQUFPQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtJQUsxQ0EsQ0FBQ0E7SUFFTUQscURBQWNBLEdBQXJCQSxVQUFzQkEsS0FBV0EsRUFBRUEsVUFBeUJBLEVBQUVBLG9CQUF5Q0EsRUFBRUEsc0JBQTZDQSxFQUFFQSxNQUFhQTtRQUVwS0UsRUFBRUEsQ0FBQ0EsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6Q0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7WUFDOURBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLE1BQU1BLENBQUNBLE1BQU1BLENBQUNBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0E7WUFDbERBLHNCQUFzQkEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsNEJBQTRCQSxDQUFDQSxZQUFZQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUN6S0EsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFqQkRGLGVBQWVBO0lBQ0RBLHlDQUFZQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFrQi9DQSxtQ0FBQ0E7QUFBREEsQ0FyQkEsQUFxQkNBLEVBckIwQyxpQkFBaUIsRUFxQjNEO0FBRUQsQUFBc0MsaUJBQTdCLDRCQUE0QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVSb3RhdGVUb0hlYWRpbmdTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdG9yXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgUGFydGljbGVOb2RlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlTm9kZUJhc2VcIik7XG5pbXBvcnQgUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVSb3RhdGVUb0hlYWRpbmdOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVSb3RhdGVUb0hlYWRpbmdTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIE1BVFJJWF9JTkRFWDpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0cHJpdmF0ZSBfbWF0cml4Ok1hdHJpeDNEID0gbmV3IE1hdHJpeDNEKCk7XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVOb2RlOlBhcnRpY2xlTm9kZUJhc2UpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVOb2RlKTtcblx0fVxuXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZCkge1xuXHRcdFx0dGhpcy5fbWF0cml4LmNvcHlGcm9tKHJlbmRlcmFibGUuc291cmNlRW50aXR5LnNjZW5lVHJhbnNmb3JtKTtcblx0XHRcdHRoaXMuX21hdHJpeC5hcHBlbmQoY2FtZXJhLmludmVyc2VTY2VuZVRyYW5zZm9ybSk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0RnJvbU1hdHJpeChhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlUm90YXRlVG9IZWFkaW5nU3RhdGUuTUFUUklYX0lOREVYKSwgdGhpcy5fbWF0cml4KTtcblx0XHR9XG5cdH1cblxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVJvdGF0ZVRvSGVhZGluZ1N0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotateToHeadingState.ts b/lib/animators/states/ParticleRotateToHeadingState.ts
new file mode 100644
index 000000000..40939c73b
--- /dev/null
+++ b/lib/animators/states/ParticleRotateToHeadingState.ts
@@ -0,0 +1,40 @@
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import ParticleRotateToHeadingNode = require("awayjs-renderergl/lib/animators/nodes/ParticleRotateToHeadingNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleRotateToHeadingState extends ParticleStateBase
+{
+ /** @private */
+ public static MATRIX_INDEX:number /*int*/ = 0;
+
+ private _matrix:Matrix3D = new Matrix3D();
+
+ constructor(animator:ParticleAnimator, particleNode:ParticleNodeBase)
+ {
+ super(animator, particleNode);
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (animationRegisterCache.hasBillboard) {
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToHeadingState.MATRIX_INDEX), this._matrix);
+ }
+ }
+
+}
+
+export = ParticleRotateToHeadingState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotateToPositionState.js b/lib/animators/states/ParticleRotateToPositionState.js
new file mode 100755
index 000000000..a8b30378c
--- /dev/null
+++ b/lib/animators/states/ParticleRotateToPositionState.js
@@ -0,0 +1,57 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleRotateToPositionState = (function (_super) {
+ __extends(ParticleRotateToPositionState, _super);
+ function ParticleRotateToPositionState(animator, particleRotateToPositionNode) {
+ _super.call(this, animator, particleRotateToPositionNode);
+ this._matrix = new Matrix3D();
+ this._particleRotateToPositionNode = particleRotateToPositionNode;
+ this._position = this._particleRotateToPositionNode._iPosition;
+ }
+ Object.defineProperty(ParticleRotateToPositionState.prototype, "position", {
+ /**
+ * Defines the position of the point the particle will rotate to face when in global mode. Defaults to 0,0,0.
+ */
+ get: function () {
+ return this._position;
+ },
+ set: function (value) {
+ this._position = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleRotateToPositionState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToPositionState.POSITION_INDEX);
+ if (animationRegisterCache.hasBillboard) {
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToPositionState.MATRIX_INDEX), this._matrix);
+ }
+ if (this._particleRotateToPositionNode.mode == ParticlePropertiesMode.GLOBAL) {
+ this._offset = renderable.sourceEntity.inverseSceneTransform.transformVector(this._position);
+ animationRegisterCache.setVertexConst(index, this._offset.x, this._offset.y, this._offset.z);
+ }
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleRotateToPositionNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ };
+ /** @private */
+ ParticleRotateToPositionState.MATRIX_INDEX = 0;
+ /** @private */
+ ParticleRotateToPositionState.POSITION_INDEX = 1;
+ return ParticleRotateToPositionState;
+})(ParticleStateBase);
+module.exports = ParticleRotateToPositionState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVyb3RhdGV0b3Bvc2l0aW9uc3RhdGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGUiLCJQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25TdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlLnBvc2l0aW9uIiwiUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGUuc2V0UmVuZGVyU3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBT3RFLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQUk3RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFFekcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyw2QkFBNkI7SUFBU0EsVUFBdENBLDZCQUE2QkEsVUFBMEJBO0lBeUI1REEsU0F6QktBLDZCQUE2QkEsQ0F5QnRCQSxRQUF5QkEsRUFBRUEsNEJBQXlEQTtRQUUvRkMsa0JBQU1BLFFBQVFBLEVBQUVBLDRCQUE0QkEsQ0FBQ0EsQ0FBQ0E7UUFsQnZDQSxZQUFPQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtRQW9CekNBLElBQUlBLENBQUNBLDZCQUE2QkEsR0FBR0EsNEJBQTRCQSxDQUFDQTtRQUNsRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsNkJBQTZCQSxDQUFDQSxVQUFVQSxDQUFDQTtJQUNoRUEsQ0FBQ0E7SUFoQkRELHNCQUFXQSxtREFBUUE7UUFIbkJBOztXQUVHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN2QkEsQ0FBQ0E7YUFFREYsVUFBb0JBLEtBQWNBO1lBRWpDRSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7OztPQUxBRjtJQWVNQSxzREFBY0EsR0FBckJBLFVBQXNCQSxLQUFXQSxFQUFFQSxVQUF5QkEsRUFBRUEsb0JBQXlDQSxFQUFFQSxzQkFBNkNBLEVBQUVBLE1BQWFBO1FBRXBLRyxJQUFJQSxLQUFLQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLDZCQUE2QkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFdklBLEVBQUVBLENBQUNBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDekNBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLFFBQVFBLENBQUNBLFVBQVVBLENBQUNBLFlBQVlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBO1lBQzlEQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQSxxQkFBcUJBLENBQUNBLENBQUNBO1lBQ2xEQSxzQkFBc0JBLENBQUNBLHdCQUF3QkEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLDZCQUE2QkEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0E7UUFDMUtBLENBQUNBO1FBRURBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLDZCQUE2QkEsQ0FBQ0EsSUFBSUEsSUFBSUEsc0JBQXNCQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUM5RUEsSUFBSUEsQ0FBQ0EsT0FBT0EsR0FBR0EsVUFBVUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtZQUM3RkEsc0JBQXNCQSxDQUFDQSxjQUFjQSxDQUFDQSxLQUFLQSxFQUFFQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM5RkEsQ0FBQ0E7UUFBQ0EsSUFBSUE7WUFDTEEsb0JBQW9CQSxDQUFDQSxvQkFBb0JBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLDZCQUE2QkEsQ0FBQ0EsWUFBWUEsRUFBRUEsS0FBS0EsRUFBRUEsMkJBQTJCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtJQUVoSkEsQ0FBQ0E7SUEvQ0RILGVBQWVBO0lBQ0RBLDBDQUFZQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFDOUNBLGVBQWVBO0lBQ0RBLDRDQUFjQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUE4Q2pEQSxvQ0FBQ0E7QUFBREEsQ0FuREEsQUFtRENBLEVBbkQyQyxpQkFBaUIsRUFtRDVEO0FBRUQsQUFBdUMsaUJBQTlCLDZCQUE2QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTWF0cml4M0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RcIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25TdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIE1BVFJJWF9JTkRFWDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFBPU0lUSU9OX0lOREVYOm51bWJlciAvKmludCovID0gMTtcblxuXHRwcml2YXRlIF9wYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlOlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGU7XG5cdHByaXZhdGUgX3Bvc2l0aW9uOlZlY3RvcjNEO1xuXHRwcml2YXRlIF9tYXRyaXg6TWF0cml4M0QgPSBuZXcgTWF0cml4M0QoKTtcblx0cHJpdmF0ZSBfb2Zmc2V0OlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgcG9pbnQgdGhlIHBhcnRpY2xlIHdpbGwgcm90YXRlIHRvIGZhY2Ugd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMCwwLDAuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHBvc2l0aW9uKCk6VmVjdG9yM0Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl9wb3NpdGlvbjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgcG9zaXRpb24odmFsdWU6VmVjdG9yM0QpXG5cdHtcblx0XHR0aGlzLl9wb3NpdGlvbiA9IHZhbHVlO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZTpQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZSA9IHBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGU7XG5cdFx0dGhpcy5fcG9zaXRpb24gPSB0aGlzLl9wYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLl9pUG9zaXRpb247XG5cdH1cblxuXHRwdWJsaWMgc2V0UmVuZGVyU3RhdGUoc3RhZ2U6U3RhZ2UsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5LCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlLlBPU0lUSU9OX0lOREVYKTtcblxuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLmhhc0JpbGxib2FyZCkge1xuXHRcdFx0dGhpcy5fbWF0cml4LmNvcHlGcm9tKHJlbmRlcmFibGUuc291cmNlRW50aXR5LnNjZW5lVHJhbnNmb3JtKTtcblx0XHRcdHRoaXMuX21hdHJpeC5hcHBlbmQoY2FtZXJhLmludmVyc2VTY2VuZVRyYW5zZm9ybSk7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0RnJvbU1hdHJpeChhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvblN0YXRlLk1BVFJJWF9JTkRFWCksIHRoaXMuX21hdHJpeCk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCkge1xuXHRcdFx0dGhpcy5fb2Zmc2V0ID0gcmVuZGVyYWJsZS5zb3VyY2VFbnRpdHkuaW52ZXJzZVNjZW5lVHJhbnNmb3JtLnRyYW5zZm9ybVZlY3Rvcih0aGlzLl9wb3NpdGlvbik7XG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl9vZmZzZXQueCwgdGhpcy5fb2Zmc2V0LnksIHRoaXMuX29mZnNldC56KTtcblx0XHR9IGVsc2Vcblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLl9pRGF0YU9mZnNldCwgc3RhZ2UsIENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdC5GTE9BVF8zKTtcblxuXHR9XG5cbn1cblxuZXhwb3J0ID0gUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uU3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotateToPositionState.ts b/lib/animators/states/ParticleRotateToPositionState.ts
new file mode 100644
index 000000000..8455db2cd
--- /dev/null
+++ b/lib/animators/states/ParticleRotateToPositionState.ts
@@ -0,0 +1,72 @@
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleRotateToPositionNode = require("awayjs-renderergl/lib/animators/nodes/ParticleRotateToPositionNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleRotateToPositionState extends ParticleStateBase
+{
+ /** @private */
+ public static MATRIX_INDEX:number /*int*/ = 0;
+ /** @private */
+ public static POSITION_INDEX:number /*int*/ = 1;
+
+ private _particleRotateToPositionNode:ParticleRotateToPositionNode;
+ private _position:Vector3D;
+ private _matrix:Matrix3D = new Matrix3D();
+ private _offset:Vector3D;
+
+ /**
+ * Defines the position of the point the particle will rotate to face when in global mode. Defaults to 0,0,0.
+ */
+ public get position():Vector3D
+ {
+ return this._position;
+ }
+
+ public set position(value:Vector3D)
+ {
+ this._position = value;
+ }
+
+ constructor(animator:ParticleAnimator, particleRotateToPositionNode:ParticleRotateToPositionNode)
+ {
+ super(animator, particleRotateToPositionNode);
+
+ this._particleRotateToPositionNode = particleRotateToPositionNode;
+ this._position = this._particleRotateToPositionNode._iPosition;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToPositionState.POSITION_INDEX);
+
+ if (animationRegisterCache.hasBillboard) {
+ this._matrix.copyFrom(renderable.sourceEntity.sceneTransform);
+ this._matrix.append(camera.inverseSceneTransform);
+ animationRegisterCache.setVertexConstFromMatrix(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotateToPositionState.MATRIX_INDEX), this._matrix);
+ }
+
+ if (this._particleRotateToPositionNode.mode == ParticlePropertiesMode.GLOBAL) {
+ this._offset = renderable.sourceEntity.inverseSceneTransform.transformVector(this._position);
+ animationRegisterCache.setVertexConst(index, this._offset.x, this._offset.y, this._offset.z);
+ } else
+ animationSubGeometry.activateVertexBuffer(index, this._particleRotateToPositionNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+
+ }
+
+}
+
+export = ParticleRotateToPositionState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotationalVelocityState.js b/lib/animators/states/ParticleRotationalVelocityState.js
new file mode 100755
index 000000000..7a88bb4c8
--- /dev/null
+++ b/lib/animators/states/ParticleRotationalVelocityState.js
@@ -0,0 +1,77 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleRotationalVelocityState = (function (_super) {
+ __extends(ParticleRotationalVelocityState, _super);
+ function ParticleRotationalVelocityState(animator, particleRotationNode) {
+ _super.call(this, animator, particleRotationNode);
+ this._particleRotationalVelocityNode = particleRotationNode;
+ this._rotationalVelocity = this._particleRotationalVelocityNode._iRotationalVelocity;
+ this.updateRotationalVelocityData();
+ }
+ Object.defineProperty(ParticleRotationalVelocityState.prototype, "rotationalVelocity", {
+ /**
+ * Defines the default rotationalVelocity of the state, used when in global mode.
+ */
+ get: function () {
+ return this._rotationalVelocity;
+ },
+ set: function (value) {
+ this._rotationalVelocity = value;
+ this.updateRotationalVelocityData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ *
+ */
+ ParticleRotationalVelocityState.prototype.getRotationalVelocities = function () {
+ return this._pDynamicProperties;
+ };
+ ParticleRotationalVelocityState.prototype.setRotationalVelocities = function (value) {
+ this._pDynamicProperties = value;
+ this._pDynamicPropertiesDirty = new Object();
+ };
+ /**
+ * @inheritDoc
+ */
+ ParticleRotationalVelocityState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotationalVelocityState.ROTATIONALVELOCITY_INDEX);
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._rotationalVelocityData.x, this._rotationalVelocityData.y, this._rotationalVelocityData.z, this._rotationalVelocityData.w);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleRotationalVelocityNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ };
+ ParticleRotationalVelocityState.prototype.updateRotationalVelocityData = function () {
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._rotationalVelocity.w <= 0)
+ throw (new Error("the cycle duration must greater than zero"));
+ var rotation = this._rotationalVelocity.clone();
+ if (rotation.length <= 0)
+ rotation.z = 1; //set the default direction
+ else
+ rotation.normalize();
+ // w is used as angle/2 in agal
+ this._rotationalVelocityData = new Vector3D(rotation.x, rotation.y, rotation.z, Math.PI / rotation.w);
+ }
+ };
+ /** @private */
+ ParticleRotationalVelocityState.ROTATIONALVELOCITY_INDEX = 0;
+ return ParticleRotationalVelocityState;
+})(ParticleStateBase);
+module.exports = ParticleRotationalVelocityState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVyb3RhdGlvbmFsdmVsb2NpdHlzdGF0ZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eVN0YXRlIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGUucm90YXRpb25hbFZlbG9jaXR5IiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZS5nZXRSb3RhdGlvbmFsVmVsb2NpdGllcyIsIlBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGUuc2V0Um90YXRpb25hbFZlbG9jaXRpZXMiLCJQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eVN0YXRlLnNldFJlbmRlclN0YXRlIiwiUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZS51cGRhdGVSb3RhdGlvbmFsVmVsb2NpdHlEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQU10RSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztHQURHO0lBQ0csK0JBQStCO0lBQVNBLFVBQXhDQSwrQkFBK0JBLFVBQTBCQTtJQXVDOURBLFNBdkNLQSwrQkFBK0JBLENBdUN4QkEsUUFBeUJBLEVBQUVBLG9CQUFtREE7UUFFekZDLGtCQUFNQSxRQUFRQSxFQUFFQSxvQkFBb0JBLENBQUNBLENBQUNBO1FBRXRDQSxJQUFJQSxDQUFDQSwrQkFBK0JBLEdBQUdBLG9CQUFvQkEsQ0FBQ0E7UUFDNURBLElBQUlBLENBQUNBLG1CQUFtQkEsR0FBR0EsSUFBSUEsQ0FBQ0EsK0JBQStCQSxDQUFDQSxvQkFBb0JBLENBQUNB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QSxDQUFDQSxFQUFFQSwyQkFBMkJBO1lBQzVDQSxJQURnQkEsQUFDWkE7Z0JBQ0hBLFFBQVFBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBO1lBQ3RCQSxBQUNBQSwrQkFEK0JBO1lBQy9CQSxJQUFJQSxDQUFDQSx1QkFBdUJBLEdBQUdBLElBQUlBLFFBQVFBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ3JHQSxDQUFDQTtJQUNGQSxDQUFDQTtJQTdFRE4sZUFBZUE7SUFDREEsd0RBQXdCQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUE2RTVEQSxzQ0FBQ0E7QUFBREEsQ0FoRkEsQUFnRkNBLEVBaEY2QyxpQkFBaUIsRUFnRjlEO0FBRUQsQUFBeUMsaUJBQWhDLCtCQUErQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGVcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFJPVEFUSU9OQUxWRUxPQ0lUWV9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdHByaXZhdGUgX3BhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5Tm9kZTpQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGU7XG5cdHByaXZhdGUgX3JvdGF0aW9uYWxWZWxvY2l0eURhdGE6VmVjdG9yM0Q7XG5cdHByaXZhdGUgX3JvdGF0aW9uYWxWZWxvY2l0eTpWZWN0b3IzRDtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZGVmYXVsdCByb3RhdGlvbmFsVmVsb2NpdHkgb2YgdGhlIHN0YXRlLCB1c2VkIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHJvdGF0aW9uYWxWZWxvY2l0eSgpOlZlY3RvcjNEXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcm90YXRpb25hbFZlbG9jaXR5O1xuXHR9XG5cblx0cHVibGljIHNldCByb3RhdGlvbmFsVmVsb2NpdHkodmFsdWU6VmVjdG9yM0QpXG5cdHtcblx0XHR0aGlzLl9yb3RhdGlvbmFsVmVsb2NpdHkgPSB2YWx1ZTtcblxuXHRcdHRoaXMudXBkYXRlUm90YXRpb25hbFZlbG9jaXR5RGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0Um90YXRpb25hbFZlbG9jaXRpZXMoKTpBcnJheTxWZWN0b3IzRD5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9wRHluYW1pY1Byb3BlcnRpZXM7XG5cdH1cblxuXHRwdWJsaWMgc2V0Um90YXRpb25hbFZlbG9jaXRpZXModmFsdWU6QXJyYXk8VmVjdG9yM0Q+KVxuXHR7XG5cdFx0dGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzID0gdmFsdWU7XG5cblx0XHR0aGlzLl9wRHluYW1pY1Byb3BlcnRpZXNEaXJ0eSA9IG5ldyBPYmplY3QoKTtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlUm90YXRpb25Ob2RlOlBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5Tm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZVJvdGF0aW9uTm9kZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUgPSBwYXJ0aWNsZVJvdGF0aW9uTm9kZTtcblx0XHR0aGlzLl9yb3RhdGlvbmFsVmVsb2NpdHkgPSB0aGlzLl9wYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUuX2lSb3RhdGlvbmFsVmVsb2NpdHk7XG5cblx0XHR0aGlzLnVwZGF0ZVJvdGF0aW9uYWxWZWxvY2l0eURhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5Tm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfRFlOQU1JQyAmJiAhdGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzRGlydHlbYW5pbWF0aW9uU3ViR2VvbWV0cnkuX2lVbmlxdWVJZF0pXG5cdFx0XHR0aGlzLl9wVXBkYXRlRHluYW1pY1Byb3BlcnRpZXMoYW5pbWF0aW9uU3ViR2VvbWV0cnkpO1xuXG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eVN0YXRlLlJPVEFUSU9OQUxWRUxPQ0lUWV9JTkRFWCk7XG5cblx0XHRpZiAodGhpcy5fcGFydGljbGVSb3RhdGlvbmFsVmVsb2NpdHlOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl9yb3RhdGlvbmFsVmVsb2NpdHlEYXRhLngsIHRoaXMuX3JvdGF0aW9uYWxWZWxvY2l0eURhdGEueSwgdGhpcy5fcm90YXRpb25hbFZlbG9jaXR5RGF0YS56LCB0aGlzLl9yb3RhdGlvbmFsVmVsb2NpdHlEYXRhLncpO1xuXHRcdGVsc2Vcblx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzQpO1xuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVSb3RhdGlvbmFsVmVsb2NpdHlEYXRhKClcblx0e1xuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZVJvdGF0aW9uYWxWZWxvY2l0eU5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCkge1xuXHRcdFx0aWYgKHRoaXMuX3JvdGF0aW9uYWxWZWxvY2l0eS53IDw9IDApXG5cdFx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHRcdHZhciByb3RhdGlvbjpWZWN0b3IzRCA9IHRoaXMuX3JvdGF0aW9uYWxWZWxvY2l0eS5jbG9uZSgpO1xuXG5cdFx0XHRpZiAocm90YXRpb24ubGVuZ3RoIDw9IDApXG5cdFx0XHRcdHJvdGF0aW9uLnogPSAxOyAvL3NldCB0aGUgZGVmYXVsdCBkaXJlY3Rpb25cblx0XHRcdGVsc2Vcblx0XHRcdFx0cm90YXRpb24ubm9ybWFsaXplKCk7XG5cdFx0XHQvLyB3IGlzIHVzZWQgYXMgYW5nbGUvMiBpbiBhZ2FsXG5cdFx0XHR0aGlzLl9yb3RhdGlvbmFsVmVsb2NpdHlEYXRhID0gbmV3IFZlY3RvcjNEKHJvdGF0aW9uLngsIHJvdGF0aW9uLnksIHJvdGF0aW9uLnosIE1hdGguUEkvcm90YXRpb24udyk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlUm90YXRpb25hbFZlbG9jaXR5U3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/ParticleRotationalVelocityState.ts b/lib/animators/states/ParticleRotationalVelocityState.ts
new file mode 100644
index 000000000..90a34fadf
--- /dev/null
+++ b/lib/animators/states/ParticleRotationalVelocityState.ts
@@ -0,0 +1,100 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleRotationalVelocityNode = require("awayjs-renderergl/lib/animators/nodes/ParticleRotationalVelocityNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleRotationalVelocityState extends ParticleStateBase
+{
+ /** @private */
+ public static ROTATIONALVELOCITY_INDEX:number /*uint*/ = 0;
+
+ private _particleRotationalVelocityNode:ParticleRotationalVelocityNode;
+ private _rotationalVelocityData:Vector3D;
+ private _rotationalVelocity:Vector3D;
+
+ /**
+ * Defines the default rotationalVelocity of the state, used when in global mode.
+ */
+ public get rotationalVelocity():Vector3D
+ {
+ return this._rotationalVelocity;
+ }
+
+ public set rotationalVelocity(value:Vector3D)
+ {
+ this._rotationalVelocity = value;
+
+ this.updateRotationalVelocityData();
+ }
+
+ /**
+ *
+ */
+ public getRotationalVelocities():Array
+ {
+ return this._pDynamicProperties;
+ }
+
+ public setRotationalVelocities(value:Array)
+ {
+ this._pDynamicProperties = value;
+
+ this._pDynamicPropertiesDirty = new Object();
+ }
+
+ constructor(animator:ParticleAnimator, particleRotationNode:ParticleRotationalVelocityNode)
+ {
+ super(animator, particleRotationNode);
+
+ this._particleRotationalVelocityNode = particleRotationNode;
+ this._rotationalVelocity = this._particleRotationalVelocityNode._iRotationalVelocity;
+
+ this.updateRotationalVelocityData();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleRotationalVelocityState.ROTATIONALVELOCITY_INDEX);
+
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._rotationalVelocityData.x, this._rotationalVelocityData.y, this._rotationalVelocityData.z, this._rotationalVelocityData.w);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleRotationalVelocityNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ }
+
+ private updateRotationalVelocityData()
+ {
+ if (this._particleRotationalVelocityNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._rotationalVelocity.w <= 0)
+ throw(new Error("the cycle duration must greater than zero"));
+ var rotation:Vector3D = this._rotationalVelocity.clone();
+
+ if (rotation.length <= 0)
+ rotation.z = 1; //set the default direction
+ else
+ rotation.normalize();
+ // w is used as angle/2 in agal
+ this._rotationalVelocityData = new Vector3D(rotation.x, rotation.y, rotation.z, Math.PI/rotation.w);
+ }
+ }
+}
+
+export = ParticleRotationalVelocityState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleScaleState.js b/lib/animators/states/ParticleScaleState.js
new file mode 100755
index 000000000..e04312cd2
--- /dev/null
+++ b/lib/animators/states/ParticleScaleState.js
@@ -0,0 +1,115 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleScaleState = (function (_super) {
+ __extends(ParticleScaleState, _super);
+ function ParticleScaleState(animator, particleScaleNode) {
+ _super.call(this, animator, particleScaleNode);
+ this._particleScaleNode = particleScaleNode;
+ this._usesCycle = this._particleScaleNode._iUsesCycle;
+ this._usesPhase = this._particleScaleNode._iUsesPhase;
+ this._minScale = this._particleScaleNode._iMinScale;
+ this._maxScale = this._particleScaleNode._iMaxScale;
+ this._cycleDuration = this._particleScaleNode._iCycleDuration;
+ this._cyclePhase = this._particleScaleNode._iCyclePhase;
+ this.updateScaleData();
+ }
+ Object.defineProperty(ParticleScaleState.prototype, "minScale", {
+ /**
+ * Defines the end scale of the state, when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._minScale;
+ },
+ set: function (value) {
+ this._minScale = value;
+ this.updateScaleData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleScaleState.prototype, "maxScale", {
+ /**
+ * Defines the end scale of the state, when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._maxScale;
+ },
+ set: function (value) {
+ this._maxScale = value;
+ this.updateScaleData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleScaleState.prototype, "cycleDuration", {
+ /**
+ * Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._cycleDuration;
+ },
+ set: function (value) {
+ this._cycleDuration = value;
+ this.updateScaleData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleScaleState.prototype, "cyclePhase", {
+ /**
+ * Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ get: function () {
+ return this._cyclePhase;
+ },
+ set: function (value) {
+ this._cyclePhase = value;
+ this.updateScaleData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleScaleState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleScaleState.SCALE_INDEX);
+ if (this._particleScaleNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesCycle) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_2);
+ }
+ else
+ animationRegisterCache.setVertexConst(index, this._scaleData.x, this._scaleData.y, this._scaleData.z, this._scaleData.w);
+ };
+ ParticleScaleState.prototype.updateScaleData = function () {
+ if (this._particleScaleNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._scaleData = new Vector3D((this._minScale + this._maxScale) / 2, Math.abs(this._minScale - this._maxScale) / 2, Math.PI * 2 / this._cycleDuration, this._cyclePhase * Math.PI / 180);
+ }
+ else
+ this._scaleData = new Vector3D(this._minScale, this._maxScale - this._minScale, 0, 0);
+ }
+ };
+ /** @private */
+ ParticleScaleState.SCALE_INDEX = 0;
+ return ParticleScaleState;
+})(ParticleStateBase);
+module.exports = ParticleScaleState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVzY2FsZXN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlU2NhbGVTdGF0ZSIsIlBhcnRpY2xlU2NhbGVTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlU2NhbGVTdGF0ZS5taW5TY2FsZSIsIlBhcnRpY2xlU2NhbGVTdGF0ZS5tYXhTY2FsZSIsIlBhcnRpY2xlU2NhbGVTdGF0ZS5jeWNsZUR1cmF0aW9uIiwiUGFydGljbGVTY2FsZVN0YXRlLmN5Y2xlUGhhc2UiLCJQYXJ0aWNsZVNjYWxlU3RhdGUuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZVNjYWxlU3RhdGUudXBkYXRlU2NhbGVEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQU10RSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTBCQTtJQTBFakRBLFNBMUVLQSxrQkFBa0JBLENBMEVYQSxRQUF5QkEsRUFBRUEsaUJBQW1DQTtRQUV6RUMsa0JBQU1BLFFBQVFBLEVBQUVBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0E7UUFFbkNBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsaUJBQWlCQSxDQUFDQTtRQUM1Q0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUN0REEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUN0REEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFD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LEdBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGNBQWNBLEVBQUVBLElBQUlBLENBQUNBLFdBQVdBLEdBQUNBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQy9LQSxDQUFDQTtZQUFDQSxJQUFJQTtnQkFDTEEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDeEZBLENBQUNBO0lBQ0ZBLENBQUNBO0lBakhEUCxlQUFlQTtJQUNEQSw4QkFBV0EsR0FBbUJBLENBQUNBLENBQUNBO0lBaUgvQ0EseUJBQUNBO0FBQURBLENBcEhBLEFBb0hDQSxFQXBIZ0MsaUJBQWlCLEVBb0hqRDtBQUVELEFBQTRCLGlCQUFuQixrQkFBa0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU2NhbGVTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVNjYWxlTm9kZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZVNjYWxlTm9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZVN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVTdGF0ZUJhc2VcIik7XG5cbi8qKlxuICogLi4uXG4gKi9cbmNsYXNzIFBhcnRpY2xlU2NhbGVTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFNDQUxFX0lOREVYOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0cHJpdmF0ZSBfcGFydGljbGVTY2FsZU5vZGU6UGFydGljbGVTY2FsZU5vZGU7XG5cdHByaXZhdGUgX3VzZXNDeWNsZTpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzUGhhc2U6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfbWluU2NhbGU6bnVtYmVyO1xuXHRwcml2YXRlIF9tYXhTY2FsZTpudW1iZXI7XG5cdHByaXZhdGUgX2N5Y2xlRHVyYXRpb246bnVtYmVyO1xuXHRwcml2YXRlIF9jeWNsZVBoYXNlOm51bWJlcjtcblx0cHJpdmF0ZSBfc2NhbGVEYXRhOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBlbmQgc2NhbGUgb2YgdGhlIHN0YXRlLCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKi9cblx0cHVibGljIGdldCBtaW5TY2FsZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX21pblNjYWxlO1xuXHR9XG5cblx0cHVibGljIHNldCBtaW5TY2FsZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9taW5TY2FsZSA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVTY2FsZURhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBlbmQgc2NhbGUgb2YgdGhlIHN0YXRlLCB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAxLlxuXHQgKi9cblx0cHVibGljIGdldCBtYXhTY2FsZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX21heFNjYWxlO1xuXHR9XG5cblx0cHVibGljIHNldCBtYXhTY2FsZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9tYXhTY2FsZSA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVTY2FsZURhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluIHNlY29uZHMsIHVzZWQgYXMgYSBwZXJpb2QgaW5kZXBlbmRlbnQgb2YgcGFydGljbGUgZHVyYXRpb24gd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMS5cblx0ICovXG5cdHB1YmxpYyBnZXQgY3ljbGVEdXJhdGlvbigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N5Y2xlRHVyYXRpb247XG5cdH1cblxuXHRwdWJsaWMgc2V0IGN5Y2xlRHVyYXRpb24odmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fY3ljbGVEdXJhdGlvbiA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVTY2FsZURhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSBwaGFzZSBvZiB0aGUgY3ljbGUgaW4gZGVncmVlcywgdXNlZCBhcyB0aGUgc3RhcnRpbmcgb2Zmc2V0IG9mIHRoZSBjeWNsZSB3aGVuIGluIGdsb2JhbCBtb2RlLiBEZWZhdWx0cyB0byAwLlxuXHQgKi9cblx0cHVibGljIGdldCBjeWNsZVBoYXNlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY3ljbGVQaGFzZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgY3ljbGVQaGFzZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9jeWNsZVBoYXNlID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZVNjYWxlRGF0YSgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVTY2FsZU5vZGU6UGFydGljbGVTY2FsZU5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVTY2FsZU5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVTY2FsZU5vZGUgPSBwYXJ0aWNsZVNjYWxlTm9kZTtcblx0XHR0aGlzLl91c2VzQ3ljbGUgPSB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faVVzZXNDeWNsZTtcblx0XHR0aGlzLl91c2VzUGhhc2UgPSB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faVVzZXNQaGFzZTtcblx0XHR0aGlzLl9taW5TY2FsZSA9IHRoaXMuX3BhcnRpY2xlU2NhbGVOb2RlLl9pTWluU2NhbGU7XG5cdFx0dGhpcy5fbWF4U2NhbGUgPSB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faU1heFNjYWxlO1xuXHRcdHRoaXMuX2N5Y2xlRHVyYXRpb24gPSB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faUN5Y2xlRHVyYXRpb247XG5cdFx0dGhpcy5fY3ljbGVQaGFzZSA9IHRoaXMuX3BhcnRpY2xlU2NhbGVOb2RlLl9pQ3ljbGVQaGFzZTtcblxuXHRcdHRoaXMudXBkYXRlU2NhbGVEYXRhKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0UmVuZGVyU3RhdGUoc3RhZ2U6U3RhZ2UsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5LCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlU2NhbGVTdGF0ZS5TQ0FMRV9JTkRFWCk7XG5cblx0XHRpZiAodGhpcy5fcGFydGljbGVTY2FsZU5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQykge1xuXHRcdFx0aWYgKHRoaXMuX3VzZXNDeWNsZSkge1xuXHRcdFx0XHRpZiAodGhpcy5fdXNlc1BoYXNlKVxuXHRcdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfNCk7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihpbmRleCwgdGhpcy5fcGFydGljbGVTY2FsZU5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHRcdFx0fSBlbHNlXG5cdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZVNjYWxlTm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfMik7XG5cdFx0fSBlbHNlXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl9zY2FsZURhdGEueCwgdGhpcy5fc2NhbGVEYXRhLnksIHRoaXMuX3NjYWxlRGF0YS56LCB0aGlzLl9zY2FsZURhdGEudyk7XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZVNjYWxlRGF0YSgpXG5cdHtcblx0XHRpZiAodGhpcy5fcGFydGljbGVTY2FsZU5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkdMT0JBTCkge1xuXHRcdFx0aWYgKHRoaXMuX3VzZXNDeWNsZSkge1xuXHRcdFx0XHRpZiAodGhpcy5fY3ljbGVEdXJhdGlvbiA8PSAwKVxuXHRcdFx0XHRcdHRocm93KG5ldyBFcnJvcihcInRoZSBjeWNsZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvXCIpKTtcblx0XHRcdFx0dGhpcy5fc2NhbGVEYXRhID0gbmV3IFZlY3RvcjNEKCh0aGlzLl9taW5TY2FsZSArIHRoaXMuX21heFNjYWxlKS8yLCBNYXRoLmFicyh0aGlzLl9taW5TY2FsZSAtIHRoaXMuX21heFNjYWxlKS8yLCBNYXRoLlBJKjIvdGhpcy5fY3ljbGVEdXJhdGlvbiwgdGhpcy5fY3ljbGVQaGFzZSpNYXRoLlBJLzE4MCk7XG5cdFx0XHR9IGVsc2Vcblx0XHRcdFx0dGhpcy5fc2NhbGVEYXRhID0gbmV3IFZlY3RvcjNEKHRoaXMuX21pblNjYWxlLCB0aGlzLl9tYXhTY2FsZSAtIHRoaXMuX21pblNjYWxlLCAwLCAwKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVTY2FsZVN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleScaleState.ts b/lib/animators/states/ParticleScaleState.ts
new file mode 100644
index 000000000..e3e7a8802
--- /dev/null
+++ b/lib/animators/states/ParticleScaleState.ts
@@ -0,0 +1,136 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleScaleNode = require("awayjs-renderergl/lib/animators/nodes/ParticleScaleNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleScaleState extends ParticleStateBase
+{
+ /** @private */
+ public static SCALE_INDEX:number /*uint*/ = 0;
+
+ private _particleScaleNode:ParticleScaleNode;
+ private _usesCycle:boolean;
+ private _usesPhase:boolean;
+ private _minScale:number;
+ private _maxScale:number;
+ private _cycleDuration:number;
+ private _cyclePhase:number;
+ private _scaleData:Vector3D;
+
+ /**
+ * Defines the end scale of the state, when in global mode. Defaults to 1.
+ */
+ public get minScale():number
+ {
+ return this._minScale;
+ }
+
+ public set minScale(value:number)
+ {
+ this._minScale = value;
+
+ this.updateScaleData();
+ }
+
+ /**
+ * Defines the end scale of the state, when in global mode. Defaults to 1.
+ */
+ public get maxScale():number
+ {
+ return this._maxScale;
+ }
+
+ public set maxScale(value:number)
+ {
+ this._maxScale = value;
+
+ this.updateScaleData();
+ }
+
+ /**
+ * Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
+ */
+ public get cycleDuration():number
+ {
+ return this._cycleDuration;
+ }
+
+ public set cycleDuration(value:number)
+ {
+ this._cycleDuration = value;
+
+ this.updateScaleData();
+ }
+
+ /**
+ * Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
+ */
+ public get cyclePhase():number
+ {
+ return this._cyclePhase;
+ }
+
+ public set cyclePhase(value:number)
+ {
+ this._cyclePhase = value;
+
+ this.updateScaleData();
+ }
+
+ constructor(animator:ParticleAnimator, particleScaleNode:ParticleScaleNode)
+ {
+ super(animator, particleScaleNode);
+
+ this._particleScaleNode = particleScaleNode;
+ this._usesCycle = this._particleScaleNode._iUsesCycle;
+ this._usesPhase = this._particleScaleNode._iUsesPhase;
+ this._minScale = this._particleScaleNode._iMinScale;
+ this._maxScale = this._particleScaleNode._iMaxScale;
+ this._cycleDuration = this._particleScaleNode._iCycleDuration;
+ this._cyclePhase = this._particleScaleNode._iCyclePhase;
+
+ this.updateScaleData();
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleScaleState.SCALE_INDEX);
+
+ if (this._particleScaleNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesCycle) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ } else
+ animationSubGeometry.activateVertexBuffer(index, this._particleScaleNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_2);
+ } else
+ animationRegisterCache.setVertexConst(index, this._scaleData.x, this._scaleData.y, this._scaleData.z, this._scaleData.w);
+ }
+
+ private updateScaleData()
+ {
+ if (this._particleScaleNode.mode == ParticlePropertiesMode.GLOBAL) {
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._scaleData = new Vector3D((this._minScale + this._maxScale)/2, Math.abs(this._minScale - this._maxScale)/2, Math.PI*2/this._cycleDuration, this._cyclePhase*Math.PI/180);
+ } else
+ this._scaleData = new Vector3D(this._minScale, this._maxScale - this._minScale, 0, 0);
+ }
+ }
+}
+
+export = ParticleScaleState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleSegmentedColorState.js b/lib/animators/states/ParticleSegmentedColorState.js
new file mode 100755
index 000000000..f89addc78
--- /dev/null
+++ b/lib/animators/states/ParticleSegmentedColorState.js
@@ -0,0 +1,153 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ *
+ */
+var ParticleSegmentedColorState = (function (_super) {
+ __extends(ParticleSegmentedColorState, _super);
+ function ParticleSegmentedColorState(animator, particleSegmentedColorNode) {
+ _super.call(this, animator, particleSegmentedColorNode);
+ this._usesMultiplier = particleSegmentedColorNode._iUsesMultiplier;
+ this._usesOffset = particleSegmentedColorNode._iUsesOffset;
+ this._startColor = particleSegmentedColorNode._iStartColor;
+ this._endColor = particleSegmentedColorNode._iEndColor;
+ this._segmentPoints = particleSegmentedColorNode._iSegmentPoints;
+ this._numSegmentPoint = particleSegmentedColorNode._iNumSegmentPoint;
+ this.updateColorData();
+ }
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "startColor", {
+ /**
+ * Defines the start color transform of the state, when in global mode.
+ */
+ get: function () {
+ return this._startColor;
+ },
+ set: function (value) {
+ this._startColor = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "endColor", {
+ /**
+ * Defines the end color transform of the state, when in global mode.
+ */
+ get: function () {
+ return this._endColor;
+ },
+ set: function (value) {
+ this._endColor = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "numSegmentPoint", {
+ /**
+ * Defines the number of segments.
+ */
+ get: function () {
+ return this._numSegmentPoint;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "segmentPoints", {
+ /**
+ * Defines the key points of color
+ */
+ get: function () {
+ return this._segmentPoints;
+ },
+ set: function (value) {
+ this._segmentPoints = value;
+ this.updateColorData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "usesMultiplier", {
+ get: function () {
+ return this._usesMultiplier;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSegmentedColorState.prototype, "usesOffset", {
+ get: function () {
+ return this._usesOffset;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleSegmentedColorState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (animationRegisterCache.needFragmentAnimation) {
+ if (this._numSegmentPoint > 0)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.TIME_DATA_INDEX), this._timeLifeData[0], this._timeLifeData[1], this._timeLifeData[2], this._timeLifeData[3]);
+ if (this._usesMultiplier)
+ animationRegisterCache.setVertexConstFromArray(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.START_MULTIPLIER_INDEX), this._multiplierData);
+ if (this._usesOffset)
+ animationRegisterCache.setVertexConstFromArray(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.START_OFFSET_INDEX), this._offsetData);
+ }
+ };
+ ParticleSegmentedColorState.prototype.updateColorData = function () {
+ this._timeLifeData = new Array();
+ this._multiplierData = new Array();
+ this._offsetData = new Array();
+ var i /*int*/;
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._timeLifeData.push(this._segmentPoints[i].life);
+ else
+ this._timeLifeData.push(this._segmentPoints[i].life - this._segmentPoints[i - 1].life);
+ }
+ if (this._numSegmentPoint == 0)
+ this._timeLifeData.push(1);
+ else
+ this._timeLifeData.push(1 - this._segmentPoints[i - 1].life);
+ if (this._usesMultiplier) {
+ this._multiplierData.push(this._startColor.redMultiplier, this._startColor.greenMultiplier, this._startColor.blueMultiplier, this._startColor.alphaMultiplier);
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._multiplierData.push((this._segmentPoints[i].color.redMultiplier - this._startColor.redMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.greenMultiplier - this._startColor.greenMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.blueMultiplier - this._startColor.blueMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.alphaMultiplier - this._startColor.alphaMultiplier) / this._timeLifeData[i]);
+ else
+ this._multiplierData.push((this._segmentPoints[i].color.redMultiplier - this._segmentPoints[i - 1].color.redMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.greenMultiplier - this._segmentPoints[i - 1].color.greenMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.blueMultiplier - this._segmentPoints[i - 1].color.blueMultiplier) / this._timeLifeData[i], (this._segmentPoints[i].color.alphaMultiplier - this._segmentPoints[i - 1].color.alphaMultiplier) / this._timeLifeData[i]);
+ }
+ if (this._numSegmentPoint == 0)
+ this._multiplierData.push(this._endColor.redMultiplier - this._startColor.redMultiplier, this._endColor.greenMultiplier - this._startColor.greenMultiplier, this._endColor.blueMultiplier - this._startColor.blueMultiplier, this._endColor.alphaMultiplier - this._startColor.alphaMultiplier);
+ else
+ this._multiplierData.push((this._endColor.redMultiplier - this._segmentPoints[i - 1].color.redMultiplier) / this._timeLifeData[i], (this._endColor.greenMultiplier - this._segmentPoints[i - 1].color.greenMultiplier) / this._timeLifeData[i], (this._endColor.blueMultiplier - this._segmentPoints[i - 1].color.blueMultiplier) / this._timeLifeData[i], (this._endColor.alphaMultiplier - this._segmentPoints[i - 1].color.alphaMultiplier) / this._timeLifeData[i]);
+ }
+ if (this._usesOffset) {
+ this._offsetData.push(this._startColor.redOffset / 255, this._startColor.greenOffset / 255, this._startColor.blueOffset / 255, this._startColor.alphaOffset / 255);
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._offsetData.push((this._segmentPoints[i].color.redOffset - this._startColor.redOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.greenOffset - this._startColor.greenOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.blueOffset - this._startColor.blueOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.alphaOffset - this._startColor.alphaOffset) / this._timeLifeData[i] / 255);
+ else
+ this._offsetData.push((this._segmentPoints[i].color.redOffset - this._segmentPoints[i - 1].color.redOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.greenOffset - this._segmentPoints[i - 1].color.greenOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.blueOffset - this._segmentPoints[i - 1].color.blueOffset) / this._timeLifeData[i] / 255, (this._segmentPoints[i].color.alphaOffset - this._segmentPoints[i - 1].color.alphaOffset) / this._timeLifeData[i] / 255);
+ }
+ if (this._numSegmentPoint == 0)
+ this._offsetData.push((this._endColor.redOffset - this._startColor.redOffset) / 255, (this._endColor.greenOffset - this._startColor.greenOffset) / 255, (this._endColor.blueOffset - this._startColor.blueOffset) / 255, (this._endColor.alphaOffset - this._startColor.alphaOffset) / 255);
+ else
+ this._offsetData.push((this._endColor.redOffset - this._segmentPoints[i - 1].color.redOffset) / this._timeLifeData[i] / 255, (this._endColor.greenOffset - this._segmentPoints[i - 1].color.greenOffset) / this._timeLifeData[i] / 255, (this._endColor.blueOffset - this._segmentPoints[i - 1].color.blueOffset) / this._timeLifeData[i] / 255, (this._endColor.alphaOffset - this._segmentPoints[i - 1].color.alphaOffset) / this._timeLifeData[i] / 255);
+ }
+ //cut off the data
+ this._timeLifeData.length = 4;
+ };
+ /** @private */
+ ParticleSegmentedColorState.START_MULTIPLIER_INDEX = 0;
+ /** @private */
+ ParticleSegmentedColorState.START_OFFSET_INDEX = 1;
+ /** @private */
+ ParticleSegmentedColorState.TIME_DATA_INDEX = 2;
+ return ParticleSegmentedColorState;
+})(ParticleStateBase);
+module.exports = ParticleSegmentedColorState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVzZWdtZW50ZWRjb2xvcnN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZSIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5zdGFydENvbG9yIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLmVuZENvbG9yIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLm51bVNlZ21lbnRQb2ludCIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5zZWdtZW50UG9pbnRzIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLnVzZXNNdWx0aXBsaWVyIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLnVzZXNPZmZzZXQiLCJQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUudXBkYXRlQ29sb3JEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFjQSxJQUFPLGlCQUFpQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFFbEcsQUFHQTs7R0FERztJQUNHLDJCQUEyQjtJQUFTQSxVQUFwQ0EsMkJBQTJCQSxVQUEwQkE7SUFtRjFEQSxTQW5GS0EsMkJBQTJCQSxDQW1GcEJBLFFBQXlCQSxFQUFFQSwwQkFBcURBO1FBRTNGQyxrQkFBTUEsUUFBUUEsRUFBRUEsMEJBQTBCQSxDQUFDQSxDQUFDQTtRQUU1Q0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsMEJBQTBCQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1FBQ25FQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSwwQkFBMEJBLENBQUNBLFlBQVlBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSwwQkFBMEJBLENBQUNBLFlBQVlBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSwwQkFBMEJBLENBQUNBLFVBQVVBLENBQUNBO1FBQ3ZEQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSwwQkFBMEJBLENBQUNBLGVBQWVBLENBQUNBO1FBQ2pFQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLDBCQUEwQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQTtRQUNyRUEsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBckVERCxzQkFBV0EsbURBQVVBO1FBSHJCQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDekJBLENBQUNBO2FBRURGLFVBQXNCQSxLQUFvQkE7WUFFekNFLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEtBQUtBLENBQUNBO1lBRXpCQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7OztPQVBBRjtJQVlEQSxzQkFBV0EsaURBQVFBO1FBSG5CQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDdkJBLENBQUNBO2FBRURILFVBQW9CQSxLQUFvQkE7WUFFdkNHLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLEtBQUtBLENBQUNBO1lBQ3ZCQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7OztPQU5BSDtJQVdEQSxzQkFBV0Esd0RBQWVBO1FBSDFCQTs7V0FFR0E7YUFDSEE7WUFFQ0ksTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQTtRQUM5QkEsQ0FBQ0E7OztPQUFBSjtJQUtEQSxzQkFBV0Esc0RBQWFBO1FBSHhCQTs7V0FFR0E7YUFDSEE7WUFFQ0ssTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0E7UUFDNUJBLENBQUNBO2FBRURMLFVBQXlCQSxLQUE4QkE7WUFFdERLLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLEtBQUtBLENBQUNBO1lBQzVCQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7OztPQU5BTDtJQVFEQSxzQkFBV0EsdURBQWNBO2FBQXpCQTtZQUVDTSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQTtRQUM3QkEsQ0FBQ0E7OztPQUFBTjtJQUVEQSxzQkFBV0EsbURBQVVBO2FBQXJCQTtZQUVDTyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUN6QkEsQ0FBQ0E7OztPQUFBUDtJQWVNQSxvREFBY0EsR0FBckJBLFVBQXNCQSxLQUFXQSxFQUFFQSxVQUF5QkEsRUFBRUEsb0JBQXlDQSxFQUFFQSxzQkFBNkNBLEVBQUVBLE1BQWFBO1FBRXBLUSxFQUFFQSxDQUFDQSxDQUFDQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbERBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzdCQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSwyQkFBMkJBLENBQUNBLGVBQWVBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQy9PQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQTtnQkFDeEJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsMkJBQTJCQSxDQUFDQSxzQkFBc0JBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1lBQ3pMQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDcEJBLHNCQUFzQkEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsMkJBQTJCQSxDQUFDQSxrQkFBa0JBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO1FBQ2xMQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVPUixxREFBZUEsR0FBdkJBO1FBRUNTLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLEtBQUtBLEVBQVVBLENBQUNBO1FBQ3pDQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxLQUFLQSxFQUFVQSxDQUFDQTtRQUMzQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBQ0E7UUFDdkNBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3JCQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtnQkFDVkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDdERBLElBQUlBO2dCQUNIQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUN6RkEsQ0FBQ0E7UUFDREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLElBQUlBO1lBQ0hBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1FBRTlEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMxQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7WUFDL0pBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDVkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3piQSxJQUFJQTtvQkFDSEEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDMWZBLENBQUNBO1lBQ0RBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxhQUFhQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxlQUFlQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxjQUFjQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtZQUNqU0EsSUFBSUE7Z0JBQ0hBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGFBQWFBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGNBQWNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ2xjQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN0QkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsU0FBU0EsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsVUFBVUEsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDM0pBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDVkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JhQSxJQUFJQTtvQkFDSEEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDdGVBLENBQUNBO1lBQ0RBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzlCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxTQUFTQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxVQUFVQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNyUkEsSUFBSUE7Z0JBQ0hBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFNBQVNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFVBQVVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQzlhQSxDQUFDQTtRQUNEQSxBQUNBQSxrQkFEa0JBO1FBQ2xCQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxNQUFNQSxHQUFHQSxDQUFDQSxDQUFDQTtJQUMvQkEsQ0FBQ0E7SUF4SkRULGVBQWVBO0lBQ0RBLGtEQUFzQkEsR0FBbUJBLENBQUNBLENBQUNBO0lBRXpEQSxlQUFlQTtJQUNEQSw4Q0FBa0JBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUVyREEsZUFBZUE7SUFDREEsMkNBQWVBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQWtKbkRBLGtDQUFDQTtBQUFEQSxDQTNKQSxBQTJKQ0EsRUEzSnlDLGlCQUFpQixFQTJKMUQ7QUFFRCxBQUFxQyxpQkFBNUIsMkJBQTJCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29sb3JUcmFuc2Zvcm1cdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Db2xvclRyYW5zZm9ybVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IENvbG9yU2VnbWVudFBvaW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQ29sb3JTZWdtZW50UG9pbnRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqXG4gKi9cbmNsYXNzIFBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFNUQVJUX01VTFRJUExJRVJfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBTVEFSVF9PRkZTRVRfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBUSU1FX0RBVEFfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMjtcblxuXHRwcml2YXRlIF91c2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzT2Zmc2V0OmJvb2xlYW47XG5cdHByaXZhdGUgX3N0YXJ0Q29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdHByaXZhdGUgX2VuZENvbG9yOkNvbG9yVHJhbnNmb3JtO1xuXHRwcml2YXRlIF9zZWdtZW50UG9pbnRzOkFycmF5PENvbG9yU2VnbWVudFBvaW50Pjtcblx0cHJpdmF0ZSBfbnVtU2VnbWVudFBvaW50Om51bWJlciAvKmludCovO1xuXG5cdHByaXZhdGUgX3RpbWVMaWZlRGF0YTpBcnJheTxudW1iZXI+O1xuXHRwcml2YXRlIF9tdWx0aXBsaWVyRGF0YTpBcnJheTxudW1iZXI+O1xuXHRwcml2YXRlIF9vZmZzZXREYXRhOkFycmF5PG51bWJlcj47XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIHN0YXJ0IGNvbG9yIHRyYW5zZm9ybSBvZiB0aGUgc3RhdGUsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHN0YXJ0Q29sb3IoKTpDb2xvclRyYW5zZm9ybVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3N0YXJ0Q29sb3I7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHN0YXJ0Q29sb3IodmFsdWU6Q29sb3JUcmFuc2Zvcm0pXG5cdHtcblx0XHR0aGlzLl9zdGFydENvbG9yID0gdmFsdWU7XG5cblx0XHR0aGlzLnVwZGF0ZUNvbG9yRGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIGVuZCBjb2xvciB0cmFuc2Zvcm0gb2YgdGhlIHN0YXRlLCB3aGVuIGluIGdsb2JhbCBtb2RlLlxuXHQgKi9cblx0cHVibGljIGdldCBlbmRDb2xvcigpOkNvbG9yVHJhbnNmb3JtXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZW5kQ29sb3I7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGVuZENvbG9yKHZhbHVlOkNvbG9yVHJhbnNmb3JtKVxuXHR7XG5cdFx0dGhpcy5fZW5kQ29sb3IgPSB2YWx1ZTtcblx0XHR0aGlzLnVwZGF0ZUNvbG9yRGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmluZXMgdGhlIG51bWJlciBvZiBzZWdtZW50cy5cblx0ICovXG5cdHB1YmxpYyBnZXQgbnVtU2VnbWVudFBvaW50KCk6bnVtYmVyIC8qaW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9udW1TZWdtZW50UG9pbnQ7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUga2V5IHBvaW50cyBvZiBjb2xvclxuXHQgKi9cblx0cHVibGljIGdldCBzZWdtZW50UG9pbnRzKCk6QXJyYXk8Q29sb3JTZWdtZW50UG9pbnQ+XG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc2VnbWVudFBvaW50cztcblx0fVxuXG5cdHB1YmxpYyBzZXQgc2VnbWVudFBvaW50cyh2YWx1ZTpBcnJheTxDb2xvclNlZ21lbnRQb2ludD4pXG5cdHtcblx0XHR0aGlzLl9zZWdtZW50UG9pbnRzID0gdmFsdWU7XG5cdFx0dGhpcy51cGRhdGVDb2xvckRhdGEoKTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgdXNlc011bHRpcGxpZXIoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdXNlc011bHRpcGxpZXI7XG5cdH1cblxuXHRwdWJsaWMgZ2V0IHVzZXNPZmZzZXQoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdXNlc09mZnNldDtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlOlBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlKTtcblxuXHRcdHRoaXMuX3VzZXNNdWx0aXBsaWVyID0gcGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGUuX2lVc2VzTXVsdGlwbGllcjtcblx0XHR0aGlzLl91c2VzT2Zmc2V0ID0gcGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGUuX2lVc2VzT2Zmc2V0O1xuXHRcdHRoaXMuX3N0YXJ0Q29sb3IgPSBwYXJ0aWNsZVNlZ21lbnRlZENvbG9yTm9kZS5faVN0YXJ0Q29sb3I7XG5cdFx0dGhpcy5fZW5kQ29sb3IgPSBwYXJ0aWNsZVNlZ21lbnRlZENvbG9yTm9kZS5faUVuZENvbG9yO1xuXHRcdHRoaXMuX3NlZ21lbnRQb2ludHMgPSBwYXJ0aWNsZVNlZ21lbnRlZENvbG9yTm9kZS5faVNlZ21lbnRQb2ludHM7XG5cdFx0dGhpcy5fbnVtU2VnbWVudFBvaW50ID0gcGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGUuX2lOdW1TZWdtZW50UG9pbnQ7XG5cdFx0dGhpcy51cGRhdGVDb2xvckRhdGEoKTtcblx0fVxuXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGlmIChhbmltYXRpb25SZWdpc3RlckNhY2hlLm5lZWRGcmFnbWVudEFuaW1hdGlvbikge1xuXHRcdFx0aWYgKHRoaXMuX251bVNlZ21lbnRQb2ludCA+IDApXG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuVElNRV9EQVRBX0lOREVYKSwgdGhpcy5fdGltZUxpZmVEYXRhWzBdLCB0aGlzLl90aW1lTGlmZURhdGFbMV0sIHRoaXMuX3RpbWVMaWZlRGF0YVsyXSwgdGhpcy5fdGltZUxpZmVEYXRhWzNdKTtcblx0XHRcdGlmICh0aGlzLl91c2VzTXVsdGlwbGllcilcblx0XHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdEZyb21BcnJheShhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5TVEFSVF9NVUxUSVBMSUVSX0lOREVYKSwgdGhpcy5fbXVsdGlwbGllckRhdGEpO1xuXHRcdFx0aWYgKHRoaXMuX3VzZXNPZmZzZXQpXG5cdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3RGcm9tQXJyYXkoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuU1RBUlRfT0ZGU0VUX0lOREVYKSwgdGhpcy5fb2Zmc2V0RGF0YSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVDb2xvckRhdGEoKVxuXHR7XG5cdFx0dGhpcy5fdGltZUxpZmVEYXRhID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHR0aGlzLl9tdWx0aXBsaWVyRGF0YSA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0dGhpcy5fb2Zmc2V0RGF0YSA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0dmFyIGk6bnVtYmVyIC8qaW50Ki87XG5cdFx0Zm9yIChpID0gMDsgaSA8IHRoaXMuX251bVNlZ21lbnRQb2ludDsgaSsrKSB7XG5cdFx0XHRpZiAoaSA9PSAwKVxuXHRcdFx0XHR0aGlzLl90aW1lTGlmZURhdGEucHVzaCh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmxpZmUpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHR0aGlzLl90aW1lTGlmZURhdGEucHVzaCh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmxpZmUgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5saWZlKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuX251bVNlZ21lbnRQb2ludCA9PSAwKVxuXHRcdFx0dGhpcy5fdGltZUxpZmVEYXRhLnB1c2goMSk7XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5fdGltZUxpZmVEYXRhLnB1c2goMSAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmxpZmUpO1xuXG5cdFx0aWYgKHRoaXMuX3VzZXNNdWx0aXBsaWVyKSB7XG5cdFx0XHR0aGlzLl9tdWx0aXBsaWVyRGF0YS5wdXNoKHRoaXMuX3N0YXJ0Q29sb3IucmVkTXVsdGlwbGllciwgdGhpcy5fc3RhcnRDb2xvci5ncmVlbk11bHRpcGxpZXIsIHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIsIHRoaXMuX3N0YXJ0Q29sb3IuYWxwaGFNdWx0aXBsaWVyKTtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCB0aGlzLl9udW1TZWdtZW50UG9pbnQ7IGkrKykge1xuXHRcdFx0XHRpZiAoaSA9PSAwKVxuXHRcdFx0XHRcdHRoaXMuX211bHRpcGxpZXJEYXRhLnB1c2goKHRoaXMuX3NlZ21lbnRQb2ludHNbaV0uY29sb3IucmVkTXVsdGlwbGllciAtIHRoaXMuX3N0YXJ0Q29sb3IucmVkTXVsdGlwbGllcikvdGhpcy5fdGltZUxpZmVEYXRhW2ldLCAodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5ncmVlbk11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmdyZWVuTXVsdGlwbGllcikvdGhpcy5fdGltZUxpZmVEYXRhW2ldLCAodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5ibHVlTXVsdGlwbGllciAtIHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU11bHRpcGxpZXIpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXSwgKHRoaXMuX3NlZ21lbnRQb2ludHNbaV0uY29sb3IuYWxwaGFNdWx0aXBsaWVyIC0gdGhpcy5fc3RhcnRDb2xvci5hbHBoYU11bHRpcGxpZXIpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXSk7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHR0aGlzLl9tdWx0aXBsaWVyRGF0YS5wdXNoKCh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmNvbG9yLnJlZE11bHRpcGxpZXIgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5jb2xvci5yZWRNdWx0aXBsaWVyKS90aGlzLl90aW1lTGlmZURhdGFbaV0sICh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmNvbG9yLmdyZWVuTXVsdGlwbGllciAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmdyZWVuTXVsdGlwbGllcikvdGhpcy5fdGltZUxpZmVEYXRhW2ldLCAodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5ibHVlTXVsdGlwbGllciAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmJsdWVNdWx0aXBsaWVyKS90aGlzLl90aW1lTGlmZURhdGFbaV0sICh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmNvbG9yLmFscGhhTXVsdGlwbGllciAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmFscGhhTXVsdGlwbGllcikvdGhpcy5fdGltZUxpZmVEYXRhW2ldKTtcblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLl9udW1TZWdtZW50UG9pbnQgPT0gMClcblx0XHRcdFx0dGhpcy5fbXVsdGlwbGllckRhdGEucHVzaCh0aGlzLl9lbmRDb2xvci5yZWRNdWx0aXBsaWVyIC0gdGhpcy5fc3RhcnRDb2xvci5yZWRNdWx0aXBsaWVyLCB0aGlzLl9lbmRDb2xvci5ncmVlbk11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmdyZWVuTXVsdGlwbGllciwgdGhpcy5fZW5kQ29sb3IuYmx1ZU11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmJsdWVNdWx0aXBsaWVyLCB0aGlzLl9lbmRDb2xvci5hbHBoYU11bHRpcGxpZXIgLSB0aGlzLl9zdGFydENvbG9yLmFscGhhTXVsdGlwbGllcik7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHRoaXMuX211bHRpcGxpZXJEYXRhLnB1c2goKHRoaXMuX2VuZENvbG9yLnJlZE11bHRpcGxpZXIgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5jb2xvci5yZWRNdWx0aXBsaWVyKS90aGlzLl90aW1lTGlmZURhdGFbaV0sICh0aGlzLl9lbmRDb2xvci5ncmVlbk11bHRpcGxpZXIgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5jb2xvci5ncmVlbk11bHRpcGxpZXIpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXSwgKHRoaXMuX2VuZENvbG9yLmJsdWVNdWx0aXBsaWVyIC0gdGhpcy5fc2VnbWVudFBvaW50c1tpIC0gMV0uY29sb3IuYmx1ZU11bHRpcGxpZXIpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXSwgKHRoaXMuX2VuZENvbG9yLmFscGhhTXVsdGlwbGllciAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmFscGhhTXVsdGlwbGllcikvdGhpcy5fdGltZUxpZmVEYXRhW2ldKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fdXNlc09mZnNldCkge1xuXHRcdFx0dGhpcy5fb2Zmc2V0RGF0YS5wdXNoKHRoaXMuX3N0YXJ0Q29sb3IucmVkT2Zmc2V0LzI1NSwgdGhpcy5fc3RhcnRDb2xvci5ncmVlbk9mZnNldC8yNTUsIHRoaXMuX3N0YXJ0Q29sb3IuYmx1ZU9mZnNldC8yNTUsIHRoaXMuX3N0YXJ0Q29sb3IuYWxwaGFPZmZzZXQvMjU1KTtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCB0aGlzLl9udW1TZWdtZW50UG9pbnQ7IGkrKykge1xuXHRcdFx0XHRpZiAoaSA9PSAwKVxuXHRcdFx0XHRcdHRoaXMuX29mZnNldERhdGEucHVzaCgodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5yZWRPZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLnJlZE9mZnNldCkvdGhpcy5fdGltZUxpZmVEYXRhW2ldLzI1NSwgKHRoaXMuX3NlZ21lbnRQb2ludHNbaV0uY29sb3IuZ3JlZW5PZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLmdyZWVuT2Zmc2V0KS90aGlzLl90aW1lTGlmZURhdGFbaV0vMjU1LCAodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5ibHVlT2Zmc2V0IC0gdGhpcy5fc3RhcnRDb2xvci5ibHVlT2Zmc2V0KS90aGlzLl90aW1lTGlmZURhdGFbaV0vMjU1LCAodGhpcy5fc2VnbWVudFBvaW50c1tpXS5jb2xvci5hbHBoYU9mZnNldCAtIHRoaXMuX3N0YXJ0Q29sb3IuYWxwaGFPZmZzZXQpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXS8yNTUpO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0dGhpcy5fb2Zmc2V0RGF0YS5wdXNoKCh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmNvbG9yLnJlZE9mZnNldCAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLnJlZE9mZnNldCkvdGhpcy5fdGltZUxpZmVEYXRhW2ldLzI1NSwgKHRoaXMuX3NlZ21lbnRQb2ludHNbaV0uY29sb3IuZ3JlZW5PZmZzZXQgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5jb2xvci5ncmVlbk9mZnNldCkvdGhpcy5fdGltZUxpZmVEYXRhW2ldLzI1NSwgKHRoaXMuX3NlZ21lbnRQb2ludHNbaV0uY29sb3IuYmx1ZU9mZnNldCAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmJsdWVPZmZzZXQpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXS8yNTUsICh0aGlzLl9zZWdtZW50UG9pbnRzW2ldLmNvbG9yLmFscGhhT2Zmc2V0IC0gdGhpcy5fc2VnbWVudFBvaW50c1tpIC0gMV0uY29sb3IuYWxwaGFPZmZzZXQpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXS8yNTUpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuX251bVNlZ21lbnRQb2ludCA9PSAwKVxuXHRcdFx0XHR0aGlzLl9vZmZzZXREYXRhLnB1c2goKHRoaXMuX2VuZENvbG9yLnJlZE9mZnNldCAtIHRoaXMuX3N0YXJ0Q29sb3IucmVkT2Zmc2V0KS8yNTUsICh0aGlzLl9lbmRDb2xvci5ncmVlbk9mZnNldCAtIHRoaXMuX3N0YXJ0Q29sb3IuZ3JlZW5PZmZzZXQpLzI1NSwgKHRoaXMuX2VuZENvbG9yLmJsdWVPZmZzZXQgLSB0aGlzLl9zdGFydENvbG9yLmJsdWVPZmZzZXQpLzI1NSwgKHRoaXMuX2VuZENvbG9yLmFscGhhT2Zmc2V0IC0gdGhpcy5fc3RhcnRDb2xvci5hbHBoYU9mZnNldCkvMjU1KTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0dGhpcy5fb2Zmc2V0RGF0YS5wdXNoKCh0aGlzLl9lbmRDb2xvci5yZWRPZmZzZXQgLSB0aGlzLl9zZWdtZW50UG9pbnRzW2kgLSAxXS5jb2xvci5yZWRPZmZzZXQpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXS8yNTUsICh0aGlzLl9lbmRDb2xvci5ncmVlbk9mZnNldCAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmdyZWVuT2Zmc2V0KS90aGlzLl90aW1lTGlmZURhdGFbaV0vMjU1LCAodGhpcy5fZW5kQ29sb3IuYmx1ZU9mZnNldCAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmJsdWVPZmZzZXQpL3RoaXMuX3RpbWVMaWZlRGF0YVtpXS8yNTUsICh0aGlzLl9lbmRDb2xvci5hbHBoYU9mZnNldCAtIHRoaXMuX3NlZ21lbnRQb2ludHNbaSAtIDFdLmNvbG9yLmFscGhhT2Zmc2V0KS90aGlzLl90aW1lTGlmZURhdGFbaV0vMjU1KTtcblx0XHR9XG5cdFx0Ly9jdXQgb2ZmIHRoZSBkYXRhXG5cdFx0dGhpcy5fdGltZUxpZmVEYXRhLmxlbmd0aCA9IDQ7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleSegmentedColorState.ts b/lib/animators/states/ParticleSegmentedColorState.ts
new file mode 100644
index 000000000..8dff14261
--- /dev/null
+++ b/lib/animators/states/ParticleSegmentedColorState.ts
@@ -0,0 +1,177 @@
+import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ColorSegmentPoint = require("awayjs-renderergl/lib/animators/data/ColorSegmentPoint");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleSegmentedColorNode = require("awayjs-renderergl/lib/animators/nodes/ParticleSegmentedColorNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ *
+ */
+class ParticleSegmentedColorState extends ParticleStateBase
+{
+ /** @private */
+ public static START_MULTIPLIER_INDEX:number /*uint*/ = 0;
+
+ /** @private */
+ public static START_OFFSET_INDEX:number /*uint*/ = 1;
+
+ /** @private */
+ public static TIME_DATA_INDEX:number /*uint*/ = 2;
+
+ private _usesMultiplier:boolean;
+ private _usesOffset:boolean;
+ private _startColor:ColorTransform;
+ private _endColor:ColorTransform;
+ private _segmentPoints:Array;
+ private _numSegmentPoint:number /*int*/;
+
+ private _timeLifeData:Array;
+ private _multiplierData:Array;
+ private _offsetData:Array;
+
+ /**
+ * Defines the start color transform of the state, when in global mode.
+ */
+ public get startColor():ColorTransform
+ {
+ return this._startColor;
+ }
+
+ public set startColor(value:ColorTransform)
+ {
+ this._startColor = value;
+
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the end color transform of the state, when in global mode.
+ */
+ public get endColor():ColorTransform
+ {
+ return this._endColor;
+ }
+
+ public set endColor(value:ColorTransform)
+ {
+ this._endColor = value;
+ this.updateColorData();
+ }
+
+ /**
+ * Defines the number of segments.
+ */
+ public get numSegmentPoint():number /*int*/
+ {
+ return this._numSegmentPoint;
+ }
+
+ /**
+ * Defines the key points of color
+ */
+ public get segmentPoints():Array
+ {
+ return this._segmentPoints;
+ }
+
+ public set segmentPoints(value:Array)
+ {
+ this._segmentPoints = value;
+ this.updateColorData();
+ }
+
+ public get usesMultiplier():boolean
+ {
+ return this._usesMultiplier;
+ }
+
+ public get usesOffset():boolean
+ {
+ return this._usesOffset;
+ }
+
+ constructor(animator:ParticleAnimator, particleSegmentedColorNode:ParticleSegmentedColorNode)
+ {
+ super(animator, particleSegmentedColorNode);
+
+ this._usesMultiplier = particleSegmentedColorNode._iUsesMultiplier;
+ this._usesOffset = particleSegmentedColorNode._iUsesOffset;
+ this._startColor = particleSegmentedColorNode._iStartColor;
+ this._endColor = particleSegmentedColorNode._iEndColor;
+ this._segmentPoints = particleSegmentedColorNode._iSegmentPoints;
+ this._numSegmentPoint = particleSegmentedColorNode._iNumSegmentPoint;
+ this.updateColorData();
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (animationRegisterCache.needFragmentAnimation) {
+ if (this._numSegmentPoint > 0)
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.TIME_DATA_INDEX), this._timeLifeData[0], this._timeLifeData[1], this._timeLifeData[2], this._timeLifeData[3]);
+ if (this._usesMultiplier)
+ animationRegisterCache.setVertexConstFromArray(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.START_MULTIPLIER_INDEX), this._multiplierData);
+ if (this._usesOffset)
+ animationRegisterCache.setVertexConstFromArray(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSegmentedColorState.START_OFFSET_INDEX), this._offsetData);
+ }
+ }
+
+ private updateColorData()
+ {
+ this._timeLifeData = new Array();
+ this._multiplierData = new Array();
+ this._offsetData = new Array();
+ var i:number /*int*/;
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._timeLifeData.push(this._segmentPoints[i].life);
+ else
+ this._timeLifeData.push(this._segmentPoints[i].life - this._segmentPoints[i - 1].life);
+ }
+ if (this._numSegmentPoint == 0)
+ this._timeLifeData.push(1);
+ else
+ this._timeLifeData.push(1 - this._segmentPoints[i - 1].life);
+
+ if (this._usesMultiplier) {
+ this._multiplierData.push(this._startColor.redMultiplier, this._startColor.greenMultiplier, this._startColor.blueMultiplier, this._startColor.alphaMultiplier);
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._multiplierData.push((this._segmentPoints[i].color.redMultiplier - this._startColor.redMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.greenMultiplier - this._startColor.greenMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.blueMultiplier - this._startColor.blueMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.alphaMultiplier - this._startColor.alphaMultiplier)/this._timeLifeData[i]);
+ else
+ this._multiplierData.push((this._segmentPoints[i].color.redMultiplier - this._segmentPoints[i - 1].color.redMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.greenMultiplier - this._segmentPoints[i - 1].color.greenMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.blueMultiplier - this._segmentPoints[i - 1].color.blueMultiplier)/this._timeLifeData[i], (this._segmentPoints[i].color.alphaMultiplier - this._segmentPoints[i - 1].color.alphaMultiplier)/this._timeLifeData[i]);
+ }
+ if (this._numSegmentPoint == 0)
+ this._multiplierData.push(this._endColor.redMultiplier - this._startColor.redMultiplier, this._endColor.greenMultiplier - this._startColor.greenMultiplier, this._endColor.blueMultiplier - this._startColor.blueMultiplier, this._endColor.alphaMultiplier - this._startColor.alphaMultiplier);
+ else
+ this._multiplierData.push((this._endColor.redMultiplier - this._segmentPoints[i - 1].color.redMultiplier)/this._timeLifeData[i], (this._endColor.greenMultiplier - this._segmentPoints[i - 1].color.greenMultiplier)/this._timeLifeData[i], (this._endColor.blueMultiplier - this._segmentPoints[i - 1].color.blueMultiplier)/this._timeLifeData[i], (this._endColor.alphaMultiplier - this._segmentPoints[i - 1].color.alphaMultiplier)/this._timeLifeData[i]);
+ }
+
+ if (this._usesOffset) {
+ this._offsetData.push(this._startColor.redOffset/255, this._startColor.greenOffset/255, this._startColor.blueOffset/255, this._startColor.alphaOffset/255);
+ for (i = 0; i < this._numSegmentPoint; i++) {
+ if (i == 0)
+ this._offsetData.push((this._segmentPoints[i].color.redOffset - this._startColor.redOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.greenOffset - this._startColor.greenOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.blueOffset - this._startColor.blueOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.alphaOffset - this._startColor.alphaOffset)/this._timeLifeData[i]/255);
+ else
+ this._offsetData.push((this._segmentPoints[i].color.redOffset - this._segmentPoints[i - 1].color.redOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.greenOffset - this._segmentPoints[i - 1].color.greenOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.blueOffset - this._segmentPoints[i - 1].color.blueOffset)/this._timeLifeData[i]/255, (this._segmentPoints[i].color.alphaOffset - this._segmentPoints[i - 1].color.alphaOffset)/this._timeLifeData[i]/255);
+ }
+ if (this._numSegmentPoint == 0)
+ this._offsetData.push((this._endColor.redOffset - this._startColor.redOffset)/255, (this._endColor.greenOffset - this._startColor.greenOffset)/255, (this._endColor.blueOffset - this._startColor.blueOffset)/255, (this._endColor.alphaOffset - this._startColor.alphaOffset)/255);
+ else
+ this._offsetData.push((this._endColor.redOffset - this._segmentPoints[i - 1].color.redOffset)/this._timeLifeData[i]/255, (this._endColor.greenOffset - this._segmentPoints[i - 1].color.greenOffset)/this._timeLifeData[i]/255, (this._endColor.blueOffset - this._segmentPoints[i - 1].color.blueOffset)/this._timeLifeData[i]/255, (this._endColor.alphaOffset - this._segmentPoints[i - 1].color.alphaOffset)/this._timeLifeData[i]/255);
+ }
+ //cut off the data
+ this._timeLifeData.length = 4;
+ }
+}
+
+export = ParticleSegmentedColorState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleSpriteSheetState.js b/lib/animators/states/ParticleSpriteSheetState.js
new file mode 100755
index 000000000..17993592b
--- /dev/null
+++ b/lib/animators/states/ParticleSpriteSheetState.js
@@ -0,0 +1,94 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleSpriteSheetState = (function (_super) {
+ __extends(ParticleSpriteSheetState, _super);
+ function ParticleSpriteSheetState(animator, particleSpriteSheetNode) {
+ _super.call(this, animator, particleSpriteSheetNode);
+ this._particleSpriteSheetNode = particleSpriteSheetNode;
+ this._usesCycle = this._particleSpriteSheetNode._iUsesCycle;
+ this._usesPhase = this._particleSpriteSheetNode._iUsesCycle;
+ this._totalFrames = this._particleSpriteSheetNode._iTotalFrames;
+ this._numColumns = this._particleSpriteSheetNode._iNumColumns;
+ this._numRows = this._particleSpriteSheetNode._iNumRows;
+ this._cycleDuration = this._particleSpriteSheetNode._iCycleDuration;
+ this._cyclePhase = this._particleSpriteSheetNode._iCyclePhase;
+ this.updateSpriteSheetData();
+ }
+ Object.defineProperty(ParticleSpriteSheetState.prototype, "cyclePhase", {
+ /**
+ * Defines the cycle phase, when in global mode. Defaults to zero.
+ */
+ get: function () {
+ return this._cyclePhase;
+ },
+ set: function (value) {
+ this._cyclePhase = value;
+ this.updateSpriteSheetData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ParticleSpriteSheetState.prototype, "cycleDuration", {
+ /**
+ * Defines the cycle duration in seconds, when in global mode. Defaults to 1.
+ */
+ get: function () {
+ return this._cycleDuration;
+ },
+ set: function (value) {
+ this._cycleDuration = value;
+ this.updateSpriteSheetData();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleSpriteSheetState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (animationRegisterCache.needUVAnimation) {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSpriteSheetState.UV_INDEX_0), this._spriteSheetData[0], this._spriteSheetData[1], this._spriteSheetData[2], this._spriteSheetData[3]);
+ if (this._usesCycle) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSpriteSheetState.UV_INDEX_1);
+ if (this._particleSpriteSheetNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleSpriteSheetNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleSpriteSheetNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_2);
+ }
+ else
+ animationRegisterCache.setVertexConst(index, this._spriteSheetData[4], this._spriteSheetData[5]);
+ }
+ }
+ };
+ ParticleSpriteSheetState.prototype.updateSpriteSheetData = function () {
+ this._spriteSheetData = new Array(8);
+ var uTotal = this._totalFrames / this._numColumns;
+ this._spriteSheetData[0] = uTotal;
+ this._spriteSheetData[1] = 1 / this._numColumns;
+ this._spriteSheetData[2] = 1 / this._numRows;
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw (new Error("the cycle duration must be greater than zero"));
+ this._spriteSheetData[4] = uTotal / this._cycleDuration;
+ this._spriteSheetData[5] = this._cycleDuration;
+ if (this._usesPhase)
+ this._spriteSheetData[6] = this._cyclePhase;
+ }
+ };
+ /** @private */
+ ParticleSpriteSheetState.UV_INDEX_0 = 0;
+ /** @private */
+ ParticleSpriteSheetState.UV_INDEX_1 = 1;
+ return ParticleSpriteSheetState;
+})(ParticleStateBase);
+module.exports = ParticleSpriteSheetState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVzcHJpdGVzaGVldHN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZSIsIlBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlU3ByaXRlU2hlZXRTdGF0ZS5jeWNsZVBoYXNlIiwiUGFydGljbGVTcHJpdGVTaGVldFN0YXRlLmN5Y2xlRHVyYXRpb24iLCJQYXJ0aWNsZVNwcml0ZVNoZWV0U3RhdGUuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZVNwcml0ZVNoZWV0U3RhdGUudXBkYXRlU3ByaXRlU2hlZXREYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFJN0csSUFBTyxzQkFBc0IsV0FBYSw2REFBNkQsQ0FBQyxDQUFDO0FBRXpHLElBQU8saUJBQWlCLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUVsRyxBQUdBOztHQURHO0lBQ0csd0JBQXdCO0lBQVNBLFVBQWpDQSx3QkFBd0JBLFVBQTBCQTtJQWdEdkRBLFNBaERLQSx3QkFBd0JBLENBZ0RqQkEsUUFBeUJBLEVBQUVBLHVCQUErQ0E7UUFFckZDLGtCQUFNQSxRQUFRQSxFQUFFQSx1QkFBdUJBLENBQUNBLENBQUNBO1FBRXpDQSxJQUFJQSxDQUFDQSx3QkFBd0JBLEdBQUdBLHVCQUF1QkEsQ0FBQ0E7UUFFeERBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDNURBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDNURBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7UUFDaEVBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlB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QUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtZQUMvQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7Z0JBQ25CQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBQzlDQSxDQUFDQTtJQUNGQSxDQUFDQTtJQWxHREwsZUFBZUE7SUFDREEsbUNBQVVBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUU3Q0EsZUFBZUE7SUFDREEsbUNBQVVBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQStGOUNBLCtCQUFDQTtBQUFEQSxDQXJHQSxBQXFHQ0EsRUFyR3NDLGlCQUFpQixFQXFHdkQ7QUFFRCxBQUFrQyxpQkFBekIsd0JBQXdCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVNwcml0ZVNoZWV0U3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTcHJpdGVTaGVldE5vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlU3ByaXRlU2hlZXROb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVTcHJpdGVTaGVldFN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgVVZfSU5ERVhfMDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFVWX0lOREVYXzE6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHRwcml2YXRlIF9wYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZTpQYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZTtcblx0cHJpdmF0ZSBfdXNlc0N5Y2xlOmJvb2xlYW47XG5cdHByaXZhdGUgX3VzZXNQaGFzZTpib29sZWFuO1xuXHRwcml2YXRlIF90b3RhbEZyYW1lczpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBfbnVtQ29sdW1uczpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBfbnVtUm93czpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBfY3ljbGVEdXJhdGlvbjpudW1iZXI7XG5cdHByaXZhdGUgX2N5Y2xlUGhhc2U6bnVtYmVyO1xuXHRwcml2YXRlIF9zcHJpdGVTaGVldERhdGE6QXJyYXk8bnVtYmVyPjtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgY3ljbGUgcGhhc2UsIHdoZW4gaW4gZ2xvYmFsIG1vZGUuIERlZmF1bHRzIHRvIHplcm8uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGN5Y2xlUGhhc2UoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9jeWNsZVBoYXNlO1xuXHR9XG5cblx0cHVibGljIHNldCBjeWNsZVBoYXNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2N5Y2xlUGhhc2UgPSB2YWx1ZTtcblxuXHRcdHRoaXMudXBkYXRlU3ByaXRlU2hlZXREYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgY3ljbGUgZHVyYXRpb24gaW4gc2Vjb25kcywgd2hlbiBpbiBnbG9iYWwgbW9kZS4gRGVmYXVsdHMgdG8gMS5cblx0ICovXG5cdHB1YmxpYyBnZXQgY3ljbGVEdXJhdGlvbigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N5Y2xlRHVyYXRpb247XG5cdH1cblxuXHRwdWJsaWMgc2V0IGN5Y2xlRHVyYXRpb24odmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fY3ljbGVEdXJhdGlvbiA9IHZhbHVlO1xuXG5cdFx0dGhpcy51cGRhdGVTcHJpdGVTaGVldERhdGEoKTtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOlBhcnRpY2xlQW5pbWF0b3IsIHBhcnRpY2xlU3ByaXRlU2hlZXROb2RlOlBhcnRpY2xlU3ByaXRlU2hlZXROb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHBhcnRpY2xlU3ByaXRlU2hlZXROb2RlKTtcblxuXHRcdHRoaXMuX3BhcnRpY2xlU3ByaXRlU2hlZXROb2RlID0gcGFydGljbGVTcHJpdGVTaGVldE5vZGU7XG5cblx0XHR0aGlzLl91c2VzQ3ljbGUgPSB0aGlzLl9wYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5faVVzZXNDeWNsZTtcblx0XHR0aGlzLl91c2VzUGhhc2UgPSB0aGlzLl9wYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5faVVzZXNDeWNsZTtcblx0XHR0aGlzLl90b3RhbEZyYW1lcyA9IHRoaXMuX3BhcnRpY2xlU3ByaXRlU2hlZXROb2RlLl9pVG90YWxGcmFtZXM7XG5cdFx0dGhpcy5fbnVtQ29sdW1ucyA9IHRoaXMuX3BhcnRpY2xlU3ByaXRlU2hlZXROb2RlLl9pTnVtQ29sdW1ucztcblx0XHR0aGlzLl9udW1Sb3dzID0gdGhpcy5fcGFydGljbGVTcHJpdGVTaGVldE5vZGUuX2lOdW1Sb3dzO1xuXHRcdHRoaXMuX2N5Y2xlRHVyYXRpb24gPSB0aGlzLl9wYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5faUN5Y2xlRHVyYXRpb247XG5cdFx0dGhpcy5fY3ljbGVQaGFzZSA9IHRoaXMuX3BhcnRpY2xlU3ByaXRlU2hlZXROb2RlLl9pQ3ljbGVQaGFzZTtcblxuXHRcdHRoaXMudXBkYXRlU3ByaXRlU2hlZXREYXRhKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0UmVuZGVyU3RhdGUoc3RhZ2U6U3RhZ2UsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5LCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHRpZiAoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5uZWVkVVZBbmltYXRpb24pIHtcblx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVNwcml0ZVNoZWV0U3RhdGUuVVZfSU5ERVhfMCksIHRoaXMuX3Nwcml0ZVNoZWV0RGF0YVswXSwgdGhpcy5fc3ByaXRlU2hlZXREYXRhWzFdLCB0aGlzLl9zcHJpdGVTaGVldERhdGFbMl0sIHRoaXMuX3Nwcml0ZVNoZWV0RGF0YVszXSk7XG5cdFx0XHRpZiAodGhpcy5fdXNlc0N5Y2xlKSB7XG5cdFx0XHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVTcHJpdGVTaGVldFN0YXRlLlVWX0lOREVYXzEpO1xuXHRcdFx0XHRpZiAodGhpcy5fcGFydGljbGVTcHJpdGVTaGVldE5vZGUubW9kZSA9PSBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlLkxPQ0FMX1NUQVRJQykge1xuXHRcdFx0XHRcdGlmICh0aGlzLl91c2VzUGhhc2UpXG5cdFx0XHRcdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihpbmRleCwgdGhpcy5fcGFydGljbGVTcHJpdGVTaGVldE5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHRcdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGluZGV4LCB0aGlzLl9wYXJ0aWNsZVNwcml0ZVNoZWV0Tm9kZS5faURhdGFPZmZzZXQsIHN0YWdlLCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXQuRkxPQVRfMik7XG5cdFx0XHRcdH0gZWxzZVxuXHRcdFx0XHRcdGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuc2V0VmVydGV4Q29uc3QoaW5kZXgsIHRoaXMuX3Nwcml0ZVNoZWV0RGF0YVs0XSwgdGhpcy5fc3ByaXRlU2hlZXREYXRhWzVdKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZVNwcml0ZVNoZWV0RGF0YSgpXG5cdHtcblx0XHR0aGlzLl9zcHJpdGVTaGVldERhdGEgPSBuZXcgQXJyYXk8bnVtYmVyPig4KTtcblxuXHRcdHZhciB1VG90YWw6bnVtYmVyID0gdGhpcy5fdG90YWxGcmFtZXMvdGhpcy5fbnVtQ29sdW1ucztcblxuXHRcdHRoaXMuX3Nwcml0ZVNoZWV0RGF0YVswXSA9IHVUb3RhbDtcblx0XHR0aGlzLl9zcHJpdGVTaGVldERhdGFbMV0gPSAxL3RoaXMuX251bUNvbHVtbnM7XG5cdFx0dGhpcy5fc3ByaXRlU2hlZXREYXRhWzJdID0gMS90aGlzLl9udW1Sb3dzO1xuXG5cdFx0aWYgKHRoaXMuX3VzZXNDeWNsZSkge1xuXHRcdFx0aWYgKHRoaXMuX2N5Y2xlRHVyYXRpb24gPD0gMClcblx0XHRcdFx0dGhyb3cobmV3IEVycm9yKFwidGhlIGN5Y2xlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm9cIikpO1xuXHRcdFx0dGhpcy5fc3ByaXRlU2hlZXREYXRhWzRdID0gdVRvdGFsL3RoaXMuX2N5Y2xlRHVyYXRpb247XG5cdFx0XHR0aGlzLl9zcHJpdGVTaGVldERhdGFbNV0gPSB0aGlzLl9jeWNsZUR1cmF0aW9uO1xuXHRcdFx0aWYgKHRoaXMuX3VzZXNQaGFzZSlcblx0XHRcdFx0dGhpcy5fc3ByaXRlU2hlZXREYXRhWzZdID0gdGhpcy5fY3ljbGVQaGFzZTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVTcHJpdGVTaGVldFN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/ParticleSpriteSheetState.ts b/lib/animators/states/ParticleSpriteSheetState.ts
new file mode 100644
index 000000000..39952bb94
--- /dev/null
+++ b/lib/animators/states/ParticleSpriteSheetState.ts
@@ -0,0 +1,121 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleSpriteSheetNode = require("awayjs-renderergl/lib/animators/nodes/ParticleSpriteSheetNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleSpriteSheetState extends ParticleStateBase
+{
+ /** @private */
+ public static UV_INDEX_0:number /*uint*/ = 0;
+
+ /** @private */
+ public static UV_INDEX_1:number /*uint*/ = 1;
+
+ private _particleSpriteSheetNode:ParticleSpriteSheetNode;
+ private _usesCycle:boolean;
+ private _usesPhase:boolean;
+ private _totalFrames:number /*int*/;
+ private _numColumns:number /*int*/;
+ private _numRows:number /*int*/;
+ private _cycleDuration:number;
+ private _cyclePhase:number;
+ private _spriteSheetData:Array;
+
+ /**
+ * Defines the cycle phase, when in global mode. Defaults to zero.
+ */
+ public get cyclePhase():number
+ {
+ return this._cyclePhase;
+ }
+
+ public set cyclePhase(value:number)
+ {
+ this._cyclePhase = value;
+
+ this.updateSpriteSheetData();
+ }
+
+ /**
+ * Defines the cycle duration in seconds, when in global mode. Defaults to 1.
+ */
+ public get cycleDuration():number
+ {
+ return this._cycleDuration;
+ }
+
+ public set cycleDuration(value:number)
+ {
+ this._cycleDuration = value;
+
+ this.updateSpriteSheetData();
+ }
+
+ constructor(animator:ParticleAnimator, particleSpriteSheetNode:ParticleSpriteSheetNode)
+ {
+ super(animator, particleSpriteSheetNode);
+
+ this._particleSpriteSheetNode = particleSpriteSheetNode;
+
+ this._usesCycle = this._particleSpriteSheetNode._iUsesCycle;
+ this._usesPhase = this._particleSpriteSheetNode._iUsesCycle;
+ this._totalFrames = this._particleSpriteSheetNode._iTotalFrames;
+ this._numColumns = this._particleSpriteSheetNode._iNumColumns;
+ this._numRows = this._particleSpriteSheetNode._iNumRows;
+ this._cycleDuration = this._particleSpriteSheetNode._iCycleDuration;
+ this._cyclePhase = this._particleSpriteSheetNode._iCyclePhase;
+
+ this.updateSpriteSheetData();
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (animationRegisterCache.needUVAnimation) {
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSpriteSheetState.UV_INDEX_0), this._spriteSheetData[0], this._spriteSheetData[1], this._spriteSheetData[2], this._spriteSheetData[3]);
+ if (this._usesCycle) {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleSpriteSheetState.UV_INDEX_1);
+ if (this._particleSpriteSheetNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
+ if (this._usesPhase)
+ animationSubGeometry.activateVertexBuffer(index, this._particleSpriteSheetNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleSpriteSheetNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_2);
+ } else
+ animationRegisterCache.setVertexConst(index, this._spriteSheetData[4], this._spriteSheetData[5]);
+ }
+ }
+ }
+
+ private updateSpriteSheetData()
+ {
+ this._spriteSheetData = new Array(8);
+
+ var uTotal:number = this._totalFrames/this._numColumns;
+
+ this._spriteSheetData[0] = uTotal;
+ this._spriteSheetData[1] = 1/this._numColumns;
+ this._spriteSheetData[2] = 1/this._numRows;
+
+ if (this._usesCycle) {
+ if (this._cycleDuration <= 0)
+ throw(new Error("the cycle duration must be greater than zero"));
+ this._spriteSheetData[4] = uTotal/this._cycleDuration;
+ this._spriteSheetData[5] = this._cycleDuration;
+ if (this._usesPhase)
+ this._spriteSheetData[6] = this._cyclePhase;
+ }
+ }
+}
+
+export = ParticleSpriteSheetState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleStateBase.js b/lib/animators/states/ParticleStateBase.js
new file mode 100755
index 000000000..d1f276583
--- /dev/null
+++ b/lib/animators/states/ParticleStateBase.js
@@ -0,0 +1,74 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+/**
+ * ...
+ */
+var ParticleStateBase = (function (_super) {
+ __extends(ParticleStateBase, _super);
+ function ParticleStateBase(animator, particleNode, needUpdateTime) {
+ if (needUpdateTime === void 0) { needUpdateTime = false; }
+ _super.call(this, animator, particleNode);
+ this._pDynamicProperties = new Array();
+ this._pDynamicPropertiesDirty = new Object();
+ this._particleNode = particleNode;
+ this._pNeedUpdateTime = needUpdateTime;
+ }
+ Object.defineProperty(ParticleStateBase.prototype, "needUpdateTime", {
+ get: function () {
+ return this._pNeedUpdateTime;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ParticleStateBase.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ };
+ ParticleStateBase.prototype._pUpdateDynamicProperties = function (animationSubGeometry) {
+ this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId] = true;
+ var animationParticles = animationSubGeometry.animationParticles;
+ var vertexData = animationSubGeometry.vertexData;
+ var totalLenOfOneVertex = animationSubGeometry.totalLenOfOneVertex;
+ var dataLength = this._particleNode.dataLength;
+ var dataOffset = this._particleNode._iDataOffset;
+ var vertexLength /*uint*/;
+ // var particleOffset:number /*uint*/;
+ var startingOffset /*uint*/;
+ var vertexOffset /*uint*/;
+ var data;
+ var animationParticle;
+ // var numParticles:number /*uint*/ = _positions.length/dataLength;
+ var numParticles = this._pDynamicProperties.length;
+ var i = 0;
+ var j = 0;
+ var k = 0;
+ while (i < numParticles) {
+ while (j < numParticles && (animationParticle = animationParticles[j]).index == i) {
+ data = this._pDynamicProperties[i];
+ vertexLength = animationParticle.numVertices * totalLenOfOneVertex;
+ startingOffset = animationParticle.startVertexIndex * totalLenOfOneVertex + dataOffset;
+ for (k = 0; k < vertexLength; k += totalLenOfOneVertex) {
+ vertexOffset = startingOffset + k;
+ for (k = 0; k < vertexLength; k += totalLenOfOneVertex) {
+ vertexOffset = startingOffset + k;
+ vertexData[vertexOffset++] = data.x;
+ vertexData[vertexOffset++] = data.y;
+ vertexData[vertexOffset++] = data.z;
+ if (dataLength == 4)
+ vertexData[vertexOffset++] = data.w;
+ }
+ }
+ j++;
+ }
+ i++;
+ }
+ animationSubGeometry.invalidateBuffer();
+ };
+ return ParticleStateBase;
+})(AnimationStateBase);
+module.exports = ParticleStateBase;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVzdGF0ZWJhc2UudHMiXSwibmFtZXMiOlsiUGFydGljbGVTdGF0ZUJhc2UiLCJQYXJ0aWNsZVN0YXRlQmFzZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlU3RhdGVCYXNlLm5lZWRVcGRhdGVUaW1lIiwiUGFydGljbGVTdGF0ZUJhc2Uuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZVN0YXRlQmFzZS5fcFVwZGF0ZUR5bmFtaWNQcm9wZXJ0aWVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFXQSxJQUFPLGtCQUFrQixXQUFjLDJEQUEyRCxDQUFDLENBQUM7QUFFcEcsQUFHQTs7R0FERztJQUNHLGlCQUFpQjtJQUFTQSxVQUExQkEsaUJBQWlCQSxVQUEyQkE7SUFTakRBLFNBVEtBLGlCQUFpQkEsQ0FTVkEsUUFBeUJBLEVBQUVBLFlBQTZCQSxFQUFFQSxjQUE4QkE7UUFBOUJDLDhCQUE4QkEsR0FBOUJBLHNCQUE4QkE7UUFFbkdBLGtCQUFNQSxRQUFRQSxFQUFFQSxZQUFZQSxDQUFDQSxDQUFDQTtRQVB4QkEsd0JBQW1CQSxHQUFtQkEsSUFBSUEsS0FBS0EsRUFBWUEsQ0FBQ0E7UUFDNURBLDZCQUF3QkEsR0FBVUEsSUFBSUEsTUFBTUEsRUFBRUEsQ0FBQ0E7UUFRckRBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLFlBQVlBLENBQUNBO1FBQ2xDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLGNBQWNBLENBQUNBO0lBQ3hDQSxDQUFDQTtJQUVERCxzQkFBV0EsNkNBQWNBO2FBQXpCQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1FBQzlCQSxDQUFDQTs7O09BQUFGO0lBRU1BLDBDQUFjQSxHQUFyQkEsVUFBc0JBLEtBQVdBLEVBQUVBLFVBQXlCQSxFQUFFQSxvQkFBeUNBLEVBQUVBLHNCQUE2Q0EsRUFBRUEsTUFBYUE7SUFHcktHLENBQUNBO0lBRU1ILHFEQUF5QkEsR0FBaENBLFVBQWlD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QUNBO1lBQ0xBLENBQUNBO1lBQ0RBLENBQUNBLEVBQUVBLENBQUNBO1FBQ0xBLENBQUNBO1FBRURBLG9CQUFvQkEsQ0FBQ0EsZ0JBQWdCQSxFQUFFQSxDQUFDQTtJQUN6Q0EsQ0FBQ0E7SUFFRkosd0JBQUNBO0FBQURBLENBMUZBLEFBMEZDQSxFQTFGK0Isa0JBQWtCLEVBMEZqRDtBQUVELEFBQTJCLGlCQUFsQixpQkFBaUIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZUFuaW1hdGlvbkRhdGFcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVBbmltYXRpb25EYXRhXCIpO1xuaW1wb3J0IFBhcnRpY2xlTm9kZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9QYXJ0aWNsZU5vZGVCYXNlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZVN0YXRlQmFzZSBleHRlbmRzIEFuaW1hdGlvblN0YXRlQmFzZVxue1xuXHRwcml2YXRlIF9wYXJ0aWNsZU5vZGU6UGFydGljbGVOb2RlQmFzZTtcblxuXHRwdWJsaWMgX3BEeW5hbWljUHJvcGVydGllczpBcnJheTxWZWN0b3IzRD4gPSBuZXcgQXJyYXk8VmVjdG9yM0Q+KCk7XG5cdHB1YmxpYyBfcER5bmFtaWNQcm9wZXJ0aWVzRGlydHk6T2JqZWN0ID0gbmV3IE9iamVjdCgpO1xuXG5cdHB1YmxpYyBfcE5lZWRVcGRhdGVUaW1lOmJvb2xlYW47XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6UGFydGljbGVBbmltYXRvciwgcGFydGljbGVOb2RlOlBhcnRpY2xlTm9kZUJhc2UsIG5lZWRVcGRhdGVUaW1lOmJvb2xlYW4gPSBmYWxzZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZU5vZGUpO1xuXG5cdFx0dGhpcy5fcGFydGljbGVOb2RlID0gcGFydGljbGVOb2RlO1xuXHRcdHRoaXMuX3BOZWVkVXBkYXRlVGltZSA9IG5lZWRVcGRhdGVUaW1lO1xuXHR9XG5cblx0cHVibGljIGdldCBuZWVkVXBkYXRlVGltZSgpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9wTmVlZFVwZGF0ZVRpbWU7XG5cdH1cblxuXHRwdWJsaWMgc2V0UmVuZGVyU3RhdGUoc3RhZ2U6U3RhZ2UsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIGFuaW1hdGlvblN1Ykdlb21ldHJ5OkFuaW1hdGlvblN1Ykdlb21ldHJ5LCBhbmltYXRpb25SZWdpc3RlckNhY2hlOkFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUsIGNhbWVyYTpDYW1lcmEpXG5cdHtcblxuXHR9XG5cblx0cHVibGljIF9wVXBkYXRlRHluYW1pY1Byb3BlcnRpZXMoYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnkpXG5cdHtcblx0XHR0aGlzLl9wRHluYW1pY1Byb3BlcnRpZXNEaXJ0eVthbmltYXRpb25TdWJHZW9tZXRyeS5faVVuaXF1ZUlkXSA9IHRydWU7XG5cblx0XHR2YXIgYW5pbWF0aW9uUGFydGljbGVzOkFycmF5PFBhcnRpY2xlQW5pbWF0aW9uRGF0YT4gPSBhbmltYXRpb25TdWJHZW9tZXRyeS5hbmltYXRpb25QYXJ0aWNsZXM7XG5cdFx0dmFyIHZlcnRleERhdGE6QXJyYXk8bnVtYmVyPiA9IGFuaW1hdGlvblN1Ykdlb21ldHJ5LnZlcnRleERhdGE7XG5cdFx0dmFyIHRvdGFsTGVuT2ZPbmVWZXJ0ZXg6bnVtYmVyIC8qdWludCovID0gYW5pbWF0aW9uU3ViR2VvbWV0cnkudG90YWxMZW5PZk9uZVZlcnRleDtcblx0XHR2YXIgZGF0YUxlbmd0aDpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wYXJ0aWNsZU5vZGUuZGF0YUxlbmd0aDtcblx0XHR2YXIgZGF0YU9mZnNldDpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9wYXJ0aWNsZU5vZGUuX2lEYXRhT2Zmc2V0O1xuXHRcdHZhciB2ZXJ0ZXhMZW5ndGg6bnVtYmVyIC8qdWludCovO1xuXHRcdC8vXHRcdFx0dmFyIHBhcnRpY2xlT2Zmc2V0Om51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgc3RhcnRpbmdPZmZzZXQ6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciB2ZXJ0ZXhPZmZzZXQ6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBkYXRhOlZlY3RvcjNEO1xuXHRcdHZhciBhbmltYXRpb25QYXJ0aWNsZTpQYXJ0aWNsZUFuaW1hdGlvbkRhdGE7XG5cblx0XHQvL1x0XHRcdHZhciBudW1QYXJ0aWNsZXM6bnVtYmVyIC8qdWludCovID0gX3Bvc2l0aW9ucy5sZW5ndGgvZGF0YUxlbmd0aDtcblx0XHR2YXIgbnVtUGFydGljbGVzOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX3BEeW5hbWljUHJvcGVydGllcy5sZW5ndGg7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovID0gMDtcblx0XHR2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRcdHZhciBrOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0XHQvL2xvb3AgdGhyb3VnaCBhbGwgcGFydGljbGVzXG5cdFx0d2hpbGUgKGkgPCBudW1QYXJ0aWNsZXMpIHtcblx0XHRcdC8vbG9vcCB0aHJvdWdoIGVhY2ggcGFydGljbGUgZGF0YSBmb3IgdGhlIGN1cnJlbnQgcGFydGljbGVcblx0XHRcdHdoaWxlIChqIDwgbnVtUGFydGljbGVzICYmIChhbmltYXRpb25QYXJ0aWNsZSA9IGFuaW1hdGlvblBhcnRpY2xlc1tqXSkuaW5kZXggPT0gaSkge1xuXHRcdFx0XHRkYXRhID0gdGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzW2ldO1xuXHRcdFx0XHR2ZXJ0ZXhMZW5ndGggPSBhbmltYXRpb25QYXJ0aWNsZS5udW1WZXJ0aWNlcyp0b3RhbExlbk9mT25lVmVydGV4O1xuXHRcdFx0XHRzdGFydGluZ09mZnNldCA9IGFuaW1hdGlvblBhcnRpY2xlLnN0YXJ0VmVydGV4SW5kZXgqdG90YWxMZW5PZk9uZVZlcnRleCArIGRhdGFPZmZzZXQ7XG5cdFx0XHRcdC8vbG9vcCB0aHJvdWdoIGVhY2ggdmVydGV4IGluIHRoZSBwYXJ0aWNsZSBkYXRhXG5cdFx0XHRcdGZvciAoayA9IDA7IGsgPCB2ZXJ0ZXhMZW5ndGg7IGsgKz0gdG90YWxMZW5PZk9uZVZlcnRleCkge1xuXHRcdFx0XHRcdHZlcnRleE9mZnNldCA9IHN0YXJ0aW5nT2Zmc2V0ICsgaztcblx0XHRcdFx0XHQvL1x0XHRcdFx0XHRcdHBhcnRpY2xlT2Zmc2V0ID0gaSAqIGRhdGFMZW5ndGg7XG5cdFx0XHRcdFx0Ly9sb29wIHRocm91Z2ggYWxsIHZlcnRleCBkYXRhIGZvciB0aGUgY3VycmVudCBwYXJ0aWNsZSBkYXRhXG5cdFx0XHRcdFx0Zm9yIChrID0gMDsgayA8IHZlcnRleExlbmd0aDsgayArPSB0b3RhbExlbk9mT25lVmVydGV4KSB7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhPZmZzZXQgPSBzdGFydGluZ09mZnNldCArIGs7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW3ZlcnRleE9mZnNldCsrXSA9IGRhdGEueDtcblx0XHRcdFx0XHRcdHZlcnRleERhdGFbdmVydGV4T2Zmc2V0KytdID0gZGF0YS55O1xuXHRcdFx0XHRcdFx0dmVydGV4RGF0YVt2ZXJ0ZXhPZmZzZXQrK10gPSBkYXRhLno7XG5cblx0XHRcdFx0XHRcdGlmIChkYXRhTGVuZ3RoID09IDQpXG5cdFx0XHRcdFx0XHRcdHZlcnRleERhdGFbdmVydGV4T2Zmc2V0KytdID0gZGF0YS53O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdC8vbG9vcCB0aHJvdWdoIGVhY2ggdmFsdWUgaW4gdGhlIHBhcnRpY2xlIHZlcnRleFxuXHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHRzd2l0Y2goZGF0YUxlbmd0aCkge1xuXHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHRcdGNhc2UgNDpcblx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0XHRcdHZlcnRleERhdGFbdmVydGV4T2Zmc2V0KytdID0gX3Bvc2l0aW9uc1twYXJ0aWNsZU9mZnNldCsrXTtcblx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0XHRjYXNlIDM6XG5cdFx0XHRcdFx0XHQvL1x0XHRcdFx0XHRcdFx0XHR2ZXJ0ZXhEYXRhW3ZlcnRleE9mZnNldCsrXSA9IF9wb3NpdGlvbnNbcGFydGljbGVPZmZzZXQrK107XG5cdFx0XHRcdFx0XHQvL1x0XHRcdFx0XHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHRcdFx0dmVydGV4RGF0YVt2ZXJ0ZXhPZmZzZXQrK10gPSBfcG9zaXRpb25zW3BhcnRpY2xlT2Zmc2V0KytdO1xuXHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHRcdGNhc2UgMTpcblx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0XHRcdHZlcnRleERhdGFbdmVydGV4T2Zmc2V0KytdID0gX3Bvc2l0aW9uc1twYXJ0aWNsZU9mZnNldCsrXTtcblx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGorKztcblx0XHRcdH1cblx0XHRcdGkrKztcblx0XHR9XG5cblx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5pbnZhbGlkYXRlQnVmZmVyKCk7XG5cdH1cblxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVN0YXRlQmFzZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleStateBase.ts b/lib/animators/states/ParticleStateBase.ts
new file mode 100644
index 000000000..919d4c083
--- /dev/null
+++ b/lib/animators/states/ParticleStateBase.ts
@@ -0,0 +1,109 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleAnimationData = require("awayjs-renderergl/lib/animators/data/ParticleAnimationData");
+import ParticleNodeBase = require("awayjs-renderergl/lib/animators/nodes/ParticleNodeBase");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+
+/**
+ * ...
+ */
+class ParticleStateBase extends AnimationStateBase
+{
+ private _particleNode:ParticleNodeBase;
+
+ public _pDynamicProperties:Array = new Array();
+ public _pDynamicPropertiesDirty:Object = new Object();
+
+ public _pNeedUpdateTime:boolean;
+
+ constructor(animator:ParticleAnimator, particleNode:ParticleNodeBase, needUpdateTime:boolean = false)
+ {
+ super(animator, particleNode);
+
+ this._particleNode = particleNode;
+ this._pNeedUpdateTime = needUpdateTime;
+ }
+
+ public get needUpdateTime():boolean
+ {
+ return this._pNeedUpdateTime;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+
+ }
+
+ public _pUpdateDynamicProperties(animationSubGeometry:AnimationSubGeometry)
+ {
+ this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId] = true;
+
+ var animationParticles:Array = animationSubGeometry.animationParticles;
+ var vertexData:Array = animationSubGeometry.vertexData;
+ var totalLenOfOneVertex:number /*uint*/ = animationSubGeometry.totalLenOfOneVertex;
+ var dataLength:number /*uint*/ = this._particleNode.dataLength;
+ var dataOffset:number /*uint*/ = this._particleNode._iDataOffset;
+ var vertexLength:number /*uint*/;
+ // var particleOffset:number /*uint*/;
+ var startingOffset:number /*uint*/;
+ var vertexOffset:number /*uint*/;
+ var data:Vector3D;
+ var animationParticle:ParticleAnimationData;
+
+ // var numParticles:number /*uint*/ = _positions.length/dataLength;
+ var numParticles:number /*uint*/ = this._pDynamicProperties.length;
+ var i:number /*uint*/ = 0;
+ var j:number /*uint*/ = 0;
+ var k:number /*uint*/ = 0;
+
+ //loop through all particles
+ while (i < numParticles) {
+ //loop through each particle data for the current particle
+ while (j < numParticles && (animationParticle = animationParticles[j]).index == i) {
+ data = this._pDynamicProperties[i];
+ vertexLength = animationParticle.numVertices*totalLenOfOneVertex;
+ startingOffset = animationParticle.startVertexIndex*totalLenOfOneVertex + dataOffset;
+ //loop through each vertex in the particle data
+ for (k = 0; k < vertexLength; k += totalLenOfOneVertex) {
+ vertexOffset = startingOffset + k;
+ // particleOffset = i * dataLength;
+ //loop through all vertex data for the current particle data
+ for (k = 0; k < vertexLength; k += totalLenOfOneVertex) {
+ vertexOffset = startingOffset + k;
+ vertexData[vertexOffset++] = data.x;
+ vertexData[vertexOffset++] = data.y;
+ vertexData[vertexOffset++] = data.z;
+
+ if (dataLength == 4)
+ vertexData[vertexOffset++] = data.w;
+ }
+ //loop through each value in the particle vertex
+ // switch(dataLength) {
+ // case 4:
+ // vertexData[vertexOffset++] = _positions[particleOffset++];
+ // case 3:
+ // vertexData[vertexOffset++] = _positions[particleOffset++];
+ // case 2:
+ // vertexData[vertexOffset++] = _positions[particleOffset++];
+ // case 1:
+ // vertexData[vertexOffset++] = _positions[particleOffset++];
+ // }
+ }
+ j++;
+ }
+ i++;
+ }
+
+ animationSubGeometry.invalidateBuffer();
+ }
+
+}
+
+export = ParticleStateBase;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleTimeState.js b/lib/animators/states/ParticleTimeState.js
new file mode 100755
index 000000000..51594a7e4
--- /dev/null
+++ b/lib/animators/states/ParticleTimeState.js
@@ -0,0 +1,31 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleTimeState = (function (_super) {
+ __extends(ParticleTimeState, _super);
+ function ParticleTimeState(animator, particleTimeNode) {
+ _super.call(this, animator, particleTimeNode, true);
+ this._particleTimeNode = particleTimeNode;
+ }
+ ParticleTimeState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleTimeState.TIME_STREAM_INDEX), this._particleTimeNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+ var particleTime = this._pTime / 1000;
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleTimeState.TIME_CONSTANT_INDEX), particleTime, particleTime, particleTime, particleTime);
+ };
+ /** @private */
+ ParticleTimeState.TIME_STREAM_INDEX = 0;
+ /** @private */
+ ParticleTimeState.TIME_CONSTANT_INDEX = 1;
+ return ParticleTimeState;
+})(ParticleStateBase);
+module.exports = ParticleTimeState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGV0aW1lc3RhdGUudHMiXSwibmFtZXMiOlsiUGFydGljbGVUaW1lU3RhdGUiLCJQYXJ0aWNsZVRpbWVTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlVGltZVN0YXRlLnNldFJlbmRlclN0YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFLQSxJQUFPLDJCQUEyQixXQUFZLDZEQUE2RCxDQUFDLENBQUM7QUFNN0csSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxpQkFBaUI7SUFBU0EsVUFBMUJBLGlCQUFpQkEsVUFBMEJBO0lBVWhEQSxTQVZLQSxpQkFBaUJBLENBVVZBLFFBQXlCQSxFQUFFQSxnQkFBaUNBO1FBRXZFQyxrQkFBTUEsUUFBUUEsRUFBRUEsZ0JBQWdCQSxFQUFFQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUV4Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxnQkFBZ0JBLENBQUNBO0lBQzNDQSxDQUFDQTtJQUVNRCwwQ0FBY0EsR0FBckJBLFVBQXNCQSxLQUFXQSxFQUFFQSxVQUF5QkEsRUFBRUEsb0JBQXlDQSxFQUFFQSxzQkFBNkNBLEVBQUVBLE1BQWFBO1FBRXBLRSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLGlCQUFpQkEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFlBQVlBLEVBQUVBLEtBQUtBLEVBQUVBLDJCQUEyQkEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0E7UUFFL05BLElBQUlBLFlBQVlBLEdBQVVBLElBQUlBLENBQUNBLE1BQU1BLEdBQUNBLElBQUlBLENBQUNBO1FBQzNDQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxFQUFFQSxpQkFBaUJBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsRUFBRUEsWUFBWUEsRUFBRUEsWUFBWUEsRUFBRUEsWUFBWUEsRUFBRUEsWUFBWUEsQ0FBQ0EsQ0FBQ0E7SUFDck1BLENBQUNBO0lBckJERixlQUFlQTtJQUNEQSxtQ0FBaUJBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUVwREEsZUFBZUE7SUFDREEscUNBQW1CQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7SUFtQnZEQSx3QkFBQ0E7QUFBREEsQ0F6QkEsQUF5QkNBLEVBekIrQixpQkFBaUIsRUF5QmhEO0FBRUQsQUFBMkIsaUJBQWxCLGlCQUFpQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVUaW1lU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0XCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVByb3BlcnRpZXNNb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1BhcnRpY2xlUHJvcGVydGllc01vZGVcIik7XG5pbXBvcnQgUGFydGljbGVUaW1lTm9kZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlVGltZU5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqIC4uLlxuICovXG5jbGFzcyBQYXJ0aWNsZVRpbWVTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFRJTUVfU1RSRUFNX0lOREVYOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgVElNRV9DT05TVEFOVF9JTkRFWDpudW1iZXIgLyp1aW50Ki8gPSAxO1xuXG5cdHByaXZhdGUgX3BhcnRpY2xlVGltZU5vZGU6UGFydGljbGVUaW1lTm9kZTtcblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpQYXJ0aWNsZUFuaW1hdG9yLCBwYXJ0aWNsZVRpbWVOb2RlOlBhcnRpY2xlVGltZU5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgcGFydGljbGVUaW1lTm9kZSwgdHJ1ZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZVRpbWVOb2RlID0gcGFydGljbGVUaW1lTm9kZTtcblx0fVxuXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGFuaW1hdGlvblN1Ykdlb21ldHJ5LmFjdGl2YXRlVmVydGV4QnVmZmVyKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVUaW1lU3RhdGUuVElNRV9TVFJFQU1fSU5ERVgpLCB0aGlzLl9wYXJ0aWNsZVRpbWVOb2RlLl9pRGF0YU9mZnNldCwgc3RhZ2UsIENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdC5GTE9BVF80KTtcblxuXHRcdHZhciBwYXJ0aWNsZVRpbWU6bnVtYmVyID0gdGhpcy5fcFRpbWUvMTAwMDtcblx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUuZ2V0UmVnaXN0ZXJJbmRleCh0aGlzLl9wQW5pbWF0aW9uTm9kZSwgUGFydGljbGVUaW1lU3RhdGUuVElNRV9DT05TVEFOVF9JTkRFWCksIHBhcnRpY2xlVGltZSwgcGFydGljbGVUaW1lLCBwYXJ0aWNsZVRpbWUsIHBhcnRpY2xlVGltZSk7XG5cdH1cblxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZVRpbWVTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleTimeState.ts b/lib/animators/states/ParticleTimeState.ts
new file mode 100644
index 000000000..2f6ee07e8
--- /dev/null
+++ b/lib/animators/states/ParticleTimeState.ts
@@ -0,0 +1,44 @@
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleTimeNode = require("awayjs-renderergl/lib/animators/nodes/ParticleTimeNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleTimeState extends ParticleStateBase
+{
+ /** @private */
+ public static TIME_STREAM_INDEX:number /*uint*/ = 0;
+
+ /** @private */
+ public static TIME_CONSTANT_INDEX:number /*uint*/ = 1;
+
+ private _particleTimeNode:ParticleTimeNode;
+
+ constructor(animator:ParticleAnimator, particleTimeNode:ParticleTimeNode)
+ {
+ super(animator, particleTimeNode, true);
+
+ this._particleTimeNode = particleTimeNode;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ animationSubGeometry.activateVertexBuffer(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleTimeState.TIME_STREAM_INDEX), this._particleTimeNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_4);
+
+ var particleTime:number = this._pTime/1000;
+ animationRegisterCache.setVertexConst(animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleTimeState.TIME_CONSTANT_INDEX), particleTime, particleTime, particleTime, particleTime);
+ }
+
+}
+
+export = ParticleTimeState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleUVState.js b/lib/animators/states/ParticleUVState.js
new file mode 100755
index 000000000..3c9d8b8f5
--- /dev/null
+++ b/lib/animators/states/ParticleUVState.js
@@ -0,0 +1,30 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleUVState = (function (_super) {
+ __extends(ParticleUVState, _super);
+ function ParticleUVState(animator, particleUVNode) {
+ _super.call(this, animator, particleUVNode);
+ this._particleUVNode = particleUVNode;
+ }
+ ParticleUVState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (animationRegisterCache.needUVAnimation) {
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleUVState.UV_INDEX);
+ var data = this._particleUVNode._iUvData;
+ animationRegisterCache.setVertexConst(index, data.x, data.y);
+ }
+ };
+ /** @private */
+ ParticleUVState.UV_INDEX = 0;
+ return ParticleUVState;
+})(ParticleStateBase);
+module.exports = ParticleUVState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGV1dnN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlVVZTdGF0ZSIsIlBhcnRpY2xlVVZTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlVVZTdGF0ZS5zZXRSZW5kZXJTdGF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBVUEsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxlQUFlO0lBQVNBLFVBQXhCQSxlQUFlQSxVQUEwQkE7SUFPOUNBLFNBUEtBLGVBQWVBLENBT1JBLFFBQXlCQSxFQUFFQSxjQUE2QkE7UUFFbkVDLGtCQUFNQSxRQUFRQSxFQUFFQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUVoQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsY0FBY0EsQ0FBQ0E7SUFDdkNBLENBQUNBO0lBRU1ELHdDQUFjQSxHQUFyQkEsVUFBc0JBLEtBQVdBLEVBQUVBLFVBQXlCQSxFQUFFQSxvQkFBeUNBLEVBQUVBLHNCQUE2Q0EsRUFBRUEsTUFBYUE7UUFFcEtFLEVBQUVBLENBQUNBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDNUNBLElBQUlBLEtBQUtBLEdBQWtCQSxzQkFBc0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsRUFBRUEsZUFBZUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7WUFDbkhBLElBQUlBLElBQUlBLEdBQVlBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFFBQVFBLENBQUNBO1lBQ2xEQSxzQkFBc0JBLENBQUNBLGNBQWNBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQzlEQSxDQUFDQTtJQUNGQSxDQUFDQTtJQW5CREYsZUFBZUE7SUFDREEsd0JBQVFBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQW9CNUNBLHNCQUFDQTtBQUFEQSxDQXZCQSxBQXVCQ0EsRUF2QjZCLGlCQUFpQixFQXVCOUM7QUFFRCxBQUF5QixpQkFBaEIsZUFBZSxDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVVVlN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuXG5pbXBvcnQgUGFydGljbGVBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1BhcnRpY2xlQW5pbWF0b3JcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25TdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBQYXJ0aWNsZVVWTm9kZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlVVZOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVVVlN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgVVZfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHRwcml2YXRlIF9wYXJ0aWNsZVVWTm9kZTpQYXJ0aWNsZVVWTm9kZTtcblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpQYXJ0aWNsZUFuaW1hdG9yLCBwYXJ0aWNsZVVWTm9kZTpQYXJ0aWNsZVVWTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZVVWTm9kZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZVVWTm9kZSA9IHBhcnRpY2xlVVZOb2RlO1xuXHR9XG5cblx0cHVibGljIHNldFJlbmRlclN0YXRlKHN0YWdlOlN0YWdlLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBhbmltYXRpb25TdWJHZW9tZXRyeTpBbmltYXRpb25TdWJHZW9tZXRyeSwgYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZTpBbmltYXRpb25SZWdpc3RlckNhY2hlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0aWYgKGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGUubmVlZFVWQW5pbWF0aW9uKSB7XG5cdFx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBhbmltYXRpb25SZWdpc3RlckNhY2hlLmdldFJlZ2lzdGVySW5kZXgodGhpcy5fcEFuaW1hdGlvbk5vZGUsIFBhcnRpY2xlVVZTdGF0ZS5VVl9JTkRFWCk7XG5cdFx0XHR2YXIgZGF0YTpWZWN0b3IzRCA9IHRoaXMuX3BhcnRpY2xlVVZOb2RlLl9pVXZEYXRhO1xuXHRcdFx0YW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5zZXRWZXJ0ZXhDb25zdChpbmRleCwgZGF0YS54LCBkYXRhLnkpO1xuXHRcdH1cblx0fVxuXG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlVVZTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleUVState.ts b/lib/animators/states/ParticleUVState.ts
new file mode 100644
index 000000000..d66f7469f
--- /dev/null
+++ b/lib/animators/states/ParticleUVState.ts
@@ -0,0 +1,41 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticleUVNode = require("awayjs-renderergl/lib/animators/nodes/ParticleUVNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleUVState extends ParticleStateBase
+{
+ /** @private */
+ public static UV_INDEX:number /*uint*/ = 0;
+
+ private _particleUVNode:ParticleUVNode;
+
+ constructor(animator:ParticleAnimator, particleUVNode:ParticleUVNode)
+ {
+ super(animator, particleUVNode);
+
+ this._particleUVNode = particleUVNode;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (animationRegisterCache.needUVAnimation) {
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleUVState.UV_INDEX);
+ var data:Vector3D = this._particleUVNode._iUvData;
+ animationRegisterCache.setVertexConst(index, data.x, data.y);
+ }
+ }
+
+}
+
+export = ParticleUVState;
\ No newline at end of file
diff --git a/lib/animators/states/ParticleVelocityState.js b/lib/animators/states/ParticleVelocityState.js
new file mode 100755
index 000000000..85016161e
--- /dev/null
+++ b/lib/animators/states/ParticleVelocityState.js
@@ -0,0 +1,58 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+var ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+var ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+/**
+ * ...
+ */
+var ParticleVelocityState = (function (_super) {
+ __extends(ParticleVelocityState, _super);
+ function ParticleVelocityState(animator, particleVelocityNode) {
+ _super.call(this, animator, particleVelocityNode);
+ this._particleVelocityNode = particleVelocityNode;
+ this._velocity = this._particleVelocityNode._iVelocity;
+ }
+ Object.defineProperty(ParticleVelocityState.prototype, "velocity", {
+ /**
+ * Defines the default velocity vector of the state, used when in global mode.
+ */
+ get: function () {
+ return this._velocity;
+ },
+ set: function (value) {
+ this._velocity = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ *
+ */
+ ParticleVelocityState.prototype.getVelocities = function () {
+ return this._pDynamicProperties;
+ };
+ ParticleVelocityState.prototype.setVelocities = function (value) {
+ this._pDynamicProperties = value;
+ this._pDynamicPropertiesDirty = new Object();
+ };
+ ParticleVelocityState.prototype.setRenderState = function (stage, renderable, animationSubGeometry, animationRegisterCache, camera) {
+ if (this._particleVelocityNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+ var index = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleVelocityState.VELOCITY_INDEX);
+ if (this._particleVelocityNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._velocity.x, this._velocity.y, this._velocity.z);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleVelocityNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ };
+ /** @private */
+ ParticleVelocityState.VELOCITY_INDEX = 0;
+ return ParticleVelocityState;
+})(ParticleStateBase);
+module.exports = ParticleVelocityState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGV2ZWxvY2l0eXN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlVmVsb2NpdHlTdGF0ZSIsIlBhcnRpY2xlVmVsb2NpdHlTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlVmVsb2NpdHlTdGF0ZS52ZWxvY2l0eSIsIlBhcnRpY2xlVmVsb2NpdHlTdGF0ZS5nZXRWZWxvY2l0aWVzIiwiUGFydGljbGVWZWxvY2l0eVN0YXRlLnNldFZlbG9jaXRpZXMiLCJQYXJ0aWNsZVZlbG9jaXR5U3RhdGUuc2V0UmVuZGVyU3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQU1BLElBQU8sMkJBQTJCLFdBQVksNkRBQTZELENBQUMsQ0FBQztBQUk3RyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFFekcsSUFBTyxpQkFBaUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRWxHLEFBR0E7O0dBREc7SUFDRyxxQkFBcUI7SUFBU0EsVUFBOUJBLHFCQUFxQkEsVUFBMEJBO0lBb0NwREEsU0FwQ0tBLHFCQUFxQkEsQ0FvQ2RBLFFBQXlCQSxFQUFFQSxvQkFBeUNBO1FBRS9FQyxrQkFBTUEsUUFBUUEsRUFBRUEsb0JBQW9CQSxDQUFDQSxDQUFDQTtRQUV0Q0EsSUFBSUEsQ0FBQ0EscUJBQXFCQSxHQUFHQSxvQkFBb0JBLENBQUNBO1FBQ2xEQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQSxxQkFBcUJBLENBQUNBLFVBQVVBLENBQUNBO0lBQ3hEQSxDQUFDQTtJQS9CREQsc0JBQVdBLDJDQUFRQTtRQUhuQkE7O1dBRUdBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBO1FBQ3ZCQSxDQUFDQTthQUVERixVQUFvQkEsS0FBY0E7WUFFakNFLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLEtBQUtBLENBQUNBO1FBQ3hCQSxDQUFDQTs7O09BTEFGO0lBT0RBOztPQUVHQTtJQUNJQSw2Q0FBYUEsR0FBcEJBO1FBRUNHLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLG1CQUFtQkEsQ0FBQ0E7SUFDakNBLENBQUNBO0lBRU1ILDZDQUFhQSxHQUFwQkEsVUFBcUJBLEtBQXFCQTtRQUV6Q0ksSUFBSUEsQ0FBQ0EsbUJBQW1CQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUVqQ0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxHQUFHQSxJQUFJQSxNQUFNQSxFQUFFQSxDQUFDQTtJQUM5Q0EsQ0FBQ0E7SUFVTUosOENBQWNBLEdBQXJCQSxVQUFzQkEsS0FBV0EsRUFBRUEsVUFBeUJBLEVBQUVBLG9CQUF5Q0EsRUFBRUEsc0JBQTZDQSxFQUFFQSxNQUFhQTtRQUVwS0ssRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxJQUFJQSxJQUFJQSxzQkFBc0JBLENBQUNBLGFBQWFBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQTtZQUM5SUEsSUFBSUEsQ0FBQ0EseUJBQXlCQSxDQUFDQSxvQkFBb0JBLENBQUNBLENBQUNBO1FBRXREQSxJQUFJQSxLQUFLQSxHQUFrQkEsc0JBQXNCQSxDQUFDQSxnQkFBZ0JBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLHFCQUFxQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFL0hBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsSUFBSUEsc0JBQXNCQSxDQUFDQSxNQUFNQSxDQUFDQTtZQUNwRUEsc0JBQXNCQSxDQUFDQSxjQUFjQSxDQUFDQSxLQUFLQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNwR0EsSUFBSUE7WUFDSEEsb0JBQW9CQSxDQUFDQSxvQkFBb0JBLENBQUNBLEtBQUtBLEVBQUVBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsWUFBWUEsRUFBRUEsS0FBS0EsRUFBRUEsMkJBQTJCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtJQUN4SUEsQ0FBQ0E7SUFyRERMLGVBQWVBO0lBQ0RBLG9DQUFjQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUFxRGpEQSw0QkFBQ0E7QUFBREEsQ0F4REEsQUF3RENBLEVBeERtQyxpQkFBaUIsRUF3RHBEO0FBRUQsQUFBK0IsaUJBQXRCLHFCQUFxQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvUGFydGljbGVWZWxvY2l0eVN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IEFuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IENvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFZlcnRleEJ1ZmZlckZvcm1hdFwiKTtcblxuaW1wb3J0IFBhcnRpY2xlQW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9QYXJ0aWNsZUFuaW1hdG9yXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQW5pbWF0aW9uU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlVmVsb2NpdHlOb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlVmVsb2NpdHlOb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVN0YXRlQmFzZVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVWZWxvY2l0eVN0YXRlIGV4dGVuZHMgUGFydGljbGVTdGF0ZUJhc2Vcbntcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBzdGF0aWMgVkVMT0NJVFlfSU5ERVg6bnVtYmVyIC8qaW50Ki8gPSAwO1xuXG5cdHByaXZhdGUgX3BhcnRpY2xlVmVsb2NpdHlOb2RlOlBhcnRpY2xlVmVsb2NpdHlOb2RlO1xuXHRwcml2YXRlIF92ZWxvY2l0eTpWZWN0b3IzRDtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZGVmYXVsdCB2ZWxvY2l0eSB2ZWN0b3Igb2YgdGhlIHN0YXRlLCB1c2VkIHdoZW4gaW4gZ2xvYmFsIG1vZGUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHZlbG9jaXR5KCk6VmVjdG9yM0Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl92ZWxvY2l0eTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgdmVsb2NpdHkodmFsdWU6VmVjdG9yM0QpXG5cdHtcblx0XHR0aGlzLl92ZWxvY2l0eSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZ2V0VmVsb2NpdGllcygpOkFycmF5PFZlY3RvcjNEPlxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3BEeW5hbWljUHJvcGVydGllcztcblx0fVxuXG5cdHB1YmxpYyBzZXRWZWxvY2l0aWVzKHZhbHVlOkFycmF5PFZlY3RvcjNEPilcblx0e1xuXHRcdHRoaXMuX3BEeW5hbWljUHJvcGVydGllcyA9IHZhbHVlO1xuXG5cdFx0dGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzRGlydHkgPSBuZXcgT2JqZWN0KCk7XG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpQYXJ0aWNsZUFuaW1hdG9yLCBwYXJ0aWNsZVZlbG9jaXR5Tm9kZTpQYXJ0aWNsZVZlbG9jaXR5Tm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBwYXJ0aWNsZVZlbG9jaXR5Tm9kZSk7XG5cblx0XHR0aGlzLl9wYXJ0aWNsZVZlbG9jaXR5Tm9kZSA9IHBhcnRpY2xlVmVsb2NpdHlOb2RlO1xuXHRcdHRoaXMuX3ZlbG9jaXR5ID0gdGhpcy5fcGFydGljbGVWZWxvY2l0eU5vZGUuX2lWZWxvY2l0eTtcblx0fVxuXG5cdHB1YmxpYyBzZXRSZW5kZXJTdGF0ZShzdGFnZTpTdGFnZSwgcmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgYW5pbWF0aW9uU3ViR2VvbWV0cnk6QW5pbWF0aW9uU3ViR2VvbWV0cnksIGFuaW1hdGlvblJlZ2lzdGVyQ2FjaGU6QW5pbWF0aW9uUmVnaXN0ZXJDYWNoZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGlmICh0aGlzLl9wYXJ0aWNsZVZlbG9jaXR5Tm9kZS5tb2RlID09IFBhcnRpY2xlUHJvcGVydGllc01vZGUuTE9DQUxfRFlOQU1JQyAmJiAhdGhpcy5fcER5bmFtaWNQcm9wZXJ0aWVzRGlydHlbYW5pbWF0aW9uU3ViR2VvbWV0cnkuX2lVbmlxdWVJZF0pXG5cdFx0XHR0aGlzLl9wVXBkYXRlRHluYW1pY1Byb3BlcnRpZXMoYW5pbWF0aW9uU3ViR2VvbWV0cnkpO1xuXG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gYW5pbWF0aW9uUmVnaXN0ZXJDYWNoZS5nZXRSZWdpc3RlckluZGV4KHRoaXMuX3BBbmltYXRpb25Ob2RlLCBQYXJ0aWNsZVZlbG9jaXR5U3RhdGUuVkVMT0NJVFlfSU5ERVgpO1xuXG5cdFx0aWYgKHRoaXMuX3BhcnRpY2xlVmVsb2NpdHlOb2RlLm1vZGUgPT0gUGFydGljbGVQcm9wZXJ0aWVzTW9kZS5HTE9CQUwpXG5cdFx0XHRhbmltYXRpb25SZWdpc3RlckNhY2hlLnNldFZlcnRleENvbnN0KGluZGV4LCB0aGlzLl92ZWxvY2l0eS54LCB0aGlzLl92ZWxvY2l0eS55LCB0aGlzLl92ZWxvY2l0eS56KTtcblx0XHRlbHNlXG5cdFx0XHRhbmltYXRpb25TdWJHZW9tZXRyeS5hY3RpdmF0ZVZlcnRleEJ1ZmZlcihpbmRleCwgdGhpcy5fcGFydGljbGVWZWxvY2l0eU5vZGUuX2lEYXRhT2Zmc2V0LCBzdGFnZSwgQ29udGV4dEdMVmVydGV4QnVmZmVyRm9ybWF0LkZMT0FUXzMpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlVmVsb2NpdHlTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/ParticleVelocityState.ts b/lib/animators/states/ParticleVelocityState.ts
new file mode 100644
index 000000000..1aa8bb43c
--- /dev/null
+++ b/lib/animators/states/ParticleVelocityState.ts
@@ -0,0 +1,76 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import AnimationRegisterCache = require("awayjs-stagegl/lib/animators/data/AnimationRegisterCache");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ContextGLVertexBufferFormat = require("awayjs-stagegl/lib/core/stagegl/ContextGLVertexBufferFormat");
+
+import ParticleAnimator = require("awayjs-renderergl/lib/animators/ParticleAnimator");
+import AnimationSubGeometry = require("awayjs-renderergl/lib/animators/data/AnimationSubGeometry");
+import ParticlePropertiesMode = require("awayjs-renderergl/lib/animators/data/ParticlePropertiesMode");
+import ParticleVelocityNode = require("awayjs-renderergl/lib/animators/nodes/ParticleVelocityNode");
+import ParticleStateBase = require("awayjs-renderergl/lib/animators/states/ParticleStateBase");
+
+/**
+ * ...
+ */
+class ParticleVelocityState extends ParticleStateBase
+{
+ /** @private */
+ public static VELOCITY_INDEX:number /*int*/ = 0;
+
+ private _particleVelocityNode:ParticleVelocityNode;
+ private _velocity:Vector3D;
+
+ /**
+ * Defines the default velocity vector of the state, used when in global mode.
+ */
+ public get velocity():Vector3D
+ {
+ return this._velocity;
+ }
+
+ public set velocity(value:Vector3D)
+ {
+ this._velocity = value;
+ }
+
+ /**
+ *
+ */
+ public getVelocities():Array
+ {
+ return this._pDynamicProperties;
+ }
+
+ public setVelocities(value:Array)
+ {
+ this._pDynamicProperties = value;
+
+ this._pDynamicPropertiesDirty = new Object();
+ }
+
+ constructor(animator:ParticleAnimator, particleVelocityNode:ParticleVelocityNode)
+ {
+ super(animator, particleVelocityNode);
+
+ this._particleVelocityNode = particleVelocityNode;
+ this._velocity = this._particleVelocityNode._iVelocity;
+ }
+
+ public setRenderState(stage:Stage, renderable:RenderableBase, animationSubGeometry:AnimationSubGeometry, animationRegisterCache:AnimationRegisterCache, camera:Camera)
+ {
+ if (this._particleVelocityNode.mode == ParticlePropertiesMode.LOCAL_DYNAMIC && !this._pDynamicPropertiesDirty[animationSubGeometry._iUniqueId])
+ this._pUpdateDynamicProperties(animationSubGeometry);
+
+ var index:number /*int*/ = animationRegisterCache.getRegisterIndex(this._pAnimationNode, ParticleVelocityState.VELOCITY_INDEX);
+
+ if (this._particleVelocityNode.mode == ParticlePropertiesMode.GLOBAL)
+ animationRegisterCache.setVertexConst(index, this._velocity.x, this._velocity.y, this._velocity.z);
+ else
+ animationSubGeometry.activateVertexBuffer(index, this._particleVelocityNode._iDataOffset, stage, ContextGLVertexBufferFormat.FLOAT_3);
+ }
+}
+
+export = ParticleVelocityState;
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonBinaryLERPState.js b/lib/animators/states/SkeletonBinaryLERPState.js
new file mode 100755
index 000000000..a77755d1d
--- /dev/null
+++ b/lib/animators/states/SkeletonBinaryLERPState.js
@@ -0,0 +1,117 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+/**
+ *
+ */
+var SkeletonBinaryLERPState = (function (_super) {
+ __extends(SkeletonBinaryLERPState, _super);
+ function SkeletonBinaryLERPState(animator, skeletonAnimationNode) {
+ _super.call(this, animator, skeletonAnimationNode);
+ this._blendWeight = 0;
+ this._skeletonPose = new SkeletonPose();
+ this._skeletonPoseDirty = true;
+ this._skeletonAnimationNode = skeletonAnimationNode;
+ this._inputA = animator.getAnimationState(this._skeletonAnimationNode.inputA);
+ this._inputB = animator.getAnimationState(this._skeletonAnimationNode.inputB);
+ }
+ Object.defineProperty(SkeletonBinaryLERPState.prototype, "blendWeight", {
+ /**
+ * Defines a fractional value between 0 and 1 representing the blending ratio between inputA (0) and inputB (1),
+ * used to produce the skeleton pose output.
+ *
+ * @see inputA
+ * @see inputB
+ */
+ get: function () {
+ return this._blendWeight;
+ },
+ set: function (value) {
+ this._blendWeight = value;
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ SkeletonBinaryLERPState.prototype.phase = function (value) {
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ this._inputA.phase(value);
+ this._inputB.phase(value);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonBinaryLERPState.prototype._pUpdateTime = function (time /*int*/) {
+ this._skeletonPoseDirty = true;
+ this._inputA.update(time);
+ this._inputB.update(time);
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ SkeletonBinaryLERPState.prototype.getSkeletonPose = function (skeleton) {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+ return this._skeletonPose;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonBinaryLERPState.prototype._pUpdatePositionDelta = function () {
+ this._pPositionDeltaDirty = false;
+ var deltA = this._inputA.positionDelta;
+ var deltB = this._inputB.positionDelta;
+ this._pRootDelta.x = deltA.x + this._blendWeight * (deltB.x - deltA.x);
+ this._pRootDelta.y = deltA.y + this._blendWeight * (deltB.y - deltA.y);
+ this._pRootDelta.z = deltA.z + this._blendWeight * (deltB.z - deltA.z);
+ };
+ /**
+ * Updates the output skeleton pose of the node based on the blendWeight value between input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ SkeletonBinaryLERPState.prototype.updateSkeletonPose = function (skeleton) {
+ this._skeletonPoseDirty = false;
+ var endPose;
+ var endPoses = this._skeletonPose.jointPoses;
+ var poses1 = this._inputA.getSkeletonPose(skeleton).jointPoses;
+ var poses2 = this._inputB.getSkeletonPose(skeleton).jointPoses;
+ var pose1, pose2;
+ var p1, p2;
+ var tr;
+ var numJoints = skeleton.numJoints;
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+ for (var i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+ pose1 = poses1[i];
+ pose2 = poses2[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._blendWeight);
+ tr = endPose.translation;
+ tr.x = p1.x + this._blendWeight * (p2.x - p1.x);
+ tr.y = p1.y + this._blendWeight * (p2.y - p1.y);
+ tr.z = p1.z + this._blendWeight * (p2.z - p1.z);
+ }
+ };
+ return SkeletonBinaryLERPState;
+})(AnimationStateBase);
+module.exports = SkeletonBinaryLERPState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25iaW5hcnlsZXJwc3RhdGUudHMiXSwibmFtZXMiOlsiU2tlbGV0b25CaW5hcnlMRVJQU3RhdGUiLCJTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uQmluYXJ5TEVSUFN0YXRlLmJsZW5kV2VpZ2h0IiwiU2tlbGV0b25CaW5hcnlMRVJQU3RhdGUucGhhc2UiLCJTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZS5nZXRTa2VsZXRvblBvc2UiLCJTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZS5fcFVwZGF0ZVBvc2l0aW9uRGVsdGEiLCJTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZS51cGRhdGVTa2VsZXRvblBvc2UiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUlBLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBRWxGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBRXhGLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUdwRyxBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQTJCQTtJQTZCdkRBLFNBN0JLQSx1QkFBdUJBLENBNkJoQkEsUUFBcUJBLEVBQUVBLHFCQUE0Q0E7UUFFOUVDLGtCQUFNQSxRQUFRQSxFQUFFQSxxQkFBcUJBLENBQUNBLENBQUNBO1FBN0JoQ0EsaUJBQVlBLEdBQVVBLENBQUNBLENBQUNBO1FBRXhCQSxrQkFBYUEsR0FBZ0JBLElBQUlBLFlBQVlBLEVBQUVBLENBQUNBO1FBQ2hEQSx1QkFBa0JBLEdBQVdBLElBQUlBLENBQUNBO1FBNEJ6Q0EsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxxQkFBcUJBLENBQUNBO1FBRXBEQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUE2QkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJ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b0lDQSxFQXBJcUMsa0JBQWtCLEVBb0l2RDtBQUVELEFBQWlDLGlCQUF4Qix1QkFBdUIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvc3RhdGVzL1NrZWxldG9uQmluYXJ5TEVSUFN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvbkJpbmFyeUxFUlBOb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkJpbmFyeUxFUlBOb2RlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlXCIpO1xuaW1wb3J0IElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgU2tlbGV0b25CaW5hcnlMRVJQU3RhdGUgZXh0ZW5kcyBBbmltYXRpb25TdGF0ZUJhc2UgaW1wbGVtZW50cyBJU2tlbGV0b25BbmltYXRpb25TdGF0ZVxue1xuXHRwcml2YXRlIF9ibGVuZFdlaWdodDpudW1iZXIgPSAwO1xuXHRwcml2YXRlIF9za2VsZXRvbkFuaW1hdGlvbk5vZGU6U2tlbGV0b25CaW5hcnlMRVJQTm9kZTtcblx0cHJpdmF0ZSBfc2tlbGV0b25Qb3NlOlNrZWxldG9uUG9zZSA9IG5ldyBTa2VsZXRvblBvc2UoKTtcblx0cHJpdmF0ZSBfc2tlbGV0b25Qb3NlRGlydHk6Ym9vbGVhbiA9IHRydWU7XG5cdHByaXZhdGUgX2lucHV0QTpJU2tlbGV0b25BbmltYXRpb25TdGF0ZTtcblx0cHJpdmF0ZSBfaW5wdXRCOklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIGEgZnJhY3Rpb25hbCB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEgcmVwcmVzZW50aW5nIHRoZSBibGVuZGluZyByYXRpbyBiZXR3ZWVuIGlucHV0QSAoMCkgYW5kIGlucHV0QiAoMSksXG5cdCAqIHVzZWQgdG8gcHJvZHVjZSB0aGUgc2tlbGV0b24gcG9zZSBvdXRwdXQuXG5cdCAqXG5cdCAqIEBzZWUgaW5wdXRBXG5cdCAqIEBzZWUgaW5wdXRCXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGJsZW5kV2VpZ2h0KCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmxlbmRXZWlnaHQ7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGJsZW5kV2VpZ2h0KHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2JsZW5kV2VpZ2h0ID0gdmFsdWU7XG5cblx0XHR0aGlzLl9wUG9zaXRpb25EZWx0YURpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpBbmltYXRvckJhc2UsIHNrZWxldG9uQW5pbWF0aW9uTm9kZTpTa2VsZXRvbkJpbmFyeUxFUlBOb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHNrZWxldG9uQW5pbWF0aW9uTm9kZSk7XG5cblx0XHR0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUgPSBza2VsZXRvbkFuaW1hdGlvbk5vZGU7XG5cblx0XHR0aGlzLl9pbnB1dEEgPSA8SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMuX3NrZWxldG9uQW5pbWF0aW9uTm9kZS5pbnB1dEEpO1xuXHRcdHRoaXMuX2lucHV0QiA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLmlucHV0Qik7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBwaGFzZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSA9IHRydWU7XG5cblx0XHR0aGlzLl9wUG9zaXRpb25EZWx0YURpcnR5ID0gdHJ1ZTtcblxuXHRcdHRoaXMuX2lucHV0QS5waGFzZSh2YWx1ZSk7XG5cdFx0dGhpcy5faW5wdXRCLnBoYXNlKHZhbHVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlVGltZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXG5cdFx0dGhpcy5faW5wdXRBLnVwZGF0ZSh0aW1lKTtcblx0XHR0aGlzLl9pbnB1dEIudXBkYXRlKHRpbWUpO1xuXG5cdFx0c3VwZXIuX3BVcGRhdGVUaW1lKHRpbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGN1cnJlbnQgc2tlbGV0b24gcG9zZSBvZiB0aGUgYW5pbWF0aW9uIGluIHRoZSBjbGlwIGJhc2VkIG9uIHRoZSBpbnRlcm5hbCBwbGF5aGVhZCBwb3NpdGlvbi5cblx0ICovXG5cdHB1YmxpYyBnZXRTa2VsZXRvblBvc2Uoc2tlbGV0b246U2tlbGV0b24pOlNrZWxldG9uUG9zZVxuXHR7XG5cdFx0aWYgKHRoaXMuX3NrZWxldG9uUG9zZURpcnR5KVxuXHRcdFx0dGhpcy51cGRhdGVTa2VsZXRvblBvc2Uoc2tlbGV0b24pO1xuXG5cdFx0cmV0dXJuIHRoaXMuX3NrZWxldG9uUG9zZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlUG9zaXRpb25EZWx0YSgpXG5cdHtcblx0XHR0aGlzLl9wUG9zaXRpb25EZWx0YURpcnR5ID0gZmFsc2U7XG5cblx0XHR2YXIgZGVsdEE6VmVjdG9yM0QgPSB0aGlzLl9pbnB1dEEucG9zaXRpb25EZWx0YTtcblx0XHR2YXIgZGVsdEI6VmVjdG9yM0QgPSB0aGlzLl9pbnB1dEIucG9zaXRpb25EZWx0YTtcblxuXHRcdHRoaXMuX3BSb290RGVsdGEueCA9IGRlbHRBLnggKyB0aGlzLl9ibGVuZFdlaWdodCooZGVsdEIueCAtIGRlbHRBLngpO1xuXHRcdHRoaXMuX3BSb290RGVsdGEueSA9IGRlbHRBLnkgKyB0aGlzLl9ibGVuZFdlaWdodCooZGVsdEIueSAtIGRlbHRBLnkpO1xuXHRcdHRoaXMuX3BSb290RGVsdGEueiA9IGRlbHRBLnogKyB0aGlzLl9ibGVuZFdlaWdodCooZGVsdEIueiAtIGRlbHRBLnopO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgdGhlIG91dHB1dCBza2VsZXRvbiBwb3NlIG9mIHRoZSBub2RlIGJhc2VkIG9uIHRoZSBibGVuZFdlaWdodCB2YWx1ZSBiZXR3ZWVuIGlucHV0IG5vZGVzLlxuXHQgKlxuXHQgKiBAcGFyYW0gc2tlbGV0b24gVGhlIHNrZWxldG9uIHVzZWQgYnkgdGhlIGFuaW1hdG9yIHJlcXVlc3RpbmcgdGhlIG91cHV0IHBvc2UuXG5cdCAqL1xuXHRwcml2YXRlIHVwZGF0ZVNrZWxldG9uUG9zZShza2VsZXRvbjpTa2VsZXRvbilcblx0e1xuXHRcdHRoaXMuX3NrZWxldG9uUG9zZURpcnR5ID0gZmFsc2U7XG5cblx0XHR2YXIgZW5kUG9zZTpKb2ludFBvc2U7XG5cdFx0dmFyIGVuZFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9za2VsZXRvblBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgcG9zZXMxOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9pbnB1dEEuZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uKS5qb2ludFBvc2VzO1xuXHRcdHZhciBwb3NlczI6QXJyYXk8Sm9pbnRQb3NlPiA9IHRoaXMuX2lucHV0Qi5nZXRTa2VsZXRvblBvc2Uoc2tlbGV0b24pLmpvaW50UG9zZXM7XG5cdFx0dmFyIHBvc2UxOkpvaW50UG9zZSwgcG9zZTI6Sm9pbnRQb3NlO1xuXHRcdHZhciBwMTpWZWN0b3IzRCwgcDI6VmVjdG9yM0Q7XG5cdFx0dmFyIHRyOlZlY3RvcjNEO1xuXHRcdHZhciBudW1Kb2ludHM6bnVtYmVyIC8qdWludCovID0gc2tlbGV0b24ubnVtSm9pbnRzO1xuXG5cdFx0Ly8gOnNcblx0XHRpZiAoZW5kUG9zZXMubGVuZ3RoICE9IG51bUpvaW50cylcblx0XHRcdGVuZFBvc2VzLmxlbmd0aCA9IG51bUpvaW50cztcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IG51bUpvaW50czsgKytpKSB7XG5cdFx0XHRlbmRQb3NlID0gZW5kUG9zZXNbaV07XG5cblx0XHRcdGlmIChlbmRQb3NlID09IG51bGwpXG5cdFx0XHRcdGVuZFBvc2UgPSBlbmRQb3Nlc1tpXSA9IG5ldyBKb2ludFBvc2UoKTtcblxuXHRcdFx0cG9zZTEgPSBwb3NlczFbaV07XG5cdFx0XHRwb3NlMiA9IHBvc2VzMltpXTtcblx0XHRcdHAxID0gcG9zZTEudHJhbnNsYXRpb247XG5cdFx0XHRwMiA9IHBvc2UyLnRyYW5zbGF0aW9uO1xuXG5cdFx0XHRlbmRQb3NlLm9yaWVudGF0aW9uLmxlcnAocG9zZTEub3JpZW50YXRpb24sIHBvc2UyLm9yaWVudGF0aW9uLCB0aGlzLl9ibGVuZFdlaWdodCk7XG5cblx0XHRcdHRyID0gZW5kUG9zZS50cmFuc2xhdGlvbjtcblx0XHRcdHRyLnggPSBwMS54ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnggLSBwMS54KTtcblx0XHRcdHRyLnkgPSBwMS55ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnkgLSBwMS55KTtcblx0XHRcdHRyLnogPSBwMS56ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnogLSBwMS56KTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0ID0gU2tlbGV0b25CaW5hcnlMRVJQU3RhdGU7Il19
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonBinaryLERPState.ts b/lib/animators/states/SkeletonBinaryLERPState.ts
new file mode 100644
index 000000000..5dee2247f
--- /dev/null
+++ b/lib/animators/states/SkeletonBinaryLERPState.ts
@@ -0,0 +1,149 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import SkeletonBinaryLERPNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonBinaryLERPNode");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+
+/**
+ *
+ */
+class SkeletonBinaryLERPState extends AnimationStateBase implements ISkeletonAnimationState
+{
+ private _blendWeight:number = 0;
+ private _skeletonAnimationNode:SkeletonBinaryLERPNode;
+ private _skeletonPose:SkeletonPose = new SkeletonPose();
+ private _skeletonPoseDirty:boolean = true;
+ private _inputA:ISkeletonAnimationState;
+ private _inputB:ISkeletonAnimationState;
+
+ /**
+ * Defines a fractional value between 0 and 1 representing the blending ratio between inputA (0) and inputB (1),
+ * used to produce the skeleton pose output.
+ *
+ * @see inputA
+ * @see inputB
+ */
+ public get blendWeight():number
+ {
+ return this._blendWeight;
+ }
+
+ public set blendWeight(value:number)
+ {
+ this._blendWeight = value;
+
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ }
+
+ constructor(animator:AnimatorBase, skeletonAnimationNode:SkeletonBinaryLERPNode)
+ {
+ super(animator, skeletonAnimationNode);
+
+ this._skeletonAnimationNode = skeletonAnimationNode;
+
+ this._inputA = animator.getAnimationState(this._skeletonAnimationNode.inputA);
+ this._inputB = animator.getAnimationState(this._skeletonAnimationNode.inputB);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public phase(value:number)
+ {
+ this._skeletonPoseDirty = true;
+
+ this._pPositionDeltaDirty = true;
+
+ this._inputA.phase(value);
+ this._inputB.phase(value);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateTime(time:number /*int*/)
+ {
+ this._skeletonPoseDirty = true;
+
+ this._inputA.update(time);
+ this._inputB.update(time);
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ public getSkeletonPose(skeleton:Skeleton):SkeletonPose
+ {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+
+ return this._skeletonPose;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ this._pPositionDeltaDirty = false;
+
+ var deltA:Vector3D = this._inputA.positionDelta;
+ var deltB:Vector3D = this._inputB.positionDelta;
+
+ this._pRootDelta.x = deltA.x + this._blendWeight*(deltB.x - deltA.x);
+ this._pRootDelta.y = deltA.y + this._blendWeight*(deltB.y - deltA.y);
+ this._pRootDelta.z = deltA.z + this._blendWeight*(deltB.z - deltA.z);
+ }
+
+ /**
+ * Updates the output skeleton pose of the node based on the blendWeight value between input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ private updateSkeletonPose(skeleton:Skeleton)
+ {
+ this._skeletonPoseDirty = false;
+
+ var endPose:JointPose;
+ var endPoses:Array = this._skeletonPose.jointPoses;
+ var poses1:Array = this._inputA.getSkeletonPose(skeleton).jointPoses;
+ var poses2:Array = this._inputB.getSkeletonPose(skeleton).jointPoses;
+ var pose1:JointPose, pose2:JointPose;
+ var p1:Vector3D, p2:Vector3D;
+ var tr:Vector3D;
+ var numJoints:number /*uint*/ = skeleton.numJoints;
+
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+
+ for (var i:number /*uint*/ = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+
+ pose1 = poses1[i];
+ pose2 = poses2[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._blendWeight);
+
+ tr = endPose.translation;
+ tr.x = p1.x + this._blendWeight*(p2.x - p1.x);
+ tr.y = p1.y + this._blendWeight*(p2.y - p1.y);
+ tr.z = p1.z + this._blendWeight*(p2.z - p1.z);
+ }
+ }
+}
+
+export = SkeletonBinaryLERPState;
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonClipState.js b/lib/animators/states/SkeletonClipState.js
new file mode 100755
index 000000000..958d9abbc
--- /dev/null
+++ b/lib/animators/states/SkeletonClipState.js
@@ -0,0 +1,162 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationClipState = require("awayjs-renderergl/lib/animators/states/AnimationClipState");
+/**
+ *
+ */
+var SkeletonClipState = (function (_super) {
+ __extends(SkeletonClipState, _super);
+ function SkeletonClipState(animator, skeletonClipNode) {
+ _super.call(this, animator, skeletonClipNode);
+ this._rootPos = new Vector3D();
+ this._skeletonPose = new SkeletonPose();
+ this._skeletonPoseDirty = true;
+ this._skeletonClipNode = skeletonClipNode;
+ this._frames = this._skeletonClipNode.frames;
+ }
+ Object.defineProperty(SkeletonClipState.prototype, "currentPose", {
+ /**
+ * Returns the current skeleton pose frame of animation in the clip based on the internal playhead position.
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._currentPose;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SkeletonClipState.prototype, "nextPose", {
+ /**
+ * Returns the next skeleton pose frame of animation in the clip based on the internal playhead position.
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._nextPose;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ SkeletonClipState.prototype.getSkeletonPose = function (skeleton) {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+ return this._skeletonPose;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonClipState.prototype._pUpdateTime = function (time /*int*/) {
+ this._skeletonPoseDirty = true;
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonClipState.prototype._pUpdateFrames = function () {
+ _super.prototype._pUpdateFrames.call(this);
+ this._currentPose = this._frames[this._pCurrentFrame];
+ if (this._skeletonClipNode.looping && this._pNextFrame >= this._skeletonClipNode.lastFrame) {
+ this._nextPose = this._frames[0];
+ this._pAnimator.dispatchCycleEvent();
+ }
+ else
+ this._nextPose = this._frames[this._pNextFrame];
+ };
+ /**
+ * Updates the output skeleton pose of the node based on the internal playhead position.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ SkeletonClipState.prototype.updateSkeletonPose = function (skeleton) {
+ this._skeletonPoseDirty = false;
+ if (!this._skeletonClipNode.totalDuration)
+ return;
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ var currentPose = this._currentPose.jointPoses;
+ var nextPose = this._nextPose.jointPoses;
+ var numJoints = skeleton.numJoints;
+ var p1, p2;
+ var pose1, pose2;
+ var endPoses = this._skeletonPose.jointPoses;
+ var endPose;
+ var tr;
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+ if ((numJoints != currentPose.length) || (numJoints != nextPose.length))
+ throw new Error("joint counts don't match!");
+ for (var i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+ pose1 = currentPose[i];
+ pose2 = nextPose[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+ if (this._skeletonClipNode.highQuality)
+ endPose.orientation.slerp(pose1.orientation, pose2.orientation, this._pBlendWeight);
+ else
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._pBlendWeight);
+ if (i > 0) {
+ tr = endPose.translation;
+ tr.x = p1.x + this._pBlendWeight * (p2.x - p1.x);
+ tr.y = p1.y + this._pBlendWeight * (p2.y - p1.y);
+ tr.z = p1.z + this._pBlendWeight * (p2.z - p1.z);
+ }
+ }
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonClipState.prototype._pUpdatePositionDelta = function () {
+ this._pPositionDeltaDirty = false;
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ var p1, p2, p3;
+ var totalDelta = this._skeletonClipNode.totalDelta;
+ // jumping back, need to reset position
+ if ((this._pTimeDir > 0 && this._pNextFrame < this._pOldFrame) || (this._pTimeDir < 0 && this._pNextFrame > this._pOldFrame)) {
+ this._rootPos.x -= totalDelta.x * this._pTimeDir;
+ this._rootPos.y -= totalDelta.y * this._pTimeDir;
+ this._rootPos.z -= totalDelta.z * this._pTimeDir;
+ }
+ var dx = this._rootPos.x;
+ var dy = this._rootPos.y;
+ var dz = this._rootPos.z;
+ if (this._skeletonClipNode.stitchFinalFrame && this._pNextFrame == this._skeletonClipNode.lastFrame) {
+ p1 = this._frames[0].jointPoses[0].translation;
+ p2 = this._frames[1].jointPoses[0].translation;
+ p3 = this._currentPose.jointPoses[0].translation;
+ this._rootPos.x = p3.x + p1.x + this._pBlendWeight * (p2.x - p1.x);
+ this._rootPos.y = p3.y + p1.y + this._pBlendWeight * (p2.y - p1.y);
+ this._rootPos.z = p3.z + p1.z + this._pBlendWeight * (p2.z - p1.z);
+ }
+ else {
+ p1 = this._currentPose.jointPoses[0].translation;
+ p2 = this._frames[this._pNextFrame].jointPoses[0].translation; //cover the instances where we wrap the pose but still want the final frame translation values
+ this._rootPos.x = p1.x + this._pBlendWeight * (p2.x - p1.x);
+ this._rootPos.y = p1.y + this._pBlendWeight * (p2.y - p1.y);
+ this._rootPos.z = p1.z + this._pBlendWeight * (p2.z - p1.z);
+ }
+ this._pRootDelta.x = this._rootPos.x - dx;
+ this._pRootDelta.y = this._rootPos.y - dy;
+ this._pRootDelta.z = this._rootPos.z - dz;
+ this._pOldFrame = this._pNextFrame;
+ };
+ return SkeletonClipState;
+})(AnimationClipState);
+module.exports = SkeletonClipState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25jbGlwc3RhdGUudHMiXSwibmFtZXMiOlsiU2tlbGV0b25DbGlwU3RhdGUiLCJTa2VsZXRvbkNsaXBTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uQ2xpcFN0YXRlLmN1cnJlbnRQb3NlIiwiU2tlbGV0b25DbGlwU3RhdGUubmV4dFBvc2UiLCJTa2VsZXRvbkNsaXBTdGF0ZS5nZXRTa2VsZXRvblBvc2UiLCJTa2VsZXRvbkNsaXBTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJTa2VsZXRvbkNsaXBTdGF0ZS5fcFVwZGF0ZUZyYW1lcyIsIlNrZWxldG9uQ2xpcFN0YXRlLnVwZGF0ZVNrZWxldG9uUG9zZSIsIlNrZWxldG9uQ2xpcFN0YXRlLl9wVXBkYXRlUG9zaXRpb25EZWx0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFLdEUsSUFBTyxTQUFTLFdBQWdCLGdEQUFnRCxDQUFDLENBQUM7QUFFbEYsSUFBTyxZQUFZLFdBQWdCLG1EQUFtRCxDQUFDLENBQUM7QUFFeEYsSUFBTyxrQkFBa0IsV0FBYywyREFBMkQsQ0FBQyxDQUFDO0FBR3BHLEFBR0E7O0dBREc7SUFDRyxpQkFBaUI7SUFBU0EsVUFBMUJBLGlCQUFpQkEsVUFBMkJBO0lBZ0NqREEsU0FoQ0tBLGlCQUFpQkEsQ0FnQ1ZBLFFBQXFCQSxFQUFFQSxnQkFBaUNBO1FBRW5FQyxrQkFBTUEsUUFBUUEsRUFBRUEsZ0JBQWdCQSxDQUFDQSxDQUFDQTtRQWhDM0JBLGFBQVFBLEdBQVlBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1FBR25DQSxrQkFBYUEsR0FBZ0JBLElBQUlBLFlBQVlBLEVBQUVBLENBQUNBO1FBQ2hEQSx1QkFBa0JBLEdBQVdBLElBQUlBLENBQUNBO1FBOEJ6Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxnQkFBZ0JBLENBQUNBO1FBQzFDQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFH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SUEsRUFBV0EsRUFBRUEsRUFBV0EsQ0FBQ0E7UUFDN0JBLElBQUlBLEtBQWVBLEVBQUVBLEtBQWVBLENBQUNBO1FBQ3JDQSxJQUFJQSxRQUFRQSxHQUFvQkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDOURBLElBQUlBLE9BQWlCQSxDQUFDQTtRQUN0QkEsSUFBSUEsRUFBV0EsQ0FBQ0E7UUFFaEJBLEFBQ0FBLEtBREtBO1FBQ0xBLEVBQUVBLENBQUNBLENBQUNBLFFBQVFBLENBQUNBLE1BQU1BLElBQUlBLFNBQVNBLENBQUNBO1lBQ2hDQSxRQUFRQSxDQUFDQSxNQUFNQSxHQUFHQSxTQUFTQSxDQUFDQTtRQUU3QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsU0FBU0EsSUFBSUEsV0FBV0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsSUFBSUEsUUFBUUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7WUFDdkVBLE1BQU1BLElBQUlBLEtBQUtBLENBQUNBLDJCQUEyQkEsQ0FBQ0EsQ0FBQ0E7UUFFOUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxTQUFTQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUNwREEsT0FBT0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFdEJBLEVBQUVBLENBQUNBLENBQUNBLE9BQU9BLElBQUlBLElBQUlBLENBQUNBO2dCQUNuQkEsT0FBT0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFFekNBLEtBQUtBLEdBQUdBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3ZCQSxLQUFLQSxHQUFHQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNwQkEsRUFBRUEsR0FBR0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFDdkJBLEVBQUVBLEdBQUdBLEtBQUtBLENBQUNBLFdBQVdBLENBQUNBO1lBRXZCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFdBQVdBLENBQUNBO2dCQUN0Q0EsT0FBT0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsRUFBRUEsS0FBS0EsQ0FBQ0EsV0FBV0EsRUFBRUEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0E7WUFBQ0EsSUFBSUE7Z0JBQ3pGQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxXQUFXQSxFQUFFQSxLQUFLQSxDQUFDQSxXQUFXQSxFQUFFQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQTtZQUVwRkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1hBLEVBQUVBLEdBQUdBLE9BQU9BLENBQUNBLFdBQVdBLENBQUNBO2dCQUN6QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9DQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDL0NBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLEdBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2hEQSxDQUFDQTtRQUNGQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVEUDs7T0FFR0E7SUFDSUEsaURBQXFCQSxHQUE1QkE7UUFFQ1EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUVsQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7WUFDdEJBLElBQUlBLENBQUNBLGNBQWNBLEVBQUVBLENBQUNBO1FBRXZCQSxJQUFJQSxFQUFXQSxFQUFFQSxFQUFXQSxFQUFFQSxFQUFXQSxDQUFDQTtRQUMxQ0EsSUFBSUEsVUFBVUEsR0FBWUEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxVQUFVQSxDQUFDQTtRQUU1REEsQUFDQUEsdUNBRHVDQTtRQUN2Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsSUFBSUEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsSUFBSUEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDOUhBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLElBQUlBLFVBQVVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBO1lBQy9DQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxJQUFJQSxVQUFVQSxDQUFDQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtZQUMvQ0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsVUFBVUEsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDaERBLENBQUNBO1FBRURBLElBQUlBLEVBQUVBLEdBQVVBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBO1FBQ2hDQSxJQUFJQSxFQUFFQSxHQUFVQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNoQ0EsSUFBSUEsRUFBRUEsR0FBVUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFaENBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsZ0JBQWdCQSxJQUFJQSxJQUFJQSxDQUFDQSxXQUFXQSxJQUFJQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3JHQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUMvQ0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFDL0NBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLFdBQVdBLENBQUNBO1lBRWpEQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNqRUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDakVBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLEdBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ2xFQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUNqREEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsV0FBV0EsRUFBRUEsOEZBQThGQTtZQUM3SkEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDMURBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLEdBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzFEQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMzREEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7UUFDMUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBO1FBQzFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtRQUUxQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7SUFDcENBLENBQUNBO0lBQ0ZSLHdCQUFDQTtBQUFEQSxDQWxMQSxBQWtMQ0EsRUFsTCtCLGtCQUFrQixFQWtMakQ7QUFFRCxBQUEyQixpQkFBbEIsaUJBQWlCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9Ta2VsZXRvbkNsaXBTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuXG5pbXBvcnQgU2tlbGV0b25BbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1NrZWxldG9uQW5pbWF0b3JcIik7XG5pbXBvcnQgSm9pbnRQb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0pvaW50UG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvblx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uXCIpO1xuaW1wb3J0IFNrZWxldG9uUG9zZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvblBvc2VcIik7XG5pbXBvcnQgU2tlbGV0b25DbGlwTm9kZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1NrZWxldG9uQ2xpcE5vZGVcIik7XG5pbXBvcnQgQW5pbWF0aW9uQ2xpcFN0YXRlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9BbmltYXRpb25DbGlwU3RhdGVcIik7XG5pbXBvcnQgSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9JU2tlbGV0b25BbmltYXRpb25TdGF0ZVwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBTa2VsZXRvbkNsaXBTdGF0ZSBleHRlbmRzIEFuaW1hdGlvbkNsaXBTdGF0ZSBpbXBsZW1lbnRzIElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXG57XG5cdHByaXZhdGUgX3Jvb3RQb3M6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0cHJpdmF0ZSBfZnJhbWVzOkFycmF5PFNrZWxldG9uUG9zZT47XG5cdHByaXZhdGUgX3NrZWxldG9uQ2xpcE5vZGU6U2tlbGV0b25DbGlwTm9kZTtcblx0cHJpdmF0ZSBfc2tlbGV0b25Qb3NlOlNrZWxldG9uUG9zZSA9IG5ldyBTa2VsZXRvblBvc2UoKTtcblx0cHJpdmF0ZSBfc2tlbGV0b25Qb3NlRGlydHk6Ym9vbGVhbiA9IHRydWU7XG5cdHByaXZhdGUgX2N1cnJlbnRQb3NlOlNrZWxldG9uUG9zZTtcblx0cHJpdmF0ZSBfbmV4dFBvc2U6U2tlbGV0b25Qb3NlO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNrZWxldG9uIHBvc2UgZnJhbWUgb2YgYW5pbWF0aW9uIGluIHRoZSBjbGlwIGJhc2VkIG9uIHRoZSBpbnRlcm5hbCBwbGF5aGVhZCBwb3NpdGlvbi5cblx0ICovXG5cdHB1YmxpYyBnZXQgY3VycmVudFBvc2UoKTpTa2VsZXRvblBvc2Vcblx0e1xuXHRcdGlmICh0aGlzLl9wRnJhbWVzRGlydHkpXG5cdFx0XHR0aGlzLl9wVXBkYXRlRnJhbWVzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fY3VycmVudFBvc2U7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgbmV4dCBza2VsZXRvbiBwb3NlIGZyYW1lIG9mIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG5leHRQb3NlKCk6U2tlbGV0b25Qb3NlXG5cdHtcblx0XHRpZiAodGhpcy5fcEZyYW1lc0RpcnR5KVxuXHRcdFx0dGhpcy5fcFVwZGF0ZUZyYW1lcygpO1xuXG5cdFx0cmV0dXJuIHRoaXMuX25leHRQb3NlO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBza2VsZXRvbkNsaXBOb2RlOlNrZWxldG9uQ2xpcE5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgc2tlbGV0b25DbGlwTm9kZSk7XG5cblx0XHR0aGlzLl9za2VsZXRvbkNsaXBOb2RlID0gc2tlbGV0b25DbGlwTm9kZTtcblx0XHR0aGlzLl9mcmFtZXMgPSB0aGlzLl9za2VsZXRvbkNsaXBOb2RlLmZyYW1lcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNrZWxldG9uIHBvc2Ugb2YgdGhlIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uOlNrZWxldG9uKTpTa2VsZXRvblBvc2Vcblx0e1xuXHRcdGlmICh0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSlcblx0XHRcdHRoaXMudXBkYXRlU2tlbGV0b25Qb3NlKHNrZWxldG9uKTtcblxuXHRcdHJldHVybiB0aGlzLl9za2VsZXRvblBvc2U7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVRpbWUodGltZTpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdHRoaXMuX3NrZWxldG9uUG9zZURpcnR5ID0gdHJ1ZTtcblxuXHRcdHN1cGVyLl9wVXBkYXRlVGltZSh0aW1lKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlRnJhbWVzKClcblx0e1xuXHRcdHN1cGVyLl9wVXBkYXRlRnJhbWVzKCk7XG5cblx0XHR0aGlzLl9jdXJyZW50UG9zZSA9IHRoaXMuX2ZyYW1lc1t0aGlzLl9wQ3VycmVudEZyYW1lXTtcblxuXHRcdGlmICh0aGlzLl9za2VsZXRvbkNsaXBOb2RlLmxvb3BpbmcgJiYgdGhpcy5fcE5leHRGcmFtZSA+PSB0aGlzLl9za2VsZXRvbkNsaXBOb2RlLmxhc3RGcmFtZSkge1xuXHRcdFx0dGhpcy5fbmV4dFBvc2UgPSB0aGlzLl9mcmFtZXNbMF07XG5cdFx0XHQoPFNrZWxldG9uQW5pbWF0b3I+IHRoaXMuX3BBbmltYXRvcikuZGlzcGF0Y2hDeWNsZUV2ZW50KCk7XG5cdFx0fSBlbHNlXG5cdFx0XHR0aGlzLl9uZXh0UG9zZSA9IHRoaXMuX2ZyYW1lc1t0aGlzLl9wTmV4dEZyYW1lXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBvdXRwdXQgc2tlbGV0b24gcG9zZSBvZiB0aGUgbm9kZSBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqXG5cdCAqIEBwYXJhbSBza2VsZXRvbiBUaGUgc2tlbGV0b24gdXNlZCBieSB0aGUgYW5pbWF0b3IgcmVxdWVzdGluZyB0aGUgb3VwdXQgcG9zZS5cblx0ICovXG5cdHByaXZhdGUgdXBkYXRlU2tlbGV0b25Qb3NlKHNrZWxldG9uOlNrZWxldG9uKVxuXHR7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSBmYWxzZTtcblxuXHRcdGlmICghdGhpcy5fc2tlbGV0b25DbGlwTm9kZS50b3RhbER1cmF0aW9uKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHZhciBjdXJyZW50UG9zZTpBcnJheTxKb2ludFBvc2U+ID0gdGhpcy5fY3VycmVudFBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgbmV4dFBvc2U6QXJyYXk8Sm9pbnRQb3NlPiA9IHRoaXMuX25leHRQb3NlLmpvaW50UG9zZXM7XG5cdFx0dmFyIG51bUpvaW50czpudW1iZXIgLyp1aW50Ki8gPSBza2VsZXRvbi5udW1Kb2ludHM7XG5cdFx0dmFyIHAxOlZlY3RvcjNELCBwMjpWZWN0b3IzRDtcblx0XHR2YXIgcG9zZTE6Sm9pbnRQb3NlLCBwb3NlMjpKb2ludFBvc2U7XG5cdFx0dmFyIGVuZFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9za2VsZXRvblBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgZW5kUG9zZTpKb2ludFBvc2U7XG5cdFx0dmFyIHRyOlZlY3RvcjNEO1xuXG5cdFx0Ly8gOnNcblx0XHRpZiAoZW5kUG9zZXMubGVuZ3RoICE9IG51bUpvaW50cylcblx0XHRcdGVuZFBvc2VzLmxlbmd0aCA9IG51bUpvaW50cztcblxuXHRcdGlmICgobnVtSm9pbnRzICE9IGN1cnJlbnRQb3NlLmxlbmd0aCkgfHwgKG51bUpvaW50cyAhPSBuZXh0UG9zZS5sZW5ndGgpKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiam9pbnQgY291bnRzIGRvbid0IG1hdGNoIVwiKTtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IG51bUpvaW50czsgKytpKSB7XG5cdFx0XHRlbmRQb3NlID0gZW5kUG9zZXNbaV07XG5cblx0XHRcdGlmIChlbmRQb3NlID09IG51bGwpXG5cdFx0XHRcdGVuZFBvc2UgPSBlbmRQb3Nlc1tpXSA9IG5ldyBKb2ludFBvc2UoKTtcblxuXHRcdFx0cG9zZTEgPSBjdXJyZW50UG9zZVtpXTtcblx0XHRcdHBvc2UyID0gbmV4dFBvc2VbaV07XG5cdFx0XHRwMSA9IHBvc2UxLnRyYW5zbGF0aW9uO1xuXHRcdFx0cDIgPSBwb3NlMi50cmFuc2xhdGlvbjtcblxuXHRcdFx0aWYgKHRoaXMuX3NrZWxldG9uQ2xpcE5vZGUuaGlnaFF1YWxpdHkpXG5cdFx0XHRcdGVuZFBvc2Uub3JpZW50YXRpb24uc2xlcnAocG9zZTEub3JpZW50YXRpb24sIHBvc2UyLm9yaWVudGF0aW9uLCB0aGlzLl9wQmxlbmRXZWlnaHQpOyBlbHNlXG5cdFx0XHRcdGVuZFBvc2Uub3JpZW50YXRpb24ubGVycChwb3NlMS5vcmllbnRhdGlvbiwgcG9zZTIub3JpZW50YXRpb24sIHRoaXMuX3BCbGVuZFdlaWdodCk7XG5cblx0XHRcdGlmIChpID4gMCkge1xuXHRcdFx0XHR0ciA9IGVuZFBvc2UudHJhbnNsYXRpb247XG5cdFx0XHRcdHRyLnggPSBwMS54ICsgdGhpcy5fcEJsZW5kV2VpZ2h0KihwMi54IC0gcDEueCk7XG5cdFx0XHRcdHRyLnkgPSBwMS55ICsgdGhpcy5fcEJsZW5kV2VpZ2h0KihwMi55IC0gcDEueSk7XG5cdFx0XHRcdHRyLnogPSBwMS56ICsgdGhpcy5fcEJsZW5kV2VpZ2h0KihwMi56IC0gcDEueik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVQb3NpdGlvbkRlbHRhKClcblx0e1xuXHRcdHRoaXMuX3BQb3NpdGlvbkRlbHRhRGlydHkgPSBmYWxzZTtcblxuXHRcdGlmICh0aGlzLl9wRnJhbWVzRGlydHkpXG5cdFx0XHR0aGlzLl9wVXBkYXRlRnJhbWVzKCk7XG5cblx0XHR2YXIgcDE6VmVjdG9yM0QsIHAyOlZlY3RvcjNELCBwMzpWZWN0b3IzRDtcblx0XHR2YXIgdG90YWxEZWx0YTpWZWN0b3IzRCA9IHRoaXMuX3NrZWxldG9uQ2xpcE5vZGUudG90YWxEZWx0YTtcblxuXHRcdC8vIGp1bXBpbmcgYmFjaywgbmVlZCB0byByZXNldCBwb3NpdGlvblxuXHRcdGlmICgodGhpcy5fcFRpbWVEaXIgPiAwICYmIHRoaXMuX3BOZXh0RnJhbWUgPCB0aGlzLl9wT2xkRnJhbWUpIHx8ICh0aGlzLl9wVGltZURpciA8IDAgJiYgdGhpcy5fcE5leHRGcmFtZSA+IHRoaXMuX3BPbGRGcmFtZSkpIHtcblx0XHRcdHRoaXMuX3Jvb3RQb3MueCAtPSB0b3RhbERlbHRhLngqdGhpcy5fcFRpbWVEaXI7XG5cdFx0XHR0aGlzLl9yb290UG9zLnkgLT0gdG90YWxEZWx0YS55KnRoaXMuX3BUaW1lRGlyO1xuXHRcdFx0dGhpcy5fcm9vdFBvcy56IC09IHRvdGFsRGVsdGEueip0aGlzLl9wVGltZURpcjtcblx0XHR9XG5cblx0XHR2YXIgZHg6bnVtYmVyID0gdGhpcy5fcm9vdFBvcy54O1xuXHRcdHZhciBkeTpudW1iZXIgPSB0aGlzLl9yb290UG9zLnk7XG5cdFx0dmFyIGR6Om51bWJlciA9IHRoaXMuX3Jvb3RQb3MuejtcblxuXHRcdGlmICh0aGlzLl9za2VsZXRvbkNsaXBOb2RlLnN0aXRjaEZpbmFsRnJhbWUgJiYgdGhpcy5fcE5leHRGcmFtZSA9PSB0aGlzLl9za2VsZXRvbkNsaXBOb2RlLmxhc3RGcmFtZSkge1xuXHRcdFx0cDEgPSB0aGlzLl9mcmFtZXNbMF0uam9pbnRQb3Nlc1swXS50cmFuc2xhdGlvbjtcblx0XHRcdHAyID0gdGhpcy5fZnJhbWVzWzFdLmpvaW50UG9zZXNbMF0udHJhbnNsYXRpb247XG5cdFx0XHRwMyA9IHRoaXMuX2N1cnJlbnRQb3NlLmpvaW50UG9zZXNbMF0udHJhbnNsYXRpb247XG5cblx0XHRcdHRoaXMuX3Jvb3RQb3MueCA9IHAzLnggKyBwMS54ICsgdGhpcy5fcEJsZW5kV2VpZ2h0KihwMi54IC0gcDEueCk7XG5cdFx0XHR0aGlzLl9yb290UG9zLnkgPSBwMy55ICsgcDEueSArIHRoaXMuX3BCbGVuZFdlaWdodCoocDIueSAtIHAxLnkpO1xuXHRcdFx0dGhpcy5fcm9vdFBvcy56ID0gcDMueiArIHAxLnogKyB0aGlzLl9wQmxlbmRXZWlnaHQqKHAyLnogLSBwMS56KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cDEgPSB0aGlzLl9jdXJyZW50UG9zZS5qb2ludFBvc2VzWzBdLnRyYW5zbGF0aW9uO1xuXHRcdFx0cDIgPSB0aGlzLl9mcmFtZXNbdGhpcy5fcE5leHRGcmFtZV0uam9pbnRQb3Nlc1swXS50cmFuc2xhdGlvbjsgLy9jb3ZlciB0aGUgaW5zdGFuY2VzIHdoZXJlIHdlIHdyYXAgdGhlIHBvc2UgYnV0IHN0aWxsIHdhbnQgdGhlIGZpbmFsIGZyYW1lIHRyYW5zbGF0aW9uIHZhbHVlc1xuXHRcdFx0dGhpcy5fcm9vdFBvcy54ID0gcDEueCArIHRoaXMuX3BCbGVuZFdlaWdodCoocDIueCAtIHAxLngpO1xuXHRcdFx0dGhpcy5fcm9vdFBvcy55ID0gcDEueSArIHRoaXMuX3BCbGVuZFdlaWdodCoocDIueSAtIHAxLnkpO1xuXHRcdFx0dGhpcy5fcm9vdFBvcy56ID0gcDEueiArIHRoaXMuX3BCbGVuZFdlaWdodCoocDIueiAtIHAxLnopO1xuXHRcdH1cblxuXHRcdHRoaXMuX3BSb290RGVsdGEueCA9IHRoaXMuX3Jvb3RQb3MueCAtIGR4O1xuXHRcdHRoaXMuX3BSb290RGVsdGEueSA9IHRoaXMuX3Jvb3RQb3MueSAtIGR5O1xuXHRcdHRoaXMuX3BSb290RGVsdGEueiA9IHRoaXMuX3Jvb3RQb3MueiAtIGR6O1xuXG5cdFx0dGhpcy5fcE9sZEZyYW1lID0gdGhpcy5fcE5leHRGcmFtZTtcblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkNsaXBTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonClipState.ts b/lib/animators/states/SkeletonClipState.ts
new file mode 100644
index 000000000..c49d33ec6
--- /dev/null
+++ b/lib/animators/states/SkeletonClipState.ts
@@ -0,0 +1,196 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonAnimator = require("awayjs-renderergl/lib/animators/SkeletonAnimator");
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import SkeletonClipNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonClipNode");
+import AnimationClipState = require("awayjs-renderergl/lib/animators/states/AnimationClipState");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+
+/**
+ *
+ */
+class SkeletonClipState extends AnimationClipState implements ISkeletonAnimationState
+{
+ private _rootPos:Vector3D = new Vector3D();
+ private _frames:Array;
+ private _skeletonClipNode:SkeletonClipNode;
+ private _skeletonPose:SkeletonPose = new SkeletonPose();
+ private _skeletonPoseDirty:boolean = true;
+ private _currentPose:SkeletonPose;
+ private _nextPose:SkeletonPose;
+
+ /**
+ * Returns the current skeleton pose frame of animation in the clip based on the internal playhead position.
+ */
+ public get currentPose():SkeletonPose
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._currentPose;
+ }
+
+ /**
+ * Returns the next skeleton pose frame of animation in the clip based on the internal playhead position.
+ */
+ public get nextPose():SkeletonPose
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._nextPose;
+ }
+
+ constructor(animator:AnimatorBase, skeletonClipNode:SkeletonClipNode)
+ {
+ super(animator, skeletonClipNode);
+
+ this._skeletonClipNode = skeletonClipNode;
+ this._frames = this._skeletonClipNode.frames;
+ }
+
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ public getSkeletonPose(skeleton:Skeleton):SkeletonPose
+ {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+
+ return this._skeletonPose;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateTime(time:number /*int*/)
+ {
+ this._skeletonPoseDirty = true;
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateFrames()
+ {
+ super._pUpdateFrames();
+
+ this._currentPose = this._frames[this._pCurrentFrame];
+
+ if (this._skeletonClipNode.looping && this._pNextFrame >= this._skeletonClipNode.lastFrame) {
+ this._nextPose = this._frames[0];
+ ( this._pAnimator).dispatchCycleEvent();
+ } else
+ this._nextPose = this._frames[this._pNextFrame];
+ }
+
+ /**
+ * Updates the output skeleton pose of the node based on the internal playhead position.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ private updateSkeletonPose(skeleton:Skeleton)
+ {
+ this._skeletonPoseDirty = false;
+
+ if (!this._skeletonClipNode.totalDuration)
+ return;
+
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ var currentPose:Array = this._currentPose.jointPoses;
+ var nextPose:Array = this._nextPose.jointPoses;
+ var numJoints:number /*uint*/ = skeleton.numJoints;
+ var p1:Vector3D, p2:Vector3D;
+ var pose1:JointPose, pose2:JointPose;
+ var endPoses:Array = this._skeletonPose.jointPoses;
+ var endPose:JointPose;
+ var tr:Vector3D;
+
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+
+ if ((numJoints != currentPose.length) || (numJoints != nextPose.length))
+ throw new Error("joint counts don't match!");
+
+ for (var i:number /*uint*/ = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+
+ pose1 = currentPose[i];
+ pose2 = nextPose[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+
+ if (this._skeletonClipNode.highQuality)
+ endPose.orientation.slerp(pose1.orientation, pose2.orientation, this._pBlendWeight); else
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._pBlendWeight);
+
+ if (i > 0) {
+ tr = endPose.translation;
+ tr.x = p1.x + this._pBlendWeight*(p2.x - p1.x);
+ tr.y = p1.y + this._pBlendWeight*(p2.y - p1.y);
+ tr.z = p1.z + this._pBlendWeight*(p2.z - p1.z);
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ this._pPositionDeltaDirty = false;
+
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ var p1:Vector3D, p2:Vector3D, p3:Vector3D;
+ var totalDelta:Vector3D = this._skeletonClipNode.totalDelta;
+
+ // jumping back, need to reset position
+ if ((this._pTimeDir > 0 && this._pNextFrame < this._pOldFrame) || (this._pTimeDir < 0 && this._pNextFrame > this._pOldFrame)) {
+ this._rootPos.x -= totalDelta.x*this._pTimeDir;
+ this._rootPos.y -= totalDelta.y*this._pTimeDir;
+ this._rootPos.z -= totalDelta.z*this._pTimeDir;
+ }
+
+ var dx:number = this._rootPos.x;
+ var dy:number = this._rootPos.y;
+ var dz:number = this._rootPos.z;
+
+ if (this._skeletonClipNode.stitchFinalFrame && this._pNextFrame == this._skeletonClipNode.lastFrame) {
+ p1 = this._frames[0].jointPoses[0].translation;
+ p2 = this._frames[1].jointPoses[0].translation;
+ p3 = this._currentPose.jointPoses[0].translation;
+
+ this._rootPos.x = p3.x + p1.x + this._pBlendWeight*(p2.x - p1.x);
+ this._rootPos.y = p3.y + p1.y + this._pBlendWeight*(p2.y - p1.y);
+ this._rootPos.z = p3.z + p1.z + this._pBlendWeight*(p2.z - p1.z);
+ } else {
+ p1 = this._currentPose.jointPoses[0].translation;
+ p2 = this._frames[this._pNextFrame].jointPoses[0].translation; //cover the instances where we wrap the pose but still want the final frame translation values
+ this._rootPos.x = p1.x + this._pBlendWeight*(p2.x - p1.x);
+ this._rootPos.y = p1.y + this._pBlendWeight*(p2.y - p1.y);
+ this._rootPos.z = p1.z + this._pBlendWeight*(p2.z - p1.z);
+ }
+
+ this._pRootDelta.x = this._rootPos.x - dx;
+ this._pRootDelta.y = this._rootPos.y - dy;
+ this._pRootDelta.z = this._rootPos.z - dz;
+
+ this._pOldFrame = this._pNextFrame;
+ }
+}
+
+export = SkeletonClipState;
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonDifferenceState.js b/lib/animators/states/SkeletonDifferenceState.js
new file mode 100755
index 000000000..52c964a13
--- /dev/null
+++ b/lib/animators/states/SkeletonDifferenceState.js
@@ -0,0 +1,120 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+/**
+ *
+ */
+var SkeletonDifferenceState = (function (_super) {
+ __extends(SkeletonDifferenceState, _super);
+ function SkeletonDifferenceState(animator, skeletonAnimationNode) {
+ _super.call(this, animator, skeletonAnimationNode);
+ this._blendWeight = 0;
+ this._skeletonPose = new SkeletonPose();
+ this._skeletonPoseDirty = true;
+ this._skeletonAnimationNode = skeletonAnimationNode;
+ this._baseInput = animator.getAnimationState(this._skeletonAnimationNode.baseInput);
+ this._differenceInput = animator.getAnimationState(this._skeletonAnimationNode.differenceInput);
+ }
+ Object.defineProperty(SkeletonDifferenceState.prototype, "blendWeight", {
+ /**
+ * Defines a fractional value between 0 and 1 representing the blending ratio between the base input (0) and difference input (1),
+ * used to produce the skeleton pose output.
+ *
+ * @see #baseInput
+ * @see #differenceInput
+ */
+ get: function () {
+ return this._blendWeight;
+ },
+ set: function (value) {
+ this._blendWeight = value;
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ SkeletonDifferenceState.prototype.phase = function (value) {
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ this._baseInput.phase(value);
+ this._baseInput.phase(value);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonDifferenceState.prototype._pUpdateTime = function (time /*int*/) {
+ this._skeletonPoseDirty = true;
+ this._baseInput.update(time);
+ this._differenceInput.update(time);
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ SkeletonDifferenceState.prototype.getSkeletonPose = function (skeleton) {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+ return this._skeletonPose;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonDifferenceState.prototype._pUpdatePositionDelta = function () {
+ this._pPositionDeltaDirty = false;
+ var deltA = this._baseInput.positionDelta;
+ var deltB = this._differenceInput.positionDelta;
+ this.positionDelta.x = deltA.x + this._blendWeight * deltB.x;
+ this.positionDelta.y = deltA.y + this._blendWeight * deltB.y;
+ this.positionDelta.z = deltA.z + this._blendWeight * deltB.z;
+ };
+ /**
+ * Updates the output skeleton pose of the node based on the blendWeight value between base input and difference input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ SkeletonDifferenceState.prototype.updateSkeletonPose = function (skeleton) {
+ this._skeletonPoseDirty = false;
+ var endPose;
+ var endPoses = this._skeletonPose.jointPoses;
+ var basePoses = this._baseInput.getSkeletonPose(skeleton).jointPoses;
+ var diffPoses = this._differenceInput.getSkeletonPose(skeleton).jointPoses;
+ var base, diff;
+ var basePos, diffPos;
+ var tr;
+ var numJoints = skeleton.numJoints;
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+ for (var i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+ base = basePoses[i];
+ diff = diffPoses[i];
+ basePos = base.translation;
+ diffPos = diff.translation;
+ SkeletonDifferenceState._tempQuat.multiply(diff.orientation, base.orientation);
+ endPose.orientation.lerp(base.orientation, SkeletonDifferenceState._tempQuat, this._blendWeight);
+ tr = endPose.translation;
+ tr.x = basePos.x + this._blendWeight * diffPos.x;
+ tr.y = basePos.y + this._blendWeight * diffPos.y;
+ tr.z = basePos.z + this._blendWeight * diffPos.z;
+ }
+ };
+ SkeletonDifferenceState._tempQuat = new Quaternion();
+ return SkeletonDifferenceState;
+})(AnimationStateBase);
+module.exports = SkeletonDifferenceState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25kaWZmZXJlbmNlc3RhdGUudHMiXSwibmFtZXMiOlsiU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uRGlmZmVyZW5jZVN0YXRlLmJsZW5kV2VpZ2h0IiwiU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUucGhhc2UiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5nZXRTa2VsZXRvblBvc2UiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5fcFVwZGF0ZVBvc2l0aW9uRGVsdGEiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS51cGRhdGVTa2VsZXRvblBvc2UiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sVUFBVSxXQUFnQixzQ0FBc0MsQ0FBQyxDQUFDO0FBS3pFLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBRWxGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBRXhGLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUdwRyxBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQTJCQTtJQThCdkRBLFNBOUJLQSx1QkFBdUJBLENBOEJoQkEsUUFBcUJBLEVBQUVBLHFCQUE0Q0E7UUFFOUVDLGtCQUFNQSxRQUFRQSxFQUFFQSxxQkFBcUJBLENBQUNBLENBQUNBO1FBOUJoQ0EsaUJBQVlBLEdBQVVBLENBQUNBLENBQUNBO1FBR3hCQSxrQkFBYUEsR0FBZ0JBLElBQUlBLFlBQVlBLEVBQUVBLENBQUNBO1FBQ2hEQSx1QkFBa0JBLEdBQVdBLElBQUlBLENBQUNBO1FBNEJ6Q0EsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxxQkFBcUJBLENBQUNBO1FBRXBEQSxJQUFJQSxDQUFDQSxVQUFV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QXNJdkQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9Ta2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBRdWF0ZXJuaW9uXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9RdWF0ZXJuaW9uXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvbkRpZmZlcmVuY2VOb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkRpZmZlcmVuY2VOb2RlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlXCIpO1xuaW1wb3J0IElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUgZXh0ZW5kcyBBbmltYXRpb25TdGF0ZUJhc2UgaW1wbGVtZW50cyBJU2tlbGV0b25BbmltYXRpb25TdGF0ZVxue1xuXHRwcml2YXRlIF9ibGVuZFdlaWdodDpudW1iZXIgPSAwO1xuXHRwcml2YXRlIHN0YXRpYyBfdGVtcFF1YXQ6UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdHByaXZhdGUgX3NrZWxldG9uQW5pbWF0aW9uTm9kZTpTa2VsZXRvbkRpZmZlcmVuY2VOb2RlO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2U6U2tlbGV0b25Qb3NlID0gbmV3IFNrZWxldG9uUG9zZSgpO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2VEaXJ0eTpib29sZWFuID0gdHJ1ZTtcblx0cHJpdmF0ZSBfYmFzZUlucHV0OklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXHRwcml2YXRlIF9kaWZmZXJlbmNlSW5wdXQ6SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU7XG5cblx0LyoqXG5cdCAqIERlZmluZXMgYSBmcmFjdGlvbmFsIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIGJsZW5kaW5nIHJhdGlvIGJldHdlZW4gdGhlIGJhc2UgaW5wdXQgKDApIGFuZCBkaWZmZXJlbmNlIGlucHV0ICgxKSxcblx0ICogdXNlZCB0byBwcm9kdWNlIHRoZSBza2VsZXRvbiBwb3NlIG91dHB1dC5cblx0ICpcblx0ICogQHNlZSAjYmFzZUlucHV0XG5cdCAqIEBzZWUgI2RpZmZlcmVuY2VJbnB1dFxuXHQgKi9cblx0cHVibGljIGdldCBibGVuZFdlaWdodCgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2JsZW5kV2VpZ2h0O1xuXHR9XG5cblx0cHVibGljIHNldCBibGVuZFdlaWdodCh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9ibGVuZFdlaWdodCA9IHZhbHVlO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBza2VsZXRvbkFuaW1hdGlvbk5vZGU6U2tlbGV0b25EaWZmZXJlbmNlTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBza2VsZXRvbkFuaW1hdGlvbk5vZGUpO1xuXG5cdFx0dGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlID0gc2tlbGV0b25BbmltYXRpb25Ob2RlO1xuXG5cdFx0dGhpcy5fYmFzZUlucHV0ID0gPElTa2VsZXRvbkFuaW1hdGlvblN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUuYmFzZUlucHV0KTtcblx0XHR0aGlzLl9kaWZmZXJlbmNlSW5wdXQgPSA8SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMuX3NrZWxldG9uQW5pbWF0aW9uTm9kZS5kaWZmZXJlbmNlSW5wdXQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgcGhhc2UodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cblx0XHR0aGlzLl9iYXNlSW5wdXQucGhhc2UodmFsdWUpO1xuXHRcdHRoaXMuX2Jhc2VJbnB1dC5waGFzZSh2YWx1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVRpbWUodGltZTpudW1iZXIgLyppbnQqLylcblx0e1xuXHRcdHRoaXMuX3NrZWxldG9uUG9zZURpcnR5ID0gdHJ1ZTtcblxuXHRcdHRoaXMuX2Jhc2VJbnB1dC51cGRhdGUodGltZSk7XG5cdFx0dGhpcy5fZGlmZmVyZW5jZUlucHV0LnVwZGF0ZSh0aW1lKTtcblxuXHRcdHN1cGVyLl9wVXBkYXRlVGltZSh0aW1lKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNrZWxldG9uIHBvc2Ugb2YgdGhlIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uOlNrZWxldG9uKTpTa2VsZXRvblBvc2Vcblx0e1xuXHRcdGlmICh0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSlcblx0XHRcdHRoaXMudXBkYXRlU2tlbGV0b25Qb3NlKHNrZWxldG9uKTtcblxuXHRcdHJldHVybiB0aGlzLl9za2VsZXRvblBvc2U7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVBvc2l0aW9uRGVsdGEoKVxuXHR7XG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IGZhbHNlO1xuXG5cdFx0dmFyIGRlbHRBOlZlY3RvcjNEID0gdGhpcy5fYmFzZUlucHV0LnBvc2l0aW9uRGVsdGE7XG5cdFx0dmFyIGRlbHRCOlZlY3RvcjNEID0gdGhpcy5fZGlmZmVyZW5jZUlucHV0LnBvc2l0aW9uRGVsdGE7XG5cblx0XHR0aGlzLnBvc2l0aW9uRGVsdGEueCA9IGRlbHRBLnggKyB0aGlzLl9ibGVuZFdlaWdodCpkZWx0Qi54O1xuXHRcdHRoaXMucG9zaXRpb25EZWx0YS55ID0gZGVsdEEueSArIHRoaXMuX2JsZW5kV2VpZ2h0KmRlbHRCLnk7XG5cdFx0dGhpcy5wb3NpdGlvbkRlbHRhLnogPSBkZWx0QS56ICsgdGhpcy5fYmxlbmRXZWlnaHQqZGVsdEIuejtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBvdXRwdXQgc2tlbGV0b24gcG9zZSBvZiB0aGUgbm9kZSBiYXNlZCBvbiB0aGUgYmxlbmRXZWlnaHQgdmFsdWUgYmV0d2VlbiBiYXNlIGlucHV0IGFuZCBkaWZmZXJlbmNlIGlucHV0IG5vZGVzLlxuXHQgKlxuXHQgKiBAcGFyYW0gc2tlbGV0b24gVGhlIHNrZWxldG9uIHVzZWQgYnkgdGhlIGFuaW1hdG9yIHJlcXVlc3RpbmcgdGhlIG91cHV0IHBvc2UuXG5cdCAqL1xuXHRwcml2YXRlIHVwZGF0ZVNrZWxldG9uUG9zZShza2VsZXRvbjpTa2VsZXRvbilcblx0e1xuXHRcdHRoaXMuX3NrZWxldG9uUG9zZURpcnR5ID0gZmFsc2U7XG5cblx0XHR2YXIgZW5kUG9zZTpKb2ludFBvc2U7XG5cdFx0dmFyIGVuZFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9za2VsZXRvblBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgYmFzZVBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9iYXNlSW5wdXQuZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uKS5qb2ludFBvc2VzO1xuXHRcdHZhciBkaWZmUG9zZXM6QXJyYXk8Sm9pbnRQb3NlPiA9IHRoaXMuX2RpZmZlcmVuY2VJbnB1dC5nZXRTa2VsZXRvblBvc2Uoc2tlbGV0b24pLmpvaW50UG9zZXM7XG5cdFx0dmFyIGJhc2U6Sm9pbnRQb3NlLCBkaWZmOkpvaW50UG9zZTtcblx0XHR2YXIgYmFzZVBvczpWZWN0b3IzRCwgZGlmZlBvczpWZWN0b3IzRDtcblx0XHR2YXIgdHI6VmVjdG9yM0Q7XG5cdFx0dmFyIG51bUpvaW50czpudW1iZXIgLyp1aW50Ki8gPSBza2VsZXRvbi5udW1Kb2ludHM7XG5cblx0XHQvLyA6c1xuXHRcdGlmIChlbmRQb3Nlcy5sZW5ndGggIT0gbnVtSm9pbnRzKVxuXHRcdFx0ZW5kUG9zZXMubGVuZ3RoID0gbnVtSm9pbnRzO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwOyBpIDwgbnVtSm9pbnRzOyArK2kpIHtcblx0XHRcdGVuZFBvc2UgPSBlbmRQb3Nlc1tpXTtcblxuXHRcdFx0aWYgKGVuZFBvc2UgPT0gbnVsbClcblx0XHRcdFx0ZW5kUG9zZSA9IGVuZFBvc2VzW2ldID0gbmV3IEpvaW50UG9zZSgpO1xuXG5cdFx0XHRiYXNlID0gYmFzZVBvc2VzW2ldO1xuXHRcdFx0ZGlmZiA9IGRpZmZQb3Nlc1tpXTtcblx0XHRcdGJhc2VQb3MgPSBiYXNlLnRyYW5zbGF0aW9uO1xuXHRcdFx0ZGlmZlBvcyA9IGRpZmYudHJhbnNsYXRpb247XG5cblx0XHRcdFNrZWxldG9uRGlmZmVyZW5jZVN0YXRlLl90ZW1wUXVhdC5tdWx0aXBseShkaWZmLm9yaWVudGF0aW9uLCBiYXNlLm9yaWVudGF0aW9uKTtcblx0XHRcdGVuZFBvc2Uub3JpZW50YXRpb24ubGVycChiYXNlLm9yaWVudGF0aW9uLCBTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5fdGVtcFF1YXQsIHRoaXMuX2JsZW5kV2VpZ2h0KTtcblxuXHRcdFx0dHIgPSBlbmRQb3NlLnRyYW5zbGF0aW9uO1xuXHRcdFx0dHIueCA9IGJhc2VQb3MueCArIHRoaXMuX2JsZW5kV2VpZ2h0KmRpZmZQb3MueDtcblx0XHRcdHRyLnkgPSBiYXNlUG9zLnkgKyB0aGlzLl9ibGVuZFdlaWdodCpkaWZmUG9zLnk7XG5cdFx0XHR0ci56ID0gYmFzZVBvcy56ICsgdGhpcy5fYmxlbmRXZWlnaHQqZGlmZlBvcy56O1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonDifferenceState.ts b/lib/animators/states/SkeletonDifferenceState.ts
new file mode 100644
index 000000000..d342ede65
--- /dev/null
+++ b/lib/animators/states/SkeletonDifferenceState.ts
@@ -0,0 +1,152 @@
+import Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import SkeletonDifferenceNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonDifferenceNode");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+
+/**
+ *
+ */
+class SkeletonDifferenceState extends AnimationStateBase implements ISkeletonAnimationState
+{
+ private _blendWeight:number = 0;
+ private static _tempQuat:Quaternion = new Quaternion();
+ private _skeletonAnimationNode:SkeletonDifferenceNode;
+ private _skeletonPose:SkeletonPose = new SkeletonPose();
+ private _skeletonPoseDirty:boolean = true;
+ private _baseInput:ISkeletonAnimationState;
+ private _differenceInput:ISkeletonAnimationState;
+
+ /**
+ * Defines a fractional value between 0 and 1 representing the blending ratio between the base input (0) and difference input (1),
+ * used to produce the skeleton pose output.
+ *
+ * @see #baseInput
+ * @see #differenceInput
+ */
+ public get blendWeight():number
+ {
+ return this._blendWeight;
+ }
+
+ public set blendWeight(value:number)
+ {
+ this._blendWeight = value;
+
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ }
+
+ constructor(animator:AnimatorBase, skeletonAnimationNode:SkeletonDifferenceNode)
+ {
+ super(animator, skeletonAnimationNode);
+
+ this._skeletonAnimationNode = skeletonAnimationNode;
+
+ this._baseInput = animator.getAnimationState(this._skeletonAnimationNode.baseInput);
+ this._differenceInput = animator.getAnimationState(this._skeletonAnimationNode.differenceInput);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public phase(value:number)
+ {
+ this._skeletonPoseDirty = true;
+
+ this._pPositionDeltaDirty = true;
+
+ this._baseInput.phase(value);
+ this._baseInput.phase(value);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateTime(time:number /*int*/)
+ {
+ this._skeletonPoseDirty = true;
+
+ this._baseInput.update(time);
+ this._differenceInput.update(time);
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ public getSkeletonPose(skeleton:Skeleton):SkeletonPose
+ {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+
+ return this._skeletonPose;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ this._pPositionDeltaDirty = false;
+
+ var deltA:Vector3D = this._baseInput.positionDelta;
+ var deltB:Vector3D = this._differenceInput.positionDelta;
+
+ this.positionDelta.x = deltA.x + this._blendWeight*deltB.x;
+ this.positionDelta.y = deltA.y + this._blendWeight*deltB.y;
+ this.positionDelta.z = deltA.z + this._blendWeight*deltB.z;
+ }
+
+ /**
+ * Updates the output skeleton pose of the node based on the blendWeight value between base input and difference input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ private updateSkeletonPose(skeleton:Skeleton)
+ {
+ this._skeletonPoseDirty = false;
+
+ var endPose:JointPose;
+ var endPoses:Array = this._skeletonPose.jointPoses;
+ var basePoses:Array = this._baseInput.getSkeletonPose(skeleton).jointPoses;
+ var diffPoses:Array = this._differenceInput.getSkeletonPose(skeleton).jointPoses;
+ var base:JointPose, diff:JointPose;
+ var basePos:Vector3D, diffPos:Vector3D;
+ var tr:Vector3D;
+ var numJoints:number /*uint*/ = skeleton.numJoints;
+
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+
+ for (var i:number /*uint*/ = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+
+ base = basePoses[i];
+ diff = diffPoses[i];
+ basePos = base.translation;
+ diffPos = diff.translation;
+
+ SkeletonDifferenceState._tempQuat.multiply(diff.orientation, base.orientation);
+ endPose.orientation.lerp(base.orientation, SkeletonDifferenceState._tempQuat, this._blendWeight);
+
+ tr = endPose.translation;
+ tr.x = basePos.x + this._blendWeight*diffPos.x;
+ tr.y = basePos.y + this._blendWeight*diffPos.y;
+ tr.z = basePos.z + this._blendWeight*diffPos.z;
+ }
+ }
+}
+
+export = SkeletonDifferenceState;
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonDirectionalState.js b/lib/animators/states/SkeletonDirectionalState.js
new file mode 100755
index 000000000..2313201d1
--- /dev/null
+++ b/lib/animators/states/SkeletonDirectionalState.js
@@ -0,0 +1,162 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+/**
+ *
+ */
+var SkeletonDirectionalState = (function (_super) {
+ __extends(SkeletonDirectionalState, _super);
+ function SkeletonDirectionalState(animator, skeletonAnimationNode) {
+ _super.call(this, animator, skeletonAnimationNode);
+ this._skeletonPose = new SkeletonPose();
+ this._skeletonPoseDirty = true;
+ this._blendWeight = 0;
+ this._direction = 0;
+ this._blendDirty = true;
+ this._skeletonAnimationNode = skeletonAnimationNode;
+ this._forward = animator.getAnimationState(this._skeletonAnimationNode.forward);
+ this._backward = animator.getAnimationState(this._skeletonAnimationNode.backward);
+ this._left = animator.getAnimationState(this._skeletonAnimationNode.left);
+ this._right = animator.getAnimationState(this._skeletonAnimationNode.right);
+ }
+ Object.defineProperty(SkeletonDirectionalState.prototype, "direction", {
+ get: function () {
+ return this._direction;
+ },
+ /**
+ * Defines the direction in degrees of the aniamtion between the forwards (0), right(90) backwards (180) and left(270) input nodes,
+ * used to produce the skeleton pose output.
+ */
+ set: function (value) {
+ if (this._direction == value)
+ return;
+ this._direction = value;
+ this._blendDirty = true;
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ SkeletonDirectionalState.prototype.phase = function (value) {
+ if (this._blendDirty)
+ this.updateBlend();
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ this._inputA.phase(value);
+ this._inputB.phase(value);
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonDirectionalState.prototype._pUdateTime = function (time /*int*/) {
+ if (this._blendDirty)
+ this.updateBlend();
+ this._skeletonPoseDirty = true;
+ this._inputA.update(time);
+ this._inputB.update(time);
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ SkeletonDirectionalState.prototype.getSkeletonPose = function (skeleton) {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+ return this._skeletonPose;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonDirectionalState.prototype._pUpdatePositionDelta = function () {
+ this._pPositionDeltaDirty = false;
+ if (this._blendDirty)
+ this.updateBlend();
+ var deltA = this._inputA.positionDelta;
+ var deltB = this._inputB.positionDelta;
+ this.positionDelta.x = deltA.x + this._blendWeight * (deltB.x - deltA.x);
+ this.positionDelta.y = deltA.y + this._blendWeight * (deltB.y - deltA.y);
+ this.positionDelta.z = deltA.z + this._blendWeight * (deltB.z - deltA.z);
+ };
+ /**
+ * Updates the output skeleton pose of the node based on the direction value between forward, backwards, left and right input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ SkeletonDirectionalState.prototype.updateSkeletonPose = function (skeleton) {
+ this._skeletonPoseDirty = false;
+ if (this._blendDirty)
+ this.updateBlend();
+ var endPose;
+ var endPoses = this._skeletonPose.jointPoses;
+ var poses1 = this._inputA.getSkeletonPose(skeleton).jointPoses;
+ var poses2 = this._inputB.getSkeletonPose(skeleton).jointPoses;
+ var pose1, pose2;
+ var p1, p2;
+ var tr;
+ var numJoints = skeleton.numJoints;
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+ for (var i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+ pose1 = poses1[i];
+ pose2 = poses2[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._blendWeight);
+ tr = endPose.translation;
+ tr.x = p1.x + this._blendWeight * (p2.x - p1.x);
+ tr.y = p1.y + this._blendWeight * (p2.y - p1.y);
+ tr.z = p1.z + this._blendWeight * (p2.z - p1.z);
+ }
+ };
+ /**
+ * Updates the blend value for the animation output based on the direction value between forward, backwards, left and right input nodes.
+ *
+ * @private
+ */
+ SkeletonDirectionalState.prototype.updateBlend = function () {
+ this._blendDirty = false;
+ if (this._direction < 0 || this._direction > 360) {
+ this._direction %= 360;
+ if (this._direction < 0)
+ this._direction += 360;
+ }
+ if (this._direction < 90) {
+ this._inputA = this._forward;
+ this._inputB = this._right;
+ this._blendWeight = this._direction / 90;
+ }
+ else if (this._direction < 180) {
+ this._inputA = this._right;
+ this._inputB = this._backward;
+ this._blendWeight = (this._direction - 90) / 90;
+ }
+ else if (this._direction < 270) {
+ this._inputA = this._backward;
+ this._inputB = this._left;
+ this._blendWeight = (this._direction - 180) / 90;
+ }
+ else {
+ this._inputA = this._left;
+ this._inputB = this._forward;
+ this._blendWeight = (this._direction - 270) / 90;
+ }
+ };
+ return SkeletonDirectionalState;
+})(AnimationStateBase);
+module.exports = SkeletonDirectionalState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25kaXJlY3Rpb25hbHN0YXRlLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uRGlyZWN0aW9uYWxTdGF0ZSIsIlNrZWxldG9uRGlyZWN0aW9uYWxTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uRGlyZWN0aW9uYWxTdGF0ZS5kaXJlY3Rpb24iLCJTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGUucGhhc2UiLCJTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGUuX3BVZGF0ZVRpbWUiLCJTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGUuZ2V0U2tlbGV0b25Qb3NlIiwiU2tlbGV0b25EaXJlY3Rpb25hbFN0YXRlLl9wVXBkYXRlUG9zaXRpb25EZWx0YSIsIlNrZWxldG9uRGlyZWN0aW9uYWxTdGF0ZS51cGRhdGVTa2VsZXRvblBvc2UiLCJTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGUudXBkYXRlQmxlbmQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUlBLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBRWxGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBRXhGLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUdwRyxBQUdBOztHQURHO0lBQ0csd0JBQXdCO0lBQVNBLFVBQWpDQSx3QkFBd0JBLFVBQTJCQTtJQXFDeERBLFNBckNLQSx3QkFBd0JBLENBcUNqQkEsUUFBcUJBLEVBQUVBLHFCQUE2Q0E7UUFFL0VDLGtCQUFNQSxRQUFRQSxFQUFFQSxxQkFBcUJBLENBQUNBLENBQUNBO1FBcENoQ0Esa0JBQWFBLEdBQWdCQSxJQUFJQSxZQUFZQSxFQUFFQSxDQUFDQTtRQUNoREEsdUJBQWtCQSxHQUFXQSxJQUFJQSxDQUFDQTtRQUdsQ0EsaUJBQVlBLEdBQVVBLENBQUNBLENBQUNBO1FBQ3hCQSxlQUFVQSxHQUFVQSxDQUFDQSxDQUFDQTtRQUN0QkEsZ0JBQVdBLEdBQVdBLElBQUlBLENBQUNBO1FB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Q0EsQ0FBQ0E7WUFDbEJBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xCQSxFQUFFQSxHQUFHQSxLQUFLQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUN2QkEsRUFBRUEsR0FBR0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFFdkJBLE9BQU9BLENBQUNBLFdBQVdBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFdBQVdBLEVBQUVBLEtBQUtBLENBQUNBLFdBQVdBLEVBQUVBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBO1lBRWxGQSxFQUFFQSxHQUFHQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUN6QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDOUNBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLEdBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzlDQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMvQ0EsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFFRFA7Ozs7T0FJR0E7SUFDS0EsOENBQVdBLEdBQW5CQTtRQUVDUSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUV6QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsQ0FBQ0EsSUFBSUEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbERBLElBQUlBLENBQUNBLFVBQVVBLElBQUlBLEdBQUdBLENBQUNBO1lBQ3ZCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDdkJBLElBQUlBLENBQUNBLFVBQVVBLElBQUlBLEdBQUdBLENBQUNBO1FBQ3pCQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMxQkEsSUFBSUEsQ0FBQ0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0E7WUFDN0JBLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBO1lBQzNCQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFDQSxFQUFFQSxDQUFDQTtRQUN4Q0EsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbENBLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBO1lBQzNCQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBQ0EsRUFBRUEsQ0FBQ0E7UUFDL0NBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xDQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0E7WUFDMUJBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUNBLEVBQUVBLENBQUNBO1FBQ2hEQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQTtZQUMxQkEsSUFBSUEsQ0FBQ0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0E7WUFDN0JBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUNBLEVBQUVBLENBQUNBO1FBQ2hEQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUNGUiwrQkFBQ0E7QUFBREEsQ0E1TEEsQUE0TENBLEVBNUxzQyxrQkFBa0IsRUE0THhEO0FBRUQsQUFBa0MsaUJBQXpCLHdCQUF3QixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvU2tlbGV0b25EaXJlY3Rpb25hbFN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvbkRpcmVjdGlvbmFsTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvU2tlbGV0b25EaXJlY3Rpb25hbE5vZGVcIik7XG5pbXBvcnQgQW5pbWF0aW9uU3RhdGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9BbmltYXRpb25TdGF0ZUJhc2VcIik7XG5pbXBvcnQgSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9JU2tlbGV0b25BbmltYXRpb25TdGF0ZVwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBTa2VsZXRvbkRpcmVjdGlvbmFsU3RhdGUgZXh0ZW5kcyBBbmltYXRpb25TdGF0ZUJhc2UgaW1wbGVtZW50cyBJU2tlbGV0b25BbmltYXRpb25TdGF0ZVxue1xuXHRwcml2YXRlIF9za2VsZXRvbkFuaW1hdGlvbk5vZGU6U2tlbGV0b25EaXJlY3Rpb25hbE5vZGU7XG5cdHByaXZhdGUgX3NrZWxldG9uUG9zZTpTa2VsZXRvblBvc2UgPSBuZXcgU2tlbGV0b25Qb3NlKCk7XG5cdHByaXZhdGUgX3NrZWxldG9uUG9zZURpcnR5OmJvb2xlYW4gPSB0cnVlO1xuXHRwcml2YXRlIF9pbnB1dEE6SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU7XG5cdHByaXZhdGUgX2lucHV0QjpJU2tlbGV0b25BbmltYXRpb25TdGF0ZTtcblx0cHJpdmF0ZSBfYmxlbmRXZWlnaHQ6bnVtYmVyID0gMDtcblx0cHJpdmF0ZSBfZGlyZWN0aW9uOm51bWJlciA9IDA7XG5cdHByaXZhdGUgX2JsZW5kRGlydHk6Ym9vbGVhbiA9IHRydWU7XG5cdHByaXZhdGUgX2ZvcndhcmQ6SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU7XG5cdHByaXZhdGUgX2JhY2t3YXJkOklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXHRwcml2YXRlIF9sZWZ0OklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXHRwcml2YXRlIF9yaWdodDpJU2tlbGV0b25BbmltYXRpb25TdGF0ZTtcblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgZGlyZWN0aW9uIGluIGRlZ3JlZXMgb2YgdGhlIGFuaWFtdGlvbiBiZXR3ZWVuIHRoZSBmb3J3YXJkcyAoMCksIHJpZ2h0KDkwKSBiYWNrd2FyZHMgKDE4MCkgYW5kIGxlZnQoMjcwKSBpbnB1dCBub2Rlcyxcblx0ICogdXNlZCB0byBwcm9kdWNlIHRoZSBza2VsZXRvbiBwb3NlIG91dHB1dC5cblx0ICovXG5cdHB1YmxpYyBzZXQgZGlyZWN0aW9uKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdGlmICh0aGlzLl9kaXJlY3Rpb24gPT0gdmFsdWUpXG5cdFx0XHRyZXR1cm47XG5cblx0XHR0aGlzLl9kaXJlY3Rpb24gPSB2YWx1ZTtcblxuXHRcdHRoaXMuX2JsZW5kRGlydHkgPSB0cnVlO1xuXG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuX3BQb3NpdGlvbkRlbHRhRGlydHkgPSB0cnVlO1xuXHR9XG5cblx0cHVibGljIGdldCBkaXJlY3Rpb24oKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9kaXJlY3Rpb247XG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpBbmltYXRvckJhc2UsIHNrZWxldG9uQW5pbWF0aW9uTm9kZTpTa2VsZXRvbkRpcmVjdGlvbmFsTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBza2VsZXRvbkFuaW1hdGlvbk5vZGUpO1xuXG5cdFx0dGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlID0gc2tlbGV0b25BbmltYXRpb25Ob2RlO1xuXG5cdFx0dGhpcy5fZm9yd2FyZCA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLmZvcndhcmQpO1xuXHRcdHRoaXMuX2JhY2t3YXJkID0gPElTa2VsZXRvbkFuaW1hdGlvblN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUuYmFja3dhcmQpO1xuXHRcdHRoaXMuX2xlZnQgPSA8SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU+IGFuaW1hdG9yLmdldEFuaW1hdGlvblN0YXRlKHRoaXMuX3NrZWxldG9uQW5pbWF0aW9uTm9kZS5sZWZ0KTtcblx0XHR0aGlzLl9yaWdodCA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLnJpZ2h0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHBoYXNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdGlmICh0aGlzLl9ibGVuZERpcnR5KVxuXHRcdFx0dGhpcy51cGRhdGVCbGVuZCgpO1xuXG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cblx0XHR0aGlzLl9pbnB1dEEucGhhc2UodmFsdWUpO1xuXHRcdHRoaXMuX2lucHV0Qi5waGFzZSh2YWx1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVkYXRlVGltZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0aWYgKHRoaXMuX2JsZW5kRGlydHkpXG5cdFx0XHR0aGlzLnVwZGF0ZUJsZW5kKCk7XG5cblx0XHR0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSA9IHRydWU7XG5cblx0XHR0aGlzLl9pbnB1dEEudXBkYXRlKHRpbWUpO1xuXHRcdHRoaXMuX2lucHV0Qi51cGRhdGUodGltZSk7XG5cblx0XHRzdXBlci5fcFVwZGF0ZVRpbWUodGltZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgY3VycmVudCBza2VsZXRvbiBwb3NlIG9mIHRoZSBhbmltYXRpb24gaW4gdGhlIGNsaXAgYmFzZWQgb24gdGhlIGludGVybmFsIHBsYXloZWFkIHBvc2l0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldFNrZWxldG9uUG9zZShza2VsZXRvbjpTa2VsZXRvbik6U2tlbGV0b25Qb3NlXG5cdHtcblx0XHRpZiAodGhpcy5fc2tlbGV0b25Qb3NlRGlydHkpXG5cdFx0XHR0aGlzLnVwZGF0ZVNrZWxldG9uUG9zZShza2VsZXRvbik7XG5cblx0XHRyZXR1cm4gdGhpcy5fc2tlbGV0b25Qb3NlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVQb3NpdGlvbkRlbHRhKClcblx0e1xuXHRcdHRoaXMuX3BQb3NpdGlvbkRlbHRhRGlydHkgPSBmYWxzZTtcblxuXHRcdGlmICh0aGlzLl9ibGVuZERpcnR5KVxuXHRcdFx0dGhpcy51cGRhdGVCbGVuZCgpO1xuXG5cdFx0dmFyIGRlbHRBOlZlY3RvcjNEID0gdGhpcy5faW5wdXRBLnBvc2l0aW9uRGVsdGE7XG5cdFx0dmFyIGRlbHRCOlZlY3RvcjNEID0gdGhpcy5faW5wdXRCLnBvc2l0aW9uRGVsdGE7XG5cblx0XHR0aGlzLnBvc2l0aW9uRGVsdGEueCA9IGRlbHRBLnggKyB0aGlzLl9ibGVuZFdlaWdodCooZGVsdEIueCAtIGRlbHRBLngpO1xuXHRcdHRoaXMucG9zaXRpb25EZWx0YS55ID0gZGVsdEEueSArIHRoaXMuX2JsZW5kV2VpZ2h0KihkZWx0Qi55IC0gZGVsdEEueSk7XG5cdFx0dGhpcy5wb3NpdGlvbkRlbHRhLnogPSBkZWx0QS56ICsgdGhpcy5fYmxlbmRXZWlnaHQqKGRlbHRCLnogLSBkZWx0QS56KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBvdXRwdXQgc2tlbGV0b24gcG9zZSBvZiB0aGUgbm9kZSBiYXNlZCBvbiB0aGUgZGlyZWN0aW9uIHZhbHVlIGJldHdlZW4gZm9yd2FyZCwgYmFja3dhcmRzLCBsZWZ0IGFuZCByaWdodCBpbnB1dCBub2Rlcy5cblx0ICpcblx0ICogQHBhcmFtIHNrZWxldG9uIFRoZSBza2VsZXRvbiB1c2VkIGJ5IHRoZSBhbmltYXRvciByZXF1ZXN0aW5nIHRoZSBvdXB1dCBwb3NlLlxuXHQgKi9cblx0cHJpdmF0ZSB1cGRhdGVTa2VsZXRvblBvc2Uoc2tlbGV0b246U2tlbGV0b24pXG5cdHtcblx0XHR0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSA9IGZhbHNlO1xuXG5cdFx0aWYgKHRoaXMuX2JsZW5kRGlydHkpXG5cdFx0XHR0aGlzLnVwZGF0ZUJsZW5kKCk7XG5cblx0XHR2YXIgZW5kUG9zZTpKb2ludFBvc2U7XG5cdFx0dmFyIGVuZFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9za2VsZXRvblBvc2Uuam9pbnRQb3Nlcztcblx0XHR2YXIgcG9zZXMxOkFycmF5PEpvaW50UG9zZT4gPSB0aGlzLl9pbnB1dEEuZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uKS5qb2ludFBvc2VzO1xuXHRcdHZhciBwb3NlczI6QXJyYXk8Sm9pbnRQb3NlPiA9IHRoaXMuX2lucHV0Qi5nZXRTa2VsZXRvblBvc2Uoc2tlbGV0b24pLmpvaW50UG9zZXM7XG5cdFx0dmFyIHBvc2UxOkpvaW50UG9zZSwgcG9zZTI6Sm9pbnRQb3NlO1xuXHRcdHZhciBwMTpWZWN0b3IzRCwgcDI6VmVjdG9yM0Q7XG5cdFx0dmFyIHRyOlZlY3RvcjNEO1xuXHRcdHZhciBudW1Kb2ludHM6bnVtYmVyIC8qdWludCovID0gc2tlbGV0b24ubnVtSm9pbnRzO1xuXG5cdFx0Ly8gOnNcblx0XHRpZiAoZW5kUG9zZXMubGVuZ3RoICE9IG51bUpvaW50cylcblx0XHRcdGVuZFBvc2VzLmxlbmd0aCA9IG51bUpvaW50cztcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IG51bUpvaW50czsgKytpKSB7XG5cdFx0XHRlbmRQb3NlID0gZW5kUG9zZXNbaV07XG5cblx0XHRcdGlmIChlbmRQb3NlID09IG51bGwpXG5cdFx0XHRcdGVuZFBvc2UgPSBlbmRQb3Nlc1tpXSA9IG5ldyBKb2ludFBvc2UoKTtcblxuXHRcdFx0cG9zZTEgPSBwb3NlczFbaV07XG5cdFx0XHRwb3NlMiA9IHBvc2VzMltpXTtcblx0XHRcdHAxID0gcG9zZTEudHJhbnNsYXRpb247XG5cdFx0XHRwMiA9IHBvc2UyLnRyYW5zbGF0aW9uO1xuXG5cdFx0XHRlbmRQb3NlLm9yaWVudGF0aW9uLmxlcnAocG9zZTEub3JpZW50YXRpb24sIHBvc2UyLm9yaWVudGF0aW9uLCB0aGlzLl9ibGVuZFdlaWdodCk7XG5cblx0XHRcdHRyID0gZW5kUG9zZS50cmFuc2xhdGlvbjtcblx0XHRcdHRyLnggPSBwMS54ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnggLSBwMS54KTtcblx0XHRcdHRyLnkgPSBwMS55ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnkgLSBwMS55KTtcblx0XHRcdHRyLnogPSBwMS56ICsgdGhpcy5fYmxlbmRXZWlnaHQqKHAyLnogLSBwMS56KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgYmxlbmQgdmFsdWUgZm9yIHRoZSBhbmltYXRpb24gb3V0cHV0IGJhc2VkIG9uIHRoZSBkaXJlY3Rpb24gdmFsdWUgYmV0d2VlbiBmb3J3YXJkLCBiYWNrd2FyZHMsIGxlZnQgYW5kIHJpZ2h0IGlucHV0IG5vZGVzLlxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0cHJpdmF0ZSB1cGRhdGVCbGVuZCgpXG5cdHtcblx0XHR0aGlzLl9ibGVuZERpcnR5ID0gZmFsc2U7XG5cblx0XHRpZiAodGhpcy5fZGlyZWN0aW9uIDwgMCB8fCB0aGlzLl9kaXJlY3Rpb24gPiAzNjApIHtcblx0XHRcdHRoaXMuX2RpcmVjdGlvbiAlPSAzNjA7XG5cdFx0XHRpZiAodGhpcy5fZGlyZWN0aW9uIDwgMClcblx0XHRcdFx0dGhpcy5fZGlyZWN0aW9uICs9IDM2MDtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fZGlyZWN0aW9uIDwgOTApIHtcblx0XHRcdHRoaXMuX2lucHV0QSA9IHRoaXMuX2ZvcndhcmQ7XG5cdFx0XHR0aGlzLl9pbnB1dEIgPSB0aGlzLl9yaWdodDtcblx0XHRcdHRoaXMuX2JsZW5kV2VpZ2h0ID0gdGhpcy5fZGlyZWN0aW9uLzkwO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5fZGlyZWN0aW9uIDwgMTgwKSB7XG5cdFx0XHR0aGlzLl9pbnB1dEEgPSB0aGlzLl9yaWdodDtcblx0XHRcdHRoaXMuX2lucHV0QiA9IHRoaXMuX2JhY2t3YXJkO1xuXHRcdFx0dGhpcy5fYmxlbmRXZWlnaHQgPSAodGhpcy5fZGlyZWN0aW9uIC0gOTApLzkwO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5fZGlyZWN0aW9uIDwgMjcwKSB7XG5cdFx0XHR0aGlzLl9pbnB1dEEgPSB0aGlzLl9iYWNrd2FyZDtcblx0XHRcdHRoaXMuX2lucHV0QiA9IHRoaXMuX2xlZnQ7XG5cdFx0XHR0aGlzLl9ibGVuZFdlaWdodCA9ICh0aGlzLl9kaXJlY3Rpb24gLSAxODApLzkwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9pbnB1dEEgPSB0aGlzLl9sZWZ0O1xuXHRcdFx0dGhpcy5faW5wdXRCID0gdGhpcy5fZm9yd2FyZDtcblx0XHRcdHRoaXMuX2JsZW5kV2VpZ2h0ID0gKHRoaXMuX2RpcmVjdGlvbiAtIDI3MCkvOTA7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCA9IFNrZWxldG9uRGlyZWN0aW9uYWxTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonDirectionalState.ts b/lib/animators/states/SkeletonDirectionalState.ts
new file mode 100644
index 000000000..bc2047aaa
--- /dev/null
+++ b/lib/animators/states/SkeletonDirectionalState.ts
@@ -0,0 +1,205 @@
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import SkeletonDirectionalNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonDirectionalNode");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+
+/**
+ *
+ */
+class SkeletonDirectionalState extends AnimationStateBase implements ISkeletonAnimationState
+{
+ private _skeletonAnimationNode:SkeletonDirectionalNode;
+ private _skeletonPose:SkeletonPose = new SkeletonPose();
+ private _skeletonPoseDirty:boolean = true;
+ private _inputA:ISkeletonAnimationState;
+ private _inputB:ISkeletonAnimationState;
+ private _blendWeight:number = 0;
+ private _direction:number = 0;
+ private _blendDirty:boolean = true;
+ private _forward:ISkeletonAnimationState;
+ private _backward:ISkeletonAnimationState;
+ private _left:ISkeletonAnimationState;
+ private _right:ISkeletonAnimationState;
+
+ /**
+ * Defines the direction in degrees of the aniamtion between the forwards (0), right(90) backwards (180) and left(270) input nodes,
+ * used to produce the skeleton pose output.
+ */
+ public set direction(value:number)
+ {
+ if (this._direction == value)
+ return;
+
+ this._direction = value;
+
+ this._blendDirty = true;
+
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ }
+
+ public get direction():number
+ {
+ return this._direction;
+ }
+
+ constructor(animator:AnimatorBase, skeletonAnimationNode:SkeletonDirectionalNode)
+ {
+ super(animator, skeletonAnimationNode);
+
+ this._skeletonAnimationNode = skeletonAnimationNode;
+
+ this._forward = animator.getAnimationState(this._skeletonAnimationNode.forward);
+ this._backward = animator.getAnimationState(this._skeletonAnimationNode.backward);
+ this._left = animator.getAnimationState(this._skeletonAnimationNode.left);
+ this._right = animator.getAnimationState(this._skeletonAnimationNode.right);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public phase(value:number)
+ {
+ if (this._blendDirty)
+ this.updateBlend();
+
+ this._skeletonPoseDirty = true;
+
+ this._pPositionDeltaDirty = true;
+
+ this._inputA.phase(value);
+ this._inputB.phase(value);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUdateTime(time:number /*int*/)
+ {
+ if (this._blendDirty)
+ this.updateBlend();
+
+ this._skeletonPoseDirty = true;
+
+ this._inputA.update(time);
+ this._inputB.update(time);
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ public getSkeletonPose(skeleton:Skeleton):SkeletonPose
+ {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+
+ return this._skeletonPose;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ this._pPositionDeltaDirty = false;
+
+ if (this._blendDirty)
+ this.updateBlend();
+
+ var deltA:Vector3D = this._inputA.positionDelta;
+ var deltB:Vector3D = this._inputB.positionDelta;
+
+ this.positionDelta.x = deltA.x + this._blendWeight*(deltB.x - deltA.x);
+ this.positionDelta.y = deltA.y + this._blendWeight*(deltB.y - deltA.y);
+ this.positionDelta.z = deltA.z + this._blendWeight*(deltB.z - deltA.z);
+ }
+
+ /**
+ * Updates the output skeleton pose of the node based on the direction value between forward, backwards, left and right input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ private updateSkeletonPose(skeleton:Skeleton)
+ {
+ this._skeletonPoseDirty = false;
+
+ if (this._blendDirty)
+ this.updateBlend();
+
+ var endPose:JointPose;
+ var endPoses:Array = this._skeletonPose.jointPoses;
+ var poses1:Array = this._inputA.getSkeletonPose(skeleton).jointPoses;
+ var poses2:Array = this._inputB.getSkeletonPose(skeleton).jointPoses;
+ var pose1:JointPose, pose2:JointPose;
+ var p1:Vector3D, p2:Vector3D;
+ var tr:Vector3D;
+ var numJoints:number /*uint*/ = skeleton.numJoints;
+
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+
+ for (var i:number /*uint*/ = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+
+ pose1 = poses1[i];
+ pose2 = poses2[i];
+ p1 = pose1.translation;
+ p2 = pose2.translation;
+
+ endPose.orientation.lerp(pose1.orientation, pose2.orientation, this._blendWeight);
+
+ tr = endPose.translation;
+ tr.x = p1.x + this._blendWeight*(p2.x - p1.x);
+ tr.y = p1.y + this._blendWeight*(p2.y - p1.y);
+ tr.z = p1.z + this._blendWeight*(p2.z - p1.z);
+ }
+ }
+
+ /**
+ * Updates the blend value for the animation output based on the direction value between forward, backwards, left and right input nodes.
+ *
+ * @private
+ */
+ private updateBlend()
+ {
+ this._blendDirty = false;
+
+ if (this._direction < 0 || this._direction > 360) {
+ this._direction %= 360;
+ if (this._direction < 0)
+ this._direction += 360;
+ }
+
+ if (this._direction < 90) {
+ this._inputA = this._forward;
+ this._inputB = this._right;
+ this._blendWeight = this._direction/90;
+ } else if (this._direction < 180) {
+ this._inputA = this._right;
+ this._inputB = this._backward;
+ this._blendWeight = (this._direction - 90)/90;
+ } else if (this._direction < 270) {
+ this._inputA = this._backward;
+ this._inputB = this._left;
+ this._blendWeight = (this._direction - 180)/90;
+ } else {
+ this._inputA = this._left;
+ this._inputB = this._forward;
+ this._blendWeight = (this._direction - 270)/90;
+ }
+ }
+}
+
+export = SkeletonDirectionalState;
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonNaryLERPState.js b/lib/animators/states/SkeletonNaryLERPState.js
new file mode 100755
index 000000000..d4d8142b4
--- /dev/null
+++ b/lib/animators/states/SkeletonNaryLERPState.js
@@ -0,0 +1,181 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+var AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+/**
+ *
+ */
+var SkeletonNaryLERPState = (function (_super) {
+ __extends(SkeletonNaryLERPState, _super);
+ function SkeletonNaryLERPState(animator, skeletonAnimationNode) {
+ _super.call(this, animator, skeletonAnimationNode);
+ this._skeletonPose = new SkeletonPose();
+ this._skeletonPoseDirty = true;
+ this._blendWeights = new Array();
+ this._inputs = new Array();
+ this._skeletonAnimationNode = skeletonAnimationNode;
+ var i = this._skeletonAnimationNode.numInputs;
+ while (i--)
+ this._inputs[i] = animator.getAnimationState(this._skeletonAnimationNode._iInputs[i]);
+ }
+ /**
+ * @inheritDoc
+ */
+ SkeletonNaryLERPState.prototype.phase = function (value) {
+ this._skeletonPoseDirty = true;
+ this._pPositionDeltaDirty = true;
+ for (var j = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ if (this._blendWeights[j])
+ this._inputs[j].update(value);
+ }
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonNaryLERPState.prototype._pUdateTime = function (time /*int*/) {
+ for (var j = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ if (this._blendWeights[j])
+ this._inputs[j].update(time);
+ }
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ SkeletonNaryLERPState.prototype.getSkeletonPose = function (skeleton) {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+ return this._skeletonPose;
+ };
+ /**
+ * Returns the blend weight of the skeleton aniamtion node that resides at the given input index.
+ *
+ * @param index The input index for which the skeleton animation node blend weight is requested.
+ */
+ SkeletonNaryLERPState.prototype.getBlendWeightAt = function (index /*uint*/) {
+ return this._blendWeights[index];
+ };
+ /**
+ * Sets the blend weight of the skeleton aniamtion node that resides at the given input index.
+ *
+ * @param index The input index on which the skeleton animation node blend weight is to be set.
+ * @param blendWeight The blend weight value to use for the given skeleton animation node index.
+ */
+ SkeletonNaryLERPState.prototype.setBlendWeightAt = function (index /*uint*/, blendWeight) {
+ this._blendWeights[index] = blendWeight;
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ };
+ /**
+ * @inheritDoc
+ */
+ SkeletonNaryLERPState.prototype._pUpdatePositionDelta = function () {
+ this._pPositionDeltaDirty = false;
+ var delta;
+ var weight;
+ this.positionDelta.x = 0;
+ this.positionDelta.y = 0;
+ this.positionDelta.z = 0;
+ for (var j = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ weight = this._blendWeights[j];
+ if (weight) {
+ delta = this._inputs[j].positionDelta;
+ this.positionDelta.x += weight * delta.x;
+ this.positionDelta.y += weight * delta.y;
+ this.positionDelta.z += weight * delta.z;
+ }
+ }
+ };
+ /**
+ * Updates the output skeleton pose of the node based on the blend weight values given to the input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ SkeletonNaryLERPState.prototype.updateSkeletonPose = function (skeleton) {
+ this._skeletonPoseDirty = false;
+ var weight;
+ var endPoses = this._skeletonPose.jointPoses;
+ var poses;
+ var endPose, pose;
+ var endTr, tr;
+ var endQuat, q;
+ var firstPose;
+ var i /*uint*/;
+ var w0, x0, y0, z0;
+ var w1, x1, y1, z1;
+ var numJoints = skeleton.numJoints;
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+ for (var j = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ weight = this._blendWeights[j];
+ if (!weight)
+ continue;
+ poses = this._inputs[j].getSkeletonPose(skeleton).jointPoses;
+ if (!firstPose) {
+ firstPose = poses;
+ for (i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+ pose = poses[i];
+ q = pose.orientation;
+ tr = pose.translation;
+ endQuat = endPose.orientation;
+ endQuat.x = weight * q.x;
+ endQuat.y = weight * q.y;
+ endQuat.z = weight * q.z;
+ endQuat.w = weight * q.w;
+ endTr = endPose.translation;
+ endTr.x = weight * tr.x;
+ endTr.y = weight * tr.y;
+ endTr.z = weight * tr.z;
+ }
+ }
+ else {
+ for (i = 0; i < skeleton.numJoints; ++i) {
+ endPose = endPoses[i];
+ pose = poses[i];
+ q = firstPose[i].orientation;
+ x0 = q.x;
+ y0 = q.y;
+ z0 = q.z;
+ w0 = q.w;
+ q = pose.orientation;
+ tr = pose.translation;
+ x1 = q.x;
+ y1 = q.y;
+ z1 = q.z;
+ w1 = q.w;
+ // find shortest direction
+ if (x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1 < 0) {
+ x1 = -x1;
+ y1 = -y1;
+ z1 = -z1;
+ w1 = -w1;
+ }
+ endQuat = endPose.orientation;
+ endQuat.x += weight * x1;
+ endQuat.y += weight * y1;
+ endQuat.z += weight * z1;
+ endQuat.w += weight * w1;
+ endTr = endPose.translation;
+ endTr.x += weight * tr.x;
+ endTr.y += weight * tr.y;
+ endTr.z += weight * tr.z;
+ }
+ }
+ }
+ for (i = 0; i < skeleton.numJoints; ++i)
+ endPoses[i].orientation.normalize();
+ };
+ return SkeletonNaryLERPState;
+})(AnimationStateBase);
+module.exports = SkeletonNaryLERPState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25uYXJ5bGVycHN0YXRlLnRzIl0sIm5hbWVzIjpbIlNrZWxldG9uTmFyeUxFUlBTdGF0ZSIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS5waGFzZSIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS5fcFVkYXRlVGltZSIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS5nZXRTa2VsZXRvblBvc2UiLCJTa2VsZXRvbk5hcnlMRVJQU3RhdGUuZ2V0QmxlbmRXZWlnaHRBdCIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS5zZXRCbGVuZFdlaWdodEF0IiwiU2tlbGV0b25OYXJ5TEVSUFN0YXRlLl9wVXBkYXRlUG9zaXRpb25EZWx0YSIsIlNrZWxldG9uTmFyeUxFUlBTdGF0ZS51cGRhdGVTa2VsZXRvblBvc2UiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUtBLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBRWxGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBRXhGLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUdwRyxBQUdBOztHQURHO0lBQ0cscUJBQXFCO0lBQVNBLFVBQTlCQSxxQkFBcUJBLFVBQTJCQTtJQVFyREEsU0FSS0EscUJBQXFCQSxDQVFkQSxRQUFxQkEsRUFBRUEscUJBQTBDQTtRQUU1RUMsa0JBQU1BLFFBQVFBLEVBQUVBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0E7UUFQaENBLGtCQUFhQSxHQUFnQkEsSUFBSUEsWUFBWUEsRUFBRUEsQ0FBQ0E7UUFDaERBLHVCQUFrQkEsR0FBV0EsSUFBSUEsQ0FBQ0E7UUFDbENBLGtCQUFhQSxHQUFpQkEsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBQ0E7UUFDbERBLFlBQU9BLEdBQWtDQSxJQUFJQSxLQUFLQSxFQUEyQkEsQ0FBQ0E7UUFNckZBLElBQUlBLENBQUNBLHNCQUFzQkEsR0FB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Q0EsZUFBZUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsVUFBVUEsQ0FBQ0E7WUFFN0RBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNoQkEsU0FBU0EsR0FBR0EsS0FBS0EsQ0FBQ0E7Z0JBQ2xCQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxTQUFTQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtvQkFDaENBLE9BQU9BLEdBQUdBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUV0QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsT0FBT0EsSUFBSUEsSUFBSUEsQ0FBQ0E7d0JBQ25CQSxPQUFPQSxHQUFHQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxTQUFTQSxFQUFFQSxDQUFDQTtvQkFFekNBLElBQUlBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUNoQkEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7b0JBQ3JCQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtvQkFFdEJBLE9BQU9BLEdBQUdBLE9BQU9BLENBQUNBLFdBQVdBLENBQUNBO29CQUU5QkEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZCQSxPQUFPQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDdkJBLE9BQU9BLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUN2QkEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBRXZCQSxLQUFLQSxHQUFHQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQTtvQkFDNUJBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO29CQUN0QkEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3RCQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDdkJBLENBQUNBO1lBQ0ZBLENBQUNBO1lBQUNBLElBQUlBLENBQUNBLENBQUNBO2dCQUNQQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtvQkFDekNBLE9BQU9BLEdBQUdBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUN0QkEsSUFBSUEsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBRWhCQSxDQUFDQSxHQUFHQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQTtvQkFDN0JBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUNUQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDVEEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ1RBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUVUQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtvQkFDckJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO29CQUV0QkEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ1RBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUNUQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDVEEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ1RBLEFBQ0FBLDBCQUQwQkE7b0JBQzFCQSxFQUFFQSxDQUFDQSxDQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTt3QkFDdkNBLEVBQUVBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBO3dCQUNUQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQTt3QkFDVEEsRUFBRUEsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0E7d0JBQ1RBLEVBQUVBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBO29CQUNWQSxDQUFDQTtvQkFDREEsT0FBT0EsR0FBR0EsT0FBT0EsQ0FBQ0EsV0FBV0EsQ0FBQ0E7b0JBQzlCQSxPQUFPQSxDQUFDQSxDQUFDQSxJQUFJQSxNQUFNQSxHQUFDQSxFQUFFQSxDQUFDQTtvQkFDdkJBLE9BQU9BLENBQUNBLENBQUNBLElBQUlBLE1BQU1BLEdBQUNBLEVBQUVBLENBQUNBO29CQUN2QkEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsTUFBTUEsR0FBQ0EsRUFBRUEsQ0FBQ0E7b0JBQ3ZCQSxPQUFPQSxDQUFDQSxDQUFDQSxJQUFJQSxNQUFNQSxHQUFDQSxFQUFFQSxDQUFDQTtvQkFFdkJBLEtBQUtBLEdBQUdBLE9BQU9BLENBQUNBLFdBQVdBLENBQUNBO29CQUM1QkEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsTUFBTUEsR0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZCQSxLQUFLQSxDQUFDQSxDQUFDQSxJQUFJQSxNQUFNQSxHQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDdkJBLEtBQUtBLENBQUNBLENBQUNBLElBQUlBLE1BQU1BLEdBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4QkEsQ0FBQ0E7WUFDRkEsQ0FBQ0E7UUFDRkEsQ0FBQ0E7UUFFREEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsUUFBUUEsQ0FBQ0EsU0FBU0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFDdENBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLFdBQVdBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBO0lBQ3RDQSxDQUFDQTtJQUNGUiw0QkFBQ0E7QUFBREEsQ0FoTkEsQUFnTkNBLEVBaE5tQyxrQkFBa0IsRUFnTnJEO0FBRUQsQUFBK0IsaUJBQXRCLHFCQUFxQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvU2tlbGV0b25OYXJ5TEVSUFN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFF1YXRlcm5pb25cdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1F1YXRlcm5pb25cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcblxuaW1wb3J0IEpvaW50UG9zZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Kb2ludFBvc2VcIik7XG5pbXBvcnQgU2tlbGV0b25cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvblwiKTtcbmltcG9ydCBTa2VsZXRvblBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25Qb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uTmFyeUxFUlBOb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1NrZWxldG9uTmFyeUxFUlBOb2RlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlXCIpO1xuaW1wb3J0IElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgU2tlbGV0b25OYXJ5TEVSUFN0YXRlIGV4dGVuZHMgQW5pbWF0aW9uU3RhdGVCYXNlIGltcGxlbWVudHMgSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcbntcblx0cHJpdmF0ZSBfc2tlbGV0b25BbmltYXRpb25Ob2RlOlNrZWxldG9uTmFyeUxFUlBOb2RlO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2U6U2tlbGV0b25Qb3NlID0gbmV3IFNrZWxldG9uUG9zZSgpO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2VEaXJ0eTpib29sZWFuID0gdHJ1ZTtcblx0cHJpdmF0ZSBfYmxlbmRXZWlnaHRzOkFycmF5PG51bWJlcj4gPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRwcml2YXRlIF9pbnB1dHM6QXJyYXk8SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU+ID0gbmV3IEFycmF5PElTa2VsZXRvbkFuaW1hdGlvblN0YXRlPigpO1xuXG5cdGNvbnN0cnVjdG9yKGFuaW1hdG9yOkFuaW1hdG9yQmFzZSwgc2tlbGV0b25BbmltYXRpb25Ob2RlOlNrZWxldG9uTmFyeUxFUlBOb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHNrZWxldG9uQW5pbWF0aW9uTm9kZSk7XG5cblx0XHR0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUgPSBza2VsZXRvbkFuaW1hdGlvbk5vZGU7XG5cblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUubnVtSW5wdXRzO1xuXG5cdFx0d2hpbGUgKGktLSlcblx0XHRcdHRoaXMuX2lucHV0c1tpXSA9IDxJU2tlbGV0b25BbmltYXRpb25TdGF0ZT4gYW5pbWF0b3IuZ2V0QW5pbWF0aW9uU3RhdGUodGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLl9pSW5wdXRzW2ldKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHBoYXNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3NrZWxldG9uUG9zZURpcnR5ID0gdHJ1ZTtcblxuXHRcdHRoaXMuX3BQb3NpdGlvbkRlbHRhRGlydHkgPSB0cnVlO1xuXG5cdFx0Zm9yICh2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwOyBqIDwgdGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLm51bUlucHV0czsgKytqKSB7XG5cdFx0XHRpZiAodGhpcy5fYmxlbmRXZWlnaHRzW2pdKVxuXHRcdFx0XHR0aGlzLl9pbnB1dHNbal0udXBkYXRlKHZhbHVlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVkYXRlVGltZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0Zm9yICh2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwOyBqIDwgdGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlLm51bUlucHV0czsgKytqKSB7XG5cdFx0XHRpZiAodGhpcy5fYmxlbmRXZWlnaHRzW2pdKVxuXHRcdFx0XHR0aGlzLl9pbnB1dHNbal0udXBkYXRlKHRpbWUpO1xuXHRcdH1cblxuXHRcdHN1cGVyLl9wVXBkYXRlVGltZSh0aW1lKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNrZWxldG9uIHBvc2Ugb2YgdGhlIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0U2tlbGV0b25Qb3NlKHNrZWxldG9uOlNrZWxldG9uKTpTa2VsZXRvblBvc2Vcblx0e1xuXHRcdGlmICh0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSlcblx0XHRcdHRoaXMudXBkYXRlU2tlbGV0b25Qb3NlKHNrZWxldG9uKTtcblxuXHRcdHJldHVybiB0aGlzLl9za2VsZXRvblBvc2U7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgYmxlbmQgd2VpZ2h0IG9mIHRoZSBza2VsZXRvbiBhbmlhbXRpb24gbm9kZSB0aGF0IHJlc2lkZXMgYXQgdGhlIGdpdmVuIGlucHV0IGluZGV4LlxuXHQgKlxuXHQgKiBAcGFyYW0gaW5kZXggVGhlIGlucHV0IGluZGV4IGZvciB3aGljaCB0aGUgc2tlbGV0b24gYW5pbWF0aW9uIG5vZGUgYmxlbmQgd2VpZ2h0IGlzIHJlcXVlc3RlZC5cblx0ICovXG5cdHB1YmxpYyBnZXRCbGVuZFdlaWdodEF0KGluZGV4Om51bWJlciAvKnVpbnQqLyk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmxlbmRXZWlnaHRzW2luZGV4XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBibGVuZCB3ZWlnaHQgb2YgdGhlIHNrZWxldG9uIGFuaWFtdGlvbiBub2RlIHRoYXQgcmVzaWRlcyBhdCB0aGUgZ2l2ZW4gaW5wdXQgaW5kZXguXG5cdCAqXG5cdCAqIEBwYXJhbSBpbmRleCBUaGUgaW5wdXQgaW5kZXggb24gd2hpY2ggdGhlIHNrZWxldG9uIGFuaW1hdGlvbiBub2RlIGJsZW5kIHdlaWdodCBpcyB0byBiZSBzZXQuXG5cdCAqIEBwYXJhbSBibGVuZFdlaWdodCBUaGUgYmxlbmQgd2VpZ2h0IHZhbHVlIHRvIHVzZSBmb3IgdGhlIGdpdmVuIHNrZWxldG9uIGFuaW1hdGlvbiBub2RlIGluZGV4LlxuXHQgKi9cblx0cHVibGljIHNldEJsZW5kV2VpZ2h0QXQoaW5kZXg6bnVtYmVyIC8qdWludCovLCBibGVuZFdlaWdodDpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9ibGVuZFdlaWdodHNbaW5kZXhdID0gYmxlbmRXZWlnaHQ7XG5cblx0XHR0aGlzLl9wUG9zaXRpb25EZWx0YURpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLl9za2VsZXRvblBvc2VEaXJ0eSA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFVwZGF0ZVBvc2l0aW9uRGVsdGEoKVxuXHR7XG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IGZhbHNlO1xuXG5cdFx0dmFyIGRlbHRhOlZlY3RvcjNEO1xuXHRcdHZhciB3ZWlnaHQ6bnVtYmVyO1xuXG5cdFx0dGhpcy5wb3NpdGlvbkRlbHRhLnggPSAwO1xuXHRcdHRoaXMucG9zaXRpb25EZWx0YS55ID0gMDtcblx0XHR0aGlzLnBvc2l0aW9uRGVsdGEueiA9IDA7XG5cblx0XHRmb3IgKHZhciBqOm51bWJlciAvKnVpbnQqLyA9IDA7IGogPCB0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUubnVtSW5wdXRzOyArK2opIHtcblx0XHRcdHdlaWdodCA9IHRoaXMuX2JsZW5kV2VpZ2h0c1tqXTtcblxuXHRcdFx0aWYgKHdlaWdodCkge1xuXHRcdFx0XHRkZWx0YSA9IHRoaXMuX2lucHV0c1tqXS5wb3NpdGlvbkRlbHRhO1xuXHRcdFx0XHR0aGlzLnBvc2l0aW9uRGVsdGEueCArPSB3ZWlnaHQqZGVsdGEueDtcblx0XHRcdFx0dGhpcy5wb3NpdGlvbkRlbHRhLnkgKz0gd2VpZ2h0KmRlbHRhLnk7XG5cdFx0XHRcdHRoaXMucG9zaXRpb25EZWx0YS56ICs9IHdlaWdodCpkZWx0YS56O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBvdXRwdXQgc2tlbGV0b24gcG9zZSBvZiB0aGUgbm9kZSBiYXNlZCBvbiB0aGUgYmxlbmQgd2VpZ2h0IHZhbHVlcyBnaXZlbiB0byB0aGUgaW5wdXQgbm9kZXMuXG5cdCAqXG5cdCAqIEBwYXJhbSBza2VsZXRvbiBUaGUgc2tlbGV0b24gdXNlZCBieSB0aGUgYW5pbWF0b3IgcmVxdWVzdGluZyB0aGUgb3VwdXQgcG9zZS5cblx0ICovXG5cdHByaXZhdGUgdXBkYXRlU2tlbGV0b25Qb3NlKHNrZWxldG9uOlNrZWxldG9uKVxuXHR7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSBmYWxzZTtcblxuXHRcdHZhciB3ZWlnaHQ6bnVtYmVyO1xuXHRcdHZhciBlbmRQb3NlczpBcnJheTxKb2ludFBvc2U+ID0gdGhpcy5fc2tlbGV0b25Qb3NlLmpvaW50UG9zZXM7XG5cdFx0dmFyIHBvc2VzOkFycmF5PEpvaW50UG9zZT47XG5cdFx0dmFyIGVuZFBvc2U6Sm9pbnRQb3NlLCBwb3NlOkpvaW50UG9zZTtcblx0XHR2YXIgZW5kVHI6VmVjdG9yM0QsIHRyOlZlY3RvcjNEO1xuXHRcdHZhciBlbmRRdWF0OlF1YXRlcm5pb24sIHE6UXVhdGVybmlvbjtcblx0XHR2YXIgZmlyc3RQb3NlOkFycmF5PEpvaW50UG9zZT47XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciB3MDpudW1iZXIsIHgwOm51bWJlciwgeTA6bnVtYmVyLCB6MDpudW1iZXI7XG5cdFx0dmFyIHcxOm51bWJlciwgeDE6bnVtYmVyLCB5MTpudW1iZXIsIHoxOm51bWJlcjtcblx0XHR2YXIgbnVtSm9pbnRzOm51bWJlciAvKnVpbnQqLyA9IHNrZWxldG9uLm51bUpvaW50cztcblxuXHRcdC8vIDpzXG5cdFx0aWYgKGVuZFBvc2VzLmxlbmd0aCAhPSBudW1Kb2ludHMpXG5cdFx0XHRlbmRQb3Nlcy5sZW5ndGggPSBudW1Kb2ludHM7XG5cblx0XHRmb3IgKHZhciBqOm51bWJlciAvKnVpbnQqLyA9IDA7IGogPCB0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUubnVtSW5wdXRzOyArK2opIHtcblx0XHRcdHdlaWdodCA9IHRoaXMuX2JsZW5kV2VpZ2h0c1tqXTtcblxuXHRcdFx0aWYgKCF3ZWlnaHQpXG5cdFx0XHRcdGNvbnRpbnVlO1xuXG5cdFx0XHRwb3NlcyA9IHRoaXMuX2lucHV0c1tqXS5nZXRTa2VsZXRvblBvc2Uoc2tlbGV0b24pLmpvaW50UG9zZXM7XG5cblx0XHRcdGlmICghZmlyc3RQb3NlKSB7XG5cdFx0XHRcdGZpcnN0UG9zZSA9IHBvc2VzO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgbnVtSm9pbnRzOyArK2kpIHtcblx0XHRcdFx0XHRlbmRQb3NlID0gZW5kUG9zZXNbaV07XG5cblx0XHRcdFx0XHRpZiAoZW5kUG9zZSA9PSBudWxsKVxuXHRcdFx0XHRcdFx0ZW5kUG9zZSA9IGVuZFBvc2VzW2ldID0gbmV3IEpvaW50UG9zZSgpO1xuXG5cdFx0XHRcdFx0cG9zZSA9IHBvc2VzW2ldO1xuXHRcdFx0XHRcdHEgPSBwb3NlLm9yaWVudGF0aW9uO1xuXHRcdFx0XHRcdHRyID0gcG9zZS50cmFuc2xhdGlvbjtcblxuXHRcdFx0XHRcdGVuZFF1YXQgPSBlbmRQb3NlLm9yaWVudGF0aW9uO1xuXG5cdFx0XHRcdFx0ZW5kUXVhdC54ID0gd2VpZ2h0KnEueDtcblx0XHRcdFx0XHRlbmRRdWF0LnkgPSB3ZWlnaHQqcS55O1xuXHRcdFx0XHRcdGVuZFF1YXQueiA9IHdlaWdodCpxLno7XG5cdFx0XHRcdFx0ZW5kUXVhdC53ID0gd2VpZ2h0KnEudztcblxuXHRcdFx0XHRcdGVuZFRyID0gZW5kUG9zZS50cmFuc2xhdGlvbjtcblx0XHRcdFx0XHRlbmRUci54ID0gd2VpZ2h0KnRyLng7XG5cdFx0XHRcdFx0ZW5kVHIueSA9IHdlaWdodCp0ci55O1xuXHRcdFx0XHRcdGVuZFRyLnogPSB3ZWlnaHQqdHIuejtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IHNrZWxldG9uLm51bUpvaW50czsgKytpKSB7XG5cdFx0XHRcdFx0ZW5kUG9zZSA9IGVuZFBvc2VzW2ldO1xuXHRcdFx0XHRcdHBvc2UgPSBwb3Nlc1tpXTtcblxuXHRcdFx0XHRcdHEgPSBmaXJzdFBvc2VbaV0ub3JpZW50YXRpb247XG5cdFx0XHRcdFx0eDAgPSBxLng7XG5cdFx0XHRcdFx0eTAgPSBxLnk7XG5cdFx0XHRcdFx0ejAgPSBxLno7XG5cdFx0XHRcdFx0dzAgPSBxLnc7XG5cblx0XHRcdFx0XHRxID0gcG9zZS5vcmllbnRhdGlvbjtcblx0XHRcdFx0XHR0ciA9IHBvc2UudHJhbnNsYXRpb247XG5cblx0XHRcdFx0XHR4MSA9IHEueDtcblx0XHRcdFx0XHR5MSA9IHEueTtcblx0XHRcdFx0XHR6MSA9IHEuejtcblx0XHRcdFx0XHR3MSA9IHEudztcblx0XHRcdFx0XHQvLyBmaW5kIHNob3J0ZXN0IGRpcmVjdGlvblxuXHRcdFx0XHRcdGlmICh4MCp4MSArIHkwKnkxICsgejAqejEgKyB3MCp3MSA8IDApIHtcblx0XHRcdFx0XHRcdHgxID0gLXgxO1xuXHRcdFx0XHRcdFx0eTEgPSAteTE7XG5cdFx0XHRcdFx0XHR6MSA9IC16MTtcblx0XHRcdFx0XHRcdHcxID0gLXcxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbmRRdWF0ID0gZW5kUG9zZS5vcmllbnRhdGlvbjtcblx0XHRcdFx0XHRlbmRRdWF0LnggKz0gd2VpZ2h0KngxO1xuXHRcdFx0XHRcdGVuZFF1YXQueSArPSB3ZWlnaHQqeTE7XG5cdFx0XHRcdFx0ZW5kUXVhdC56ICs9IHdlaWdodCp6MTtcblx0XHRcdFx0XHRlbmRRdWF0LncgKz0gd2VpZ2h0KncxO1xuXG5cdFx0XHRcdFx0ZW5kVHIgPSBlbmRQb3NlLnRyYW5zbGF0aW9uO1xuXHRcdFx0XHRcdGVuZFRyLnggKz0gd2VpZ2h0KnRyLng7XG5cdFx0XHRcdFx0ZW5kVHIueSArPSB3ZWlnaHQqdHIueTtcblx0XHRcdFx0XHRlbmRUci56ICs9IHdlaWdodCp0ci56O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHNrZWxldG9uLm51bUpvaW50czsgKytpKVxuXHRcdFx0ZW5kUG9zZXNbaV0ub3JpZW50YXRpb24ubm9ybWFsaXplKCk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2tlbGV0b25OYXJ5TEVSUFN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/states/SkeletonNaryLERPState.ts b/lib/animators/states/SkeletonNaryLERPState.ts
new file mode 100644
index 000000000..16a84c27c
--- /dev/null
+++ b/lib/animators/states/SkeletonNaryLERPState.ts
@@ -0,0 +1,226 @@
+import Quaternion = require("awayjs-core/lib/core/geom/Quaternion");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose");
+import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton");
+import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose");
+import SkeletonNaryLERPNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonNaryLERPNode");
+import AnimationStateBase = require("awayjs-renderergl/lib/animators/states/AnimationStateBase");
+import ISkeletonAnimationState = require("awayjs-renderergl/lib/animators/states/ISkeletonAnimationState");
+
+/**
+ *
+ */
+class SkeletonNaryLERPState extends AnimationStateBase implements ISkeletonAnimationState
+{
+ private _skeletonAnimationNode:SkeletonNaryLERPNode;
+ private _skeletonPose:SkeletonPose = new SkeletonPose();
+ private _skeletonPoseDirty:boolean = true;
+ private _blendWeights:Array = new Array();
+ private _inputs:Array = new Array();
+
+ constructor(animator:AnimatorBase, skeletonAnimationNode:SkeletonNaryLERPNode)
+ {
+ super(animator, skeletonAnimationNode);
+
+ this._skeletonAnimationNode = skeletonAnimationNode;
+
+ var i:number /*uint*/ = this._skeletonAnimationNode.numInputs;
+
+ while (i--)
+ this._inputs[i] = animator.getAnimationState(this._skeletonAnimationNode._iInputs[i]);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public phase(value:number)
+ {
+ this._skeletonPoseDirty = true;
+
+ this._pPositionDeltaDirty = true;
+
+ for (var j:number /*uint*/ = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ if (this._blendWeights[j])
+ this._inputs[j].update(value);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUdateTime(time:number /*int*/)
+ {
+ for (var j:number /*uint*/ = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ if (this._blendWeights[j])
+ this._inputs[j].update(time);
+ }
+
+ super._pUpdateTime(time);
+ }
+
+ /**
+ * Returns the current skeleton pose of the animation in the clip based on the internal playhead position.
+ */
+ public getSkeletonPose(skeleton:Skeleton):SkeletonPose
+ {
+ if (this._skeletonPoseDirty)
+ this.updateSkeletonPose(skeleton);
+
+ return this._skeletonPose;
+ }
+
+ /**
+ * Returns the blend weight of the skeleton aniamtion node that resides at the given input index.
+ *
+ * @param index The input index for which the skeleton animation node blend weight is requested.
+ */
+ public getBlendWeightAt(index:number /*uint*/):number
+ {
+ return this._blendWeights[index];
+ }
+
+ /**
+ * Sets the blend weight of the skeleton aniamtion node that resides at the given input index.
+ *
+ * @param index The input index on which the skeleton animation node blend weight is to be set.
+ * @param blendWeight The blend weight value to use for the given skeleton animation node index.
+ */
+ public setBlendWeightAt(index:number /*uint*/, blendWeight:number)
+ {
+ this._blendWeights[index] = blendWeight;
+
+ this._pPositionDeltaDirty = true;
+ this._skeletonPoseDirty = true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ this._pPositionDeltaDirty = false;
+
+ var delta:Vector3D;
+ var weight:number;
+
+ this.positionDelta.x = 0;
+ this.positionDelta.y = 0;
+ this.positionDelta.z = 0;
+
+ for (var j:number /*uint*/ = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ weight = this._blendWeights[j];
+
+ if (weight) {
+ delta = this._inputs[j].positionDelta;
+ this.positionDelta.x += weight*delta.x;
+ this.positionDelta.y += weight*delta.y;
+ this.positionDelta.z += weight*delta.z;
+ }
+ }
+ }
+
+ /**
+ * Updates the output skeleton pose of the node based on the blend weight values given to the input nodes.
+ *
+ * @param skeleton The skeleton used by the animator requesting the ouput pose.
+ */
+ private updateSkeletonPose(skeleton:Skeleton)
+ {
+ this._skeletonPoseDirty = false;
+
+ var weight:number;
+ var endPoses:Array = this._skeletonPose.jointPoses;
+ var poses:Array;
+ var endPose:JointPose, pose:JointPose;
+ var endTr:Vector3D, tr:Vector3D;
+ var endQuat:Quaternion, q:Quaternion;
+ var firstPose:Array;
+ var i:number /*uint*/;
+ var w0:number, x0:number, y0:number, z0:number;
+ var w1:number, x1:number, y1:number, z1:number;
+ var numJoints:number /*uint*/ = skeleton.numJoints;
+
+ // :s
+ if (endPoses.length != numJoints)
+ endPoses.length = numJoints;
+
+ for (var j:number /*uint*/ = 0; j < this._skeletonAnimationNode.numInputs; ++j) {
+ weight = this._blendWeights[j];
+
+ if (!weight)
+ continue;
+
+ poses = this._inputs[j].getSkeletonPose(skeleton).jointPoses;
+
+ if (!firstPose) {
+ firstPose = poses;
+ for (i = 0; i < numJoints; ++i) {
+ endPose = endPoses[i];
+
+ if (endPose == null)
+ endPose = endPoses[i] = new JointPose();
+
+ pose = poses[i];
+ q = pose.orientation;
+ tr = pose.translation;
+
+ endQuat = endPose.orientation;
+
+ endQuat.x = weight*q.x;
+ endQuat.y = weight*q.y;
+ endQuat.z = weight*q.z;
+ endQuat.w = weight*q.w;
+
+ endTr = endPose.translation;
+ endTr.x = weight*tr.x;
+ endTr.y = weight*tr.y;
+ endTr.z = weight*tr.z;
+ }
+ } else {
+ for (i = 0; i < skeleton.numJoints; ++i) {
+ endPose = endPoses[i];
+ pose = poses[i];
+
+ q = firstPose[i].orientation;
+ x0 = q.x;
+ y0 = q.y;
+ z0 = q.z;
+ w0 = q.w;
+
+ q = pose.orientation;
+ tr = pose.translation;
+
+ x1 = q.x;
+ y1 = q.y;
+ z1 = q.z;
+ w1 = q.w;
+ // find shortest direction
+ if (x0*x1 + y0*y1 + z0*z1 + w0*w1 < 0) {
+ x1 = -x1;
+ y1 = -y1;
+ z1 = -z1;
+ w1 = -w1;
+ }
+ endQuat = endPose.orientation;
+ endQuat.x += weight*x1;
+ endQuat.y += weight*y1;
+ endQuat.z += weight*z1;
+ endQuat.w += weight*w1;
+
+ endTr = endPose.translation;
+ endTr.x += weight*tr.x;
+ endTr.y += weight*tr.y;
+ endTr.z += weight*tr.z;
+ }
+ }
+ }
+
+ for (i = 0; i < skeleton.numJoints; ++i)
+ endPoses[i].orientation.normalize();
+ }
+}
+
+export = SkeletonNaryLERPState;
\ No newline at end of file
diff --git a/lib/animators/states/VertexClipState.js b/lib/animators/states/VertexClipState.js
new file mode 100755
index 000000000..fdace4ecd
--- /dev/null
+++ b/lib/animators/states/VertexClipState.js
@@ -0,0 +1,65 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AnimationClipState = require("awayjs-renderergl/lib/animators/states/AnimationClipState");
+/**
+ *
+ */
+var VertexClipState = (function (_super) {
+ __extends(VertexClipState, _super);
+ function VertexClipState(animator, vertexClipNode) {
+ _super.call(this, animator, vertexClipNode);
+ this._vertexClipNode = vertexClipNode;
+ this._frames = this._vertexClipNode.frames;
+ }
+ Object.defineProperty(VertexClipState.prototype, "currentGeometry", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._currentGeometry;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(VertexClipState.prototype, "nextGeometry", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+ return this._nextGeometry;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ VertexClipState.prototype._pUpdateFrames = function () {
+ _super.prototype._pUpdateFrames.call(this);
+ this._currentGeometry = this._frames[this._pCurrentFrame];
+ if (this._vertexClipNode.looping && this._pNextFrame >= this._vertexClipNode.lastFrame) {
+ this._nextGeometry = this._frames[0];
+ this._pAnimator.dispatchCycleEvent();
+ }
+ else
+ this._nextGeometry = this._frames[this._pNextFrame];
+ };
+ /**
+ * @inheritDoc
+ */
+ VertexClipState.prototype._pUpdatePositionDelta = function () {
+ //TODO:implement positiondelta functionality for vertex animations
+ };
+ return VertexClipState;
+})(AnimationClipState);
+module.exports = VertexClipState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvdmVydGV4Y2xpcHN0YXRlLnRzIl0sIm5hbWVzIjpbIlZlcnRleENsaXBTdGF0ZSIsIlZlcnRleENsaXBTdGF0ZS5jb25zdHJ1Y3RvciIsIlZlcnRleENsaXBTdGF0ZS5jdXJyZW50R2VvbWV0cnkiLCJWZXJ0ZXhDbGlwU3RhdGUubmV4dEdlb21ldHJ5IiwiVmVydGV4Q2xpcFN0YXRlLl9wVXBkYXRlRnJhbWVzIiwiVmVydGV4Q2xpcFN0YXRlLl9wVXBkYXRlUG9zaXRpb25EZWx0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBTUEsSUFBTyxrQkFBa0IsV0FBYywyREFBMkQsQ0FBQyxDQUFDO0FBR3BHLEFBR0E7O0dBREc7SUFDRyxlQUFlO0lBQVNBLFVBQXhCQSxlQUFlQSxVQUEyQkE7SUE2Qi9DQSxTQTdCS0EsZUFBZUEsQ0E2QlJBLFFBQXFCQSxFQUFFQSxjQUE2QkE7UUFFL0RDLGtCQUFNQSxRQUFRQSxFQUFFQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUVoQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsY0FBY0EsQ0FBQ0E7UUFDdENBLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLE1BQU1BLENBQUNBO0lBQzVDQSxDQUFDQTtJQXpCREQsc0JBQVdBLDRDQUFlQTtRQUgxQkE7O1dBRUdBO2FBQ0hBO1lBRUNFLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO2dCQUN0QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsRUFBRUEsQ0FBQ0E7WUFFdkJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7UUFDOUJBLENBQUNBOzs7T0FBQUY7SUFLREEsc0JBQVdBLHlDQUFZQTtRQUh2QkE7O1dBRUdBO2FBQ0hBO1lBRUNHLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO2dCQUN0QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsRUFBRUEsQ0FBQ0E7WUFFdkJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1FBQzNCQSxDQUFDQTs7O09BQUFIO0lBVURBOztPQUVHQTtJQUNJQSx3Q0FBY0EsR0FBckJBO1FBRUNJLGdCQUFLQSxDQUFDQSxjQUFjQSxXQUFFQSxDQUFDQTtRQUV2QkEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUUxREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsT0FBT0EsSUFBSUEsSUFBSUEsQ0FBQ0EsV0FBV0EsSUFBSUEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeEZBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ25CQSxJQUFJQSxDQUFDQSxVQUFXQSxDQUFDQSxrQkFBa0JBLEVBQUVBLENBQUNBO1FBQ3pEQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUNMQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtJQUN0REEsQ0FBQ0E7SUFFREo7O09BRUdBO0lBQ0lBLCtDQUFxQkEsR0FBNUJBO1FBRUNLLGtFQUFrRUE7SUFDbkVBLENBQUNBO0lBQ0ZMLHNCQUFDQTtBQUFEQSxDQTVEQSxBQTREQ0EsRUE1RDZCLGtCQUFrQixFQTREL0M7QUFFRCxBQUF5QixpQkFBaEIsZUFBZSxDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy9zdGF0ZXMvVmVydGV4Q2xpcFN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEdlb21ldHJ5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0dlb21ldHJ5XCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBWZXJ0ZXhBbmltYXRvclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL1ZlcnRleEFuaW1hdG9yXCIpO1xuaW1wb3J0IFZlcnRleENsaXBOb2RlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvVmVydGV4Q2xpcE5vZGVcIik7XG5pbXBvcnQgQW5pbWF0aW9uQ2xpcFN0YXRlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3N0YXRlcy9BbmltYXRpb25DbGlwU3RhdGVcIik7XG5pbXBvcnQgSVZlcnRleEFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVZlcnRleEFuaW1hdGlvblN0YXRlXCIpO1xuXG4vKipcbiAqXG4gKi9cbmNsYXNzIFZlcnRleENsaXBTdGF0ZSBleHRlbmRzIEFuaW1hdGlvbkNsaXBTdGF0ZSBpbXBsZW1lbnRzIElWZXJ0ZXhBbmltYXRpb25TdGF0ZVxue1xuXHRwcml2YXRlIF9mcmFtZXM6QXJyYXk8R2VvbWV0cnk+O1xuXHRwcml2YXRlIF92ZXJ0ZXhDbGlwTm9kZTpWZXJ0ZXhDbGlwTm9kZTtcblx0cHJpdmF0ZSBfY3VycmVudEdlb21ldHJ5Okdlb21ldHJ5O1xuXHRwcml2YXRlIF9uZXh0R2VvbWV0cnk6R2VvbWV0cnk7XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGN1cnJlbnRHZW9tZXRyeSgpOkdlb21ldHJ5XG5cdHtcblx0XHRpZiAodGhpcy5fcEZyYW1lc0RpcnR5KVxuXHRcdFx0dGhpcy5fcFVwZGF0ZUZyYW1lcygpO1xuXG5cdFx0cmV0dXJuIHRoaXMuX2N1cnJlbnRHZW9tZXRyeTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldCBuZXh0R2VvbWV0cnkoKTpHZW9tZXRyeVxuXHR7XG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHJldHVybiB0aGlzLl9uZXh0R2VvbWV0cnk7XG5cdH1cblxuXHRjb25zdHJ1Y3RvcihhbmltYXRvcjpBbmltYXRvckJhc2UsIHZlcnRleENsaXBOb2RlOlZlcnRleENsaXBOb2RlKVxuXHR7XG5cdFx0c3VwZXIoYW5pbWF0b3IsIHZlcnRleENsaXBOb2RlKTtcblxuXHRcdHRoaXMuX3ZlcnRleENsaXBOb2RlID0gdmVydGV4Q2xpcE5vZGU7XG5cdFx0dGhpcy5fZnJhbWVzID0gdGhpcy5fdmVydGV4Q2xpcE5vZGUuZnJhbWVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVGcmFtZXMoKVxuXHR7XG5cdFx0c3VwZXIuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHRoaXMuX2N1cnJlbnRHZW9tZXRyeSA9IHRoaXMuX2ZyYW1lc1t0aGlzLl9wQ3VycmVudEZyYW1lXTtcblxuXHRcdGlmICh0aGlzLl92ZXJ0ZXhDbGlwTm9kZS5sb29waW5nICYmIHRoaXMuX3BOZXh0RnJhbWUgPj0gdGhpcy5fdmVydGV4Q2xpcE5vZGUubGFzdEZyYW1lKSB7XG5cdFx0XHR0aGlzLl9uZXh0R2VvbWV0cnkgPSB0aGlzLl9mcmFtZXNbMF07XG5cdFx0XHQoPFZlcnRleEFuaW1hdG9yPiB0aGlzLl9wQW5pbWF0b3IpLmRpc3BhdGNoQ3ljbGVFdmVudCgpO1xuXHRcdH0gZWxzZVxuXHRcdFx0dGhpcy5fbmV4dEdlb21ldHJ5ID0gdGhpcy5fZnJhbWVzW3RoaXMuX3BOZXh0RnJhbWVdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BVcGRhdGVQb3NpdGlvbkRlbHRhKClcblx0e1xuXHRcdC8vVE9ETzppbXBsZW1lbnQgcG9zaXRpb25kZWx0YSBmdW5jdGlvbmFsaXR5IGZvciB2ZXJ0ZXggYW5pbWF0aW9uc1xuXHR9XG59XG5cbmV4cG9ydCA9IFZlcnRleENsaXBTdGF0ZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/states/VertexClipState.ts b/lib/animators/states/VertexClipState.ts
new file mode 100644
index 000000000..8e235d387
--- /dev/null
+++ b/lib/animators/states/VertexClipState.ts
@@ -0,0 +1,75 @@
+import Geometry = require("awayjs-core/lib/core/base/Geometry");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import VertexAnimator = require("awayjs-renderergl/lib/animators/VertexAnimator");
+import VertexClipNode = require("awayjs-renderergl/lib/animators/nodes/VertexClipNode");
+import AnimationClipState = require("awayjs-renderergl/lib/animators/states/AnimationClipState");
+import IVertexAnimationState = require("awayjs-renderergl/lib/animators/states/IVertexAnimationState");
+
+/**
+ *
+ */
+class VertexClipState extends AnimationClipState implements IVertexAnimationState
+{
+ private _frames:Array;
+ private _vertexClipNode:VertexClipNode;
+ private _currentGeometry:Geometry;
+ private _nextGeometry:Geometry;
+
+ /**
+ * @inheritDoc
+ */
+ public get currentGeometry():Geometry
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._currentGeometry;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get nextGeometry():Geometry
+ {
+ if (this._pFramesDirty)
+ this._pUpdateFrames();
+
+ return this._nextGeometry;
+ }
+
+ constructor(animator:AnimatorBase, vertexClipNode:VertexClipNode)
+ {
+ super(animator, vertexClipNode);
+
+ this._vertexClipNode = vertexClipNode;
+ this._frames = this._vertexClipNode.frames;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateFrames()
+ {
+ super._pUpdateFrames();
+
+ this._currentGeometry = this._frames[this._pCurrentFrame];
+
+ if (this._vertexClipNode.looping && this._pNextFrame >= this._vertexClipNode.lastFrame) {
+ this._nextGeometry = this._frames[0];
+ ( this._pAnimator).dispatchCycleEvent();
+ } else
+ this._nextGeometry = this._frames[this._pNextFrame];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdatePositionDelta()
+ {
+ //TODO:implement positiondelta functionality for vertex animations
+ }
+}
+
+export = VertexClipState;
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransition.js b/lib/animators/transitions/CrossfadeTransition.js
new file mode 100755
index 000000000..39a6500f2
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransition.js
@@ -0,0 +1,22 @@
+var CrossfadeTransitionNode = require("awayjs-renderergl/lib/animators/transitions/CrossfadeTransitionNode");
+/**
+ *
+ */
+var CrossfadeTransition = (function () {
+ function CrossfadeTransition(blendSpeed) {
+ this.blendSpeed = 0.5;
+ this.blendSpeed = blendSpeed;
+ }
+ CrossfadeTransition.prototype.getAnimationNode = function (animator, startNode, endNode, startBlend /*int*/) {
+ var crossFadeTransitionNode = new CrossfadeTransitionNode();
+ crossFadeTransitionNode.inputA = startNode;
+ crossFadeTransitionNode.inputB = endNode;
+ crossFadeTransitionNode.blendSpeed = this.blendSpeed;
+ crossFadeTransitionNode.startBlend = startBlend;
+ return crossFadeTransitionNode;
+ };
+ return CrossfadeTransition;
+})();
+module.exports = CrossfadeTransition;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy90cmFuc2l0aW9ucy9jcm9zc2ZhZGV0cmFuc2l0aW9uLnRzIl0sIm5hbWVzIjpbIkNyb3NzZmFkZVRyYW5zaXRpb24iLCJDcm9zc2ZhZGVUcmFuc2l0aW9uLmNvbnN0cnVjdG9yIiwiQ3Jvc3NmYWRlVHJhbnNpdGlvbi5nZXRBbmltYXRpb25Ob2RlIl0sIm1hcHBpbmdzIjoiQUFJQSxJQUFPLHVCQUF1QixXQUFhLHFFQUFxRSxDQUFDLENBQUM7QUFHbEgsQUFHQTs7R0FERztJQUNHLG1CQUFtQjtJQUl4QkEsU0FKS0EsbUJBQW1CQSxDQUlaQSxVQUFpQkE7UUFGdEJDLGVBQVVBLEdBQVVBLEdBQUdBLENBQUNBO1FBSTlCQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxVQUFVQSxDQUFDQTtJQUM5QkEsQ0FBQ0E7SUFFTUQsOENBQWdCQSxHQUF2QkEsVUFBd0JBLFFBQXFCQSxFQUFFQSxTQUEyQkEsRUFBRUEsT0FBeUJBLEVBQUVBLFVBQVVBLENBQVFBLE9BQURBLEFBQVFBO1FBRS9IRSxJQUFJQSx1QkFBdUJBLEdBQTJCQSxJQUFJQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3BGQSx1QkFBdUJBLENBQUNBLE1BQU1BLEdBQUdBLFNBQVNBLENBQUNBO1FBQzNDQSx1QkFBdUJBLENBQUNBLE1BQU1BLEdBQUdBLE9BQU9BLENBQUNBO1FBQ3pDQSx1QkFBdUJBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBO1FBQ3JEQSx1QkFBdUJBLENBQUNBLFVBQVVBLEdBQUdBLFVBQVVBLENBQUNBO1FBRWhEQSxNQUFNQSxDQUFxQkEsdUJBQXVCQSxDQUFDQTtJQUNwREEsQ0FBQ0E7SUFDRkYsMEJBQUNBO0FBQURBLENBbkJBLEFBbUJDQSxJQUFBO0FBRUQsQUFBNkIsaUJBQXBCLG1CQUFtQixDQUFDIiwiZmlsZSI6ImFuaW1hdG9ycy90cmFuc2l0aW9ucy9Dcm9zc2ZhZGVUcmFuc2l0aW9uLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBDcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvdHJhbnNpdGlvbnMvQ3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGVcIik7XG5pbXBvcnQgSUFuaW1hdGlvblRyYW5zaXRpb25cdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvdHJhbnNpdGlvbnMvSUFuaW1hdGlvblRyYW5zaXRpb25cIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgQ3Jvc3NmYWRlVHJhbnNpdGlvbiBpbXBsZW1lbnRzIElBbmltYXRpb25UcmFuc2l0aW9uXG57XG5cdHB1YmxpYyBibGVuZFNwZWVkOm51bWJlciA9IDAuNTtcblxuXHRjb25zdHJ1Y3RvcihibGVuZFNwZWVkOm51bWJlcilcblx0e1xuXHRcdHRoaXMuYmxlbmRTcGVlZCA9IGJsZW5kU3BlZWQ7XG5cdH1cblxuXHRwdWJsaWMgZ2V0QW5pbWF0aW9uTm9kZShhbmltYXRvcjpBbmltYXRvckJhc2UsIHN0YXJ0Tm9kZTpBbmltYXRpb25Ob2RlQmFzZSwgZW5kTm9kZTpBbmltYXRpb25Ob2RlQmFzZSwgc3RhcnRCbGVuZDpudW1iZXIgLyppbnQqLyk6QW5pbWF0aW9uTm9kZUJhc2Vcblx0e1xuXHRcdHZhciBjcm9zc0ZhZGVUcmFuc2l0aW9uTm9kZTpDcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZSA9IG5ldyBDcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZSgpO1xuXHRcdGNyb3NzRmFkZVRyYW5zaXRpb25Ob2RlLmlucHV0QSA9IHN0YXJ0Tm9kZTtcblx0XHRjcm9zc0ZhZGVUcmFuc2l0aW9uTm9kZS5pbnB1dEIgPSBlbmROb2RlO1xuXHRcdGNyb3NzRmFkZVRyYW5zaXRpb25Ob2RlLmJsZW5kU3BlZWQgPSB0aGlzLmJsZW5kU3BlZWQ7XG5cdFx0Y3Jvc3NGYWRlVHJhbnNpdGlvbk5vZGUuc3RhcnRCbGVuZCA9IHN0YXJ0QmxlbmQ7XG5cblx0XHRyZXR1cm4gPEFuaW1hdGlvbk5vZGVCYXNlPiBjcm9zc0ZhZGVUcmFuc2l0aW9uTm9kZTtcblx0fVxufVxuXG5leHBvcnQgPSBDcm9zc2ZhZGVUcmFuc2l0aW9uOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransition.ts b/lib/animators/transitions/CrossfadeTransition.ts
new file mode 100644
index 000000000..735490b90
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransition.ts
@@ -0,0 +1,32 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import CrossfadeTransitionNode = require("awayjs-renderergl/lib/animators/transitions/CrossfadeTransitionNode");
+import IAnimationTransition = require("awayjs-renderergl/lib/animators/transitions/IAnimationTransition");
+
+/**
+ *
+ */
+class CrossfadeTransition implements IAnimationTransition
+{
+ public blendSpeed:number = 0.5;
+
+ constructor(blendSpeed:number)
+ {
+ this.blendSpeed = blendSpeed;
+ }
+
+ public getAnimationNode(animator:AnimatorBase, startNode:AnimationNodeBase, endNode:AnimationNodeBase, startBlend:number /*int*/):AnimationNodeBase
+ {
+ var crossFadeTransitionNode:CrossfadeTransitionNode = new CrossfadeTransitionNode();
+ crossFadeTransitionNode.inputA = startNode;
+ crossFadeTransitionNode.inputB = endNode;
+ crossFadeTransitionNode.blendSpeed = this.blendSpeed;
+ crossFadeTransitionNode.startBlend = startBlend;
+
+ return crossFadeTransitionNode;
+ }
+}
+
+export = CrossfadeTransition;
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransitionNode.js b/lib/animators/transitions/CrossfadeTransitionNode.js
new file mode 100755
index 000000000..f0ce26b4d
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransitionNode.js
@@ -0,0 +1,25 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var SkeletonBinaryLERPNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonBinaryLERPNode");
+var CrossfadeTransitionState = require("awayjs-renderergl/lib/animators/transitions/CrossfadeTransitionState");
+/**
+ * A skeleton animation node that uses two animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+var CrossfadeTransitionNode = (function (_super) {
+ __extends(CrossfadeTransitionNode, _super);
+ /**
+ * Creates a new CrossfadeTransitionNode
object.
+ */
+ function CrossfadeTransitionNode() {
+ _super.call(this);
+ this._pStateClass = CrossfadeTransitionState;
+ }
+ return CrossfadeTransitionNode;
+})(SkeletonBinaryLERPNode);
+module.exports = CrossfadeTransitionNode;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy90cmFuc2l0aW9ucy9jcm9zc2ZhZGV0cmFuc2l0aW9ubm9kZS50cyJdLCJuYW1lcyI6WyJDcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZSIsIkNyb3NzZmFkZVRyYW5zaXRpb25Ob2RlLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLHNCQUFzQixXQUFhLDhEQUE4RCxDQUFDLENBQUM7QUFDMUcsSUFBTyx3QkFBd0IsV0FBYSxzRUFBc0UsQ0FBQyxDQUFDO0FBRXBILEFBR0E7O0dBREc7SUFDRyx1QkFBdUI7SUFBU0EsVUFBaENBLHVCQUF1QkEsVUFBK0JBO0lBTTNEQTs7T0FFR0E7SUFDSEEsU0FUS0EsdUJBQXVCQTtRQVczQkMsaUJBQU9BLENBQUNBO1FBRVJBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLHdCQUF3QkEsQ0FBQ0E7SUFDOUNBLENBQUNBO0lBQ0ZELDhCQUFDQTtBQUFEQSxDQWZBLEFBZUNBLEVBZnFDLHNCQUFzQixFQWUzRDtBQUVELEFBQWlDLGlCQUF4Qix1QkFBdUIsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvdHJhbnNpdGlvbnMvQ3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgU2tlbGV0b25CaW5hcnlMRVJQTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvU2tlbGV0b25CaW5hcnlMRVJQTm9kZVwiKTtcbmltcG9ydCBDcm9zc2ZhZGVUcmFuc2l0aW9uU3RhdGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL3RyYW5zaXRpb25zL0Nyb3NzZmFkZVRyYW5zaXRpb25TdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHNrZWxldG9uIGFuaW1hdGlvbiBub2RlIHRoYXQgdXNlcyB0d28gYW5pbWF0aW9uIG5vZGUgaW5wdXRzIHRvIGJsZW5kIGEgbGluZXJhbHkgaW50ZXJwb2xhdGVkIG91dHB1dCBvZiBhIHNrZWxldG9uIHBvc2UuXG4gKi9cbmNsYXNzIENyb3NzZmFkZVRyYW5zaXRpb25Ob2RlIGV4dGVuZHMgU2tlbGV0b25CaW5hcnlMRVJQTm9kZVxue1xuXHRwdWJsaWMgYmxlbmRTcGVlZDpudW1iZXI7XG5cblx0cHVibGljIHN0YXJ0QmxlbmQ6bnVtYmVyIC8qaW50Ki87XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+Q3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGU8L2NvZGU+IG9iamVjdC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLl9wU3RhdGVDbGFzcyA9IENyb3NzZmFkZVRyYW5zaXRpb25TdGF0ZTtcblx0fVxufVxuXG5leHBvcnQgPSBDcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZTsiXX0=
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransitionNode.ts b/lib/animators/transitions/CrossfadeTransitionNode.ts
new file mode 100644
index 000000000..129b27a6d
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransitionNode.ts
@@ -0,0 +1,24 @@
+import SkeletonBinaryLERPNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonBinaryLERPNode");
+import CrossfadeTransitionState = require("awayjs-renderergl/lib/animators/transitions/CrossfadeTransitionState");
+
+/**
+ * A skeleton animation node that uses two animation node inputs to blend a lineraly interpolated output of a skeleton pose.
+ */
+class CrossfadeTransitionNode extends SkeletonBinaryLERPNode
+{
+ public blendSpeed:number;
+
+ public startBlend:number /*int*/;
+
+ /**
+ * Creates a new CrossfadeTransitionNode
object.
+ */
+ constructor()
+ {
+ super();
+
+ this._pStateClass = CrossfadeTransitionState;
+ }
+}
+
+export = CrossfadeTransitionNode;
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransitionState.js b/lib/animators/transitions/CrossfadeTransitionState.js
new file mode 100755
index 000000000..c55963505
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransitionState.js
@@ -0,0 +1,35 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var SkeletonBinaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonBinaryLERPState");
+var AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+/**
+ *
+ */
+var CrossfadeTransitionState = (function (_super) {
+ __extends(CrossfadeTransitionState, _super);
+ function CrossfadeTransitionState(animator, skeletonAnimationNode) {
+ _super.call(this, animator, skeletonAnimationNode);
+ this._crossfadeTransitionNode = skeletonAnimationNode;
+ }
+ /**
+ * @inheritDoc
+ */
+ CrossfadeTransitionState.prototype._pUpdateTime = function (time /*int*/) {
+ this.blendWeight = Math.abs(time - this._crossfadeTransitionNode.startBlend) / (1000 * this._crossfadeTransitionNode.blendSpeed);
+ if (this.blendWeight >= 1) {
+ this.blendWeight = 1;
+ if (this._animationStateTransitionComplete == null)
+ this._animationStateTransitionComplete = new AnimationStateEvent(AnimationStateEvent.TRANSITION_COMPLETE, this._pAnimator, this, this._crossfadeTransitionNode);
+ this._crossfadeTransitionNode.dispatchEvent(this._animationStateTransitionComplete);
+ }
+ _super.prototype._pUpdateTime.call(this, time);
+ };
+ return CrossfadeTransitionState;
+})(SkeletonBinaryLERPState);
+module.exports = CrossfadeTransitionState;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy90cmFuc2l0aW9ucy9jcm9zc2ZhZGV0cmFuc2l0aW9uc3RhdGUudHMiXSwibmFtZXMiOlsiQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlIiwiQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlLmNvbnN0cnVjdG9yIiwiQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlLl9wVXBkYXRlVGltZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsSUFBTyx1QkFBdUIsV0FBYSxnRUFBZ0UsQ0FBQyxDQUFDO0FBRTdHLElBQU8sbUJBQW1CLFdBQWMsa0RBQWtELENBQUMsQ0FBQztBQUU1RixBQUdBOztHQURHO0lBQ0csd0JBQXdCO0lBQVNBLFVBQWpDQSx3QkFBd0JBLFVBQWdDQTtJQUs3REEsU0FMS0Esd0JBQXdCQSxDQUtqQkEsUUFBcUJBLEVBQUVBLHFCQUE2Q0E7UUFFL0VDLGtCQUFNQSxRQUFRQSxFQUEyQkEscUJBQXFCQSxDQUFDQSxDQUFDQTtRQUVoRUEsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxHQUFHQSxxQkFBcUJBLENBQUNBO0lBQ3ZEQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsK0NBQVlBLEdBQW5CQSxVQUFvQkEsSUFBSUEsQ0FBUUEsT0FBREEsQUFBUUE7UUFFdENFLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLEdBQUdBLENBQUNBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsSUFBSUEsR0FBQ0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQTtRQUU3SEEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDM0JBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLENBQUNBLENBQUNBO1lBRXJCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxpQ0FBaUNBLElBQUlBLElBQUlBLENBQUNBO2dCQUNsREEsSUFBSUEsQ0FBQ0EsaUNBQWlDQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsbUJBQW1CQSxFQUFFQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxJQUFJQSxFQUFFQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLENBQUNBO1lBRWpLQSxJQUFJQSxDQUFDQSx3QkFBd0JBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLGlDQUFpQ0EsQ0FBQ0EsQ0FBQ0E7UUFDckZBLENBQUNBO1FBRURBLGdCQUFLQSxDQUFDQSxZQUFZQSxZQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUMxQkEsQ0FBQ0E7SUFDRkYsK0JBQUNBO0FBQURBLENBOUJBLEFBOEJDQSxFQTlCc0MsdUJBQXVCLEVBOEI3RDtBQUVELEFBQWtDLGlCQUF6Qix3QkFBd0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvdHJhbnNpdGlvbnMvQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdG9yQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0b3JCYXNlXCIpO1xuXG5pbXBvcnQgU2tlbGV0b25CaW5hcnlMRVJQTm9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvU2tlbGV0b25CaW5hcnlMRVJQTm9kZVwiKTtcbmltcG9ydCBTa2VsZXRvbkJpbmFyeUxFUlBTdGF0ZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1NrZWxldG9uQmluYXJ5TEVSUFN0YXRlXCIpO1xuaW1wb3J0IENyb3NzZmFkZVRyYW5zaXRpb25Ob2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy90cmFuc2l0aW9ucy9Dcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZVwiKTtcbmltcG9ydCBBbmltYXRpb25TdGF0ZUV2ZW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvZXZlbnRzL0FuaW1hdGlvblN0YXRlRXZlbnRcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlIGV4dGVuZHMgU2tlbGV0b25CaW5hcnlMRVJQU3RhdGVcbntcblx0cHJpdmF0ZSBfY3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGU6Q3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGU7XG5cdHByaXZhdGUgX2FuaW1hdGlvblN0YXRlVHJhbnNpdGlvbkNvbXBsZXRlOkFuaW1hdGlvblN0YXRlRXZlbnQ7XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBza2VsZXRvbkFuaW1hdGlvbk5vZGU6Q3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGUpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgPFNrZWxldG9uQmluYXJ5TEVSUE5vZGU+IHNrZWxldG9uQW5pbWF0aW9uTm9kZSk7XG5cblx0XHR0aGlzLl9jcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZSA9IHNrZWxldG9uQW5pbWF0aW9uTm9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVXBkYXRlVGltZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0dGhpcy5ibGVuZFdlaWdodCA9IE1hdGguYWJzKHRpbWUgLSB0aGlzLl9jcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZS5zdGFydEJsZW5kKS8oMTAwMCp0aGlzLl9jcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZS5ibGVuZFNwZWVkKTtcblxuXHRcdGlmICh0aGlzLmJsZW5kV2VpZ2h0ID49IDEpIHtcblx0XHRcdHRoaXMuYmxlbmRXZWlnaHQgPSAxO1xuXG5cdFx0XHRpZiAodGhpcy5fYW5pbWF0aW9uU3RhdGVUcmFuc2l0aW9uQ29tcGxldGUgPT0gbnVsbClcblx0XHRcdFx0dGhpcy5fYW5pbWF0aW9uU3RhdGVUcmFuc2l0aW9uQ29tcGxldGUgPSBuZXcgQW5pbWF0aW9uU3RhdGVFdmVudChBbmltYXRpb25TdGF0ZUV2ZW50LlRSQU5TSVRJT05fQ09NUExFVEUsIHRoaXMuX3BBbmltYXRvciwgdGhpcywgdGhpcy5fY3Jvc3NmYWRlVHJhbnNpdGlvbk5vZGUpO1xuXG5cdFx0XHR0aGlzLl9jcm9zc2ZhZGVUcmFuc2l0aW9uTm9kZS5kaXNwYXRjaEV2ZW50KHRoaXMuX2FuaW1hdGlvblN0YXRlVHJhbnNpdGlvbkNvbXBsZXRlKTtcblx0XHR9XG5cblx0XHRzdXBlci5fcFVwZGF0ZVRpbWUodGltZSk7XG5cdH1cbn1cblxuZXhwb3J0ID0gQ3Jvc3NmYWRlVHJhbnNpdGlvblN0YXRlOyJdfQ==
\ No newline at end of file
diff --git a/lib/animators/transitions/CrossfadeTransitionState.ts b/lib/animators/transitions/CrossfadeTransitionState.ts
new file mode 100644
index 000000000..eff134e42
--- /dev/null
+++ b/lib/animators/transitions/CrossfadeTransitionState.ts
@@ -0,0 +1,43 @@
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+import SkeletonBinaryLERPNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonBinaryLERPNode");
+import SkeletonBinaryLERPState = require("awayjs-renderergl/lib/animators/states/SkeletonBinaryLERPState");
+import CrossfadeTransitionNode = require("awayjs-renderergl/lib/animators/transitions/CrossfadeTransitionNode");
+import AnimationStateEvent = require("awayjs-renderergl/lib/events/AnimationStateEvent");
+
+/**
+ *
+ */
+class CrossfadeTransitionState extends SkeletonBinaryLERPState
+{
+ private _crossfadeTransitionNode:CrossfadeTransitionNode;
+ private _animationStateTransitionComplete:AnimationStateEvent;
+
+ constructor(animator:AnimatorBase, skeletonAnimationNode:CrossfadeTransitionNode)
+ {
+ super(animator, skeletonAnimationNode);
+
+ this._crossfadeTransitionNode = skeletonAnimationNode;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pUpdateTime(time:number /*int*/)
+ {
+ this.blendWeight = Math.abs(time - this._crossfadeTransitionNode.startBlend)/(1000*this._crossfadeTransitionNode.blendSpeed);
+
+ if (this.blendWeight >= 1) {
+ this.blendWeight = 1;
+
+ if (this._animationStateTransitionComplete == null)
+ this._animationStateTransitionComplete = new AnimationStateEvent(AnimationStateEvent.TRANSITION_COMPLETE, this._pAnimator, this, this._crossfadeTransitionNode);
+
+ this._crossfadeTransitionNode.dispatchEvent(this._animationStateTransitionComplete);
+ }
+
+ super._pUpdateTime(time);
+ }
+}
+
+export = CrossfadeTransitionState;
\ No newline at end of file
diff --git a/lib/animators/transitions/IAnimationTransition.js b/lib/animators/transitions/IAnimationTransition.js
new file mode 100755
index 000000000..9eb8adebf
--- /dev/null
+++ b/lib/animators/transitions/IAnimationTransition.js
@@ -0,0 +1,3 @@
+
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy90cmFuc2l0aW9ucy9pYW5pbWF0aW9udHJhbnNpdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFZOEIiLCJmaWxlIjoiYW5pbWF0b3JzL3RyYW5zaXRpb25zL0lBbmltYXRpb25UcmFuc2l0aW9uLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbk5vZGVCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbk5vZGVCYXNlXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbi8qKlxuICpcbiAqL1xuaW50ZXJmYWNlIElBbmltYXRpb25UcmFuc2l0aW9uXG57XG5cdGdldEFuaW1hdGlvbk5vZGUoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBzdGFydE5vZGU6QW5pbWF0aW9uTm9kZUJhc2UsIGVuZE5vZGU6QW5pbWF0aW9uTm9kZUJhc2UsIHN0YXJ0VGltZTpudW1iZXIgLyppbnQqLyk6QW5pbWF0aW9uTm9kZUJhc2Vcbn1cblxuZXhwb3J0ID0gSUFuaW1hdGlvblRyYW5zaXRpb247Il19
\ No newline at end of file
diff --git a/lib/animators/transitions/IAnimationTransition.ts b/lib/animators/transitions/IAnimationTransition.ts
new file mode 100644
index 000000000..da5e44e3d
--- /dev/null
+++ b/lib/animators/transitions/IAnimationTransition.ts
@@ -0,0 +1,13 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+
+/**
+ *
+ */
+interface IAnimationTransition
+{
+ getAnimationNode(animator:AnimatorBase, startNode:AnimationNodeBase, endNode:AnimationNodeBase, startTime:number /*int*/):AnimationNodeBase
+}
+
+export = IAnimationTransition;
\ No newline at end of file
diff --git a/lib/core/base/ParticleGeometry.js b/lib/core/base/ParticleGeometry.js
new file mode 100755
index 000000000..0c2438190
--- /dev/null
+++ b/lib/core/base/ParticleGeometry.js
@@ -0,0 +1,20 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Geometry = require("awayjs-core/lib/core/base/Geometry");
+/**
+ * @class away.base.ParticleGeometry
+ */
+var ParticleGeometry = (function (_super) {
+ __extends(ParticleGeometry, _super);
+ function ParticleGeometry() {
+ _super.apply(this, arguments);
+ }
+ return ParticleGeometry;
+})(Geometry);
+module.exports = ParticleGeometry;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvcmUvYmFzZS9wYXJ0aWNsZWdlb21ldHJ5LnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlR2VvbWV0cnkiLCJQYXJ0aWNsZUdlb21ldHJ5LmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUl0RSxBQUdBOztHQURHO0lBQ0csZ0JBQWdCO0lBQVNBLFVBQXpCQSxnQkFBZ0JBLFVBQWlCQTtJQUF2Q0EsU0FBTUEsZ0JBQWdCQTtRQUFTQyw4QkFBUUE7SUFNdkNBLENBQUNBO0lBQURELHVCQUFDQTtBQUFEQSxDQU5BLEFBTUNBLEVBTjhCLFFBQVEsRUFNdEM7QUFFRCxBQUEwQixpQkFBakIsZ0JBQWdCLENBQUMiLCJmaWxlIjoiY29yZS9iYXNlL1BhcnRpY2xlR2VvbWV0cnkuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgR2VvbWV0cnlcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvR2VvbWV0cnlcIik7XG5cbmltcG9ydCBQYXJ0aWNsZURhdGFcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVEYXRhXCIpO1xuXG4vKipcbiAqIEBjbGFzcyBhd2F5LmJhc2UuUGFydGljbGVHZW9tZXRyeVxuICovXG5jbGFzcyBQYXJ0aWNsZUdlb21ldHJ5IGV4dGVuZHMgR2VvbWV0cnlcbntcblx0cHVibGljIHBhcnRpY2xlczpBcnJheTxQYXJ0aWNsZURhdGE+O1xuXG5cdHB1YmxpYyBudW1QYXJ0aWNsZXM6bnVtYmVyIC8qdWludCovO1xuXG59XG5cbmV4cG9ydCA9IFBhcnRpY2xlR2VvbWV0cnk7Il19
\ No newline at end of file
diff --git a/lib/core/base/ParticleGeometry.ts b/lib/core/base/ParticleGeometry.ts
new file mode 100644
index 000000000..ef3fe100b
--- /dev/null
+++ b/lib/core/base/ParticleGeometry.ts
@@ -0,0 +1,16 @@
+import Geometry = require("awayjs-core/lib/core/base/Geometry");
+
+import ParticleData = require("awayjs-renderergl/lib/animators/data/ParticleData");
+
+/**
+ * @class away.base.ParticleGeometry
+ */
+class ParticleGeometry extends Geometry
+{
+ public particles:Array;
+
+ public numParticles:number /*uint*/;
+
+}
+
+export = ParticleGeometry;
\ No newline at end of file
diff --git a/lib/core/pick/JSPickingCollider.js b/lib/core/pick/JSPickingCollider.js
new file mode 100755
index 000000000..cfce29082
--- /dev/null
+++ b/lib/core/pick/JSPickingCollider.js
@@ -0,0 +1,137 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var PickingColliderBase = require("awayjs-renderergl/lib/core/pick/PickingColliderBase");
+/**
+ * Pure JS picking collider for display objects. Used with the RaycastPicker
picking object.
+ *
+ * @see away.base.DisplayObject#pickingCollider
+ * @see away.pick.RaycastPicker
+ *
+ * @class away.pick.JSPickingCollider
+ */
+var JSPickingCollider = (function (_super) {
+ __extends(JSPickingCollider, _super);
+ /**
+ * Creates a new JSPickingCollider
object.
+ *
+ * @param findClosestCollision Determines whether the picking collider searches for the closest collision along the ray. Defaults to false.
+ */
+ function JSPickingCollider(findClosestCollision) {
+ if (findClosestCollision === void 0) { findClosestCollision = false; }
+ _super.call(this);
+ this._findClosestCollision = findClosestCollision;
+ }
+ /**
+ * @inheritDoc
+ */
+ JSPickingCollider.prototype._pTestRenderableCollision = function (renderable, pickingCollisionVO, shortestCollisionDistance) {
+ var t;
+ var i0, i1, i2;
+ var rx, ry, rz;
+ var nx, ny, nz;
+ var cx, cy, cz;
+ var coeff, u, v, w;
+ var p0x, p0y, p0z;
+ var p1x, p1y, p1z;
+ var p2x, p2y, p2z;
+ var s0x, s0y, s0z;
+ var s1x, s1y, s1z;
+ var nl, nDotV, D, disToPlane;
+ var Q1Q2, Q1Q1, Q2Q2, RQ1, RQ2;
+ var indexData = renderable.getIndexData().data;
+ var collisionTriangleIndex = -1;
+ var bothSides = renderable.materialOwner.material.bothSides;
+ var positionData = renderable.getVertexData(TriangleSubGeometry.POSITION_DATA).data;
+ var positionStride = renderable.getVertexData(TriangleSubGeometry.POSITION_DATA).dataPerVertex;
+ var positionOffset = renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA);
+ var uvData = renderable.getVertexData(TriangleSubGeometry.UV_DATA).data;
+ var uvStride = renderable.getVertexData(TriangleSubGeometry.UV_DATA).dataPerVertex;
+ var uvOffset = renderable.getVertexOffset(TriangleSubGeometry.UV_DATA);
+ var numIndices = indexData.length;
+ for (var index = 0; index < numIndices; index += 3) {
+ // evaluate triangle indices
+ i0 = positionOffset + indexData[index] * positionStride;
+ i1 = positionOffset + indexData[(index + 1)] * positionStride;
+ i2 = positionOffset + indexData[(index + 2)] * positionStride;
+ // evaluate triangle positions
+ p0x = positionData[i0];
+ p0y = positionData[(i0 + 1)];
+ p0z = positionData[(i0 + 2)];
+ p1x = positionData[i1];
+ p1y = positionData[(i1 + 1)];
+ p1z = positionData[(i1 + 2)];
+ p2x = positionData[i2];
+ p2y = positionData[(i2 + 1)];
+ p2z = positionData[(i2 + 2)];
+ // evaluate sides and triangle normal
+ s0x = p1x - p0x; // s0 = p1 - p0
+ s0y = p1y - p0y;
+ s0z = p1z - p0z;
+ s1x = p2x - p0x; // s1 = p2 - p0
+ s1y = p2y - p0y;
+ s1z = p2z - p0z;
+ nx = s0y * s1z - s0z * s1y; // n = s0 x s1
+ ny = s0z * s1x - s0x * s1z;
+ nz = s0x * s1y - s0y * s1x;
+ nl = 1 / Math.sqrt(nx * nx + ny * ny + nz * nz); // normalize n
+ nx *= nl;
+ ny *= nl;
+ nz *= nl;
+ // -- plane intersection test --
+ nDotV = nx * this.rayDirection.x + ny * +this.rayDirection.y + nz * this.rayDirection.z; // rayDirection . normal
+ if ((!bothSides && nDotV < 0.0) || (bothSides && nDotV != 0.0)) {
+ // find collision t
+ D = -(nx * p0x + ny * p0y + nz * p0z);
+ disToPlane = -(nx * this.rayPosition.x + ny * this.rayPosition.y + nz * this.rayPosition.z + D);
+ t = disToPlane / nDotV;
+ // find collision point
+ cx = this.rayPosition.x + t * this.rayDirection.x;
+ cy = this.rayPosition.y + t * this.rayDirection.y;
+ cz = this.rayPosition.z + t * this.rayDirection.z;
+ // collision point inside triangle? ( using barycentric coordinates )
+ Q1Q2 = s0x * s1x + s0y * s1y + s0z * s1z;
+ Q1Q1 = s0x * s0x + s0y * s0y + s0z * s0z;
+ Q2Q2 = s1x * s1x + s1y * s1y + s1z * s1z;
+ rx = cx - p0x;
+ ry = cy - p0y;
+ rz = cz - p0z;
+ RQ1 = rx * s0x + ry * s0y + rz * s0z;
+ RQ2 = rx * s1x + ry * s1y + rz * s1z;
+ coeff = 1 / (Q1Q1 * Q2Q2 - Q1Q2 * Q1Q2);
+ v = coeff * (Q2Q2 * RQ1 - Q1Q2 * RQ2);
+ w = coeff * (-Q1Q2 * RQ1 + Q1Q1 * RQ2);
+ if (v < 0)
+ continue;
+ if (w < 0)
+ continue;
+ u = 1 - v - w;
+ if (!(u < 0) && t > 0 && t < shortestCollisionDistance) {
+ shortestCollisionDistance = t;
+ collisionTriangleIndex = index / 3;
+ pickingCollisionVO.rayEntryDistance = t;
+ pickingCollisionVO.localPosition = new Vector3D(cx, cy, cz);
+ pickingCollisionVO.localNormal = new Vector3D(nx, ny, nz);
+ pickingCollisionVO.uv = this._pGetCollisionUV(indexData, uvData, index, v, w, u, uvOffset, uvStride);
+ pickingCollisionVO.index = index;
+ // pickingCollisionVO.subGeometryIndex = this.pGetMeshSubMeshIndex(renderable);
+ // if not looking for best hit, first found will do...
+ if (!this._findClosestCollision)
+ return true;
+ }
+ }
+ }
+ if (collisionTriangleIndex >= 0)
+ return true;
+ return false;
+ };
+ return JSPickingCollider;
+})(PickingColliderBase);
+module.exports = JSPickingCollider;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvcmUvcGljay9qc3BpY2tpbmdjb2xsaWRlci50cyJdLCJuYW1lcyI6WyJKU1BpY2tpbmdDb2xsaWRlciIsIkpTUGlja2luZ0NvbGxpZGVyLmNvbnN0cnVjdG9yIiwiSlNQaWNraW5nQ29sbGlkZXIuX3BUZXN0UmVuZGVyYWJsZUNvbGxpc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxtQkFBbUIsV0FBYywrQ0FBK0MsQ0FBQyxDQUFDO0FBQ3pGLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBT3RFLElBQU8sbUJBQW1CLFdBQWMscURBQXFELENBQUMsQ0FBQztBQUUvRixBQVFBOzs7Ozs7O0dBREc7SUFDRyxpQkFBaUI7SUFBU0EsVUFBMUJBLGlCQUFpQkEsVUFBNEJBO0lBSWxEQTs7OztPQUlHQTtJQUNIQSxTQVRLQSxpQkFBaUJBLENBU1ZBLG9CQUFvQ0E7UUFBcENDLG9DQUFvQ0EsR0FBcENBLDRCQUFvQ0E7UUFFL0NBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxxQkFBcUJBLEdBQUdBLG9CQUFvQkEsQ0FBQ0E7SUFDbkRBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSxxREFBeUJBLEdBQWhDQSxVQUFpQ0EsVUFBeUJBLEVBQUVBLGtCQUFxQ0EsRUFBRUEseUJBQWdDQTtRQUVsSUUsSUFBSUEsQ0FBUUEsQ0FBQ0E7UUFDYkEsSUFBSUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsQ0FBQ0E7UUFDcENBLElBQUlBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLENBQUNBO1FBQ3BDQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxDQUFDQTtRQUNwQ0EsSUFBSUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsQ0FBQ0E7UUFDcENBLElBQUlBLEtBQVlBLEVBQUVBLENBQVFBLEVBQUVBLENBQVFBLEVBQUVBLENBQVFBLENBQUNBO1FBQy9DQSxJQUFJQSxHQUFVQSxFQUFFQSxHQUFVQSxFQUFFQSxHQUFVQSxDQUFDQTtRQUN2Q0EsSUFBSUEsR0FBVUEsRUFBRUEsR0FBVUEsRUFBRUEsR0FBVUEsQ0FBQ0E7UUFDdkNBLElBQUlBLEdBQVVBLEVBQUVBLEdBQVVBLEVBQUVBLEdBQVVBLENBQUNBO1FBQ3ZDQSxJQUFJQSxHQUFVQSxFQUFFQSxHQUFVQSxFQUFFQSxHQUFVQSxDQUFDQTtRQUN2Q0EsSUFBSUEsR0FBVUEsRUFBRUEsR0FBVUEsRUFBRUEsR0FBVUEsQ0FBQ0E7UUFDdkNBLElBQUlBLEVBQVNBLEVBQUVBLEtBQVlBLEVBQUVBLENBQVFBLEVBQUVBLFVBQWlCQSxDQUFDQTtRQUN6REEsSUFBSUEsSUFBV0EsRUFBRUEsSUFBV0EsRUFBRUEsSUFBV0EsRUFBRUEsR0FBVUEsRUFBRUEsR0FBVUEsQ0FBQ0E7UUFDbEVBLElBQUlBLFNBQVNBLEdBQWlCQSxVQUFVQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQTtRQUM3REEsSUFBSUEsc0JBQXNCQSxHQUFVQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN2Q0EsSUFBSUEsU0FBU0EsR0FBMkJBLFVBQVVBLENBQUNBLGFBQWFBLENBQUNBLFFBQVNBLENBQUNBLFNBQVNBLENBQUNBO1FBRXJGQSxJQUFJQSxZQUFZQSxHQUFpQkEsVUFBVUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQTtRQUNsR0EsSUFBSUEsY0FBY0EsR0FBVUEsVUFBVUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUN0R0EsSUFBSUEsY0FBY0EsR0FBVUEsVUFBVUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQTtRQUMxRkEsSUFBSUEsTUFBTUEsR0FBaUJBLFVBQVVBLENBQUNBLGFBQWFBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0E7UUFDdEZBLElBQUlBLFFBQVFBLEdBQVVBLFVBQVVBLENBQUNBLGFBQWFBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsYUFBYUEsQ0FBQ0E7UUFDMUZBLElBQUlBLFFBQVFBLEdBQVVBLFVBQVVBLENBQUNBLGVBQWVBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0E7UUFDOUVBLElBQUlBLFVBQVVBLEdBQVVBLFNBQVNBLENBQUNBLE1BQU1BLENBQUNBO1FBRXpDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxLQUFLQSxHQUFVQSxDQUFDQSxFQUFFQSxLQUFLQSxHQUFHQSxVQUFVQSxFQUFFQSxLQUFLQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUMzREEsQUFDQUEsNEJBRDRCQTtZQUM1QkEsRUFBRUEsR0FBR0EsY0FBY0EsR0FBR0EsU0FBU0EsQ0FBRUEsS0FBS0EsQ0FBRUEsR0FBQ0EsY0FBY0EsQ0FBQ0E7WUFDeERBLEVBQUVBLEdBQUdBLGNBQWNBLEdBQUdBLFNBQVNBLENBQUVBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLENBQUVBLEdBQUNBLGNBQWNBLENBQUNBO1lBQzlEQSxFQUFFQSxHQUFHQSxjQUFjQSxHQUFHQSxTQUFTQSxDQUFFQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFFQSxHQUFDQSxjQUFjQSxDQUFDQTtZQUU5REEsQUFDQUEsOEJBRDhCQTtZQUM5QkEsR0FBR0EsR0FBR0EsWUFBWUEsQ0FBRUEsRUFBRUEsQ0FBRUEsQ0FBQ0E7WUFDekJBLEdBQUdBLEdBQUdBLFlBQVlBLENBQUVBLENBQUNBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUVBLENBQUNBO1lBQy9CQSxHQUFHQSxHQUFHQSxZQUFZQSxDQUFFQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFFQSxDQUFDQTtZQUMvQkEsR0FBR0EsR0FBR0EsWUFBWUEsQ0FBRUEsRUFBRUEsQ0FBRUEsQ0FBQ0E7WUFDekJBLEdBQUdBLEdBQUdBLFlBQVlBLENBQUVBLENBQUNBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUVBLENBQUNBO1lBQy9CQSxHQUFHQSxHQUFHQSxZQUFZQSxDQUFFQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFFQSxDQUFDQTtZQUMvQkEsR0FBR0EsR0FBR0EsWUFBWUEsQ0FBRUEsRUFBRUEsQ0FBRUEsQ0FBQ0E7WUFDekJBLEdBQUdBLEdBQUdBLFlBQVlBLENBQUVBLENBQUNBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBLENBQUVBLENBQUNBO1lBQy9CQSxHQUFHQSxHQUFHQSxZQUFZQSxDQUFFQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFFQSxDQUFDQTtZQUUvQkEsQUFDQUEscUNBRHFDQTtZQUNyQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsRUFBRUEsZUFBZUE7WUFDaENBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBO1lBQ2hCQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQTtZQUNoQkEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsRUFBRUEsZUFBZUE7WUFDaENBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBO1lBQ2hCQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQTtZQUNoQkEsRUFBRUEsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsRUFBRUEsY0FBY0E7WUFDdENBLEVBQUVBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO1lBQ3ZCQSxFQUFFQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtZQUN2QkEsRUFBRUEsR0FBR0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsY0FBY0E7WUFDdkRBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBQ1RBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBQ1RBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBO1lBRVRBLEFBQ0FBLGdDQURnQ0E7WUFDaENBLEtBQUtBLEdBQUdBLEVBQUVBLEdBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUVBLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLEVBQUVBLHdCQUF3QkE7WUFDNUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUVBLENBQUNBLFNBQVNBLElBQUlBLEtBQUtBLEdBQUdBLEdBQUdBLENBQUVBLElBQUlBLENBQUVBLFNBQVNBLElBQUlBLEtBQUtBLElBQUlBLEdBQUdBLENBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNwRUEsQUFDQUEsbUJBRG1CQTtnQkFDbkJBLENBQUNBLEdBQUdBLENBQUNBLENBQUVBLEVBQUVBLEdBQUNBLEdBQUdBLEdBQUdBLEVBQUVBLEdBQUNBLEdBQUdBLEdBQUdBLEVBQUVBLEdBQUNBLEdBQUdBLENBQUVBLENBQUNBO2dCQUNsQ0EsVUFBVUEsR0FBR0EsQ0FBQ0EsQ0FBRUEsRUFBRUEsR0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBRUEsQ0FBQ0E7Z0JBQzVGQSxDQUFDQSxHQUFHQSxVQUFVQSxHQUFDQSxLQUFLQSxDQUFDQTtnQkFDckJBLEFBQ0FBLHVCQUR1QkE7Z0JBQ3ZCQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDaERBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBO2dCQUNoREEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2hEQSxBQUNBQSxxRUFEcUVBO2dCQUNyRUEsSUFBSUEsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQ25DQSxJQUFJQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDbkNBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUNuQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0E7Z0JBQ2RBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBO2dCQUNkQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQTtnQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsR0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQy9CQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDL0JBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUNBLENBQUVBLElBQUlBLEdBQUNBLElBQUlBLEdBQUdBLElBQUlBLEdBQUNBLElBQUlBLENBQUVBLENBQUNBO2dCQUNwQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBQ0EsQ0FBRUEsSUFBSUEsR0FBQ0EsR0FBR0EsR0FBR0EsSUFBSUEsR0FBQ0EsR0FBR0EsQ0FBRUEsQ0FBQ0E7Z0JBQ2xDQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFDQSxDQUFFQSxDQUFDQSxJQUFJQSxHQUFDQSxHQUFHQSxHQUFHQSxJQUFJQSxHQUFDQSxHQUFHQSxDQUFFQSxDQUFDQTtnQkFDbkNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO29CQUNUQSxRQUFRQSxDQUFDQTtnQkFDVkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ1RBLFFBQVFBLENBQUNBO2dCQUNWQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDZEEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBRUEsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsR0FBR0EseUJBQXlCQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMURBLHlCQUF5QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQzlCQSxzQkFBc0JBLEdBQUdBLEtBQUtBLEdBQUNBLENBQUNBLENBQUNBO29CQUNqQ0Esa0JBQWtCQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLENBQUNBLENBQUNBO29CQUN4Q0Esa0JBQWtCQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQTtvQkFDNURBLGtCQUFrQkEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsRUFBRUEsRUFBRUEsRUFBRUEsRUFBRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0E7b0JBQzFEQSxrQkFBa0JBLENBQUNBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsU0FBU0EsRUFBRUEsTUFBTUEsRUFBRUEsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsUUFBUUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7b0JBQ3JHQSxrQkFBa0JBLENBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLENBQUNBO29CQUN0Q0EsQUFHS0Esb0ZBSCtFQTtvQkFFL0VBLHNEQUFzREE7b0JBQ3REQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxxQkFBcUJBLENBQUNBO3dCQUMvQkEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7Z0JBQ2RBLENBQUNBO1lBQ0ZBLENBQUNBO1FBQ0ZBLENBQUNBO1FBR0RBLEVBQUVBLENBQUNBLENBQUNBLHNCQUFzQkEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO1FBRWJBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBO0lBQ2RBLENBQUNBO0lBQ0ZGLHdCQUFDQTtBQUFEQSxDQWpJQSxBQWlJQ0EsRUFqSStCLG1CQUFtQixFQWlJbEQ7QUFFRCxBQUEyQixpQkFBbEIsaUJBQWlCLENBQUMiLCJmaWxlIjoiY29yZS9waWNrL0pTUGlja2luZ0NvbGxpZGVyLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBQaWNraW5nQ29sbGlzaW9uVk9cdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL3BpY2svUGlja2luZ0NvbGxpc2lvblZPXCIpO1xuaW1wb3J0IElQaWNraW5nQ29sbGlkZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvcGljay9JUGlja2luZ0NvbGxpZGVyXCIpO1xuaW1wb3J0IE1hdGVyaWFsQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9tYXRlcmlhbHMvTWF0ZXJpYWxCYXNlXCIpO1xuXG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcblxuaW1wb3J0IFBpY2tpbmdDb2xsaWRlckJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9jb3JlL3BpY2svUGlja2luZ0NvbGxpZGVyQmFzZVwiKTtcblxuLyoqXG4gKiBQdXJlIEpTIHBpY2tpbmcgY29sbGlkZXIgZm9yIGRpc3BsYXkgb2JqZWN0cy4gVXNlZCB3aXRoIHRoZSA8Y29kZT5SYXljYXN0UGlja2VyPC9jb2RlPiBwaWNraW5nIG9iamVjdC5cbiAqXG4gKiBAc2VlIGF3YXkuYmFzZS5EaXNwbGF5T2JqZWN0I3BpY2tpbmdDb2xsaWRlclxuICogQHNlZSBhd2F5LnBpY2suUmF5Y2FzdFBpY2tlclxuICpcbiAqIEBjbGFzcyBhd2F5LnBpY2suSlNQaWNraW5nQ29sbGlkZXJcbiAqL1xuY2xhc3MgSlNQaWNraW5nQ29sbGlkZXIgZXh0ZW5kcyBQaWNraW5nQ29sbGlkZXJCYXNlIGltcGxlbWVudHMgSVBpY2tpbmdDb2xsaWRlclxue1xuXHRwcml2YXRlIF9maW5kQ2xvc2VzdENvbGxpc2lvbjpib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPkpTUGlja2luZ0NvbGxpZGVyPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBmaW5kQ2xvc2VzdENvbGxpc2lvbiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHBpY2tpbmcgY29sbGlkZXIgc2VhcmNoZXMgZm9yIHRoZSBjbG9zZXN0IGNvbGxpc2lvbiBhbG9uZyB0aGUgcmF5LiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGZpbmRDbG9zZXN0Q29sbGlzaW9uOmJvb2xlYW4gPSBmYWxzZSlcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLl9maW5kQ2xvc2VzdENvbGxpc2lvbiA9IGZpbmRDbG9zZXN0Q29sbGlzaW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX3BUZXN0UmVuZGVyYWJsZUNvbGxpc2lvbihyZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBwaWNraW5nQ29sbGlzaW9uVk86UGlja2luZ0NvbGxpc2lvblZPLCBzaG9ydGVzdENvbGxpc2lvbkRpc3RhbmNlOm51bWJlcik6Ym9vbGVhblxuXHR7XG5cdFx0dmFyIHQ6bnVtYmVyO1xuXHRcdHZhciBpMDpudW1iZXIsIGkxOm51bWJlciwgaTI6bnVtYmVyO1xuXHRcdHZhciByeDpudW1iZXIsIHJ5Om51bWJlciwgcno6bnVtYmVyO1xuXHRcdHZhciBueDpudW1iZXIsIG55Om51bWJlciwgbno6bnVtYmVyO1xuXHRcdHZhciBjeDpudW1iZXIsIGN5Om51bWJlciwgY3o6bnVtYmVyO1xuXHRcdHZhciBjb2VmZjpudW1iZXIsIHU6bnVtYmVyLCB2Om51bWJlciwgdzpudW1iZXI7XG5cdFx0dmFyIHAweDpudW1iZXIsIHAweTpudW1iZXIsIHAwejpudW1iZXI7XG5cdFx0dmFyIHAxeDpudW1iZXIsIHAxeTpudW1iZXIsIHAxejpudW1iZXI7XG5cdFx0dmFyIHAyeDpudW1iZXIsIHAyeTpudW1iZXIsIHAyejpudW1iZXI7XG5cdFx0dmFyIHMweDpudW1iZXIsIHMweTpudW1iZXIsIHMwejpudW1iZXI7XG5cdFx0dmFyIHMxeDpudW1iZXIsIHMxeTpudW1iZXIsIHMxejpudW1iZXI7XG5cdFx0dmFyIG5sOm51bWJlciwgbkRvdFY6bnVtYmVyLCBEOm51bWJlciwgZGlzVG9QbGFuZTpudW1iZXI7XG5cdFx0dmFyIFExUTI6bnVtYmVyLCBRMVExOm51bWJlciwgUTJRMjpudW1iZXIsIFJRMTpudW1iZXIsIFJRMjpudW1iZXI7XG5cdFx0dmFyIGluZGV4RGF0YTpBcnJheTxudW1iZXI+ID0gcmVuZGVyYWJsZS5nZXRJbmRleERhdGEoKS5kYXRhO1xuXHRcdHZhciBjb2xsaXNpb25UcmlhbmdsZUluZGV4Om51bWJlciA9IC0xO1xuXHRcdHZhciBib3RoU2lkZXM6Ym9vbGVhbiA9ICg8TWF0ZXJpYWxCYXNlPiByZW5kZXJhYmxlLm1hdGVyaWFsT3duZXIubWF0ZXJpYWwpLmJvdGhTaWRlcztcblxuXHRcdHZhciBwb3NpdGlvbkRhdGE6QXJyYXk8bnVtYmVyPiA9IHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLmRhdGE7XG5cdFx0dmFyIHBvc2l0aW9uU3RyaWRlOm51bWJlciA9IHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLmRhdGFQZXJWZXJ0ZXg7XG5cdFx0dmFyIHBvc2l0aW9uT2Zmc2V0Om51bWJlciA9IHJlbmRlcmFibGUuZ2V0VmVydGV4T2Zmc2V0KFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fREFUQSk7XG5cdFx0dmFyIHV2RGF0YTpBcnJheTxudW1iZXI+ID0gcmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuVVZfREFUQSkuZGF0YTtcblx0XHR2YXIgdXZTdHJpZGU6bnVtYmVyID0gcmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuVVZfREFUQSkuZGF0YVBlclZlcnRleDtcblx0XHR2YXIgdXZPZmZzZXQ6bnVtYmVyID0gcmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5VVl9EQVRBKTtcblx0XHR2YXIgbnVtSW5kaWNlczpudW1iZXIgPSBpbmRleERhdGEubGVuZ3RoO1xuXG5cdFx0Zm9yICh2YXIgaW5kZXg6bnVtYmVyID0gMDsgaW5kZXggPCBudW1JbmRpY2VzOyBpbmRleCArPSAzKSB7IC8vIHN3ZWVwIGFsbCB0cmlhbmdsZXNcblx0XHRcdC8vIGV2YWx1YXRlIHRyaWFuZ2xlIGluZGljZXNcblx0XHRcdGkwID0gcG9zaXRpb25PZmZzZXQgKyBpbmRleERhdGFbIGluZGV4IF0qcG9zaXRpb25TdHJpZGU7XG5cdFx0XHRpMSA9IHBvc2l0aW9uT2Zmc2V0ICsgaW5kZXhEYXRhWyAoaW5kZXggKyAxKSBdKnBvc2l0aW9uU3RyaWRlO1xuXHRcdFx0aTIgPSBwb3NpdGlvbk9mZnNldCArIGluZGV4RGF0YVsgKGluZGV4ICsgMikgXSpwb3NpdGlvblN0cmlkZTtcblxuXHRcdFx0Ly8gZXZhbHVhdGUgdHJpYW5nbGUgcG9zaXRpb25zXG5cdFx0XHRwMHggPSBwb3NpdGlvbkRhdGFbIGkwIF07XG5cdFx0XHRwMHkgPSBwb3NpdGlvbkRhdGFbIChpMCArIDEpIF07XG5cdFx0XHRwMHogPSBwb3NpdGlvbkRhdGFbIChpMCArIDIpIF07XG5cdFx0XHRwMXggPSBwb3NpdGlvbkRhdGFbIGkxIF07XG5cdFx0XHRwMXkgPSBwb3NpdGlvbkRhdGFbIChpMSArIDEpIF07XG5cdFx0XHRwMXogPSBwb3NpdGlvbkRhdGFbIChpMSArIDIpIF07XG5cdFx0XHRwMnggPSBwb3NpdGlvbkRhdGFbIGkyIF07XG5cdFx0XHRwMnkgPSBwb3NpdGlvbkRhdGFbIChpMiArIDEpIF07XG5cdFx0XHRwMnogPSBwb3NpdGlvbkRhdGFbIChpMiArIDIpIF07XG5cblx0XHRcdC8vIGV2YWx1YXRlIHNpZGVzIGFuZCB0cmlhbmdsZSBub3JtYWxcblx0XHRcdHMweCA9IHAxeCAtIHAweDsgLy8gczAgPSBwMSAtIHAwXG5cdFx0XHRzMHkgPSBwMXkgLSBwMHk7XG5cdFx0XHRzMHogPSBwMXogLSBwMHo7XG5cdFx0XHRzMXggPSBwMnggLSBwMHg7IC8vIHMxID0gcDIgLSBwMFxuXHRcdFx0czF5ID0gcDJ5IC0gcDB5O1xuXHRcdFx0czF6ID0gcDJ6IC0gcDB6O1xuXHRcdFx0bnggPSBzMHkqczF6IC0gczB6KnMxeTsgLy8gbiA9IHMwIHggczFcblx0XHRcdG55ID0gczB6KnMxeCAtIHMweCpzMXo7XG5cdFx0XHRueiA9IHMweCpzMXkgLSBzMHkqczF4O1xuXHRcdFx0bmwgPSAxL01hdGguc3FydChueCpueCArIG55Km55ICsgbnoqbnopOyAvLyBub3JtYWxpemUgblxuXHRcdFx0bnggKj0gbmw7XG5cdFx0XHRueSAqPSBubDtcblx0XHRcdG56ICo9IG5sO1xuXG5cdFx0XHQvLyAtLSBwbGFuZSBpbnRlcnNlY3Rpb24gdGVzdCAtLVxuXHRcdFx0bkRvdFYgPSBueCp0aGlzLnJheURpcmVjdGlvbi54ICsgbnkqICt0aGlzLnJheURpcmVjdGlvbi55ICsgbnoqdGhpcy5yYXlEaXJlY3Rpb24uejsgLy8gcmF5RGlyZWN0aW9uIC4gbm9ybWFsXG5cdFx0XHRpZiAoKCAhYm90aFNpZGVzICYmIG5Eb3RWIDwgMC4wICkgfHwgKCBib3RoU2lkZXMgJiYgbkRvdFYgIT0gMC4wICkpIHsgLy8gYW4gaW50ZXJzZWN0aW9uIG11c3QgZXhpc3Rcblx0XHRcdFx0Ly8gZmluZCBjb2xsaXNpb24gdFxuXHRcdFx0XHREID0gLSggbngqcDB4ICsgbnkqcDB5ICsgbnoqcDB6ICk7XG5cdFx0XHRcdGRpc1RvUGxhbmUgPSAtKCBueCp0aGlzLnJheVBvc2l0aW9uLnggKyBueSp0aGlzLnJheVBvc2l0aW9uLnkgKyBueip0aGlzLnJheVBvc2l0aW9uLnogKyBEICk7XG5cdFx0XHRcdHQgPSBkaXNUb1BsYW5lL25Eb3RWO1xuXHRcdFx0XHQvLyBmaW5kIGNvbGxpc2lvbiBwb2ludFxuXHRcdFx0XHRjeCA9IHRoaXMucmF5UG9zaXRpb24ueCArIHQqdGhpcy5yYXlEaXJlY3Rpb24ueDtcblx0XHRcdFx0Y3kgPSB0aGlzLnJheVBvc2l0aW9uLnkgKyB0KnRoaXMucmF5RGlyZWN0aW9uLnk7XG5cdFx0XHRcdGN6ID0gdGhpcy5yYXlQb3NpdGlvbi56ICsgdCp0aGlzLnJheURpcmVjdGlvbi56O1xuXHRcdFx0XHQvLyBjb2xsaXNpb24gcG9pbnQgaW5zaWRlIHRyaWFuZ2xlPyAoIHVzaW5nIGJhcnljZW50cmljIGNvb3JkaW5hdGVzIClcblx0XHRcdFx0UTFRMiA9IHMweCpzMXggKyBzMHkqczF5ICsgczB6KnMxejtcblx0XHRcdFx0UTFRMSA9IHMweCpzMHggKyBzMHkqczB5ICsgczB6KnMwejtcblx0XHRcdFx0UTJRMiA9IHMxeCpzMXggKyBzMXkqczF5ICsgczF6KnMxejtcblx0XHRcdFx0cnggPSBjeCAtIHAweDtcblx0XHRcdFx0cnkgPSBjeSAtIHAweTtcblx0XHRcdFx0cnogPSBjeiAtIHAwejtcblx0XHRcdFx0UlExID0gcngqczB4ICsgcnkqczB5ICsgcnoqczB6O1xuXHRcdFx0XHRSUTIgPSByeCpzMXggKyByeSpzMXkgKyByeipzMXo7XG5cdFx0XHRcdGNvZWZmID0gMS8oIFExUTEqUTJRMiAtIFExUTIqUTFRMiApO1xuXHRcdFx0XHR2ID0gY29lZmYqKCBRMlEyKlJRMSAtIFExUTIqUlEyICk7XG5cdFx0XHRcdHcgPSBjb2VmZiooIC1RMVEyKlJRMSArIFExUTEqUlEyICk7XG5cdFx0XHRcdGlmICh2IDwgMClcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0aWYgKHcgPCAwKVxuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR1ID0gMSAtIHYgLSB3O1xuXHRcdFx0XHRpZiAoISggdSA8IDAgKSAmJiB0ID4gMCAmJiB0IDwgc2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZSkgeyAvLyBhbGwgdGVzdHMgcGFzc2VkXG5cdFx0XHRcdFx0c2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZSA9IHQ7XG5cdFx0XHRcdFx0Y29sbGlzaW9uVHJpYW5nbGVJbmRleCA9IGluZGV4LzM7XG5cdFx0XHRcdFx0cGlja2luZ0NvbGxpc2lvblZPLnJheUVudHJ5RGlzdGFuY2UgPSB0O1xuXHRcdFx0XHRcdHBpY2tpbmdDb2xsaXNpb25WTy5sb2NhbFBvc2l0aW9uID0gbmV3IFZlY3RvcjNEKGN4LCBjeSwgY3opO1xuXHRcdFx0XHRcdHBpY2tpbmdDb2xsaXNpb25WTy5sb2NhbE5vcm1hbCA9IG5ldyBWZWN0b3IzRChueCwgbnksIG56KTtcblx0XHRcdFx0XHRwaWNraW5nQ29sbGlzaW9uVk8udXYgPSB0aGlzLl9wR2V0Q29sbGlzaW9uVVYoaW5kZXhEYXRhLCB1dkRhdGEsIGluZGV4LCB2LCB3LCB1LCB1dk9mZnNldCwgdXZTdHJpZGUpO1xuXHRcdFx0XHRcdHBpY2tpbmdDb2xsaXNpb25WTy5pbmRleCA9IGluZGV4O1xuLy9cdFx0XHRcdFx0XHRwaWNraW5nQ29sbGlzaW9uVk8uc3ViR2VvbWV0cnlJbmRleCA9IHRoaXMucEdldE1lc2hTdWJNZXNoSW5kZXgocmVuZGVyYWJsZSk7XG5cblx0XHRcdFx0XHQvLyBpZiBub3QgbG9va2luZyBmb3IgYmVzdCBoaXQsIGZpcnN0IGZvdW5kIHdpbGwgZG8uLi5cblx0XHRcdFx0XHRpZiAoIXRoaXMuX2ZpbmRDbG9zZXN0Q29sbGlzaW9uKVxuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblxuXHRcdGlmIChjb2xsaXNpb25UcmlhbmdsZUluZGV4ID49IDApXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5leHBvcnQgPSBKU1BpY2tpbmdDb2xsaWRlcjsiXX0=
\ No newline at end of file
diff --git a/lib/core/pick/JSPickingCollider.ts b/lib/core/pick/JSPickingCollider.ts
new file mode 100644
index 000000000..533fb78d2
--- /dev/null
+++ b/lib/core/pick/JSPickingCollider.ts
@@ -0,0 +1,150 @@
+import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import PickingCollisionVO = require("awayjs-core/lib/core/pick/PickingCollisionVO");
+import IPickingCollider = require("awayjs-core/lib/core/pick/IPickingCollider");
+import MaterialBase = require("awayjs-core/lib/materials/MaterialBase");
+
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+
+import PickingColliderBase = require("awayjs-renderergl/lib/core/pick/PickingColliderBase");
+
+/**
+ * Pure JS picking collider for display objects. Used with the RaycastPicker
picking object.
+ *
+ * @see away.base.DisplayObject#pickingCollider
+ * @see away.pick.RaycastPicker
+ *
+ * @class away.pick.JSPickingCollider
+ */
+class JSPickingCollider extends PickingColliderBase implements IPickingCollider
+{
+ private _findClosestCollision:boolean;
+
+ /**
+ * Creates a new JSPickingCollider
object.
+ *
+ * @param findClosestCollision Determines whether the picking collider searches for the closest collision along the ray. Defaults to false.
+ */
+ constructor(findClosestCollision:boolean = false)
+ {
+ super();
+
+ this._findClosestCollision = findClosestCollision;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pTestRenderableCollision(renderable:RenderableBase, pickingCollisionVO:PickingCollisionVO, shortestCollisionDistance:number):boolean
+ {
+ var t:number;
+ var i0:number, i1:number, i2:number;
+ var rx:number, ry:number, rz:number;
+ var nx:number, ny:number, nz:number;
+ var cx:number, cy:number, cz:number;
+ var coeff:number, u:number, v:number, w:number;
+ var p0x:number, p0y:number, p0z:number;
+ var p1x:number, p1y:number, p1z:number;
+ var p2x:number, p2y:number, p2z:number;
+ var s0x:number, s0y:number, s0z:number;
+ var s1x:number, s1y:number, s1z:number;
+ var nl:number, nDotV:number, D:number, disToPlane:number;
+ var Q1Q2:number, Q1Q1:number, Q2Q2:number, RQ1:number, RQ2:number;
+ var indexData:Array = renderable.getIndexData().data;
+ var collisionTriangleIndex:number = -1;
+ var bothSides:boolean = ( renderable.materialOwner.material).bothSides;
+
+ var positionData:Array = renderable.getVertexData(TriangleSubGeometry.POSITION_DATA).data;
+ var positionStride:number = renderable.getVertexData(TriangleSubGeometry.POSITION_DATA).dataPerVertex;
+ var positionOffset:number = renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA);
+ var uvData:Array = renderable.getVertexData(TriangleSubGeometry.UV_DATA).data;
+ var uvStride:number = renderable.getVertexData(TriangleSubGeometry.UV_DATA).dataPerVertex;
+ var uvOffset:number = renderable.getVertexOffset(TriangleSubGeometry.UV_DATA);
+ var numIndices:number = indexData.length;
+
+ for (var index:number = 0; index < numIndices; index += 3) { // sweep all triangles
+ // evaluate triangle indices
+ i0 = positionOffset + indexData[ index ]*positionStride;
+ i1 = positionOffset + indexData[ (index + 1) ]*positionStride;
+ i2 = positionOffset + indexData[ (index + 2) ]*positionStride;
+
+ // evaluate triangle positions
+ p0x = positionData[ i0 ];
+ p0y = positionData[ (i0 + 1) ];
+ p0z = positionData[ (i0 + 2) ];
+ p1x = positionData[ i1 ];
+ p1y = positionData[ (i1 + 1) ];
+ p1z = positionData[ (i1 + 2) ];
+ p2x = positionData[ i2 ];
+ p2y = positionData[ (i2 + 1) ];
+ p2z = positionData[ (i2 + 2) ];
+
+ // evaluate sides and triangle normal
+ s0x = p1x - p0x; // s0 = p1 - p0
+ s0y = p1y - p0y;
+ s0z = p1z - p0z;
+ s1x = p2x - p0x; // s1 = p2 - p0
+ s1y = p2y - p0y;
+ s1z = p2z - p0z;
+ nx = s0y*s1z - s0z*s1y; // n = s0 x s1
+ ny = s0z*s1x - s0x*s1z;
+ nz = s0x*s1y - s0y*s1x;
+ nl = 1/Math.sqrt(nx*nx + ny*ny + nz*nz); // normalize n
+ nx *= nl;
+ ny *= nl;
+ nz *= nl;
+
+ // -- plane intersection test --
+ nDotV = nx*this.rayDirection.x + ny* +this.rayDirection.y + nz*this.rayDirection.z; // rayDirection . normal
+ if (( !bothSides && nDotV < 0.0 ) || ( bothSides && nDotV != 0.0 )) { // an intersection must exist
+ // find collision t
+ D = -( nx*p0x + ny*p0y + nz*p0z );
+ disToPlane = -( nx*this.rayPosition.x + ny*this.rayPosition.y + nz*this.rayPosition.z + D );
+ t = disToPlane/nDotV;
+ // find collision point
+ cx = this.rayPosition.x + t*this.rayDirection.x;
+ cy = this.rayPosition.y + t*this.rayDirection.y;
+ cz = this.rayPosition.z + t*this.rayDirection.z;
+ // collision point inside triangle? ( using barycentric coordinates )
+ Q1Q2 = s0x*s1x + s0y*s1y + s0z*s1z;
+ Q1Q1 = s0x*s0x + s0y*s0y + s0z*s0z;
+ Q2Q2 = s1x*s1x + s1y*s1y + s1z*s1z;
+ rx = cx - p0x;
+ ry = cy - p0y;
+ rz = cz - p0z;
+ RQ1 = rx*s0x + ry*s0y + rz*s0z;
+ RQ2 = rx*s1x + ry*s1y + rz*s1z;
+ coeff = 1/( Q1Q1*Q2Q2 - Q1Q2*Q1Q2 );
+ v = coeff*( Q2Q2*RQ1 - Q1Q2*RQ2 );
+ w = coeff*( -Q1Q2*RQ1 + Q1Q1*RQ2 );
+ if (v < 0)
+ continue;
+ if (w < 0)
+ continue;
+ u = 1 - v - w;
+ if (!( u < 0 ) && t > 0 && t < shortestCollisionDistance) { // all tests passed
+ shortestCollisionDistance = t;
+ collisionTriangleIndex = index/3;
+ pickingCollisionVO.rayEntryDistance = t;
+ pickingCollisionVO.localPosition = new Vector3D(cx, cy, cz);
+ pickingCollisionVO.localNormal = new Vector3D(nx, ny, nz);
+ pickingCollisionVO.uv = this._pGetCollisionUV(indexData, uvData, index, v, w, u, uvOffset, uvStride);
+ pickingCollisionVO.index = index;
+// pickingCollisionVO.subGeometryIndex = this.pGetMeshSubMeshIndex(renderable);
+
+ // if not looking for best hit, first found will do...
+ if (!this._findClosestCollision)
+ return true;
+ }
+ }
+ }
+
+
+ if (collisionTriangleIndex >= 0)
+ return true;
+
+ return false;
+ }
+}
+
+export = JSPickingCollider;
\ No newline at end of file
diff --git a/lib/core/pick/PickingColliderBase.js b/lib/core/pick/PickingColliderBase.js
new file mode 100755
index 000000000..352dd9f8a
--- /dev/null
+++ b/lib/core/pick/PickingColliderBase.js
@@ -0,0 +1,102 @@
+var RenderablePool = require("awayjs-core/lib/core/pool/RenderablePool");
+var Point = require("awayjs-core/lib/core/geom/Point");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var AbstractMethodError = require("awayjs-core/lib/errors/AbstractMethodError");
+var BillboardRenderable = require("awayjs-stagegl/lib/core/pool/BillboardRenderable");
+var TriangleSubMeshRenderable = require("awayjs-stagegl/lib/core/pool/TriangleSubMeshRenderable");
+/**
+ * An abstract base class for all picking collider classes. It should not be instantiated directly.
+ *
+ * @class away.pick.PickingColliderBase
+ */
+var PickingColliderBase = (function () {
+ function PickingColliderBase() {
+ this._billboardRenderablePool = RenderablePool.getPool(BillboardRenderable);
+ this._subMeshRenderablePool = RenderablePool.getPool(TriangleSubMeshRenderable);
+ }
+ PickingColliderBase.prototype._pPetCollisionNormal = function (indexData /*uint*/, vertexData, triangleIndex) {
+ var normal = new Vector3D();
+ var i0 = indexData[triangleIndex] * 3;
+ var i1 = indexData[triangleIndex + 1] * 3;
+ var i2 = indexData[triangleIndex + 2] * 3;
+ var p0 = new Vector3D(vertexData[i0], vertexData[i0 + 1], vertexData[i0 + 2]);
+ var p1 = new Vector3D(vertexData[i1], vertexData[i1 + 1], vertexData[i1 + 2]);
+ var p2 = new Vector3D(vertexData[i2], vertexData[i2 + 1], vertexData[i2 + 2]);
+ var side0 = p1.subtract(p0);
+ var side1 = p2.subtract(p0);
+ normal = side0.crossProduct(side1);
+ normal.normalize();
+ return normal;
+ };
+ PickingColliderBase.prototype._pGetCollisionUV = function (indexData /*uint*/, uvData, triangleIndex, v, w, u, uvOffset, uvStride) {
+ var uv = new Point();
+ var uIndex = indexData[triangleIndex] * uvStride + uvOffset;
+ var uv0 = new Vector3D(uvData[uIndex], uvData[uIndex + 1]);
+ uIndex = indexData[triangleIndex + 1] * uvStride + uvOffset;
+ var uv1 = new Vector3D(uvData[uIndex], uvData[uIndex + 1]);
+ uIndex = indexData[triangleIndex + 2] * uvStride + uvOffset;
+ var uv2 = new Vector3D(uvData[uIndex], uvData[uIndex + 1]);
+ uv.x = u * uv0.x + v * uv1.x + w * uv2.x;
+ uv.y = u * uv0.y + v * uv1.y + w * uv2.y;
+ return uv;
+ };
+ /**
+ * @inheritDoc
+ */
+ PickingColliderBase.prototype._pTestRenderableCollision = function (renderable, pickingCollisionVO, shortestCollisionDistance) {
+ throw new AbstractMethodError();
+ };
+ /**
+ * @inheritDoc
+ */
+ PickingColliderBase.prototype.setLocalRay = function (localPosition, localDirection) {
+ this.rayPosition = localPosition;
+ this.rayDirection = localDirection;
+ };
+ /**
+ * Tests a Billboard
object for a collision with the picking ray.
+ *
+ * @param billboard The billboard instance to be tested.
+ * @param pickingCollisionVO The collision object used to store the collision results
+ * @param shortestCollisionDistance The current value of the shortest distance to a detected collision along the ray.
+ * @param findClosest
+ */
+ PickingColliderBase.prototype.testBillboardCollision = function (billboard, pickingCollisionVO, shortestCollisionDistance) {
+ this.setLocalRay(pickingCollisionVO.localRayPosition, pickingCollisionVO.localRayDirection);
+ pickingCollisionVO.materialOwner = null;
+ if (this._pTestRenderableCollision(this._billboardRenderablePool.getItem(billboard), pickingCollisionVO, shortestCollisionDistance)) {
+ shortestCollisionDistance = pickingCollisionVO.rayEntryDistance;
+ pickingCollisionVO.materialOwner = billboard;
+ return true;
+ }
+ return false;
+ };
+ /**
+ * Tests a Mesh
object for a collision with the picking ray.
+ *
+ * @param mesh The mesh instance to be tested.
+ * @param pickingCollisionVO The collision object used to store the collision results
+ * @param shortestCollisionDistance The current value of the shortest distance to a detected collision along the ray.
+ * @param findClosest
+ */
+ PickingColliderBase.prototype.testMeshCollision = function (mesh, pickingCollisionVO, shortestCollisionDistance, findClosest) {
+ this.setLocalRay(pickingCollisionVO.localRayPosition, pickingCollisionVO.localRayDirection);
+ pickingCollisionVO.materialOwner = null;
+ var subMesh;
+ var len = mesh.subMeshes.length;
+ for (var i = 0; i < len; ++i) {
+ subMesh = mesh.subMeshes[i];
+ if (this._pTestRenderableCollision(this._subMeshRenderablePool.getItem(subMesh), pickingCollisionVO, shortestCollisionDistance)) {
+ shortestCollisionDistance = pickingCollisionVO.rayEntryDistance;
+ pickingCollisionVO.materialOwner = subMesh;
+ if (!findClosest)
+ return true;
+ }
+ }
+ return pickingCollisionVO.materialOwner != null;
+ };
+ return PickingColliderBase;
+})();
+module.exports = PickingColliderBase;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvcmUvcGljay9waWNraW5nY29sbGlkZXJiYXNlLnRzIl0sIm5hbWVzIjpbIlBpY2tpbmdDb2xsaWRlckJhc2UiLCJQaWNraW5nQ29sbGlkZXJCYXNlLmNvbnN0cnVjdG9yIiwiUGlja2luZ0NvbGxpZGVyQmFzZS5fcFBldENvbGxpc2lvbk5vcm1hbCIsIlBpY2tpbmdDb2xsaWRlckJhc2UuX3BHZXRDb2xsaXNpb25VViIsIlBpY2tpbmdDb2xsaWRlckJhc2UuX3BUZXN0UmVuZGVyYWJsZUNvbGxpc2lvbiIsIlBpY2tpbmdDb2xsaWRlckJhc2Uuc2V0TG9jYWxSYXkiLCJQaWNraW5nQ29sbGlkZXJCYXNlLnRlc3RCaWxsYm9hcmRDb2xsaXNpb24iLCJQaWNraW5nQ29sbGlkZXJCYXNlLnRlc3RNZXNoQ29sbGlzaW9uIl0sIm1hcHBpbmdzIjoiQUFFQSxJQUFPLGNBQWMsV0FBZSwwQ0FBMEMsQ0FBQyxDQUFDO0FBQ2hGLElBQU8sS0FBSyxXQUFpQixpQ0FBaUMsQ0FBQyxDQUFDO0FBQ2hFLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBR3RFLElBQU8sbUJBQW1CLFdBQWMsNENBQTRDLENBQUMsQ0FBQztBQUV0RixJQUFPLG1CQUFtQixXQUFjLGtEQUFrRCxDQUFDLENBQUM7QUFFNUYsSUFBTyx5QkFBeUIsV0FBWSx3REFBd0QsQ0FBQyxDQUFDO0FBRXRHLEFBS0E7Ozs7R0FERztJQUNHLG1CQUFtQjtJQVF4QkEsU0FSS0EsbUJBQW1CQTtRQVV2QkMsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxHQUFHQSxjQUFjQSxDQUFDQSxPQUFPQSxDQUFDQSxtQkFBbUJBLENBQUNBLENBQUNBO1FBQzVFQSxJQUFJQSxDQUFDQSxzQkFBc0JBLEdBQUdBLGNBQWNBLENBQUNBLE9BQU9BLENBQUNBLHlCQUF5QkEsQ0FBQ0EsQ0FBQ0E7SUFDakZBLENBQUNBO0lBRU1ELGtEQUFvQkEsR0FBM0JBLFVBQTRCQSxTQUFTQSxDQUFlQSxRQUFEQSxBQUFTQSxFQUFFQSxVQUF3QkEsRUFBRUEsYUFBb0JBO1FBRTNHRSxJQUFJQSxNQUFNQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtRQUNyQ0EsSUFBSUEsRUFBRUEsR0FBVUEsU0FBU0EsQ0FBRUEsYUFBYUEsQ0FBRUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0NBLElBQUlBLEVBQUVBLEdBQVVBLFNBQVNBLENBQUVBLGFBQWFBLEdBQUdBLENBQUNBLENBQUVBLEdBQUNBLENBQUNBLENBQUNBO1FBQ2pEQSxJQUFJQSxFQUFFQSxHQUFVQSxTQUFTQSxDQUFFQSxhQUFhQSxHQUFHQSxDQUFDQSxDQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNqREEsSUFBSUEsRUFBRUEsR0FBWUEsSUFBSUEsUUFBUUEsQ0FBQ0EsVUFBVUEsQ0FBRUEsRUFBRUEsQ0FBRUEsRUFBRUEsVUFBVUEsQ0FBRUEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBRUEsRUFBRUEsVUFBVUEsQ0FBRUEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBRUEsQ0FBQ0EsQ0FBQ0E7UUFDN0ZBLElBQUlBLEVBQUVBLEdBQVlBLElBQUlBLFFBQVFBLENBQUNBLFVBQVVBLENBQUVBLEVBQUVBLENBQUVBLEVBQUVBLFVBQVVBLENBQUVBLEVBQUVBLEdBQUdBLENBQUNBLENBQUVBLEVBQUVBLFVBQVVBLENBQUVBLEVBQUVBLEdBQUdBLENBQUNBLENBQUVBLENBQUNBLENBQUNBO1FBQzdGQSxJQUFJQSxFQUFFQSxHQUFZQSxJQUFJQSxRQUFRQSxDQUFDQSxVQUFVQSxDQUFFQSxFQUFFQSxDQUFFQSxFQUFFQSxVQUFVQSxDQUFFQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFFQSxFQUFFQSxVQUFVQSxDQUFFQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFFQSxDQUFDQSxDQUFDQTtRQUM3RkEsSUFBSUEsS0FBS0EsR0FBWUEsRUFBRUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDckNBLElBQUlBLEtBQUtBLEdBQVlBLEVBQUVBLENBQUNBLFFBQVFBLENBQUNBLEVB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Q0FBQ0EsRUFBRUEsa0JBQWtCQSxFQUFFQSx5QkFBeUJBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNsSkEseUJBQXlCQSxHQUFHQSxrQkFBa0JBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7Z0JBRWhFQSxrQkFBa0JBLENBQUNBLGFBQWFBLEdBQUdBLE9BQU9BLENBQUNBO2dCQUUzQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsV0FBV0EsQ0FBQ0E7b0JBQ2hCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtZQUNkQSxDQUFDQTtRQUNGQSxDQUFDQTtRQUVEQSxNQUFNQSxDQUFDQSxrQkFBa0JBLENBQUNBLGFBQWFBLElBQUlBLElBQUlBLENBQUNBO0lBQ2pEQSxDQUFDQTtJQUNGUCwwQkFBQ0E7QUFBREEsQ0FwSEEsQUFvSENBLElBQUE7QUFFRCxBQUE2QixpQkFBcEIsbUJBQW1CLENBQUMiLCJmaWxlIjoiY29yZS9waWNrL1BpY2tpbmdDb2xsaWRlckJhc2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSVN1Yk1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvSVN1Yk1lc2hcIik7XG5pbXBvcnQgUGlja2luZ0NvbGxpc2lvblZPXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9waWNrL1BpY2tpbmdDb2xsaXNpb25WT1wiKTtcbmltcG9ydCBSZW5kZXJhYmxlUG9vbFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9wb29sL1JlbmRlcmFibGVQb29sXCIpO1xuaW1wb3J0IFBvaW50XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1BvaW50XCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IEJpbGxib2FyZFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9CaWxsYm9hcmRcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvTWVzaFwiKTtcbmltcG9ydCBBYnN0cmFjdE1ldGhvZEVycm9yXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZXJyb3JzL0Fic3RyYWN0TWV0aG9kRXJyb3JcIik7XG5cbmltcG9ydCBCaWxsYm9hcmRSZW5kZXJhYmxlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL0JpbGxib2FyZFJlbmRlcmFibGVcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvVHJpYW5nbGVTdWJNZXNoUmVuZGVyYWJsZVwiKTtcblxuLyoqXG4gKiBBbiBhYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgcGlja2luZyBjb2xsaWRlciBjbGFzc2VzLiBJdCBzaG91bGQgbm90IGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseS5cbiAqXG4gKiBAY2xhc3MgYXdheS5waWNrLlBpY2tpbmdDb2xsaWRlckJhc2VcbiAqL1xuY2xhc3MgUGlja2luZ0NvbGxpZGVyQmFzZVxue1xuXHRwcml2YXRlIF9iaWxsYm9hcmRSZW5kZXJhYmxlUG9vbDpSZW5kZXJhYmxlUG9vbDtcblx0cHJpdmF0ZSBfc3ViTWVzaFJlbmRlcmFibGVQb29sOlJlbmRlcmFibGVQb29sO1xuXG5cdHB1YmxpYyByYXlQb3NpdGlvbjpWZWN0b3IzRDtcblx0cHVibGljIHJheURpcmVjdGlvbjpWZWN0b3IzRDtcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHR0aGlzLl9iaWxsYm9hcmRSZW5kZXJhYmxlUG9vbCA9IFJlbmRlcmFibGVQb29sLmdldFBvb2woQmlsbGJvYXJkUmVuZGVyYWJsZSk7XG5cdFx0dGhpcy5fc3ViTWVzaFJlbmRlcmFibGVQb29sID0gUmVuZGVyYWJsZVBvb2wuZ2V0UG9vbChUcmlhbmdsZVN1Yk1lc2hSZW5kZXJhYmxlKTtcblx0fVxuXG5cdHB1YmxpYyBfcFBldENvbGxpc2lvbk5vcm1hbChpbmRleERhdGE6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLywgdmVydGV4RGF0YTpBcnJheTxudW1iZXI+LCB0cmlhbmdsZUluZGV4Om51bWJlcik6VmVjdG9yM0QgLy8gUFJPVEVDVEVEXG5cdHtcblx0XHR2YXIgbm9ybWFsOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEKCk7XG5cdFx0dmFyIGkwOm51bWJlciA9IGluZGV4RGF0YVsgdHJpYW5nbGVJbmRleCBdKjM7XG5cdFx0dmFyIGkxOm51bWJlciA9IGluZGV4RGF0YVsgdHJpYW5nbGVJbmRleCArIDEgXSozO1xuXHRcdHZhciBpMjpudW1iZXIgPSBpbmRleERhdGFbIHRyaWFuZ2xlSW5kZXggKyAyIF0qMztcblx0XHR2YXIgcDA6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QodmVydGV4RGF0YVsgaTAgXSwgdmVydGV4RGF0YVsgaTAgKyAxIF0sIHZlcnRleERhdGFbIGkwICsgMiBdKTtcblx0XHR2YXIgcDE6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QodmVydGV4RGF0YVsgaTEgXSwgdmVydGV4RGF0YVsgaTEgKyAxIF0sIHZlcnRleERhdGFbIGkxICsgMiBdKTtcblx0XHR2YXIgcDI6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QodmVydGV4RGF0YVsgaTIgXSwgdmVydGV4RGF0YVsgaTIgKyAxIF0sIHZlcnRleERhdGFbIGkyICsgMiBdKTtcblx0XHR2YXIgc2lkZTA6VmVjdG9yM0QgPSBwMS5zdWJ0cmFjdChwMCk7XG5cdFx0dmFyIHNpZGUxOlZlY3RvcjNEID0gcDIuc3VidHJhY3QocDApO1xuXHRcdG5vcm1hbCA9IHNpZGUwLmNyb3NzUHJvZHVjdChzaWRlMSk7XG5cdFx0bm9ybWFsLm5vcm1hbGl6ZSgpO1xuXHRcdHJldHVybiBub3JtYWw7XG5cdH1cblxuXHRwdWJsaWMgX3BHZXRDb2xsaXNpb25VVihpbmRleERhdGE6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLywgdXZEYXRhOkFycmF5PG51bWJlcj4sIHRyaWFuZ2xlSW5kZXg6bnVtYmVyLCB2Om51bWJlciwgdzpudW1iZXIsIHU6bnVtYmVyLCB1dk9mZnNldDpudW1iZXIsIHV2U3RyaWRlOm51bWJlcik6UG9pbnQgLy8gUFJPVEVDVEVEXG5cdHtcblx0XHR2YXIgdXY6UG9pbnQgPSBuZXcgUG9pbnQoKTtcblx0XHR2YXIgdUluZGV4Om51bWJlciA9IGluZGV4RGF0YVsgdHJpYW5nbGVJbmRleCBdKnV2U3RyaWRlICsgdXZPZmZzZXQ7XG5cdFx0dmFyIHV2MDpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCh1dkRhdGFbIHVJbmRleCBdLCB1dkRhdGFbIHVJbmRleCArIDEgXSk7XG5cdFx0dUluZGV4ID0gaW5kZXhEYXRhWyB0cmlhbmdsZUluZGV4ICsgMSBdKnV2U3RyaWRlICsgdXZPZmZzZXQ7XG5cdFx0dmFyIHV2MTpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCh1dkRhdGFbIHVJbmRleCBdLCB1dkRhdGFbIHVJbmRleCArIDEgXSk7XG5cdFx0dUluZGV4ID0gaW5kZXhEYXRhWyB0cmlhbmdsZUluZGV4ICsgMiBdKnV2U3RyaWRlICsgdXZPZmZzZXQ7XG5cdFx0dmFyIHV2MjpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCh1dkRhdGFbIHVJbmRleCBdLCB1dkRhdGFbIHVJbmRleCArIDEgXSk7XG5cdFx0dXYueCA9IHUqdXYwLnggKyB2KnV2MS54ICsgdyp1djIueDtcblx0XHR1di55ID0gdSp1djAueSArIHYqdXYxLnkgKyB3KnV2Mi55O1xuXHRcdHJldHVybiB1djtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wVGVzdFJlbmRlcmFibGVDb2xsaXNpb24ocmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgcGlja2luZ0NvbGxpc2lvblZPOlBpY2tpbmdDb2xsaXNpb25WTywgc2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZTpudW1iZXIpOmJvb2xlYW5cblx0e1xuXHRcdHRocm93IG5ldyBBYnN0cmFjdE1ldGhvZEVycm9yKCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBzZXRMb2NhbFJheShsb2NhbFBvc2l0aW9uOlZlY3RvcjNELCBsb2NhbERpcmVjdGlvbjpWZWN0b3IzRClcblx0e1xuXHRcdHRoaXMucmF5UG9zaXRpb24gPSBsb2NhbFBvc2l0aW9uO1xuXHRcdHRoaXMucmF5RGlyZWN0aW9uID0gbG9jYWxEaXJlY3Rpb247XG5cdH1cblxuXHQvKipcblx0ICogVGVzdHMgYSA8Y29kZT5CaWxsYm9hcmQ8L2NvZGU+IG9iamVjdCBmb3IgYSBjb2xsaXNpb24gd2l0aCB0aGUgcGlja2luZyByYXkuXG5cdCAqXG5cdCAqIEBwYXJhbSBiaWxsYm9hcmQgVGhlIGJpbGxib2FyZCBpbnN0YW5jZSB0byBiZSB0ZXN0ZWQuXG5cdCAqIEBwYXJhbSBwaWNraW5nQ29sbGlzaW9uVk8gVGhlIGNvbGxpc2lvbiBvYmplY3QgdXNlZCB0byBzdG9yZSB0aGUgY29sbGlzaW9uIHJlc3VsdHNcblx0ICogQHBhcmFtIHNob3J0ZXN0Q29sbGlzaW9uRGlzdGFuY2UgVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNob3J0ZXN0IGRpc3RhbmNlIHRvIGEgZGV0ZWN0ZWQgY29sbGlzaW9uIGFsb25nIHRoZSByYXkuXG5cdCAqIEBwYXJhbSBmaW5kQ2xvc2VzdFxuXHQgKi9cblx0cHVibGljIHRlc3RCaWxsYm9hcmRDb2xsaXNpb24oYmlsbGJvYXJkOkJpbGxib2FyZCwgcGlja2luZ0NvbGxpc2lvblZPOlBpY2tpbmdDb2xsaXNpb25WTywgc2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLnNldExvY2FsUmF5KHBpY2tpbmdDb2xsaXNpb25WTy5sb2NhbFJheVBvc2l0aW9uLCBwaWNraW5nQ29sbGlzaW9uVk8ubG9jYWxSYXlEaXJlY3Rpb24pO1xuXHRcdHBpY2tpbmdDb2xsaXNpb25WTy5tYXRlcmlhbE93bmVyID0gbnVsbDtcblxuXHRcdGlmICh0aGlzLl9wVGVzdFJlbmRlcmFibGVDb2xsaXNpb24oPFJlbmRlcmFibGVCYXNlPiB0aGlzLl9iaWxsYm9hcmRSZW5kZXJhYmxlUG9vbC5nZXRJdGVtKGJpbGxib2FyZCksIHBpY2tpbmdDb2xsaXNpb25WTywgc2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZSkpIHtcblx0XHRcdHNob3J0ZXN0Q29sbGlzaW9uRGlzdGFuY2UgPSBwaWNraW5nQ29sbGlzaW9uVk8ucmF5RW50cnlEaXN0YW5jZTtcblxuXHRcdFx0cGlja2luZ0NvbGxpc2lvblZPLm1hdGVyaWFsT3duZXIgPSBiaWxsYm9hcmQ7XG5cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZXN0cyBhIDxjb2RlPk1lc2g8L2NvZGU+IG9iamVjdCBmb3IgYSBjb2xsaXNpb24gd2l0aCB0aGUgcGlja2luZyByYXkuXG5cdCAqXG5cdCAqIEBwYXJhbSBtZXNoIFRoZSBtZXNoIGluc3RhbmNlIHRvIGJlIHRlc3RlZC5cblx0ICogQHBhcmFtIHBpY2tpbmdDb2xsaXNpb25WTyBUaGUgY29sbGlzaW9uIG9iamVjdCB1c2VkIHRvIHN0b3JlIHRoZSBjb2xsaXNpb24gcmVzdWx0c1xuXHQgKiBAcGFyYW0gc2hvcnRlc3RDb2xsaXNpb25EaXN0YW5jZSBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc2hvcnRlc3QgZGlzdGFuY2UgdG8gYSBkZXRlY3RlZCBjb2xsaXNpb24gYWxvbmcgdGhlIHJheS5cblx0ICogQHBhcmFtIGZpbmRDbG9zZXN0XG5cdCAqL1xuXHRwdWJsaWMgdGVzdE1lc2hDb2xsaXNpb24obWVzaDpNZXNoLCBwaWNraW5nQ29sbGlzaW9uVk86UGlja2luZ0NvbGxpc2lvblZPLCBzaG9ydGVzdENvbGxpc2lvbkRpc3RhbmNlOm51bWJlciwgZmluZENsb3Nlc3Q6Ym9vbGVhbik6Ym9vbGVhblxuXHR7XG5cdFx0dGhpcy5zZXRMb2NhbFJheShwaWNraW5nQ29sbGlzaW9uVk8ubG9jYWxSYXlQb3NpdGlvbiwgcGlja2luZ0NvbGxpc2lvblZPLmxvY2FsUmF5RGlyZWN0aW9uKTtcblx0XHRwaWNraW5nQ29sbGlzaW9uVk8ubWF0ZXJpYWxPd25lciA9IG51bGw7XG5cblx0XHR2YXIgc3ViTWVzaDpJU3ViTWVzaDtcblxuXHRcdHZhciBsZW46bnVtYmVyID0gbWVzaC5zdWJNZXNoZXMubGVuZ3RoO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cdFx0XHRzdWJNZXNoID0gbWVzaC5zdWJNZXNoZXNbaV07XG5cblx0XHRcdGlmICh0aGlzLl9wVGVzdFJlbmRlcmFibGVDb2xsaXNpb24oPFJlbmRlcmFibGVCYXNlPiB0aGlzLl9zdWJNZXNoUmVuZGVyYWJsZVBvb2wuZ2V0SXRlbShzdWJNZXNoKSwgcGlja2luZ0NvbGxpc2lvblZPLCBzaG9ydGVzdENvbGxpc2lvbkRpc3RhbmNlKSkge1xuXHRcdFx0XHRzaG9ydGVzdENvbGxpc2lvbkRpc3RhbmNlID0gcGlja2luZ0NvbGxpc2lvblZPLnJheUVudHJ5RGlzdGFuY2U7XG5cblx0XHRcdFx0cGlja2luZ0NvbGxpc2lvblZPLm1hdGVyaWFsT3duZXIgPSBzdWJNZXNoO1xuXG5cdFx0XHRcdGlmICghZmluZENsb3Nlc3QpXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBpY2tpbmdDb2xsaXNpb25WTy5tYXRlcmlhbE93bmVyICE9IG51bGw7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGlja2luZ0NvbGxpZGVyQmFzZTsiXX0=
\ No newline at end of file
diff --git a/lib/core/pick/PickingColliderBase.ts b/lib/core/pick/PickingColliderBase.ts
new file mode 100644
index 000000000..448cc19f5
--- /dev/null
+++ b/lib/core/pick/PickingColliderBase.ts
@@ -0,0 +1,137 @@
+import ISubMesh = require("awayjs-core/lib/core/base/ISubMesh");
+import PickingCollisionVO = require("awayjs-core/lib/core/pick/PickingCollisionVO");
+import RenderablePool = require("awayjs-core/lib/core/pool/RenderablePool");
+import Point = require("awayjs-core/lib/core/geom/Point");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import Billboard = require("awayjs-core/lib/entities/Billboard");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import AbstractMethodError = require("awayjs-core/lib/errors/AbstractMethodError");
+
+import BillboardRenderable = require("awayjs-stagegl/lib/core/pool/BillboardRenderable");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import TriangleSubMeshRenderable = require("awayjs-stagegl/lib/core/pool/TriangleSubMeshRenderable");
+
+/**
+ * An abstract base class for all picking collider classes. It should not be instantiated directly.
+ *
+ * @class away.pick.PickingColliderBase
+ */
+class PickingColliderBase
+{
+ private _billboardRenderablePool:RenderablePool;
+ private _subMeshRenderablePool:RenderablePool;
+
+ public rayPosition:Vector3D;
+ public rayDirection:Vector3D;
+
+ constructor()
+ {
+ this._billboardRenderablePool = RenderablePool.getPool(BillboardRenderable);
+ this._subMeshRenderablePool = RenderablePool.getPool(TriangleSubMeshRenderable);
+ }
+
+ public _pPetCollisionNormal(indexData:Array /*uint*/, vertexData:Array, triangleIndex:number):Vector3D // PROTECTED
+ {
+ var normal:Vector3D = new Vector3D();
+ var i0:number = indexData[ triangleIndex ]*3;
+ var i1:number = indexData[ triangleIndex + 1 ]*3;
+ var i2:number = indexData[ triangleIndex + 2 ]*3;
+ var p0:Vector3D = new Vector3D(vertexData[ i0 ], vertexData[ i0 + 1 ], vertexData[ i0 + 2 ]);
+ var p1:Vector3D = new Vector3D(vertexData[ i1 ], vertexData[ i1 + 1 ], vertexData[ i1 + 2 ]);
+ var p2:Vector3D = new Vector3D(vertexData[ i2 ], vertexData[ i2 + 1 ], vertexData[ i2 + 2 ]);
+ var side0:Vector3D = p1.subtract(p0);
+ var side1:Vector3D = p2.subtract(p0);
+ normal = side0.crossProduct(side1);
+ normal.normalize();
+ return normal;
+ }
+
+ public _pGetCollisionUV(indexData:Array /*uint*/, uvData:Array, triangleIndex:number, v:number, w:number, u:number, uvOffset:number, uvStride:number):Point // PROTECTED
+ {
+ var uv:Point = new Point();
+ var uIndex:number = indexData[ triangleIndex ]*uvStride + uvOffset;
+ var uv0:Vector3D = new Vector3D(uvData[ uIndex ], uvData[ uIndex + 1 ]);
+ uIndex = indexData[ triangleIndex + 1 ]*uvStride + uvOffset;
+ var uv1:Vector3D = new Vector3D(uvData[ uIndex ], uvData[ uIndex + 1 ]);
+ uIndex = indexData[ triangleIndex + 2 ]*uvStride + uvOffset;
+ var uv2:Vector3D = new Vector3D(uvData[ uIndex ], uvData[ uIndex + 1 ]);
+ uv.x = u*uv0.x + v*uv1.x + w*uv2.x;
+ uv.y = u*uv0.y + v*uv1.y + w*uv2.y;
+ return uv;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public _pTestRenderableCollision(renderable:RenderableBase, pickingCollisionVO:PickingCollisionVO, shortestCollisionDistance:number):boolean
+ {
+ throw new AbstractMethodError();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setLocalRay(localPosition:Vector3D, localDirection:Vector3D)
+ {
+ this.rayPosition = localPosition;
+ this.rayDirection = localDirection;
+ }
+
+ /**
+ * Tests a Billboard
object for a collision with the picking ray.
+ *
+ * @param billboard The billboard instance to be tested.
+ * @param pickingCollisionVO The collision object used to store the collision results
+ * @param shortestCollisionDistance The current value of the shortest distance to a detected collision along the ray.
+ * @param findClosest
+ */
+ public testBillboardCollision(billboard:Billboard, pickingCollisionVO:PickingCollisionVO, shortestCollisionDistance:number)
+ {
+ this.setLocalRay(pickingCollisionVO.localRayPosition, pickingCollisionVO.localRayDirection);
+ pickingCollisionVO.materialOwner = null;
+
+ if (this._pTestRenderableCollision( this._billboardRenderablePool.getItem(billboard), pickingCollisionVO, shortestCollisionDistance)) {
+ shortestCollisionDistance = pickingCollisionVO.rayEntryDistance;
+
+ pickingCollisionVO.materialOwner = billboard;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Tests a Mesh
object for a collision with the picking ray.
+ *
+ * @param mesh The mesh instance to be tested.
+ * @param pickingCollisionVO The collision object used to store the collision results
+ * @param shortestCollisionDistance The current value of the shortest distance to a detected collision along the ray.
+ * @param findClosest
+ */
+ public testMeshCollision(mesh:Mesh, pickingCollisionVO:PickingCollisionVO, shortestCollisionDistance:number, findClosest:boolean):boolean
+ {
+ this.setLocalRay(pickingCollisionVO.localRayPosition, pickingCollisionVO.localRayDirection);
+ pickingCollisionVO.materialOwner = null;
+
+ var subMesh:ISubMesh;
+
+ var len:number = mesh.subMeshes.length;
+ for (var i:number = 0; i < len; ++i) {
+ subMesh = mesh.subMeshes[i];
+
+ if (this._pTestRenderableCollision( this._subMeshRenderablePool.getItem(subMesh), pickingCollisionVO, shortestCollisionDistance)) {
+ shortestCollisionDistance = pickingCollisionVO.rayEntryDistance;
+
+ pickingCollisionVO.materialOwner = subMesh;
+
+ if (!findClosest)
+ return true;
+ }
+ }
+
+ return pickingCollisionVO.materialOwner != null;
+ }
+}
+
+export = PickingColliderBase;
\ No newline at end of file
diff --git a/lib/core/pick/ShaderPicker.js b/lib/core/pick/ShaderPicker.js
new file mode 100755
index 000000000..8c2b5aae5
--- /dev/null
+++ b/lib/core/pick/ShaderPicker.js
@@ -0,0 +1,415 @@
+var Debug = require("awayjs-core/lib/utils/Debug");
+var BitmapData = require("awayjs-core/lib/core/base/BitmapData");
+var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+var Matrix3DUtils = require("awayjs-core/lib/core/geom/Matrix3DUtils");
+var Point = require("awayjs-core/lib/core/geom/Point");
+var Rectangle = require("awayjs-core/lib/core/geom/Rectangle");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var AGALMiniAssembler = require("awayjs-stagegl/lib/aglsl/assembler/AGALMiniAssembler");
+var ContextGLBlendFactor = require("awayjs-stagegl/lib/core/stagegl/ContextGLBlendFactor");
+var ContextGLClearMask = require("awayjs-stagegl/lib/core/stagegl/ContextGLClearMask");
+var ContextGLCompareMode = require("awayjs-stagegl/lib/core/stagegl/ContextGLCompareMode");
+var ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+var ContextGLTriangleFace = require("awayjs-stagegl/lib/core/stagegl/ContextGLTriangleFace");
+/**
+ * Picks a 3d object from a view or scene by performing a separate render pass on the scene around the area being picked using key color values,
+ * then reading back the color value of the pixel in the render representing the picking ray. Requires multiple passes and readbacks for retriving details
+ * on an entity that has its shaderPickingDetails property set to true.
+ *
+ * A read-back operation from any GPU is not a very efficient process, and the amount of processing used can vary significantly between different hardware.
+ *
+ * @see away.entities.Entity#shaderPickingDetails
+ *
+ * @class away.pick.ShaderPicker
+ */
+var ShaderPicker = (function () {
+ /**
+ * Creates a new ShaderPicker
object.
+ *
+ * @param shaderPickingDetails Determines whether the picker includes a second pass to calculate extra
+ * properties such as uv and normal coordinates.
+ */
+ function ShaderPicker(shaderPickingDetails) {
+ if (shaderPickingDetails === void 0) { shaderPickingDetails = false; }
+ this._onlyMouseEnabled = true;
+ this._interactives = new Array();
+ this._localHitPosition = new Vector3D();
+ this._hitUV = new Point();
+ this._localHitNormal = new Vector3D();
+ this._rayPos = new Vector3D();
+ this._rayDir = new Vector3D();
+ this._shaderPickingDetails = shaderPickingDetails;
+ this._id = new Array(4);
+ this._viewportData = new Array(4); // first 2 contain scale, last 2 translation
+ this._boundOffsetScale = new Array(8); // first 2 contain scale, last 2 translation
+ this._boundOffsetScale[3] = 0;
+ this._boundOffsetScale[7] = 1;
+ }
+ Object.defineProperty(ShaderPicker.prototype, "onlyMouseEnabled", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return this._onlyMouseEnabled;
+ },
+ set: function (value) {
+ this._onlyMouseEnabled = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ ShaderPicker.prototype.getViewCollision = function (x, y, view) {
+ var collector = view.iEntityCollector;
+ this._stage = view.renderer.stage;
+ if (!this._stage)
+ return null;
+ this._context = this._stage.context;
+ this._viewportData[0] = view.width;
+ this._viewportData[1] = view.height;
+ this._viewportData[2] = -(this._projX = 2 * x / view.width - 1);
+ this._viewportData[3] = this._projY = 2 * y / view.height - 1;
+ // _potentialFound will be set to true if any object is actually rendered
+ this._potentialFound = false;
+ //reset head values
+ this._blendedRenderableHead = null;
+ this._opaqueRenderableHead = null;
+ this.pDraw(collector, null);
+ // clear buffers
+ this._context.setVertexBufferAt(0, null);
+ if (!this._context || !this._potentialFound)
+ return null;
+ if (!this._bitmapData)
+ this._bitmapData = new BitmapData(1, 1, false, 0);
+ this._context.drawToBitmapData(this._bitmapData);
+ this._hitColor = this._bitmapData.getPixel(0, 0);
+ if (!this._hitColor) {
+ this._context.present();
+ return null;
+ }
+ this._hitRenderable = this._interactives[this._hitColor - 1];
+ this._hitEntity = this._hitRenderable.sourceEntity;
+ if (this._onlyMouseEnabled && !this._hitEntity._iIsMouseEnabled())
+ return null;
+ var _collisionVO = this._hitEntity._iPickingCollisionVO;
+ if (this._shaderPickingDetails) {
+ this.getHitDetails(view.camera);
+ _collisionVO.localPosition = this._localHitPosition;
+ _collisionVO.localNormal = this._localHitNormal;
+ _collisionVO.uv = this._hitUV;
+ _collisionVO.index = this._faceIndex;
+ }
+ else {
+ _collisionVO.localPosition = null;
+ _collisionVO.localNormal = null;
+ _collisionVO.uv = null;
+ _collisionVO.index = 0;
+ }
+ return _collisionVO;
+ };
+ //*/
+ /**
+ * @inheritDoc
+ */
+ ShaderPicker.prototype.getSceneCollision = function (position, direction, scene) {
+ return null;
+ };
+ /**
+ * @inheritDoc
+ */
+ ShaderPicker.prototype.pDraw = function (entityCollector, target) {
+ var camera = entityCollector.camera;
+ this._context.clear(0, 0, 0, 1);
+ this._stage.scissorRect = ShaderPicker.MOUSE_SCISSOR_RECT;
+ this._interactives.length = this._interactiveId = 0;
+ if (!this._objectProgram)
+ this.initObjectProgram();
+ this._context.setBlendFactors(ContextGLBlendFactor.ONE, ContextGLBlendFactor.ZERO);
+ this._context.setDepthTest(true, ContextGLCompareMode.LESS);
+ this._context.setProgram(this._objectProgram);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 4, this._viewportData, 1);
+ //this.drawRenderables(entityCollector.opaqueRenderableHead, camera);
+ //this.drawRenderables(entityCollector.blendedRenderableHead, camera);
+ //TODO: reimplement ShaderPicker inheriting from RendererBase
+ };
+ /**
+ * Draw a list of renderables.
+ * @param renderables The renderables to draw.
+ * @param camera The camera for which to render.
+ */
+ ShaderPicker.prototype.drawRenderables = function (renderable, camera) {
+ var matrix = Matrix3DUtils.CALCULATION_MATRIX;
+ var viewProjection = camera.viewProjection;
+ while (renderable) {
+ // it's possible that the renderable was already removed from the scene
+ if (!renderable.sourceEntity.scene || !renderable.sourceEntity._iIsMouseEnabled()) {
+ renderable = renderable.next;
+ continue;
+ }
+ this._potentialFound = true;
+ this._context.setCulling(renderable.materialOwner.material.bothSides ? ContextGLTriangleFace.NONE : ContextGLTriangleFace.BACK, camera.projection.coordinateSystem);
+ this._interactives[this._interactiveId++] = renderable;
+ // color code so that reading from bitmapdata will contain the correct value
+ this._id[1] = (this._interactiveId >> 8) / 255; // on green channel
+ this._id[2] = (this._interactiveId & 0xff) / 255; // on blue channel
+ matrix.copyFrom(renderable.sourceEntity.getRenderSceneTransform(camera));
+ matrix.append(viewProjection);
+ this._context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, matrix, true);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, 0, this._id, 1);
+ this._context.activateBuffer(0, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ this._context.drawTriangles(this._context.getIndexBuffer(renderable.getIndexData()), 0, renderable.numTriangles);
+ renderable = renderable.next;
+ }
+ };
+ ShaderPicker.prototype.updateRay = function (camera) {
+ this._rayPos = camera.scenePosition;
+ this._rayDir = camera.getRay(this._projX, this._projY, 1);
+ this._rayDir.normalize();
+ };
+ /**
+ * Creates the Program that color-codes objects.
+ */
+ ShaderPicker.prototype.initObjectProgram = function () {
+ var vertexCode;
+ var fragmentCode;
+ this._objectProgram = this._context.createProgram();
+ vertexCode = "m44 vt0, va0, vc0 \n" + "mul vt1.xy, vt0.w, vc4.zw \n" + "add vt0.xy, vt0.xy, vt1.xy \n" + "mul vt0.xy, vt0.xy, vc4.xy \n" + "mov op, vt0 \n";
+ fragmentCode = "mov oc, fc0"; // write identifier
+ Debug.throwPIR('ShaderPicker', 'initTriangleProgram', 'Dependency: initObjectProgram');
+ //_objectProgram.upload(new AGALMiniAssembler().assemble(ContextGLProgramType.VERTEX, vertexCode),new AGALMiniAssembler().assemble(ContextGLProgramType.FRAGMENT, fragmentCode));
+ };
+ /**
+ * Creates the Program that renders positions.
+ */
+ ShaderPicker.prototype.initTriangleProgram = function () {
+ var vertexCode;
+ var fragmentCode;
+ this._triangleProgram = this._context.createProgram();
+ // todo: add animation code
+ vertexCode = "add vt0, va0, vc5 \n" + "mul vt0, vt0, vc6 \n" + "mov v0, vt0 \n" + "m44 vt0, va0, vc0 \n" + "mul vt1.xy, vt0.w, vc4.zw \n" + "add vt0.xy, vt0.xy, vt1.xy \n" + "mul vt0.xy, vt0.xy, vc4.xy \n" + "mov op, vt0 \n";
+ fragmentCode = "mov oc, v0"; // write identifier
+ var vertexByteCode = (new AGALMiniAssembler().assemble("part vertex 1\n" + vertexCode + "endpart"))['vertex'].data;
+ var fragmentByteCode = (new AGALMiniAssembler().assemble("part fragment 1\n" + fragmentCode + "endpart"))['fragment'].data;
+ this._triangleProgram.upload(vertexByteCode, fragmentByteCode);
+ };
+ /**
+ * Gets more detailed information about the hir position, if required.
+ * @param camera The camera used to view the hit object.
+ */
+ ShaderPicker.prototype.getHitDetails = function (camera) {
+ this.getApproximatePosition(camera);
+ this.getPreciseDetails(camera);
+ };
+ /**
+ * Finds a first-guess approximate position about the hit position.
+ *
+ * @param camera The camera used to view the hit object.
+ */
+ ShaderPicker.prototype.getApproximatePosition = function (camera) {
+ var bounds = this._hitRenderable.sourceEntity.bounds.aabb;
+ var col;
+ var scX, scY, scZ;
+ var offsX, offsY, offsZ;
+ var localViewProjection = Matrix3DUtils.CALCULATION_MATRIX;
+ localViewProjection.copyFrom(this._hitRenderable.sourceEntity.getRenderSceneTransform(camera));
+ localViewProjection.append(camera.viewProjection);
+ if (!this._triangleProgram) {
+ this.initTriangleProgram();
+ }
+ this._boundOffsetScale[4] = 1 / (scX = bounds.width);
+ this._boundOffsetScale[5] = 1 / (scY = bounds.height);
+ this._boundOffsetScale[6] = 1 / (scZ = bounds.depth);
+ this._boundOffsetScale[0] = offsX = -bounds.x;
+ this._boundOffsetScale[1] = offsY = -bounds.y;
+ this._boundOffsetScale[2] = offsZ = -bounds.z;
+ this._context.setProgram(this._triangleProgram);
+ this._context.clear(0, 0, 0, 0, 1, 0, ContextGLClearMask.DEPTH);
+ this._context.setScissorRectangle(ShaderPicker.MOUSE_SCISSOR_RECT);
+ this._context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, localViewProjection, true);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 5, this._boundOffsetScale, 2);
+ this._context.activateBuffer(0, this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA), this._hitRenderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ this._context.drawTriangles(this._context.getIndexBuffer(this._hitRenderable.getIndexData()), 0, this._hitRenderable.numTriangles);
+ this._context.drawToBitmapData(this._bitmapData);
+ col = this._bitmapData.getPixel(0, 0);
+ this._localHitPosition.x = ((col >> 16) & 0xff) * scX / 255 - offsX;
+ this._localHitPosition.y = ((col >> 8) & 0xff) * scY / 255 - offsY;
+ this._localHitPosition.z = (col & 0xff) * scZ / 255 - offsZ;
+ };
+ /**
+ * Use the approximate position info to find the face under the mouse position from which we can derive the precise
+ * ray-face intersection point, then use barycentric coordinates to figure out the uv coordinates, etc.
+ * @param camera The camera used to view the hit object.
+ */
+ ShaderPicker.prototype.getPreciseDetails = function (camera) {
+ var len = indices.length;
+ var x1, y1, z1;
+ var x2, y2, z2;
+ var x3, y3, z3;
+ var i = 0, j = 1, k = 2;
+ var t1, t2, t3;
+ var v0x, v0y, v0z;
+ var v1x, v1y, v1z;
+ var v2x, v2y, v2z;
+ var ni1, ni2, ni3;
+ var n1, n2, n3, nLength;
+ var dot00, dot01, dot02, dot11, dot12;
+ var s, t, invDenom;
+ var x = this._localHitPosition.x, y = this._localHitPosition.y, z = this._localHitPosition.z;
+ var u, v;
+ var ui1, ui2, ui3;
+ var s0x, s0y, s0z;
+ var s1x, s1y, s1z;
+ var nl;
+ var indices = this._hitRenderable.getIndexData().data;
+ var positions = this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA).data;
+ var positionStride = this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA).dataPerVertex;
+ var positionOffset = this._hitRenderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA);
+ var uvs = this._hitRenderable.getVertexData(TriangleSubGeometry.UV_DATA).data;
+ var uvStride = this._hitRenderable.getVertexData(TriangleSubGeometry.UV_DATA).dataPerVertex;
+ var uvOffset = this._hitRenderable.getVertexOffset(TriangleSubGeometry.UV_DATA);
+ var normals = this._hitRenderable.getVertexData(TriangleSubGeometry.NORMAL_DATA).data;
+ var normalStride = this._hitRenderable.getVertexData(TriangleSubGeometry.NORMAL_DATA).dataPerVertex;
+ var normalOffset = this._hitRenderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA);
+ this.updateRay(camera);
+ while (i < len) {
+ t1 = positionOffset + indices[i] * positionStride;
+ t2 = positionOffset + indices[j] * positionStride;
+ t3 = positionOffset + indices[k] * positionStride;
+ x1 = positions[t1];
+ y1 = positions[t1 + 1];
+ z1 = positions[t1 + 2];
+ x2 = positions[t2];
+ y2 = positions[t2 + 1];
+ z2 = positions[t2 + 2];
+ x3 = positions[t3];
+ y3 = positions[t3 + 1];
+ z3 = positions[t3 + 2];
+ // if within bounds
+ if (!((x < x1 && x < x2 && x < x3) || (y < y1 && y < y2 && y < y3) || (z < z1 && z < z2 && z < z3) || (x > x1 && x > x2 && x > x3) || (y > y1 && y > y2 && y > y3) || (z > z1 && z > z2 && z > z3))) {
+ // calculate barycentric coords for approximated position
+ v0x = x3 - x1;
+ v0y = y3 - y1;
+ v0z = z3 - z1;
+ v1x = x2 - x1;
+ v1y = y2 - y1;
+ v1z = z2 - z1;
+ v2x = x - x1;
+ v2y = y - y1;
+ v2z = z - z1;
+ dot00 = v0x * v0x + v0y * v0y + v0z * v0z;
+ dot01 = v0x * v1x + v0y * v1y + v0z * v1z;
+ dot02 = v0x * v2x + v0y * v2y + v0z * v2z;
+ dot11 = v1x * v1x + v1y * v1y + v1z * v1z;
+ dot12 = v1x * v2x + v1y * v2y + v1z * v2z;
+ invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ s = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ t = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ // if inside the current triangle, fetch details hit information
+ if (s >= 0 && t >= 0 && (s + t) <= 1) {
+ ni1 = normalOffset + indices[i] * normalStride;
+ ni2 = normalOffset + indices[j] * normalStride;
+ ni3 = normalOffset + indices[k] * normalStride;
+ n1 = indices[ni1] + indices[ni2] + indices[ni3];
+ n2 = indices[ni1 + 1] + indices[ni2 + 1] + indices[ni3 + 1];
+ n3 = indices[ni1 + 2] + indices[ni2 + 2] + indices[ni3 + 2];
+ nLength = Math.sqrt(n1 * n1 + n2 * n2 + n3 * n3);
+ n1 /= nLength;
+ n2 /= nLength;
+ n3 /= nLength;
+ // this is def the triangle, now calculate precise coords
+ this.getPrecisePosition(this._hitRenderable.sourceEntity.inverseSceneTransform, n1, n2, n3, x1, y1, z1);
+ v2x = this._localHitPosition.x - x1;
+ v2y = this._localHitPosition.y - y1;
+ v2z = this._localHitPosition.z - z1;
+ s0x = x2 - x1; // s0 = p1 - p0
+ s0y = y2 - y1;
+ s0z = z2 - z1;
+ s1x = x3 - x1; // s1 = p2 - p0
+ s1y = y3 - y1;
+ s1z = z3 - z1;
+ this._localHitNormal.x = s0y * s1z - s0z * s1y; // n = s0 x s1
+ this._localHitNormal.y = s0z * s1x - s0x * s1z;
+ this._localHitNormal.z = s0x * s1y - s0y * s1x;
+ nl = 1 / Math.sqrt(this._localHitNormal.x * this._localHitNormal.x + this._localHitNormal.y * this._localHitNormal.y + this._localHitNormal.z * this._localHitNormal.z); // normalize n
+ this._localHitNormal.x *= nl;
+ this._localHitNormal.y *= nl;
+ this._localHitNormal.z *= nl;
+ dot02 = v0x * v2x + v0y * v2y + v0z * v2z;
+ dot12 = v1x * v2x + v1y * v2y + v1z * v2z;
+ s = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ t = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ ui1 = uvOffset + indices[i] * uvStride;
+ ui2 = uvOffset + indices[j] * uvStride;
+ ui3 = uvOffset + indices[k] * uvStride;
+ u = uvs[ui1];
+ v = uvs[ui1 + 1];
+ this._hitUV.x = u + t * (uvs[ui2] - u) + s * (uvs[ui3] - u);
+ this._hitUV.y = v + t * (uvs[ui2 + 1] - v) + s * (uvs[ui3 + 1] - v);
+ this._faceIndex = i;
+ //TODO add back subGeometryIndex value
+ //this._subGeometryIndex = away.utils.GeometryUtils.getMeshSubGeometryIndex(subGeom);
+ return;
+ }
+ }
+ i += 3;
+ j += 3;
+ k += 3;
+ }
+ };
+ /**
+ * Finds the precise hit position by unprojecting the screen coordinate back unto the hit face's plane and
+ * calculating the intersection point.
+ * @param camera The camera used to render the object.
+ * @param invSceneTransform The inverse scene transformation of the hit object.
+ * @param nx The x-coordinate of the face's plane normal.
+ * @param ny The y-coordinate of the face plane normal.
+ * @param nz The z-coordinate of the face plane normal.
+ * @param px The x-coordinate of a point on the face's plane (ie a face vertex)
+ * @param py The y-coordinate of a point on the face's plane (ie a face vertex)
+ * @param pz The z-coordinate of a point on the face's plane (ie a face vertex)
+ */
+ ShaderPicker.prototype.getPrecisePosition = function (invSceneTransform, nx, ny, nz, px, py, pz) {
+ // calculate screen ray and find exact intersection position with triangle
+ var rx, ry, rz;
+ var ox, oy, oz;
+ var t;
+ var raw = Matrix3DUtils.RAW_DATA_CONTAINER;
+ var cx = this._rayPos.x, cy = this._rayPos.y, cz = this._rayPos.z;
+ // unprojected projection point, gives ray dir in cam space
+ ox = this._rayDir.x;
+ oy = this._rayDir.y;
+ oz = this._rayDir.z;
+ // transform ray dir and origin (cam pos) to object space
+ //invSceneTransform.copyRawDataTo( raw );
+ invSceneTransform.copyRawDataTo(raw);
+ rx = raw[0] * ox + raw[4] * oy + raw[8] * oz;
+ ry = raw[1] * ox + raw[5] * oy + raw[9] * oz;
+ rz = raw[2] * ox + raw[6] * oy + raw[10] * oz;
+ ox = raw[0] * cx + raw[4] * cy + raw[8] * cz + raw[12];
+ oy = raw[1] * cx + raw[5] * cy + raw[9] * cz + raw[13];
+ oz = raw[2] * cx + raw[6] * cy + raw[10] * cz + raw[14];
+ t = ((px - ox) * nx + (py - oy) * ny + (pz - oz) * nz) / (rx * nx + ry * ny + rz * nz);
+ this._localHitPosition.x = ox + rx * t;
+ this._localHitPosition.y = oy + ry * t;
+ this._localHitPosition.z = oz + rz * t;
+ };
+ ShaderPicker.prototype.dispose = function () {
+ this._bitmapData.dispose();
+ if (this._triangleProgram)
+ this._triangleProgram.dispose();
+ if (this._objectProgram)
+ this._objectProgram.dispose();
+ this._triangleProgram = null;
+ this._objectProgram = null;
+ this._bitmapData = null;
+ this._hitRenderable = null;
+ this._hitEntity = null;
+ };
+ ShaderPicker.MOUSE_SCISSOR_RECT = new Rectangle(0, 0, 1, 1);
+ return ShaderPicker;
+})();
+module.exports = ShaderPicker;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvcmUvcGljay9zaGFkZXJwaWNrZXIudHMiXSwibmFtZXMiOlsiU2hhZGVyUGlja2VyIiwiU2hhZGVyUGlja2VyLmNvbnN0cnVjdG9yIiwiU2hhZGVyUGlja2VyLm9ubHlNb3VzZUVuYWJsZWQiLCJTaGFkZXJQaWNrZXIuZ2V0Vmlld0NvbGxpc2lvbiIsIlNoYWRlclBpY2tlci5nZXRTY2VuZUNvbGxpc2lvbiIsIlNoYWRlclBpY2tlci5wRHJhdyIsIlNoYWRlclBpY2tlci5kcmF3UmVuZGVyYWJsZXMiLCJTaGFkZXJQaWNrZXIudXBkYXRlUmF5IiwiU2hhZGVyUGlja2VyLmluaXRPYmplY3RQcm9ncmFtIiwiU2hhZGVyUGlja2VyLmluaXRUcmlhbmdsZVByb2dyYW0iLCJTaGFkZXJQaWNrZXIuZ2V0SGl0RGV0YWlscyIsIlNoYWRlclBpY2tlci5nZXRBcHByb3hpbWF0ZVBvc2l0aW9uIiwiU2hhZGVyUGlja2VyLmdldFByZWNpc2VEZXRhaWxzIiwiU2hhZGVyUGlja2VyLmdldFByZWNpc2VQb3NpdGlvbiIsIlNoYWRlclBpY2tlci5kaXNwb3NlIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLEtBQUssV0FBaUIsNkJBQTZCLENBQUMsQ0FBQztBQUM1RCxJQUFPLFVBQVUsV0FBZ0Isc0NBQXNDLENBQUMsQ0FBQztBQUN6RSxJQUFPLG1CQUFtQixXQUFjLCtDQUErQyxDQUFDLENBQUM7QUFLekYsSUFBTyxhQUFhLFdBQWUseUNBQXlDLENBQUMsQ0FBQztBQUM5RSxJQUFPLEtBQUssV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUNoRSxJQUFPLFNBQVMsV0FBZ0IscUNBQXFDLENBQUMsQ0FBQztBQUN2RSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQVN0RSxJQUFPLGlCQUFpQixXQUFjLHNEQUFzRCxDQUFDLENBQUM7QUFJOUYsSUFBTyxvQkFBb0IsV0FBYyxzREFBc0QsQ0FBQyxDQUFDO0FBQ2pHLElBQU8sa0JBQWtCLFdBQWMsb0RBQW9ELENB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QTtRQUNwREEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxNQUFNQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUNuREEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM5Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM5Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU5Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxDQUFDQTtRQUNoREEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsa0JBQWtCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUNoRUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxZQUFZQSxDQUFDQSxrQkFBa0JBLENBQUNBLENBQUNBO1FBQ25FQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSw2QkFBNkJBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsbUJBQW1CQSxFQUFFQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUN2R0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsNEJBQTRCQSxDQUFDQSxvQkFBb0JBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGlCQUFpQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFdEdBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLGFBQWFBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxhQUFhQSxDQUFDQSxFQUFFQSxtQkFBbUJBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1FBQ25OQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxhQUFhQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxjQUFjQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQTtRQUVuSUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtRQUVqREEsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFdENBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBQ0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDaEVBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBQ0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDL0RBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBQ0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsS0FBS0EsQ0FBQ0E7SUFDekRBLENBQUNBO0lBRURYOzs7O09BSUdBO0lBQ0tBLHdDQUFpQkEsR0FBekJBLFVBQTBCQSxNQUFhQTtRQUV0Q1ksSUFBSUEsR0FBR0EsR0FBVUEsT0FBT0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDaENBLElBQUlBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLENBQUNBO1FBQ3BDQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxDQUFDQTtRQUNwQ0EsSUFBSUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsQ0FBQ0E7UUFDcENBLElBQUlBLENBQUNBLEdBQVVBLENBQUNBLEVBQUVBLENBQUNBLEdBQVVBLENBQUNBLEVBQUVBLENBQUNBLEdBQVVBLENBQUNBLENBQUNBO1FBQzdDQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxDQUFDQTtRQUNwQ0EsSUFBSUEsR0FBVUEsRUFBRUEsR0FBVUEsRUFBRUEsR0FBVUEsQ0FBQ0E7UUFDdkNBLElBQUlBLEdBQVVBLEVBQUVBLEdBQVVBLEVBQUVBLEdBQVVBLENBQUNBO1FBQ3ZDQSxJQUFJQSxHQUFVQSxFQUFFQSxHQUFVQSxFQUFFQSxHQUFVQSxDQUFDQTtRQUN2Q0EsSUFBSUEsR0FBVUEsRUFBRUEsR0FBVUEsRUFBRUEsR0FBVUEsQ0FBQ0E7UUFDdkNBLElBQUlBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLE9BQWNBLENBQUNBO1FBQ3BEQSxJQUFJQSxLQUFZQSxFQUFFQSxLQUFZQSxFQUFFQSxLQUFZQSxFQUFFQSxLQUFZQSxFQUFFQSxLQUFZQSxDQUFDQTtRQUN6RUEsSUFBSUEsQ0FBUUEsRUFBRUEsQ0FBUUEsRUFBRUEsUUFBZUEsQ0FBQ0E7UUFDeENBLElBQUlBLENBQUNBLEdBQVVBLElBQUlBLENB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Q0FBQ0EsQ0FBQ0E7WUFDdkJBLEVBQUVBLEdBQUdBLFNBQVNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ25CQSxFQUFFQSxHQUFHQSxTQUFTQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN2QkEsRUFBRUEsR0FBR0EsU0FBU0EsQ0FBQ0EsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLEVBQUVBLEdBQUdBLFNBQVNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ25CQSxFQUFFQSxHQUFHQSxTQUFTQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN2QkEsRUFBRUEsR0FBR0EsU0FBU0EsQ0FBQ0EsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFdkJBLEFBQ0FBLG1CQURtQkE7WUFDbkJBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUtBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUV6TUEsQUFDQUEseURBRHlEQTtnQkFDekRBLEdBQUdBLEdBQUdBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBO2dCQUNkQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQTtnQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7Z0JBQ2RBLEdBQUdBLEdBQUdBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBO2dCQUNkQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQTtnQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7Z0JBQ2RBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBO2dCQUNiQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtnQkFDYkEsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7Z0JBQ2JBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUNwQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQ3BDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDcENBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUNwQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FB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QUFDQTtvQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsRUFBRUEsZUFBZUE7b0JBQzlCQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQTtvQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7b0JBQ2RBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEVBQUVBLGNBQWNBO29CQUMxREEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7b0JBQzNDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtvQkFDM0NBLEVBQUVBLEdBQUdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLGNBQWNBO29CQUMvS0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0E7b0JBQzdCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQTtvQkFDN0JBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBO29CQUU3QkEsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7b0JBQ3BDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtvQkFDcENBLENBQUNBLEdBQUdBLENBQUNBLEtBQUtBLEdBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUNBLEtBQUtBLENBQUNBLEdBQUNBLFFBQVFBLENBQUNBO29CQUN6Q0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsS0FBS0EsR0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBQ0EsUUFBUUEsQ0FBQ0E7b0JBRXpDQSxHQUFHQSxHQUFHQSxRQUFRQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxRQUFRQSxDQUFBQTtvQkFDcENBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLFFBQVFBLENBQUFBO29CQUNwQ0EsR0FBR0EsR0FBR0EsUUFBUUEsR0FBR0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsUUFBUUEsQ0FBQUE7b0JBRXBDQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDYkEsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pCQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDeERBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNB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Q0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDakRBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBRWxEQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQSxHQUFDQSxDQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUV6RUEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtJQUN0Q0EsQ0FBQ0E7SUFFTWIsOEJBQU9BLEdBQWRBO1FBRUNjLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQzNCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1lBQ3pCQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBRWpDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtZQUN2QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFFL0JBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO1FBQzNCQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBO0lBQ3hCQSxDQUFDQTtJQS9kY2QsK0JBQWtCQSxHQUFhQSxJQUFJQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtJQWdlekVBLG1CQUFDQTtBQUFEQSxDQWxnQkEsQUFrZ0JDQSxJQUFBO0FBRUQsQUFBc0IsaUJBQWIsWUFBWSxDQUFDIiwiZmlsZSI6ImNvcmUvcGljay9TaGFkZXJQaWNrZXIuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGVidWdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9EZWJ1Z1wiKTtcbmltcG9ydCBCaXRtYXBEYXRhXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9CaXRtYXBEYXRhXCIpO1xuaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBTY2VuZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvU2NlbmVcIik7XG5pbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9WaWV3XCIpO1xuaW1wb3J0IEJveFx0XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL0JveFwiKTtcbmltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBNYXRyaXgzRFV0aWxzXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RVdGlsc1wiKTtcbmltcG9ydCBQb2ludFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Qb2ludFwiKTtcbmltcG9ydCBSZWN0YW5nbGVcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1JlY3RhbmdsZVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBJUGlja2VyXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9waWNrL0lQaWNrZXJcIik7XG5pbXBvcnQgUGlja2luZ0NvbGxpc2lvblZPXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9waWNrL1BpY2tpbmdDb2xsaXNpb25WT1wiKTtcbmltcG9ydCBFbnRpdHlDb2xsZWN0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvdHJhdmVyc2UvRW50aXR5Q29sbGVjdG9yXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcbmltcG9ydCBJRW50aXR5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvSUVudGl0eVwiKTtcbmltcG9ydCBNYXRlcmlhbEJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL01hdGVyaWFsQmFzZVwiKTtcbmltcG9ydCBCeXRlQXJyYXlcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvQnl0ZUFycmF5XCIpO1xuXG5pbXBvcnQgQUdBTE1pbmlBc3NlbWJsZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hZ2xzbC9hc3NlbWJsZXIvQUdBTE1pbmlBc3NlbWJsZXJcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBEZWZhdWx0UmVuZGVyZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcbmltcG9ydCBDb250ZXh0R0xCbGVuZEZhY3Rvclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xCbGVuZEZhY3RvclwiKTtcbmltcG9ydCBDb250ZXh0R0xDbGVhck1hc2tcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMQ2xlYXJNYXNrXCIpO1xuaW1wb3J0IENvbnRleHRHTENvbXBhcmVNb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTENvbXBhcmVNb2RlXCIpO1xuaW1wb3J0IENvbnRleHRHTFByb2dyYW1UeXBlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFByb2dyYW1UeXBlXCIpO1xuaW1wb3J0IENvbnRleHRHTFRyaWFuZ2xlRmFjZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVHJpYW5nbGVGYWNlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBJUHJvZ3JhbVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JUHJvZ3JhbVwiKTtcbmltcG9ydCBJVGV4dHVyZUJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lUZXh0dXJlQmFzZVwiKTtcblxuLyoqXG4gKiBQaWNrcyBhIDNkIG9iamVjdCBmcm9tIGEgdmlldyBvciBzY2VuZSBieSBwZXJmb3JtaW5nIGEgc2VwYXJhdGUgcmVuZGVyIHBhc3Mgb24gdGhlIHNjZW5lIGFyb3VuZCB0aGUgYXJlYSBiZWluZyBwaWNrZWQgdXNpbmcga2V5IGNvbG9yIHZhbHVlcyxcbiAqIHRoZW4gcmVhZGluZyBiYWNrIHRoZSBjb2xvciB2YWx1ZSBvZiB0aGUgcGl4ZWwgaW4gdGhlIHJlbmRlciByZXByZXNlbnRpbmcgdGhlIHBpY2tpbmcgcmF5LiBSZXF1aXJlcyBtdWx0aXBsZSBwYXNzZXMgYW5kIHJlYWRiYWNrcyBmb3IgcmV0cml2aW5nIGRldGFpbHNcbiAqIG9uIGFuIGVudGl0eSB0aGF0IGhhcyBpdHMgc2hhZGVyUGlja2luZ0RldGFpbHMgcHJvcGVydHkgc2V0IHRvIHRydWUuXG4gKlxuICogQSByZWFkLWJhY2sgb3BlcmF0aW9uIGZyb20gYW55IEdQVSBpcyBub3QgYSB2ZXJ5IGVmZmljaWVudCBwcm9jZXNzLCBhbmQgdGhlIGFtb3VudCBvZiBwcm9jZXNzaW5nIHVzZWQgY2FuIHZhcnkgc2lnbmlmaWNhbnRseSBiZXR3ZWVuIGRpZmZlcmVudCBoYXJkd2FyZS5cbiAqXG4gKiBAc2VlIGF3YXkuZW50aXRpZXMuRW50aXR5I3NoYWRlclBpY2tpbmdEZXRhaWxzXG4gKlxuICogQGNsYXNzIGF3YXkucGljay5TaGFkZXJQaWNrZXJcbiAqL1xuY2xhc3MgU2hhZGVyUGlja2VyIGltcGxlbWVudHMgSVBpY2tlclxue1xuXHRwcml2YXRlIF9vcGFxdWVSZW5kZXJhYmxlSGVhZDpSZW5kZXJhYmxlQmFzZTtcblx0cHJpdmF0ZSBfYmxlbmRlZFJlbmRlcmFibGVIZWFkOlJlbmRlcmFibGVCYXNlO1xuXG5cdHByaXZhdGUgX3N0YWdlOlN0YWdlO1xuXHRwcml2YXRlIF9jb250ZXh0OklDb250ZXh0U3RhZ2VHTDtcblx0cHJpdmF0ZSBfb25seU1vdXNlRW5hYmxlZDpib29sZWFuID0gdHJ1ZTtcblxuXHRwcml2YXRlIF9vYmplY3RQcm9ncmFtOklQcm9ncmFtO1xuXHRwcml2YXRlIF90cmlhbmdsZVByb2dyYW06SVByb2dyYW07XG5cdHByaXZhdGUgX2JpdG1hcERhdGE6Qml0bWFwRGF0YTtcblx0cHJpdmF0ZSBfdmlld3BvcnREYXRhOkFycmF5PG51bWJlcj47XG5cdHByaXZhdGUgX2JvdW5kT2Zmc2V0U2NhbGU6QXJyYXk8bnVtYmVyPjtcblx0cHJpdmF0ZSBfaWQ6QXJyYXk8bnVtYmVyPjtcblxuXHRwcml2YXRlIF9pbnRlcmFjdGl2ZXM6QXJyYXk8UmVuZGVyYWJsZUJhc2U+ID0gbmV3IEFycmF5PFJlbmRlcmFibGVCYXNlPigpO1xuXHRwcml2YXRlIF9pbnRlcmFjdGl2ZUlkOm51bWJlcjtcblx0cHJpdmF0ZSBfaGl0Q29sb3I6bnVtYmVyO1xuXHRwcml2YXRlIF9wcm9qWDpudW1iZXI7XG5cdHByaXZhdGUgX3Byb2pZOm51bWJlcjtcblxuXHRwcml2YXRlIF9oaXRSZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlO1xuXHRwcml2YXRlIF9oaXRFbnRpdHk6SUVudGl0eTtcblx0cHJpdmF0ZSBfbG9jYWxIaXRQb3NpdGlvbjpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCgpO1xuXHRwcml2YXRlIF9oaXRVVjpQb2ludCA9IG5ldyBQb2ludCgpO1xuXHRwcml2YXRlIF9mYWNlSW5kZXg6bnVtYmVyO1xuXHRwcml2YXRlIF9zdWJHZW9tZXRyeUluZGV4Om51bWJlcjtcblxuXHRwcml2YXRlIF9sb2NhbEhpdE5vcm1hbDpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCgpO1xuXG5cdHByaXZhdGUgX3JheVBvczpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCgpO1xuXHRwcml2YXRlIF9yYXlEaXI6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0cHJpdmF0ZSBfcG90ZW50aWFsRm91bmQ6Ym9vbGVhbjtcblx0cHJpdmF0ZSBzdGF0aWMgTU9VU0VfU0NJU1NPUl9SRUNUOlJlY3RhbmdsZSA9IG5ldyBSZWN0YW5nbGUoMCwgMCwgMSwgMSk7XG5cblx0cHJpdmF0ZSBfc2hhZGVyUGlja2luZ0RldGFpbHM6Ym9vbGVhbjtcblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXQgb25seU1vdXNlRW5hYmxlZCgpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiB0aGlzLl9vbmx5TW91c2VFbmFibGVkO1xuXHR9XG5cblx0cHVibGljIHNldCBvbmx5TW91c2VFbmFibGVkKHZhbHVlOmJvb2xlYW4pXG5cdHtcblx0XHR0aGlzLl9vbmx5TW91c2VFbmFibGVkID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5TaGFkZXJQaWNrZXI8L2NvZGU+IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHNoYWRlclBpY2tpbmdEZXRhaWxzIERldGVybWluZXMgd2hldGhlciB0aGUgcGlja2VyIGluY2x1ZGVzIGEgc2Vjb25kIHBhc3MgdG8gY2FsY3VsYXRlIGV4dHJhXG5cdCAqIHByb3BlcnRpZXMgc3VjaCBhcyB1diBhbmQgbm9ybWFsIGNvb3JkaW5hdGVzLlxuXHQgKi9cblx0Y29uc3RydWN0b3Ioc2hhZGVyUGlja2luZ0RldGFpbHM6Ym9vbGVhbiA9IGZhbHNlKVxuXHR7XG5cdFx0dGhpcy5fc2hhZGVyUGlja2luZ0RldGFpbHMgPSBzaGFkZXJQaWNraW5nRGV0YWlscztcblxuXHRcdHRoaXMuX2lkID0gbmV3IEFycmF5PG51bWJlcj4oNCk7XG5cdFx0dGhpcy5fdmlld3BvcnREYXRhID0gbmV3IEFycmF5PG51bWJlcj4oNCk7IC8vIGZpcnN0IDIgY29udGFpbiBzY2FsZSwgbGFzdCAyIHRyYW5zbGF0aW9uXG5cdFx0dGhpcy5fYm91bmRPZmZzZXRTY2FsZSA9IG5ldyBBcnJheTxudW1iZXI+KDgpOyAvLyBmaXJzdCAyIGNvbnRhaW4gc2NhbGUsIGxhc3QgMiB0cmFuc2xhdGlvblxuXHRcdHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGVbM10gPSAwO1xuXHRcdHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGVbN10gPSAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0Vmlld0NvbGxpc2lvbih4Om51bWJlciwgeTpudW1iZXIsIHZpZXc6Vmlldyk6UGlja2luZ0NvbGxpc2lvblZPXG5cdHtcblx0XHR2YXIgY29sbGVjdG9yOkVudGl0eUNvbGxlY3RvciA9IDxFbnRpdHlDb2xsZWN0b3I+IHZpZXcuaUVudGl0eUNvbGxlY3RvcjtcblxuXHRcdHRoaXMuX3N0YWdlID0gKDxEZWZhdWx0UmVuZGVyZXI+IHZpZXcucmVuZGVyZXIpLnN0YWdlO1xuXG5cdFx0aWYgKCF0aGlzLl9zdGFnZSlcblx0XHRcdHJldHVybiBudWxsO1xuXG5cdFx0dGhpcy5fY29udGV4dCA9IDxJQ29udGV4dFN0YWdlR0w+IHRoaXMuX3N0YWdlLmNvbnRleHQ7XG5cblx0XHR0aGlzLl92aWV3cG9ydERhdGFbMF0gPSB2aWV3LndpZHRoO1xuXHRcdHRoaXMuX3ZpZXdwb3J0RGF0YVsxXSA9IHZpZXcuaGVpZ2h0O1xuXHRcdHRoaXMuX3ZpZXdwb3J0RGF0YVsyXSA9IC0odGhpcy5fcHJvalggPSAyKngvdmlldy53aWR0aCAtIDEpO1xuXHRcdHRoaXMuX3ZpZXdwb3J0RGF0YVszXSA9IHRoaXMuX3Byb2pZID0gMip5L3ZpZXcuaGVpZ2h0IC0gMTtcblxuXHRcdC8vIF9wb3RlbnRpYWxGb3VuZCB3aWxsIGJlIHNldCB0byB0cnVlIGlmIGFueSBvYmplY3QgaXMgYWN0dWFsbHkgcmVuZGVyZWRcblx0XHR0aGlzLl9wb3RlbnRpYWxGb3VuZCA9IGZhbHNlO1xuXG5cdFx0Ly9yZXNldCBoZWFkIHZhbHVlc1xuXHRcdHRoaXMuX2JsZW5kZWRSZW5kZXJhYmxlSGVhZCA9IG51bGw7XG5cdFx0dGhpcy5fb3BhcXVlUmVuZGVyYWJsZUhlYWQgPSBudWxsO1xuXG5cdFx0dGhpcy5wRHJhdyhjb2xsZWN0b3IsIG51bGwpO1xuXG5cdFx0Ly8gY2xlYXIgYnVmZmVyc1xuXHRcdHRoaXMuX2NvbnRleHQuc2V0VmVydGV4QnVmZmVyQXQoMCwgbnVsbCk7XG5cblx0XHRpZiAoIXRoaXMuX2NvbnRleHQgfHwgIXRoaXMuX3BvdGVudGlhbEZvdW5kKVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHRpZiAoIXRoaXMuX2JpdG1hcERhdGEpXG5cdFx0XHR0aGlzLl9iaXRtYXBEYXRhID0gbmV3IEJpdG1hcERhdGEoMSwgMSwgZmFsc2UsIDApO1xuXG5cdFx0dGhpcy5fY29udGV4dC5kcmF3VG9CaXRtYXBEYXRhKHRoaXMuX2JpdG1hcERhdGEpO1xuXHRcdHRoaXMuX2hpdENvbG9yID0gdGhpcy5fYml0bWFwRGF0YS5nZXRQaXhlbCgwLCAwKTtcblxuXHRcdGlmICghdGhpcy5faGl0Q29sb3IpIHtcblx0XHRcdHRoaXMuX2NvbnRleHQucHJlc2VudCgpO1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0dGhpcy5faGl0UmVuZGVyYWJsZSA9IHRoaXMuX2ludGVyYWN0aXZlc1t0aGlzLl9oaXRDb2xvciAtIDFdO1xuXHRcdHRoaXMuX2hpdEVudGl0eSA9IHRoaXMuX2hpdFJlbmRlcmFibGUuc291cmNlRW50aXR5O1xuXG5cdFx0aWYgKHRoaXMuX29ubHlNb3VzZUVuYWJsZWQgJiYgIXRoaXMuX2hpdEVudGl0eS5faUlzTW91c2VFbmFibGVkKCkpXG5cdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdHZhciBfY29sbGlzaW9uVk86UGlja2luZ0NvbGxpc2lvblZPID0gdGhpcy5faGl0RW50aXR5Ll9pUGlja2luZ0NvbGxpc2lvblZPO1xuXHRcdGlmICh0aGlzLl9zaGFkZXJQaWNraW5nRGV0YWlscykge1xuXHRcdFx0dGhpcy5nZXRIaXREZXRhaWxzKHZpZXcuY2FtZXJhKTtcblx0XHRcdF9jb2xsaXNpb25WTy5sb2NhbFBvc2l0aW9uID0gdGhpcy5fbG9jYWxIaXRQb3NpdGlvbjtcblx0XHRcdF9jb2xsaXNpb25WTy5sb2NhbE5vcm1hbCA9IHRoaXMuX2xvY2FsSGl0Tm9ybWFsO1xuXHRcdFx0X2NvbGxpc2lvblZPLnV2ID0gdGhpcy5faGl0VVY7XG5cdFx0XHRfY29sbGlzaW9uVk8uaW5kZXggPSB0aGlzLl9mYWNlSW5kZXg7XG5cdFx0XHQvL19jb2xsaXNpb25WTy5zdWJHZW9tZXRyeUluZGV4ID0gdGhpcy5fc3ViR2VvbWV0cnlJbmRleDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRfY29sbGlzaW9uVk8ubG9jYWxQb3NpdGlvbiA9IG51bGw7XG5cdFx0XHRfY29sbGlzaW9uVk8ubG9jYWxOb3JtYWwgPSBudWxsO1xuXHRcdFx0X2NvbGxpc2lvblZPLnV2ID0gbnVsbDtcblx0XHRcdF9jb2xsaXNpb25WTy5pbmRleCA9IDA7XG5cdFx0XHQvL19jb2xsaXNpb25WTy5zdWJHZW9tZXRyeUluZGV4ID0gMDtcblx0XHR9XG5cblx0XHRyZXR1cm4gX2NvbGxpc2lvblZPO1xuXHR9XG5cblx0Ly8qL1xuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXRTY2VuZUNvbGxpc2lvbihwb3NpdGlvbjpWZWN0b3IzRCwgZGlyZWN0aW9uOlZlY3RvcjNELCBzY2VuZTpTY2VuZSk6UGlja2luZ0NvbGxpc2lvblZPXG5cdHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHBEcmF3KGVudGl0eUNvbGxlY3RvcjpFbnRpdHlDb2xsZWN0b3IsIHRhcmdldDpJVGV4dHVyZUJhc2UpXG5cdHtcblxuXHRcdHZhciBjYW1lcmE6Q2FtZXJhID0gZW50aXR5Q29sbGVjdG9yLmNhbWVyYTtcblxuXHRcdHRoaXMuX2NvbnRleHQuY2xlYXIoMCwgMCwgMCwgMSk7XG5cdFx0dGhpcy5fc3RhZ2Uuc2Npc3NvclJlY3QgPSBTaGFkZXJQaWNrZXIuTU9VU0VfU0NJU1NPUl9SRUNUO1xuXG5cdFx0dGhpcy5faW50ZXJhY3RpdmVzLmxlbmd0aCA9IHRoaXMuX2ludGVyYWN0aXZlSWQgPSAwO1xuXG5cdFx0aWYgKCF0aGlzLl9vYmplY3RQcm9ncmFtKVxuXHRcdFx0dGhpcy5pbml0T2JqZWN0UHJvZ3JhbSgpO1xuXG5cdFx0dGhpcy5fY29udGV4dC5zZXRCbGVuZEZhY3RvcnMoQ29udGV4dEdMQmxlbmRGYWN0b3IuT05FLCBDb250ZXh0R0xCbGVuZEZhY3Rvci5aRVJPKTtcblx0XHR0aGlzLl9jb250ZXh0LnNldERlcHRoVGVzdCh0cnVlLCBDb250ZXh0R0xDb21wYXJlTW9kZS5MRVNTKTtcblx0XHR0aGlzLl9jb250ZXh0LnNldFByb2dyYW0odGhpcy5fb2JqZWN0UHJvZ3JhbSk7XG5cdFx0dGhpcy5fY29udGV4dC5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbUFycmF5KENvbnRleHRHTFByb2dyYW1UeXBlLlZFUlRFWCwgNCwgdGhpcy5fdmlld3BvcnREYXRhLCAxKTtcblx0XHQvL3RoaXMuZHJhd1JlbmRlcmFibGVzKGVudGl0eUNvbGxlY3Rvci5vcGFxdWVSZW5kZXJhYmxlSGVhZCwgY2FtZXJhKTtcblx0XHQvL3RoaXMuZHJhd1JlbmRlcmFibGVzKGVudGl0eUNvbGxlY3Rvci5ibGVuZGVkUmVuZGVyYWJsZUhlYWQsIGNhbWVyYSk7XG5cdFx0Ly9UT0RPOiByZWltcGxlbWVudCBTaGFkZXJQaWNrZXIgaW5oZXJpdGluZyBmcm9tIFJlbmRlcmVyQmFzZVxuXHR9XG5cblx0LyoqXG5cdCAqIERyYXcgYSBsaXN0IG9mIHJlbmRlcmFibGVzLlxuXHQgKiBAcGFyYW0gcmVuZGVyYWJsZXMgVGhlIHJlbmRlcmFibGVzIHRvIGRyYXcuXG5cdCAqIEBwYXJhbSBjYW1lcmEgVGhlIGNhbWVyYSBmb3Igd2hpY2ggdG8gcmVuZGVyLlxuXHQgKi9cblx0cHJpdmF0ZSBkcmF3UmVuZGVyYWJsZXMocmVuZGVyYWJsZTpSZW5kZXJhYmxlQmFzZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHZhciBtYXRyaXg6TWF0cml4M0QgPSBNYXRyaXgzRFV0aWxzLkNBTENVTEFUSU9OX01BVFJJWDtcblx0XHR2YXIgdmlld1Byb2plY3Rpb246TWF0cml4M0QgPSBjYW1lcmEudmlld1Byb2plY3Rpb247XG5cblx0XHR3aGlsZSAocmVuZGVyYWJsZSkge1xuXHRcdFx0Ly8gaXQncyBwb3NzaWJsZSB0aGF0IHRoZSByZW5kZXJhYmxlIHdhcyBhbHJlYWR5IHJlbW92ZWQgZnJvbSB0aGUgc2NlbmVcblx0XHRcdGlmICghcmVuZGVyYWJsZS5zb3VyY2VFbnRpdHkuc2NlbmUgfHwgIXJlbmRlcmFibGUuc291cmNlRW50aXR5Ll9pSXNNb3VzZUVuYWJsZWQoKSkge1xuXHRcdFx0XHRyZW5kZXJhYmxlID0gcmVuZGVyYWJsZS5uZXh0O1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fcG90ZW50aWFsRm91bmQgPSB0cnVlO1xuXG5cdFx0XHR0aGlzLl9jb250ZXh0LnNldEN1bGxpbmcoKDxNYXRlcmlhbEJhc2U+IHJlbmRlcmFibGUubWF0ZXJpYWxPd25lci5tYXRlcmlhbCkuYm90aFNpZGVzPyBDb250ZXh0R0xUcmlhbmdsZUZhY2UuTk9ORSA6IENvbnRleHRHTFRyaWFuZ2xlRmFjZS5CQUNLLCBjYW1lcmEucHJvamVjdGlvbi5jb29yZGluYXRlU3lzdGVtKTtcblxuXHRcdFx0dGhpcy5faW50ZXJhY3RpdmVzW3RoaXMuX2ludGVyYWN0aXZlSWQrK10gPSByZW5kZXJhYmxlO1xuXHRcdFx0Ly8gY29sb3IgY29kZSBzbyB0aGF0IHJlYWRpbmcgZnJvbSBiaXRtYXBkYXRhIHdpbGwgY29udGFpbiB0aGUgY29ycmVjdCB2YWx1ZVxuXHRcdFx0dGhpcy5faWRbMV0gPSAodGhpcy5faW50ZXJhY3RpdmVJZCA+PiA4KS8yNTU7IC8vIG9uIGdyZWVuIGNoYW5uZWxcblx0XHRcdHRoaXMuX2lkWzJdID0gKHRoaXMuX2ludGVyYWN0aXZlSWQgJiAweGZmKS8yNTU7IC8vIG9uIGJsdWUgY2hhbm5lbFxuXG5cdFx0XHRtYXRyaXguY29weUZyb20ocmVuZGVyYWJsZS5zb3VyY2VFbnRpdHkuZ2V0UmVuZGVyU2NlbmVUcmFuc2Zvcm0oY2FtZXJhKSk7XG5cdFx0XHRtYXRyaXguYXBwZW5kKHZpZXdQcm9qZWN0aW9uKTtcblx0XHRcdHRoaXMuX2NvbnRleHQuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21NYXRyaXgoQ29udGV4dEdMUHJvZ3JhbVR5cGUuVkVSVEVYLCAwLCBtYXRyaXgsIHRydWUpO1xuXHRcdFx0dGhpcy5fY29udGV4dC5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbUFycmF5KENvbnRleHRHTFByb2dyYW1UeXBlLkZSQUdNRU5ULCAwLCB0aGlzLl9pZCwgMSk7XG5cdFx0XHR0aGlzLl9jb250ZXh0LmFjdGl2YXRlQnVmZmVyKDAsIHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLCByZW5kZXJhYmxlLmdldFZlcnRleE9mZnNldChUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0RBVEEpLCBUcmlhbmdsZVN1Ykdlb21ldHJ5LlBPU0lUSU9OX0ZPUk1BVCk7XG5cdFx0XHR0aGlzLl9jb250ZXh0LmRyYXdUcmlhbmdsZXModGhpcy5fY29udGV4dC5nZXRJbmRleEJ1ZmZlcihyZW5kZXJhYmxlLmdldEluZGV4RGF0YSgpKSwgMCwgcmVuZGVyYWJsZS5udW1UcmlhbmdsZXMpO1xuXG5cdFx0XHRyZW5kZXJhYmxlID0gcmVuZGVyYWJsZS5uZXh0O1xuXHRcdH1cblxuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVSYXkoY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHRoaXMuX3JheVBvcyA9IGNhbWVyYS5zY2VuZVBvc2l0aW9uO1xuXG5cdFx0dGhpcy5fcmF5RGlyID0gY2FtZXJhLmdldFJheSh0aGlzLl9wcm9qWCwgdGhpcy5fcHJvalksIDEpO1xuXHRcdHRoaXMuX3JheURpci5ub3JtYWxpemUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIHRoZSBQcm9ncmFtIHRoYXQgY29sb3ItY29kZXMgb2JqZWN0cy5cblx0ICovXG5cdHByaXZhdGUgaW5pdE9iamVjdFByb2dyYW0oKVxuXHR7XG5cdFx0dmFyIHZlcnRleENvZGU6c3RyaW5nO1xuXHRcdHZhciBmcmFnbWVudENvZGU6c3RyaW5nO1xuXG5cdFx0dGhpcy5fb2JqZWN0UHJvZ3JhbSA9IHRoaXMuX2NvbnRleHQuY3JlYXRlUHJvZ3JhbSgpO1xuXG5cdFx0dmVydGV4Q29kZSA9IFwibTQ0IHZ0MCwgdmEwLCB2YzBcdFx0XHRcXG5cIiArIFwibXVsIHZ0MS54eSwgdnQwLncsIHZjNC56d1x0XFxuXCIgKyBcImFkZCB2dDAueHksIHZ0MC54eSwgdnQxLnh5XHRcXG5cIiArIFwibXVsIHZ0MC54eSwgdnQwLnh5LCB2YzQueHlcdFxcblwiICsgXCJtb3Ygb3AsIHZ0MFx0XFxuXCI7XG5cdFx0ZnJhZ21lbnRDb2RlID0gXCJtb3Ygb2MsIGZjMFwiOyAvLyB3cml0ZSBpZGVudGlmaWVyXG5cblx0XHREZWJ1Zy50aHJvd1BJUignU2hhZGVyUGlja2VyJywgJ2luaXRUcmlhbmdsZVByb2dyYW0nLCAnRGVwZW5kZW5jeTogaW5pdE9iamVjdFByb2dyYW0nKVxuXHRcdC8vX29iamVjdFByb2dyYW0udXBsb2FkKG5ldyBBR0FMTWluaUFzc2VtYmxlcigpLmFzc2VtYmxlKENvbnRleHRHTFByb2dyYW1UeXBlLlZFUlRFWCwgdmVydGV4Q29kZSksbmV3IEFHQUxNaW5pQXNzZW1ibGVyKCkuYXNzZW1ibGUoQ29udGV4dEdMUHJvZ3JhbVR5cGUuRlJBR01FTlQsIGZyYWdtZW50Q29kZSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgdGhlIFByb2dyYW0gdGhhdCByZW5kZXJzIHBvc2l0aW9ucy5cblx0ICovXG5cblx0cHJpdmF0ZSBpbml0VHJpYW5nbGVQcm9ncmFtKClcblx0e1xuXHRcdHZhciB2ZXJ0ZXhDb2RlOnN0cmluZztcblx0XHR2YXIgZnJhZ21lbnRDb2RlOnN0cmluZztcblxuXHRcdHRoaXMuX3RyaWFuZ2xlUHJvZ3JhbSA9IHRoaXMuX2NvbnRleHQuY3JlYXRlUHJvZ3JhbSgpO1xuXG5cdFx0Ly8gdG9kbzogYWRkIGFuaW1hdGlvbiBjb2RlXG5cdFx0dmVydGV4Q29kZSA9IFwiYWRkIHZ0MCwgdmEwLCB2YzUgXHRcdFx0XFxuXCIgKyBcIm11bCB2dDAsIHZ0MCwgdmM2IFx0XHRcdFxcblwiICsgXCJtb3YgdjAsIHZ0MFx0XHRcdFx0XFxuXCIgKyBcIm00NCB2dDAsIHZhMCwgdmMwXHRcdFx0XFxuXCIgKyBcIm11bCB2dDEueHksIHZ0MC53LCB2YzQuendcdFxcblwiICsgXCJhZGQgdnQwLnh5LCB2dDAueHksIHZ0MS54eVx0XFxuXCIgKyBcIm11bCB2dDAueHksIHZ0MC54eSwgdmM0Lnh5XHRcXG5cIiArIFwibW92IG9wLCB2dDBcdFxcblwiO1xuXHRcdGZyYWdtZW50Q29kZSA9IFwibW92IG9jLCB2MFwiOyAvLyB3cml0ZSBpZGVudGlmaWVyXG5cblx0XHR2YXIgdmVydGV4Qnl0ZUNvZGU6Qnl0ZUFycmF5ID0gKG5ldyBBR0FMTWluaUFzc2VtYmxlcigpLmFzc2VtYmxlKFwicGFydCB2ZXJ0ZXggMVxcblwiICsgdmVydGV4Q29kZSArIFwiZW5kcGFydFwiKSlbJ3ZlcnRleCddLmRhdGE7XG5cdFx0dmFyIGZyYWdtZW50Qnl0ZUNvZGU6Qnl0ZUFycmF5ID0gKG5ldyBBR0FMTWluaUFzc2VtYmxlcigpLmFzc2VtYmxlKFwicGFydCBmcmFnbWVudCAxXFxuXCIgKyBmcmFnbWVudENvZGUgKyBcImVuZHBhcnRcIikpWydmcmFnbWVudCddLmRhdGE7XG5cdFx0dGhpcy5fdHJpYW5nbGVQcm9ncmFtLnVwbG9hZCh2ZXJ0ZXhCeXRlQ29kZSwgZnJhZ21lbnRCeXRlQ29kZSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBoaXIgcG9zaXRpb24sIGlmIHJlcXVpcmVkLlxuXHQgKiBAcGFyYW0gY2FtZXJhIFRoZSBjYW1lcmEgdXNlZCB0byB2aWV3IHRoZSBoaXQgb2JqZWN0LlxuXHQgKi9cblx0cHJpdmF0ZSBnZXRIaXREZXRhaWxzKGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHR0aGlzLmdldEFwcHJveGltYXRlUG9zaXRpb24oY2FtZXJhKTtcblx0XHR0aGlzLmdldFByZWNpc2VEZXRhaWxzKGNhbWVyYSk7XG5cdH1cblxuXHQvKipcblx0ICogRmluZHMgYSBmaXJzdC1ndWVzcyBhcHByb3hpbWF0ZSBwb3NpdGlvbiBhYm91dCB0aGUgaGl0IHBvc2l0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gY2FtZXJhIFRoZSBjYW1lcmEgdXNlZCB0byB2aWV3IHRoZSBoaXQgb2JqZWN0LlxuXHQgKi9cblx0cHJpdmF0ZSBnZXRBcHByb3hpbWF0ZVBvc2l0aW9uKGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHR2YXIgYm91bmRzOkJveCA9IHRoaXMuX2hpdFJlbmRlcmFibGUuc291cmNlRW50aXR5LmJvdW5kcy5hYWJiO1xuXHRcdHZhciBjb2w6bnVtYmVyO1xuXHRcdHZhciBzY1g6bnVtYmVyLCBzY1k6bnVtYmVyLCBzY1o6bnVtYmVyO1xuXHRcdHZhciBvZmZzWDpudW1iZXIsIG9mZnNZOm51bWJlciwgb2Zmc1o6bnVtYmVyO1xuXHRcdHZhciBsb2NhbFZpZXdQcm9qZWN0aW9uOk1hdHJpeDNEID0gTWF0cml4M0RVdGlscy5DQUxDVUxBVElPTl9NQVRSSVg7XG5cblx0XHRsb2NhbFZpZXdQcm9qZWN0aW9uLmNvcHlGcm9tKHRoaXMuX2hpdFJlbmRlcmFibGUuc291cmNlRW50aXR5LmdldFJlbmRlclNjZW5lVHJhbnNmb3JtKGNhbWVyYSkpO1xuXHRcdGxvY2FsVmlld1Byb2plY3Rpb24uYXBwZW5kKGNhbWVyYS52aWV3UHJvamVjdGlvbik7XG5cdFx0aWYgKCF0aGlzLl90cmlhbmdsZVByb2dyYW0pIHtcblx0XHRcdHRoaXMuaW5pdFRyaWFuZ2xlUHJvZ3JhbSgpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGVbNF0gPSAxLyhzY1ggPSBib3VuZHMud2lkdGgpO1xuXHRcdHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGVbNV0gPSAxLyhzY1kgPSBib3VuZHMuaGVpZ2h0KTtcblx0XHR0aGlzLl9ib3VuZE9mZnNldFNjYWxlWzZdID0gMS8oc2NaID0gYm91bmRzLmRlcHRoKTtcblx0XHR0aGlzLl9ib3VuZE9mZnNldFNjYWxlWzBdID0gb2Zmc1ggPSAtYm91bmRzLng7XG5cdFx0dGhpcy5fYm91bmRPZmZzZXRTY2FsZVsxXSA9IG9mZnNZID0gLWJvdW5kcy55O1xuXHRcdHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGVbMl0gPSBvZmZzWiA9IC1ib3VuZHMuejtcblxuXHRcdHRoaXMuX2NvbnRleHQuc2V0UHJvZ3JhbSh0aGlzLl90cmlhbmdsZVByb2dyYW0pO1xuXHRcdHRoaXMuX2NvbnRleHQuY2xlYXIoMCwgMCwgMCwgMCwgMSwgMCwgQ29udGV4dEdMQ2xlYXJNYXNrLkRFUFRIKTtcblx0XHR0aGlzLl9jb250ZXh0LnNldFNjaXNzb3JSZWN0YW5nbGUoU2hhZGVyUGlja2VyLk1PVVNFX1NDSVNTT1JfUkVDVCk7XG5cdFx0dGhpcy5fY29udGV4dC5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbU1hdHJpeChDb250ZXh0R0xQcm9ncmFtVHlwZS5WRVJURVgsIDAsIGxvY2FsVmlld1Byb2plY3Rpb24sIHRydWUpO1xuXHRcdHRoaXMuX2NvbnRleHQuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21BcnJheShDb250ZXh0R0xQcm9ncmFtVHlwZS5WRVJURVgsIDUsIHRoaXMuX2JvdW5kT2Zmc2V0U2NhbGUsIDIpO1xuXG5cdFx0dGhpcy5fY29udGV4dC5hY3RpdmF0ZUJ1ZmZlcigwLCB0aGlzLl9oaXRSZW5kZXJhYmxlLmdldFZlcnRleERhdGEoVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9EQVRBKSwgdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9EQVRBKSwgVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9GT1JNQVQpO1xuXHRcdHRoaXMuX2NvbnRleHQuZHJhd1RyaWFuZ2xlcyh0aGlzLl9jb250ZXh0LmdldEluZGV4QnVmZmVyKHRoaXMuX2hpdFJlbmRlcmFibGUuZ2V0SW5kZXhEYXRhKCkpLCAwLCB0aGlzLl9oaXRSZW5kZXJhYmxlLm51bVRyaWFuZ2xlcyk7XG5cblx0XHR0aGlzLl9jb250ZXh0LmRyYXdUb0JpdG1hcERhdGEodGhpcy5fYml0bWFwRGF0YSk7XG5cblx0XHRjb2wgPSB0aGlzLl9iaXRtYXBEYXRhLmdldFBpeGVsKDAsIDApO1xuXG5cdFx0dGhpcy5fbG9jYWxIaXRQb3NpdGlvbi54ID0gKChjb2wgPj4gMTYpICYgMHhmZikqc2NYLzI1NSAtIG9mZnNYO1xuXHRcdHRoaXMuX2xvY2FsSGl0UG9zaXRpb24ueSA9ICgoY29sID4+IDgpICYgMHhmZikqc2NZLzI1NSAtIG9mZnNZO1xuXHRcdHRoaXMuX2xvY2FsSGl0UG9zaXRpb24ueiA9IChjb2wgJiAweGZmKSpzY1ovMjU1IC0gb2Zmc1o7XG5cdH1cblxuXHQvKipcblx0ICogVXNlIHRoZSBhcHByb3hpbWF0ZSBwb3NpdGlvbiBpbmZvIHRvIGZpbmQgdGhlIGZhY2UgdW5kZXIgdGhlIG1vdXNlIHBvc2l0aW9uIGZyb20gd2hpY2ggd2UgY2FuIGRlcml2ZSB0aGUgcHJlY2lzZVxuXHQgKiByYXktZmFjZSBpbnRlcnNlY3Rpb24gcG9pbnQsIHRoZW4gdXNlIGJhcnljZW50cmljIGNvb3JkaW5hdGVzIHRvIGZpZ3VyZSBvdXQgdGhlIHV2IGNvb3JkaW5hdGVzLCBldGMuXG5cdCAqIEBwYXJhbSBjYW1lcmEgVGhlIGNhbWVyYSB1c2VkIHRvIHZpZXcgdGhlIGhpdCBvYmplY3QuXG5cdCAqL1xuXHRwcml2YXRlIGdldFByZWNpc2VEZXRhaWxzKGNhbWVyYTpDYW1lcmEpXG5cdHtcblx0XHR2YXIgbGVuOm51bWJlciA9IGluZGljZXMubGVuZ3RoO1xuXHRcdHZhciB4MTpudW1iZXIsIHkxOm51bWJlciwgejE6bnVtYmVyO1xuXHRcdHZhciB4MjpudW1iZXIsIHkyOm51bWJlciwgejI6bnVtYmVyO1xuXHRcdHZhciB4MzpudW1iZXIsIHkzOm51bWJlciwgejM6bnVtYmVyO1xuXHRcdHZhciBpOm51bWJlciA9IDAsIGo6bnVtYmVyID0gMSwgazpudW1iZXIgPSAyO1xuXHRcdHZhciB0MTpudW1iZXIsIHQyOm51bWJlciwgdDM6bnVtYmVyO1xuXHRcdHZhciB2MHg6bnVtYmVyLCB2MHk6bnVtYmVyLCB2MHo6bnVtYmVyO1xuXHRcdHZhciB2MXg6bnVtYmVyLCB2MXk6bnVtYmVyLCB2MXo6bnVtYmVyO1xuXHRcdHZhciB2Mng6bnVtYmVyLCB2Mnk6bnVtYmVyLCB2Mno6bnVtYmVyO1xuXHRcdHZhciBuaTE6bnVtYmVyLCBuaTI6bnVtYmVyLCBuaTM6bnVtYmVyO1xuXHRcdHZhciBuMTpudW1iZXIsIG4yOm51bWJlciwgbjM6bnVtYmVyLCBuTGVuZ3RoOm51bWJlcjtcblx0XHR2YXIgZG90MDA6bnVtYmVyLCBkb3QwMTpudW1iZXIsIGRvdDAyOm51bWJlciwgZG90MTE6bnVtYmVyLCBkb3QxMjpudW1iZXI7XG5cdFx0dmFyIHM6bnVtYmVyLCB0Om51bWJlciwgaW52RGVub206bnVtYmVyO1xuXHRcdHZhciB4Om51bWJlciA9IHRoaXMuX2xvY2FsSGl0UG9zaXRpb24ueCwgeTpudW1iZXIgPSB0aGlzLl9sb2NhbEhpdFBvc2l0aW9uLnksIHo6bnVtYmVyID0gdGhpcy5fbG9jYWxIaXRQb3NpdGlvbi56O1xuXHRcdHZhciB1Om51bWJlciwgdjpudW1iZXI7XG5cdFx0dmFyIHVpMTpudW1iZXIsIHVpMjpudW1iZXIsIHVpMzpudW1iZXI7XG5cdFx0dmFyIHMweDpudW1iZXIsIHMweTpudW1iZXIsIHMwejpudW1iZXI7XG5cdFx0dmFyIHMxeDpudW1iZXIsIHMxeTpudW1iZXIsIHMxejpudW1iZXI7XG5cdFx0dmFyIG5sOm51bWJlcjtcblx0XHR2YXIgaW5kaWNlczpBcnJheTxudW1iZXI+ID0gdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRJbmRleERhdGEoKS5kYXRhO1xuXG5cdFx0dmFyIHBvc2l0aW9uczpBcnJheTxudW1iZXI+ID0gdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fREFUQSkuZGF0YTtcblx0XHR2YXIgcG9zaXRpb25TdHJpZGU6bnVtYmVyID0gdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fREFUQSkuZGF0YVBlclZlcnRleDtcblx0XHR2YXIgcG9zaXRpb25PZmZzZXQ6bnVtYmVyID0gdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5QT1NJVElPTl9EQVRBKTtcblxuXHRcdHZhciB1dnM6QXJyYXk8bnVtYmVyPiA9IHRoaXMuX2hpdFJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LlVWX0RBVEEpLmRhdGE7XG5cdFx0dmFyIHV2U3RyaWRlOm51bWJlciA9IHRoaXMuX2hpdFJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5LlVWX0RBVEEpLmRhdGFQZXJWZXJ0ZXg7XG5cdFx0dmFyIHV2T2Zmc2V0Om51bWJlciA9IHRoaXMuX2hpdFJlbmRlcmFibGUuZ2V0VmVydGV4T2Zmc2V0KFRyaWFuZ2xlU3ViR2VvbWV0cnkuVVZfREFUQSk7XG5cblx0XHR2YXIgbm9ybWFsczpBcnJheTxudW1iZXI+ID0gdGhpcy5faGl0UmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuTk9STUFMX0RBVEEpLmRhdGE7XG5cdFx0dmFyIG5vcm1hbFN0cmlkZTpudW1iZXIgPSB0aGlzLl9oaXRSZW5kZXJhYmxlLmdldFZlcnRleERhdGEoVHJpYW5nbGVTdWJHZW9tZXRyeS5OT1JNQUxfREFUQSkuZGF0YVBlclZlcnRleDtcblx0XHR2YXIgbm9ybWFsT2Zmc2V0Om51bWJlciA9IHRoaXMuX2hpdFJlbmRlcmFibGUuZ2V0VmVydGV4T2Zmc2V0KFRyaWFuZ2xlU3ViR2VvbWV0cnkuTk9STUFMX0RBVEEpO1xuXG5cdFx0dGhpcy51cGRhdGVSYXkoY2FtZXJhKTtcblxuXHRcdHdoaWxlIChpIDwgbGVuKSB7XG5cdFx0XHR0MSA9IHBvc2l0aW9uT2Zmc2V0ICsgaW5kaWNlc1tpXSpwb3NpdGlvblN0cmlkZTtcblx0XHRcdHQyID0gcG9zaXRpb25PZmZzZXQgKyBpbmRpY2VzW2pdKnBvc2l0aW9uU3RyaWRlO1xuXHRcdFx0dDMgPSBwb3NpdGlvbk9mZnNldCArIGluZGljZXNba10qcG9zaXRpb25TdHJpZGU7XG5cdFx0XHR4MSA9IHBvc2l0aW9uc1t0MV07XG5cdFx0XHR5MSA9IHBvc2l0aW9uc1t0MSArIDFdO1xuXHRcdFx0ejEgPSBwb3NpdGlvbnNbdDEgKyAyXTtcblx0XHRcdHgyID0gcG9zaXRpb25zW3QyXTtcblx0XHRcdHkyID0gcG9zaXRpb25zW3QyICsgMV07XG5cdFx0XHR6MiA9IHBvc2l0aW9uc1t0MiArIDJdO1xuXHRcdFx0eDMgPSBwb3NpdGlvbnNbdDNdO1xuXHRcdFx0eTMgPSBwb3NpdGlvbnNbdDMgKyAxXTtcblx0XHRcdHozID0gcG9zaXRpb25zW3QzICsgMl07XG5cblx0XHRcdC8vIGlmIHdpdGhpbiBib3VuZHNcblx0XHRcdGlmICghKCAgICAoeCA8IHgxICYmIHggPCB4MiAmJiB4IDwgeDMpIHx8ICh5IDwgeTEgJiYgeSA8IHkyICYmIHkgPCB5MykgfHwgKHogPCB6MSAmJiB6IDwgejIgJiYgeiA8IHozKSB8fCAoeCA+IHgxICYmIHggPiB4MiAmJiB4ID4geDMpIHx8ICh5ID4geTEgJiYgeSA+IHkyICYmIHkgPiB5MykgfHwgKHogPiB6MSAmJiB6ID4gejIgJiYgeiA+IHozKSkpIHtcblxuXHRcdFx0XHQvLyBjYWxjdWxhdGUgYmFyeWNlbnRyaWMgY29vcmRzIGZvciBhcHByb3hpbWF0ZWQgcG9zaXRpb25cblx0XHRcdFx0djB4ID0geDMgLSB4MTtcblx0XHRcdFx0djB5ID0geTMgLSB5MTtcblx0XHRcdFx0djB6ID0gejMgLSB6MTtcblx0XHRcdFx0djF4ID0geDIgLSB4MTtcblx0XHRcdFx0djF5ID0geTIgLSB5MTtcblx0XHRcdFx0djF6ID0gejIgLSB6MTtcblx0XHRcdFx0djJ4ID0geCAtIHgxO1xuXHRcdFx0XHR2MnkgPSB5IC0geTE7XG5cdFx0XHRcdHYyeiA9IHogLSB6MTtcblx0XHRcdFx0ZG90MDAgPSB2MHgqdjB4ICsgdjB5KnYweSArIHYweip2MHo7XG5cdFx0XHRcdGRvdDAxID0gdjB4KnYxeCArIHYweSp2MXkgKyB2MHoqdjF6O1xuXHRcdFx0XHRkb3QwMiA9IHYweCp2MnggKyB2MHkqdjJ5ICsgdjB6KnYyejtcblx0XHRcdFx0ZG90MTEgPSB2MXgqdjF4ICsgdjF5KnYxeSArIHYxeip2MXo7XG5cdFx0XHRcdGRvdDEyID0gdjF4KnYyeCArIHYxeSp2MnkgKyB2MXoqdjJ6O1xuXHRcdFx0XHRpbnZEZW5vbSA9IDEvKGRvdDAwKmRvdDExIC0gZG90MDEqZG90MDEpO1xuXHRcdFx0XHRzID0gKGRvdDExKmRvdDAyIC0gZG90MDEqZG90MTIpKmludkRlbm9tO1xuXHRcdFx0XHR0ID0gKGRvdDAwKmRvdDEyIC0gZG90MDEqZG90MDIpKmludkRlbm9tO1xuXG5cdFx0XHRcdC8vIGlmIGluc2lkZSB0aGUgY3VycmVudCB0cmlhbmdsZSwgZmV0Y2ggZGV0YWlscyBoaXQgaW5mb3JtYXRpb25cblx0XHRcdFx0aWYgKHMgPj0gMCAmJiB0ID49IDAgJiYgKHMgKyB0KSA8PSAxKSB7XG5cblx0XHRcdFx0XHRuaTEgPSBub3JtYWxPZmZzZXQgKyBpbmRpY2VzW2ldKm5vcm1hbFN0cmlkZTtcblx0XHRcdFx0XHRuaTIgPSBub3JtYWxPZmZzZXQgKyBpbmRpY2VzW2pdKm5vcm1hbFN0cmlkZTtcblx0XHRcdFx0XHRuaTMgPSBub3JtYWxPZmZzZXQgKyBpbmRpY2VzW2tdKm5vcm1hbFN0cmlkZTtcblxuXHRcdFx0XHRcdG4xID0gaW5kaWNlc1tuaTFdICsgaW5kaWNlc1tuaTJdICsgaW5kaWNlc1tuaTNdO1xuXHRcdFx0XHRcdG4yID0gaW5kaWNlc1tuaTEgKyAxXSArIGluZGljZXNbbmkyICsgMV0gKyBpbmRpY2VzW25pMyArIDFdO1xuXHRcdFx0XHRcdG4zID0gaW5kaWNlc1tuaTEgKyAyXSArIGluZGljZXNbbmkyICsgMl0gKyBpbmRpY2VzW25pMyArIDJdO1xuXG5cdFx0XHRcdFx0bkxlbmd0aCA9IE1hdGguc3FydChuMSpuMSArIG4yKm4yICsgbjMqbjMpO1xuXG5cdFx0XHRcdFx0bjEgLz0gbkxlbmd0aDtcblx0XHRcdFx0XHRuMiAvPSBuTGVuZ3RoO1xuXHRcdFx0XHRcdG4zIC89IG5MZW5ndGg7XG5cblx0XHRcdFx0XHQvLyB0aGlzIGlzIGRlZiB0aGUgdHJpYW5nbGUsIG5vdyBjYWxjdWxhdGUgcHJlY2lzZSBjb29yZHNcblx0XHRcdFx0XHR0aGlzLmdldFByZWNpc2VQb3NpdGlvbih0aGlzLl9oaXRSZW5kZXJhYmxlLnNvdXJjZUVudGl0eS5pbnZlcnNlU2NlbmVUcmFuc2Zvcm0sIG4xLCBuMiwgbjMsIHgxLCB5MSwgejEpO1xuXG5cdFx0XHRcdFx0djJ4ID0gdGhpcy5fbG9jYWxIaXRQb3NpdGlvbi54IC0geDE7XG5cdFx0XHRcdFx0djJ5ID0gdGhpcy5fbG9jYWxIaXRQb3NpdGlvbi55IC0geTE7XG5cdFx0XHRcdFx0djJ6ID0gdGhpcy5fbG9jYWxIaXRQb3NpdGlvbi56IC0gejE7XG5cblx0XHRcdFx0XHRzMHggPSB4MiAtIHgxOyAvLyBzMCA9IHAxIC0gcDBcblx0XHRcdFx0XHRzMHkgPSB5MiAtIHkxO1xuXHRcdFx0XHRcdHMweiA9IHoyIC0gejE7XG5cdFx0XHRcdFx0czF4ID0geDMgLSB4MTsgLy8gczEgPSBwMiAtIHAwXG5cdFx0XHRcdFx0czF5ID0geTMgLSB5MTtcblx0XHRcdFx0XHRzMXogPSB6MyAtIHoxO1xuXHRcdFx0XHRcdHRoaXMuX2xvY2FsSGl0Tm9ybWFsLnggPSBzMHkqczF6IC0gczB6KnMxeTsgLy8gbiA9IHMwIHggczFcblx0XHRcdFx0XHR0aGlzLl9sb2NhbEhpdE5vcm1hbC55ID0gczB6KnMxeCAtIHMweCpzMXo7XG5cdFx0XHRcdFx0dGhpcy5fbG9jYWxIaXROb3JtYWwueiA9IHMweCpzMXkgLSBzMHkqczF4O1xuXHRcdFx0XHRcdG5sID0gMS9NYXRoLnNxcnQodGhpcy5fbG9jYWxIaXROb3JtYWwueCp0aGlzLl9sb2NhbEhpdE5vcm1hbC54ICsgdGhpcy5fbG9jYWxIaXROb3JtYWwueSp0aGlzLl9sb2NhbEhpdE5vcm1hbC55ICsgdGhpcy5fbG9jYWxIaXROb3JtYWwueip0aGlzLl9sb2NhbEhpdE5vcm1hbC56KTsgLy8gbm9ybWFsaXplIG5cblx0XHRcdFx0XHR0aGlzLl9sb2NhbEhpdE5vcm1hbC54ICo9IG5sO1xuXHRcdFx0XHRcdHRoaXMuX2xvY2FsSGl0Tm9ybWFsLnkgKj0gbmw7XG5cdFx0XHRcdFx0dGhpcy5fbG9jYWxIaXROb3JtYWwueiAqPSBubDtcblxuXHRcdFx0XHRcdGRvdDAyID0gdjB4KnYyeCArIHYweSp2MnkgKyB2MHoqdjJ6O1xuXHRcdFx0XHRcdGRvdDEyID0gdjF4KnYyeCArIHYxeSp2MnkgKyB2MXoqdjJ6O1xuXHRcdFx0XHRcdHMgPSAoZG90MTEqZG90MDIgLSBkb3QwMSpkb3QxMikqaW52RGVub207XG5cdFx0XHRcdFx0dCA9IChkb3QwMCpkb3QxMiAtIGRvdDAxKmRvdDAyKSppbnZEZW5vbTtcblxuXHRcdFx0XHRcdHVpMSA9IHV2T2Zmc2V0ICsgaW5kaWNlc1tpXSp1dlN0cmlkZVxuXHRcdFx0XHRcdHVpMiA9IHV2T2Zmc2V0ICsgaW5kaWNlc1tqXSp1dlN0cmlkZVxuXHRcdFx0XHRcdHVpMyA9IHV2T2Zmc2V0ICsgaW5kaWNlc1trXSp1dlN0cmlkZVxuXG5cdFx0XHRcdFx0dSA9IHV2c1t1aTFdO1xuXHRcdFx0XHRcdHYgPSB1dnNbdWkxICsgMV07XG5cdFx0XHRcdFx0dGhpcy5faGl0VVYueCA9IHUgKyB0Kih1dnNbdWkyXSAtIHUpICsgcyoodXZzW3VpM10gLSB1KTtcblx0XHRcdFx0XHR0aGlzLl9oaXRVVi55ID0gdiArIHQqKHV2c1t1aTIgKyAxXSAtIHYpICsgcyoodXZzW3VpMyArIDFdIC0gdik7XG5cblx0XHRcdFx0XHR0aGlzLl9mYWNlSW5kZXggPSBpO1xuXHRcdFx0XHRcdC8vVE9ETyBhZGQgYmFjayBzdWJHZW9tZXRyeUluZGV4IHZhbHVlXG5cdFx0XHRcdFx0Ly90aGlzLl9zdWJHZW9tZXRyeUluZGV4ID0gYXdheS51dGlscy5HZW9tZXRyeVV0aWxzLmdldE1lc2hTdWJHZW9tZXRyeUluZGV4KHN1Ykdlb20pO1xuXG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGkgKz0gMztcblx0XHRcdGogKz0gMztcblx0XHRcdGsgKz0gMztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRmluZHMgdGhlIHByZWNpc2UgaGl0IHBvc2l0aW9uIGJ5IHVucHJvamVjdGluZyB0aGUgc2NyZWVuIGNvb3JkaW5hdGUgYmFjayB1bnRvIHRoZSBoaXQgZmFjZSdzIHBsYW5lIGFuZFxuXHQgKiBjYWxjdWxhdGluZyB0aGUgaW50ZXJzZWN0aW9uIHBvaW50LlxuXHQgKiBAcGFyYW0gY2FtZXJhIFRoZSBjYW1lcmEgdXNlZCB0byByZW5kZXIgdGhlIG9iamVjdC5cblx0ICogQHBhcmFtIGludlNjZW5lVHJhbnNmb3JtIFRoZSBpbnZlcnNlIHNjZW5lIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBoaXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0gbnggVGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgZmFjZSdzIHBsYW5lIG5vcm1hbC5cblx0ICogQHBhcmFtIG55IFRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIGZhY2UgcGxhbmUgbm9ybWFsLlxuXHQgKiBAcGFyYW0gbnogVGhlIHotY29vcmRpbmF0ZSBvZiB0aGUgZmFjZSBwbGFuZSBub3JtYWwuXG5cdCAqIEBwYXJhbSBweCBUaGUgeC1jb29yZGluYXRlIG9mIGEgcG9pbnQgb24gdGhlIGZhY2UncyBwbGFuZSAoaWUgYSBmYWNlIHZlcnRleClcblx0ICogQHBhcmFtIHB5IFRoZSB5LWNvb3JkaW5hdGUgb2YgYSBwb2ludCBvbiB0aGUgZmFjZSdzIHBsYW5lIChpZSBhIGZhY2UgdmVydGV4KVxuXHQgKiBAcGFyYW0gcHogVGhlIHotY29vcmRpbmF0ZSBvZiBhIHBvaW50IG9uIHRoZSBmYWNlJ3MgcGxhbmUgKGllIGEgZmFjZSB2ZXJ0ZXgpXG5cdCAqL1xuXG5cdHByaXZhdGUgZ2V0UHJlY2lzZVBvc2l0aW9uKGludlNjZW5lVHJhbnNmb3JtOk1hdHJpeDNELCBueDpudW1iZXIsIG55Om51bWJlciwgbno6bnVtYmVyLCBweDpudW1iZXIsIHB5Om51bWJlciwgcHo6bnVtYmVyKVxuXHR7XG5cdFx0Ly8gY2FsY3VsYXRlIHNjcmVlbiByYXkgYW5kIGZpbmQgZXhhY3QgaW50ZXJzZWN0aW9uIHBvc2l0aW9uIHdpdGggdHJpYW5nbGVcblx0XHR2YXIgcng6bnVtYmVyLCByeTpudW1iZXIsIHJ6Om51bWJlcjtcblx0XHR2YXIgb3g6bnVtYmVyLCBveTpudW1iZXIsIG96Om51bWJlcjtcblx0XHR2YXIgdDpudW1iZXI7XG5cdFx0dmFyIHJhdzpBcnJheTxudW1iZXI+ID0gTWF0cml4M0RVdGlscy5SQVdfREFUQV9DT05UQUlORVI7XG5cdFx0dmFyIGN4Om51bWJlciA9IHRoaXMuX3JheVBvcy54LCBjeTpudW1iZXIgPSB0aGlzLl9yYXlQb3MueSwgY3o6bnVtYmVyID0gdGhpcy5fcmF5UG9zLno7XG5cblx0XHQvLyB1bnByb2plY3RlZCBwcm9qZWN0aW9uIHBvaW50LCBnaXZlcyByYXkgZGlyIGluIGNhbSBzcGFjZVxuXHRcdG94ID0gdGhpcy5fcmF5RGlyLng7XG5cdFx0b3kgPSB0aGlzLl9yYXlEaXIueTtcblx0XHRveiA9IHRoaXMuX3JheURpci56O1xuXG5cdFx0Ly8gdHJhbnNmb3JtIHJheSBkaXIgYW5kIG9yaWdpbiAoY2FtIHBvcykgdG8gb2JqZWN0IHNwYWNlXG5cdFx0Ly9pbnZTY2VuZVRyYW5zZm9ybS5jb3B5UmF3RGF0YVRvKCByYXcgICk7XG5cdFx0aW52U2NlbmVUcmFuc2Zvcm0uY29weVJhd0RhdGFUbyhyYXcpO1xuXHRcdHJ4ID0gcmF3WzBdKm94ICsgcmF3WzRdKm95ICsgcmF3WzhdKm96O1xuXHRcdHJ5ID0gcmF3WzFdKm94ICsgcmF3WzVdKm95ICsgcmF3WzldKm96O1xuXHRcdHJ6ID0gcmF3WzJdKm94ICsgcmF3WzZdKm95ICsgcmF3WzEwXSpvejtcblxuXHRcdG94ID0gcmF3WzBdKmN4ICsgcmF3WzRdKmN5ICsgcmF3WzhdKmN6ICsgcmF3WzEyXTtcblx0XHRveSA9IHJhd1sxXSpjeCArIHJhd1s1XSpjeSArIHJhd1s5XSpjeiArIHJhd1sxM107XG5cdFx0b3ogPSByYXdbMl0qY3ggKyByYXdbNl0qY3kgKyByYXdbMTBdKmN6ICsgcmF3WzE0XTtcblxuXHRcdHQgPSAoKHB4IC0gb3gpKm54ICsgKHB5IC0gb3kpKm55ICsgKHB6IC0gb3opKm56KS8ocngqbnggKyByeSpueSArIHJ6Km56KTtcblxuXHRcdHRoaXMuX2xvY2FsSGl0UG9zaXRpb24ueCA9IG94ICsgcngqdDtcblx0XHR0aGlzLl9sb2NhbEhpdFBvc2l0aW9uLnkgPSBveSArIHJ5KnQ7XG5cdFx0dGhpcy5fbG9jYWxIaXRQb3NpdGlvbi56ID0gb3ogKyByeip0O1xuXHR9XG5cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cdFx0dGhpcy5fYml0bWFwRGF0YS5kaXNwb3NlKCk7XG5cdFx0aWYgKHRoaXMuX3RyaWFuZ2xlUHJvZ3JhbSlcblx0XHRcdHRoaXMuX3RyaWFuZ2xlUHJvZ3JhbS5kaXNwb3NlKCk7XG5cblx0XHRpZiAodGhpcy5fb2JqZWN0UHJvZ3JhbSlcblx0XHRcdHRoaXMuX29iamVjdFByb2dyYW0uZGlzcG9zZSgpO1xuXG5cdFx0dGhpcy5fdHJpYW5nbGVQcm9ncmFtID0gbnVsbDtcblx0XHR0aGlzLl9vYmplY3RQcm9ncmFtID0gbnVsbDtcblx0XHR0aGlzLl9iaXRtYXBEYXRhID0gbnVsbDtcblx0XHR0aGlzLl9oaXRSZW5kZXJhYmxlID0gbnVsbDtcblx0XHR0aGlzLl9oaXRFbnRpdHkgPSBudWxsO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNoYWRlclBpY2tlcjsiXX0=
\ No newline at end of file
diff --git a/lib/core/pick/ShaderPicker.ts b/lib/core/pick/ShaderPicker.ts
new file mode 100644
index 000000000..b480e38ff
--- /dev/null
+++ b/lib/core/pick/ShaderPicker.ts
@@ -0,0 +1,560 @@
+import Debug = require("awayjs-core/lib/utils/Debug");
+import BitmapData = require("awayjs-core/lib/core/base/BitmapData");
+import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry");
+import Scene = require("awayjs-core/lib/containers/Scene");
+import View = require("awayjs-core/lib/containers/View");
+import Box = require("awayjs-core/lib/core/geom/Box");
+import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D");
+import Matrix3DUtils = require("awayjs-core/lib/core/geom/Matrix3DUtils");
+import Point = require("awayjs-core/lib/core/geom/Point");
+import Rectangle = require("awayjs-core/lib/core/geom/Rectangle");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import IPicker = require("awayjs-core/lib/core/pick/IPicker");
+import PickingCollisionVO = require("awayjs-core/lib/core/pick/PickingCollisionVO");
+import EntityCollector = require("awayjs-core/lib/core/traverse/EntityCollector");
+import Camera = require("awayjs-core/lib/entities/Camera");
+import IEntity = require("awayjs-core/lib/entities/IEntity");
+import MaterialBase = require("awayjs-core/lib/materials/MaterialBase");
+import ByteArray = require("awayjs-core/lib/utils/ByteArray");
+
+import AGALMiniAssembler = require("awayjs-stagegl/lib/aglsl/assembler/AGALMiniAssembler");
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+import ContextGLBlendFactor = require("awayjs-stagegl/lib/core/stagegl/ContextGLBlendFactor");
+import ContextGLClearMask = require("awayjs-stagegl/lib/core/stagegl/ContextGLClearMask");
+import ContextGLCompareMode = require("awayjs-stagegl/lib/core/stagegl/ContextGLCompareMode");
+import ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType");
+import ContextGLTriangleFace = require("awayjs-stagegl/lib/core/stagegl/ContextGLTriangleFace");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import IProgram = require("awayjs-stagegl/lib/core/stagegl/IProgram");
+import ITextureBase = require("awayjs-stagegl/lib/core/stagegl/ITextureBase");
+
+/**
+ * Picks a 3d object from a view or scene by performing a separate render pass on the scene around the area being picked using key color values,
+ * then reading back the color value of the pixel in the render representing the picking ray. Requires multiple passes and readbacks for retriving details
+ * on an entity that has its shaderPickingDetails property set to true.
+ *
+ * A read-back operation from any GPU is not a very efficient process, and the amount of processing used can vary significantly between different hardware.
+ *
+ * @see away.entities.Entity#shaderPickingDetails
+ *
+ * @class away.pick.ShaderPicker
+ */
+class ShaderPicker implements IPicker
+{
+ private _opaqueRenderableHead:RenderableBase;
+ private _blendedRenderableHead:RenderableBase;
+
+ private _stage:Stage;
+ private _context:IContextStageGL;
+ private _onlyMouseEnabled:boolean = true;
+
+ private _objectProgram:IProgram;
+ private _triangleProgram:IProgram;
+ private _bitmapData:BitmapData;
+ private _viewportData:Array;
+ private _boundOffsetScale:Array;
+ private _id:Array;
+
+ private _interactives:Array = new Array();
+ private _interactiveId:number;
+ private _hitColor:number;
+ private _projX:number;
+ private _projY:number;
+
+ private _hitRenderable:RenderableBase;
+ private _hitEntity:IEntity;
+ private _localHitPosition:Vector3D = new Vector3D();
+ private _hitUV:Point = new Point();
+ private _faceIndex:number;
+ private _subGeometryIndex:number;
+
+ private _localHitNormal:Vector3D = new Vector3D();
+
+ private _rayPos:Vector3D = new Vector3D();
+ private _rayDir:Vector3D = new Vector3D();
+ private _potentialFound:boolean;
+ private static MOUSE_SCISSOR_RECT:Rectangle = new Rectangle(0, 0, 1, 1);
+
+ private _shaderPickingDetails:boolean;
+
+ /**
+ * @inheritDoc
+ */
+ public get onlyMouseEnabled():boolean
+ {
+ return this._onlyMouseEnabled;
+ }
+
+ public set onlyMouseEnabled(value:boolean)
+ {
+ this._onlyMouseEnabled = value;
+ }
+
+ /**
+ * Creates a new ShaderPicker
object.
+ *
+ * @param shaderPickingDetails Determines whether the picker includes a second pass to calculate extra
+ * properties such as uv and normal coordinates.
+ */
+ constructor(shaderPickingDetails:boolean = false)
+ {
+ this._shaderPickingDetails = shaderPickingDetails;
+
+ this._id = new Array(4);
+ this._viewportData = new Array(4); // first 2 contain scale, last 2 translation
+ this._boundOffsetScale = new Array(8); // first 2 contain scale, last 2 translation
+ this._boundOffsetScale[3] = 0;
+ this._boundOffsetScale[7] = 1;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getViewCollision(x:number, y:number, view:View):PickingCollisionVO
+ {
+ var collector:EntityCollector = view.iEntityCollector;
+
+ this._stage = ( view.renderer).stage;
+
+ if (!this._stage)
+ return null;
+
+ this._context = this._stage.context;
+
+ this._viewportData[0] = view.width;
+ this._viewportData[1] = view.height;
+ this._viewportData[2] = -(this._projX = 2*x/view.width - 1);
+ this._viewportData[3] = this._projY = 2*y/view.height - 1;
+
+ // _potentialFound will be set to true if any object is actually rendered
+ this._potentialFound = false;
+
+ //reset head values
+ this._blendedRenderableHead = null;
+ this._opaqueRenderableHead = null;
+
+ this.pDraw(collector, null);
+
+ // clear buffers
+ this._context.setVertexBufferAt(0, null);
+
+ if (!this._context || !this._potentialFound)
+ return null;
+
+ if (!this._bitmapData)
+ this._bitmapData = new BitmapData(1, 1, false, 0);
+
+ this._context.drawToBitmapData(this._bitmapData);
+ this._hitColor = this._bitmapData.getPixel(0, 0);
+
+ if (!this._hitColor) {
+ this._context.present();
+ return null;
+ }
+
+ this._hitRenderable = this._interactives[this._hitColor - 1];
+ this._hitEntity = this._hitRenderable.sourceEntity;
+
+ if (this._onlyMouseEnabled && !this._hitEntity._iIsMouseEnabled())
+ return null;
+
+ var _collisionVO:PickingCollisionVO = this._hitEntity._iPickingCollisionVO;
+ if (this._shaderPickingDetails) {
+ this.getHitDetails(view.camera);
+ _collisionVO.localPosition = this._localHitPosition;
+ _collisionVO.localNormal = this._localHitNormal;
+ _collisionVO.uv = this._hitUV;
+ _collisionVO.index = this._faceIndex;
+ //_collisionVO.subGeometryIndex = this._subGeometryIndex;
+
+ } else {
+ _collisionVO.localPosition = null;
+ _collisionVO.localNormal = null;
+ _collisionVO.uv = null;
+ _collisionVO.index = 0;
+ //_collisionVO.subGeometryIndex = 0;
+ }
+
+ return _collisionVO;
+ }
+
+ //*/
+ /**
+ * @inheritDoc
+ */
+ public getSceneCollision(position:Vector3D, direction:Vector3D, scene:Scene):PickingCollisionVO
+ {
+ return null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public pDraw(entityCollector:EntityCollector, target:ITextureBase)
+ {
+
+ var camera:Camera = entityCollector.camera;
+
+ this._context.clear(0, 0, 0, 1);
+ this._stage.scissorRect = ShaderPicker.MOUSE_SCISSOR_RECT;
+
+ this._interactives.length = this._interactiveId = 0;
+
+ if (!this._objectProgram)
+ this.initObjectProgram();
+
+ this._context.setBlendFactors(ContextGLBlendFactor.ONE, ContextGLBlendFactor.ZERO);
+ this._context.setDepthTest(true, ContextGLCompareMode.LESS);
+ this._context.setProgram(this._objectProgram);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 4, this._viewportData, 1);
+ //this.drawRenderables(entityCollector.opaqueRenderableHead, camera);
+ //this.drawRenderables(entityCollector.blendedRenderableHead, camera);
+ //TODO: reimplement ShaderPicker inheriting from RendererBase
+ }
+
+ /**
+ * Draw a list of renderables.
+ * @param renderables The renderables to draw.
+ * @param camera The camera for which to render.
+ */
+ private drawRenderables(renderable:RenderableBase, camera:Camera)
+ {
+ var matrix:Matrix3D = Matrix3DUtils.CALCULATION_MATRIX;
+ var viewProjection:Matrix3D = camera.viewProjection;
+
+ while (renderable) {
+ // it's possible that the renderable was already removed from the scene
+ if (!renderable.sourceEntity.scene || !renderable.sourceEntity._iIsMouseEnabled()) {
+ renderable = renderable.next;
+ continue;
+ }
+
+ this._potentialFound = true;
+
+ this._context.setCulling(( renderable.materialOwner.material).bothSides? ContextGLTriangleFace.NONE : ContextGLTriangleFace.BACK, camera.projection.coordinateSystem);
+
+ this._interactives[this._interactiveId++] = renderable;
+ // color code so that reading from bitmapdata will contain the correct value
+ this._id[1] = (this._interactiveId >> 8)/255; // on green channel
+ this._id[2] = (this._interactiveId & 0xff)/255; // on blue channel
+
+ matrix.copyFrom(renderable.sourceEntity.getRenderSceneTransform(camera));
+ matrix.append(viewProjection);
+ this._context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, matrix, true);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, 0, this._id, 1);
+ this._context.activateBuffer(0, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ this._context.drawTriangles(this._context.getIndexBuffer(renderable.getIndexData()), 0, renderable.numTriangles);
+
+ renderable = renderable.next;
+ }
+
+ }
+
+ private updateRay(camera:Camera)
+ {
+ this._rayPos = camera.scenePosition;
+
+ this._rayDir = camera.getRay(this._projX, this._projY, 1);
+ this._rayDir.normalize();
+ }
+
+ /**
+ * Creates the Program that color-codes objects.
+ */
+ private initObjectProgram()
+ {
+ var vertexCode:string;
+ var fragmentCode:string;
+
+ this._objectProgram = this._context.createProgram();
+
+ vertexCode = "m44 vt0, va0, vc0 \n" + "mul vt1.xy, vt0.w, vc4.zw \n" + "add vt0.xy, vt0.xy, vt1.xy \n" + "mul vt0.xy, vt0.xy, vc4.xy \n" + "mov op, vt0 \n";
+ fragmentCode = "mov oc, fc0"; // write identifier
+
+ Debug.throwPIR('ShaderPicker', 'initTriangleProgram', 'Dependency: initObjectProgram')
+ //_objectProgram.upload(new AGALMiniAssembler().assemble(ContextGLProgramType.VERTEX, vertexCode),new AGALMiniAssembler().assemble(ContextGLProgramType.FRAGMENT, fragmentCode));
+ }
+
+ /**
+ * Creates the Program that renders positions.
+ */
+
+ private initTriangleProgram()
+ {
+ var vertexCode:string;
+ var fragmentCode:string;
+
+ this._triangleProgram = this._context.createProgram();
+
+ // todo: add animation code
+ vertexCode = "add vt0, va0, vc5 \n" + "mul vt0, vt0, vc6 \n" + "mov v0, vt0 \n" + "m44 vt0, va0, vc0 \n" + "mul vt1.xy, vt0.w, vc4.zw \n" + "add vt0.xy, vt0.xy, vt1.xy \n" + "mul vt0.xy, vt0.xy, vc4.xy \n" + "mov op, vt0 \n";
+ fragmentCode = "mov oc, v0"; // write identifier
+
+ var vertexByteCode:ByteArray = (new AGALMiniAssembler().assemble("part vertex 1\n" + vertexCode + "endpart"))['vertex'].data;
+ var fragmentByteCode:ByteArray = (new AGALMiniAssembler().assemble("part fragment 1\n" + fragmentCode + "endpart"))['fragment'].data;
+ this._triangleProgram.upload(vertexByteCode, fragmentByteCode);
+ }
+
+ /**
+ * Gets more detailed information about the hir position, if required.
+ * @param camera The camera used to view the hit object.
+ */
+ private getHitDetails(camera:Camera)
+ {
+ this.getApproximatePosition(camera);
+ this.getPreciseDetails(camera);
+ }
+
+ /**
+ * Finds a first-guess approximate position about the hit position.
+ *
+ * @param camera The camera used to view the hit object.
+ */
+ private getApproximatePosition(camera:Camera)
+ {
+ var bounds:Box = this._hitRenderable.sourceEntity.bounds.aabb;
+ var col:number;
+ var scX:number, scY:number, scZ:number;
+ var offsX:number, offsY:number, offsZ:number;
+ var localViewProjection:Matrix3D = Matrix3DUtils.CALCULATION_MATRIX;
+
+ localViewProjection.copyFrom(this._hitRenderable.sourceEntity.getRenderSceneTransform(camera));
+ localViewProjection.append(camera.viewProjection);
+ if (!this._triangleProgram) {
+ this.initTriangleProgram();
+ }
+
+ this._boundOffsetScale[4] = 1/(scX = bounds.width);
+ this._boundOffsetScale[5] = 1/(scY = bounds.height);
+ this._boundOffsetScale[6] = 1/(scZ = bounds.depth);
+ this._boundOffsetScale[0] = offsX = -bounds.x;
+ this._boundOffsetScale[1] = offsY = -bounds.y;
+ this._boundOffsetScale[2] = offsZ = -bounds.z;
+
+ this._context.setProgram(this._triangleProgram);
+ this._context.clear(0, 0, 0, 0, 1, 0, ContextGLClearMask.DEPTH);
+ this._context.setScissorRectangle(ShaderPicker.MOUSE_SCISSOR_RECT);
+ this._context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, localViewProjection, true);
+ this._context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 5, this._boundOffsetScale, 2);
+
+ this._context.activateBuffer(0, this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA), this._hitRenderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT);
+ this._context.drawTriangles(this._context.getIndexBuffer(this._hitRenderable.getIndexData()), 0, this._hitRenderable.numTriangles);
+
+ this._context.drawToBitmapData(this._bitmapData);
+
+ col = this._bitmapData.getPixel(0, 0);
+
+ this._localHitPosition.x = ((col >> 16) & 0xff)*scX/255 - offsX;
+ this._localHitPosition.y = ((col >> 8) & 0xff)*scY/255 - offsY;
+ this._localHitPosition.z = (col & 0xff)*scZ/255 - offsZ;
+ }
+
+ /**
+ * Use the approximate position info to find the face under the mouse position from which we can derive the precise
+ * ray-face intersection point, then use barycentric coordinates to figure out the uv coordinates, etc.
+ * @param camera The camera used to view the hit object.
+ */
+ private getPreciseDetails(camera:Camera)
+ {
+ var len:number = indices.length;
+ var x1:number, y1:number, z1:number;
+ var x2:number, y2:number, z2:number;
+ var x3:number, y3:number, z3:number;
+ var i:number = 0, j:number = 1, k:number = 2;
+ var t1:number, t2:number, t3:number;
+ var v0x:number, v0y:number, v0z:number;
+ var v1x:number, v1y:number, v1z:number;
+ var v2x:number, v2y:number, v2z:number;
+ var ni1:number, ni2:number, ni3:number;
+ var n1:number, n2:number, n3:number, nLength:number;
+ var dot00:number, dot01:number, dot02:number, dot11:number, dot12:number;
+ var s:number, t:number, invDenom:number;
+ var x:number = this._localHitPosition.x, y:number = this._localHitPosition.y, z:number = this._localHitPosition.z;
+ var u:number, v:number;
+ var ui1:number, ui2:number, ui3:number;
+ var s0x:number, s0y:number, s0z:number;
+ var s1x:number, s1y:number, s1z:number;
+ var nl:number;
+ var indices:Array = this._hitRenderable.getIndexData().data;
+
+ var positions:Array = this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA).data;
+ var positionStride:number = this._hitRenderable.getVertexData(TriangleSubGeometry.POSITION_DATA).dataPerVertex;
+ var positionOffset:number = this._hitRenderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA);
+
+ var uvs:Array = this._hitRenderable.getVertexData(TriangleSubGeometry.UV_DATA).data;
+ var uvStride:number = this._hitRenderable.getVertexData(TriangleSubGeometry.UV_DATA).dataPerVertex;
+ var uvOffset:number = this._hitRenderable.getVertexOffset(TriangleSubGeometry.UV_DATA);
+
+ var normals:Array = this._hitRenderable.getVertexData(TriangleSubGeometry.NORMAL_DATA).data;
+ var normalStride:number = this._hitRenderable.getVertexData(TriangleSubGeometry.NORMAL_DATA).dataPerVertex;
+ var normalOffset:number = this._hitRenderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA);
+
+ this.updateRay(camera);
+
+ while (i < len) {
+ t1 = positionOffset + indices[i]*positionStride;
+ t2 = positionOffset + indices[j]*positionStride;
+ t3 = positionOffset + indices[k]*positionStride;
+ x1 = positions[t1];
+ y1 = positions[t1 + 1];
+ z1 = positions[t1 + 2];
+ x2 = positions[t2];
+ y2 = positions[t2 + 1];
+ z2 = positions[t2 + 2];
+ x3 = positions[t3];
+ y3 = positions[t3 + 1];
+ z3 = positions[t3 + 2];
+
+ // if within bounds
+ if (!( (x < x1 && x < x2 && x < x3) || (y < y1 && y < y2 && y < y3) || (z < z1 && z < z2 && z < z3) || (x > x1 && x > x2 && x > x3) || (y > y1 && y > y2 && y > y3) || (z > z1 && z > z2 && z > z3))) {
+
+ // calculate barycentric coords for approximated position
+ v0x = x3 - x1;
+ v0y = y3 - y1;
+ v0z = z3 - z1;
+ v1x = x2 - x1;
+ v1y = y2 - y1;
+ v1z = z2 - z1;
+ v2x = x - x1;
+ v2y = y - y1;
+ v2z = z - z1;
+ dot00 = v0x*v0x + v0y*v0y + v0z*v0z;
+ dot01 = v0x*v1x + v0y*v1y + v0z*v1z;
+ dot02 = v0x*v2x + v0y*v2y + v0z*v2z;
+ dot11 = v1x*v1x + v1y*v1y + v1z*v1z;
+ dot12 = v1x*v2x + v1y*v2y + v1z*v2z;
+ invDenom = 1/(dot00*dot11 - dot01*dot01);
+ s = (dot11*dot02 - dot01*dot12)*invDenom;
+ t = (dot00*dot12 - dot01*dot02)*invDenom;
+
+ // if inside the current triangle, fetch details hit information
+ if (s >= 0 && t >= 0 && (s + t) <= 1) {
+
+ ni1 = normalOffset + indices[i]*normalStride;
+ ni2 = normalOffset + indices[j]*normalStride;
+ ni3 = normalOffset + indices[k]*normalStride;
+
+ n1 = indices[ni1] + indices[ni2] + indices[ni3];
+ n2 = indices[ni1 + 1] + indices[ni2 + 1] + indices[ni3 + 1];
+ n3 = indices[ni1 + 2] + indices[ni2 + 2] + indices[ni3 + 2];
+
+ nLength = Math.sqrt(n1*n1 + n2*n2 + n3*n3);
+
+ n1 /= nLength;
+ n2 /= nLength;
+ n3 /= nLength;
+
+ // this is def the triangle, now calculate precise coords
+ this.getPrecisePosition(this._hitRenderable.sourceEntity.inverseSceneTransform, n1, n2, n3, x1, y1, z1);
+
+ v2x = this._localHitPosition.x - x1;
+ v2y = this._localHitPosition.y - y1;
+ v2z = this._localHitPosition.z - z1;
+
+ s0x = x2 - x1; // s0 = p1 - p0
+ s0y = y2 - y1;
+ s0z = z2 - z1;
+ s1x = x3 - x1; // s1 = p2 - p0
+ s1y = y3 - y1;
+ s1z = z3 - z1;
+ this._localHitNormal.x = s0y*s1z - s0z*s1y; // n = s0 x s1
+ this._localHitNormal.y = s0z*s1x - s0x*s1z;
+ this._localHitNormal.z = s0x*s1y - s0y*s1x;
+ nl = 1/Math.sqrt(this._localHitNormal.x*this._localHitNormal.x + this._localHitNormal.y*this._localHitNormal.y + this._localHitNormal.z*this._localHitNormal.z); // normalize n
+ this._localHitNormal.x *= nl;
+ this._localHitNormal.y *= nl;
+ this._localHitNormal.z *= nl;
+
+ dot02 = v0x*v2x + v0y*v2y + v0z*v2z;
+ dot12 = v1x*v2x + v1y*v2y + v1z*v2z;
+ s = (dot11*dot02 - dot01*dot12)*invDenom;
+ t = (dot00*dot12 - dot01*dot02)*invDenom;
+
+ ui1 = uvOffset + indices[i]*uvStride
+ ui2 = uvOffset + indices[j]*uvStride
+ ui3 = uvOffset + indices[k]*uvStride
+
+ u = uvs[ui1];
+ v = uvs[ui1 + 1];
+ this._hitUV.x = u + t*(uvs[ui2] - u) + s*(uvs[ui3] - u);
+ this._hitUV.y = v + t*(uvs[ui2 + 1] - v) + s*(uvs[ui3 + 1] - v);
+
+ this._faceIndex = i;
+ //TODO add back subGeometryIndex value
+ //this._subGeometryIndex = away.utils.GeometryUtils.getMeshSubGeometryIndex(subGeom);
+
+ return;
+ }
+ }
+
+ i += 3;
+ j += 3;
+ k += 3;
+ }
+ }
+
+ /**
+ * Finds the precise hit position by unprojecting the screen coordinate back unto the hit face's plane and
+ * calculating the intersection point.
+ * @param camera The camera used to render the object.
+ * @param invSceneTransform The inverse scene transformation of the hit object.
+ * @param nx The x-coordinate of the face's plane normal.
+ * @param ny The y-coordinate of the face plane normal.
+ * @param nz The z-coordinate of the face plane normal.
+ * @param px The x-coordinate of a point on the face's plane (ie a face vertex)
+ * @param py The y-coordinate of a point on the face's plane (ie a face vertex)
+ * @param pz The z-coordinate of a point on the face's plane (ie a face vertex)
+ */
+
+ private getPrecisePosition(invSceneTransform:Matrix3D, nx:number, ny:number, nz:number, px:number, py:number, pz:number)
+ {
+ // calculate screen ray and find exact intersection position with triangle
+ var rx:number, ry:number, rz:number;
+ var ox:number, oy:number, oz:number;
+ var t:number;
+ var raw:Array = Matrix3DUtils.RAW_DATA_CONTAINER;
+ var cx:number = this._rayPos.x, cy:number = this._rayPos.y, cz:number = this._rayPos.z;
+
+ // unprojected projection point, gives ray dir in cam space
+ ox = this._rayDir.x;
+ oy = this._rayDir.y;
+ oz = this._rayDir.z;
+
+ // transform ray dir and origin (cam pos) to object space
+ //invSceneTransform.copyRawDataTo( raw );
+ invSceneTransform.copyRawDataTo(raw);
+ rx = raw[0]*ox + raw[4]*oy + raw[8]*oz;
+ ry = raw[1]*ox + raw[5]*oy + raw[9]*oz;
+ rz = raw[2]*ox + raw[6]*oy + raw[10]*oz;
+
+ ox = raw[0]*cx + raw[4]*cy + raw[8]*cz + raw[12];
+ oy = raw[1]*cx + raw[5]*cy + raw[9]*cz + raw[13];
+ oz = raw[2]*cx + raw[6]*cy + raw[10]*cz + raw[14];
+
+ t = ((px - ox)*nx + (py - oy)*ny + (pz - oz)*nz)/(rx*nx + ry*ny + rz*nz);
+
+ this._localHitPosition.x = ox + rx*t;
+ this._localHitPosition.y = oy + ry*t;
+ this._localHitPosition.z = oz + rz*t;
+ }
+
+ public dispose()
+ {
+ this._bitmapData.dispose();
+ if (this._triangleProgram)
+ this._triangleProgram.dispose();
+
+ if (this._objectProgram)
+ this._objectProgram.dispose();
+
+ this._triangleProgram = null;
+ this._objectProgram = null;
+ this._bitmapData = null;
+ this._hitRenderable = null;
+ this._hitEntity = null;
+ }
+}
+
+export = ShaderPicker;
\ No newline at end of file
diff --git a/lib/events/AnimationStateEvent.js b/lib/events/AnimationStateEvent.js
new file mode 100755
index 000000000..dcc3ef3ac
--- /dev/null
+++ b/lib/events/AnimationStateEvent.js
@@ -0,0 +1,73 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var Event = require("awayjs-core/lib/events/Event");
+/**
+ * Dispatched to notify changes in an animation state's state.
+ */
+var AnimationStateEvent = (function (_super) {
+ __extends(AnimationStateEvent, _super);
+ /**
+ * Create a new AnimatonStateEvent
+ *
+ * @param type The event type.
+ * @param animator The animation state object that is the subject of this event.
+ * @param animationNode The animation node inside the animation state from which the event originated.
+ */
+ function AnimationStateEvent(type, animator, animationState, animationNode) {
+ _super.call(this, type);
+ this._animator = animator;
+ this._animationState = animationState;
+ this._animationNode = animationNode;
+ }
+ Object.defineProperty(AnimationStateEvent.prototype, "animator", {
+ /**
+ * The animator object that is the subject of this event.
+ */
+ get: function () {
+ return this._animator;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationStateEvent.prototype, "animationState", {
+ /**
+ * The animation state object that is the subject of this event.
+ */
+ get: function () {
+ return this._animationState;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnimationStateEvent.prototype, "animationNode", {
+ /**
+ * The animation node inside the animation state from which the event originated.
+ */
+ get: function () {
+ return this._animationNode;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Clones the event.
+ *
+ * @return An exact duplicate of the current object.
+ */
+ AnimationStateEvent.prototype.clone = function () {
+ return new AnimationStateEvent(this.type, this._animator, this._animationState, this._animationNode);
+ };
+ /**
+ * Dispatched when a non-looping clip node inside an animation state reaches the end of its timeline.
+ */
+ AnimationStateEvent.PLAYBACK_COMPLETE = "playbackComplete";
+ AnimationStateEvent.TRANSITION_COMPLETE = "transitionComplete";
+ return AnimationStateEvent;
+})(Event);
+module.exports = AnimationStateEvent;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImV2ZW50cy9hbmltYXRpb25zdGF0ZWV2ZW50LnRzIl0sIm5hbWVzIjpbIkFuaW1hdGlvblN0YXRlRXZlbnQiLCJBbmltYXRpb25TdGF0ZUV2ZW50LmNvbnN0cnVjdG9yIiwiQW5pbWF0aW9uU3RhdGVFdmVudC5hbmltYXRvciIsIkFuaW1hdGlvblN0YXRlRXZlbnQuYW5pbWF0aW9uU3RhdGUiLCJBbmltYXRpb25TdGF0ZUV2ZW50LmFuaW1hdGlvbk5vZGUiLCJBbmltYXRpb25TdGF0ZUV2ZW50LmNsb25lIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxJQUFPLEtBQUssV0FBaUIsOEJBQThCLENBQUMsQ0FBQztBQUs3RCxBQUdBOztHQURHO0lBQ0csbUJBQW1CO0lBQVNBLFVBQTVCQSxtQkFBbUJBLFVBQWNBO0lBYXRDQTs7Ozs7O09BTUdBO0lBQ0hBLFNBcEJLQSxtQkFBbUJBLENBb0JaQSxJQUFXQSxFQUFFQSxRQUFxQkEsRUFBRUEsY0FBOEJBLEVBQUVBLGFBQStCQTtRQUU5R0Msa0JBQU1BLElBQUlBLENBQUNBLENBQUNBO1FBRVpBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLFFBQVFBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxjQUFjQSxDQUFDQTtRQUN0Q0EsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsYUFBYUEsQ0FBQ0E7SUFDckNBLENBQUNBO0lBS0RELHNCQUFXQSx5Q0FBUUE7UUFIbkJBOztXQUVHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN2QkEsQ0FBQ0E7OztPQUFBRjtJQUtEQSxzQkFBV0EsK0NBQWNBO1FBSHpCQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDN0JBLENBQUNBOzs7T0FBQUg7SUFLREEsc0JBQVdBLDhDQUFhQTtRQUh4QkE7O1dBRUdBO2FBQ0hBO1lBRUNJLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBO1FBQzVCQSxDQUFDQTs7O09BQUFKO0lBRURBOzs7O09BSUdBO0lBQ0lBLG1DQUFLQSxHQUFaQTtRQUVDSyxNQUFNQSxDQUFDQSxJQUFJQSxtQkFBbUJBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLEVBQUVBLElBQUlBLENBQUNBLFNBQVNBLEVBQUVBLElBQUlBLENBQUNBLGVBQWVBLEVBQUVBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBO0lBQ3RHQSxDQUFDQTtJQTNEREw7O09BRUdBO0lBQ1dBLHFDQUFpQkEsR0FBVUEsa0JBQWtCQSxDQUFDQTtJQUU5Q0EsdUNBQW1CQSxHQUFVQSxvQkFBb0JBLENBQUNBO0lBdURqRUEsMEJBQUNBO0FBQURBLENBOURBLEFBOERDQSxFQTlEaUMsS0FBSyxFQThEdEM7QUFFRCxBQUE2QixpQkFBcEIsbUJBQW1CLENBQUMiLCJmaWxlIjoiZXZlbnRzL0FuaW1hdGlvblN0YXRlRXZlbnQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQW5pbWF0aW9uTm9kZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9hbmltYXRvcnMvbm9kZXMvQW5pbWF0aW9uTm9kZUJhc2VcIik7XG5pbXBvcnQgRXZlbnRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvRXZlbnRcIik7XG5cbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBJQW5pbWF0aW9uU3RhdGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSUFuaW1hdGlvblN0YXRlXCIpO1xuXG4vKipcbiAqIERpc3BhdGNoZWQgdG8gbm90aWZ5IGNoYW5nZXMgaW4gYW4gYW5pbWF0aW9uIHN0YXRlJ3Mgc3RhdGUuXG4gKi9cbmNsYXNzIEFuaW1hdGlvblN0YXRlRXZlbnQgZXh0ZW5kcyBFdmVudFxue1xuXHQvKipcblx0ICogRGlzcGF0Y2hlZCB3aGVuIGEgbm9uLWxvb3BpbmcgY2xpcCBub2RlIGluc2lkZSBhbiBhbmltYXRpb24gc3RhdGUgcmVhY2hlcyB0aGUgZW5kIG9mIGl0cyB0aW1lbGluZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgUExBWUJBQ0tfQ09NUExFVEU6c3RyaW5nID0gXCJwbGF5YmFja0NvbXBsZXRlXCI7XG5cblx0cHVibGljIHN0YXRpYyBUUkFOU0lUSU9OX0NPTVBMRVRFOnN0cmluZyA9IFwidHJhbnNpdGlvbkNvbXBsZXRlXCI7XG5cblx0cHJpdmF0ZSBfYW5pbWF0b3I6QW5pbWF0b3JCYXNlO1xuXHRwcml2YXRlIF9hbmltYXRpb25TdGF0ZTpJQW5pbWF0aW9uU3RhdGU7XG5cdHByaXZhdGUgX2FuaW1hdGlvbk5vZGU6QW5pbWF0aW9uTm9kZUJhc2U7XG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIG5ldyA8Y29kZT5BbmltYXRvblN0YXRlRXZlbnQ8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSB0eXBlIFRoZSBldmVudCB0eXBlLlxuXHQgKiBAcGFyYW0gYW5pbWF0b3IgVGhlIGFuaW1hdGlvbiBzdGF0ZSBvYmplY3QgdGhhdCBpcyB0aGUgc3ViamVjdCBvZiB0aGlzIGV2ZW50LlxuXHQgKiBAcGFyYW0gYW5pbWF0aW9uTm9kZSBUaGUgYW5pbWF0aW9uIG5vZGUgaW5zaWRlIHRoZSBhbmltYXRpb24gc3RhdGUgZnJvbSB3aGljaCB0aGUgZXZlbnQgb3JpZ2luYXRlZC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHR5cGU6c3RyaW5nLCBhbmltYXRvcjpBbmltYXRvckJhc2UsIGFuaW1hdGlvblN0YXRlOklBbmltYXRpb25TdGF0ZSwgYW5pbWF0aW9uTm9kZTpBbmltYXRpb25Ob2RlQmFzZSlcblx0e1xuXHRcdHN1cGVyKHR5cGUpO1xuXG5cdFx0dGhpcy5fYW5pbWF0b3IgPSBhbmltYXRvcjtcblx0XHR0aGlzLl9hbmltYXRpb25TdGF0ZSA9IGFuaW1hdGlvblN0YXRlO1xuXHRcdHRoaXMuX2FuaW1hdGlvbk5vZGUgPSBhbmltYXRpb25Ob2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBhbmltYXRvciBvYmplY3QgdGhhdCBpcyB0aGUgc3ViamVjdCBvZiB0aGlzIGV2ZW50LlxuXHQgKi9cblx0cHVibGljIGdldCBhbmltYXRvcigpOkFuaW1hdG9yQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2FuaW1hdG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBhbmltYXRpb24gc3RhdGUgb2JqZWN0IHRoYXQgaXMgdGhlIHN1YmplY3Qgb2YgdGhpcyBldmVudC5cblx0ICovXG5cdHB1YmxpYyBnZXQgYW5pbWF0aW9uU3RhdGUoKTpJQW5pbWF0aW9uU3RhdGVcblx0e1xuXHRcdHJldHVybiB0aGlzLl9hbmltYXRpb25TdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW5pbWF0aW9uIG5vZGUgaW5zaWRlIHRoZSBhbmltYXRpb24gc3RhdGUgZnJvbSB3aGljaCB0aGUgZXZlbnQgb3JpZ2luYXRlZC5cblx0ICovXG5cdHB1YmxpYyBnZXQgYW5pbWF0aW9uTm9kZSgpOkFuaW1hdGlvbk5vZGVCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYW5pbWF0aW9uTm9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9uZXMgdGhlIGV2ZW50LlxuXHQgKlxuXHQgKiBAcmV0dXJuIEFuIGV4YWN0IGR1cGxpY2F0ZSBvZiB0aGUgY3VycmVudCBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgY2xvbmUoKTpFdmVudFxuXHR7XG5cdFx0cmV0dXJuIG5ldyBBbmltYXRpb25TdGF0ZUV2ZW50KHRoaXMudHlwZSwgdGhpcy5fYW5pbWF0b3IsIHRoaXMuX2FuaW1hdGlvblN0YXRlLCB0aGlzLl9hbmltYXRpb25Ob2RlKTtcblx0fVxufVxuXG5leHBvcnQgPSBBbmltYXRpb25TdGF0ZUV2ZW50OyJdfQ==
\ No newline at end of file
diff --git a/lib/events/AnimationStateEvent.ts b/lib/events/AnimationStateEvent.ts
new file mode 100644
index 000000000..cc709ce9e
--- /dev/null
+++ b/lib/events/AnimationStateEvent.ts
@@ -0,0 +1,74 @@
+import AnimationNodeBase = require("awayjs-core/lib/animators/nodes/AnimationNodeBase");
+import Event = require("awayjs-core/lib/events/Event");
+
+import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase");
+import IAnimationState = require("awayjs-stagegl/lib/animators/states/IAnimationState");
+
+/**
+ * Dispatched to notify changes in an animation state's state.
+ */
+class AnimationStateEvent extends Event
+{
+ /**
+ * Dispatched when a non-looping clip node inside an animation state reaches the end of its timeline.
+ */
+ public static PLAYBACK_COMPLETE:string = "playbackComplete";
+
+ public static TRANSITION_COMPLETE:string = "transitionComplete";
+
+ private _animator:AnimatorBase;
+ private _animationState:IAnimationState;
+ private _animationNode:AnimationNodeBase;
+
+ /**
+ * Create a new AnimatonStateEvent
+ *
+ * @param type The event type.
+ * @param animator The animation state object that is the subject of this event.
+ * @param animationNode The animation node inside the animation state from which the event originated.
+ */
+ constructor(type:string, animator:AnimatorBase, animationState:IAnimationState, animationNode:AnimationNodeBase)
+ {
+ super(type);
+
+ this._animator = animator;
+ this._animationState = animationState;
+ this._animationNode = animationNode;
+ }
+
+ /**
+ * The animator object that is the subject of this event.
+ */
+ public get animator():AnimatorBase
+ {
+ return this._animator;
+ }
+
+ /**
+ * The animation state object that is the subject of this event.
+ */
+ public get animationState():IAnimationState
+ {
+ return this._animationState;
+ }
+
+ /**
+ * The animation node inside the animation state from which the event originated.
+ */
+ public get animationNode():AnimationNodeBase
+ {
+ return this._animationNode;
+ }
+
+ /**
+ * Clones the event.
+ *
+ * @return An exact duplicate of the current object.
+ */
+ public clone():Event
+ {
+ return new AnimationStateEvent(this.type, this._animator, this._animationState, this._animationNode);
+ }
+}
+
+export = AnimationStateEvent;
\ No newline at end of file
diff --git a/lib/materials/methods/AmbientEnvMapMethod.js b/lib/materials/methods/AmbientEnvMapMethod.js
new file mode 100755
index 000000000..e67d79289
--- /dev/null
+++ b/lib/materials/methods/AmbientEnvMapMethod.js
@@ -0,0 +1,69 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var AmbientBasicMethod = require("awayjs-stagegl/lib/materials/methods/AmbientBasicMethod");
+var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+/**
+ * AmbientEnvMapMethod provides a diffuse shading method that uses a diffuse irradiance environment map to
+ * approximate global lighting rather than lights.
+ */
+var AmbientEnvMapMethod = (function (_super) {
+ __extends(AmbientEnvMapMethod, _super);
+ /**
+ * Creates a new AmbientEnvMapMethod
object.
+ *
+ * @param envMap The cube environment map to use for the ambient lighting.
+ */
+ function AmbientEnvMapMethod(envMap) {
+ _super.call(this);
+ this._cubeTexture = envMap;
+ }
+ /**
+ * @inheritDoc
+ */
+ AmbientEnvMapMethod.prototype.iInitVO = function (shaderObject, methodVO) {
+ _super.prototype.iInitVO.call(this, shaderObject, methodVO);
+ methodVO.needsNormals = true;
+ };
+ Object.defineProperty(AmbientEnvMapMethod.prototype, "envMap", {
+ /**
+ * The cube environment map to use for the diffuse lighting.
+ */
+ get: function () {
+ return this._cubeTexture;
+ },
+ set: function (value) {
+ this._cubeTexture = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ AmbientEnvMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ stage.context.activateCubeTexture(methodVO.texturesIndex, this._cubeTexture);
+ };
+ /**
+ * @inheritDoc
+ */
+ AmbientEnvMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, regCache, sharedRegisters) {
+ var code = "";
+ var ambientInputRegister;
+ var cubeMapReg = regCache.getFreeTextureReg();
+ methodVO.texturesIndex = cubeMapReg.index;
+ code += ShaderCompilerHelper.getTexCubeSampleCode(targetReg, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, sharedRegisters.normalFragment);
+ ambientInputRegister = regCache.getFreeFragmentConstant();
+ methodVO.fragmentConstantsIndex = ambientInputRegister.index;
+ code += "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + ambientInputRegister + ".xyz\n";
+ return code;
+ };
+ return AmbientEnvMapMethod;
+})(AmbientBasicMethod);
+module.exports = AmbientEnvMapMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2FtYmllbnRlbnZtYXBtZXRob2QudHMiXSwibmFtZXMiOlsiQW1iaWVudEVudk1hcE1ldGhvZCIsIkFtYmllbnRFbnZNYXBNZXRob2QuY29uc3RydWN0b3IiLCJBbWJpZW50RW52TWFwTWV0aG9kLmlJbml0Vk8iLCJBbWJpZW50RW52TWFwTWV0aG9kLmVudk1hcCIsIkFtYmllbnRFbnZNYXBNZXRob2QuaUFjdGl2YXRlIiwiQW1iaWVudEVudk1hcE1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFTQSxJQUFPLGtCQUFrQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFDbEcsSUFBTyxvQkFBb0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBRXBHLEFBSUE7OztHQURHO0lBQ0csbUJBQW1CO0lBQVNBLFVBQTVCQSxtQkFBbUJBLFVBQTJCQTtJQUluREE7Ozs7T0FJR0E7SUFDSEEsU0FUS0EsbUJBQW1CQSxDQVNaQSxNQUFzQkE7UUFFakNDLGlCQUFPQSxDQUFDQTtRQUNSQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtJQUM1QkEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLHFDQUFPQSxHQUFkQSxVQUFlQSxZQUE2QkEsRUFBRUEsUUFBaUJBO1FBRTlERSxnQkFBS0EsQ0FBQ0EsT0FBT0EsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7UUFFdENBLFFBQVFBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBO0lBQzlCQSxDQUFDQTtJQUtERixzQkFBV0EsdUNBQU1BO1FBSGpCQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0E7UUFDMUJBLENBQUNBO2FBRURILFVBQWtCQSxLQUFxQkE7WUFFdENHLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLEtBQUtBLENBQUNBO1FBQzNCQSxDQUFDQTs7O09BTEFIO0lBT0RBOztPQUVHQTtJQUNJQSx1Q0FBU0EsR0FBaEJBLFVBQWlCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLEtBQVdBO1FBRTdFSSxnQkFBS0EsQ0FBQ0EsU0FBU0EsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFFNUJBLEtBQUtBLENBQUNBLE9BQVFBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsYUFBYUEsRUFBRUEsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0E7SUFDbEdBLENBQUNBO0lBRURKOztPQUVHQTtJQUNJQSw4Q0FBZ0JBLEdBQXZCQSxVQUF3QkEsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxTQUErQkEsRUFBRUEsUUFBNEJBLEVBQUVBLGVBQWtDQTtRQUUxS0ssSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLG9CQUEwQ0EsQ0FBQ0E7UUFDL0NBLElBQUlBLFVBQVVBLEdBQXlCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLEVBQUVBLENBQUNBO1FBQ3BFQSxRQUFRQSxDQUFDQSxhQUFhQSxHQUFHQSxVQUFVQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUUxQ0EsSUFBSUEsSUFBSUEsb0JBQW9CQSxDQUFDQSxvQkFBb0JBLENBQUNBLFNBQVNBLEVBQUVBLFVBQVVBLEVBQUVBLElBQUlBLENBQUNBLFlBQVlBLEVBQUVBLFlBQVlBLENBQUNBLGlCQUFpQkEsRUFBRUEsWUFBWUEsQ0FBQ0EsYUFBYUEsRUFBRUEsZUFBZUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFeExBLG9CQUFvQkEsR0FBR0EsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUMxREEsUUFBUUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxvQkFBb0JBLENBQUNBLEtBQUtBLENBQUNBO1FBRTdEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxvQkFBb0JBLEdBQUdBLFFBQVFBLENBQUNBO1FBRS9GQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUNGTCwwQkFBQ0E7QUFBREEsQ0FuRUEsQUFtRUNBLEVBbkVpQyxrQkFBa0IsRUFtRW5EO0FBRUQsQUFBNkIsaUJBQXBCLG1CQUFtQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0FtYmllbnRFbnZNYXBNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ3ViZVRleHR1cmVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9DdWJlVGV4dHVyZUJhc2VcIik7XG5cbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgQW1iaWVudEJhc2ljTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvQW1iaWVudEJhc2ljTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIEFtYmllbnRFbnZNYXBNZXRob2QgcHJvdmlkZXMgYSBkaWZmdXNlIHNoYWRpbmcgbWV0aG9kIHRoYXQgdXNlcyBhIGRpZmZ1c2UgaXJyYWRpYW5jZSBlbnZpcm9ubWVudCBtYXAgdG9cbiAqIGFwcHJveGltYXRlIGdsb2JhbCBsaWdodGluZyByYXRoZXIgdGhhbiBsaWdodHMuXG4gKi9cbmNsYXNzIEFtYmllbnRFbnZNYXBNZXRob2QgZXh0ZW5kcyBBbWJpZW50QmFzaWNNZXRob2Rcbntcblx0cHJpdmF0ZSBfY3ViZVRleHR1cmU6Q3ViZVRleHR1cmVCYXNlO1xuXHRcblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+QW1iaWVudEVudk1hcE1ldGhvZDwvY29kZT4gb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gZW52TWFwIFRoZSBjdWJlIGVudmlyb25tZW50IG1hcCB0byB1c2UgZm9yIHRoZSBhbWJpZW50IGxpZ2h0aW5nLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW52TWFwOkN1YmVUZXh0dXJlQmFzZSlcblx0e1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5fY3ViZVRleHR1cmUgPSBlbnZNYXA7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdFZPKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHN1cGVyLmlJbml0Vk8oc2hhZGVyT2JqZWN0LCBtZXRob2RWTyk7XG5cblx0XHRtZXRob2RWTy5uZWVkc05vcm1hbHMgPSB0cnVlO1xuXHR9XG5cdFxuXHQvKipcblx0ICogVGhlIGN1YmUgZW52aXJvbm1lbnQgbWFwIHRvIHVzZSBmb3IgdGhlIGRpZmZ1c2UgbGlnaHRpbmcuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVudk1hcCgpOkN1YmVUZXh0dXJlQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N1YmVUZXh0dXJlO1xuXHR9XG5cdFxuXHRwdWJsaWMgc2V0IGVudk1hcCh2YWx1ZTpDdWJlVGV4dHVyZUJhc2UpXG5cdHtcblx0XHR0aGlzLl9jdWJlVGV4dHVyZSA9IHZhbHVlO1xuXHR9XG5cdFxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVDdWJlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4LCB0aGlzLl9jdWJlVGV4dHVyZSk7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIGFtYmllbnRJbnB1dFJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0XHR2YXIgY3ViZU1hcFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdG1ldGhvZFZPLnRleHR1cmVzSW5kZXggPSBjdWJlTWFwUmVnLmluZGV4O1xuXHRcdFxuXHRcdGNvZGUgKz0gU2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4Q3ViZVNhbXBsZUNvZGUodGFyZ2V0UmVnLCBjdWJlTWFwUmVnLCB0aGlzLl9jdWJlVGV4dHVyZSwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZywgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50KTtcblxuXHRcdGFtYmllbnRJbnB1dFJlZ2lzdGVyID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gYW1iaWVudElucHV0UmVnaXN0ZXIuaW5kZXg7XG5cdFx0XG5cdFx0Y29kZSArPSBcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgYW1iaWVudElucHV0UmVnaXN0ZXIgKyBcIi54eXpcXG5cIjtcblx0XHRcblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBBbWJpZW50RW52TWFwTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/AmbientEnvMapMethod.ts b/lib/materials/methods/AmbientEnvMapMethod.ts
new file mode 100644
index 000000000..7090ece2b
--- /dev/null
+++ b/lib/materials/methods/AmbientEnvMapMethod.ts
@@ -0,0 +1,86 @@
+import CubeTextureBase = require("awayjs-core/lib/textures/CubeTextureBase");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import AmbientBasicMethod = require("awayjs-stagegl/lib/materials/methods/AmbientBasicMethod");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+/**
+ * AmbientEnvMapMethod provides a diffuse shading method that uses a diffuse irradiance environment map to
+ * approximate global lighting rather than lights.
+ */
+class AmbientEnvMapMethod extends AmbientBasicMethod
+{
+ private _cubeTexture:CubeTextureBase;
+
+ /**
+ * Creates a new AmbientEnvMapMethod
object.
+ *
+ * @param envMap The cube environment map to use for the ambient lighting.
+ */
+ constructor(envMap:CubeTextureBase)
+ {
+ super();
+ this._cubeTexture = envMap;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO)
+ {
+ super.iInitVO(shaderObject, methodVO);
+
+ methodVO.needsNormals = true;
+ }
+
+ /**
+ * The cube environment map to use for the diffuse lighting.
+ */
+ public get envMap():CubeTextureBase
+ {
+ return this._cubeTexture;
+ }
+
+ public set envMap(value:CubeTextureBase)
+ {
+ this._cubeTexture = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage)
+ {
+ super.iActivate(shaderObject, methodVO, stage);
+
+ ( stage.context).activateCubeTexture(methodVO.texturesIndex, this._cubeTexture);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = "";
+ var ambientInputRegister:ShaderRegisterElement;
+ var cubeMapReg:ShaderRegisterElement = regCache.getFreeTextureReg();
+ methodVO.texturesIndex = cubeMapReg.index;
+
+ code += ShaderCompilerHelper.getTexCubeSampleCode(targetReg, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, sharedRegisters.normalFragment);
+
+ ambientInputRegister = regCache.getFreeFragmentConstant();
+ methodVO.fragmentConstantsIndex = ambientInputRegister.index;
+
+ code += "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + ambientInputRegister + ".xyz\n";
+
+ return code;
+ }
+}
+
+export = AmbientEnvMapMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseCelMethod.js b/lib/materials/methods/DiffuseCelMethod.js
new file mode 100755
index 000000000..4905b6bc3
--- /dev/null
+++ b/lib/materials/methods/DiffuseCelMethod.js
@@ -0,0 +1,103 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+/**
+ * DiffuseCelMethod provides a shading method to add diffuse cel (cartoon) shading.
+ */
+var DiffuseCelMethod = (function (_super) {
+ __extends(DiffuseCelMethod, _super);
+ /**
+ * Creates a new DiffuseCelMethod object.
+ * @param levels The amount of shadow gradations.
+ * @param baseMethod An optional diffuse method on which the cartoon shading is based. If omitted, DiffuseBasicMethod is used.
+ */
+ function DiffuseCelMethod(levels, baseMethod) {
+ var _this = this;
+ if (levels === void 0) { levels = 3; }
+ if (baseMethod === void 0) { baseMethod = null; }
+ _super.call(this, null, baseMethod);
+ this._smoothness = .1;
+ this.baseMethod._iModulateMethod = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { return _this.clampDiffuse(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); };
+ this._levels = levels;
+ }
+ /**
+ * @inheritDoc
+ */
+ DiffuseCelMethod.prototype.iInitConstants = function (shaderObject, methodVO) {
+ var data = shaderObject.fragmentConstantData;
+ var index = methodVO.secondaryFragmentConstantsIndex;
+ _super.prototype.iInitConstants.call(this, shaderObject, methodVO);
+ data[index + 1] = 1;
+ data[index + 2] = 0;
+ };
+ Object.defineProperty(DiffuseCelMethod.prototype, "levels", {
+ /**
+ * The amount of shadow gradations.
+ */
+ get: function () {
+ return this._levels;
+ },
+ set: function (value /*uint*/) {
+ this._levels = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseCelMethod.prototype, "smoothness", {
+ /**
+ * The smoothness of the edge between 2 shading levels.
+ */
+ get: function () {
+ return this._smoothness;
+ },
+ set: function (value) {
+ this._smoothness = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseCelMethod.prototype.iCleanCompilationData = function () {
+ _super.prototype.iCleanCompilationData.call(this);
+ this._dataReg = null;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCelMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ this._dataReg = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._dataReg.index * 4;
+ return _super.prototype.iGetFragmentPreLightingCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCelMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ var data = shaderObject.fragmentConstantData;
+ var index = methodVO.secondaryFragmentConstantsIndex;
+ data[index] = this._levels;
+ data[index + 3] = this._smoothness;
+ };
+ /**
+ * Snaps the diffuse shading of the wrapped method to one of the levels.
+ * @param vo The MethodVO used to compile the current shader.
+ * @param t The register containing the diffuse strength in the "w" component.
+ * @param regCache The register cache used for the shader compilation.
+ * @param sharedRegisters The shared register data for this shader.
+ * @return The AGAL fragment code for the method.
+ */
+ DiffuseCelMethod.prototype.clampDiffuse = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ return "mul " + targetReg + ".w, " + targetReg + ".w, " + this._dataReg + ".x\n" + "frc " + targetReg + ".z, " + targetReg + ".w\n" + "sub " + targetReg + ".y, " + targetReg + ".w, " + targetReg + ".z\n" + "mov " + targetReg + ".x, " + this._dataReg + ".x\n" + "sub " + targetReg + ".x, " + targetReg + ".x, " + this._dataReg + ".y\n" + "rcp " + targetReg + ".x," + targetReg + ".x\n" + "mul " + targetReg + ".w, " + targetReg + ".y, " + targetReg + ".x\n" + "sub " + targetReg + ".y, " + targetReg + ".w, " + targetReg + ".x\n" + "div " + targetReg + ".z, " + targetReg + ".z, " + this._dataReg + ".w\n" + "sat " + targetReg + ".z, " + targetReg + ".z\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".z\n" + "sub " + targetReg + ".z, " + this._dataReg + ".y, " + targetReg + ".z\n" + "mul " + targetReg + ".y, " + targetReg + ".y, " + targetReg + ".z\n" + "add " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n" + "sat " + targetReg + ".w, " + targetReg + ".w\n";
+ };
+ return DiffuseCelMethod;
+})(DiffuseCompositeMethod);
+module.exports = DiffuseCelMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VjZWxtZXRob2QudHMiXSwibmFtZXMiOlsiRGlmZnVzZUNlbE1ldGhvZCIsIkRpZmZ1c2VDZWxNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlQ2VsTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRGlmZnVzZUNlbE1ldGhvZC5sZXZlbHMiLCJEaWZmdXNlQ2VsTWV0aG9kLnNtb290aG5lc3MiLCJEaWZmdXNlQ2VsTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIkRpZmZ1c2VDZWxNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiRGlmZnVzZUNlbE1ldGhvZC5pQWN0aXZhdGUiLCJEaWZmdXNlQ2VsTWV0aG9kLmNsYW1wRGlmZnVzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBV0EsSUFBTyxzQkFBc0IsV0FBYSxnRUFBZ0UsQ0FBQyxDQUFDO0FBRTVHLEFBR0E7O0dBREc7SUFDRyxnQkFBZ0I7SUFBU0EsVUFBekJBLGdCQUFnQkEsVUFBK0JBO0lBTXBEQTs7OztPQUlHQTtJQUNIQSxTQVhLQSxnQkFBZ0JBLENBV1RBLE1BQTBCQSxFQUFFQSxVQUFvQ0E7UUFYN0VDLGlCQTBIQ0E7UUEvR1lBLHNCQUEwQkEsR0FBMUJBLFVBQTBCQTtRQUFFQSwwQkFBb0NBLEdBQXBDQSxpQkFBb0NBO1FBRTNFQSxrQkFBTUEsSUFBSUEsRUFBRUEsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFUakJBLGdCQUFXQSxHQUFVQSxFQUFFQSxDQUFDQTtRQVcvQkEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxVQUFDQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBLElBQUtBLE9BQUFBLEtBQUlBLENBQUNBLFlBQVlBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLFNBQVNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLEVBQXBG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QUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUMvRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDaERBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3JFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUNwREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FDekVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLEtBQUtBLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQy9DQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUdyRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FHckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUVoREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FFckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUNyRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLENBQUNBO0lBQ25EQSxDQUFDQTtJQUNGUix1QkFBQ0E7QUFBREEsQ0ExSEEsQUEwSENBLEVBMUg4QixzQkFBc0IsRUEwSHBEO0FBRUQsQUFBMEIsaUJBQWpCLGdCQUFnQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VDZWxNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgSUNvbnRleHRTdGFnZUdMXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvSUNvbnRleHRTdGFnZUdMXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuaW1wb3J0IERpZmZ1c2VDb21wb3NpdGVNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFwiKTtcblxuLyoqXG4gKiBEaWZmdXNlQ2VsTWV0aG9kIHByb3ZpZGVzIGEgc2hhZGluZyBtZXRob2QgdG8gYWRkIGRpZmZ1c2UgY2VsIChjYXJ0b29uKSBzaGFkaW5nLlxuICovXG5jbGFzcyBEaWZmdXNlQ2VsTWV0aG9kIGV4dGVuZHMgRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFxue1xuXHRwcml2YXRlIF9sZXZlbHM6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9kYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc21vb3RobmVzczpudW1iZXIgPSAuMTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlQ2VsTWV0aG9kIG9iamVjdC5cblx0ICogQHBhcmFtIGxldmVscyBUaGUgYW1vdW50IG9mIHNoYWRvdyBncmFkYXRpb25zLlxuXHQgKiBAcGFyYW0gYmFzZU1ldGhvZCBBbiBvcHRpb25hbCBkaWZmdXNlIG1ldGhvZCBvbiB3aGljaCB0aGUgY2FydG9vbiBzaGFkaW5nIGlzIGJhc2VkLiBJZiBvbWl0dGVkLCBEaWZmdXNlQmFzaWNNZXRob2QgaXMgdXNlZC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGxldmVsczpudW1iZXIgLyp1aW50Ki8gPSAzLCBiYXNlTWV0aG9kOkRpZmZ1c2VCYXNpY01ldGhvZCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihudWxsLCBiYXNlTWV0aG9kKTtcblxuXHRcdHRoaXMuYmFzZU1ldGhvZC5faU1vZHVsYXRlTWV0aG9kID0gKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKSA9PiB0aGlzLmNsYW1wRGlmZnVzZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCB0YXJnZXRSZWcsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cblx0XHR0aGlzLl9sZXZlbHMgPSBsZXZlbHM7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHN1cGVyLmlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdCwgbWV0aG9kVk8pO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDE7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IG9mIHNoYWRvdyBncmFkYXRpb25zLlxuXHQgKi9cblx0cHVibGljIGdldCBsZXZlbHMoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9sZXZlbHM7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGxldmVscyh2YWx1ZTpudW1iZXIgLyp1aW50Ki8pXG5cdHtcblx0XHR0aGlzLl9sZXZlbHMgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgc21vb3RobmVzcyBvZiB0aGUgZWRnZSBiZXR3ZWVuIDIgc2hhZGluZyBsZXZlbHMuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHNtb290aG5lc3MoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9zbW9vdGhuZXNzO1xuXHR9XG5cblx0cHVibGljIHNldCBzbW9vdGhuZXNzKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3Ntb290aG5lc3MgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0XHR0aGlzLl9kYXRhUmVnID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5fZGF0YVJlZyA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4ID0gdGhpcy5fZGF0YVJlZy5pbmRleCo0O1xuXG5cdFx0cmV0dXJuIHN1cGVyLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c3VwZXIuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IG1ldGhvZFZPLnNlY29uZGFyeUZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cdFx0ZGF0YVtpbmRleF0gPSB0aGlzLl9sZXZlbHM7XG5cdFx0ZGF0YVtpbmRleCArIDNdID0gdGhpcy5fc21vb3RobmVzcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTbmFwcyB0aGUgZGlmZnVzZSBzaGFkaW5nIG9mIHRoZSB3cmFwcGVkIG1ldGhvZCB0byBvbmUgb2YgdGhlIGxldmVscy5cblx0ICogQHBhcmFtIHZvIFRoZSBNZXRob2RWTyB1c2VkIHRvIGNvbXBpbGUgdGhlIGN1cnJlbnQgc2hhZGVyLlxuXHQgKiBAcGFyYW0gdCBUaGUgcmVnaXN0ZXIgY29udGFpbmluZyB0aGUgZGlmZnVzZSBzdHJlbmd0aCBpbiB0aGUgXCJ3XCIgY29tcG9uZW50LlxuXHQgKiBAcGFyYW0gcmVnQ2FjaGUgVGhlIHJlZ2lzdGVyIGNhY2hlIHVzZWQgZm9yIHRoZSBzaGFkZXIgY29tcGlsYXRpb24uXG5cdCAqIEBwYXJhbSBzaGFyZWRSZWdpc3RlcnMgVGhlIHNoYXJlZCByZWdpc3RlciBkYXRhIGZvciB0aGlzIHNoYWRlci5cblx0ICogQHJldHVybiBUaGUgQUdBTCBmcmFnbWVudCBjb2RlIGZvciB0aGUgbWV0aG9kLlxuXHQgKi9cblx0cHJpdmF0ZSBjbGFtcERpZmZ1c2Uoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIFwibXVsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRoaXMuX2RhdGFSZWcgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJmcmMgXCIgKyB0YXJnZXRSZWcgKyBcIi56LCBcIiArIHRhcmdldFJlZyArIFwiLndcXG5cIiArXG5cdFx0XHRcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi56XFxuXCIgK1xuXHRcdFx0XCJtb3YgXCIgKyB0YXJnZXRSZWcgKyBcIi54LCBcIiArIHRoaXMuX2RhdGFSZWcgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi54LCBcIiArIHRhcmdldFJlZyArIFwiLngsIFwiICsgdGhpcy5fZGF0YVJlZyArIFwiLnlcXG5cIiArXG5cdFx0XHRcInJjcCBcIiArIHRhcmdldFJlZyArIFwiLngsXCIgKyB0YXJnZXRSZWcgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIueFxcblwiICtcblxuXHRcdFx0Ly8gcHJldmlvdXMgY2xhbXBlZCBzdHJlbmd0aFxuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIueFxcblwiICtcblxuXHRcdFx0Ly8gZnJhY3QvZXBzaWxvbiAoc28gMCAtIGVwc2lsb24gd2lsbCBiZWNvbWUgMCAtIDEpXG5cdFx0XHRcImRpdiBcIiArIHRhcmdldFJlZyArIFwiLnosIFwiICsgdGFyZ2V0UmVnICsgXCIueiwgXCIgKyB0aGlzLl9kYXRhUmVnICsgXCIud1xcblwiICtcblx0XHRcdFwic2F0IFwiICsgdGFyZ2V0UmVnICsgXCIueiwgXCIgKyB0YXJnZXRSZWcgKyBcIi56XFxuXCIgK1xuXG5cdFx0XHRcIm11bCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi56XFxuXCIgK1xuXHRcdFx0Ly8gMS16XG5cdFx0XHRcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnosIFwiICsgdGhpcy5fZGF0YVJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIuelxcblwiICtcblx0XHRcdFwibXVsIFwiICsgdGFyZ2V0UmVnICsgXCIueSwgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRhcmdldFJlZyArIFwiLnpcXG5cIiArXG5cdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi55XFxuXCIgK1xuXHRcdFx0XCJzYXQgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLndcXG5cIjtcblx0fVxufVxuXG5leHBvcnQgPSBEaWZmdXNlQ2VsTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseCelMethod.ts b/lib/materials/methods/DiffuseCelMethod.ts
new file mode 100644
index 000000000..64f2dc654
--- /dev/null
+++ b/lib/materials/methods/DiffuseCelMethod.ts
@@ -0,0 +1,141 @@
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+import DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+
+/**
+ * DiffuseCelMethod provides a shading method to add diffuse cel (cartoon) shading.
+ */
+class DiffuseCelMethod extends DiffuseCompositeMethod
+{
+ private _levels:number /*uint*/;
+ private _dataReg:ShaderRegisterElement;
+ private _smoothness:number = .1;
+
+ /**
+ * Creates a new DiffuseCelMethod object.
+ * @param levels The amount of shadow gradations.
+ * @param baseMethod An optional diffuse method on which the cartoon shading is based. If omitted, DiffuseBasicMethod is used.
+ */
+ constructor(levels:number /*uint*/ = 3, baseMethod:DiffuseBasicMethod = null)
+ {
+ super(null, baseMethod);
+
+ this.baseMethod._iModulateMethod = (shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => this.clampDiffuse(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+
+ this._levels = levels;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitConstants(shaderObject:ShaderLightingObject, methodVO:MethodVO)
+ {
+ var data:Array = shaderObject.fragmentConstantData;
+ var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex;
+ super.iInitConstants(shaderObject, methodVO);
+ data[index + 1] = 1;
+ data[index + 2] = 0;
+ }
+
+ /**
+ * The amount of shadow gradations.
+ */
+ public get levels():number /*uint*/
+ {
+ return this._levels;
+ }
+
+ public set levels(value:number /*uint*/)
+ {
+ this._levels = value;
+ }
+
+ /**
+ * The smoothness of the edge between 2 shading levels.
+ */
+ public get smoothness():number
+ {
+ return this._smoothness;
+ }
+
+ public set smoothness(value:number)
+ {
+ this._smoothness = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iCleanCompilationData()
+ {
+ super.iCleanCompilationData();
+ this._dataReg = null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ this._dataReg = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._dataReg.index*4;
+
+ return super.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ super.iActivate(shaderObject, methodVO, stage);
+ var data:Array = shaderObject.fragmentConstantData;
+ var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex;
+ data[index] = this._levels;
+ data[index + 3] = this._smoothness;
+ }
+
+ /**
+ * Snaps the diffuse shading of the wrapped method to one of the levels.
+ * @param vo The MethodVO used to compile the current shader.
+ * @param t The register containing the diffuse strength in the "w" component.
+ * @param regCache The register cache used for the shader compilation.
+ * @param sharedRegisters The shared register data for this shader.
+ * @return The AGAL fragment code for the method.
+ */
+ private clampDiffuse(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ return "mul " + targetReg + ".w, " + targetReg + ".w, " + this._dataReg + ".x\n" +
+ "frc " + targetReg + ".z, " + targetReg + ".w\n" +
+ "sub " + targetReg + ".y, " + targetReg + ".w, " + targetReg + ".z\n" +
+ "mov " + targetReg + ".x, " + this._dataReg + ".x\n" +
+ "sub " + targetReg + ".x, " + targetReg + ".x, " + this._dataReg + ".y\n" +
+ "rcp " + targetReg + ".x," + targetReg + ".x\n" +
+ "mul " + targetReg + ".w, " + targetReg + ".y, " + targetReg + ".x\n" +
+
+ // previous clamped strength
+ "sub " + targetReg + ".y, " + targetReg + ".w, " + targetReg + ".x\n" +
+
+ // fract/epsilon (so 0 - epsilon will become 0 - 1)
+ "div " + targetReg + ".z, " + targetReg + ".z, " + this._dataReg + ".w\n" +
+ "sat " + targetReg + ".z, " + targetReg + ".z\n" +
+
+ "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".z\n" +
+ // 1-z
+ "sub " + targetReg + ".z, " + this._dataReg + ".y, " + targetReg + ".z\n" +
+ "mul " + targetReg + ".y, " + targetReg + ".y, " + targetReg + ".z\n" +
+ "add " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n" +
+ "sat " + targetReg + ".w, " + targetReg + ".w\n";
+ }
+}
+
+export = DiffuseCelMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseCompositeMethod.js b/lib/materials/methods/DiffuseCompositeMethod.js
new file mode 100755
index 000000000..621096f87
--- /dev/null
+++ b/lib/materials/methods/DiffuseCompositeMethod.js
@@ -0,0 +1,190 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ShadingMethodEvent = require("awayjs-stagegl/lib/events/ShadingMethodEvent");
+var DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+/**
+ * DiffuseCompositeMethod provides a base class for diffuse methods that wrap a diffuse method to alter the
+ * calculated diffuse reflection strength.
+ */
+var DiffuseCompositeMethod = (function (_super) {
+ __extends(DiffuseCompositeMethod, _super);
+ /**
+ * Creates a new DiffuseCompositeMethod
object.
+ *
+ * @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature clampDiffuse(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the diffuse strength.
+ * @param baseMethod The base diffuse method on which this method's shading is based.
+ */
+ function DiffuseCompositeMethod(modulateMethod, baseMethod) {
+ var _this = this;
+ if (baseMethod === void 0) { baseMethod = null; }
+ _super.call(this);
+ this._onShaderInvalidatedDelegate = function (event) { return _this.onShaderInvalidated(event); };
+ this.pBaseMethod = baseMethod || new DiffuseBasicMethod();
+ this.pBaseMethod._iModulateMethod = modulateMethod;
+ this.pBaseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ }
+ Object.defineProperty(DiffuseCompositeMethod.prototype, "baseMethod", {
+ /**
+ * The base diffuse method on which this method's shading is based.
+ */
+ get: function () {
+ return this.pBaseMethod;
+ },
+ set: function (value) {
+ if (this.pBaseMethod == value)
+ return;
+ this.pBaseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.pBaseMethod = value;
+ this.pBaseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.iInvalidateShaderProgram();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iInitVO = function (shaderObject, methodVO) {
+ this.pBaseMethod.iInitVO(shaderObject, methodVO);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iInitConstants = function (shaderObject, methodVO) {
+ this.pBaseMethod.iInitConstants(shaderObject, methodVO);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.dispose = function () {
+ this.pBaseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.pBaseMethod.dispose();
+ };
+ Object.defineProperty(DiffuseCompositeMethod.prototype, "texture", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return this.pBaseMethod.texture;
+ },
+ /**
+ * @inheritDoc
+ */
+ set: function (value) {
+ this.pBaseMethod.texture = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseCompositeMethod.prototype, "diffuseColor", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return this.pBaseMethod.diffuseColor;
+ },
+ /**
+ * @inheritDoc
+ */
+ set: function (value) {
+ this.pBaseMethod.diffuseColor = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseCompositeMethod.prototype, "ambientColor", {
+ /**
+ * @inheritDoc
+ */
+ get: function () {
+ return this.pBaseMethod.ambientColor;
+ },
+ /**
+ * @inheritDoc
+ */
+ set: function (value) {
+ this.pBaseMethod.ambientColor = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ return this.pBaseMethod.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) {
+ var code = this.pBaseMethod.iGetFragmentCodePerLight(shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters);
+ this._pTotalLightColorReg = this.pBaseMethod._pTotalLightColorReg;
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iGetFragmentCodePerProbe = function (shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters) {
+ var code = this.pBaseMethod.iGetFragmentCodePerProbe(shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters);
+ this._pTotalLightColorReg = this.pBaseMethod._pTotalLightColorReg;
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ this.pBaseMethod.iActivate(shaderObject, methodVO, stage);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iSetRenderState = function (shaderObject, methodVO, renderable, stage, camera) {
+ this.pBaseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iDeactivate = function (shaderObject, methodVO, stage) {
+ this.pBaseMethod.iDeactivate(shaderObject, methodVO, stage);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iGetVertexCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ return this.pBaseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iGetFragmentPostLightingCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ return this.pBaseMethod.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iReset = function () {
+ this.pBaseMethod.iReset();
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseCompositeMethod.prototype.iCleanCompilationData = function () {
+ _super.prototype.iCleanCompilationData.call(this);
+ this.pBaseMethod.iCleanCompilationData();
+ };
+ /**
+ * Called when the base method's shader code is invalidated.
+ */
+ DiffuseCompositeMethod.prototype.onShaderInvalidated = function (event) {
+ this.iInvalidateShaderProgram();
+ };
+ return DiffuseCompositeMethod;
+})(DiffuseBasicMethod);
+module.exports = DiffuseCompositeMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2Vjb21wb3NpdGVtZXRob2QudHMiXSwibmFtZXMiOlsiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZCIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmJhc2VNZXRob2QiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlJbml0Vk8iLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5kaXNwb3NlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC50ZXh0dXJlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5kaWZmdXNlQ29sb3IiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmFtYmllbnRDb2xvciIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJQcm9iZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUFjdGl2YXRlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pU2V0UmVuZGVyU3RhdGUiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlEZWFjdGl2YXRlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pR2V0VmVydGV4Q29kZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaVJlc2V0IiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLm9uU2hhZGVySW52YWxpZGF0ZWQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUtB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bkRtQixJQUFJQSxDQUFDQSx3QkFBd0JBLEVBQUVBLENBQUNBO0lBQ2pDQSxDQUFDQTtJQUNGbkIsNkJBQUNBO0FBQURBLENBaE5BLEFBZ05DQSxFQWhOb0Msa0JBQWtCLEVBZ050RDtBQUVELEFBQWdDLGlCQUF2QixzQkFBc0IsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRleHR1cmUyREJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmUyREJhc2VcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBTaGFkaW5nTWV0aG9kRXZlbnRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9ldmVudHMvU2hhZGluZ01ldGhvZEV2ZW50XCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcblxuLyoqXG4gKiBEaWZmdXNlQ29tcG9zaXRlTWV0aG9kIHByb3ZpZGVzIGEgYmFzZSBjbGFzcyBmb3IgZGlmZnVzZSBtZXRob2RzIHRoYXQgd3JhcCBhIGRpZmZ1c2UgbWV0aG9kIHRvIGFsdGVyIHRoZVxuICogY2FsY3VsYXRlZCBkaWZmdXNlIHJlZmxlY3Rpb24gc3RyZW5ndGguXG4gKi9cbmNsYXNzIERpZmZ1c2VDb21wb3NpdGVNZXRob2QgZXh0ZW5kcyBEaWZmdXNlQmFzaWNNZXRob2Rcbntcblx0cHVibGljIHBCYXNlTWV0aG9kOkRpZmZ1c2VCYXNpY01ldGhvZDtcblxuXHRwcml2YXRlIF9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGU6RnVuY3Rpb247XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+RGlmZnVzZUNvbXBvc2l0ZU1ldGhvZDwvY29kZT4gb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gbW9kdWxhdGVNZXRob2QgVGhlIG1ldGhvZCB3aGljaCB3aWxsIGFkZCB0aGUgY29kZSB0byBhbHRlciB0aGUgYmFzZSBtZXRob2QncyBzdHJlbmd0aC4gSXQgbmVlZHMgdG8gaGF2ZSB0aGUgc2lnbmF0dXJlIGNsYW1wRGlmZnVzZSh0OlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSk6c3RyaW5nLCBpbiB3aGljaCB0Lncgd2lsbCBjb250YWluIHRoZSBkaWZmdXNlIHN0cmVuZ3RoLlxuXHQgKiBAcGFyYW0gYmFzZU1ldGhvZCBUaGUgYmFzZSBkaWZmdXNlIG1ldGhvZCBvbiB3aGljaCB0aGlzIG1ldGhvZCdzIHNoYWRpbmcgaXMgYmFzZWQuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihtb2R1bGF0ZU1ldGhvZDooc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpID0+IHN0cmluZywgYmFzZU1ldGhvZDpEaWZmdXNlQmFzaWNNZXRob2QgPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX29uU2hhZGVySW52YWxpZGF0ZWREZWxlZ2F0ZSA9IChldmVudDpTaGFkaW5nTWV0aG9kRXZlbnQpID0+IHRoaXMub25TaGFkZXJJbnZhbGlkYXRlZChldmVudCk7XG5cblx0XHR0aGlzLnBCYXNlTWV0aG9kID0gYmFzZU1ldGhvZCB8fCBuZXcgRGlmZnVzZUJhc2ljTWV0aG9kKCk7XG5cdFx0dGhpcy5wQmFzZU1ldGhvZC5faU1vZHVsYXRlTWV0aG9kID0gbW9kdWxhdGVNZXRob2Q7XG5cdFx0dGhpcy5wQmFzZU1ldGhvZC5hZGRFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIHRoaXMuX29uU2hhZGVySW52YWxpZGF0ZWREZWxlZ2F0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGJhc2UgZGlmZnVzZSBtZXRob2Qgb24gd2hpY2ggdGhpcyBtZXRob2QncyBzaGFkaW5nIGlzIGJhc2VkLlxuXHQgKi9cblx0cHVibGljIGdldCBiYXNlTWV0aG9kKCk6RGlmZnVzZUJhc2ljTWV0aG9kXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5wQmFzZU1ldGhvZDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYmFzZU1ldGhvZCh2YWx1ZTpEaWZmdXNlQmFzaWNNZXRob2QpXG5cdHtcblx0XHRpZiAodGhpcy5wQmFzZU1ldGhvZCA9PSB2YWx1ZSlcblx0XHRcdHJldHVybjtcblxuXHRcdHRoaXMucEJhc2VNZXRob2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCB0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUpO1xuXHRcdHRoaXMucEJhc2VNZXRob2QgPSB2YWx1ZTtcblx0XHR0aGlzLnBCYXNlTWV0aG9kLmFkZEV2ZW50TGlzdGVuZXIoU2hhZGluZ01ldGhvZEV2ZW50LlNIQURFUl9JTlZBTElEQVRFRCwgdGhpcy5fb25TaGFkZXJJbnZhbGlkYXRlZERlbGVnYXRlKTtcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRWTyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dGhpcy5wQmFzZU1ldGhvZC5pSW5pdFZPKHNoYWRlck9iamVjdCwgbWV0aG9kVk8pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QuaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0LCBtZXRob2RWTyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCB0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUpO1xuXHRcdHRoaXMucEJhc2VNZXRob2QuZGlzcG9zZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHRleHR1cmUoKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5wQmFzZU1ldGhvZC50ZXh0dXJlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgc2V0IHRleHR1cmUodmFsdWU6VGV4dHVyZTJEQmFzZSlcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QudGV4dHVyZSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGRpZmZ1c2VDb2xvcigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMucEJhc2VNZXRob2QuZGlmZnVzZUNvbG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgc2V0IGRpZmZ1c2VDb2xvcih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLnBCYXNlTWV0aG9kLmRpZmZ1c2VDb2xvciA9IHZhbHVlO1xuXHR9XG5cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXQgYW1iaWVudENvbG9yKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5wQmFzZU1ldGhvZC5hbWJpZW50Q29sb3I7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBzZXQgYW1iaWVudENvbG9yKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QuYW1iaWVudENvbG9yID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRQcmVMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLnBCYXNlTWV0aG9kLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZVBlckxpZ2h0KHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIGxpZ2h0RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgbGlnaHRDb2xSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gdGhpcy5wQmFzZU1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgbGlnaHREaXJSZWcsIGxpZ2h0Q29sUmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHRcdHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgPSB0aGlzLnBCYXNlTWV0aG9kLl9wVG90YWxMaWdodENvbG9yUmVnO1xuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZVBlclByb2JlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIGN1YmVNYXBSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCB3ZWlnaHRSZWdpc3RlcjpzdHJpbmcsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSB0aGlzLnBCYXNlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJQcm9iZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBjdWJlTWFwUmVnLCB3ZWlnaHRSZWdpc3RlciwgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0XHR0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnID0gdGhpcy5wQmFzZU1ldGhvZC5fcFRvdGFsTGlnaHRDb2xvclJlZztcblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlTZXRSZW5kZXJTdGF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHRoaXMucEJhc2VNZXRob2QuaVNldFJlbmRlclN0YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlbmRlcmFibGUsIHN0YWdlLCBjYW1lcmEpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaURlYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHR0aGlzLnBCYXNlTWV0aG9kLmlEZWFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLnBCYXNlTWV0aG9kLmlHZXRWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRQb3N0TGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5wQmFzZU1ldGhvZC5pR2V0RnJhZ21lbnRQb3N0TGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHRhcmdldFJlZywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlSZXNldCgpXG5cdHtcblx0XHR0aGlzLnBCYXNlTWV0aG9kLmlSZXNldCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUNsZWFuQ29tcGlsYXRpb25EYXRhKClcblx0e1xuXHRcdHN1cGVyLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpO1xuXHRcdHRoaXMucEJhc2VNZXRob2QuaUNsZWFuQ29tcGlsYXRpb25EYXRhKCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsbGVkIHdoZW4gdGhlIGJhc2UgbWV0aG9kJ3Mgc2hhZGVyIGNvZGUgaXMgaW52YWxpZGF0ZWQuXG5cdCAqL1xuXHRwcml2YXRlIG9uU2hhZGVySW52YWxpZGF0ZWQoZXZlbnQ6U2hhZGluZ01ldGhvZEV2ZW50KVxuXHR7XG5cdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0fVxufVxuXG5leHBvcnQgPSBEaWZmdXNlQ29tcG9zaXRlTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseCompositeMethod.ts b/lib/materials/methods/DiffuseCompositeMethod.ts
new file mode 100755
index 000000000..32a3a1c0c
--- /dev/null
+++ b/lib/materials/methods/DiffuseCompositeMethod.ts
@@ -0,0 +1,229 @@
+import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase");
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import ShadingMethodEvent = require("awayjs-stagegl/lib/events/ShadingMethodEvent");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+
+/**
+ * DiffuseCompositeMethod provides a base class for diffuse methods that wrap a diffuse method to alter the
+ * calculated diffuse reflection strength.
+ */
+class DiffuseCompositeMethod extends DiffuseBasicMethod
+{
+ public pBaseMethod:DiffuseBasicMethod;
+
+ private _onShaderInvalidatedDelegate:Function;
+
+ /**
+ * Creates a new DiffuseCompositeMethod
object.
+ *
+ * @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature clampDiffuse(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the diffuse strength.
+ * @param baseMethod The base diffuse method on which this method's shading is based.
+ */
+ constructor(modulateMethod:(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => string, baseMethod:DiffuseBasicMethod = null)
+ {
+ super();
+
+ this._onShaderInvalidatedDelegate = (event:ShadingMethodEvent) => this.onShaderInvalidated(event);
+
+ this.pBaseMethod = baseMethod || new DiffuseBasicMethod();
+ this.pBaseMethod._iModulateMethod = modulateMethod;
+ this.pBaseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ }
+
+ /**
+ * The base diffuse method on which this method's shading is based.
+ */
+ public get baseMethod():DiffuseBasicMethod
+ {
+ return this.pBaseMethod;
+ }
+
+ public set baseMethod(value:DiffuseBasicMethod)
+ {
+ if (this.pBaseMethod == value)
+ return;
+
+ this.pBaseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.pBaseMethod = value;
+ this.pBaseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.iInvalidateShaderProgram();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO)
+ {
+ this.pBaseMethod.iInitVO(shaderObject, methodVO);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitConstants(shaderObject:ShaderLightingObject, methodVO:MethodVO)
+ {
+ this.pBaseMethod.iInitConstants(shaderObject, methodVO);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public dispose()
+ {
+ this.pBaseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
+ this.pBaseMethod.dispose();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get texture():Texture2DBase
+ {
+ return this.pBaseMethod.texture;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public set texture(value:Texture2DBase)
+ {
+ this.pBaseMethod.texture = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public get diffuseColor():number
+ {
+ return this.pBaseMethod.diffuseColor;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public set diffuseColor(value:number)
+ {
+ this.pBaseMethod.diffuseColor = value;
+ }
+
+
+ /**
+ * @inheritDoc
+ */
+ public get ambientColor():number
+ {
+ return this.pBaseMethod.ambientColor;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public set ambientColor(value:number)
+ {
+ this.pBaseMethod.ambientColor = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ return this.pBaseMethod.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = this.pBaseMethod.iGetFragmentCodePerLight(shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters);
+ this._pTotalLightColorReg = this.pBaseMethod._pTotalLightColorReg;
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCodePerProbe(shaderObject:ShaderLightingObject, methodVO:MethodVO, cubeMapReg:ShaderRegisterElement, weightRegister:string, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = this.pBaseMethod.iGetFragmentCodePerProbe(shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters);
+ this._pTotalLightColorReg = this.pBaseMethod._pTotalLightColorReg;
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ this.pBaseMethod.iActivate(shaderObject, methodVO, stage);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iSetRenderState(shaderObject:ShaderLightingObject, methodVO:MethodVO, renderable:RenderableBase, stage:Stage, camera:Camera)
+ {
+ this.pBaseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iDeactivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ this.pBaseMethod.iDeactivate(shaderObject, methodVO, stage);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetVertexCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ return this.pBaseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPostLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ return this.pBaseMethod.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iReset()
+ {
+ this.pBaseMethod.iReset();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iCleanCompilationData()
+ {
+ super.iCleanCompilationData();
+ this.pBaseMethod.iCleanCompilationData();
+ }
+
+ /**
+ * Called when the base method's shader code is invalidated.
+ */
+ private onShaderInvalidated(event:ShadingMethodEvent)
+ {
+ this.iInvalidateShaderProgram();
+ }
+}
+
+export = DiffuseCompositeMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseDepthMethod.js b/lib/materials/methods/DiffuseDepthMethod.js
new file mode 100755
index 000000000..330041fa5
--- /dev/null
+++ b/lib/materials/methods/DiffuseDepthMethod.js
@@ -0,0 +1,62 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+/**
+ * DiffuseDepthMethod provides a debug method to visualise depth maps
+ */
+var DiffuseDepthMethod = (function (_super) {
+ __extends(DiffuseDepthMethod, _super);
+ /**
+ * Creates a new DiffuseBasicMethod object.
+ */
+ function DiffuseDepthMethod() {
+ _super.call(this);
+ }
+ /**
+ * @inheritDoc
+ */
+ DiffuseDepthMethod.prototype.iInitConstants = function (shaderObject, methodVO) {
+ var data = shaderObject.fragmentConstantData;
+ var index = methodVO.fragmentConstantsIndex;
+ data[index] = 1.0;
+ data[index + 1] = 1 / 255.0;
+ data[index + 2] = 1 / 65025.0;
+ data[index + 3] = 1 / 16581375.0;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseDepthMethod.prototype.iGetFragmentPostLightingCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ var code = "";
+ var temp;
+ var decReg;
+ if (!this._pUseTexture)
+ throw new Error("DiffuseDepthMethod requires texture!");
+ // incorporate input from ambient
+ if (shaderObject.numLights > 0) {
+ if (sharedRegisters.shadowTarget)
+ code += "mul " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + sharedRegisters.shadowTarget + ".w\n";
+ code += "add " + targetReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + targetReg + ".xyz\n" + "sat " + targetReg + ".xyz, " + targetReg + ".xyz\n";
+ registerCache.removeFragmentTempUsage(this._pTotalLightColorReg);
+ }
+ temp = shaderObject.numLights > 0 ? registerCache.getFreeFragmentVectorTemp() : targetReg;
+ this._pDiffuseInputRegister = registerCache.getFreeTextureReg();
+ methodVO.texturesIndex = this._pDiffuseInputRegister.index;
+ decReg = registerCache.getFreeFragmentConstant();
+ methodVO.fragmentConstantsIndex = decReg.index * 4;
+ code += ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pDiffuseInputRegister, this.texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) + "dp4 " + temp + ".x, " + temp + ", " + decReg + "\n" + "mov " + temp + ".yz, " + temp + ".xx \n" + "mov " + temp + ".w, " + decReg + ".x\n" + "sub " + temp + ".xyz, " + decReg + ".xxx, " + temp + ".xyz\n";
+ if (shaderObject.numLights == 0)
+ return code;
+ code += "mul " + targetReg + ".xyz, " + temp + ".xyz, " + targetReg + ".xyz\n" + "mov " + targetReg + ".w, " + temp + ".w\n";
+ return code;
+ };
+ return DiffuseDepthMethod;
+})(DiffuseBasicMethod);
+module.exports = DiffuseDepthMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VkZXB0aG1ldGhvZC50cyJdLCJuYW1lcyI6WyJEaWZmdXNlRGVwdGhNZXRob2QiLCJEaWZmdXNlRGVwdGhNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlRGVwdGhNZXRob2QuaUluaXRDb25zdGFudHMiLCJEaWZmdXNlRGVwdGhNZXRob2QuaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBTUEsSUFBTyxrQkFBa0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBQ2xHLElBQU8sb0JBQW9CLFdBQWMseURBQXlELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTJCQTtJQUVsREE7O09BRUdBO0lBQ0hBLFNBTEtBLGtCQUFrQkE7UUFPdEJDLGlCQUFPQSxDQUFDQTtJQUNUQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsMkNBQWNBLEdBQXJCQSxVQUFzQkEsWUFBNkJBLEVBQUVBLFFBQWlCQTtRQUVyRUUsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSxzQkFBc0JBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQTtRQUNsQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsS0FBS0EsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLE9BQU9BLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxVQUFVQSxDQUFDQTtJQUNoQ0EsQ0FBQ0E7SUFFREY7O09BRUdBO0lBQ0lBLHlEQUE0QkEsR0FBbkNBLFVBQW9DQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRS9MRyxJQUFJQSxJQUFJQSxHQUFVQSxFQUFFQSxDQUFDQTtRQUNyQkEsSUFBSUEsSUFBMEJBLENBQUNBO1FBQy9CQSxJQUFJQSxNQUE0QkEsQ0FBQ0E7UUFFakNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO1lBQ3RCQSxNQUFNQSxJQUFJQSxLQUFLQSxDQUFDQSxzQ0FBc0NBLENBQUNBLENBQUNBO1FBRXpEQSxBQUNBQSxpQ0FEaUNBO1FBQ2pDQSxFQUFFQSxDQUFDQSxDQUFDQSxZQUFZQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNoQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsWUFBWUEsQ0FBQ0E7Z0JBQ2hDQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsZUFBZUEsQ0FBQ0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDdElBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FDbEdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLENBQUNBO1lBQ3REQSxhQUFhQSxDQUFDQSx1QkFBdUJBLENBQUNBLElBQUlBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsQ0FBQ0E7UUFDbEVBLENBQUNBO1FBRURBLElBQUlBLEdBQUdBLFlBQVlBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLEdBQUVBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsR0FBQ0EsU0FBU0EsQ0FBQ0E7UUFFdkZBLElBQUlBLENBQUNBLHNCQUFzQkEsR0FBR0EsYUFBYUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtRQUNoRUEsUUFBUUEsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUMzREEsTUFBTUEsR0FBR0EsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUNqREEsUUFBUUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxNQUFNQSxDQUFDQSxLQUFLQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNqREEsSUFBSUEsSUFBSUEsb0JBQW9CQSxDQUFDQSxrQkFBa0JBLENBQUNBLElBQUlBLEVBQUVBLGVBQWVBLEVBQUVBLElBQUlBLENBQUNBLHNCQUFzQkEsRUFBRUEsSUFBSUEsQ0FBQ0EsT0FBT0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxjQUFjQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxDQUFDQSxHQUN6TUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FDcERBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLEdBQUdBLFVBQVVBLEdBQzNDQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUN4Q0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFFaEVBLEVBQUVBLENBQUNBLENBQUNBLFlBQVlBLENBQUNBLFNBQVNBLElBQUlBLENBQUNBLENBQUNBO1lBQy9CQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtRQUViQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUM3RUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFFN0NBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBQ0ZILHlCQUFDQTtBQUFEQSxDQWhFQSxBQWdFQ0EsRUFoRWdDLGtCQUFrQixFQWdFbEQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZURlcHRoTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuLyoqXG4gKiBEaWZmdXNlRGVwdGhNZXRob2QgcHJvdmlkZXMgYSBkZWJ1ZyBtZXRob2QgdG8gdmlzdWFsaXNlIGRlcHRoIG1hcHNcbiAqL1xuY2xhc3MgRGlmZnVzZURlcHRoTWV0aG9kIGV4dGVuZHMgRGlmZnVzZUJhc2ljTWV0aG9kXG57XG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IERpZmZ1c2VCYXNpY01ldGhvZCBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGRhdGFbaW5kZXhdID0gMS4wO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDEvMjU1LjA7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gMS82NTAyNS4wO1xuXHRcdGRhdGFbaW5kZXggKyAzXSA9IDEvMTY1ODEzNzUuMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdHZhciBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXG5cdFx0aWYgKCF0aGlzLl9wVXNlVGV4dHVyZSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkRpZmZ1c2VEZXB0aE1ldGhvZCByZXF1aXJlcyB0ZXh0dXJlIVwiKTtcblxuXHRcdC8vIGluY29ycG9yYXRlIGlucHV0IGZyb20gYW1iaWVudFxuXHRcdGlmIChzaGFkZXJPYmplY3QubnVtTGlnaHRzID4gMCkge1xuXHRcdFx0aWYgKHNoYXJlZFJlZ2lzdGVycy5zaGFkb3dUYXJnZXQpXG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIueHl6LCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnNoYWRvd1RhcmdldCArIFwiLndcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwic2F0IFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRhcmdldFJlZyArIFwiLnh5elxcblwiO1xuXHRcdFx0cmVnaXN0ZXJDYWNoZS5yZW1vdmVGcmFnbWVudFRlbXBVc2FnZSh0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnKTtcblx0XHR9XG5cblx0XHR0ZW1wID0gc2hhZGVyT2JqZWN0Lm51bUxpZ2h0cyA+IDA/IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpOnRhcmdldFJlZztcblxuXHRcdHRoaXMuX3BEaWZmdXNlSW5wdXRSZWdpc3RlciA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblx0XHRtZXRob2RWTy50ZXh0dXJlc0luZGV4ID0gdGhpcy5fcERpZmZ1c2VJbnB1dFJlZ2lzdGVyLmluZGV4O1xuXHRcdGRlY1JlZyA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGVjUmVnLmluZGV4KjQ7XG5cdFx0Y29kZSArPSBTaGFkZXJDb21waWxlckhlbHBlci5nZXRUZXgyRFNhbXBsZUNvZGUodGVtcCwgc2hhcmVkUmVnaXN0ZXJzLCB0aGlzLl9wRGlmZnVzZUlucHV0UmVnaXN0ZXIsIHRoaXMudGV4dHVyZSwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QucmVwZWF0VGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nKSArXG5cdFx0XHRcImRwNCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIiwgXCIgKyBkZWNSZWcgKyBcIlxcblwiICtcblx0XHRcdFwibW92IFwiICsgdGVtcCArIFwiLnl6LCBcIiArIHRlbXAgKyBcIi54eFx0XHRcdFxcblwiICtcblx0XHRcdFwibW92IFwiICsgdGVtcCArIFwiLncsIFwiICsgZGVjUmVnICsgXCIueFxcblwiICtcblx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyBkZWNSZWcgKyBcIi54eHgsIFwiICsgdGVtcCArIFwiLnh5elxcblwiO1xuXG5cdFx0aWYgKHNoYWRlck9iamVjdC5udW1MaWdodHMgPT0gMClcblx0XHRcdHJldHVybiBjb2RlO1xuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIHRhcmdldFJlZyArIFwiLnh5elxcblwiICtcblx0XHRcdFwibW92IFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0ZW1wICsgXCIud1xcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gRGlmZnVzZURlcHRoTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseDepthMethod.ts b/lib/materials/methods/DiffuseDepthMethod.ts
new file mode 100644
index 000000000..513a7a50a
--- /dev/null
+++ b/lib/materials/methods/DiffuseDepthMethod.ts
@@ -0,0 +1,79 @@
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+/**
+ * DiffuseDepthMethod provides a debug method to visualise depth maps
+ */
+class DiffuseDepthMethod extends DiffuseBasicMethod
+{
+ /**
+ * Creates a new DiffuseBasicMethod object.
+ */
+ constructor()
+ {
+ super();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO)
+ {
+ var data:Array = shaderObject.fragmentConstantData;
+ var index:number /*int*/ = methodVO.fragmentConstantsIndex;
+ data[index] = 1.0;
+ data[index + 1] = 1/255.0;
+ data[index + 2] = 1/65025.0;
+ data[index + 3] = 1/16581375.0;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPostLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = "";
+ var temp:ShaderRegisterElement;
+ var decReg:ShaderRegisterElement;
+
+ if (!this._pUseTexture)
+ throw new Error("DiffuseDepthMethod requires texture!");
+
+ // incorporate input from ambient
+ if (shaderObject.numLights > 0) {
+ if (sharedRegisters.shadowTarget)
+ code += "mul " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + sharedRegisters.shadowTarget + ".w\n";
+ code += "add " + targetReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + targetReg + ".xyz\n" +
+ "sat " + targetReg + ".xyz, " + targetReg + ".xyz\n";
+ registerCache.removeFragmentTempUsage(this._pTotalLightColorReg);
+ }
+
+ temp = shaderObject.numLights > 0? registerCache.getFreeFragmentVectorTemp():targetReg;
+
+ this._pDiffuseInputRegister = registerCache.getFreeTextureReg();
+ methodVO.texturesIndex = this._pDiffuseInputRegister.index;
+ decReg = registerCache.getFreeFragmentConstant();
+ methodVO.fragmentConstantsIndex = decReg.index*4;
+ code += ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pDiffuseInputRegister, this.texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) +
+ "dp4 " + temp + ".x, " + temp + ", " + decReg + "\n" +
+ "mov " + temp + ".yz, " + temp + ".xx \n" +
+ "mov " + temp + ".w, " + decReg + ".x\n" +
+ "sub " + temp + ".xyz, " + decReg + ".xxx, " + temp + ".xyz\n";
+
+ if (shaderObject.numLights == 0)
+ return code;
+
+ code += "mul " + targetReg + ".xyz, " + temp + ".xyz, " + targetReg + ".xyz\n" +
+ "mov " + targetReg + ".w, " + temp + ".w\n";
+
+ return code;
+ }
+}
+
+export = DiffuseDepthMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseGradientMethod.js b/lib/materials/methods/DiffuseGradientMethod.js
new file mode 100755
index 000000000..1a5dc15da
--- /dev/null
+++ b/lib/materials/methods/DiffuseGradientMethod.js
@@ -0,0 +1,103 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+/**
+ * DiffuseGradientMethod is an alternative to DiffuseBasicMethod in which the shading can be modulated with a gradient
+ * to introduce color-tinted shading as opposed to the single-channel diffuse strength. This can be used as a crude
+ * approximation to subsurface scattering (for instance, the mid-range shading for skin can be tinted red to similate
+ * scattered light within the skin attributing to the final colour)
+ */
+var DiffuseGradientMethod = (function (_super) {
+ __extends(DiffuseGradientMethod, _super);
+ /**
+ * Creates a new DiffuseGradientMethod object.
+ * @param gradient A texture that contains the light colour based on the angle. This can be used to change
+ * the light colour due to subsurface scattering when the surface faces away from the light.
+ */
+ function DiffuseGradientMethod(gradient) {
+ _super.call(this);
+ this._gradient = gradient;
+ }
+ Object.defineProperty(DiffuseGradientMethod.prototype, "gradient", {
+ /**
+ * A texture that contains the light colour based on the angle. This can be used to change the light colour
+ * due to subsurface scattering when the surface faces away from the light.
+ */
+ get: function () {
+ return this._gradient;
+ },
+ set: function (value) {
+ if (value.hasMipmaps != this._gradient.hasMipmaps || value.format != this._gradient.format)
+ this.iInvalidateShaderProgram();
+ this._gradient = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseGradientMethod.prototype.iCleanCompilationData = function () {
+ _super.prototype.iCleanCompilationData.call(this);
+ this._gradientTextureRegister = null;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseGradientMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ var code = _super.prototype.iGetFragmentPreLightingCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters);
+ this._pIsFirstLight = true;
+ if (shaderObject.numLights > 0) {
+ this._gradientTextureRegister = registerCache.getFreeTextureReg();
+ methodVO.secondaryTexturesIndex = this._gradientTextureRegister.index;
+ }
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseGradientMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) {
+ var code = "";
+ var t;
+ // write in temporary if not first light, so we can add to total diffuse colour
+ if (this._pIsFirstLight)
+ t = this._pTotalLightColorReg;
+ else {
+ t = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(t, 1);
+ }
+ code += "dp3 " + t + ".w, " + lightDirReg + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + "mul " + t + ".w, " + t + ".w, " + sharedRegisters.commons + ".x\n" + "add " + t + ".w, " + t + ".w, " + sharedRegisters.commons + ".x\n" + "mul " + t + ".xyz, " + t + ".w, " + lightDirReg + ".w\n";
+ if (this._iModulateMethod != null)
+ code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters);
+ code += ShaderCompilerHelper.getTex2DSampleCode(t, sharedRegisters, this._gradientTextureRegister, this._gradient, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, t, "clamp") + "mul " + t + ".xyz, " + t + ".xyz, " + lightColReg + ".xyz\n";
+ if (!this._pIsFirstLight) {
+ code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n";
+ registerCache.removeFragmentTempUsage(t);
+ }
+ this._pIsFirstLight = false;
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseGradientMethod.prototype.pApplyShadow = function (shaderObject, methodVO, regCache, sharedRegisters) {
+ var t = regCache.getFreeFragmentVectorTemp();
+ return "mov " + t + ", " + sharedRegisters.shadowTarget + ".wwww\n" + ShaderCompilerHelper.getTex2DSampleCode(t, sharedRegisters, this._gradientTextureRegister, this._gradient, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, t, "clamp") + "mul " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ", " + t + "\n";
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseGradientMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ stage.context.activateTexture(methodVO.secondaryTexturesIndex, this._gradient);
+ };
+ return DiffuseGradientMethod;
+})(DiffuseBasicMethod);
+module.exports = DiffuseGradientMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VncmFkaWVudG1ldGhvZC50cyJdLCJuYW1lcyI6WyJEaWZmdXNlR3JhZGllbnRNZXRob2QiLCJEaWZmdXNlR3JhZGllbnRNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlR3JhZGllbnRNZXRob2QuZ3JhZGllbnQiLCJEaWZmdXNlR3JhZGllbnRNZXRob2QuaUNsZWFuQ29tcGlsYXRpb25EYXRhIiwiRGlmZnVzZUdyYWRpZW50TWV0aG9kLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZSIsIkRpZmZ1c2VHcmFkaWVudE1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQiLCJEaWZmdXNlR3JhZGllbnRNZXRob2QucEFwcGx5U2hhZG93IiwiRGlmZnVzZUdyYWRpZW50TWV0aG9kLmlBY3RpdmF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBU0EsSUFBTyxrQkFBa0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBQ2xHLElBQU8sb0JBQW9CLFdBQWMseURBQXlELENBQUMsQ0FBQztBQUVwRyxBQU1BOzs7OztHQURHO0lBQ0cscUJBQXFCO0lBQVNBLFVBQTlCQSxxQkFBcUJBLFVBQTJCQTtJQUtyREE7Ozs7T0FJR0E7SUFDSEEsU0FWS0EscUJBQXFCQSxDQVVkQSxRQUFzQkE7UUFFakNDLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxRQUFRQSxDQUFDQTtJQUMzQkEsQ0FBQ0E7SUFNREQsc0JBQVdBLDJDQUFRQTtRQUpuQkE7OztXQUdHQTthQUNIQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN2QkEsQ0FBQ0E7YUFFREYsVUFBb0JBLEtBQW1CQTtZQUV0Q0UsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsSUFBSUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsVUFBVUEsSUFBSUEsS0FBS0EsQ0FBQ0EsTUFBTUEsSUFBSUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7Z0JBQzFGQSxJQUFJQSxDQUFDQSx3QkFBd0JBLEVBQUVBLENBQUNBO1lBQ2pDQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7OztPQVBBRjtJQVNEQTs7T0FFR0E7SUFDSUEscURBQXFCQSxHQUE1QkE7UUFFQ0csZ0JBQUtBLENBQUNBLHFCQUFxQkEsV0FBRUEsQ0FBQ0E7UUFDOUJBLElBQUlBLENBQUNBLHdCQUF3QkEsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDdENBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSwyREFBMkJBLEdBQWxDQSxVQUFtQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTdKSSxJQUFJQSxJQUFJQSxHQUFVQSxnQkFBS0EsQ0FBQ0EsMkJBQTJCQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUM1R0EsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFFM0JBLEVBQUVBLENBQUNBLENBQUNBLFlBQVlBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2hDQSxJQUFJQSxDQUFDQSx3QkFBd0JBLEdBQUdBLGFBQWFBLENBQUNBLGlCQUFpQkEsRUFBRUEsQ0FBQ0E7WUFDbEVBLFFBQVFBLENBQUNBLHNCQUFzQkEsR0FBR0EsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUN2RUEsQ0FBQ0E7UUFDREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFREo7O09BRUdBO0lBQ0lBLHdEQUF3QkEsR0FBL0JBLFVBQWdDQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLFdBQWlDQSxFQUFFQSxXQUFpQ0EsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUVoT0ssSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLENBQXVCQSxDQUFDQTtRQUU1QkEsQUFDQUEsK0VBRCtFQTtRQUMvRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0E7WUFDdkJBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDL0JBLElBQUlBLENBQUNBLENBQUNBO1lBQ0xBLENBQUNBLEdBQUdBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7WUFDOUNBLGFBQWFBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDM0NBLENBQUNBO1FBRURBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLFdBQVdBLEdBQUdBLFFBQVFBLEdBQUdBLGVBQWVBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLEdBQy9GQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxlQUFlQSxDQUFDQSxPQUFPQSxHQUFHQSxNQUFNQSxHQUNuRUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsZUFBZUEsQ0FBQ0EsT0FBT0EsR0FBR0EsTUFBTUEsR0FDbkVBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLFFBQVFBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLFdBQVdBLEdBQUdBLE1BQU1BLENBQUNBO1FBRTNEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLElBQUlBLElBQUlBLENBQUNBO1lBQ2pDQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLENBQUNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO1FBRTFGQSxJQUFJQSxJQUFJQSxvQkFBb0JBLENBQUNBLGtCQUFrQkEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsZUFBZUEsRUFBRUEsSUFBSUEsQ0FBQ0Esd0JBQXdCQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxFQUFFQSxZQUFZQSxDQUFDQSxpQkFBaUJBLEVBQUVBLFlBQVlBLENBQUNBLGNBQWNBLEVBQUVBLFlBQVlBLENBQUNBLGFBQWFBLEVBQUVBLENBQUNBLEVBQUVBLE9BQU9BLENBQUNBLEdBRXROQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxHQUFHQSxXQUFXQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUUvREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDMUJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxRQUFRQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUM1R0EsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMxQ0EsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFNUJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURMOztPQUVHQTtJQUNJQSw0Q0FBWUEsR0FBbkJBLFVBQW9CQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLFFBQTRCQSxFQUFFQSxlQUFrQ0E7UUFFeklNLElBQUlBLENBQUNBLEdBQXlCQSxRQUFRQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1FBRW5FQSxNQUFNQSxDQUFDQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxDQUFDQSxZQUFZQSxHQUFHQSxTQUFTQSxHQUNsRUEsb0JBQW9CQSxDQUFDQSxrQkFBa0JBLENBQUNBLENBQUNBLEVBQUVBLGVBQWVBLEVBQUVBLElBQUlBLENBQUNBLHdCQUF3QkEsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxjQUFjQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQSxFQUFFQSxPQUFPQSxDQUFDQSxHQUMvTUEsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLEdBQUdBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBO0lBQzlGQSxDQUFDQTtJQUVETjs7T0FFR0E7SUFDSUEseUNBQVNBLEdBQWhCQSxVQUFpQkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxLQUFXQTtRQUVqRk8sZ0JBQUtBLENBQUNBLFNBQVNBLFlBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO1FBRTVCQSxLQUFLQSxDQUFDQSxPQUFRQSxDQUFDQSxlQUFlQSxDQUFDQSxRQUFRQSxDQUFDQSxzQkFBc0JBLEVBQUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBO0lBQ3BHQSxDQUFDQTtJQUNGUCw0QkFBQ0E7QUFBREEsQ0FwSEEsQUFvSENBLEVBcEhtQyxrQkFBa0IsRUFvSHJEO0FBRUQsQUFBK0IsaUJBQXRCLHFCQUFxQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VHcmFkaWVudE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlMkRCYXNlXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgSUNvbnRleHRTdGFnZUdMXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvSUNvbnRleHRTdGFnZUdMXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuLyoqXG4gKiBEaWZmdXNlR3JhZGllbnRNZXRob2QgaXMgYW4gYWx0ZXJuYXRpdmUgdG8gRGlmZnVzZUJhc2ljTWV0aG9kIGluIHdoaWNoIHRoZSBzaGFkaW5nIGNhbiBiZSBtb2R1bGF0ZWQgd2l0aCBhIGdyYWRpZW50XG4gKiB0byBpbnRyb2R1Y2UgY29sb3ItdGludGVkIHNoYWRpbmcgYXMgb3Bwb3NlZCB0byB0aGUgc2luZ2xlLWNoYW5uZWwgZGlmZnVzZSBzdHJlbmd0aC4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIGNydWRlXG4gKiBhcHByb3hpbWF0aW9uIHRvIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyAoZm9yIGluc3RhbmNlLCB0aGUgbWlkLXJhbmdlIHNoYWRpbmcgZm9yIHNraW4gY2FuIGJlIHRpbnRlZCByZWQgdG8gc2ltaWxhdGVcbiAqIHNjYXR0ZXJlZCBsaWdodCB3aXRoaW4gdGhlIHNraW4gYXR0cmlidXRpbmcgdG8gdGhlIGZpbmFsIGNvbG91cilcbiAqL1xuY2xhc3MgRGlmZnVzZUdyYWRpZW50TWV0aG9kIGV4dGVuZHMgRGlmZnVzZUJhc2ljTWV0aG9kXG57XG5cdHByaXZhdGUgX2dyYWRpZW50VGV4dHVyZVJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfZ3JhZGllbnQ6VGV4dHVyZTJEQmFzZTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlR3JhZGllbnRNZXRob2Qgb2JqZWN0LlxuXHQgKiBAcGFyYW0gZ3JhZGllbnQgQSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIGxpZ2h0IGNvbG91ciBiYXNlZCBvbiB0aGUgYW5nbGUuIFRoaXMgY2FuIGJlIHVzZWQgdG8gY2hhbmdlXG5cdCAqIHRoZSBsaWdodCBjb2xvdXIgZHVlIHRvIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyB3aGVuIHRoZSBzdXJmYWNlIGZhY2VzIGF3YXkgZnJvbSB0aGUgbGlnaHQuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihncmFkaWVudDpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX2dyYWRpZW50ID0gZ3JhZGllbnQ7XG5cdH1cblxuXHQvKipcblx0ICogQSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIGxpZ2h0IGNvbG91ciBiYXNlZCBvbiB0aGUgYW5nbGUuIFRoaXMgY2FuIGJlIHVzZWQgdG8gY2hhbmdlIHRoZSBsaWdodCBjb2xvdXJcblx0ICogZHVlIHRvIHN1YnN1cmZhY2Ugc2NhdHRlcmluZyB3aGVuIHRoZSBzdXJmYWNlIGZhY2VzIGF3YXkgZnJvbSB0aGUgbGlnaHQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGdyYWRpZW50KCk6VGV4dHVyZTJEQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2dyYWRpZW50O1xuXHR9XG5cblx0cHVibGljIHNldCBncmFkaWVudCh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0aWYgKHZhbHVlLmhhc01pcG1hcHMgIT0gdGhpcy5fZ3JhZGllbnQuaGFzTWlwbWFwcyB8fCB2YWx1ZS5mb3JtYXQgIT0gdGhpcy5fZ3JhZGllbnQuZm9ybWF0KVxuXHRcdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0XHR0aGlzLl9ncmFkaWVudCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUNsZWFuQ29tcGlsYXRpb25EYXRhKClcblx0e1xuXHRcdHN1cGVyLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpO1xuXHRcdHRoaXMuX2dyYWRpZW50VGV4dHVyZVJlZ2lzdGVyID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gc3VwZXIuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdFx0dGhpcy5fcElzRmlyc3RMaWdodCA9IHRydWU7XG5cblx0XHRpZiAoc2hhZGVyT2JqZWN0Lm51bUxpZ2h0cyA+IDApIHtcblx0XHRcdHRoaXMuX2dyYWRpZW50VGV4dHVyZVJlZ2lzdGVyID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdFx0bWV0aG9kVk8uc2Vjb25kYXJ5VGV4dHVyZXNJbmRleCA9IHRoaXMuX2dyYWRpZW50VGV4dHVyZVJlZ2lzdGVyLmluZGV4O1xuXHRcdH1cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGVQZXJMaWdodChzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBsaWdodERpclJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIGxpZ2h0Q29sUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIHQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXG5cdFx0Ly8gd3JpdGUgaW4gdGVtcG9yYXJ5IGlmIG5vdCBmaXJzdCBsaWdodCwgc28gd2UgY2FuIGFkZCB0byB0b3RhbCBkaWZmdXNlIGNvbG91clxuXHRcdGlmICh0aGlzLl9wSXNGaXJzdExpZ2h0KVxuXHRcdFx0dCA9IHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWc7XG5cdFx0ZWxzZSB7XG5cdFx0XHR0ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0XHRyZWdpc3RlckNhY2hlLmFkZEZyYWdtZW50VGVtcFVzYWdlcyh0LCAxKTtcblx0XHR9XG5cblx0XHRjb2RlICs9IFwiZHAzIFwiICsgdCArIFwiLncsIFwiICsgbGlnaHREaXJSZWcgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50ICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIudywgXCIgKyBzaGFyZWRSZWdpc3RlcnMuY29tbW9ucyArIFwiLnhcXG5cIiArXG5cdFx0XHRcImFkZCBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53LCBcIiArIHNoYXJlZFJlZ2lzdGVycy5jb21tb25zICsgXCIueFxcblwiICtcblx0XHRcdFwibXVsIFwiICsgdCArIFwiLnh5eiwgXCIgKyB0ICsgXCIudywgXCIgKyBsaWdodERpclJlZyArIFwiLndcXG5cIjtcblxuXHRcdGlmICh0aGlzLl9pTW9kdWxhdGVNZXRob2QgIT0gbnVsbClcblx0XHRcdGNvZGUgKz0gdGhpcy5faU1vZHVsYXRlTWV0aG9kKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHQsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cblx0XHRjb2RlICs9IFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleDJEU2FtcGxlQ29kZSh0LCBzaGFyZWRSZWdpc3RlcnMsIHRoaXMuX2dyYWRpZW50VGV4dHVyZVJlZ2lzdGVyLCB0aGlzLl9ncmFkaWVudCwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QucmVwZWF0VGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCB0LCBcImNsYW1wXCIpICtcblx0XHRcdC8vXHRcdFx0XHRcdFwibXVsIFwiICsgdCArIFwiLnh5eiwgXCIgKyB0ICsgXCIueHl6LCBcIiArIHQgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ICsgXCIueHl6LCBcIiArIHQgKyBcIi54eXosIFwiICsgbGlnaHRDb2xSZWcgKyBcIi54eXpcXG5cIjtcblxuXHRcdGlmICghdGhpcy5fcElzRmlyc3RMaWdodCkge1xuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZyArIFwiLnh5eiwgXCIgKyB0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHQpO1xuXHRcdH1cblxuXHRcdHRoaXMuX3BJc0ZpcnN0TGlnaHQgPSBmYWxzZTtcblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgcEFwcGx5U2hhZG93KHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHJlZ0NhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXG5cdFx0cmV0dXJuIFwibW92IFwiICsgdCArIFwiLCBcIiArIHNoYXJlZFJlZ2lzdGVycy5zaGFkb3dUYXJnZXQgKyBcIi53d3d3XFxuXCIgK1xuXHRcdFx0U2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4MkRTYW1wbGVDb2RlKHQsIHNoYXJlZFJlZ2lzdGVycywgdGhpcy5fZ3JhZGllbnRUZXh0dXJlUmVnaXN0ZXIsIHRoaXMuX2dyYWRpZW50LCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC5yZXBlYXRUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnVzZU1pcG1hcHBpbmcsIHQsIFwiY2xhbXBcIikgK1xuXHRcdFx0XCJtdWwgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIueHl6LCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIiwgXCIgKyB0ICsgXCJcXG5cIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVUZXh0dXJlKG1ldGhvZFZPLnNlY29uZGFyeVRleHR1cmVzSW5kZXgsIHRoaXMuX2dyYWRpZW50KTtcblx0fVxufVxuXG5leHBvcnQgPSBEaWZmdXNlR3JhZGllbnRNZXRob2Q7Il19
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseGradientMethod.ts b/lib/materials/methods/DiffuseGradientMethod.ts
new file mode 100644
index 000000000..5c51f52e2
--- /dev/null
+++ b/lib/materials/methods/DiffuseGradientMethod.ts
@@ -0,0 +1,137 @@
+import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+/**
+ * DiffuseGradientMethod is an alternative to DiffuseBasicMethod in which the shading can be modulated with a gradient
+ * to introduce color-tinted shading as opposed to the single-channel diffuse strength. This can be used as a crude
+ * approximation to subsurface scattering (for instance, the mid-range shading for skin can be tinted red to similate
+ * scattered light within the skin attributing to the final colour)
+ */
+class DiffuseGradientMethod extends DiffuseBasicMethod
+{
+ private _gradientTextureRegister:ShaderRegisterElement;
+ private _gradient:Texture2DBase;
+
+ /**
+ * Creates a new DiffuseGradientMethod object.
+ * @param gradient A texture that contains the light colour based on the angle. This can be used to change
+ * the light colour due to subsurface scattering when the surface faces away from the light.
+ */
+ constructor(gradient:Texture2DBase)
+ {
+ super();
+
+ this._gradient = gradient;
+ }
+
+ /**
+ * A texture that contains the light colour based on the angle. This can be used to change the light colour
+ * due to subsurface scattering when the surface faces away from the light.
+ */
+ public get gradient():Texture2DBase
+ {
+ return this._gradient;
+ }
+
+ public set gradient(value:Texture2DBase)
+ {
+ if (value.hasMipmaps != this._gradient.hasMipmaps || value.format != this._gradient.format)
+ this.iInvalidateShaderProgram();
+ this._gradient = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iCleanCompilationData()
+ {
+ super.iCleanCompilationData();
+ this._gradientTextureRegister = null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = super.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ this._pIsFirstLight = true;
+
+ if (shaderObject.numLights > 0) {
+ this._gradientTextureRegister = registerCache.getFreeTextureReg();
+ methodVO.secondaryTexturesIndex = this._gradientTextureRegister.index;
+ }
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = "";
+ var t:ShaderRegisterElement;
+
+ // write in temporary if not first light, so we can add to total diffuse colour
+ if (this._pIsFirstLight)
+ t = this._pTotalLightColorReg;
+ else {
+ t = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(t, 1);
+ }
+
+ code += "dp3 " + t + ".w, " + lightDirReg + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" +
+ "mul " + t + ".w, " + t + ".w, " + sharedRegisters.commons + ".x\n" +
+ "add " + t + ".w, " + t + ".w, " + sharedRegisters.commons + ".x\n" +
+ "mul " + t + ".xyz, " + t + ".w, " + lightDirReg + ".w\n";
+
+ if (this._iModulateMethod != null)
+ code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters);
+
+ code += ShaderCompilerHelper.getTex2DSampleCode(t, sharedRegisters, this._gradientTextureRegister, this._gradient, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, t, "clamp") +
+ // "mul " + t + ".xyz, " + t + ".xyz, " + t + ".w\n" +
+ "mul " + t + ".xyz, " + t + ".xyz, " + lightColReg + ".xyz\n";
+
+ if (!this._pIsFirstLight) {
+ code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n";
+ registerCache.removeFragmentTempUsage(t);
+ }
+
+ this._pIsFirstLight = false;
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public pApplyShadow(shaderObject:ShaderLightingObject, methodVO:MethodVO, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var t:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
+
+ return "mov " + t + ", " + sharedRegisters.shadowTarget + ".wwww\n" +
+ ShaderCompilerHelper.getTex2DSampleCode(t, sharedRegisters, this._gradientTextureRegister, this._gradient, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, t, "clamp") +
+ "mul " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ", " + t + "\n";
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ super.iActivate(shaderObject, methodVO, stage);
+
+ ( stage.context).activateTexture(methodVO.secondaryTexturesIndex, this._gradient);
+ }
+}
+
+export = DiffuseGradientMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseLightMapMethod.js b/lib/materials/methods/DiffuseLightMapMethod.js
new file mode 100755
index 000000000..8cccaeafe
--- /dev/null
+++ b/lib/materials/methods/DiffuseLightMapMethod.js
@@ -0,0 +1,115 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+var DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+/**
+ * DiffuseLightMapMethod provides a diffuse shading method that uses a light map to modulate the calculated diffuse
+ * lighting. It is different from EffectLightMapMethod in that the latter modulates the entire calculated pixel color, rather
+ * than only the diffuse lighting value.
+ */
+var DiffuseLightMapMethod = (function (_super) {
+ __extends(DiffuseLightMapMethod, _super);
+ /**
+ * Creates a new DiffuseLightMapMethod method.
+ *
+ * @param lightMap The texture containing the light map.
+ * @param blendMode The blend mode with which the light map should be applied to the lighting result.
+ * @param useSecondaryUV Indicates whether the secondary UV set should be used to map the light map.
+ * @param baseMethod The diffuse method used to calculate the regular diffuse-based lighting.
+ */
+ function DiffuseLightMapMethod(lightMap, blendMode, useSecondaryUV, baseMethod) {
+ if (blendMode === void 0) { blendMode = "multiply"; }
+ if (useSecondaryUV === void 0) { useSecondaryUV = false; }
+ if (baseMethod === void 0) { baseMethod = null; }
+ _super.call(this, null, baseMethod);
+ this._useSecondaryUV = useSecondaryUV;
+ this._lightMapTexture = lightMap;
+ this.blendMode = blendMode;
+ }
+ /**
+ * @inheritDoc
+ */
+ DiffuseLightMapMethod.prototype.iInitVO = function (shaderObject, methodVO) {
+ methodVO.needsSecondaryUV = this._useSecondaryUV;
+ methodVO.needsUV = !this._useSecondaryUV;
+ };
+ Object.defineProperty(DiffuseLightMapMethod.prototype, "blendMode", {
+ /**
+ * The blend mode with which the light map should be applied to the lighting result.
+ *
+ * @see DiffuseLightMapMethod.ADD
+ * @see DiffuseLightMapMethod.MULTIPLY
+ */
+ get: function () {
+ return this._blendMode;
+ },
+ set: function (value) {
+ if (value != DiffuseLightMapMethod.ADD && value != DiffuseLightMapMethod.MULTIPLY)
+ throw new Error("Unknown blendmode!");
+ if (this._blendMode == value)
+ return;
+ this._blendMode = value;
+ this.iInvalidateShaderProgram();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseLightMapMethod.prototype, "lightMapTexture", {
+ /**
+ * The texture containing the light map data.
+ */
+ get: function () {
+ return this._lightMapTexture;
+ },
+ set: function (value) {
+ this._lightMapTexture = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseLightMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ stage.context.activateTexture(methodVO.secondaryTexturesIndex, this._lightMapTexture);
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseLightMapMethod.prototype.iGetFragmentPostLightingCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ var code;
+ var lightMapReg = registerCache.getFreeTextureReg();
+ var temp = registerCache.getFreeFragmentVectorTemp();
+ methodVO.secondaryTexturesIndex = lightMapReg.index;
+ code = ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, lightMapReg, this._lightMapTexture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, sharedRegisters.secondaryUVVarying);
+ switch (this._blendMode) {
+ case DiffuseLightMapMethod.MULTIPLY:
+ code += "mul " + this._pTotalLightColorReg + ", " + this._pTotalLightColorReg + ", " + temp + "\n";
+ break;
+ case DiffuseLightMapMethod.ADD:
+ code += "add " + this._pTotalLightColorReg + ", " + this._pTotalLightColorReg + ", " + temp + "\n";
+ break;
+ }
+ code += _super.prototype.iGetFragmentPostLightingCode.call(this, shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+ return code;
+ };
+ /**
+ * Indicates the light map should be multiplied with the calculated shading result.
+ * This can be used to add pre-calculated shadows or occlusion.
+ */
+ DiffuseLightMapMethod.MULTIPLY = "multiply";
+ /**
+ * Indicates the light map should be added into the calculated shading result.
+ * This can be used to add pre-calculated lighting or global illumination.
+ */
+ DiffuseLightMapMethod.ADD = "add";
+ return DiffuseLightMapMethod;
+})(DiffuseCompositeMethod);
+module.exports = DiffuseLightMapMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VsaWdodG1hcG1ldGhvZC50cyJdLCJuYW1lcyI6WyJEaWZmdXNlTGlnaHRNYXBNZXRob2QiLCJEaWZmdXNlTGlnaHRNYXBNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlTGlnaHRNYXBNZXRob2QuaUluaXRWTyIsIkRpZmZ1c2VMaWdodE1hcE1ldGhvZC5ibGVuZE1vZGUiLCJEaWZmdXNlTGlnaHRNYXBNZXRob2QubGlnaHRNYXBUZXh0dXJlIiwiRGlmZnVzZUxpZ2h0TWFwTWV0aG9kLmlBY3RpdmF0ZSIsIkRpZmZ1c2VMaWdodE1hcE1ldGhvZC5pR2V0RnJhZ21lbnRQb3N0TGlnaHRpbmdDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFVQSxJQUFPLG9CQUFvQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFcEcsSUFBTyxzQkFBc0IsV0FBYSxnRUFBZ0UsQ0FBQyxDQUFDO0FBRTVHLEFBS0E7Ozs7R0FERztJQUNHLHFCQUFxQjtJQUFTQSxVQUE5QkEscUJBQXFCQSxVQUErQkE7SUFrQnpEQTs7Ozs7OztPQU9HQTtJQUNIQSxTQTFCS0EscUJBQXFCQSxDQTBCZEEsUUFBc0JBLEVBQUVBLFNBQTZCQSxFQUFFQSxjQUE4QkEsRUFBRUEsVUFBb0NBO1FBQW5HQyx5QkFBNkJBLEdBQTdCQSxzQkFBNkJBO1FBQUVBLDhCQUE4QkEsR0FBOUJBLHNCQUE4QkE7UUFBRUEsMEJBQW9DQSxHQUFwQ0EsaUJBQW9DQTtRQUV0SUEsa0JBQU1BLElBQUlBLEVBQUVBLFVBQVVBLENBQUNBLENBQUNBO1FBRXhCQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxjQUFjQSxDQUFDQTtRQUN0Q0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUNqQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsU0FBU0EsQ0FBQ0E7SUFDNUJBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSx1Q0FBT0EsR0FBZEEsVUFBZUEsWUFB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QUNBO1lBQ1BBLEtBQUtBLHFCQUFxQkEsQ0FBQ0EsR0FBR0E7Z0JBQzdCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQ25HQSxLQUFLQSxDQUFDQTtRQUNSQSxDQUFDQTtRQUVEQSxJQUFJQSxJQUFJQSxnQkFBS0EsQ0FBQ0EsNEJBQTRCQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxTQUFTQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUU5R0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFqSEROOzs7T0FHR0E7SUFDV0EsOEJBQVFBLEdBQVVBLFVBQVVBLENBQUNBO0lBRTNDQTs7O09BR0dBO0lBQ1dBLHlCQUFHQSxHQUFVQSxLQUFLQSxDQUFDQTtJQXdHbENBLDRCQUFDQTtBQUFEQSxDQXBIQSxBQW9IQ0EsRUFwSG1DLHNCQUFzQixFQW9IekQ7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZUxpZ2h0TWFwTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRleHR1cmUyREJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmUyREJhc2VcIik7XG5cbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyTGlnaHRpbmdPYmplY3RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyTGlnaHRpbmdPYmplY3RcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgRGlmZnVzZUJhc2ljTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZUJhc2ljTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG5pbXBvcnQgRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQ29tcG9zaXRlTWV0aG9kXCIpO1xuXG4vKipcbiAqIERpZmZ1c2VMaWdodE1hcE1ldGhvZCBwcm92aWRlcyBhIGRpZmZ1c2Ugc2hhZGluZyBtZXRob2QgdGhhdCB1c2VzIGEgbGlnaHQgbWFwIHRvIG1vZHVsYXRlIHRoZSBjYWxjdWxhdGVkIGRpZmZ1c2VcbiAqIGxpZ2h0aW5nLiBJdCBpcyBkaWZmZXJlbnQgZnJvbSBFZmZlY3RMaWdodE1hcE1ldGhvZCBpbiB0aGF0IHRoZSBsYXR0ZXIgbW9kdWxhdGVzIHRoZSBlbnRpcmUgY2FsY3VsYXRlZCBwaXhlbCBjb2xvciwgcmF0aGVyXG4gKiB0aGFuIG9ubHkgdGhlIGRpZmZ1c2UgbGlnaHRpbmcgdmFsdWUuXG4gKi9cbmNsYXNzIERpZmZ1c2VMaWdodE1hcE1ldGhvZCBleHRlbmRzIERpZmZ1c2VDb21wb3NpdGVNZXRob2Rcbntcblx0LyoqXG5cdCAqIEluZGljYXRlcyB0aGUgbGlnaHQgbWFwIHNob3VsZCBiZSBtdWx0aXBsaWVkIHdpdGggdGhlIGNhbGN1bGF0ZWQgc2hhZGluZyByZXN1bHQuXG5cdCAqIFRoaXMgY2FuIGJlIHVzZWQgdG8gYWRkIHByZS1jYWxjdWxhdGVkIHNoYWRvd3Mgb3Igb2NjbHVzaW9uLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBNVUxUSVBMWTpzdHJpbmcgPSBcIm11bHRpcGx5XCI7XG5cblx0LyoqXG5cdCAqIEluZGljYXRlcyB0aGUgbGlnaHQgbWFwIHNob3VsZCBiZSBhZGRlZCBpbnRvIHRoZSBjYWxjdWxhdGVkIHNoYWRpbmcgcmVzdWx0LlxuXHQgKiBUaGlzIGNhbiBiZSB1c2VkIHRvIGFkZCBwcmUtY2FsY3VsYXRlZCBsaWdodGluZyBvciBnbG9iYWwgaWxsdW1pbmF0aW9uLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBBREQ6c3RyaW5nID0gXCJhZGRcIjtcblxuXHRwcml2YXRlIF9saWdodE1hcFRleHR1cmU6VGV4dHVyZTJEQmFzZTtcblx0cHJpdmF0ZSBfYmxlbmRNb2RlOnN0cmluZztcblx0cHJpdmF0ZSBfdXNlU2Vjb25kYXJ5VVY6Ym9vbGVhbjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlTGlnaHRNYXBNZXRob2QgbWV0aG9kLlxuXHQgKlxuXHQgKiBAcGFyYW0gbGlnaHRNYXAgVGhlIHRleHR1cmUgY29udGFpbmluZyB0aGUgbGlnaHQgbWFwLlxuXHQgKiBAcGFyYW0gYmxlbmRNb2RlIFRoZSBibGVuZCBtb2RlIHdpdGggd2hpY2ggdGhlIGxpZ2h0IG1hcCBzaG91bGQgYmUgYXBwbGllZCB0byB0aGUgbGlnaHRpbmcgcmVzdWx0LlxuXHQgKiBAcGFyYW0gdXNlU2Vjb25kYXJ5VVYgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNlY29uZGFyeSBVViBzZXQgc2hvdWxkIGJlIHVzZWQgdG8gbWFwIHRoZSBsaWdodCBtYXAuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBkaWZmdXNlIG1ldGhvZCB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgcmVndWxhciBkaWZmdXNlLWJhc2VkIGxpZ2h0aW5nLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobGlnaHRNYXA6VGV4dHVyZTJEQmFzZSwgYmxlbmRNb2RlOnN0cmluZyA9IFwibXVsdGlwbHlcIiwgdXNlU2Vjb25kYXJ5VVY6Ym9vbGVhbiA9IGZhbHNlLCBiYXNlTWV0aG9kOkRpZmZ1c2VCYXNpY01ldGhvZCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihudWxsLCBiYXNlTWV0aG9kKTtcblxuXHRcdHRoaXMuX3VzZVNlY29uZGFyeVVWID0gdXNlU2Vjb25kYXJ5VVY7XG5cdFx0dGhpcy5fbGlnaHRNYXBUZXh0dXJlID0gbGlnaHRNYXA7XG5cdFx0dGhpcy5ibGVuZE1vZGUgPSBibGVuZE1vZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdFZPKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRtZXRob2RWTy5uZWVkc1NlY29uZGFyeVVWID0gdGhpcy5fdXNlU2Vjb25kYXJ5VVY7XG5cdFx0bWV0aG9kVk8ubmVlZHNVViA9ICF0aGlzLl91c2VTZWNvbmRhcnlVVjtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYmxlbmQgbW9kZSB3aXRoIHdoaWNoIHRoZSBsaWdodCBtYXAgc2hvdWxkIGJlIGFwcGxpZWQgdG8gdGhlIGxpZ2h0aW5nIHJlc3VsdC5cblx0ICpcblx0ICogQHNlZSBEaWZmdXNlTGlnaHRNYXBNZXRob2QuQUREXG5cdCAqIEBzZWUgRGlmZnVzZUxpZ2h0TWFwTWV0aG9kLk1VTFRJUExZXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGJsZW5kTW9kZSgpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2JsZW5kTW9kZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYmxlbmRNb2RlKHZhbHVlOnN0cmluZylcblx0e1xuXHRcdGlmICh2YWx1ZSAhPSBEaWZmdXNlTGlnaHRNYXBNZXRob2QuQUREICYmIHZhbHVlICE9IERpZmZ1c2VMaWdodE1hcE1ldGhvZC5NVUxUSVBMWSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24gYmxlbmRtb2RlIVwiKTtcblxuXHRcdGlmICh0aGlzLl9ibGVuZE1vZGUgPT0gdmFsdWUpXG5cdFx0XHRyZXR1cm47XG5cblx0XHR0aGlzLl9ibGVuZE1vZGUgPSB2YWx1ZTtcblxuXHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRleHR1cmUgY29udGFpbmluZyB0aGUgbGlnaHQgbWFwIGRhdGEuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGxpZ2h0TWFwVGV4dHVyZSgpOlRleHR1cmUyREJhc2Vcblx0e1xuXHRcdHJldHVybiB0aGlzLl9saWdodE1hcFRleHR1cmU7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGxpZ2h0TWFwVGV4dHVyZSh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0dGhpcy5fbGlnaHRNYXBUZXh0dXJlID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVUZXh0dXJlKG1ldGhvZFZPLnNlY29uZGFyeVRleHR1cmVzSW5kZXgsIHRoaXMuX2xpZ2h0TWFwVGV4dHVyZSk7XG5cblx0XHRzdXBlci5pQWN0aXZhdGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgc3RhZ2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nO1xuXHRcdHZhciBsaWdodE1hcFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVUZXh0dXJlUmVnKCk7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0bWV0aG9kVk8uc2Vjb25kYXJ5VGV4dHVyZXNJbmRleCA9IGxpZ2h0TWFwUmVnLmluZGV4O1xuXG5cdFx0Y29kZSA9IFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleDJEU2FtcGxlQ29kZSh0ZW1wLCBzaGFyZWRSZWdpc3RlcnMsIGxpZ2h0TWFwUmVnLCB0aGlzLl9saWdodE1hcFRleHR1cmUsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnJlcGVhdFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZywgc2hhcmVkUmVnaXN0ZXJzLnNlY29uZGFyeVVWVmFyeWluZyk7XG5cblx0XHRzd2l0Y2ggKHRoaXMuX2JsZW5kTW9kZSkge1xuXHRcdFx0Y2FzZSBEaWZmdXNlTGlnaHRNYXBNZXRob2QuTVVMVElQTFk6XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIsIFwiICsgdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZyArIFwiLCBcIiArIHRlbXAgKyBcIlxcblwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRGlmZnVzZUxpZ2h0TWFwTWV0aG9kLkFERDpcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIiwgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIsIFwiICsgdGVtcCArIFwiXFxuXCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdGNvZGUgKz0gc3VwZXIuaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCB0YXJnZXRSZWcsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBEaWZmdXNlTGlnaHRNYXBNZXRob2Q7Il19
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseLightMapMethod.ts b/lib/materials/methods/DiffuseLightMapMethod.ts
new file mode 100644
index 000000000..c58acc6fe
--- /dev/null
+++ b/lib/materials/methods/DiffuseLightMapMethod.ts
@@ -0,0 +1,138 @@
+import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+import DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+
+/**
+ * DiffuseLightMapMethod provides a diffuse shading method that uses a light map to modulate the calculated diffuse
+ * lighting. It is different from EffectLightMapMethod in that the latter modulates the entire calculated pixel color, rather
+ * than only the diffuse lighting value.
+ */
+class DiffuseLightMapMethod extends DiffuseCompositeMethod
+{
+ /**
+ * Indicates the light map should be multiplied with the calculated shading result.
+ * This can be used to add pre-calculated shadows or occlusion.
+ */
+ public static MULTIPLY:string = "multiply";
+
+ /**
+ * Indicates the light map should be added into the calculated shading result.
+ * This can be used to add pre-calculated lighting or global illumination.
+ */
+ public static ADD:string = "add";
+
+ private _lightMapTexture:Texture2DBase;
+ private _blendMode:string;
+ private _useSecondaryUV:boolean;
+
+ /**
+ * Creates a new DiffuseLightMapMethod method.
+ *
+ * @param lightMap The texture containing the light map.
+ * @param blendMode The blend mode with which the light map should be applied to the lighting result.
+ * @param useSecondaryUV Indicates whether the secondary UV set should be used to map the light map.
+ * @param baseMethod The diffuse method used to calculate the regular diffuse-based lighting.
+ */
+ constructor(lightMap:Texture2DBase, blendMode:string = "multiply", useSecondaryUV:boolean = false, baseMethod:DiffuseBasicMethod = null)
+ {
+ super(null, baseMethod);
+
+ this._useSecondaryUV = useSecondaryUV;
+ this._lightMapTexture = lightMap;
+ this.blendMode = blendMode;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO)
+ {
+ methodVO.needsSecondaryUV = this._useSecondaryUV;
+ methodVO.needsUV = !this._useSecondaryUV;
+ }
+
+ /**
+ * The blend mode with which the light map should be applied to the lighting result.
+ *
+ * @see DiffuseLightMapMethod.ADD
+ * @see DiffuseLightMapMethod.MULTIPLY
+ */
+ public get blendMode():string
+ {
+ return this._blendMode;
+ }
+
+ public set blendMode(value:string)
+ {
+ if (value != DiffuseLightMapMethod.ADD && value != DiffuseLightMapMethod.MULTIPLY)
+ throw new Error("Unknown blendmode!");
+
+ if (this._blendMode == value)
+ return;
+
+ this._blendMode = value;
+
+ this.iInvalidateShaderProgram();
+ }
+
+ /**
+ * The texture containing the light map data.
+ */
+ public get lightMapTexture():Texture2DBase
+ {
+ return this._lightMapTexture;
+ }
+
+ public set lightMapTexture(value:Texture2DBase)
+ {
+ this._lightMapTexture = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ ( stage.context).activateTexture(methodVO.secondaryTexturesIndex, this._lightMapTexture);
+
+ super.iActivate(shaderObject, methodVO, stage);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPostLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string;
+ var lightMapReg:ShaderRegisterElement = registerCache.getFreeTextureReg();
+ var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp();
+ methodVO.secondaryTexturesIndex = lightMapReg.index;
+
+ code = ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, lightMapReg, this._lightMapTexture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, sharedRegisters.secondaryUVVarying);
+
+ switch (this._blendMode) {
+ case DiffuseLightMapMethod.MULTIPLY:
+ code += "mul " + this._pTotalLightColorReg + ", " + this._pTotalLightColorReg + ", " + temp + "\n";
+ break;
+ case DiffuseLightMapMethod.ADD:
+ code += "add " + this._pTotalLightColorReg + ", " + this._pTotalLightColorReg + ", " + temp + "\n";
+ break;
+ }
+
+ code += super.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+
+ return code;
+ }
+}
+
+export = DiffuseLightMapMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseSubSurfaceMethod.js b/lib/materials/methods/DiffuseSubSurfaceMethod.js
new file mode 100755
index 000000000..f3920f96d
--- /dev/null
+++ b/lib/materials/methods/DiffuseSubSurfaceMethod.js
@@ -0,0 +1,211 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+var SingleObjectDepthPass = require("awayjs-renderergl/lib/materials/passes/SingleObjectDepthPass");
+/**
+ * DiffuseSubSurfaceMethod provides a depth map-based diffuse shading method that mimics the scattering of
+ * light inside translucent surfaces. It allows light to shine through an object and to soften the diffuse shading.
+ * It can be used for candle wax, ice, skin, ...
+ */
+var DiffuseSubSurfaceMethod = (function (_super) {
+ __extends(DiffuseSubSurfaceMethod, _super);
+ /**
+ * Creates a new DiffuseSubSurfaceMethod
object.
+ *
+ * @param depthMapSize The size of the depth map used.
+ * @param depthMapOffset The amount by which the rendered object will be inflated, to prevent depth map rounding errors.
+ * @param baseMethod The diffuse method used to calculate the regular diffuse-based lighting.
+ */
+ function DiffuseSubSurfaceMethod(depthMapSize, depthMapOffset, baseMethod) {
+ var _this = this;
+ if (depthMapSize === void 0) { depthMapSize = 512; }
+ if (depthMapOffset === void 0) { depthMapOffset = 15; }
+ if (baseMethod === void 0) { baseMethod = null; }
+ _super.call(this, null, baseMethod);
+ this._translucency = 1;
+ this._scatterColor = 0xffffff;
+ this._scatterR = 1.0;
+ this._scatterG = 1.0;
+ this._scatterB = 1.0;
+ this.pBaseMethod._iModulateMethod = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { return _this.scatterLight(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); };
+ this._passes = new Array();
+ this._depthPass = new SingleObjectDepthPass();
+ this._depthPass.textureSize = depthMapSize;
+ this._depthPass.polyOffset = depthMapOffset;
+ this._passes.push(this._depthPass);
+ this._scattering = 0.2;
+ this._translucency = 1;
+ }
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iInitConstants = function (shaderObject, methodVO) {
+ _super.prototype.iInitConstants.call(this, shaderObject, methodVO);
+ var data = shaderObject.vertexConstantData;
+ var index = methodVO.secondaryVertexConstantsIndex;
+ data[index] = .5;
+ data[index + 1] = -.5;
+ data[index + 2] = 0;
+ data[index + 3] = 1;
+ data = shaderObject.fragmentConstantData;
+ index = methodVO.secondaryFragmentConstantsIndex;
+ data[index + 3] = 1.0;
+ data[index + 4] = 1.0;
+ data[index + 5] = 1 / 255;
+ data[index + 6] = 1 / 65025;
+ data[index + 7] = 1 / 16581375;
+ data[index + 10] = .5;
+ data[index + 11] = -.1;
+ };
+ DiffuseSubSurfaceMethod.prototype.iCleanCompilationData = function () {
+ _super.prototype.iCleanCompilationData.call(this);
+ this._lightProjVarying = null;
+ this._propReg = null;
+ this._lightColorReg = null;
+ this._colorReg = null;
+ this._decReg = null;
+ this._targetReg = null;
+ };
+ Object.defineProperty(DiffuseSubSurfaceMethod.prototype, "scattering", {
+ /**
+ * The amount by which the light scatters. It can be used to set the translucent surface's thickness. Use low
+ * values for skin.
+ */
+ get: function () {
+ return this._scattering;
+ },
+ set: function (value) {
+ this._scattering = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseSubSurfaceMethod.prototype, "translucency", {
+ /**
+ * The translucency of the object.
+ */
+ get: function () {
+ return this._translucency;
+ },
+ set: function (value) {
+ this._translucency = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DiffuseSubSurfaceMethod.prototype, "scatterColor", {
+ /**
+ * The colour of the "insides" of the object, ie: the colour the light becomes after leaving the object.
+ */
+ get: function () {
+ return this._scatterColor;
+ },
+ set: function (scatterColor /*uint*/) {
+ this._scatterColor = scatterColor;
+ this._scatterR = ((scatterColor >> 16) & 0xff) / 0xff;
+ this._scatterG = ((scatterColor >> 8) & 0xff) / 0xff;
+ this._scatterB = (scatterColor & 0xff) / 0xff;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iGetVertexCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ var code = _super.prototype.iGetVertexCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters);
+ var lightProjection;
+ var toTexRegister;
+ var temp = registerCache.getFreeVertexVectorTemp();
+ toTexRegister = registerCache.getFreeVertexConstant();
+ methodVO.secondaryVertexConstantsIndex = toTexRegister.index * 4;
+ this._lightProjVarying = registerCache.getFreeVarying();
+ lightProjection = registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+ code += "m44 " + temp + ", vt0, " + lightProjection + "\n" + "div " + temp + ".xyz, " + temp + ".xyz, " + temp + ".w\n" + "mul " + temp + ".xy, " + temp + ".xy, " + toTexRegister + ".xy\n" + "add " + temp + ".xy, " + temp + ".xy, " + toTexRegister + ".xx\n" + "mov " + this._lightProjVarying + ".xyz, " + temp + ".xyz\n" + "mov " + this._lightProjVarying + ".w, va0.w\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ this._colorReg = registerCache.getFreeFragmentConstant();
+ this._decReg = registerCache.getFreeFragmentConstant();
+ this._propReg = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._colorReg.index * 4;
+ return _super.prototype.iGetFragmentPreLightingCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) {
+ this._pIsFirstLight = true;
+ this._lightColorReg = lightColReg;
+ return _super.prototype.iGetFragmentCodePerLight.call(this, shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters);
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iGetFragmentPostLightingCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ var code = _super.prototype.iGetFragmentPostLightingCode.call(this, shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+ var temp = registerCache.getFreeFragmentVectorTemp();
+ code += "mul " + temp + ".xyz, " + this._lightColorReg + ".xyz, " + this._targetReg + ".w\n" + "mul " + temp + ".xyz, " + temp + ".xyz, " + this._colorReg + ".xyz\n" + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n";
+ if (this._targetReg != sharedRegisters.viewDirFragment)
+ registerCache.removeFragmentTempUsage(targetReg);
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ var index = methodVO.secondaryFragmentConstantsIndex;
+ var data = shaderObject.fragmentConstantData;
+ data[index] = this._scatterR;
+ data[index + 1] = this._scatterG;
+ data[index + 2] = this._scatterB;
+ data[index + 8] = this._scattering;
+ data[index + 9] = this._translucency;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseSubSurfaceMethod.prototype.iSetRenderState = function (shaderObject, methodVO, renderable, stage, camera) {
+ stage.context.activateTexture(methodVO.secondaryTexturesIndex, this._depthPass._iGetDepthMap(renderable));
+ this._depthPass._iGetProjection(renderable).copyRawDataTo(shaderObject.vertexConstantData, methodVO.secondaryVertexConstantsIndex + 4, true);
+ };
+ /**
+ * Generates the code for this method
+ */
+ DiffuseSubSurfaceMethod.prototype.scatterLight = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ // only scatter first light
+ if (!this._pIsFirstLight)
+ return "";
+ this._pIsFirstLight = false;
+ var code = "";
+ var depthReg = registerCache.getFreeTextureReg();
+ if (sharedRegisters.viewDirFragment) {
+ this._targetReg = sharedRegisters.viewDirFragment;
+ }
+ else {
+ this._targetReg = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(this._targetReg, 1);
+ }
+ methodVO.secondaryTexturesIndex = depthReg.index;
+ var temp = registerCache.getFreeFragmentVectorTemp();
+ code += "tex " + temp + ", " + this._lightProjVarying + ", " + depthReg + " <2d,nearest,clamp>\n" + "dp4 " + targetReg + ".z, " + temp + ", " + this._decReg + "\n";
+ // currentDistanceToLight - closestDistanceToLight
+ code += "sub " + targetReg + ".z, " + this._lightProjVarying + ".z, " + targetReg + ".z\n" + "sub " + targetReg + ".z, " + this._propReg + ".x, " + targetReg + ".z\n" + "mul " + targetReg + ".z, " + this._propReg + ".y, " + targetReg + ".z\n" + "sat " + targetReg + ".z, " + targetReg + ".z\n" + "neg " + targetReg + ".y, " + targetReg + ".x\n" + "mul " + targetReg + ".y, " + targetReg + ".y, " + this._propReg + ".z\n" + "add " + targetReg + ".y, " + targetReg + ".y, " + this._propReg + ".z\n" + "mul " + this._targetReg + ".w, " + targetReg + ".z, " + targetReg + ".y\n" + "sub " + targetReg + ".y, " + this._colorReg + ".w, " + this._targetReg + ".w\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n";
+ return code;
+ };
+ return DiffuseSubSurfaceMethod;
+})(DiffuseCompositeMethod);
+module.exports = DiffuseSubSurfaceMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VzdWJzdXJmYWNlbWV0aG9kLnRzIl0sIm5hbWVzIjpbIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kIiwiRGlmZnVzZVN1YlN1cmZhY2VNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pSW5pdENvbnN0YW50cyIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLnNjYXR0ZXJpbmciLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC50cmFuc2x1Y2VuY3kiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5zY2F0dGVyQ29sb3IiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pR2V0VmVydGV4Q29kZSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodCIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pQWN0aXZhdGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pU2V0UmVuZGVyU3RhdGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5zY2F0dGVyTGlnaHQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQWNBLElBQU8sc0JBQXNCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUM1RyxJQUFPLHFCQUFxQixXQUFhLDhEQUE4RCxDQUFDLENBQUM7QUFFekcsQUFLQTs7OztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQStCQTtJQWdCM0RBOzs7Ozs7T0FNR0E7SUFDSEEsU0F2QktBLHVCQUF1QkEsQ0F1QmhCQSxZQUFpQ0EsRUFBRUEsY0FBMEJBLEVBQUVBLFVBQW9DQTtRQXZCaEhDLGlCQXFRQ0E7UUE5T1lBLDRCQUFpQ0EsR0FBakNBLGtCQUFpQ0E7UUFBRUEsOEJBQTBCQSxHQUExQkEsbUJBQTBCQTtRQUFFQSwwQkFBb0NBLEdBQXBDQSxpQkFBb0NBO1FBRTlHQSxrQkFBTUEsSUFBSUEsRUFBRUEsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFuQmpCQSxrQkFBYUEsR0FBVUEsQ0FBQ0EsQ0FBQ0E7UUFFekJBLGtCQUFhQSxHQUFtQkEsUUFBUUEsQ0FBQ0E7UUFHekNBLGNBQVNBLEdBQVVBLEdBQUdBLENBQUNBO1FBQ3ZCQSxjQUFTQSxHQUFVQSxHQUFHQSxDQUFDQTtRQUN2QkEsY0FBU0EsR0FBVUEsR0FBR0EsQ0FBQ0E7UUFjOUJBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGdCQUFnQkEsR0FBR0EsVUFBQ0EsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxTQUErQkEsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQSxJQUFLQSxPQUFBQSxLQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxTQUFTQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxFQUFwRkEsQ0FBb0ZBLENBQUNBO1FBRXZSQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxLQUFLQSxFQUFvQkEsQ0FBQ0E7UUFDN0NBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFDOUNBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLFdBQVdBLEdBQUdBLFlBQVlBLENBQUNBO1FBQzNDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxVQUFVQSxHQUFHQSxjQUFjQSxDQUFDQTtRQUM1Q0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFDbkNBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEdBQUdBLENBQUNBO1FBQ3ZCQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxDQUFDQSxDQUFDQTtJQUN4QkEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLGdEQUFjQSxHQUFyQkEsVUFBc0JBLFlBQWlDQSxFQUFFQSxRQUFpQkE7UUFFekVFLGdCQUFLQSxDQUFDQSxjQUFjQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUU3Q0EsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLGtCQUFrQkEsQ0FBQ0E7UUFDekRBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSw2QkFBNkJBLENBQUNBO1FBQ2xFQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtRQUNqQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0E7UUFDdEJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3BCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVwQkEsSUFBSUEsR0FBR0EsWUFBWUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUN6Q0EsS0FBS0EsR0FBR0EsUUFBUUEsQ0FBQ0EsK0JBQStCQSxDQUFDQTtRQUNqREEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0E7UUFDdEJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBO1FBQ3RCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsS0FBS0EsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLFFBQVFBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtRQUN0QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBRU1GLHVEQUFxQkEsR0FBNUJBO1FBRUNHLGdCQUFLQSxDQUFDQSxxQkFBcUJBLFdBQUVBLENBQUNBO1FBRTlCQSxJQUFJQSxDQUFDQSxpQkFBaUJBLEdBQUdBLElBQUlBLENBQUNBO1FBQzlCQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNyQkEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBO1FBQ3RCQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNwQkEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBTURILHNCQUFXQSwrQ0FBVUE7UUFKckJBOzs7V0FHR0E7YUFDSEE7WUFFQ0ksTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDekJBLENBQUNBO2FBRURKLFVBQXNCQSxLQUFZQTtZQUVqQ0ksSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDMUJBLENBQUNBOzs7T0FMQUo7SUFVREEsc0JBQVdBLGlEQUFZQTtRQUh2QkE7O1dBRUdBO2FBQ0hBO1lBRUNLLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1FBQzNCQSxDQUFDQTthQUVETCxVQUF3QkEsS0FBWUE7WUFFbkNLLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLEtBQUtBLENBQUNBO1FBQzVCQSxDQUFDQTs7O09BTEFMO0lBVURBLHNCQUFXQSxpREFBWUE7UUFIdkJBOztXQUVHQTthQUNIQTtZQUVDTSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUMzQkEsQ0FBQ0E7YUFFRE4sVUFBd0JBLFlBQVlBLENBQVFBLFFBQURBLEFBQVNBO1lBRW5ETSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxZQUFZQSxDQUFDQTtZQUNsQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsWUFBWUEsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0E7WUFDcERBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLFlBQVlBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBO1lBQ25EQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxZQUFZQSxHQUFHQSxJQUFJQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQTtRQUM3Q0EsQ0FBQ0E7OztPQVJBTjtJQVVEQTs7T0FFR0E7SUFDSUEsZ0RBQWNBLEdBQXJCQSxVQUFzQkEsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTVJTyxJQUFJQSxJQUFJQSxHQUFVQSxnQkFBS0EsQ0FBQ0EsY0FBY0EsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsYUFBYUEsRUFBRUEsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDL0ZBLElBQUlBLGVBQXFDQSxDQUFDQTtRQUMxQ0EsSUFBSUEsYUFBbUNBLENBQUNBO1FBQ3hDQSxJQUFJQSxJQUFJQSxHQUF5QkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUV6RUEsYUFBYUEsR0FBR0EsYUFBYUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUN0REEsUUFBUUEsQ0FBQ0EsNkJBQTZCQSxHQUFHQSxhQUFhQSxDQUFDQSxLQUFLQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUUvREEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxhQUFhQSxDQUFDQSxjQUFjQSxFQUFFQSxDQUFDQTtRQUN4REEsZUFBZUEsR0FBR0EsYUFBYUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUN4REEsYUFBYUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUN0Q0EsYUFBYUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUN0Q0EsYUFBYUEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUV0Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsU0FBU0EsR0FBR0EsZUFBZUEsR0FBR0EsSUFBSUEsR0FDekRBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQzFEQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxhQUFhQSxHQUFHQSxPQUFPQSxHQUNsRUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsR0FBR0EsT0FBT0EsR0FBR0EsYUFBYUEsR0FBR0EsT0FBT0EsR0FDbEVBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsR0FDNURBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsYUFBYUEsQ0FBQ0E7UUFFakRBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURQOztPQUVHQTtJQUNJQSw2REFBMkJBLEdBQWxDQSxVQUFtQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTdKUSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3pEQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3ZEQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3hEQSxRQUFRQSxDQUFDQSwrQkFBK0JBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLEdBQUNBLENBQUNBLENBQUNBO1FBRWxFQSxNQUFNQSxDQUFDQSxnQkFBS0EsQ0FBQ0EsMkJBQTJCQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtJQUNsR0EsQ0FBQ0E7SUFFRFI7O09BRUdBO0lBQ0lBLDBEQUF3QkEsR0FBL0JBLFVBQWdDQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLFdBQWlDQSxFQUFFQSxXQUFpQ0EsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUVoT1MsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFdBQVdBLENBQUNBO1FBQ2xDQSxNQUFNQSxDQUFDQSxnQkFBS0EsQ0FBQ0Esd0JBQXdCQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxXQUFXQSxFQUFFQSxXQUFXQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtJQUN6SEEsQ0FBQ0E7SUFFRFQ7O09BRUdBO0lBQ0lBLDhEQUE0QkEsR0FBbkNBLFVBQW9DQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRS9MVSxJQUFJQSxJQUFJQSxHQUFVQSxnQkFBS0EsQ0FBQ0EsNEJBQTRCQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxTQUFTQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUN4SEEsSUFBSUEsSUFBSUEsR0FBeUJBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7UUFFM0VBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLE1BQU1BLEdBQzNGQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUN0RUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFFeEVBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLElBQUlBLGVBQWVBLENBQUNBLGVBQWVBLENBQUNBO1lBQ3REQSxhQUFhQSxDQUFDQSx1QkFBdUJBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBO1FBRWxEQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVEVjs7T0FFR0E7SUFDSUEsMkNBQVNBLEdBQWhCQSxVQUFpQkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxLQUFXQTtRQUVqRlcsZ0JBQUtBLENBQUNBLFNBQVNBLFlBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO1FBRS9DQSxJQUFJQSxLQUFLQSxHQUFrQkEsUUFBUUEsQ0FBQ0EsK0JBQStCQSxDQUFDQTtRQUNwRUEsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUNqQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDakNBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBQ25DQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtJQUN0Q0EsQ0FBQ0E7SUFFRFg7O09BRUdBO0lBQ0lBLGlEQUFlQSxHQUF0QkEsVUFBdUJBLFlBQTZCQSxFQUFFQSxRQUFpQkEsRUFBRUEsVUFBeUJBLEVBQUVBLEtBQVdBLEVBQUVBLE1BQWFBO1FBRTFHWSxLQUFLQSxDQUFDQSxPQUFRQSxDQUFDQSxlQUFlQSxDQUFDQSxRQUFRQSxDQUFDQSxzQkFBc0JBLEVBQUVBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLGFBQWFBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBO1FBRTlIQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxlQUFlQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQSxhQUFhQSxDQUFDQSxZQUFZQSxDQUFDQSxrQkFBa0JBLEVBQUVBLFFBQVFBLENBQUNBLDZCQUE2QkEsR0FBR0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDOUlBLENBQUNBO0lBRURaOztPQUVHQTtJQUNLQSw4Q0FBWUEsR0FBcEJBLFVBQXFCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTVLYSxBQUNBQSwyQkFEMkJBO1FBQzNCQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtZQUN4QkEsTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7UUFFWEEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFNUJBLElBQUlBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBQ3JCQSxJQUFJQSxRQUFRQSxHQUF5QkEsYUFBYUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtRQUV2RUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDckNBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLGVBQWVBLENBQUNBLGVBQWVBLENBQUNBO1FBQ25EQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1lBQzVEQSxhQUFhQSxDQUFDQSxxQkFBcUJBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQ3pEQSxDQUFDQTtRQUVEQSxRQUFRQSxDQUFDQSxzQkFBc0JBLEdBQUdBLFFBQVFBLENBQUNBLEtBQUtBLENBQUNBO1FBRWpEQSxJQUFJQSxJQUFJQSxHQUF5QkEsYUFBYUEsQ0FBQ0EseUJBQXlCQSxFQUFFQSxDQUFDQTtRQUMzRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSx1QkFBdUJBLEdBRWhHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUNqRUEsQUFDQUEsa0RBRGtEQTtRQUNsREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUV6RkEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDekVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUloREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDaERBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUN6RUEsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FHM0VBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLE1BQU1BLEdBQ2hGQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUV2RUEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFDRmIsOEJBQUNBO0FBQURBLENBclFBLEFBcVFDQSxFQXJRcUMsc0JBQXNCLEVBcVEzRDtBQUVELEFBQWlDLGlCQUF4Qix1QkFBdUIsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBEaWZmdXNlQmFzaWNNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQmFzaWNNZXRob2RcIik7XG5pbXBvcnQgTWF0ZXJpYWxQYXNzQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3Bhc3Nlcy9NYXRlcmlhbFBhc3NCYXNlXCIpO1xuXG5pbXBvcnQgRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQ29tcG9zaXRlTWV0aG9kXCIpO1xuaW1wb3J0IFNpbmdsZU9iamVjdERlcHRoUGFzc1x0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvcGFzc2VzL1NpbmdsZU9iamVjdERlcHRoUGFzc1wiKTtcblxuLyoqXG4gKiBEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZCBwcm92aWRlcyBhIGRlcHRoIG1hcC1iYXNlZCBkaWZmdXNlIHNoYWRpbmcgbWV0aG9kIHRoYXQgbWltaWNzIHRoZSBzY2F0dGVyaW5nIG9mXG4gKiBsaWdodCBpbnNpZGUgdHJhbnNsdWNlbnQgc3VyZmFjZXMuIEl0IGFsbG93cyBsaWdodCB0byBzaGluZSB0aHJvdWdoIGFuIG9iamVjdCBhbmQgdG8gc29mdGVuIHRoZSBkaWZmdXNlIHNoYWRpbmcuXG4gKiBJdCBjYW4gYmUgdXNlZCBmb3IgY2FuZGxlIHdheCwgaWNlLCBza2luLCAuLi5cbiAqL1xuY2xhc3MgRGlmZnVzZVN1YlN1cmZhY2VNZXRob2QgZXh0ZW5kcyBEaWZmdXNlQ29tcG9zaXRlTWV0aG9kXG57XG5cdHByaXZhdGUgX2RlcHRoUGFzczpTaW5nbGVPYmplY3REZXB0aFBhc3M7XG5cdHByaXZhdGUgX2xpZ2h0UHJvalZhcnlpbmc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRwcml2YXRlIF9wcm9wUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc2NhdHRlcmluZzpudW1iZXI7XG5cdHByaXZhdGUgX3RyYW5zbHVjZW5jeTpudW1iZXIgPSAxO1xuXHRwcml2YXRlIF9saWdodENvbG9yUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc2NhdHRlckNvbG9yOm51bWJlciAvKnVpbnQqLyA9IDB4ZmZmZmZmO1xuXHRwcml2YXRlIF9jb2xvclJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdHByaXZhdGUgX2RlY1JlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdHByaXZhdGUgX3NjYXR0ZXJSOm51bWJlciA9IDEuMDtcblx0cHJpdmF0ZSBfc2NhdHRlckc6bnVtYmVyID0gMS4wO1xuXHRwcml2YXRlIF9zY2F0dGVyQjpudW1iZXIgPSAxLjA7XG5cdHByaXZhdGUgX3RhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5EaWZmdXNlU3ViU3VyZmFjZU1ldGhvZDwvY29kZT4gb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gZGVwdGhNYXBTaXplIFRoZSBzaXplIG9mIHRoZSBkZXB0aCBtYXAgdXNlZC5cblx0ICogQHBhcmFtIGRlcHRoTWFwT2Zmc2V0IFRoZSBhbW91bnQgYnkgd2hpY2ggdGhlIHJlbmRlcmVkIG9iamVjdCB3aWxsIGJlIGluZmxhdGVkLCB0byBwcmV2ZW50IGRlcHRoIG1hcCByb3VuZGluZyBlcnJvcnMuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBkaWZmdXNlIG1ldGhvZCB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgcmVndWxhciBkaWZmdXNlLWJhc2VkIGxpZ2h0aW5nLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoZGVwdGhNYXBTaXplOm51bWJlciAvKmludCovID0gNTEyLCBkZXB0aE1hcE9mZnNldDpudW1iZXIgPSAxNSwgYmFzZU1ldGhvZDpEaWZmdXNlQmFzaWNNZXRob2QgPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIobnVsbCwgYmFzZU1ldGhvZCk7XG5cblx0XHR0aGlzLnBCYXNlTWV0aG9kLl9pTW9kdWxhdGVNZXRob2QgPSAoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpID0+IHRoaXMuc2NhdHRlckxpZ2h0KHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHRhcmdldFJlZywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblxuXHRcdHRoaXMuX3Bhc3NlcyA9IG5ldyBBcnJheTxNYXRlcmlhbFBhc3NCYXNlPigpO1xuXHRcdHRoaXMuX2RlcHRoUGFzcyA9IG5ldyBTaW5nbGVPYmplY3REZXB0aFBhc3MoKTtcblx0XHR0aGlzLl9kZXB0aFBhc3MudGV4dHVyZVNpemUgPSBkZXB0aE1hcFNpemU7XG5cdFx0dGhpcy5fZGVwdGhQYXNzLnBvbHlPZmZzZXQgPSBkZXB0aE1hcE9mZnNldDtcblx0XHR0aGlzLl9wYXNzZXMucHVzaCh0aGlzLl9kZXB0aFBhc3MpO1xuXHRcdHRoaXMuX3NjYXR0ZXJpbmcgPSAwLjI7XG5cdFx0dGhpcy5fdHJhbnNsdWNlbmN5ID0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRzdXBlci5pSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblxuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QudmVydGV4Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IG1ldGhvZFZPLnNlY29uZGFyeVZlcnRleENvbnN0YW50c0luZGV4O1xuXHRcdGRhdGFbaW5kZXhdID0gLjU7XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gLS41O1xuXHRcdGRhdGFbaW5kZXggKyAyXSA9IDA7XG5cdFx0ZGF0YVtpbmRleCArIDNdID0gMTtcblx0XHRcblx0XHRkYXRhID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdGluZGV4ID0gbWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHRkYXRhW2luZGV4ICsgM10gPSAxLjA7XG5cdFx0ZGF0YVtpbmRleCArIDRdID0gMS4wO1xuXHRcdGRhdGFbaW5kZXggKyA1XSA9IDEvMjU1O1xuXHRcdGRhdGFbaW5kZXggKyA2XSA9IDEvNjUwMjU7XG5cdFx0ZGF0YVtpbmRleCArIDddID0gMS8xNjU4MTM3NTtcblx0XHRkYXRhW2luZGV4ICsgMTBdID0gLjU7XG5cdFx0ZGF0YVtpbmRleCArIDExXSA9IC0uMTtcblx0fVxuXHRcblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblxuXHRcdHRoaXMuX2xpZ2h0UHJvalZhcnlpbmcgPSBudWxsO1xuXHRcdHRoaXMuX3Byb3BSZWcgPSBudWxsO1xuXHRcdHRoaXMuX2xpZ2h0Q29sb3JSZWcgPSBudWxsO1xuXHRcdHRoaXMuX2NvbG9yUmVnID0gbnVsbDtcblx0XHR0aGlzLl9kZWNSZWcgPSBudWxsO1xuXHRcdHRoaXMuX3RhcmdldFJlZyA9IG51bGw7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IGJ5IHdoaWNoIHRoZSBsaWdodCBzY2F0dGVycy4gSXQgY2FuIGJlIHVzZWQgdG8gc2V0IHRoZSB0cmFuc2x1Y2VudCBzdXJmYWNlJ3MgdGhpY2tuZXNzLiBVc2UgbG93XG5cdCAqIHZhbHVlcyBmb3Igc2tpbi5cblx0ICovXG5cdHB1YmxpYyBnZXQgc2NhdHRlcmluZygpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3NjYXR0ZXJpbmc7XG5cdH1cblx0XG5cdHB1YmxpYyBzZXQgc2NhdHRlcmluZyh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9zY2F0dGVyaW5nID0gdmFsdWU7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBUaGUgdHJhbnNsdWNlbmN5IG9mIHRoZSBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHRyYW5zbHVjZW5jeSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3RyYW5zbHVjZW5jeTtcblx0fVxuXHRcblx0cHVibGljIHNldCB0cmFuc2x1Y2VuY3kodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fdHJhbnNsdWNlbmN5ID0gdmFsdWU7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBUaGUgY29sb3VyIG9mIHRoZSBcImluc2lkZXNcIiBvZiB0aGUgb2JqZWN0LCBpZTogdGhlIGNvbG91ciB0aGUgbGlnaHQgYmVjb21lcyBhZnRlciBsZWF2aW5nIHRoZSBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHNjYXR0ZXJDb2xvcigpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3NjYXR0ZXJDb2xvcjtcblx0fVxuXHRcblx0cHVibGljIHNldCBzY2F0dGVyQ29sb3Ioc2NhdHRlckNvbG9yOm51bWJlciAvKnVpbnQqLylcblx0e1xuXHRcdHRoaXMuX3NjYXR0ZXJDb2xvciA9IHNjYXR0ZXJDb2xvcjtcblx0XHR0aGlzLl9zY2F0dGVyUiA9ICgoc2NhdHRlckNvbG9yID4+IDE2KSAmIDB4ZmYpLzB4ZmY7XG5cdFx0dGhpcy5fc2NhdHRlckcgPSAoKHNjYXR0ZXJDb2xvciA+PiA4KSAmIDB4ZmYpLzB4ZmY7XG5cdFx0dGhpcy5fc2NhdHRlckIgPSAoc2NhdHRlckNvbG9yICYgMHhmZikvMHhmZjtcblx0fVxuXHRcblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gc3VwZXIuaUdldFZlcnRleENvZGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0XHR2YXIgbGlnaHRQcm9qZWN0aW9uOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0XHR2YXIgdG9UZXhSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4VmVjdG9yVGVtcCgpO1xuXHRcdFxuXHRcdHRvVGV4UmVnaXN0ZXIgPSByZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdG1ldGhvZFZPLnNlY29uZGFyeVZlcnRleENvbnN0YW50c0luZGV4ID0gdG9UZXhSZWdpc3Rlci5pbmRleCo0O1xuXG5cdFx0dGhpcy5fbGlnaHRQcm9qVmFyeWluZyA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZhcnlpbmcoKTtcblx0XHRsaWdodFByb2plY3Rpb24gPSByZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRyZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdFxuXHRcdGNvZGUgKz0gXCJtNDQgXCIgKyB0ZW1wICsgXCIsIHZ0MCwgXCIgKyBsaWdodFByb2plY3Rpb24gKyBcIlxcblwiICtcblx0XHRcdFwiZGl2IFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIueHksIFwiICsgdGVtcCArIFwiLnh5LCBcIiArIHRvVGV4UmVnaXN0ZXIgKyBcIi54eVxcblwiICtcblx0XHRcdFwiYWRkIFwiICsgdGVtcCArIFwiLnh5LCBcIiArIHRlbXAgKyBcIi54eSwgXCIgKyB0b1RleFJlZ2lzdGVyICsgXCIueHhcXG5cIiArXG5cdFx0XHRcIm1vdiBcIiArIHRoaXMuX2xpZ2h0UHJvalZhcnlpbmcgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5elxcblwiICtcblx0XHRcdFwibW92IFwiICsgdGhpcy5fbGlnaHRQcm9qVmFyeWluZyArIFwiLncsIHZhMC53XFxuXCI7XG5cdFx0XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5fY29sb3JSZWcgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dGhpcy5fZGVjUmVnID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHRoaXMuX3Byb3BSZWcgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0bWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleCA9IHRoaXMuX2NvbG9yUmVnLmluZGV4KjQ7XG5cdFx0XG5cdFx0cmV0dXJuIHN1cGVyLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgbGlnaHREaXJSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBsaWdodENvbFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR0aGlzLl9wSXNGaXJzdExpZ2h0ID0gdHJ1ZTtcblx0XHR0aGlzLl9saWdodENvbG9yUmVnID0gbGlnaHRDb2xSZWc7XG5cdFx0cmV0dXJuIHN1cGVyLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodChzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBsaWdodERpclJlZywgbGlnaHRDb2xSZWcsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IHN1cGVyLmlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgdGFyZ2V0UmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdFxuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIHRoaXMuX2xpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgdGhpcy5fdGFyZ2V0UmVnICsgXCIud1xcblwiICtcblx0XHRcdFwibXVsIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIHRoaXMuX2NvbG9yUmVnICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi54eXpcXG5cIjtcblx0XHRcblx0XHRpZiAodGhpcy5fdGFyZ2V0UmVnICE9IHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQpXG5cdFx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHRhcmdldFJlZyk7XG5cdFx0XG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cdFx0XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gbWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdGRhdGFbaW5kZXhdID0gdGhpcy5fc2NhdHRlclI7XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gdGhpcy5fc2NhdHRlckc7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gdGhpcy5fc2NhdHRlckI7XG5cdFx0ZGF0YVtpbmRleCArIDhdID0gdGhpcy5fc2NhdHRlcmluZztcblx0XHRkYXRhW2luZGV4ICsgOV0gPSB0aGlzLl90cmFuc2x1Y2VuY3k7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpU2V0UmVuZGVyU3RhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZVRleHR1cmUobWV0aG9kVk8uc2Vjb25kYXJ5VGV4dHVyZXNJbmRleCwgdGhpcy5fZGVwdGhQYXNzLl9pR2V0RGVwdGhNYXAocmVuZGVyYWJsZSkpO1xuXG5cdFx0dGhpcy5fZGVwdGhQYXNzLl9pR2V0UHJvamVjdGlvbihyZW5kZXJhYmxlKS5jb3B5UmF3RGF0YVRvKHNoYWRlck9iamVjdC52ZXJ0ZXhDb25zdGFudERhdGEsIG1ldGhvZFZPLnNlY29uZGFyeVZlcnRleENvbnN0YW50c0luZGV4ICsgNCwgdHJ1ZSk7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBHZW5lcmF0ZXMgdGhlIGNvZGUgZm9yIHRoaXMgbWV0aG9kXG5cdCAqL1xuXHRwcml2YXRlIHNjYXR0ZXJMaWdodChzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHQvLyBvbmx5IHNjYXR0ZXIgZmlyc3QgbGlnaHRcblx0XHRpZiAoIXRoaXMuX3BJc0ZpcnN0TGlnaHQpXG5cdFx0XHRyZXR1cm4gXCJcIjtcblxuXHRcdHRoaXMuX3BJc0ZpcnN0TGlnaHQgPSBmYWxzZTtcblxuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIGRlcHRoUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblxuXHRcdGlmIChzaGFyZWRSZWdpc3RlcnMudmlld0RpckZyYWdtZW50KSB7XG5cdFx0XHR0aGlzLl90YXJnZXRSZWcgPSBzaGFyZWRSZWdpc3RlcnMudmlld0RpckZyYWdtZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl90YXJnZXRSZWcgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblx0XHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHRoaXMuX3RhcmdldFJlZywgMSk7XG5cdFx0fVxuXG5cdFx0bWV0aG9kVk8uc2Vjb25kYXJ5VGV4dHVyZXNJbmRleCA9IGRlcHRoUmVnLmluZGV4O1xuXHRcdFxuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdGNvZGUgKz0gXCJ0ZXggXCIgKyB0ZW1wICsgXCIsIFwiICsgdGhpcy5fbGlnaHRQcm9qVmFyeWluZyArIFwiLCBcIiArIGRlcHRoUmVnICsgXCIgPDJkLG5lYXJlc3QsY2xhbXA+XFxuXCIgK1xuXHRcdFx0Ly8gcmVlbmNvZGUgUkdCQVxuXHRcdFx0XCJkcDQgXCIgKyB0YXJnZXRSZWcgKyBcIi56LCBcIiArIHRlbXAgKyBcIiwgXCIgKyB0aGlzLl9kZWNSZWcgKyBcIlxcblwiO1xuXHRcdC8vIGN1cnJlbnREaXN0YW5jZVRvTGlnaHQgLSBjbG9zZXN0RGlzdGFuY2VUb0xpZ2h0XG5cdFx0Y29kZSArPSBcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnosIFwiICsgdGhpcy5fbGlnaHRQcm9qVmFyeWluZyArIFwiLnosIFwiICsgdGFyZ2V0UmVnICsgXCIuelxcblwiICtcblx0XHRcdFxuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi56LCBcIiArIHRoaXMuX3Byb3BSZWcgKyBcIi54LCBcIiArIHRhcmdldFJlZyArIFwiLnpcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRhcmdldFJlZyArIFwiLnosIFwiICsgdGhpcy5fcHJvcFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIuelxcblwiICtcblx0XHRcdFwic2F0IFwiICsgdGFyZ2V0UmVnICsgXCIueiwgXCIgKyB0YXJnZXRSZWcgKyBcIi56XFxuXCIgK1xuXHRcdFx0XG5cdFx0XHQvLyB0YXJnZXRSZWcueCBjb250YWlucyBkb3QobGlnaHREaXIsIG5vcm1hbClcblx0XHRcdC8vIG1vZHVsYXRlIGFjY29yZGluZyB0byBpbmNpZGVudCBsaWdodCBhbmdsZSAoc2NhdHRlciA9IHNjYXR0ZXIqKC0uNSpkb3QobGlnaHQsIG5vcm1hbCkgKyAuNSlcblx0XHRcdFwibmVnIFwiICsgdGFyZ2V0UmVnICsgXCIueSwgXCIgKyB0YXJnZXRSZWcgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGhpcy5fcHJvcFJlZyArIFwiLnpcXG5cIiArXG5cdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIueSwgXCIgKyB0aGlzLl9wcm9wUmVnICsgXCIuelxcblwiICtcblx0XHRcdFwibXVsIFwiICsgdGhpcy5fdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi56LCBcIiArIHRhcmdldFJlZyArIFwiLnlcXG5cIiArXG5cdFx0XHRcblx0XHRcdC8vIGJsZW5kIGRpZmZ1c2U6IGQnID0gKDEtcykqZCArIHMqMVxuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRoaXMuX2NvbG9yUmVnICsgXCIudywgXCIgKyB0aGlzLl90YXJnZXRSZWcgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiO1xuXHRcdFxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG59XG5cbmV4cG9ydCA9IERpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseSubSurfaceMethod.ts b/lib/materials/methods/DiffuseSubSurfaceMethod.ts
new file mode 100644
index 000000000..6b0622b9a
--- /dev/null
+++ b/lib/materials/methods/DiffuseSubSurfaceMethod.ts
@@ -0,0 +1,286 @@
+import Camera = require("awayjs-core/lib/entities/Camera");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+import MaterialPassBase = require("awayjs-stagegl/lib/materials/passes/MaterialPassBase");
+
+import DiffuseCompositeMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCompositeMethod");
+import SingleObjectDepthPass = require("awayjs-renderergl/lib/materials/passes/SingleObjectDepthPass");
+
+/**
+ * DiffuseSubSurfaceMethod provides a depth map-based diffuse shading method that mimics the scattering of
+ * light inside translucent surfaces. It allows light to shine through an object and to soften the diffuse shading.
+ * It can be used for candle wax, ice, skin, ...
+ */
+class DiffuseSubSurfaceMethod extends DiffuseCompositeMethod
+{
+ private _depthPass:SingleObjectDepthPass;
+ private _lightProjVarying:ShaderRegisterElement;
+ private _propReg:ShaderRegisterElement;
+ private _scattering:number;
+ private _translucency:number = 1;
+ private _lightColorReg:ShaderRegisterElement;
+ private _scatterColor:number /*uint*/ = 0xffffff;
+ private _colorReg:ShaderRegisterElement;
+ private _decReg:ShaderRegisterElement;
+ private _scatterR:number = 1.0;
+ private _scatterG:number = 1.0;
+ private _scatterB:number = 1.0;
+ private _targetReg:ShaderRegisterElement;
+
+ /**
+ * Creates a new DiffuseSubSurfaceMethod
object.
+ *
+ * @param depthMapSize The size of the depth map used.
+ * @param depthMapOffset The amount by which the rendered object will be inflated, to prevent depth map rounding errors.
+ * @param baseMethod The diffuse method used to calculate the regular diffuse-based lighting.
+ */
+ constructor(depthMapSize:number /*int*/ = 512, depthMapOffset:number = 15, baseMethod:DiffuseBasicMethod = null)
+ {
+ super(null, baseMethod);
+
+ this.pBaseMethod._iModulateMethod = (shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => this.scatterLight(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+
+ this._passes = new Array();
+ this._depthPass = new SingleObjectDepthPass();
+ this._depthPass.textureSize = depthMapSize;
+ this._depthPass.polyOffset = depthMapOffset;
+ this._passes.push(this._depthPass);
+ this._scattering = 0.2;
+ this._translucency = 1;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitConstants(shaderObject:ShaderLightingObject, methodVO:MethodVO)
+ {
+ super.iInitConstants(shaderObject, methodVO);
+
+ var data:Array = shaderObject.vertexConstantData;
+ var index:number /*int*/ = methodVO.secondaryVertexConstantsIndex;
+ data[index] = .5;
+ data[index + 1] = -.5;
+ data[index + 2] = 0;
+ data[index + 3] = 1;
+
+ data = shaderObject.fragmentConstantData;
+ index = methodVO.secondaryFragmentConstantsIndex;
+ data[index + 3] = 1.0;
+ data[index + 4] = 1.0;
+ data[index + 5] = 1/255;
+ data[index + 6] = 1/65025;
+ data[index + 7] = 1/16581375;
+ data[index + 10] = .5;
+ data[index + 11] = -.1;
+ }
+
+ public iCleanCompilationData()
+ {
+ super.iCleanCompilationData();
+
+ this._lightProjVarying = null;
+ this._propReg = null;
+ this._lightColorReg = null;
+ this._colorReg = null;
+ this._decReg = null;
+ this._targetReg = null;
+ }
+
+ /**
+ * The amount by which the light scatters. It can be used to set the translucent surface's thickness. Use low
+ * values for skin.
+ */
+ public get scattering():number
+ {
+ return this._scattering;
+ }
+
+ public set scattering(value:number)
+ {
+ this._scattering = value;
+ }
+
+ /**
+ * The translucency of the object.
+ */
+ public get translucency():number
+ {
+ return this._translucency;
+ }
+
+ public set translucency(value:number)
+ {
+ this._translucency = value;
+ }
+
+ /**
+ * The colour of the "insides" of the object, ie: the colour the light becomes after leaving the object.
+ */
+ public get scatterColor():number /*uint*/
+ {
+ return this._scatterColor;
+ }
+
+ public set scatterColor(scatterColor:number /*uint*/)
+ {
+ this._scatterColor = scatterColor;
+ this._scatterR = ((scatterColor >> 16) & 0xff)/0xff;
+ this._scatterG = ((scatterColor >> 8) & 0xff)/0xff;
+ this._scatterB = (scatterColor & 0xff)/0xff;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetVertexCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = super.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ var lightProjection:ShaderRegisterElement;
+ var toTexRegister:ShaderRegisterElement;
+ var temp:ShaderRegisterElement = registerCache.getFreeVertexVectorTemp();
+
+ toTexRegister = registerCache.getFreeVertexConstant();
+ methodVO.secondaryVertexConstantsIndex = toTexRegister.index*4;
+
+ this._lightProjVarying = registerCache.getFreeVarying();
+ lightProjection = registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+ registerCache.getFreeVertexConstant();
+
+ code += "m44 " + temp + ", vt0, " + lightProjection + "\n" +
+ "div " + temp + ".xyz, " + temp + ".xyz, " + temp + ".w\n" +
+ "mul " + temp + ".xy, " + temp + ".xy, " + toTexRegister + ".xy\n" +
+ "add " + temp + ".xy, " + temp + ".xy, " + toTexRegister + ".xx\n" +
+ "mov " + this._lightProjVarying + ".xyz, " + temp + ".xyz\n" +
+ "mov " + this._lightProjVarying + ".w, va0.w\n";
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ this._colorReg = registerCache.getFreeFragmentConstant();
+ this._decReg = registerCache.getFreeFragmentConstant();
+ this._propReg = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._colorReg.index*4;
+
+ return super.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ this._pIsFirstLight = true;
+ this._lightColorReg = lightColReg;
+ return super.iGetFragmentCodePerLight(shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPostLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = super.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters);
+ var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp();
+
+ code += "mul " + temp + ".xyz, " + this._lightColorReg + ".xyz, " + this._targetReg + ".w\n" +
+ "mul " + temp + ".xyz, " + temp + ".xyz, " + this._colorReg + ".xyz\n" +
+ "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n";
+
+ if (this._targetReg != sharedRegisters.viewDirFragment)
+ registerCache.removeFragmentTempUsage(targetReg);
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ super.iActivate(shaderObject, methodVO, stage);
+
+ var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex;
+ var data:Array = shaderObject.fragmentConstantData;
+ data[index] = this._scatterR;
+ data[index + 1] = this._scatterG;
+ data[index + 2] = this._scatterB;
+ data[index + 8] = this._scattering;
+ data[index + 9] = this._translucency;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iSetRenderState(shaderObject:ShaderObjectBase, methodVO:MethodVO, renderable:RenderableBase, stage:Stage, camera:Camera)
+ {
+ ( stage.context).activateTexture(methodVO.secondaryTexturesIndex, this._depthPass._iGetDepthMap(renderable));
+
+ this._depthPass._iGetProjection(renderable).copyRawDataTo(shaderObject.vertexConstantData, methodVO.secondaryVertexConstantsIndex + 4, true);
+ }
+
+ /**
+ * Generates the code for this method
+ */
+ private scatterLight(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ // only scatter first light
+ if (!this._pIsFirstLight)
+ return "";
+
+ this._pIsFirstLight = false;
+
+ var code:string = "";
+ var depthReg:ShaderRegisterElement = registerCache.getFreeTextureReg();
+
+ if (sharedRegisters.viewDirFragment) {
+ this._targetReg = sharedRegisters.viewDirFragment;
+ } else {
+ this._targetReg = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(this._targetReg, 1);
+ }
+
+ methodVO.secondaryTexturesIndex = depthReg.index;
+
+ var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp();
+ code += "tex " + temp + ", " + this._lightProjVarying + ", " + depthReg + " <2d,nearest,clamp>\n" +
+ // reencode RGBA
+ "dp4 " + targetReg + ".z, " + temp + ", " + this._decReg + "\n";
+ // currentDistanceToLight - closestDistanceToLight
+ code += "sub " + targetReg + ".z, " + this._lightProjVarying + ".z, " + targetReg + ".z\n" +
+
+ "sub " + targetReg + ".z, " + this._propReg + ".x, " + targetReg + ".z\n" +
+ "mul " + targetReg + ".z, " + this._propReg + ".y, " + targetReg + ".z\n" +
+ "sat " + targetReg + ".z, " + targetReg + ".z\n" +
+
+ // targetReg.x contains dot(lightDir, normal)
+ // modulate according to incident light angle (scatter = scatter*(-.5*dot(light, normal) + .5)
+ "neg " + targetReg + ".y, " + targetReg + ".x\n" +
+ "mul " + targetReg + ".y, " + targetReg + ".y, " + this._propReg + ".z\n" +
+ "add " + targetReg + ".y, " + targetReg + ".y, " + this._propReg + ".z\n" +
+ "mul " + this._targetReg + ".w, " + targetReg + ".z, " + targetReg + ".y\n" +
+
+ // blend diffuse: d' = (1-s)*d + s*1
+ "sub " + targetReg + ".y, " + this._colorReg + ".w, " + this._targetReg + ".w\n" +
+ "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n";
+
+ return code;
+ }
+}
+
+export = DiffuseSubSurfaceMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseWrapMethod.js b/lib/materials/methods/DiffuseWrapMethod.js
new file mode 100755
index 000000000..4dd9ee90f
--- /dev/null
+++ b/lib/materials/methods/DiffuseWrapMethod.js
@@ -0,0 +1,93 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+/**
+ * DiffuseWrapMethod is an alternative to DiffuseBasicMethod in which the light is allowed to be "wrapped around" the normally dark area, to some extent.
+ * It can be used as a crude approximation to Oren-Nayar or simple subsurface scattering.
+ */
+var DiffuseWrapMethod = (function (_super) {
+ __extends(DiffuseWrapMethod, _super);
+ /**
+ * Creates a new DiffuseWrapMethod object.
+ * @param wrapFactor A factor to indicate the amount by which the light is allowed to wrap
+ */
+ function DiffuseWrapMethod(wrapFactor) {
+ if (wrapFactor === void 0) { wrapFactor = .5; }
+ _super.call(this);
+ this.wrapFactor = wrapFactor;
+ }
+ /**
+ * @inheritDoc
+ */
+ DiffuseWrapMethod.prototype.iCleanCompilationData = function () {
+ _super.prototype.iCleanCompilationData.call(this);
+ this._wrapDataRegister = null;
+ };
+ Object.defineProperty(DiffuseWrapMethod.prototype, "wrapFactor", {
+ /**
+ * A factor to indicate the amount by which the light is allowed to wrap.
+ */
+ get: function () {
+ return this._wrapFactor;
+ },
+ set: function (value) {
+ this._wrapFactor = value;
+ this._wrapFactor = 1 / (value + 1);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ DiffuseWrapMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) {
+ var code = _super.prototype.iGetFragmentPreLightingCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters);
+ this._pIsFirstLight = true;
+ this._wrapDataRegister = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._wrapDataRegister.index * 4;
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseWrapMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) {
+ var code = "";
+ var t;
+ // write in temporary if not first light, so we can add to total diffuse colour
+ if (this._pIsFirstLight) {
+ t = this._pTotalLightColorReg;
+ }
+ else {
+ t = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(t, 1);
+ }
+ code += "dp3 " + t + ".x, " + lightDirReg + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + "add " + t + ".y, " + t + ".x, " + this._wrapDataRegister + ".x\n" + "mul " + t + ".y, " + t + ".y, " + this._wrapDataRegister + ".y\n" + "sat " + t + ".w, " + t + ".y\n" + "mul " + t + ".xz, " + t + ".w, " + lightDirReg + ".wz\n";
+ if (this._iModulateMethod != null)
+ code += this._iModulateMethod(shaderObject, methodVO, lightDirReg, registerCache, sharedRegisters);
+ code += "mul " + t + ", " + t + ".x, " + lightColReg + "\n";
+ if (!this._pIsFirstLight) {
+ code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n";
+ registerCache.removeFragmentTempUsage(t);
+ }
+ this._pIsFirstLight = false;
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ DiffuseWrapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ _super.prototype.iActivate.call(this, shaderObject, methodVO, stage);
+ var index = methodVO.secondaryFragmentConstantsIndex;
+ var data = shaderObject.fragmentConstantData;
+ data[index] = this._wrapFactor;
+ data[index + 1] = 1 / (this._wrapFactor + 1);
+ };
+ return DiffuseWrapMethod;
+})(DiffuseBasicMethod);
+module.exports = DiffuseWrapMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2V3cmFwbWV0aG9kLnRzIl0sIm5hbWVzIjpbIkRpZmZ1c2VXcmFwTWV0aG9kIiwiRGlmZnVzZVdyYXBNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlV3JhcE1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJEaWZmdXNlV3JhcE1ldGhvZC53cmFwRmFjdG9yIiwiRGlmZnVzZVdyYXBNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiRGlmZnVzZVdyYXBNZXRob2QuaUdldEZyYWdtZW50Q29kZVBlckxpZ2h0IiwiRGlmZnVzZVdyYXBNZXRob2QuaUFjdGl2YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLGtCQUFrQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFbEcsQUFJQTs7O0dBREc7SUFDRyxpQkFBaUI7SUFBU0EsVUFBMUJBLGlCQUFpQkEsVUFBMkJBO0lBS2pEQTs7O09BR0dBO0lBQ0hBLFNBVEtBLGlCQUFpQkEsQ0FTVkEsVUFBc0JBO1FBQXRCQywwQkFBc0JBLEdBQXRCQSxlQUFzQkE7UUFFakNBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxVQUFVQSxDQUFDQTtJQUM5QkEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLGlEQUFxQkEsR0FBNUJBO1FBRUNFLGdCQUFLQSxDQUFDQSxxQkFBcUJBLFdBQUVBLENBQUNBO1FBRTlCQSxJQUFJQSxDQUFDQSxpQkFBaUJBLEdBQUdBLElBQUlBLENBQUNBO0lBQy9CQSxDQUFDQTtJQUtERixzQkFBV0EseUNBQVVBO1FBSHJCQTs7V0FFR0E7YUFDSEE7WUFFQ0csTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDekJBLENBQUNBO2FBRURILFVBQXNCQSxLQUFZQTtZQUVqQ0csSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0E7WUFDekJBLElBQUlBLENBQUNBLFdB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QUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFDNUdBLGFBQWFBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDMUNBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLEtBQUtBLENBQUNBO1FBRTVCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEscUNBQVNBLEdBQWhCQSxVQUFpQkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxLQUFXQTtRQUVqRk0sZ0JBQUtBLENBQUNBLFNBQVNBLFlBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO1FBRS9DQSxJQUFJQSxLQUFLQSxHQUFrQkEsUUFBUUEsQ0FBQ0EsK0JBQStCQSxDQUFDQTtRQUNwRUEsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBQy9CQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUM1Q0EsQ0FBQ0E7SUFDRk4sd0JBQUNBO0FBQURBLENBdEdBLEFBc0dDQSxFQXRHK0Isa0JBQWtCLEVBc0dqRDtBQUVELEFBQTJCLGlCQUFsQixpQkFBaUIsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlV3JhcE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBEaWZmdXNlQmFzaWNNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQmFzaWNNZXRob2RcIik7XG5cbi8qKlxuICogRGlmZnVzZVdyYXBNZXRob2QgaXMgYW4gYWx0ZXJuYXRpdmUgdG8gRGlmZnVzZUJhc2ljTWV0aG9kIGluIHdoaWNoIHRoZSBsaWdodCBpcyBhbGxvd2VkIHRvIGJlIFwid3JhcHBlZCBhcm91bmRcIiB0aGUgbm9ybWFsbHkgZGFyayBhcmVhLCB0byBzb21lIGV4dGVudC5cbiAqIEl0IGNhbiBiZSB1c2VkIGFzIGEgY3J1ZGUgYXBwcm94aW1hdGlvbiB0byBPcmVuLU5heWFyIG9yIHNpbXBsZSBzdWJzdXJmYWNlIHNjYXR0ZXJpbmcuXG4gKi9cbmNsYXNzIERpZmZ1c2VXcmFwTWV0aG9kIGV4dGVuZHMgRGlmZnVzZUJhc2ljTWV0aG9kXG57XG5cdHByaXZhdGUgX3dyYXBEYXRhUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRwcml2YXRlIF93cmFwRmFjdG9yOm51bWJlcjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlV3JhcE1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSB3cmFwRmFjdG9yIEEgZmFjdG9yIHRvIGluZGljYXRlIHRoZSBhbW91bnQgYnkgd2hpY2ggdGhlIGxpZ2h0IGlzIGFsbG93ZWQgdG8gd3JhcFxuXHQgKi9cblx0Y29uc3RydWN0b3Iod3JhcEZhY3RvcjpudW1iZXIgPSAuNSlcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLndyYXBGYWN0b3IgPSB3cmFwRmFjdG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUNsZWFuQ29tcGlsYXRpb25EYXRhKClcblx0e1xuXHRcdHN1cGVyLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpO1xuXG5cdFx0dGhpcy5fd3JhcERhdGFSZWdpc3RlciA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQSBmYWN0b3IgdG8gaW5kaWNhdGUgdGhlIGFtb3VudCBieSB3aGljaCB0aGUgbGlnaHQgaXMgYWxsb3dlZCB0byB3cmFwLlxuXHQgKi9cblx0cHVibGljIGdldCB3cmFwRmFjdG9yKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fd3JhcEZhY3Rvcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgd3JhcEZhY3Rvcih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl93cmFwRmFjdG9yID0gdmFsdWU7XG5cdFx0dGhpcy5fd3JhcEZhY3RvciA9IDEvKHZhbHVlICsgMSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRQcmVMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IHN1cGVyLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHRcdHRoaXMuX3BJc0ZpcnN0TGlnaHQgPSB0cnVlO1xuXHRcdHRoaXMuX3dyYXBEYXRhUmVnaXN0ZXIgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0bWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleCA9IHRoaXMuX3dyYXBEYXRhUmVnaXN0ZXIuaW5kZXgqNDtcblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZVBlckxpZ2h0KHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIGxpZ2h0RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgbGlnaHRDb2xSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgdDpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cblx0XHQvLyB3cml0ZSBpbiB0ZW1wb3JhcnkgaWYgbm90IGZpcnN0IGxpZ2h0LCBzbyB3ZSBjYW4gYWRkIHRvIHRvdGFsIGRpZmZ1c2UgY29sb3VyXG5cdFx0aWYgKHRoaXMuX3BJc0ZpcnN0TGlnaHQpIHtcblx0XHRcdHQgPSB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0XHRyZWdpc3RlckNhY2hlLmFkZEZyYWdtZW50VGVtcFVzYWdlcyh0LCAxKTtcblx0XHR9XG5cblx0XHRjb2RlICs9IFwiZHAzIFwiICsgdCArIFwiLngsIFwiICsgbGlnaHREaXJSZWcgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50ICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJhZGQgXCIgKyB0ICsgXCIueSwgXCIgKyB0ICsgXCIueCwgXCIgKyB0aGlzLl93cmFwRGF0YVJlZ2lzdGVyICsgXCIueFxcblwiICtcblx0XHRcdFwibXVsIFwiICsgdCArIFwiLnksIFwiICsgdCArIFwiLnksIFwiICsgdGhpcy5fd3JhcERhdGFSZWdpc3RlciArIFwiLnlcXG5cIiArXG5cdFx0XHRcInNhdCBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi55XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ICsgXCIueHosIFwiICsgdCArIFwiLncsIFwiICsgbGlnaHREaXJSZWcgKyBcIi53elxcblwiO1xuXG5cdFx0aWYgKHRoaXMuX2lNb2R1bGF0ZU1ldGhvZCAhPSBudWxsKVxuXHRcdFx0Y29kZSArPSB0aGlzLl9pTW9kdWxhdGVNZXRob2Qoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgbGlnaHREaXJSZWcsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cblx0XHRjb2RlICs9IFwibXVsIFwiICsgdCArIFwiLCBcIiArIHQgKyBcIi54LCBcIiArIGxpZ2h0Q29sUmVnICsgXCJcXG5cIjtcblxuXHRcdGlmICghdGhpcy5fcElzRmlyc3RMaWdodCkge1xuXHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZyArIFwiLnh5eiwgXCIgKyB0ICsgXCIueHl6XFxuXCI7XG5cdFx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHQpO1xuXHRcdH1cblxuXHRcdHRoaXMuX3BJc0ZpcnN0TGlnaHQgPSBmYWxzZTtcblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c3VwZXIuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblxuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IG1ldGhvZFZPLnNlY29uZGFyeUZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHRkYXRhW2luZGV4XSA9IHRoaXMuX3dyYXBGYWN0b3I7XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gMS8odGhpcy5fd3JhcEZhY3RvciArIDEpO1xuXHR9XG59XG5cbmV4cG9ydCA9IERpZmZ1c2VXcmFwTWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/DiffuseWrapMethod.ts b/lib/materials/methods/DiffuseWrapMethod.ts
new file mode 100644
index 000000000..1f84822d9
--- /dev/null
+++ b/lib/materials/methods/DiffuseWrapMethod.ts
@@ -0,0 +1,117 @@
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import DiffuseBasicMethod = require("awayjs-stagegl/lib/materials/methods/DiffuseBasicMethod");
+
+/**
+ * DiffuseWrapMethod is an alternative to DiffuseBasicMethod in which the light is allowed to be "wrapped around" the normally dark area, to some extent.
+ * It can be used as a crude approximation to Oren-Nayar or simple subsurface scattering.
+ */
+class DiffuseWrapMethod extends DiffuseBasicMethod
+{
+ private _wrapDataRegister:ShaderRegisterElement;
+ private _wrapFactor:number;
+
+ /**
+ * Creates a new DiffuseWrapMethod object.
+ * @param wrapFactor A factor to indicate the amount by which the light is allowed to wrap
+ */
+ constructor(wrapFactor:number = .5)
+ {
+ super();
+
+ this.wrapFactor = wrapFactor;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iCleanCompilationData()
+ {
+ super.iCleanCompilationData();
+
+ this._wrapDataRegister = null;
+ }
+
+ /**
+ * A factor to indicate the amount by which the light is allowed to wrap.
+ */
+ public get wrapFactor():number
+ {
+ return this._wrapFactor;
+ }
+
+ public set wrapFactor(value:number)
+ {
+ this._wrapFactor = value;
+ this._wrapFactor = 1/(value + 1);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = super.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters);
+ this._pIsFirstLight = true;
+ this._wrapDataRegister = registerCache.getFreeFragmentConstant();
+ methodVO.secondaryFragmentConstantsIndex = this._wrapDataRegister.index*4;
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var code:string = "";
+ var t:ShaderRegisterElement;
+
+ // write in temporary if not first light, so we can add to total diffuse colour
+ if (this._pIsFirstLight) {
+ t = this._pTotalLightColorReg;
+ } else {
+ t = registerCache.getFreeFragmentVectorTemp();
+ registerCache.addFragmentTempUsages(t, 1);
+ }
+
+ code += "dp3 " + t + ".x, " + lightDirReg + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" +
+ "add " + t + ".y, " + t + ".x, " + this._wrapDataRegister + ".x\n" +
+ "mul " + t + ".y, " + t + ".y, " + this._wrapDataRegister + ".y\n" +
+ "sat " + t + ".w, " + t + ".y\n" +
+ "mul " + t + ".xz, " + t + ".w, " + lightDirReg + ".wz\n";
+
+ if (this._iModulateMethod != null)
+ code += this._iModulateMethod(shaderObject, methodVO, lightDirReg, registerCache, sharedRegisters);
+
+ code += "mul " + t + ", " + t + ".x, " + lightColReg + "\n";
+
+ if (!this._pIsFirstLight) {
+ code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n";
+ registerCache.removeFragmentTempUsage(t);
+ }
+
+ this._pIsFirstLight = false;
+
+ return code;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ super.iActivate(shaderObject, methodVO, stage);
+
+ var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex;
+ var data:Array = shaderObject.fragmentConstantData;
+ data[index] = this._wrapFactor;
+ data[index + 1] = 1/(this._wrapFactor + 1);
+ }
+}
+
+export = DiffuseWrapMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/EffectAlphaMaskMethod.js b/lib/materials/methods/EffectAlphaMaskMethod.js
new file mode 100755
index 000000000..aa229bf2b
--- /dev/null
+++ b/lib/materials/methods/EffectAlphaMaskMethod.js
@@ -0,0 +1,86 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase");
+var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+/**
+ * EffectAlphaMaskMethod allows the use of an additional texture to specify the alpha value of the material. When used
+ * with the secondary uv set, it allows for a tiled main texture with independently varying alpha (useful for water
+ * etc).
+ */
+var EffectAlphaMaskMethod = (function (_super) {
+ __extends(EffectAlphaMaskMethod, _super);
+ /**
+ * Creates a new EffectAlphaMaskMethod object.
+ *
+ * @param texture The texture to use as the alpha mask.
+ * @param useSecondaryUV Indicated whether or not the secondary uv set for the mask. This allows mapping alpha independently.
+ */
+ function EffectAlphaMaskMethod(texture, useSecondaryUV) {
+ if (useSecondaryUV === void 0) { useSecondaryUV = false; }
+ _super.call(this);
+ this._texture = texture;
+ this._useSecondaryUV = useSecondaryUV;
+ }
+ /**
+ * @inheritDoc
+ */
+ EffectAlphaMaskMethod.prototype.iInitVO = function (shaderObject, methodVO) {
+ methodVO.needsSecondaryUV = this._useSecondaryUV;
+ methodVO.needsUV = !this._useSecondaryUV;
+ };
+ Object.defineProperty(EffectAlphaMaskMethod.prototype, "useSecondaryUV", {
+ /**
+ * Indicated whether or not the secondary uv set for the mask. This allows mapping alpha independently, for
+ * instance to tile the main texture and normal map while providing untiled alpha, for example to define the
+ * transparency over a tiled water surface.
+ */
+ get: function () {
+ return this._useSecondaryUV;
+ },
+ set: function (value) {
+ if (this._useSecondaryUV == value)
+ return;
+ this._useSecondaryUV = value;
+ this.iInvalidateShaderProgram();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EffectAlphaMaskMethod.prototype, "texture", {
+ /**
+ * The texture to use as the alpha mask.
+ */
+ get: function () {
+ return this._texture;
+ },
+ set: function (value) {
+ this._texture = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ EffectAlphaMaskMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ stage.context.activateTexture(methodVO.texturesIndex, this._texture);
+ };
+ /**
+ * @inheritDoc
+ */
+ EffectAlphaMaskMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ var textureReg = registerCache.getFreeTextureReg();
+ var temp = registerCache.getFreeFragmentVectorTemp();
+ var uvReg = this._useSecondaryUV ? sharedRegisters.secondaryUVVarying : sharedRegisters.uvVarying;
+ methodVO.texturesIndex = textureReg.index;
+ return ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, textureReg, this._texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, uvReg) + "mul " + targetReg + ", " + targetReg + ", " + temp + ".x\n";
+ };
+ return EffectAlphaMaskMethod;
+})(EffectMethodBase);
+module.exports = EffectAlphaMaskMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGFscGhhbWFza21ldGhvZC50cyJdLCJuYW1lcyI6WyJFZmZlY3RBbHBoYU1hc2tNZXRob2QiLCJFZmZlY3RBbHBoYU1hc2tNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RBbHBoYU1hc2tNZXRob2QuaUluaXRWTyIsIkVmZmVjdEFscGhhTWFza01ldGhvZC51c2VTZWNvbmRhcnlVViIsIkVmZmVjdEFscGhhTWFza01ldGhvZC50ZXh0dXJlIiwiRWZmZWN0QWxwaGFNYXNrTWV0aG9kLmlBY3RpdmF0ZSIsIkVmZmVjdEFscGhhTWFza01ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFVQSxJQUFPLGdCQUFnQixXQUFlLHVEQUF1RCxDQUFDLENBQUM7QUFDL0YsSUFBTyxvQkFBb0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBRXBHLEFBS0E7Ozs7R0FERztJQUNHLHFCQUFxQjtJQUFTQSxVQUE5QkEscUJBQXFCQSxVQUF5QkE7SUFLbkRBOzs7OztPQUtHQTtJQUNIQSxTQVhLQSxxQkFBcUJBLENBV2RBLE9BQXFCQSxFQUFFQSxjQUE4QkE7UUFBOUJDLDhCQUE4QkEsR0FBOUJBLHNCQUE4QkE7UUFFaEVBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxPQUFPQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsY0FBY0EsQ0FBQ0E7SUFDdkNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSx1Q0FBT0EsR0FBZEEsVUFBZUEsWUFBNkJBLEVBQUVBLFFBQWlCQTtRQUU5REUsUUFBUUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQTtRQUNqREEsUUFBUUEsQ0FBQ0EsT0FBT0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBT0RGLHNCQUFXQSxpREFBY0E7UUFMekJBOzs7O1dBSUdBO2FBQ0hBO1lBRUNHLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBO1FBQzdCQSxDQUFDQTthQUVESCxVQUEwQkEsS0FBYUE7WUFFdENHLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLElBQUlBLEtBQUtBLENBQUNBO2dCQUNqQ0EsTUFBTUEsQ0FBQ0E7WUFDUkEsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsS0FBS0EsQ0FBQ0E7WUFDN0JBLElBQUlBLENBQUNBLHdCQUF3QkEsRUFBRUEsQ0FBQ0E7UUFDakNBLENBQUNBOzs7T0FSQUg7SUFhREEsc0JBQVdBLDBDQUFPQTtRQUhsQkE7O1dBRUdBO2FBQ0hBO1lBRUNJLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBO1FBQ3RCQSxDQUFDQTthQUVESixVQUFtQkEsS0FBbUJBO1lBRXJDSSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUN2QkEsQ0FBQ0E7OztPQUxBSjtJQU9EQTs7T0FFR0E7SUFDSUEseUNBQVNBLEdBQWhCQSxVQUFpQkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxLQUFXQTtRQUU5REssS0FBS0EsQ0FBQ0EsT0FBUUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsYUFBYUEsRUFBRUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7SUFDMUZBLENBQUNBO0lBRURMOztPQUVHQTtJQUNJQSxnREFBZ0JBLEdBQXZCQSxVQUF3QkEsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxTQUErQkEsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUUvS00sSUFBSUEsVUFBVUEsR0FBeUJBLGFBQWFBLENBQUNBLGlCQUFpQkEsRUFBRUEsQ0FBQ0E7UUFDekVBLElBQUlBLElBQUlBLEdBQXlCQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1FBQzNFQSxJQUFJQSxLQUFLQSxHQUF5QkEsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBRUEsZUFBZUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxlQUFlQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN2SEEsUUFBUUEsQ0FBQ0EsYUFBYUEsR0FBR0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0E7UUFFMUNBLE1BQU1BLENBQUNBLG9CQUFvQkEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxJQUFJQSxFQUFFQSxlQUFlQSxFQUFFQSxVQUFVQSxFQUFFQSxJQUFJQSxDQUFDQSxRQUFRQSxFQUFFQSxZQUFZQSxDQUFDQSxpQkFBaUJBLEVBQUVBLFlBQVlBLENBQUNBLGNBQWNBLEVBQUVBLFlBQVlBLENBQUNBLGFBQWFBLEVBQUVBLEtBQUtBLENBQUNBLEdBQy9MQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxDQUFDQTtJQUMvREEsQ0FBQ0E7SUFDRk4sNEJBQUNBO0FBQURBLENBaEZBLEFBZ0ZDQSxFQWhGbUMsZ0JBQWdCLEVBZ0ZuRDtBQUVELEFBQStCLGlCQUF0QixxQkFBcUIsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RBbHBoYU1hc2tNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIEVmZmVjdEFscGhhTWFza01ldGhvZCBhbGxvd3MgdGhlIHVzZSBvZiBhbiBhZGRpdGlvbmFsIHRleHR1cmUgdG8gc3BlY2lmeSB0aGUgYWxwaGEgdmFsdWUgb2YgdGhlIG1hdGVyaWFsLiBXaGVuIHVzZWRcbiAqIHdpdGggdGhlIHNlY29uZGFyeSB1diBzZXQsIGl0IGFsbG93cyBmb3IgYSB0aWxlZCBtYWluIHRleHR1cmUgd2l0aCBpbmRlcGVuZGVudGx5IHZhcnlpbmcgYWxwaGEgKHVzZWZ1bCBmb3Igd2F0ZXJcbiAqIGV0YykuXG4gKi9cbmNsYXNzIEVmZmVjdEFscGhhTWFza01ldGhvZCBleHRlbmRzIEVmZmVjdE1ldGhvZEJhc2Vcbntcblx0cHJpdmF0ZSBfdGV4dHVyZTpUZXh0dXJlMkRCYXNlO1xuXHRwcml2YXRlIF91c2VTZWNvbmRhcnlVVjpib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IEVmZmVjdEFscGhhTWFza01ldGhvZCBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB0ZXh0dXJlIFRoZSB0ZXh0dXJlIHRvIHVzZSBhcyB0aGUgYWxwaGEgbWFzay5cblx0ICogQHBhcmFtIHVzZVNlY29uZGFyeVVWIEluZGljYXRlZCB3aGV0aGVyIG9yIG5vdCB0aGUgc2Vjb25kYXJ5IHV2IHNldCBmb3IgdGhlIG1hc2suIFRoaXMgYWxsb3dzIG1hcHBpbmcgYWxwaGEgaW5kZXBlbmRlbnRseS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHRleHR1cmU6VGV4dHVyZTJEQmFzZSwgdXNlU2Vjb25kYXJ5VVY6Ym9vbGVhbiA9IGZhbHNlKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX3RleHR1cmUgPSB0ZXh0dXJlO1xuXHRcdHRoaXMuX3VzZVNlY29uZGFyeVVWID0gdXNlU2Vjb25kYXJ5VVY7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdFZPKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdG1ldGhvZFZPLm5lZWRzU2Vjb25kYXJ5VVYgPSB0aGlzLl91c2VTZWNvbmRhcnlVVjtcblx0XHRtZXRob2RWTy5uZWVkc1VWID0gIXRoaXMuX3VzZVNlY29uZGFyeVVWO1xuXHR9XG5cblx0LyoqXG5cdCAqIEluZGljYXRlZCB3aGV0aGVyIG9yIG5vdCB0aGUgc2Vjb25kYXJ5IHV2IHNldCBmb3IgdGhlIG1hc2suIFRoaXMgYWxsb3dzIG1hcHBpbmcgYWxwaGEgaW5kZXBlbmRlbnRseSwgZm9yXG5cdCAqIGluc3RhbmNlIHRvIHRpbGUgdGhlIG1haW4gdGV4dHVyZSBhbmQgbm9ybWFsIG1hcCB3aGlsZSBwcm92aWRpbmcgdW50aWxlZCBhbHBoYSwgZm9yIGV4YW1wbGUgdG8gZGVmaW5lIHRoZVxuXHQgKiB0cmFuc3BhcmVuY3kgb3ZlciBhIHRpbGVkIHdhdGVyIHN1cmZhY2UuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHVzZVNlY29uZGFyeVVWKCk6Ym9vbGVhblxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3VzZVNlY29uZGFyeVVWO1xuXHR9XG5cblx0cHVibGljIHNldCB1c2VTZWNvbmRhcnlVVih2YWx1ZTpib29sZWFuKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3VzZVNlY29uZGFyeVVWID09IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXHRcdHRoaXMuX3VzZVNlY29uZGFyeVVWID0gdmFsdWU7XG5cdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgdGV4dHVyZSB0byB1c2UgYXMgdGhlIGFscGhhIG1hc2suXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHRleHR1cmUoKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdGV4dHVyZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgdGV4dHVyZSh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0dGhpcy5fdGV4dHVyZSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4LCB0aGlzLl90ZXh0dXJlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHRleHR1cmVSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHZhciB1dlJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSB0aGlzLl91c2VTZWNvbmRhcnlVVj8gc2hhcmVkUmVnaXN0ZXJzLnNlY29uZGFyeVVWVmFyeWluZyA6IHNoYXJlZFJlZ2lzdGVycy51dlZhcnlpbmc7XG5cdFx0bWV0aG9kVk8udGV4dHVyZXNJbmRleCA9IHRleHR1cmVSZWcuaW5kZXg7XG5cblx0XHRyZXR1cm4gU2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4MkRTYW1wbGVDb2RlKHRlbXAsIHNoYXJlZFJlZ2lzdGVycywgdGV4dHVyZVJlZywgdGhpcy5fdGV4dHVyZSwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QucmVwZWF0VGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCB1dlJlZykgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0ZW1wICsgXCIueFxcblwiO1xuXHR9XG59XG5cbmV4cG9ydCA9IEVmZmVjdEFscGhhTWFza01ldGhvZDsiXX0=
\ No newline at end of file
diff --git a/lib/materials/methods/EffectAlphaMaskMethod.ts b/lib/materials/methods/EffectAlphaMaskMethod.ts
new file mode 100644
index 000000000..e4cc62a76
--- /dev/null
+++ b/lib/materials/methods/EffectAlphaMaskMethod.ts
@@ -0,0 +1,101 @@
+import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase");
+
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import IContextStageGL = require("awayjs-stagegl/lib/core/stagegl/IContextStageGL");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderLightingObject = require("awayjs-stagegl/lib/materials/compilation/ShaderLightingObject");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase");
+import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper");
+
+/**
+ * EffectAlphaMaskMethod allows the use of an additional texture to specify the alpha value of the material. When used
+ * with the secondary uv set, it allows for a tiled main texture with independently varying alpha (useful for water
+ * etc).
+ */
+class EffectAlphaMaskMethod extends EffectMethodBase
+{
+ private _texture:Texture2DBase;
+ private _useSecondaryUV:boolean;
+
+ /**
+ * Creates a new EffectAlphaMaskMethod object.
+ *
+ * @param texture The texture to use as the alpha mask.
+ * @param useSecondaryUV Indicated whether or not the secondary uv set for the mask. This allows mapping alpha independently.
+ */
+ constructor(texture:Texture2DBase, useSecondaryUV:boolean = false)
+ {
+ super();
+
+ this._texture = texture;
+ this._useSecondaryUV = useSecondaryUV;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO)
+ {
+ methodVO.needsSecondaryUV = this._useSecondaryUV;
+ methodVO.needsUV = !this._useSecondaryUV;
+ }
+
+ /**
+ * Indicated whether or not the secondary uv set for the mask. This allows mapping alpha independently, for
+ * instance to tile the main texture and normal map while providing untiled alpha, for example to define the
+ * transparency over a tiled water surface.
+ */
+ public get useSecondaryUV():boolean
+ {
+ return this._useSecondaryUV;
+ }
+
+ public set useSecondaryUV(value:boolean)
+ {
+ if (this._useSecondaryUV == value)
+ return;
+ this._useSecondaryUV = value;
+ this.iInvalidateShaderProgram();
+ }
+
+ /**
+ * The texture to use as the alpha mask.
+ */
+ public get texture():Texture2DBase
+ {
+ return this._texture;
+ }
+
+ public set texture(value:Texture2DBase)
+ {
+ this._texture = value;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage)
+ {
+ ( stage.context).activateTexture(methodVO.texturesIndex, this._texture);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string
+ {
+ var textureReg:ShaderRegisterElement = registerCache.getFreeTextureReg();
+ var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp();
+ var uvReg:ShaderRegisterElement = this._useSecondaryUV? sharedRegisters.secondaryUVVarying : sharedRegisters.uvVarying;
+ methodVO.texturesIndex = textureReg.index;
+
+ return ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, textureReg, this._texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, uvReg) +
+ "mul " + targetReg + ", " + targetReg + ", " + temp + ".x\n";
+ }
+}
+
+export = EffectAlphaMaskMethod;
\ No newline at end of file
diff --git a/lib/materials/methods/EffectColorMatrixMethod.js b/lib/materials/methods/EffectColorMatrixMethod.js
new file mode 100755
index 000000000..a4d6299e6
--- /dev/null
+++ b/lib/materials/methods/EffectColorMatrixMethod.js
@@ -0,0 +1,89 @@
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+var EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase");
+/**
+ * EffectColorMatrixMethod provides a shading method that changes the colour of a material analogous to a ColorMatrixFilter.
+ */
+var EffectColorMatrixMethod = (function (_super) {
+ __extends(EffectColorMatrixMethod, _super);
+ /**
+ * Creates a new EffectColorTransformMethod.
+ *
+ * @param matrix An array of 20 items for 4 x 5 color transform.
+ */
+ function EffectColorMatrixMethod(matrix) {
+ _super.call(this);
+ if (matrix.length != 20)
+ throw new Error("Matrix length must be 20!");
+ this._matrix = matrix;
+ }
+ Object.defineProperty(EffectColorMatrixMethod.prototype, "colorMatrix", {
+ /**
+ * The 4 x 5 matrix to transform the color of the material.
+ */
+ get: function () {
+ return this._matrix;
+ },
+ set: function (value) {
+ this._matrix = value;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @inheritDoc
+ */
+ EffectColorMatrixMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) {
+ var code = "";
+ var colorMultReg = registerCache.getFreeFragmentConstant();
+ registerCache.getFreeFragmentConstant();
+ registerCache.getFreeFragmentConstant();
+ registerCache.getFreeFragmentConstant();
+ var colorOffsetReg = registerCache.getFreeFragmentConstant();
+ methodVO.fragmentConstantsIndex = colorMultReg.index * 4;
+ var temp = registerCache.getFreeFragmentVectorTemp();
+ code += "m44 " + temp + ", " + targetReg + ", " + colorMultReg + "\n" + "add " + targetReg + ", " + temp + ", " + colorOffsetReg + "\n";
+ return code;
+ };
+ /**
+ * @inheritDoc
+ */
+ EffectColorMatrixMethod.prototype.iActivate = function (shaderObject, methodVO, stage) {
+ var matrix = this._matrix;
+ var index = methodVO.fragmentConstantsIndex;
+ var data = shaderObject.fragmentConstantData;
+ // r
+ data[index] = matrix[0];
+ data[index + 1] = matrix[1];
+ data[index + 2] = matrix[2];
+ data[index + 3] = matrix[3];
+ // g
+ data[index + 4] = matrix[5];
+ data[index + 5] = matrix[6];
+ data[index + 6] = matrix[7];
+ data[index + 7] = matrix[8];
+ // b
+ data[index + 8] = matrix[10];
+ data[index + 9] = matrix[11];
+ data[index + 10] = matrix[12];
+ data[index + 11] = matrix[13];
+ // a
+ data[index + 12] = matrix[15];
+ data[index + 13] = matrix[16];
+ data[index + 14] = matrix[17];
+ data[index + 15] = matrix[18];
+ // rgba offset
+ data[index + 16] = matrix[4];
+ data[index + 17] = matrix[9];
+ data[index + 18] = matrix[14];
+ data[index + 19] = matrix[19];
+ };
+ return EffectColorMatrixMethod;
+})(EffectMethodBase);
+module.exports = EffectColorMatrixMethod;
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGNvbG9ybWF0cml4bWV0aG9kLnRzIl0sIm5hbWVzIjpbIkVmZmVjdENvbG9yTWF0cml4TWV0aG9kIiwiRWZmZWN0Q29sb3JNYXRyaXhNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RDb2xvck1hdHJpeE1ldGhvZC5jb2xvck1hdHJpeCIsIkVmZmVjdENvbG9yTWF0cml4TWV0aG9kLmlHZXRGcmFnbWVudENvZGUiLCJFZmZlY3RDb2xvck1hdHJpeE1ldGhvZC5pQWN0aXZhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQU1BLElBQU8sZ0JBQWdCLFdBQWUsdURBQXVELENBQUMsQ0FBQztBQUUvRixBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQXlCQTtJQUlyREE7Ozs7T0FJR0E7SUFDSEEsU0FUS0EsdUJBQXVCQSxDQVNoQkEsTUFBb0JBO1FBRS9CQyxpQkFBT0EsQ0FBQ0E7UUFFUkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsTUFBTUEsSUFBSUEsRUFBRUEsQ0FBQ0E7WUFDdkJBLE1BQU1BLElBQUlBLEtBQUtBLENBQUNBLDJCQUEyQkEsQ0FBQ0EsQ0FBQ0E7UUFFOUNBLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLE1BQU1BLENBQUNBO0lBQ3ZCQSxDQUFDQTtJQUtERCxzQkFBV0EsZ0RBQVdBO1FBSHRCQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDckJBLENBQUNBO2FBRURGLFVBQXVCQSxLQUFtQkE7WUFFekNFLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLEtBQUtBLENBQUNBO1FBQ3RCQSxDQUFDQTs7O09BTEFGO0lBT0RBOztPQUVHQTtJQUNJQSxrREFBZ0JBLEdBQXZCQSxVQUF3QkEsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxTQUErQkEsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUUvS0csSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLFlBQVlBLEdBQXlCQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ2pGQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3hDQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBQ3hDQSxhQUFhQSxDQUFDQSx1QkFBdUJBLEVBQUVBLENBQUNBO1FBRXhDQSxJQUFJQSxjQUFjQSxHQUF5QkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUVuRkEsUUFBUUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxZQUFZQSxDQUFDQSxLQUFLQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUV2REEsSUFBSUEsSUFBSUEsR0FBeUJBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7UUFFM0VBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLFlBQVlBLEdBQUdBLElBQUlBLEdBQ25FQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUVsRUEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFREg7O09BRUdBO0lBQ0lBLDJDQUFTQSxHQUFoQkEsVUFBaUJBLFlBQTZCQSxFQUFFQSxRQUFpQkEsRUFBRUEsS0FBV0E7UUFFN0VJLElBQUlBLE1BQU1BLEdBQWlCQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQTtRQUN4Q0EsSUFBSUEsS0FBS0EsR0FBa0JBLFFBQVFBLENBQUNBLHNCQUFzQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLElBQUlBLEdBQWlCQSxZQUFZQSxDQUFDQSxvQkFBb0JBLENBQUNBO1FBRTNEQSxBQUNBQSxJQURJQTtRQUNKQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU1QkEsQUFDQUEsSUFESUE7UUFDSkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM1QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFNUJBLEFBQ0FBLElBRElBO1FBQ0pBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUM3QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDOUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBRTlCQSxBQUNBQSxJQURJQTtRQUNKQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUM5QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDOUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBQzlCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUU5QkEsQUFDQUEsY0FEY0E7UUFDZEEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLEVBQUVBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUM5QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7SUFDL0JBLENBQUNBO0lBQ0ZKLDhCQUFDQTtBQUFEQSxDQTlGQSxBQThGQ0EsRUE5RnFDLGdCQUFnQixFQThGckQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0Q29sb3JNYXRyaXhNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgRWZmZWN0TWV0aG9kQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0TWV0aG9kQmFzZVwiKTtcblxuLyoqXG4gKiBFZmZlY3RDb2xvck1hdHJpeE1ldGhvZCBwcm92aWRlcyBhIHNoYWRpbmcgbWV0aG9kIHRoYXQgY2hhbmdlcyB0aGUgY29sb3VyIG9mIGEgbWF0ZXJpYWwgYW5hbG9nb3VzIHRvIGEgQ29sb3JNYXRyaXhGaWx0ZXIuXG4gKi9cbmNsYXNzIEVmZmVjdENvbG9yTWF0cml4TWV0aG9kIGV4dGVuZHMgRWZmZWN0TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9tYXRyaXg6QXJyYXk8bnVtYmVyPjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBFZmZlY3RDb2xvclRyYW5zZm9ybU1ldGhvZC5cblx0ICpcblx0ICogQHBhcmFtIG1hdHJpeCBBbiBhcnJheSBvZiAyMCBpdGVtcyBmb3IgNCB4IDUgY29sb3IgdHJhbnNmb3JtLlxuXHQgKi9cblx0Y29uc3RydWN0b3IobWF0cml4OkFycmF5PG51bWJlcj4pXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0aWYgKG1hdHJpeC5sZW5ndGggIT0gMjApXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJNYXRyaXggbGVuZ3RoIG11c3QgYmUgMjAhXCIpO1xuXG5cdFx0dGhpcy5fbWF0cml4ID0gbWF0cml4O1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSA0IHggNSBtYXRyaXggdG8gdHJhbnNmb3JtIHRoZSBjb2xvciBvZiB0aGUgbWF0ZXJpYWwuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGNvbG9yTWF0cml4KCk6QXJyYXk8bnVtYmVyPlxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX21hdHJpeDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgY29sb3JNYXRyaXgodmFsdWU6QXJyYXk8bnVtYmVyPilcblx0e1xuXHRcdHRoaXMuX21hdHJpeCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBjb2xvck11bHRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRyZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXG5cdFx0dmFyIGNvbG9yT2Zmc2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblxuXHRcdG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSBjb2xvck11bHRSZWcuaW5kZXgqNDtcblxuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXG5cdFx0Y29kZSArPSBcIm00NCBcIiArIHRlbXAgKyBcIiwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyBjb2xvck11bHRSZWcgKyBcIlxcblwiICtcblx0XHRcdFx0XCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgY29sb3JPZmZzZXRSZWcgKyBcIlxcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHZhciBtYXRyaXg6QXJyYXk8bnVtYmVyPiA9IHRoaXMuX21hdHJpeDtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cblx0XHQvLyByXG5cdFx0ZGF0YVtpbmRleF0gPSBtYXRyaXhbMF07XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gbWF0cml4WzFdO1xuXHRcdGRhdGFbaW5kZXggKyAyXSA9IG1hdHJpeFsyXTtcblx0XHRkYXRhW2luZGV4ICsgM10gPSBtYXRyaXhbM107XG5cblx0XHQvLyBnXG5cdFx0ZGF0YVtpbmRleCArIDRdID0gbWF0cml4WzVdO1xuXHRcdGRhdGFbaW5kZXggKyA1XSA9IG1hdHJpeFs2XTtcblx0XHRkYXRhW2luZGV4ICsgNl0gPSBtYXRyaXhbN107XG5cdFx0ZGF0YVtpbmRleCArIDddID0gbWF0cml4WzhdO1xuXG5cdFx0Ly8gYlxuXHRcdGRhdGFbaW5kZXggKyA4XSA9IG1hdHJpeFsxMF07XG5cdFx0ZGF0YVtpbmRleCArIDldID0gbWF0cml4WzExXTtcblx0XHRkYXRhW2luZGV4ICsgMTBdID0gbWF0cml4WzEyXTtcblx0XHRkYXRhW2luZGV4ICsgMTFdID0gbWF0cml4WzEzXTtcblxuXHRcdC8vIGFcblx0XHRkYXRhW2luZGV4ICsgMTJdID0gbWF0cml4WzE1XTtcblx0XHRkYXRhW2luZGV4ICsgMTNdID0gbWF0cml4WzE2XTtcblx0XHRkYXRhW2luZGV4ICsgMTRdID0gbWF0cml4WzE3XTtcblx0XHRkYXRhW2luZGV4ICsgMTVdID0gbWF0cml4WzE4XTtcblxuXHRcdC8vIHJnYmEgb2Zmc2V0XG5cdFx0ZGF0YVtpbmRleCArIDE2XSA9IG1hdHJpeFs0XTtcblx0XHRkYXRhW2luZGV4ICsgMTddID0gbWF0cml4WzldO1xuXHRcdGRhdGFbaW5kZXggKyAxOF0gPSBtYXRyaXhbMTRdO1xuXHRcdGRhdGFbaW5kZXggKyAxOV0gPSBtYXRyaXhbMTldO1xuXHR9XG59XG5cbmV4cG9ydCA9IEVmZmVjdENvbG9yTWF0cml4TWV0aG9kOyJdfQ==
\ No newline at end of file
diff --git a/lib/materials/methods/EffectColorMatrixMethod.ts b/lib/materials/methods/EffectColorMatrixMethod.ts
new file mode 100644
index 000000000..d4fa01402
--- /dev/null
+++ b/lib/materials/methods/EffectColorMatrixMethod.ts
@@ -0,0 +1,108 @@
+import Stage = require("awayjs-stagegl/lib/core/base/Stage");
+import MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO");
+import ShaderObjectBase = require("awayjs-stagegl/lib/materials/compilation/ShaderObjectBase");
+import ShaderRegisterCache = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterCache");
+import ShaderRegisterData = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterData");
+import ShaderRegisterElement = require("awayjs-stagegl/lib/materials/compilation/ShaderRegisterElement");
+import EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase");
+
+/**
+ * EffectColorMatrixMethod provides a shading method that changes the colour of a material analogous to a ColorMatrixFilter.
+ */
+class EffectColorMatrixMethod extends EffectMethodBase
+{
+ private _matrix:Array;
+
+ /**
+ * Creates a new EffectColorTransformMethod.
+ *
+ * @param matrix An array of 20 items for 4 x 5 color transform.
+ */
+ constructor(matrix:Array