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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9za2VsZXRvbmFuaW1hdGlvbnNldC50cyJdLCJuYW1lcyI6WyJTa2VsZXRvbkFuaW1hdGlvblNldCIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmNvbnN0cnVjdG9yIiwiU2tlbGV0b25BbmltYXRpb25TZXQuam9pbnRzUGVyVmVydGV4IiwiU2tlbGV0b25BbmltYXRpb25TZXQuZ2V0QUdBTFZlcnRleENvZGUiLCJTa2VsZXRvbkFuaW1hdGlvblNldC5hY3RpdmF0ZSIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmRlYWN0aXZhdGUiLCJTa2VsZXRvbkFuaW1hdGlvblNldC5nZXRBR0FMRnJhZ21lbnRDb2RlIiwiU2tlbGV0b25BbmltYXRpb25TZXQuZ2V0QUdBTFVWQ29kZSIsIlNrZWxldG9uQW5pbWF0aW9uU2V0LmRvbmVBR0FMQ29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUEsSUFBTyxnQkFBZ0IsV0FBZSwrQ0FBK0MsQ0FBQyxDQUFDO0FBSXZGLEFBS0E7Ozs7R0FERztJQUNHLG9CQUFvQjtJQUFTQSxVQUE3QkEsb0JBQW9CQSxVQUF5QkE7SUFhbERBOzs7O09BSUdBO0lBQ0hBLFNBbEJLQSxvQkFBb0JBLENBa0JiQSxlQUFtQ0E7UUFBbkNDLCtCQUFtQ0EsR0FBbkNBLG1CQUFtQ0E7UUFFOUNBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLGVBQWVBLENBQUNBO0lBQ3pDQSxDQUFDQTtJQWZERCxzQkFBV0EsaURBQWVBO1FBSjFCQTs7O1dBR0dBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7UUFDOUJBLENBQUNBOzs7T0FBQUY7SUFjREE7O09BRUdBO0lBQ0lBLGdEQUFpQkEsR0FBeEJBLFVBQXlCQSxZQUE2QkE7UUFFckRHLElBQUlBLEdBQUdBLEdBQW1CQSxZQUFZQSxDQUFDQSxvQkFBb0JBLENBQUNBLE1BQU1BLENBQUNBO1FBRW5FQSxJQUFJQSxZQUFZQSxHQUFtQkEsWUFBWUEsQ0FBQ0Esc0JBQXNCQSxDQUFDQTtRQUN2RUEsSUFBSUEsWUFBWUEsR0FBbUJBLFlBQVlBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3BEQSxJQUFJQSxZQUFZQSxHQUFtQkEsWUFBWUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDcERBLElBQUlBLFdBQVdBLEdBQVVBLElBQUlBLEdBQUdBLFlBQVlBLENBQUNBLGNBQWNBLENBQUNBO1FBQzVEQSxJQUFJQSxZQUFZQSxHQUFVQSxJQUFJQSxHQUFHQSxDQUFDQSxZQUFZQSxDQUFDQSxjQUFjQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNuRUEsSUFBSUEsT0FBT0EsR0FBaUJBLENBQUVBLFdBQVdBLEdBQUdBLElBQUlBLEVBQUVBLFdBQVdBLEdBQUdBLElBQUlBLEVBQUVBLFdBQVdBLEdBQUdBLElBQUlBLEVBQUVBLFdBQVdBLEdBQUdBLElBQUlBLENBQUVBLENBQUNBO1FBQy9HQSxJQUFJQSxPQUFPQSxHQUFpQkEsQ0FBRUEsWUFBWUEsR0FBR0EsSUFBSUEsRUFBRUEsWUFBWUEsR0FBR0EsSUFBSUEsRUFBRUEsWUFBWUEsR0FBR0EsSUFBSUEsRUFBRUEsWUFBWUEsR0FBR0EsSUFBSUEsQ0FBRUEsQ0FBQ0E7UUFDbkhBLElBQUlBLEtBQUtBLEdBQVVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFlBQVlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsQ0FBQ0E7UUFDN0VBLElBQUlBLEtBQUtBLEdBQVVBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFlBQVlBLENBQUNBLHdCQUF3QkEsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDcEZBLElBQUlBLEdBQUdBLEdBQVVBLEtBQUtBLENBQUNBO1FBQ3ZCQSxJQUFJQSxJQUFJQSxHQUFVQSxFQUFFQSxDQUFDQTtRQUVyQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBbUJBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBO1lBRTlDQSxJQUFJQSxHQUFHQSxHQUFVQSxZQUFZQSxDQUFDQSxvQkFBb0JBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBRXREQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFtQkEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtnQkFDaEVBLElBQUlBLElBQUlBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLE9BQU9BLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLFlBQVlBLEdBQUdBLEtBQUtBLEdBQzNGQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUNwRkEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsWUFBWUEsR0FBR0EsS0FBS0EsR0FDcEZBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQ3RDQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxFQUFFQSxlQUFlQTtnQkFFMUVBLEFBQ0FBLDZGQUQ2RkE7Z0JBQzdGQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDVkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7Z0JBQUNBLElBQUlBO29CQUNsREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDOURBLENBQUNBO1lBQ0RBLEFBQ0FBLCtHQUQrR0E7WUFDL0dBLEdBQUdBLEdBQUdBLEtBQUtBLENBQUNBO1lBQ1pBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDakZBLENBQUNBO1FBRURBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSx1Q0FBUUEsR0FBZkEsVUFBZ0JBLFlBQTZCQSxFQUFFQSxLQUFXQTtJQUUxREksQ0FBQ0E7SUFFREo7O09BRUdBO0lBQ0lBLHlDQUFVQSxHQUFqQkEsVUFBa0JBLFlBQTZCQSxFQUFFQSxLQUFXQTtRQUU3REssNERBQTREQTtRQUM1REEsbUVBQW1FQTtRQUNuRUEsbURBQW1EQTtRQUNuREEsdURBQXVEQTtJQUN0REEsQ0FBQ0E7SUFFREw7O09BRUdBO0lBQ0lBLGtEQUFtQkEsR0FBMUJBLFVBQTJCQSxZQUE2QkEsRUFBRUEsWUFBbUJBO1FBRTVFTSxNQUFNQSxDQUFDQSxFQUFFQSxDQUFDQTtJQUNYQSxDQUFDQTtJQUVETjs7T0FFR0E7SUFDSUEsNENBQWFBLEdBQXBCQSxVQUFxQkEsWUFBNkJBO1FBRWpETyxNQUFNQSxDQUFDQSxNQUFNQSxHQUFHQSxZQUFZQSxDQUFDQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFHQSxZQUFZQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUM1RUEsQ0FBQ0E7SUFFRFA7O09BRUdBO0lBQ0lBLDJDQUFZQSxHQUFuQkEsVUFBb0JBLFlBQTZCQTtJQUdqRFEsQ0FBQ0E7SUFDRlIsMkJBQUNBO0FBQURBLENBN0dBLEFBNkdDQSxFQTdHa0MsZ0JBQWdCLEVBNkdsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJhbmltYXRvcnMvU2tlbGV0b25BbmltYXRpb25TZXQuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSUFuaW1hdGlvblNldFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvYW5pbWF0b3JzL0lBbmltYXRpb25TZXRcIik7XG5cbmltcG9ydCBBbmltYXRpb25TZXRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0aW9uU2V0QmFzZVwiKTtcbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcblxuLyoqXG4gKiBUaGUgYW5pbWF0aW9uIGRhdGEgc2V0IHVzZWQgYnkgc2tlbGV0b24tYmFzZWQgYW5pbWF0b3JzLCBjb250YWluaW5nIHNrZWxldG9uIGFuaW1hdGlvbiBkYXRhLlxuICpcbiAqIEBzZWUgYXdheS5hbmltYXRvcnMuU2tlbGV0b25BbmltYXRvclxuICovXG5jbGFzcyBTa2VsZXRvbkFuaW1hdGlvblNldCBleHRlbmRzIEFuaW1hdGlvblNldEJhc2UgaW1wbGVtZW50cyBJQW5pbWF0aW9uU2V0XG57XG5cdHByaXZhdGUgX2pvaW50c1BlclZlcnRleDpudW1iZXIgLyp1aW50Ki87XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGFtb3VudCBvZiBza2VsZXRvbiBqb2ludHMgdGhhdCBjYW4gYmUgbGlua2VkIHRvIGEgc2luZ2xlIHZlcnRleCB2aWEgc2tpbm5lZCB3ZWlnaHQgdmFsdWVzLiBGb3IgR1BVLWJhc2UgYW5pbWF0aW9uLCB0aGVcblx0ICogbWF4aW11bSBhbGxvd2VkIHZhbHVlIGlzIDQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGpvaW50c1BlclZlcnRleCgpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2pvaW50c1BlclZlcnRleDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlNrZWxldG9uQW5pbWF0aW9uU2V0PC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBqb2ludHNQZXJWZXJ0ZXggU2V0cyB0aGUgYW1vdW50IG9mIHNrZWxldG9uIGpvaW50cyB0aGF0IGNhbiBiZSBsaW5rZWQgdG8gYSBzaW5nbGUgdmVydGV4IHZpYSBza2lubmVkIHdlaWdodCB2YWx1ZXMuIEZvciBHUFUtYmFzZSBhbmltYXRpb24sIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUgaXMgNC4gRGVmYXVsdHMgdG8gNC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGpvaW50c1BlclZlcnRleDpudW1iZXIgLyp1aW50Ki8gPSA0KVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMuX2pvaW50c1BlclZlcnRleCA9IGpvaW50c1BlclZlcnRleDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxWZXJ0ZXhDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKTpzdHJpbmdcblx0e1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzLmxlbmd0aDtcblxuXHRcdHZhciBpbmRleE9mZnNldDA6bnVtYmVyIC8qdWludCovID0gc2hhZGVyT2JqZWN0Lm51bVVzZWRWZXJ0ZXhDb25zdGFudHM7XG5cdFx0dmFyIGluZGV4T2Zmc2V0MTpudW1iZXIgLyp1aW50Ki8gPSBpbmRleE9mZnNldDAgKyAxO1xuXHRcdHZhciBpbmRleE9mZnNldDI6bnVtYmVyIC8qdWludCovID0gaW5kZXhPZmZzZXQwICsgMjtcblx0XHR2YXIgaW5kZXhTdHJlYW06c3RyaW5nID0gXCJ2YVwiICsgc2hhZGVyT2JqZWN0Lm51bVVzZWRTdHJlYW1zO1xuXHRcdHZhciB3ZWlnaHRTdHJlYW06c3RyaW5nID0gXCJ2YVwiICsgKHNoYWRlck9iamVjdC5udW1Vc2VkU3RyZWFtcyArIDEpO1xuXHRcdHZhciBpbmRpY2VzOkFycmF5PHN0cmluZz4gPSBbIGluZGV4U3RyZWFtICsgXCIueFwiLCBpbmRleFN0cmVhbSArIFwiLnlcIiwgaW5kZXhTdHJlYW0gKyBcIi56XCIsIGluZGV4U3RyZWFtICsgXCIud1wiIF07XG5cdFx0dmFyIHdlaWdodHM6QXJyYXk8c3RyaW5nPiA9IFsgd2VpZ2h0U3RyZWFtICsgXCIueFwiLCB3ZWlnaHRTdHJlYW0gKyBcIi55XCIsIHdlaWdodFN0cmVhbSArIFwiLnpcIiwgd2VpZ2h0U3RyZWFtICsgXCIud1wiIF07XG5cdFx0dmFyIHRlbXAxOnN0cmluZyA9IHRoaXMuX3BGaW5kVGVtcFJlZyhzaGFkZXJPYmplY3QuYW5pbWF0aW9uVGFyZ2V0UmVnaXN0ZXJzKTtcblx0XHR2YXIgdGVtcDI6c3RyaW5nID0gdGhpcy5fcEZpbmRUZW1wUmVnKHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnMsIHRlbXAxKTtcblx0XHR2YXIgZG90OnN0cmluZyA9IFwiZHA0XCI7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cblx0XHRcdHZhciBzcmM6c3RyaW5nID0gc2hhZGVyT2JqZWN0LmFuaW1hdGFibGVBdHRyaWJ1dGVzW2ldO1xuXG5cdFx0XHRmb3IgKHZhciBqOm51bWJlciAvKnVpbnQqLyA9IDA7IGogPCB0aGlzLl9qb2ludHNQZXJWZXJ0ZXg7ICsraikge1xuXHRcdFx0XHRjb2RlICs9IGRvdCArIFwiIFwiICsgdGVtcDEgKyBcIi54LCBcIiArIHNyYyArIFwiLCB2Y1tcIiArIGluZGljZXNbal0gKyBcIitcIiArIGluZGV4T2Zmc2V0MCArIFwiXVxcblwiICtcblx0XHRcdFx0XHRkb3QgKyBcIiBcIiArIHRlbXAxICsgXCIueSwgXCIgKyBzcmMgKyBcIiwgdmNbXCIgKyBpbmRpY2VzW2pdICsgXCIrXCIgKyBpbmRleE9mZnNldDEgKyBcIl1cXG5cIiArXG5cdFx0XHRcdFx0ZG90ICsgXCIgXCIgKyB0ZW1wMSArIFwiLnosIFwiICsgc3JjICsgXCIsIHZjW1wiICsgaW5kaWNlc1tqXSArIFwiK1wiICsgaW5kZXhPZmZzZXQyICsgXCJdXFxuXCIgK1xuXHRcdFx0XHRcdFwibW92IFwiICsgdGVtcDEgKyBcIi53LCBcIiArIHNyYyArIFwiLndcXG5cIiArXG5cdFx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wMSArIFwiLCBcIiArIHRlbXAxICsgXCIsIFwiICsgd2VpZ2h0c1tqXSArIFwiXFxuXCI7IC8vIGFwcGx5IHdlaWdodFxuXG5cdFx0XHRcdC8vIGFkZCBvciBtb3YgdG8gdGFyZ2V0LiBOZWVkIHRvIHdyaXRlIHRvIGEgdGVtcCByZWcgZmlyc3QsIGJlY2F1c2UgYW4gb3V0cHV0IGNhbiBiZSBhIHRhcmdldFxuXHRcdFx0XHRpZiAoaiA9PSAwKVxuXHRcdFx0XHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB0ZW1wMiArIFwiLCBcIiArIHRlbXAxICsgXCJcXG5cIjsgZWxzZVxuXHRcdFx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0ZW1wMiArIFwiLCBcIiArIHRlbXAyICsgXCIsIFwiICsgdGVtcDEgKyBcIlxcblwiO1xuXHRcdFx0fVxuXHRcdFx0Ly8gc3dpdGNoIHRvIGRwMyBvbmNlIHBvc2l0aW9ucyBoYXZlIGJlZW4gdHJhbnNmb3JtZWQsIGZyb20gbm93IG9uLCBpdCBzaG91bGQgb25seSBiZSB2ZWN0b3JzIGluc3RlYWQgb2YgcG9pbnRzXG5cdFx0XHRkb3QgPSBcImRwM1wiO1xuXHRcdFx0Y29kZSArPSBcIm1vdiBcIiArIHNoYWRlck9iamVjdC5hbmltYXRpb25UYXJnZXRSZWdpc3RlcnNbaV0gKyBcIiwgXCIgKyB0ZW1wMiArIFwiXFxuXCI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBhY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRlYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIHN0YWdlOlN0YWdlKVxuXHR7XG4vL1x0XHRcdHZhciBzdHJlYW1PZmZzZXQ6bnVtYmVyIC8qdWludCovID0gcGFzcy5udW1Vc2VkU3RyZWFtcztcbi8vXHRcdFx0dmFyIGNvbnRleHQ6SUNvbnRleHRTdGFnZUdMID0gPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dDtcbi8vXHRcdFx0Y29udGV4dC5zZXRWZXJ0ZXhCdWZmZXJBdChzdHJlYW1PZmZzZXQsIG51bGwpO1xuLy9cdFx0XHRjb250ZXh0LnNldFZlcnRleEJ1ZmZlckF0KHN0cmVhbU9mZnNldCArIDEsIG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0QUdBTEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgc2hhZGVkVGFyZ2V0OnN0cmluZyk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGdldEFHQUxVVkNvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIFwibW92IFwiICsgc2hhZGVyT2JqZWN0LnV2VGFyZ2V0ICsgXCIsXCIgKyBzaGFkZXJPYmplY3QudXZTb3VyY2UgKyBcIlxcblwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZG9uZUFHQUxDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlKVxuXHR7XG5cblx0fVxufVxuXG5leHBvcnQgPSBTa2VsZXRvbkFuaW1hdGlvblNldDsiXX0= \ 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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QUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMUNBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUMxQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzFDQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDMUNBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFNBQVNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUMxQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsU0FBU0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7b0JBQzNDQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQTtvQkFDM0NBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBO29CQUN2REEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDdkRBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLENBQUNBLENBQUNBO29CQUNqREEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtvQkFDakRBLEVBQUVBLElBQUlBLE1BQU1BLEdBQUNBLENBQUNBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUNBLEtBQUtBLENBQUNBLENBQUNBO29CQUNqREEsRUFBRUEsSUFBSUEsTUFBTUEsR0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pEQSxFQUFFQSxJQUFJQSxNQUFNQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtvQkFDakRBLEVBQUVBLENBQUNBLENBQUNBO2dCQUNMQSxDQUFDQTtnQkFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7b0JBQ1BBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBO2dCQUMzQkEsQ0FBQ0E7WUFDRkEsQ0FBQ0E7WUFFREEsZUFBZUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7WUFDNUJBLGVBQWVBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBO1lBQ2hDQSxlQUFlQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtZQUNoQ0EsYUFBYUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7WUFDMUJBLGFBQWFBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBO1lBQzlCQSxhQUFhQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtZQUM5QkEsY0FBY0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7WUFDM0JBLGNBQWNBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBO1lBQy9CQSxjQUFjQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtZQUUvQkEsS0FBS0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDWkEsQ0FBQ0E7UUFFREEsaUJBQWlCQSxDQUFDQSxlQUFlQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUNuREEsaUJBQWlCQSxDQUFDQSxtQkFBbUJBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBO1FBQ3JEQSxpQkFBaUJBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7SUFDeERBLENBQUNBO0lBRURmOzs7O09BSUdBO0lBQ0tBLDRDQUFpQkEsR0FBekJBLFVBQTBCQSxVQUF1QkEsRUFBRUEsVUFBdUJBLEVBQUVBLFFBQWlCQTtRQUU1RmdCLElBQUlBLFdBQVdBLEdBQW9CQSxVQUFVQSxDQUFDQSxVQUFVQSxDQUFDQTtRQUN6REEsSUFBSUEsZUFBeUJBLENBQUNBO1FBQzlCQSxJQUFJQSxNQUFNQSxHQUF3QkEsUUFBUUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDbERBLElBQUlBLEdBQUdBLEdBQW1CQSxVQUFVQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUNuREEsSUFBSUEsVUFBVUEsR0FBb0JBLFVBQVVBLENBQUNBLFVBQVVBLENBQUNBO1FBQ3hEQSxJQUFJQSxXQUFXQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUMvQkEsSUFBSUEsS0FBbUJBLENBQUNBO1FBQ3hCQSxJQUFJQSxVQUFvQkEsQ0FBQ0E7UUFDekJBLElBQUlBLElBQWNBLENBQUNBO1FBQ25CQSxJQUFJQSxFQUFhQSxDQUFDQTtRQUNsQkEsSUFBSUEsRUFBV0EsQ0FBQ0E7UUFDaEJBLElBQUlBLENBQVVBLENBQUNBO1FBQ2ZBLElBQUlBLENBQVlBLENBQUNBO1FBRWpCQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxDQUFDQTtRQUMvQ0EsSUFBSUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsQ0FBQ0E7UUFDL0NBLElBQUlBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLENBQUNBO1FBRXBDQSxBQUNBQSxLQURLQTtRQUNMQSxFQUFFQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQSxNQUFNQSxJQUFJQSxHQUFHQSxDQUFDQTtZQUM3QkEsV0FBV0EsQ0FBQ0EsTUFBTUEsR0FBR0EsR0FBR0EsQ0FBQ0E7UUFFMUJBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUM5Q0EsZUFBZUEsR0FBR0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFakNBLEVBQUVBLENBQUNBLENBQUNBLGVBQWVBLElBQUlBLElBQUlBLENBQUNBO2dCQUMzQkEsZUFBZUEsR0FBR0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFFcERBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xCQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUNoQ0EsSUFBSUEsR0FBR0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFckJBLENBQUNBLEdBQUdBLGVBQWVBLENBQUNBLFdBQVdBLENBQUNBO1lBQ2hDQSxDQUFDQSxHQUFHQSxlQUFlQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUVoQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsV0FBV0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JCQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDdEJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO2dCQUN0QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1hBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNYQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDWEEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1hBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNYQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDWEEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDWkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ1BBLEFBQ0FBLHFCQURxQkE7Z0JBQ3JCQSxVQUFVQSxHQUFHQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtnQkFFdENBLEFBQ0FBLGVBRGVBO2dCQUNmQSxFQUFFQSxHQUFHQSxVQUFVQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDNUJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO2dCQUN0QkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRVZBLEVBQUVBLEdBQUdBLENBQUNBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLENBQUNBO2dCQUM1QkEsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsQ0FBQ0E7Z0JBQzNCQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxDQUFDQTtnQkFDM0JBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLENBQUNBO2dCQUUzQkEsQUFDQUEsNEJBRDRCQTtnQkFDNUJBLEVBQUVBLEdBQUdBLFVBQVVBLENBQUNBLFdBQVdBLENBQUNBO2dCQUM1QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzVDQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDNUNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUNBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUU1Q0EsQUFDQUEsNEJBRDRCQTtnQkFDNUJBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDdEJBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNWQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDVkEsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1ZBLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUVWQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFH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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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZW9yYml0bm9kZS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZU9yYml0Tm9kZSIsIlBhcnRpY2xlT3JiaXROb2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVPcmJpdE5vZGUuZ2V0QUdBTFZlcnRleENvZGUiLCJQYXJ0aWNsZU9yYml0Tm9kZS5nZXRBbmltYXRpb25TdGF0ZSIsIlBhcnRpY2xlT3JiaXROb2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csaUJBQWlCO0lBQVNBLFVBQTFCQSxpQkFBaUJBLFVBQXlCQTtJQTBCL0NBOzs7Ozs7Ozs7OztPQVdHQTtJQUNIQSxTQXRDS0EsaUJBQWlCQSxDQXNDVkEsSUFBSUEsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsVUFBeUJBLEVBQUVBLFNBQXlCQSxFQUFFQSxTQUF5QkEsRUFBRUEsTUFBbUJBLEVBQUVBLGFBQXdCQSxFQUFFQSxVQUFxQkEsRUFBRUEsTUFBc0JBO1FBQTdLQywwQkFBeUJBLEdBQXpCQSxpQkFBeUJBO1FBQUVBLHlCQUF5QkEsR0FBekJBLGlCQUF5QkE7UUFBRUEseUJBQXlCQSxHQUF6QkEsaUJBQXlCQTtRQUFFQSxzQkFBbUJBLEdBQW5CQSxZQUFtQkE7UUFBRUEsNkJBQXdCQSxHQUF4QkEsaUJBQXdCQTtRQUFFQSwwQkFBcUJBLEdBQXJCQSxjQUFxQkE7UUFBRUEsc0JBQXNCQSxHQUF0QkEsYUFBc0JBO1FBRTlNQSxJQUFJQSxHQUFHQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7UUFDM0JBLEVBQUVBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBO1lBQ2JBLEdBQUdBLEVBQUVBLENBQUNBO1FBQ1BBLGtCQUFNQSxlQUFlQSxFQUFFQSxJQUFJQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVsQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0Esa0JBQWtCQSxDQUFDQTtRQUV2Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsVUFBVUEsQ0FBQ0E7UUFDL0JBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLFNBQVNBLENBQUNBO1FBQzdCQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxTQUFTQSxDQUFDQTtRQUU3QkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFDdkJBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLGFBQWFBLENBQUNBO1FBQ3JDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxVQUFVQSxDQUFDQTtRQUMvQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSw2Q0FBaUJBLEdBQXhCQSxVQUF5QkEsWUFBNkJBLEVBQUVBLHNCQUE2Q0E7UUFFcEdFLElBQUlBLGFBQWFBLEdBQXlCQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxJQUFJQSxzQkFBc0JBLENBQUNBLE1BQU1BLENBQUNBLEdBQUVBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxHQUFHQSxzQkFBc0JBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7UUFDM0xBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxrQkFBa0JBLENBQUNBLFdBQVdBLEVBQUVBLGFBQWFBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBRW5HQSxJQUFJQSxvQkFBb0JBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFDaEdBLHNCQUFzQkEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxJQUFJQSxFQUFFQSxrQkFBa0JBLENBQUNBLFlBQVlBLEVBQUVBLG9CQUFvQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDM0dBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxDQUFDQTtRQUMvQ0Esc0JBQXNCQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO1FBQy9DQSxzQkFBc0JBLENBQUNBLHFCQUFxQkEsRUFBRUEsQ0FBQ0E7UUFFL0NBLElBQUlBLEtBQUtBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDbkZBLHNCQUFzQkEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNyREEsSUFBSUEsUUFBUUEsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsRUFBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFFM0ZBLElBQUlBLEtBQUtBLEdBQXlCQSxzQkFBc0JBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDbkZBLElBQUlBLEdBQUdBLEdBQXlCQSxJQUFJQSxxQkFBcUJBLENBQUNBLEtBQUtBLENBQUNBLE9BQU9BLEVBQUVBLEtBQUtBLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQ3pGQSxJQUFJQSxHQUFHQSxHQUF5QkEsSUFBSUEscUJBQXFCQSxDQUFDQSxLQUFLQSxDQUFDQSxPQUFPQSxFQUFFQSxLQUFLQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN6RkEsSUFBSUEsTUFBTUEsR0FBeUJBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsRUFBRUEsS0FBS0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUZBLHNCQUFzQkEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUVwREEsSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFFckJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1lBRWpHQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDcEJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBQ3hFQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUNMQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLFVBQVVBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBRWxHQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzQ0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0NBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLENBQUNBO1FBQ3ZFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxhQUFhQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUN2RUEsSUFB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LENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQzVCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxJQUFJQSxLQUFLQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNwQ0EsTUFBS0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsOENBQThDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNsRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBRUEsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDL0RBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLEVBQUVBLEdBQUNBLENBQUNBLENBQUNBO1FBQ3RDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUNwQkEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBQ0EsR0FBR0EsQ0FBQ0E7SUFDMUNBLENBQUNBO0lBeEhESjs7O09BR0dBO0lBQ1dBLGdDQUFjQSxHQUFVQSxlQUFlQSxDQUFDQTtJQXFIdkRBLHdCQUFDQTtBQUFEQSxDQTdJQSxBQTZJQ0EsRUE3SStCLGdCQUFnQixFQTZJL0M7QUFFRCxBQUEyQixpQkFBbEIsaUJBQWlCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL25vZGVzL1BhcnRpY2xlT3JiaXROb2RlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5pbXBvcnQgQW5pbWF0aW9uUmVnaXN0ZXJDYWNoZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvZGF0YS9BbmltYXRpb25SZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuXG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzXCIpO1xuaW1wb3J0IFBhcnRpY2xlUHJvcGVydGllc01vZGVcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVQcm9wZXJ0aWVzTW9kZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU5vZGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVOb2RlQmFzZVwiKTtcbmltcG9ydCBQYXJ0aWNsZU9yYml0U3RhdGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlT3JiaXRTdGF0ZVwiKTtcblxuLyoqXG4gKiBBIHBhcnRpY2xlIGFuaW1hdGlvbiBub2RlIHVzZWQgdG8gY29udHJvbCB0aGUgcG9zaXRpb24gb2YgYSBwYXJ0aWNsZSBvdmVyIHRpbWUgYXJvdW5kIGEgY2lyY3VsYXIgb3JiaXQuXG4gKi9cbmNsYXNzIFBhcnRpY2xlT3JiaXROb2RlIGV4dGVuZHMgUGFydGljbGVOb2RlQmFzZVxue1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc0V1bGVyczpib29sZWFuO1xuXG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lVc2VzQ3ljbGU6Ym9vbGVhbjtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pVXNlc1BoYXNlOmJvb2xlYW47XG5cblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaVJhZGl1czpudW1iZXI7XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgX2lDeWNsZUR1cmF0aW9uOm51bWJlcjtcblx0LyoqIEBwcml2YXRlICovXG5cdHB1YmxpYyBfaUN5Y2xlUGhhc2U6bnVtYmVyO1xuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIF9pRXVsZXJzOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgZm9yIG9yYml0IG5vZGUgcHJvcGVydGllcyBvbiBhIHNpbmdsZSBwYXJ0aWNsZSAod2hlbiBpbiBsb2NhbCBwcm9wZXJ0eSBtb2RlKS5cblx0ICogRXhwZWN0cyBhIDxjb2RlPlZlY3RvcjNEPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSByYWRpdXMgKHgpLCBjeWNsZSBzcGVlZCAoeSkgYW5kIGN5Y2xlIHBoYXNlICh6KSBvZiB0aGUgbW90aW9uIG9uIHRoZSBwYXJ0aWNsZS5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgT1JCSVRfVkVDVE9SM0Q6c3RyaW5nID0gXCJPcmJpdFZlY3RvcjNEXCI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9ub2Rlcy9wYXJ0aWNsZXJvdGF0ZXRvcG9zaXRpb25ub2RlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUiLCJQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLmNvbnN0cnVjdG9yIiwiUGFydGljbGVSb3RhdGVUb1Bvc2l0aW9uTm9kZS5nZXRBR0FMVmVydGV4Q29kZSIsIlBhcnRpY2xlUm90YXRlVG9Qb3NpdGlvbk5vZGUuZ2V0QW5pbWF0aW9uU3RhdGUiLCJQYXJ0aWNsZVJvdGF0ZVRvUG9zaXRpb25Ob2RlLl9pR2VuZXJhdGVQcm9wZXJ0eU9mT25lUGFydGljbGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8scUJBQXFCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUczRyxJQUFPLHNCQUFzQixXQUFhLDZEQUE2RCxDQUFDLENBQUM7QUFDekcsSUFBTyxnQkFBZ0IsV0FBZSx3REFBd0QsQ0FBQyxDQUFDO0FBQ2hHLElBQU8sNkJBQTZCLFdBQVcsc0VBQXNFLENBQUMsQ0FBQztBQUV2SCxBQUdBOztHQURHO0lBQ0csNEJBQTRCO0lBQVNBLFVBQXJDQSw0QkFBNEJBLFVBQXlCQTtJQVcxREE7O09BRUdBO0lBQ0hBLFNBZEtBLDRCQUE0QkEsQ0FjckJBLElBQUlBLENBQVFBLFFBQURBLEFBQVNBLEVBQUVBLFFBQXdCQTtRQUF4QkMsd0JBQXdCQSxHQUF4QkEsZUFBd0JBO1FBRXpEQSxrQkFBTUEsMEJBQTBCQSxFQUFFQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU5Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsNkJBQTZCQSxDQUFDQTtRQUVsREEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsUUFBUUEsSUFBSUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDOUNBLENBQUNBO0lBRURE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QSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE1BQU1BLENBQUNBO1lBQzlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO1lBRTlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUNuREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFL0RBLEFBQ0FBLGdDQURnQ0E7WUFDaENBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLEdBQUdBLEtBQUtBLEdBQUdBLHNCQUFzQkEsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLFlBQVlBLEdBQUdBLE9BQU9BLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLENBQUNBO1lBQzlFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO1lBRTlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO1lBQ3RGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxPQUFPQSxHQUFHQSxZQUFZQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUVsRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUM3RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFL0RBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLFlBQVlBLEdBQUdBLE1BQU1BLENBQUNBO1lBQ25EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUN6RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0E7WUFDOURBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBO1lBRXZEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLE1BQU1BLENBQUNBO1lBQzlGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLG9CQUFvQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFFOUZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtZQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxvQkFBb0JBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO1lBRTlGQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtnQkFDMUJBLEFBRUFBLGlDQUZpQ0E7Z0JBQ2pDQSx1REFBdURBO2dCQUN2REEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsaUJBQWlCQSxHQUFHQSxPQUFPQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUN6SEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsWUFBWUEsR0FBR0EsUUFBUUEsQ0FBQ0E7Z0JBQ2xFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtnQkFDbkRBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUNwREEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLEtBQUtBLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7Z0JBQ25EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxDQUFDQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsQ0FBQ0EsR0FBR0EsS0FBS0EsR0FBR0EsWUFBWUEsR0FBR0EsTUFBTUEsQ0FBQ0E7Z0JBQy9EQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO2dCQUN0RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsWUFBWUEsR0FBR0EsT0FBT0EsR0FBR0EsWUFBWUEsR0FBR0EsUUFBUUEsQ0FBQ0E7Z0JBQzlFQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxzQkFBc0JBLENBQUNBLGVBQWVBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLElBQUlBLENBQUNBO2dCQUM5RkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsWUFBWUEsR0FBR0EsS0FBS0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDdEZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFlBQVlBLEdBQUdBLE9BQU9BLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLENBQUNBO2dCQUNsRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBR0Esc0JBQXNCQSxDQUFDQSxjQUFjQSxHQUFHQSxHQUFHQSxHQUFHQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDN0ZBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUdBLEdB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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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvYW5pbWF0aW9uY2xpcHN0YXRlLnRzIl0sIm5hbWVzIjpbIkFuaW1hdGlvbkNsaXBTdGF0ZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5jb25zdHJ1Y3RvciIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5ibGVuZFdlaWdodCIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5jdXJyZW50RnJhbWUiLCJBbmltYXRpb25DbGlwU3RhdGUubmV4dEZyYW1lIiwiQW5pbWF0aW9uQ2xpcFN0YXRlLnVwZGF0ZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5waGFzZSIsIkFuaW1hdGlvbkNsaXBTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJBbmltYXRpb25DbGlwU3RhdGUuX3BVcGRhdGVGcmFtZXMiLCJBbmltYXRpb25DbGlwU3RhdGUubm90aWZ5UGxheWJhY2tDb21wbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsSUFBTyxrQkFBa0IsV0FBYywyREFBMkQsQ0FBQyxDQUFDO0FBQ3BHLElBQU8sbUJBQW1CLFdBQWMsa0RBQWtELENBQUMsQ0FBQztBQUU1RixBQUdBOztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTJCQTtJQWlEbERBLFNBakRLQSxrQkFBa0JBLENBaURYQSxRQUFxQkEsRUFBRUEsaUJBQXVDQTtRQUV6RUMsa0JBQU1BLFFBQVFBLEVBQUVBLGlCQUFpQkEsQ0FBQ0EsQ0FBQ0E7UUF6QzdCQSxrQkFBYUEsR0FBV0EsSUFBSUEsQ0FBQ0E7UUEyQ25DQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLGlCQUFpQkEsQ0FBQ0E7SUFDN0NBLENBQUNBO0lBbkNERCxzQkFBV0EsMkNBQVdBO1FBUHRCQTs7Ozs7O1dBTUdBO2FBQ0hBO1lBRUNFLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO2dCQUN0QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsRUFBRUEsQ0FBQ0E7WUFFdkJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1FBQzNCQSxDQUFDQTs7O09BQUFGO0lBS0RBLHNCQUFXQSw0Q0FBWUE7UUFIdkJBOztXQUVHQTthQUNIQTtZQUVDRyxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtnQkFDdEJBLElBQUlBLENBQUNBLGNBQWNBLEVBQUVBLENBQUNBO1lBRXZCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUM1QkEsQ0FBQ0E7OztPQUFBSDtJQUtEQSxzQkFBV0EseUNBQVNBO1FBSHBCQTs7V0FFR0E7YUFDSEE7WUFFQ0ksRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7Z0JBQ3RCQSxJQUFJQSxDQUFDQSxjQUFjQSxFQUFFQSxDQUFDQTtZQUV2QkEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDekJBLENBQUNBOzs7T0FBQUo7SUFTREE7O09BRUdBO0lBQ0lBLG1DQUFNQSxHQUFiQSxVQUFjQSxJQUFJQSxDQUFRQSxPQUFEQSxBQUFRQTtRQUVoQ0ssRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN0Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxhQUFhQSxDQUFDQTtnQkFDbkVBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7Z0JBQ2xHQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUMxQkEsQ0FBQ0E7UUFFREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsSUFBSUEsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFDMUNBLE1BQU1BLENBQUNBO1FBRVJBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ3pCQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEsa0NBQUtBLEdBQVpBLFVBQWFBLEtBQVlBO1FBRXhCTSxJQUFJQSxJQUFJQSxHQUFrQkEsS0FBS0EsR0FBQ0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUV6RkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsSUFBSUEsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFDMUNBLE1BQU1BLENBQUNBO1FBRVJBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQ3pCQSxDQUFDQTtJQUVETjs7T0FFR0E7SUFDSUEseUNBQVlBLEdBQW5CQSxVQUFvQkEsSUFBSUEsQ0FBUUEsT0FBREEsQUFBUUE7UUFFdENPLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO1FBRTFCQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxHQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVqRUEsZ0JBQUtBLENBQUNBLFlBQVlBLFlBQUNBLElBQUlBLENBQUNBLENBQUNBO0lBQzFCQSxDQUFDQTtJQUVEUDs7Ozs7O09BTUdBO0lBQ0lBLDJDQUFjQSxHQUFyQkE7UUFFQ1EsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFM0JBLElBQUlBLE9BQU9BLEdBQVdBLElBQUlBLENBQUNBLGtCQUFrQkEsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDdERBLElBQUlBLGFBQWFBLEdBQW1CQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLGFBQWFBLENBQUNBO1FBQzFFQSxJQUFJQSxTQUFTQSxHQUFtQkEsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUNsRUEsSUFBSUEsSUFBSUEsR0FBa0JBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBO1FBRXRDQSxBQUNBQSxvQ0FEb0NBO1FBQ3BDQSxFQUFFQSxDQUFDQSxDQUFDQSxPQUFPQSxJQUFJQSxDQUFDQSxJQUFJQSxJQUFJQSxhQUFhQSxJQUFJQSxJQUFJQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNwREEsSUFBSUEsSUFBSUEsYUFBYUEsQ0FBQ0E7WUFDdEJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLEdBQUdBLENBQUNBLENBQUNBO2dCQUNaQSxJQUFJQSxJQUFJQSxhQUFhQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7UUFFREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsT0FBT0EsSUFBSUEsSUFBSUEsSUFBSUEsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkNBLElBQUlBLENBQUNBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7WUFDOUJBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLFNBQVNBLENBQUNBO1lBQ2hDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxTQUFTQSxDQUFDQTtZQUM3QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDeEJBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLE9BQU9BLElBQUlBLElBQUlBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2xDQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUN4QkEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDckJBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3hCQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBO1lBQ25EQSxJQUFJQSxDQUFDQSxHQUFVQSxJQUFJQSxHQUFDQSxhQUFhQSxHQUFDQSxTQUFTQSxDQUFDQTtZQUM1Q0EsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDcENBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBO1lBQzdDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUM1Q0EsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDUEEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDeEJBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLENBQUNBLENBQUNBO1lBRXJCQSxJQUFJQSxHQUFHQSxHQUFtQkEsQ0FBQ0EsRUFBRUEsU0FBU0EsQ0FBUUEsUUFBREEsQUFBU0EsQ0FBQ0E7WUFDdkRBLElBQUlBLFNBQVNBLEdBQTBCQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLFNBQVNBLENBQUNBO1lBRXpFQSxHQUFHQSxDQUFDQTtnQkFDSEEsU0FBU0EsR0FBR0EsR0FBR0EsQ0FBQ0E7Z0JBQ2hCQSxHQUFHQSxJQUFJQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtnQkFDbkNBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLEVBQUVBLENBQUNBO1lBQzFDQSxDQUFDQSxRQUFRQSxJQUFJQSxHQUFHQSxHQUFHQSxFQUFFQTtZQUVyQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsSUFBSUEsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3RDQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDeEJBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLENBQUNBLENBQUNBO1lBQ3RCQSxDQUFDQTtZQUVEQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxDQUFDQSxJQUFJQSxHQUFHQSxTQUFTQSxDQUFDQSxHQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQTtRQUN4RUEsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFFT1IsbURBQXNCQSxHQUE5QkE7UUFFQ1MsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsK0JBQStCQSxJQUFJQSxJQUFJQSxDQUFDQTtZQUNoREEsSUFBSUEsQ0FBQ0EsK0JBQStCQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxJQUFJQSxFQUFFQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLENBQUNBO1FBRXZKQSxJQUFJQSxDQUFDQSxrQkFBa0JBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLCtCQUErQkEsQ0FBQ0EsQ0FBQ0E7SUFDN0VBLENBQUNBO0lBQ0ZULHlCQUFDQTtBQUFEQSxDQXBLQSxBQW9LQ0EsRUFwS2dDLGtCQUFrQixFQW9LbEQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9BbmltYXRpb25DbGlwU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBBbmltYXRpb25DbGlwTm9kZUJhc2VcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL0FuaW1hdGlvbkNsaXBOb2RlQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25TdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL0FuaW1hdGlvblN0YXRlQmFzZVwiKTtcbmltcG9ydCBBbmltYXRpb25TdGF0ZUV2ZW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvZXZlbnRzL0FuaW1hdGlvblN0YXRlRXZlbnRcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgQW5pbWF0aW9uQ2xpcFN0YXRlIGV4dGVuZHMgQW5pbWF0aW9uU3RhdGVCYXNlXG57XG5cdHByaXZhdGUgX2FuaW1hdGlvbkNsaXBOb2RlOkFuaW1hdGlvbkNsaXBOb2RlQmFzZTtcblx0cHJpdmF0ZSBfYW5pbWF0aW9uU3RhdGVQbGF5YmFja0NvbXBsZXRlOkFuaW1hdGlvblN0YXRlRXZlbnQ7XG5cdHB1YmxpYyBfcEJsZW5kV2VpZ2h0Om51bWJlcjtcblx0cHVibGljIF9wQ3VycmVudEZyYW1lOm51bWJlciAvKnVpbnQqLztcblx0cHVibGljIF9wTmV4dEZyYW1lOm51bWJlciAvKnVpbnQqLztcblxuXHRwdWJsaWMgX3BPbGRGcmFtZTpudW1iZXIgLyp1aW50Ki87XG5cdHB1YmxpYyBfcFRpbWVEaXI6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyBfcEZyYW1lc0RpcnR5OmJvb2xlYW4gPSB0cnVlO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZnJhY3Rpb25hbCB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEgcmVwcmVzZW50aW5nIHRoZSBibGVuZGluZyByYXRpbyBvZiB0aGUgY3VycmVudCBwbGF5aGVhZCBwb3NpdGlvblxuXHQgKiBiZXR3ZWVuIHRoZSBjdXJyZW50IGZyYW1lICgwKSBhbmQgbmV4dCBmcmFtZSAoMSkgb2YgdGhlIGFuaW1hdGlvbi5cblx0ICpcblx0ICogQHNlZSAjY3VycmVudEZyYW1lXG5cdCAqIEBzZWUgI25leHRGcmFtZVxuXHQgKi9cblx0cHVibGljIGdldCBibGVuZFdlaWdodCgpOm51bWJlclxuXHR7XG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHJldHVybiB0aGlzLl9wQmxlbmRXZWlnaHQ7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgY3VycmVudCBmcmFtZSBvZiBhbmltYXRpb24gaW4gdGhlIGNsaXAgYmFzZWQgb24gdGhlIGludGVybmFsIHBsYXloZWFkIHBvc2l0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldCBjdXJyZW50RnJhbWUoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdGlmICh0aGlzLl9wRnJhbWVzRGlydHkpXG5cdFx0XHR0aGlzLl9wVXBkYXRlRnJhbWVzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fcEN1cnJlbnRGcmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBuZXh0IGZyYW1lIG9mIGFuaW1hdGlvbiBpbiB0aGUgY2xpcCBiYXNlZCBvbiB0aGUgaW50ZXJuYWwgcGxheWhlYWQgcG9zaXRpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG5leHRGcmFtZSgpOm51bWJlciAvKnVpbnQqL1xuXHR7XG5cdFx0aWYgKHRoaXMuX3BGcmFtZXNEaXJ0eSlcblx0XHRcdHRoaXMuX3BVcGRhdGVGcmFtZXMoKTtcblxuXHRcdHJldHVybiB0aGlzLl9wTmV4dEZyYW1lO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBhbmltYXRpb25DbGlwTm9kZTpBbmltYXRpb25DbGlwTm9kZUJhc2UpXG5cdHtcblx0XHRzdXBlcihhbmltYXRvciwgYW5pbWF0aW9uQ2xpcE5vZGUpO1xuXG5cdFx0dGhpcy5fYW5pbWF0aW9uQ2xpcE5vZGUgPSBhbmltYXRpb25DbGlwTm9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIHVwZGF0ZSh0aW1lOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0aWYgKCF0aGlzLl9hbmltYXRpb25DbGlwTm9kZS5sb29waW5nKSB7XG5cdFx0XHRpZiAodGltZSA+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvcGFydGljbGVzZWdtZW50ZWRjb2xvcnN0YXRlLnRzIl0sIm5hbWVzIjpbIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZSIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5zdGFydENvbG9yIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLmVuZENvbG9yIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLm51bVNlZ21lbnRQb2ludCIsIlBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZS5zZWdtZW50UG9pbnRzIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLnVzZXNNdWx0aXBsaWVyIiwiUGFydGljbGVTZWdtZW50ZWRDb2xvclN0YXRlLnVzZXNPZmZzZXQiLCJQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuc2V0UmVuZGVyU3RhdGUiLCJQYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUudXBkYXRlQ29sb3JEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFjQSxJQUFPLGlCQUFpQixXQUFjLDBEQUEwRCxDQUFDLENBQUM7QUFFbEcsQUFHQTs7R0FERztJQUNHLDJCQUEyQjtJQUFTQSxVQUFwQ0EsMkJBQTJCQSxVQUEwQkE7SUFtRjFEQSxTQW5GS0EsMkJBQTJCQSxDQW1GcEJBLFFBQXlCQSxFQUFFQSwwQkFBcURBO1FBRTNGQyxrQkFBTUEsUUFBUUEsRUFBRUEsMEJBQTBCQSxDQUFDQSxDQUFDQTtRQUU1Q0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsMEJBQTBCQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1FBQ25FQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSwwQkFBMEJBLENBQUNBLFlBQVlBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSwwQkFBMEJBLENBQUNBLFlBQVlBLENBQUNBO1FBQzNEQSxJQUFJ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QUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUN6RkEsQ0FBQ0E7UUFDREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDNUJBLElBQUlBO1lBQ0hBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1FBRTlEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMxQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7WUFDL0pBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDVkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3piQSxJQUFJQTtvQkFDSEEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsY0FBY0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDMWZBLENBQUNBO1lBQ0RBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxhQUFhQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxlQUFlQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxjQUFjQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtZQUNqU0EsSUFBSUE7Z0JBQ0hBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGFBQWFBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGNBQWNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLGVBQWVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ2xjQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN0QkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsU0FBU0EsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsVUFBVUEsR0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDM0pBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDVkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JhQSxJQUFJQTtvQkFDSEEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDdGVBLENBQUNBO1lBQ0RBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGdCQUFnQkEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzlCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxTQUFTQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxVQUFVQSxDQUFDQSxHQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNyUkEsSUFBSUE7Z0JBQ0hBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFNBQVNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFVBQVVBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLFdBQVdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQzlhQSxDQUFDQTtRQUNEQSxBQUNBQSxrQkFEa0JBO1FBQ2xCQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxNQUFNQSxHQUFHQSxDQUFDQSxDQUFDQTtJQUMvQkEsQ0FBQ0E7SUF4SkRULGVBQWVBO0lBQ0RBLGtEQUFzQkEsR0FBbUJBLENBQUNBLENBQUNBO0lBRXpEQSxlQUFlQTtJQUNEQSw4Q0FBa0JBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQUVyREEsZUFBZUE7SUFDREEsMkNBQWVBLEdBQW1CQSxDQUFDQSxDQUFDQTtJQWtKbkRBLGtDQUFDQTtBQUFEQSxDQTNKQSxBQTJKQ0EsRUEzSnlDLGlCQUFpQixFQTJKMUQ7QUFFRCxBQUFxQyxpQkFBNUIsMkJBQTJCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9QYXJ0aWNsZVNlZ21lbnRlZENvbG9yU3RhdGUuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29sb3JUcmFuc2Zvcm1cdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Db2xvclRyYW5zZm9ybVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBBbmltYXRpb25SZWdpc3RlckNhY2hlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xWZXJ0ZXhCdWZmZXJGb3JtYXRcIik7XG5cbmltcG9ydCBQYXJ0aWNsZUFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvUGFydGljbGVBbmltYXRvclwiKTtcbmltcG9ydCBBbmltYXRpb25TdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL0FuaW1hdGlvblN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IENvbG9yU2VnbWVudFBvaW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvQ29sb3JTZWdtZW50UG9pbnRcIik7XG5pbXBvcnQgUGFydGljbGVQcm9wZXJ0aWVzTW9kZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9QYXJ0aWNsZVByb3BlcnRpZXNNb2RlXCIpO1xuaW1wb3J0IFBhcnRpY2xlU2VnbWVudGVkQ29sb3JOb2RlXHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvUGFydGljbGVTZWdtZW50ZWRDb2xvck5vZGVcIik7XG5pbXBvcnQgUGFydGljbGVTdGF0ZUJhc2VcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvc3RhdGVzL1BhcnRpY2xlU3RhdGVCYXNlXCIpO1xuXG4vKipcbiAqXG4gKi9cbmNsYXNzIFBhcnRpY2xlU2VnbWVudGVkQ29sb3JTdGF0ZSBleHRlbmRzIFBhcnRpY2xlU3RhdGVCYXNlXG57XG5cdC8qKiBAcHJpdmF0ZSAqL1xuXHRwdWJsaWMgc3RhdGljIFNUQVJUX01VTFRJUExJRVJfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBTVEFSVF9PRkZTRVRfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMTtcblxuXHQvKiogQHByaXZhdGUgKi9cblx0cHVibGljIHN0YXRpYyBUSU1FX0RBVEFfSU5ERVg6bnVtYmVyIC8qdWludCovID0gMjtcblxuXHRwcml2YXRlIF91c2VzTXVsdGlwbGllcjpib29sZWFuO1xuXHRwcml2YXRlIF91c2VzT2Zmc2V0OmJvb2xlYW47XG5cdHByaXZhdGUgX3N0YXJ0Q29sb3I6Q29sb3JUcmFuc2Zvcm07XG5cdHByaXZhdGUgX2VuZENvbG9yOkNvbG9yVHJhbnNmb3JtO1xuXHRwcml2YXRlIF9zZWdtZW50UG9pbnRzOkFycmF5PENvbG9yU2VnbWVudFBvaW50Pjtcblx0cHJpdmF0ZSBfbnVtU2VnbWVudFBvaW50Om51bWJlciAvKmludCovO1xuXG5cdHByaXZhdGUgX3RpbWVMaWZlRGF0YTpBcnJheTxudW1iZXI+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFuaW1hdG9ycy9zdGF0ZXMvc2tlbGV0b25kaWZmZXJlbmNlc3RhdGUudHMiXSwibmFtZXMiOlsiU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5jb25zdHJ1Y3RvciIsIlNrZWxldG9uRGlmZmVyZW5jZVN0YXRlLmJsZW5kV2VpZ2h0IiwiU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUucGhhc2UiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5fcFVwZGF0ZVRpbWUiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5nZXRTa2VsZXRvblBvc2UiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5fcFVwZGF0ZVBvc2l0aW9uRGVsdGEiLCJTa2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS51cGRhdGVTa2VsZXRvblBvc2UiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sVUFBVSxXQUFnQixzQ0FBc0MsQ0FBQyxDQUFDO0FBS3pFLElBQU8sU0FBUyxXQUFnQixnREFBZ0QsQ0FBQyxDQUFDO0FBRWxGLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBRXhGLElBQU8sa0JBQWtCLFdBQWMsMkRBQTJELENBQUMsQ0FBQztBQUdwRyxBQUdBOztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQTJCQTtJQThCdkRBLFNBOUJLQSx1QkFBdUJBLENBOEJoQkEsUUFBcUJBLEVBQUVBLHFCQUE0Q0E7UUFFOUVDLGtCQUFNQSxRQUFRQSxFQUFFQSxxQkFBcUJBLENBQUNBLENBQUNBO1FBOUJoQ0EsaUJBQVlBLEdBQVVBLENBQUNBLENBQUNBO1FBR3hCQSxrQkFBYUEsR0FBZ0JBLElBQUlBLFlBQVlBLEVBQUVBLENBQUNBO1FBQ2hEQSx1QkFBa0JBLEdBQVdBLElBQUlBLENBQUNBO1FBNEJ6Q0EsSUFBSUEsQ0FBQ0Esc0JBQXNCQSxHQUFHQSxxQkFBcUJBLENBQUNBO1FBRXBEQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUE2QkEsUUFBUUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxJQUFJQSxDQUFDQSxzQkFBc0JBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBO1FBQzlHQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLEdBQTZCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLENBQUNBLElBQUlBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7SUFDM0hBLENBQUNBO0lBckJERCxzQkFBV0EsZ0RBQVdBO1FBUHRCQTs7Ozs7O1dBTUdBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO1FBQzFCQSxDQUFDQTthQUVERixVQUF1QkEsS0FBWUE7WUFFbENFLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLEtBQUtBLENBQUNBO1lBRTFCQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLENBQUNBO1lBQ2pDQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLElBQUlBLENBQUNBO1FBQ2hDQSxDQUFDQTs7O09BUkFGO0lBb0JEQTs7T0FFR0E7SUFDSUEsdUNBQUtBLEdBQVpBLFVBQWFBLEtBQVlBO1FBRXhCRyxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLElBQUlBLENBQUNBO1FBRS9CQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLENBQUNBO1FBRWpDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUM3QkEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7SUFDOUJBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSw4Q0FBWUEsR0FBbkJBLFVBQW9CQSxJQUFJQSxDQUFRQSxPQUFEQSxBQUFRQTtRQUV0Q0ksSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUUvQkEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFFbkNBLGdCQUFLQSxDQUFDQSxZQUFZQSxZQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUMxQkEsQ0FBQ0E7SUFFREo7O09BRUdBO0lBQ0lBLGlEQUFlQSxHQUF0QkEsVUFBdUJBLFFBQWlCQTtRQUV2Q0ssRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQTtZQUMzQkEsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUVuQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7SUFDM0JBLENBQUNBO0lBRURMOztPQUVHQTtJQUNJQSx1REFBcUJBLEdBQTVCQTtRQUVDTSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLEtBQUtBLENBQUNBO1FBRWxDQSxJQUFJQSxLQUFLQSxHQUFZQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUNuREEsSUFBSUEsS0FBS0EsR0FBWUEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxhQUFhQSxDQUFDQTtRQUV6REEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDM0RBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLEdBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUM1REEsQ0FBQ0E7SUFFRE47Ozs7T0FJR0E7SUFDS0Esb0RBQWtCQSxHQUExQkEsVUFBMkJBLFFBQWlCQTtRQUUzQ08sSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUVoQ0EsSUFBSUEsT0FBaUJBLENBQUNBO1FBQ3RCQSxJQUFJQSxRQUFRQSxHQUFvQkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDOURBLElBQUlBLFNBQVNBLEdBQW9CQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxlQUFlQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxVQUFVQSxDQUFDQTtRQUN0RkEsSUFBSUEsU0FBU0EsR0FBb0JBLElBQUlBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDNUZBLElBQUlBLElBQWNBLEVBQUVBLElBQWNBLENBQUNBO1FBQ25DQSxJQUFJQSxPQUFnQkEsRUFBRUEsT0FBZ0JBLENBQUNBO1FBQ3ZDQSxJQUFJQSxFQUFXQSxDQUFDQTtRQUNoQkEsSUFBSUEsU0FBU0EsR0FBbUJBLFFBQVFBLENBQUNBLFNBQVNBLENBQUNBO1FBRW5EQSxBQUNBQSxLQURLQTtRQUNMQSxFQUFFQSxDQUFDQSxDQUFDQSxRQUFRQSxDQUFDQSxNQUFNQSxJQUFJQSxTQUFTQSxDQUFDQTtZQUNoQ0EsUUFBUUEsQ0FBQ0EsTUFBTUEsR0FBR0EsU0FBU0EsQ0FBQ0E7UUFFN0JBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQW1CQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxTQUFTQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUNwREEsT0FBT0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFdEJBLEVBQUVBLENBQUNBLENBQUNBLE9BQU9BLElBQUlBLElBQUlBLENBQUNBO2dCQUNuQkEsT0FBT0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFFekNBLElBQUlBLEdBQUdBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3BCQSxJQUFJQSxHQUFHQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNwQkEsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7WUFDM0JBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1lBRTNCQSx1QkFBdUJBLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLEVBQUVBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO1lBQy9FQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxFQUFFQSx1QkFBdUJBLENBQUNBLFNBQVNBLEVBQUVBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBO1lBRWpHQSxFQUFFQSxHQUFHQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUN6QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDL0NBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLEdBQUNBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBO1lBQy9DQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNoREEsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFsSWNQLGlDQUFTQSxHQUFjQSxJQUFJQSxVQUFVQSxFQUFFQSxDQUFDQTtJQW1JeERBLDhCQUFDQTtBQUFEQSxDQXRJQSxBQXNJQ0EsRUF0SXFDLGtCQUFrQixFQXNJdkQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoiYW5pbWF0b3JzL3N0YXRlcy9Ta2VsZXRvbkRpZmZlcmVuY2VTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBRdWF0ZXJuaW9uXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9RdWF0ZXJuaW9uXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuXG5pbXBvcnQgQW5pbWF0b3JCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2FuaW1hdG9ycy9BbmltYXRvckJhc2VcIik7XG5cbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvbkRpZmZlcmVuY2VOb2RlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkRpZmZlcmVuY2VOb2RlXCIpO1xuaW1wb3J0IEFuaW1hdGlvblN0YXRlQmFzZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvQW5pbWF0aW9uU3RhdGVCYXNlXCIpO1xuaW1wb3J0IElTa2VsZXRvbkFuaW1hdGlvblN0YXRlXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9zdGF0ZXMvSVNrZWxldG9uQW5pbWF0aW9uU3RhdGVcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgU2tlbGV0b25EaWZmZXJlbmNlU3RhdGUgZXh0ZW5kcyBBbmltYXRpb25TdGF0ZUJhc2UgaW1wbGVtZW50cyBJU2tlbGV0b25BbmltYXRpb25TdGF0ZVxue1xuXHRwcml2YXRlIF9ibGVuZFdlaWdodDpudW1iZXIgPSAwO1xuXHRwcml2YXRlIHN0YXRpYyBfdGVtcFF1YXQ6UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdHByaXZhdGUgX3NrZWxldG9uQW5pbWF0aW9uTm9kZTpTa2VsZXRvbkRpZmZlcmVuY2VOb2RlO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2U6U2tlbGV0b25Qb3NlID0gbmV3IFNrZWxldG9uUG9zZSgpO1xuXHRwcml2YXRlIF9za2VsZXRvblBvc2VEaXJ0eTpib29sZWFuID0gdHJ1ZTtcblx0cHJpdmF0ZSBfYmFzZUlucHV0OklTa2VsZXRvbkFuaW1hdGlvblN0YXRlO1xuXHRwcml2YXRlIF9kaWZmZXJlbmNlSW5wdXQ6SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU7XG5cblx0LyoqXG5cdCAqIERlZmluZXMgYSBmcmFjdGlvbmFsIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIGJsZW5kaW5nIHJhdGlvIGJldHdlZW4gdGhlIGJhc2UgaW5wdXQgKDApIGFuZCBkaWZmZXJlbmNlIGlucHV0ICgxKSxcblx0ICogdXNlZCB0byBwcm9kdWNlIHRoZSBza2VsZXRvbiBwb3NlIG91dHB1dC5cblx0ICpcblx0ICogQHNlZSAjYmFzZUlucHV0XG5cdCAqIEBzZWUgI2RpZmZlcmVuY2VJbnB1dFxuXHQgKi9cblx0cHVibGljIGdldCBibGVuZFdlaWdodCgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2JsZW5kV2VpZ2h0O1xuXHR9XG5cblx0cHVibGljIHNldCBibGVuZFdlaWdodCh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9ibGVuZFdlaWdodCA9IHZhbHVlO1xuXG5cdFx0dGhpcy5fcFBvc2l0aW9uRGVsdGFEaXJ0eSA9IHRydWU7XG5cdFx0dGhpcy5fc2tlbGV0b25Qb3NlRGlydHkgPSB0cnVlO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoYW5pbWF0b3I6QW5pbWF0b3JCYXNlLCBza2VsZXRvbkFuaW1hdGlvbk5vZGU6U2tlbGV0b25EaWZmZXJlbmNlTm9kZSlcblx0e1xuXHRcdHN1cGVyKGFuaW1hdG9yLCBza2VsZXRvbkFuaW1hdGlvbk5vZGUpO1xuXG5cdFx0dGhpcy5fc2tlbGV0b25BbmltYXRpb25Ob2RlID0gc2tlbGV0b25BbmltYXRpb25Ob2RlO1xuXG5cdFx0dGhpcy5fYmFzZUlucHV0ID0gPElTa2VsZXRvbkFuaW1hdGlvblN0YXRlPiBhbmltYXRvci5nZXRBbmltYXRpb25TdGF0ZSh0aGlzLl9za2VsZXRvbkFuaW1hdGlvbk5vZGUuYmFzZUlucHV0KTtcblx0XHR0aGlzLl9kaWZmZXJlbmNlSW5wdXQgPSA8SVNrZWxldG9uQW5pbWF0aW9uU3RhdGU+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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QUFDQTtvQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsRUFBRUEsZUFBZUE7b0JBQzlCQSxHQUFHQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQTtvQkFDZEEsR0FBR0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7b0JBQ2RBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLEdBQUNBLEdBQUdBLEVBQUVBLGNBQWNBO29CQUMxREEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7b0JBQzNDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtvQkFDM0NBLEVBQUVBLEdBQUdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLENBQUNBLEVBQUVBLGNBQWNBO29CQUMvS0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0E7b0JBQzdCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQTtvQkFDN0JBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBO29CQUU3QkEsS0FBS0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7b0JBQ3BDQSxLQUFLQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxHQUFDQSxHQUFHQSxDQUFDQTtvQkFDcENBLENBQUNBLEdBQUdBLENBQUNBLEtBQUtBLEdBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLEdBQUNBLEtBQUtBLENBQUNBLEdBQUNBLFFBQVFBLENBQUNBO29CQUN6Q0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsS0FBS0EsR0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsR0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBQ0EsUUFBUUEsQ0FBQ0E7b0JBRXpDQSxHQUFHQSxHQUFHQSxRQUFRQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxRQUFRQSxDQUFBQTtvQkFDcENBLEdBQUdBLEdBQUdBLFFBQVFBLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLFFBQVFBLENBQUFBO29CQUNwQ0EsR0FBR0EsR0FBR0EsUUFBUUEsR0FBR0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsUUFBUUEsQ0FBQUE7b0JBRXBDQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDYkEsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2pCQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDeERBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUVoRUEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3BCQSxBQUdBQSxzQ0FIc0NBO29CQUN0Q0EscUZBQXFGQTtvQkFFckZBLE1BQU1BLENBQUNBO2dCQUNSQSxDQUFDQTtZQUNGQSxDQUFDQTtZQUVEQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUNSQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVEWjs7Ozs7Ozs7Ozs7T0FXR0E7SUFFS0EseUNBQWtCQSxHQUExQkEsVUFBMkJBLGlCQUEwQkEsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0E7UUFFdEhhLEFBQ0FBLDBFQUQwRUE7WUFDdEVBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLENBQUNBO1FBQ3BDQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFFQSxFQUFTQSxDQUFDQTtRQUNwQ0EsSUFBSUEsQ0FBUUEsQ0FBQ0E7UUFDYkEsSUFBSUEsR0FBR0EsR0FBaUJBLGFBQWFBLENBQUNBLGtCQUFrQkEsQ0FBQ0E7UUFDekRBLElBQUlBLEVBQUVBLEdBQVVBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLEVBQUVBLEVBQUVBLEdBQVVBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLEVBQUVBLEVBQUVBLEdBQVVBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBO1FBRXZGQSxBQUNBQSwyREFEMkRBO1FBQzNEQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNwQkEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDcEJBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBO1FBRXBCQSxBQUVBQSx5REFGeURBO1FBQ3pEQSwwQ0FBMENBO1FBQzFDQSxpQkFBaUJBLENBQUNBLGFBQWFBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3JDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQTtRQUN2Q0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsQ0FBQ0E7UUFDdkNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUNBLEVBQUVBLENBQUNBO1FBRXhDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUNqREEsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsRUFBRUEsR0FBR0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDakRBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUNBLEVBQUVBLEdBQUdBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1FBRWxEQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxHQUFDQSxFQUFFQSxDQUFDQSxHQUFDQSxDQUFDQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUV6RUEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFDQSxDQUFDQSxDQUFDQTtJQUN0Q0EsQ0FBQ0E7SUFFTWIsOEJBQU9BLEdBQWRBO1FBRUNjLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQzNCQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBO1lBQ3pCQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBRWpDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtZQUN2QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFFL0JBLElBQUlBLENBQUNBLGdCQUFnQkEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDN0JBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBO1FBQzNCQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBO0lBQ3hCQSxDQUFDQTtJQS9kY2QsK0JBQWtCQSxHQUFhQSxJQUFJQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtJQWdlekVBLG1CQUFDQTtBQUFEQSxDQWxnQkEsQUFrZ0JDQSxJQUFBO0FBRUQsQUFBc0IsaUJBQWIsWUFBWSxDQUFDIiwiZmlsZSI6ImNvcmUvcGljay9TaGFkZXJQaWNrZXIuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGVidWdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9EZWJ1Z1wiKTtcbmltcG9ydCBCaXRtYXBEYXRhXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9CaXRtYXBEYXRhXCIpO1xuaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBTY2VuZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvU2NlbmVcIik7XG5pbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9WaWV3XCIpO1xuaW1wb3J0IEJveFx0XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL0JveFwiKTtcbmltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBNYXRyaXgzRFV0aWxzXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RVdGlsc1wiKTtcbmltcG9ydCBQb2ludFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Qb2ludFwiKTtcbmltcG9ydCBSZWN0YW5nbGVcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1JlY3RhbmdsZVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBJUGlja2VyXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9waWNrL0lQaWNrZXJcIik7XG5pbXBvcnQgUGlja2luZ0NvbGxpc2lvblZPXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9waWNrL1BpY2tpbmdDb2xsaXNpb25WT1wiKTtcbmltcG9ydCBFbnRpdHlDb2xsZWN0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvdHJhdmVyc2UvRW50aXR5Q29sbGVjdG9yXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcbmltcG9ydCBJRW50aXR5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvSUVudGl0eVwiKTtcbmltcG9ydCBNYXRlcmlhbEJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL01hdGVyaWFsQmFzZVwiKTtcbmltcG9ydCBCeXRlQXJyYXlcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvQnl0ZUFycmF5XCIpO1xuXG5pbXBvcnQgQUdBTE1pbmlBc3NlbWJsZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hZ2xzbC9hc3NlbWJsZXIvQUdBTE1pbmlBc3NlbWJsZXJcIik7XG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBEZWZhdWx0UmVuZGVyZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcbmltcG9ydCBDb250ZXh0R0xCbGVuZEZhY3Rvclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xCbGVuZEZhY3RvclwiKTtcbmltcG9ydCBDb250ZXh0R0xDbGVhck1hc2tcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMQ2xlYXJNYXNrXCIpO1xuaW1wb3J0IENvbnRleHRHTENvbXBhcmVNb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTENvbXBhcmVNb2RlXCIpO1xuaW1wb3J0IENvbnRleHRHTFByb2dyYW1UeXBlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0NvbnRleHRHTFByb2dyYW1UeXBlXCIpO1xuaW1wb3J0IENvbnRleHRHTFRyaWFuZ2xlRmFjZVx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvQ29udGV4dEdMVHJpYW5nbGVGYWNlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBJUHJvZ3JhbVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JUHJvZ3JhbVwiKTtcbmltcG9ydCBJVGV4dHVyZUJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lUZXh0dXJlQmFzZVwiKTtcblxuLyoqXG4gKiBQaWNrcyBhIDNkIG9iamVjdCBmcm9tIGEgdmlldyBvciBzY2VuZSBieSBwZXJmb3JtaW5nIGEgc2VwYXJhdGUgcmVuZGVyIHBhc3Mgb24gdGhlIHNjZW5lIGFyb3VuZCB0aGUgYXJlYSBiZWluZyBwaWNrZWQgdXNpbmcga2V5IGNvbG9yIHZhbHVlcyxcbiAqIHRoZW4gcmVhZGluZyBiYWNrIHRoZSBjb2xvciB2YWx1ZSBvZiB0aGUgcGl4ZWwgaW4gdGhlIHJlbmRlciByZXByZXNlbnRpbmcgdGhlIHBpY2tpbmcgcmF5LiBSZXF1aXJlcyBtdWx0aXBsZSBwYXNzZXMgYW5kIHJlYWRiYWNrcyBmb3IgcmV0cml2aW5nIGRldGFpbHNcbiAqIG9uIGFuIGVudGl0eSB0aGF0IGhhcyBpdHMgc2hhZGVyUGlja2luZ0RldGFpbHMgcHJvcGVydHkgc2V0IHRvIHRydWUuXG4gKlxuICogQSByZWFkLWJhY2sgb3BlcmF0aW9uIGZyb20gYW55IEdQVSBpcyBub3QgYSB2ZXJ5IGVmZmljaWVudCBwcm9jZXNzLCBhbmQgdGhlIGFtb3VudCBvZiBwcm9jZXNzaW5nIHVzZWQgY2FuIHZhcnkgc2lnbmlmaWNhbnRseSBiZXR3ZWVuIGRpZmZlcmVudCBoYXJkd2FyZS5cbiAqXG4gKiBAc2VlIGF3YXkuZW50aXRpZXMuRW50aXR5I3NoYWRlclBpY2tpbmdEZXRhaWxzXG4gKlxuICogQGNsYXNzIGF3YXkucGljay5TaGFkZXJQaWNrZXJcbiAqL1xuY2xhc3MgU2hhZGVyUGlja2VyIGltcGxlbWVudHMgSVBpY2tlclxue1xuXHRwcml2YXRlIF9vcGFxdWVSZW5kZXJhYmxlSGVhZDpSZW5kZXJhYmxlQmFzZTtcblx0cHJpdmF0ZSBfYmxlbmRlZFJlbmRlcmFibGVIZWFkOlJlbmRlcmFibGVCYXNlO1xuXG5cdHByaXZhdGUgX3N0YWdlOlN0YWdlO1xuXHRwcml2YXRlIF9jb250ZXh0OklDb250ZXh0U3RhZ2VHTDtcblx0cHJpdmF0ZSBfb25seU1vdXNlRW5hYmxlZDpib29sZWFuID0gdHJ1ZTtcblxuXHRwcml2YXRlIF9vYmplY3RQcm9ncmFtOklQcm9ncmFtO1xuXHRwcml2YXRlIF90cmlhbmdsZVByb2dyYW06SVByb2dyYW07XG5cdHByaXZhdGUgX2JpdG1hcERhdGE6Qml0bWFwRGF0YTtcblx0cHJpdmF0ZSBfdmlld3BvcnREYXRhOkFycmF5PG51bWJlcj47XG5cdHByaXZhdGUgX2JvdW5kT2Zmc2V0U2NhbGU6QXJyYXk8bnVtYmVyPjtcblx0cHJpdmF0ZSBfaWQ6QXJyYXk8bnVtYmVyPjtcblxuXHRwcml2YXRlIF9pbnRlcmFjdGl2ZXM6QXJyYXk8UmVuZGVyYWJsZUJhc2U+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VjZWxtZXRob2QudHMiXSwibmFtZXMiOlsiRGlmZnVzZUNlbE1ldGhvZCIsIkRpZmZ1c2VDZWxNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlQ2VsTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRGlmZnVzZUNlbE1ldGhvZC5sZXZlbHMiLCJEaWZmdXNlQ2VsTWV0aG9kLnNtb290aG5lc3MiLCJEaWZmdXNlQ2VsTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIkRpZmZ1c2VDZWxNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiRGlmZnVzZUNlbE1ldGhvZC5pQWN0aXZhdGUiLCJEaWZmdXNlQ2VsTWV0aG9kLmNsYW1wRGlmZnVzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBV0EsSUFBTyxzQkFBc0IsV0FBYSxnRUFBZ0UsQ0FBQyxDQUFDO0FBRTVHLEFBR0E7O0dBREc7SUFDRyxnQkFBZ0I7SUFBU0EsVUFBekJBLGdCQUFnQkEsVUFBK0JBO0lBTXBEQTs7OztPQUlHQTtJQUNIQSxTQVhLQSxnQkFBZ0JBLENBV1RBLE1BQTBCQSxFQUFFQSxVQUFvQ0E7UUFYN0VDLGlCQTBIQ0E7UUEvR1lBLHNCQUEwQkEsR0FBMUJBLFVBQTBCQTtRQUFFQSwwQkFBb0NBLEdBQXBDQSxpQkFBb0NBO1FBRTNFQSxrQkFBTUEsSUFBSUEsRUFBRUEsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFUakJBLGdCQUFXQSxHQUFVQSxFQUFFQSxDQUFDQTtRQVcvQkEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxVQUFDQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBLElBQUtBLE9BQUFBLEtBQUlBLENBQUNBLFlBQVlBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLFNBQVNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLEVBQXBGQSxDQUFvRkEsQ0FBQ0E7UUFFdFJBLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLE1BQU1BLENBQUNBO0lBQ3ZCQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEseUNBQWNBLEdBQXJCQSxVQUFzQkEsWUFBaUNBLEVBQUVBLFFBQWlCQTtRQUV6RUUsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSwrQkFBK0JBLENBQUNBO1FBQ3BFQSxnQkFBS0EsQ0FBQ0EsY0FBY0EsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7UUFDN0NBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3BCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtJQUNyQkEsQ0FBQ0E7SUFLREYsc0JBQVdBLG9DQUFNQTtRQUhqQkE7O1dBRUdBO2FBQ0hBO1lBRUNHLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBO1FBQ3JCQSxDQUFDQTthQUVESCxVQUFrQkEsS0FBS0EsQ0FBUUEsUUFBREEsQUFBU0E7WUFFdENHLElBQUlBLENBQUNBLE9BQU9BLEdBQUdBLEtBQUtBLENBQUNBO1FBQ3RCQSxDQUFDQTs7O09BTEFIO0lBVURBLHNCQUFXQSx3Q0FBVUE7UUFIckJBOztXQUVHQTthQUNIQTtZQUVDSSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUN6QkEsQ0FBQ0E7YUFFREosVUFBc0JBLEtBQVlBO1lBRWpDSSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUMxQkEsQ0FBQ0E7OztPQUxBSjtJQU9EQTs7T0FFR0E7SUFDSUEsZ0RBQXFCQSxHQUE1QkE7UUFFQ0ssZ0JBQUtBLENBQUNBLHFCQUFxQkEsV0FBRUEsQ0FBQ0E7UUFDOUJBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBO0lBQ3RCQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEsc0RBQTJCQSxHQUFsQ0EsVUFBbUNBLFlBQWlDQSxFQUFFQSxRQUFpQkEsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUU3Sk0sSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUN4REEsUUFBUUEsQ0FBQ0EsK0JBQStCQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxLQUFLQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUVqRUEsTUFBTUEsQ0FBQ0EsZ0JBQUtBLENBQUNBLDJCQUEyQkEsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsYUFBYUEsRUFBRUEsZUFBZUEsQ0FBQ0EsQ0FBQ0E7SUFDbEdBLENBQUNBO0lBRUROOztPQUVHQTtJQUNJQSxvQ0FBU0EsR0FBaEJBLFVBQWlCQSxZQUFpQ0EsRUFBRUEsUUFBaUJBLEVBQUVBLEtBQVdBO1FBRWpGTyxnQkFBS0EsQ0FBQ0EsU0FBU0EsWUFBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDL0NBLElBQUlBLElBQUlBLEdBQWlCQSxZQUFZQSxDQUFDQSxvQkFBb0JBLENBQUNBO1FBQzNEQSxJQUFJQSxLQUFLQSxHQUFrQkEsUUFBUUEsQ0FBQ0EsK0JBQStCQSxDQUFDQTtRQUNwRUEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO0lBQ3BDQSxDQUFDQTtJQUVEUDs7Ozs7OztPQU9HQTtJQUNLQSx1Q0FBWUEsR0FBcEJBLFVBQXFCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTVLUSxNQUFNQSxDQUFDQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUMvRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDaERBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3JFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUNwREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FDekVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLEtBQUtBLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQy9DQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUdyRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FHckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUVoREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FFckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUNyRUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLENBQUNBO0lBQ25EQSxDQUFDQTtJQUNGUix1QkFBQ0E7QUFBREEsQ0ExSEEsQUEwSENBLEVBMUg4QixzQkFBc0IsRUEwSHBEO0FBRUQsQUFBMEIsaUJBQWpCLGdCQUFnQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VDZWxNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgSUNvbnRleHRTdGFnZUdMXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvSUNvbnRleHRTdGFnZUdMXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuaW1wb3J0IERpZmZ1c2VDb21wb3NpdGVNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFwiKTtcblxuLyoqXG4gKiBEaWZmdXNlQ2VsTWV0aG9kIHByb3ZpZGVzIGEgc2hhZGluZyBtZXRob2QgdG8gYWRkIGRpZmZ1c2UgY2VsIChjYXJ0b29uKSBzaGFkaW5nLlxuICovXG5jbGFzcyBEaWZmdXNlQ2VsTWV0aG9kIGV4dGVuZHMgRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFxue1xuXHRwcml2YXRlIF9sZXZlbHM6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9kYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc21vb3RobmVzczpudW1iZXIgPSAuMTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlQ2VsTWV0aG9kIG9iamVjdC5cblx0ICogQHBhcmFtIGxldmVscyBUaGUgYW1vdW50IG9mIHNoYWRvdyBncmFkYXRpb25zLlxuXHQgKiBAcGFyYW0gYmFzZU1ldGhvZCBBbiBvcHRpb25hbCBkaWZmdXNlIG1ldGhvZCBvbiB3aGljaCB0aGUgY2FydG9vbiBzaGFkaW5nIGlzIGJhc2VkLiBJZiBvbWl0dGVkLCBEaWZmdXNlQmFzaWNNZXRob2QgaXMgdXNlZC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGxldmVsczpudW1iZXIgLyp1aW50Ki8gPSAzLCBiYXNlTWV0aG9kOkRpZmZ1c2VCYXNpY01ldGhvZCA9IG51bGwpXG5cdHtcblx0XHRzdXBlcihudWxsLCBiYXNlTWV0aG9kKTtcblxuXHRcdHRoaXMuYmFzZU1ldGhvZC5faU1vZHVsYXRlTWV0aG9kID0gKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKSA9PiB0aGlzLmNsYW1wRGlmZnVzZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCB0YXJnZXRSZWcsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cblx0XHR0aGlzLl9sZXZlbHMgPSBsZXZlbHM7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHN1cGVyLmlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdCwgbWV0aG9kVk8pO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDE7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IG9mIHNoYWRvdyBncmFkYXRpb25zLlxuXHQgKi9cblx0cHVibGljIGdldCBsZXZlbHMoKTpudW1iZXIgLyp1aW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9sZXZlbHM7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGxldmVscyh2YWx1ZTpudW1iZXIgLyp1aW50Ki8pXG5cdHtcblx0XHR0aGlzLl9sZXZlbHMgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgc21vb3RobmVzcyBvZiB0aGUgZWRnZSBiZXR3ZWVuIDIgc2hhZGluZyBsZXZlbHMuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHNtb290aG5lc3MoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9zbW9vdGhuZXNzO1xuXHR9XG5cblx0cHVibGljIHNldCBzbW9vdGhuZXNzKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3Ntb290aG5lc3MgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0XHR0aGlzLl9kYXRhUmVnID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5fZGF0YVJlZyA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4ID0gdGhpcy5fZGF0YVJlZy5pbmRleCo0O1xuXG5cdFx0cmV0dXJuIHN1cGVyLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c3VwZXIuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2Vjb21wb3NpdGVtZXRob2QudHMiXSwibmFtZXMiOlsiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZCIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmJhc2VNZXRob2QiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlJbml0Vk8iLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5kaXNwb3NlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC50ZXh0dXJlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5kaWZmdXNlQ29sb3IiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmFtYmllbnRDb2xvciIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJQcm9iZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUFjdGl2YXRlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pU2V0UmVuZGVyU3RhdGUiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmlEZWFjdGl2YXRlIiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pR2V0VmVydGV4Q29kZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZSIsIkRpZmZ1c2VDb21wb3NpdGVNZXRob2QuaVJlc2V0IiwiRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJEaWZmdXNlQ29tcG9zaXRlTWV0aG9kLm9uU2hhZGVySW52YWxpZGF0ZWQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUtBLElBQU8sa0JBQWtCLFdBQWMsOENBQThDLENBQUMsQ0FBQztBQU92RixJQUFPLGtCQUFrQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFbEcsQUFJQTs7O0dBREc7SUFDRyxzQkFBc0I7SUFBU0EsVUFBL0JBLHNCQUFzQkEsVUFBMkJBO0lBTXREQTs7Ozs7T0FLR0E7SUFDSEEsU0FaS0Esc0JBQXNCQSxDQVlmQSxjQUFtTEEsRUFBRUEsVUFBb0NBO1FBWnRPQyxpQkFnTkNBO1FBcE1pTUEsMEJBQW9DQSxHQUFwQ0EsaUJBQW9DQTtRQUVwT0EsaUJBQU9BLENBQUNBO1FBRVJBLElBQUlBLENBQUNBLDRCQUE0QkEsR0FBR0EsVUFBQ0EsS0FBd0JBLElBQUtBLE9BQUFBLEtBQUlBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsRUFBL0JBLENBQStCQSxDQUFDQTtRQUVsR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsVUFBVUEsSUFBSUEsSUFBSUEsa0JBQWtCQSxFQUFFQSxDQUFDQTtRQUMxREEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZ0JBQWdCQSxHQUFHQSxjQUFjQSxDQUFDQTtRQUNuREEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxrQkFBa0JBLENBQUNBLGtCQUFrQkEsRUFBRUEsSUFBSUEsQ0FBQ0EsNEJBQTRCQSxDQUFDQSxDQUFDQTtJQUM3R0EsQ0FBQ0E7SUFLREQsc0JBQVdBLDhDQUFVQTtRQUhyQkE7O1dBRUdBO2FBQ0hBO1lBRUNFLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBQ3pCQSxDQUFDQTthQUVERixVQUFzQkEsS0FBd0JBO1lBRTdDRSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxJQUFJQSxLQUFLQSxDQUFDQTtnQkFDN0JBLE1BQU1BLENBQUNBO1lBRVJBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLG1CQUFtQkEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxrQkFBa0JBLEVBQUVBLElBQUlBLENBQUNBLDRCQUE0QkEsQ0FBQ0EsQ0FBQ0E7WUFDL0dBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEtBQUtBLENBQUNBO1lBQ3pCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxnQkFBZ0JBLENBQUNBLGtCQUFrQkEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxJQUFJQSxDQUFDQSw0QkFBNEJBLENBQUNBLENBQUNBO1lBQzVHQSxJQUFJQSxDQUFDQSx3QkFBd0JBLEVBQUVBLENBQUNBO1FBQ2pDQSxDQUFDQTs7O09BWEFGO0lBYURBOztPQUVHQTtJQUNJQSx3Q0FBT0EsR0FBZEEsVUFBZUEsWUFBaUNBLEVBQUVBLFFBQWlCQTtRQUVsRUcsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7SUFDbERBLENBQUNBO0lBRURIOztPQUVHQTtJQUNJQSwrQ0FBY0EsR0FBckJBLFVBQXNCQSxZQUFpQ0EsRUFBRUEsUUFBaUJBO1FBRXpFSSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxjQUFjQSxDQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQTtJQUN6REEsQ0FBQ0E7SUFFREo7O09BRUdBO0lBQ0lBLHdDQUFPQSxHQUFkQTtRQUVDSyxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxtQkFBbUJBLENBQUNBLGtCQUFrQkEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxJQUFJQSxDQUFDQSw0QkFBNEJBLENBQUNBLENBQUNBO1FBQy9HQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtJQUM1QkEsQ0FBQ0E7SUFLREwsc0JBQVdBLDJDQUFPQTtRQUhsQkE7O1dBRUdBO2FBQ0hBO1lBRUNNLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLE9BQU9BLENBQUNBO1FBQ2pDQSxDQUFDQTtRQUVETjs7V0FFR0E7YUFDSEEsVUFBbUJBLEtBQW1CQTtZQUVyQ00sSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsT0FBT0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDbENBLENBQUNBOzs7T0FSQU47SUFhREEsc0JBQVdBLGdEQUFZQTtRQUh2QkE7O1dBRUdBO2FBQ0hBO1lBRUNPLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFlBQVlBLENBQUNBO1FBQ3RDQSxDQUFDQTtRQUVEUDs7V0FFR0E7YUFDSEEsVUFBd0JBLEtBQVlBO1lBRW5DTyxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUN2Q0EsQ0FBQ0E7OztPQVJBUDtJQWNEQSxzQkFBV0EsZ0RBQVlBO1FBSHZCQTs7V0FFR0E7YUFDSEE7WUFFQ1EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsWUFBWUEsQ0FBQ0E7UUFDdENBLENBQUNBO1FBRURSOztXQUVHQTthQUNIQSxVQUF3QkEsS0FBWUE7WUFFbkNRLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFlBQVlBLEdBQUdBLEtBQUtBLENBQUNBO1FBQ3ZDQSxDQUFDQTs7O09BUkFSO0lBVURBOztPQUVHQTtJQUNJQSw0REFBMkJBLEdBQWxDQSxVQUFtQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRTdKUyxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSwyQkFBMkJBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO0lBQzdHQSxDQUFDQTtJQUVEVDs7T0FFR0E7SUFDSUEseURBQXdCQSxHQUEvQkEsVUFBZ0NBLFlBQWlDQSxFQUFFQSxRQUFpQkEsRUFBRUEsV0FBaUNBLEVBQUVBLFdBQWlDQSxFQUFFQSxhQUFpQ0EsRUFBRUEsZUFBa0NBO1FBRWhPVSxJQUFJQSxJQUFJQSxHQUFVQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSx3QkFBd0JBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLFdBQVdBLEVBQUVBLFdBQVdBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO1FBQzlJQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDbEVBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURWOztPQUVHQTtJQUNJQSx5REFBd0JBLEdBQS9CQSxVQUFnQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxVQUFnQ0EsRUFBRUEsY0FBcUJBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFbk5XLElBQUlBLElBQUlBLEdBQVVBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsVUFBVUEsRUFBRUEsY0FBY0EsRUFBRUEsYUFBYUEsRUFBRUEsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDaEpBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUNsRUEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFRFg7O09BRUdBO0lBQ0lBLDBDQUFTQSxHQUFoQkEsVUFBaUJBLFlBQWlDQSxFQUFFQSxRQUFpQkEsRUFBRUEsS0FBV0E7UUFFakZZLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFNBQVNBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO0lBQzNEQSxDQUFDQTtJQUVEWjs7T0FFR0E7SUFDSUEsZ0RBQWVBLEdBQXRCQSxVQUF1QkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxVQUF5QkEsRUFBRUEsS0FBV0EsRUFBRUEsTUFBYUE7UUFFaklhLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGVBQWVBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLFVBQVVBLEVBQUVBLEtBQUtBLEVBQUVBLE1BQU1BLENBQUNBLENBQUNBO0lBQ3JGQSxDQUFDQTtJQUVEYjs7T0FFR0E7SUFDSUEsNENBQVdBLEdBQWxCQSxVQUFtQkEsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxLQUFXQTtRQUVuRmMsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0E7SUFDN0RBLENBQUNBO0lBRURkOztPQUVHQTtJQUNJQSwrQ0FBY0EsR0FBckJBLFVBQXNCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFNUllLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLGNBQWNBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO0lBQ2hHQSxDQUFDQTtJQUVEZjs7T0FFR0E7SUFDSUEsNkRBQTRCQSxHQUFuQ0EsVUFBb0NBLFlBQWlDQSxFQUFFQSxRQUFpQkEsRUFBRUEsU0FBK0JBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFL0xnQixNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSw0QkFBNEJBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLFNBQVNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO0lBQ3pIQSxDQUFDQTtJQUVEaEI7O09BRUdBO0lBQ0lBLHVDQUFNQSxHQUFiQTtRQUVDaUIsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0E7SUFDM0JBLENBQUNBO0lBRURqQjs7T0FFR0E7SUFDSUEsc0RBQXFCQSxHQUE1QkE7UUFFQ2tCLGdCQUFLQSxDQUFDQSxxQkFBcUJBLFdBQUVBLENBQUNBO1FBQzlCQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxxQkFBcUJBLEVBQUVBLENBQUNBO0lBQzFDQSxDQUFDQTtJQUVEbEI7O09BRUdBO0lBQ0tBLG9EQUFtQkEsR0FBM0JBLFVBQTRCQSxLQUF3QkE7UUFFbkRtQixJQUFJQSxDQUFDQSx3QkFBd0JBLEVBQUVBLENBQUNBO0lBQ2pDQSxDQUFDQTtJQUNGbkIsNkJBQUNBO0FBQURBLENBaE5BLEFBZ05DQSxFQWhOb0Msa0JBQWtCLEVBZ050RDtBQUVELEFBQWdDLGlCQUF2QixzQkFBc0IsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQ29tcG9zaXRlTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRleHR1cmUyREJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmUyREJhc2VcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBTaGFkaW5nTWV0aG9kRXZlbnRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9ldmVudHMvU2hhZGluZ01ldGhvZEV2ZW50XCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcblxuLyoqXG4gKiBEaWZmdXNlQ29tcG9zaXRlTWV0aG9kIHByb3ZpZGVzIGEgYmFzZSBjbGFzcyBmb3IgZGlmZnVzZSBtZXRob2RzIHRoYXQgd3JhcCBhIGRpZmZ1c2UgbWV0aG9kIHRvIGFsdGVyIHRoZVxuICogY2FsY3VsYXRlZCBkaWZmdXNlIHJlZmxlY3Rpb24gc3RyZW5ndGguXG4gKi9cbmNsYXNzIERpZmZ1c2VDb21wb3NpdGVNZXRob2QgZXh0ZW5kcyBEaWZmdXNlQmFzaWNNZXRob2Rcbntcblx0cHVibGljIHBCYXNlTWV0aG9kOkRpZmZ1c2VCYXNpY01ldGhvZDtcblxuXHRwcml2YXRlIF9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGU6RnVuY3Rpb247XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VkZXB0aG1ldGhvZC50cyJdLCJuYW1lcyI6WyJEaWZmdXNlRGVwdGhNZXRob2QiLCJEaWZmdXNlRGVwdGhNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlRGVwdGhNZXRob2QuaUluaXRDb25zdGFudHMiLCJEaWZmdXNlRGVwdGhNZXRob2QuaUdldEZyYWdtZW50UG9zdExpZ2h0aW5nQ29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBTUEsSUFBTyxrQkFBa0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBQ2xHLElBQU8sb0JBQW9CLFdBQWMseURBQXlELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csa0JBQWtCO0lBQVNBLFVBQTNCQSxrQkFBa0JBLFVBQTJCQTtJQUVsREE7O09BRUdBO0lBQ0hBLFNBTEtBLGtCQUFrQkE7UUFPdEJDLGlCQUFPQSxDQUFDQTtJQUNUQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsMkNBQWNBLEdBQXJCQSxVQUFzQkEsWUFBNkJBLEVBQUVBLFFBQWlCQTtRQUVyRUUsSUFBSUEsSUFBSUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDM0RBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSxzQkFBc0JBLENBQUNBO1FBQzNEQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQTtRQUNsQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsS0FBS0EsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLE9BQU9BLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxVQUFVQSxDQUFDQTtJQUNoQ0EsQ0FBQ0E7SUFFREY7O09BRUdBO0lBQ0lB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QUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUM3RUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFFN0NBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBQ0ZILHlCQUFDQTtBQUFEQSxDQWhFQSxBQWdFQ0EsRUFoRWdDLGtCQUFrQixFQWdFbEQ7QUFFRCxBQUE0QixpQkFBbkIsa0JBQWtCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZURlcHRoTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IERpZmZ1c2VCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuLyoqXG4gKiBEaWZmdXNlRGVwdGhNZXRob2QgcHJvdmlkZXMgYSBkZWJ1ZyBtZXRob2QgdG8gdmlzdWFsaXNlIGRlcHRoIG1hcHNcbiAqL1xuY2xhc3MgRGlmZnVzZURlcHRoTWV0aG9kIGV4dGVuZHMgRGlmZnVzZUJhc2ljTWV0aG9kXG57XG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IERpZmZ1c2VCYXNpY01ldGhvZCBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGRhdGFbaW5kZXhdID0gMS4wO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDEvMjU1LjA7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gMS82NTAyNS4wO1xuXHRcdGRhdGFbaW5kZXggKyAzXSA9IDEvMTY1ODEzNzUuMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdHZhciBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXG5cdFx0aWYgKCF0aGlzLl9wVXNlVGV4dHVyZSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkRpZmZ1c2VEZXB0aE1ldGhvZCByZXF1aXJlcyB0ZXh0dXJlIVwiKTtcblxuXHRcdC8vIGluY29ycG9yYXRlIGlucHV0IGZyb20gYW1iaWVudFxuXHRcdGlmIChzaGFkZXJPYmplY3QubnVtTGlnaHRzID4gMCkge1xuXHRcdFx0aWYgKHNoYXJlZFJlZ2lzdGVycy5zaGFkb3dUYXJnZXQpXG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIueHl6LCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnNoYWRvd1RhcmdldCArIFwiLndcXG5cIjtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwic2F0IFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRhcmdldFJlZyArIFwiLnh5elxcblwiO1xuXHRcdFx0cmVnaXN0ZXJDYWNoZS5yZW1vdmVGcmFnbWVudFRlbXBVc2FnZSh0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnKTtcblx0XHR9XG5cblx0XHR0ZW1wID0gc2hhZGVyT2JqZWN0Lm51bUxpZ2h0cyA+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2RpZmZ1c2VzdWJzdXJmYWNlbWV0aG9kLnRzIl0sIm5hbWVzIjpbIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kIiwiRGlmZnVzZVN1YlN1cmZhY2VNZXRob2QuY29uc3RydWN0b3IiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pSW5pdENvbnN0YW50cyIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLnNjYXR0ZXJpbmciLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC50cmFuc2x1Y2VuY3kiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5zY2F0dGVyQ29sb3IiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pR2V0VmVydGV4Q29kZSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZSIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodCIsIkRpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kLmlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pQWN0aXZhdGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5pU2V0UmVuZGVyU3RhdGUiLCJEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5zY2F0dGVyTGlnaHQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQWNBLElBQU8sc0JBQXNCLFdBQWEsZ0VBQWdFLENBQUMsQ0FBQztBQUM1RyxJQUFPLHFCQUFxQixXQUFhLDhEQUE4RCxDQUFDLENBQUM7QUFFekcsQUFLQTs7OztHQURHO0lBQ0csdUJBQXVCO0lBQVNBLFVBQWhDQSx1QkFBdUJBLFVBQStCQTtJQWdCM0RBOzs7Ozs7T0FNR0E7SUFDSEEsU0F2QktBLHVCQUF1QkEsQ0F1QmhCQSxZQUFpQ0EsRUFBRUEsY0FBMEJBLEVBQUVBLFVB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QU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUloREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDaERBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUN6RUEsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FHM0VBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLEdBQUdBLE1BQU1BLEdBQ2hGQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUV2RUEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFDRmIsOEJBQUNBO0FBQURBLENBclFBLEFBcVFDQSxFQXJRcUMsc0JBQXNCLEVBcVEzRDtBQUVELEFBQWlDLGlCQUF4Qix1QkFBdUIsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlU3ViU3VyZmFjZU1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5cbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBSZW5kZXJhYmxlQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL1JlbmRlcmFibGVCYXNlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBEaWZmdXNlQmFzaWNNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQmFzaWNNZXRob2RcIik7XG5pbXBvcnQgTWF0ZXJpYWxQYXNzQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3Bhc3Nlcy9NYXRlcmlhbFBhc3NCYXNlXCIpO1xuXG5pbXBvcnQgRGlmZnVzZUNvbXBvc2l0ZU1ldGhvZFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9EaWZmdXNlQ29tcG9zaXRlTWV0aG9kXCIpO1xuaW1wb3J0IFNpbmdsZU9iamVjdERlcHRoUGFzc1x0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvcGFzc2VzL1NpbmdsZU9iamVjdERlcHRoUGFzc1wiKTtcblxuLyoqXG4gKiBEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZCBwcm92aWRlcyBhIGRlcHRoIG1hcC1iYXNlZCBkaWZmdXNlIHNoYWRpbmcgbWV0aG9kIHRoYXQgbWltaWNzIHRoZSBzY2F0dGVyaW5nIG9mXG4gKiBsaWdodCBpbnNpZGUgdHJhbnNsdWNlbnQgc3VyZmFjZXMuIEl0IGFsbG93cyBsaWdodCB0byBzaGluZSB0aHJvdWdoIGFuIG9iamVjdCBhbmQgdG8gc29mdGVuIHRoZSBkaWZmdXNlIHNoYWRpbmcuXG4gKiBJdCBjYW4gYmUgdXNlZCBmb3IgY2FuZGxlIHdheCwgaWNlLCBza2luLCAuLi5cbiAqL1xuY2xhc3MgRGlmZnVzZVN1YlN1cmZhY2VNZXRob2QgZXh0ZW5kcyBEaWZmdXNlQ29tcG9zaXRlTWV0aG9kXG57XG5cdHByaXZhdGUgX2RlcHRoUGFzczpTaW5nbGVPYmplY3REZXB0aFBhc3M7XG5cdHByaXZhdGUgX2xpZ2h0UHJvalZhcnlpbmc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRwcml2YXRlIF9wcm9wUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc2NhdHRlcmluZzpudW1iZXI7XG5cdHByaXZhdGUgX3RyYW5zbHVjZW5jeTpudW1iZXIgPSAxO1xuXHRwcml2YXRlIF9saWdodENvbG9yUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfc2NhdHRlckNvbG9yOm51bWJlciAvKnVpbnQqLyA9IDB4ZmZmZmZmO1xuXHRwcml2YXRlIF9jb2xvclJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdHByaXZhdGUgX2RlY1JlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdHByaXZhdGUgX3NjYXR0ZXJSOm51bWJlciA9IDEuMDtcblx0cHJpdmF0ZSBfc2NhdHRlckc6bnVtYmVyID0gMS4wO1xuXHRwcml2YXRlIF9zY2F0dGVyQjpudW1iZXIgPSAxLjA7XG5cdHByaXZhdGUgX3RhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5EaWZmdXNlU3ViU3VyZmFjZU1ldGhvZDwvY29kZT4gb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gZGVwdGhNYXBTaXplIFRoZSBzaXplIG9mIHRoZSBkZXB0aCBtYXAgdXNlZC5cblx0ICogQHBhcmFtIGRlcHRoTWFwT2Zmc2V0IFRoZSBhbW91bnQgYnkgd2hpY2ggdGhlIHJlbmRlcmVkIG9iamVjdCB3aWxsIGJlIGluZmxhdGVkLCB0byBwcmV2ZW50IGRlcHRoIG1hcCByb3VuZGluZyBlcnJvcnMuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBkaWZmdXNlIG1ldGhvZCB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgcmVndWxhciBkaWZmdXNlLWJhc2VkIGxpZ2h0aW5nLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoZGVwdGhNYXBTaXplOm51bWJlciAvKmludCovID0gNTEyLCBkZXB0aE1hcE9mZnNldDpudW1iZXIgPSAxNSwgYmFzZU1ldGhvZDpEaWZmdXNlQmFzaWNNZXRob2QgPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIobnVsbCwgYmFzZU1ldGhvZCk7XG5cblx0XHR0aGlzLnBCYXNlTWV0aG9kLl9pTW9kdWxhdGVNZXRob2QgPSAoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpID0+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) + { + super(); + + if (matrix.length != 20) + throw new Error("Matrix length must be 20!"); + + this._matrix = matrix; + } + + /** + * The 4 x 5 matrix to transform the color of the material. + */ + public get colorMatrix():Array + { + return this._matrix; + } + + public set colorMatrix(value:Array) + { + this._matrix = value; + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + var colorMultReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + registerCache.getFreeFragmentConstant(); + registerCache.getFreeFragmentConstant(); + registerCache.getFreeFragmentConstant(); + + var colorOffsetReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + + methodVO.fragmentConstantsIndex = colorMultReg.index*4; + + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + + code += "m44 " + temp + ", " + targetReg + ", " + colorMultReg + "\n" + + "add " + targetReg + ", " + temp + ", " + colorOffsetReg + "\n"; + + return code; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var matrix:Array = this._matrix; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + var data:Array = 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]; + } +} + +export = EffectColorMatrixMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectEnvMapMethod.js b/lib/materials/methods/EffectEnvMapMethod.js new file mode 100755 index 000000000..a899ce018 --- /dev/null +++ b/lib/materials/methods/EffectEnvMapMethod.js @@ -0,0 +1,112 @@ +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"); +/** + * EffectEnvMapMethod provides a material method to perform reflection mapping using cube maps. + */ +var EffectEnvMapMethod = (function (_super) { + __extends(EffectEnvMapMethod, _super); + /** + * Creates an EffectEnvMapMethod object. + * @param envMap The environment map containing the reflected scene. + * @param alpha The reflectivity of the surface. + */ + function EffectEnvMapMethod(envMap, alpha) { + if (alpha === void 0) { alpha = 1; } + _super.call(this); + this._cubeTexture = envMap; + this._alpha = alpha; + } + Object.defineProperty(EffectEnvMapMethod.prototype, "mask", { + /** + * An optional texture to modulate the reflectivity of the surface. + */ + get: function () { + return this._mask; + }, + set: function (value) { + if (value != this._mask || (value && this._mask && (value.hasMipmaps != this._mask.hasMipmaps || value.format != this._mask.format))) + this.iInvalidateShaderProgram(); + this._mask = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectEnvMapMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsNormals = true; + methodVO.needsView = true; + methodVO.needsUV = this._mask != null; + }; + Object.defineProperty(EffectEnvMapMethod.prototype, "envMap", { + /** + * The cubic environment map containing the reflected scene. + */ + get: function () { + return this._cubeTexture; + }, + set: function (value) { + this._cubeTexture = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectEnvMapMethod.prototype.dispose = function () { + }; + Object.defineProperty(EffectEnvMapMethod.prototype, "alpha", { + /** + * The reflectivity of the surface. + */ + get: function () { + return this._alpha; + }, + set: function (value) { + this._alpha = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectEnvMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex] = this._alpha; + stage.context.activateCubeTexture(methodVO.texturesIndex, this._cubeTexture); + if (this._mask) + stage.context.activateTexture(methodVO.texturesIndex + 1, this._mask); + }; + /** + * @inheritDoc + */ + EffectEnvMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var dataRegister = registerCache.getFreeFragmentConstant(); + var temp = registerCache.getFreeFragmentVectorTemp(); + var code = ""; + var cubeMapReg = registerCache.getFreeTextureReg(); + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = dataRegister.index * 4; + registerCache.addFragmentTempUsages(temp, 1); + var temp2 = registerCache.getFreeFragmentVectorTemp(); + // r = I - 2(I.N)*N + code += "dp3 " + temp + ".w, " + sharedRegisters.viewDirFragment + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + "add " + temp + ".w, " + temp + ".w, " + temp + ".w\n" + "mul " + temp + ".xyz, " + sharedRegisters.normalFragment + ".xyz, " + temp + ".w\n" + "sub " + temp + ".xyz, " + temp + ".xyz, " + sharedRegisters.viewDirFragment + ".xyz\n" + ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, temp) + "sub " + temp2 + ".w, " + temp + ".w, fc0.x\n" + "kil " + temp2 + ".w\n" + "sub " + temp + ", " + temp + ", " + targetReg + "\n"; + if (this._mask) + code += ShaderCompilerHelper.getTex2DSampleCode(temp2, sharedRegisters, registerCache.getFreeTextureReg(), this._mask, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) + "mul " + temp + ", " + temp2 + ", " + temp + "\n"; + code += "mul " + temp + ", " + temp + ", " + dataRegister + ".x\n" + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + registerCache.removeFragmentTempUsage(temp); + return code; + }; + return EffectEnvMapMethod; +})(EffectMethodBase); +module.exports = EffectEnvMapMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGVudm1hcG1ldGhvZC50cyJdLCJuYW1lcyI6WyJFZmZlY3RFbnZNYXBNZXRob2QiLCJFZmZlY3RFbnZNYXBNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RFbnZNYXBNZXRob2QubWFzayIsIkVmZmVjdEVudk1hcE1ldGhvZC5pSW5pdFZPIiwiRWZmZWN0RW52TWFwTWV0aG9kLmVudk1hcCIsIkVmZmVjdEVudk1hcE1ldGhvZC5kaXNwb3NlIiwiRWZmZWN0RW52TWFwTWV0aG9kLmFscGhhIiwiRWZmZWN0RW52TWFwTWV0aG9kLmlBY3RpdmF0ZSIsIkVmZmVjdEVudk1hcE1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFVQSxJQUFPLGdCQUFnQixXQUFlLHVEQUF1RCxDQUFDLENBQUM7QUFDL0YsSUFBTyxvQkFBb0IsV0FBYyx5REFBeUQsQ0FBQyxDQUFDO0FBRXBHLEFBR0E7O0dBREc7SUFDRyxrQkFBa0I7SUFBU0EsVUFBM0JBLGtCQUFrQkEsVUFBeUJBO0lBTWhEQTs7OztPQUlHQTtJQUNIQSxTQVhLQSxrQkFBa0JBLENBV1hBLE1BQXNCQSxFQUFFQSxLQUFnQkE7UUFBaEJDLHFCQUFnQkEsR0FBaEJBLFNBQWdCQTtRQUVuREEsaUJBQU9BLENBQUNBO1FBQ1JBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLE1BQU1BLENBQUNBO1FBQzNCQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxLQUFLQSxDQUFDQTtJQUVyQkEsQ0FBQ0E7SUFLREQsc0JBQVdBLG9DQUFJQTtRQUhmQTs7V0FFR0E7YUFDSEE7WUFFQ0UsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0E7UUFDbkJBLENBQUNBO2FBRURGLFVBQWdCQSxLQUFtQkE7WUFFbENFLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLElBQUlBLElBQUlBLENBQUNBLEtBQUtBLElBQUlBLENBQUNBLEtBQUtBLElBQUlBLElBQUlB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QSxDQUFDQSxrQkFBa0JBLENBQUNBLEtBQUtBLEVBQUVBLGVBQWVBLEVBQUVBLGFBQWFBLENBQUNBLGlCQUFpQkEsRUFBRUEsRUFBRUEsSUFBSUEsQ0FBQ0EsS0FBS0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxjQUFjQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxDQUFDQSxHQUM5TUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsS0FBS0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFFcERBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLFlBQVlBLEdBQUdBLE1BQU1BLEdBQ2hFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUU3REEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUU1Q0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFDRlIseUJBQUNBO0FBQURBLENBL0hBLEFBK0hDQSxFQS9IZ0MsZ0JBQWdCLEVBK0hoRDtBQUVELEFBQTRCLGlCQUFuQixrQkFBa0IsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RFbnZNYXBNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ3ViZVRleHR1cmVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9DdWJlVGV4dHVyZUJhc2VcIik7XG5pbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIEVmZmVjdEVudk1hcE1ldGhvZCBwcm92aWRlcyBhIG1hdGVyaWFsIG1ldGhvZCB0byBwZXJmb3JtIHJlZmxlY3Rpb24gbWFwcGluZyB1c2luZyBjdWJlIG1hcHMuXG4gKi9cbmNsYXNzIEVmZmVjdEVudk1hcE1ldGhvZCBleHRlbmRzIEVmZmVjdE1ldGhvZEJhc2Vcbntcblx0cHJpdmF0ZSBfY3ViZVRleHR1cmU6Q3ViZVRleHR1cmVCYXNlO1xuXHRwcml2YXRlIF9hbHBoYTpudW1iZXI7XG5cdHByaXZhdGUgX21hc2s6VGV4dHVyZTJEQmFzZTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBFZmZlY3RFbnZNYXBNZXRob2Qgb2JqZWN0LlxuXHQgKiBAcGFyYW0gZW52TWFwIFRoZSBlbnZpcm9ubWVudCBtYXAgY29udGFpbmluZyB0aGUgcmVmbGVjdGVkIHNjZW5lLlxuXHQgKiBAcGFyYW0gYWxwaGEgVGhlIHJlZmxlY3Rpdml0eSBvZiB0aGUgc3VyZmFjZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVudk1hcDpDdWJlVGV4dHVyZUJhc2UsIGFscGhhOm51bWJlciA9IDEpXG5cdHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMuX2N1YmVUZXh0dXJlID0gZW52TWFwO1xuXHRcdHRoaXMuX2FscGhhID0gYWxwaGE7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBBbiBvcHRpb25hbCB0ZXh0dXJlIHRvIG1vZHVsYXRlIHRoZSByZWZsZWN0aXZpdHkgb2YgdGhlIHN1cmZhY2UuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG1hc2soKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fbWFzaztcblx0fVxuXG5cdHB1YmxpYyBzZXQgbWFzayh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0aWYgKHZhbHVlICE9IHRoaXMuX21hc2sgfHwgKHZhbHVlICYmIHRoaXMuX21hc2sgJiYgKHZhbHVlLmhhc01pcG1hcHMgIT0gdGhpcy5fbWFzay5oYXNNaXBtYXBzIHx8IHZhbHVlLmZvcm1hdCAhPSB0aGlzLl9tYXNrLmZvcm1hdCkpKVxuXHRcdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblxuXHRcdHRoaXMuX21hc2sgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0bWV0aG9kVk8ubmVlZHNOb3JtYWxzID0gdHJ1ZTtcblx0XHRtZXRob2RWTy5uZWVkc1ZpZXcgPSB0cnVlO1xuXHRcdG1ldGhvZFZPLm5lZWRzVVYgPSB0aGlzLl9tYXNrICE9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGN1YmljIGVudmlyb25tZW50IG1hcCBjb250YWluaW5nIHRoZSByZWZsZWN0ZWQgc2NlbmUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVudk1hcCgpOkN1YmVUZXh0dXJlQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N1YmVUZXh0dXJlO1xuXHR9XG5cblx0cHVibGljIHNldCBlbnZNYXAodmFsdWU6Q3ViZVRleHR1cmVCYXNlKVxuXHR7XG5cdFx0dGhpcy5fY3ViZVRleHR1cmUgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHJlZmxlY3Rpdml0eSBvZiB0aGUgc3VyZmFjZS5cblx0ICovXG5cdHB1YmxpYyBnZXQgYWxwaGEoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9hbHBoYTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYWxwaGEodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fYWxwaGEgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhW21ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXhdID0gdGhpcy5fYWxwaGE7XG5cblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVDdWJlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4LCB0aGlzLl9jdWJlVGV4dHVyZSk7XG5cdFx0aWYgKHRoaXMuX21hc2spXG5cdFx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVUZXh0dXJlKG1ldGhvZFZPLnRleHR1cmVzSW5kZXggKyAxLCB0aGlzLl9tYXNrKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGRhdGFSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgY3ViZU1hcFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVUZXh0dXJlUmVnKCk7XG5cblx0XHRtZXRob2RWTy50ZXh0dXJlc0luZGV4ID0gY3ViZU1hcFJlZy5pbmRleDtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGF0YVJlZ2lzdGVyLmluZGV4KjQ7XG5cblx0XHRyZWdpc3RlckNhY2hlLmFkZEZyYWdtZW50VGVtcFVzYWdlcyh0ZW1wLCAxKTtcblx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cblx0XHQvLyByID0gSSAtIDIoSS5OKSpOXG5cdFx0Y29kZSArPSBcImRwMyBcIiArIHRlbXAgKyBcIi53LCBcIiArIHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50ICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRlbXAgKyBcIi53LCBcIiArIHRlbXAgKyBcIi53LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50ICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcInN1YiBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyBzaGFyZWRSZWdpc3RlcnMudmlld0RpckZyYWdtZW50ICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0U2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4Q3ViZVNhbXBsZUNvZGUodGVtcCwgY3ViZU1hcFJlZywgdGhpcy5fY3ViZVRleHR1cmUsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnVzZU1pcG1hcHBpbmcsIHRlbXApICtcblx0XHRcdFx0XCJzdWIgXCIgKyB0ZW1wMiArIFwiLncsIFwiICsgdGVtcCArIFwiLncsIGZjMC54XFxuXCIgKyAvLyAtLjVcblx0XHRcdFx0XCJraWwgXCIgKyB0ZW1wMiArIFwiLndcXG5cIiArXHQvLyB1c2VkIGZvciByZWFsIHRpbWUgcmVmbGVjdGlvbiBtYXBwaW5nIC0gaWYgYWxwaGEgaXMgbm90IDEgKG1vY2sgdGV4dHVyZSkga2lsIG91dHB1dFxuXHRcdFx0XHRcInN1YiBcIiArIHRlbXAgKyBcIiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCJcXG5cIjtcblxuXHRcdGlmICh0aGlzLl9tYXNrKVxuXHRcdFx0Y29kZSArPSBTaGFkZXJDb21waWxlckhlbHBlci5nZXRUZXgyRFNhbXBsZUNvZGUodGVtcDIsIHNoYXJlZFJlZ2lzdGVycywgcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpLCB0aGlzLl9tYXNrLCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC5yZXBlYXRUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnVzZU1pcG1hcHBpbmcpICtcblx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcDIgKyBcIiwgXCIgKyB0ZW1wICsgXCJcXG5cIjtcblxuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIGRhdGFSZWdpc3RlciArIFwiLnhcXG5cIiArXG5cdFx0XHRcdFwiYWRkIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGVtcCArIFwiXFxuXCI7XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gRWZmZWN0RW52TWFwTWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/EffectEnvMapMethod.ts b/lib/materials/methods/EffectEnvMapMethod.ts new file mode 100755 index 000000000..2571c0d45 --- /dev/null +++ b/lib/materials/methods/EffectEnvMapMethod.ts @@ -0,0 +1,146 @@ +import CubeTextureBase = require("awayjs-core/lib/textures/CubeTextureBase"); +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 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"); + +/** + * EffectEnvMapMethod provides a material method to perform reflection mapping using cube maps. + */ +class EffectEnvMapMethod extends EffectMethodBase +{ + private _cubeTexture:CubeTextureBase; + private _alpha:number; + private _mask:Texture2DBase; + + /** + * Creates an EffectEnvMapMethod object. + * @param envMap The environment map containing the reflected scene. + * @param alpha The reflectivity of the surface. + */ + constructor(envMap:CubeTextureBase, alpha:number = 1) + { + super(); + this._cubeTexture = envMap; + this._alpha = alpha; + + } + + /** + * An optional texture to modulate the reflectivity of the surface. + */ + public get mask():Texture2DBase + { + return this._mask; + } + + public set mask(value:Texture2DBase) + { + if (value != this._mask || (value && this._mask && (value.hasMipmaps != this._mask.hasMipmaps || value.format != this._mask.format))) + this.iInvalidateShaderProgram(); + + this._mask = value; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + methodVO.needsNormals = true; + methodVO.needsView = true; + methodVO.needsUV = this._mask != null; + } + + /** + * The cubic environment map containing the reflected scene. + */ + public get envMap():CubeTextureBase + { + return this._cubeTexture; + } + + public set envMap(value:CubeTextureBase) + { + this._cubeTexture = value; + } + + /** + * @inheritDoc + */ + public dispose() + { + } + + /** + * The reflectivity of the surface. + */ + public get alpha():number + { + return this._alpha; + } + + public set alpha(value:number) + { + this._alpha = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex] = this._alpha; + + ( stage.context).activateCubeTexture(methodVO.texturesIndex, this._cubeTexture); + if (this._mask) + ( stage.context).activateTexture(methodVO.texturesIndex + 1, this._mask); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var dataRegister:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var code:string = ""; + var cubeMapReg:ShaderRegisterElement = registerCache.getFreeTextureReg(); + + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = dataRegister.index*4; + + registerCache.addFragmentTempUsages(temp, 1); + var temp2:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + + // r = I - 2(I.N)*N + code += "dp3 " + temp + ".w, " + sharedRegisters.viewDirFragment + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + + "add " + temp + ".w, " + temp + ".w, " + temp + ".w\n" + + "mul " + temp + ".xyz, " + sharedRegisters.normalFragment + ".xyz, " + temp + ".w\n" + + "sub " + temp + ".xyz, " + temp + ".xyz, " + sharedRegisters.viewDirFragment + ".xyz\n" + + ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, temp) + + "sub " + temp2 + ".w, " + temp + ".w, fc0.x\n" + // -.5 + "kil " + temp2 + ".w\n" + // used for real time reflection mapping - if alpha is not 1 (mock texture) kil output + "sub " + temp + ", " + temp + ", " + targetReg + "\n"; + + if (this._mask) + code += ShaderCompilerHelper.getTex2DSampleCode(temp2, sharedRegisters, registerCache.getFreeTextureReg(), this._mask, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) + + "mul " + temp + ", " + temp2 + ", " + temp + "\n"; + + code += "mul " + temp + ", " + temp + ", " + dataRegister + ".x\n" + + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + + registerCache.removeFragmentTempUsage(temp); + + return code; + } +} + +export = EffectEnvMapMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectFogMethod.js b/lib/materials/methods/EffectFogMethod.js new file mode 100755 index 000000000..21319c6f3 --- /dev/null +++ b/lib/materials/methods/EffectFogMethod.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 EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase"); +/** + * EffectFogMethod provides a method to add distance-based fog to a material. + */ +var EffectFogMethod = (function (_super) { + __extends(EffectFogMethod, _super); + /** + * Creates a new EffectFogMethod object. + * @param minDistance The distance from which the fog starts appearing. + * @param maxDistance The distance at which the fog is densest. + * @param fogColor The colour of the fog. + */ + function EffectFogMethod(minDistance, maxDistance, fogColor) { + if (fogColor === void 0) { fogColor = 0x808080; } + _super.call(this); + this._minDistance = 0; + this._maxDistance = 1000; + this.minDistance = minDistance; + this.maxDistance = maxDistance; + this.fogColor = fogColor; + } + /** + * @inheritDoc + */ + EffectFogMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsProjection = true; + }; + /** + * @inheritDoc + */ + EffectFogMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + data[index + 3] = 1; + data[index + 6] = 0; + data[index + 7] = 0; + }; + Object.defineProperty(EffectFogMethod.prototype, "minDistance", { + /** + * The distance from which the fog starts appearing. + */ + get: function () { + return this._minDistance; + }, + set: function (value) { + this._minDistance = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFogMethod.prototype, "maxDistance", { + /** + * The distance at which the fog is densest. + */ + get: function () { + return this._maxDistance; + }, + set: function (value) { + this._maxDistance = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFogMethod.prototype, "fogColor", { + /** + * The colour of the fog. + */ + get: function () { + return this._fogColor; + }, + set: function (value /*uint*/) { + this._fogColor = value; + this._fogR = ((value >> 16) & 0xff) / 0xff; + this._fogG = ((value >> 8) & 0xff) / 0xff; + this._fogB = (value & 0xff) / 0xff; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectFogMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + data[index] = this._fogR; + data[index + 1] = this._fogG; + data[index + 2] = this._fogB; + data[index + 4] = this._minDistance; + data[index + 5] = 1 / (this._maxDistance - this._minDistance); + }; + /** + * @inheritDoc + */ + EffectFogMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var fogColor = registerCache.getFreeFragmentConstant(); + var fogData = registerCache.getFreeFragmentConstant(); + var temp = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(temp, 1); + var temp2 = registerCache.getFreeFragmentVectorTemp(); + var code = ""; + methodVO.fragmentConstantsIndex = fogColor.index * 4; + code += "sub " + temp2 + ".w, " + sharedRegisters.projectionFragment + ".z, " + fogData + ".x\n" + "mul " + temp2 + ".w, " + temp2 + ".w, " + fogData + ".y\n" + "sat " + temp2 + ".w, " + temp2 + ".w\n" + "sub " + temp + ", " + fogColor + ", " + targetReg + "\n" + "mul " + temp + ", " + temp + ", " + temp2 + ".w\n" + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; // fogRatio*(fogColor- col) + col + registerCache.removeFragmentTempUsage(temp); + return code; + }; + return EffectFogMethod; +})(EffectMethodBase); +module.exports = EffectFogMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGZvZ21ldGhvZC50cyJdLCJuYW1lcyI6WyJFZmZlY3RGb2dNZXRob2QiLCJFZmZlY3RGb2dNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RGb2dNZXRob2QuaUluaXRWTyIsIkVmZmVjdEZvZ01ldGhvZC5pSW5pdENvbnN0YW50cyIsIkVmZmVjdEZvZ01ldGhvZC5taW5EaXN0YW5jZSIsIkVmZmVjdEZvZ01ldGhvZC5tYXhEaXN0YW5jZSIsIkVmZmVjdEZvZ01ldGhvZC5mb2dDb2xvciIsIkVmZmVjdEZvZ01ldGhvZC5pQWN0aXZhdGUiLCJFZmZlY3RGb2dNZXRob2QuaUdldEZyYWdtZW50Q29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBT0EsSUFBTyxnQkFBZ0IsV0FBZSx1REFBdUQsQ0FBQyxDQUFDO0FBRS9GLEFBR0E7O0dBREc7SUFDRyxlQUFlO0lBQVNBLFVBQXhCQSxlQUFlQSxVQUF5QkE7SUFTN0NBOzs7OztPQUtHQTtJQUNIQSxTQWZLQSxlQUFlQSxDQWVSQSxXQUFrQkEsRUFBRUEsV0FBa0JBLEVBQUVBLFFBQW1DQTtRQUFuQ0Msd0JBQW1DQSxHQUFuQ0EsbUJBQW1DQTtRQUV0RkEsaUJBQU9BLENBQUNBO1FBZkRBLGlCQUFZQSxHQUFVQSxDQUFDQSxDQUFDQTtRQUN4QkEsaUJBQVlBLEdBQVVBLElBQUlBLENBQUNBO1FBZWxDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxXQUFXQSxDQUFDQTtRQUMvQkEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsV0FBV0EsQ0FBQ0E7UUFDL0JBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLFFBQVFBLENBQUNBO0lBQzFCQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsaUNBQU9BLEdBQWRBLFVBQWVBLFlBQWlDQSxFQUFFQSxRQUFpQkE7UUFFbEVFLFFBQVFBLENBQUNBLGVBQWVBLEdBQUdBLElBQUlBLENBQUNBO0lBQ2pDQSxDQUFDQTtJQUVERjs7T0FFR0E7SUFD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QUNuREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsRUFBRUEsaUNBQWlDQTtRQUUvRkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUU1Q0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFDRlIsc0JBQUNBO0FBQURBLENBM0hBLEFBMkhDQSxFQTNINkIsZ0JBQWdCLEVBMkg3QztBQUVELEFBQXlCLGlCQUFoQixlQUFlLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0Rm9nTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IEVmZmVjdE1ldGhvZEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0VmZmVjdE1ldGhvZEJhc2VcIik7XG5cbi8qKlxuICogRWZmZWN0Rm9nTWV0aG9kIHByb3ZpZGVzIGEgbWV0aG9kIHRvIGFkZCBkaXN0YW5jZS1iYXNlZCBmb2cgdG8gYSBtYXRlcmlhbC5cbiAqL1xuY2xhc3MgRWZmZWN0Rm9nTWV0aG9kIGV4dGVuZHMgRWZmZWN0TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9taW5EaXN0YW5jZTpudW1iZXIgPSAwO1xuXHRwcml2YXRlIF9tYXhEaXN0YW5jZTpudW1iZXIgPSAxMDAwO1xuXHRwcml2YXRlIF9mb2dDb2xvcjpudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX2ZvZ1I6bnVtYmVyO1xuXHRwcml2YXRlIF9mb2dHOm51bWJlcjtcblx0cHJpdmF0ZSBfZm9nQjpudW1iZXI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgRWZmZWN0Rm9nTWV0aG9kIG9iamVjdC5cblx0ICogQHBhcmFtIG1pbkRpc3RhbmNlIFRoZSBkaXN0YW5jZSBmcm9tIHdoaWNoIHRoZSBmb2cgc3RhcnRzIGFwcGVhcmluZy5cblx0ICogQHBhcmFtIG1heERpc3RhbmNlIFRoZSBkaXN0YW5jZSBhdCB3aGljaCB0aGUgZm9nIGlzIGRlbnNlc3QuXG5cdCAqIEBwYXJhbSBmb2dDb2xvciBUaGUgY29sb3VyIG9mIHRoZSBmb2cuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihtaW5EaXN0YW5jZTpudW1iZXIsIG1heERpc3RhbmNlOm51bWJlciwgZm9nQ29sb3I6bnVtYmVyIC8qdWludCovID0gMHg4MDgwODApXG5cdHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMubWluRGlzdGFuY2UgPSBtaW5EaXN0YW5jZTtcblx0XHR0aGlzLm1heERpc3RhbmNlID0gbWF4RGlzdGFuY2U7XG5cdFx0dGhpcy5mb2dDb2xvciA9IGZvZ0NvbG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRWTyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0bWV0aG9kVk8ubmVlZHNQcm9qZWN0aW9uID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHRkYXRhW2luZGV4ICsgM10gPSAxO1xuXHRcdGRhdGFbaW5kZXggKyA2XSA9IDA7XG5cdFx0ZGF0YVtpbmRleCArIDddID0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgZGlzdGFuY2UgZnJvbSB3aGljaCB0aGUgZm9nIHN0YXJ0cyBhcHBlYXJpbmcuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG1pbkRpc3RhbmNlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fbWluRGlzdGFuY2U7XG5cdH1cblxuXHRwdWJsaWMgc2V0IG1pbkRpc3RhbmNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX21pbkRpc3RhbmNlID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGRpc3RhbmNlIGF0IHdoaWNoIHRoZSBmb2cgaXMgZGVuc2VzdC5cblx0ICovXG5cdHB1YmxpYyBnZXQgbWF4RGlzdGFuY2UoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9tYXhEaXN0YW5jZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgbWF4RGlzdGFuY2UodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fbWF4RGlzdGFuY2UgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgY29sb3VyIG9mIHRoZSBmb2cuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGZvZ0NvbG9yKCk6bnVtYmVyIC8qdWludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZm9nQ29sb3I7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGZvZ0NvbG9yKHZhbHVlOm51bWJlci8qdWludCovKVxuXHR7XG5cdFx0dGhpcy5fZm9nQ29sb3IgPSB2YWx1ZTtcblx0XHR0aGlzLl9mb2dSID0gKCh2YWx1ZSA+PiAxNikgJiAweGZmKS8weGZmO1xuXHRcdHRoaXMuX2ZvZ0cgPSAoKHZhbHVlID4+IDgpICYgMHhmZikvMHhmZjtcblx0XHR0aGlzLl9mb2dCID0gKHZhbHVlICYgMHhmZikvMHhmZjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGRhdGFbaW5kZXhdID0gdGhpcy5fZm9nUjtcblx0XHRkYXRhW2luZGV4ICsgMV0gPSB0aGlzLl9mb2dHO1xuXHRcdGRhdGFbaW5kZXggKyAyXSA9IHRoaXMuX2ZvZ0I7XG5cdFx0ZGF0YVtpbmRleCArIDRdID0gdGhpcy5fbWluRGlzdGFuY2U7XG5cdFx0ZGF0YVtpbmRleCArIDVdID0gMS8odGhpcy5fbWF4RGlzdGFuY2UgLSB0aGlzLl9taW5EaXN0YW5jZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBmb2dDb2xvcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dmFyIGZvZ0RhdGE6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdHZhciB0ZW1wMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSBmb2dDb2xvci5pbmRleCo0O1xuXG5cdFx0Y29kZSArPSBcInN1YiBcIiArIHRlbXAyICsgXCIudywgXCIgKyBzaGFyZWRSZWdpc3RlcnMucHJvamVjdGlvbkZyYWdtZW50ICsgXCIueiwgXCIgKyBmb2dEYXRhICsgXCIueFxcblwiICtcblx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wMiArIFwiLncsIFwiICsgdGVtcDIgKyBcIi53LCBcIiArIGZvZ0RhdGEgKyBcIi55XFxuXCIgK1xuXHRcdFx0XHRcInNhdCBcIiArIHRlbXAyICsgXCIudywgXCIgKyB0ZW1wMiArIFwiLndcXG5cIiArXG5cdFx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLCBcIiArIGZvZ0NvbG9yICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCJcXG5cIiArIC8vIChmb2dDb2xvci0gY29sKVxuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcDIgKyBcIi53XFxuXCIgKyAvLyAoZm9nQ29sb3ItIGNvbCkqZm9nUmF0aW9cblx0XHRcdFx0XCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0ZW1wICsgXCJcXG5cIjsgLy8gZm9nUmF0aW8qKGZvZ0NvbG9yLSBjb2wpICsgY29sXG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gRWZmZWN0Rm9nTWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/EffectFogMethod.ts b/lib/materials/methods/EffectFogMethod.ts new file mode 100644 index 000000000..a6be9b1d1 --- /dev/null +++ b/lib/materials/methods/EffectFogMethod.ts @@ -0,0 +1,138 @@ +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 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"); + +/** + * EffectFogMethod provides a method to add distance-based fog to a material. + */ +class EffectFogMethod extends EffectMethodBase +{ + private _minDistance:number = 0; + private _maxDistance:number = 1000; + private _fogColor:number /*uint*/; + private _fogR:number; + private _fogG:number; + private _fogB:number; + + /** + * Creates a new EffectFogMethod object. + * @param minDistance The distance from which the fog starts appearing. + * @param maxDistance The distance at which the fog is densest. + * @param fogColor The colour of the fog. + */ + constructor(minDistance:number, maxDistance:number, fogColor:number /*uint*/ = 0x808080) + { + super(); + this.minDistance = minDistance; + this.maxDistance = maxDistance; + this.fogColor = fogColor; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + methodVO.needsProjection = true; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + var data:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + data[index + 3] = 1; + data[index + 6] = 0; + data[index + 7] = 0; + } + + /** + * The distance from which the fog starts appearing. + */ + public get minDistance():number + { + return this._minDistance; + } + + public set minDistance(value:number) + { + this._minDistance = value; + } + + /** + * The distance at which the fog is densest. + */ + public get maxDistance():number + { + return this._maxDistance; + } + + public set maxDistance(value:number) + { + this._maxDistance = value; + } + + /** + * The colour of the fog. + */ + public get fogColor():number /*uint*/ + { + return this._fogColor; + } + + public set fogColor(value:number/*uint*/) + { + this._fogColor = value; + this._fogR = ((value >> 16) & 0xff)/0xff; + this._fogG = ((value >> 8) & 0xff)/0xff; + this._fogB = (value & 0xff)/0xff; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var data:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + data[index] = this._fogR; + data[index + 1] = this._fogG; + data[index + 2] = this._fogB; + data[index + 4] = this._minDistance; + data[index + 5] = 1/(this._maxDistance - this._minDistance); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var fogColor:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var fogData:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(temp, 1); + var temp2:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var code:string = ""; + methodVO.fragmentConstantsIndex = fogColor.index*4; + + code += "sub " + temp2 + ".w, " + sharedRegisters.projectionFragment + ".z, " + fogData + ".x\n" + + "mul " + temp2 + ".w, " + temp2 + ".w, " + fogData + ".y\n" + + "sat " + temp2 + ".w, " + temp2 + ".w\n" + + "sub " + temp + ", " + fogColor + ", " + targetReg + "\n" + // (fogColor- col) + "mul " + temp + ", " + temp + ", " + temp2 + ".w\n" + // (fogColor- col)*fogRatio + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; // fogRatio*(fogColor- col) + col + + registerCache.removeFragmentTempUsage(temp); + + return code; + } +} + +export = EffectFogMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectFresnelEnvMapMethod.js b/lib/materials/methods/EffectFresnelEnvMapMethod.js new file mode 100755 index 000000000..3b64df18e --- /dev/null +++ b/lib/materials/methods/EffectFresnelEnvMapMethod.js @@ -0,0 +1,155 @@ +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"); +/** + * EffectFresnelEnvMapMethod provides a method to add fresnel-based reflectivity to an object using cube maps, which gets + * stronger as the viewing angle becomes more grazing. + */ +var EffectFresnelEnvMapMethod = (function (_super) { + __extends(EffectFresnelEnvMapMethod, _super); + /** + * Creates a new EffectFresnelEnvMapMethod object. + * + * @param envMap The environment map containing the reflected scene. + * @param alpha The reflectivity of the material. + */ + function EffectFresnelEnvMapMethod(envMap, alpha) { + if (alpha === void 0) { alpha = 1; } + _super.call(this); + this._fresnelPower = 5; + this._normalReflectance = 0; + this._cubeTexture = envMap; + this._alpha = alpha; + } + /** + * @inheritDoc + */ + EffectFresnelEnvMapMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsNormals = true; + methodVO.needsView = true; + methodVO.needsUV = this._mask != null; + }; + /** + * @inheritDoc + */ + EffectFresnelEnvMapMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 3] = 1; + }; + Object.defineProperty(EffectFresnelEnvMapMethod.prototype, "mask", { + /** + * An optional texture to modulate the reflectivity of the surface. + */ + get: function () { + return this._mask; + }, + set: function (value) { + if (Boolean(value) != Boolean(this._mask) || (value && this._mask && (value.hasMipmaps != this._mask.hasMipmaps || value.format != this._mask.format))) { + this.iInvalidateShaderProgram(); + } + this._mask = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFresnelEnvMapMethod.prototype, "fresnelPower", { + /** + * The power used in the Fresnel equation. Higher values make the fresnel effect more pronounced. Defaults to 5. + */ + get: function () { + return this._fresnelPower; + }, + set: function (value) { + this._fresnelPower = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFresnelEnvMapMethod.prototype, "envMap", { + /** + * The cubic environment map containing the reflected scene. + */ + get: function () { + return this._cubeTexture; + }, + set: function (value) { + this._cubeTexture = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFresnelEnvMapMethod.prototype, "alpha", { + /** + * The reflectivity of the surface. + */ + get: function () { + return this._alpha; + }, + set: function (value) { + this._alpha = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectFresnelEnvMapMethod.prototype, "normalReflectance", { + /** + * The minimum amount of reflectance, ie the reflectance when the view direction is normal to the surface or light direction. + */ + get: function () { + return this._normalReflectance; + }, + set: function (value) { + this._normalReflectance = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectFresnelEnvMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + data[index] = this._alpha; + data[index + 1] = this._normalReflectance; + data[index + 2] = this._fresnelPower; + stage.context.activateCubeTexture(methodVO.texturesIndex, this._cubeTexture); + if (this._mask) + stage.context.activateTexture(methodVO.texturesIndex + 1, this._mask); + }; + /** + * @inheritDoc + */ + EffectFresnelEnvMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var dataRegister = registerCache.getFreeFragmentConstant(); + var temp = registerCache.getFreeFragmentVectorTemp(); + var code = ""; + var cubeMapReg = registerCache.getFreeTextureReg(); + var viewDirReg = sharedRegisters.viewDirFragment; + var normalReg = sharedRegisters.normalFragment; + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = dataRegister.index * 4; + registerCache.addFragmentTempUsages(temp, 1); + var temp2 = registerCache.getFreeFragmentVectorTemp(); + // r = V - 2(V.N)*N + code += "dp3 " + temp + ".w, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + "add " + temp + ".w, " + temp + ".w, " + temp + ".w\n" + "mul " + temp + ".xyz, " + normalReg + ".xyz, " + temp + ".w\n" + "sub " + temp + ".xyz, " + temp + ".xyz, " + viewDirReg + ".xyz\n" + ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, temp) + "sub " + temp2 + ".w, " + temp + ".w, fc0.x\n" + "kil " + temp2 + ".w\n" + "sub " + temp + ", " + temp + ", " + targetReg + "\n"; + // calculate fresnel term + code += "dp3 " + viewDirReg + ".w, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + "sub " + viewDirReg + ".w, " + dataRegister + ".w, " + viewDirReg + ".w\n" + "pow " + viewDirReg + ".w, " + viewDirReg + ".w, " + dataRegister + ".z\n" + "sub " + normalReg + ".w, " + dataRegister + ".w, " + viewDirReg + ".w\n" + "mul " + normalReg + ".w, " + dataRegister + ".y, " + normalReg + ".w\n" + "add " + viewDirReg + ".w, " + viewDirReg + ".w, " + normalReg + ".w\n" + "mul " + viewDirReg + ".w, " + dataRegister + ".x, " + viewDirReg + ".w\n"; + if (this._mask) { + var maskReg = registerCache.getFreeTextureReg(); + code += ShaderCompilerHelper.getTex2DSampleCode(temp2, sharedRegisters, maskReg, this._mask, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) + "mul " + viewDirReg + ".w, " + temp2 + ".x, " + viewDirReg + ".w\n"; + } + // blend + code += "mul " + temp + ", " + temp + ", " + viewDirReg + ".w\n" + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + registerCache.removeFragmentTempUsage(temp); + return code; + }; + return EffectFresnelEnvMapMethod; +})(EffectMethodBase); +module.exports = EffectFresnelEnvMapMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGZyZXNuZWxlbnZtYXBtZXRob2QudHMiXSwibmFtZXMiOlsiRWZmZWN0RnJlc25lbEVudk1hcE1ldGhvZCIsIkVmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kLmlJbml0Vk8iLCJFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRWZmZWN0RnJlc25lbEVudk1hcE1ldGhvZC5tYXNrIiwiRWZmZWN0RnJlc25lbEVudk1hcE1ldGhvZC5mcmVzbmVsUG93ZXIiLCJFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kLmVudk1hcCIsIkVmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2QuYWxwaGEiLCJFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kLm5vcm1hbFJlZmxlY3RhbmNlIiwiRWZmZWN0RnJlc25lbEVudk1hcE1ldGhvZC5pQWN0aXZhdGUiLCJFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kLmlHZXRGcmFnbWVudENvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVVBLElBQU8sZ0JBQWdCLFdBQWUsdURBQXVELENBQUMsQ0FBQztBQUMvRixJQUFPLG9CQUFvQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFcEcsQUFJQTs7O0dBREc7SUFDRyx5QkFBeUI7SUFBU0EsVUFBbENBLHlCQUF5QkEsVUFBeUJBO0lBUXZEQTs7Ozs7T0FLR0E7SUFDSEEsU0FkS0EseUJBQXlCQSxDQWNsQkEsTUFBc0JBLEVBQUVBLEtBQWdCQTtRQUFoQkMscUJBQWdCQSxHQUFoQkEsU0FBZ0JBO1FBRW5EQSxpQkFBT0EsQ0FBQ0E7UUFiREEsa0JBQWFBLEdBQVVBLENBQUNBLENBQUNBO1FBQ3pCQSx1QkFBa0JBLEdBQVVBLENBQUNBLENBQUNBO1FBY3JDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUMzQkEsSUFBSUEsQ0FBQ0EsTUFB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QUFPQSxFQUFFQSxJQUFJQSxDQUFDQSxLQUFLQSxFQUFFQSxZQUFZQSxDQUFDQSxpQkFBaUJBLEVBQUVBLFlBQVlBLENBQUNBLGNBQWNBLEVBQUVBLFlBQVlBLENBQUNBLGFBQWFBLENBQUNBLEdBQ3BMQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUN0RUEsQ0FBQ0E7UUFFREEsQUFDQUEsUUFEUUE7UUFDUkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsVUFBVUEsR0FBR0EsTUFBTUEsR0FDOURBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBO1FBRTdEQSxhQUFhQSxDQUFDQSx1QkFBdUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1FBRTVDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUNGVixnQ0FBQ0E7QUFBREEsQ0FuTEEsQUFtTENBLEVBbkx1QyxnQkFBZ0IsRUFtTHZEO0FBRUQsQUFBbUMsaUJBQTFCLHlCQUF5QixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0VmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ3ViZVRleHR1cmVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9DdWJlVGV4dHVyZUJhc2VcIik7XG5pbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIEVmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2QgcHJvdmlkZXMgYSBtZXRob2QgdG8gYWRkIGZyZXNuZWwtYmFzZWQgcmVmbGVjdGl2aXR5IHRvIGFuIG9iamVjdCB1c2luZyBjdWJlIG1hcHMsIHdoaWNoIGdldHNcbiAqIHN0cm9uZ2VyIGFzIHRoZSB2aWV3aW5nIGFuZ2xlIGJlY29tZXMgbW9yZSBncmF6aW5nLlxuICovXG5jbGFzcyBFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kIGV4dGVuZHMgRWZmZWN0TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9jdWJlVGV4dHVyZTpDdWJlVGV4dHVyZUJhc2U7XG5cdHByaXZhdGUgX2ZyZXNuZWxQb3dlcjpudW1iZXIgPSA1O1xuXHRwcml2YXRlIF9ub3JtYWxSZWZsZWN0YW5jZTpudW1iZXIgPSAwO1xuXHRwcml2YXRlIF9hbHBoYTpudW1iZXI7XG5cdHByaXZhdGUgX21hc2s6VGV4dHVyZTJEQmFzZTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5FZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBlbnZNYXAgVGhlIGVudmlyb25tZW50IG1hcCBjb250YWluaW5nIHRoZSByZWZsZWN0ZWQgc2NlbmUuXG5cdCAqIEBwYXJhbSBhbHBoYSBUaGUgcmVmbGVjdGl2aXR5IG9mIHRoZSBtYXRlcmlhbC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVudk1hcDpDdWJlVGV4dHVyZUJhc2UsIGFscGhhOm51bWJlciA9IDEpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0dGhpcy5fY3ViZVRleHR1cmUgPSBlbnZNYXA7XG5cdFx0dGhpcy5fYWxwaGEgPSBhbHBoYTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0bWV0aG9kVk8ubmVlZHNOb3JtYWxzID0gdHJ1ZTtcblx0XHRtZXRob2RWTy5uZWVkc1ZpZXcgPSB0cnVlO1xuXHRcdG1ldGhvZFZPLm5lZWRzVVYgPSB0aGlzLl9tYXNrICE9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGFbbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleCArIDNdID0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbiBvcHRpb25hbCB0ZXh0dXJlIHRvIG1vZHVsYXRlIHRoZSByZWZsZWN0aXZpdHkgb2YgdGhlIHN1cmZhY2UuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG1hc2soKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fbWFzaztcblx0fVxuXG5cdHB1YmxpYyBzZXQgbWFzayh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0aWYgKEJvb2xlYW4odmFsdWUpICE9IEJvb2xlYW4odGhpcy5fbWFzaykgfHxcblx0XHRcdCh2YWx1ZSAmJiB0aGlzLl9tYXNrICYmICh2YWx1ZS5oYXNNaXBtYXBzICE9IHRoaXMuX21hc2suaGFzTWlwbWFwcyB8fCB2YWx1ZS5mb3JtYXQgIT0gdGhpcy5fbWFzay5mb3JtYXQpKSkge1xuXHRcdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0XHR9XG5cdFx0dGhpcy5fbWFzayA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBwb3dlciB1c2VkIGluIHRoZSBGcmVzbmVsIGVxdWF0aW9uLiBIaWdoZXIgdmFsdWVzIG1ha2UgdGhlIGZyZXNuZWwgZWZmZWN0IG1vcmUgcHJvbm91bmNlZC4gRGVmYXVsdHMgdG8gNS5cblx0ICovXG5cdHB1YmxpYyBnZXQgZnJlc25lbFBvd2VyKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZnJlc25lbFBvd2VyO1xuXHR9XG5cblx0cHVibGljIHNldCBmcmVzbmVsUG93ZXIodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fZnJlc25lbFBvd2VyID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGN1YmljIGVudmlyb25tZW50IG1hcCBjb250YWluaW5nIHRoZSByZWZsZWN0ZWQgc2NlbmUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVudk1hcCgpOkN1YmVUZXh0dXJlQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2N1YmVUZXh0dXJlO1xuXHR9XG5cblx0cHVibGljIHNldCBlbnZNYXAodmFsdWU6Q3ViZVRleHR1cmVCYXNlKVxuXHR7XG5cdFx0dGhpcy5fY3ViZVRleHR1cmUgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgcmVmbGVjdGl2aXR5IG9mIHRoZSBzdXJmYWNlLlxuXHQgKi9cblx0cHVibGljIGdldCBhbHBoYSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2FscGhhO1xuXHR9XG5cblx0cHVibGljIHNldCBhbHBoYSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9hbHBoYSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBtaW5pbXVtIGFtb3VudCBvZiByZWZsZWN0YW5jZSwgaWUgdGhlIHJlZmxlY3RhbmNlIHdoZW4gdGhlIHZpZXcgZGlyZWN0aW9uIGlzIG5vcm1hbCB0byB0aGUgc3VyZmFjZSBvciBsaWdodCBkaXJlY3Rpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG5vcm1hbFJlZmxlY3RhbmNlKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fbm9ybWFsUmVmbGVjdGFuY2U7XG5cdH1cblxuXHRwdWJsaWMgc2V0IG5vcm1hbFJlZmxlY3RhbmNlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX25vcm1hbFJlZmxlY3RhbmNlID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHRkYXRhW2luZGV4XSA9IHRoaXMuX2FscGhhO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IHRoaXMuX25vcm1hbFJlZmxlY3RhbmNlO1xuXHRcdGRhdGFbaW5kZXggKyAyXSA9IHRoaXMuX2ZyZXNuZWxQb3dlcjtcblxuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZUN1YmVUZXh0dXJlKG1ldGhvZFZPLnRleHR1cmVzSW5kZXgsIHRoaXMuX2N1YmVUZXh0dXJlKTtcblxuXHRcdGlmICh0aGlzLl9tYXNrKVxuXHRcdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4ICsgMSwgdGhpcy5fbWFzayk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBkYXRhUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIGN1YmVNYXBSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciB2aWV3RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQ7XG5cdFx0dmFyIG5vcm1hbFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBzaGFyZWRSZWdpc3RlcnMubm9ybWFsRnJhZ21lbnQ7XG5cblx0XHRtZXRob2RWTy50ZXh0dXJlc0luZGV4ID0gY3ViZU1hcFJlZy5pbmRleDtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGF0YVJlZ2lzdGVyLmluZGV4KjQ7XG5cblx0XHRyZWdpc3RlckNhY2hlLmFkZEZyYWdtZW50VGVtcFVzYWdlcyh0ZW1wLCAxKTtcblx0XHR2YXIgdGVtcDI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cblx0XHQvLyByID0gViAtIDIoVi5OKSpOXG5cdFx0Y29kZSArPSBcImRwMyBcIiArIHRlbXAgKyBcIi53LCBcIiArIHZpZXdEaXJSZWcgKyBcIi54eXosIFwiICsgbm9ybWFsUmVnICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRlbXAgKyBcIi53LCBcIiArIHRlbXAgKyBcIi53LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgbm9ybWFsUmVnICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcInN1YiBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyB2aWV3RGlyUmVnICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0U2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4Q3ViZVNhbXBsZUNvZGUodGVtcCwgY3ViZU1hcFJlZywgdGhpcy5fY3ViZVRleHR1cmUsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnVzZU1pcG1hcHBpbmcsIHRlbXApICtcblx0XHRcdFx0XCJzdWIgXCIgKyB0ZW1wMiArIFwiLncsIFwiICsgdGVtcCArIFwiLncsIGZjMC54XFxuXCIgKyAgICAgICAgICAgICAgIFx0Ly8gLS41XG5cdFx0XHRcdFwia2lsIFwiICsgdGVtcDIgKyBcIi53XFxuXCIgK1x0Ly8gdXNlZCBmb3IgcmVhbCB0aW1lIHJlZmxlY3Rpb24gbWFwcGluZyAtIGlmIGFscGhhIGlzIG5vdCAxIChtb2NrIHRleHR1cmUpIGtpbCBvdXRwdXRcblx0XHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIHRhcmdldFJlZyArIFwiXFxuXCI7XG5cblx0XHQvLyBjYWxjdWxhdGUgZnJlc25lbCB0ZXJtXG5cdFx0Y29kZSArPSBcImRwMyBcIiArIHZpZXdEaXJSZWcgKyBcIi53LCBcIiArIHZpZXdEaXJSZWcgKyBcIi54eXosIFwiICsgbm9ybWFsUmVnICsgXCIueHl6XFxuXCIgKyAgLy8gZG90KFYsIEgpXG5cdFx0XHRcdFwic3ViIFwiICsgdmlld0RpclJlZyArIFwiLncsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIudywgXCIgKyB2aWV3RGlyUmVnICsgXCIud1xcblwiICsgICAgICAgLy8gYmFzZSA9IDEtZG90KFYsIEgpXG5cdFx0XHRcdFwicG93IFwiICsgdmlld0RpclJlZyArIFwiLncsIFwiICsgdmlld0RpclJlZyArIFwiLncsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIuelxcblwiICsgICAgICAgLy8gZXhwID0gcG93KGJhc2UsIDUpXG5cdFx0XHRcdFwic3ViIFwiICsgbm9ybWFsUmVnICsgXCIudywgXCIgKyBkYXRhUmVnaXN0ZXIgKyBcIi53LCBcIiArIHZpZXdEaXJSZWcgKyBcIi53XFxuXCIgKyAgICAgICAgLy8gMSAtIGV4cFxuXHRcdFx0XHRcIm11bCBcIiArIG5vcm1hbFJlZyArIFwiLncsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIueSwgXCIgKyBub3JtYWxSZWcgKyBcIi53XFxuXCIgKyAgICAgICAgIC8vIGYwKigxIC0gZXhwKVxuXHRcdFx0XHRcImFkZCBcIiArIHZpZXdEaXJSZWcgKyBcIi53LCBcIiArIHZpZXdEaXJSZWcgKyBcIi53LCBcIiArIG5vcm1hbFJlZyArIFwiLndcXG5cIiArICAgICAgICAgIC8vIGV4cCArIGYwKigxIC0gZXhwKVxuXG5cdFx0XHRcdC8vIHRvdGFsIGFscGhhXG5cdFx0XHRcdFwibXVsIFwiICsgdmlld0RpclJlZyArIFwiLncsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIueCwgXCIgKyB2aWV3RGlyUmVnICsgXCIud1xcblwiO1xuXG5cdFx0aWYgKHRoaXMuX21hc2spIHtcblx0XHRcdHZhciBtYXNrUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblx0XHRcdGNvZGUgKz0gU2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4MkRTYW1wbGVDb2RlKHRlbXAyLCBzaGFyZWRSZWdpc3RlcnMsIG1hc2tSZWcsIHRoaXMuX21hc2ssIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnJlcGVhdFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZykgK1xuXHRcdFx0XHRcIm11bCBcIiArIHZpZXdEaXJSZWcgKyBcIi53LCBcIiArIHRlbXAyICsgXCIueCwgXCIgKyB2aWV3RGlyUmVnICsgXCIud1xcblwiO1xuXHRcdH1cblxuXHRcdC8vIGJsZW5kXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdmlld0RpclJlZyArIFwiLndcXG5cIiArXG5cdFx0XHRcdFwiYWRkIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGVtcCArIFwiXFxuXCI7XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHRlbXApO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gRWZmZWN0RnJlc25lbEVudk1hcE1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/EffectFresnelEnvMapMethod.ts b/lib/materials/methods/EffectFresnelEnvMapMethod.ts new file mode 100644 index 000000000..fe58a40fd --- /dev/null +++ b/lib/materials/methods/EffectFresnelEnvMapMethod.ts @@ -0,0 +1,199 @@ +import CubeTextureBase = require("awayjs-core/lib/textures/CubeTextureBase"); +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 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"); + +/** + * EffectFresnelEnvMapMethod provides a method to add fresnel-based reflectivity to an object using cube maps, which gets + * stronger as the viewing angle becomes more grazing. + */ +class EffectFresnelEnvMapMethod extends EffectMethodBase +{ + private _cubeTexture:CubeTextureBase; + private _fresnelPower:number = 5; + private _normalReflectance:number = 0; + private _alpha:number; + private _mask:Texture2DBase; + + /** + * Creates a new EffectFresnelEnvMapMethod object. + * + * @param envMap The environment map containing the reflected scene. + * @param alpha The reflectivity of the material. + */ + constructor(envMap:CubeTextureBase, alpha:number = 1) + { + super(); + + this._cubeTexture = envMap; + this._alpha = alpha; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + methodVO.needsNormals = true; + methodVO.needsView = true; + methodVO.needsUV = this._mask != null; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 3] = 1; + } + + /** + * An optional texture to modulate the reflectivity of the surface. + */ + public get mask():Texture2DBase + { + return this._mask; + } + + public set mask(value:Texture2DBase) + { + if (Boolean(value) != Boolean(this._mask) || + (value && this._mask && (value.hasMipmaps != this._mask.hasMipmaps || value.format != this._mask.format))) { + this.iInvalidateShaderProgram(); + } + this._mask = value; + } + + /** + * The power used in the Fresnel equation. Higher values make the fresnel effect more pronounced. Defaults to 5. + */ + public get fresnelPower():number + { + return this._fresnelPower; + } + + public set fresnelPower(value:number) + { + this._fresnelPower = value; + } + + /** + * The cubic environment map containing the reflected scene. + */ + public get envMap():CubeTextureBase + { + return this._cubeTexture; + } + + public set envMap(value:CubeTextureBase) + { + this._cubeTexture = value; + } + + /** + * The reflectivity of the surface. + */ + public get alpha():number + { + return this._alpha; + } + + public set alpha(value:number) + { + this._alpha = value; + } + + /** + * The minimum amount of reflectance, ie the reflectance when the view direction is normal to the surface or light direction. + */ + public get normalReflectance():number + { + return this._normalReflectance; + } + + public set normalReflectance(value:number) + { + this._normalReflectance = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var data:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + data[index] = this._alpha; + data[index + 1] = this._normalReflectance; + data[index + 2] = this._fresnelPower; + + ( stage.context).activateCubeTexture(methodVO.texturesIndex, this._cubeTexture); + + if (this._mask) + ( stage.context).activateTexture(methodVO.texturesIndex + 1, this._mask); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var dataRegister:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var code:string = ""; + var cubeMapReg:ShaderRegisterElement = registerCache.getFreeTextureReg(); + var viewDirReg:ShaderRegisterElement = sharedRegisters.viewDirFragment; + var normalReg:ShaderRegisterElement = sharedRegisters.normalFragment; + + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = dataRegister.index*4; + + registerCache.addFragmentTempUsages(temp, 1); + var temp2:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + + // r = V - 2(V.N)*N + code += "dp3 " + temp + ".w, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + + "add " + temp + ".w, " + temp + ".w, " + temp + ".w\n" + + "mul " + temp + ".xyz, " + normalReg + ".xyz, " + temp + ".w\n" + + "sub " + temp + ".xyz, " + temp + ".xyz, " + viewDirReg + ".xyz\n" + + ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._cubeTexture, shaderObject.useSmoothTextures, shaderObject.useMipmapping, temp) + + "sub " + temp2 + ".w, " + temp + ".w, fc0.x\n" + // -.5 + "kil " + temp2 + ".w\n" + // used for real time reflection mapping - if alpha is not 1 (mock texture) kil output + "sub " + temp + ", " + temp + ", " + targetReg + "\n"; + + // calculate fresnel term + code += "dp3 " + viewDirReg + ".w, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + // dot(V, H) + "sub " + viewDirReg + ".w, " + dataRegister + ".w, " + viewDirReg + ".w\n" + // base = 1-dot(V, H) + "pow " + viewDirReg + ".w, " + viewDirReg + ".w, " + dataRegister + ".z\n" + // exp = pow(base, 5) + "sub " + normalReg + ".w, " + dataRegister + ".w, " + viewDirReg + ".w\n" + // 1 - exp + "mul " + normalReg + ".w, " + dataRegister + ".y, " + normalReg + ".w\n" + // f0*(1 - exp) + "add " + viewDirReg + ".w, " + viewDirReg + ".w, " + normalReg + ".w\n" + // exp + f0*(1 - exp) + + // total alpha + "mul " + viewDirReg + ".w, " + dataRegister + ".x, " + viewDirReg + ".w\n"; + + if (this._mask) { + var maskReg:ShaderRegisterElement = registerCache.getFreeTextureReg(); + code += ShaderCompilerHelper.getTex2DSampleCode(temp2, sharedRegisters, maskReg, this._mask, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping) + + "mul " + viewDirReg + ".w, " + temp2 + ".x, " + viewDirReg + ".w\n"; + } + + // blend + code += "mul " + temp + ", " + temp + ", " + viewDirReg + ".w\n" + + "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + + registerCache.removeFragmentTempUsage(temp); + + return code; + } +} + +export = EffectFresnelEnvMapMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectLightMapMethod.js b/lib/materials/methods/EffectLightMapMethod.js new file mode 100755 index 000000000..b0363032e --- /dev/null +++ b/lib/materials/methods/EffectLightMapMethod.js @@ -0,0 +1,112 @@ +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"); +/** + * EffectLightMapMethod provides a method that allows applying a light map texture to the calculated pixel colour. + * It is different from DiffuseLightMapMethod in that the latter only modulates the diffuse shading value rather + * than the whole pixel colour. + */ +var EffectLightMapMethod = (function (_super) { + __extends(EffectLightMapMethod, _super); + /** + * Creates a new EffectLightMapMethod object. + * + * @param texture 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. + */ + function EffectLightMapMethod(texture, blendMode, useSecondaryUV) { + if (blendMode === void 0) { blendMode = "multiply"; } + if (useSecondaryUV === void 0) { useSecondaryUV = false; } + _super.call(this); + this._useSecondaryUV = useSecondaryUV; + this._texture = texture; + this.blendMode = blendMode; + } + /** + * @inheritDoc + */ + EffectLightMapMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsUV = !this._useSecondaryUV; + methodVO.needsSecondaryUV = this._useSecondaryUV; + }; + Object.defineProperty(EffectLightMapMethod.prototype, "blendMode", { + /** + * The blend mode with which the light map should be applied to the lighting result. + * + * @see EffectLightMapMethod.ADD + * @see EffectLightMapMethod.MULTIPLY + */ + get: function () { + return this._blendMode; + }, + set: function (value) { + if (value != EffectLightMapMethod.ADD && value != EffectLightMapMethod.MULTIPLY) + throw new Error("Unknown blendmode!"); + if (this._blendMode == value) + return; + this._blendMode = value; + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectLightMapMethod.prototype, "texture", { + /** + * The texture containing the light map. + */ + get: function () { + return this._texture; + }, + set: function (value) { + if (value.hasMipmaps != this._texture.hasMipmaps || value.format != this._texture.format) + this.iInvalidateShaderProgram(); + this._texture = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectLightMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + stage.context.activateTexture(methodVO.texturesIndex, this._texture); + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + EffectLightMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var code; + var lightMapReg = registerCache.getFreeTextureReg(); + var temp = registerCache.getFreeFragmentVectorTemp(); + methodVO.texturesIndex = lightMapReg.index; + code = ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, lightMapReg, this._texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, this._useSecondaryUV ? sharedRegisters.secondaryUVVarying : sharedRegisters.uvVarying); + switch (this._blendMode) { + case EffectLightMapMethod.MULTIPLY: + code += "mul " + targetReg + ", " + targetReg + ", " + temp + "\n"; + break; + case EffectLightMapMethod.ADD: + code += "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + break; + } + return code; + }; + /** + * Indicates the light map should be multiplied with the calculated shading result. + */ + EffectLightMapMethod.MULTIPLY = "multiply"; + /** + * Indicates the light map should be added into the calculated shading result. + */ + EffectLightMapMethod.ADD = "add"; + return EffectLightMapMethod; +})(EffectMethodBase); +module.exports = EffectLightMapMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdGxpZ2h0bWFwbWV0aG9kLnRzIl0sIm5hbWVzIjpbIkVmZmVjdExpZ2h0TWFwTWV0aG9kIiwiRWZmZWN0TGlnaHRNYXBNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RMaWdodE1hcE1ldGhvZC5pSW5pdFZPIiwiRWZmZWN0TGlnaHRNYXBNZXRob2QuYmxlbmRNb2RlIiwiRWZmZWN0TGlnaHRNYXBNZXRob2QudGV4dHVyZSIsIkVmZmVjdExpZ2h0TWFwTWV0aG9kLmlBY3RpdmF0ZSIsIkVmZmVjdExpZ2h0TWFwTWV0aG9kLmlHZXRGcmFnbWVudENvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVNBLElBQU8sZ0JBQWdCLFdBQWUsdURBQXVELENBQUMsQ0FBQztBQUMvRixJQUFPLG9CQUFvQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFcEcsQUFLQTs7OztHQURHO0lBQ0csb0JBQW9CO0lBQVNBLFVBQTdCQSxvQkFBb0JBLFVBQXlCQTtJQWlCbERBOzs7Ozs7T0FNR0E7SUFDSEEsU0F4QktBLG9CQUFvQkEsQ0F3QmJBLE9BQXFCQSxFQUFFQSxTQUE2QkEsRUFBRUEsY0FBOEJBO1FBQTdEQyx5QkFBNkJBLEdBQTdCQSxzQkFBNkJBO1FBQUVBLDhCQUE4QkEsR0FBOUJBLHNCQUE4QkE7UUFFL0ZBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxjQUFjQSxDQUFDQTtRQUN0Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsT0FBT0EsQ0FBQ0E7UUFDeEJBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLFNBQVNBLENBQUNBO0lBQzVCQSxDQUFDQTtJQUVERDs7T0FFR0E7SUFDSUEsc0NBQU9BLEdBQWRBLFVBQWVBLFlBQTZCQSxFQUFFQSxRQUFpQkE7UUFFOURFLFFBQVFBLENBQUNBLE9BQU9BLEdBQUdBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBO1FBQ3pDQSxRQUFRQSxDQUFDQSxn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LEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBO2dCQUNuRUEsS0FBS0EsQ0FBQ0E7WUFDUEEsS0FBS0Esb0JBQW9CQSxDQUFDQSxHQUFHQTtnQkFDNUJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBO2dCQUNuRUEsS0FBS0EsQ0FBQ0E7UUFDUkEsQ0FBQ0E7UUFFREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUEvR0ROOztPQUVHQTtJQUNXQSw2QkFBUUEsR0FBVUEsVUFBVUEsQ0FBQ0E7SUFFM0NBOztPQUVHQTtJQUNXQSx3QkFBR0EsR0FBVUEsS0FBS0EsQ0FBQ0E7SUF3R2xDQSwyQkFBQ0E7QUFBREEsQ0FsSEEsQUFrSENBLEVBbEhrQyxnQkFBZ0IsRUFrSGxEO0FBRUQsQUFBOEIsaUJBQXJCLG9CQUFvQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL0VmZmVjdExpZ2h0TWFwTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRleHR1cmUyREJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmUyREJhc2VcIik7XG5cbmltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgRWZmZWN0TWV0aG9kQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0TWV0aG9kQmFzZVwiKTtcbmltcG9ydCBTaGFkZXJDb21waWxlckhlbHBlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9TaGFkZXJDb21waWxlckhlbHBlclwiKTtcblxuLyoqXG4gKiBFZmZlY3RMaWdodE1hcE1ldGhvZCBwcm92aWRlcyBhIG1ldGhvZCB0aGF0IGFsbG93cyBhcHBseWluZyBhIGxpZ2h0IG1hcCB0ZXh0dXJlIHRvIHRoZSBjYWxjdWxhdGVkIHBpeGVsIGNvbG91ci5cbiAqIEl0IGlzIGRpZmZlcmVudCBmcm9tIERpZmZ1c2VMaWdodE1hcE1ldGhvZCBpbiB0aGF0IHRoZSBsYXR0ZXIgb25seSBtb2R1bGF0ZXMgdGhlIGRpZmZ1c2Ugc2hhZGluZyB2YWx1ZSByYXRoZXJcbiAqIHRoYW4gdGhlIHdob2xlIHBpeGVsIGNvbG91ci5cbiAqL1xuY2xhc3MgRWZmZWN0TGlnaHRNYXBNZXRob2QgZXh0ZW5kcyBFZmZlY3RNZXRob2RCYXNlXG57XG5cdC8qKlxuXHQgKiBJbmRpY2F0ZXMgdGhlIGxpZ2h0IG1hcCBzaG91bGQgYmUgbXVsdGlwbGllZCB3aXRoIHRoZSBjYWxjdWxhdGVkIHNoYWRpbmcgcmVzdWx0LlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBNVUxUSVBMWTpzdHJpbmcgPSBcIm11bHRpcGx5XCI7XG5cblx0LyoqXG5cdCAqIEluZGljYXRlcyB0aGUgbGlnaHQgbWFwIHNob3VsZCBiZSBhZGRlZCBpbnRvIHRoZSBjYWxjdWxhdGVkIHNoYWRpbmcgcmVzdWx0LlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBBREQ6c3RyaW5nID0gXCJhZGRcIjtcblxuXHRwcml2YXRlIF90ZXh0dXJlOlRleHR1cmUyREJhc2U7XG5cblx0cHJpdmF0ZSBfYmxlbmRNb2RlOnN0cmluZztcblx0cHJpdmF0ZSBfdXNlU2Vjb25kYXJ5VVY6Ym9vbGVhbjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBFZmZlY3RMaWdodE1hcE1ldGhvZCBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB0ZXh0dXJlIFRoZSB0ZXh0dXJlIGNvbnRhaW5pbmcgdGhlIGxpZ2h0IG1hcC5cblx0ICogQHBhcmFtIGJsZW5kTW9kZSBUaGUgYmxlbmQgbW9kZSB3aXRoIHdoaWNoIHRoZSBsaWdodCBtYXAgc2hvdWxkIGJlIGFwcGxpZWQgdG8gdGhlIGxpZ2h0aW5nIHJlc3VsdC5cblx0ICogQHBhcmFtIHVzZVNlY29uZGFyeVVWIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzZWNvbmRhcnkgVVYgc2V0IHNob3VsZCBiZSB1c2VkIHRvIG1hcCB0aGUgbGlnaHQgbWFwLlxuXHQgKi9cblx0Y29uc3RydWN0b3IodGV4dHVyZTpUZXh0dXJlMkRCYXNlLCBibGVuZE1vZGU6c3RyaW5nID0gXCJtdWx0aXBseVwiLCB1c2VTZWNvbmRhcnlVVjpib29sZWFuID0gZmFsc2UpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0dGhpcy5fdXNlU2Vjb25kYXJ5VVYgPSB1c2VTZWNvbmRhcnlVVjtcblx0XHR0aGlzLl90ZXh0dXJlID0gdGV4dHVyZTtcblx0XHR0aGlzLmJsZW5kTW9kZSA9IGJsZW5kTW9kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0bWV0aG9kVk8ubmVlZHNVViA9ICF0aGlzLl91c2VTZWNvbmRhcnlVVjtcblx0XHRtZXRob2RWTy5uZWVkc1NlY29uZGFyeVVWID0gdGhpcy5fdXNlU2Vjb25kYXJ5VVY7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGJsZW5kIG1vZGUgd2l0aCB3aGljaCB0aGUgbGlnaHQgbWFwIHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoZSBsaWdodGluZyByZXN1bHQuXG5cdCAqXG5cdCAqIEBzZWUgRWZmZWN0TGlnaHRNYXBNZXRob2QuQUREXG5cdCAqIEBzZWUgRWZmZWN0TGlnaHRNYXBNZXRob2QuTVVMVElQTFlcblx0ICovXG5cdHB1YmxpYyBnZXQgYmxlbmRNb2RlKCk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmxlbmRNb2RlO1xuXHR9XG5cblx0cHVibGljIHNldCBibGVuZE1vZGUodmFsdWU6c3RyaW5nKVxuXHR7XG5cdFx0aWYgKHZhbHVlICE9IEVmZmVjdExpZ2h0TWFwTWV0aG9kLkFERCAmJiB2YWx1ZSAhPSBFZmZlY3RMaWdodE1hcE1ldGhvZC5NVUxUSVBMWSlcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24gYmxlbmRtb2RlIVwiKTtcblx0XHRpZiAodGhpcy5fYmxlbmRNb2RlID09IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5fYmxlbmRNb2RlID0gdmFsdWU7XG5cblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSB0ZXh0dXJlIGNvbnRhaW5pbmcgdGhlIGxpZ2h0IG1hcC5cblx0ICovXG5cdHB1YmxpYyBnZXQgdGV4dHVyZSgpOlRleHR1cmUyREJhc2Vcblx0e1xuXHRcdHJldHVybiB0aGlzLl90ZXh0dXJlO1xuXHR9XG5cblx0cHVibGljIHNldCB0ZXh0dXJlKHZhbHVlOlRleHR1cmUyREJhc2UpXG5cdHtcblx0XHRpZiAodmFsdWUuaGFzTWlwbWFwcyAhPSB0aGlzLl90ZXh0dXJlLmhhc01pcG1hcHMgfHwgdmFsdWUuZm9ybWF0ICE9IHRoaXMuX3RleHR1cmUuZm9ybWF0KVxuXHRcdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblxuXHRcdHRoaXMuX3RleHR1cmUgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4LCB0aGlzLl90ZXh0dXJlKTtcblxuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZztcblx0XHR2YXIgbGlnaHRNYXBSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdG1ldGhvZFZPLnRleHR1cmVzSW5kZXggPSBsaWdodE1hcFJlZy5pbmRleDtcblxuXHRcdGNvZGUgPSBTaGFkZXJDb21waWxlckhlbHBlci5nZXRUZXgyRFNhbXBsZUNvZGUodGVtcCwgc2hhcmVkUmVnaXN0ZXJzLCBsaWdodE1hcFJlZywgdGhpcy5fdGV4dHVyZSwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QucmVwZWF0VGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCB0aGlzLl91c2VTZWNvbmRhcnlVVj8gc2hhcmVkUmVnaXN0ZXJzLnNlY29uZGFyeVVWVmFyeWluZyA6IHNoYXJlZFJlZ2lzdGVycy51dlZhcnlpbmcpO1xuXG5cdFx0c3dpdGNoICh0aGlzLl9ibGVuZE1vZGUpIHtcblx0XHRcdGNhc2UgRWZmZWN0TGlnaHRNYXBNZXRob2QuTVVMVElQTFk6XG5cdFx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0YXJnZXRSZWcgKyBcIiwgXCIgKyB0ZW1wICsgXCJcXG5cIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEVmZmVjdExpZ2h0TWFwTWV0aG9kLkFERDpcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLCBcIiArIHRhcmdldFJlZyArIFwiLCBcIiArIHRlbXAgKyBcIlxcblwiO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBFZmZlY3RMaWdodE1hcE1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/EffectLightMapMethod.ts b/lib/materials/methods/EffectLightMapMethod.ts new file mode 100644 index 000000000..86df1f0d2 --- /dev/null +++ b/lib/materials/methods/EffectLightMapMethod.ts @@ -0,0 +1,134 @@ +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 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"); + +/** + * EffectLightMapMethod provides a method that allows applying a light map texture to the calculated pixel colour. + * It is different from DiffuseLightMapMethod in that the latter only modulates the diffuse shading value rather + * than the whole pixel colour. + */ +class EffectLightMapMethod extends EffectMethodBase +{ + /** + * Indicates the light map should be multiplied with the calculated shading result. + */ + public static MULTIPLY:string = "multiply"; + + /** + * Indicates the light map should be added into the calculated shading result. + */ + public static ADD:string = "add"; + + private _texture:Texture2DBase; + + private _blendMode:string; + private _useSecondaryUV:boolean; + + /** + * Creates a new EffectLightMapMethod object. + * + * @param texture 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. + */ + constructor(texture:Texture2DBase, blendMode:string = "multiply", useSecondaryUV:boolean = false) + { + super(); + + this._useSecondaryUV = useSecondaryUV; + this._texture = texture; + this.blendMode = blendMode; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + methodVO.needsUV = !this._useSecondaryUV; + methodVO.needsSecondaryUV = this._useSecondaryUV; + } + + /** + * The blend mode with which the light map should be applied to the lighting result. + * + * @see EffectLightMapMethod.ADD + * @see EffectLightMapMethod.MULTIPLY + */ + public get blendMode():string + { + return this._blendMode; + } + + public set blendMode(value:string) + { + if (value != EffectLightMapMethod.ADD && value != EffectLightMapMethod.MULTIPLY) + throw new Error("Unknown blendmode!"); + if (this._blendMode == value) + return; + + this._blendMode = value; + + this.iInvalidateShaderProgram(); + } + + /** + * The texture containing the light map. + */ + public get texture():Texture2DBase + { + return this._texture; + } + + public set texture(value:Texture2DBase) + { + if (value.hasMipmaps != this._texture.hasMipmaps || value.format != this._texture.format) + this.iInvalidateShaderProgram(); + + this._texture = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + ( stage.context).activateTexture(methodVO.texturesIndex, this._texture); + + super.iActivate(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string; + var lightMapReg:ShaderRegisterElement = registerCache.getFreeTextureReg(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + methodVO.texturesIndex = lightMapReg.index; + + code = ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, lightMapReg, this._texture, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, this._useSecondaryUV? sharedRegisters.secondaryUVVarying : sharedRegisters.uvVarying); + + switch (this._blendMode) { + case EffectLightMapMethod.MULTIPLY: + code += "mul " + targetReg + ", " + targetReg + ", " + temp + "\n"; + break; + case EffectLightMapMethod.ADD: + code += "add " + targetReg + ", " + targetReg + ", " + temp + "\n"; + break; + } + + return code; + } +} + +export = EffectLightMapMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectRefractionEnvMapMethod.js b/lib/materials/methods/EffectRefractionEnvMapMethod.js new file mode 100755 index 000000000..91991eb14 --- /dev/null +++ b/lib/materials/methods/EffectRefractionEnvMapMethod.js @@ -0,0 +1,208 @@ +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"); +/** + * EffectRefractionEnvMapMethod provides a method to add refracted transparency based on cube maps. + */ +var EffectRefractionEnvMapMethod = (function (_super) { + __extends(EffectRefractionEnvMapMethod, _super); + /** + * Creates a new EffectRefractionEnvMapMethod object. Example values for dispersion are: dispersionR: -0.03, dispersionG: -0.01, dispersionB: = .0015 + * + * @param envMap The environment map containing the refracted scene. + * @param refractionIndex The refractive index of the material. + * @param dispersionR The amount of chromatic dispersion of the red channel. Defaults to 0 (none). + * @param dispersionG The amount of chromatic dispersion of the green channel. Defaults to 0 (none). + * @param dispersionB The amount of chromatic dispersion of the blue channel. Defaults to 0 (none). + */ + function EffectRefractionEnvMapMethod(envMap, refractionIndex, dispersionR, dispersionG, dispersionB) { + if (refractionIndex === void 0) { refractionIndex = .1; } + if (dispersionR === void 0) { dispersionR = 0; } + if (dispersionG === void 0) { dispersionG = 0; } + if (dispersionB === void 0) { dispersionB = 0; } + _super.call(this); + this._dispersionR = 0; + this._dispersionG = 0; + this._dispersionB = 0; + this._alpha = 1; + this._envMap = envMap; + this._dispersionR = dispersionR; + this._dispersionG = dispersionG; + this._dispersionB = dispersionB; + this._useDispersion = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + this._refractionIndex = refractionIndex; + } + /** + * @inheritDoc + */ + EffectRefractionEnvMapMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var index = methodVO.fragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index + 4] = 1; + data[index + 5] = 0; + data[index + 7] = 1; + }; + /** + * @inheritDoc + */ + EffectRefractionEnvMapMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsNormals = true; + methodVO.needsView = true; + }; + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "envMap", { + /** + * The cube environment map to use for the refraction. + */ + get: function () { + return this._envMap; + }, + set: function (value) { + this._envMap = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "refractionIndex", { + /** + * The refractive index of the material. + */ + get: function () { + return this._refractionIndex; + }, + set: function (value) { + this._refractionIndex = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "dispersionR", { + /** + * The amount of chromatic dispersion of the red channel. Defaults to 0 (none). + */ + get: function () { + return this._dispersionR; + }, + set: function (value) { + this._dispersionR = value; + var useDispersion = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "dispersionG", { + /** + * The amount of chromatic dispersion of the green channel. Defaults to 0 (none). + */ + get: function () { + return this._dispersionG; + }, + set: function (value) { + this._dispersionG = value; + var useDispersion = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "dispersionB", { + /** + * The amount of chromatic dispersion of the blue channel. Defaults to 0 (none). + */ + get: function () { + return this._dispersionB; + }, + set: function (value) { + this._dispersionB = value; + var useDispersion = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRefractionEnvMapMethod.prototype, "alpha", { + /** + * The amount of transparency of the object. Warning: the alpha applies to the refracted color, not the actual + * material. A value of 1 will make it appear fully transparent. + */ + get: function () { + return this._alpha; + }, + set: function (value) { + this._alpha = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectRefractionEnvMapMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + var index = methodVO.fragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index] = this._dispersionR + this._refractionIndex; + if (this._useDispersion) { + data[index + 1] = this._dispersionG + this._refractionIndex; + data[index + 2] = this._dispersionB + this._refractionIndex; + } + data[index + 3] = this._alpha; + stage.context.activateCubeTexture(methodVO.texturesIndex, this._envMap); + }; + /** + * @inheritDoc + */ + EffectRefractionEnvMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + // todo: data2.x could use common reg, so only 1 reg is used + var data = registerCache.getFreeFragmentConstant(); + var data2 = registerCache.getFreeFragmentConstant(); + var code = ""; + var cubeMapReg = registerCache.getFreeTextureReg(); + var refractionDir; + var refractionColor; + var temp; + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = data.index * 4; + refractionDir = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(refractionDir, 1); + refractionColor = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(refractionColor, 1); + temp = registerCache.getFreeFragmentVectorTemp(); + var viewDirReg = sharedRegisters.viewDirFragment; + var normalReg = sharedRegisters.normalFragment; + code += "neg " + viewDirReg + ".xyz, " + viewDirReg + ".xyz\n"; + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".x, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".x, " + temp + ".w\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "sqt " + temp + ".y, " + temp + ".w\n" + "mul " + temp + ".x, " + data + ".x, " + temp + ".x\n" + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + "mul " + refractionDir + ", " + data + ".x, " + viewDirReg + "\n" + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(refractionColor, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + "sub " + refractionColor + ".w, " + refractionColor + ".w, fc0.x \n" + "kil " + refractionColor + ".w\n"; + if (this._useDispersion) { + // GREEN + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".y, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".y, " + temp + ".w\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "sqt " + temp + ".y, " + temp + ".w\n" + "mul " + temp + ".x, " + data + ".y, " + temp + ".x\n" + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + "mul " + refractionDir + ", " + data + ".y, " + viewDirReg + "\n" + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + "mov " + refractionColor + ".y, " + temp + ".y\n"; + // BLUE + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".z, " + temp + ".w\n" + "mul " + temp + ".w, " + data + ".z, " + temp + ".w\n" + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + "sqt " + temp + ".y, " + temp + ".w\n" + "mul " + temp + ".x, " + data + ".z, " + temp + ".x\n" + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + "mul " + refractionDir + ", " + data + ".z, " + viewDirReg + "\n" + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + "mov " + refractionColor + ".z, " + temp + ".z\n"; + } + registerCache.removeFragmentTempUsage(refractionDir); + code += "sub " + refractionColor + ".xyz, " + refractionColor + ".xyz, " + targetReg + ".xyz\n" + "mul " + refractionColor + ".xyz, " + refractionColor + ".xyz, " + data + ".w\n" + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + refractionColor + ".xyz\n"; + registerCache.removeFragmentTempUsage(refractionColor); + // restore + code += "neg " + viewDirReg + ".xyz, " + viewDirReg + ".xyz\n"; + return code; + }; + return EffectRefractionEnvMapMethod; +})(EffectMethodBase); +module.exports = EffectRefractionEnvMapMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdHJlZnJhY3Rpb25lbnZtYXBtZXRob2QudHMiXSwibmFtZXMiOlsiRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZCIsIkVmZmVjdFJlZnJhY3Rpb25FbnZNYXBNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZC5pSW5pdFZPIiwiRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZC5lbnZNYXAiLCJFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kLnJlZnJhY3Rpb25JbmRleCIsIkVmZmVjdFJlZnJhY3Rpb25FbnZNYXBNZXRob2QuZGlzcGVyc2lvblIiLCJFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kLmRpc3BlcnNpb25HIiwiRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZC5kaXNwZXJzaW9uQiIsIkVmZmVjdFJlZnJhY3Rpb25FbnZNYXBNZXRob2QuYWxwaGEiLCJFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kLmlBY3RpdmF0ZSIsIkVmZmVjdFJlZnJhY3Rpb25FbnZNYXBNZXRob2QuaUdldEZyYWdtZW50Q29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBU0EsSUFBTyxnQkFBZ0IsV0FBZSx1REFBdUQsQ0FBQyxDQUFDO0FBQy9GLElBQU8sb0JBQW9CLFdBQWMseURBQXlELENBQUMsQ0FBQztBQUVwRyxBQUdBOztHQURHO0lBQ0csNEJBQTRCO0lBQVNBLFVBQXJDQSw0QkFBNEJBLFVBQXlCQTtJQVcxREE7Ozs7Ozs7O09BUUdBO0lBQ0hBLFNBcEJLQSw0QkFBNEJBLENBb0JyQkEsTUFBc0JBLEVBQUVBLGVBQTJCQSxFQUFFQSxXQUFzQkEsRUFBRUEsV0FBc0JBLEVBQUVBLFdBQXNCQTtRQUFuR0MsK0JBQTJCQSxHQUEzQkEsb0JBQTJCQTtRQUFFQSwyQkFBc0JBLEdBQXRCQSxl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LEVBQUVBLENBQUNBO1FBQzVEQSxhQUFhQSxDQUFDQSxxQkFBcUJBLENBQUNBLGVBQWVBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBRXhEQSxJQUFJQSxHQUFHQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1FBRWpEQSxJQUFJQSxVQUFVQSxHQUF5QkEsZUFBZUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDdkVBLElBQUlBLFNBQVNBLEdBQXlCQSxlQUFlQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUVyRUEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsVUFBVUEsR0FBR0EsUUFBUUEsR0FBR0EsVUFBVUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFFL0RBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFVBQVVBLEdBQUdBLFFBQVFBLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLEdBQzVFQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN0REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDdkRBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ3REQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN0REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDdkRBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBRXRDQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN0REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDdERBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLEdBRS9EQSxNQUFNQSxHQUFHQSxhQUFhQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxVQUFVQSxHQUFHQSxJQUFJQSxHQUNqRUEsTUFBTUEsR0FBR0EsYUFBYUEsR0FBR0EsUUFBUUEsR0FBR0EsYUFBYUEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsR0FDOUVBLE1BQU1BLEdBQUdBLGFBQWFBLEdBQUdBLFFBQVFBLEdBQUdBLGFBQWFBLEdBQUdBLFFBQVFBLENBQUNBO1FBQzlEQSxJQUFJQSxJQUFJQSxvQkFBb0JBLENBQUNBLG9CQUFvQkEsQ0FBQ0EsZUFBZUEsRUFBRUEsVUFBVUEsRUFBRUEsSUFBSUEsQ0FBQ0EsT0FBT0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxFQUFFQSxhQUFhQSxDQUFDQSxHQUN0S0EsTUFBTUEsR0FBR0EsZUFBZUEsR0FBR0EsTUFBTUEsR0FBR0EsZUFBZUEsR0FBR0EsY0FBY0EsR0FDcEVBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLE1BQU1BLENBQUNBO1FBRW5DQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6QkEsQUFDQUEsUUFEUUE7WUFDUkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsVUFBVUEsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FDNUVBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ3REQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN2REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDdERBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ3REQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN2REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FFdENBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ3REQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUN0REEsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FFL0RBLE1BQU1BLEdBQUdBLGFBQWFBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFVBQVVBLEdBQUdBLElBQUlBLEdBQ2pFQSxNQUFNQSxHQUFHQSxhQUFhQSxHQUFHQSxRQUFRQSxHQUFHQSxhQUFhQSxHQUFHQSxR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OUZBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLFFBQVFBLEdBQUdBLGVBQWVBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ2hGQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxlQUFlQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUVuRkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUV2REEsQUFDQUEsVUFEVUE7UUFDVkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsVUFBVUEsR0FBR0EsUUFBUUEsR0FBR0EsVUFBVUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFFL0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBQ0ZYLG1DQUFDQTtBQUFEQSxDQTdRQSxBQTZRQ0EsRUE3UTBDLGdCQUFnQixFQTZRMUQ7QUFFRCxBQUFzQyxpQkFBN0IsNEJBQTRCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDdWJlVGV4dHVyZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL0N1YmVUZXh0dXJlQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIEVmZmVjdFJlZnJhY3Rpb25FbnZNYXBNZXRob2QgcHJvdmlkZXMgYSBtZXRob2QgdG8gYWRkIHJlZnJhY3RlZCB0cmFuc3BhcmVuY3kgYmFzZWQgb24gY3ViZSBtYXBzLlxuICovXG5jbGFzcyBFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kIGV4dGVuZHMgRWZmZWN0TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9lbnZNYXA6Q3ViZVRleHR1cmVCYXNlO1xuXG5cdHByaXZhdGUgX2Rpc3BlcnNpb25SOm51bWJlciA9IDA7XG5cdHByaXZhdGUgX2Rpc3BlcnNpb25HOm51bWJlciA9IDA7XG5cdHByaXZhdGUgX2Rpc3BlcnNpb25COm51bWJlciA9IDA7XG5cdHByaXZhdGUgX3VzZURpc3BlcnNpb246Ym9vbGVhbjtcblx0cHJpdmF0ZSBfcmVmcmFjdGlvbkluZGV4Om51bWJlcjtcblx0cHJpdmF0ZSBfYWxwaGE6bnVtYmVyID0gMTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBFZmZlY3RSZWZyYWN0aW9uRW52TWFwTWV0aG9kIG9iamVjdC4gRXhhbXBsZSB2YWx1ZXMgZm9yIGRpc3BlcnNpb24gYXJlOiBkaXNwZXJzaW9uUjogLTAuMDMsIGRpc3BlcnNpb25HOiAtMC4wMSwgZGlzcGVyc2lvbkI6ID0gLjAwMTVcblx0ICpcblx0ICogQHBhcmFtIGVudk1hcCBUaGUgZW52aXJvbm1lbnQgbWFwIGNvbnRhaW5pbmcgdGhlIHJlZnJhY3RlZCBzY2VuZS5cblx0ICogQHBhcmFtIHJlZnJhY3Rpb25JbmRleCBUaGUgcmVmcmFjdGl2ZSBpbmRleCBvZiB0aGUgbWF0ZXJpYWwuXG5cdCAqIEBwYXJhbSBkaXNwZXJzaW9uUiBUaGUgYW1vdW50IG9mIGNocm9tYXRpYyBkaXNwZXJzaW9uIG9mIHRoZSByZWQgY2hhbm5lbC4gRGVmYXVsdHMgdG8gMCAobm9uZSkuXG5cdCAqIEBwYXJhbSBkaXNwZXJzaW9uRyBUaGUgYW1vdW50IG9mIGNocm9tYXRpYyBkaXNwZXJzaW9uIG9mIHRoZSBncmVlbiBjaGFubmVsLiBEZWZhdWx0cyB0byAwIChub25lKS5cblx0ICogQHBhcmFtIGRpc3BlcnNpb25CIFRoZSBhbW91bnQgb2YgY2hyb21hdGljIGRpc3BlcnNpb24gb2YgdGhlIGJsdWUgY2hhbm5lbC4gRGVmYXVsdHMgdG8gMCAobm9uZSkuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihlbnZNYXA6Q3ViZVRleHR1cmVCYXNlLCByZWZyYWN0aW9uSW5kZXg6bnVtYmVyID0gLjEsIGRpc3BlcnNpb25SOm51bWJlciA9IDAsIGRpc3BlcnNpb25HOm51bWJlciA9IDAsIGRpc3BlcnNpb25COm51bWJlciA9IDApXG5cdHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMuX2Vudk1hcCA9IGVudk1hcDtcblx0XHR0aGlzLl9kaXNwZXJzaW9uUiA9IGRpc3BlcnNpb25SO1xuXHRcdHRoaXMuX2Rpc3BlcnNpb25HID0gZGlzcGVyc2lvbkc7XG5cdFx0dGhpcy5fZGlzcGVyc2lvbkIgPSBkaXNwZXJzaW9uQjtcblx0XHR0aGlzLl91c2VEaXNwZXJzaW9uID0gISh0aGlzLl9kaXNwZXJzaW9uUiA9PSB0aGlzLl9kaXNwZXJzaW9uQiAmJiB0aGlzLl9kaXNwZXJzaW9uUiA9PSB0aGlzLl9kaXNwZXJzaW9uRyk7XG5cdFx0dGhpcy5fcmVmcmFjdGlvbkluZGV4ID0gcmVmcmFjdGlvbkluZGV4O1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdGRhdGFbaW5kZXggKyA0XSA9IDE7XG5cdFx0ZGF0YVtpbmRleCArIDVdID0gMDtcblx0XHRkYXRhW2luZGV4ICsgN10gPSAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRWTyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRtZXRob2RWTy5uZWVkc05vcm1hbHMgPSB0cnVlO1xuXHRcdG1ldGhvZFZPLm5lZWRzVmlldyA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGN1YmUgZW52aXJvbm1lbnQgbWFwIHRvIHVzZSBmb3IgdGhlIHJlZnJhY3Rpb24uXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVudk1hcCgpOkN1YmVUZXh0dXJlQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Vudk1hcDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgZW52TWFwKHZhbHVlOkN1YmVUZXh0dXJlQmFzZSlcblx0e1xuXHRcdHRoaXMuX2Vudk1hcCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSByZWZyYWN0aXZlIGluZGV4IG9mIHRoZSBtYXRlcmlhbC5cblx0ICovXG5cdHB1YmxpYyBnZXQgcmVmcmFjdGlvbkluZGV4KCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcmVmcmFjdGlvbkluZGV4O1xuXHR9XG5cblx0cHVibGljIHNldCByZWZyYWN0aW9uSW5kZXgodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fcmVmcmFjdGlvbkluZGV4ID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGFtb3VudCBvZiBjaHJvbWF0aWMgZGlzcGVyc2lvbiBvZiB0aGUgcmVkIGNoYW5uZWwuIERlZmF1bHRzIHRvIDAgKG5vbmUpLlxuXHQgKi9cblx0cHVibGljIGdldCBkaXNwZXJzaW9uUigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Rpc3BlcnNpb25SO1xuXHR9XG5cblx0cHVibGljIHNldCBkaXNwZXJzaW9uUih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9kaXNwZXJzaW9uUiA9IHZhbHVlO1xuXG5cdFx0dmFyIHVzZURpc3BlcnNpb246Ym9vbGVhbiA9ICEodGhpcy5fZGlzcGVyc2lvblIgPT0gdGhpcy5fZGlzcGVyc2lvbkIgJiYgdGhpcy5fZGlzcGVyc2lvblIgPT0gdGhpcy5fZGlzcGVyc2lvbkcpO1xuXHRcdGlmICh0aGlzLl91c2VEaXNwZXJzaW9uICE9IHVzZURpc3BlcnNpb24pIHtcblx0XHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdFx0XHR0aGlzLl91c2VEaXNwZXJzaW9uID0gdXNlRGlzcGVyc2lvbjtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGFtb3VudCBvZiBjaHJvbWF0aWMgZGlzcGVyc2lvbiBvZiB0aGUgZ3JlZW4gY2hhbm5lbC4gRGVmYXVsdHMgdG8gMCAobm9uZSkuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGRpc3BlcnNpb25HKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZGlzcGVyc2lvbkc7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGRpc3BlcnNpb25HKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2Rpc3BlcnNpb25HID0gdmFsdWU7XG5cblx0XHR2YXIgdXNlRGlzcGVyc2lvbjpib29sZWFuID0gISh0aGlzLl9kaXNwZXJzaW9uUiA9PSB0aGlzLl9kaXNwZXJzaW9uQiAmJiB0aGlzLl9kaXNwZXJzaW9uUiA9PSB0aGlzLl9kaXNwZXJzaW9uRyk7XG5cdFx0aWYgKHRoaXMuX3VzZURpc3BlcnNpb24gIT0gdXNlRGlzcGVyc2lvbikge1xuXHRcdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0XHRcdHRoaXMuX3VzZURpc3BlcnNpb24gPSB1c2VEaXNwZXJzaW9uO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IG9mIGNocm9tYXRpYyBkaXNwZXJzaW9uIG9mIHRoZSBibHVlIGNoYW5uZWwuIERlZmF1bHRzIHRvIDAgKG5vbmUpLlxuXHQgKi9cblx0cHVibGljIGdldCBkaXNwZXJzaW9uQigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Rpc3BlcnNpb25CO1xuXHR9XG5cblx0cHVibGljIHNldCBkaXNwZXJzaW9uQih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9kaXNwZXJzaW9uQiA9IHZhbHVlO1xuXG5cdFx0dmFyIHVzZURpc3BlcnNpb246Ym9vbGVhbiA9ICEodGhpcy5fZGlzcGVyc2lvblIgPT0gdGhpcy5fZGlzcGVyc2lvbkIgJiYgdGhpcy5fZGlzcGVyc2lvblIgPT0gdGhpcy5fZGlzcGVyc2lvbkcpO1xuXHRcdGlmICh0aGlzLl91c2VEaXNwZXJzaW9uICE9IHVzZURpc3BlcnNpb24pIHtcblx0XHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdFx0XHR0aGlzLl91c2VEaXNwZXJzaW9uID0gdXNlRGlzcGVyc2lvbjtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGFtb3VudCBvZiB0cmFuc3BhcmVuY3kgb2YgdGhlIG9iamVjdC4gV2FybmluZzogdGhlIGFscGhhIGFwcGxpZXMgdG8gdGhlIHJlZnJhY3RlZCBjb2xvciwgbm90IHRoZSBhY3R1YWxcblx0ICogbWF0ZXJpYWwuIEEgdmFsdWUgb2YgMSB3aWxsIG1ha2UgaXQgYXBwZWFyIGZ1bGx5IHRyYW5zcGFyZW50LlxuXHQgKi9cblx0cHVibGljIGdldCBhbHBoYSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2FscGhhO1xuXHR9XG5cblx0cHVibGljIHNldCBhbHBoYSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9hbHBoYSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cblx0XHRkYXRhW2luZGV4XSA9IHRoaXMuX2Rpc3BlcnNpb25SICsgdGhpcy5fcmVmcmFjdGlvbkluZGV4O1xuXG5cdFx0aWYgKHRoaXMuX3VzZURpc3BlcnNpb24pIHtcblx0XHRcdGRhdGFbaW5kZXggKyAxXSA9IHRoaXMuX2Rpc3BlcnNpb25HICsgdGhpcy5fcmVmcmFjdGlvbkluZGV4O1xuXHRcdFx0ZGF0YVtpbmRleCArIDJdID0gdGhpcy5fZGlzcGVyc2lvbkIgKyB0aGlzLl9yZWZyYWN0aW9uSW5kZXg7XG5cdFx0fVxuXHRcdGRhdGFbaW5kZXggKyAzXSA9IHRoaXMuX2FscGhhO1xuXG5cdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlQ3ViZVRleHR1cmUobWV0aG9kVk8udGV4dHVyZXNJbmRleCwgdGhpcy5fZW52TWFwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0Ly8gdG9kbzogZGF0YTIueCBjb3VsZCB1c2UgY29tbW9uIHJlZywgc28gb25seSAxIHJlZyBpcyB1c2VkXG5cdFx0dmFyIGRhdGE6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBkYXRhMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgY3ViZU1hcFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVUZXh0dXJlUmVnKCk7XG5cdFx0dmFyIHJlZnJhY3Rpb25EaXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdHZhciByZWZyYWN0aW9uQ29sb3I6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblxuXHRcdG1ldGhvZFZPLnRleHR1cmVzSW5kZXggPSBjdWJlTWFwUmVnLmluZGV4O1xuXHRcdG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSBkYXRhLmluZGV4KjQ7XG5cblx0XHRyZWZyYWN0aW9uRGlyID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXMocmVmcmFjdGlvbkRpciwgMSk7XG5cdFx0cmVmcmFjdGlvbkNvbG9yID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXMocmVmcmFjdGlvbkNvbG9yLCAxKTtcblxuXHRcdHRlbXAgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblxuXHRcdHZhciB2aWV3RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQ7XG5cdFx0dmFyIG5vcm1hbFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSBzaGFyZWRSZWdpc3RlcnMubm9ybWFsRnJhZ21lbnQ7XG5cblx0XHRjb2RlICs9IFwibmVnIFwiICsgdmlld0RpclJlZyArIFwiLnh5eiwgXCIgKyB2aWV3RGlyUmVnICsgXCIueHl6XFxuXCI7XG5cblx0XHRjb2RlICs9IFwiZHAzIFwiICsgdGVtcCArIFwiLngsIFwiICsgdmlld0RpclJlZyArIFwiLnh5eiwgXCIgKyBub3JtYWxSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIudywgXCIgKyBkYXRhMiArIFwiLngsIFwiICsgdGVtcCArIFwiLndcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEgKyBcIi54LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIudywgXCIgKyBkYXRhICsgXCIueCwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLncsIFwiICsgZGF0YTIgKyBcIi54LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJzcXQgXCIgKyB0ZW1wICsgXCIueSwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblxuXHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIueCwgXCIgKyBkYXRhICsgXCIueCwgXCIgKyB0ZW1wICsgXCIueFxcblwiICtcblx0XHRcdFwiYWRkIFwiICsgdGVtcCArIFwiLngsIFwiICsgdGVtcCArIFwiLngsIFwiICsgdGVtcCArIFwiLnlcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLngsIFwiICsgbm9ybWFsUmVnICsgXCIueHl6XFxuXCIgK1xuXG5cdFx0XHRcIm11bCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIiwgXCIgKyBkYXRhICsgXCIueCwgXCIgKyB2aWV3RGlyUmVnICsgXCJcXG5cIiArXG5cdFx0XHRcInN1YiBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXosIFwiICsgcmVmcmFjdGlvbkRpciArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJucm0gXCIgKyByZWZyYWN0aW9uRGlyICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXpcXG5cIjtcblx0XHRjb2RlICs9IFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleEN1YmVTYW1wbGVDb2RlKHJlZnJhY3Rpb25Db2xvciwgY3ViZU1hcFJlZywgdGhpcy5fZW52TWFwLCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCByZWZyYWN0aW9uRGlyKSArXG5cdFx0XHRcInN1YiBcIiArIHJlZnJhY3Rpb25Db2xvciArIFwiLncsIFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIudywgZmMwLnhcdFxcblwiICtcblx0XHRcdFwia2lsIFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIud1xcblwiO1xuXG5cdFx0aWYgKHRoaXMuX3VzZURpc3BlcnNpb24pIHtcblx0XHRcdC8vIEdSRUVOXG5cdFx0XHRjb2RlICs9IFwiZHAzIFwiICsgdGVtcCArIFwiLngsIFwiICsgdmlld0RpclJlZyArIFwiLnh5eiwgXCIgKyBub3JtYWxSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwibXVsIFwiICsgdGVtcCArIFwiLncsIFwiICsgdGVtcCArIFwiLngsIFwiICsgdGVtcCArIFwiLnhcXG5cIiArXG5cdFx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLncsIFwiICsgZGF0YTIgKyBcIi54LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEgKyBcIi55LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEgKyBcIi55LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcInN1YiBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEyICsgXCIueCwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblx0XHRcdFx0XCJzcXQgXCIgKyB0ZW1wICsgXCIueSwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblxuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54LCBcIiArIGRhdGEgKyBcIi55LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi55XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLngsIFwiICsgbm9ybWFsUmVnICsgXCIueHl6XFxuXCIgK1xuXG5cdFx0XHRcdFwibXVsIFwiICsgcmVmcmFjdGlvbkRpciArIFwiLCBcIiArIGRhdGEgKyBcIi55LCBcIiArIHZpZXdEaXJSZWcgKyBcIlxcblwiICtcblx0XHRcdFx0XCJzdWIgXCIgKyByZWZyYWN0aW9uRGlyICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5elxcblwiICtcblx0XHRcdFx0XCJucm0gXCIgKyByZWZyYWN0aW9uRGlyICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gU2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4Q3ViZVNhbXBsZUNvZGUodGVtcCwgY3ViZU1hcFJlZywgdGhpcy5fZW52TWFwLCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCByZWZyYWN0aW9uRGlyKSArXG5cdFx0XHRcdFwibW92IFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIueSwgXCIgKyB0ZW1wICsgXCIueVxcblwiO1xuXG5cdFx0XHQvLyBCTFVFXG5cdFx0XHRjb2RlICs9IFwiZHAzIFwiICsgdGVtcCArIFwiLngsIFwiICsgdmlld0RpclJlZyArIFwiLnh5eiwgXCIgKyBub3JtYWxSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwibXVsIFwiICsgdGVtcCArIFwiLncsIFwiICsgdGVtcCArIFwiLngsIFwiICsgdGVtcCArIFwiLnhcXG5cIiArXG5cdFx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLncsIFwiICsgZGF0YTIgKyBcIi54LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEgKyBcIi56LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEgKyBcIi56LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcInN1YiBcIiArIHRlbXAgKyBcIi53LCBcIiArIGRhdGEyICsgXCIueCwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblx0XHRcdFx0XCJzcXQgXCIgKyB0ZW1wICsgXCIueSwgXCIgKyB0ZW1wICsgXCIud1xcblwiICtcblxuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54LCBcIiArIGRhdGEgKyBcIi56LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi55XFxuXCIgK1xuXHRcdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLngsIFwiICsgbm9ybWFsUmVnICsgXCIueHl6XFxuXCIgK1xuXG5cdFx0XHRcdFwibXVsIFwiICsgcmVmcmFjdGlvbkRpciArIFwiLCBcIiArIGRhdGEgKyBcIi56LCBcIiArIHZpZXdEaXJSZWcgKyBcIlxcblwiICtcblx0XHRcdFx0XCJzdWIgXCIgKyByZWZyYWN0aW9uRGlyICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5elxcblwiICtcblx0XHRcdFx0XCJucm0gXCIgKyByZWZyYWN0aW9uRGlyICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25EaXIgKyBcIi54eXpcXG5cIjtcblx0XHRcdGNvZGUgKz0gU2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4Q3ViZVNhbXBsZUNvZGUodGVtcCwgY3ViZU1hcFJlZywgdGhpcy5fZW52TWFwLCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCByZWZyYWN0aW9uRGlyKSArXG5cdFx0XHRcdFwibW92IFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIueiwgXCIgKyB0ZW1wICsgXCIuelxcblwiO1xuXHRcdH1cblxuXHRcdHJlZ2lzdGVyQ2FjaGUucmVtb3ZlRnJhZ21lbnRUZW1wVXNhZ2UocmVmcmFjdGlvbkRpcik7XG5cblx0XHRjb2RlICs9IFwic3ViIFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIueHl6LCBcIiArIHJlZnJhY3Rpb25Db2xvciArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHJlZnJhY3Rpb25Db2xvciArIFwiLnh5eiwgXCIgKyByZWZyYWN0aW9uQ29sb3IgKyBcIi54eXosIFwiICsgZGF0YSArIFwiLndcXG5cIiArXG5cdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgcmVmcmFjdGlvbkNvbG9yICsgXCIueHl6XFxuXCI7XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHJlZnJhY3Rpb25Db2xvcik7XG5cblx0XHQvLyByZXN0b3JlXG5cdFx0Y29kZSArPSBcIm5lZyBcIiArIHZpZXdEaXJSZWcgKyBcIi54eXosIFwiICsgdmlld0RpclJlZyArIFwiLnh5elxcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gRWZmZWN0UmVmcmFjdGlvbkVudk1hcE1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/EffectRefractionEnvMapMethod.ts b/lib/materials/methods/EffectRefractionEnvMapMethod.ts new file mode 100644 index 000000000..2e73baa6e --- /dev/null +++ b/lib/materials/methods/EffectRefractionEnvMapMethod.ts @@ -0,0 +1,287 @@ +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 EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase"); +import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); + +/** + * EffectRefractionEnvMapMethod provides a method to add refracted transparency based on cube maps. + */ +class EffectRefractionEnvMapMethod extends EffectMethodBase +{ + private _envMap:CubeTextureBase; + + private _dispersionR:number = 0; + private _dispersionG:number = 0; + private _dispersionB:number = 0; + private _useDispersion:boolean; + private _refractionIndex:number; + private _alpha:number = 1; + + /** + * Creates a new EffectRefractionEnvMapMethod object. Example values for dispersion are: dispersionR: -0.03, dispersionG: -0.01, dispersionB: = .0015 + * + * @param envMap The environment map containing the refracted scene. + * @param refractionIndex The refractive index of the material. + * @param dispersionR The amount of chromatic dispersion of the red channel. Defaults to 0 (none). + * @param dispersionG The amount of chromatic dispersion of the green channel. Defaults to 0 (none). + * @param dispersionB The amount of chromatic dispersion of the blue channel. Defaults to 0 (none). + */ + constructor(envMap:CubeTextureBase, refractionIndex:number = .1, dispersionR:number = 0, dispersionG:number = 0, dispersionB:number = 0) + { + super(); + this._envMap = envMap; + this._dispersionR = dispersionR; + this._dispersionG = dispersionG; + this._dispersionB = dispersionB; + this._useDispersion = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + this._refractionIndex = refractionIndex; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + data[index + 4] = 1; + data[index + 5] = 0; + data[index + 7] = 1; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + methodVO.needsNormals = true; + methodVO.needsView = true; + } + + /** + * The cube environment map to use for the refraction. + */ + public get envMap():CubeTextureBase + { + return this._envMap; + } + + public set envMap(value:CubeTextureBase) + { + this._envMap = value; + } + + /** + * The refractive index of the material. + */ + public get refractionIndex():number + { + return this._refractionIndex; + } + + public set refractionIndex(value:number) + { + this._refractionIndex = value; + } + + /** + * The amount of chromatic dispersion of the red channel. Defaults to 0 (none). + */ + public get dispersionR():number + { + return this._dispersionR; + } + + public set dispersionR(value:number) + { + this._dispersionR = value; + + var useDispersion:boolean = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + } + + /** + * The amount of chromatic dispersion of the green channel. Defaults to 0 (none). + */ + public get dispersionG():number + { + return this._dispersionG; + } + + public set dispersionG(value:number) + { + this._dispersionG = value; + + var useDispersion:boolean = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + } + + /** + * The amount of chromatic dispersion of the blue channel. Defaults to 0 (none). + */ + public get dispersionB():number + { + return this._dispersionB; + } + + public set dispersionB(value:number) + { + this._dispersionB = value; + + var useDispersion:boolean = !(this._dispersionR == this._dispersionB && this._dispersionR == this._dispersionG); + if (this._useDispersion != useDispersion) { + this.iInvalidateShaderProgram(); + this._useDispersion = useDispersion; + } + } + + /** + * The amount of transparency of the object. Warning: the alpha applies to the refracted color, not the actual + * material. A value of 1 will make it appear fully transparent. + */ + public get alpha():number + { + return this._alpha; + } + + public set alpha(value:number) + { + this._alpha = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + + data[index] = this._dispersionR + this._refractionIndex; + + if (this._useDispersion) { + data[index + 1] = this._dispersionG + this._refractionIndex; + data[index + 2] = this._dispersionB + this._refractionIndex; + } + data[index + 3] = this._alpha; + + ( stage.context).activateCubeTexture(methodVO.texturesIndex, this._envMap); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + // todo: data2.x could use common reg, so only 1 reg is used + var data:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var data2:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var code:string = ""; + var cubeMapReg:ShaderRegisterElement = registerCache.getFreeTextureReg(); + var refractionDir:ShaderRegisterElement; + var refractionColor:ShaderRegisterElement; + var temp:ShaderRegisterElement; + + methodVO.texturesIndex = cubeMapReg.index; + methodVO.fragmentConstantsIndex = data.index*4; + + refractionDir = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(refractionDir, 1); + refractionColor = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(refractionColor, 1); + + temp = registerCache.getFreeFragmentVectorTemp(); + + var viewDirReg:ShaderRegisterElement = sharedRegisters.viewDirFragment; + var normalReg:ShaderRegisterElement = sharedRegisters.normalFragment; + + code += "neg " + viewDirReg + ".xyz, " + viewDirReg + ".xyz\n"; + + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".x, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".x, " + temp + ".w\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "sqt " + temp + ".y, " + temp + ".w\n" + + + "mul " + temp + ".x, " + data + ".x, " + temp + ".x\n" + + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + + + "mul " + refractionDir + ", " + data + ".x, " + viewDirReg + "\n" + + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(refractionColor, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + + "sub " + refractionColor + ".w, " + refractionColor + ".w, fc0.x \n" + + "kil " + refractionColor + ".w\n"; + + if (this._useDispersion) { + // GREEN + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".y, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".y, " + temp + ".w\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "sqt " + temp + ".y, " + temp + ".w\n" + + + "mul " + temp + ".x, " + data + ".y, " + temp + ".x\n" + + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + + + "mul " + refractionDir + ", " + data + ".y, " + viewDirReg + "\n" + + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + + "mov " + refractionColor + ".y, " + temp + ".y\n"; + + // BLUE + code += "dp3 " + temp + ".x, " + viewDirReg + ".xyz, " + normalReg + ".xyz\n" + + "mul " + temp + ".w, " + temp + ".x, " + temp + ".x\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".z, " + temp + ".w\n" + + "mul " + temp + ".w, " + data + ".z, " + temp + ".w\n" + + "sub " + temp + ".w, " + data2 + ".x, " + temp + ".w\n" + + "sqt " + temp + ".y, " + temp + ".w\n" + + + "mul " + temp + ".x, " + data + ".z, " + temp + ".x\n" + + "add " + temp + ".x, " + temp + ".x, " + temp + ".y\n" + + "mul " + temp + ".xyz, " + temp + ".x, " + normalReg + ".xyz\n" + + + "mul " + refractionDir + ", " + data + ".z, " + viewDirReg + "\n" + + "sub " + refractionDir + ".xyz, " + refractionDir + ".xyz, " + temp + ".xyz\n" + + "nrm " + refractionDir + ".xyz, " + refractionDir + ".xyz\n"; + code += ShaderCompilerHelper.getTexCubeSampleCode(temp, cubeMapReg, this._envMap, shaderObject.useSmoothTextures, shaderObject.useMipmapping, refractionDir) + + "mov " + refractionColor + ".z, " + temp + ".z\n"; + } + + registerCache.removeFragmentTempUsage(refractionDir); + + code += "sub " + refractionColor + ".xyz, " + refractionColor + ".xyz, " + targetReg + ".xyz\n" + + "mul " + refractionColor + ".xyz, " + refractionColor + ".xyz, " + data + ".w\n" + + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + refractionColor + ".xyz\n"; + + registerCache.removeFragmentTempUsage(refractionColor); + + // restore + code += "neg " + viewDirReg + ".xyz, " + viewDirReg + ".xyz\n"; + + return code; + } +} + +export = EffectRefractionEnvMapMethod; \ No newline at end of file diff --git a/lib/materials/methods/EffectRimLightMethod.js b/lib/materials/methods/EffectRimLightMethod.js new file mode 100755 index 000000000..0715cbc8f --- /dev/null +++ b/lib/materials/methods/EffectRimLightMethod.js @@ -0,0 +1,147 @@ +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"); +/** + * EffectRimLightMethod provides a method to add rim lighting to a material. This adds a glow-like effect to edges of objects. + */ +var EffectRimLightMethod = (function (_super) { + __extends(EffectRimLightMethod, _super); + /** + * Creates a new EffectRimLightMethod object. + * + * @param color The colour of the rim light. + * @param strength The strength of the rim light. + * @param power The power of the rim light. Higher values will result in a higher edge fall-off. + * @param blend The blend mode with which to add the light to the object. + */ + function EffectRimLightMethod(color, strength, power, blend) { + if (color === void 0) { color = 0xffffff; } + if (strength === void 0) { strength = .4; } + if (power === void 0) { power = 2; } + if (blend === void 0) { blend = "mix"; } + _super.call(this); + this._blendMode = blend; + this._strength = strength; + this._power = power; + this.color = color; + } + /** + * @inheritDoc + */ + EffectRimLightMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 3] = 1; + }; + /** + * @inheritDoc + */ + EffectRimLightMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsNormals = true; + methodVO.needsView = true; + }; + Object.defineProperty(EffectRimLightMethod.prototype, "blendMode", { + /** + * The blend mode with which to add the light to the object. + * + * EffectRimLightMethod.MULTIPLY multiplies the rim light with the material's colour. + * EffectRimLightMethod.ADD adds the rim light with the material's colour. + * EffectRimLightMethod.MIX provides normal alpha blending. + */ + get: function () { + return this._blendMode; + }, + set: function (value) { + if (this._blendMode == value) + return; + this._blendMode = value; + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRimLightMethod.prototype, "color", { + /** + * The color of the rim light. + */ + get: function () { + return this._color; + }, + set: function (value /*uint*/) { + this._color = value; + this._colorR = ((value >> 16) & 0xff) / 0xff; + this._colorG = ((value >> 8) & 0xff) / 0xff; + this._colorB = (value & 0xff) / 0xff; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRimLightMethod.prototype, "strength", { + /** + * The strength of the rim light. + */ + get: function () { + return this._strength; + }, + set: function (value) { + this._strength = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EffectRimLightMethod.prototype, "power", { + /** + * The power of the rim light. Higher values will result in a higher edge fall-off. + */ + get: function () { + return this._power; + }, + set: function (value) { + this._power = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + EffectRimLightMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + var index = methodVO.fragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index] = this._colorR; + data[index + 1] = this._colorG; + data[index + 2] = this._colorB; + data[index + 4] = this._strength; + data[index + 5] = this._power; + }; + /** + * @inheritDoc + */ + EffectRimLightMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var dataRegister = registerCache.getFreeFragmentConstant(); + var dataRegister2 = registerCache.getFreeFragmentConstant(); + var temp = registerCache.getFreeFragmentVectorTemp(); + var code = ""; + methodVO.fragmentConstantsIndex = dataRegister.index * 4; + code += "dp3 " + temp + ".x, " + sharedRegisters.viewDirFragment + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + "sat " + temp + ".x, " + temp + ".x\n" + "sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x\n" + "pow " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".y\n" + "mul " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".x\n" + "sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x\n" + "mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".x\n" + "sub " + temp + ".w, " + dataRegister + ".w, " + temp + ".x\n"; + if (this._blendMode == EffectRimLightMethod.ADD) { + code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz\n" + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } + else if (this._blendMode == EffectRimLightMethod.MULTIPLY) { + code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz\n" + "mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } + else { + code += "sub " + temp + ".xyz, " + dataRegister + ".xyz, " + targetReg + ".xyz\n" + "mul " + temp + ".xyz, " + temp + ".xyz, " + temp + ".w\n" + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } + return code; + }; + EffectRimLightMethod.ADD = "add"; + EffectRimLightMethod.MULTIPLY = "multiply"; + EffectRimLightMethod.MIX = "mix"; + return EffectRimLightMethod; +})(EffectMethodBase); +module.exports = EffectRimLightMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL2VmZmVjdHJpbWxpZ2h0bWV0aG9kLnRzIl0sIm5hbWVzIjpbIkVmZmVjdFJpbUxpZ2h0TWV0aG9kIiwiRWZmZWN0UmltTGlnaHRNZXRob2QuY29uc3RydWN0b3IiLCJFZmZlY3RSaW1MaWdodE1ldGhvZC5pSW5pdENvbnN0YW50cyIsIkVmZmVjdFJpbUxpZ2h0TWV0aG9kLmlJbml0Vk8iLCJFZmZlY3RSaW1MaWdodE1ldGhvZC5ibGVuZE1vZGUiLCJFZmZlY3RSaW1MaWdodE1ldGhvZC5jb2xvciIsIkVmZmVjdFJpbUxpZ2h0TWV0aG9kLnN0cmVuZ3RoIiwiRWZmZWN0UmltTGlnaHRNZXRob2QucG93ZXIiLCJFZmZlY3RSaW1MaWdodE1ldGhvZC5pQWN0aXZhdGUiLCJFZmZlY3RSaW1MaWdodE1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQSxJQUFPLGdCQUFnQixXQUFlLHVEQUF1RCxDQUFDLENBQUM7QUFFL0YsQUFHQTs7R0FERztJQUNHLG9CQUFvQjtJQUFTQSxVQUE3QkEsb0JBQW9CQSxVQUF5QkE7SUFjbERBOzs7Ozs7O09BT0dBO0lBQ0hBLFNBdEJLQSxvQkFBb0JBLENBc0JiQSxLQUFnQ0EsRUFBRUEsUUFBb0JBLEVBQUVBLEtBQWdCQSxFQUFFQSxLQUFvQkE7UUFBOUZDLHFCQUFnQ0EsR0FBaENBLGdCQUFnQ0E7UUFBRUEsd0JBQW9CQSxHQUFwQkEsYUFBb0JBO1FBQUVBLHFCQUFnQkEsR0FBaEJBLFNBQWdCQTtRQUFFQSxxQkFBb0JBLEdBQXBCQSxhQUFvQkE7UUFFekdBLGlCQUFPQSxDQUFDQTtRQUVSQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUN4QkEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDMUJBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLEtBQUtBLENBQUNBO1FBRXBCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFH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R0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDekVBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLFFBQVFBLEdBQUdBLFlBQVlBLEdBQUdBLFFBQVFBLEdBQUdBLFNBQVNBLEdBQUdBLFFBQVFBLEdBQ2hGQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUMxREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsUUFBUUEsQ0FBQ0E7UUFDekVBLENBQUNBO1FBRURBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBakthVCx3QkFBR0EsR0FBVUEsS0FBS0EsQ0FBQ0E7SUFDbkJBLDZCQUFRQSxHQUFVQSxVQUFVQSxDQUFDQTtJQUM3QkEsd0JBQUdBLEdBQVVBLEtBQUtBLENBQUNBO0lBZ0tsQ0EsMkJBQUNBO0FBQURBLENBcEtBLEFBb0tDQSxFQXBLa0MsZ0JBQWdCLEVBb0tsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RSaW1MaWdodE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBTdGFnZVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvYmFzZS9TdGFnZVwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuXG4vKipcbiAqIEVmZmVjdFJpbUxpZ2h0TWV0aG9kIHByb3ZpZGVzIGEgbWV0aG9kIHRvIGFkZCByaW0gbGlnaHRpbmcgdG8gYSBtYXRlcmlhbC4gVGhpcyBhZGRzIGEgZ2xvdy1saWtlIGVmZmVjdCB0byBlZGdlcyBvZiBvYmplY3RzLlxuICovXG5jbGFzcyBFZmZlY3RSaW1MaWdodE1ldGhvZCBleHRlbmRzIEVmZmVjdE1ldGhvZEJhc2Vcbntcblx0cHVibGljIHN0YXRpYyBBREQ6c3RyaW5nID0gXCJhZGRcIjtcblx0cHVibGljIHN0YXRpYyBNVUxUSVBMWTpzdHJpbmcgPSBcIm11bHRpcGx5XCI7XG5cdHB1YmxpYyBzdGF0aWMgTUlYOnN0cmluZyA9IFwibWl4XCI7XG5cblx0cHJpdmF0ZSBfY29sb3I6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9ibGVuZE1vZGU6c3RyaW5nO1xuXHRwcml2YXRlIF9jb2xvclI6bnVtYmVyO1xuXHRwcml2YXRlIF9jb2xvckc6bnVtYmVyO1xuXHRwcml2YXRlIF9jb2xvckI6bnVtYmVyO1xuXHRwcml2YXRlIF9zdHJlbmd0aDpudW1iZXI7XG5cdHByaXZhdGUgX3Bvd2VyOm51bWJlcjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5FZmZlY3RSaW1MaWdodE1ldGhvZDwvY29kZT4gb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gY29sb3IgVGhlIGNvbG91ciBvZiB0aGUgcmltIGxpZ2h0LlxuXHQgKiBAcGFyYW0gc3RyZW5ndGggVGhlIHN0cmVuZ3RoIG9mIHRoZSByaW0gbGlnaHQuXG5cdCAqIEBwYXJhbSBwb3dlciBUaGUgcG93ZXIgb2YgdGhlIHJpbSBsaWdodC4gSGlnaGVyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBhIGhpZ2hlciBlZGdlIGZhbGwtb2ZmLlxuXHQgKiBAcGFyYW0gYmxlbmQgVGhlIGJsZW5kIG1vZGUgd2l0aCB3aGljaCB0byBhZGQgdGhlIGxpZ2h0IHRvIHRoZSBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihjb2xvcjpudW1iZXIgLyp1aW50Ki8gPSAweGZmZmZmZiwgc3RyZW5ndGg6bnVtYmVyID0gLjQsIHBvd2VyOm51bWJlciA9IDIsIGJsZW5kOnN0cmluZyA9IFwibWl4XCIpXG5cdHtcblx0XHRzdXBlcigpO1xuXG5cdFx0dGhpcy5fYmxlbmRNb2RlID0gYmxlbmQ7XG5cdFx0dGhpcy5fc3RyZW5ndGggPSBzdHJlbmd0aDtcblx0XHR0aGlzLl9wb3dlciA9IHBvd2VyO1xuXG5cdFx0dGhpcy5jb2xvciA9IGNvbG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0c2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhW21ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXggKyAzXSA9IDE7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdFZPKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdG1ldGhvZFZPLm5lZWRzTm9ybWFscyA9IHRydWU7XG5cdFx0bWV0aG9kVk8ubmVlZHNWaWV3ID0gdHJ1ZTtcblx0fVxuXG5cblx0LyoqXG5cdCAqIFRoZSBibGVuZCBtb2RlIHdpdGggd2hpY2ggdG8gYWRkIHRoZSBsaWdodCB0byB0aGUgb2JqZWN0LlxuXHQgKlxuXHQgKiBFZmZlY3RSaW1MaWdodE1ldGhvZC5NVUxUSVBMWSBtdWx0aXBsaWVzIHRoZSByaW0gbGlnaHQgd2l0aCB0aGUgbWF0ZXJpYWwncyBjb2xvdXIuXG5cdCAqIEVmZmVjdFJpbUxpZ2h0TWV0aG9kLkFERCBhZGRzIHRoZSByaW0gbGlnaHQgd2l0aCB0aGUgbWF0ZXJpYWwncyBjb2xvdXIuXG5cdCAqIEVmZmVjdFJpbUxpZ2h0TWV0aG9kLk1JWCBwcm92aWRlcyBub3JtYWwgYWxwaGEgYmxlbmRpbmcuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGJsZW5kTW9kZSgpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2JsZW5kTW9kZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYmxlbmRNb2RlKHZhbHVlOnN0cmluZylcblx0e1xuXHRcdGlmICh0aGlzLl9ibGVuZE1vZGUgPT0gdmFsdWUpXG5cdFx0XHRyZXR1cm47XG5cblx0XHR0aGlzLl9ibGVuZE1vZGUgPSB2YWx1ZTtcblxuXHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGNvbG9yIG9mIHRoZSByaW0gbGlnaHQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGNvbG9yKCk6bnVtYmVyIC8qdWludCovXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY29sb3I7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGNvbG9yKHZhbHVlOm51bWJlciAvKnVpbnQqLylcblx0e1xuXHRcdHRoaXMuX2NvbG9yID0gdmFsdWU7XG5cdFx0dGhpcy5fY29sb3JSID0gKCh2YWx1ZSA+PiAxNikgJiAweGZmKS8weGZmO1xuXHRcdHRoaXMuX2NvbG9yRyA9ICgodmFsdWUgPj4gOCkgJiAweGZmKS8weGZmO1xuXHRcdHRoaXMuX2NvbG9yQiA9ICh2YWx1ZSAmIDB4ZmYpLzB4ZmY7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHN0cmVuZ3RoIG9mIHRoZSByaW0gbGlnaHQuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHN0cmVuZ3RoKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc3RyZW5ndGg7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHN0cmVuZ3RoKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3N0cmVuZ3RoID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHBvd2VyIG9mIHRoZSByaW0gbGlnaHQuIEhpZ2hlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gYSBoaWdoZXIgZWRnZSBmYWxsLW9mZi5cblx0ICovXG5cdHB1YmxpYyBnZXQgcG93ZXIoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9wb3dlcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgcG93ZXIodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fcG93ZXIgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0dmFyIGluZGV4Om51bWJlciAvKmludCovID0gbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdGRhdGFbaW5kZXhdID0gdGhpcy5fY29sb3JSO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IHRoaXMuX2NvbG9yRztcblx0XHRkYXRhW2luZGV4ICsgMl0gPSB0aGlzLl9jb2xvckI7XG5cdFx0ZGF0YVtpbmRleCArIDRdID0gdGhpcy5fc3RyZW5ndGg7XG5cdFx0ZGF0YVtpbmRleCArIDVdID0gdGhpcy5fcG93ZXI7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBkYXRhUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBkYXRhUmVnaXN0ZXIyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXG5cdFx0bWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleCA9IGRhdGFSZWdpc3Rlci5pbmRleCo0O1xuXG5cdFx0Y29kZSArPSBcImRwMyBcIiArIHRlbXAgKyBcIi54LCBcIiArIHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50ICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJzYXQgXCIgKyB0ZW1wICsgXCIueCwgXCIgKyB0ZW1wICsgXCIueFxcblwiICtcblx0XHRcdFwic3ViIFwiICsgdGVtcCArIFwiLngsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIudywgXCIgKyB0ZW1wICsgXCIueFxcblwiICtcblx0XHRcdFwicG93IFwiICsgdGVtcCArIFwiLngsIFwiICsgdGVtcCArIFwiLngsIFwiICsgZGF0YVJlZ2lzdGVyMiArIFwiLnlcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRlbXAgKyBcIi54LCBcIiArIHRlbXAgKyBcIi54LCBcIiArIGRhdGFSZWdpc3RlcjIgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIueCwgXCIgKyBkYXRhUmVnaXN0ZXIgKyBcIi53LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIudywgXCIgKyBkYXRhUmVnaXN0ZXIgKyBcIi53LCBcIiArIHRlbXAgKyBcIi54XFxuXCI7XG5cblx0XHRpZiAodGhpcy5fYmxlbmRNb2RlID09IEVmZmVjdFJpbUxpZ2h0TWV0aG9kLkFERCkge1xuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHRlbXAgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLncsIFwiICsgZGF0YVJlZ2lzdGVyICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5elxcblwiO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5fYmxlbmRNb2RlID09IEVmZmVjdFJpbUxpZ2h0TWV0aG9kLk1VTFRJUExZKSB7XG5cdFx0XHRjb2RlICs9IFwibXVsIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIudywgXCIgKyBkYXRhUmVnaXN0ZXIgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwibXVsIFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6XFxuXCI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIGRhdGFSZWdpc3RlciArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXpcXG5cIiArXG5cdFx0XHRcdFwibXVsIFwiICsgdGVtcCArIFwiLnh5eiwgXCIgKyB0ZW1wICsgXCIueHl6LCBcIiArIHRlbXAgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGVtcCArIFwiLnh5elxcblwiO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG59XG5cbmV4cG9ydCA9IEVmZmVjdFJpbUxpZ2h0TWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/EffectRimLightMethod.ts b/lib/materials/methods/EffectRimLightMethod.ts new file mode 100644 index 000000000..793e47924 --- /dev/null +++ b/lib/materials/methods/EffectRimLightMethod.ts @@ -0,0 +1,178 @@ +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"); + +/** + * EffectRimLightMethod provides a method to add rim lighting to a material. This adds a glow-like effect to edges of objects. + */ +class EffectRimLightMethod extends EffectMethodBase +{ + public static ADD:string = "add"; + public static MULTIPLY:string = "multiply"; + public static MIX:string = "mix"; + + private _color:number /*uint*/; + private _blendMode:string; + private _colorR:number; + private _colorG:number; + private _colorB:number; + private _strength:number; + private _power:number; + + /** + * Creates a new EffectRimLightMethod object. + * + * @param color The colour of the rim light. + * @param strength The strength of the rim light. + * @param power The power of the rim light. Higher values will result in a higher edge fall-off. + * @param blend The blend mode with which to add the light to the object. + */ + constructor(color:number /*uint*/ = 0xffffff, strength:number = .4, power:number = 2, blend:string = "mix") + { + super(); + + this._blendMode = blend; + this._strength = strength; + this._power = power; + + this.color = color; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 3] = 1; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + methodVO.needsNormals = true; + methodVO.needsView = true; + } + + + /** + * The blend mode with which to add the light to the object. + * + * EffectRimLightMethod.MULTIPLY multiplies the rim light with the material's colour. + * EffectRimLightMethod.ADD adds the rim light with the material's colour. + * EffectRimLightMethod.MIX provides normal alpha blending. + */ + public get blendMode():string + { + return this._blendMode; + } + + public set blendMode(value:string) + { + if (this._blendMode == value) + return; + + this._blendMode = value; + + this.iInvalidateShaderProgram(); + } + + /** + * The color of the rim light. + */ + public get color():number /*uint*/ + { + return this._color; + } + + public set color(value:number /*uint*/) + { + this._color = value; + this._colorR = ((value >> 16) & 0xff)/0xff; + this._colorG = ((value >> 8) & 0xff)/0xff; + this._colorB = (value & 0xff)/0xff; + } + + /** + * The strength of the rim light. + */ + public get strength():number + { + return this._strength; + } + + public set strength(value:number) + { + this._strength = value; + } + + /** + * The power of the rim light. Higher values will result in a higher edge fall-off. + */ + public get power():number + { + return this._power; + } + + public set power(value:number) + { + this._power = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + data[index] = this._colorR; + data[index + 1] = this._colorG; + data[index + 2] = this._colorB; + data[index + 4] = this._strength; + data[index + 5] = this._power; + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var dataRegister:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var dataRegister2:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var code:string = ""; + + methodVO.fragmentConstantsIndex = dataRegister.index*4; + + code += "dp3 " + temp + ".x, " + sharedRegisters.viewDirFragment + ".xyz, " + sharedRegisters.normalFragment + ".xyz\n" + + "sat " + temp + ".x, " + temp + ".x\n" + + "sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x\n" + + "pow " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".y\n" + + "mul " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".x\n" + + "sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x\n" + + "mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".x\n" + + "sub " + temp + ".w, " + dataRegister + ".w, " + temp + ".x\n"; + + if (this._blendMode == EffectRimLightMethod.ADD) { + code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz\n" + + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } else if (this._blendMode == EffectRimLightMethod.MULTIPLY) { + code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz\n" + + "mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } else { + code += "sub " + temp + ".xyz, " + dataRegister + ".xyz, " + targetReg + ".xyz\n" + + "mul " + temp + ".xyz, " + temp + ".xyz, " + temp + ".w\n" + + "add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz\n"; + } + + return code; + } +} + +export = EffectRimLightMethod; \ No newline at end of file diff --git a/lib/materials/methods/NormalHeightMapMethod.js b/lib/materials/methods/NormalHeightMapMethod.js new file mode 100755 index 000000000..edd8bf8ec --- /dev/null +++ b/lib/materials/methods/NormalHeightMapMethod.js @@ -0,0 +1,75 @@ +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 NormalBasicMethod = require("awayjs-stagegl/lib/materials/methods/NormalBasicMethod"); +var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); +/** + * NormalHeightMapMethod provides a normal map method that uses a height map to calculate the normals. + */ +var NormalHeightMapMethod = (function (_super) { + __extends(NormalHeightMapMethod, _super); + /** + * Creates a new NormalHeightMapMethod method. + * + * @param heightMap The texture containing the height data. 0 means low, 1 means high. + * @param worldWidth The width of the 'world'. This is used to map uv coordinates' u component to scene dimensions. + * @param worldHeight The height of the 'world'. This is used to map the height map values to scene dimensions. + * @param worldDepth The depth of the 'world'. This is used to map uv coordinates' v component to scene dimensions. + */ + function NormalHeightMapMethod(heightMap, worldWidth, worldHeight, worldDepth) { + _super.call(this); + this.normalMap = heightMap; + this._worldXYRatio = worldWidth / worldHeight; + this._worldXZRatio = worldDepth / worldHeight; + } + /** + * @inheritDoc + */ + NormalHeightMapMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var index = methodVO.fragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index] = 1 / this.normalMap.width; + data[index + 1] = 1 / this.normalMap.height; + data[index + 2] = 0; + data[index + 3] = 1; + data[index + 4] = this._worldXYRatio; + data[index + 5] = this._worldXZRatio; + }; + Object.defineProperty(NormalHeightMapMethod.prototype, "tangentSpace", { + /** + * @inheritDoc + */ + get: function () { + return false; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + NormalHeightMapMethod.prototype.copyFrom = function (method) { + _super.prototype.copyFrom.call(this, method); + this._worldXYRatio = method._worldXYRatio; + this._worldXZRatio = method._worldXZRatio; + }; + /** + * @inheritDoc + */ + NormalHeightMapMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var temp = registerCache.getFreeFragmentVectorTemp(); + var dataReg = registerCache.getFreeFragmentConstant(); + var dataReg2 = registerCache.getFreeFragmentConstant(); + this._pNormalTextureRegister = registerCache.getFreeTextureReg(); + methodVO.texturesIndex = this._pNormalTextureRegister.index; + methodVO.fragmentConstantsIndex = dataReg.index * 4; + return ShaderCompilerHelper.getTex2DSampleCode(targetReg, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, sharedRegisters.uvVarying, "clamp") + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg + ".xzzz\n" + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp, "clamp") + "sub " + targetReg + ".x, " + targetReg + ".x, " + temp + ".x\n" + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg + ".zyzz\n" + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp, "clamp") + "sub " + targetReg + ".z, " + targetReg + ".z, " + temp + ".x\n" + "mov " + targetReg + ".y, " + dataReg + ".w\n" + "mul " + targetReg + ".xz, " + targetReg + ".xz, " + dataReg2 + ".xy\n" + "nrm " + targetReg + ".xyz, " + targetReg + ".xyz\n"; + }; + return NormalHeightMapMethod; +})(NormalBasicMethod); +module.exports = NormalHeightMapMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL25vcm1hbGhlaWdodG1hcG1ldGhvZC50cyJdLCJuYW1lcyI6WyJOb3JtYWxIZWlnaHRNYXBNZXRob2QiLCJOb3JtYWxIZWlnaHRNYXBNZXRob2QuY29uc3RydWN0b3IiLCJOb3JtYWxIZWlnaHRNYXBNZXRob2QuaUluaXRDb25zdGFudHMiLCJOb3JtYWxIZWlnaHRNYXBNZXRob2QudGFuZ2VudFNwYWNlIiwiTm9ybWFsSGVpZ2h0TWFwTWV0aG9kLmNvcHlGcm9tIiwiTm9ybWFsSGVpZ2h0TWFwTWV0aG9kLmlHZXRGcmFnbWVudENvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQU9BLElBQU8saUJBQWlCLFdBQWMsd0RBQXdELENBQUMsQ0FBQztBQUVoRyxJQUFPLG9CQUFvQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFcEcsQUFHQTs7R0FERztJQUNHLHFCQUFxQjtJQUFTQSxVQUE5QkEscUJBQXFCQSxVQUEwQkE7SUFLcERBOzs7Ozs7O09BT0dBO0lBQ0hBLFNBYktBLHFCQUFxQkEsQ0FhZEEsU0FBdUJBLEVBQUVBLFVBQWlCQSxFQUFFQSxXQUFrQkEsRUFBRUEsVUFBaUJBO1FBRTVGQyxpQkFBT0EsQ0FBQ0E7UUFFUkEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsU0FBU0EsQ0FBQ0E7UUFDM0JBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLFVBQVVBLEdBQUNBLFdBQVdBLENBQUNBO1FBQzVDQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxVQUFVQSxHQUFDQSxXQUFXQSxDQUFDQTtJQUM3Q0EsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLDhDQUFjQSxHQUFyQkEsVUFBc0JBLFlBQTZCQSxFQUFFQSxRQUFpQkE7UUFFckVFLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSxzQkFBc0JBLENBQUNBO1FBQzNEQSxJQUFJQSxJQUFJQSxHQUFpQkEsWUFBWUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUMzREEsSUFBSUEsQ0FB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LE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQ2hFQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxTQUFTQSxHQUU3RUEsb0JBQW9CQSxDQUFDQSxrQkFBa0JBLENBQUNBLElBQUlBLEVBQUVBLGVBQWVBLEVBQUVBLElBQUlBLENBQUNBLHVCQUF1QkEsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxjQUFjQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxFQUFFQSxJQUFJQSxFQUFFQSxPQUFPQSxDQUFDQSxHQUVwTkEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDaEVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLE9BQU9BLEdBQUdBLE1BQU1BLEdBQzlDQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxPQUFPQSxHQUFHQSxTQUFTQSxHQUFHQSxPQUFPQSxHQUFHQSxRQUFRQSxHQUFHQSxPQUFPQSxHQUN2RUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsQ0FBQ0E7SUFDdkRBLENBQUNBO0lBQ0ZMLDRCQUFDQTtBQUFEQSxDQXBGQSxBQW9GQ0EsRUFwRm1DLGlCQUFpQixFQW9GcEQ7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvTm9ybWFsSGVpZ2h0TWFwTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRleHR1cmUyREJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmUyREJhc2VcIik7XG5cbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBOb3JtYWxCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL05vcm1hbEJhc2ljTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRpbmdNZXRob2RCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU2hhZGluZ01ldGhvZEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyQ29tcGlsZXJIZWxwZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvdXRpbHMvU2hhZGVyQ29tcGlsZXJIZWxwZXJcIik7XG5cbi8qKlxuICogTm9ybWFsSGVpZ2h0TWFwTWV0aG9kIHByb3ZpZGVzIGEgbm9ybWFsIG1hcCBtZXRob2QgdGhhdCB1c2VzIGEgaGVpZ2h0IG1hcCB0byBjYWxjdWxhdGUgdGhlIG5vcm1hbHMuXG4gKi9cbmNsYXNzIE5vcm1hbEhlaWdodE1hcE1ldGhvZCBleHRlbmRzIE5vcm1hbEJhc2ljTWV0aG9kXG57XG5cdHByaXZhdGUgX3dvcmxkWFlSYXRpbzpudW1iZXI7XG5cdHByaXZhdGUgX3dvcmxkWFpSYXRpbzpudW1iZXI7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgTm9ybWFsSGVpZ2h0TWFwTWV0aG9kIG1ldGhvZC5cblx0ICpcblx0ICogQHBhcmFtIGhlaWdodE1hcCBUaGUgdGV4dHVyZSBjb250YWluaW5nIHRoZSBoZWlnaHQgZGF0YS4gMCBtZWFucyBsb3csIDEgbWVhbnMgaGlnaC5cblx0ICogQHBhcmFtIHdvcmxkV2lkdGggVGhlIHdpZHRoIG9mIHRoZSAnd29ybGQnLiBUaGlzIGlzIHVzZWQgdG8gbWFwIHV2IGNvb3JkaW5hdGVzJyB1IGNvbXBvbmVudCB0byBzY2VuZSBkaW1lbnNpb25zLlxuXHQgKiBAcGFyYW0gd29ybGRIZWlnaHQgVGhlIGhlaWdodCBvZiB0aGUgJ3dvcmxkJy4gVGhpcyBpcyB1c2VkIHRvIG1hcCB0aGUgaGVpZ2h0IG1hcCB2YWx1ZXMgdG8gc2NlbmUgZGltZW5zaW9ucy5cblx0ICogQHBhcmFtIHdvcmxkRGVwdGggVGhlIGRlcHRoIG9mIHRoZSAnd29ybGQnLiBUaGlzIGlzIHVzZWQgdG8gbWFwIHV2IGNvb3JkaW5hdGVzJyB2IGNvbXBvbmVudCB0byBzY2VuZSBkaW1lbnNpb25zLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoaGVpZ2h0TWFwOlRleHR1cmUyREJhc2UsIHdvcmxkV2lkdGg6bnVtYmVyLCB3b3JsZEhlaWdodDpudW1iZXIsIHdvcmxkRGVwdGg6bnVtYmVyKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdHRoaXMubm9ybWFsTWFwID0gaGVpZ2h0TWFwO1xuXHRcdHRoaXMuX3dvcmxkWFlSYXRpbyA9IHdvcmxkV2lkdGgvd29ybGRIZWlnaHQ7XG5cdFx0dGhpcy5fd29ybGRYWlJhdGlvID0gd29ybGREZXB0aC93b3JsZEhlaWdodDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHRkYXRhW2luZGV4XSA9IDEvdGhpcy5ub3JtYWxNYXAud2lkdGg7XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gMS90aGlzLm5vcm1hbE1hcC5oZWlnaHQ7XG5cdFx0ZGF0YVtpbmRleCArIDJdID0gMDtcblx0XHRkYXRhW2luZGV4ICsgM10gPSAxO1xuXHRcdGRhdGFbaW5kZXggKyA0XSA9IHRoaXMuX3dvcmxkWFlSYXRpbztcblx0XHRkYXRhW2luZGV4ICsgNV0gPSB0aGlzLl93b3JsZFhaUmF0aW87XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBnZXQgdGFuZ2VudFNwYWNlKCk6Ym9vbGVhblxuXHR7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgY29weUZyb20obWV0aG9kOlNoYWRpbmdNZXRob2RCYXNlKVxuXHR7XG5cdFx0c3VwZXIuY29weUZyb20obWV0aG9kKTtcblxuXHRcdHRoaXMuX3dvcmxkWFlSYXRpbyA9ICg8Tm9ybWFsSGVpZ2h0TWFwTWV0aG9kPiBtZXRob2QpLl93b3JsZFhZUmF0aW87XG5cdFx0dGhpcy5fd29ybGRYWlJhdGlvID0gKDxOb3JtYWxIZWlnaHRNYXBNZXRob2Q+IG1ldGhvZCkuX3dvcmxkWFpSYXRpbztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGRhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBkYXRhUmVnMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3RlciA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblx0XHRtZXRob2RWTy50ZXh0dXJlc0luZGV4ID0gdGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3Rlci5pbmRleDtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGF0YVJlZy5pbmRleCo0O1xuXG5cdFx0cmV0dXJuIFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleDJEU2FtcGxlQ29kZSh0YXJnZXRSZWcsIHNoYXJlZFJlZ2lzdGVycywgdGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3RlciwgdGhpcy5ub3JtYWxNYXAsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnJlcGVhdFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZywgc2hhcmVkUmVnaXN0ZXJzLnV2VmFyeWluZywgXCJjbGFtcFwiKSArXG5cblx0XHRcdFwiYWRkIFwiICsgdGVtcCArIFwiLCBcIiArIHNoYXJlZFJlZ2lzdGVycy51dlZhcnlpbmcgKyBcIiwgXCIgKyBkYXRhUmVnICsgXCIueHp6elxcblwiICtcblxuXHRcdFx0U2hhZGVyQ29tcGlsZXJIZWxwZXIuZ2V0VGV4MkRTYW1wbGVDb2RlKHRlbXAsIHNoYXJlZFJlZ2lzdGVycywgdGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3RlciwgdGhpcy5ub3JtYWxNYXAsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnJlcGVhdFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZywgdGVtcCwgXCJjbGFtcFwiKSArXG5cblx0XHRcdFwic3ViIFwiICsgdGFyZ2V0UmVnICsgXCIueCwgXCIgKyB0YXJnZXRSZWcgKyBcIi54LCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJhZGQgXCIgKyB0ZW1wICsgXCIsIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnV2VmFyeWluZyArIFwiLCBcIiArIGRhdGFSZWcgKyBcIi56eXp6XFxuXCIgK1xuXG5cdFx0XHRTaGFkZXJDb21waWxlckhlbHBlci5nZXRUZXgyRFNhbXBsZUNvZGUodGVtcCwgc2hhcmVkUmVnaXN0ZXJzLCB0aGlzLl9wTm9ybWFsVGV4dHVyZVJlZ2lzdGVyLCB0aGlzLm5vcm1hbE1hcCwgc2hhZGVyT2JqZWN0LnVzZVNtb290aFRleHR1cmVzLCBzaGFkZXJPYmplY3QucmVwZWF0VGV4dHVyZXMsIHNoYWRlck9iamVjdC51c2VNaXBtYXBwaW5nLCB0ZW1wLCBcImNsYW1wXCIpICtcblxuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi56LCBcIiArIHRhcmdldFJlZyArIFwiLnosIFwiICsgdGVtcCArIFwiLnhcXG5cIiArXG5cdFx0XHRcIm1vdiBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgZGF0YVJlZyArIFwiLndcXG5cIiArXG5cdFx0XHRcIm11bCBcIiArIHRhcmdldFJlZyArIFwiLnh6LCBcIiArIHRhcmdldFJlZyArIFwiLnh6LCBcIiArIGRhdGFSZWcyICsgXCIueHlcXG5cIiArXG5cdFx0XHRcIm5ybSBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyB0YXJnZXRSZWcgKyBcIi54eXpcXG5cIjtcblx0fVxufVxuXG5leHBvcnQgPSBOb3JtYWxIZWlnaHRNYXBNZXRob2Q7Il19 \ No newline at end of file diff --git a/lib/materials/methods/NormalHeightMapMethod.ts b/lib/materials/methods/NormalHeightMapMethod.ts new file mode 100644 index 000000000..5fffa81d5 --- /dev/null +++ b/lib/materials/methods/NormalHeightMapMethod.ts @@ -0,0 +1,101 @@ +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); + +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 NormalBasicMethod = require("awayjs-stagegl/lib/materials/methods/NormalBasicMethod"); +import ShadingMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadingMethodBase"); +import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); + +/** + * NormalHeightMapMethod provides a normal map method that uses a height map to calculate the normals. + */ +class NormalHeightMapMethod extends NormalBasicMethod +{ + private _worldXYRatio:number; + private _worldXZRatio:number; + + /** + * Creates a new NormalHeightMapMethod method. + * + * @param heightMap The texture containing the height data. 0 means low, 1 means high. + * @param worldWidth The width of the 'world'. This is used to map uv coordinates' u component to scene dimensions. + * @param worldHeight The height of the 'world'. This is used to map the height map values to scene dimensions. + * @param worldDepth The depth of the 'world'. This is used to map uv coordinates' v component to scene dimensions. + */ + constructor(heightMap:Texture2DBase, worldWidth:number, worldHeight:number, worldDepth:number) + { + super(); + + this.normalMap = heightMap; + this._worldXYRatio = worldWidth/worldHeight; + this._worldXZRatio = worldDepth/worldHeight; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + data[index] = 1/this.normalMap.width; + data[index + 1] = 1/this.normalMap.height; + data[index + 2] = 0; + data[index + 3] = 1; + data[index + 4] = this._worldXYRatio; + data[index + 5] = this._worldXZRatio; + } + + /** + * @inheritDoc + */ + public get tangentSpace():boolean + { + return false; + } + + /** + * @inheritDoc + */ + public copyFrom(method:ShadingMethodBase) + { + super.copyFrom(method); + + this._worldXYRatio = ( method)._worldXYRatio; + this._worldXZRatio = ( method)._worldXZRatio; + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var dataReg2:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + this._pNormalTextureRegister = registerCache.getFreeTextureReg(); + methodVO.texturesIndex = this._pNormalTextureRegister.index; + methodVO.fragmentConstantsIndex = dataReg.index*4; + + return ShaderCompilerHelper.getTex2DSampleCode(targetReg, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, sharedRegisters.uvVarying, "clamp") + + + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg + ".xzzz\n" + + + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp, "clamp") + + + "sub " + targetReg + ".x, " + targetReg + ".x, " + temp + ".x\n" + + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg + ".zyzz\n" + + + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp, "clamp") + + + "sub " + targetReg + ".z, " + targetReg + ".z, " + temp + ".x\n" + + "mov " + targetReg + ".y, " + dataReg + ".w\n" + + "mul " + targetReg + ".xz, " + targetReg + ".xz, " + dataReg2 + ".xy\n" + + "nrm " + targetReg + ".xyz, " + targetReg + ".xyz\n"; + } +} + +export = NormalHeightMapMethod; \ No newline at end of file diff --git a/lib/materials/methods/NormalSimpleWaterMethod.js b/lib/materials/methods/NormalSimpleWaterMethod.js new file mode 100755 index 000000000..9c5fc15b0 --- /dev/null +++ b/lib/materials/methods/NormalSimpleWaterMethod.js @@ -0,0 +1,158 @@ +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 NormalBasicMethod = require("awayjs-stagegl/lib/materials/methods/NormalBasicMethod"); +var ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); +/** + * NormalSimpleWaterMethod provides a basic normal map method to create water ripples by translating two wave normal maps. + */ +var NormalSimpleWaterMethod = (function (_super) { + __extends(NormalSimpleWaterMethod, _super); + /** + * Creates a new NormalSimpleWaterMethod object. + * @param waveMap1 A normal map containing one layer of a wave structure. + * @param waveMap2 A normal map containing a second layer of a wave structure. + */ + function NormalSimpleWaterMethod(waveMap1, waveMap2) { + _super.call(this); + this._useSecondNormalMap = false; + this._water1OffsetX = 0; + this._water1OffsetY = 0; + this._water2OffsetX = 0; + this._water2OffsetY = 0; + this.normalMap = waveMap1; + this.secondaryNormalMap = waveMap2; + } + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var index = methodVO.fragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index] = .5; + data[index + 1] = 0; + data[index + 2] = 0; + data[index + 3] = 1; + }; + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.iInitVO = function (shaderObject, methodVO) { + _super.prototype.iInitVO.call(this, shaderObject, methodVO); + this._useSecondNormalMap = this.normalMap != this.secondaryNormalMap; + }; + Object.defineProperty(NormalSimpleWaterMethod.prototype, "water1OffsetX", { + /** + * The translation of the first wave layer along the X-axis. + */ + get: function () { + return this._water1OffsetX; + }, + set: function (value) { + this._water1OffsetX = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(NormalSimpleWaterMethod.prototype, "water1OffsetY", { + /** + * The translation of the first wave layer along the Y-axis. + */ + get: function () { + return this._water1OffsetY; + }, + set: function (value) { + this._water1OffsetY = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(NormalSimpleWaterMethod.prototype, "water2OffsetX", { + /** + * The translation of the second wave layer along the X-axis. + */ + get: function () { + return this._water2OffsetX; + }, + set: function (value) { + this._water2OffsetX = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(NormalSimpleWaterMethod.prototype, "water2OffsetY", { + /** + * The translation of the second wave layer along the Y-axis. + */ + get: function () { + return this._water2OffsetY; + }, + set: function (value) { + this._water2OffsetY = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(NormalSimpleWaterMethod.prototype, "secondaryNormalMap", { + /** + * A second normal map that will be combined with the first to create a wave-like animation pattern. + */ + get: function () { + return this._texture2; + }, + set: function (value) { + this._texture2 = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._normalTextureRegister2 = null; + }; + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.dispose = function () { + _super.prototype.dispose.call(this); + this._texture2 = null; + }; + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + data[index + 4] = this._water1OffsetX; + data[index + 5] = this._water1OffsetY; + data[index + 6] = this._water2OffsetX; + data[index + 7] = this._water2OffsetY; + //if (this._useSecondNormalMap >= 0) + if (this._useSecondNormalMap) + stage.context.activateTexture(methodVO.texturesIndex + 1, this._texture2); + }; + /** + * @inheritDoc + */ + NormalSimpleWaterMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var temp = registerCache.getFreeFragmentVectorTemp(); + var dataReg = registerCache.getFreeFragmentConstant(); + var dataReg2 = registerCache.getFreeFragmentConstant(); + this._pNormalTextureRegister = registerCache.getFreeTextureReg(); + this._normalTextureRegister2 = this._useSecondNormalMap ? registerCache.getFreeTextureReg() : this._pNormalTextureRegister; + methodVO.texturesIndex = this._pNormalTextureRegister.index; + methodVO.fragmentConstantsIndex = dataReg.index * 4; + return "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg2 + ".xyxy\n" + ShaderCompilerHelper.getTex2DSampleCode(targetReg, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp) + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg2 + ".zwzw\n" + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._normalTextureRegister2, this._texture2, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp) + "add " + targetReg + ", " + targetReg + ", " + temp + " \n" + "mul " + targetReg + ", " + targetReg + ", " + dataReg + ".x \n" + "sub " + targetReg + ".xyz, " + targetReg + ".xyz, " + sharedRegisters.commons + ".xxx \n" + "nrm " + targetReg + ".xyz, " + targetReg + ".xyz \n"; + }; + return NormalSimpleWaterMethod; +})(NormalBasicMethod); +module.exports = NormalSimpleWaterMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL25vcm1hbHNpbXBsZXdhdGVybWV0aG9kLnRzIl0sIm5hbWVzIjpbIk5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kIiwiTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2QuY29uc3RydWN0b3IiLCJOb3JtYWxTaW1wbGVXYXRlck1ldGhvZC5pSW5pdENvbnN0YW50cyIsIk5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kLmlJbml0Vk8iLCJOb3JtYWxTaW1wbGVXYXRlck1ldGhvZC53YXRlcjFPZmZzZXRYIiwiTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2Qud2F0ZXIxT2Zmc2V0WSIsIk5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kLndhdGVyMk9mZnNldFgiLCJOb3JtYWxTaW1wbGVXYXRlck1ldGhvZC53YXRlcjJPZmZzZXRZIiwiTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2Quc2Vjb25kYXJ5Tm9ybWFsTWFwIiwiTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2QuaUNsZWFuQ29tcGlsYXRpb25EYXRhIiwiTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2QuZGlzcG9zZSIsIk5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kLmlBY3RpdmF0ZSIsIk5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kLmlHZXRGcmFnbWVudENvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVNBLElBQU8saUJBQWlCLFdBQWMsd0RBQXdELENBQUMsQ0FBQztBQUNoRyxJQUFPLG9CQUFvQixXQUFjLHlEQUF5RCxDQUFDLENBQUM7QUFFcEcsQUFHQTs7R0FERztJQUNHLHVCQUF1QjtJQUFTQSxVQUFoQ0EsdUJBQXVCQSxVQUEwQkE7SUFVdERBOzs7O09BSUdBO0lBQ0hBLFNBZktBLHVCQUF1QkEsQ0FlaEJBLFFBQXNCQSxFQUFFQSxRQUFzQkE7UUFFekRDLGlCQUFPQSxDQUFDQTtRQWJEQSx3QkFBbUJBLEdBQVdBLEtBQUtBLENBQUNBO1FBQ3BDQSxtQkFBY0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7UUFDMUJBLG1CQUFj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QSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUM5RUEsb0JBQW9CQSxDQUFDQSxrQkFBa0JBLENBQUNBLElBQUlBLEVBQUVBLGVBQWVBLEVBQUVBLElBQUlBLENBQUNBLHVCQUF1QkEsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsWUFBWUEsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxZQUFZQSxDQUFDQSxjQUFjQSxFQUFFQSxZQUFZQSxDQUFDQSxhQUFhQSxFQUFFQSxJQUFJQSxDQUFDQSxHQUMzTUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FDNURBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLFNBQVNBLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLE9BQU9BLEdBQ2hFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxRQUFRQSxHQUFHQSxlQUFlQSxDQUFDQSxPQUFPQSxHQUFHQSxTQUFTQSxHQUMxRkEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsUUFBUUEsR0FBR0EsU0FBU0EsR0FBR0EsZUFBZUEsQ0FBQ0E7SUFDOURBLENBQUNBO0lBQ0ZaLDhCQUFDQTtBQUFEQSxDQTNLQSxBQTJLQ0EsRUEzS3FDLGlCQUFpQixFQTJLdEQ7QUFFRCxBQUFpQyxpQkFBeEIsdUJBQXVCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IElDb250ZXh0U3RhZ2VHTFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9zdGFnZWdsL0lDb250ZXh0U3RhZ2VHTFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBOb3JtYWxCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL05vcm1hbEJhc2ljTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIE5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kIHByb3ZpZGVzIGEgYmFzaWMgbm9ybWFsIG1hcCBtZXRob2QgdG8gY3JlYXRlIHdhdGVyIHJpcHBsZXMgYnkgdHJhbnNsYXRpbmcgdHdvIHdhdmUgbm9ybWFsIG1hcHMuXG4gKi9cbmNsYXNzIE5vcm1hbFNpbXBsZVdhdGVyTWV0aG9kIGV4dGVuZHMgTm9ybWFsQmFzaWNNZXRob2Rcbntcblx0cHJpdmF0ZSBfdGV4dHVyZTI6VGV4dHVyZTJEQmFzZTtcblx0cHJpdmF0ZSBfbm9ybWFsVGV4dHVyZVJlZ2lzdGVyMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdHByaXZhdGUgX3VzZVNlY29uZE5vcm1hbE1hcDpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgX3dhdGVyMU9mZnNldFg6bnVtYmVyID0gMDtcblx0cHJpdmF0ZSBfd2F0ZXIxT2Zmc2V0WTpudW1iZXIgPSAwO1xuXHRwcml2YXRlIF93YXRlcjJPZmZzZXRYOm51bWJlciA9IDA7XG5cdHByaXZhdGUgX3dhdGVyMk9mZnNldFk6bnVtYmVyID0gMDtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBOb3JtYWxTaW1wbGVXYXRlck1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSB3YXZlTWFwMSBBIG5vcm1hbCBtYXAgY29udGFpbmluZyBvbmUgbGF5ZXIgb2YgYSB3YXZlIHN0cnVjdHVyZS5cblx0ICogQHBhcmFtIHdhdmVNYXAyIEEgbm9ybWFsIG1hcCBjb250YWluaW5nIGEgc2Vjb25kIGxheWVyIG9mIGEgd2F2ZSBzdHJ1Y3R1cmUuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih3YXZlTWFwMTpUZXh0dXJlMkRCYXNlLCB3YXZlTWFwMjpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLm5vcm1hbE1hcCA9IHdhdmVNYXAxO1xuXHRcdHRoaXMuc2Vjb25kYXJ5Tm9ybWFsTWFwID0gd2F2ZU1hcDI7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHR2YXIgaW5kZXg6bnVtYmVyID0gbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdGRhdGFbaW5kZXhdID0gLjU7XG5cdFx0ZGF0YVtpbmRleCArIDFdID0gMDtcblx0XHRkYXRhW2luZGV4ICsgMl0gPSAwO1xuXHRcdGRhdGFbaW5kZXggKyAzXSA9IDE7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdFZPKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHN1cGVyLmlJbml0Vk8oc2hhZGVyT2JqZWN0LCBtZXRob2RWTyk7XG5cblx0XHR0aGlzLl91c2VTZWNvbmROb3JtYWxNYXAgPSB0aGlzLm5vcm1hbE1hcCAhPSB0aGlzLnNlY29uZGFyeU5vcm1hbE1hcDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgdHJhbnNsYXRpb24gb2YgdGhlIGZpcnN0IHdhdmUgbGF5ZXIgYWxvbmcgdGhlIFgtYXhpcy5cblx0ICovXG5cdHB1YmxpYyBnZXQgd2F0ZXIxT2Zmc2V0WCgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3dhdGVyMU9mZnNldFg7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHdhdGVyMU9mZnNldFgodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fd2F0ZXIxT2Zmc2V0WCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSB0cmFuc2xhdGlvbiBvZiB0aGUgZmlyc3Qgd2F2ZSBsYXllciBhbG9uZyB0aGUgWS1heGlzLlxuXHQgKi9cblx0cHVibGljIGdldCB3YXRlcjFPZmZzZXRZKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fd2F0ZXIxT2Zmc2V0WTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgd2F0ZXIxT2Zmc2V0WSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl93YXRlcjFPZmZzZXRZID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRyYW5zbGF0aW9uIG9mIHRoZSBzZWNvbmQgd2F2ZSBsYXllciBhbG9uZyB0aGUgWC1heGlzLlxuXHQgKi9cblx0cHVibGljIGdldCB3YXRlcjJPZmZzZXRYKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fd2F0ZXIyT2Zmc2V0WDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgd2F0ZXIyT2Zmc2V0WCh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl93YXRlcjJPZmZzZXRYID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRyYW5zbGF0aW9uIG9mIHRoZSBzZWNvbmQgd2F2ZSBsYXllciBhbG9uZyB0aGUgWS1heGlzLlxuXHQgKi9cblx0cHVibGljIGdldCB3YXRlcjJPZmZzZXRZKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fd2F0ZXIyT2Zmc2V0WTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgd2F0ZXIyT2Zmc2V0WSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl93YXRlcjJPZmZzZXRZID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQSBzZWNvbmQgbm9ybWFsIG1hcCB0aGF0IHdpbGwgYmUgY29tYmluZWQgd2l0aCB0aGUgZmlyc3QgdG8gY3JlYXRlIGEgd2F2ZS1saWtlIGFuaW1hdGlvbiBwYXR0ZXJuLlxuXHQgKi9cblx0cHVibGljIGdldCBzZWNvbmRhcnlOb3JtYWxNYXAoKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdGV4dHVyZTI7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHNlY29uZGFyeU5vcm1hbE1hcCh2YWx1ZTpUZXh0dXJlMkRCYXNlKVxuXHR7XG5cdFx0dGhpcy5fdGV4dHVyZTIgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0XHR0aGlzLl9ub3JtYWxUZXh0dXJlUmVnaXN0ZXIyID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cdFx0c3VwZXIuZGlzcG9zZSgpO1xuXHRcdHRoaXMuX3RleHR1cmUyID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c3VwZXIuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblxuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cdFx0dmFyIGluZGV4Om51bWJlciA9IG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cblx0XHRkYXRhW2luZGV4ICsgNF0gPSB0aGlzLl93YXRlcjFPZmZzZXRYO1xuXHRcdGRhdGFbaW5kZXggKyA1XSA9IHRoaXMuX3dhdGVyMU9mZnNldFk7XG5cdFx0ZGF0YVtpbmRleCArIDZdID0gdGhpcy5fd2F0ZXIyT2Zmc2V0WDtcblx0XHRkYXRhW2luZGV4ICsgN10gPSB0aGlzLl93YXRlcjJPZmZzZXRZO1xuXG5cdFx0Ly9pZiAodGhpcy5fdXNlU2Vjb25kTm9ybWFsTWFwID49IDApXG5cdFx0aWYgKHRoaXMuX3VzZVNlY29uZE5vcm1hbE1hcClcblx0XHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZVRleHR1cmUobWV0aG9kVk8udGV4dHVyZXNJbmRleCArIDEsIHRoaXMuX3RleHR1cmUyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0dmFyIGRhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBkYXRhUmVnMjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3RlciA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblx0XHR0aGlzLl9ub3JtYWxUZXh0dXJlUmVnaXN0ZXIyID0gdGhpcy5fdXNlU2Vjb25kTm9ybWFsTWFwPyByZWdpc3RlckNhY2hlLmdldEZyZWVUZXh0dXJlUmVnKCk6dGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3Rlcjtcblx0XHRtZXRob2RWTy50ZXh0dXJlc0luZGV4ID0gdGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3Rlci5pbmRleDtcblxuXHRcdG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSBkYXRhUmVnLmluZGV4KjQ7XG5cblx0XHRyZXR1cm4gXCJhZGQgXCIgKyB0ZW1wICsgXCIsIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnV2VmFyeWluZyArIFwiLCBcIiArIGRhdGFSZWcyICsgXCIueHl4eVxcblwiICtcblx0XHRcdFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleDJEU2FtcGxlQ29kZSh0YXJnZXRSZWcsIHNoYXJlZFJlZ2lzdGVycywgdGhpcy5fcE5vcm1hbFRleHR1cmVSZWdpc3RlciwgdGhpcy5ub3JtYWxNYXAsIHNoYWRlck9iamVjdC51c2VTbW9vdGhUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnJlcGVhdFRleHR1cmVzLCBzaGFkZXJPYmplY3QudXNlTWlwbWFwcGluZywgdGVtcCkgK1xuXHRcdFx0XCJhZGQgXCIgKyB0ZW1wICsgXCIsIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnV2VmFyeWluZyArIFwiLCBcIiArIGRhdGFSZWcyICsgXCIuend6d1xcblwiICtcblx0XHRcdFNoYWRlckNvbXBpbGVySGVscGVyLmdldFRleDJEU2FtcGxlQ29kZSh0ZW1wLCBzaGFyZWRSZWdpc3RlcnMsIHRoaXMuX25vcm1hbFRleHR1cmVSZWdpc3RlcjIsIHRoaXMuX3RleHR1cmUyLCBzaGFkZXJPYmplY3QudXNlU21vb3RoVGV4dHVyZXMsIHNoYWRlck9iamVjdC5yZXBlYXRUZXh0dXJlcywgc2hhZGVyT2JqZWN0LnVzZU1pcG1hcHBpbmcsIHRlbXApICtcblx0XHRcdFwiYWRkIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGVtcCArIFwiXHRcdFxcblwiICtcblx0XHRcdFwibXVsIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgdGFyZ2V0UmVnICsgXCIsIFwiICsgZGF0YVJlZyArIFwiLnhcdFxcblwiICtcblx0XHRcdFwic3ViIFwiICsgdGFyZ2V0UmVnICsgXCIueHl6LCBcIiArIHRhcmdldFJlZyArIFwiLnh5eiwgXCIgKyBzaGFyZWRSZWdpc3RlcnMuY29tbW9ucyArIFwiLnh4eFx0XFxuXCIgK1xuXHRcdFx0XCJucm0gXCIgKyB0YXJnZXRSZWcgKyBcIi54eXosIFwiICsgdGFyZ2V0UmVnICsgXCIueHl6XHRcdFx0XHRcdFx0XHRcXG5cIjtcblx0fVxufVxuXG5leHBvcnQgPSBOb3JtYWxTaW1wbGVXYXRlck1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/NormalSimpleWaterMethod.ts b/lib/materials/methods/NormalSimpleWaterMethod.ts new file mode 100755 index 000000000..d097aae51 --- /dev/null +++ b/lib/materials/methods/NormalSimpleWaterMethod.ts @@ -0,0 +1,189 @@ +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 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 NormalBasicMethod = require("awayjs-stagegl/lib/materials/methods/NormalBasicMethod"); +import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); + +/** + * NormalSimpleWaterMethod provides a basic normal map method to create water ripples by translating two wave normal maps. + */ +class NormalSimpleWaterMethod extends NormalBasicMethod +{ + private _texture2:Texture2DBase; + private _normalTextureRegister2:ShaderRegisterElement; + private _useSecondNormalMap:boolean = false; + private _water1OffsetX:number = 0; + private _water1OffsetY:number = 0; + private _water2OffsetX:number = 0; + private _water2OffsetY:number = 0; + + /** + * Creates a new NormalSimpleWaterMethod object. + * @param waveMap1 A normal map containing one layer of a wave structure. + * @param waveMap2 A normal map containing a second layer of a wave structure. + */ + constructor(waveMap1:Texture2DBase, waveMap2:Texture2DBase) + { + super(); + this.normalMap = waveMap1; + this.secondaryNormalMap = waveMap2; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + var index:number = methodVO.fragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + data[index] = .5; + data[index + 1] = 0; + data[index + 2] = 0; + data[index + 3] = 1; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + super.iInitVO(shaderObject, methodVO); + + this._useSecondNormalMap = this.normalMap != this.secondaryNormalMap; + } + + /** + * The translation of the first wave layer along the X-axis. + */ + public get water1OffsetX():number + { + return this._water1OffsetX; + } + + public set water1OffsetX(value:number) + { + this._water1OffsetX = value; + } + + /** + * The translation of the first wave layer along the Y-axis. + */ + public get water1OffsetY():number + { + return this._water1OffsetY; + } + + public set water1OffsetY(value:number) + { + this._water1OffsetY = value; + } + + /** + * The translation of the second wave layer along the X-axis. + */ + public get water2OffsetX():number + { + return this._water2OffsetX; + } + + public set water2OffsetX(value:number) + { + this._water2OffsetX = value; + } + + /** + * The translation of the second wave layer along the Y-axis. + */ + public get water2OffsetY():number + { + return this._water2OffsetY; + } + + public set water2OffsetY(value:number) + { + this._water2OffsetY = value; + } + + /** + * A second normal map that will be combined with the first to create a wave-like animation pattern. + */ + public get secondaryNormalMap():Texture2DBase + { + return this._texture2; + } + + public set secondaryNormalMap(value:Texture2DBase) + { + this._texture2 = value; + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._normalTextureRegister2 = null; + } + + /** + * @inheritDoc + */ + public dispose() + { + super.dispose(); + this._texture2 = null; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + super.iActivate(shaderObject, methodVO, stage); + + var data:Array = shaderObject.fragmentConstantData; + var index:number = methodVO.fragmentConstantsIndex; + + data[index + 4] = this._water1OffsetX; + data[index + 5] = this._water1OffsetY; + data[index + 6] = this._water2OffsetX; + data[index + 7] = this._water2OffsetY; + + //if (this._useSecondNormalMap >= 0) + if (this._useSecondNormalMap) + ( stage.context).activateTexture(methodVO.texturesIndex + 1, this._texture2); + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var dataReg2:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + this._pNormalTextureRegister = registerCache.getFreeTextureReg(); + this._normalTextureRegister2 = this._useSecondNormalMap? registerCache.getFreeTextureReg():this._pNormalTextureRegister; + methodVO.texturesIndex = this._pNormalTextureRegister.index; + + methodVO.fragmentConstantsIndex = dataReg.index*4; + + return "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg2 + ".xyxy\n" + + ShaderCompilerHelper.getTex2DSampleCode(targetReg, sharedRegisters, this._pNormalTextureRegister, this.normalMap, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp) + + "add " + temp + ", " + sharedRegisters.uvVarying + ", " + dataReg2 + ".zwzw\n" + + ShaderCompilerHelper.getTex2DSampleCode(temp, sharedRegisters, this._normalTextureRegister2, this._texture2, shaderObject.useSmoothTextures, shaderObject.repeatTextures, shaderObject.useMipmapping, temp) + + "add " + targetReg + ", " + targetReg + ", " + temp + " \n" + + "mul " + targetReg + ", " + targetReg + ", " + dataReg + ".x \n" + + "sub " + targetReg + ".xyz, " + targetReg + ".xyz, " + sharedRegisters.commons + ".xxx \n" + + "nrm " + targetReg + ".xyz, " + targetReg + ".xyz \n"; + } +} + +export = NormalSimpleWaterMethod; \ No newline at end of file diff --git a/lib/materials/methods/ShadowCascadeMethod.js b/lib/materials/methods/ShadowCascadeMethod.js new file mode 100755 index 000000000..ce7bb735c --- /dev/null +++ b/lib/materials/methods/ShadowCascadeMethod.js @@ -0,0 +1,200 @@ +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 DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +var Event = require("awayjs-core/lib/events/Event"); +var ShadingMethodEvent = require("awayjs-stagegl/lib/events/ShadingMethodEvent"); +var MethodVO = require("awayjs-stagegl/lib/materials/compilation/MethodVO"); +var ShadowMapMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMapMethodBase"); +/** + * ShadowCascadeMethod is a shadow map method to apply cascade shadow mapping on materials. + * Must be used with a DirectionalLight with a CascadeShadowMapper assigned to its shadowMapper property. + * + * @see away.lights.CascadeShadowMapper + */ +var ShadowCascadeMethod = (function (_super) { + __extends(ShadowCascadeMethod, _super); + /** + * Creates a new ShadowCascadeMethod object. + * + * @param shadowMethodBase The shadow map sampling method used to sample individual cascades (fe: ShadowHardMethod, ShadowSoftMethod) + */ + function ShadowCascadeMethod(shadowMethodBase) { + var _this = this; + _super.call(this, shadowMethodBase.castingLight); + this._baseMethod = shadowMethodBase; + if (!(this._pCastingLight instanceof DirectionalLight)) + throw new Error("ShadowCascadeMethod is only compatible with DirectionalLight"); + this._cascadeShadowMapper = this._pCastingLight.shadowMapper; + if (!this._cascadeShadowMapper) + throw new Error("ShadowCascadeMethod requires a light that has a CascadeShadowMapper instance assigned to shadowMapper."); + this._cascadeShadowMapper.addEventListener(Event.CHANGE, function (event) { return _this.onCascadeChange(event); }); + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, function (event) { return _this.onShaderInvalidated(event); }); + } + Object.defineProperty(ShadowCascadeMethod.prototype, "baseMethod", { + /** + * The shadow map sampling method used to sample individual cascades. These are typically those used in conjunction + * with a DirectionalShadowMapper. + * + * @see ShadowHardMethod + * @see ShadowSoftMethod + */ + get: function () { + return this._baseMethod; + }, + set: function (value) { + var _this = this; + if (this._baseMethod == value) + return; + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, function (event) { return _this.onShaderInvalidated(event); }); + this._baseMethod = value; + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, function (event) { return _this.onShaderInvalidated(event); }); + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iInitVO = function (shaderObject, methodVO) { + var tempVO = new MethodVO(this._baseMethod); + this._baseMethod.iInitVO(shaderObject, tempVO); + methodVO.needsGlobalVertexPos = true; + methodVO.needsProjection = true; + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var fragmentData = shaderObject.fragmentConstantData; + var vertexData = shaderObject.vertexConstantData; + var index = methodVO.fragmentConstantsIndex; + fragmentData[index] = 1.0; + fragmentData[index + 1] = 1 / 255.0; + fragmentData[index + 2] = 1 / 65025.0; + fragmentData[index + 3] = 1 / 16581375.0; + fragmentData[index + 6] = .5; + fragmentData[index + 7] = -.5; + index = methodVO.vertexConstantsIndex; + vertexData[index] = .5; + vertexData[index + 1] = -.5; + vertexData[index + 2] = 0; + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._cascadeProjections = null; + this._depthMapCoordVaryings = null; + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iGetVertexCode = function (shaderObject, methodVO, registerCache, sharedRegisters) { + var code = ""; + var dataReg = registerCache.getFreeVertexConstant(); + this.initProjectionsRegs(registerCache); + methodVO.vertexConstantsIndex = dataReg.index * 4; + var temp = registerCache.getFreeVertexVectorTemp(); + for (var i = 0; i < this._cascadeShadowMapper.numCascades; ++i) { + code += "m44 " + temp + ", " + sharedRegisters.globalPositionVertex + ", " + this._cascadeProjections[i] + "\n" + "add " + this._depthMapCoordVaryings[i] + ", " + temp + ", " + dataReg + ".zzwz\n"; + } + return code; + }; + /** + * Creates the registers for the cascades' projection coordinates. + */ + ShadowCascadeMethod.prototype.initProjectionsRegs = function (registerCache) { + this._cascadeProjections = new Array(this._cascadeShadowMapper.numCascades); + this._depthMapCoordVaryings = new Array(this._cascadeShadowMapper.numCascades); + for (var i = 0; i < this._cascadeShadowMapper.numCascades; ++i) { + this._depthMapCoordVaryings[i] = registerCache.getFreeVarying(); + this._cascadeProjections[i] = registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + } + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var numCascades = this._cascadeShadowMapper.numCascades; + var depthMapRegister = registerCache.getFreeTextureReg(); + var decReg = registerCache.getFreeFragmentConstant(); + var dataReg = registerCache.getFreeFragmentConstant(); + var planeDistanceReg = registerCache.getFreeFragmentConstant(); + var planeDistances = Array(planeDistanceReg + ".x", planeDistanceReg + ".y", planeDistanceReg + ".z", planeDistanceReg + ".w"); + var code; + methodVO.fragmentConstantsIndex = decReg.index * 4; + methodVO.texturesIndex = depthMapRegister.index; + var inQuad = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(inQuad, 1); + var uvCoord = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(uvCoord, 1); + // assume lowest partition is selected, will be overwritten later otherwise + code = "mov " + uvCoord + ", " + this._depthMapCoordVaryings[numCascades - 1] + "\n"; + for (var i = numCascades - 2; i >= 0; --i) { + var uvProjection = this._depthMapCoordVaryings[i]; + // calculate if in texturemap (result == 0 or 1, only 1 for a single partition) + code += "slt " + inQuad + ".z, " + sharedRegisters.projectionFragment + ".z, " + planeDistances[i] + "\n"; // z = x > minX, w = y > minY + var temp = registerCache.getFreeFragmentVectorTemp(); + // linearly interpolate between old and new uv coords using predicate value == conditional toggle to new value if predicate == 1 (true) + code += "sub " + temp + ", " + uvProjection + ", " + uvCoord + "\n" + "mul " + temp + ", " + temp + ", " + inQuad + ".z\n" + "add " + uvCoord + ", " + uvCoord + ", " + temp + "\n"; + } + registerCache.removeFragmentTempUsage(inQuad); + code += "div " + uvCoord + ", " + uvCoord + ", " + uvCoord + ".w\n" + "mul " + uvCoord + ".xy, " + uvCoord + ".xy, " + dataReg + ".zw\n" + "add " + uvCoord + ".xy, " + uvCoord + ".xy, " + dataReg + ".zz\n"; + code += this._baseMethod._iGetCascadeFragmentCode(shaderObject, methodVO, decReg, depthMapRegister, uvCoord, targetReg, registerCache, sharedRegisters) + "add " + targetReg + ".w, " + targetReg + ".w, " + dataReg + ".y\n"; + registerCache.removeFragmentTempUsage(uvCoord); + return code; + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + stage.context.activateTexture(methodVO.texturesIndex, this._pCastingLight.shadowMapper.depthMap); + var vertexData = shaderObject.vertexConstantData; + var vertexIndex = methodVO.vertexConstantsIndex; + shaderObject.vertexConstantData[methodVO.vertexConstantsIndex + 3] = -1 / (this._cascadeShadowMapper.depth * this._pEpsilon); + var numCascades = this._cascadeShadowMapper.numCascades; + vertexIndex += 4; + for (var k = 0; k < numCascades; ++k) { + this._cascadeShadowMapper.getDepthProjections(k).copyRawDataTo(vertexData, vertexIndex, true); + vertexIndex += 16; + } + var fragmentData = shaderObject.fragmentConstantData; + var fragmentIndex = methodVO.fragmentConstantsIndex; + fragmentData[fragmentIndex + 5] = 1 - this._pAlpha; + var nearPlaneDistances = this._cascadeShadowMapper._iNearPlaneDistances; + fragmentIndex += 8; + for (var i = 0; i < numCascades; ++i) + fragmentData[fragmentIndex + i] = nearPlaneDistances[i]; + this._baseMethod.iActivateForCascade(shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + ShadowCascadeMethod.prototype.iSetRenderState = function (shaderObject, methodVO, renderable, stage, camera) { + }; + /** + * Called when the shadow mappers cascade configuration changes. + */ + ShadowCascadeMethod.prototype.onCascadeChange = function (event) { + this.iInvalidateShaderProgram(); + }; + /** + * Called when the base method's shader code is invalidated. + */ + ShadowCascadeMethod.prototype.onShaderInvalidated = function (event) { + this.iInvalidateShaderProgram(); + }; + return ShadowCascadeMethod; +})(ShadowMapMethodBase); +module.exports = ShadowCascadeMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NoYWRvd2Nhc2NhZGVtZXRob2QudHMiXSwibmFtZXMiOlsiU2hhZG93Q2FzY2FkZU1ldGhvZCIsIlNoYWRvd0Nhc2NhZGVNZXRob2QuY29uc3RydWN0b3IiLCJTaGFkb3dDYXNjYWRlTWV0aG9kLmJhc2VNZXRob2QiLCJTaGFkb3dDYXNjYWRlTWV0aG9kLmlJbml0Vk8iLCJTaGFkb3dDYXNjYWRlTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiU2hhZG93Q2FzY2FkZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJTaGFkb3dDYXNjYWRlTWV0aG9kLmlHZXRWZXJ0ZXhDb2RlIiwiU2hhZG93Q2FzY2FkZU1ldGhvZC5pbml0UHJvamVjdGlvbnNSZWdzIiwiU2hhZG93Q2FzY2FkZU1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIiwiU2hhZG93Q2FzY2FkZU1ldGhvZC5pQWN0aXZhdGUiLCJTaGFkb3dDYXNjYWRlTWV0aG9kLmlTZXRSZW5kZXJTdGF0ZSIsIlNoYWRvd0Nhc2NhZGVNZXRob2Qub25DYXNjYWRlQ2hhbmdlIiwiU2hhZG93Q2FzY2FkZU1ldGhvZC5vblNoYWRlckludmFsaWRhdGVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxJQUFPLGdCQUFnQixXQUFlLDJDQUEyQyxDQUFDLENBQUM7QUFDbkYsSUFBTyxLQUFLLFdBQWlCLDhCQUE4QixDQUFDLENBQUM7QUFPN0QsSUFBTyxrQkFBa0IsV0FBYyw4Q0FBOEMsQ0FBQyxDQUFDO0FBQ3ZGLElBQU8sUUFBUSxXQUFpQixtREFBbUQsQ0FBQyxDQUFDO0FBTXJGLElBQU8sbUJBQW1CLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUlwRyxBQU1BOzs7OztHQURHO0lBQ0csbUJBQW1CO0lBQVNBLFVBQTVCQSxtQkFBbUJBLFVBQTRCQTtJQU9wREE7Ozs7T0FJR0E7SUFDSEEsU0FaS0EsbUJBQW1CQSxDQVlaQSxnQkFBaUNBO1FBWjlDQyxpQkFtUENBO1FBck9DQSxrQkFBTUEs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WUFBWUEsR0FBeUJBLElBQUlBLENBQUNBLHNCQUFzQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFeEVBLEFBQ0FBLCtFQUQrRUE7WUFDL0VBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLGVBQWVBLENBQUNBLGtCQUFrQkEsR0FBR0EsTUFBTUEsR0FBR0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsRUFBRUEsNkJBQTZCQTtZQUV4SUEsSUFBSUEsSUFBSUEsR0FBeUJBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7WUFFM0VBLEFBQ0FBLHVJQUR1SUE7WUFDdklBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLFlBQVlBLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLEdBQ2xFQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUNwREEsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDekRBLENBQUNBO1FBRURBLGFBQWFBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7UUFFOUNBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLEdBQUdBLE9BQU9BLEdBQUdBLE1BQU1BLEdBQ2xFQSxNQUFNQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUNsRUEsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsR0FBR0EsT0FBT0EsQ0FBQ0E7UUFFcEVBLElBQUlBLElBQUlBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLHdCQUF3QkEsQ0FBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsTUFBTUEsRUFBRUEsZ0JBQWdCQSxFQUFFQSxPQUFPQSxFQUFFQSxTQUFTQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxHQUN0SkEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFFckVBLGFBQWFBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0E7UUFFL0NBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRURSOztPQUVHQTtJQUNJQSx1Q0FBU0EsR0FBaEJBLFVBQWlCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLEtBQVdBO1FBRTFEUyxLQUFLQSxDQUFDQSxPQUFRQSxDQUFDQSxlQUFlQSxDQUFDQSxRQUFRQSxDQUFDQSxhQUFhQSxFQUFrQkEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsWUFBWUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7UUFFcklBLElBQUlBLFVBQVVBLEdBQWlCQSxZQUFZQSxDQUFDQSxrQkFBa0JBLENBQUNBO1FBQy9EQSxJQUFJQSxXQUFXQSxHQUFVQSxRQUFRQSxDQUFDQSxvQkFBb0JBLENBQUNBO1FBRXZEQSxZQUFZQSxDQUFDQSxrQkFBa0JBLENBQUNBLFFBQVFBLENBQUNBLG9CQUFvQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxLQUFLQSxHQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUV6SEEsSUFBSUEsV0FBV0EsR0FBVUEsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQSxXQUFXQSxDQUFDQTtRQUMvREEsV0FBV0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDakJBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQVVBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFdBQVdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBO1lBQzdDQSxJQUFJQSxDQUFDQSxvQkFBb0JBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsVUFBVUEsRUFBRUEsV0FBV0EsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDOUZBLFdBQVdBLElBQUlBLEVBQUVBLENBQUNBO1FBQ25CQSxDQUFDQTtRQUVEQSxJQUFJQSxZQUFZQSxHQUFpQkEsWUFBWUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUNuRUEsSUFBSUEsYUFBYUEsR0FBVUEsUUFBUUEsQ0FBQ0Esc0JBQXNCQSxDQUFDQTtRQUMzREEsWUFBWUEsQ0FBQ0EsYUFBYUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFFbkRBLElBQUlBLGtCQUFrQkEsR0FBaUJBLElBQUlBLENBQUNBLG9CQUFvQkEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUV0RkEsYUFBYUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDbkJBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQVVBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFdBQVdBLEVBQUVBLEVBQUVBLENBQUNBO1lBQzFDQSxZQUFZQSxDQUFDQSxhQUFhQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxrQkFBa0JBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBRXpEQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxtQkFBbUJBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO0lBQ3JFQSxDQUFDQTtJQUVEVDs7T0FFR0E7SUFDSUEsNkNBQWVBLEdBQXRCQSxVQUF1QkEsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxVQUF5QkEsRUFBRUEsS0FBV0EsRUFBRUEsTUFBYUE7SUFFOUhVLENBQUNBO0lBRURWOztPQUVHQTtJQUNLQSw2Q0FBZUEsR0FBdkJBLFVBQXdCQSxLQUFXQTtRQUVsQ1csSUFBSUEsQ0FBQ0Esd0JBQXdCQSxFQUFFQSxDQUFDQTtJQUNqQ0EsQ0FBQ0E7SUFFRFg7O09BRUdBO0lBQ0tBLGlEQUFtQkEsR0FBM0JBLFVBQTRCQSxLQUF3QkE7UUFFbkRZLElBQUlBLENBQUNBLHdCQUF3QkEsRUFBRUEsQ0FBQ0E7SUFDakNBLENBQUNBO0lBQ0ZaLDBCQUFDQTtBQUFEQSxDQW5QQSxBQW1QQ0EsRUFuUGlDLG1CQUFtQixFQW1QcEQ7QUFFRCxBQUE2QixpQkFBcEIsbUJBQW1CLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvU2hhZG93Q2FzY2FkZU1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5pbXBvcnQgRGlyZWN0aW9uYWxMaWdodFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvRGlyZWN0aW9uYWxMaWdodFwiKTtcbmltcG9ydCBFdmVudFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9FdmVudFwiKTtcbmltcG9ydCBDYXNjYWRlU2hhZG93TWFwcGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL3NoYWRvd21hcHBlcnMvQ2FzY2FkZVNoYWRvd01hcHBlclwiKTtcbmltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlMkRCYXNlXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgU2hhZGluZ01ldGhvZEV2ZW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvZXZlbnRzL1NoYWRpbmdNZXRob2RFdmVudFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBTaGFkb3dNYXBNZXRob2RCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU2hhZG93TWFwTWV0aG9kQmFzZVwiKTtcbmltcG9ydCBTaGFkb3dNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TaGFkb3dNZXRob2RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlckNvbXBpbGVySGVscGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL1NoYWRlckNvbXBpbGVySGVscGVyXCIpO1xuXG4vKipcbiAqIFNoYWRvd0Nhc2NhZGVNZXRob2QgaXMgYSBzaGFkb3cgbWFwIG1ldGhvZCB0byBhcHBseSBjYXNjYWRlIHNoYWRvdyBtYXBwaW5nIG9uIG1hdGVyaWFscy5cbiAqIE11c3QgYmUgdXNlZCB3aXRoIGEgRGlyZWN0aW9uYWxMaWdodCB3aXRoIGEgQ2FzY2FkZVNoYWRvd01hcHBlciBhc3NpZ25lZCB0byBpdHMgc2hhZG93TWFwcGVyIHByb3BlcnR5LlxuICpcbiAqIEBzZWUgYXdheS5saWdodHMuQ2FzY2FkZVNoYWRvd01hcHBlclxuICovXG5jbGFzcyBTaGFkb3dDYXNjYWRlTWV0aG9kIGV4dGVuZHMgU2hhZG93TWFwTWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9iYXNlTWV0aG9kOlNoYWRvd01ldGhvZEJhc2U7XG5cdHByaXZhdGUgX2Nhc2NhZGVTaGFkb3dNYXBwZXI6Q2FzY2FkZVNoYWRvd01hcHBlcjtcblx0cHJpdmF0ZSBfZGVwdGhNYXBDb29yZFZhcnlpbmdzOkFycmF5PFNoYWRlclJlZ2lzdGVyRWxlbWVudD47XG5cdHByaXZhdGUgX2Nhc2NhZGVQcm9qZWN0aW9uczpBcnJheTxTaGFkZXJSZWdpc3RlckVsZW1lbnQ+O1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IFNoYWRvd0Nhc2NhZGVNZXRob2Qgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gc2hhZG93TWV0aG9kQmFzZSBUaGUgc2hhZG93IG1hcCBzYW1wbGluZyBtZXRob2QgdXNlZCB0byBzYW1wbGUgaW5kaXZpZHVhbCBjYXNjYWRlcyAoZmU6IFNoYWRvd0hhcmRNZXRob2QsIFNoYWRvd1NvZnRNZXRob2QpXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihzaGFkb3dNZXRob2RCYXNlOlNoYWRvd01ldGhvZEJhc2UpXG5cdHtcblx0XHRzdXBlcihzaGFkb3dNZXRob2RCYXNlLmNhc3RpbmdMaWdodCk7XG5cblx0XHR0aGlzLl9iYXNlTWV0aG9kID0gc2hhZG93TWV0aG9kQmFzZTtcblx0XHRpZiAoISh0aGlzLl9wQ2FzdGluZ0xpZ2h0IGluc3RhbmNlb2YgRGlyZWN0aW9uYWxMaWdodCkpXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJTaGFkb3dDYXNjYWRlTWV0aG9kIGlzIG9ubHkgY29tcGF0aWJsZSB3aXRoIERpcmVjdGlvbmFsTGlnaHRcIik7XG5cblx0XHR0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyID0gPENhc2NhZGVTaGFkb3dNYXBwZXI+IHRoaXMuX3BDYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyO1xuXG5cdFx0aWYgKCF0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiU2hhZG93Q2FzY2FkZU1ldGhvZCByZXF1aXJlcyBhIGxpZ2h0IHRoYXQgaGFzIGEgQ2FzY2FkZVNoYWRvd01hcHBlciBpbnN0YW5jZSBhc3NpZ25lZCB0byBzaGFkb3dNYXBwZXIuXCIpO1xuXG5cdFx0dGhpcy5fY2FzY2FkZVNoYWRvd01hcHBlci5hZGRFdmVudExpc3RlbmVyKEV2ZW50LkNIQU5HRSwgKGV2ZW50OkV2ZW50KSA9PiB0aGlzLm9uQ2FzY2FkZUNoYW5nZShldmVudCkpO1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuYWRkRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCAoZXZlbnQ6U2hhZGluZ01ldGhvZEV2ZW50KSA9PiB0aGlzLm9uU2hhZGVySW52YWxpZGF0ZWQoZXZlbnQpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgc2hhZG93IG1hcCBzYW1wbGluZyBtZXRob2QgdXNlZCB0byBzYW1wbGUgaW5kaXZpZHVhbCBjYXNjYWRlcy4gVGhlc2UgYXJlIHR5cGljYWxseSB0aG9zZSB1c2VkIGluIGNvbmp1bmN0aW9uXG5cdCAqIHdpdGggYSBEaXJlY3Rpb25hbFNoYWRvd01hcHBlci5cblx0ICpcblx0ICogQHNlZSBTaGFkb3dIYXJkTWV0aG9kXG5cdCAqIEBzZWUgU2hhZG93U29mdE1ldGhvZFxuXHQgKi9cblx0cHVibGljIGdldCBiYXNlTWV0aG9kKCk6U2hhZG93TWV0aG9kQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Jhc2VNZXRob2Q7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGJhc2VNZXRob2QodmFsdWU6U2hhZG93TWV0aG9kQmFzZSlcblx0e1xuXHRcdGlmICh0aGlzLl9iYXNlTWV0aG9kID09IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5yZW1vdmVFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIChldmVudDpTaGFkaW5nTWV0aG9kRXZlbnQpID0+IHRoaXMub25TaGFkZXJJbnZhbGlkYXRlZChldmVudCkpO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZCA9IHZhbHVlO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5hZGRFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIChldmVudDpTaGFkaW5nTWV0aG9kRXZlbnQpID0+IHRoaXMub25TaGFkZXJJbnZhbGlkYXRlZChldmVudCkpO1xuXG5cdFx0dGhpcy5pSW52YWxpZGF0ZVNoYWRlclByb2dyYW0oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHZhciB0ZW1wVk86TWV0aG9kVk8gPSBuZXcgTWV0aG9kVk8odGhpcy5fYmFzZU1ldGhvZCk7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5pSW5pdFZPKHNoYWRlck9iamVjdCwgdGVtcFZPKTtcblxuXHRcdG1ldGhvZFZPLm5lZWRzR2xvYmFsVmVydGV4UG9zID0gdHJ1ZTtcblx0XHRtZXRob2RWTy5uZWVkc1Byb2plY3Rpb24gPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0dmFyIGZyYWdtZW50RGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciB2ZXJ0ZXhEYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QudmVydGV4Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleF0gPSAxLjA7XG5cdFx0ZnJhZ21lbnREYXRhW2luZGV4ICsgMV0gPSAxLzI1NS4wO1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDJdID0gMS82NTAyNS4wO1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDNdID0gMS8xNjU4MTM3NS4wO1xuXG5cdFx0ZnJhZ21lbnREYXRhW2luZGV4ICsgNl0gPSAuNTtcblx0XHRmcmFnbWVudERhdGFbaW5kZXggKyA3XSA9IC0uNTtcblxuXHRcdGluZGV4ID0gbWV0aG9kVk8udmVydGV4Q29uc3RhbnRzSW5kZXg7XG5cdFx0dmVydGV4RGF0YVtpbmRleF0gPSAuNTtcblx0XHR2ZXJ0ZXhEYXRhW2luZGV4ICsgMV0gPSAtLjU7XG5cdFx0dmVydGV4RGF0YVtpbmRleCArIDJdID0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0XHR0aGlzLl9jYXNjYWRlUHJvamVjdGlvbnMgPSBudWxsO1xuXHRcdHRoaXMuX2RlcHRoTWFwQ29vcmRWYXJ5aW5ncyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0VmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBkYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cblx0XHR0aGlzLmluaXRQcm9qZWN0aW9uc1JlZ3MocmVnaXN0ZXJDYWNoZSk7XG5cdFx0bWV0aG9kVk8udmVydGV4Q29uc3RhbnRzSW5kZXggPSBkYXRhUmVnLmluZGV4KjQ7XG5cblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhWZWN0b3JUZW1wKCk7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCB0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyLm51bUNhc2NhZGVzOyArK2kpIHtcblx0XHRcdGNvZGUgKz0gXCJtNDQgXCIgKyB0ZW1wICsgXCIsIFwiICsgc2hhcmVkUmVnaXN0ZXJzLmdsb2JhbFBvc2l0aW9uVmVydGV4ICsgXCIsIFwiICsgdGhpcy5fY2FzY2FkZVByb2plY3Rpb25zW2ldICsgXCJcXG5cIiArXG5cdFx0XHRcdFwiYWRkIFwiICsgdGhpcy5fZGVwdGhNYXBDb29yZFZhcnlpbmdzW2ldICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIGRhdGFSZWcgKyBcIi56end6XFxuXCI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyB0aGUgcmVnaXN0ZXJzIGZvciB0aGUgY2FzY2FkZXMnIHByb2plY3Rpb24gY29vcmRpbmF0ZXMuXG5cdCAqL1xuXHRwcml2YXRlIGluaXRQcm9qZWN0aW9uc1JlZ3MocmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlKVxuXHR7XG5cdFx0dGhpcy5fY2FzY2FkZVByb2plY3Rpb25zID0gbmV3IEFycmF5PFNoYWRlclJlZ2lzdGVyRWxlbWVudD4odGhpcy5fY2FzY2FkZVNoYWRvd01hcHBlci5udW1DYXNjYWRlcyk7XG5cdFx0dGhpcy5fZGVwdGhNYXBDb29yZFZhcnlpbmdzID0gbmV3IEFycmF5PFNoYWRlclJlZ2lzdGVyRWxlbWVudD4odGhpcy5fY2FzY2FkZVNoYWRvd01hcHBlci5udW1DYXNjYWRlcyk7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCB0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyLm51bUNhc2NhZGVzOyArK2kpIHtcblx0XHRcdHRoaXMuX2RlcHRoTWFwQ29vcmRWYXJ5aW5nc1tpXSA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZhcnlpbmcoKTtcblx0XHRcdHRoaXMuX2Nhc2NhZGVQcm9qZWN0aW9uc1tpXSA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0XHRyZWdpc3RlckNhY2hlLmdldEZyZWVWZXJ0ZXhDb25zdGFudCgpO1xuXHRcdFx0cmVnaXN0ZXJDYWNoZS5nZXRGcmVlVmVydGV4Q29uc3RhbnQoKTtcblx0XHRcdHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZVZlcnRleENvbnN0YW50KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgbnVtQ2FzY2FkZXM6bnVtYmVyID0gdGhpcy5fY2FzY2FkZVNoYWRvd01hcHBlci5udW1DYXNjYWRlcztcblx0XHR2YXIgZGVwdGhNYXBSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVUZXh0dXJlUmVnKCk7XG5cdFx0dmFyIGRlY1JlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0dmFyIGRhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBwbGFuZURpc3RhbmNlUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgcGxhbmVEaXN0YW5jZXM6QXJyYXk8c3RyaW5nPiA9IEFycmF5PHN0cmluZz4oIHBsYW5lRGlzdGFuY2VSZWcgKyBcIi54XCIsIHBsYW5lRGlzdGFuY2VSZWcgKyBcIi55XCIsIHBsYW5lRGlzdGFuY2VSZWcgKyBcIi56XCIsIHBsYW5lRGlzdGFuY2VSZWcgKyBcIi53XCIgKTtcblx0XHR2YXIgY29kZTpzdHJpbmc7XG5cblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGVjUmVnLmluZGV4KjQ7XG5cdFx0bWV0aG9kVk8udGV4dHVyZXNJbmRleCA9IGRlcHRoTWFwUmVnaXN0ZXIuaW5kZXg7XG5cblx0XHR2YXIgaW5RdWFkOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKGluUXVhZCwgMSk7XG5cdFx0dmFyIHV2Q29vcmQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXModXZDb29yZCwgMSk7XG5cblx0XHQvLyBhc3N1bWUgbG93ZXN0IHBhcnRpdGlvbiBpcyBzZWxlY3RlZCwgd2lsbCBiZSBvdmVyd3JpdHRlbiBsYXRlciBvdGhlcndpc2Vcblx0XHRjb2RlID0gXCJtb3YgXCIgKyB1dkNvb3JkICsgXCIsIFwiICsgdGhpcy5fZGVwdGhNYXBDb29yZFZhcnlpbmdzW251bUNhc2NhZGVzIC0gMV0gKyBcIlxcblwiO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgPSBudW1DYXNjYWRlcyAtIDI7IGkgPj0gMDsgLS1pKSB7XG5cdFx0XHR2YXIgdXZQcm9qZWN0aW9uOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHRoaXMuX2RlcHRoTWFwQ29vcmRWYXJ5aW5nc1tpXTtcblxuXHRcdFx0Ly8gY2FsY3VsYXRlIGlmIGluIHRleHR1cmVtYXAgKHJlc3VsdCA9PSAwIG9yIDEsIG9ubHkgMSBmb3IgYSBzaW5nbGUgcGFydGl0aW9uKVxuXHRcdFx0Y29kZSArPSBcInNsdCBcIiArIGluUXVhZCArIFwiLnosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnByb2plY3Rpb25GcmFnbWVudCArIFwiLnosIFwiICsgcGxhbmVEaXN0YW5jZXNbaV0gKyBcIlxcblwiOyAvLyB6ID0geCA+IG1pblgsIHcgPSB5ID4gbWluWVxuXG5cdFx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblxuXHRcdFx0Ly8gbGluZWFybHkgaW50ZXJwb2xhdGUgYmV0d2VlbiBvbGQgYW5kIG5ldyB1diBjb29yZHMgdXNpbmcgcHJlZGljYXRlIHZhbHVlID09IGNvbmRpdGlvbmFsIHRvZ2dsZSB0byBuZXcgdmFsdWUgaWYgcHJlZGljYXRlID09IDEgKHRydWUpXG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgdGVtcCArIFwiLCBcIiArIHV2UHJvamVjdGlvbiArIFwiLCBcIiArIHV2Q29vcmQgKyBcIlxcblwiICtcblx0XHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIGluUXVhZCArIFwiLnpcXG5cIiArXG5cdFx0XHRcdFwiYWRkIFwiICsgdXZDb29yZCArIFwiLCBcIiArIHV2Q29vcmQgKyBcIiwgXCIgKyB0ZW1wICsgXCJcXG5cIjtcblx0XHR9XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKGluUXVhZCk7XG5cblx0XHRjb2RlICs9IFwiZGl2IFwiICsgdXZDb29yZCArIFwiLCBcIiArIHV2Q29vcmQgKyBcIiwgXCIgKyB1dkNvb3JkICsgXCIud1xcblwiICtcblx0XHRcdFwibXVsIFwiICsgdXZDb29yZCArIFwiLnh5LCBcIiArIHV2Q29vcmQgKyBcIi54eSwgXCIgKyBkYXRhUmVnICsgXCIuendcXG5cIiArXG5cdFx0XHRcImFkZCBcIiArIHV2Q29vcmQgKyBcIi54eSwgXCIgKyB1dkNvb3JkICsgXCIueHksIFwiICsgZGF0YVJlZyArIFwiLnp6XFxuXCI7XG5cblx0XHRjb2RlICs9IHRoaXMuX2Jhc2VNZXRob2QuX2lHZXRDYXNjYWRlRnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIGRlY1JlZywgZGVwdGhNYXBSZWdpc3RlciwgdXZDb29yZCwgdGFyZ2V0UmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpICtcblx0XHRcdFwiYWRkIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIGRhdGFSZWcgKyBcIi55XFxuXCI7XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHV2Q29vcmQpO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5hY3RpdmF0ZVRleHR1cmUobWV0aG9kVk8udGV4dHVyZXNJbmRleCwgPFRleHR1cmUyREJhc2U+IHRoaXMuX3BDYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyLmRlcHRoTWFwKTtcblxuXHRcdHZhciB2ZXJ0ZXhEYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QudmVydGV4Q29uc3RhbnREYXRhO1xuXHRcdHZhciB2ZXJ0ZXhJbmRleDpudW1iZXIgPSBtZXRob2RWTy52ZXJ0ZXhDb25zdGFudHNJbmRleDtcblxuXHRcdHNoYWRlck9iamVjdC52ZXJ0ZXhDb25zdGFudERhdGFbbWV0aG9kVk8udmVydGV4Q29uc3RhbnRzSW5kZXggKyAzXSA9IC0xLyh0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyLmRlcHRoKnRoaXMuX3BFcHNpbG9uKTtcblxuXHRcdHZhciBudW1DYXNjYWRlczpudW1iZXIgPSB0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyLm51bUNhc2NhZGVzO1xuXHRcdHZlcnRleEluZGV4ICs9IDQ7XG5cdFx0Zm9yICh2YXIgazpudW1iZXIgPSAwOyBrIDwgbnVtQ2FzY2FkZXM7ICsraykge1xuXHRcdFx0dGhpcy5fY2FzY2FkZVNoYWRvd01hcHBlci5nZXREZXB0aFByb2plY3Rpb25zKGspLmNvcHlSYXdEYXRhVG8odmVydGV4RGF0YSwgdmVydGV4SW5kZXgsIHRydWUpO1xuXHRcdFx0dmVydGV4SW5kZXggKz0gMTY7XG5cdFx0fVxuXG5cdFx0dmFyIGZyYWdtZW50RGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBmcmFnbWVudEluZGV4Om51bWJlciA9IG1ldGhvZFZPLmZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cdFx0ZnJhZ21lbnREYXRhW2ZyYWdtZW50SW5kZXggKyA1XSA9IDEgLSB0aGlzLl9wQWxwaGE7XG5cblx0XHR2YXIgbmVhclBsYW5lRGlzdGFuY2VzOkFycmF5PG51bWJlcj4gPSB0aGlzLl9jYXNjYWRlU2hhZG93TWFwcGVyLl9pTmVhclBsYW5lRGlzdGFuY2VzO1xuXG5cdFx0ZnJhZ21lbnRJbmRleCArPSA4O1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IG51bUNhc2NhZGVzOyArK2kpXG5cdFx0XHRmcmFnbWVudERhdGFbZnJhZ21lbnRJbmRleCArIGldID0gbmVhclBsYW5lRGlzdGFuY2VzW2ldO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5pQWN0aXZhdGVGb3JDYXNjYWRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlTZXRSZW5kZXJTdGF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIHN0YWdlOlN0YWdlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsbGVkIHdoZW4gdGhlIHNoYWRvdyBtYXBwZXJzIGNhc2NhZGUgY29uZmlndXJhdGlvbiBjaGFuZ2VzLlxuXHQgKi9cblx0cHJpdmF0ZSBvbkNhc2NhZGVDaGFuZ2UoZXZlbnQ6RXZlbnQpXG5cdHtcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbGxlZCB3aGVuIHRoZSBiYXNlIG1ldGhvZCdzIHNoYWRlciBjb2RlIGlzIGludmFsaWRhdGVkLlxuXHQgKi9cblx0cHJpdmF0ZSBvblNoYWRlckludmFsaWRhdGVkKGV2ZW50OlNoYWRpbmdNZXRob2RFdmVudClcblx0e1xuXHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2hhZG93Q2FzY2FkZU1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/ShadowCascadeMethod.ts b/lib/materials/methods/ShadowCascadeMethod.ts new file mode 100644 index 000000000..3a20a6c22 --- /dev/null +++ b/lib/materials/methods/ShadowCascadeMethod.ts @@ -0,0 +1,272 @@ +import Camera = require("awayjs-core/lib/entities/Camera"); +import DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +import Event = require("awayjs-core/lib/events/Event"); +import CascadeShadowMapper = require("awayjs-core/lib/materials/shadowmappers/CascadeShadowMapper"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); + +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 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 ShadowMapMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMapMethodBase"); +import ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +import ShaderCompilerHelper = require("awayjs-stagegl/lib/materials/utils/ShaderCompilerHelper"); + +/** + * ShadowCascadeMethod is a shadow map method to apply cascade shadow mapping on materials. + * Must be used with a DirectionalLight with a CascadeShadowMapper assigned to its shadowMapper property. + * + * @see away.lights.CascadeShadowMapper + */ +class ShadowCascadeMethod extends ShadowMapMethodBase +{ + private _baseMethod:ShadowMethodBase; + private _cascadeShadowMapper:CascadeShadowMapper; + private _depthMapCoordVaryings:Array; + private _cascadeProjections:Array; + + /** + * Creates a new ShadowCascadeMethod object. + * + * @param shadowMethodBase The shadow map sampling method used to sample individual cascades (fe: ShadowHardMethod, ShadowSoftMethod) + */ + constructor(shadowMethodBase:ShadowMethodBase) + { + super(shadowMethodBase.castingLight); + + this._baseMethod = shadowMethodBase; + if (!(this._pCastingLight instanceof DirectionalLight)) + throw new Error("ShadowCascadeMethod is only compatible with DirectionalLight"); + + this._cascadeShadowMapper = this._pCastingLight.shadowMapper; + + if (!this._cascadeShadowMapper) + throw new Error("ShadowCascadeMethod requires a light that has a CascadeShadowMapper instance assigned to shadowMapper."); + + this._cascadeShadowMapper.addEventListener(Event.CHANGE, (event:Event) => this.onCascadeChange(event)); + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, (event:ShadingMethodEvent) => this.onShaderInvalidated(event)); + } + + /** + * The shadow map sampling method used to sample individual cascades. These are typically those used in conjunction + * with a DirectionalShadowMapper. + * + * @see ShadowHardMethod + * @see ShadowSoftMethod + */ + public get baseMethod():ShadowMethodBase + { + return this._baseMethod; + } + + public set baseMethod(value:ShadowMethodBase) + { + if (this._baseMethod == value) + return; + + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, (event:ShadingMethodEvent) => this.onShaderInvalidated(event)); + + this._baseMethod = value; + + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, (event:ShadingMethodEvent) => this.onShaderInvalidated(event)); + + this.iInvalidateShaderProgram(); + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + var tempVO:MethodVO = new MethodVO(this._baseMethod); + this._baseMethod.iInitVO(shaderObject, tempVO); + + methodVO.needsGlobalVertexPos = true; + methodVO.needsProjection = true; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + var fragmentData:Array = shaderObject.fragmentConstantData; + var vertexData:Array = shaderObject.vertexConstantData; + var index:number = methodVO.fragmentConstantsIndex; + fragmentData[index] = 1.0; + fragmentData[index + 1] = 1/255.0; + fragmentData[index + 2] = 1/65025.0; + fragmentData[index + 3] = 1/16581375.0; + + fragmentData[index + 6] = .5; + fragmentData[index + 7] = -.5; + + index = methodVO.vertexConstantsIndex; + vertexData[index] = .5; + vertexData[index + 1] = -.5; + vertexData[index + 2] = 0; + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._cascadeProjections = null; + this._depthMapCoordVaryings = null; + } + + /** + * @inheritDoc + */ + public iGetVertexCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + var dataReg:ShaderRegisterElement = registerCache.getFreeVertexConstant(); + + this.initProjectionsRegs(registerCache); + methodVO.vertexConstantsIndex = dataReg.index*4; + + var temp:ShaderRegisterElement = registerCache.getFreeVertexVectorTemp(); + + for (var i:number = 0; i < this._cascadeShadowMapper.numCascades; ++i) { + code += "m44 " + temp + ", " + sharedRegisters.globalPositionVertex + ", " + this._cascadeProjections[i] + "\n" + + "add " + this._depthMapCoordVaryings[i] + ", " + temp + ", " + dataReg + ".zzwz\n"; + } + + return code; + } + + /** + * Creates the registers for the cascades' projection coordinates. + */ + private initProjectionsRegs(registerCache:ShaderRegisterCache) + { + this._cascadeProjections = new Array(this._cascadeShadowMapper.numCascades); + this._depthMapCoordVaryings = new Array(this._cascadeShadowMapper.numCascades); + + for (var i:number = 0; i < this._cascadeShadowMapper.numCascades; ++i) { + this._depthMapCoordVaryings[i] = registerCache.getFreeVarying(); + this._cascadeProjections[i] = registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + registerCache.getFreeVertexConstant(); + } + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var numCascades:number = this._cascadeShadowMapper.numCascades; + var depthMapRegister:ShaderRegisterElement = registerCache.getFreeTextureReg(); + var decReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var planeDistanceReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var planeDistances:Array = Array( planeDistanceReg + ".x", planeDistanceReg + ".y", planeDistanceReg + ".z", planeDistanceReg + ".w" ); + var code:string; + + methodVO.fragmentConstantsIndex = decReg.index*4; + methodVO.texturesIndex = depthMapRegister.index; + + var inQuad:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(inQuad, 1); + var uvCoord:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(uvCoord, 1); + + // assume lowest partition is selected, will be overwritten later otherwise + code = "mov " + uvCoord + ", " + this._depthMapCoordVaryings[numCascades - 1] + "\n"; + + for (var i:number = numCascades - 2; i >= 0; --i) { + var uvProjection:ShaderRegisterElement = this._depthMapCoordVaryings[i]; + + // calculate if in texturemap (result == 0 or 1, only 1 for a single partition) + code += "slt " + inQuad + ".z, " + sharedRegisters.projectionFragment + ".z, " + planeDistances[i] + "\n"; // z = x > minX, w = y > minY + + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + + // linearly interpolate between old and new uv coords using predicate value == conditional toggle to new value if predicate == 1 (true) + code += "sub " + temp + ", " + uvProjection + ", " + uvCoord + "\n" + + "mul " + temp + ", " + temp + ", " + inQuad + ".z\n" + + "add " + uvCoord + ", " + uvCoord + ", " + temp + "\n"; + } + + registerCache.removeFragmentTempUsage(inQuad); + + code += "div " + uvCoord + ", " + uvCoord + ", " + uvCoord + ".w\n" + + "mul " + uvCoord + ".xy, " + uvCoord + ".xy, " + dataReg + ".zw\n" + + "add " + uvCoord + ".xy, " + uvCoord + ".xy, " + dataReg + ".zz\n"; + + code += this._baseMethod._iGetCascadeFragmentCode(shaderObject, methodVO, decReg, depthMapRegister, uvCoord, targetReg, registerCache, sharedRegisters) + + "add " + targetReg + ".w, " + targetReg + ".w, " + dataReg + ".y\n"; + + registerCache.removeFragmentTempUsage(uvCoord); + + return code; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + ( stage.context).activateTexture(methodVO.texturesIndex, this._pCastingLight.shadowMapper.depthMap); + + var vertexData:Array = shaderObject.vertexConstantData; + var vertexIndex:number = methodVO.vertexConstantsIndex; + + shaderObject.vertexConstantData[methodVO.vertexConstantsIndex + 3] = -1/(this._cascadeShadowMapper.depth*this._pEpsilon); + + var numCascades:number = this._cascadeShadowMapper.numCascades; + vertexIndex += 4; + for (var k:number = 0; k < numCascades; ++k) { + this._cascadeShadowMapper.getDepthProjections(k).copyRawDataTo(vertexData, vertexIndex, true); + vertexIndex += 16; + } + + var fragmentData:Array = shaderObject.fragmentConstantData; + var fragmentIndex:number = methodVO.fragmentConstantsIndex; + fragmentData[fragmentIndex + 5] = 1 - this._pAlpha; + + var nearPlaneDistances:Array = this._cascadeShadowMapper._iNearPlaneDistances; + + fragmentIndex += 8; + for (var i:number = 0; i < numCascades; ++i) + fragmentData[fragmentIndex + i] = nearPlaneDistances[i]; + + this._baseMethod.iActivateForCascade(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iSetRenderState(shaderObject:ShaderObjectBase, methodVO:MethodVO, renderable:RenderableBase, stage:Stage, camera:Camera) + { + } + + /** + * Called when the shadow mappers cascade configuration changes. + */ + private onCascadeChange(event:Event) + { + this.iInvalidateShaderProgram(); + } + + /** + * Called when the base method's shader code is invalidated. + */ + private onShaderInvalidated(event:ShadingMethodEvent) + { + this.iInvalidateShaderProgram(); + } +} + +export = ShadowCascadeMethod; \ No newline at end of file diff --git a/lib/materials/methods/ShadowDitheredMethod.js b/lib/materials/methods/ShadowDitheredMethod.js new file mode 100755 index 000000000..8d54a6b02 --- /dev/null +++ b/lib/materials/methods/ShadowDitheredMethod.js @@ -0,0 +1,236 @@ +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 BitmapData = require("awayjs-core/lib/core/base/BitmapData"); +var BitmapTexture = require("awayjs-core/lib/textures/BitmapTexture"); +var ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +/** + * ShadowDitheredMethod provides a soft shadowing technique by randomly distributing sample points differently for each fragment. + */ +var ShadowDitheredMethod = (function (_super) { + __extends(ShadowDitheredMethod, _super); + /** + * Creates a new ShadowDitheredMethod object. + * @param castingLight The light casting the shadows + * @param numSamples The amount of samples to take for dithering. Minimum 1, maximum 24. + */ + function ShadowDitheredMethod(castingLight, numSamples, range) { + if (numSamples === void 0) { numSamples = 4; } + if (range === void 0) { range = 1; } + _super.call(this, castingLight); + this._depthMapSize = this._pCastingLight.shadowMapper.depthMapSize; + this.numSamples = numSamples; + this.range = range; + ++ShadowDitheredMethod._grainUsages; + if (!ShadowDitheredMethod._grainTexture) + this.initGrainTexture(); + } + Object.defineProperty(ShadowDitheredMethod.prototype, "numSamples", { + /** + * The amount of samples to take for dithering. Minimum 1, maximum 24. The actual maximum may depend on the + * complexity of the shader. + */ + get: function () { + return this._numSamples; + }, + set: function (value /*int*/) { + this._numSamples = value; + if (this._numSamples < 1) + this._numSamples = 1; + else if (this._numSamples > 24) + this._numSamples = 24; + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype.iInitVO = function (shaderObject, methodVO) { + _super.prototype.iInitVO.call(this, shaderObject, methodVO); + methodVO.needsProjection = true; + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + _super.prototype.iInitConstants.call(this, shaderObject, methodVO); + var fragmentData = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + fragmentData[index + 8] = 1 / this._numSamples; + }; + Object.defineProperty(ShadowDitheredMethod.prototype, "range", { + /** + * The range in the shadow map in which to distribute the samples. + */ + get: function () { + return this._range * 2; + }, + set: function (value) { + this._range = value / 2; + }, + enumerable: true, + configurable: true + }); + /** + * Creates a texture containing the dithering noise texture. + */ + ShadowDitheredMethod.prototype.initGrainTexture = function () { + ShadowDitheredMethod._grainBitmapData = new BitmapData(64, 64, false); + var vec = new Array(); + var len = 4096; + var step = 1 / (this._depthMapSize * this._range); + var r, g; + for (var i = 0; i < len; ++i) { + r = 2 * (Math.random() - .5); + g = 2 * (Math.random() - .5); + if (r < 0) + r -= step; + else + r += step; + if (g < 0) + g -= step; + else + g += step; + if (r > 1) + r = 1; + else if (r < -1) + r = -1; + if (g > 1) + g = 1; + else if (g < -1) + g = -1; + vec[i] = (Math.floor((r * .5 + .5) * 0xff) << 16) | (Math.floor((g * .5 + .5) * 0xff) << 8); + } + ShadowDitheredMethod._grainBitmapData.setVector(ShadowDitheredMethod._grainBitmapData.rect, vec); + ShadowDitheredMethod._grainTexture = new BitmapTexture(ShadowDitheredMethod._grainBitmapData); + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype.dispose = function () { + if (--ShadowDitheredMethod._grainUsages == 0) { + ShadowDitheredMethod._grainTexture.dispose(); + ShadowDitheredMethod._grainBitmapData.dispose(); + ShadowDitheredMethod._grainTexture = null; + } + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + data[index + 9] = (stage.width - 1) / 63; + data[index + 10] = (stage.height - 1) / 63; + data[index + 11] = 2 * this._range / this._depthMapSize; + stage.context.activateTexture(methodVO.texturesIndex + 1, ShadowDitheredMethod._grainTexture); + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype._pGetPlanarFragmentCode = function (methodVO, targetReg, regCache, sharedRegisters) { + var depthMapRegister = regCache.getFreeTextureReg(); + var decReg = regCache.getFreeFragmentConstant(); + var dataReg = regCache.getFreeFragmentConstant(); + var customDataReg = regCache.getFreeFragmentConstant(); + methodVO.fragmentConstantsIndex = decReg.index * 4; + methodVO.texturesIndex = depthMapRegister.index; + return this.getSampleCode(customDataReg, depthMapRegister, decReg, targetReg, regCache, sharedRegisters); + }; + /** + * Get the actual shader code for shadow mapping + * @param regCache The register cache managing the registers. + * @param depthMapRegister The texture register containing the depth map. + * @param decReg The register containing the depth map decoding data. + * @param targetReg The target register to add the shadow coverage. + */ + ShadowDitheredMethod.prototype.getSampleCode = function (customDataReg, depthMapRegister, decReg, targetReg, regCache, sharedRegisters) { + var code = ""; + var grainRegister = regCache.getFreeTextureReg(); + var uvReg = regCache.getFreeFragmentVectorTemp(); + var numSamples = this._numSamples; + regCache.addFragmentTempUsages(uvReg, 1); + var temp = regCache.getFreeFragmentVectorTemp(); + var projectionReg = sharedRegisters.projectionFragment; + code += "div " + uvReg + ", " + projectionReg + ", " + projectionReg + ".w\n" + "mul " + uvReg + ".xy, " + uvReg + ".xy, " + customDataReg + ".yz\n"; + while (numSamples > 0) { + if (numSamples == this._numSamples) + code += "tex " + uvReg + ", " + uvReg + ", " + grainRegister + " <2d,nearest,repeat,mipnone>\n"; + else + code += "tex " + uvReg + ", " + uvReg + ".zwxy, " + grainRegister + " <2d,nearest,repeat,mipnone>\n"; + // keep grain in uvReg.zw + code += "sub " + uvReg + ".zw, " + uvReg + ".xy, fc0.xx\n" + "mul " + uvReg + ".zw, " + uvReg + ".zw, " + customDataReg + ".w\n"; // (tex unpack scale and tex scale in one) + if (numSamples == this._numSamples) { + // first sample + code += "add " + uvReg + ".xy, " + uvReg + ".zw, " + this._pDepthMapCoordReg + ".xy\n" + "tex " + temp + ", " + uvReg + ", " + depthMapRegister + " <2d,nearest,clamp,mipnone>\n" + "dp4 " + temp + ".z, " + temp + ", " + decReg + "\n" + "slt " + targetReg + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n"; // 0 if in shadow + } + else { + code += this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + } + if (numSamples > 4) + code += "add " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + if (numSamples > 1) + code += "sub " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + if (numSamples > 5) + code += "sub " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + if (numSamples > 2) { + code += "neg " + uvReg + ".w, " + uvReg + ".w\n"; // will be rotated 90 degrees when being accessed as wz + code += "add " + uvReg + ".xy, " + uvReg + ".wz, " + this._pDepthMapCoordReg + ".xy\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + } + if (numSamples > 6) + code += "add " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + if (numSamples > 3) + code += "sub " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + if (numSamples > 7) + code += "sub " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + numSamples -= 8; + } + regCache.removeFragmentTempUsage(uvReg); + code += "mul " + targetReg + ".w, " + targetReg + ".w, " + customDataReg + ".x\n"; // average + return code; + }; + /** + * Adds the code for another tap to the shader code. + * @param uvReg The uv register for the tap. + * @param depthMapRegister The texture register containing the depth map. + * @param decReg The register containing the depth map decoding data. + * @param targetReg The target register to add the tap comparison result. + * @param regCache The register cache managing the registers. + * @return + */ + ShadowDitheredMethod.prototype.addSample = function (uvReg, depthMapRegister, decReg, targetReg, regCache) { + var temp = regCache.getFreeFragmentVectorTemp(); + return "tex " + temp + ", " + uvReg + ", " + depthMapRegister + " <2d,nearest,clamp,mipnone>\n" + "dp4 " + temp + ".z, " + temp + ", " + decReg + "\n" + "slt " + temp + ".z, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n" + "add " + targetReg + ".w, " + targetReg + ".w, " + temp + ".z\n"; + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype.iActivateForCascade = function (shaderObject, methodVO, stage) { + var data = shaderObject.fragmentConstantData; + var index = methodVO.secondaryFragmentConstantsIndex; + data[index] = 1 / this._numSamples; + data[index + 1] = (stage.width - 1) / 63; + data[index + 2] = (stage.height - 1) / 63; + data[index + 3] = 2 * this._range / this._depthMapSize; + stage.context.activateTexture(methodVO.texturesIndex + 1, ShadowDitheredMethod._grainTexture); + }; + /** + * @inheritDoc + */ + ShadowDitheredMethod.prototype._iGetCascadeFragmentCode = function (shaderObject, methodVO, decodeRegister, depthTexture, depthProjection, targetRegister, registerCache, sharedRegisters) { + this._pDepthMapCoordReg = depthProjection; + var dataReg = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index * 4; + return this.getSampleCode(dataReg, depthTexture, decodeRegister, targetRegister, registerCache, sharedRegisters); + }; + return ShadowDitheredMethod; +})(ShadowMethodBase); +module.exports = ShadowDitheredMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NoYWRvd2RpdGhlcmVkbWV0aG9kLnRzIl0sIm5hbWVzIjpbIlNoYWRvd0RpdGhlcmVkTWV0aG9kIiwiU2hhZG93RGl0aGVyZWRNZXRob2QuY29uc3RydWN0b3IiLCJTaGFkb3dEaXRoZXJlZE1ldGhvZC5udW1TYW1wbGVzIiwiU2hhZG93RGl0aGVyZWRNZXRob2QuaUluaXRWTyIsIlNoYWRvd0RpdGhlcmVkTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiU2hhZG93RGl0aGVyZWRNZXRob2QucmFuZ2UiLCJTaGFkb3dEaXRoZXJlZE1ldGhvZC5pbml0R3JhaW5UZXh0dXJlIiwiU2hhZG93RGl0aGVyZWRNZXRob2QuZGlzcG9zZSIsIlNoYWRvd0RpdGhlcmVkTWV0aG9kLmlBY3RpdmF0ZSIsIlNoYWRvd0RpdGhlcmVkTWV0aG9kLl9wR2V0UGxhbmFyRnJhZ21lbnRDb2RlIiwiU2hhZG93RGl0aGVyZWRNZXRob2QuZ2V0U2FtcGxlQ29kZSIsIlNoYWRvd0RpdGhlcmVkTWV0aG9kLmFkZFNhbXBsZSIsIlNoYWRvd0RpdGhlcmVkTWV0aG9kLmlBY3RpdmF0ZUZvckNhc2NhZGUiLCJTaGFkb3dEaXRoZXJlZE1ldGhvZC5faUdldENhc2NhZGVGcmFnbWVudENvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sVUFBVSxXQUFnQixzQ0FBc0MsQ0FBQyxDQUFDO0FBRXpFLElBQU8sYUFBYSxXQUFlLHdDQUF3QyxDQUFDLENBQUM7QUFVN0UsSUFBTyxnQkFBZ0IsV0FBZSx1REFBdUQsQ0FBQyxDQUFDO0FBRS9GLEFBR0E7O0dBREc7SUFDRyxvQkFBb0I7SUFBU0EsVUFBN0JBLG9CQUFvQkEsVUFBeUJBO0lBU2xEQTs7OztPQUlHQTtJQUNIQSxTQWRLQSxvQkFBb0JBLENBY2JBLFlBQTZCQSxFQUFFQSxVQUE2QkEsRUFBRUEsS0FBZ0JBO1FBQS9DQywwQkFBNkJBLEdBQTdCQSxjQUE2QkE7UUFBRUEscUJBQWdCQSxHQUFoQkEsU0FB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Q0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7UUFDckRBLElBQUlBLENBQVFBLEVBQUVBLENBQVFBLENBQUNBO1FBRXZCQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFtQkEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDOUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBO1lBQzNCQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUMzQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1RBLENBQUNBLElBQUlBLElBQUlBLENBQUNBO1lBQUNBLElBQUlBO2dCQUNmQSxDQUFDQSxJQUFJQSxJQUFJQSxDQUFDQTtZQUNYQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDVEEsQ0FBQ0EsSUFBSUEsSUFBSUEsQ0FBQ0E7WUFBQ0EsSUFBSUE7Z0JBQ2ZBLENBQUNBLElBQUlBLElBQUlBLENBQUNBO1lBQ1hBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO2dCQUNUQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDdkJBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO1lBQ1JBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO2dCQUNUQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxD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QUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUNwREEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxFQUFFQSxpQkFBaUJBO1lBQ25HQSxDQUFDQSxHQURnRkE7WUFDL0VBLElBQUlBLENBQUNBLENBQUNBO2dCQUNQQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxnQkFBZ0JBLEVBQUVBLE1BQU1BLEVBQUVBLFNBQVNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBO1lBQzlFQSxDQUFDQTtZQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDbEJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLEVBQUVBLGdCQUFnQkEsRUFBRUEsTUFBTUEsRUFBRUEsU0FBU0EsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7WUFFN0lBLEVBQUVBLENBQUNBLENBQUNBLFVBQVVBLEdBQUdBLENBQUNBLENBQUNBO2dCQUNsQkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxnQkFBZ0JBLEVBQUVBLE1BQU1BLEVBQUVBLFNBQVNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBO1lBRS9KQSxFQUFFQSxDQUFDQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDbEJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLEVBQUVBLGdCQUFnQkEsRUFBRUEsTUFBTUEsRUFBRUEsU0FBU0EsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7WUFFN0lBLEVBQUVBLENBQUNBLENBQUNBLFVBQVVBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNwQkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsRUFBRUEsdURBQXVEQTtnQkFDekdBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLEtBQUtBLEdBQUdBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsZ0JBQWdCQSxFQUFFQSxNQUFNQSxFQUFFQSxTQUFTQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQTtZQUMvSkEsQ0FBQ0E7WUFFREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsVUFBVUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2xCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxnQkFBZ0JBLEVBQUVBLE1BQU1BLEVBQUVBLFNBQVNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBO1lBRTdJQSxFQUFFQSxDQUFDQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDbEJBLElBQUlBLElBQUlBLE1BQU1BLEdB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Q0E7UUFFaENBLEtBQUtBLENBQUNBLE9BQVFBLENBQUNBLGVBQWVBLENBQUNBLFFBQVFBLENBQUNBLGFBQWFBLEdBQUdBLENBQUNBLEVBQUVBLG9CQUFvQkEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0E7SUFDbkhBLENBQUNBO0lBRURaOztPQUVHQTtJQUNJQSx1REFBd0JBLEdBQS9CQSxVQUFnQ0EsWUFBNkJBLEVBQUVBLFFBQWlCQSxFQUFFQSxjQUFvQ0EsRUFBRUEsWUFBa0NBLEVBQUVBLGVBQXFDQSxFQUFFQSxjQUFvQ0EsRUFBRUEsYUFBaUNBLEVBQUVBLGVBQWtDQTtRQUU3U2EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxlQUFlQSxDQUFDQTtRQUUxQ0EsSUFBSUEsT0FBT0EsR0FBeUJBLGFBQWFBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDNUVBLFFBQVFBLENBQUNBLCtCQUErQkEsR0FBR0EsT0FBT0EsQ0FBQ0EsS0FBS0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFM0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLE9BQU9BLEVBQUVBLFlBQVlBLEVBQUVBLGNBQWNBLEVBQUVBLGNBQWNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO0lBQ2xIQSxDQUFDQTtJQUNGYiwyQkFBQ0E7QUFBREEsQ0FyUkEsQUFxUkNBLEVBclJrQyxnQkFBZ0IsRUFxUmxEO0FBRUQsQUFBOEIsaUJBQXJCLG9CQUFvQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL1NoYWRvd0RpdGhlcmVkTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpdG1hcERhdGFcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0JpdG1hcERhdGFcIik7XG5pbXBvcnQgRGlyZWN0aW9uYWxMaWdodFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvRGlyZWN0aW9uYWxMaWdodFwiKTtcbmltcG9ydCBCaXRtYXBUZXh0dXJlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9CaXRtYXBUZXh0dXJlXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgSUNvbnRleHRTdGFnZUdMXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3N0YWdlZ2wvSUNvbnRleHRTdGFnZUdMXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IFNoYWRvd01ldGhvZEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NoYWRvd01ldGhvZEJhc2VcIik7XG5cbi8qKlxuICogU2hhZG93RGl0aGVyZWRNZXRob2QgcHJvdmlkZXMgYSBzb2Z0IHNoYWRvd2luZyB0ZWNobmlxdWUgYnkgcmFuZG9tbHkgZGlzdHJpYnV0aW5nIHNhbXBsZSBwb2ludHMgZGlmZmVyZW50bHkgZm9yIGVhY2ggZnJhZ21lbnQuXG4gKi9cbmNsYXNzIFNoYWRvd0RpdGhlcmVkTWV0aG9kIGV4dGVuZHMgU2hhZG93TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIHN0YXRpYyBfZ3JhaW5UZXh0dXJlOkJpdG1hcFRleHR1cmU7XG5cdHByaXZhdGUgc3RhdGljIF9ncmFpblVzYWdlczpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBzdGF0aWMgX2dyYWluQml0bWFwRGF0YTpCaXRtYXBEYXRhO1xuXHRwcml2YXRlIF9kZXB0aE1hcFNpemU6bnVtYmVyIC8qaW50Ki87XG5cdHByaXZhdGUgX3JhbmdlOm51bWJlcjtcblx0cHJpdmF0ZSBfbnVtU2FtcGxlczpudW1iZXIgLyppbnQqLztcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBTaGFkb3dEaXRoZXJlZE1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSBjYXN0aW5nTGlnaHQgVGhlIGxpZ2h0IGNhc3RpbmcgdGhlIHNoYWRvd3Ncblx0ICogQHBhcmFtIG51bVNhbXBsZXMgVGhlIGFtb3VudCBvZiBzYW1wbGVzIHRvIHRha2UgZm9yIGRpdGhlcmluZy4gTWluaW11bSAxLCBtYXhpbXVtIDI0LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoY2FzdGluZ0xpZ2h0OkRpcmVjdGlvbmFsTGlnaHQsIG51bVNhbXBsZXM6bnVtYmVyIC8qaW50Ki8gPSA0LCByYW5nZTpudW1iZXIgPSAxKVxuXHR7XG5cdFx0c3VwZXIoY2FzdGluZ0xpZ2h0KTtcblxuXHRcdHRoaXMuX2RlcHRoTWFwU2l6ZSA9IHRoaXMuX3BDYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyLmRlcHRoTWFwU2l6ZTtcblxuXHRcdHRoaXMubnVtU2FtcGxlcyA9IG51bVNhbXBsZXM7XG5cdFx0dGhpcy5yYW5nZSA9IHJhbmdlO1xuXG5cdFx0KytTaGFkb3dEaXRoZXJlZE1ldGhvZC5fZ3JhaW5Vc2FnZXM7XG5cblx0XHRpZiAoIVNoYWRvd0RpdGhlcmVkTWV0aG9kLl9ncmFpblRleHR1cmUpXG5cdFx0XHR0aGlzLmluaXRHcmFpblRleHR1cmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IG9mIHNhbXBsZXMgdG8gdGFrZSBmb3IgZGl0aGVyaW5nLiBNaW5pbXVtIDEsIG1heGltdW0gMjQuIFRoZSBhY3R1YWwgbWF4aW11bSBtYXkgZGVwZW5kIG9uIHRoZVxuXHQgKiBjb21wbGV4aXR5IG9mIHRoZSBzaGFkZXIuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IG51bVNhbXBsZXMoKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX251bVNhbXBsZXM7XG5cdH1cblxuXHRwdWJsaWMgc2V0IG51bVNhbXBsZXModmFsdWU6bnVtYmVyIC8qaW50Ki8pXG5cdHtcblx0XHR0aGlzLl9udW1TYW1wbGVzID0gdmFsdWU7XG5cdFx0aWYgKHRoaXMuX251bVNhbXBsZXMgPCAxKVxuXHRcdFx0dGhpcy5fbnVtU2FtcGxlcyA9IDE7IGVsc2UgaWYgKHRoaXMuX251bVNhbXBsZXMgPiAyNClcblx0XHRcdHRoaXMuX251bVNhbXBsZXMgPSAyNDtcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRWTyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0c3VwZXIuaUluaXRWTyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblxuXHRcdG1ldGhvZFZPLm5lZWRzUHJvamVjdGlvbiA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRzdXBlci5pSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblxuXHRcdHZhciBmcmFnbWVudERhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDhdID0gMS90aGlzLl9udW1TYW1wbGVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSByYW5nZSBpbiB0aGUgc2hhZG93IG1hcCBpbiB3aGljaCB0byBkaXN0cmlidXRlIHRoZSBzYW1wbGVzLlxuXHQgKi9cblx0cHVibGljIGdldCByYW5nZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3JhbmdlKjI7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHJhbmdlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3JhbmdlID0gdmFsdWUvMjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgdGV4dHVyZSBjb250YWluaW5nIHRoZSBkaXRoZXJpbmcgbm9pc2UgdGV4dHVyZS5cblx0ICovXG5cdHByaXZhdGUgaW5pdEdyYWluVGV4dHVyZSgpXG5cdHtcblx0XHRTaGFkb3dEaXRoZXJlZE1ldGhvZC5fZ3JhaW5CaXRtYXBEYXRhID0gbmV3IEJpdG1hcERhdGEoNjQsIDY0LCBmYWxzZSk7XG5cdFx0dmFyIHZlYzpBcnJheTxudW1iZXI+IC8qdWludCovID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLyA9IDQwOTY7XG5cdFx0dmFyIHN0ZXA6bnVtYmVyID0gMS8odGhpcy5fZGVwdGhNYXBTaXplKnRoaXMuX3JhbmdlKTtcblx0XHR2YXIgcjpudW1iZXIsIGc6bnVtYmVyO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwOyBpIDwgbGVuOyArK2kpIHtcblx0XHRcdHIgPSAyKihNYXRoLnJhbmRvbSgpIC0gLjUpO1xuXHRcdFx0ZyA9IDIqKE1hdGgucmFuZG9tKCkgLSAuNSk7XG5cdFx0XHRpZiAociA8IDApXG5cdFx0XHRcdHIgLT0gc3RlcDsgZWxzZVxuXHRcdFx0XHRyICs9IHN0ZXA7XG5cdFx0XHRpZiAoZyA8IDApXG5cdFx0XHRcdGcgLT0gc3RlcDsgZWxzZVxuXHRcdFx0XHRnICs9IHN0ZXA7XG5cdFx0XHRpZiAociA+IDEpXG5cdFx0XHRcdHIgPSAxOyBlbHNlIGlmIChyIDwgLTEpXG5cdFx0XHRcdHIgPSAtMTtcblx0XHRcdGlmIChnID4gMSlcblx0XHRcdFx0ZyA9IDE7IGVsc2UgaWYgKGcgPCAtMSlcblx0XHRcdFx0ZyA9IC0xO1xuXHRcdFx0dmVjW2ldID0gKE1hdGguZmxvb3IoKHIqLjUgKyAuNSkqMHhmZikgPDwgMTYpIHwgKE1hdGguZmxvb3IoKGcqLjUgKyAuNSkqMHhmZikgPDwgOCk7XG5cdFx0fVxuXG5cdFx0U2hhZG93RGl0aGVyZWRNZXRob2QuX2dyYWluQml0bWFwRGF0YS5zZXRWZWN0b3IoU2hhZG93RGl0aGVyZWRNZXRob2QuX2dyYWluQml0bWFwRGF0YS5yZWN0LCB2ZWMpO1xuXHRcdFNoYWRvd0RpdGhlcmVkTWV0aG9kLl9ncmFpblRleHR1cmUgPSBuZXcgQml0bWFwVGV4dHVyZShTaGFkb3dEaXRoZXJlZE1ldGhvZC5fZ3JhaW5CaXRtYXBEYXRhKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cdFx0aWYgKC0tU2hhZG93RGl0aGVyZWRNZXRob2QuX2dyYWluVXNhZ2VzID09IDApIHtcblx0XHRcdFNoYWRvd0RpdGhlcmVkTWV0aG9kLl9ncmFpblRleHR1cmUuZGlzcG9zZSgpO1xuXHRcdFx0U2hhZG93RGl0aGVyZWRNZXRob2QuX2dyYWluQml0bWFwRGF0YS5kaXNwb3NlKCk7XG5cdFx0XHRTaGFkb3dEaXRoZXJlZE1ldGhvZC5fZ3JhaW5UZXh0dXJlID0gbnVsbDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyp1aW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGRhdGFbaW5kZXggKyA5XSA9IChzdGFnZS53aWR0aCAtIDEpLzYzO1xuXHRcdGRhdGFbaW5kZXggKyAxMF0gPSAoc3RhZ2UuaGVpZ2h0IC0gMSkvNjM7XG5cdFx0ZGF0YVtpbmRleCArIDExXSA9IDIqdGhpcy5fcmFuZ2UvdGhpcy5fZGVwdGhNYXBTaXplO1xuXG5cdFx0KDxJQ29udGV4dFN0YWdlR0w+IHN0YWdlLmNvbnRleHQpLmFjdGl2YXRlVGV4dHVyZShtZXRob2RWTy50ZXh0dXJlc0luZGV4ICsgMSwgU2hhZG93RGl0aGVyZWRNZXRob2QuX2dyYWluVGV4dHVyZSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcEdldFBsYW5hckZyYWdtZW50Q29kZShtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgZGVwdGhNYXBSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgZGF0YVJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBjdXN0b21EYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ0NhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGVjUmVnLmluZGV4KjQ7XG5cdFx0bWV0aG9kVk8udGV4dHVyZXNJbmRleCA9IGRlcHRoTWFwUmVnaXN0ZXIuaW5kZXg7XG5cblx0XHRyZXR1cm4gdGhpcy5nZXRTYW1wbGVDb2RlKGN1c3RvbURhdGFSZWcsIGRlcHRoTWFwUmVnaXN0ZXIsIGRlY1JlZywgdGFyZ2V0UmVnLCByZWdDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGFjdHVhbCBzaGFkZXIgY29kZSBmb3Igc2hhZG93IG1hcHBpbmdcblx0ICogQHBhcmFtIHJlZ0NhY2hlIFRoZSByZWdpc3RlciBjYWNoZSBtYW5hZ2luZyB0aGUgcmVnaXN0ZXJzLlxuXHQgKiBAcGFyYW0gZGVwdGhNYXBSZWdpc3RlciBUaGUgdGV4dHVyZSByZWdpc3RlciBjb250YWluaW5nIHRoZSBkZXB0aCBtYXAuXG5cdCAqIEBwYXJhbSBkZWNSZWcgVGhlIHJlZ2lzdGVyIGNvbnRhaW5pbmcgdGhlIGRlcHRoIG1hcCBkZWNvZGluZyBkYXRhLlxuXHQgKiBAcGFyYW0gdGFyZ2V0UmVnIFRoZSB0YXJnZXQgcmVnaXN0ZXIgdG8gYWRkIHRoZSBzaGFkb3cgY292ZXJhZ2UuXG5cdCAqL1xuXHRwcml2YXRlIGdldFNhbXBsZUNvZGUoY3VzdG9tRGF0YVJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIGRlcHRoTWFwUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIGdyYWluUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZVRleHR1cmVSZWcoKTtcblx0XHR2YXIgdXZSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHZhciBudW1TYW1wbGVzOm51bWJlciAvKmludCovID0gdGhpcy5fbnVtU2FtcGxlcztcblx0XHRyZWdDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXModXZSZWcsIDEpO1xuXG5cdFx0dmFyIHRlbXA6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXG5cdFx0dmFyIHByb2plY3Rpb25SZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gc2hhcmVkUmVnaXN0ZXJzLnByb2plY3Rpb25GcmFnbWVudDtcblxuXHRcdGNvZGUgKz0gXCJkaXYgXCIgKyB1dlJlZyArIFwiLCBcIiArIHByb2plY3Rpb25SZWcgKyBcIiwgXCIgKyBwcm9qZWN0aW9uUmVnICsgXCIud1xcblwiICsgXCJtdWwgXCIgKyB1dlJlZyArIFwiLnh5LCBcIiArIHV2UmVnICsgXCIueHksIFwiICsgY3VzdG9tRGF0YVJlZyArIFwiLnl6XFxuXCI7XG5cblx0XHR3aGlsZSAobnVtU2FtcGxlcyA+IDApIHtcblx0XHRcdGlmIChudW1TYW1wbGVzID09IHRoaXMuX251bVNhbXBsZXMpXG5cdFx0XHRcdGNvZGUgKz0gXCJ0ZXggXCIgKyB1dlJlZyArIFwiLCBcIiArIHV2UmVnICsgXCIsIFwiICsgZ3JhaW5SZWdpc3RlciArIFwiIDwyZCxuZWFyZXN0LHJlcGVhdCxtaXBub25lPlxcblwiO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRjb2RlICs9IFwidGV4IFwiICsgdXZSZWcgKyBcIiwgXCIgKyB1dlJlZyArIFwiLnp3eHksIFwiICsgZ3JhaW5SZWdpc3RlciArIFwiIDwyZCxuZWFyZXN0LHJlcGVhdCxtaXBub25lPlxcblwiO1xuXG5cdFx0XHQvLyBrZWVwIGdyYWluIGluIHV2UmVnLnp3XG5cdFx0XHRjb2RlICs9IFwic3ViIFwiICsgdXZSZWcgKyBcIi56dywgXCIgKyB1dlJlZyArIFwiLnh5LCBmYzAueHhcXG5cIiArIC8vIHV2LS41XG5cdFx0XHRcdFwibXVsIFwiICsgdXZSZWcgKyBcIi56dywgXCIgKyB1dlJlZyArIFwiLnp3LCBcIiArIGN1c3RvbURhdGFSZWcgKyBcIi53XFxuXCI7IC8vICh0ZXggdW5wYWNrIHNjYWxlIGFuZCB0ZXggc2NhbGUgaW4gb25lKVxuXG5cdFx0XHRpZiAobnVtU2FtcGxlcyA9PSB0aGlzLl9udW1TYW1wbGVzKSB7XG5cdFx0XHRcdC8vIGZpcnN0IHNhbXBsZVxuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdXZSZWcgKyBcIi54eSwgXCIgKyB1dlJlZyArIFwiLnp3LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueHlcXG5cIiArXG5cdFx0XHRcdFx0XCJ0ZXggXCIgKyB0ZW1wICsgXCIsIFwiICsgdXZSZWcgKyBcIiwgXCIgKyBkZXB0aE1hcFJlZ2lzdGVyICsgXCIgPDJkLG5lYXJlc3QsY2xhbXAsbWlwbm9uZT5cXG5cIiArXG5cdFx0XHRcdFx0XCJkcDQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGVjUmVnICsgXCJcXG5cIiArXG5cdFx0XHRcdFx0XCJzbHQgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueiwgXCIgKyB0ZW1wICsgXCIuelxcblwiOyAvLyAwIGlmIGluIHNoYWRvd1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29kZSArPSB0aGlzLmFkZFNhbXBsZSh1dlJlZywgZGVwdGhNYXBSZWdpc3RlciwgZGVjUmVnLCB0YXJnZXRSZWcsIHJlZ0NhY2hlKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKG51bVNhbXBsZXMgPiA0KVxuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdXZSZWcgKyBcIi54eSwgXCIgKyB1dlJlZyArIFwiLnh5LCBcIiArIHV2UmVnICsgXCIuendcXG5cIiArIHRoaXMuYWRkU2FtcGxlKHV2UmVnLCBkZXB0aE1hcFJlZ2lzdGVyLCBkZWNSZWcsIHRhcmdldFJlZywgcmVnQ2FjaGUpO1xuXG5cdFx0XHRpZiAobnVtU2FtcGxlcyA+IDEpXG5cdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyB1dlJlZyArIFwiLnh5LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueHksIFwiICsgdXZSZWcgKyBcIi56d1xcblwiICsgdGhpcy5hZGRTYW1wbGUodXZSZWcsIGRlcHRoTWFwUmVnaXN0ZXIsIGRlY1JlZywgdGFyZ2V0UmVnLCByZWdDYWNoZSk7XG5cblx0XHRcdGlmIChudW1TYW1wbGVzID4gNSlcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHV2UmVnICsgXCIueHksIFwiICsgdXZSZWcgKyBcIi54eSwgXCIgKyB1dlJlZyArIFwiLnp3XFxuXCIgKyB0aGlzLmFkZFNhbXBsZSh1dlJlZywgZGVwdGhNYXBSZWdpc3RlciwgZGVjUmVnLCB0YXJnZXRSZWcsIHJlZ0NhY2hlKTtcblxuXHRcdFx0aWYgKG51bVNhbXBsZXMgPiAyKSB7XG5cdFx0XHRcdGNvZGUgKz0gXCJuZWcgXCIgKyB1dlJlZyArIFwiLncsIFwiICsgdXZSZWcgKyBcIi53XFxuXCI7IC8vIHdpbGwgYmUgcm90YXRlZCA5MCBkZWdyZWVzIHdoZW4gYmVpbmcgYWNjZXNzZWQgYXMgd3pcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHV2UmVnICsgXCIueHksIFwiICsgdXZSZWcgKyBcIi53eiwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLnh5XFxuXCIgKyB0aGlzLmFkZFNhbXBsZSh1dlJlZywgZGVwdGhNYXBSZWdpc3RlciwgZGVjUmVnLCB0YXJnZXRSZWcsIHJlZ0NhY2hlKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKG51bVNhbXBsZXMgPiA2KVxuXHRcdFx0XHRjb2RlICs9IFwiYWRkIFwiICsgdXZSZWcgKyBcIi54eSwgXCIgKyB1dlJlZyArIFwiLnh5LCBcIiArIHV2UmVnICsgXCIud3pcXG5cIiArIHRoaXMuYWRkU2FtcGxlKHV2UmVnLCBkZXB0aE1hcFJlZ2lzdGVyLCBkZWNSZWcsIHRhcmdldFJlZywgcmVnQ2FjaGUpO1xuXG5cdFx0XHRpZiAobnVtU2FtcGxlcyA+IDMpXG5cdFx0XHRcdGNvZGUgKz0gXCJzdWIgXCIgKyB1dlJlZyArIFwiLnh5LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueHksIFwiICsgdXZSZWcgKyBcIi53elxcblwiICsgdGhpcy5hZGRTYW1wbGUodXZSZWcsIGRlcHRoTWFwUmVnaXN0ZXIsIGRlY1JlZywgdGFyZ2V0UmVnLCByZWdDYWNoZSk7XG5cblx0XHRcdGlmIChudW1TYW1wbGVzID4gNylcblx0XHRcdFx0Y29kZSArPSBcInN1YiBcIiArIHV2UmVnICsgXCIueHksIFwiICsgdXZSZWcgKyBcIi54eSwgXCIgKyB1dlJlZyArIFwiLnd6XFxuXCIgKyB0aGlzLmFkZFNhbXBsZSh1dlJlZywgZGVwdGhNYXBSZWdpc3RlciwgZGVjUmVnLCB0YXJnZXRSZWcsIHJlZ0NhY2hlKTtcblxuXHRcdFx0bnVtU2FtcGxlcyAtPSA4O1xuXHRcdH1cblxuXHRcdHJlZ0NhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHV2UmVnKTtcblx0XHRjb2RlICs9IFwibXVsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIGN1c3RvbURhdGFSZWcgKyBcIi54XFxuXCI7IC8vIGF2ZXJhZ2Vcblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRoZSBjb2RlIGZvciBhbm90aGVyIHRhcCB0byB0aGUgc2hhZGVyIGNvZGUuXG5cdCAqIEBwYXJhbSB1dlJlZyBUaGUgdXYgcmVnaXN0ZXIgZm9yIHRoZSB0YXAuXG5cdCAqIEBwYXJhbSBkZXB0aE1hcFJlZ2lzdGVyIFRoZSB0ZXh0dXJlIHJlZ2lzdGVyIGNvbnRhaW5pbmcgdGhlIGRlcHRoIG1hcC5cblx0ICogQHBhcmFtIGRlY1JlZyBUaGUgcmVnaXN0ZXIgY29udGFpbmluZyB0aGUgZGVwdGggbWFwIGRlY29kaW5nIGRhdGEuXG5cdCAqIEBwYXJhbSB0YXJnZXRSZWcgVGhlIHRhcmdldCByZWdpc3RlciB0byBhZGQgdGhlIHRhcCBjb21wYXJpc29uIHJlc3VsdC5cblx0ICogQHBhcmFtIHJlZ0NhY2hlIFRoZSByZWdpc3RlciBjYWNoZSBtYW5hZ2luZyB0aGUgcmVnaXN0ZXJzLlxuXHQgKiBAcmV0dXJuXG5cdCAqL1xuXHRwcml2YXRlIGFkZFNhbXBsZSh1dlJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIGRlcHRoTWFwUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlKTpzdHJpbmdcblx0e1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ0NhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblxuXHRcdHJldHVybiBcInRleCBcIiArIHRlbXAgKyBcIiwgXCIgKyB1dlJlZyArIFwiLCBcIiArIGRlcHRoTWFwUmVnaXN0ZXIgKyBcIiA8MmQsbmVhcmVzdCxjbGFtcCxtaXBub25lPlxcblwiICtcblx0XHRcdFwiZHA0IFwiICsgdGVtcCArIFwiLnosIFwiICsgdGVtcCArIFwiLCBcIiArIGRlY1JlZyArIFwiXFxuXCIgK1xuXHRcdFx0XCJzbHQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLnosIFwiICsgdGVtcCArIFwiLnpcXG5cIiArIC8vIDAgaWYgaW4gc2hhZG93XG5cdFx0XHRcImFkZCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0ZW1wICsgXCIuelxcblwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlRm9yQ2FzY2FkZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0dmFyIGRhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qdWludCovID0gbWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleDtcblx0XHRkYXRhW2luZGV4XSA9IDEvdGhpcy5fbnVtU2FtcGxlcztcblx0XHRkYXRhW2luZGV4ICsgMV0gPSAoc3RhZ2Uud2lkdGggLSAxKS82Mztcblx0XHRkYXRhW2luZGV4ICsgMl0gPSAoc3RhZ2UuaGVpZ2h0IC0gMSkvNjM7XG5cdFx0ZGF0YVtpbmRleCArIDNdID0gMip0aGlzLl9yYW5nZS90aGlzLl9kZXB0aE1hcFNpemU7XG5cblx0XHQoPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dCkuYWN0aXZhdGVUZXh0dXJlKG1ldGhvZFZPLnRleHR1cmVzSW5kZXggKyAxLCBTaGFkb3dEaXRoZXJlZE1ldGhvZC5fZ3JhaW5UZXh0dXJlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2V0Q2FzY2FkZUZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIGRlY29kZVJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgZGVwdGhUZXh0dXJlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgZGVwdGhQcm9qZWN0aW9uOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgdGFyZ2V0UmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgPSBkZXB0aFByb2plY3Rpb247XG5cblx0XHR2YXIgZGF0YVJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cdFx0bWV0aG9kVk8uc2Vjb25kYXJ5RnJhZ21lbnRDb25zdGFudHNJbmRleCA9IGRhdGFSZWcuaW5kZXgqNDtcblxuXHRcdHJldHVybiB0aGlzLmdldFNhbXBsZUNvZGUoZGF0YVJlZywgZGVwdGhUZXh0dXJlLCBkZWNvZGVSZWdpc3RlciwgdGFyZ2V0UmVnaXN0ZXIsIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2hhZG93RGl0aGVyZWRNZXRob2Q7Il19 \ No newline at end of file diff --git a/lib/materials/methods/ShadowDitheredMethod.ts b/lib/materials/methods/ShadowDitheredMethod.ts new file mode 100644 index 000000000..cbbfea3a4 --- /dev/null +++ b/lib/materials/methods/ShadowDitheredMethod.ts @@ -0,0 +1,297 @@ +import BitmapData = require("awayjs-core/lib/core/base/BitmapData"); +import DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +import BitmapTexture = require("awayjs-core/lib/textures/BitmapTexture"); + +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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); + +/** + * ShadowDitheredMethod provides a soft shadowing technique by randomly distributing sample points differently for each fragment. + */ +class ShadowDitheredMethod extends ShadowMethodBase +{ + private static _grainTexture:BitmapTexture; + private static _grainUsages:number /*int*/; + private static _grainBitmapData:BitmapData; + private _depthMapSize:number /*int*/; + private _range:number; + private _numSamples:number /*int*/; + + /** + * Creates a new ShadowDitheredMethod object. + * @param castingLight The light casting the shadows + * @param numSamples The amount of samples to take for dithering. Minimum 1, maximum 24. + */ + constructor(castingLight:DirectionalLight, numSamples:number /*int*/ = 4, range:number = 1) + { + super(castingLight); + + this._depthMapSize = this._pCastingLight.shadowMapper.depthMapSize; + + this.numSamples = numSamples; + this.range = range; + + ++ShadowDitheredMethod._grainUsages; + + if (!ShadowDitheredMethod._grainTexture) + this.initGrainTexture(); + } + + /** + * The amount of samples to take for dithering. Minimum 1, maximum 24. The actual maximum may depend on the + * complexity of the shader. + */ + public get numSamples():number /*int*/ + { + return this._numSamples; + } + + public set numSamples(value:number /*int*/) + { + this._numSamples = value; + if (this._numSamples < 1) + this._numSamples = 1; else if (this._numSamples > 24) + this._numSamples = 24; + this.iInvalidateShaderProgram(); + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + super.iInitVO(shaderObject, methodVO); + + methodVO.needsProjection = true; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + super.iInitConstants(shaderObject, methodVO); + + var fragmentData:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + fragmentData[index + 8] = 1/this._numSamples; + } + + /** + * The range in the shadow map in which to distribute the samples. + */ + public get range():number + { + return this._range*2; + } + + public set range(value:number) + { + this._range = value/2; + } + + /** + * Creates a texture containing the dithering noise texture. + */ + private initGrainTexture() + { + ShadowDitheredMethod._grainBitmapData = new BitmapData(64, 64, false); + var vec:Array /*uint*/ = new Array(); + var len:number /*uint*/ = 4096; + var step:number = 1/(this._depthMapSize*this._range); + var r:number, g:number; + + for (var i:number /*uint*/ = 0; i < len; ++i) { + r = 2*(Math.random() - .5); + g = 2*(Math.random() - .5); + if (r < 0) + r -= step; else + r += step; + if (g < 0) + g -= step; else + g += step; + if (r > 1) + r = 1; else if (r < -1) + r = -1; + if (g > 1) + g = 1; else if (g < -1) + g = -1; + vec[i] = (Math.floor((r*.5 + .5)*0xff) << 16) | (Math.floor((g*.5 + .5)*0xff) << 8); + } + + ShadowDitheredMethod._grainBitmapData.setVector(ShadowDitheredMethod._grainBitmapData.rect, vec); + ShadowDitheredMethod._grainTexture = new BitmapTexture(ShadowDitheredMethod._grainBitmapData); + } + + /** + * @inheritDoc + */ + public dispose() + { + if (--ShadowDitheredMethod._grainUsages == 0) { + ShadowDitheredMethod._grainTexture.dispose(); + ShadowDitheredMethod._grainBitmapData.dispose(); + ShadowDitheredMethod._grainTexture = null; + } + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + super.iActivate(shaderObject, methodVO, stage); + + var data:Array = shaderObject.fragmentConstantData; + var index:number /*uint*/ = methodVO.fragmentConstantsIndex; + data[index + 9] = (stage.width - 1)/63; + data[index + 10] = (stage.height - 1)/63; + data[index + 11] = 2*this._range/this._depthMapSize; + + ( stage.context).activateTexture(methodVO.texturesIndex + 1, ShadowDitheredMethod._grainTexture); + } + + /** + * @inheritDoc + */ + public _pGetPlanarFragmentCode(methodVO:MethodVO, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var depthMapRegister:ShaderRegisterElement = regCache.getFreeTextureReg(); + var decReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var dataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var customDataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + + methodVO.fragmentConstantsIndex = decReg.index*4; + methodVO.texturesIndex = depthMapRegister.index; + + return this.getSampleCode(customDataReg, depthMapRegister, decReg, targetReg, regCache, sharedRegisters); + } + + /** + * Get the actual shader code for shadow mapping + * @param regCache The register cache managing the registers. + * @param depthMapRegister The texture register containing the depth map. + * @param decReg The register containing the depth map decoding data. + * @param targetReg The target register to add the shadow coverage. + */ + private getSampleCode(customDataReg:ShaderRegisterElement, depthMapRegister:ShaderRegisterElement, decReg:ShaderRegisterElement, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + var grainRegister:ShaderRegisterElement = regCache.getFreeTextureReg(); + var uvReg:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + var numSamples:number /*int*/ = this._numSamples; + regCache.addFragmentTempUsages(uvReg, 1); + + var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + + var projectionReg:ShaderRegisterElement = sharedRegisters.projectionFragment; + + code += "div " + uvReg + ", " + projectionReg + ", " + projectionReg + ".w\n" + "mul " + uvReg + ".xy, " + uvReg + ".xy, " + customDataReg + ".yz\n"; + + while (numSamples > 0) { + if (numSamples == this._numSamples) + code += "tex " + uvReg + ", " + uvReg + ", " + grainRegister + " <2d,nearest,repeat,mipnone>\n"; + else + code += "tex " + uvReg + ", " + uvReg + ".zwxy, " + grainRegister + " <2d,nearest,repeat,mipnone>\n"; + + // keep grain in uvReg.zw + code += "sub " + uvReg + ".zw, " + uvReg + ".xy, fc0.xx\n" + // uv-.5 + "mul " + uvReg + ".zw, " + uvReg + ".zw, " + customDataReg + ".w\n"; // (tex unpack scale and tex scale in one) + + if (numSamples == this._numSamples) { + // first sample + code += "add " + uvReg + ".xy, " + uvReg + ".zw, " + this._pDepthMapCoordReg + ".xy\n" + + "tex " + temp + ", " + uvReg + ", " + depthMapRegister + " <2d,nearest,clamp,mipnone>\n" + + "dp4 " + temp + ".z, " + temp + ", " + decReg + "\n" + + "slt " + targetReg + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n"; // 0 if in shadow + } else { + code += this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + } + + if (numSamples > 4) + code += "add " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + if (numSamples > 1) + code += "sub " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + if (numSamples > 5) + code += "sub " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".zw\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + if (numSamples > 2) { + code += "neg " + uvReg + ".w, " + uvReg + ".w\n"; // will be rotated 90 degrees when being accessed as wz + code += "add " + uvReg + ".xy, " + uvReg + ".wz, " + this._pDepthMapCoordReg + ".xy\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + } + + if (numSamples > 6) + code += "add " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + if (numSamples > 3) + code += "sub " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + if (numSamples > 7) + code += "sub " + uvReg + ".xy, " + uvReg + ".xy, " + uvReg + ".wz\n" + this.addSample(uvReg, depthMapRegister, decReg, targetReg, regCache); + + numSamples -= 8; + } + + regCache.removeFragmentTempUsage(uvReg); + code += "mul " + targetReg + ".w, " + targetReg + ".w, " + customDataReg + ".x\n"; // average + return code; + } + + /** + * Adds the code for another tap to the shader code. + * @param uvReg The uv register for the tap. + * @param depthMapRegister The texture register containing the depth map. + * @param decReg The register containing the depth map decoding data. + * @param targetReg The target register to add the tap comparison result. + * @param regCache The register cache managing the registers. + * @return + */ + private addSample(uvReg:ShaderRegisterElement, depthMapRegister:ShaderRegisterElement, decReg:ShaderRegisterElement, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache):string + { + var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + + return "tex " + temp + ", " + uvReg + ", " + depthMapRegister + " <2d,nearest,clamp,mipnone>\n" + + "dp4 " + temp + ".z, " + temp + ", " + decReg + "\n" + + "slt " + temp + ".z, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n" + // 0 if in shadow + "add " + targetReg + ".w, " + targetReg + ".w, " + temp + ".z\n"; + } + + /** + * @inheritDoc + */ + public iActivateForCascade(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var data:Array = shaderObject.fragmentConstantData; + var index:number /*uint*/ = methodVO.secondaryFragmentConstantsIndex; + data[index] = 1/this._numSamples; + data[index + 1] = (stage.width - 1)/63; + data[index + 2] = (stage.height - 1)/63; + data[index + 3] = 2*this._range/this._depthMapSize; + + ( stage.context).activateTexture(methodVO.texturesIndex + 1, ShadowDitheredMethod._grainTexture); + } + + /** + * @inheritDoc + */ + public _iGetCascadeFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, decodeRegister:ShaderRegisterElement, depthTexture:ShaderRegisterElement, depthProjection:ShaderRegisterElement, targetRegister:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + this._pDepthMapCoordReg = depthProjection; + + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index*4; + + return this.getSampleCode(dataReg, depthTexture, decodeRegister, targetRegister, registerCache, sharedRegisters); + } +} + +export = ShadowDitheredMethod; \ No newline at end of file diff --git a/lib/materials/methods/ShadowFilteredMethod.js b/lib/materials/methods/ShadowFilteredMethod.js new file mode 100755 index 000000000..f10694e60 --- /dev/null +++ b/lib/materials/methods/ShadowFilteredMethod.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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +/** + * ShadowFilteredMethod provides a softened shadowing technique by bilinearly interpolating shadow comparison + * results of neighbouring pixels. + */ +var ShadowFilteredMethod = (function (_super) { + __extends(ShadowFilteredMethod, _super); + /** + * Creates a new DiffuseBasicMethod object. + * + * @param castingLight The light casting the shadow + */ + function ShadowFilteredMethod(castingLight) { + _super.call(this, castingLight); + } + /** + * @inheritDoc + */ + ShadowFilteredMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + _super.prototype.iInitConstants.call(this, shaderObject, methodVO); + var fragmentData = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex; + fragmentData[index + 8] = .5; + var size = this.castingLight.shadowMapper.depthMapSize; + fragmentData[index + 9] = size; + fragmentData[index + 10] = 1 / size; + }; + /** + * @inheritDoc + */ + ShadowFilteredMethod.prototype._pGetPlanarFragmentCode = function (methodVO, targetReg, regCache, sharedRegisters) { + var depthMapRegister = regCache.getFreeTextureReg(); + var decReg = regCache.getFreeFragmentConstant(); + var dataReg = regCache.getFreeFragmentConstant(); + // TODO: not used + dataReg = dataReg; + var customDataReg = regCache.getFreeFragmentConstant(); + var depthCol = regCache.getFreeFragmentVectorTemp(); + var uvReg; + var code = ""; + methodVO.fragmentConstantsIndex = decReg.index * 4; + regCache.addFragmentTempUsages(depthCol, 1); + uvReg = regCache.getFreeFragmentVectorTemp(); + regCache.addFragmentTempUsages(uvReg, 1); + code += "mov " + uvReg + ", " + this._pDepthMapCoordReg + "\n" + "tex " + depthCol + ", " + this._pDepthMapCoordReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".z, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + "add " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".z\n" + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".w, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + targetReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" + "mov " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x\n" + "add " + uvReg + ".y, " + this._pDepthMapCoordReg + ".y, " + customDataReg + ".z\n" + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".z, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + "add " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".z\n" + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".w, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + uvReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".y, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + targetReg + ".w\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + targetReg + ".w, " + targetReg + ".w, " + uvReg + ".w\n"; + regCache.removeFragmentTempUsage(depthCol); + regCache.removeFragmentTempUsage(uvReg); + methodVO.texturesIndex = depthMapRegister.index; + return code; + }; + /** + * @inheritDoc + */ + ShadowFilteredMethod.prototype.iActivateForCascade = function (shaderObject, methodVO, stage) { + var size = this.castingLight.shadowMapper.depthMapSize; + var index = methodVO.secondaryFragmentConstantsIndex; + var data = shaderObject.fragmentConstantData; + data[index] = size; + data[index + 1] = 1 / size; + }; + /** + * @inheritDoc + */ + ShadowFilteredMethod.prototype._iGetCascadeFragmentCode = function (shaderObject, methodVO, decodeRegister, depthTexture, depthProjection, targetRegister, registerCache, sharedRegisters) { + var code; + var dataReg = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index * 4; + var temp = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(temp, 1); + var predicate = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(predicate, 1); + code = "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".x, " + depthProjection + ".z, " + temp + ".z\n" + "add " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".z, " + depthProjection + ".z, " + temp + ".z\n" + "add " + depthProjection + ".y, " + depthProjection + ".y, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".w, " + depthProjection + ".z, " + temp + ".z\n" + "sub " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".y, " + depthProjection + ".z, " + temp + ".z\n" + "mul " + temp + ".xy, " + depthProjection + ".xy, " + dataReg + ".x\n" + "frc " + temp + ".xy, " + temp + ".xy\n" + "sub " + depthProjection + ", " + predicate + ".xyzw, " + predicate + ".zwxy\n" + "mul " + depthProjection + ", " + depthProjection + ", " + temp + ".x\n" + "add " + predicate + ".xy, " + predicate + ".xy, " + depthProjection + ".zw\n" + "sub " + predicate + ".y, " + predicate + ".y, " + predicate + ".x\n" + "mul " + predicate + ".y, " + predicate + ".y, " + temp + ".y\n" + "add " + targetRegister + ".w, " + predicate + ".x, " + predicate + ".y\n"; + registerCache.removeFragmentTempUsage(temp); + registerCache.removeFragmentTempUsage(predicate); + return code; + }; + return ShadowFilteredMethod; +})(ShadowMethodBase); +module.exports = ShadowFilteredMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NoYWRvd2ZpbHRlcmVkbWV0aG9kLnRzIl0sIm5hbWVzIjpbIlNoYWRvd0ZpbHRlcmVkTWV0aG9kIiwiU2hhZG93RmlsdGVyZWRNZXRob2QuY29uc3RydWN0b3IiLCJTaGFkb3dGaWx0ZXJlZE1ldGhvZC5pSW5pdENvbnN0YW50cyIsIlNoYWRvd0ZpbHRlcmVkTWV0aG9kLl9wR2V0UGxhbmFyRnJhZ21lbnRDb2RlIiwiU2hhZG93RmlsdGVyZWRNZXRob2QuaUFjdGl2YXRlRm9yQ2FzY2FkZSIsIlNoYWRvd0ZpbHRlcmVkTWV0aG9kLl9pR2V0Q2FzY2FkZUZyYWdtZW50Q29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBU0EsSUFBTyxnQkFBZ0IsV0FBZSx1REFBdUQsQ0FBQyxDQUFDO0FBRS9GLEFBSUE7OztHQURHO0lBQ0csb0JBQW9CO0lBQVNBLFVBQTdCQSxvQkFBb0JBLFVBQXlCQTtJQUVsREE7Ozs7T0FJR0E7SUFDSEEsU0FQS0Esb0JBQW9CQSxDQU9iQSxZQUE2QkE7UUFFeENDLGtCQUFNQSxZQUFZQSxDQUFDQSxDQUFDQTtJQUNyQkEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLDZDQUFjQSxHQUFyQkEsVUFBc0JBLFlBQWlDQSxFQUFFQSxRQUFpQkE7UUFFekVFLGdCQUFLQSxDQUFDQSxjQUFjQSxZQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUU3Q0EsSUFBSUEsWUFBWUEsR0FBaUJBLFlBQVlBLENBQUNBLG9CQUFvQkEsQ0FBQ0E7UUFDbkVBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSxzQkFBc0JBLENBQUNBO1FBQzNEQSxZQUFZQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQTtRQUM3QkEsSUFBSUEsSUFBSUEsR0FBa0JBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLFlBQVlBLENBQUNBLFlBQVlBLENBQUNBO1FBQ3RFQSxZQUFZQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMvQkEsWUFBWUEsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDbkNBLENBQUNBO0lBRURGOztPQUVHQTtJQUNJQSxzREFBdUJBLEdBQTlCQSxVQUErQkEsUUFBaUJBLEVBQUVBLFNBQStCQSxFQUFFQSxRQUE0QkEsRUFBRUEsZUFBa0NBO1FBRWxKRyxJQUFJQSxnQkFBZ0JBLEdBQXlCQSxRQUFRQSxDQUFDQSxpQkFBaUJBLEVBQUVBLENBQUNBO1FBQzFFQSxJQUFJQSxNQUFNQSxHQUF5QkEsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUN0RUEsSUFBSUEsT0FBT0EsR0FBeUJBLFFBQVFBLENBQUNBLHVCQUF1QkEsRUFBRUEsQ0FBQ0E7UUFDdkVBLEFBQ0FBLGlCQURpQkE7UUFDakJBLE9BQU9BLEdBQUdBLE9BQU9BLENBQUNBO1FBQ2xCQSxJQUFJQSxhQUFhQSxHQUF5QkEsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUM3RUEsSUFBSUEsUUFBUUEsR0FBeUJBLFFBQVFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7UUFDMUVBLElBQUlBLEtBQTJCQSxDQUFDQTtRQUNoQ0EsSUFBSUEsSUFBSUEsR0FBVUEsRUFBRUEsQ0FBQ0E7UUFDckJBLFFBQVFBLENBQUNBLHNCQUFzQkEsR0FBR0EsTUFBTUEsQ0FBQ0EsS0FBS0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFakRBLFFBQVFBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsUUFBUUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFNUNBLEtBQUtBLEdBQUdBLFFBQVFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7UUFDN0NBLFFBQVFBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFekNBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsSUFBSUEsR0FFN0RBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsSUFBSUEsR0FBR0EsZ0JBQWdCQSxHQUFHQSx5QkFBeUJBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FFeFBBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsTUFBTUEsR0FBR0EsYUFBYUEsR0FBR0EsTUFBTUEsR0FDbkZBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLEdBQUdBLGdCQUFnQkEsR0FBR0EseUJBQXlCQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBRXRPQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE1BQU1BLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBRWxVQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLEtBQUtBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsR0FBR0EsTUFBTUEsR0FBR0EsYUFBYUEsR0FBR0EsTUFBTUEsR0FDaEpBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLEdBQUdBLEtBQUtBLEdBQUdBLElBQUlBLEdBQUdBLGdCQUFnQkEsR0FBR0EseUJBQXlCQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE1BQU1BLEdBQUdBLFFBQVFBLEdBQUdBLE1BQU1BLEdBRXRPQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE1BQU1BLEdBQUdBLGFBQWFBLEdBQUdBLE1BQU1BLEdBQ25GQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxJQUFJQSxHQUFHQSxLQUFLQSxHQUFHQSxJQUFJQSxHQUFHQSxnQkFBZ0JBLEdBQUdBLHlCQUF5QkEsR0FBR0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FBR0EsS0FBS0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUd0T0EsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxHQUFHQSxhQUFhQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUU5VEEsTUFBTUEsR0FBR0EsUUFBUUEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxHQUFHQSxhQUFhQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUU1VUEsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUMzQ0EsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUV4Q0EsUUFBUUEsQ0FBQ0EsYUFBYUEsR0FBR0EsZ0JBQWdCQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUVoREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFREg7O09BRUdBO0lBQ0lBLGtEQUFtQkEsR0FBMUJBLFVBQTJCQSxZQUE2QkEsRUFBRUEsUUFBaUJBLEVBQUVBLEtBQVdBO1FBRXZGSSxJQUFJQSxJQUFJQSxHQUFrQkEsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsWUFBWUEsQ0FBQ0E7UUFDdEVBLElBQUlBLEtBQUtBLEdBQWtCQSxRQUFRQSxDQUFDQSwrQkFBK0JBLENBQUNBO1FBQ3BFQSxJQUFJQSxJQUFJQSxHQUFpQkEsWUFBWUEsQ0FBQ0Esb0JBQW9CQSxDQUFDQTtRQUMzREEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDbkJBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBO0lBQzFCQSxDQUFDQTtJQUVESjs7T0FFR0E7SUFDSUEsdURBQXdCQSxHQUEvQkEsVUFBZ0NBLFlBQTZCQSxFQUFFQSxRQUFpQkEsRUFBRUEsY0FBb0NBLEVBQUVBLFlBQWtDQSxFQUFFQSxlQUFxQ0EsRUFBRUEsY0FBb0NBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFN1NLLElBQUlBLElBQVdBLENBQUNBO1FBQ2hCQSxJQUFJQSxPQUFPQSxHQUF5QkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxFQUFFQSxDQUFDQTtRQUM1RUEsUUFBUUEsQ0FBQ0EsK0JBQStCQSxHQUFHQSxPQUFPQSxDQUFDQSxLQUFLQSxHQUFDQSxDQUFDQSxDQUFDQTtRQUMzREEsSUFBSUEsSUFBSUEsR0FBeUJBLGFBQWFBLENBQUNBLHlCQUF5QkEsRUFBRUEsQ0FBQ0E7UUFDM0VBLGFBQWFBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0NBLElBQUlBLFNBQVNBLEdBQXlCQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1FBQ2hGQSxhQUFhQSxDQUFDQSxxQkFBcUJBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBRWxEQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxHQUFHQSxJQUFJQSxHQUFHQSxZQUFZQSxHQUFHQSx5QkFBeUJBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLGNBQWNBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBRXRPQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxPQUFPQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxHQUFHQSxJQUFJQSxHQUFHQSxZQUFZQSxHQUFHQSx5QkFBeUJBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLGNBQWNBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBRWxUQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxPQUFPQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxHQUFHQSxJQUFJQSxHQUFHQSxZQUFZQSxHQUFHQSx5QkFBeUJBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLGNBQWNBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBRWxUQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxlQUFlQSxHQUFHQSxNQUFNQSxHQUFHQSxPQUFPQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxlQUFlQSxHQUFHQSxJQUFJQSxHQUFHQSxZQUFZQSxHQUFHQSx5QkFBeUJBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLElBQUlBLEdBQUdBLGNBQWNBLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLGVBQWVBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLEdBQUdBLE1BQU1BLEdBRWxUQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxlQUFlQSxHQUFHQSxPQUFPQSxHQUFHQSxPQUFPQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUFHQSxJQUFJQSxHQUFHQSxPQUFPQSxHQUdqSEEsTUFBTUEsR0FBR0EsZUFBZUEsR0FBR0EsSUFBSUEsR0FBR0EsU0FBU0EsR0FBR0EsU0FBU0EsR0FBR0EsU0FBU0EsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsZUFBZUEsR0FBR0EsSUFBSUEsR0FBR0EsZUFBZUEsR0FBR0EsSUFBSUEsR0FBR0EsSUFBSUEsR0FBR0EsTUFBTUEsR0FFMUpBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE9BQU9BLEdBQUdBLFNBQVNBLEdBQUdBLE9BQU9BLEdBQUdBLGVBQWVBLEdBQUdBLE9BQU9BLEdBRTlFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxNQUFNQSxHQUFHQSxjQUFjQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUV2TkEsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUM1Q0EsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUNqREEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFDRkwsMkJBQUNBO0FBQURBLENBMUhBLEFBMEhDQSxFQTFIa0MsZ0JBQWdCLEVBMEhsRDtBQUVELEFBQThCLGlCQUFyQixvQkFBb0IsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9TaGFkb3dGaWx0ZXJlZE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEaXJlY3Rpb25hbExpZ2h0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9EaXJlY3Rpb25hbExpZ2h0XCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyTGlnaHRpbmdPYmplY3RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyTGlnaHRpbmdPYmplY3RcIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgU2hhZG93TWV0aG9kQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU2hhZG93TWV0aG9kQmFzZVwiKTtcblxuLyoqXG4gKiBTaGFkb3dGaWx0ZXJlZE1ldGhvZCBwcm92aWRlcyBhIHNvZnRlbmVkIHNoYWRvd2luZyB0ZWNobmlxdWUgYnkgYmlsaW5lYXJseSBpbnRlcnBvbGF0aW5nIHNoYWRvdyBjb21wYXJpc29uXG4gKiByZXN1bHRzIG9mIG5laWdoYm91cmluZyBwaXhlbHMuXG4gKi9cbmNsYXNzIFNoYWRvd0ZpbHRlcmVkTWV0aG9kIGV4dGVuZHMgU2hhZG93TWV0aG9kQmFzZVxue1xuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBEaWZmdXNlQmFzaWNNZXRob2Qgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gY2FzdGluZ0xpZ2h0IFRoZSBsaWdodCBjYXN0aW5nIHRoZSBzaGFkb3dcblx0ICovXG5cdGNvbnN0cnVjdG9yKGNhc3RpbmdMaWdodDpEaXJlY3Rpb25hbExpZ2h0KVxuXHR7XG5cdFx0c3VwZXIoY2FzdGluZ0xpZ2h0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRzdXBlci5pSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblxuXHRcdHZhciBmcmFnbWVudERhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDhdID0gLjU7XG5cdFx0dmFyIHNpemU6bnVtYmVyIC8qaW50Ki8gPSB0aGlzLmNhc3RpbmdMaWdodC5zaGFkb3dNYXBwZXIuZGVwdGhNYXBTaXplO1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDldID0gc2l6ZTtcblx0XHRmcmFnbWVudERhdGFbaW5kZXggKyAxMF0gPSAxL3NpemU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcEdldFBsYW5hckZyYWdtZW50Q29kZShtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgZGVwdGhNYXBSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgZGF0YVJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdC8vIFRPRE86IG5vdCB1c2VkXG5cdFx0ZGF0YVJlZyA9IGRhdGFSZWc7XG5cdFx0dmFyIGN1c3RvbURhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgZGVwdGhDb2w6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHZhciB1dlJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGVjUmVnLmluZGV4KjQ7XG5cblx0XHRyZWdDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXMoZGVwdGhDb2wsIDEpO1xuXG5cdFx0dXZSZWcgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmVnQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHV2UmVnLCAxKTtcblxuXHRcdGNvZGUgKz0gXCJtb3YgXCIgKyB1dlJlZyArIFwiLCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCJcXG5cIiArXG5cblx0XHRcdFwidGV4IFwiICsgZGVwdGhDb2wgKyBcIiwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLCBcIiArIGRlcHRoTWFwUmVnaXN0ZXIgKyBcIiA8MmQsIG5lYXJlc3QsIGNsYW1wPlxcblwiICsgXCJkcDQgXCIgKyBkZXB0aENvbCArIFwiLnosIFwiICsgZGVwdGhDb2wgKyBcIiwgXCIgKyBkZWNSZWcgKyBcIlxcblwiICsgXCJzbHQgXCIgKyB1dlJlZyArIFwiLnosIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi56LCBcIiArIGRlcHRoQ29sICsgXCIuelxcblwiICsgICAvLyAwIGlmIGluIHNoYWRvd1xuXG5cdFx0XHRcImFkZCBcIiArIHV2UmVnICsgXCIueCwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLngsIFwiICsgY3VzdG9tRGF0YVJlZyArIFwiLnpcXG5cIiArIFx0Ly8gKDEsIDApXG5cdFx0XHRcInRleCBcIiArIGRlcHRoQ29sICsgXCIsIFwiICsgdXZSZWcgKyBcIiwgXCIgKyBkZXB0aE1hcFJlZ2lzdGVyICsgXCIgPDJkLCBuZWFyZXN0LCBjbGFtcD5cXG5cIiArIFwiZHA0IFwiICsgZGVwdGhDb2wgKyBcIi56LCBcIiArIGRlcHRoQ29sICsgXCIsIFwiICsgZGVjUmVnICsgXCJcXG5cIiArIFwic2x0IFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueiwgXCIgKyBkZXB0aENvbCArIFwiLnpcXG5cIiArICAgLy8gMCBpZiBpbiBzaGFkb3dcblxuXHRcdFx0XCJtdWwgXCIgKyBkZXB0aENvbCArIFwiLngsIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi54LCBcIiArIGN1c3RvbURhdGFSZWcgKyBcIi55XFxuXCIgKyBcImZyYyBcIiArIGRlcHRoQ29sICsgXCIueCwgXCIgKyBkZXB0aENvbCArIFwiLnhcXG5cIiArIFwic3ViIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHV2UmVnICsgXCIudywgXCIgKyB1dlJlZyArIFwiLnpcXG5cIiArIFwibXVsIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHV2UmVnICsgXCIudywgXCIgKyBkZXB0aENvbCArIFwiLnhcXG5cIiArIFwiYWRkIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB1dlJlZyArIFwiLnosIFwiICsgdXZSZWcgKyBcIi53XFxuXCIgK1xuXG5cdFx0XHRcIm1vdiBcIiArIHV2UmVnICsgXCIueCwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLnhcXG5cIiArIFwiYWRkIFwiICsgdXZSZWcgKyBcIi55LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueSwgXCIgKyBjdXN0b21EYXRhUmVnICsgXCIuelxcblwiICtcdC8vICgwLCAxKVxuXHRcdFx0XCJ0ZXggXCIgKyBkZXB0aENvbCArIFwiLCBcIiArIHV2UmVnICsgXCIsIFwiICsgZGVwdGhNYXBSZWdpc3RlciArIFwiIDwyZCwgbmVhcmVzdCwgY2xhbXA+XFxuXCIgKyBcImRwNCBcIiArIGRlcHRoQ29sICsgXCIueiwgXCIgKyBkZXB0aENvbCArIFwiLCBcIiArIGRlY1JlZyArIFwiXFxuXCIgKyBcInNsdCBcIiArIHV2UmVnICsgXCIueiwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLnosIFwiICsgZGVwdGhDb2wgKyBcIi56XFxuXCIgKyAgIC8vIDAgaWYgaW4gc2hhZG93XG5cblx0XHRcdFwiYWRkIFwiICsgdXZSZWcgKyBcIi54LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueCwgXCIgKyBjdXN0b21EYXRhUmVnICsgXCIuelxcblwiICtcdC8vICgxLCAxKVxuXHRcdFx0XCJ0ZXggXCIgKyBkZXB0aENvbCArIFwiLCBcIiArIHV2UmVnICsgXCIsIFwiICsgZGVwdGhNYXBSZWdpc3RlciArIFwiIDwyZCwgbmVhcmVzdCwgY2xhbXA+XFxuXCIgKyBcImRwNCBcIiArIGRlcHRoQ29sICsgXCIueiwgXCIgKyBkZXB0aENvbCArIFwiLCBcIiArIGRlY1JlZyArIFwiXFxuXCIgKyBcInNsdCBcIiArIHV2UmVnICsgXCIudywgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLnosIFwiICsgZGVwdGhDb2wgKyBcIi56XFxuXCIgKyAgIC8vIDAgaWYgaW4gc2hhZG93XG5cblx0XHRcdC8vIHJlY2FsY3VsYXRlIGZyYWN0aW9uLCBzaW5jZSB3ZSByYW4gb3V0IG9mIHJlZ2lzdGVycyA6KFxuXHRcdFx0XCJtdWwgXCIgKyBkZXB0aENvbCArIFwiLngsIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi54LCBcIiArIGN1c3RvbURhdGFSZWcgKyBcIi55XFxuXCIgKyBcImZyYyBcIiArIGRlcHRoQ29sICsgXCIueCwgXCIgKyBkZXB0aENvbCArIFwiLnhcXG5cIiArIFwic3ViIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHV2UmVnICsgXCIudywgXCIgKyB1dlJlZyArIFwiLnpcXG5cIiArIFwibXVsIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHV2UmVnICsgXCIudywgXCIgKyBkZXB0aENvbCArIFwiLnhcXG5cIiArIFwiYWRkIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIHV2UmVnICsgXCIueiwgXCIgKyB1dlJlZyArIFwiLndcXG5cIiArXG5cblx0XHRcdFwibXVsIFwiICsgZGVwdGhDb2wgKyBcIi54LCBcIiArIHRoaXMuX3BEZXB0aE1hcENvb3JkUmVnICsgXCIueSwgXCIgKyBjdXN0b21EYXRhUmVnICsgXCIueVxcblwiICsgXCJmcmMgXCIgKyBkZXB0aENvbCArIFwiLngsIFwiICsgZGVwdGhDb2wgKyBcIi54XFxuXCIgKyBcInN1YiBcIiArIHV2UmVnICsgXCIudywgXCIgKyB1dlJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIud1xcblwiICsgXCJtdWwgXCIgKyB1dlJlZyArIFwiLncsIFwiICsgdXZSZWcgKyBcIi53LCBcIiArIGRlcHRoQ29sICsgXCIueFxcblwiICsgXCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdXZSZWcgKyBcIi53XFxuXCI7XG5cblx0XHRyZWdDYWNoZS5yZW1vdmVGcmFnbWVudFRlbXBVc2FnZShkZXB0aENvbCk7XG5cdFx0cmVnQ2FjaGUucmVtb3ZlRnJhZ21lbnRUZW1wVXNhZ2UodXZSZWcpO1xuXG5cdFx0bWV0aG9kVk8udGV4dHVyZXNJbmRleCA9IGRlcHRoTWFwUmVnaXN0ZXIuaW5kZXg7XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZUZvckNhc2NhZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHZhciBzaXplOm51bWJlciAvKmludCovID0gdGhpcy5jYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyLmRlcHRoTWFwU2l6ZTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cdFx0ZGF0YVtpbmRleF0gPSBzaXplO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDEvc2l6ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2V0Q2FzY2FkZUZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIGRlY29kZVJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgZGVwdGhUZXh0dXJlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgZGVwdGhQcm9qZWN0aW9uOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgdGFyZ2V0UmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nO1xuXHRcdHZhciBkYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGF0YVJlZy5pbmRleCo0O1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHRlbXAsIDEpO1xuXHRcdHZhciBwcmVkaWNhdGU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmVnaXN0ZXJDYWNoZS5hZGRGcmFnbWVudFRlbXBVc2FnZXMocHJlZGljYXRlLCAxKTtcblxuXHRcdGNvZGUgPSBcInRleCBcIiArIHRlbXAgKyBcIiwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIiwgXCIgKyBkZXB0aFRleHR1cmUgKyBcIiA8MmQsIG5lYXJlc3QsIGNsYW1wPlxcblwiICsgXCJkcDQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGVjb2RlUmVnaXN0ZXIgKyBcIlxcblwiICsgXCJzbHQgXCIgKyBwcmVkaWNhdGUgKyBcIi54LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnosIFwiICsgdGVtcCArIFwiLnpcXG5cIiArXG5cblx0XHRcdFwiYWRkIFwiICsgZGVwdGhQcm9qZWN0aW9uICsgXCIueCwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIi54LCBcIiArIGRhdGFSZWcgKyBcIi55XFxuXCIgKyBcInRleCBcIiArIHRlbXAgKyBcIiwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIiwgXCIgKyBkZXB0aFRleHR1cmUgKyBcIiA8MmQsIG5lYXJlc3QsIGNsYW1wPlxcblwiICsgXCJkcDQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGVjb2RlUmVnaXN0ZXIgKyBcIlxcblwiICsgXCJzbHQgXCIgKyBwcmVkaWNhdGUgKyBcIi56LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnosIFwiICsgdGVtcCArIFwiLnpcXG5cIiArXG5cblx0XHRcdFwiYWRkIFwiICsgZGVwdGhQcm9qZWN0aW9uICsgXCIueSwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIi55LCBcIiArIGRhdGFSZWcgKyBcIi55XFxuXCIgKyBcInRleCBcIiArIHRlbXAgKyBcIiwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIiwgXCIgKyBkZXB0aFRleHR1cmUgKyBcIiA8MmQsIG5lYXJlc3QsIGNsYW1wPlxcblwiICsgXCJkcDQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGVjb2RlUmVnaXN0ZXIgKyBcIlxcblwiICsgXCJzbHQgXCIgKyBwcmVkaWNhdGUgKyBcIi53LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnosIFwiICsgdGVtcCArIFwiLnpcXG5cIiArXG5cblx0XHRcdFwic3ViIFwiICsgZGVwdGhQcm9qZWN0aW9uICsgXCIueCwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIi54LCBcIiArIGRhdGFSZWcgKyBcIi55XFxuXCIgKyBcInRleCBcIiArIHRlbXAgKyBcIiwgXCIgKyBkZXB0aFByb2plY3Rpb24gKyBcIiwgXCIgKyBkZXB0aFRleHR1cmUgKyBcIiA8MmQsIG5lYXJlc3QsIGNsYW1wPlxcblwiICsgXCJkcDQgXCIgKyB0ZW1wICsgXCIueiwgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGVjb2RlUmVnaXN0ZXIgKyBcIlxcblwiICsgXCJzbHQgXCIgKyBwcmVkaWNhdGUgKyBcIi55LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnosIFwiICsgdGVtcCArIFwiLnpcXG5cIiArXG5cblx0XHRcdFwibXVsIFwiICsgdGVtcCArIFwiLnh5LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnh5LCBcIiArIGRhdGFSZWcgKyBcIi54XFxuXCIgKyBcImZyYyBcIiArIHRlbXAgKyBcIi54eSwgXCIgKyB0ZW1wICsgXCIueHlcXG5cIiArXG5cblx0XHRcdC8vIHNvbWUgc3RyYW5nZSByZWdpc3RlciBqdWdnbGluZyB0byBwcmV2ZW50IGFnYWwgYnVnZ2luZyBvdXRcblx0XHRcdFwic3ViIFwiICsgZGVwdGhQcm9qZWN0aW9uICsgXCIsIFwiICsgcHJlZGljYXRlICsgXCIueHl6dywgXCIgKyBwcmVkaWNhdGUgKyBcIi56d3h5XFxuXCIgKyBcIm11bCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLCBcIiArIHRlbXAgKyBcIi54XFxuXCIgK1xuXG5cdFx0XHRcImFkZCBcIiArIHByZWRpY2F0ZSArIFwiLnh5LCBcIiArIHByZWRpY2F0ZSArIFwiLnh5LCBcIiArIGRlcHRoUHJvamVjdGlvbiArIFwiLnp3XFxuXCIgK1xuXG5cdFx0XHRcInN1YiBcIiArIHByZWRpY2F0ZSArIFwiLnksIFwiICsgcHJlZGljYXRlICsgXCIueSwgXCIgKyBwcmVkaWNhdGUgKyBcIi54XFxuXCIgKyBcIm11bCBcIiArIHByZWRpY2F0ZSArIFwiLnksIFwiICsgcHJlZGljYXRlICsgXCIueSwgXCIgKyB0ZW1wICsgXCIueVxcblwiICsgXCJhZGQgXCIgKyB0YXJnZXRSZWdpc3RlciArIFwiLncsIFwiICsgcHJlZGljYXRlICsgXCIueCwgXCIgKyBwcmVkaWNhdGUgKyBcIi55XFxuXCI7XG5cblx0XHRyZWdpc3RlckNhY2hlLnJlbW92ZUZyYWdtZW50VGVtcFVzYWdlKHRlbXApO1xuXHRcdHJlZ2lzdGVyQ2FjaGUucmVtb3ZlRnJhZ21lbnRUZW1wVXNhZ2UocHJlZGljYXRlKTtcblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBTaGFkb3dGaWx0ZXJlZE1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/ShadowFilteredMethod.ts b/lib/materials/methods/ShadowFilteredMethod.ts new file mode 100644 index 000000000..d234fecd3 --- /dev/null +++ b/lib/materials/methods/ShadowFilteredMethod.ts @@ -0,0 +1,140 @@ +import DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); + +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 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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); + +/** + * ShadowFilteredMethod provides a softened shadowing technique by bilinearly interpolating shadow comparison + * results of neighbouring pixels. + */ +class ShadowFilteredMethod extends ShadowMethodBase +{ + /** + * Creates a new DiffuseBasicMethod object. + * + * @param castingLight The light casting the shadow + */ + constructor(castingLight:DirectionalLight) + { + super(castingLight); + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + super.iInitConstants(shaderObject, methodVO); + + var fragmentData:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.fragmentConstantsIndex; + fragmentData[index + 8] = .5; + var size:number /*int*/ = this.castingLight.shadowMapper.depthMapSize; + fragmentData[index + 9] = size; + fragmentData[index + 10] = 1/size; + } + + /** + * @inheritDoc + */ + public _pGetPlanarFragmentCode(methodVO:MethodVO, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var depthMapRegister:ShaderRegisterElement = regCache.getFreeTextureReg(); + var decReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var dataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + // TODO: not used + dataReg = dataReg; + var customDataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var depthCol:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + var uvReg:ShaderRegisterElement; + var code:string = ""; + methodVO.fragmentConstantsIndex = decReg.index*4; + + regCache.addFragmentTempUsages(depthCol, 1); + + uvReg = regCache.getFreeFragmentVectorTemp(); + regCache.addFragmentTempUsages(uvReg, 1); + + code += "mov " + uvReg + ", " + this._pDepthMapCoordReg + "\n" + + + "tex " + depthCol + ", " + this._pDepthMapCoordReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".z, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow + + "add " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".z\n" + // (1, 0) + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".w, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow + + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + targetReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" + + + "mov " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x\n" + "add " + uvReg + ".y, " + this._pDepthMapCoordReg + ".y, " + customDataReg + ".z\n" + // (0, 1) + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".z, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow + + "add " + uvReg + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".z\n" + // (1, 1) + "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" + "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" + "slt " + uvReg + ".w, " + this._pDepthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow + + // recalculate fraction, since we ran out of registers :( + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".x, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + uvReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" + + + "mul " + depthCol + ".x, " + this._pDepthMapCoordReg + ".y, " + customDataReg + ".y\n" + "frc " + depthCol + ".x, " + depthCol + ".x\n" + "sub " + uvReg + ".w, " + uvReg + ".w, " + targetReg + ".w\n" + "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" + "add " + targetReg + ".w, " + targetReg + ".w, " + uvReg + ".w\n"; + + regCache.removeFragmentTempUsage(depthCol); + regCache.removeFragmentTempUsage(uvReg); + + methodVO.texturesIndex = depthMapRegister.index; + + return code; + } + + /** + * @inheritDoc + */ + public iActivateForCascade(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + var size:number /*int*/ = this.castingLight.shadowMapper.depthMapSize; + var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex; + var data:Array = shaderObject.fragmentConstantData; + data[index] = size; + data[index + 1] = 1/size; + } + + /** + * @inheritDoc + */ + public _iGetCascadeFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, decodeRegister:ShaderRegisterElement, depthTexture:ShaderRegisterElement, depthProjection:ShaderRegisterElement, targetRegister:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string; + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index*4; + var temp:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(temp, 1); + var predicate:ShaderRegisterElement = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(predicate, 1); + + code = "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".x, " + depthProjection + ".z, " + temp + ".z\n" + + + "add " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".z, " + depthProjection + ".z, " + temp + ".z\n" + + + "add " + depthProjection + ".y, " + depthProjection + ".y, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".w, " + depthProjection + ".z, " + temp + ".z\n" + + + "sub " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" + "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + predicate + ".y, " + depthProjection + ".z, " + temp + ".z\n" + + + "mul " + temp + ".xy, " + depthProjection + ".xy, " + dataReg + ".x\n" + "frc " + temp + ".xy, " + temp + ".xy\n" + + + // some strange register juggling to prevent agal bugging out + "sub " + depthProjection + ", " + predicate + ".xyzw, " + predicate + ".zwxy\n" + "mul " + depthProjection + ", " + depthProjection + ", " + temp + ".x\n" + + + "add " + predicate + ".xy, " + predicate + ".xy, " + depthProjection + ".zw\n" + + + "sub " + predicate + ".y, " + predicate + ".y, " + predicate + ".x\n" + "mul " + predicate + ".y, " + predicate + ".y, " + temp + ".y\n" + "add " + targetRegister + ".w, " + predicate + ".x, " + predicate + ".y\n"; + + registerCache.removeFragmentTempUsage(temp); + registerCache.removeFragmentTempUsage(predicate); + return code; + } +} + +export = ShadowFilteredMethod; \ No newline at end of file diff --git a/lib/materials/methods/ShadowNearMethod.js b/lib/materials/methods/ShadowNearMethod.js new file mode 100755 index 000000000..a2f82f4e2 --- /dev/null +++ b/lib/materials/methods/ShadowNearMethod.js @@ -0,0 +1,185 @@ +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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +// TODO: shadow mappers references in materials should be an interface so that this class should NOT extend ShadowMapMethodBase just for some delegation work +/** + * ShadowNearMethod provides a shadow map method that restricts the shadowed area near the camera to optimize + * shadow map usage. This method needs to be used in conjunction with a NearDirectionalShadowMapper. + * + * @see away.lights.NearDirectionalShadowMapper + */ +var ShadowNearMethod = (function (_super) { + __extends(ShadowNearMethod, _super); + /** + * Creates a new ShadowNearMethod object. + * @param baseMethod The shadow map sampling method used to sample individual cascades (fe: ShadowHardMethod, ShadowSoftMethod) + * @param fadeRatio The amount of shadow fading to the outer shadow area. A value of 1 would mean the shadows start fading from the camera's near plane. + */ + function ShadowNearMethod(baseMethod, fadeRatio) { + var _this = this; + if (fadeRatio === void 0) { fadeRatio = .1; } + _super.call(this, baseMethod.castingLight); + this._onShaderInvalidatedDelegate = function (event) { return _this.onShaderInvalidated(event); }; + this._baseMethod = baseMethod; + this._fadeRatio = fadeRatio; + this._nearShadowMapper = this._pCastingLight.shadowMapper; + if (!this._nearShadowMapper) + throw new Error("ShadowNearMethod requires a light that has a NearDirectionalShadowMapper instance assigned to shadowMapper."); + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + } + Object.defineProperty(ShadowNearMethod.prototype, "baseMethod", { + /** + * The base shadow map method on which this method's shading is based. + */ + get: function () { + return this._baseMethod; + }, + set: function (value) { + if (this._baseMethod == value) + return; + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this._baseMethod = value; + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + _super.prototype.iInitConstants.call(this, shaderObject, methodVO); + this._baseMethod.iInitConstants(shaderObject, methodVO); + var fragmentData = shaderObject.fragmentConstantData; + var index = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index + 2] = 0; + fragmentData[index + 3] = 1; + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iInitVO = function (shaderObject, methodVO) { + this._baseMethod.iInitVO(shaderObject, methodVO); + methodVO.needsProjection = true; + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.dispose = function () { + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + }; + Object.defineProperty(ShadowNearMethod.prototype, "alpha", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.alpha; + }, + set: function (value) { + this._baseMethod.alpha = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ShadowNearMethod.prototype, "epsilon", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.epsilon; + }, + set: function (value) { + this._baseMethod.epsilon = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ShadowNearMethod.prototype, "fadeRatio", { + /** + * The amount of shadow fading to the outer shadow area. A value of 1 would mean the shadows start fading from the camera's near plane. + */ + get: function () { + return this._fadeRatio; + }, + set: function (value) { + this._fadeRatio = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iGetFragmentCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var code = this._baseMethod.iGetFragmentCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + var dataReg = registerCache.getFreeFragmentConstant(); + var temp = registerCache.getFreeFragmentSingleTemp(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index * 4; + code += "abs " + temp + ", " + sharedRegisters.projectionFragment + ".w\n" + "sub " + temp + ", " + temp + ", " + dataReg + ".x\n" + "mul " + temp + ", " + temp + ", " + dataReg + ".y\n" + "sat " + temp + ", " + temp + "\n" + "sub " + temp + ", " + dataReg + ".w," + temp + "\n" + "sub " + targetReg + ".w, " + dataReg + ".w," + targetReg + ".w\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + temp + "\n" + "sub " + targetReg + ".w, " + dataReg + ".w," + targetReg + ".w\n"; + return code; + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + this._baseMethod.iActivate(shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iDeactivate = function (shaderObject, methodVO, stage) { + this._baseMethod.iDeactivate(shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iSetRenderState = function (shaderObject, methodVO, renderable, stage, camera) { + // todo: move this to activate (needs camera) + var near = camera.projection.near; + var d = camera.projection.far - near; + var maxDistance = this._nearShadowMapper.coverageRatio; + var minDistance = maxDistance * (1 - this._fadeRatio); + maxDistance = near + maxDistance * d; + minDistance = near + minDistance * d; + var fragmentData = shaderObject.fragmentConstantData; + var index = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index] = minDistance; + fragmentData[index + 1] = 1 / (maxDistance - minDistance); + this._baseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera); + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iGetVertexCode = function (shaderObject, methodVO, registerCache, sharedRegisters) { + return this._baseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iReset = function () { + this._baseMethod.iReset(); + }; + /** + * @inheritDoc + */ + ShadowNearMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._baseMethod.iCleanCompilationData(); + }; + /** + * Called when the base method's shader code is invalidated. + */ + ShadowNearMethod.prototype.onShaderInvalidated = function (event) { + this.iInvalidateShaderProgram(); + }; + return ShadowNearMethod; +})(ShadowMethodBase); +module.exports = ShadowNearMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NoYWRvd25lYXJtZXRob2QudHMiXSwibmFtZXMiOlsiU2hhZG93TmVhck1ldGhvZCIsIlNoYWRvd05lYXJNZXRob2QuY29uc3RydWN0b3IiLCJTaGFkb3dOZWFyTWV0aG9kLmJhc2VNZXRob2QiLCJTaGFkb3dOZWFyTWV0aG9kLmlJbml0Q29uc3RhbnRzIiwiU2hhZG93TmVhck1ldGhvZC5pSW5pdFZPIiwiU2hhZG93TmVhck1ldGhvZC5kaXNwb3NlIiwiU2hhZG93TmVhck1ldGhvZC5hbHBoYSIsIlNoYWRvd05lYXJNZXRob2QuZXBzaWxvbiIsIlNoYWRvd05lYXJNZXRob2QuZmFkZVJhdGlvIiwiU2hhZG93TmVhck1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlIiwiU2hhZG93TmVhck1ldGhvZC5pQWN0aXZhdGUiLCJTaGFkb3dOZWFyTWV0aG9kLmlEZWFjdGl2YXRlIiwiU2hhZG93TmVhck1ldGhvZC5pU2V0UmVuZGVyU3RhdGUiLCJTaGFkb3dOZWFyTWV0aG9kLmlHZXRWZXJ0ZXhDb2RlIiwiU2hhZG93TmVhck1ldGhvZC5pUmVzZXQiLCJTaGFkb3dOZWFyTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIlNoYWRvd05lYXJNZXRob2Qub25TaGFkZXJJbnZhbGlkYXRlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBS0EsSUFBTyxrQkFBa0IsV0FBYyw4Q0FBOEMsQ0FBQyxDQUFDO0FBT3ZGLElBQU8sZ0JBQWdCLFdBQWUsdURBQXVELENBQUMsQ0FBQztBQUUvRixBQU9BLDZKQVA2SjtBQUM3Sjs7Ozs7R0FLRztJQUNHLGdCQUFnQjtJQUFTQSxVQUF6QkEsZ0JBQWdCQSxVQUF5QkE7SUFTOUNBOzs7O09BSUdBO0lBQ0hBLFNBZEtBLGdCQUFnQkEsQ0FjVEEsVUFBMkJBLEVBQUVBLFNBQXFCQTtRQWQvREMsaUJBc05DQTtRQXhNeUNBLHlCQUFxQkEsR0FBckJBLGNBQXFCQTtRQUU3REEsa0JBQU1BLFVBQVVBLENBQUNBLFlB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ZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTmVhckRpcmVjdGlvbmFsU2hhZG93TWFwcGVyXHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9tYXRlcmlhbHMvc2hhZG93bWFwcGVycy9OZWFyRGlyZWN0aW9uYWxTaGFkb3dNYXBwZXJcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBTaGFkaW5nTWV0aG9kRXZlbnRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9ldmVudHMvU2hhZGluZ01ldGhvZEV2ZW50XCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IFNoYWRvd01ldGhvZEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NoYWRvd01ldGhvZEJhc2VcIik7XG5cbi8vIFRPRE86IHNoYWRvdyBtYXBwZXJzIHJlZmVyZW5jZXMgaW4gbWF0ZXJpYWxzIHNob3VsZCBiZSBhbiBpbnRlcmZhY2Ugc28gdGhhdCB0aGlzIGNsYXNzIHNob3VsZCBOT1QgZXh0ZW5kIFNoYWRvd01hcE1ldGhvZEJhc2UganVzdCBmb3Igc29tZSBkZWxlZ2F0aW9uIHdvcmtcbi8qKlxuICogU2hhZG93TmVhck1ldGhvZCBwcm92aWRlcyBhIHNoYWRvdyBtYXAgbWV0aG9kIHRoYXQgcmVzdHJpY3RzIHRoZSBzaGFkb3dlZCBhcmVhIG5lYXIgdGhlIGNhbWVyYSB0byBvcHRpbWl6ZVxuICogc2hhZG93IG1hcCB1c2FnZS4gVGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGEgTmVhckRpcmVjdGlvbmFsU2hhZG93TWFwcGVyLlxuICpcbiAqIEBzZWUgYXdheS5saWdodHMuTmVhckRpcmVjdGlvbmFsU2hhZG93TWFwcGVyXG4gKi9cbmNsYXNzIFNoYWRvd05lYXJNZXRob2QgZXh0ZW5kcyBTaGFkb3dNZXRob2RCYXNlXG57XG5cdHByaXZhdGUgX2Jhc2VNZXRob2Q6U2hhZG93TWV0aG9kQmFzZTtcblxuXHRwcml2YXRlIF9mYWRlUmF0aW86bnVtYmVyO1xuXHRwcml2YXRlIF9uZWFyU2hhZG93TWFwcGVyOk5lYXJEaXJlY3Rpb25hbFNoYWRvd01hcHBlcjtcblxuXHRwcml2YXRlIF9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGU6RnVuY3Rpb247XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgU2hhZG93TmVhck1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBzaGFkb3cgbWFwIHNhbXBsaW5nIG1ldGhvZCB1c2VkIHRvIHNhbXBsZSBpbmRpdmlkdWFsIGNhc2NhZGVzIChmZTogU2hhZG93SGFyZE1ldGhvZCwgU2hhZG93U29mdE1ldGhvZClcblx0ICogQHBhcmFtIGZhZGVSYXRpbyBUaGUgYW1vdW50IG9mIHNoYWRvdyBmYWRpbmcgdG8gdGhlIG91dGVyIHNoYWRvdyBhcmVhLiBBIHZhbHVlIG9mIDEgd291bGQgbWVhbiB0aGUgc2hhZG93cyBzdGFydCBmYWRpbmcgZnJvbSB0aGUgY2FtZXJhJ3MgbmVhciBwbGFuZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGJhc2VNZXRob2Q6U2hhZG93TWV0aG9kQmFzZSwgZmFkZVJhdGlvOm51bWJlciA9IC4xKVxuXHR7XG5cdFx0c3VwZXIoYmFzZU1ldGhvZC5jYXN0aW5nTGlnaHQpO1xuXG5cdFx0dGhpcy5fb25TaGFkZXJJbnZhbGlkYXRlZERlbGVnYXRlID0gKGV2ZW50OlNoYWRpbmdNZXRob2RFdmVudCkgPT4gdGhpcy5vblNoYWRlckludmFsaWRhdGVkKGV2ZW50KTtcblxuXHRcdHRoaXMuX2Jhc2VNZXRob2QgPSBiYXNlTWV0aG9kO1xuXHRcdHRoaXMuX2ZhZGVSYXRpbyA9IGZhZGVSYXRpbztcblx0XHR0aGlzLl9uZWFyU2hhZG93TWFwcGVyID0gPE5lYXJEaXJlY3Rpb25hbFNoYWRvd01hcHBlcj4gdGhpcy5fcENhc3RpbmdMaWdodC5zaGFkb3dNYXBwZXI7XG5cdFx0aWYgKCF0aGlzLl9uZWFyU2hhZG93TWFwcGVyKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiU2hhZG93TmVhck1ldGhvZCByZXF1aXJlcyBhIGxpZ2h0IHRoYXQgaGFzIGEgTmVhckRpcmVjdGlvbmFsU2hhZG93TWFwcGVyIGluc3RhbmNlIGFzc2lnbmVkIHRvIHNoYWRvd01hcHBlci5cIik7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5hZGRFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIHRoaXMuX29uU2hhZGVySW52YWxpZGF0ZWREZWxlZ2F0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGJhc2Ugc2hhZG93IG1hcCBtZXRob2Qgb24gd2hpY2ggdGhpcyBtZXRob2QncyBzaGFkaW5nIGlzIGJhc2VkLlxuXHQgKi9cblx0cHVibGljIGdldCBiYXNlTWV0aG9kKCk6U2hhZG93TWV0aG9kQmFzZVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Jhc2VNZXRob2Q7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGJhc2VNZXRob2QodmFsdWU6U2hhZG93TWV0aG9kQmFzZSlcblx0e1xuXHRcdGlmICh0aGlzLl9iYXNlTWV0aG9kID09IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5yZW1vdmVFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIHRoaXMuX29uU2hhZGVySW52YWxpZGF0ZWREZWxlZ2F0ZSk7XG5cblx0XHR0aGlzLl9iYXNlTWV0aG9kID0gdmFsdWU7XG5cblx0XHR0aGlzLl9iYXNlTWV0aG9kLmFkZEV2ZW50TGlzdGVuZXIoU2hhZGluZ01ldGhvZEV2ZW50LlNIQURFUl9JTlZBTElEQVRFRCwgdGhpcy5fb25TaGFkZXJJbnZhbGlkYXRlZERlbGVnYXRlKTtcblxuXHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblx0XHRzdXBlci5pSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblx0XHR0aGlzLl9iYXNlTWV0aG9kLmlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdCwgbWV0aG9kVk8pO1xuXG5cdFx0dmFyIGZyYWdtZW50RGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IG1ldGhvZFZPLnNlY29uZGFyeUZyYWdtZW50Q29uc3RhbnRzSW5kZXg7XG5cdFx0ZnJhZ21lbnREYXRhW2luZGV4ICsgMl0gPSAwO1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleCArIDNdID0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaUluaXRWTyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblxuXHRcdG1ldGhvZFZPLm5lZWRzUHJvamVjdGlvbiA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCB0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGFscGhhKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5hbHBoYTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYWxwaGEodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5hbHBoYSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGVwc2lsb24oKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9iYXNlTWV0aG9kLmVwc2lsb247XG5cdH1cblxuXHRwdWJsaWMgc2V0IGVwc2lsb24odmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5lcHNpbG9uID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGFtb3VudCBvZiBzaGFkb3cgZmFkaW5nIHRvIHRoZSBvdXRlciBzaGFkb3cgYXJlYS4gQSB2YWx1ZSBvZiAxIHdvdWxkIG1lYW4gdGhlIHNoYWRvd3Mgc3RhcnQgZmFkaW5nIGZyb20gdGhlIGNhbWVyYSdzIG5lYXIgcGxhbmUuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGZhZGVSYXRpbygpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2ZhZGVSYXRpbztcblx0fVxuXG5cdHB1YmxpYyBzZXQgZmFkZVJhdGlvKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2ZhZGVSYXRpbyA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmcgPSB0aGlzLl9iYXNlTWV0aG9kLmlHZXRGcmFnbWVudENvZGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgdGFyZ2V0UmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXG5cdFx0dmFyIGRhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciB0ZW1wOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50U2luZ2xlVGVtcCgpO1xuXHRcdG1ldGhvZFZPLnNlY29uZGFyeUZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSBkYXRhUmVnLmluZGV4KjQ7XG5cblx0XHRjb2RlICs9IFwiYWJzIFwiICsgdGVtcCArIFwiLCBcIiArIHNoYXJlZFJlZ2lzdGVycy5wcm9qZWN0aW9uRnJhZ21lbnQgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIGRhdGFSZWcgKyBcIi54XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiLCBcIiArIGRhdGFSZWcgKyBcIi55XFxuXCIgK1xuXHRcdFx0XCJzYXQgXCIgKyB0ZW1wICsgXCIsIFwiICsgdGVtcCArIFwiXFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0ZW1wICsgXCIsIFwiICsgZGF0YVJlZyArIFwiLncsXCIgKyB0ZW1wICsgXCJcXG5cIiArXG5cdFx0XHRcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgZGF0YVJlZyArIFwiLncsXCIgKyB0YXJnZXRSZWcgKyBcIi53XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGVtcCArIFwiXFxuXCIgK1xuXHRcdFx0XCJzdWIgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIGRhdGFSZWcgKyBcIi53LFwiICsgdGFyZ2V0UmVnICsgXCIud1xcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlEZWFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHR0aGlzLl9iYXNlTWV0aG9kLmlEZWFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlTZXRSZW5kZXJTdGF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIHN0YWdlOlN0YWdlLCBjYW1lcmE6Q2FtZXJhKVxuXHR7XG5cdFx0Ly8gdG9kbzogbW92ZSB0aGlzIHRvIGFjdGl2YXRlIChuZWVkcyBjYW1lcmEpXG5cdFx0dmFyIG5lYXI6bnVtYmVyID0gY2FtZXJhLnByb2plY3Rpb24ubmVhcjtcblx0XHR2YXIgZDpudW1iZXIgPSBjYW1lcmEucHJvamVjdGlvbi5mYXIgLSBuZWFyO1xuXHRcdHZhciBtYXhEaXN0YW5jZTpudW1iZXIgPSB0aGlzLl9uZWFyU2hhZG93TWFwcGVyLmNvdmVyYWdlUmF0aW87XG5cdFx0dmFyIG1pbkRpc3RhbmNlOm51bWJlciA9IG1heERpc3RhbmNlKigxIC0gdGhpcy5fZmFkZVJhdGlvKTtcblxuXHRcdG1heERpc3RhbmNlID0gbmVhciArIG1heERpc3RhbmNlKmQ7XG5cdFx0bWluRGlzdGFuY2UgPSBuZWFyICsgbWluRGlzdGFuY2UqZDtcblxuXHRcdHZhciBmcmFnbWVudERhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleF0gPSBtaW5EaXN0YW5jZTtcblx0XHRmcmFnbWVudERhdGFbaW5kZXggKyAxXSA9IDEvKG1heERpc3RhbmNlIC0gbWluRGlzdGFuY2UpO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5pU2V0UmVuZGVyU3RhdGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgcmVuZGVyYWJsZSwgc3RhZ2UsIGNhbWVyYSk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0VmVydGV4Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5pR2V0VmVydGV4Q29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaVJlc2V0KClcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaVJlc2V0KCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQ2xlYW5Db21waWxhdGlvbkRhdGEoKVxuXHR7XG5cdFx0c3VwZXIuaUNsZWFuQ29tcGlsYXRpb25EYXRhKCk7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgd2hlbiB0aGUgYmFzZSBtZXRob2QncyBzaGFkZXIgY29kZSBpcyBpbnZhbGlkYXRlZC5cblx0ICovXG5cdHByaXZhdGUgb25TaGFkZXJJbnZhbGlkYXRlZChldmVudDpTaGFkaW5nTWV0aG9kRXZlbnQpXG5cdHtcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNoYWRvd05lYXJNZXRob2Q7Il19 \ No newline at end of file diff --git a/lib/materials/methods/ShadowNearMethod.ts b/lib/materials/methods/ShadowNearMethod.ts new file mode 100644 index 000000000..5588edebf --- /dev/null +++ b/lib/materials/methods/ShadowNearMethod.ts @@ -0,0 +1,238 @@ +import NearDirectionalShadowMapper = require("awayjs-core/lib/materials/shadowmappers/NearDirectionalShadowMapper"); +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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); + +// TODO: shadow mappers references in materials should be an interface so that this class should NOT extend ShadowMapMethodBase just for some delegation work +/** + * ShadowNearMethod provides a shadow map method that restricts the shadowed area near the camera to optimize + * shadow map usage. This method needs to be used in conjunction with a NearDirectionalShadowMapper. + * + * @see away.lights.NearDirectionalShadowMapper + */ +class ShadowNearMethod extends ShadowMethodBase +{ + private _baseMethod:ShadowMethodBase; + + private _fadeRatio:number; + private _nearShadowMapper:NearDirectionalShadowMapper; + + private _onShaderInvalidatedDelegate:Function; + + /** + * Creates a new ShadowNearMethod object. + * @param baseMethod The shadow map sampling method used to sample individual cascades (fe: ShadowHardMethod, ShadowSoftMethod) + * @param fadeRatio The amount of shadow fading to the outer shadow area. A value of 1 would mean the shadows start fading from the camera's near plane. + */ + constructor(baseMethod:ShadowMethodBase, fadeRatio:number = .1) + { + super(baseMethod.castingLight); + + this._onShaderInvalidatedDelegate = (event:ShadingMethodEvent) => this.onShaderInvalidated(event); + + this._baseMethod = baseMethod; + this._fadeRatio = fadeRatio; + this._nearShadowMapper = this._pCastingLight.shadowMapper; + if (!this._nearShadowMapper) + throw new Error("ShadowNearMethod requires a light that has a NearDirectionalShadowMapper instance assigned to shadowMapper."); + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + } + + /** + * The base shadow map method on which this method's shading is based. + */ + public get baseMethod():ShadowMethodBase + { + return this._baseMethod; + } + + public set baseMethod(value:ShadowMethodBase) + { + if (this._baseMethod == value) + return; + + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + + this._baseMethod = value; + + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + + this.iInvalidateShaderProgram(); + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + super.iInitConstants(shaderObject, methodVO); + this._baseMethod.iInitConstants(shaderObject, methodVO); + + var fragmentData:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index + 2] = 0; + fragmentData[index + 3] = 1; + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + this._baseMethod.iInitVO(shaderObject, methodVO); + + methodVO.needsProjection = true; + } + + /** + * @inheritDoc + */ + public dispose() + { + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + } + + /** + * @inheritDoc + */ + public get alpha():number + { + return this._baseMethod.alpha; + } + + public set alpha(value:number) + { + this._baseMethod.alpha = value; + } + + /** + * @inheritDoc + */ + public get epsilon():number + { + return this._baseMethod.epsilon; + } + + public set epsilon(value:number) + { + this._baseMethod.epsilon = value; + } + + /** + * The amount of shadow fading to the outer shadow area. A value of 1 would mean the shadows start fading from the camera's near plane. + */ + public get fadeRatio():number + { + return this._fadeRatio; + } + + public set fadeRatio(value:number) + { + this._fadeRatio = value; + } + + /** + * @inheritDoc + */ + public iGetFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = this._baseMethod.iGetFragmentCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + var temp:ShaderRegisterElement = registerCache.getFreeFragmentSingleTemp(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index*4; + + code += "abs " + temp + ", " + sharedRegisters.projectionFragment + ".w\n" + + "sub " + temp + ", " + temp + ", " + dataReg + ".x\n" + + "mul " + temp + ", " + temp + ", " + dataReg + ".y\n" + + "sat " + temp + ", " + temp + "\n" + + "sub " + temp + ", " + dataReg + ".w," + temp + "\n" + + "sub " + targetReg + ".w, " + dataReg + ".w," + targetReg + ".w\n" + + "mul " + targetReg + ".w, " + targetReg + ".w, " + temp + "\n" + + "sub " + targetReg + ".w, " + dataReg + ".w," + targetReg + ".w\n"; + + return code; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + this._baseMethod.iActivate(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iDeactivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + this._baseMethod.iDeactivate(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iSetRenderState(shaderObject:ShaderObjectBase, methodVO:MethodVO, renderable:RenderableBase, stage:Stage, camera:Camera) + { + // todo: move this to activate (needs camera) + var near:number = camera.projection.near; + var d:number = camera.projection.far - near; + var maxDistance:number = this._nearShadowMapper.coverageRatio; + var minDistance:number = maxDistance*(1 - this._fadeRatio); + + maxDistance = near + maxDistance*d; + minDistance = near + minDistance*d; + + var fragmentData:Array = shaderObject.fragmentConstantData; + var index:number /*int*/ = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index] = minDistance; + fragmentData[index + 1] = 1/(maxDistance - minDistance); + + this._baseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera); + } + + /** + * @inheritDoc + */ + public iGetVertexCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + */ + public iReset() + { + this._baseMethod.iReset(); + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._baseMethod.iCleanCompilationData(); + } + + /** + * Called when the base method's shader code is invalidated. + */ + private onShaderInvalidated(event:ShadingMethodEvent) + { + this.iInvalidateShaderProgram(); + } +} + +export = ShadowNearMethod; \ No newline at end of file diff --git a/lib/materials/methods/ShadowSoftMethod.js b/lib/materials/methods/ShadowSoftMethod.js new file mode 100755 index 000000000..08fc6b728 --- /dev/null +++ b/lib/materials/methods/ShadowSoftMethod.js @@ -0,0 +1,172 @@ +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 PoissonLookup = require("awayjs-core/lib/core/geom/PoissonLookup"); +var ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +/** + * ShadowSoftMethod provides a soft shadowing technique by randomly distributing sample points. + */ +var ShadowSoftMethod = (function (_super) { + __extends(ShadowSoftMethod, _super); + /** + * Creates a new DiffuseBasicMethod object. + * + * @param castingLight The light casting the shadows + * @param numSamples The amount of samples to take for dithering. Minimum 1, maximum 32. + */ + function ShadowSoftMethod(castingLight, numSamples, range) { + if (numSamples === void 0) { numSamples = 5; } + if (range === void 0) { range = 1; } + _super.call(this, castingLight); + this._range = 1; + this.numSamples = numSamples; + this.range = range; + } + Object.defineProperty(ShadowSoftMethod.prototype, "numSamples", { + /** + * The amount of samples to take for dithering. Minimum 1, maximum 32. The actual maximum may depend on the + * complexity of the shader. + */ + get: function () { + return this._numSamples; + }, + set: function (value /*int*/) { + this._numSamples = value; + if (this._numSamples < 1) + this._numSamples = 1; + else if (this._numSamples > 32) + this._numSamples = 32; + this._offsets = PoissonLookup.getDistribution(this._numSamples); + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ShadowSoftMethod.prototype, "range", { + /** + * The range in the shadow map in which to distribute the samples. + */ + get: function () { + return this._range; + }, + set: function (value) { + this._range = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + ShadowSoftMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + _super.prototype.iInitConstants.call(this, shaderObject, methodVO); + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 8] = 1 / this._numSamples; + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 9] = 0; + }; + /** + * @inheritDoc + */ + ShadowSoftMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + var texRange = .5 * this._range / this._pCastingLight.shadowMapper.depthMapSize; + var data = shaderObject.fragmentConstantData; + var index = methodVO.fragmentConstantsIndex + 10; + var len = this._numSamples << 1; + for (var i = 0; i < len; ++i) + data[index + i] = this._offsets[i] * texRange; + }; + /** + * @inheritDoc + */ + ShadowSoftMethod.prototype._pGetPlanarFragmentCode = function (methodVO, targetReg, regCache, sharedRegisters) { + // todo: move some things to super + var depthMapRegister = regCache.getFreeTextureReg(); + var decReg = regCache.getFreeFragmentConstant(); + var dataReg = regCache.getFreeFragmentConstant(); + var customDataReg = regCache.getFreeFragmentConstant(); + methodVO.fragmentConstantsIndex = decReg.index * 4; + methodVO.texturesIndex = depthMapRegister.index; + return this.getSampleCode(regCache, depthMapRegister, decReg, targetReg, customDataReg); + }; + /** + * Adds the code for another tap to the shader code. + * @param uv The uv register for the tap. + * @param texture The texture register containing the depth map. + * @param decode The register containing the depth map decoding data. + * @param target The target register to add the tap comparison result. + * @param regCache The register cache managing the registers. + * @return + */ + ShadowSoftMethod.prototype.addSample = function (uv, texture, decode, target, regCache) { + var temp = regCache.getFreeFragmentVectorTemp(); + return "tex " + temp + ", " + uv + ", " + texture + " <2d,nearest,clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decode + "\n" + "slt " + uv + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n" + "add " + target + ".w, " + target + ".w, " + uv + ".w\n"; + }; + /** + * @inheritDoc + */ + ShadowSoftMethod.prototype.iActivateForCascade = function (shaderObject, methodVO, stage) { + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + var texRange = this._range / this._pCastingLight.shadowMapper.depthMapSize; + var data = shaderObject.fragmentConstantData; + var index = methodVO.secondaryFragmentConstantsIndex; + var len = this._numSamples << 1; + data[index] = 1 / this._numSamples; + data[index + 1] = 0; + index += 2; + for (var i = 0; i < len; ++i) + data[index + i] = this._offsets[i] * texRange; + if (len % 4 == 0) { + data[index + len] = 0; + data[index + len + 1] = 0; + } + }; + /** + * @inheritDoc + */ + ShadowSoftMethod.prototype._iGetCascadeFragmentCode = function (shaderObject, methodVO, decodeRegister, depthTexture, depthProjection, targetRegister, registerCache, sharedRegisters) { + this._pDepthMapCoordReg = depthProjection; + var dataReg = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index * 4; + return this.getSampleCode(registerCache, depthTexture, decodeRegister, targetRegister, dataReg); + }; + /** + * Get the actual shader code for shadow mapping + * @param regCache The register cache managing the registers. + * @param depthTexture The texture register containing the depth map. + * @param decodeRegister The register containing the depth map decoding data. + * @param targetReg The target register to add the shadow coverage. + * @param dataReg The register containing additional data. + */ + ShadowSoftMethod.prototype.getSampleCode = function (regCache, depthTexture, decodeRegister, targetRegister, dataReg) { + var uvReg; + var code; + var offsets = new Array(dataReg + ".zw"); + uvReg = regCache.getFreeFragmentVectorTemp(); + regCache.addFragmentTempUsages(uvReg, 1); + var temp = regCache.getFreeFragmentVectorTemp(); + var numRegs = this._numSamples >> 1; + for (var i = 0; i < numRegs; ++i) { + var reg = regCache.getFreeFragmentConstant(); + offsets.push(reg + ".xy"); + offsets.push(reg + ".zw"); + } + for (i = 0; i < this._numSamples; ++i) { + if (i == 0) { + code = "add " + uvReg + ", " + this._pDepthMapCoordReg + ", " + dataReg + ".zwyy\n" + "tex " + temp + ", " + uvReg + ", " + depthTexture + " <2d,nearest,clamp>\n" + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + "slt " + targetRegister + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n"; // 0 if in shadow; + } + else { + code += "add " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + offsets[i] + "\n" + this.addSample(uvReg, depthTexture, decodeRegister, targetRegister, regCache); + } + } + regCache.removeFragmentTempUsage(uvReg); + code += "mul " + targetRegister + ".w, " + targetRegister + ".w, " + dataReg + ".x\n"; // average + return code; + }; + return ShadowSoftMethod; +})(ShadowMethodBase); +module.exports = ShadowSoftMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NoYWRvd3NvZnRtZXRob2QudHMiXSwibmFtZXMiOlsiU2hhZG93U29mdE1ldGhvZCIsIlNoYWRvd1NvZnRNZXRob2QuY29uc3RydWN0b3IiLCJTaGFkb3dTb2Z0TWV0aG9kLm51bVNhbXBsZXMiLCJTaGFkb3dTb2Z0TWV0aG9kLnJhbmdlIiwiU2hhZG93U29mdE1ldGhvZC5pSW5pdENvbnN0YW50cyIsIlNoYWRvd1NvZnRNZXRob2QuaUFjdGl2YXRlIiwiU2hhZG93U29mdE1ldGhvZC5fcEdldFBsYW5hckZyYWdtZW50Q29kZSIsIlNoYWRvd1NvZnRNZXRob2QuYWRkU2FtcGxlIiwiU2hhZG93U29mdE1ldGhvZC5pQWN0aXZhdGVGb3JDYXNjYWRlIiwiU2hhZG93U29mdE1ldGhvZC5faUdldENhc2NhZGVGcmFnbWVudENvZGUiLCJTaGFkb3dTb2Z0TWV0aG9kLmdldFNhbXBsZUNvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sYUFBYSxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFTOUUsSUFBTyxnQkFBZ0IsV0FBZSx1REFBdUQsQ0FBQyxDQUFDO0FBRS9GLEFBR0E7O0dBREc7SUFDRyxnQkFBZ0I7SUFBU0EsVUFBekJBLGdCQUFnQkEsVUFBeUJBO0lBTTlDQTs7Ozs7T0FLR0E7SUFDSEEsU0FaS0EsZ0JBQWdCQSxDQVlUQSxZQUE2QkEsRUFBRUEsVUFBNkJBLEVBQUVBLEtBQWdCQTtRQUEvQ0MsMEJBQTZCQSxHQUE3QkEsY0FBNkJBO1FBQUVBLHFCQUFnQkEsR0FBaEJBLFNBQWdCQTtRQUV6RkEsa0JBQU1BLFlBQVlBLENBQUNBLENBQUNBO1FBWmJBLFdBQU1BLEdBQVVBLENBQUNBLENBQUNBO1FBY3pCQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxVQUFVQSxDQUFDQTtRQUM3QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsQ0FBQ0E7SUFDcEJBLENBQUNBO0lBTURELHNCQUFXQSx3Q0FBVUE7UUFK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QUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxJQUFJQSxHQUFHQSxjQUFjQSxHQUFHQSxJQUFJQSxHQUM1REEsTUFBTUEsR0FBR0EsY0FBY0EsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxHQUFHQSxNQUFNQSxFQUFFQSxrQkFBa0JBO1lBQ3pHQSxDQUFDQSxHQURxRkE7WUFDcEZBLElBQUlBLENBQUNBLENBQUNBO2dCQUNQQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxLQUFLQSxHQUFHQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxrQkFBa0JBLEdBQUdBLE9BQU9BLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLEdBQ3ZGQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxZQUFZQSxFQUFFQSxjQUFjQSxFQUFFQSxjQUFjQSxFQUFFQSxRQUFRQSxDQUFDQSxDQUFDQTtZQUNoRkEsQ0FBQ0E7UUFDRkEsQ0FBQ0E7UUFFREEsUUFBUUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUV4Q0EsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsY0FBY0EsR0FBR0EsTUFBTUEsR0FBR0EsY0FBY0EsR0FBR0EsTUFBTUEsR0FBR0EsT0FBT0EsR0FBR0EsTUFBTUEsRUFBRUEsVUFBVUE7UUFFakdBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBQ0ZWLHVCQUFDQTtBQUFEQSxDQXRNQSxBQXNNQ0EsRUF0TThCLGdCQUFnQixFQXNNOUM7QUFFRCxBQUEwQixpQkFBakIsZ0JBQWdCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvU2hhZG93U29mdE1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQb2lzc29uTG9va3VwXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vUG9pc3Nvbkxvb2t1cFwiKTtcbmltcG9ydCBEaXJlY3Rpb25hbExpZ2h0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9EaXJlY3Rpb25hbExpZ2h0XCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgU2hhZG93TWV0aG9kQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU2hhZG93TWV0aG9kQmFzZVwiKTtcblxuLyoqXG4gKiBTaGFkb3dTb2Z0TWV0aG9kIHByb3ZpZGVzIGEgc29mdCBzaGFkb3dpbmcgdGVjaG5pcXVlIGJ5IHJhbmRvbWx5IGRpc3RyaWJ1dGluZyBzYW1wbGUgcG9pbnRzLlxuICovXG5jbGFzcyBTaGFkb3dTb2Z0TWV0aG9kIGV4dGVuZHMgU2hhZG93TWV0aG9kQmFzZVxue1xuXHRwcml2YXRlIF9yYW5nZTpudW1iZXIgPSAxO1xuXHRwcml2YXRlIF9udW1TYW1wbGVzOm51bWJlciAvKmludCovO1xuXHRwcml2YXRlIF9vZmZzZXRzOkFycmF5PG51bWJlcj47XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgRGlmZnVzZUJhc2ljTWV0aG9kIG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIGNhc3RpbmdMaWdodCBUaGUgbGlnaHQgY2FzdGluZyB0aGUgc2hhZG93c1xuXHQgKiBAcGFyYW0gbnVtU2FtcGxlcyBUaGUgYW1vdW50IG9mIHNhbXBsZXMgdG8gdGFrZSBmb3IgZGl0aGVyaW5nLiBNaW5pbXVtIDEsIG1heGltdW0gMzIuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihjYXN0aW5nTGlnaHQ6RGlyZWN0aW9uYWxMaWdodCwgbnVtU2FtcGxlczpudW1iZXIgLyppbnQqLyA9IDUsIHJhbmdlOm51bWJlciA9IDEpXG5cdHtcblx0XHRzdXBlcihjYXN0aW5nTGlnaHQpO1xuXG5cdFx0dGhpcy5udW1TYW1wbGVzID0gbnVtU2FtcGxlcztcblx0XHR0aGlzLnJhbmdlID0gcmFuZ2U7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGFtb3VudCBvZiBzYW1wbGVzIHRvIHRha2UgZm9yIGRpdGhlcmluZy4gTWluaW11bSAxLCBtYXhpbXVtIDMyLiBUaGUgYWN0dWFsIG1heGltdW0gbWF5IGRlcGVuZCBvbiB0aGVcblx0ICogY29tcGxleGl0eSBvZiB0aGUgc2hhZGVyLlxuXHQgKi9cblx0cHVibGljIGdldCBudW1TYW1wbGVzKCk6bnVtYmVyIC8qaW50Ki9cblx0e1xuXHRcdHJldHVybiB0aGlzLl9udW1TYW1wbGVzO1xuXHR9XG5cblx0cHVibGljIHNldCBudW1TYW1wbGVzKHZhbHVlOm51bWJlciAvKmludCovKVxuXHR7XG5cdFx0dGhpcy5fbnVtU2FtcGxlcyA9IHZhbHVlO1xuXHRcdFxuXHRcdGlmICh0aGlzLl9udW1TYW1wbGVzIDwgMSlcblx0XHRcdHRoaXMuX251bVNhbXBsZXMgPSAxO1xuXHRcdGVsc2UgaWYgKHRoaXMuX251bVNhbXBsZXMgPiAzMilcblx0XHRcdHRoaXMuX251bVNhbXBsZXMgPSAzMjtcblxuXHRcdHRoaXMuX29mZnNldHMgPSBQb2lzc29uTG9va3VwLmdldERpc3RyaWJ1dGlvbih0aGlzLl9udW1TYW1wbGVzKTtcblx0XHRcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSByYW5nZSBpbiB0aGUgc2hhZG93IG1hcCBpbiB3aGljaCB0byBkaXN0cmlidXRlIHRoZSBzYW1wbGVzLlxuXHQgKi9cblx0cHVibGljIGdldCByYW5nZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3JhbmdlO1xuXHR9XG5cblx0cHVibGljIHNldCByYW5nZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9yYW5nZSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0c3VwZXIuaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0LCBtZXRob2RWTyk7XG5cblx0XHRzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGFbbWV0aG9kVk8uZnJhZ21lbnRDb25zdGFudHNJbmRleCArIDhdID0gMS90aGlzLl9udW1TYW1wbGVzO1xuXHRcdHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YVttZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ICsgOV0gPSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHRzdXBlci5pQWN0aXZhdGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgc3RhZ2UpO1xuXG5cdFx0dmFyIHRleFJhbmdlOm51bWJlciA9IC41KnRoaXMuX3JhbmdlL3RoaXMuX3BDYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyLmRlcHRoTWFwU2l6ZTtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyp1aW50Ki8gPSBtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ICsgMTA7XG5cdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9udW1TYW1wbGVzIDw8IDE7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IGxlbjsgKytpKVxuXHRcdFx0ZGF0YVtpbmRleCArIGldID0gdGhpcy5fb2Zmc2V0c1tpXSp0ZXhSYW5nZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wR2V0UGxhbmFyRnJhZ21lbnRDb2RlKG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdC8vIHRvZG86IG1vdmUgc29tZSB0aGluZ3MgdG8gc3VwZXJcblx0XHR2YXIgZGVwdGhNYXBSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlVGV4dHVyZVJlZygpO1xuXHRcdHZhciBkZWNSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50ID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHR2YXIgZGF0YVJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdHZhciBjdXN0b21EYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ0NhY2hlLmdldEZyZWVGcmFnbWVudENvbnN0YW50KCk7XG5cblx0XHRtZXRob2RWTy5mcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGVjUmVnLmluZGV4KjQ7XG5cdFx0bWV0aG9kVk8udGV4dHVyZXNJbmRleCA9IGRlcHRoTWFwUmVnaXN0ZXIuaW5kZXg7XG5cblx0XHRyZXR1cm4gdGhpcy5nZXRTYW1wbGVDb2RlKHJlZ0NhY2hlLCBkZXB0aE1hcFJlZ2lzdGVyLCBkZWNSZWcsIHRhcmdldFJlZywgY3VzdG9tRGF0YVJlZyk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgY29kZSBmb3IgYW5vdGhlciB0YXAgdG8gdGhlIHNoYWRlciBjb2RlLlxuXHQgKiBAcGFyYW0gdXYgVGhlIHV2IHJlZ2lzdGVyIGZvciB0aGUgdGFwLlxuXHQgKiBAcGFyYW0gdGV4dHVyZSBUaGUgdGV4dHVyZSByZWdpc3RlciBjb250YWluaW5nIHRoZSBkZXB0aCBtYXAuXG5cdCAqIEBwYXJhbSBkZWNvZGUgVGhlIHJlZ2lzdGVyIGNvbnRhaW5pbmcgdGhlIGRlcHRoIG1hcCBkZWNvZGluZyBkYXRhLlxuXHQgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgcmVnaXN0ZXIgdG8gYWRkIHRoZSB0YXAgY29tcGFyaXNvbiByZXN1bHQuXG5cdCAqIEBwYXJhbSByZWdDYWNoZSBUaGUgcmVnaXN0ZXIgY2FjaGUgbWFuYWdpbmcgdGhlIHJlZ2lzdGVycy5cblx0ICogQHJldHVyblxuXHQgKi9cblx0cHJpdmF0ZSBhZGRTYW1wbGUodXY6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCB0ZXh0dXJlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgZGVjb2RlOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgdGFyZ2V0OlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cdFx0cmV0dXJuIFwidGV4IFwiICsgdGVtcCArIFwiLCBcIiArIHV2ICsgXCIsIFwiICsgdGV4dHVyZSArIFwiIDwyZCxuZWFyZXN0LGNsYW1wPlxcblwiICtcblx0XHRcdFwiZHA0IFwiICsgdGVtcCArIFwiLnosIFwiICsgdGVtcCArIFwiLCBcIiArIGRlY29kZSArIFwiXFxuXCIgK1xuXHRcdFx0XCJzbHQgXCIgKyB1diArIFwiLncsIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi56LCBcIiArIHRlbXAgKyBcIi56XFxuXCIgKyAvLyAwIGlmIGluIHNoYWRvd1xuXHRcdFx0XCJhZGQgXCIgKyB0YXJnZXQgKyBcIi53LCBcIiArIHRhcmdldCArIFwiLncsIFwiICsgdXYgKyBcIi53XFxuXCI7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQWN0aXZhdGVGb3JDYXNjYWRlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgc3RhZ2U6U3RhZ2UpXG5cdHtcblx0XHRzdXBlci5pQWN0aXZhdGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgc3RhZ2UpO1xuXG5cdFx0dmFyIHRleFJhbmdlOm51bWJlciA9IHRoaXMuX3JhbmdlL3RoaXMuX3BDYXN0aW5nTGlnaHQuc2hhZG93TWFwcGVyLmRlcHRoTWFwU2l6ZTtcblx0XHR2YXIgZGF0YTpBcnJheTxudW1iZXI+ID0gc2hhZGVyT2JqZWN0LmZyYWdtZW50Q29uc3RhbnREYXRhO1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyp1aW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gdGhpcy5fbnVtU2FtcGxlcyA8PCAxO1xuXHRcdGRhdGFbaW5kZXhdID0gMS90aGlzLl9udW1TYW1wbGVzO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IDA7XG5cdFx0aW5kZXggKz0gMjtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qaW50Ki8gPSAwOyBpIDwgbGVuOyArK2kpXG5cdFx0XHRkYXRhW2luZGV4ICsgaV0gPSB0aGlzLl9vZmZzZXRzW2ldKnRleFJhbmdlO1xuXG5cdFx0aWYgKGxlbiU0ID09IDApIHtcblx0XHRcdGRhdGFbaW5kZXggKyBsZW5dID0gMDtcblx0XHRcdGRhdGFbaW5kZXggKyBsZW4gKyAxXSA9IDA7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lHZXRDYXNjYWRlRnJhZ21lbnRDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgZGVjb2RlUmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBkZXB0aFRleHR1cmU6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBkZXB0aFByb2plY3Rpb246U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCB0YXJnZXRSZWdpc3RlcjpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyA9IGRlcHRoUHJvamVjdGlvbjtcblxuXHRcdHZhciBkYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblx0XHRtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4ID0gZGF0YVJlZy5pbmRleCo0O1xuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0U2FtcGxlQ29kZShyZWdpc3RlckNhY2hlLCBkZXB0aFRleHR1cmUsIGRlY29kZVJlZ2lzdGVyLCB0YXJnZXRSZWdpc3RlciwgZGF0YVJlZyk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0IHRoZSBhY3R1YWwgc2hhZGVyIGNvZGUgZm9yIHNoYWRvdyBtYXBwaW5nXG5cdCAqIEBwYXJhbSByZWdDYWNoZSBUaGUgcmVnaXN0ZXIgY2FjaGUgbWFuYWdpbmcgdGhlIHJlZ2lzdGVycy5cblx0ICogQHBhcmFtIGRlcHRoVGV4dHVyZSBUaGUgdGV4dHVyZSByZWdpc3RlciBjb250YWluaW5nIHRoZSBkZXB0aCBtYXAuXG5cdCAqIEBwYXJhbSBkZWNvZGVSZWdpc3RlciBUaGUgcmVnaXN0ZXIgY29udGFpbmluZyB0aGUgZGVwdGggbWFwIGRlY29kaW5nIGRhdGEuXG5cdCAqIEBwYXJhbSB0YXJnZXRSZWcgVGhlIHRhcmdldCByZWdpc3RlciB0byBhZGQgdGhlIHNoYWRvdyBjb3ZlcmFnZS5cblx0ICogQHBhcmFtIGRhdGFSZWcgVGhlIHJlZ2lzdGVyIGNvbnRhaW5pbmcgYWRkaXRpb25hbCBkYXRhLlxuXHQgKi9cblx0cHJpdmF0ZSBnZXRTYW1wbGVDb2RlKHJlZ0NhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIGRlcHRoVGV4dHVyZTpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIGRlY29kZVJlZ2lzdGVyOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgdGFyZ2V0UmVnaXN0ZXI6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBkYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCk6c3RyaW5nXG5cdHtcblx0XHR2YXIgdXZSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRcdHZhciBjb2RlOnN0cmluZztcblx0XHR2YXIgb2Zmc2V0czpBcnJheTxzdHJpbmc+ID0gbmV3IEFycmF5PHN0cmluZz4oZGF0YVJlZyArIFwiLnp3XCIpO1xuXHRcdHV2UmVnID0gcmVnQ2FjaGUuZ2V0RnJlZUZyYWdtZW50VmVjdG9yVGVtcCgpO1xuXHRcdHJlZ0NhY2hlLmFkZEZyYWdtZW50VGVtcFVzYWdlcyh1dlJlZywgMSk7XG5cblx0XHR2YXIgdGVtcDpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRWZWN0b3JUZW1wKCk7XG5cblx0XHR2YXIgbnVtUmVnczpudW1iZXIgLyppbnQqLyA9IHRoaXMuX251bVNhbXBsZXMgPj4gMTtcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IG51bVJlZ3M7ICsraSkge1xuXHRcdFx0dmFyIHJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQgPSByZWdDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdFx0b2Zmc2V0cy5wdXNoKHJlZyArIFwiLnh5XCIpO1xuXHRcdFx0b2Zmc2V0cy5wdXNoKHJlZyArIFwiLnp3XCIpO1xuXHRcdH1cblxuXHRcdGZvciAoaSA9IDA7IGkgPCB0aGlzLl9udW1TYW1wbGVzOyArK2kpIHtcblx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0Y29kZSA9IFwiYWRkIFwiICsgdXZSZWcgKyBcIiwgXCIgKyB0aGlzLl9wRGVwdGhNYXBDb29yZFJlZyArIFwiLCBcIiArIGRhdGFSZWcgKyBcIi56d3l5XFxuXCIgK1xuXHRcdFx0XHRcdFwidGV4IFwiICsgdGVtcCArIFwiLCBcIiArIHV2UmVnICsgXCIsIFwiICsgZGVwdGhUZXh0dXJlICsgXCIgPDJkLG5lYXJlc3QsY2xhbXA+XFxuXCIgK1xuXHRcdFx0XHRcdFwiZHA0IFwiICsgdGVtcCArIFwiLnosIFwiICsgdGVtcCArIFwiLCBcIiArIGRlY29kZVJlZ2lzdGVyICsgXCJcXG5cIiArXG5cdFx0XHRcdFx0XCJzbHQgXCIgKyB0YXJnZXRSZWdpc3RlciArIFwiLncsIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi56LCBcIiArIHRlbXAgKyBcIi56XFxuXCI7IC8vIDAgaWYgaW4gc2hhZG93O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29kZSArPSBcImFkZCBcIiArIHV2UmVnICsgXCIueHksIFwiICsgdGhpcy5fcERlcHRoTWFwQ29vcmRSZWcgKyBcIi54eSwgXCIgKyBvZmZzZXRzW2ldICsgXCJcXG5cIiArXG5cdFx0XHRcdFx0dGhpcy5hZGRTYW1wbGUodXZSZWcsIGRlcHRoVGV4dHVyZSwgZGVjb2RlUmVnaXN0ZXIsIHRhcmdldFJlZ2lzdGVyLCByZWdDYWNoZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmVnQ2FjaGUucmVtb3ZlRnJhZ21lbnRUZW1wVXNhZ2UodXZSZWcpO1xuXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHRhcmdldFJlZ2lzdGVyICsgXCIudywgXCIgKyB0YXJnZXRSZWdpc3RlciArIFwiLncsIFwiICsgZGF0YVJlZyArIFwiLnhcXG5cIjsgLy8gYXZlcmFnZVxuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2hhZG93U29mdE1ldGhvZDsiXX0= \ No newline at end of file diff --git a/lib/materials/methods/ShadowSoftMethod.ts b/lib/materials/methods/ShadowSoftMethod.ts new file mode 100644 index 000000000..c17216a81 --- /dev/null +++ b/lib/materials/methods/ShadowSoftMethod.ts @@ -0,0 +1,215 @@ +import PoissonLookup = require("awayjs-core/lib/core/geom/PoissonLookup"); +import DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); + +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 ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); + +/** + * ShadowSoftMethod provides a soft shadowing technique by randomly distributing sample points. + */ +class ShadowSoftMethod extends ShadowMethodBase +{ + private _range:number = 1; + private _numSamples:number /*int*/; + private _offsets:Array; + + /** + * Creates a new DiffuseBasicMethod object. + * + * @param castingLight The light casting the shadows + * @param numSamples The amount of samples to take for dithering. Minimum 1, maximum 32. + */ + constructor(castingLight:DirectionalLight, numSamples:number /*int*/ = 5, range:number = 1) + { + super(castingLight); + + this.numSamples = numSamples; + this.range = range; + } + + /** + * The amount of samples to take for dithering. Minimum 1, maximum 32. The actual maximum may depend on the + * complexity of the shader. + */ + public get numSamples():number /*int*/ + { + return this._numSamples; + } + + public set numSamples(value:number /*int*/) + { + this._numSamples = value; + + if (this._numSamples < 1) + this._numSamples = 1; + else if (this._numSamples > 32) + this._numSamples = 32; + + this._offsets = PoissonLookup.getDistribution(this._numSamples); + + this.iInvalidateShaderProgram(); + } + + /** + * The range in the shadow map in which to distribute the samples. + */ + public get range():number + { + return this._range; + } + + public set range(value:number) + { + this._range = value; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + super.iInitConstants(shaderObject, methodVO); + + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 8] = 1/this._numSamples; + shaderObject.fragmentConstantData[methodVO.fragmentConstantsIndex + 9] = 0; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + super.iActivate(shaderObject, methodVO, stage); + + var texRange:number = .5*this._range/this._pCastingLight.shadowMapper.depthMapSize; + var data:Array = shaderObject.fragmentConstantData; + var index:number /*uint*/ = methodVO.fragmentConstantsIndex + 10; + var len:number /*uint*/ = this._numSamples << 1; + + for (var i:number /*int*/ = 0; i < len; ++i) + data[index + i] = this._offsets[i]*texRange; + } + + /** + * @inheritDoc + */ + public _pGetPlanarFragmentCode(methodVO:MethodVO, targetReg:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + // todo: move some things to super + var depthMapRegister:ShaderRegisterElement = regCache.getFreeTextureReg(); + var decReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var dataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var customDataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + + methodVO.fragmentConstantsIndex = decReg.index*4; + methodVO.texturesIndex = depthMapRegister.index; + + return this.getSampleCode(regCache, depthMapRegister, decReg, targetReg, customDataReg); + } + + /** + * Adds the code for another tap to the shader code. + * @param uv The uv register for the tap. + * @param texture The texture register containing the depth map. + * @param decode The register containing the depth map decoding data. + * @param target The target register to add the tap comparison result. + * @param regCache The register cache managing the registers. + * @return + */ + private addSample(uv:ShaderRegisterElement, texture:ShaderRegisterElement, decode:ShaderRegisterElement, target:ShaderRegisterElement, regCache:ShaderRegisterCache):string + { + var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + return "tex " + temp + ", " + uv + ", " + texture + " <2d,nearest,clamp>\n" + + "dp4 " + temp + ".z, " + temp + ", " + decode + "\n" + + "slt " + uv + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n" + // 0 if in shadow + "add " + target + ".w, " + target + ".w, " + uv + ".w\n"; + } + + /** + * @inheritDoc + */ + public iActivateForCascade(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + super.iActivate(shaderObject, methodVO, stage); + + var texRange:number = this._range/this._pCastingLight.shadowMapper.depthMapSize; + var data:Array = shaderObject.fragmentConstantData; + var index:number /*uint*/ = methodVO.secondaryFragmentConstantsIndex; + var len:number /*uint*/ = this._numSamples << 1; + data[index] = 1/this._numSamples; + data[index + 1] = 0; + index += 2; + + for (var i:number /*int*/ = 0; i < len; ++i) + data[index + i] = this._offsets[i]*texRange; + + if (len%4 == 0) { + data[index + len] = 0; + data[index + len + 1] = 0; + } + } + + /** + * @inheritDoc + */ + public _iGetCascadeFragmentCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, decodeRegister:ShaderRegisterElement, depthTexture:ShaderRegisterElement, depthProjection:ShaderRegisterElement, targetRegister:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + this._pDepthMapCoordReg = depthProjection; + + var dataReg:ShaderRegisterElement = registerCache.getFreeFragmentConstant(); + methodVO.secondaryFragmentConstantsIndex = dataReg.index*4; + + return this.getSampleCode(registerCache, depthTexture, decodeRegister, targetRegister, dataReg); + } + + /** + * Get the actual shader code for shadow mapping + * @param regCache The register cache managing the registers. + * @param depthTexture The texture register containing the depth map. + * @param decodeRegister The register containing the depth map decoding data. + * @param targetReg The target register to add the shadow coverage. + * @param dataReg The register containing additional data. + */ + private getSampleCode(regCache:ShaderRegisterCache, depthTexture:ShaderRegisterElement, decodeRegister:ShaderRegisterElement, targetRegister:ShaderRegisterElement, dataReg:ShaderRegisterElement):string + { + var uvReg:ShaderRegisterElement; + var code:string; + var offsets:Array = new Array(dataReg + ".zw"); + uvReg = regCache.getFreeFragmentVectorTemp(); + regCache.addFragmentTempUsages(uvReg, 1); + + var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + + var numRegs:number /*int*/ = this._numSamples >> 1; + for (var i:number /*int*/ = 0; i < numRegs; ++i) { + var reg:ShaderRegisterElement = regCache.getFreeFragmentConstant(); + offsets.push(reg + ".xy"); + offsets.push(reg + ".zw"); + } + + for (i = 0; i < this._numSamples; ++i) { + if (i == 0) { + code = "add " + uvReg + ", " + this._pDepthMapCoordReg + ", " + dataReg + ".zwyy\n" + + "tex " + temp + ", " + uvReg + ", " + depthTexture + " <2d,nearest,clamp>\n" + + "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" + + "slt " + targetRegister + ".w, " + this._pDepthMapCoordReg + ".z, " + temp + ".z\n"; // 0 if in shadow; + } else { + code += "add " + uvReg + ".xy, " + this._pDepthMapCoordReg + ".xy, " + offsets[i] + "\n" + + this.addSample(uvReg, depthTexture, decodeRegister, targetRegister, regCache); + } + } + + regCache.removeFragmentTempUsage(uvReg); + + code += "mul " + targetRegister + ".w, " + targetRegister + ".w, " + dataReg + ".x\n"; // average + + return code; + } +} + +export = ShadowSoftMethod; \ No newline at end of file diff --git a/lib/materials/methods/SpecularAnisotropicMethod.js b/lib/materials/methods/SpecularAnisotropicMethod.js new file mode 100755 index 000000000..41ccc09b5 --- /dev/null +++ b/lib/materials/methods/SpecularAnisotropicMethod.js @@ -0,0 +1,66 @@ +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +/** + * SpecularAnisotropicMethod provides a specular method resulting in anisotropic highlights. These are typical for + * surfaces with microfacet details such as tiny grooves. In particular, this uses the Heidrich-Seidel distrubution. + * The tangent vectors are used as the surface groove directions. + */ +var SpecularAnisotropicMethod = (function (_super) { + __extends(SpecularAnisotropicMethod, _super); + /** + * Creates a new SpecularAnisotropicMethod object. + */ + function SpecularAnisotropicMethod() { + _super.call(this); + } + /** + * @inheritDoc + */ + SpecularAnisotropicMethod.prototype.iInitVO = function (shaderObject, methodVO) { + methodVO.needsTangents = true; + methodVO.needsView = true; + }; + /** + * @inheritDoc + */ + SpecularAnisotropicMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) { + var code = ""; + var t; + if (this._pIsFirstLight) + t = this._pTotalLightColorReg; + else { + t = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(t, 1); + } + // (sin(l,t) * sin(v,t) - cos(l,t)*cos(v,t)) ^ k + code += "nrm " + t + ".xyz, " + sharedRegisters.tangentVarying + ".xyz\n" + "dp3 " + t + ".w, " + t + ".xyz, " + lightDirReg + ".xyz\n" + "dp3 " + t + ".z, " + t + ".xyz, " + sharedRegisters.viewDirFragment + ".xyz\n"; + // (sin(t.w) * sin(t.z) - cos(t.w)*cos(t.z)) ^ k + code += "sin " + t + ".x, " + t + ".w\n" + "sin " + t + ".y, " + t + ".z\n" + "mul " + t + ".x, " + t + ".x, " + t + ".y\n" + "cos " + t + ".z, " + t + ".z\n" + "cos " + t + ".w, " + t + ".w\n" + "mul " + t + ".w, " + t + ".w, " + t + ".z\n" + "sub " + t + ".w, " + t + ".x, " + t + ".w\n"; + if (this._pUseTexture) { + // apply gloss modulation from texture + code += "mul " + this._pSpecularTexData + ".w, " + this._pSpecularTexData + ".y, " + this._pSpecularDataRegister + ".w\n" + "pow " + t + ".w, " + t + ".w, " + this._pSpecularTexData + ".w\n"; + } + else + code += "pow " + t + ".w, " + t + ".w, " + this._pSpecularDataRegister + ".w\n"; + // attenuate + code += "mul " + t + ".w, " + t + ".w, " + lightDirReg + ".w\n"; + if (this._iModulateMethod != null) + code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters); + code += "mul " + t + ".xyz, " + lightColReg + ".xyz, " + t + ".w\n"; + if (!this._pIsFirstLight) { + code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n"; + registerCache.removeFragmentTempUsage(t); + } + this._pIsFirstLight = false; + return code; + }; + return SpecularAnisotropicMethod; +})(SpecularBasicMethod); +module.exports = SpecularAnisotropicMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NwZWN1bGFyYW5pc290cm9waWNtZXRob2QudHMiXSwibmFtZXMiOlsiU3BlY3VsYXJBbmlzb3Ryb3BpY01ldGhvZCIsIlNwZWN1bGFyQW5pc290cm9waWNNZXRob2QuY29uc3RydWN0b3IiLCJTcGVjdWxhckFuaXNvdHJvcGljTWV0aG9kLmlJbml0Vk8iLCJTcGVjdWxhckFuaXNvdHJvcGljTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBS0EsSUFBTyxtQkFBbUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRXBHLEFBS0E7Ozs7R0FERztJQUNHLHlCQUF5QjtJQUFTQSxVQUFsQ0EseUJBQXlCQSxVQUE0QkE7SUFFMURBOztPQUVHQTtJQUNIQSxTQUxLQSx5QkFBeUJBO1FBTzdCQyxpQkFBT0EsQ0FBQ0E7SUFDVEEsQ0FBQ0E7SUFFREQ7O09BRUdBO0lBQ0lBLDJDQUFPQSxHQUFkQSxVQUFlQSxZQUFpQ0EsRUFBRUEsUUFBaUJBO1FBRWxFRSxRQUFRQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUM5QkEsUUFBUUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDM0JBLENBQUNBO0lBRURGOztPQUVHQTtJQUNJQSw0REFBd0JBLEdBQS9CQSxVQUFnQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxXQUFpQ0EsRUFBRUEsV0FBaUNBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFaE9HLElBQUlBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBQ3JCQSxJQUFJQSxDQUF1QkEsQ0FBQ0E7UUFFNUJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBO1lBQ3ZCQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLENBQUNBO1FBQy9CQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNMQSxDQUFDQSxHQUFHQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1lBQzlDQSxhQUFhQSxDQUFDQSxxQkFBcUJBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQzNDQSxDQUFDQTtRQUVEQSxBQUVBQSxnREFGZ0RBO1FBRWhEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxHQUFHQSxlQUFlQSxDQUFDQSxjQUFjQSxHQUFHQSxRQUFRQSxHQUN4RUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsR0FBR0EsV0FBV0EsR0FBR0EsUUFBUUEsR0FDM0RBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLFFBQVFBLEdBQUdBLGVBQWVBLENBQUNBLGVBQWVBLEdBQUdBLFFBQVFBLENBQUNBO1FBRWpGQSxBQUNBQSxnREFEZ0RBO1FBQ2hEQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUN2Q0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FFaENBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBRTdDQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUNoQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FFaENBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBRTdDQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUUvQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLEFBQ0FBLHNDQURzQ0E7WUFDdENBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxzQkFBc0JBLEdBQUdBLE1BQU1BLEdBQ3hIQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxpQkFBaUJBLEdBQUdBLE1BQU1BLENBQUNBO1FBQ3JFQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUNMQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxzQkFBc0JBLEdBQUdBLE1BQU1BLENBQUNBO1FBRWpGQSxBQUNBQSxZQURZQTtRQUNaQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxXQUFXQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUVoRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxJQUFJQSxJQUFJQSxDQUFDQTtZQUNqQ0EsSUFBSUEsSUFBSUEsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxZQUFZQSxFQUFFQSxRQUFRQSxFQUFFQSxDQUFDQSxFQUFFQSxhQUFhQSxFQUFFQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUUxRkEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsR0FBR0EsV0FBV0EsR0FBR0EsUUFBUUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFFcEVBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBO1lBQzFCQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLEdBQUdBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFDNUdBLGFBQWFBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDMUNBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLEtBQUtBLENBQUNBO1FBRTVCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUNGSCxnQ0FBQ0E7QUFBREEsQ0E3RUEsQUE2RUNBLEVBN0V1QyxtQkFBbUIsRUE2RTFEO0FBRUQsQUFBbUMsaUJBQTFCLHlCQUF5QixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL1NwZWN1bGFyQW5pc290cm9waWNNZXRob2QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyTGlnaHRpbmdPYmplY3RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyTGlnaHRpbmdPYmplY3RcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJFbGVtZW50XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckVsZW1lbnRcIik7XG5pbXBvcnQgU3BlY3VsYXJCYXNpY01ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NwZWN1bGFyQmFzaWNNZXRob2RcIik7XG5cbi8qKlxuICogU3BlY3VsYXJBbmlzb3Ryb3BpY01ldGhvZCBwcm92aWRlcyBhIHNwZWN1bGFyIG1ldGhvZCByZXN1bHRpbmcgaW4gYW5pc290cm9waWMgaGlnaGxpZ2h0cy4gVGhlc2UgYXJlIHR5cGljYWwgZm9yXG4gKiBzdXJmYWNlcyB3aXRoIG1pY3JvZmFjZXQgZGV0YWlscyBzdWNoIGFzIHRpbnkgZ3Jvb3Zlcy4gSW4gcGFydGljdWxhciwgdGhpcyB1c2VzIHRoZSBIZWlkcmljaC1TZWlkZWwgZGlzdHJ1YnV0aW9uLlxuICogVGhlIHRhbmdlbnQgdmVjdG9ycyBhcmUgdXNlZCBhcyB0aGUgc3VyZmFjZSBncm9vdmUgZGlyZWN0aW9ucy5cbiAqL1xuY2xhc3MgU3BlY3VsYXJBbmlzb3Ryb3BpY01ldGhvZCBleHRlbmRzIFNwZWN1bGFyQmFzaWNNZXRob2Rcbntcblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgU3BlY3VsYXJBbmlzb3Ryb3BpY01ldGhvZCBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUluaXRWTyhzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPKVxuXHR7XG5cdFx0bWV0aG9kVk8ubmVlZHNUYW5nZW50cyA9IHRydWU7XG5cdFx0bWV0aG9kVk8ubmVlZHNWaWV3ID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudENvZGVQZXJMaWdodChzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBsaWdodERpclJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIGxpZ2h0Q29sUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIHQ6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXG5cdFx0aWYgKHRoaXMuX3BJc0ZpcnN0TGlnaHQpXG5cdFx0XHR0ID0gdGhpcy5fcFRvdGFsTGlnaHRDb2xvclJlZztcblx0XHRlbHNlIHtcblx0XHRcdHQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblx0XHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHQsIDEpO1xuXHRcdH1cblxuXHRcdC8vIChzaW4obCx0KSAqIHNpbih2LHQpIC0gY29zKGwsdCkqY29zKHYsdCkpIF4ga1xuXG5cdFx0Y29kZSArPSBcIm5ybSBcIiArIHQgKyBcIi54eXosIFwiICsgc2hhcmVkUmVnaXN0ZXJzLnRhbmdlbnRWYXJ5aW5nICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJkcDMgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIueHl6LCBcIiArIGxpZ2h0RGlyUmVnICsgXCIueHl6XFxuXCIgK1xuXHRcdFx0XCJkcDMgXCIgKyB0ICsgXCIueiwgXCIgKyB0ICsgXCIueHl6LCBcIiArIHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQgKyBcIi54eXpcXG5cIjtcblxuXHRcdC8vIChzaW4odC53KSAqIHNpbih0LnopIC0gY29zKHQudykqY29zKHQueikpIF4ga1xuXHRcdGNvZGUgKz0gXCJzaW4gXCIgKyB0ICsgXCIueCwgXCIgKyB0ICsgXCIud1xcblwiICtcblx0XHRcdFwic2luIFwiICsgdCArIFwiLnksIFwiICsgdCArIFwiLnpcXG5cIiArXG5cdFx0XHQvLyAodC54ICogdC55IC0gY29zKHQudykqY29zKHQueikpIF4ga1xuXHRcdFx0XCJtdWwgXCIgKyB0ICsgXCIueCwgXCIgKyB0ICsgXCIueCwgXCIgKyB0ICsgXCIueVxcblwiICtcblx0XHRcdC8vICh0LnggLSBjb3ModC53KSpjb3ModC56KSkgXiBrXG5cdFx0XHRcImNvcyBcIiArIHQgKyBcIi56LCBcIiArIHQgKyBcIi56XFxuXCIgK1xuXHRcdFx0XCJjb3MgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIud1xcblwiICtcblx0XHRcdC8vICh0LnggLSB0LncqdC56KSBeIGtcblx0XHRcdFwibXVsIFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLnpcXG5cIiArXG5cdFx0XHQvLyAodC54IC0gdC53KSBeIGtcblx0XHRcdFwic3ViIFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLngsIFwiICsgdCArIFwiLndcXG5cIjtcblxuXHRcdGlmICh0aGlzLl9wVXNlVGV4dHVyZSkge1xuXHRcdFx0Ly8gYXBwbHkgZ2xvc3MgbW9kdWxhdGlvbiBmcm9tIHRleHR1cmVcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aGlzLl9wU3BlY3VsYXJUZXhEYXRhICsgXCIudywgXCIgKyB0aGlzLl9wU3BlY3VsYXJUZXhEYXRhICsgXCIueSwgXCIgKyB0aGlzLl9wU3BlY3VsYXJEYXRhUmVnaXN0ZXIgKyBcIi53XFxuXCIgK1xuXHRcdFx0XHRcInBvdyBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53LCBcIiArIHRoaXMuX3BTcGVjdWxhclRleERhdGEgKyBcIi53XFxuXCI7XG5cdFx0fSBlbHNlXG5cdFx0XHRjb2RlICs9IFwicG93IFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLncsIFwiICsgdGhpcy5fcFNwZWN1bGFyRGF0YVJlZ2lzdGVyICsgXCIud1xcblwiO1xuXG5cdFx0Ly8gYXR0ZW51YXRlXG5cdFx0Y29kZSArPSBcIm11bCBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53LCBcIiArIGxpZ2h0RGlyUmVnICsgXCIud1xcblwiO1xuXG5cdFx0aWYgKHRoaXMuX2lNb2R1bGF0ZU1ldGhvZCAhPSBudWxsKVxuXHRcdFx0Y29kZSArPSB0aGlzLl9pTW9kdWxhdGVNZXRob2Qoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgdCwgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblxuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ICsgXCIueHl6LCBcIiArIGxpZ2h0Q29sUmVnICsgXCIueHl6LCBcIiArIHQgKyBcIi53XFxuXCI7XG5cblx0XHRpZiAoIXRoaXMuX3BJc0ZpcnN0TGlnaHQpIHtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIueHl6LCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgdCArIFwiLnh5elxcblwiO1xuXHRcdFx0cmVnaXN0ZXJDYWNoZS5yZW1vdmVGcmFnbWVudFRlbXBVc2FnZSh0KTtcblx0XHR9XG5cblx0XHR0aGlzLl9wSXNGaXJzdExpZ2h0ID0gZmFsc2U7XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBTcGVjdWxhckFuaXNvdHJvcGljTWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/SpecularAnisotropicMethod.ts b/lib/materials/methods/SpecularAnisotropicMethod.ts new file mode 100644 index 000000000..6a2100d3e --- /dev/null +++ b/lib/materials/methods/SpecularAnisotropicMethod.ts @@ -0,0 +1,92 @@ +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); + +/** + * SpecularAnisotropicMethod provides a specular method resulting in anisotropic highlights. These are typical for + * surfaces with microfacet details such as tiny grooves. In particular, this uses the Heidrich-Seidel distrubution. + * The tangent vectors are used as the surface groove directions. + */ +class SpecularAnisotropicMethod extends SpecularBasicMethod +{ + /** + * Creates a new SpecularAnisotropicMethod object. + */ + constructor() + { + super(); + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + methodVO.needsTangents = true; + methodVO.needsView = true; + } + + /** + * @inheritDoc + */ + public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + var t:ShaderRegisterElement; + + if (this._pIsFirstLight) + t = this._pTotalLightColorReg; + else { + t = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(t, 1); + } + + // (sin(l,t) * sin(v,t) - cos(l,t)*cos(v,t)) ^ k + + code += "nrm " + t + ".xyz, " + sharedRegisters.tangentVarying + ".xyz\n" + + "dp3 " + t + ".w, " + t + ".xyz, " + lightDirReg + ".xyz\n" + + "dp3 " + t + ".z, " + t + ".xyz, " + sharedRegisters.viewDirFragment + ".xyz\n"; + + // (sin(t.w) * sin(t.z) - cos(t.w)*cos(t.z)) ^ k + code += "sin " + t + ".x, " + t + ".w\n" + + "sin " + t + ".y, " + t + ".z\n" + + // (t.x * t.y - cos(t.w)*cos(t.z)) ^ k + "mul " + t + ".x, " + t + ".x, " + t + ".y\n" + + // (t.x - cos(t.w)*cos(t.z)) ^ k + "cos " + t + ".z, " + t + ".z\n" + + "cos " + t + ".w, " + t + ".w\n" + + // (t.x - t.w*t.z) ^ k + "mul " + t + ".w, " + t + ".w, " + t + ".z\n" + + // (t.x - t.w) ^ k + "sub " + t + ".w, " + t + ".x, " + t + ".w\n"; + + if (this._pUseTexture) { + // apply gloss modulation from texture + code += "mul " + this._pSpecularTexData + ".w, " + this._pSpecularTexData + ".y, " + this._pSpecularDataRegister + ".w\n" + + "pow " + t + ".w, " + t + ".w, " + this._pSpecularTexData + ".w\n"; + } else + code += "pow " + t + ".w, " + t + ".w, " + this._pSpecularDataRegister + ".w\n"; + + // attenuate + code += "mul " + t + ".w, " + t + ".w, " + lightDirReg + ".w\n"; + + if (this._iModulateMethod != null) + code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters); + + code += "mul " + t + ".xyz, " + lightColReg + ".xyz, " + t + ".w\n"; + + if (!this._pIsFirstLight) { + code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n"; + registerCache.removeFragmentTempUsage(t); + } + + this._pIsFirstLight = false; + + return code; + } +} + +export = SpecularAnisotropicMethod; \ No newline at end of file diff --git a/lib/materials/methods/SpecularCelMethod.js b/lib/materials/methods/SpecularCelMethod.js new file mode 100755 index 000000000..c1425ee2b --- /dev/null +++ b/lib/materials/methods/SpecularCelMethod.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 SpecularCompositeMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCompositeMethod"); +/** + * SpecularCelMethod provides a shading method to add specular cel (cartoon) shading. + */ +var SpecularCelMethod = (function (_super) { + __extends(SpecularCelMethod, _super); + /** + * Creates a new SpecularCelMethod object. + * @param specularCutOff The threshold at which the specular highlight should be shown. + * @param baseMethod An optional specular method on which the cartoon shading is based. If ommitted, SpecularBasicMethod is used. + */ + function SpecularCelMethod(specularCutOff, baseMethod) { + var _this = this; + if (specularCutOff === void 0) { specularCutOff = .5; } + if (baseMethod === void 0) { baseMethod = null; } + _super.call(this, null, baseMethod); + this._smoothness = .1; + this._specularCutOff = .1; + this.baseMethod._iModulateMethod = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { return _this.clampSpecular(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); }; + this._specularCutOff = specularCutOff; + } + Object.defineProperty(SpecularCelMethod.prototype, "smoothness", { + /** + * The smoothness of the highlight edge. + */ + get: function () { + return this._smoothness; + }, + set: function (value) { + this._smoothness = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpecularCelMethod.prototype, "specularCutOff", { + /** + * The threshold at which the specular highlight should be shown. + */ + get: function () { + return this._specularCutOff; + }, + set: function (value) { + this._specularCutOff = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SpecularCelMethod.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._smoothness; + data[index + 1] = this._specularCutOff; + }; + /** + * @inheritDoc + */ + SpecularCelMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._dataReg = null; + }; + /** + * Snaps the specular shading strength of the wrapped method to zero or one, depending on whether or not it exceeds the specularCutOff + * @param vo The MethodVO used to compile the current shader. + * @param t The register containing the specular strength in the "w" component, and either the half-vector or the reflection vector in "xyz". + * @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. + */ + SpecularCelMethod.prototype.clampSpecular = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + return "sub " + targetReg + ".y, " + targetReg + ".w, " + this._dataReg + ".y\n" + "div " + targetReg + ".y, " + targetReg + ".y, " + this._dataReg + ".x\n" + "sat " + targetReg + ".y, " + targetReg + ".y\n" + "sge " + targetReg + ".w, " + targetReg + ".w, " + this._dataReg + ".y\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n"; + }; + /** + * @inheritDoc + */ + SpecularCelMethod.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); + }; + return SpecularCelMethod; +})(SpecularCompositeMethod); +module.exports = SpecularCelMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NwZWN1bGFyY2VsbWV0aG9kLnRzIl0sIm5hbWVzIjpbIlNwZWN1bGFyQ2VsTWV0aG9kIiwiU3BlY3VsYXJDZWxNZXRob2QuY29uc3RydWN0b3IiLCJTcGVjdWxhckNlbE1ldGhvZC5zbW9vdGhuZXNzIiwiU3BlY3VsYXJDZWxNZXRob2Quc3BlY3VsYXJDdXRPZmYiLCJTcGVjdWxhckNlbE1ldGhvZC5pQWN0aXZhdGUiLCJTcGVjdWxhckNlbE1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJTcGVjdWxhckNlbE1ldGhvZC5jbGFtcFNwZWN1bGFyIiwiU3BlY3VsYXJDZWxNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFTQSxJQUFPLHVCQUF1QixXQUFhLGlFQUFpRSxDQUFDLENBQUM7QUFFOUcsQUFHQTs7R0FERztJQUNHLGlCQUFpQjtJQUFTQSxVQUExQkEsaUJBQWlCQSxVQUFnQ0E7SUFNdERBOzs7O09BSUdBO0lBQ0hBLFNBWEtBLGlCQUFpQkEsQ0FXVkEsY0FBMEJBLEVBQUVBLFVBQXFDQTtRQVg5RUMsaUJBK0ZDQTtRQXBGWUEsOEJBQTBCQSxHQUExQkEsbUJBQTBCQTtRQUFFQSwwQkFBcUNBLEdBQXJDQSxpQkFBcUNBO1FBRTVFQSxrQkFBTUEsSUFBSUEsRUFBRUEsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFWakJBLGdCQUFXQSxHQUFVQSxFQUFFQSxDQUFDQTtRQUN4QkEsb0JBQWVBLEdBQVVBLEVBQUVBLENBQUNBO1FBV25DQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxnQkFBZ0JBLEdBQUdBLFVBQUNBLFlBQTZCQSxFQUFFQSxRQUFpQkEsRUFBRUEsU0FBK0JBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0EsSUFBS0EsT0FBQUEsS0FBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsWUFBWUEsRUFBRUEsUUFBUUEsRUFBRUEsU0FBU0EsRUFBRUEsYUFBYUEsRUFBRUEs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QUFDQSwyQkFBMkJBLFlBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO0lBQ2xHQSxDQUFDQTtJQUNGUCx3QkFBQ0E7QUFBREEsQ0EvRkEsQUErRkNBLEVBL0YrQix1QkFBdUIsRUErRnREO0FBRUQsQUFBMkIsaUJBQWxCLGlCQUFpQixDQUFDIiwiZmlsZSI6Im1hdGVyaWFscy9tZXRob2RzL1NwZWN1bGFyQ2VsTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IFNwZWN1bGFyQmFzaWNNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TcGVjdWxhckJhc2ljTWV0aG9kXCIpO1xuXG5pbXBvcnQgU3BlY3VsYXJDb21wb3NpdGVNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJDb21wb3NpdGVNZXRob2RcIik7XG5cbi8qKlxuICogU3BlY3VsYXJDZWxNZXRob2QgcHJvdmlkZXMgYSBzaGFkaW5nIG1ldGhvZCB0byBhZGQgc3BlY3VsYXIgY2VsIChjYXJ0b29uKSBzaGFkaW5nLlxuICovXG5jbGFzcyBTcGVjdWxhckNlbE1ldGhvZCBleHRlbmRzIFNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kXG57XG5cdHByaXZhdGUgX2RhdGFSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50O1xuXHRwcml2YXRlIF9zbW9vdGhuZXNzOm51bWJlciA9IC4xO1xuXHRwcml2YXRlIF9zcGVjdWxhckN1dE9mZjpudW1iZXIgPSAuMTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBTcGVjdWxhckNlbE1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSBzcGVjdWxhckN1dE9mZiBUaGUgdGhyZXNob2xkIGF0IHdoaWNoIHRoZSBzcGVjdWxhciBoaWdobGlnaHQgc2hvdWxkIGJlIHNob3duLlxuXHQgKiBAcGFyYW0gYmFzZU1ldGhvZCBBbiBvcHRpb25hbCBzcGVjdWxhciBtZXRob2Qgb24gd2hpY2ggdGhlIGNhcnRvb24gc2hhZGluZyBpcyBiYXNlZC4gSWYgb21taXR0ZWQsIFNwZWN1bGFyQmFzaWNNZXRob2QgaXMgdXNlZC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHNwZWN1bGFyQ3V0T2ZmOm51bWJlciA9IC41LCBiYXNlTWV0aG9kOlNwZWN1bGFyQmFzaWNNZXRob2QgPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIobnVsbCwgYmFzZU1ldGhvZCk7XG5cblx0XHR0aGlzLmJhc2VNZXRob2QuX2lNb2R1bGF0ZU1ldGhvZCA9IChzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSkgPT4gdGhpcy5jbGFtcFNwZWN1bGFyKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHRhcmdldFJlZywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblxuXHRcdHRoaXMuX3NwZWN1bGFyQ3V0T2ZmID0gc3BlY3VsYXJDdXRPZmY7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHNtb290aG5lc3Mgb2YgdGhlIGhpZ2hsaWdodCBlZGdlLlxuXHQgKi9cblx0cHVibGljIGdldCBzbW9vdGhuZXNzKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fc21vb3RobmVzcztcblx0fVxuXG5cdHB1YmxpYyBzZXQgc21vb3RobmVzcyh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9zbW9vdGhuZXNzID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRocmVzaG9sZCBhdCB3aGljaCB0aGUgc3BlY3VsYXIgaGlnaGxpZ2h0IHNob3VsZCBiZSBzaG93bi5cblx0ICovXG5cdHB1YmxpYyBnZXQgc3BlY3VsYXJDdXRPZmYoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9zcGVjdWxhckN1dE9mZjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgc3BlY3VsYXJDdXRPZmYodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fc3BlY3VsYXJDdXRPZmYgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHN1cGVyLmlBY3RpdmF0ZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBzdGFnZSk7XG5cblx0XHR2YXIgaW5kZXg6bnVtYmVyIC8qaW50Ki8gPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj4gPSBzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGE7XG5cdFx0ZGF0YVtpbmRleF0gPSB0aGlzLl9zbW9vdGhuZXNzO1xuXHRcdGRhdGFbaW5kZXggKyAxXSA9IHRoaXMuX3NwZWN1bGFyQ3V0T2ZmO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUNsZWFuQ29tcGlsYXRpb25EYXRhKClcblx0e1xuXHRcdHN1cGVyLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpO1xuXHRcdHRoaXMuX2RhdGFSZWcgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNuYXBzIHRoZSBzcGVjdWxhciBzaGFkaW5nIHN0cmVuZ3RoIG9mIHRoZSB3cmFwcGVkIG1ldGhvZCB0byB6ZXJvIG9yIG9uZSwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgb3Igbm90IGl0IGV4Y2VlZHMgdGhlIHNwZWN1bGFyQ3V0T2ZmXG5cdCAqIEBwYXJhbSB2byBUaGUgTWV0aG9kVk8gdXNlZCB0byBjb21waWxlIHRoZSBjdXJyZW50IHNoYWRlci5cblx0ICogQHBhcmFtIHQgVGhlIHJlZ2lzdGVyIGNvbnRhaW5pbmcgdGhlIHNwZWN1bGFyIHN0cmVuZ3RoIGluIHRoZSBcIndcIiBjb21wb25lbnQsIGFuZCBlaXRoZXIgdGhlIGhhbGYtdmVjdG9yIG9yIHRoZSByZWZsZWN0aW9uIHZlY3RvciBpbiBcInh5elwiLlxuXHQgKiBAcGFyYW0gcmVnQ2FjaGUgVGhlIHJlZ2lzdGVyIGNhY2hlIHVzZWQgZm9yIHRoZSBzaGFkZXIgY29tcGlsYXRpb24uXG5cdCAqIEBwYXJhbSBzaGFyZWRSZWdpc3RlcnMgVGhlIHNoYXJlZCByZWdpc3RlciBkYXRhIGZvciB0aGlzIHNoYWRlci5cblx0ICogQHJldHVybiBUaGUgQUdBTCBmcmFnbWVudCBjb2RlIGZvciB0aGUgbWV0aG9kLlxuXHQgKi9cblx0cHJpdmF0ZSBjbGFtcFNwZWN1bGFyKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiBcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0aGlzLl9kYXRhUmVnICsgXCIueVxcblwiICsgLy8geCAtIGN1dG9mZlxuXHRcdFx0XCJkaXYgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGhpcy5fZGF0YVJlZyArIFwiLnhcXG5cIiArIC8vICh4IC0gY3V0b2ZmKS9lcHNpbG9uXG5cdFx0XHRcInNhdCBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiICtcblx0XHRcdFwic2dlIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRoaXMuX2RhdGFSZWcgKyBcIi55XFxuXCIgK1xuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi53LCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR0aGlzLl9kYXRhUmVnID0gcmVnaXN0ZXJDYWNoZS5nZXRGcmVlRnJhZ21lbnRDb25zdGFudCgpO1xuXHRcdG1ldGhvZFZPLnNlY29uZGFyeUZyYWdtZW50Q29uc3RhbnRzSW5kZXggPSB0aGlzLl9kYXRhUmVnLmluZGV4KjQ7XG5cblx0XHRyZXR1cm4gc3VwZXIuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU3BlY3VsYXJDZWxNZXRob2Q7Il19 \ No newline at end of file diff --git a/lib/materials/methods/SpecularCelMethod.ts b/lib/materials/methods/SpecularCelMethod.ts new file mode 100644 index 000000000..53ada1afb --- /dev/null +++ b/lib/materials/methods/SpecularCelMethod.ts @@ -0,0 +1,112 @@ +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 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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); + +import SpecularCompositeMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCompositeMethod"); + +/** + * SpecularCelMethod provides a shading method to add specular cel (cartoon) shading. + */ +class SpecularCelMethod extends SpecularCompositeMethod +{ + private _dataReg:ShaderRegisterElement; + private _smoothness:number = .1; + private _specularCutOff:number = .1; + + /** + * Creates a new SpecularCelMethod object. + * @param specularCutOff The threshold at which the specular highlight should be shown. + * @param baseMethod An optional specular method on which the cartoon shading is based. If ommitted, SpecularBasicMethod is used. + */ + constructor(specularCutOff:number = .5, baseMethod:SpecularBasicMethod = null) + { + super(null, baseMethod); + + this.baseMethod._iModulateMethod = (shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => this.clampSpecular(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + + this._specularCutOff = specularCutOff; + } + + /** + * The smoothness of the highlight edge. + */ + public get smoothness():number + { + return this._smoothness; + } + + public set smoothness(value:number) + { + this._smoothness = value; + } + + /** + * The threshold at which the specular highlight should be shown. + */ + public get specularCutOff():number + { + return this._specularCutOff; + } + + public set specularCutOff(value:number) + { + this._specularCutOff = value; + } + + /** + * @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._smoothness; + data[index + 1] = this._specularCutOff; + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._dataReg = null; + } + + /** + * Snaps the specular shading strength of the wrapped method to zero or one, depending on whether or not it exceeds the specularCutOff + * @param vo The MethodVO used to compile the current shader. + * @param t The register containing the specular strength in the "w" component, and either the half-vector or the reflection vector in "xyz". + * @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 clampSpecular(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return "sub " + targetReg + ".y, " + targetReg + ".w, " + this._dataReg + ".y\n" + // x - cutoff + "div " + targetReg + ".y, " + targetReg + ".y, " + this._dataReg + ".x\n" + // (x - cutoff)/epsilon + "sat " + targetReg + ".y, " + targetReg + ".y\n" + + "sge " + targetReg + ".w, " + targetReg + ".w, " + this._dataReg + ".y\n" + + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n"; + } + + /** + * @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); + } +} + +export = SpecularCelMethod; \ No newline at end of file diff --git a/lib/materials/methods/SpecularCompositeMethod.js b/lib/materials/methods/SpecularCompositeMethod.js new file mode 100755 index 000000000..0dff27405 --- /dev/null +++ b/lib/materials/methods/SpecularCompositeMethod.js @@ -0,0 +1,188 @@ +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +/** + * SpecularCompositeMethod provides a base class for specular methods that wrap a specular method to alter the + * calculated specular reflection strength. + */ +var SpecularCompositeMethod = (function (_super) { + __extends(SpecularCompositeMethod, _super); + /** + * Creates a new SpecularCompositeMethod object. + * + * @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature modSpecular(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the specular strength and t.xyz will contain the half-vector or the reflection vector. + * @param baseMethod The base specular method on which this method's shading is based. + */ + function SpecularCompositeMethod(modulateMethod, baseMethod) { + var _this = this; + if (baseMethod === void 0) { baseMethod = null; } + _super.call(this); + this._onShaderInvalidatedDelegate = function (event) { return _this.onShaderInvalidated(event); }; + this._baseMethod = baseMethod || new SpecularBasicMethod(); + this._baseMethod._iModulateMethod = modulateMethod; + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + } + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iInitVO = function (shaderObject, methodVO) { + this._baseMethod.iInitVO(shaderObject, methodVO); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + this._baseMethod.iInitConstants(shaderObject, methodVO); + }; + Object.defineProperty(SpecularCompositeMethod.prototype, "baseMethod", { + /** + * The base specular method on which this method's shading is based. + */ + get: function () { + return this._baseMethod; + }, + set: function (value) { + if (this._baseMethod == value) + return; + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this._baseMethod = value; + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpecularCompositeMethod.prototype, "gloss", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.gloss; + }, + set: function (value) { + this._baseMethod.gloss = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpecularCompositeMethod.prototype, "specular", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.specular; + }, + set: function (value) { + this._baseMethod.specular = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpecularCompositeMethod.prototype, "passes", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.passes; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.dispose = function () { + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this._baseMethod.dispose(); + }; + Object.defineProperty(SpecularCompositeMethod.prototype, "texture", { + /** + * @inheritDoc + */ + get: function () { + return this._baseMethod.texture; + }, + set: function (value) { + this._baseMethod.texture = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + this._baseMethod.iActivate(shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iSetRenderState = function (shaderObject, methodVO, renderable, stage, camera) { + this._baseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iDeactivate = function (shaderObject, methodVO, stage) { + this._baseMethod.iDeactivate(shaderObject, methodVO, stage); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iGetVertexCode = function (shaderObject, methodVO, registerCache, sharedRegisters) { + return this._baseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) { + return this._baseMethod.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) { + return this._baseMethod.iGetFragmentCodePerLight(shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + * @return + */ + SpecularCompositeMethod.prototype.iGetFragmentCodePerProbe = function (shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters) { + return this._baseMethod.iGetFragmentCodePerProbe(shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iGetFragmentPostLightingCode = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + return this._baseMethod.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iReset = function () { + this._baseMethod.iReset(); + }; + /** + * @inheritDoc + */ + SpecularCompositeMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._baseMethod.iCleanCompilationData(); + }; + /** + * Called when the base method's shader code is invalidated. + */ + SpecularCompositeMethod.prototype.onShaderInvalidated = function (event) { + this.iInvalidateShaderProgram(); + }; + return SpecularCompositeMethod; +})(SpecularBasicMethod); +module.exports = SpecularCompositeMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NwZWN1bGFyY29tcG9zaXRlbWV0aG9kLnRzIl0sIm5hbWVzIjpbIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuY29uc3RydWN0b3IiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5pSW5pdFZPIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuaUluaXRDb25zdGFudHMiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5iYXNlTWV0aG9kIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuZ2xvc3MiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5zcGVjdWxhciIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLnBhc3NlcyIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLmRpc3Bvc2UiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC50ZXh0dXJlIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuaUFjdGl2YXRlIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuaVNldFJlbmRlclN0YXRlIiwiU3BlY3VsYXJDb21wb3NpdGVNZXRob2QuaURlYWN0aXZhdGUiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5pR2V0VmVydGV4Q29kZSIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZSIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodCIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJQcm9iZSIsIlNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kLmlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5pUmVzZXQiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEiLCJTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5v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bUJBQW1CLEVBOE14RDtBQUVELEFBQWlDLGlCQUF4Qix1QkFBdUIsQ0FBQyIsImZpbGUiOiJtYXRlcmlhbHMvbWV0aG9kcy9TcGVjdWxhckNvbXBvc2l0ZU1ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDYW1lcmFcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9DYW1lcmFcIik7XG5pbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IFJlbmRlcmFibGVCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3Bvb2wvUmVuZGVyYWJsZUJhc2VcIik7XG5pbXBvcnQgU2hhZGluZ01ldGhvZEV2ZW50XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvZXZlbnRzL1NoYWRpbmdNZXRob2RFdmVudFwiKTtcbmltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJPYmplY3RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyT2JqZWN0QmFzZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBTcGVjdWxhckJhc2ljTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBNYXRlcmlhbFBhc3NCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvcGFzc2VzL01hdGVyaWFsUGFzc0Jhc2VcIik7XG5cbi8qKlxuICogU3BlY3VsYXJDb21wb3NpdGVNZXRob2QgcHJvdmlkZXMgYSBiYXNlIGNsYXNzIGZvciBzcGVjdWxhciBtZXRob2RzIHRoYXQgd3JhcCBhIHNwZWN1bGFyIG1ldGhvZCB0byBhbHRlciB0aGVcbiAqIGNhbGN1bGF0ZWQgc3BlY3VsYXIgcmVmbGVjdGlvbiBzdHJlbmd0aC5cbiAqL1xuY2xhc3MgU3BlY3VsYXJDb21wb3NpdGVNZXRob2QgZXh0ZW5kcyBTcGVjdWxhckJhc2ljTWV0aG9kXG57XG5cdHByaXZhdGUgX2Jhc2VNZXRob2Q6U3BlY3VsYXJCYXNpY01ldGhvZDtcblxuXHRwcml2YXRlIF9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGU6RnVuY3Rpb247XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+U3BlY3VsYXJDb21wb3NpdGVNZXRob2Q8L2NvZGU+IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIG1vZHVsYXRlTWV0aG9kIFRoZSBtZXRob2Qgd2hpY2ggd2lsbCBhZGQgdGhlIGNvZGUgdG8gYWx0ZXIgdGhlIGJhc2UgbWV0aG9kJ3Mgc3RyZW5ndGguIEl0IG5lZWRzIHRvIGhhdmUgdGhlIHNpZ25hdHVyZSBtb2RTcGVjdWxhcih0OlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSk6c3RyaW5nLCBpbiB3aGljaCB0Lncgd2lsbCBjb250YWluIHRoZSBzcGVjdWxhciBzdHJlbmd0aCBhbmQgdC54eXogd2lsbCBjb250YWluIHRoZSBoYWxmLXZlY3RvciBvciB0aGUgcmVmbGVjdGlvbiB2ZWN0b3IuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBiYXNlIHNwZWN1bGFyIG1ldGhvZCBvbiB3aGljaCB0aGlzIG1ldGhvZCdzIHNoYWRpbmcgaXMgYmFzZWQuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihtb2R1bGF0ZU1ldGhvZDooc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCB0YXJnZXRSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpID0+IHN0cmluZywgYmFzZU1ldGhvZDpTcGVjdWxhckJhc2ljTWV0aG9kID0gbnVsbClcblx0e1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUgPSAoZXZlbnQ6U2hhZGluZ01ldGhvZEV2ZW50KSA9PiB0aGlzLm9uU2hhZGVySW52YWxpZGF0ZWQoZXZlbnQpO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZCA9IGJhc2VNZXRob2QgfHwgbmV3IFNwZWN1bGFyQmFzaWNNZXRob2QoKTtcblx0XHR0aGlzLl9iYXNlTWV0aG9kLl9pTW9kdWxhdGVNZXRob2QgPSBtb2R1bGF0ZU1ldGhvZDtcblx0XHR0aGlzLl9iYXNlTWV0aG9kLmFkZEV2ZW50TGlzdGVuZXIoU2hhZGluZ01ldGhvZEV2ZW50LlNIQURFUl9JTlZBTElEQVRFRCwgdGhpcy5fb25TaGFkZXJJbnZhbGlkYXRlZERlbGVnYXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Vk8oc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaUluaXRWTyhzaGFkZXJPYmplY3QsIG1ldGhvZFZPKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlJbml0Q29uc3RhbnRzKHNoYWRlck9iamVjdDpTaGFkZXJPYmplY3RCYXNlLCBtZXRob2RWTzpNZXRob2RWTylcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaUluaXRDb25zdGFudHMoc2hhZGVyT2JqZWN0LCBtZXRob2RWTyk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGJhc2Ugc3BlY3VsYXIgbWV0aG9kIG9uIHdoaWNoIHRoaXMgbWV0aG9kJ3Mgc2hhZGluZyBpcyBiYXNlZC5cblx0ICovXG5cdHB1YmxpYyBnZXQgYmFzZU1ldGhvZCgpOlNwZWN1bGFyQmFzaWNNZXRob2Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl9iYXNlTWV0aG9kO1xuXHR9XG5cblx0cHVibGljIHNldCBiYXNlTWV0aG9kKHZhbHVlOlNwZWN1bGFyQmFzaWNNZXRob2QpXG5cdHtcblx0XHRpZiAodGhpcy5fYmFzZU1ldGhvZCA9PSB2YWx1ZSlcblx0XHRcdHJldHVybjtcblxuXHRcdHRoaXMuX2Jhc2VNZXRob2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCB0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUpO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZCA9IHZhbHVlO1xuXG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5hZGRFdmVudExpc3RlbmVyKFNoYWRpbmdNZXRob2RFdmVudC5TSEFERVJfSU5WQUxJREFURUQsIHRoaXMuX29uU2hhZGVySW52YWxpZGF0ZWREZWxlZ2F0ZSk7XG5cblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IGdsb3NzKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5nbG9zcztcblx0fVxuXG5cdHB1YmxpYyBzZXQgZ2xvc3ModmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5nbG9zcyA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHNwZWN1bGFyKCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5zcGVjdWxhcjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgc3BlY3VsYXIodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5zcGVjdWxhciA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHBhc3NlcygpOkFycmF5PE1hdGVyaWFsUGFzc0Jhc2U+XG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5wYXNzZXM7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBkaXNwb3NlKClcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihTaGFkaW5nTWV0aG9kRXZlbnQuU0hBREVSX0lOVkFMSURBVEVELCB0aGlzLl9vblNoYWRlckludmFsaWRhdGVkRGVsZWdhdGUpO1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuZGlzcG9zZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZ2V0IHRleHR1cmUoKTpUZXh0dXJlMkRCYXNlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC50ZXh0dXJlO1xuXHR9XG5cblx0cHVibGljIHNldCB0ZXh0dXJlKHZhbHVlOlRleHR1cmUyREJhc2UpXG5cdHtcblx0XHR0aGlzLl9iYXNlTWV0aG9kLnRleHR1cmUgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlBY3RpdmF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlTZXRSZW5kZXJTdGF0ZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaVNldFJlbmRlclN0YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlbmRlcmFibGUsIHN0YWdlLCBjYW1lcmEpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaURlYWN0aXZhdGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCBzdGFnZTpTdGFnZSlcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaURlYWN0aXZhdGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgc3RhZ2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldFZlcnRleENvZGUoc2hhZGVyT2JqZWN0OlNoYWRlck9iamVjdEJhc2UsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Jhc2VNZXRob2QuaUdldFZlcnRleENvZGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2Jhc2VNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVycyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgbGlnaHREaXJSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCBsaWdodENvbFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYmFzZU1ldGhvZC5pR2V0RnJhZ21lbnRDb2RlUGVyTGlnaHQoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgbGlnaHREaXJSZWcsIGxpZ2h0Q29sUmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqIEByZXR1cm5cblx0ICovXG5cdHB1YmxpYyBpR2V0RnJhZ21lbnRDb2RlUGVyUHJvYmUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgY3ViZU1hcFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHdlaWdodFJlZ2lzdGVyOnN0cmluZywgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLl9iYXNlTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJQcm9iZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCBjdWJlTWFwUmVnLCB3ZWlnaHRSZWdpc3RlciwgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0OlNoYWRlckxpZ2h0aW5nT2JqZWN0LCBtZXRob2RWTzpNZXRob2RWTywgdGFyZ2V0UmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHJldHVybiB0aGlzLl9iYXNlTWV0aG9kLmlHZXRGcmFnbWVudFBvc3RMaWdodGluZ0NvZGUoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgdGFyZ2V0UmVnLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaVJlc2V0KClcblx0e1xuXHRcdHRoaXMuX2Jhc2VNZXRob2QuaVJlc2V0KCk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpQ2xlYW5Db21waWxhdGlvbkRhdGEoKVxuXHR7XG5cdFx0c3VwZXIuaUNsZWFuQ29tcGlsYXRpb25EYXRhKCk7XG5cdFx0dGhpcy5fYmFzZU1ldGhvZC5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgd2hlbiB0aGUgYmFzZSBtZXRob2QncyBzaGFkZXIgY29kZSBpcyBpbnZhbGlkYXRlZC5cblx0ICovXG5cdHByaXZhdGUgb25TaGFkZXJJbnZhbGlkYXRlZChldmVudDpTaGFkaW5nTWV0aG9kRXZlbnQpXG5cdHtcblx0XHR0aGlzLmlJbnZhbGlkYXRlU2hhZGVyUHJvZ3JhbSgpO1xuXHR9XG59XG5cbmV4cG9ydCA9IFNwZWN1bGFyQ29tcG9zaXRlTWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/SpecularCompositeMethod.ts b/lib/materials/methods/SpecularCompositeMethod.ts new file mode 100755 index 000000000..51f0ea6a2 --- /dev/null +++ b/lib/materials/methods/SpecularCompositeMethod.ts @@ -0,0 +1,228 @@ +import Camera = require("awayjs-core/lib/entities/Camera"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); + +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +import MaterialPassBase = require("awayjs-stagegl/lib/materials/passes/MaterialPassBase"); + +/** + * SpecularCompositeMethod provides a base class for specular methods that wrap a specular method to alter the + * calculated specular reflection strength. + */ +class SpecularCompositeMethod extends SpecularBasicMethod +{ + private _baseMethod:SpecularBasicMethod; + + private _onShaderInvalidatedDelegate:Function; + + /** + * Creates a new SpecularCompositeMethod object. + * + * @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature modSpecular(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the specular strength and t.xyz will contain the half-vector or the reflection vector. + * @param baseMethod The base specular method on which this method's shading is based. + */ + constructor(modulateMethod:(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => string, baseMethod:SpecularBasicMethod = null) + { + super(); + + this._onShaderInvalidatedDelegate = (event:ShadingMethodEvent) => this.onShaderInvalidated(event); + + this._baseMethod = baseMethod || new SpecularBasicMethod(); + this._baseMethod._iModulateMethod = modulateMethod; + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + } + + /** + * @inheritDoc + */ + public iInitVO(shaderObject:ShaderLightingObject, methodVO:MethodVO) + { + this._baseMethod.iInitVO(shaderObject, methodVO); + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + this._baseMethod.iInitConstants(shaderObject, methodVO); + } + + /** + * The base specular method on which this method's shading is based. + */ + public get baseMethod():SpecularBasicMethod + { + return this._baseMethod; + } + + public set baseMethod(value:SpecularBasicMethod) + { + if (this._baseMethod == value) + return; + + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + + this._baseMethod = value; + + this._baseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + + this.iInvalidateShaderProgram(); + } + + /** + * @inheritDoc + */ + public get gloss():number + { + return this._baseMethod.gloss; + } + + public set gloss(value:number) + { + this._baseMethod.gloss = value; + } + + /** + * @inheritDoc + */ + public get specular():number + { + return this._baseMethod.specular; + } + + public set specular(value:number) + { + this._baseMethod.specular = value; + } + + /** + * @inheritDoc + */ + public get passes():Array + { + return this._baseMethod.passes; + } + + /** + * @inheritDoc + */ + public dispose() + { + this._baseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate); + this._baseMethod.dispose(); + } + + /** + * @inheritDoc + */ + public get texture():Texture2DBase + { + return this._baseMethod.texture; + } + + public set texture(value:Texture2DBase) + { + this._baseMethod.texture = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage) + { + this._baseMethod.iActivate(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iSetRenderState(shaderObject:ShaderLightingObject, methodVO:MethodVO, renderable:RenderableBase, stage:Stage, camera:Camera) + { + this._baseMethod.iSetRenderState(shaderObject, methodVO, renderable, stage, camera); + } + + /** + * @inheritDoc + */ + public iDeactivate(shaderObject:ShaderObjectBase, methodVO:MethodVO, stage:Stage) + { + this._baseMethod.iDeactivate(shaderObject, methodVO, stage); + } + + /** + * @inheritDoc + */ + public iGetVertexCode(shaderObject:ShaderObjectBase, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetVertexCode(shaderObject, methodVO, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + */ + public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + */ + public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetFragmentCodePerLight(shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + * @return + */ + public iGetFragmentCodePerProbe(shaderObject:ShaderLightingObject, methodVO:MethodVO, cubeMapReg:ShaderRegisterElement, weightRegister:string, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetFragmentCodePerProbe(shaderObject, methodVO, cubeMapReg, weightRegister, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + */ + public iGetFragmentPostLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + return this._baseMethod.iGetFragmentPostLightingCode(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + } + + /** + * @inheritDoc + */ + public iReset() + { + this._baseMethod.iReset(); + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._baseMethod.iCleanCompilationData(); + } + + /** + * Called when the base method's shader code is invalidated. + */ + private onShaderInvalidated(event:ShadingMethodEvent) + { + this.iInvalidateShaderProgram(); + } +} + +export = SpecularCompositeMethod; \ No newline at end of file diff --git a/lib/materials/methods/SpecularFresnelMethod.js b/lib/materials/methods/SpecularFresnelMethod.js new file mode 100755 index 000000000..8a90fc249 --- /dev/null +++ b/lib/materials/methods/SpecularFresnelMethod.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 SpecularCompositeMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCompositeMethod"); +/** + * SpecularFresnelMethod provides a specular shading method that causes stronger highlights on grazing view angles. + */ +var SpecularFresnelMethod = (function (_super) { + __extends(SpecularFresnelMethod, _super); + /** + * Creates a new SpecularFresnelMethod object. + * @param basedOnSurface Defines whether the fresnel effect should be based on the view angle on the surface (if true), or on the angle between the light and the view. + * @param baseMethod The specular method to which the fresnel equation. Defaults to SpecularBasicMethod. + */ + function SpecularFresnelMethod(basedOnSurface, baseMethod) { + var _this = this; + if (basedOnSurface === void 0) { basedOnSurface = true; } + if (baseMethod === void 0) { baseMethod = null; } + // may want to offer diff speculars + _super.call(this, null, baseMethod); + this._fresnelPower = 5; + this._normalReflectance = .028; // default value for skin + this.baseMethod._iModulateMethod = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { return _this.modulateSpecular(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); }; + this._incidentLight = !basedOnSurface; + } + /** + * @inheritDoc + */ + SpecularFresnelMethod.prototype.iInitConstants = function (shaderObject, methodVO) { + var index = methodVO.secondaryFragmentConstantsIndex; + shaderObject.fragmentConstantData[index + 2] = 1; + shaderObject.fragmentConstantData[index + 3] = 0; + }; + Object.defineProperty(SpecularFresnelMethod.prototype, "basedOnSurface", { + /** + * Defines whether the fresnel effect should be based on the view angle on the surface (if true), or on the angle between the light and the view. + */ + get: function () { + return !this._incidentLight; + }, + set: function (value) { + if (this._incidentLight != value) + return; + this._incidentLight = !value; + this.iInvalidateShaderProgram(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpecularFresnelMethod.prototype, "fresnelPower", { + /** + * The power used in the Fresnel equation. Higher values make the fresnel effect more pronounced. Defaults to 5. + */ + get: function () { + return this._fresnelPower; + }, + set: function (value) { + this._fresnelPower = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SpecularFresnelMethod.prototype.iCleanCompilationData = function () { + _super.prototype.iCleanCompilationData.call(this); + this._dataReg = null; + }; + Object.defineProperty(SpecularFresnelMethod.prototype, "normalReflectance", { + /** + * The minimum amount of reflectance, ie the reflectance when the view direction is normal to the surface or light direction. + */ + get: function () { + return this._normalReflectance; + }, + set: function (value) { + this._normalReflectance = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SpecularFresnelMethod.prototype.iActivate = function (shaderObject, methodVO, stage) { + _super.prototype.iActivate.call(this, shaderObject, methodVO, stage); + var fragmentData = shaderObject.fragmentConstantData; + var index = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index] = this._normalReflectance; + fragmentData[index + 1] = this._fresnelPower; + }; + /** + * @inheritDoc + */ + SpecularFresnelMethod.prototype.iGetFragmentPreLightingCode = function (shaderObject, methodVO, registerCache, sharedRegisters) { + this._dataReg = registerCache.getFreeFragmentConstant(); + console.log('SpecularFresnelMethod', 'iGetFragmentPreLightingCode', this._dataReg); + methodVO.secondaryFragmentConstantsIndex = this._dataReg.index * 4; + return _super.prototype.iGetFragmentPreLightingCode.call(this, shaderObject, methodVO, registerCache, sharedRegisters); + }; + /** + * Applies the fresnel effect to the specular strength. + * + * @param vo The MethodVO object containing the method data for the currently compiled material pass. + * @param target The register containing the specular strength in the "w" component, and the half-vector/reflection vector in "xyz". + * @param regCache The register cache used for the shader compilation. + * @param sharedRegisters The shared registers created by the compiler. + * @return The AGAL fragment code for the method. + */ + SpecularFresnelMethod.prototype.modulateSpecular = function (shaderObject, methodVO, targetReg, registerCache, sharedRegisters) { + var code; + code = "dp3 " + targetReg + ".y, " + sharedRegisters.viewDirFragment + ".xyz, " + (this._incidentLight ? targetReg : sharedRegisters.normalFragment) + ".xyz\n" + "sub " + targetReg + ".y, " + this._dataReg + ".z, " + targetReg + ".y\n" + "pow " + targetReg + ".x, " + targetReg + ".y, " + this._dataReg + ".y\n" + "sub " + targetReg + ".y, " + this._dataReg + ".z, " + targetReg + ".y\n" + "mul " + targetReg + ".y, " + this._dataReg + ".x, " + targetReg + ".y\n" + "add " + targetReg + ".y, " + targetReg + ".x, " + targetReg + ".y\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n"; + console.log('SpecularFresnelMethod', 'modulateSpecular', code); + return code; + }; + return SpecularFresnelMethod; +})(SpecularCompositeMethod); +module.exports = SpecularFresnelMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NwZWN1bGFyZnJlc25lbG1ldGhvZC50cyJdLCJuYW1lcyI6WyJTcGVjdWxhckZyZXNuZWxNZXRob2QiLCJTcGVjdWxhckZyZXNuZWxNZXRob2QuY29uc3RydWN0b3IiLCJTcGVjdWxhckZyZXNuZWxNZXRob2QuaUluaXRDb25zdGFudHMiLCJTcGVjdWxhckZyZXNuZWxNZXRob2QuYmFzZWRPblN1cmZhY2UiLCJTcGVjdWxhckZyZXNuZWxNZXRob2QuZnJlc25lbFBvd2VyIiwiU3BlY3VsYXJGcmVzbmVsTWV0aG9kLmlDbGVhbkNvbXBpbGF0aW9uRGF0YSIsIlNwZWN1bGFyRnJlc25lbE1ldGhvZC5ub3JtYWxSZWZsZWN0YW5jZSIsIlNwZWN1bGFyRnJlc25lbE1ldGhvZC5pQWN0aXZhdGUiLCJTcGVjdWxhckZyZXNuZWxNZXRob2QuaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlIiwiU3BlY3VsYXJGcmVzbmVsTWV0aG9kLm1vZHVsYXRlU3BlY3VsYXIiXSwibWFwcGluZ3MiOiI7Ozs7OztBQVdBLElBQU8sdUJBQXVCLFdBQWEsaUVBQWlFLENBQUMsQ0FBQztBQUU5RyxBQUdBOztHQURHO0lBQ0cscUJBQXFCO0lBQVNBLFVBQTlCQSxxQkFBcUJBLFVBQWdDQTtJQU8xREE7Ozs7T0FJR0E7SUFDSEEsU0FaS0EscUJBQXFCQSxDQVlkQSxjQUE2QkEsRUFBRUEsVUFBcUNBO1FBWmpGQyxpQkE2SUNBO1FBaklZQSw4QkFBNkJBLEdBQTdCQSxxQkFBNkJBO1FBQUVBLDBCQUFxQ0EsR0FBckNBLGlCQUFxQ0E7UUFFL0VBLEFBQ0FBLG1DQURtQ0E7UUFDbkNBLGtCQUFNQSxJQUFJQSxFQUFFQSxVQUFVQSxDQUFDQSxDQUFDQTtRQVhqQkEsa0JBQWFBLEdBQVVBLENBQUNBLENBQUNBO1FBQ3pCQSx1QkFBa0JBLEdBQVVBLElBQUlBLENBQUNBLENBQUNBLHlCQUF5QkE7UUFZbEVBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLGdCQUFn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LENBQUNBLFFBQVFBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQ3pFQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxNQUFNQSxHQUFHQSxTQUFTQSxHQUFHQSxNQUFNQSxHQUN6RUEsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FBR0EsU0FBU0EsR0FBR0EsTUFBTUEsR0FDckVBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLEdBQUdBLFNBQVNBLEdBQUdBLE1BQU1BLENBQUNBO1FBR3ZFQSxPQUFPQSxDQUFDQSxHQUFHQSxDQUFDQSx1QkFBdUJBLEVBQUVBLGtCQUFrQkEsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFFL0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBRUZULDRCQUFDQTtBQUFEQSxDQTdJQSxBQTZJQ0EsRUE3SW1DLHVCQUF1QixFQTZJMUQ7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJGcmVzbmVsTWV0aG9kLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcblxuaW1wb3J0IFN0YWdlXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9iYXNlL1N0YWdlXCIpO1xuaW1wb3J0IE1ldGhvZFZPXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL01ldGhvZFZPXCIpO1xuaW1wb3J0IFNoYWRlckxpZ2h0aW5nT2JqZWN0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlckxpZ2h0aW5nT2JqZWN0XCIpO1xuaW1wb3J0IFNoYWRlck9iamVjdEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJPYmplY3RCYXNlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyQ2FjaGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJDYWNoZVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckRhdGFcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJEYXRhXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRWxlbWVudFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vU2hhZGVyUmVnaXN0ZXJFbGVtZW50XCIpO1xuaW1wb3J0IFNwZWN1bGFyQmFzaWNNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TcGVjdWxhckJhc2ljTWV0aG9kXCIpO1xuXG5pbXBvcnQgU3BlY3VsYXJDb21wb3NpdGVNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJDb21wb3NpdGVNZXRob2RcIik7XG5cbi8qKlxuICogU3BlY3VsYXJGcmVzbmVsTWV0aG9kIHByb3ZpZGVzIGEgc3BlY3VsYXIgc2hhZGluZyBtZXRob2QgdGhhdCBjYXVzZXMgc3Ryb25nZXIgaGlnaGxpZ2h0cyBvbiBncmF6aW5nIHZpZXcgYW5nbGVzLlxuICovXG5jbGFzcyBTcGVjdWxhckZyZXNuZWxNZXRob2QgZXh0ZW5kcyBTcGVjdWxhckNvbXBvc2l0ZU1ldGhvZFxue1xuXHRwcml2YXRlIF9kYXRhUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudDtcblx0cHJpdmF0ZSBfaW5jaWRlbnRMaWdodDpib29sZWFuO1xuXHRwcml2YXRlIF9mcmVzbmVsUG93ZXI6bnVtYmVyID0gNTtcblx0cHJpdmF0ZSBfbm9ybWFsUmVmbGVjdGFuY2U6bnVtYmVyID0gLjAyODsgLy8gZGVmYXVsdCB2YWx1ZSBmb3Igc2tpblxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IFNwZWN1bGFyRnJlc25lbE1ldGhvZCBvYmplY3QuXG5cdCAqIEBwYXJhbSBiYXNlZE9uU3VyZmFjZSBEZWZpbmVzIHdoZXRoZXIgdGhlIGZyZXNuZWwgZWZmZWN0IHNob3VsZCBiZSBiYXNlZCBvbiB0aGUgdmlldyBhbmdsZSBvbiB0aGUgc3VyZmFjZSAoaWYgdHJ1ZSksIG9yIG9uIHRoZSBhbmdsZSBiZXR3ZWVuIHRoZSBsaWdodCBhbmQgdGhlIHZpZXcuXG5cdCAqIEBwYXJhbSBiYXNlTWV0aG9kIFRoZSBzcGVjdWxhciBtZXRob2QgdG8gd2hpY2ggdGhlIGZyZXNuZWwgZXF1YXRpb24uIERlZmF1bHRzIHRvIFNwZWN1bGFyQmFzaWNNZXRob2QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihiYXNlZE9uU3VyZmFjZTpib29sZWFuID0gdHJ1ZSwgYmFzZU1ldGhvZDpTcGVjdWxhckJhc2ljTWV0aG9kID0gbnVsbClcblx0e1xuXHRcdC8vIG1heSB3YW50IHRvIG9mZmVyIGRpZmYgc3BlY3VsYXJzXG5cdFx0c3VwZXIobnVsbCwgYmFzZU1ldGhvZCk7XG5cblx0XHR0aGlzLmJhc2VNZXRob2QuX2lNb2R1bGF0ZU1ldGhvZCA9IChzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSkgPT4gdGhpcy5tb2R1bGF0ZVNwZWN1bGFyKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHRhcmdldFJlZywgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblxuXHRcdHRoaXMuX2luY2lkZW50TGlnaHQgPSAhYmFzZWRPblN1cmZhY2U7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBpSW5pdENvbnN0YW50cyhzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8pXG5cdHtcblxuXHRcdHZhciBpbmRleDpudW1iZXIgPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YVtpbmRleCArIDJdID0gMTtcblx0XHRzaGFkZXJPYmplY3QuZnJhZ21lbnRDb25zdGFudERhdGFbaW5kZXggKyAzXSA9IDA7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB3aGV0aGVyIHRoZSBmcmVzbmVsIGVmZmVjdCBzaG91bGQgYmUgYmFzZWQgb24gdGhlIHZpZXcgYW5nbGUgb24gdGhlIHN1cmZhY2UgKGlmIHRydWUpLCBvciBvbiB0aGUgYW5nbGUgYmV0d2VlbiB0aGUgbGlnaHQgYW5kIHRoZSB2aWV3LlxuXHQgKi9cblx0cHVibGljIGdldCBiYXNlZE9uU3VyZmFjZSgpOmJvb2xlYW5cblx0e1xuXHRcdHJldHVybiAhdGhpcy5faW5jaWRlbnRMaWdodDtcblx0fVxuXG5cdHB1YmxpYyBzZXQgYmFzZWRPblN1cmZhY2UodmFsdWU6Ym9vbGVhbilcblx0e1xuXHRcdGlmICh0aGlzLl9pbmNpZGVudExpZ2h0ICE9IHZhbHVlKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5faW5jaWRlbnRMaWdodCA9ICF2YWx1ZTtcblxuXHRcdHRoaXMuaUludmFsaWRhdGVTaGFkZXJQcm9ncmFtKCk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHBvd2VyIHVzZWQgaW4gdGhlIEZyZXNuZWwgZXF1YXRpb24uIEhpZ2hlciB2YWx1ZXMgbWFrZSB0aGUgZnJlc25lbCBlZmZlY3QgbW9yZSBwcm9ub3VuY2VkLiBEZWZhdWx0cyB0byA1LlxuXHQgKi9cblx0cHVibGljIGdldCBmcmVzbmVsUG93ZXIoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl9mcmVzbmVsUG93ZXI7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGZyZXNuZWxQb3dlcih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9mcmVzbmVsUG93ZXIgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlDbGVhbkNvbXBpbGF0aW9uRGF0YSgpXG5cdHtcblx0XHRzdXBlci5pQ2xlYW5Db21waWxhdGlvbkRhdGEoKTtcblx0XHR0aGlzLl9kYXRhUmVnID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgbWluaW11bSBhbW91bnQgb2YgcmVmbGVjdGFuY2UsIGllIHRoZSByZWZsZWN0YW5jZSB3aGVuIHRoZSB2aWV3IGRpcmVjdGlvbiBpcyBub3JtYWwgdG8gdGhlIHN1cmZhY2Ugb3IgbGlnaHQgZGlyZWN0aW9uLlxuXHQgKi9cblx0cHVibGljIGdldCBub3JtYWxSZWZsZWN0YW5jZSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX25vcm1hbFJlZmxlY3RhbmNlO1xuXHR9XG5cblx0cHVibGljIHNldCBub3JtYWxSZWZsZWN0YW5jZSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9ub3JtYWxSZWZsZWN0YW5jZSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUFjdGl2YXRlKHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIHN0YWdlOlN0YWdlKVxuXHR7XG5cdFx0c3VwZXIuaUFjdGl2YXRlKHNoYWRlck9iamVjdCwgbWV0aG9kVk8sIHN0YWdlKTtcblxuXHRcdHZhciBmcmFnbWVudERhdGE6QXJyYXk8bnVtYmVyPiA9IHNoYWRlck9iamVjdC5mcmFnbWVudENvbnN0YW50RGF0YTtcblxuXHRcdHZhciBpbmRleDpudW1iZXIgPSBtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4O1xuXHRcdGZyYWdtZW50RGF0YVtpbmRleF0gPSB0aGlzLl9ub3JtYWxSZWZsZWN0YW5jZTtcblx0XHRmcmFnbWVudERhdGFbaW5kZXggKyAxXSA9IHRoaXMuX2ZyZXNuZWxQb3dlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIGlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3Q6U2hhZGVyTGlnaHRpbmdPYmplY3QsIG1ldGhvZFZPOk1ldGhvZFZPLCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5fZGF0YVJlZyA9IHJlZ2lzdGVyQ2FjaGUuZ2V0RnJlZUZyYWdtZW50Q29uc3RhbnQoKTtcblxuXHRcdGNvbnNvbGUubG9nKCdTcGVjdWxhckZyZXNuZWxNZXRob2QnLCAnaUdldEZyYWdtZW50UHJlTGlnaHRpbmdDb2RlJywgdGhpcy5fZGF0YVJlZyk7XG5cblx0XHRtZXRob2RWTy5zZWNvbmRhcnlGcmFnbWVudENvbnN0YW50c0luZGV4ID0gdGhpcy5fZGF0YVJlZy5pbmRleCo0O1xuXG5cdFx0cmV0dXJuIHN1cGVyLmlHZXRGcmFnbWVudFByZUxpZ2h0aW5nQ29kZShzaGFkZXJPYmplY3QsIG1ldGhvZFZPLCByZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGxpZXMgdGhlIGZyZXNuZWwgZWZmZWN0IHRvIHRoZSBzcGVjdWxhciBzdHJlbmd0aC5cblx0ICpcblx0ICogQHBhcmFtIHZvIFRoZSBNZXRob2RWTyBvYmplY3QgY29udGFpbmluZyB0aGUgbWV0aG9kIGRhdGEgZm9yIHRoZSBjdXJyZW50bHkgY29tcGlsZWQgbWF0ZXJpYWwgcGFzcy5cblx0ICogQHBhcmFtIHRhcmdldCBUaGUgcmVnaXN0ZXIgY29udGFpbmluZyB0aGUgc3BlY3VsYXIgc3RyZW5ndGggaW4gdGhlIFwid1wiIGNvbXBvbmVudCwgYW5kIHRoZSBoYWxmLXZlY3Rvci9yZWZsZWN0aW9uIHZlY3RvciBpbiBcInh5elwiLlxuXHQgKiBAcGFyYW0gcmVnQ2FjaGUgVGhlIHJlZ2lzdGVyIGNhY2hlIHVzZWQgZm9yIHRoZSBzaGFkZXIgY29tcGlsYXRpb24uXG5cdCAqIEBwYXJhbSBzaGFyZWRSZWdpc3RlcnMgVGhlIHNoYXJlZCByZWdpc3RlcnMgY3JlYXRlZCBieSB0aGUgY29tcGlsZXIuXG5cdCAqIEByZXR1cm4gVGhlIEFHQUwgZnJhZ21lbnQgY29kZSBmb3IgdGhlIG1ldGhvZC5cblx0ICovXG5cdHByaXZhdGUgbW9kdWxhdGVTcGVjdWxhcihzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgbWV0aG9kVk86TWV0aG9kVk8sIHRhcmdldFJlZzpTaGFkZXJSZWdpc3RlckVsZW1lbnQsIHJlZ2lzdGVyQ2FjaGU6U2hhZGVyUmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzOlNoYWRlclJlZ2lzdGVyRGF0YSk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY29kZTpzdHJpbmc7XG5cblx0XHRjb2RlID0gXCJkcDMgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHNoYXJlZFJlZ2lzdGVycy52aWV3RGlyRnJhZ21lbnQgKyBcIi54eXosIFwiICsgKHRoaXMuX2luY2lkZW50TGlnaHQ/IHRhcmdldFJlZyA6IHNoYXJlZFJlZ2lzdGVycy5ub3JtYWxGcmFnbWVudCkgKyBcIi54eXpcXG5cIiArICAgLy8gZG90KFYsIEgpXG5cdFx0XHRcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGhpcy5fZGF0YVJlZyArIFwiLnosIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiICsgICAgICAgICAgICAgLy8gYmFzZSA9IDEtZG90KFYsIEgpXG5cdFx0XHRcInBvdyBcIiArIHRhcmdldFJlZyArIFwiLngsIFwiICsgdGFyZ2V0UmVnICsgXCIueSwgXCIgKyB0aGlzLl9kYXRhUmVnICsgXCIueVxcblwiICsgICAgICAgICAgICAgLy8gZXhwID0gcG93KGJhc2UsIDUpXG5cdFx0XHRcInN1YiBcIiArIHRhcmdldFJlZyArIFwiLnksIFwiICsgdGhpcy5fZGF0YVJlZyArIFwiLnosIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiICsgICAgICAgICAgICAgLy8gMSAtIGV4cFxuXHRcdFx0XCJtdWwgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRoaXMuX2RhdGFSZWcgKyBcIi54LCBcIiArIHRhcmdldFJlZyArIFwiLnlcXG5cIiArICAgICAgICAgICAgIC8vIGYwKigxIC0gZXhwKVxuXHRcdFx0XCJhZGQgXCIgKyB0YXJnZXRSZWcgKyBcIi55LCBcIiArIHRhcmdldFJlZyArIFwiLngsIFwiICsgdGFyZ2V0UmVnICsgXCIueVxcblwiICsgICAgICAgICAgLy8gZXhwICsgZjAqKDEgLSBleHApXG5cdFx0XHRcIm11bCBcIiArIHRhcmdldFJlZyArIFwiLncsIFwiICsgdGFyZ2V0UmVnICsgXCIudywgXCIgKyB0YXJnZXRSZWcgKyBcIi55XFxuXCI7XG5cblxuXHRcdGNvbnNvbGUubG9nKCdTcGVjdWxhckZyZXNuZWxNZXRob2QnLCAnbW9kdWxhdGVTcGVjdWxhcicsIGNvZGUpO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxufVxuXG5leHBvcnQgPSBTcGVjdWxhckZyZXNuZWxNZXRob2Q7Il19 \ No newline at end of file diff --git a/lib/materials/methods/SpecularFresnelMethod.ts b/lib/materials/methods/SpecularFresnelMethod.ts new file mode 100755 index 000000000..848414229 --- /dev/null +++ b/lib/materials/methods/SpecularFresnelMethod.ts @@ -0,0 +1,160 @@ +import Camera = require("awayjs-core/lib/entities/Camera"); + +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 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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); + +import SpecularCompositeMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCompositeMethod"); + +/** + * SpecularFresnelMethod provides a specular shading method that causes stronger highlights on grazing view angles. + */ +class SpecularFresnelMethod extends SpecularCompositeMethod +{ + private _dataReg:ShaderRegisterElement; + private _incidentLight:boolean; + private _fresnelPower:number = 5; + private _normalReflectance:number = .028; // default value for skin + + /** + * Creates a new SpecularFresnelMethod object. + * @param basedOnSurface Defines whether the fresnel effect should be based on the view angle on the surface (if true), or on the angle between the light and the view. + * @param baseMethod The specular method to which the fresnel equation. Defaults to SpecularBasicMethod. + */ + constructor(basedOnSurface:boolean = true, baseMethod:SpecularBasicMethod = null) + { + // may want to offer diff speculars + super(null, baseMethod); + + this.baseMethod._iModulateMethod = (shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData) => this.modulateSpecular(shaderObject, methodVO, targetReg, registerCache, sharedRegisters); + + this._incidentLight = !basedOnSurface; + } + + /** + * @inheritDoc + */ + public iInitConstants(shaderObject:ShaderObjectBase, methodVO:MethodVO) + { + + var index:number = methodVO.secondaryFragmentConstantsIndex; + shaderObject.fragmentConstantData[index + 2] = 1; + shaderObject.fragmentConstantData[index + 3] = 0; + } + + /** + * Defines whether the fresnel effect should be based on the view angle on the surface (if true), or on the angle between the light and the view. + */ + public get basedOnSurface():boolean + { + return !this._incidentLight; + } + + public set basedOnSurface(value:boolean) + { + if (this._incidentLight != value) + return; + + this._incidentLight = !value; + + this.iInvalidateShaderProgram(); + } + + /** + * The power used in the Fresnel equation. Higher values make the fresnel effect more pronounced. Defaults to 5. + */ + public get fresnelPower():number + { + return this._fresnelPower; + } + + public set fresnelPower(value:number) + { + this._fresnelPower = value; + } + + /** + * @inheritDoc + */ + public iCleanCompilationData() + { + super.iCleanCompilationData(); + this._dataReg = null; + } + + /** + * The minimum amount of reflectance, ie the reflectance when the view direction is normal to the surface or light direction. + */ + public get normalReflectance():number + { + return this._normalReflectance; + } + + public set normalReflectance(value:number) + { + this._normalReflectance = value; + } + + /** + * @inheritDoc + */ + public iActivate(shaderObject:ShaderLightingObject, methodVO:MethodVO, stage:Stage) + { + super.iActivate(shaderObject, methodVO, stage); + + var fragmentData:Array = shaderObject.fragmentConstantData; + + var index:number = methodVO.secondaryFragmentConstantsIndex; + fragmentData[index] = this._normalReflectance; + fragmentData[index + 1] = this._fresnelPower; + } + + /** + * @inheritDoc + */ + public iGetFragmentPreLightingCode(shaderObject:ShaderLightingObject, methodVO:MethodVO, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + this._dataReg = registerCache.getFreeFragmentConstant(); + + console.log('SpecularFresnelMethod', 'iGetFragmentPreLightingCode', this._dataReg); + + methodVO.secondaryFragmentConstantsIndex = this._dataReg.index*4; + + return super.iGetFragmentPreLightingCode(shaderObject, methodVO, registerCache, sharedRegisters); + } + + /** + * Applies the fresnel effect to the specular strength. + * + * @param vo The MethodVO object containing the method data for the currently compiled material pass. + * @param target The register containing the specular strength in the "w" component, and the half-vector/reflection vector in "xyz". + * @param regCache The register cache used for the shader compilation. + * @param sharedRegisters The shared registers created by the compiler. + * @return The AGAL fragment code for the method. + */ + private modulateSpecular(shaderObject:ShaderObjectBase, methodVO:MethodVO, targetReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string; + + code = "dp3 " + targetReg + ".y, " + sharedRegisters.viewDirFragment + ".xyz, " + (this._incidentLight? targetReg : sharedRegisters.normalFragment) + ".xyz\n" + // dot(V, H) + "sub " + targetReg + ".y, " + this._dataReg + ".z, " + targetReg + ".y\n" + // base = 1-dot(V, H) + "pow " + targetReg + ".x, " + targetReg + ".y, " + this._dataReg + ".y\n" + // exp = pow(base, 5) + "sub " + targetReg + ".y, " + this._dataReg + ".z, " + targetReg + ".y\n" + // 1 - exp + "mul " + targetReg + ".y, " + this._dataReg + ".x, " + targetReg + ".y\n" + // f0*(1 - exp) + "add " + targetReg + ".y, " + targetReg + ".x, " + targetReg + ".y\n" + // exp + f0*(1 - exp) + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".y\n"; + + + console.log('SpecularFresnelMethod', 'modulateSpecular', code); + + return code; + } + +} + +export = SpecularFresnelMethod; \ No newline at end of file diff --git a/lib/materials/methods/SpecularPhongMethod.js b/lib/materials/methods/SpecularPhongMethod.js new file mode 100755 index 000000000..c9244cec4 --- /dev/null +++ b/lib/materials/methods/SpecularPhongMethod.js @@ -0,0 +1,59 @@ +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +/** + * SpecularPhongMethod provides a specular method that provides Phong highlights. + */ +var SpecularPhongMethod = (function (_super) { + __extends(SpecularPhongMethod, _super); + /** + * Creates a new SpecularPhongMethod object. + */ + function SpecularPhongMethod() { + _super.call(this); + } + /** + * @inheritDoc + */ + SpecularPhongMethod.prototype.iGetFragmentCodePerLight = function (shaderObject, methodVO, lightDirReg, lightColReg, registerCache, sharedRegisters) { + var code = ""; + var t; + if (this._pIsFirstLight) { + t = this._pTotalLightColorReg; + } + else { + t = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(t, 1); + } + var viewDirReg = sharedRegisters.viewDirFragment; + var normalReg = sharedRegisters.normalFragment; + // phong model + code += "dp3 " + t + ".w, " + lightDirReg + ", " + normalReg + "\n" + "add " + t + ".w, " + t + ".w, " + t + ".w\n" + "mul " + t + ".xyz, " + normalReg + ", " + t + ".w\n" + "sub " + t + ".xyz, " + t + ", " + lightDirReg + "\n" + "add " + t + ".w, " + t + ".w, " + sharedRegisters.commons + ".w\n" + "sat " + t + ".w, " + t + ".w\n" + "mul " + t + ".xyz, " + t + ", " + t + ".w\n" + "dp3 " + t + ".w, " + t + ", " + viewDirReg + "\n" + "sat " + t + ".w, " + t + ".w\n"; + if (this._pUseTexture) { + // apply gloss modulation from texture + code += "mul " + this._pSpecularTexData + ".w, " + this._pSpecularTexData + ".y, " + this._pSpecularDataRegister + ".w\n" + "pow " + t + ".w, " + t + ".w, " + this._pSpecularTexData + ".w\n"; + } + else + code += "pow " + t + ".w, " + t + ".w, " + this._pSpecularDataRegister + ".w\n"; + // attenuate + if (shaderObject.usesLightFallOff) + code += "mul " + t + ".w, " + t + ".w, " + lightDirReg + ".w\n"; + if (this._iModulateMethod != null) + code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters); + code += "mul " + t + ".xyz, " + lightColReg + ".xyz, " + t + ".w\n"; + if (!this._pIsFirstLight) { + code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n"; + registerCache.removeFragmentTempUsage(t); + } + this._pIsFirstLight = false; + return code; + }; + return SpecularPhongMethod; +})(SpecularBasicMethod); +module.exports = SpecularPhongMethod; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tZXRob2RzL3NwZWN1bGFycGhvbmdtZXRob2QudHMiXSwibmFtZXMiOlsiU3BlY3VsYXJQaG9uZ01ldGhvZCIsIlNwZWN1bGFyUGhvbmdNZXRob2QuY29uc3RydWN0b3IiLCJTcGVjdWxhclBob25nTWV0aG9kLmlHZXRGcmFnbWVudENvZGVQZXJMaWdodCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBS0EsSUFBTyxtQkFBbUIsV0FBYywwREFBMEQsQ0FBQyxDQUFDO0FBRXBHLEFBR0E7O0dBREc7SUFDRyxtQkFBbUI7SUFBU0EsVUFBNUJBLG1CQUFtQkEsVUFBNEJBO0lBRXBEQTs7T0FFR0E7SUFDSEEsU0FMS0EsbUJBQW1CQTtRQU92QkMsaUJBQU9BLENBQUNBO0lBQ1RBLENBQUNBO0lBRUREOztPQUVHQTtJQUNJQSxzREFBd0JBLEdBQS9CQSxVQUFnQ0EsWUFBaUNBLEVBQUVBLFFBQWlCQSxFQUFFQSxXQUFpQ0EsRUFBRUEsV0FBaUNBLEVBQUVBLGFBQWlDQSxFQUFFQSxlQUFrQ0E7UUFFaE9FLElBQUlBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBQ3JCQSxJQUFJQSxDQUF1QkEsQ0FBQ0E7UUFFNUJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3pCQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLENBQUNBO1FBQy9CQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxDQUFDQSxHQUFHQSxhQUFhQSxDQUFDQSx5QkFBeUJBLEVBQUVBLENBQUNBO1lBQzlDQSxhQUFhQSxDQUFDQSxxQkFBcUJBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBQzNDQSxDQUFDQTtRQUVEQSxJQUFJQSxVQUFVQSxHQUF3QkEsZUFBZUEsQ0FBQ0EsZUFBZUEsQ0FBQ0E7UUFDdEVBLElBQUlBLFNBQVNBLEdBQXdCQSxlQUFlQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUVwRUEsQUFDQUEsY0FEY0E7UUFDZEEsSUFBSUEsSUFBSUEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FBR0EsV0FBV0EsR0FBR0EsSUFBSUEsR0FBR0EsU0FBU0EsR0FBR0EsSUFBSUEsR0FHbEVBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQzdDQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxHQUFHQSxTQUFTQSxHQUFHQSxJQUFJQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUNyREEsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsR0FBR0EsQ0FBQ0EsR0FBR0EsSUFBSUEsR0FBR0EsV0FBV0EsR0FBR0EsSUFBSUEsR0FHckRBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUVBLGVBQWVBLENBQUNBLE9BQU9BLEdBQUdBLE1BQU1BLEdBQ2xFQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUNoQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsR0FBR0EsUUFBUUEsR0FBR0EsQ0FBQ0EsR0FBR0EsSUFBSUEsR0FBR0EsQ0FBQ0EsR0FBR0EsTUFBTUEsR0FHN0NBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLElBQUlBLEdBQUdBLFVBQVVBLEdBQUdBLElBQUlBLEdBQ2xEQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUVsQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLEFBQ0FBLHNDQURzQ0E7WUFDdENBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxHQUFHQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxzQkFBc0JBLEdBQUdBLE1BQU1BLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFDaE1BLENBQUNBO1FBQUNBLElBQUlBO1lBQ0xBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLHNCQUFzQkEsR0FBR0EsTUFBTUEsQ0FBQ0E7UUFFakZBLEFBQ0FBLFlBRFlBO1FBQ1pBLEVBQUVBLENBQUNBLENBQUNBLFlBQVlBLENBQUNBLGdCQUFnQkEsQ0FBQ0E7WUFDakNBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLENBQUNBLEdBQUdBLE1BQU1BLEdBQUdBLFdBQVdBLEdBQUdBLE1BQU1BLENBQUNBO1FBRWpFQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLElBQUlBLElBQUlBLENBQUNBO1lBQ2pDQSxJQUFJQSxJQUFJQSxJQUFJQSxDQUFDQSxnQkFBZ0JBLENBQUNBLFlBQVlBLEVBQUVBLFFBQVFBLEVBQUVBLENBQUNBLEVBQUVBLGFBQWFBLEVBQUVBLGVBQWVBLENBQUNBLENBQUNBO1FBRTFGQSxJQUFJQSxJQUFJQSxNQUFNQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxHQUFHQSxXQUFXQSxHQUFHQSxRQUFRQSxHQUFHQSxDQUFDQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUVwRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDMUJBLElBQUlBLElBQUlBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLG9CQUFvQkEsR0FBR0EsUUFBUUEsR0FBR0EsSUFBSUEsQ0FBQ0Esb0JBQW9CQSxHQUFHQSxRQUFRQSxHQUFHQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUM1R0EsYUFBYUEsQ0FBQ0EsdUJBQXVCQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUMxQ0EsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsY0FBY0EsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFNUJBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBQ0ZGLDBCQUFDQTtBQUFEQSxDQXJFQSxBQXFFQ0EsRUFyRWlDLG1CQUFtQixFQXFFcEQ7QUFFRCxBQUE2QixpQkFBcEIsbUJBQW1CLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJQaG9uZ01ldGhvZC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNZXRob2RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9NZXRob2RWT1wiKTtcbmltcG9ydCBTaGFkZXJMaWdodGluZ09iamVjdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJMaWdodGluZ09iamVjdFwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckNhY2hlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyQ2FjaGVcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJEYXRhXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRGF0YVwiKTtcbmltcG9ydCBTaGFkZXJSZWdpc3RlckVsZW1lbnRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlclJlZ2lzdGVyRWxlbWVudFwiKTtcbmltcG9ydCBTcGVjdWxhckJhc2ljTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJCYXNpY01ldGhvZFwiKTtcblxuLyoqXG4gKiBTcGVjdWxhclBob25nTWV0aG9kIHByb3ZpZGVzIGEgc3BlY3VsYXIgbWV0aG9kIHRoYXQgcHJvdmlkZXMgUGhvbmcgaGlnaGxpZ2h0cy5cbiAqL1xuY2xhc3MgU3BlY3VsYXJQaG9uZ01ldGhvZCBleHRlbmRzIFNwZWN1bGFyQmFzaWNNZXRob2Rcbntcblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgU3BlY3VsYXJQaG9uZ01ldGhvZCBvYmplY3QuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgaUdldEZyYWdtZW50Q29kZVBlckxpZ2h0KHNoYWRlck9iamVjdDpTaGFkZXJMaWdodGluZ09iamVjdCwgbWV0aG9kVk86TWV0aG9kVk8sIGxpZ2h0RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCwgbGlnaHRDb2xSZWc6U2hhZGVyUmVnaXN0ZXJFbGVtZW50LCByZWdpc3RlckNhY2hlOlNoYWRlclJlZ2lzdGVyQ2FjaGUsIHNoYXJlZFJlZ2lzdGVyczpTaGFkZXJSZWdpc3RlckRhdGEpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgdDpTaGFkZXJSZWdpc3RlckVsZW1lbnQ7XG5cblx0XHRpZiAodGhpcy5fcElzRmlyc3RMaWdodCkge1xuXHRcdFx0dCA9IHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHQgPSByZWdpc3RlckNhY2hlLmdldEZyZWVGcmFnbWVudFZlY3RvclRlbXAoKTtcblx0XHRcdHJlZ2lzdGVyQ2FjaGUuYWRkRnJhZ21lbnRUZW1wVXNhZ2VzKHQsIDEpO1xuXHRcdH1cblxuXHRcdHZhciB2aWV3RGlyUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9c2hhcmVkUmVnaXN0ZXJzLnZpZXdEaXJGcmFnbWVudDtcblx0XHR2YXIgbm9ybWFsUmVnOlNoYWRlclJlZ2lzdGVyRWxlbWVudCA9c2hhcmVkUmVnaXN0ZXJzLm5vcm1hbEZyYWdtZW50O1xuXG5cdFx0Ly8gcGhvbmcgbW9kZWxcblx0XHRjb2RlICs9IFwiZHAzIFwiICsgdCArIFwiLncsIFwiICsgbGlnaHREaXJSZWcgKyBcIiwgXCIgKyBub3JtYWxSZWcgKyBcIlxcblwiICsgLy8gc2NhMSA9IGxpZ2h0Lm5vcm1hbFxuXG5cdFx0XHQvL2ZpbmQgdGhlIHJlZmxlY3RlZCBsaWdodCB2ZWN0b3IgUlxuXHRcdFx0XCJhZGQgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIud1xcblwiICsgLy8gc2NhMSA9IHNjYTEqMlxuXHRcdFx0XCJtdWwgXCIgKyB0ICsgXCIueHl6LCBcIiArIG5vcm1hbFJlZyArIFwiLCBcIiArIHQgKyBcIi53XFxuXCIgKyAvLyB2ZWMxID0gbm9ybWFsKnNjYTFcblx0XHRcdFwic3ViIFwiICsgdCArIFwiLnh5eiwgXCIgKyB0ICsgXCIsIFwiICsgbGlnaHREaXJSZWcgKyBcIlxcblwiICsgLy8gdmVjMSA9IHZlYzEgLSBsaWdodCAobGlnaHQgdmVjdG9yIGlzIG5lZ2F0aXZlKVxuXG5cdFx0XHQvL3Ntb290aCB0aGUgZWRnZSBhcyBpbmNpZGVuY2UgYW5nbGUgYXBwcm9hY2hlcyA5MFxuXHRcdFx0XCJhZGQgXCIgKyB0ICsgXCIudywgXCIgKyB0ICsgXCIudywgXCIgK3NoYXJlZFJlZ2lzdGVycy5jb21tb25zICsgXCIud1xcblwiICsgLy8gc2NhMSA9IHNjYTEgKyBzbW9vdGh0ZXA7XG5cdFx0XHRcInNhdCBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53XFxuXCIgKyAvLyBzY2ExIHJhbmdlIDAgLSAxXG5cdFx0XHRcIm11bCBcIiArIHQgKyBcIi54eXosIFwiICsgdCArIFwiLCBcIiArIHQgKyBcIi53XFxuXCIgKyAvLyB2ZWMxID0gdmVjMSpzY2ExXG5cblx0XHRcdC8vZmluZCB0aGUgZG90IHByb2R1Y3QgYmV0d2VlbiBSIGFuZCBWXG5cdFx0XHRcImRwMyBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIiwgXCIgKyB2aWV3RGlyUmVnICsgXCJcXG5cIiArIC8vIHNjYTEgPSB2ZWMxLnZpZXdcblx0XHRcdFwic2F0IFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLndcXG5cIjtcblxuXHRcdGlmICh0aGlzLl9wVXNlVGV4dHVyZSkge1xuXHRcdFx0Ly8gYXBwbHkgZ2xvc3MgbW9kdWxhdGlvbiBmcm9tIHRleHR1cmVcblx0XHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0aGlzLl9wU3BlY3VsYXJUZXhEYXRhICsgXCIudywgXCIgKyB0aGlzLl9wU3BlY3VsYXJUZXhEYXRhICsgXCIueSwgXCIgKyB0aGlzLl9wU3BlY3VsYXJEYXRhUmVnaXN0ZXIgKyBcIi53XFxuXCIgKyBcInBvdyBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53LCBcIiArIHRoaXMuX3BTcGVjdWxhclRleERhdGEgKyBcIi53XFxuXCI7XG5cdFx0fSBlbHNlXG5cdFx0XHRjb2RlICs9IFwicG93IFwiICsgdCArIFwiLncsIFwiICsgdCArIFwiLncsIFwiICsgdGhpcy5fcFNwZWN1bGFyRGF0YVJlZ2lzdGVyICsgXCIud1xcblwiO1xuXG5cdFx0Ly8gYXR0ZW51YXRlXG5cdFx0aWYgKHNoYWRlck9iamVjdC51c2VzTGlnaHRGYWxsT2ZmKVxuXHRcdFx0Y29kZSArPSBcIm11bCBcIiArIHQgKyBcIi53LCBcIiArIHQgKyBcIi53LCBcIiArIGxpZ2h0RGlyUmVnICsgXCIud1xcblwiO1xuXG5cdFx0aWYgKHRoaXMuX2lNb2R1bGF0ZU1ldGhvZCAhPSBudWxsKVxuXHRcdFx0Y29kZSArPSB0aGlzLl9pTW9kdWxhdGVNZXRob2Qoc2hhZGVyT2JqZWN0LCBtZXRob2RWTywgdCwgcmVnaXN0ZXJDYWNoZSwgc2hhcmVkUmVnaXN0ZXJzKTtcblxuXHRcdGNvZGUgKz0gXCJtdWwgXCIgKyB0ICsgXCIueHl6LCBcIiArIGxpZ2h0Q29sUmVnICsgXCIueHl6LCBcIiArIHQgKyBcIi53XFxuXCI7XG5cblx0XHRpZiAoIXRoaXMuX3BJc0ZpcnN0TGlnaHQpIHtcblx0XHRcdGNvZGUgKz0gXCJhZGQgXCIgKyB0aGlzLl9wVG90YWxMaWdodENvbG9yUmVnICsgXCIueHl6LCBcIiArIHRoaXMuX3BUb3RhbExpZ2h0Q29sb3JSZWcgKyBcIi54eXosIFwiICsgdCArIFwiLnh5elxcblwiO1xuXHRcdFx0cmVnaXN0ZXJDYWNoZS5yZW1vdmVGcmFnbWVudFRlbXBVc2FnZSh0KTtcblx0XHR9XG5cblx0XHR0aGlzLl9wSXNGaXJzdExpZ2h0ID0gZmFsc2U7XG5cblx0XHRyZXR1cm4gY29kZTtcblx0fVxufVxuXG5leHBvcnQgPSBTcGVjdWxhclBob25nTWV0aG9kOyJdfQ== \ No newline at end of file diff --git a/lib/materials/methods/SpecularPhongMethod.ts b/lib/materials/methods/SpecularPhongMethod.ts new file mode 100644 index 000000000..f41a05ee9 --- /dev/null +++ b/lib/materials/methods/SpecularPhongMethod.ts @@ -0,0 +1,82 @@ +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 SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); + +/** + * SpecularPhongMethod provides a specular method that provides Phong highlights. + */ +class SpecularPhongMethod extends SpecularBasicMethod +{ + /** + * Creates a new SpecularPhongMethod object. + */ + constructor() + { + super(); + } + + /** + * @inheritDoc + */ + public iGetFragmentCodePerLight(shaderObject:ShaderLightingObject, methodVO:MethodVO, lightDirReg:ShaderRegisterElement, lightColReg:ShaderRegisterElement, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + var t:ShaderRegisterElement; + + if (this._pIsFirstLight) { + t = this._pTotalLightColorReg; + } else { + t = registerCache.getFreeFragmentVectorTemp(); + registerCache.addFragmentTempUsages(t, 1); + } + + var viewDirReg:ShaderRegisterElement =sharedRegisters.viewDirFragment; + var normalReg:ShaderRegisterElement =sharedRegisters.normalFragment; + + // phong model + code += "dp3 " + t + ".w, " + lightDirReg + ", " + normalReg + "\n" + // sca1 = light.normal + + //find the reflected light vector R + "add " + t + ".w, " + t + ".w, " + t + ".w\n" + // sca1 = sca1*2 + "mul " + t + ".xyz, " + normalReg + ", " + t + ".w\n" + // vec1 = normal*sca1 + "sub " + t + ".xyz, " + t + ", " + lightDirReg + "\n" + // vec1 = vec1 - light (light vector is negative) + + //smooth the edge as incidence angle approaches 90 + "add " + t + ".w, " + t + ".w, " +sharedRegisters.commons + ".w\n" + // sca1 = sca1 + smoothtep; + "sat " + t + ".w, " + t + ".w\n" + // sca1 range 0 - 1 + "mul " + t + ".xyz, " + t + ", " + t + ".w\n" + // vec1 = vec1*sca1 + + //find the dot product between R and V + "dp3 " + t + ".w, " + t + ", " + viewDirReg + "\n" + // sca1 = vec1.view + "sat " + t + ".w, " + t + ".w\n"; + + if (this._pUseTexture) { + // apply gloss modulation from texture + code += "mul " + this._pSpecularTexData + ".w, " + this._pSpecularTexData + ".y, " + this._pSpecularDataRegister + ".w\n" + "pow " + t + ".w, " + t + ".w, " + this._pSpecularTexData + ".w\n"; + } else + code += "pow " + t + ".w, " + t + ".w, " + this._pSpecularDataRegister + ".w\n"; + + // attenuate + if (shaderObject.usesLightFallOff) + code += "mul " + t + ".w, " + t + ".w, " + lightDirReg + ".w\n"; + + if (this._iModulateMethod != null) + code += this._iModulateMethod(shaderObject, methodVO, t, registerCache, sharedRegisters); + + code += "mul " + t + ".xyz, " + lightColReg + ".xyz, " + t + ".w\n"; + + if (!this._pIsFirstLight) { + code += "add " + this._pTotalLightColorReg + ".xyz, " + this._pTotalLightColorReg + ".xyz, " + t + ".xyz\n"; + registerCache.removeFragmentTempUsage(t); + } + + this._pIsFirstLight = false; + + return code; + } +} + +export = SpecularPhongMethod; \ No newline at end of file diff --git a/lib/materials/passes/SingleObjectDepthPass.js b/lib/materials/passes/SingleObjectDepthPass.js new file mode 100755 index 000000000..44dac4493 --- /dev/null +++ b/lib/materials/passes/SingleObjectDepthPass.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 TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +var RenderTexture = require("awayjs-core/lib/textures/RenderTexture"); +var ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType"); +var MaterialPassBase = require("awayjs-stagegl/lib/materials/passes/MaterialPassBase"); +/** + * The SingleObjectDepthPass provides a material pass that renders a single object to a depth map from the point + * of view from a light. + */ +var SingleObjectDepthPass = (function (_super) { + __extends(SingleObjectDepthPass, _super); + /** + * Creates a new SingleObjectDepthPass object. + */ + function SingleObjectDepthPass() { + _super.call(this); + this._textureSize = 512; + this._polyOffset = Array(15, 0, 0, 0); + this._projectionTexturesInvalid = true; + //this._pNumUsedStreams = 2; + //this._pNumUsedVertexConstants = 7; + //this._enc = Array(1.0, 255.0, 65025.0, 16581375.0, 1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); + // + //this._pAnimatableAttributes = Array("va0", "va1"); + //this._pAnimationTargetRegisters = Array("vt0", "vt1"); + } + Object.defineProperty(SingleObjectDepthPass.prototype, "textureSize", { + /** + * The size of the depth map texture to render to. + */ + get: function () { + return this._textureSize; + }, + set: function (value) { + this._textureSize = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SingleObjectDepthPass.prototype, "polyOffset", { + /** + * The amount by which the rendered object will be inflated, to prevent depth map rounding errors. + */ + get: function () { + return this._polyOffset[0]; + }, + set: function (value) { + this._polyOffset[0] = value; + }, + enumerable: true, + configurable: true + }); + /** + * @inheritDoc + */ + SingleObjectDepthPass.prototype.dispose = function () { + if (this._textures) { + for (var key in this._textures) { + var texture = this._textures[key]; + texture.dispose(); + } + this._textures = null; + } + }; + /** + * Updates the projection textures used to contain the depth renders. + */ + SingleObjectDepthPass.prototype.updateProjectionTextures = function () { + if (this._textures) { + for (var key in this._textures) { + var texture = this._textures[key]; + texture.dispose(); + } + } + this._textures = new Object(); + this._projections = new Object(); + this._projectionTexturesInvalid = false; + }; + /** + * @inheritDoc + */ + SingleObjectDepthPass.prototype._iGetVertexCode = function () { + var code; + // offset + code = "mul vt7, vt1, vc4.x \n" + "add vt7, vt7, vt0\n" + "mov vt7.w, vt0.w\n"; + // project + code += "m44 vt2, vt7, vc0\n" + "mov op, vt2\n"; + // perspective divide + code += "div v0, vt2, vt2.w\n"; + return code; + }; + /** + * @inheritDoc + */ + SingleObjectDepthPass.prototype._iGetFragmentCode = function (shaderObject, registerCache, sharedRegisters) { + var code = ""; + // encode float -> rgba + code += "mul ft0, fc0, v0.z\n" + "frc ft0, ft0\n" + "mul ft1, ft0.yzww, fc1\n" + "sub ft0, ft0, ft1\n" + "mov oc, ft0\n"; + return code; + }; + /** + * Gets the depth maps rendered for this object from all lights. + * @param renderable The renderable for which to retrieve the depth maps. + * @param stage3DProxy The Stage3DProxy object currently used for rendering. + * @return A list of depth map textures for all supported lights. + */ + SingleObjectDepthPass.prototype._iGetDepthMap = function (renderable) { + return this._textures[renderable.materialOwner.id]; + }; + /** + * Retrieves the depth map projection maps for all lights. + * @param renderable The renderable for which to retrieve the projection maps. + * @return A list of projection maps for all supported lights. + */ + SingleObjectDepthPass.prototype._iGetProjection = function (renderable) { + return this._projections[renderable.materialOwner.id]; + }; + /** + * @inheritDoc + */ + SingleObjectDepthPass.prototype._iRender = function (pass, renderable, stage, camera, viewProjection) { + var matrix; + var context = stage.context; + var len /*uint*/; + var light; + var lights = this._pLightPicker.allPickedLights; + var rId = renderable.materialOwner.id; + if (!this._textures[rId]) + this._textures[rId] = new RenderTexture(this._textureSize, this._textureSize); + if (!this._projections[rId]) + this._projections[rId] = new Matrix3D(); + len = lights.length; + // local position = enough + light = lights[0]; + matrix = light.iGetObjectProjectionMatrix(renderable.sourceEntity, camera, this._projections[rId]); + context.setRenderTarget(this._textures[rId], true); + context.clear(1.0, 1.0, 1.0); + context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, matrix, true); + context.setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, 0, this._enc, 2); + context.activateBuffer(0, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT); + context.activateBuffer(1, renderable.getVertexData(TriangleSubGeometry.NORMAL_DATA), renderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT); + context.drawTriangles(context.getIndexBuffer(renderable.getIndexData()), 0, renderable.numTriangles); + }; + /** + * @inheritDoc + */ + SingleObjectDepthPass.prototype._iActivate = function (pass, stage, camera) { + if (this._projectionTexturesInvalid) + this.updateProjectionTextures(); + // never scale + _super.prototype._iActivate.call(this, pass, stage, camera); + stage.context.setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 4, this._polyOffset, 1); + }; + return SingleObjectDepthPass; +})(MaterialPassBase); +module.exports = SingleObjectDepthPass; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9wYXNzZXMvc2luZ2xlb2JqZWN0ZGVwdGhwYXNzLnRzIl0sIm5hbWVzIjpbIlNpbmdsZU9iamVjdERlcHRoUGFzcyIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5jb25zdHJ1Y3RvciIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy50ZXh0dXJlU2l6ZSIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5wb2x5T2Zmc2V0IiwiU2luZ2xlT2JqZWN0RGVwdGhQYXNzLmRpc3Bvc2UiLCJTaW5nbGVPYmplY3REZXB0aFBhc3MudXBkYXRlUHJvamVjdGlvblRleHR1cmVzIiwiU2luZ2xlT2JqZWN0RGVwdGhQYXNzLl9pR2V0VmVydGV4Q29kZSIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5faUdldEZyYWdtZW50Q29kZSIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5faUdldERlcHRoTWFwIiwiU2luZ2xlT2JqZWN0RGVwdGhQYXNzLl9pR2V0UHJvamVjdGlvbiIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5faVJlbmRlciIsIlNpbmdsZU9iamVjdERlcHRoUGFzcy5faUFjdGl2YXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxJQUFPLG1CQUFtQixXQUFjLCtDQUErQyxDQUFDLENBQUM7QUFDekYsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFHdEUsSUFBTyxhQUFhLFdBQWUsd0NBQXdDLENBQUMsQ0FBQztBQUs3RSxJQUFPLG9CQUFvQixXQUFjLHNEQUFzRCxDQUFDLENBQUM7QUFNakcsSUFBTyxnQkFBZ0IsV0FBZSxzREFBc0QsQ0FBQyxDQUFDO0FBRTlGLEFBSUE7OztHQURHO0lBQ0cscUJBQXFCO0lBQVNBLFVBQTlCQSxxQkFBcUJBLFVBQXlCQTtJQW1DbkRBOztPQUVHQTtJQUNIQSxTQXRDS0EscUJBQXFCQTtRQXdDekJDLGlCQUFPQSxDQUFDQTtRQXBDREEsaUJBQVlBLEdBQW1CQSxHQUFHQSxDQUFDQTtRQUNuQ0EsZ0JBQVdBLEdBQWlC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Q0FBQ0EsQ0FBQ0EsQ0FBQ0E7SUFDckhBLENBQUNBO0lBQ0ZYLDRCQUFDQTtBQUFEQSxDQTNMQSxBQTJMQ0EsRUEzTG1DLGdCQUFnQixFQTJMbkQ7QUFFRCxBQUErQixpQkFBdEIscUJBQXFCLENBQUMiLCJmaWxlIjoibWF0ZXJpYWxzL3Bhc3Nlcy9TaW5nbGVPYmplY3REZXB0aFBhc3MuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTGlnaHRCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9MaWdodEJhc2VcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9UcmlhbmdsZVN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IE1hdHJpeDNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeDNEXCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcbmltcG9ydCBNYXRlcmlhbEJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL01hdGVyaWFsQmFzZVwiKTtcbmltcG9ydCBSZW5kZXJUZXh0dXJlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9SZW5kZXJUZXh0dXJlXCIpO1xuXG5pbXBvcnQgU3RhZ2VcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL2Jhc2UvU3RhZ2VcIik7XG5pbXBvcnQgTWF0ZXJpYWxQYXNzRGF0YVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9wb29sL01hdGVyaWFsUGFzc0RhdGFcIik7XG5pbXBvcnQgUmVuZGVyYWJsZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcG9vbC9SZW5kZXJhYmxlQmFzZVwiKTtcbmltcG9ydCBDb250ZXh0R0xQcm9ncmFtVHlwZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9Db250ZXh0R0xQcm9ncmFtVHlwZVwiKTtcbmltcG9ydCBJQ29udGV4dFN0YWdlR0xcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvc3RhZ2VnbC9JQ29udGV4dFN0YWdlR0xcIik7XG5pbXBvcnQgTWV0aG9kVk9cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvY29tcGlsYXRpb24vTWV0aG9kVk9cIik7XG5pbXBvcnQgU2hhZGVyT2JqZWN0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL2NvbXBpbGF0aW9uL1NoYWRlck9iamVjdEJhc2VcIik7XG5pbXBvcnQgU2hhZGVyUmVnaXN0ZXJDYWNoZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckNhY2hlXCIpO1xuaW1wb3J0IFNoYWRlclJlZ2lzdGVyRGF0YVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9jb21waWxhdGlvbi9TaGFkZXJSZWdpc3RlckRhdGFcIik7XG5pbXBvcnQgTWF0ZXJpYWxQYXNzQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3Bhc3Nlcy9NYXRlcmlhbFBhc3NCYXNlXCIpO1xuXG4vKipcbiAqIFRoZSBTaW5nbGVPYmplY3REZXB0aFBhc3MgcHJvdmlkZXMgYSBtYXRlcmlhbCBwYXNzIHRoYXQgcmVuZGVycyBhIHNpbmdsZSBvYmplY3QgdG8gYSBkZXB0aCBtYXAgZnJvbSB0aGUgcG9pbnRcbiAqIG9mIHZpZXcgZnJvbSBhIGxpZ2h0LlxuICovXG5jbGFzcyBTaW5nbGVPYmplY3REZXB0aFBhc3MgZXh0ZW5kcyBNYXRlcmlhbFBhc3NCYXNlXG57XG5cdHByaXZhdGUgX3RleHR1cmVzOk9iamVjdDtcblx0cHJpdmF0ZSBfcHJvamVjdGlvbnM6T2JqZWN0O1xuXHRwcml2YXRlIF90ZXh0dXJlU2l6ZTpudW1iZXIgLyp1aW50Ki8gPSA1MTI7XG5cdHByaXZhdGUgX3BvbHlPZmZzZXQ6QXJyYXk8bnVtYmVyPiA9IEFycmF5PG51bWJlcj4oMTUsIDAsIDAsIDApO1xuXHRwcml2YXRlIF9lbmM6QXJyYXk8bnVtYmVyPjtcblx0cHJpdmF0ZSBfcHJvamVjdGlvblRleHR1cmVzSW52YWxpZDpCb29sZWFuID0gdHJ1ZTtcblxuXHQvKipcblx0ICogVGhlIHNpemUgb2YgdGhlIGRlcHRoIG1hcCB0ZXh0dXJlIHRvIHJlbmRlciB0by5cblx0ICovXG5cdHB1YmxpYyBnZXQgdGV4dHVyZVNpemUoKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiB0aGlzLl90ZXh0dXJlU2l6ZTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgdGV4dHVyZVNpemUodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5fdGV4dHVyZVNpemUgPSB2YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYW1vdW50IGJ5IHdoaWNoIHRoZSByZW5kZXJlZCBvYmplY3Qgd2lsbCBiZSBpbmZsYXRlZCwgdG8gcHJldmVudCBkZXB0aCBtYXAgcm91bmRpbmcgZXJyb3JzLlxuXHQgKi9cblx0cHVibGljIGdldCBwb2x5T2Zmc2V0KCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcG9seU9mZnNldFswXTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgcG9seU9mZnNldCh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl9wb2x5T2Zmc2V0WzBdID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBTaW5nbGVPYmplY3REZXB0aFBhc3Mgb2JqZWN0LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8vdGhpcy5fcE51bVVzZWRTdHJlYW1zID0gMjtcblx0XHQvL3RoaXMuX3BOdW1Vc2VkVmVydGV4Q29uc3RhbnRzID0gNztcblx0XHQvL3RoaXMuX2VuYyA9IEFycmF5PG51bWJlcj4oMS4wLCAyNTUuMCwgNjUwMjUuMCwgMTY1ODEzNzUuMCwgMS4wLzI1NS4wLCAxLjAvMjU1LjAsIDEuMC8yNTUuMCwgMC4wKTtcblx0XHQvL1xuXHRcdC8vdGhpcy5fcEFuaW1hdGFibGVBdHRyaWJ1dGVzID0gQXJyYXk8c3RyaW5nPihcInZhMFwiLCBcInZhMVwiKTtcblx0XHQvL3RoaXMuX3BBbmltYXRpb25UYXJnZXRSZWdpc3RlcnMgPSBBcnJheTxzdHJpbmc+KFwidnQwXCIsIFwidnQxXCIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgZGlzcG9zZSgpXG5cdHtcblx0XHRpZiAodGhpcy5fdGV4dHVyZXMpIHtcblx0XHRcdGZvciAodmFyIGtleSBpbiB0aGlzLl90ZXh0dXJlcykge1xuXHRcdFx0XHR2YXIgdGV4dHVyZTpSZW5kZXJUZXh0dXJlID0gdGhpcy5fdGV4dHVyZXNba2V5XTtcblx0XHRcdFx0dGV4dHVyZS5kaXNwb3NlKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl90ZXh0dXJlcyA9IG51bGw7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgdGhlIHByb2plY3Rpb24gdGV4dHVyZXMgdXNlZCB0byBjb250YWluIHRoZSBkZXB0aCByZW5kZXJzLlxuXHQgKi9cblx0cHJpdmF0ZSB1cGRhdGVQcm9qZWN0aW9uVGV4dHVyZXMoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3RleHR1cmVzKSB7XG5cdFx0XHRmb3IgKHZhciBrZXkgaW4gdGhpcy5fdGV4dHVyZXMpIHtcblx0XHRcdFx0dmFyIHRleHR1cmU6UmVuZGVyVGV4dHVyZSA9IHRoaXMuX3RleHR1cmVzW2tleV07XG5cdFx0XHRcdHRleHR1cmUuZGlzcG9zZSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuX3RleHR1cmVzID0gbmV3IE9iamVjdCgpO1xuXHRcdHRoaXMuX3Byb2plY3Rpb25zID0gbmV3IE9iamVjdCgpO1xuXHRcdHRoaXMuX3Byb2plY3Rpb25UZXh0dXJlc0ludmFsaWQgPSBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pR2V0VmVydGV4Q29kZSgpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNvZGU6c3RyaW5nO1xuXHRcdC8vIG9mZnNldFxuXHRcdGNvZGUgPSBcIm11bCB2dDcsIHZ0MSwgdmM0LnhcdFxcblwiICtcblx0XHRcdFx0XCJhZGQgdnQ3LCB2dDcsIHZ0MFxcblwiICtcblx0XHRcdFx0XCJtb3YgdnQ3LncsIHZ0MC53XFxuXCI7XG5cdFx0Ly8gcHJvamVjdFxuXHRcdGNvZGUgKz0gXCJtNDQgdnQyLCB2dDcsIHZjMFxcblwiICtcblx0XHRcdFx0XCJtb3Ygb3AsIHZ0MlxcblwiO1xuXG5cdFx0Ly8gcGVyc3BlY3RpdmUgZGl2aWRlXG5cdFx0Y29kZSArPSBcImRpdiB2MCwgdnQyLCB2dDIud1xcblwiO1xuXG5cdFx0cmV0dXJuIGNvZGU7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaUdldEZyYWdtZW50Q29kZShzaGFkZXJPYmplY3Q6U2hhZGVyT2JqZWN0QmFzZSwgcmVnaXN0ZXJDYWNoZTpTaGFkZXJSZWdpc3RlckNhY2hlLCBzaGFyZWRSZWdpc3RlcnM6U2hhZGVyUmVnaXN0ZXJEYXRhKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjb2RlOnN0cmluZyA9IFwiXCI7XG5cblx0XHQvLyBlbmNvZGUgZmxvYXQgLT4gcmdiYVxuXHRcdGNvZGUgKz0gXCJtdWwgZnQwLCBmYzAsIHYwLnpcXG5cIiArXG5cdFx0XHRcdFwiZnJjIGZ0MCwgZnQwXFxuXCIgK1xuXHRcdFx0XHRcIm11bCBmdDEsIGZ0MC55end3LCBmYzFcXG5cIiArXG5cdFx0XHRcdFwic3ViIGZ0MCwgZnQwLCBmdDFcXG5cIiArXG5cdFx0XHRcdFwibW92IG9jLCBmdDBcXG5cIjtcblxuXHRcdHJldHVybiBjb2RlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGRlcHRoIG1hcHMgcmVuZGVyZWQgZm9yIHRoaXMgb2JqZWN0IGZyb20gYWxsIGxpZ2h0cy5cblx0ICogQHBhcmFtIHJlbmRlcmFibGUgVGhlIHJlbmRlcmFibGUgZm9yIHdoaWNoIHRvIHJldHJpZXZlIHRoZSBkZXB0aCBtYXBzLlxuXHQgKiBAcGFyYW0gc3RhZ2UzRFByb3h5IFRoZSBTdGFnZTNEUHJveHkgb2JqZWN0IGN1cnJlbnRseSB1c2VkIGZvciByZW5kZXJpbmcuXG5cdCAqIEByZXR1cm4gQSBsaXN0IG9mIGRlcHRoIG1hcCB0ZXh0dXJlcyBmb3IgYWxsIHN1cHBvcnRlZCBsaWdodHMuXG5cdCAqL1xuXHRwdWJsaWMgX2lHZXREZXB0aE1hcChyZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlKTpSZW5kZXJUZXh0dXJlXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdGV4dHVyZXNbcmVuZGVyYWJsZS5tYXRlcmlhbE93bmVyLmlkXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIGRlcHRoIG1hcCBwcm9qZWN0aW9uIG1hcHMgZm9yIGFsbCBsaWdodHMuXG5cdCAqIEBwYXJhbSByZW5kZXJhYmxlIFRoZSByZW5kZXJhYmxlIGZvciB3aGljaCB0byByZXRyaWV2ZSB0aGUgcHJvamVjdGlvbiBtYXBzLlxuXHQgKiBAcmV0dXJuIEEgbGlzdCBvZiBwcm9qZWN0aW9uIG1hcHMgZm9yIGFsbCBzdXBwb3J0ZWQgbGlnaHRzLlxuXHQgKi9cblx0cHVibGljIF9pR2V0UHJvamVjdGlvbihyZW5kZXJhYmxlOlJlbmRlcmFibGVCYXNlKTpNYXRyaXgzRFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3Byb2plY3Rpb25zW3JlbmRlcmFibGUubWF0ZXJpYWxPd25lci5pZF07XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVJlbmRlcihwYXNzOk1hdGVyaWFsUGFzc0RhdGEsIHJlbmRlcmFibGU6UmVuZGVyYWJsZUJhc2UsIHN0YWdlOlN0YWdlLCBjYW1lcmE6Q2FtZXJhLCB2aWV3UHJvamVjdGlvbjpNYXRyaXgzRClcblx0e1xuXHRcdHZhciBtYXRyaXg6TWF0cml4M0Q7XG5cdFx0dmFyIGNvbnRleHQ6SUNvbnRleHRTdGFnZUdMID0gPElDb250ZXh0U3RhZ2VHTD4gc3RhZ2UuY29udGV4dDtcblx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgbGlnaHQ6TGlnaHRCYXNlO1xuXHRcdHZhciBsaWdodHM6QXJyYXk8TGlnaHRCYXNlPiA9IHRoaXMuX3BMaWdodFBpY2tlci5hbGxQaWNrZWRMaWdodHM7XG5cdFx0dmFyIHJJZDpudW1iZXIgPSByZW5kZXJhYmxlLm1hdGVyaWFsT3duZXIuaWQ7XG5cblx0XHRpZiAoIXRoaXMuX3RleHR1cmVzW3JJZF0pXG5cdFx0XHR0aGlzLl90ZXh0dXJlc1tySWRdID0gbmV3IFJlbmRlclRleHR1cmUodGhpcy5fdGV4dHVyZVNpemUsIHRoaXMuX3RleHR1cmVTaXplKTtcblxuXHRcdGlmICghdGhpcy5fcHJvamVjdGlvbnNbcklkXSlcblx0XHRcdHRoaXMuX3Byb2plY3Rpb25zW3JJZF0gPSBuZXcgTWF0cml4M0QoKTtcblxuXHRcdGxlbiA9IGxpZ2h0cy5sZW5ndGg7XG5cblx0XHQvLyBsb2NhbCBwb3NpdGlvbiA9IGVub3VnaFxuXHRcdGxpZ2h0ID0gbGlnaHRzWzBdO1xuXG5cdFx0bWF0cml4ID0gbGlnaHQuaUdldE9iamVjdFByb2plY3Rpb25NYXRyaXgocmVuZGVyYWJsZS5zb3VyY2VFbnRpdHksIGNhbWVyYSwgdGhpcy5fcHJvamVjdGlvbnNbcklkXSk7XG5cblx0XHRjb250ZXh0LnNldFJlbmRlclRhcmdldCh0aGlzLl90ZXh0dXJlc1tySWRdLCB0cnVlKTtcblx0XHRjb250ZXh0LmNsZWFyKDEuMCwgMS4wLCAxLjApO1xuXHRcdGNvbnRleHQuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21NYXRyaXgoQ29udGV4dEdMUHJvZ3JhbVR5cGUuVkVSVEVYLCAwLCBtYXRyaXgsIHRydWUpO1xuXHRcdGNvbnRleHQuc2V0UHJvZ3JhbUNvbnN0YW50c0Zyb21BcnJheShDb250ZXh0R0xQcm9ncmFtVHlwZS5GUkFHTUVOVCwgMCwgdGhpcy5fZW5jLCAyKTtcblxuXHRcdGNvbnRleHQuYWN0aXZhdGVCdWZmZXIoMCwgcmVuZGVyYWJsZS5nZXRWZXJ0ZXhEYXRhKFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fREFUQSksIHJlbmRlcmFibGUuZ2V0VmVydGV4T2Zmc2V0KFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fREFUQSksIFRyaWFuZ2xlU3ViR2VvbWV0cnkuUE9TSVRJT05fRk9STUFUKTtcblx0XHRjb250ZXh0LmFjdGl2YXRlQnVmZmVyKDEsIHJlbmRlcmFibGUuZ2V0VmVydGV4RGF0YShUcmlhbmdsZVN1Ykdlb21ldHJ5Lk5PUk1BTF9EQVRBKSwgcmVuZGVyYWJsZS5nZXRWZXJ0ZXhPZmZzZXQoVHJpYW5nbGVTdWJHZW9tZXRyeS5OT1JNQUxfREFUQSksIFRyaWFuZ2xlU3ViR2VvbWV0cnkuTk9STUFMX0ZPUk1BVCk7XG5cdFx0Y29udGV4dC5kcmF3VHJpYW5nbGVzKGNvbnRleHQuZ2V0SW5kZXhCdWZmZXIocmVuZGVyYWJsZS5nZXRJbmRleERhdGEoKSksIDAsIHJlbmRlcmFibGUubnVtVHJpYW5nbGVzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pQWN0aXZhdGUocGFzczpNYXRlcmlhbFBhc3NEYXRhLCBzdGFnZTpTdGFnZSwgY2FtZXJhOkNhbWVyYSlcblx0e1xuXHRcdGlmICh0aGlzLl9wcm9qZWN0aW9uVGV4dHVyZXNJbnZhbGlkKVxuXHRcdFx0dGhpcy51cGRhdGVQcm9qZWN0aW9uVGV4dHVyZXMoKTtcblxuXHRcdC8vIG5ldmVyIHNjYWxlXG5cdFx0c3VwZXIuX2lBY3RpdmF0ZShwYXNzLCBzdGFnZSwgY2FtZXJhKTtcblxuXHRcdCg8SUNvbnRleHRTdGFnZUdMPiBzdGFnZS5jb250ZXh0KS5zZXRQcm9ncmFtQ29uc3RhbnRzRnJvbUFycmF5KENvbnRleHRHTFByb2dyYW1UeXBlLlZFUlRFWCwgNCwgdGhpcy5fcG9seU9mZnNldCwgMSk7XG5cdH1cbn1cblxuZXhwb3J0ID0gU2luZ2xlT2JqZWN0RGVwdGhQYXNzOyJdfQ== \ No newline at end of file diff --git a/lib/materials/passes/SingleObjectDepthPass.ts b/lib/materials/passes/SingleObjectDepthPass.ts new file mode 100644 index 000000000..62006f4ea --- /dev/null +++ b/lib/materials/passes/SingleObjectDepthPass.ts @@ -0,0 +1,212 @@ +import LightBase = require("awayjs-core/lib/core/base/LightBase"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +import Camera = require("awayjs-core/lib/entities/Camera"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); +import RenderTexture = require("awayjs-core/lib/textures/RenderTexture"); + +import Stage = require("awayjs-stagegl/lib/core/base/Stage"); +import MaterialPassData = require("awayjs-stagegl/lib/core/pool/MaterialPassData"); +import RenderableBase = require("awayjs-stagegl/lib/core/pool/RenderableBase"); +import ContextGLProgramType = require("awayjs-stagegl/lib/core/stagegl/ContextGLProgramType"); +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 MaterialPassBase = require("awayjs-stagegl/lib/materials/passes/MaterialPassBase"); + +/** + * The SingleObjectDepthPass provides a material pass that renders a single object to a depth map from the point + * of view from a light. + */ +class SingleObjectDepthPass extends MaterialPassBase +{ + private _textures:Object; + private _projections:Object; + private _textureSize:number /*uint*/ = 512; + private _polyOffset:Array = Array(15, 0, 0, 0); + private _enc:Array; + private _projectionTexturesInvalid:Boolean = true; + + /** + * The size of the depth map texture to render to. + */ + public get textureSize():number + { + return this._textureSize; + } + + public set textureSize(value:number) + { + this._textureSize = value; + } + + /** + * The amount by which the rendered object will be inflated, to prevent depth map rounding errors. + */ + public get polyOffset():number + { + return this._polyOffset[0]; + } + + public set polyOffset(value:number) + { + this._polyOffset[0] = value; + } + + /** + * Creates a new SingleObjectDepthPass object. + */ + constructor() + { + super(); + + //this._pNumUsedStreams = 2; + //this._pNumUsedVertexConstants = 7; + //this._enc = Array(1.0, 255.0, 65025.0, 16581375.0, 1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); + // + //this._pAnimatableAttributes = Array("va0", "va1"); + //this._pAnimationTargetRegisters = Array("vt0", "vt1"); + } + + /** + * @inheritDoc + */ + public dispose() + { + if (this._textures) { + for (var key in this._textures) { + var texture:RenderTexture = this._textures[key]; + texture.dispose(); + } + this._textures = null; + } + } + + /** + * Updates the projection textures used to contain the depth renders. + */ + private updateProjectionTextures() + { + if (this._textures) { + for (var key in this._textures) { + var texture:RenderTexture = this._textures[key]; + texture.dispose(); + } + } + + this._textures = new Object(); + this._projections = new Object(); + this._projectionTexturesInvalid = false; + } + + /** + * @inheritDoc + */ + public _iGetVertexCode():string + { + var code:string; + // offset + code = "mul vt7, vt1, vc4.x \n" + + "add vt7, vt7, vt0\n" + + "mov vt7.w, vt0.w\n"; + // project + code += "m44 vt2, vt7, vc0\n" + + "mov op, vt2\n"; + + // perspective divide + code += "div v0, vt2, vt2.w\n"; + + return code; + } + + /** + * @inheritDoc + */ + public _iGetFragmentCode(shaderObject:ShaderObjectBase, registerCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):string + { + var code:string = ""; + + // encode float -> rgba + code += "mul ft0, fc0, v0.z\n" + + "frc ft0, ft0\n" + + "mul ft1, ft0.yzww, fc1\n" + + "sub ft0, ft0, ft1\n" + + "mov oc, ft0\n"; + + return code; + } + + /** + * Gets the depth maps rendered for this object from all lights. + * @param renderable The renderable for which to retrieve the depth maps. + * @param stage3DProxy The Stage3DProxy object currently used for rendering. + * @return A list of depth map textures for all supported lights. + */ + public _iGetDepthMap(renderable:RenderableBase):RenderTexture + { + return this._textures[renderable.materialOwner.id]; + } + + /** + * Retrieves the depth map projection maps for all lights. + * @param renderable The renderable for which to retrieve the projection maps. + * @return A list of projection maps for all supported lights. + */ + public _iGetProjection(renderable:RenderableBase):Matrix3D + { + return this._projections[renderable.materialOwner.id]; + } + + /** + * @inheritDoc + */ + public _iRender(pass:MaterialPassData, renderable:RenderableBase, stage:Stage, camera:Camera, viewProjection:Matrix3D) + { + var matrix:Matrix3D; + var context:IContextStageGL = stage.context; + var len:number /*uint*/; + var light:LightBase; + var lights:Array = this._pLightPicker.allPickedLights; + var rId:number = renderable.materialOwner.id; + + if (!this._textures[rId]) + this._textures[rId] = new RenderTexture(this._textureSize, this._textureSize); + + if (!this._projections[rId]) + this._projections[rId] = new Matrix3D(); + + len = lights.length; + + // local position = enough + light = lights[0]; + + matrix = light.iGetObjectProjectionMatrix(renderable.sourceEntity, camera, this._projections[rId]); + + context.setRenderTarget(this._textures[rId], true); + context.clear(1.0, 1.0, 1.0); + context.setProgramConstantsFromMatrix(ContextGLProgramType.VERTEX, 0, matrix, true); + context.setProgramConstantsFromArray(ContextGLProgramType.FRAGMENT, 0, this._enc, 2); + + context.activateBuffer(0, renderable.getVertexData(TriangleSubGeometry.POSITION_DATA), renderable.getVertexOffset(TriangleSubGeometry.POSITION_DATA), TriangleSubGeometry.POSITION_FORMAT); + context.activateBuffer(1, renderable.getVertexData(TriangleSubGeometry.NORMAL_DATA), renderable.getVertexOffset(TriangleSubGeometry.NORMAL_DATA), TriangleSubGeometry.NORMAL_FORMAT); + context.drawTriangles(context.getIndexBuffer(renderable.getIndexData()), 0, renderable.numTriangles); + } + + /** + * @inheritDoc + */ + public _iActivate(pass:MaterialPassData, stage:Stage, camera:Camera) + { + if (this._projectionTexturesInvalid) + this.updateProjectionTextures(); + + // never scale + super._iActivate(pass, stage, camera); + + ( stage.context).setProgramConstantsFromArray(ContextGLProgramType.VERTEX, 4, this._polyOffset, 1); + } +} + +export = SingleObjectDepthPass; \ No newline at end of file diff --git a/lib/parsers/AWDParser.js b/lib/parsers/AWDParser.js new file mode 100755 index 000000000..22d460026 --- /dev/null +++ b/lib/parsers/AWDParser.js @@ -0,0 +1,2202 @@ +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 DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var BlendMode = require("awayjs-core/lib/core/base/BlendMode"); +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform"); +var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +var PointLight = require("awayjs-core/lib/entities/PointLight"); +var Camera = require("awayjs-core/lib/entities/Camera"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +var Skybox = require("awayjs-core/lib/entities/Skybox"); +var StaticLightPicker = require("awayjs-core/lib/materials/lightpickers/StaticLightPicker"); +var CubeMapShadowMapper = require("awayjs-core/lib/materials/shadowmappers/CubeMapShadowMapper"); +var DirectionalShadowMapper = require("awayjs-core/lib/materials/shadowmappers/DirectionalShadowMapper"); +var PrefabBase = require("awayjs-core/lib/prefabs/PrefabBase"); +var PrimitiveCapsulePrefab = require("awayjs-core/lib/prefabs/PrimitiveCapsulePrefab"); +var PrimitiveConePrefab = require("awayjs-core/lib/prefabs/PrimitiveConePrefab"); +var PrimitiveCubePrefab = require("awayjs-core/lib/prefabs/PrimitiveCubePrefab"); +var PrimitiveCylinderPrefab = require("awayjs-core/lib/prefabs/PrimitiveCylinderPrefab"); +var PrimitivePlanePrefab = require("awayjs-core/lib/prefabs/PrimitivePlanePrefab"); +var PrimitiveSpherePrefab = require("awayjs-core/lib/prefabs/PrimitiveSpherePrefab"); +var PrimitiveTorusPrefab = require("awayjs-core/lib/prefabs/PrimitiveTorusPrefab"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +var PerspectiveProjection = require("awayjs-core/lib/projections/PerspectiveProjection"); +var OrthographicProjection = require("awayjs-core/lib/projections/OrthographicProjection"); +var OrthographicOffCenterProjection = require("awayjs-core/lib/projections/OrthographicOffCenterProjection"); +var BitmapCubeTexture = require("awayjs-core/lib/textures/BitmapCubeTexture"); +var ImageCubeTexture = require("awayjs-core/lib/textures/ImageCubeTexture"); +var ImageTexture = require("awayjs-core/lib/textures/ImageTexture"); +var ByteArray = require("awayjs-core/lib/utils/ByteArray"); +var SkyboxMaterial = require("awayjs-stagegl/lib/materials/SkyboxMaterial"); +var TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +var VertexAnimationSet = require("awayjs-renderergl/lib/animators/VertexAnimationSet"); +var VertexAnimator = require("awayjs-renderergl/lib/animators/VertexAnimator"); +var SkeletonAnimationSet = require("awayjs-renderergl/lib/animators/SkeletonAnimationSet"); +var SkeletonAnimator = require("awayjs-renderergl/lib/animators/SkeletonAnimator"); +var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose"); +var Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton"); +var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose"); +var SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint"); +var SkeletonClipNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonClipNode"); +var VertexClipNode = require("awayjs-renderergl/lib/animators/nodes/VertexClipNode"); +var AmbientEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/AmbientEnvMapMethod"); +var DiffuseDepthMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseDepthMethod"); +var DiffuseCelMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCelMethod"); +var DiffuseGradientMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseGradientMethod"); +var DiffuseLightMapMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseLightMapMethod"); +var DiffuseWrapMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseWrapMethod"); +var EffectAlphaMaskMethod = require("awayjs-renderergl/lib/materials/methods/EffectAlphaMaskMethod"); +var EffectColorMatrixMethod = require("awayjs-renderergl/lib/materials/methods/EffectColorMatrixMethod"); +var EffectColorTransformMethod = require("awayjs-stagegl/lib/materials/methods/EffectColorTransformMethod"); +var EffectEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectEnvMapMethod"); +var EffectFogMethod = require("awayjs-renderergl/lib/materials/methods/EffectFogMethod"); +var EffectFresnelEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectFresnelEnvMapMethod"); +var EffectLightMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectLightMapMethod"); +var EffectRimLightMethod = require("awayjs-renderergl/lib/materials/methods/EffectRimLightMethod"); +var NormalSimpleWaterMethod = require("awayjs-renderergl/lib/materials/methods/NormalSimpleWaterMethod"); +var ShadowDitheredMethod = require("awayjs-renderergl/lib/materials/methods/ShadowDitheredMethod"); +var ShadowFilteredMethod = require("awayjs-renderergl/lib/materials/methods/ShadowFilteredMethod"); +var SpecularFresnelMethod = require("awayjs-renderergl/lib/materials/methods/SpecularFresnelMethod"); +var ShadowHardMethod = require("awayjs-stagegl/lib/materials/methods/ShadowHardMethod"); +var SpecularAnisotropicMethod = require("awayjs-renderergl/lib/materials/methods/SpecularAnisotropicMethod"); +var SpecularCelMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCelMethod"); +var SpecularPhongMethod = require("awayjs-renderergl/lib/materials/methods/SpecularPhongMethod"); +var ShadowNearMethod = require("awayjs-renderergl/lib/materials/methods/ShadowNearMethod"); +var ShadowSoftMethod = require("awayjs-renderergl/lib/materials/methods/ShadowSoftMethod"); +var AWDBlock = require("awayjs-renderergl/lib/parsers/data/AWDBlock"); +var AWDProperties = require("awayjs-renderergl/lib/parsers/data/AWDProperties"); +var BitFlags = require("awayjs-renderergl/lib/parsers/data/BitFlags"); +/** + * AWDParser provides a parser for the AWD data type. + */ +var AWDParser = (function (_super) { + __extends(AWDParser, _super); + /** + * Creates a new AWDParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + function AWDParser() { + _super.call(this, URLLoaderDataFormat.ARRAY_BUFFER); + //set to "true" to have some console.logs in the Console + this._debug = false; + this._startedParsing = false; + this._texture_users = {}; + this._parsed_header = false; + this._blocks = new Array(); + this._blocks[0] = new AWDBlock(); + this._blocks[0].data = null; // Zero address means null in AWD + this.blendModeDic = new Array(); // used to translate ints to blendMode-strings + this.blendModeDic.push(BlendMode.NORMAL); + this.blendModeDic.push(BlendMode.ADD); + this.blendModeDic.push(BlendMode.ALPHA); + this.blendModeDic.push(BlendMode.DARKEN); + this.blendModeDic.push(BlendMode.DIFFERENCE); + this.blendModeDic.push(BlendMode.ERASE); + this.blendModeDic.push(BlendMode.HARDLIGHT); + this.blendModeDic.push(BlendMode.INVERT); + this.blendModeDic.push(BlendMode.LAYER); + this.blendModeDic.push(BlendMode.LIGHTEN); + this.blendModeDic.push(BlendMode.MULTIPLY); + this.blendModeDic.push(BlendMode.NORMAL); + this.blendModeDic.push(BlendMode.OVERLAY); + this.blendModeDic.push(BlendMode.SCREEN); + this.blendModeDic.push(BlendMode.SHADER); + this.blendModeDic.push(BlendMode.OVERLAY); + this._depthSizeDic = new Array(); // used to translate ints to depthSize-values + this._depthSizeDic.push(256); + this._depthSizeDic.push(512); + this._depthSizeDic.push(2048); + this._depthSizeDic.push(1024); + this._version = Array(); // will contain 2 int (major-version, minor-version) for awd-version-check + } + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + AWDParser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "awd"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + AWDParser.supportsData = function (data) { + return (ParserUtils.toString(data, 3) == 'AWD'); + }; + /** + * @inheritDoc + */ + AWDParser.prototype._iResolveDependency = function (resourceDependency) { + // this will be called when Dependency has finished loading. + // the Assets waiting for this Bitmap, can be Texture or CubeTexture. + // if the Bitmap is awaited by a CubeTexture, we need to check if its the last Bitmap of the CubeTexture, + // so we know if we have to finalize the Asset (CubeTexture) or not. + if (resourceDependency.assets.length == 1) { + var isCubeTextureArray = resourceDependency.id.split("#"); + var ressourceID = isCubeTextureArray[0]; + var asset; + var thisBitmapTexture; + var block; + if (isCubeTextureArray.length == 1) { + asset = resourceDependency.assets[0]; + if (asset) { + var mat; + var users; + block = this._blocks[resourceDependency.id]; + block.data = asset; // Store finished asset + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + block.name = asset.name; + // Finalize texture asset to dispatch texture event, which was + // previously suppressed while the dependency was loaded. + this._pFinalizeAsset(asset); + if (this._debug) { + console.log("Successfully loaded Bitmap for texture"); + console.log("Parsed texture: Name = " + block.name); + } + } + } + if (isCubeTextureArray.length > 1) { + thisBitmapTexture = resourceDependency.assets[0]; + var tx = thisBitmapTexture; + this._cubeTextures[isCubeTextureArray[1]] = tx.htmlImageElement; // ? + this._texture_users[ressourceID].push(1); + if (this._debug) { + console.log("Successfully loaded Bitmap " + this._texture_users[ressourceID].length + " / 6 for Cubetexture"); + } + if (this._texture_users[ressourceID].length == this._cubeTextures.length) { + var posX = this._cubeTextures[0]; + var negX = this._cubeTextures[1]; + var posY = this._cubeTextures[2]; + var negY = this._cubeTextures[3]; + var posZ = this._cubeTextures[4]; + var negZ = this._cubeTextures[5]; + asset = new ImageCubeTexture(posX, negX, posY, negY, posZ, negZ); + block = this._blocks[ressourceID]; + block.data = asset; // Store finished asset + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + block.name = asset.name; + // Finalize texture asset to dispatch texture event, which was + // previously suppressed while the dependency was loaded. + this._pFinalizeAsset(asset); + if (this._debug) { + console.log("Parsed CubeTexture: Name = " + block.name); + } + } + } + } + }; + /** + * @inheritDoc + */ + AWDParser.prototype._iResolveDependencyFailure = function (resourceDependency) { + //not used - if a dependcy fails, the awaiting Texture or CubeTexture will never be finalized, and the default-bitmaps will be used. + // this means, that if one Bitmap of a CubeTexture fails, the CubeTexture will have the DefaultTexture applied for all six Bitmaps. + }; + /** + * Resolve a dependency name + * + * @param resourceDependency The dependency to be resolved. + */ + AWDParser.prototype._iResolveDependencyName = function (resourceDependency, asset) { + var oldName = asset.name; + if (asset) { + var block = this._blocks[parseInt(resourceDependency.id)]; + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + } + var newName = asset.name; + asset.name = oldName; + return newName; + }; + /** + * @inheritDoc + */ + AWDParser.prototype._pProceedParsing = function () { + if (!this._startedParsing) { + this._byteData = this._pGetByteData(); //getByteData(); + this._startedParsing = true; + } + if (!this._parsed_header) { + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN; + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + // Parse header and decompress body if needed + this.parseHeader(); + switch (this._compression) { + case AWDParser.DEFLATE: + case AWDParser.LZMA: + this._pDieWithError('Compressed AWD formats not yet supported'); + break; + case AWDParser.UNCOMPRESSED: + this._body = this._byteData; + break; + } + this._parsed_header = true; + } + if (this._body) { + while (this._body.getBytesAvailable() > 0 && !this.parsingPaused) { + this.parseNextBlock(); + } + //---------------------------------------------------------------------------- + // Return complete status + if (this._body.getBytesAvailable() == 0) { + this.dispose(); + return ParserBase.PARSING_DONE; + } + else { + return ParserBase.MORE_TO_PARSE; + } + } + else { + switch (this._compression) { + case AWDParser.DEFLATE: + case AWDParser.LZMA: + if (this._debug) { + console.log("(!) AWDParser Error: Compressed AWD formats not yet supported (!)"); + } + break; + } + // Error - most likely _body not set because we do not support compression. + return ParserBase.PARSING_DONE; + } + }; + AWDParser.prototype._pStartParsing = function (frameLimit) { + _super.prototype._pStartParsing.call(this, frameLimit); + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + }; + AWDParser.prototype.dispose = function () { + for (var c in this._blocks) { + var b = this._blocks[c]; + b.dispose(); + } + }; + AWDParser.prototype.parseNextBlock = function () { + var block; + var assetData; + var isParsed = false; + var ns; + var type; + var flags; + var len; + this._cur_block_id = this._body.readUnsignedInt(); + ns = this._body.readUnsignedByte(); + type = this._body.readUnsignedByte(); + flags = this._body.readUnsignedByte(); + len = this._body.readUnsignedInt(); + var blockCompression = BitFlags.test(flags, BitFlags.FLAG4); + var blockCompressionLZMA = BitFlags.test(flags, BitFlags.FLAG5); + if (this._accuracyOnBlocks) { + this._accuracyMatrix = BitFlags.test(flags, BitFlags.FLAG1); + this._accuracyGeo = BitFlags.test(flags, BitFlags.FLAG2); + this._accuracyProps = BitFlags.test(flags, BitFlags.FLAG3); + this._geoNrType = AWDParser.FLOAT32; + if (this._accuracyGeo) { + this._geoNrType = AWDParser.FLOAT64; + } + this._matrixNrType = AWDParser.FLOAT32; + if (this._accuracyMatrix) { + this._matrixNrType = AWDParser.FLOAT64; + } + this._propsNrType = AWDParser.FLOAT32; + if (this._accuracyProps) { + this._propsNrType = AWDParser.FLOAT64; + } + } + var blockEndAll = this._body.position + len; + if (len > this._body.getBytesAvailable()) { + this._pDieWithError('AWD2 block length is bigger than the bytes that are available!'); + this._body.position += this._body.getBytesAvailable(); + return; + } + this._newBlockBytes = new ByteArray(); + this._body.readBytes(this._newBlockBytes, 0, len); + //---------------------------------------------------------------------------- + // Compressed AWD Formats not yet supported + if (blockCompression) { + this._pDieWithError('Compressed AWD formats not yet supported'); + } + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._newBlockBytes.endian = Endian.LITTLE_ENDIAN; + //---------------------------------------------------------------------------- + this._newBlockBytes.position = 0; + block = new AWDBlock(); + block.len = this._newBlockBytes.position + len; + block.id = this._cur_block_id; + var blockEndBlock = this._newBlockBytes.position + len; + if (blockCompression) { + this._pDieWithError('Compressed AWD formats not yet supported'); + } + if (this._debug) { + console.log("AWDBlock: ID = " + this._cur_block_id + " | TypeID = " + type + " | Compression = " + blockCompression + " | Matrix-Precision = " + this._accuracyMatrix + " | Geometry-Precision = " + this._accuracyGeo + " | Properties-Precision = " + this._accuracyProps); + } + this._blocks[this._cur_block_id] = block; + if ((this._version[0] == 2) && (this._version[1] == 1)) { + switch (type) { + case 11: + this.parsePrimitves(this._cur_block_id); + isParsed = true; + break; + case 31: + this.parseSkyboxInstance(this._cur_block_id); + isParsed = true; + break; + case 41: + this.parseLight(this._cur_block_id); + isParsed = true; + break; + case 42: + this.parseCamera(this._cur_block_id); + isParsed = true; + break; + case 51: + this.parseLightPicker(this._cur_block_id); + isParsed = true; + break; + case 81: + this.parseMaterial_v1(this._cur_block_id); + isParsed = true; + break; + case 83: + this.parseCubeTexture(this._cur_block_id); + isParsed = true; + break; + case 91: + this.parseSharedMethodBlock(this._cur_block_id); + isParsed = true; + break; + case 92: + this.parseShadowMethodBlock(this._cur_block_id); + isParsed = true; + break; + case 111: + this.parseMeshPoseAnimation(this._cur_block_id, true); + isParsed = true; + break; + case 112: + this.parseMeshPoseAnimation(this._cur_block_id); + isParsed = true; + break; + case 113: + this.parseVertexAnimationSet(this._cur_block_id); + isParsed = true; + break; + case 122: + this.parseAnimatorSet(this._cur_block_id); + isParsed = true; + break; + case 253: + this.parseCommand(this._cur_block_id); + isParsed = true; + break; + } + } + //* + if (isParsed == false) { + switch (type) { + case 1: + this.parseTriangleGeometrieBlock(this._cur_block_id); + break; + case 22: + this.parseContainer(this._cur_block_id); + break; + case 23: + this.parseMeshInstance(this._cur_block_id); + break; + case 81: + this.parseMaterial(this._cur_block_id); + break; + case 82: + this.parseTexture(this._cur_block_id); + break; + case 101: + this.parseSkeleton(this._cur_block_id); + break; + case 102: + this.parseSkeletonPose(this._cur_block_id); + break; + case 103: + this.parseSkeletonAnimation(this._cur_block_id); + break; + case 121: + case 254: + this.parseNameSpace(this._cur_block_id); + break; + case 255: + this.parseMetaData(this._cur_block_id); + break; + default: + if (this._debug) { + console.log("AWDBlock: Unknown BlockType (BlockID = " + this._cur_block_id + ") - Skip " + len + " bytes"); + } + this._newBlockBytes.position += len; + break; + } + } + //*/ + var msgCnt = 0; + if (this._newBlockBytes.position == blockEndBlock) { + if (this._debug) { + if (block.errorMessages) { + while (msgCnt < block.errorMessages.length) { + console.log(" (!) Error: " + block.errorMessages[msgCnt] + " (!)"); + msgCnt++; + } + } + } + if (this._debug) { + console.log("\n"); + } + } + else { + if (this._debug) { + console.log(" (!)(!)(!) Error while reading AWDBlock ID " + this._cur_block_id + " = skip to next block"); + if (block.errorMessages) { + while (msgCnt < block.errorMessages.length) { + console.log(" (!) Error: " + block.errorMessages[msgCnt] + " (!)"); + msgCnt++; + } + } + } + } + this._body.position = blockEndAll; + this._newBlockBytes = null; + }; + //--Parser Blocks--------------------------------------------------------------------------- + //Block ID = 1 + AWDParser.prototype.parseTriangleGeometrieBlock = function (blockID) { + var geom = new Geometry(); + // Read name and sub count + var name = this.parseVarStr(); + var num_subs = this._newBlockBytes.readUnsignedShort(); + // Read optional properties + var props = this.parseProperties({ 1: this._geoNrType, 2: this._geoNrType }); + var geoScaleU = props.get(1, 1); + var geoScaleV = props.get(2, 1); + // Loop through sub meshes + var subs_parsed = 0; + while (subs_parsed < num_subs) { + var i; + var sm_len, sm_end; + var sub_geom; + var w_indices; + var weights; + sm_len = this._newBlockBytes.readUnsignedInt(); + sm_end = this._newBlockBytes.position + sm_len; + // Ignore for now + var subProps = this.parseProperties({ 1: this._geoNrType, 2: this._geoNrType }); + while (this._newBlockBytes.position < sm_end) { + var idx = 0; + var str_ftype, str_type, str_len, str_end; + // Type, field type, length + str_type = this._newBlockBytes.readUnsignedByte(); + str_ftype = this._newBlockBytes.readUnsignedByte(); + str_len = this._newBlockBytes.readUnsignedInt(); + str_end = this._newBlockBytes.position + str_len; + var x, y, z; + if (str_type == 1) { + var verts = new Array(); + while (this._newBlockBytes.position < str_end) { + // TODO: Respect stream field type + x = this.readNumber(this._accuracyGeo); + y = this.readNumber(this._accuracyGeo); + z = this.readNumber(this._accuracyGeo); + verts[idx++] = x; + verts[idx++] = y; + verts[idx++] = z; + } + } + else if (str_type == 2) { + var indices = new Array(); + while (this._newBlockBytes.position < str_end) { + // TODO: Respect stream field type + indices[idx++] = this._newBlockBytes.readUnsignedShort(); + } + } + else if (str_type == 3) { + var uvs = new Array(); + while (this._newBlockBytes.position < str_end) { + uvs[idx++] = this.readNumber(this._accuracyGeo); + } + } + else if (str_type == 4) { + var normals = new Array(); + while (this._newBlockBytes.position < str_end) { + normals[idx++] = this.readNumber(this._accuracyGeo); + } + } + else if (str_type == 6) { + w_indices = Array(); + while (this._newBlockBytes.position < str_end) { + w_indices[idx++] = this._newBlockBytes.readUnsignedShort() * 3; // TODO: Respect stream field type + } + } + else if (str_type == 7) { + weights = new Array(); + while (this._newBlockBytes.position < str_end) { + weights[idx++] = this.readNumber(this._accuracyGeo); + } + } + else { + this._newBlockBytes.position = str_end; + } + } + this.parseUserAttributes(); // Ignore sub-mesh attributes for now + sub_geom = new TriangleSubGeometry(true); + if (weights) + sub_geom.jointsPerVertex = weights.length / (verts.length / 3); + if (normals) + sub_geom.autoDeriveNormals = false; + if (uvs) + sub_geom.autoDeriveUVs = false; + sub_geom.updateIndices(indices); + sub_geom.updatePositions(verts); + sub_geom.updateVertexNormals(normals); + sub_geom.updateUVs(uvs); + sub_geom.updateVertexTangents(null); + sub_geom.updateJointWeights(weights); + sub_geom.updateJointIndices(w_indices); + var scaleU = subProps.get(1, 1); + var scaleV = subProps.get(2, 1); + var setSubUVs = false; //this should remain false atm, because in AwayBuilder the uv is only scaled by the geometry + if ((geoScaleU != scaleU) || (geoScaleV != scaleV)) { + setSubUVs = true; + scaleU = geoScaleU / scaleU; + scaleV = geoScaleV / scaleV; + } + if (setSubUVs) + sub_geom.scaleUV(scaleU, scaleV); + geom.addSubGeometry(sub_geom); + // TODO: Somehow map in-sub to out-sub indices to enable look-up + // when creating meshes (and their material assignments.) + subs_parsed++; + } + if ((geoScaleU != 1) || (geoScaleV != 1)) + geom.scaleUV(geoScaleU, geoScaleV); + this.parseUserAttributes(); + this._pFinalizeAsset(geom, name); + this._blocks[blockID].data = geom; + if (this._debug) { + console.log("Parsed a TriangleGeometry: Name = " + name + "| Id = " + sub_geom.id); + } + }; + //Block ID = 11 + AWDParser.prototype.parsePrimitves = function (blockID) { + var name; + var prefab; + var primType; + var subs_parsed; + var props; + var bsm; + // Read name and sub count + name = this.parseVarStr(); + primType = this._newBlockBytes.readUnsignedByte(); + props = this.parseProperties({ 101: this._geoNrType, 102: this._geoNrType, 103: this._geoNrType, 110: this._geoNrType, 111: this._geoNrType, 301: AWDParser.UINT16, 302: AWDParser.UINT16, 303: AWDParser.UINT16, 701: AWDParser.BOOL, 702: AWDParser.BOOL, 703: AWDParser.BOOL, 704: AWDParser.BOOL }); + var primitiveTypes = ["Unsupported Type-ID", "PrimitivePlanePrefab", "PrimitiveCubePrefab", "PrimitiveSpherePrefab", "PrimitiveCylinderPrefab", "PrimitivesConePrefab", "PrimitivesCapsulePrefab", "PrimitivesTorusPrefab"]; + switch (primType) { + case 1: + prefab = new PrimitivePlanePrefab(props.get(101, 100), props.get(102, 100), props.get(301, 1), props.get(302, 1), props.get(701, true), props.get(702, false)); + break; + case 2: + prefab = new PrimitiveCubePrefab(props.get(101, 100), props.get(102, 100), props.get(103, 100), props.get(301, 1), props.get(302, 1), props.get(303, 1), props.get(701, true)); + break; + case 3: + prefab = new PrimitiveSpherePrefab(props.get(101, 50), props.get(301, 16), props.get(302, 12), props.get(701, true)); + break; + case 4: + prefab = new PrimitiveCylinderPrefab(props.get(101, 50), props.get(102, 50), props.get(103, 100), props.get(301, 16), props.get(302, 1), true, true, true); // bool701, bool702, bool703, bool704); + if (!props.get(701, true)) + prefab.topClosed = false; + if (!props.get(702, true)) + prefab.bottomClosed = false; + if (!props.get(703, true)) + prefab.yUp = false; + break; + case 5: + prefab = new PrimitiveConePrefab(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 1), props.get(701, true), props.get(702, true)); + break; + case 6: + prefab = new PrimitiveCapsulePrefab(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 15), props.get(701, true)); + break; + case 7: + prefab = new PrimitiveTorusPrefab(props.get(101, 50), props.get(102, 50), props.get(301, 16), props.get(302, 8), props.get(701, true)); + break; + default: + prefab = new PrefabBase(); + console.log("ERROR: UNSUPPORTED PREFAB_TYPE"); + break; + } + if ((props.get(110, 1) != 1) || (props.get(111, 1) != 1)) { + } + this.parseUserAttributes(); + prefab.name = name; + this._pFinalizeAsset(prefab, name); + this._blocks[blockID].data = prefab; + if (this._debug) { + if ((primType < 0) || (primType > 7)) { + primType = 0; + } + console.log("Parsed a Primivite: Name = " + name + "| type = " + primitiveTypes[primType]); + } + }; + // Block ID = 22 + AWDParser.prototype.parseContainer = function (blockID) { + var name; + var par_id; + var mtx; + var ctr; + var parent; + par_id = this._newBlockBytes.readUnsignedInt(); + mtx = this.parseMatrix3D(); + name = this.parseVarStr(); + var parentName = "Root (TopLevel)"; + ctr = new DisplayObjectContainer(); + ctr.transform.matrix3D = mtx; + var returnedArray = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + if (returnedArray[0]) { + var obj = returnedArray[1].addChild(ctr); + parentName = returnedArray[1].name; + } + else if (par_id > 0) { + this._blocks[blockID].addError("Could not find a parent for this ObjectContainer3D"); + } + else { + //add to the content property + this._pContent.addChild(ctr); + } + // in AWD version 2.1 we read the Container properties + if ((this._version[0] == 2) && (this._version[1] == 1)) { + var props = this.parseProperties({ 1: this._matrixNrType, 2: this._matrixNrType, 3: this._matrixNrType, 4: AWDParser.UINT8 }); + ctr.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + } + else { + this.parseProperties(null); + } + // the extraProperties should only be set for AWD2.1-Files, but is read for both versions + ctr.extra = this.parseUserAttributes(); + this._pFinalizeAsset(ctr, name); + this._blocks[blockID].data = ctr; + if (this._debug) { + console.log("Parsed a Container: Name = '" + name + "' | Parent-Name = " + parentName); + } + }; + // Block ID = 23 + AWDParser.prototype.parseMeshInstance = function (blockID) { + var num_materials; + var materials_parsed; + var parent; + var par_id = this._newBlockBytes.readUnsignedInt(); + var mtx = this.parseMatrix3D(); + var name = this.parseVarStr(); + var parentName = "Root (TopLevel)"; + var data_id = this._newBlockBytes.readUnsignedInt(); + var geom; + var returnedArrayGeometry = this.getAssetByID(data_id, [AssetType.GEOMETRY]); + if (returnedArrayGeometry[0]) { + geom = returnedArrayGeometry[1]; + } + else { + this._blocks[blockID].addError("Could not find a Geometry for this Mesh. A empty Geometry is created!"); + geom = new Geometry(); + } + this._blocks[blockID].geoID = data_id; + var materials = new Array(); + num_materials = this._newBlockBytes.readUnsignedShort(); + var materialNames = new Array(); + materials_parsed = 0; + var returnedArrayMaterial; + while (materials_parsed < num_materials) { + var mat_id; + mat_id = this._newBlockBytes.readUnsignedInt(); + returnedArrayMaterial = this.getAssetByID(mat_id, [AssetType.MATERIAL]); + if ((!returnedArrayMaterial[0]) && (mat_id > 0)) { + this._blocks[blockID].addError("Could not find Material Nr " + materials_parsed + " (ID = " + mat_id + " ) for this Mesh"); + } + var m = returnedArrayMaterial[1]; + materials.push(m); + materialNames.push(m.name); + materials_parsed++; + } + var mesh = new Mesh(geom, null); + mesh.transform.matrix3D = mtx; + var returnedArrayParent = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + if (returnedArrayParent[0]) { + var objC = returnedArrayParent[1]; + objC.addChild(mesh); + parentName = objC.name; + } + else if (par_id > 0) { + this._blocks[blockID].addError("Could not find a parent for this Mesh"); + } + else { + //add to the content property + this._pContent.addChild(mesh); + } + if (materials.length >= 1 && mesh.subMeshes.length == 1) { + mesh.material = materials[0]; + } + else if (materials.length > 1) { + var i; + for (i = 0; i < mesh.subMeshes.length; i++) { + mesh.subMeshes[i].material = materials[Math.min(materials.length - 1, i)]; + } + } + if ((this._version[0] == 2) && (this._version[1] == 1)) { + var props = this.parseProperties({ 1: this._matrixNrType, 2: this._matrixNrType, 3: this._matrixNrType, 4: AWDParser.UINT8, 5: AWDParser.BOOL }); + mesh.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + mesh.castsShadows = props.get(5, true); + } + else { + this.parseProperties(null); + } + mesh.extra = this.parseUserAttributes(); + this._pFinalizeAsset(mesh, name); + this._blocks[blockID].data = mesh; + if (this._debug) { + console.log("Parsed a Mesh: Name = '" + name + "' | Parent-Name = " + parentName + "| Geometry-Name = " + geom.name + " | SubMeshes = " + mesh.subMeshes.length + " | Mat-Names = " + materialNames.toString()); + } + }; + //Block ID 31 + AWDParser.prototype.parseSkyboxInstance = function (blockID) { + var name = this.parseVarStr(); + var cubeTexAddr = this._newBlockBytes.readUnsignedInt(); + var returnedArrayCubeTex = this.getAssetByID(cubeTexAddr, [AssetType.TEXTURE], "CubeTexture"); + if ((!returnedArrayCubeTex[0]) && (cubeTexAddr != 0)) + this._blocks[blockID].addError("Could not find the Cubetexture (ID = " + cubeTexAddr + " ) for this Skybox"); + var asset = new Skybox(new SkyboxMaterial(returnedArrayCubeTex[1])); + this.parseProperties(null); + asset.extra = this.parseUserAttributes(); + this._pFinalizeAsset(asset, name); + this._blocks[blockID].data = asset; + if (this._debug) + console.log("Parsed a Skybox: Name = '" + name + "' | CubeTexture-Name = " + returnedArrayCubeTex[1].name); + }; + //Block ID = 41 + AWDParser.prototype.parseLight = function (blockID) { + var light; + var newShadowMapper; + var par_id = this._newBlockBytes.readUnsignedInt(); + var mtx = this.parseMatrix3D(); + var name = this.parseVarStr(); + var lightType = this._newBlockBytes.readUnsignedByte(); + var props = this.parseProperties({ 1: this._propsNrType, 2: this._propsNrType, 3: AWDParser.COLOR, 4: this._propsNrType, 5: this._propsNrType, 6: AWDParser.BOOL, 7: AWDParser.COLOR, 8: this._propsNrType, 9: AWDParser.UINT8, 10: AWDParser.UINT8, 11: this._propsNrType, 12: AWDParser.UINT16, 21: this._matrixNrType, 22: this._matrixNrType, 23: this._matrixNrType }); + var shadowMapperType = props.get(9, 0); + var parentName = "Root (TopLevel)"; + var lightTypes = ["Unsupported LightType", "PointLight", "DirectionalLight"]; + var shadowMapperTypes = ["No ShadowMapper", "DirectionalShadowMapper", "NearDirectionalShadowMapper", "CascadeShadowMapper", "CubeMapShadowMapper"]; + if (lightType == 1) { + light = new PointLight(); + light.radius = props.get(1, 90000); + light.fallOff = props.get(2, 100000); + if (shadowMapperType > 0) { + if (shadowMapperType == 4) { + newShadowMapper = new CubeMapShadowMapper(); + } + } + light.transform.matrix3D = mtx; + } + if (lightType == 2) { + light = new DirectionalLight(props.get(21, 0), props.get(22, -1), props.get(23, 1)); + if (shadowMapperType > 0) { + if (shadowMapperType == 1) { + newShadowMapper = new DirectionalShadowMapper(); + } + } + } + light.color = props.get(3, 0xffffff); + light.specular = props.get(4, 1.0); + light.diffuse = props.get(5, 1.0); + light.ambientColor = props.get(7, 0xffffff); + light.ambient = props.get(8, 0.0); + // if a shadowMapper has been created, adjust the depthMapSize if needed, assign to light and set castShadows to true + if (newShadowMapper) { + if (newShadowMapper instanceof CubeMapShadowMapper) { + if (props.get(10, 1) != 1) { + newShadowMapper.depthMapSize = this._depthSizeDic[props.get(10, 1)]; + } + } + else { + if (props.get(10, 2) != 2) { + newShadowMapper.depthMapSize = this._depthSizeDic[props.get(10, 2)]; + } + } + light.shadowMapper = newShadowMapper; + light.castsShadows = true; + } + if (par_id != 0) { + var returnedArrayParent = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + if (returnedArrayParent[0]) { + returnedArrayParent[1].addChild(light); + parentName = returnedArrayParent[1].name; + } + else { + this._blocks[blockID].addError("Could not find a parent for this Light"); + } + } + else { + //add to the content property + this._pContent.addChild(light); + } + this.parseUserAttributes(); + this._pFinalizeAsset(light, name); + this._blocks[blockID].data = light; + if (this._debug) + console.log("Parsed a Light: Name = '" + name + "' | Type = " + lightTypes[lightType] + " | Parent-Name = " + parentName + " | ShadowMapper-Type = " + shadowMapperTypes[shadowMapperType]); + }; + //Block ID = 43 + AWDParser.prototype.parseCamera = function (blockID) { + var par_id = this._newBlockBytes.readUnsignedInt(); + var mtx = this.parseMatrix3D(); + var name = this.parseVarStr(); + var parentName = "Root (TopLevel)"; + var projection; + this._newBlockBytes.readUnsignedByte(); //set as active camera + this._newBlockBytes.readShort(); //lengthof lenses - not used yet + var projectiontype = this._newBlockBytes.readShort(); + var props = this.parseProperties({ 101: this._propsNrType, 102: this._propsNrType, 103: this._propsNrType, 104: this._propsNrType }); + switch (projectiontype) { + case 5001: + projection = new PerspectiveProjection(props.get(101, 60)); + break; + case 5002: + projection = new OrthographicProjection(props.get(101, 500)); + break; + case 5003: + projection = new OrthographicOffCenterProjection(props.get(101, -400), props.get(102, 400), props.get(103, -300), props.get(104, 300)); + break; + default: + console.log("unsupportedLenstype"); + return; + } + var camera = new Camera(projection); + camera.transform.matrix3D = mtx; + var returnedArrayParent = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + if (returnedArrayParent[0]) { + var objC = returnedArrayParent[1]; + objC.addChild(camera); + parentName = objC.name; + } + else if (par_id > 0) { + this._blocks[blockID].addError("Could not find a parent for this Camera"); + } + else { + //add to the content property + this._pContent.addChild(camera); + } + camera.name = name; + props = this.parseProperties({ 1: this._matrixNrType, 2: this._matrixNrType, 3: this._matrixNrType, 4: AWDParser.UINT8 }); + camera.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + camera.extra = this.parseUserAttributes(); + this._pFinalizeAsset(camera, name); + this._blocks[blockID].data = camera; + if (this._debug) { + console.log("Parsed a Camera: Name = '" + name + "' | Projectiontype = " + projection + " | Parent-Name = " + parentName); + } + }; + //Block ID = 51 + AWDParser.prototype.parseLightPicker = function (blockID) { + var name = this.parseVarStr(); + var numLights = this._newBlockBytes.readUnsignedShort(); + var lightsArray = new Array(); + var k = 0; + var lightID = 0; + var returnedArrayLight; + var lightsArrayNames = new Array(); + for (k = 0; k < numLights; k++) { + lightID = this._newBlockBytes.readUnsignedInt(); + returnedArrayLight = this.getAssetByID(lightID, [AssetType.LIGHT]); + if (returnedArrayLight[0]) { + lightsArray.push(returnedArrayLight[1]); + lightsArrayNames.push(returnedArrayLight[1].name); + } + else { + this._blocks[blockID].addError("Could not find a Light Nr " + k + " (ID = " + lightID + " ) for this LightPicker"); + } + } + if (lightsArray.length == 0) { + this._blocks[blockID].addError("Could not create this LightPicker, cause no Light was found."); + this.parseUserAttributes(); + return; //return without any more parsing for this block + } + var lightPick = new StaticLightPicker(lightsArray); + lightPick.name = name; + this.parseUserAttributes(); + this._pFinalizeAsset(lightPick, name); + this._blocks[blockID].data = lightPick; + if (this._debug) { + console.log("Parsed a StaticLightPicker: Name = '" + name + "' | Texture-Name = " + lightsArrayNames.toString()); + } + }; + //Block ID = 81 + AWDParser.prototype.parseMaterial = function (blockID) { + // TODO: not used + ////blockLength = block.len; + var name; + var type; + var props; + var mat; + var attributes; + var finalize; + var num_methods; + var methods_parsed; + var returnedArray; + name = this.parseVarStr(); + type = this._newBlockBytes.readUnsignedByte(); + num_methods = this._newBlockBytes.readUnsignedByte(); + // Read material numerical properties + // (1=color, 2=bitmap url, 10=alpha, 11=alpha_blending, 12=alpha_threshold, 13=repeat) + props = this.parseProperties({ 1: AWDParser.INT32, 2: AWDParser.BADDR, 10: this._propsNrType, 11: AWDParser.BOOL, 12: this._propsNrType, 13: AWDParser.BOOL }); + methods_parsed = 0; + while (methods_parsed < num_methods) { + var method_type; + method_type = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); + this.parseUserAttributes(); + methods_parsed += 1; + } + var debugString = ""; + attributes = this.parseUserAttributes(); + if (type === 1) { + debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | "; + var color; + color = props.get(1, 0xffffff); + if (this.materialMode < 2) { + mat = new TriangleMethodMaterial(color, props.get(10, 1.0)); + } + else { + mat = new TriangleMethodMaterial(color); + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + } + } + else if (type === 2) { + var tex_addr = props.get(2, 0); + returnedArray = this.getAssetByID(tex_addr, [AssetType.TEXTURE]); + if ((!returnedArray[0]) && (tex_addr > 0)) + this._blocks[blockID].addError("Could not find the DiffsueTexture (ID = " + tex_addr + " ) for this Material"); + mat = new TriangleMethodMaterial(returnedArray[1]); + if (this.materialMode < 2) { + mat.alphaBlending = props.get(11, false); + mat.alpha = props.get(10, 1.0); + debugString += "Parsed a TriangleMethodMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + mat.name; + } + else { + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + debugString += "Parsed a TriangleMethodMaterial(MultiPass): Name = '" + name + "' | Texture-Name = " + mat.name; + } + } + mat.extra = attributes; + mat.alphaThreshold = props.get(12, 0.0); + mat.repeat = props.get(13, false); + this._pFinalizeAsset(mat, name); + this._blocks[blockID].data = mat; + if (this._debug) { + console.log(debugString); + } + }; + // Block ID = 81 AWD2.1 + AWDParser.prototype.parseMaterial_v1 = function (blockID) { + var mat; + var normalTexture; + var specTexture; + var returnedArray; + var name = this.parseVarStr(); + var type = this._newBlockBytes.readUnsignedByte(); + var num_methods = this._newBlockBytes.readUnsignedByte(); + var props = this.parseProperties({ 1: AWDParser.UINT32, 2: AWDParser.BADDR, 3: AWDParser.BADDR, 4: AWDParser.UINT8, 5: AWDParser.BOOL, 6: AWDParser.BOOL, 7: AWDParser.BOOL, 8: AWDParser.BOOL, 9: AWDParser.UINT8, 10: this._propsNrType, 11: AWDParser.BOOL, 12: this._propsNrType, 13: AWDParser.BOOL, 15: this._propsNrType, 16: AWDParser.UINT32, 17: AWDParser.BADDR, 18: this._propsNrType, 19: this._propsNrType, 20: AWDParser.UINT32, 21: AWDParser.BADDR, 22: AWDParser.BADDR }); + var spezialType = props.get(4, 0); + var debugString = ""; + if (spezialType >= 2) { + this._blocks[blockID].addError("Material-spezialType '" + spezialType + "' is not supported, can only be 0:singlePass, 1:MultiPass !"); + return; + } + if (this.materialMode == 1) + spezialType = 0; + else if (this.materialMode == 2) + spezialType = 1; + if (spezialType < 2) { + if (type == 1) { + var color = props.get(1, 0xcccccc); //TODO temporarily swapped so that diffuse color goes to ambient + if (spezialType == 1) { + mat = new TriangleMethodMaterial(color); + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + debugString += "Parsed a ColorMaterial(MultiPass): Name = '" + name + "' | "; + } + else { + mat = new TriangleMethodMaterial(color, props.get(10, 1.0)); + mat.alphaBlending = props.get(11, false); + debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | "; + } + } + else if (type == 2) { + var tex_addr = props.get(2, 0); //TODO temporarily swapped so that diffuse texture goes to ambient + returnedArray = this.getAssetByID(tex_addr, [AssetType.TEXTURE]); + if ((!returnedArray[0]) && (tex_addr > 0)) + this._blocks[blockID].addError("Could not find the AmbientTexture (ID = " + tex_addr + " ) for this TriangleMethodMaterial"); + var texture = returnedArray[1]; + mat = new TriangleMethodMaterial(texture); + if (spezialType == 1) { + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + debugString += "Parsed a TriangleMethodMaterial(MultiPass): Name = '" + name + "' | Texture-Name = " + texture.name; + } + else { + mat.alpha = props.get(10, 1.0); + mat.alphaBlending = props.get(11, false); + debugString += "Parsed a TriangleMethodMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + texture.name; + } + } + var diffuseTexture; + var diffuseTex_addr = props.get(17, 0); + returnedArray = this.getAssetByID(diffuseTex_addr, [AssetType.TEXTURE]); + if ((!returnedArray[0]) && (diffuseTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the DiffuseTexture (ID = " + diffuseTex_addr + " ) for this TriangleMethodMaterial"); + } + if (returnedArray[0]) + diffuseTexture = returnedArray[1]; + if (diffuseTexture) { + mat.diffuseTexture = diffuseTexture; + debugString += " | DiffuseTexture-Name = " + diffuseTexture.name; + } + var normalTex_addr = props.get(3, 0); + returnedArray = this.getAssetByID(normalTex_addr, [AssetType.TEXTURE]); + if ((!returnedArray[0]) && (normalTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the NormalTexture (ID = " + normalTex_addr + " ) for this TriangleMethodMaterial"); + } + if (returnedArray[0]) { + normalTexture = returnedArray[1]; + debugString += " | NormalTexture-Name = " + normalTexture.name; + } + var specTex_addr = props.get(21, 0); + returnedArray = this.getAssetByID(specTex_addr, [AssetType.TEXTURE]); + if ((!returnedArray[0]) && (specTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the SpecularTexture (ID = " + specTex_addr + " ) for this TriangleMethodMaterial"); + } + if (returnedArray[0]) { + specTexture = returnedArray[1]; + debugString += " | SpecularTexture-Name = " + specTexture.name; + } + var lightPickerAddr = props.get(22, 0); + returnedArray = this.getAssetByID(lightPickerAddr, [AssetType.LIGHT_PICKER]); + if ((!returnedArray[0]) && (lightPickerAddr)) { + this._blocks[blockID].addError("Could not find the LightPicker (ID = " + lightPickerAddr + " ) for this TriangleMethodMaterial"); + } + else { + mat.lightPicker = returnedArray[1]; + } + mat.smooth = props.get(5, true); + mat.mipmap = props.get(6, true); + mat.bothSides = props.get(7, false); + mat.alphaPremultiplied = props.get(8, false); + mat.blendMode = this.blendModeDic[props.get(9, 0)]; + mat.repeat = props.get(13, false); + if (normalTexture) + mat.normalMap = normalTexture; + if (specTexture) + mat.specularMap = specTexture; + mat.alphaThreshold = props.get(12, 0.0); + mat.ambient = props.get(15, 1.0); + mat.diffuseColor = props.get(16, 0xffffff); + mat.specular = props.get(18, 1.0); + mat.gloss = props.get(19, 50); + mat.specularColor = props.get(20, 0xffffff); + var methods_parsed = 0; + var targetID; + while (methods_parsed < num_methods) { + var method_type; + method_type = this._newBlockBytes.readUnsignedShort(); + props = this.parseProperties({ 1: AWDParser.BADDR, 2: AWDParser.BADDR, 3: AWDParser.BADDR, 101: this._propsNrType, 102: this._propsNrType, 103: this._propsNrType, 201: AWDParser.UINT32, 202: AWDParser.UINT32, 301: AWDParser.UINT16, 302: AWDParser.UINT16, 401: AWDParser.UINT8, 402: AWDParser.UINT8, 601: AWDParser.COLOR, 602: AWDParser.COLOR, 701: AWDParser.BOOL, 702: AWDParser.BOOL, 801: AWDParser.MTX4x4 }); + switch (method_type) { + case 999: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.EFFECTS_METHOD]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the EffectMethod (ID = " + targetID + " ) for this Material"); + } + else { + mat.addEffectMethod(returnedArray[1]); + debugString += " | EffectMethod-Name = " + returnedArray[1].name; + } + break; + case 998: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the ShadowMethod (ID = " + targetID + " ) for this Material"); + } + else { + mat.shadowMethod = returnedArray[1]; + debugString += " | ShadowMethod-Name = " + returnedArray[1].name; + } + break; + case 1: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this EnvMapAmbientMethodMaterial"); + mat.ambientMethod = new AmbientEnvMapMethod(returnedArray[1]); + debugString += " | AmbientEnvMapMethod | EnvMap-Name =" + returnedArray[1].name; + break; + case 51: + mat.diffuseMethod = new DiffuseDepthMethod(); + debugString += " | DiffuseDepthMethod"; + break; + case 52: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the GradientDiffuseTexture (ID = " + targetID + " ) for this GradientDiffuseMethod"); + mat.diffuseMethod = new DiffuseGradientMethod(returnedArray[1]); + debugString += " | DiffuseGradientMethod | GradientDiffuseTexture-Name =" + returnedArray[1].name; + break; + case 53: + mat.diffuseMethod = new DiffuseWrapMethod(props.get(101, 5)); + debugString += " | DiffuseWrapMethod"; + break; + case 54: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the LightMap (ID = " + targetID + " ) for this LightMapDiffuseMethod"); + mat.diffuseMethod = new DiffuseLightMapMethod(returnedArray[1], this.blendModeDic[props.get(401, 10)], false, mat.diffuseMethod); + debugString += " | DiffuseLightMapMethod | LightMapTexture-Name =" + returnedArray[1].name; + break; + case 55: + mat.diffuseMethod = new DiffuseCelMethod(props.get(401, 3), mat.diffuseMethod); + mat.diffuseMethod.smoothness = props.get(101, 0.1); + debugString += " | DiffuseCelMethod"; + break; + case 56: + break; + case 101: + mat.specularMethod = new SpecularAnisotropicMethod(); + debugString += " | SpecularAnisotropicMethod"; + break; + case 102: + mat.specularMethod = new SpecularPhongMethod(); + debugString += " | SpecularPhongMethod"; + break; + case 103: + mat.specularMethod = new SpecularCelMethod(props.get(101, 0.5), mat.specularMethod); + mat.specularMethod.smoothness = props.get(102, 0.1); + debugString += " | SpecularCelMethod"; + break; + case 104: + mat.specularMethod = new SpecularFresnelMethod(props.get(701, true), mat.specularMethod); + mat.specularMethod.fresnelPower = props.get(101, 5); + mat.specularMethod.normalReflectance = props.get(102, 0.1); + debugString += " | SpecularFresnelMethod"; + break; + case 151: + break; + case 152: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the SecoundNormalMap (ID = " + targetID + " ) for this SimpleWaterNormalMethod"); + if (!mat.normalMap) + this._blocks[blockID].addError("Could not find a normal Map on this Material to use with this SimpleWaterNormalMethod"); + mat.normalMap = returnedArray[1]; + mat.normalMethod = new NormalSimpleWaterMethod(mat.normalMap, returnedArray[1]); + debugString += " | NormalSimpleWaterMethod | Second-NormalTexture-Name = " + returnedArray[1].name; + break; + } + this.parseUserAttributes(); + methods_parsed += 1; + } + } + mat.extra = this.parseUserAttributes(); + this._pFinalizeAsset(mat, name); + this._blocks[blockID].data = mat; + if (this._debug) { + console.log(debugString); + } + }; + //Block ID = 82 + AWDParser.prototype.parseTexture = function (blockID) { + var asset; + this._blocks[blockID].name = this.parseVarStr(); + var type = this._newBlockBytes.readUnsignedByte(); + var data_len; + this._texture_users[this._cur_block_id.toString()] = []; + // External + if (type == 0) { + data_len = this._newBlockBytes.readUnsignedInt(); + var url; + url = this._newBlockBytes.readUTFBytes(data_len); + this._pAddDependency(this._cur_block_id.toString(), new URLRequest(url), false, null, true); + } + else { + data_len = this._newBlockBytes.readUnsignedInt(); + var data; + data = new ByteArray(); + this._newBlockBytes.readBytes(data, 0, data_len); + // + // AWDParser - Fix for FireFox Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=715075 . + // + // Converting data to image here instead of parser - fix FireFox bug where image width / height is 0 when created from data + // This gives the browser time to initialise image width / height. + this._pAddDependency(this._cur_block_id.toString(), null, false, ParserUtils.byteArrayToImage(data), true); + } + // Ignore for now + this.parseProperties(null); + this._blocks[blockID].extras = this.parseUserAttributes(); + this._pPauseAndRetrieveDependencies(); + this._blocks[blockID].data = asset; + if (this._debug) { + var textureStylesNames = ["external", "embed"]; + console.log("Start parsing a " + textureStylesNames[type] + " Bitmap for Texture"); + } + }; + //Block ID = 83 + AWDParser.prototype.parseCubeTexture = function (blockID) { + //blockLength = block.len; + var data_len; + var asset; + var i; + this._cubeTextures = new Array(); + this._texture_users[this._cur_block_id.toString()] = []; + var type = this._newBlockBytes.readUnsignedByte(); + this._blocks[blockID].name = this.parseVarStr(); + for (i = 0; i < 6; i++) { + this._texture_users[this._cur_block_id.toString()] = []; + this._cubeTextures.push(null); + // External + if (type == 0) { + data_len = this._newBlockBytes.readUnsignedInt(); + var url; + url = this._newBlockBytes.readUTFBytes(data_len); + this._pAddDependency(this._cur_block_id.toString() + "#" + i, new URLRequest(url), false, null, true); + } + else { + data_len = this._newBlockBytes.readUnsignedInt(); + var data; + data = new ByteArray(); + this._newBlockBytes.readBytes(data, 0, data_len); + this._pAddDependency(this._cur_block_id.toString() + "#" + i, null, false, ParserUtils.byteArrayToImage(data), true); + } + } + // Ignore for now + this.parseProperties(null); + this._blocks[blockID].extras = this.parseUserAttributes(); + this._pPauseAndRetrieveDependencies(); + this._blocks[blockID].data = asset; + if (this._debug) { + var textureStylesNames = ["external", "embed"]; + console.log("Start parsing 6 " + textureStylesNames[type] + " Bitmaps for CubeTexture"); + } + }; + //Block ID = 91 + AWDParser.prototype.parseSharedMethodBlock = function (blockID) { + var asset; + this._blocks[blockID].name = this.parseVarStr(); + asset = this.parseSharedMethodList(blockID); + this.parseUserAttributes(); + this._blocks[blockID].data = asset; + this._pFinalizeAsset(asset, this._blocks[blockID].name); + this._blocks[blockID].data = asset; + if (this._debug) { + console.log("Parsed a EffectMethod: Name = " + asset.name + " Type = " + asset); + } + }; + //Block ID = 92 + AWDParser.prototype.parseShadowMethodBlock = function (blockID) { + var type; + var data_len; + var asset; + var shadowLightID; + this._blocks[blockID].name = this.parseVarStr(); + shadowLightID = this._newBlockBytes.readUnsignedInt(); + var returnedArray = this.getAssetByID(shadowLightID, [AssetType.LIGHT]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the TargetLight (ID = " + shadowLightID + " ) for this ShadowMethod - ShadowMethod not created"); + return; + } + asset = this.parseShadowMethodList(returnedArray[1], blockID); + if (!asset) + return; + this.parseUserAttributes(); // Ignore for now + this._pFinalizeAsset(asset, this._blocks[blockID].name); + this._blocks[blockID].data = asset; + if (this._debug) { + console.log("Parsed a ShadowMapMethodMethod: Name = " + asset.name + " | Type = " + asset + " | Light-Name = ", returnedArray[1].name); + } + }; + //Block ID = 253 + AWDParser.prototype.parseCommand = function (blockID) { + var hasBlocks = (this._newBlockBytes.readUnsignedByte() == 1); + var par_id = this._newBlockBytes.readUnsignedInt(); + var mtx = this.parseMatrix3D(); + var name = this.parseVarStr(); + var parentObject; + var targetObject; + var returnedArray = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + if (returnedArray[0]) { + parentObject = returnedArray[1]; + } + var numCommands = this._newBlockBytes.readShort(); + var typeCommand = this._newBlockBytes.readShort(); + var props = this.parseProperties({ 1: AWDParser.BADDR }); + switch (typeCommand) { + case 1: + var targetID = props.get(1, 0); + var returnedArrayTarget = this.getAssetByID(targetID, [AssetType.LIGHT, AssetType.TEXTURE_PROJECTOR]); //for no only light is requested!!!! + if ((!returnedArrayTarget[0]) && (targetID != 0)) { + this._blocks[blockID].addError("Could not find the light (ID = " + targetID + " ( for this CommandBock!"); + return; + } + targetObject = returnedArrayTarget[1]; + if (parentObject) { + parentObject.addChild(targetObject); + } + targetObject.transform.matrix3D = mtx; + break; + } + if (targetObject) { + props = this.parseProperties({ 1: this._matrixNrType, 2: this._matrixNrType, 3: this._matrixNrType, 4: AWDParser.UINT8 }); + targetObject.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + targetObject.extra = this.parseUserAttributes(); + } + this._blocks[blockID].data = targetObject; + if (this._debug) { + console.log("Parsed a CommandBlock: Name = '" + name); + } + }; + //blockID 255 + AWDParser.prototype.parseMetaData = function (blockID) { + var props = this.parseProperties({ 1: AWDParser.UINT32, 2: AWDParser.AWDSTRING, 3: AWDParser.AWDSTRING, 4: AWDParser.AWDSTRING, 5: AWDParser.AWDSTRING }); + if (this._debug) { + console.log("Parsed a MetaDataBlock: TimeStamp = " + props.get(1, 0)); + console.log(" EncoderName = " + props.get(2, "unknown")); + console.log(" EncoderVersion = " + props.get(3, "unknown")); + console.log(" GeneratorName = " + props.get(4, "unknown")); + console.log(" GeneratorVersion = " + props.get(5, "unknown")); + } + }; + //blockID 254 + AWDParser.prototype.parseNameSpace = function (blockID) { + var id = this._newBlockBytes.readUnsignedByte(); + var nameSpaceString = this.parseVarStr(); + if (this._debug) + console.log("Parsed a NameSpaceBlock: ID = " + id + " | String = " + nameSpaceString); + }; + //--Parser UTILS--------------------------------------------------------------------------- + // this functions reads and creates a ShadowMethodMethod + AWDParser.prototype.parseShadowMethodList = function (light, blockID) { + var methodType = this._newBlockBytes.readUnsignedShort(); + var shadowMethod; + var props = this.parseProperties({ 1: AWDParser.BADDR, 2: AWDParser.BADDR, 3: AWDParser.BADDR, 101: this._propsNrType, 102: this._propsNrType, 103: this._propsNrType, 201: AWDParser.UINT32, 202: AWDParser.UINT32, 301: AWDParser.UINT16, 302: AWDParser.UINT16, 401: AWDParser.UINT8, 402: AWDParser.UINT8, 601: AWDParser.COLOR, 602: AWDParser.COLOR, 701: AWDParser.BOOL, 702: AWDParser.BOOL, 801: AWDParser.MTX4x4 }); + var targetID; + var returnedArray; + switch (methodType) { + case 1002: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the ShadowBaseMethod (ID = " + targetID + " ) for this ShadowNearMethod - ShadowMethod not created"); + return shadowMethod; + } + shadowMethod = new ShadowNearMethod(returnedArray[1]); + break; + case 1101: + shadowMethod = new ShadowFilteredMethod(light); + shadowMethod.alpha = props.get(101, 1); + shadowMethod.epsilon = props.get(102, 0.002); + break; + case 1102: + shadowMethod = new ShadowDitheredMethod(light, props.get(201, 5)); + shadowMethod.alpha = props.get(101, 1); + shadowMethod.epsilon = props.get(102, 0.002); + shadowMethod.range = props.get(103, 1); + break; + case 1103: + shadowMethod = new ShadowSoftMethod(light, props.get(201, 5)); + shadowMethod.alpha = props.get(101, 1); + shadowMethod.epsilon = props.get(102, 0.002); + shadowMethod.range = props.get(103, 1); + break; + case 1104: + shadowMethod = new ShadowHardMethod(light); + shadowMethod.alpha = props.get(101, 1); + shadowMethod.epsilon = props.get(102, 0.002); + break; + } + this.parseUserAttributes(); + return shadowMethod; + }; + //Block ID 101 + AWDParser.prototype.parseSkeleton = function (blockID /*uint*/) { + var name = this.parseVarStr(); + var num_joints = this._newBlockBytes.readUnsignedShort(); + var skeleton = new Skeleton(); + this.parseProperties(null); // Discard properties for now + var joints_parsed = 0; + while (joints_parsed < num_joints) { + var joint; + var ibp; + // Ignore joint id + this._newBlockBytes.readUnsignedShort(); + joint = new SkeletonJoint(); + joint.parentIndex = this._newBlockBytes.readUnsignedShort() - 1; // 0=null in AWD + joint.name = this.parseVarStr(); + ibp = this.parseMatrix3D(); + joint.inverseBindPose = ibp.rawData; + // Ignore joint props/attributes for now + this.parseProperties(null); + this.parseUserAttributes(); + skeleton.joints.push(joint); + joints_parsed++; + } + // Discard attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(skeleton, name); + this._blocks[blockID].data = skeleton; + if (this._debug) + console.log("Parsed a Skeleton: Name = " + skeleton.name + " | Number of Joints = " + joints_parsed); + }; + //Block ID = 102 + AWDParser.prototype.parseSkeletonPose = function (blockID /*uint*/) { + var name = this.parseVarStr(); + var num_joints = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); // Ignore properties for now + var pose = new SkeletonPose(); + var joints_parsed = 0; + while (joints_parsed < num_joints) { + var joint_pose; + var has_transform /*uint*/; + joint_pose = new JointPose(); + has_transform = this._newBlockBytes.readUnsignedByte(); + if (has_transform == 1) { + var mtx_data = this.parseMatrix43RawData(); + var mtx = new Matrix3D(mtx_data); + joint_pose.orientation.fromMatrix(mtx); + joint_pose.translation.copyFrom(mtx.position); + pose.jointPoses[joints_parsed] = joint_pose; + } + joints_parsed++; + } + // Skip attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(pose, name); + this._blocks[blockID].data = pose; + if (this._debug) + console.log("Parsed a SkeletonPose: Name = " + pose.name + " | Number of Joints = " + joints_parsed); + }; + //blockID 103 + AWDParser.prototype.parseSkeletonAnimation = function (blockID /*uint*/) { + var frame_dur; + var pose_addr /*uint*/; + var name = this.parseVarStr(); + var clip = new SkeletonClipNode(); + var num_frames = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); // Ignore properties for now + var frames_parsed = 0; + var returnedArray; + while (frames_parsed < num_frames) { + pose_addr = this._newBlockBytes.readUnsignedInt(); + frame_dur = this._newBlockBytes.readUnsignedShort(); + returnedArray = this.getAssetByID(pose_addr, [AssetType.SKELETON_POSE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the SkeletonPose Frame # " + frames_parsed + " (ID = " + pose_addr + " ) for this SkeletonClipNode"); + else + clip.addFrame(this._blocks[pose_addr].data, frame_dur); + frames_parsed++; + } + if (clip.frames.length == 0) { + this._blocks[blockID].addError("Could not this SkeletonClipNode, because no Frames where set."); + return; + } + // Ignore attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(clip, name); + this._blocks[blockID].data = clip; + if (this._debug) + console.log("Parsed a SkeletonClipNode: Name = " + clip.name + " | Number of Frames = " + clip.frames.length); + }; + //Block ID = 111 / Block ID = 112 + AWDParser.prototype.parseMeshPoseAnimation = function (blockID /*uint*/, poseOnly) { + if (poseOnly === void 0) { poseOnly = false; } + var num_frames = 1; + var num_submeshes /*uint*/; + var frames_parsed /*uint*/; + var subMeshParsed /*uint*/; + var frame_dur; + var x; + var y; + var z; + var str_len; + var str_end; + var geometry; + var subGeom; + var idx = 0; + var clip = new VertexClipNode(); + var indices /*uint*/; + var verts; + var num_Streams = 0; + var streamsParsed = 0; + var streamtypes = new Array() /*int*/; + var props; + var thisGeo; + var name = this.parseVarStr(); + var geoAdress = this._newBlockBytes.readUnsignedInt(); + var returnedArray = this.getAssetByID(geoAdress, [AssetType.GEOMETRY]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the target-Geometry-Object " + geoAdress + " ) for this VertexClipNode"); + return; + } + var uvs = this.getUVForVertexAnimation(geoAdress); + if (!poseOnly) + num_frames = this._newBlockBytes.readUnsignedShort(); + num_submeshes = this._newBlockBytes.readUnsignedShort(); + num_Streams = this._newBlockBytes.readUnsignedShort(); + streamsParsed = 0; + while (streamsParsed < num_Streams) { + streamtypes.push(this._newBlockBytes.readUnsignedShort()); + streamsParsed++; + } + props = this.parseProperties({ 1: AWDParser.BOOL, 2: AWDParser.BOOL }); + clip.looping = props.get(1, true); + clip.stitchFinalFrame = props.get(2, false); + frames_parsed = 0; + while (frames_parsed < num_frames) { + frame_dur = this._newBlockBytes.readUnsignedShort(); + geometry = new Geometry(); + subMeshParsed = 0; + while (subMeshParsed < num_submeshes) { + streamsParsed = 0; + str_len = this._newBlockBytes.readUnsignedInt(); + str_end = this._newBlockBytes.position + str_len; + while (streamsParsed < num_Streams) { + if (streamtypes[streamsParsed] == 1) { + indices = returnedArray[1].subGeometries[subMeshParsed].indices; + verts = new Array(); + idx = 0; + while (this._newBlockBytes.position < str_end) { + x = this.readNumber(this._accuracyGeo); + y = this.readNumber(this._accuracyGeo); + z = this.readNumber(this._accuracyGeo); + verts[idx++] = x; + verts[idx++] = y; + verts[idx++] = z; + } + subGeom = new TriangleSubGeometry(true); + subGeom.updateIndices(indices); + subGeom.updatePositions(verts); + subGeom.updateUVs(uvs[subMeshParsed]); + subGeom.updateVertexNormals(null); + subGeom.updateVertexTangents(null); + subGeom.autoDeriveNormals = false; + subGeom.autoDeriveTangents = false; + subMeshParsed++; + geometry.addSubGeometry(subGeom); + } + else + this._newBlockBytes.position = str_end; + streamsParsed++; + } + } + clip.addFrame(geometry, frame_dur); + frames_parsed++; + } + this.parseUserAttributes(); + this._pFinalizeAsset(clip, name); + this._blocks[blockID].data = clip; + if (this._debug) + console.log("Parsed a VertexClipNode: Name = " + clip.name + " | Target-Geometry-Name = " + returnedArray[1].name + " | Number of Frames = " + clip.frames.length); + }; + //BlockID 113 + AWDParser.prototype.parseVertexAnimationSet = function (blockID /*uint*/) { + var poseBlockAdress; /*int*/ + var outputString = ""; + var name = this.parseVarStr(); + var num_frames = this._newBlockBytes.readUnsignedShort(); + var props = this.parseProperties({ 1: AWDParser.UINT16 }); + var frames_parsed = 0; + var skeletonFrames = new Array(); + var vertexFrames = new Array(); + while (frames_parsed < num_frames) { + poseBlockAdress = this._newBlockBytes.readUnsignedInt(); + var returnedArray = this.getAssetByID(poseBlockAdress, [AssetType.ANIMATION_NODE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the AnimationClipNode Nr " + frames_parsed + " ( " + poseBlockAdress + " ) for this AnimationSet"); + else { + if (returnedArray[1] instanceof VertexClipNode) + vertexFrames.push(returnedArray[1]); + if (returnedArray[1] instanceof SkeletonClipNode) + skeletonFrames.push(returnedArray[1]); + } + frames_parsed++; + } + if ((vertexFrames.length == 0) && (skeletonFrames.length == 0)) { + this._blocks[blockID].addError("Could not create this AnimationSet, because it contains no animations"); + return; + } + this.parseUserAttributes(); + if (vertexFrames.length > 0) { + var newVertexAnimationSet = new VertexAnimationSet(); + for (var i = 0; i < vertexFrames.length; i++) + newVertexAnimationSet.addAnimation(vertexFrames[i]); + this._pFinalizeAsset(newVertexAnimationSet, name); + this._blocks[blockID].data = newVertexAnimationSet; + if (this._debug) + console.log("Parsed a VertexAnimationSet: Name = " + name + " | Animations = " + newVertexAnimationSet.animations.length + " | Animation-Names = " + newVertexAnimationSet.animationNames.toString()); + } + else if (skeletonFrames.length > 0) { + returnedArray = this.getAssetByID(poseBlockAdress, [AssetType.ANIMATION_NODE]); + var newSkeletonAnimationSet = new SkeletonAnimationSet(props.get(1, 4)); //props.get(1,4)); + for (var i = 0; i < skeletonFrames.length; i++) + newSkeletonAnimationSet.addAnimation(skeletonFrames[i]); + this._pFinalizeAsset(newSkeletonAnimationSet, name); + this._blocks[blockID].data = newSkeletonAnimationSet; + if (this._debug) + console.log("Parsed a SkeletonAnimationSet: Name = " + name + " | Animations = " + newSkeletonAnimationSet.animations.length + " | Animation-Names = " + newSkeletonAnimationSet.animationNames.toString()); + } + }; + //BlockID 122 + AWDParser.prototype.parseAnimatorSet = function (blockID /*uint*/) { + var targetMesh; + var animSetBlockAdress; /*int*/ + var targetAnimationSet; + var outputString = ""; + var name = this.parseVarStr(); + var type = this._newBlockBytes.readUnsignedShort(); + var props = this.parseProperties({ 1: AWDParser.BADDR }); + animSetBlockAdress = this._newBlockBytes.readUnsignedInt(); + var targetMeshLength = this._newBlockBytes.readUnsignedShort(); + var meshAdresses = new Array() /*uint*/; + for (var i = 0; i < targetMeshLength; i++) + meshAdresses.push(this._newBlockBytes.readUnsignedInt()); + var activeState = this._newBlockBytes.readUnsignedShort(); + var autoplay = (this._newBlockBytes.readUnsignedByte() == 1); + this.parseUserAttributes(); + this.parseUserAttributes(); + var returnedArray; + var targetMeshes = new Array(); + for (i = 0; i < meshAdresses.length; i++) { + returnedArray = this.getAssetByID(meshAdresses[i], [AssetType.MESH]); + if (returnedArray[0]) + targetMeshes.push(returnedArray[1]); + } + returnedArray = this.getAssetByID(animSetBlockAdress, [AssetType.ANIMATION_SET]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the AnimationSet ( " + animSetBlockAdress + " ) for this Animator"); + ; + return; + } + targetAnimationSet = returnedArray[1]; + var thisAnimator; + if (type == 1) { + returnedArray = this.getAssetByID(props.get(1, 0), [AssetType.SKELETON]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the Skeleton ( " + props.get(1, 0) + " ) for this Animator"); + return; + } + thisAnimator = new SkeletonAnimator(targetAnimationSet, returnedArray[1]); + } + else if (type == 2) + thisAnimator = new VertexAnimator(targetAnimationSet); + this._pFinalizeAsset(thisAnimator, name); + this._blocks[blockID].data = thisAnimator; + for (i = 0; i < targetMeshes.length; i++) { + if (type == 1) + targetMeshes[i].animator = thisAnimator; + if (type == 2) + targetMeshes[i].animator = thisAnimator; + } + if (this._debug) + console.log("Parsed a Animator: Name = " + name); + }; + // this functions reads and creates a EffectMethod + AWDParser.prototype.parseSharedMethodList = function (blockID) { + var methodType = this._newBlockBytes.readUnsignedShort(); + var effectMethodReturn; + var props = this.parseProperties({ 1: AWDParser.BADDR, 2: AWDParser.BADDR, 3: AWDParser.BADDR, 101: this._propsNrType, 102: this._propsNrType, 103: this._propsNrType, 104: this._propsNrType, 105: this._propsNrType, 106: this._propsNrType, 107: this._propsNrType, 201: AWDParser.UINT32, 202: AWDParser.UINT32, 301: AWDParser.UINT16, 302: AWDParser.UINT16, 401: AWDParser.UINT8, 402: AWDParser.UINT8, 601: AWDParser.COLOR, 602: AWDParser.COLOR, 701: AWDParser.BOOL, 702: AWDParser.BOOL }); + var targetID; + var returnedArray; + switch (methodType) { + case 401: + effectMethodReturn = new EffectColorMatrixMethod(props.get(101, new Array(0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))); + break; + case 402: + effectMethodReturn = new EffectColorTransformMethod(); + var offCol = props.get(601, 0x00000000); + effectMethodReturn.colorTransform = new ColorTransform(props.get(102, 1), props.get(103, 1), props.get(104, 1), props.get(101, 1), ((offCol >> 16) & 0xFF), ((offCol >> 8) & 0xFF), (offCol & 0xFF), ((offCol >> 24) & 0xFF)); + break; + case 403: + targetID = props.get(1, 0); + console.log('ENV MAP', targetID); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this EnvMapMethod"); + effectMethodReturn = new EffectEnvMapMethod(returnedArray[1], props.get(101, 1)); + targetID = props.get(2, 0); + if (targetID > 0) { + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the Mask-texture (ID = " + targetID + " ) for this EnvMapMethod"); + } + break; + case 404: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the LightMap (ID = " + targetID + " ) for this LightMapMethod"); + effectMethodReturn = new EffectLightMapMethod(returnedArray[1], this.blendModeDic[props.get(401, 10)]); //usesecondaryUV not set + break; + case 406: + effectMethodReturn = new EffectRimLightMethod(props.get(601, 0xffffff), props.get(101, 0.4), props.get(101, 2)); //blendMode + break; + case 407: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the Alpha-texture (ID = " + targetID + " ) for this AlphaMaskMethod"); + effectMethodReturn = new EffectAlphaMaskMethod(returnedArray[1], props.get(701, false)); + break; + case 410: + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this FresnelEnvMapMethod"); + effectMethodReturn = new EffectFresnelEnvMapMethod(returnedArray[1], props.get(101, 1)); + break; + case 411: + effectMethodReturn = new EffectFogMethod(props.get(101, 0), props.get(102, 1000), props.get(601, 0x808080)); + break; + } + this.parseUserAttributes(); + return effectMethodReturn; + }; + AWDParser.prototype.parseUserAttributes = function () { + var attributes; + var list_len; + var attibuteCnt; + list_len = this._newBlockBytes.readUnsignedInt(); + if (list_len > 0) { + var list_end; + attributes = {}; + list_end = this._newBlockBytes.position + list_len; + while (this._newBlockBytes.position < list_end) { + var ns_id; + var attr_key; + var attr_type; + var attr_len; + var attr_val; + // TODO: Properly tend to namespaces in attributes + ns_id = this._newBlockBytes.readUnsignedByte(); + attr_key = this.parseVarStr(); + attr_type = this._newBlockBytes.readUnsignedByte(); + attr_len = this._newBlockBytes.readUnsignedInt(); + if ((this._newBlockBytes.position + attr_len) > list_end) { + console.log(" Error in reading attribute # " + attibuteCnt + " = skipped to end of attribute-list"); + this._newBlockBytes.position = list_end; + return attributes; + } + switch (attr_type) { + case AWDParser.AWDSTRING: + attr_val = this._newBlockBytes.readUTFBytes(attr_len); + break; + case AWDParser.INT8: + attr_val = this._newBlockBytes.readByte(); + break; + case AWDParser.INT16: + attr_val = this._newBlockBytes.readShort(); + break; + case AWDParser.INT32: + attr_val = this._newBlockBytes.readInt(); + break; + case AWDParser.BOOL: + case AWDParser.UINT8: + attr_val = this._newBlockBytes.readUnsignedByte(); + break; + case AWDParser.UINT16: + attr_val = this._newBlockBytes.readUnsignedShort(); + break; + case AWDParser.UINT32: + case AWDParser.BADDR: + attr_val = this._newBlockBytes.readUnsignedInt(); + break; + case AWDParser.FLOAT32: + attr_val = this._newBlockBytes.readFloat(); + break; + case AWDParser.FLOAT64: + attr_val = this._newBlockBytes.readDouble(); + break; + default: + attr_val = 'unimplemented attribute type ' + attr_type; + this._newBlockBytes.position += attr_len; + break; + } + if (this._debug) { + console.log("attribute = name: " + attr_key + " / value = " + attr_val); + } + attributes[attr_key] = attr_val; + attibuteCnt += 1; + } + } + return attributes; + }; + AWDParser.prototype.parseProperties = function (expected) { + var list_end; + var list_len; + var propertyCnt = 0; + var props = new AWDProperties(); + list_len = this._newBlockBytes.readUnsignedInt(); + list_end = this._newBlockBytes.position + list_len; + if (expected) { + while (this._newBlockBytes.position < list_end) { + var len; + var key; + var type; + key = this._newBlockBytes.readUnsignedShort(); + len = this._newBlockBytes.readUnsignedInt(); + if ((this._newBlockBytes.position + len) > list_end) { + console.log(" Error in reading property # " + propertyCnt + " = skipped to end of propertie-list"); + this._newBlockBytes.position = list_end; + return props; + } + if (expected.hasOwnProperty(key.toString())) { + type = expected[key]; + props.set(key, this.parseAttrValue(type, len)); + } + else { + this._newBlockBytes.position += len; + } + propertyCnt += 1; + } + } + else { + this._newBlockBytes.position = list_end; + } + return props; + }; + AWDParser.prototype.parseAttrValue = function (type, len) { + var elem_len; + var read_func; + switch (type) { + case AWDParser.BOOL: + case AWDParser.INT8: + elem_len = 1; + read_func = this._newBlockBytes.readByte; + break; + case AWDParser.INT16: + elem_len = 2; + read_func = this._newBlockBytes.readShort; + break; + case AWDParser.INT32: + elem_len = 4; + read_func = this._newBlockBytes.readInt; + break; + case AWDParser.UINT8: + elem_len = 1; + read_func = this._newBlockBytes.readUnsignedByte; + break; + case AWDParser.UINT16: + elem_len = 2; + read_func = this._newBlockBytes.readUnsignedShort; + break; + case AWDParser.UINT32: + case AWDParser.COLOR: + case AWDParser.BADDR: + elem_len = 4; + read_func = this._newBlockBytes.readUnsignedInt; + break; + case AWDParser.FLOAT32: + elem_len = 4; + read_func = this._newBlockBytes.readFloat; + break; + case AWDParser.FLOAT64: + elem_len = 8; + read_func = this._newBlockBytes.readDouble; + break; + case AWDParser.AWDSTRING: + return this._newBlockBytes.readUTFBytes(len); + case AWDParser.VECTOR2x1: + case AWDParser.VECTOR3x1: + case AWDParser.VECTOR4x1: + case AWDParser.MTX3x2: + case AWDParser.MTX3x3: + case AWDParser.MTX4x3: + case AWDParser.MTX4x4: + elem_len = 8; + read_func = this._newBlockBytes.readDouble; + break; + } + if (elem_len < len) { + var list = []; + var num_read = 0; + var num_elems = len / elem_len; + while (num_read < num_elems) { + list.push(read_func.apply(this._newBlockBytes)); // list.push(read_func()); + num_read++; + } + return list; + } + else { + var val = read_func.apply(this._newBlockBytes); //read_func(); + return val; + } + }; + AWDParser.prototype.parseHeader = function () { + var flags; + var body_len; + this._byteData.position = 3; // Skip magic string and parse version + this._version[0] = this._byteData.readUnsignedByte(); + this._version[1] = this._byteData.readUnsignedByte(); + flags = this._byteData.readUnsignedShort(); // Parse bit flags + this._streaming = BitFlags.test(flags, BitFlags.FLAG1); + if ((this._version[0] == 2) && (this._version[1] == 1)) { + this._accuracyMatrix = BitFlags.test(flags, BitFlags.FLAG2); + this._accuracyGeo = BitFlags.test(flags, BitFlags.FLAG3); + this._accuracyProps = BitFlags.test(flags, BitFlags.FLAG4); + } + // if we set _accuracyOnBlocks, the precision-values are read from each block-header. + // set storagePrecision types + this._geoNrType = AWDParser.FLOAT32; + if (this._accuracyGeo) { + this._geoNrType = AWDParser.FLOAT64; + } + this._matrixNrType = AWDParser.FLOAT32; + if (this._accuracyMatrix) { + this._matrixNrType = AWDParser.FLOAT64; + } + this._propsNrType = AWDParser.FLOAT32; + if (this._accuracyProps) { + this._propsNrType = AWDParser.FLOAT64; + } + this._compression = this._byteData.readUnsignedByte(); // compression + if (this._debug) { + console.log("Import AWDFile of version = " + this._version[0] + " - " + this._version[1]); + console.log("Global Settings = Compression = " + this._compression + " | Streaming = " + this._streaming + " | Matrix-Precision = " + this._accuracyMatrix + " | Geometry-Precision = " + this._accuracyGeo + " | Properties-Precision = " + this._accuracyProps); + } + // Check file integrity + body_len = this._byteData.readUnsignedInt(); + if (!this._streaming && body_len != this._byteData.getBytesAvailable()) { + this._pDieWithError('AWD2 body length does not match header integrity field'); + } + }; + // Helper - functions + AWDParser.prototype.getUVForVertexAnimation = function (meshID /*uint*/) { + if (this._blocks[meshID].data instanceof Mesh) + meshID = this._blocks[meshID].geoID; + if (this._blocks[meshID].uvsForVertexAnimation) + return this._blocks[meshID].uvsForVertexAnimation; + var geometry = this._blocks[meshID].data; + var geoCnt = 0; + var ud; + var uStride /*uint*/; + var uOffs /*uint*/; + var numPoints /*uint*/; + var i /*int*/; + var newUvs; + var sub_geom; + this._blocks[meshID].uvsForVertexAnimation = new Array(); + while (geoCnt < geometry.subGeometries.length) { + newUvs = new Array(); + sub_geom = geometry.subGeometries[geoCnt]; + numPoints = sub_geom.numVertices; + ud = sub_geom.uvs; + uStride = sub_geom.getStride(TriangleSubGeometry.UV_DATA); + uOffs = sub_geom.getOffset(TriangleSubGeometry.UV_DATA); + for (i = 0; i < numPoints; i++) { + newUvs.push(ud[uOffs + i * uStride + 0]); + newUvs.push(ud[uOffs + i * uStride + 1]); + } + this._blocks[meshID].uvsForVertexAnimation.push(newUvs); + geoCnt++; + } + return this._blocks[meshID].uvsForVertexAnimation; + }; + AWDParser.prototype.parseVarStr = function () { + var len = this._newBlockBytes.readUnsignedShort(); + return this._newBlockBytes.readUTFBytes(len); + }; + AWDParser.prototype.getAssetByID = function (assetID, assetTypesToGet, extraTypeInfo) { + if (extraTypeInfo === void 0) { extraTypeInfo = "SingleTexture"; } + var returnArray = new Array(); + var typeCnt = 0; + if (assetID > 0) { + if (this._blocks[assetID]) { + if (this._blocks[assetID].data) { + while (typeCnt < assetTypesToGet.length) { + var iasset = this._blocks[assetID].data; + if (iasset.assetType == assetTypesToGet[typeCnt]) { + //if the right assetType was found + if ((assetTypesToGet[typeCnt] == AssetType.TEXTURE) && (extraTypeInfo == "CubeTexture")) { + if (this._blocks[assetID].data instanceof ImageCubeTexture) { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + } + } + if ((assetTypesToGet[typeCnt] == AssetType.TEXTURE) && (extraTypeInfo == "SingleTexture")) { + if (this._blocks[assetID].data instanceof ImageTexture) { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + } + } + else { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + } + } + //if ((assetTypesToGet[typeCnt] == AssetType.GEOMETRY) && (IAsset(_blocks[assetID].data).assetType == AssetType.MESH)) { + if ((assetTypesToGet[typeCnt] == AssetType.GEOMETRY) && (iasset.assetType == AssetType.MESH)) { + var mesh = this._blocks[assetID].data; + returnArray.push(true); + returnArray.push(mesh.geometry); + return returnArray; + } + typeCnt++; + } + } + } + } + // if the has not returned anything yet, the asset is not found, or the found asset is not the right type. + returnArray.push(false); + returnArray.push(this.getDefaultAsset(assetTypesToGet[0], extraTypeInfo)); + return returnArray; + }; + AWDParser.prototype.getDefaultAsset = function (assetType, extraTypeInfo) { + switch (true) { + case (assetType == AssetType.TEXTURE): + if (extraTypeInfo == "CubeTexture") + return this.getDefaultCubeTexture(); + if (extraTypeInfo == "SingleTexture") + return this.getDefaultTexture(); + break; + case (assetType == AssetType.MATERIAL): + return this.getDefaultMaterial(); + break; + default: + break; + } + return null; + }; + AWDParser.prototype.getDefaultMaterial = function () { + if (!this._defaultBitmapMaterial) + this._defaultBitmapMaterial = DefaultMaterialManager.getDefaultMaterial(); + return this._defaultBitmapMaterial; + }; + AWDParser.prototype.getDefaultTexture = function () { + if (!this._defaultTexture) + this._defaultTexture = DefaultMaterialManager.getDefaultTexture(); + return this._defaultTexture; + }; + AWDParser.prototype.getDefaultCubeTexture = function () { + if (!this._defaultCubeTexture) { + var defaultBitmap = DefaultMaterialManager.createCheckeredBitmapData(); + this._defaultCubeTexture = new BitmapCubeTexture(defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap); + this._defaultCubeTexture.name = "defaultCubeTexture"; + } + return this._defaultCubeTexture; + }; + AWDParser.prototype.readNumber = function (precision) { + if (precision === void 0) { precision = false; } + if (precision) + return this._newBlockBytes.readDouble(); + return this._newBlockBytes.readFloat(); + }; + AWDParser.prototype.parseMatrix3D = function () { + return new Matrix3D(this.parseMatrix43RawData()); + }; + AWDParser.prototype.parseMatrix32RawData = function () { + var i; + var mtx_raw = new Array(6); + for (i = 0; i < 6; i++) { + mtx_raw[i] = this._newBlockBytes.readFloat(); + } + return mtx_raw; + }; + AWDParser.prototype.parseMatrix43RawData = function () { + var mtx_raw = new Array(16); + mtx_raw[0] = this.readNumber(this._accuracyMatrix); + mtx_raw[1] = this.readNumber(this._accuracyMatrix); + mtx_raw[2] = this.readNumber(this._accuracyMatrix); + mtx_raw[3] = 0.0; + mtx_raw[4] = this.readNumber(this._accuracyMatrix); + mtx_raw[5] = this.readNumber(this._accuracyMatrix); + mtx_raw[6] = this.readNumber(this._accuracyMatrix); + mtx_raw[7] = 0.0; + mtx_raw[8] = this.readNumber(this._accuracyMatrix); + mtx_raw[9] = this.readNumber(this._accuracyMatrix); + mtx_raw[10] = this.readNumber(this._accuracyMatrix); + mtx_raw[11] = 0.0; + mtx_raw[12] = this.readNumber(this._accuracyMatrix); + mtx_raw[13] = this.readNumber(this._accuracyMatrix); + mtx_raw[14] = this.readNumber(this._accuracyMatrix); + mtx_raw[15] = 1.0; + //TODO: fix max exporter to remove NaN values in joint 0 inverse bind pose + if (isNaN(mtx_raw[0])) { + mtx_raw[0] = 1; + mtx_raw[1] = 0; + mtx_raw[2] = 0; + mtx_raw[4] = 0; + mtx_raw[5] = 1; + mtx_raw[6] = 0; + mtx_raw[8] = 0; + mtx_raw[9] = 0; + mtx_raw[10] = 1; + mtx_raw[12] = 0; + mtx_raw[13] = 0; + mtx_raw[14] = 0; + } + return mtx_raw; + }; + AWDParser.COMPRESSIONMODE_LZMA = "lzma"; + AWDParser.UNCOMPRESSED = 0; + AWDParser.DEFLATE = 1; + AWDParser.LZMA = 2; + AWDParser.INT8 = 1; + AWDParser.INT16 = 2; + AWDParser.INT32 = 3; + AWDParser.UINT8 = 4; + AWDParser.UINT16 = 5; + AWDParser.UINT32 = 6; + AWDParser.FLOAT32 = 7; + AWDParser.FLOAT64 = 8; + AWDParser.BOOL = 21; + AWDParser.COLOR = 22; + AWDParser.BADDR = 23; + AWDParser.AWDSTRING = 31; + AWDParser.AWDBYTEARRAY = 32; + AWDParser.VECTOR2x1 = 41; + AWDParser.VECTOR3x1 = 42; + AWDParser.VECTOR4x1 = 43; + AWDParser.MTX3x2 = 44; + AWDParser.MTX3x3 = 45; + AWDParser.MTX4x3 = 46; + AWDParser.MTX4x4 = 47; + return AWDParser; +})(ParserBase); +module.exports = AWDParser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvYXdkcGFyc2VyLnRzIl0sIm5hbWVzIjpbIkFXRFBhcnNlciIsIkFXRFBhcnNlci5jb25zdHJ1Y3RvciIsIkFXRFBhcnNlci5zdXBwb3J0c1R5cGUiLCJBV0RQYXJzZXIuc3VwcG9ydHNEYXRhIiwiQVdEUGFyc2VyLl9pUmVzb2x2ZURlcGVuZGVuY3kiLCJBV0RQYXJzZXIuX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUiLCJBV0RQYXJzZXIuX2lSZXNvbHZlRGVwZW5kZW5jeU5hbWUiLCJBV0RQYXJzZXIuX3BQcm9jZWVkUGFyc2luZyIsIkFXRFBhcnNlci5fcFN0YXJ0UGFyc2luZyIsIkFXRFBhcnNlci5kaXNwb3NlIiwiQVdEUGFyc2VyLnBhcnNlTmV4dEJsb2NrIiwiQVdEUGFyc2VyLnBhcnNlVHJpYW5nbGVHZW9tZXRyaWVCbG9jayIsIkFXRFBhcnNlci5wYXJzZVByaW1pdHZlcyIsIkFXRFBhcnNlci5wYXJzZUNvbnRhaW5lciIsIkFXRFBhcnNlci5wYXJzZU1lc2hJbnN0YW5jZSIsIkFXRFBhcnNlci5wYXJzZVNreWJveEluc3RhbmNlIiwiQVdEUGFyc2VyLnBhcnNlTGlnaHQiLCJBV0RQYXJzZXIucGFyc2VDYW1lcmEiLCJBV0RQYXJzZXIucGFyc2VMaWdodFBpY2tlciIsIkFXRFBhcnNlci5wYXJzZU1hdGVyaWFsIiwiQVdEUGFyc2VyLnBhcnNlTWF0ZXJpYWxfdjEiLCJBV0RQYXJzZXIucGFyc2VUZXh0dXJlIiwiQVdEUGFyc2VyLnBhcnNlQ3ViZVRleHR1cmUiLCJBV0RQYXJzZXIucGFyc2VTaGFyZWRNZXRob2RCbG9jayIsIkFXRFBhcnNlci5wYXJzZVNoYWRvd01ldGhvZEJsb2NrIiwiQVdEUGFyc2VyLnBhcnNlQ29tbWFuZCIsIkFXRFBhcnNlci5wYXJzZU1ldGFEYXRhIiwiQVdEUGFyc2VyLnBhcnNlTmFtZVNwYWNlIiwiQVdEUGFyc2VyLnBhcnNlU2hhZG93TWV0aG9kTGlzdCIsIkFXRFBhcnNlci5wYXJzZVNrZWxldG9uIiwiQVdEUGFyc2VyLnBhcnNlU2tlbGV0b25Qb3NlIiwiQVdEUGFyc2VyLnBhcnNlU2tlbGV0b25BbmltYXRpb24iLCJBV0RQYXJzZXIucGFyc2VNZXNoUG9zZUFuaW1hdGlvbiIsIkFXRFBhcnNlci5wYXJzZVZlcnRleEFuaW1hdGlvblNldCIsIkFXRFBhcnNlci5wYXJzZUFuaW1hdG9yU2V0IiwiQVdEUGFyc2VyLnBhcnNlU2hhcmVkTWV0aG9kTGlzdCIsIkFXRFBhcnNlci5wYXJzZVVzZXJBdHRyaWJ1dGVzIiwiQVdEUGFyc2VyLnBhcnNlUHJvcGVydGllcyIsIkFXRFBhcnNlci5wYXJzZUF0dHJWYWx1ZSIsIkFXRFBhcnNlci5wYXJzZUhlYWRlciIsIkFXRFBhcnNlci5nZXRVVkZvclZlcnRleEFuaW1hdGlvbiIsIkFXRFBhcnNlci5wYXJzZVZhclN0ciIsIkFXRFBhcnNlci5nZXRBc3NldEJ5SUQiLCJBV0RQYXJzZXIuZ2V0RGVmYXVsdEFzc2V0IiwiQVdEUGFyc2VyLmdldERlZmF1bHRNYXRlcmlhbCIsIkFXRFBhcnNlci5nZXREZWZhdWx0VGV4dHVyZSIsIkFXRFBhcnNlci5nZXREZWZhdWx0Q3ViZVRleHR1cmUiLCJBV0RQYXJzZXIucmVhZE51bWJlciIsIkFXRFBhcnNlci5wYXJzZU1hdHJpeDNEIiwiQVdEUGFyc2VyLnBhcnNlTWF0cml4MzJSYXdEYXRhIiwiQVdEUGFyc2VyLnBhcnNlTWF0cml4NDNSYXdEYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLHNCQUFzQixXQUFhLG1EQUFtRCxDQUFDLENBQUM7QUFFL0YsSUFBTyxTQUFTLFdBQWdCLHFDQUFxQyxDQUFDLENBQUM7QUFFdkUsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFFdEUsSUFBTyxtQkFBbUIsV0FBYywrQ0FBK0MsQ0FBQyxDQUFDO0FBQ3pGLElBQU8sY0FBYyxXQUFlLDBDQUEwQyxDQUFDLENBQUM7QUFDaEYsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFDdEUsSUFBTyxR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QTtRQUN6Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0E7UUFDN0NBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBQ3hDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUM1Q0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7UUFDekNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBQ3hDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7UUFDM0NBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBO1FBQ3pDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7UUFDekNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBO1FBQ3pDQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUUxQ0EsSUFBSUEsQ0FBQ0EsYUFB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QUNBLEdBQUdBLEVBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLEdBQUdBLEVBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLEdBQUdBLEVBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLEdBQUdBLEVBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLEdBQUdBLEVBQUNBLElBQUlBLENBQUNBLFVBQVVBLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLElBQUlBLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLElBQUlBLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLElBQUlBLEVBQUVBLEdBQUdBLEVBQUNBLFNBQVNBLENBQUNBLElBQUlBLEVBQUNBLENBQUNBLENBQUNBO1FBRTFSQSxJQUFJQSxjQUFjQSxHQUFpQkEsQ0FBQ0EscUJBQXFCQSxFQUFFQSxzQkFBc0JBLEVBQUVBLHFCQUFxQkEsRUFBRUEsdUJBQXVCQSxFQUFFQSx5QkFBeUJBLEVBQUVBLHNCQUFzQkEsRUFBRUEseUJBQXlCQSxFQUFFQSx1QkFBdUJBLENBQUNBLENBQUFBO1FBRXpPQSxNQUFNQSxDQUFDQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUdsQkEsS0FBS0EsQ0FBQ0E7Z0JBQ0xBLE1BQU1BLEdBQUdBLElBQUlBLG9CQUFvQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBR0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBR0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9KQSxLQUFLQSxDQUFDQTtZQUVQQSxLQUFLQSxDQUFDQTtnQkFDTEEsTUFBTUEsR0FBR0EsSUFBSUEsbUJBQW1CQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxHQUFHQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDL0tBLEtBQUtBLENBQUNBO1lBRVBBLEtBQUtBLENBQUNBO2dCQUNMQSxNQUFNQSxHQUFHQSxJQUFJQSxxQkFBcUJBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO2dCQUNySEEsS0FBS0EsQ0FBQ0E7WUFFUEEsS0FBS0EsQ0FBQ0E7Z0JBQ0xBLE1BQU1BLEdBQUdBLElBQUlBLHVCQUF1QkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBR0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsRUFBRUEsSUFBSUEsRUFBRUEsSUFBSUEsQ0FBQ0EsRUFBRUEsdUNBQXVDQTtnQkFDbk1BLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO29CQUNDQSxNQUFPQSxDQUFDQSxTQUFTQSxHQUFHQSxLQUFLQSxDQUFDQTtnQkFDckRBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO29CQUNDQSxNQUFPQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQTtnQkFDeERBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO29CQUNDQSxNQUFPQSxDQUFDQSxHQUFHQSxHQUFHQSxLQUFLQSxDQUFDQTtnQkFFL0NBLEtBQUtBLENBQUNBO1lBRVBBLEtBQUtBLENBQUNBO2dCQUNMQSxNQUFNQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUdBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEVBQUVBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLEVBQUVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO2dCQUM3SkEsS0FBS0EsQ0FBQ0E7WUFFUEEsS0FBS0EsQ0FBQ0E7Z0JBQ0xBLE1BQU1BLEdBQUdBLElBQUlBLHNCQUFzQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBR0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzNJQSxLQUFLQSxDQUFDQTtZQUVQQSxLQUFLQSxDQUFDQTtnQkFDTEEsTUFBTUEsR0FBR0EsSUFBSUEsb0JBQW9CQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDdklBLEtBQUtBLENBQUNBO1lBRVBBO2dCQUNDQSxNQUFNQSxHQUFHQSxJQUFJQSxVQUFVQSxFQUFFQSxDQUFDQTtnQkFDMUJBLE9BQU9BLENBQUNBLEdBQUdBLENBQUNBLGdDQUFnQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzlDQSxLQUFLQSxDQUFDQTtRQUNSQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUczREEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsbUJBQW1CQSxFQUFFQSxDQUFDQTtRQUMzQkEsTUFBTUEsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDbkJBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLE1BQU1BLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO1FBQ25DQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxJQUFJQSxHQUFHQSxNQUFNQSxDQUFDQTtRQUVwQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDakJBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLFFBQVFBLEdBQUdBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUN0Q0EsUUFBUUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDZEEsQ0FBQ0E7WUFDREEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsNkJBQTZCQSxHQUFHQSxJQUFJQSxHQUFHQSxXQUFXQSxHQUFHQSxjQUFjQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM1RkEsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFFRFosZ0JBQWdCQTtJQUNSQSxrQ0FBY0EsR0FBdEJBLFVBQXVCQSxPQUFjQTtRQUVwQ2EsSUFBSUEsSUFBV0EsQ0FBQ0E7UUFDaEJBLElBQUlBLE1BQWFBLENBQUNBO1FBQ2xCQSxJQUFJQSxHQUFZQSxDQUFDQTtRQUNqQkEsSUFBSUEsR0FBMEJBLENBQUNBO1FBQy9CQSxJQUFJQSxNQUE2QkEsQ0FBQ0E7UUFFbENBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLGVBQWVBLEVBQUVBLENBQUNBO1FBQy9DQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQTtRQUMzQkEsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsRUFBRUEsQ0FBQ0E7UUFFMUJBLElBQUlBLFVBQVVBLEdBQVVBLGlCQUFpQkEsQ0FBQ0E7UUFDMUNBLEdBQUdBLEdBQUdBLElBQUlBLHNCQUFzQkEsRUFBRUEsQ0FBQ0E7UUFDbkNBLEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLEdBQUdBLEdBQUdBLENBQUNBO1FBRTdCQSxJQUFJQSxhQUFhQSxHQUFjQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVqSEEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdEJBLElBQUlBLEdBQUdBLEdBQTJDQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFFQSxDQUFDQSxRQUFRQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNsRkEsVUFBVUEsR0FBNkJBLGFBQWFBLENBQUNBLENBQUNBLENBQUVBLENBQUNBLElBQUlBLENBQUNBO1FBQy9EQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxNQUFNQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN2QkEsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBRUEsT0FBT0EsQ0FBRUEsQ0FBQ0EsUUFBUUEsQ0FBQ0Esb0RBQW9EQSxDQUFDQSxDQUFDQTtRQUN4RkEsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDUEEsQUFDQUEsNkJBRDZCQTtZQUNIQSxJQUFJQSxDQUFDQSxTQUFVQSxDQUFDQSxRQUFRQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUN6REEsQ0FBQ0E7UUFFREEsQUFDQUEsc0RBRHNEQTtRQUN0REEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeERBLElBQUlBLEtBQUtBLEdBQWlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxFQUFDQSxDQUFDQSxFQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQSxFQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQSxFQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFDQSxDQUFDQSxDQUFDQTtZQUN0SUEsR0FBR0EsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEs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QUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUM1QkEsSUFBSUEsSUFBSUEsR0FBbURBLG1CQUFtQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbEZBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ3BCQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQTtRQUN4QkEsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLFFBQVFBLENBQUNBLHVDQUF1Q0EsQ0FBQ0EsQ0FBQ0E7UUFDekVBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLEFBQ0FBLDZCQUQ2QkE7WUFDSEEsSUFBSUEsQ0FBQ0EsU0FBVUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDMURBLENBQUNBO1FBRURBLEVBQUVBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLElBQUlBLENBQUNBLElBQUlBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLElBQUlBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3pEQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM5QkEsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDakNBLElBQUlBLENBQVFBLENBQUNBO1lBSWJBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO2dCQUM1Q0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsUUFBUUEsR0FBR0EsU0FBU0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDM0VBLENBQUNBO1FBQ0ZBLENBQUNBO1FBQ0RBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3hEQSxJQUFJQSxLQUFLQSxHQUFpQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsRUFBQ0EsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeEpBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLElBQUlBLFFBQVFBLENBQVNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEVBQVVBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLEVBQVdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3RHQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxD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QSxDQUFDQTtRQUMxREEsSUFBSUEsR0FBR0EsR0FBWUEsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsQ0FBQ0E7UUFDeENBLElBQUlBLElBQUlBLEdBQVVBLElBQUlBLENBQUNBLFdBQVdBLEVBQUVBLENBQUNBO1FBQ3JDQSxJQUFJQSxTQUFTQSxHQUFVQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLENBQUNBO1FBQzlEQSxJQUFJQSxLQUFLQSxHQUFpQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsRUFBQ0EsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsRUFBRUEsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsRUFBRUEsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsRUFBRUEsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsRUFBRUEsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsRUFBRUEsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsRUFBRUEsRUFBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDeldBLElBQUlBLGdCQUFnQkEsR0FBVUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDOUNBLElBQUlBLFVBQVVBLEdBQVVB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Q0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzNCQSxlQUFlQSxDQUFDQSxZQUFZQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDckVBLENBQUNBO1lBQ0ZBLENBQUNBO1lBQUNBLElBQUlBLENBQUNBLENBQUNBO2dCQUNQQSxFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDM0JBLGVBQWVBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNyRUEsQ0FBQ0E7WUFDRkEsQ0FBQ0E7WUFFREEsS0FBS0EsQ0FBQ0EsWUFBWUEsR0FBR0EsZUFBZUEsQ0FBQ0E7WUFDckNBLEtBQUtBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBO1FBQzNCQSxDQUFDQTtRQUVEQSxFQUFFQSxDQUFDQSxDQUFDQSxNQUFNQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUVqQkEsSUFBSUEsbUJBQW1CQSxHQUFjQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFBQTtZQUV0SEEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDRkEsbUJBQW1CQSxDQUFDQSxD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MkJBLENBQUNBO1FBQ2hDQSxJQUFJQSxXQUF5QkEsQ0FBQ0E7UUFDOUJBLElBQUlBLGFBQXdCQSxDQUFDQTtRQUU3QkEsSUFBSUEsSUFBSUEsR0FBVUEsSUFBSUEsQ0FBQ0EsV0FBV0EsRUFBRUEsQ0FBQ0E7UUFDckNBLElBQUlBLElBQUlBLEdBQVVBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0E7UUFDekRBLElBQUlBLFdBQVdBLEdBQVVBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0E7UUFDaEVBLElBQUlBLEtBQUtBLEdBQWlCQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxFQUFDQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxFQUFFQSxFQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxFQUFFQSxFQUFFQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxFQUFFQSxFQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxFQUFFQSxFQUFFQSxFQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxFQUFFQSxFQUFFQSxFQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxFQUFFQSxFQUFFQSxFQUFDQSxTQUFTQSxDQUFDQSxNQUFNQSxFQUFFQSxFQUFFQSxFQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxFQUFFQSxFQUFFQSxFQUFDQSxJ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ZUFBZUEsR0FBVUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDOUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLGVBQWVBLEVBQUVBLENBQUNBLFNBQVNBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUFBO1lBRTVFQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDOUNBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLFFBQVFBLENBQUNBLHVDQUF1Q0EsR0FBR0EsZUFBZUEsR0FBR0Esb0NBQW9DQSxDQUFDQSxDQUFDQTtZQUNsSUEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ1BBLEdBQUdBLENBQUNBLFdBQVdBLEdBQXFCQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUV0REEsQ0FBQ0E7WUFFREEsR0FBR0EsQ0FBQ0EsTUFBTUEsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDaENBLEdBQUdBLENBQUNBLE1BQU1BLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO1lBQ2hDQSxHQUFHQSxDQUFDQSxTQUFTQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUNwQ0EsR0FBR0EsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUM3Q0EsR0FBR0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbkRBLEdBQUdBLENBQUNBLE1BQU1BLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO1lBRWxDQSxFQUFFQSxDQUFDQSxDQUFDQSxhQUFhQSxDQUFDQTtnQkFDakJBLEdBQUdBLENBQUNBLFNBQVNBLEdBQUdBLGFBQWFBLENBQUNBO1lBRS9CQSxFQUFFQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDZkEsR0FBR0EsQ0FBQ0EsV0FBV0EsR0FBR0EsV0FBV0EsQ0FBQ0E7WUFFL0JBLEdBQUdBLENBQUNBLGNBQWNBLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBO1lBQ3hDQSxHQUFHQSxDQUFDQSxPQUFPQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNqQ0EsR0FBR0EsQ0FBQ0EsWUFBWUEsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7WUFDM0NBLEdBQUdBLENBQUNBLFFBQVFBLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2xDQSxHQUFHQSxDQUFDQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUM5QkEsR0FBR0EsQ0FBQ0EsYUFBYUEsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsRUFBRUEsUUFBUUEsQ0FBQ0EsQ0FBQ0E7WUFFNUNBLElBQUlBLGNBQWNBLEdBQVVBLENBQUNBLENBQUNBO1lBQzlCQSxJQUFJQSxRQUFlQSxDQUFDQTtZQUVwQkEsT0FBT0EsY0FBY0EsR0FBR0EsV0FBV0EsRUFBRUEsQ0FBQ0E7Z0JBQ3JDQSxJQUFJQSxXQUFrQkEsQ0FBQ0E7Z0JBQ3ZCQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxpQkFBaUJBLEVBQUVBLENBQUNBO2dCQUV0REEsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsRUFBQ0EsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRXZZQSxNQUFNQSxDQUFDQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDckJBLEtBQUtBLEdBQUdBO3dCQUVQQSxRQUFRQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxFQUFFQSxD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RUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0E7WUFDeERBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBRTlCQSxBQUNBQSxXQURXQTtZQUNYQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDZkEsUUFBUUEsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsZUFBZUEsRUFBRUEsQ0FBQ0E7Z0JBQ2pEQSxJQUFJQSxHQUFVQSxDQUFDQTtnQkFDZkEsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsWUFBWUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0E7Z0JBRWpEQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxRQUFRQSxFQUFFQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxFQUFFQSxJQUFJQSxVQUFVQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxLQUFLQSxFQUFFQSxJQUFJQSxFQUFFQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUN2R0EsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBRVBBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLGVBQWVBLEVBQUVBLENBQUNBO2dCQUNqREEsSUFBSUEsSUFBY0EsQ0FBQ0E7Z0JBQ25CQSxJQUFJQSxHQUFHQSxJQUFJQSxTQUFTQSxFQUFFQSxDQUFDQTtnQkFFdkJBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLFNBQVNBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLEVBQUVBLFFBQVFBLENBQUNBLENBQUNBO2dCQUVqREEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsUUFBUUEsRUFBRUEsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0EsRUFBRUEsSUFBSUEsRUFBRUEsS0FBS0EsRUFBRUEsV0FBV0EsQ0FBQ0EsZ0JBQWdCQSxD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VUEsR0FBVUEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtRQUNoRUEsSUFBSUEsWUFBNkJBLENBQUNBO1FBQ2xDQSxJQUFJQSxLQUFLQSxHQUFpQkEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsRUFBQ0EsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFelpBLElBQUlBLFFBQWVBLENBQUNBO1FBQ3BCQSxJQUFJQSxhQUF3QkEsQ0FBQUE7UUFDNUJBLE1BQU1BLENBQUNBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBO1lBVXBCQSxLQUFLQSxJQUFJQTtnQkFDUkEsUUFBUUEsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzNCQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxRQUFRQSxFQUFFQSxDQUFDQSxTQUFTQSxDQUFDQSxpQkFBaUJBLENBQUNBLENBQUNBLENBQUNBO2dCQUMzRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZCQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxRQUFRQSxDQUFDQSw0Q0FBNENBLEdBQUdBLFFBQVFBLEdBQUdBLHlEQUF5REEsQ0FBQ0EsQ0FBQ0E7b0JBQ3BKQSxNQUFNQSxDQUFDQSxZQUFZQSxDQUFDQTtnQkFDckJBLENBQUNBO2dCQUNEQSxZQUFZQSxHQUFHQSxJQUFJQSxnQkFBZ0JBLENBQW9CQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDekVBLEtBQUtBLENBQUNBO1lBQ1BBLEtBQUtBLElBQUlBO2dCQUVSQSxZQUFZQSxHQUFHQSxJQUFJQSxvQkFBb0JBLENBQW9CQSxLQUFLQSxDQUFDQSxDQUFDQTtnQkFDMUNBLFlBQWFBLENBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4Q0EsWUFBYUEsQ0FBQ0EsT0FBT0EsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3RFQSxLQUFLQSxDQUFDQTtZQUVQQSxLQUFLQSxJQUFJQTtnQkFHUkEsWUFBWUEsR0FBR0EsSUFBSUEsb0JBQW9CQSxDQUFvQkEsS0FBS0EsRUFBV0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3RFQSxZQUFhQSxDQUFDQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDeENBLFlBQWFBLENBQUNBLE9BQU9BLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO2dCQUM5Q0EsWUFBYUEsQ0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRWhFQSxLQUFLQSxDQUFDQTtZQUNQQSxLQUFLQSxJQUFJQTtnQkFFUkEsWUFBWUEsR0FBR0EsSUFBSUEsZ0JBQWdCQSxDQUFvQkEsS0FBS0EsRUFBV0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3RFQSxZQUFhQSxDQUFDQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDeENBLFlBQWFBLENBQUNBLE9BQU9BLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLEtBQUtBLENBQUNBLENBQUNBO2dCQUM5Q0EsWUFBYUEsQ0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRTVEQSxLQUFLQSxDQUFDQTtZQUNQQSxLQUFLQSxJQUFJQTtnQkFDUkEsWUFBWUEsR0FBR0EsSUFBSUEsZ0JBQWdCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtnQkFDdkJBLFlBQWFBLENBQUNBLEtBQUtBLEdBQUdBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4Q0EsWUFBYUEsQ0FBQ0EsT0FBT0EsR0FBR0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsS0FBS0EsQ0FBQ0Es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S0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsRUFBQ0EsU0FBU0EsQ0FBQ0EsSUFBSUEsRUFBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDL2RBLElBQUlBLFFBQWVBLENBQUNBO1FBQ3BCQSxJQUFJQSxhQUF3QkEsQ0FBQ0E7UUFFN0JBLE1BQU1BLENBQUNBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBO1lBRXBCQSxLQUFLQSxHQUFHQTtnQkFDUEEsa0JBQWtCQSxHQUFHQSxJQUFJQSx1QkFBdUJBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLEVBQUVBLElBQUlBLEtBQUtBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4SUEsS0FBS0EsQ0FBQ0E7WUFDUEEsS0FBS0EsR0FBR0E7Z0JBQ1BBLGtCQUFrQkEsR0FBR0EsSUFBSUEsMEJBQTBCQSxFQUFFQSxDQUFDQTtnQkFDdERBLElBQUlBLE1BQU1BLEdBQW1CQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxVQUFVQSxDQUFDQSxDQUFDQTtnQkFDMUJBLGtCQUFtQkEsQ0FBQ0EsY0FBY0EsR0FBR0EsSUFBSUEsY0FBY0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsSUFBSUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsSUFBSUEsRUFBRUEs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R0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDbkRBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1FBQ25EQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQTtRQUNqQkEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDbkRBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1FBQ25EQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUNuREEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0E7UUFDakJBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1FBQ25EQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUNuREEsT0FBT0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDcERBLE9BQU9BLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBO1FBQ2xCQSxPQUFPQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQTtRQUNwREEsT0FBT0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0E7UUFDcERBLE9BQU9BLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLENBQUNBO1FBQ3BEQSxPQUFPQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQTtRQUVsQkEsQUFFQUEsMEVBRjBFQTtRQUUxRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2ZBLE9BQU9BLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2hCQSxPQUFPQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNoQkEsT0FBT0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDaEJBLE9BQU9BLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBRWpCQSxDQUFDQTtRQUVEQSxNQUFNQSxDQUFDQSxPQUFPQSxDQUFDQTtJQUNoQkEsQ0FBQ0E7SUFob0ZhbEQsOEJBQW9CQSxHQUFVQSxNQUFNQSxDQUFDQTtJQUNyQ0Esc0JBQVlBLEdBQVVBLENBQUNBLENBQUNBO0lBQ3hCQSxpQkFBT0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7SUFDbkJBLGNBQUlBLEdBQVVBLENBQUNBLENBQUNBO0lBQ2hCQSxjQUFJQSxHQUFVQSxDQUFDQSxDQUFDQTtJQUNoQkEsZUFBS0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7SUFDakJBLGVBQUtBLEdBQVVBLENBQUNBLENBQUNBO0lBQ2pCQSxlQUFLQSxHQUFVQSxDQUFDQSxDQUFDQTtJQUNqQkEsZ0JBQU1BLEdBQVVBLENBQUNBLENBQUNBO0lBQ2xCQSxnQkFBTUEsR0FBVUEsQ0FBQ0EsQ0FBQ0E7SUFDbEJBLGlCQUFPQSxHQUFVQSxDQUFDQSxDQUFDQTtJQUNuQkEsaUJBQU9BLEdBQVVBLENBQUNBLENBQUNBO0lBQ25CQSxjQUFJQSxHQUFVQSxFQUFFQSxDQUFDQTtJQUNqQkEsZUFBS0EsR0FBVUEsRUFBRUEsQ0FBQ0E7SUFDbEJBLGVBQUtBLEdBQVVBLEVBQUVBLENBQUNBO0lBQ2xCQSxtQkFBU0EsR0FBVUEsRUFBRUEsQ0FBQ0E7SUFDdEJBLHNCQUFZQSxHQUFVQSxFQUFFQSxDQUFDQTtJQUN6QkEsbUJBQVNBLEdBQVVBLEVBQUVBLENBQUNBO0lBQ3RCQSxtQkFBU0EsR0FBVUEsRUFBRUEsQ0FBQ0E7SUFDdEJBLG1CQUFTQSxHQUFVQSxFQUFFQSxDQUFDQTtJQUN0QkEsZ0JBQU1BLEdBQVVBLEVBQUVBLENBQUNBO0lBQ25CQSxnQkFBTUEsR0FBVUEsRUFBRUEsQ0FBQ0E7SUFDbkJBLGdCQUFNQSxHQUFVQSxFQUFFQSxDQUFDQTtJQUNuQkEsZ0JBQU1BLEdBQVVBLEVBQUVBLENBQUNBO0lBMm1GbENBLGdCQUFDQTtBQUFEQSxDQTdwRkEsQUE2cEZDQSxFQTdwRnVCLFVBQVUsRUE2cEZqQztBQUVELEFBQW1CLGlCQUFWLFNBQVMsQ0FBQyIsImZpbGUiOiJwYXJzZXJzL0FXRFBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEaXNwbGF5T2JqZWN0Q29udGFpbmVyXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvRGlzcGxheU9iamVjdENvbnRhaW5lclwiKTtcbmltcG9ydCBCaXRtYXBEYXRhXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9CaXRtYXBEYXRhXCIpO1xuaW1wb3J0IEJsZW5kTW9kZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvQmxlbmRNb2RlXCIpO1xuaW1wb3J0IERpc3BsYXlPYmplY3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9EaXNwbGF5T2JqZWN0XCIpO1xuaW1wb3J0IEdlb21ldHJ5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0dlb21ldHJ5XCIpO1xuaW1wb3J0IExpZ2h0QmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvTGlnaHRCYXNlXCIpO1xuaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBDb2xvclRyYW5zZm9ybVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL0NvbG9yVHJhbnNmb3JtXCIpO1xuaW1wb3J0IE1hdHJpeDNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeDNEXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IFVSTExvYWRlckRhdGFGb3JtYXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxMb2FkZXJEYXRhRm9ybWF0XCIpO1xuaW1wb3J0IFVSTFJlcXVlc3RcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMUmVxdWVzdFwiKTtcbmltcG9ydCBBc3NldFR5cGVcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0VHlwZVwiKTtcbmltcG9ydCBJQXNzZXRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IERpcmVjdGlvbmFsTGlnaHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0RpcmVjdGlvbmFsTGlnaHRcIik7XG5pbXBvcnQgUG9pbnRMaWdodFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9Qb2ludExpZ2h0XCIpO1xuaW1wb3J0IENhbWVyYVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0NhbWVyYVwiKTtcbmltcG9ydCBNZXNoXHRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IFNreWJveFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL1NreWJveFwiKTtcbmltcG9ydCBNYXRlcmlhbEJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL01hdGVyaWFsQmFzZVwiKTtcbmltcG9ydCBMaWdodFBpY2tlckJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9saWdodHBpY2tlcnMvTGlnaHRQaWNrZXJCYXNlXCIpO1xuaW1wb3J0IFN0YXRpY0xpZ2h0UGlja2VyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL2xpZ2h0cGlja2Vycy9TdGF0aWNMaWdodFBpY2tlclwiKTtcbmltcG9ydCBDdWJlTWFwU2hhZG93TWFwcGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL3NoYWRvd21hcHBlcnMvQ3ViZU1hcFNoYWRvd01hcHBlclwiKTtcbmltcG9ydCBEaXJlY3Rpb25hbFNoYWRvd01hcHBlclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9tYXRlcmlhbHMvc2hhZG93bWFwcGVycy9EaXJlY3Rpb25hbFNoYWRvd01hcHBlclwiKTtcbmltcG9ydCBTaGFkb3dNYXBwZXJCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9tYXRlcmlhbHMvc2hhZG93bWFwcGVycy9TaGFkb3dNYXBwZXJCYXNlXCIpO1xuaW1wb3J0IFByZWZhYkJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJlZmFicy9QcmVmYWJCYXNlXCIpO1xuaW1wb3J0IFByaW1pdGl2ZUNhcHN1bGVQcmVmYWJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJlZmFicy9QcmltaXRpdmVDYXBzdWxlUHJlZmFiXCIpO1xuaW1wb3J0IFByaW1pdGl2ZUNvbmVQcmVmYWJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZUNvbmVQcmVmYWJcIik7XG5pbXBvcnQgUHJpbWl0aXZlQ3ViZVByZWZhYlx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3ByZWZhYnMvUHJpbWl0aXZlQ3ViZVByZWZhYlwiKTtcbmltcG9ydCBQcmltaXRpdmVDeWxpbmRlclByZWZhYlx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZUN5bGluZGVyUHJlZmFiXCIpO1xuaW1wb3J0IFByaW1pdGl2ZVBsYW5lUHJlZmFiXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJlZmFicy9QcmltaXRpdmVQbGFuZVByZWZhYlwiKTtcbmltcG9ydCBQcmltaXRpdmVTcGhlcmVQcmVmYWJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJlZmFicy9QcmltaXRpdmVTcGhlcmVQcmVmYWJcIik7XG5pbXBvcnQgUHJpbWl0aXZlVG9ydXNQcmVmYWJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZVRvcnVzUHJlZmFiXCIpO1xuaW1wb3J0IFBhcnNlckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9QYXJzZXJCYXNlXCIpO1xuaW1wb3J0IFBhcnNlclV0aWxzXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3BhcnNlcnMvUGFyc2VyVXRpbHNcIik7XG5pbXBvcnQgUmVzb3VyY2VEZXBlbmRlbmN5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9SZXNvdXJjZURlcGVuZGVuY3lcIik7XG5pbXBvcnQgUHJvamVjdGlvbkJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3Byb2plY3Rpb25zL1Byb2plY3Rpb25CYXNlXCIpO1xuaW1wb3J0IFBlcnNwZWN0aXZlUHJvamVjdGlvblx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcm9qZWN0aW9ucy9QZXJzcGVjdGl2ZVByb2plY3Rpb25cIik7XG5pbXBvcnQgT3J0aG9ncmFwaGljUHJvamVjdGlvblx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcm9qZWN0aW9ucy9PcnRob2dyYXBoaWNQcm9qZWN0aW9uXCIpO1xuaW1wb3J0IE9ydGhvZ3JhcGhpY09mZkNlbnRlclByb2plY3Rpb25cdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcm9qZWN0aW9ucy9PcnRob2dyYXBoaWNPZmZDZW50ZXJQcm9qZWN0aW9uXCIpO1xuaW1wb3J0IEJpdG1hcEN1YmVUZXh0dXJlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvQml0bWFwQ3ViZVRleHR1cmVcIik7XG5pbXBvcnQgQml0bWFwVGV4dHVyZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvQml0bWFwVGV4dHVyZVwiKTtcbmltcG9ydCBDdWJlVGV4dHVyZUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL0N1YmVUZXh0dXJlQmFzZVwiKTtcbmltcG9ydCBJbWFnZUN1YmVUZXh0dXJlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9JbWFnZUN1YmVUZXh0dXJlXCIpO1xuaW1wb3J0IEltYWdlVGV4dHVyZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9JbWFnZVRleHR1cmVcIik7XG5pbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcbmltcG9ydCBUZXh0dXJlUHJveHlCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlUHJveHlCYXNlXCIpO1xuaW1wb3J0IEJ5dGVBcnJheVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9CeXRlQXJyYXlcIik7XG5cbmltcG9ydCBBbmltYXRpb25TZXRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9hbmltYXRvcnMvQW5pbWF0aW9uU2V0QmFzZVwiKTtcbmltcG9ydCBBbmltYXRvckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvYW5pbWF0b3JzL0FuaW1hdG9yQmFzZVwiKTtcbmltcG9ydCBTa3lib3hNYXRlcmlhbFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1NreWJveE1hdGVyaWFsXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWF0ZXJpYWxNb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWF0ZXJpYWxNb2RlXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5pbXBvcnQgRGVmYXVsdE1hdGVyaWFsTWFuYWdlclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvdXRpbHMvRGVmYXVsdE1hdGVyaWFsTWFuYWdlclwiKTtcblxuaW1wb3J0IFZlcnRleEFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9WZXJ0ZXhBbmltYXRpb25TZXRcIik7XG5pbXBvcnQgVmVydGV4QW5pbWF0b3JcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9WZXJ0ZXhBbmltYXRvclwiKTtcbmltcG9ydCBTa2VsZXRvbkFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9Ta2VsZXRvbkFuaW1hdGlvblNldFwiKTtcbmltcG9ydCBTa2VsZXRvbkFuaW1hdG9yXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvU2tlbGV0b25BbmltYXRvclwiKTtcbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvU2tlbGV0b25cIik7XG5pbXBvcnQgU2tlbGV0b25Qb3NlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9kYXRhL1NrZWxldG9uUG9zZVwiKTtcbmltcG9ydCBTa2VsZXRvbkpvaW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvbkpvaW50XCIpO1xuaW1wb3J0IFNrZWxldG9uQ2xpcE5vZGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9ub2Rlcy9Ta2VsZXRvbkNsaXBOb2RlXCIpO1xuaW1wb3J0IFZlcnRleENsaXBOb2RlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvbm9kZXMvVmVydGV4Q2xpcE5vZGVcIik7XG5pbXBvcnQgQW1iaWVudEVudk1hcE1ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0FtYmllbnRFbnZNYXBNZXRob2RcIik7XG5pbXBvcnQgRGlmZnVzZURlcHRoTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZURlcHRoTWV0aG9kXCIpO1xuaW1wb3J0IERpZmZ1c2VDZWxNZXRob2RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VDZWxNZXRob2RcIik7XG5pbXBvcnQgRGlmZnVzZUdyYWRpZW50TWV0aG9kXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0RpZmZ1c2VHcmFkaWVudE1ldGhvZFwiKTtcbmltcG9ydCBEaWZmdXNlTGlnaHRNYXBNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZUxpZ2h0TWFwTWV0aG9kXCIpO1xuaW1wb3J0IERpZmZ1c2VXcmFwTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRGlmZnVzZVdyYXBNZXRob2RcIik7XG5pbXBvcnQgRWZmZWN0QWxwaGFNYXNrTWV0aG9kXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0VmZmVjdEFscGhhTWFza01ldGhvZFwiKTtcbmltcG9ydCBFZmZlY3RDb2xvck1hdHJpeE1ldGhvZFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RDb2xvck1hdHJpeE1ldGhvZFwiKTtcbmltcG9ydCBFZmZlY3RDb2xvclRyYW5zZm9ybU1ldGhvZFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0Q29sb3JUcmFuc2Zvcm1NZXRob2RcIik7XG5pbXBvcnQgRWZmZWN0RW52TWFwTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0RW52TWFwTWV0aG9kXCIpO1xuaW1wb3J0IEVmZmVjdEZvZ01ldGhvZFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0Rm9nTWV0aG9kXCIpO1xuaW1wb3J0IEVmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2RcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL0VmZmVjdEZyZXNuZWxFbnZNYXBNZXRob2RcIik7XG5pbXBvcnQgRWZmZWN0TGlnaHRNYXBNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RMaWdodE1hcE1ldGhvZFwiKTtcbmltcG9ydCBFZmZlY3RNZXRob2RCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9FZmZlY3RNZXRob2RCYXNlXCIpO1xuaW1wb3J0IEVmZmVjdFJpbUxpZ2h0TWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvRWZmZWN0UmltTGlnaHRNZXRob2RcIik7XG5pbXBvcnQgTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2RcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2RcIik7XG5pbXBvcnQgU2hhZG93RGl0aGVyZWRNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TaGFkb3dEaXRoZXJlZE1ldGhvZFwiKTtcbmltcG9ydCBTaGFkb3dGaWx0ZXJlZE1ldGhvZFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NoYWRvd0ZpbHRlcmVkTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRvd01ldGhvZEJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NoYWRvd01ldGhvZEJhc2VcIik7XG5pbXBvcnQgU3BlY3VsYXJGcmVzbmVsTWV0aG9kXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NwZWN1bGFyRnJlc25lbE1ldGhvZFwiKTtcbmltcG9ydCBTaGFkb3dIYXJkTWV0aG9kXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TaGFkb3dIYXJkTWV0aG9kXCIpO1xuaW1wb3J0IFNwZWN1bGFyQW5pc290cm9waWNNZXRob2RcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NwZWN1bGFyQW5pc290cm9waWNNZXRob2RcIik7XG5pbXBvcnQgU3BlY3VsYXJDZWxNZXRob2RcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TcGVjdWxhckNlbE1ldGhvZFwiKTtcbmltcG9ydCBTcGVjdWxhclBob25nTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJQaG9uZ01ldGhvZFwiKTtcbmltcG9ydCBTaGFkb3dOZWFyTWV0aG9kXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9tYXRlcmlhbHMvbWV0aG9kcy9TaGFkb3dOZWFyTWV0aG9kXCIpO1xuaW1wb3J0IFNoYWRvd1NvZnRNZXRob2RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL21hdGVyaWFscy9tZXRob2RzL1NoYWRvd1NvZnRNZXRob2RcIik7XG5cbmltcG9ydCBBV0RCbG9ja1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvZGF0YS9BV0RCbG9ja1wiKTtcbmltcG9ydCBBV0RQcm9wZXJ0aWVzXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL2RhdGEvQVdEUHJvcGVydGllc1wiKTtcbmltcG9ydCBCaXRGbGFnc1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvZGF0YS9CaXRGbGFnc1wiKTtcblxuLyoqXG4gKiBBV0RQYXJzZXIgcHJvdmlkZXMgYSBwYXJzZXIgZm9yIHRoZSBBV0QgZGF0YSB0eXBlLlxuICovXG5jbGFzcyBBV0RQYXJzZXIgZXh0ZW5kcyBQYXJzZXJCYXNlXG57XG5cdC8vc2V0IHRvIFwidHJ1ZVwiIHRvIGhhdmUgc29tZSBjb25zb2xlLmxvZ3MgaW4gdGhlIENvbnNvbGVcblx0cHJpdmF0ZSBfZGVidWc6Ym9vbGVhbiA9IGZhbHNlO1xuXHRwcml2YXRlIF9ieXRlRGF0YTpCeXRlQXJyYXk7XG5cdHByaXZhdGUgX3N0YXJ0ZWRQYXJzaW5nOmJvb2xlYW4gPSBmYWxzZTtcblx0cHJpdmF0ZSBfY3VyX2Jsb2NrX2lkOm51bWJlcjtcblx0cHJpdmF0ZSBfYmxvY2tzOkFycmF5PEFXREJsb2NrPjtcblx0cHJpdmF0ZSBfbmV3QmxvY2tCeXRlczpCeXRlQXJyYXk7XG5cdHByaXZhdGUgX3ZlcnNpb246QXJyYXk8bnVtYmVyPjtcblx0cHJpdmF0ZSBfY29tcHJlc3Npb246bnVtYmVyO1xuXHRwcml2YXRlIF9hY2N1cmFjeU9uQmxvY2tzOmJvb2xlYW47XG5cdHByaXZhdGUgX2FjY3VyYWN5TWF0cml4OmJvb2xlYW47XG5cdHByaXZhdGUgX2FjY3VyYWN5R2VvOmJvb2xlYW47XG5cdHByaXZhdGUgX2FjY3VyYWN5UHJvcHM6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfbWF0cml4TnJUeXBlOm51bWJlcjtcblx0cHJpdmF0ZSBfZ2VvTnJUeXBlOm51bWJlcjtcblx0cHJpdmF0ZSBfcHJvcHNOclR5cGU6bnVtYmVyO1xuXHRwcml2YXRlIF9zdHJlYW1pbmc6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfdGV4dHVyZV91c2VyczpPYmplY3QgPSB7fTtcblx0cHJpdmF0ZSBfcGFyc2VkX2hlYWRlcjpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgX2JvZHk6Qnl0ZUFycmF5O1xuXHRwcml2YXRlIF9kZWZhdWx0VGV4dHVyZTpCaXRtYXBUZXh0dXJlOyAgICAgLy8gSFRNTCBJTUFHRSBURVhUVVJFID4/ICFcblx0cHJpdmF0ZSBfY3ViZVRleHR1cmVzOkFycmF5PGFueT47XG5cdHByaXZhdGUgX2RlZmF1bHRCaXRtYXBNYXRlcmlhbDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXHRwcml2YXRlIF9kZWZhdWx0Q3ViZVRleHR1cmU6Qml0bWFwQ3ViZVRleHR1cmU7XG5cblx0cHVibGljIHN0YXRpYyBDT01QUkVTU0lPTk1PREVfTFpNQTpzdHJpbmcgPSBcImx6bWFcIjtcblx0cHVibGljIHN0YXRpYyBVTkNPTVBSRVNTRUQ6bnVtYmVyID0gMDtcblx0cHVibGljIHN0YXRpYyBERUZMQVRFOm51bWJlciA9IDE7XG5cdHB1YmxpYyBzdGF0aWMgTFpNQTpudW1iZXIgPSAyO1xuXHRwdWJsaWMgc3RhdGljIElOVDg6bnVtYmVyID0gMTtcblx0cHVibGljIHN0YXRpYyBJTlQxNjpudW1iZXIgPSAyO1xuXHRwdWJsaWMgc3RhdGljIElOVDMyOm51bWJlciA9IDM7XG5cdHB1YmxpYyBzdGF0aWMgVUlOVDg6bnVtYmVyID0gNDtcblx0cHVibGljIHN0YXRpYyBVSU5UMTY6bnVtYmVyID0gNTtcblx0cHVibGljIHN0YXRpYyBVSU5UMzI6bnVtYmVyID0gNjtcblx0cHVibGljIHN0YXRpYyBGTE9BVDMyOm51bWJlciA9IDc7XG5cdHB1YmxpYyBzdGF0aWMgRkxPQVQ2NDpudW1iZXIgPSA4O1xuXHRwdWJsaWMgc3RhdGljIEJPT0w6bnVtYmVyID0gMjE7XG5cdHB1YmxpYyBzdGF0aWMgQ09MT1I6bnVtYmVyID0gMjI7XG5cdHB1YmxpYyBzdGF0aWMgQkFERFI6bnVtYmVyID0gMjM7XG5cdHB1YmxpYyBzdGF0aWMgQVdEU1RSSU5HOm51bWJlciA9IDMxO1xuXHRwdWJsaWMgc3RhdGljIEFXREJZVEVBUlJBWTpudW1iZXIgPSAzMjtcblx0cHVibGljIHN0YXRpYyBWRUNUT1IyeDE6bnVtYmVyID0gNDE7XG5cdHB1YmxpYyBzdGF0aWMgVkVDVE9SM3gxOm51bWJlciA9IDQyO1xuXHRwdWJsaWMgc3RhdGljIFZFQ1RPUjR4MTpudW1iZXIgPSA0Mztcblx0cHVibGljIHN0YXRpYyBNVFgzeDI6bnVtYmVyID0gNDQ7XG5cdHB1YmxpYyBzdGF0aWMgTVRYM3gzOm51bWJlciA9IDQ1O1xuXHRwdWJsaWMgc3RhdGljIE1UWDR4MzpudW1iZXIgPSA0Njtcblx0cHVibGljIHN0YXRpYyBNVFg0eDQ6bnVtYmVyID0gNDc7XG5cblx0cHJpdmF0ZSBibGVuZE1vZGVEaWM6QXJyYXk8c3RyaW5nPjtcblx0cHJpdmF0ZSBfZGVwdGhTaXplRGljOkFycmF5PG51bWJlcj47XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgQVdEUGFyc2VyIG9iamVjdC5cblx0ICogQHBhcmFtIHVyaSBUaGUgdXJsIG9yIGlkIG9mIHRoZSBkYXRhIG9yIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcGFyYW0gZXh0cmEgVGhlIGhvbGRlciBmb3IgZXh0cmEgY29udGV4dHVhbCBkYXRhIHRoYXQgdGhlIHBhcnNlciBtaWdodCBuZWVkLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0c3VwZXIoVVJMTG9hZGVyRGF0YUZvcm1hdC5BUlJBWV9CVUZGRVIpO1xuXG5cdFx0dGhpcy5fYmxvY2tzID0gbmV3IEFycmF5PEFXREJsb2NrPigpO1xuXHRcdHRoaXMuX2Jsb2Nrc1swXSA9IG5ldyBBV0RCbG9jaygpO1xuXHRcdHRoaXMuX2Jsb2Nrc1swXS5kYXRhID0gbnVsbDsgLy8gWmVybyBhZGRyZXNzIG1lYW5zIG51bGwgaW4gQVdEXG5cblx0XHR0aGlzLmJsZW5kTW9kZURpYyA9IG5ldyBBcnJheTxzdHJpbmc+KCk7IC8vIHVzZWQgdG8gdHJhbnNsYXRlIGludHMgdG8gYmxlbmRNb2RlLXN0cmluZ3Ncblx0XHR0aGlzLmJsZW5kTW9kZURpYy5wdXNoKEJsZW5kTW9kZS5OT1JNQUwpO1xuXHRcdHRoaXMuYmxlbmRNb2RlRGljLnB1c2goQmxlbmRNb2RlLkFERCk7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuQUxQSEEpO1xuXHRcdHRoaXMuYmxlbmRNb2RlRGljLnB1c2goQmxlbmRNb2RlLkRBUktFTik7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuRElGRkVSRU5DRSk7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuRVJBU0UpO1xuXHRcdHRoaXMuYmxlbmRNb2RlRGljLnB1c2goQmxlbmRNb2RlLkhBUkRMSUdIVCk7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuSU5WRVJUKTtcblx0XHR0aGlzLmJsZW5kTW9kZURpYy5wdXNoKEJsZW5kTW9kZS5MQVlFUik7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuTElHSFRFTik7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuTVVMVElQTFkpO1xuXHRcdHRoaXMuYmxlbmRNb2RlRGljLnB1c2goQmxlbmRNb2RlLk5PUk1BTCk7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuT1ZFUkxBWSk7XG5cdFx0dGhpcy5ibGVuZE1vZGVEaWMucHVzaChCbGVuZE1vZGUuU0NSRUVOKTtcblx0XHR0aGlzLmJsZW5kTW9kZURpYy5wdXNoKEJsZW5kTW9kZS5TSEFERVIpO1xuXHRcdHRoaXMuYmxlbmRNb2RlRGljLnB1c2goQmxlbmRNb2RlLk9WRVJMQVkpO1xuXG5cdFx0dGhpcy5fZGVwdGhTaXplRGljID0gbmV3IEFycmF5PG51bWJlcj4oKTsgLy8gdXNlZCB0byB0cmFuc2xhdGUgaW50cyB0byBkZXB0aFNpemUtdmFsdWVzXG5cdFx0dGhpcy5fZGVwdGhTaXplRGljLnB1c2goMjU2KTtcblx0XHR0aGlzLl9kZXB0aFNpemVEaWMucHVzaCg1MTIpO1xuXHRcdHRoaXMuX2RlcHRoU2l6ZURpYy5wdXNoKDIwNDgpO1xuXHRcdHRoaXMuX2RlcHRoU2l6ZURpYy5wdXNoKDEwMjQpO1xuXHRcdHRoaXMuX3ZlcnNpb24gPSBBcnJheTxudW1iZXI+KCk7IC8vIHdpbGwgY29udGFpbiAyIGludCAobWFqb3ItdmVyc2lvbiwgbWlub3ItdmVyc2lvbikgZm9yIGF3ZC12ZXJzaW9uLWNoZWNrXG5cdH1cblxuXHQvKipcblx0ICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gZmlsZSBleHRlbnNpb24gaXMgc3VwcG9ydGVkIGJ5IHRoZSBwYXJzZXIuXG5cdCAqIEBwYXJhbSBleHRlbnNpb24gVGhlIGZpbGUgZXh0ZW5zaW9uIG9mIGEgcG90ZW50aWFsIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBmaWxlIHR5cGUgaXMgc3VwcG9ydGVkLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBzdXBwb3J0c1R5cGUoZXh0ZW5zaW9uOnN0cmluZyk6Ym9vbGVhblxuXHR7XG5cdFx0ZXh0ZW5zaW9uID0gZXh0ZW5zaW9uLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIGV4dGVuc2lvbiA9PSBcImF3ZFwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gKFBhcnNlclV0aWxzLnRvU3RyaW5nKGRhdGEsIDMpID09ICdBV0QnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pUmVzb2x2ZURlcGVuZGVuY3kocmVzb3VyY2VEZXBlbmRlbmN5OlJlc291cmNlRGVwZW5kZW5jeSk6dm9pZFxuXHR7XG5cdFx0Ly8gdGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIERlcGVuZGVuY3kgaGFzIGZpbmlzaGVkIGxvYWRpbmcuXG5cdFx0Ly8gdGhlIEFzc2V0cyB3YWl0aW5nIGZvciB0aGlzIEJpdG1hcCwgY2FuIGJlIFRleHR1cmUgb3IgQ3ViZVRleHR1cmUuXG5cdFx0Ly8gaWYgdGhlIEJpdG1hcCBpcyBhd2FpdGVkIGJ5IGEgQ3ViZVRleHR1cmUsIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXRzIHRoZSBsYXN0IEJpdG1hcCBvZiB0aGUgQ3ViZVRleHR1cmUsXG5cdFx0Ly8gc28gd2Uga25vdyBpZiB3ZSBoYXZlIHRvIGZpbmFsaXplIHRoZSBBc3NldCAoQ3ViZVRleHR1cmUpIG9yIG5vdC5cblx0XHRpZiAocmVzb3VyY2VEZXBlbmRlbmN5LmFzc2V0cy5sZW5ndGggPT0gMSkge1xuXHRcdFx0dmFyIGlzQ3ViZVRleHR1cmVBcnJheTpBcnJheTxzdHJpbmc+ID0gcmVzb3VyY2VEZXBlbmRlbmN5LmlkLnNwbGl0KFwiI1wiKTtcblx0XHRcdHZhciByZXNzb3VyY2VJRDpzdHJpbmcgPSBpc0N1YmVUZXh0dXJlQXJyYXlbMF07XG5cdFx0XHR2YXIgYXNzZXQ6VGV4dHVyZVByb3h5QmFzZTtcblx0XHRcdHZhciB0aGlzQml0bWFwVGV4dHVyZTpUZXh0dXJlMkRCYXNlO1xuXHRcdFx0dmFyIGJsb2NrOkFXREJsb2NrO1xuXG5cdFx0XHRpZiAoaXNDdWJlVGV4dHVyZUFycmF5Lmxlbmd0aCA9PSAxKSAvLyBOb3QgYSBjdWJlIHRleHR1cmVcblx0XHRcdHtcblx0XHRcdFx0YXNzZXQgPSA8VGV4dHVyZTJEQmFzZT4gcmVzb3VyY2VEZXBlbmRlbmN5LmFzc2V0c1swXTtcblx0XHRcdFx0aWYgKGFzc2V0KSB7XG5cdFx0XHRcdFx0dmFyIG1hdDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXHRcdFx0XHRcdHZhciB1c2VyczpBcnJheTxzdHJpbmc+O1xuXG5cdFx0XHRcdFx0YmxvY2sgPSB0aGlzLl9ibG9ja3NbIHJlc291cmNlRGVwZW5kZW5jeS5pZCBdO1xuXHRcdFx0XHRcdGJsb2NrLmRhdGEgPSBhc3NldDsgLy8gU3RvcmUgZmluaXNoZWQgYXNzZXRcblxuXHRcdFx0XHRcdC8vIFJlc2V0IG5hbWUgb2YgdGV4dHVyZSB0byB0aGUgb25lIGRlZmluZWQgaW4gdGhlIEFXRCBmaWxlLFxuXHRcdFx0XHRcdC8vIGFzIG9wcG9zZWQgdG8gd2hhdGV2ZXIgdGhlIGltYWdlIHBhcnNlciBjYW1lIHVwIHdpdGguXG5cdFx0XHRcdFx0YXNzZXQucmVzZXRBc3NldFBhdGgoYmxvY2submFtZSwgbnVsbCwgdHJ1ZSk7XG5cdFx0XHRcdFx0YmxvY2submFtZSA9IGFzc2V0Lm5hbWU7XG5cdFx0XHRcdFx0Ly8gRmluYWxpemUgdGV4dHVyZSBhc3NldCB0byBkaXNwYXRjaCB0ZXh0dXJlIGV2ZW50LCB3aGljaCB3YXNcblx0XHRcdFx0XHQvLyBwcmV2aW91c2x5IHN1cHByZXNzZWQgd2hpbGUgdGhlIGRlcGVuZGVuY3kgd2FzIGxvYWRlZC5cblx0XHRcdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldCg8SUFzc2V0PiBhc3NldCk7XG5cblx0XHRcdFx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiU3VjY2Vzc2Z1bGx5IGxvYWRlZCBCaXRtYXAgZm9yIHRleHR1cmVcIik7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCB0ZXh0dXJlOiBOYW1lID0gXCIgKyBibG9jay5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKGlzQ3ViZVRleHR1cmVBcnJheS5sZW5ndGggPiAxKSAvLyBDdWJlIFRleHR1cmVcblx0XHRcdHtcblx0XHRcdFx0dGhpc0JpdG1hcFRleHR1cmUgPSA8Qml0bWFwVGV4dHVyZT4gcmVzb3VyY2VEZXBlbmRlbmN5LmFzc2V0c1swXTtcblxuXHRcdFx0XHR2YXIgdHg6SW1hZ2VUZXh0dXJlID0gPEltYWdlVGV4dHVyZT4gdGhpc0JpdG1hcFRleHR1cmU7XG5cblx0XHRcdFx0dGhpcy5fY3ViZVRleHR1cmVzWyBpc0N1YmVUZXh0dXJlQXJyYXlbMV0gXSA9IHR4Lmh0bWxJbWFnZUVsZW1lbnQ7IC8vID9cblx0XHRcdFx0dGhpcy5fdGV4dHVyZV91c2Vyc1tyZXNzb3VyY2VJRF0ucHVzaCgxKTtcblxuXHRcdFx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIlN1Y2Nlc3NmdWxseSBsb2FkZWQgQml0bWFwIFwiICsgdGhpcy5fdGV4dHVyZV91c2Vyc1tyZXNzb3VyY2VJRF0ubGVuZ3RoICsgXCIgLyA2IGZvciBDdWJldGV4dHVyZVwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGhpcy5fdGV4dHVyZV91c2Vyc1tyZXNzb3VyY2VJRF0ubGVuZ3RoID09IHRoaXMuX2N1YmVUZXh0dXJlcy5sZW5ndGgpIHtcblxuXHRcdFx0XHRcdHZhciBwb3NYOmFueSA9IHRoaXMuX2N1YmVUZXh0dXJlc1swXTtcblx0XHRcdFx0XHR2YXIgbmVnWDphbnkgPSB0aGlzLl9jdWJlVGV4dHVyZXNbMV07XG5cdFx0XHRcdFx0dmFyIHBvc1k6YW55ID0gdGhpcy5fY3ViZVRleHR1cmVzWzJdO1xuXHRcdFx0XHRcdHZhciBuZWdZOmFueSA9IHRoaXMuX2N1YmVUZXh0dXJlc1szXTtcblx0XHRcdFx0XHR2YXIgcG9zWjphbnkgPSB0aGlzLl9jdWJlVGV4dHVyZXNbNF07XG5cdFx0XHRcdFx0dmFyIG5lZ1o6YW55ID0gdGhpcy5fY3ViZVRleHR1cmVzWzVdO1xuXG5cdFx0XHRcdFx0YXNzZXQgPSA8VGV4dHVyZVByb3h5QmFzZT4gbmV3IEltYWdlQ3ViZVRleHR1cmUocG9zWCwgbmVnWCwgcG9zWSwgbmVnWSwgcG9zWiwgbmVnWik7XG5cdFx0XHRcdFx0YmxvY2sgPSB0aGlzLl9ibG9ja3NbcmVzc291cmNlSURdO1xuXHRcdFx0XHRcdGJsb2NrLmRhdGEgPSBhc3NldDsgLy8gU3RvcmUgZmluaXNoZWQgYXNzZXRcblxuXHRcdFx0XHRcdC8vIFJlc2V0IG5hbWUgb2YgdGV4dHVyZSB0byB0aGUgb25lIGRlZmluZWQgaW4gdGhlIEFXRCBmaWxlLFxuXHRcdFx0XHRcdC8vIGFzIG9wcG9zZWQgdG8gd2hhdGV2ZXIgdGhlIGltYWdlIHBhcnNlciBjYW1lIHVwIHdpdGguXG5cdFx0XHRcdFx0YXNzZXQucmVzZXRBc3NldFBhdGgoYmxvY2submFtZSwgbnVsbCwgdHJ1ZSk7XG5cdFx0XHRcdFx0YmxvY2submFtZSA9IGFzc2V0Lm5hbWU7XG5cdFx0XHRcdFx0Ly8gRmluYWxpemUgdGV4dHVyZSBhc3NldCB0byBkaXNwYXRjaCB0ZXh0dXJlIGV2ZW50LCB3aGljaCB3YXNcblx0XHRcdFx0XHQvLyBwcmV2aW91c2x5IHN1cHByZXNzZWQgd2hpbGUgdGhlIGRlcGVuZGVuY3kgd2FzIGxvYWRlZC5cblx0XHRcdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldCg8SUFzc2V0PiBhc3NldCk7XG5cdFx0XHRcdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBDdWJlVGV4dHVyZTogTmFtZSA9IFwiICsgYmxvY2submFtZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVJlc29sdmVEZXBlbmRlbmN5RmFpbHVyZShyZXNvdXJjZURlcGVuZGVuY3k6UmVzb3VyY2VEZXBlbmRlbmN5KTp2b2lkXG5cdHtcblx0XHQvL25vdCB1c2VkIC0gaWYgYSBkZXBlbmRjeSBmYWlscywgdGhlIGF3YWl0aW5nIFRleHR1cmUgb3IgQ3ViZVRleHR1cmUgd2lsbCBuZXZlciBiZSBmaW5hbGl6ZWQsIGFuZCB0aGUgZGVmYXVsdC1iaXRtYXBzIHdpbGwgYmUgdXNlZC5cblx0XHQvLyB0aGlzIG1lYW5zLCB0aGF0IGlmIG9uZSBCaXRtYXAgb2YgYSBDdWJlVGV4dHVyZSBmYWlscywgdGhlIEN1YmVUZXh0dXJlIHdpbGwgaGF2ZSB0aGUgRGVmYXVsdFRleHR1cmUgYXBwbGllZCBmb3IgYWxsIHNpeCBCaXRtYXBzLlxuXHR9XG5cblx0LyoqXG5cdCAqIFJlc29sdmUgYSBkZXBlbmRlbmN5IG5hbWVcblx0ICpcblx0ICogQHBhcmFtIHJlc291cmNlRGVwZW5kZW5jeSBUaGUgZGVwZW5kZW5jeSB0byBiZSByZXNvbHZlZC5cblx0ICovXG5cdHB1YmxpYyBfaVJlc29sdmVEZXBlbmRlbmN5TmFtZShyZXNvdXJjZURlcGVuZGVuY3k6UmVzb3VyY2VEZXBlbmRlbmN5LCBhc3NldDpJQXNzZXQpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIG9sZE5hbWU6c3RyaW5nID0gYXNzZXQubmFtZTtcblxuXHRcdGlmIChhc3NldCkge1xuXHRcdFx0dmFyIGJsb2NrOkFXREJsb2NrID0gdGhpcy5fYmxvY2tzW3BhcnNlSW50KHJlc291cmNlRGVwZW5kZW5jeS5pZCldO1xuXHRcdFx0Ly8gUmVzZXQgbmFtZSBvZiB0ZXh0dXJlIHRvIHRoZSBvbmUgZGVmaW5lZCBpbiB0aGUgQVdEIGZpbGUsXG5cdFx0XHQvLyBhcyBvcHBvc2VkIHRvIHdoYXRldmVyIHRoZSBpbWFnZSBwYXJzZXIgY2FtZSB1cCB3aXRoLlxuXHRcdFx0YXNzZXQucmVzZXRBc3NldFBhdGgoYmxvY2submFtZSwgbnVsbCwgdHJ1ZSk7XG5cdFx0fVxuXG5cdFx0dmFyIG5ld05hbWU6c3RyaW5nID0gYXNzZXQubmFtZTtcblxuXHRcdGFzc2V0Lm5hbWUgPSBvbGROYW1lO1xuXG5cdFx0cmV0dXJuIG5ld05hbWU7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wUHJvY2VlZFBhcnNpbmcoKTpib29sZWFuXG5cdHtcblxuXHRcdGlmICghdGhpcy5fc3RhcnRlZFBhcnNpbmcpIHtcblx0XHRcdHRoaXMuX2J5dGVEYXRhID0gdGhpcy5fcEdldEJ5dGVEYXRhKCk7Ly9nZXRCeXRlRGF0YSgpO1xuXHRcdFx0dGhpcy5fc3RhcnRlZFBhcnNpbmcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICghdGhpcy5fcGFyc2VkX2hlYWRlcikge1xuXG5cdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdC8vIExJVFRMRV9FTkRJQU4gLSBEZWZhdWx0IGZvciBBcnJheUJ1ZmZlciAvIE5vdCBpbXBsZW1lbnRlZCBpbiBCeXRlQXJyYXlcblx0XHRcdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdFx0Ly90aGlzLl9ieXRlRGF0YS5lbmRpYW4gPSBFbmRpYW4uTElUVExFX0VORElBTjtcblx0XHRcdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdC8vIFBhcnNlIGhlYWRlciBhbmQgZGVjb21wcmVzcyBib2R5IGlmIG5lZWRlZFxuXHRcdFx0dGhpcy5wYXJzZUhlYWRlcigpO1xuXG5cdFx0XHRzd2l0Y2ggKHRoaXMuX2NvbXByZXNzaW9uKSB7XG5cblx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuREVGTEFURTpcblx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuTFpNQTpcblx0XHRcdFx0XHR0aGlzLl9wRGllV2l0aEVycm9yKCdDb21wcmVzc2VkIEFXRCBmb3JtYXRzIG5vdCB5ZXQgc3VwcG9ydGVkJyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuVU5DT01QUkVTU0VEOlxuXHRcdFx0XHRcdHRoaXMuX2JvZHkgPSB0aGlzLl9ieXRlRGF0YTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdFx0Ly8gQ29tcHJlc3NlZCBBV0QgRm9ybWF0cyBub3QgeWV0IHN1cHBvcnRlZFxuXHRcdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRcdFx0XHQvKlxuXHRcdFx0XHQgY2FzZSBBV0RQYXJzZXIuREVGTEFURTpcblxuXHRcdFx0XHQgdGhpcy5fYm9keSA9IG5ldyBCeXRlQXJyYXkoKTtcblx0XHRcdFx0IHRoaXMuX2J5dGVEYXRhLnJlYWRCeXRlcyh0aGlzLl9ib2R5LCAwLCB0aGlzLl9ieXRlRGF0YS5nZXRCeXRlc0F2YWlsYWJsZSgpKTtcblx0XHRcdFx0IHRoaXMuX2JvZHkudW5jb21wcmVzcygpO1xuXG5cdFx0XHRcdCBicmVhaztcblx0XHRcdFx0IGNhc2UgQVdEUGFyc2VyLkxaTUE6XG5cblx0XHRcdFx0IHRoaXMuX2JvZHkgPSBuZXcgQnl0ZUFycmF5KCk7XG5cdFx0XHRcdCB0aGlzLl9ieXRlRGF0YS5yZWFkQnl0ZXModGhpcy5fYm9keSwgMCwgdGhpcy5fYnl0ZURhdGEuZ2V0Qnl0ZXNBdmFpbGFibGUoKSk7XG5cdFx0XHRcdCB0aGlzLl9ib2R5LnVuY29tcHJlc3MoQ09NUFJFU1NJT05NT0RFX0xaTUEpO1xuXG5cdFx0XHRcdCBicmVhaztcblx0XHRcdFx0IC8vKi9cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9wYXJzZWRfaGVhZGVyID0gdHJ1ZTtcblxuXHRcdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0XHQvLyBMSVRUTEVfRU5ESUFOIC0gRGVmYXVsdCBmb3IgQXJyYXlCdWZmZXIgLyBOb3QgaW1wbGVtZW50ZWQgaW4gQnl0ZUFycmF5XG5cdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdC8vdGhpcy5fYm9keS5lbmRpYW4gPSBFbmRpYW4uTElUVExFX0VORElBTjsvLyBTaG91bGQgYmUgZGVmYXVsdFxuXHRcdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0XHR9XG5cblx0XHRpZiAodGhpcy5fYm9keSkge1xuXG5cdFx0XHR3aGlsZSAodGhpcy5fYm9keS5nZXRCeXRlc0F2YWlsYWJsZSgpID4gMCAmJiAhdGhpcy5wYXJzaW5nUGF1c2VkKSAvLyYmIHRoaXMuX3BIYXNUaW1lKCkgKVxuXHRcdFx0e1xuXHRcdFx0XHR0aGlzLnBhcnNlTmV4dEJsb2NrKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0XHQvLyBSZXR1cm4gY29tcGxldGUgc3RhdHVzXG5cdFx0XHRpZiAodGhpcy5fYm9keS5nZXRCeXRlc0F2YWlsYWJsZSgpID09IDApIHtcblx0XHRcdFx0dGhpcy5kaXNwb3NlKCk7XG5cdFx0XHRcdHJldHVybiAgUGFyc2VyQmFzZS5QQVJTSU5HX0RPTkU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gIFBhcnNlckJhc2UuTU9SRV9UT19QQVJTRTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRzd2l0Y2ggKHRoaXMuX2NvbXByZXNzaW9uKSB7XG5cblx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuREVGTEFURTpcblx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuTFpNQTpcblxuXHRcdFx0XHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0XHRcdFx0Y29uc29sZS5sb2coXCIoISkgQVdEUGFyc2VyIEVycm9yOiBDb21wcmVzc2VkIEFXRCBmb3JtYXRzIG5vdCB5ZXQgc3VwcG9ydGVkICghKVwiKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0fVxuXHRcdFx0Ly8gRXJyb3IgLSBtb3N0IGxpa2VseSBfYm9keSBub3Qgc2V0IGJlY2F1c2Ugd2UgZG8gbm90IHN1cHBvcnQgY29tcHJlc3Npb24uXG5cdFx0XHRyZXR1cm4gIFBhcnNlckJhc2UuUEFSU0lOR19ET05FO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRwdWJsaWMgX3BTdGFydFBhcnNpbmcoZnJhbWVMaW1pdDpudW1iZXIpXG5cdHtcblx0XHRzdXBlci5fcFN0YXJ0UGFyc2luZyhmcmFtZUxpbWl0KTtcblxuXHRcdC8vY3JlYXRlIGEgY29udGVudCBvYmplY3QgZm9yIExvYWRlcnNcblx0XHR0aGlzLl9wQ29udGVudCA9IG5ldyBEaXNwbGF5T2JqZWN0Q29udGFpbmVyKCk7XG5cdH1cblxuXHRwcml2YXRlIGRpc3Bvc2UoKTp2b2lkXG5cdHtcblxuXHRcdGZvciAodmFyIGMgaW4gdGhpcy5fYmxvY2tzKSB7XG5cblx0XHRcdHZhciBiOkFXREJsb2NrID0gPEFXREJsb2NrPiB0aGlzLl9ibG9ja3NbIGMgXTtcblx0XHRcdGIuZGlzcG9zZSgpO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRwcml2YXRlIHBhcnNlTmV4dEJsb2NrKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGJsb2NrOkFXREJsb2NrO1xuXHRcdHZhciBhc3NldERhdGE6SUFzc2V0O1xuXHRcdHZhciBpc1BhcnNlZDpib29sZWFuID0gZmFsc2U7XG5cdFx0dmFyIG5zOm51bWJlcjtcblx0XHR2YXIgdHlwZTpudW1iZXI7XG5cdFx0dmFyIGZsYWdzOm51bWJlcjtcblx0XHR2YXIgbGVuOm51bWJlcjtcblxuXHRcdHRoaXMuX2N1cl9ibG9ja19pZCA9IHRoaXMuX2JvZHkucmVhZFVuc2lnbmVkSW50KCk7XG5cblx0XHRucyA9IHRoaXMuX2JvZHkucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdHR5cGUgPSB0aGlzLl9ib2R5LnJlYWRVbnNpZ25lZEJ5dGUoKTtcblx0XHRmbGFncyA9IHRoaXMuX2JvZHkucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdGxlbiA9IHRoaXMuX2JvZHkucmVhZFVuc2lnbmVkSW50KCk7XG5cblx0XHR2YXIgYmxvY2tDb21wcmVzc2lvbjpib29sZWFuID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzQpO1xuXHRcdHZhciBibG9ja0NvbXByZXNzaW9uTFpNQTpib29sZWFuID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzUpO1xuXG5cdFx0aWYgKHRoaXMuX2FjY3VyYWN5T25CbG9ja3MpIHtcblx0XHRcdHRoaXMuX2FjY3VyYWN5TWF0cml4ID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzEpO1xuXHRcdFx0dGhpcy5fYWNjdXJhY3lHZW8gPSBCaXRGbGFncy50ZXN0KGZsYWdzLCBCaXRGbGFncy5GTEFHMik7XG5cdFx0XHR0aGlzLl9hY2N1cmFjeVByb3BzID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzMpO1xuXHRcdFx0dGhpcy5fZ2VvTnJUeXBlID0gQVdEUGFyc2VyLkZMT0FUMzI7XG5cblx0XHRcdGlmICh0aGlzLl9hY2N1cmFjeUdlbykge1xuXHRcdFx0XHR0aGlzLl9nZW9OclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQ2NDtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fbWF0cml4TnJUeXBlID0gQVdEUGFyc2VyLkZMT0FUMzI7XG5cblx0XHRcdGlmICh0aGlzLl9hY2N1cmFjeU1hdHJpeCkge1xuXHRcdFx0XHR0aGlzLl9tYXRyaXhOclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQ2NDtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fcHJvcHNOclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQzMjtcblxuXHRcdFx0aWYgKHRoaXMuX2FjY3VyYWN5UHJvcHMpIHtcblx0XHRcdFx0dGhpcy5fcHJvcHNOclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQ2NDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgYmxvY2tFbmRBbGw6bnVtYmVyID0gdGhpcy5fYm9keS5wb3NpdGlvbiArIGxlbjtcblxuXHRcdGlmIChsZW4gPiB0aGlzLl9ib2R5LmdldEJ5dGVzQXZhaWxhYmxlKCkpIHtcblx0XHRcdHRoaXMuX3BEaWVXaXRoRXJyb3IoJ0FXRDIgYmxvY2sgbGVuZ3RoIGlzIGJpZ2dlciB0aGFuIHRoZSBieXRlcyB0aGF0IGFyZSBhdmFpbGFibGUhJyk7XG5cdFx0XHR0aGlzLl9ib2R5LnBvc2l0aW9uICs9IHRoaXMuX2JvZHkuZ2V0Qnl0ZXNBdmFpbGFibGUoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5fbmV3QmxvY2tCeXRlcyA9IG5ldyBCeXRlQXJyYXkoKTtcblxuXG5cdFx0dGhpcy5fYm9keS5yZWFkQnl0ZXModGhpcy5fbmV3QmxvY2tCeXRlcywgMCwgbGVuKTtcblxuXHRcdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdC8vIENvbXByZXNzZWQgQVdEIEZvcm1hdHMgbm90IHlldCBzdXBwb3J0ZWRcblxuXHRcdGlmIChibG9ja0NvbXByZXNzaW9uKSB7XG5cdFx0XHR0aGlzLl9wRGllV2l0aEVycm9yKCdDb21wcmVzc2VkIEFXRCBmb3JtYXRzIG5vdCB5ZXQgc3VwcG9ydGVkJyk7XG5cblx0XHRcdC8qXG5cdFx0XHQgaWYgKGJsb2NrQ29tcHJlc3Npb25MWk1BKVxuXHRcdFx0IHtcblx0XHRcdCB0aGlzLl9uZXdCbG9ja0J5dGVzLnVuY29tcHJlc3MoQVdEUGFyc2VyLkNPTVBSRVNTSU9OTU9ERV9MWk1BKTtcblx0XHRcdCB9XG5cdFx0XHQgZWxzZVxuXHRcdFx0IHtcblx0XHRcdCB0aGlzLl9uZXdCbG9ja0J5dGVzLnVuY29tcHJlc3MoKTtcblx0XHRcdCB9XG5cdFx0XHQgKi9cblxuXHRcdH1cblxuXHRcdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdC8vIExJVFRMRV9FTkRJQU4gLSBEZWZhdWx0IGZvciBBcnJheUJ1ZmZlciAvIE5vdCBpbXBsZW1lbnRlZCBpbiBCeXRlQXJyYXlcblx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHQvL3RoaXMuX25ld0Jsb2NrQnl0ZXMuZW5kaWFuID0gRW5kaWFuLkxJVFRMRV9FTkRJQU47XG5cdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uID0gMDtcblx0XHRibG9jayA9IG5ldyBBV0RCbG9jaygpO1xuXHRcdGJsb2NrLmxlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gKyBsZW47XG5cdFx0YmxvY2suaWQgPSB0aGlzLl9jdXJfYmxvY2tfaWQ7XG5cblx0XHR2YXIgYmxvY2tFbmRCbG9jazpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uICsgbGVuO1xuXG5cdFx0aWYgKGJsb2NrQ29tcHJlc3Npb24pIHtcblx0XHRcdHRoaXMuX3BEaWVXaXRoRXJyb3IoJ0NvbXByZXNzZWQgQVdEIGZvcm1hdHMgbm90IHlldCBzdXBwb3J0ZWQnKTtcblx0XHRcdC8vYmxvY2tFbmRCbG9jayAgID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiArIHRoaXMuX25ld0Jsb2NrQnl0ZXMubGVuZ3RoO1xuXHRcdFx0Ly9ibG9jay5sZW4gICAgICAgPSBibG9ja0VuZEJsb2NrO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coXCJBV0RCbG9jazogIElEID0gXCIgKyB0aGlzLl9jdXJfYmxvY2tfaWQgKyBcIiB8IFR5cGVJRCA9IFwiICsgdHlwZSArIFwiIHwgQ29tcHJlc3Npb24gPSBcIiArIGJsb2NrQ29tcHJlc3Npb24gKyBcIiB8IE1hdHJpeC1QcmVjaXNpb24gPSBcIiArIHRoaXMuX2FjY3VyYWN5TWF0cml4ICsgXCIgfCBHZW9tZXRyeS1QcmVjaXNpb24gPSBcIiArIHRoaXMuX2FjY3VyYWN5R2VvICsgXCIgfCBQcm9wZXJ0aWVzLVByZWNpc2lvbiA9IFwiICsgdGhpcy5fYWNjdXJhY3lQcm9wcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fYmxvY2tzW3RoaXMuX2N1cl9ibG9ja19pZF0gPSBibG9jaztcblxuXHRcdGlmICgodGhpcy5fdmVyc2lvblswXSA9PSAyKSAmJiAodGhpcy5fdmVyc2lvblsxXSA9PSAxKSkge1xuXG5cdFx0XHRzd2l0Y2ggKHR5cGUpIHtcblx0XHRcdFx0Y2FzZSAxMTpcblx0XHRcdFx0XHR0aGlzLnBhcnNlUHJpbWl0dmVzKHRoaXMuX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdFx0aXNQYXJzZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDMxOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VTa3lib3hJbnN0YW5jZSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGlzUGFyc2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSA0MTpcblx0XHRcdFx0XHR0aGlzLnBhcnNlTGlnaHQodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRpc1BhcnNlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgNDI6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUNhbWVyYSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGlzUGFyc2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHQvLyAgY2FzZSA0Mzpcblx0XHRcdFx0Ly8gICAgICBwYXJzZVRleHR1cmVQcm9qZWN0b3IoX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdC8vICAgICAgaXNQYXJzZWQgPSB0cnVlO1xuXHRcdFx0XHQvLyAgICAgIGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgNTE6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUxpZ2h0UGlja2VyKHRoaXMuX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdFx0aXNQYXJzZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDgxOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VNYXRlcmlhbF92MSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGlzUGFyc2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSA4Mzpcblx0XHRcdFx0XHR0aGlzLnBhcnNlQ3ViZVRleHR1cmUodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRpc1BhcnNlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgOTE6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZVNoYXJlZE1ldGhvZEJsb2NrKHRoaXMuX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdFx0aXNQYXJzZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDkyOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VTaGFkb3dNZXRob2RCbG9jayh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGlzUGFyc2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAxMTE6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZU1lc2hQb3NlQW5pbWF0aW9uKHRoaXMuX2N1cl9ibG9ja19pZCwgdHJ1ZSk7XG5cdFx0XHRcdFx0aXNQYXJzZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDExMjpcblx0XHRcdFx0XHR0aGlzLnBhcnNlTWVzaFBvc2VBbmltYXRpb24odGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRpc1BhcnNlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMTEzOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VWZXJ0ZXhBbmltYXRpb25TZXQodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRpc1BhcnNlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMTIyOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VBbmltYXRvclNldCh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGlzUGFyc2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAyNTM6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUNvbW1hbmQodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRpc1BhcnNlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHQvLyovXG5cdFx0fVxuXHRcdC8vKlxuXHRcdGlmIChpc1BhcnNlZCA9PSBmYWxzZSkge1xuXHRcdFx0c3dpdGNoICh0eXBlKSB7XG5cblx0XHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VUcmlhbmdsZUdlb21ldHJpZUJsb2NrKHRoaXMuX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMjI6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUNvbnRhaW5lcih0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDIzOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VNZXNoSW5zdGFuY2UodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSA4MTpcblx0XHRcdFx0XHR0aGlzLnBhcnNlTWF0ZXJpYWwodGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSA4Mjpcblx0XHRcdFx0XHR0aGlzLnBhcnNlVGV4dHVyZSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDEwMTpcblx0XHRcdFx0XHR0aGlzLnBhcnNlU2tlbGV0b24odGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAxMDI6XG5cdFx0XHRcdFx0dGhpcy5wYXJzZVNrZWxldG9uUG9zZSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDEwMzpcblx0XHRcdFx0XHR0aGlzLnBhcnNlU2tlbGV0b25BbmltYXRpb24odGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAxMjE6XG5cdFx0XHRcdFx0Ly90aGlzLnBhcnNlVVZBbmltYXRpb24odGhpcy5fY3VyX2Jsb2NrX2lkKTtcblx0XHRcdFx0XHQvL2JyZWFrO1xuXHRcdFx0XHRjYXNlIDI1NDpcblx0XHRcdFx0XHR0aGlzLnBhcnNlTmFtZVNwYWNlKHRoaXMuX2N1cl9ibG9ja19pZCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMjU1OlxuXHRcdFx0XHRcdHRoaXMucGFyc2VNZXRhRGF0YSh0aGlzLl9jdXJfYmxvY2tfaWQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0XHRcdFx0Y29uc29sZS5sb2coXCJBV0RCbG9jazogICBVbmtub3duIEJsb2NrVHlwZSAgKEJsb2NrSUQgPSBcIiArIHRoaXMuX2N1cl9ibG9ja19pZCArIFwiKSAtIFNraXAgXCIgKyBsZW4gKyBcIiBieXRlc1wiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiArPSBsZW47XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vKi9cblxuXHRcdHZhciBtc2dDbnQ6bnVtYmVyID0gMDtcblx0XHRpZiAodGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiA9PSBibG9ja0VuZEJsb2NrKSB7XG5cdFx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdFx0aWYgKGJsb2NrLmVycm9yTWVzc2FnZXMpIHtcblx0XHRcdFx0XHR3aGlsZSAobXNnQ250IDwgYmxvY2suZXJyb3JNZXNzYWdlcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiICAgICAgICAoISkgRXJyb3I6IFwiICsgYmxvY2suZXJyb3JNZXNzYWdlc1ttc2dDbnRdICsgXCIgKCEpXCIpO1xuXHRcdFx0XHRcdFx0bXNnQ250Kys7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdFx0Y29uc29sZS5sb2coXCJcXG5cIik7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXG5cdFx0XHRcdGNvbnNvbGUubG9nKFwiICAoISkoISkoISkgRXJyb3Igd2hpbGUgcmVhZGluZyBBV0RCbG9jayBJRCBcIiArIHRoaXMuX2N1cl9ibG9ja19pZCArIFwiID0gc2tpcCB0byBuZXh0IGJsb2NrXCIpO1xuXG5cdFx0XHRcdGlmIChibG9jay5lcnJvck1lc3NhZ2VzKSB7XG5cdFx0XHRcdFx0d2hpbGUgKG1zZ0NudCA8IGJsb2NrLmVycm9yTWVzc2FnZXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIiAgICAgICAgKCEpIEVycm9yOiBcIiArIGJsb2NrLmVycm9yTWVzc2FnZXNbbXNnQ250XSArIFwiICghKVwiKTtcblx0XHRcdFx0XHRcdG1zZ0NudCsrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuX2JvZHkucG9zaXRpb24gPSBibG9ja0VuZEFsbDtcblx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzID0gbnVsbDtcblxuXHR9XG5cblxuXHQvLy0tUGFyc2VyIEJsb2Nrcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdC8vQmxvY2sgSUQgPSAxXG5cdHByaXZhdGUgcGFyc2VUcmlhbmdsZUdlb21ldHJpZUJsb2NrKGJsb2NrSUQ6bnVtYmVyKTp2b2lkXG5cdHtcblxuXHRcdHZhciBnZW9tOkdlb21ldHJ5ID0gbmV3IEdlb21ldHJ5KCk7XG5cblx0XHQvLyBSZWFkIG5hbWUgYW5kIHN1YiBjb3VudFxuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgbnVtX3N1YnM6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXG5cdFx0Ly8gUmVhZCBvcHRpb25hbCBwcm9wZXJ0aWVzXG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTp0aGlzLl9nZW9OclR5cGUsIDI6dGhpcy5fZ2VvTnJUeXBlfSk7XG5cdFx0dmFyIGdlb1NjYWxlVTpudW1iZXIgPSBwcm9wcy5nZXQoMSwgMSk7XG5cdFx0dmFyIGdlb1NjYWxlVjpudW1iZXIgPSBwcm9wcy5nZXQoMiwgMSk7XG5cblx0XHQvLyBMb29wIHRocm91Z2ggc3ViIG1lc2hlc1xuXHRcdHZhciBzdWJzX3BhcnNlZDpudW1iZXIgPSAwO1xuXHRcdHdoaWxlIChzdWJzX3BhcnNlZCA8IG51bV9zdWJzKSB7XG5cdFx0XHR2YXIgaTpudW1iZXI7XG5cdFx0XHR2YXIgc21fbGVuOm51bWJlciwgc21fZW5kOm51bWJlcjtcblx0XHRcdHZhciBzdWJfZ2VvbTpUcmlhbmdsZVN1Ykdlb21ldHJ5O1xuXHRcdFx0dmFyIHdfaW5kaWNlczpBcnJheTxudW1iZXI+O1xuXHRcdFx0dmFyIHdlaWdodHM6QXJyYXk8bnVtYmVyPjtcblxuXHRcdFx0c21fbGVuID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHRcdHNtX2VuZCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gKyBzbV9sZW47XG5cblx0XHRcdC8vIElnbm9yZSBmb3Igbm93XG5cdFx0XHR2YXIgc3ViUHJvcHM6QVdEUHJvcGVydGllcyA9IHRoaXMucGFyc2VQcm9wZXJ0aWVzKHsxOnRoaXMuX2dlb05yVHlwZSwgMjp0aGlzLl9nZW9OclR5cGV9KTtcblx0XHRcdC8vIExvb3AgdGhyb3VnaCBkYXRhIHN0cmVhbXNcblx0XHRcdHdoaWxlICh0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uIDwgc21fZW5kKSB7XG5cdFx0XHRcdHZhciBpZHg6bnVtYmVyID0gMDtcblx0XHRcdFx0dmFyIHN0cl9mdHlwZTpudW1iZXIsIHN0cl90eXBlOm51bWJlciwgc3RyX2xlbjpudW1iZXIsIHN0cl9lbmQ6bnVtYmVyO1xuXG5cdFx0XHRcdC8vIFR5cGUsIGZpZWxkIHR5cGUsIGxlbmd0aFxuXHRcdFx0XHRzdHJfdHlwZSA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRzdHJfZnR5cGUgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTtcblx0XHRcdFx0c3RyX2xlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0XHRcdHN0cl9lbmQgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uICsgc3RyX2xlbjtcblxuXHRcdFx0XHR2YXIgeDpudW1iZXIsIHk6bnVtYmVyLCB6Om51bWJlcjtcblxuXHRcdFx0XHRpZiAoc3RyX3R5cGUgPT0gMSkge1xuXHRcdFx0XHRcdHZhciB2ZXJ0czpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuXHRcdFx0XHRcdHdoaWxlICh0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uIDwgc3RyX2VuZCkge1xuXHRcdFx0XHRcdFx0Ly8gVE9ETzogUmVzcGVjdCBzdHJlYW0gZmllbGQgdHlwZVxuXHRcdFx0XHRcdFx0eCA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeUdlbyk7XG5cdFx0XHRcdFx0XHR5ID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5R2VvKTtcblx0XHRcdFx0XHRcdHogPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lHZW8pO1xuXG5cdFx0XHRcdFx0XHR2ZXJ0c1tpZHgrK10gPSB4O1xuXHRcdFx0XHRcdFx0dmVydHNbaWR4KytdID0geTtcblx0XHRcdFx0XHRcdHZlcnRzW2lkeCsrXSA9IHo7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKHN0cl90eXBlID09IDIpIHtcblx0XHRcdFx0XHR2YXIgaW5kaWNlczpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuXHRcdFx0XHRcdHdoaWxlICh0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uIDwgc3RyX2VuZCkge1xuXHRcdFx0XHRcdFx0Ly8gVE9ETzogUmVzcGVjdCBzdHJlYW0gZmllbGQgdHlwZVxuXHRcdFx0XHRcdFx0aW5kaWNlc1tpZHgrK10gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSBpZiAoc3RyX3R5cGUgPT0gMykge1xuXHRcdFx0XHRcdHZhciB1dnM6QXJyYXk8bnVtYmVyPiA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0XHRcdFx0d2hpbGUgKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPCBzdHJfZW5kKSB7XG5cdFx0XHRcdFx0XHR1dnNbaWR4KytdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5R2VvKTtcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChzdHJfdHlwZSA9PSA0KSB7XG5cblx0XHRcdFx0XHR2YXIgbm9ybWFsczpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuXHRcdFx0XHRcdHdoaWxlICh0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uIDwgc3RyX2VuZCkge1xuXHRcdFx0XHRcdFx0bm9ybWFsc1tpZHgrK10gPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lHZW8pO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2UgaWYgKHN0cl90eXBlID09IDYpIHtcblx0XHRcdFx0XHR3X2luZGljZXMgPSBBcnJheTxudW1iZXI+KCk7XG5cblx0XHRcdFx0XHR3aGlsZSAodGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiA8IHN0cl9lbmQpIHtcblx0XHRcdFx0XHRcdHdfaW5kaWNlc1tpZHgrK10gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCkqMzsgLy8gVE9ETzogUmVzcGVjdCBzdHJlYW0gZmllbGQgdHlwZVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2UgaWYgKHN0cl90eXBlID09IDcpIHtcblxuXHRcdFx0XHRcdHdlaWdodHMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXG5cdFx0XHRcdFx0d2hpbGUgKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPCBzdHJfZW5kKSB7XG5cdFx0XHRcdFx0XHR3ZWlnaHRzW2lkeCsrXSA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeUdlbyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPSBzdHJfZW5kO1xuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7IC8vIElnbm9yZSBzdWItbWVzaCBhdHRyaWJ1dGVzIGZvciBub3dcblxuXHRcdFx0c3ViX2dlb20gPSBuZXcgVHJpYW5nbGVTdWJHZW9tZXRyeSh0cnVlKTtcblx0XHRcdGlmICh3ZWlnaHRzKVxuXHRcdFx0XHRzdWJfZ2VvbS5qb2ludHNQZXJWZXJ0ZXggPSB3ZWlnaHRzLmxlbmd0aC8odmVydHMubGVuZ3RoLzMpO1xuXHRcdFx0aWYgKG5vcm1hbHMpXG5cdFx0XHRcdHN1Yl9nZW9tLmF1dG9EZXJpdmVOb3JtYWxzID0gZmFsc2U7XG5cdFx0XHRpZiAodXZzKVxuXHRcdFx0XHRzdWJfZ2VvbS5hdXRvRGVyaXZlVVZzID0gZmFsc2U7XG5cdFx0XHRzdWJfZ2VvbS51cGRhdGVJbmRpY2VzKGluZGljZXMpO1xuXHRcdFx0c3ViX2dlb20udXBkYXRlUG9zaXRpb25zKHZlcnRzKTtcblx0XHRcdHN1Yl9nZW9tLnVwZGF0ZVZlcnRleE5vcm1hbHMobm9ybWFscyk7XG5cdFx0XHRzdWJfZ2VvbS51cGRhdGVVVnModXZzKTtcblx0XHRcdHN1Yl9nZW9tLnVwZGF0ZVZlcnRleFRhbmdlbnRzKG51bGwpO1xuXHRcdFx0c3ViX2dlb20udXBkYXRlSm9pbnRXZWlnaHRzKHdlaWdodHMpO1xuXHRcdFx0c3ViX2dlb20udXBkYXRlSm9pbnRJbmRpY2VzKHdfaW5kaWNlcyk7XG5cblx0XHRcdHZhciBzY2FsZVU6bnVtYmVyID0gc3ViUHJvcHMuZ2V0KDEsIDEpO1xuXHRcdFx0dmFyIHNjYWxlVjpudW1iZXIgPSBzdWJQcm9wcy5nZXQoMiwgMSk7XG5cdFx0XHR2YXIgc2V0U3ViVVZzOmJvb2xlYW4gPSBmYWxzZTsgLy90aGlzIHNob3VsZCByZW1haW4gZmFsc2UgYXRtLCBiZWNhdXNlIGluIEF3YXlCdWlsZGVyIHRoZSB1diBpcyBvbmx5IHNjYWxlZCBieSB0aGUgZ2VvbWV0cnlcblxuXHRcdFx0aWYgKChnZW9TY2FsZVUgIT0gc2NhbGVVKSB8fCAoZ2VvU2NhbGVWICE9IHNjYWxlVikpIHtcblx0XHRcdFx0c2V0U3ViVVZzID0gdHJ1ZTtcblx0XHRcdFx0c2NhbGVVID0gZ2VvU2NhbGVVL3NjYWxlVTtcblx0XHRcdFx0c2NhbGVWID0gZ2VvU2NhbGVWL3NjYWxlVjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNldFN1YlVWcylcblx0XHRcdFx0c3ViX2dlb20uc2NhbGVVVihzY2FsZVUsIHNjYWxlVik7XG5cblx0XHRcdGdlb20uYWRkU3ViR2VvbWV0cnkoc3ViX2dlb20pO1xuXG5cdFx0XHQvLyBUT0RPOiBTb21laG93IG1hcCBpbi1zdWIgdG8gb3V0LXN1YiBpbmRpY2VzIHRvIGVuYWJsZSBsb29rLXVwXG5cdFx0XHQvLyB3aGVuIGNyZWF0aW5nIG1lc2hlcyAoYW5kIHRoZWlyIG1hdGVyaWFsIGFzc2lnbm1lbnRzLilcblxuXHRcdFx0c3Vic19wYXJzZWQrKztcblx0XHR9XG5cdFx0aWYgKChnZW9TY2FsZVUgIT0gMSkgfHwgKGdlb1NjYWxlViAhPSAxKSlcblx0XHRcdGdlb20uc2NhbGVVVihnZW9TY2FsZVUsIGdlb1NjYWxlVik7XG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gZ2VvbSwgbmFtZSk7XG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBnZW9tO1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIFRyaWFuZ2xlR2VvbWV0cnk6IE5hbWUgPSBcIiArIG5hbWUgKyBcInwgSWQgPSBcIiArIHN1Yl9nZW9tLmlkKTtcblx0XHR9XG5cblx0fVxuXG5cdC8vQmxvY2sgSUQgPSAxMVxuXHRwcml2YXRlIHBhcnNlUHJpbWl0dmVzKGJsb2NrSUQ6bnVtYmVyKTp2b2lkXG5cdHtcblx0XHR2YXIgbmFtZTpzdHJpbmc7XG5cdFx0dmFyIHByZWZhYjpQcmVmYWJCYXNlO1xuXHRcdHZhciBwcmltVHlwZTpudW1iZXI7XG5cdFx0dmFyIHN1YnNfcGFyc2VkOm51bWJlcjtcblx0XHR2YXIgcHJvcHM6QVdEUHJvcGVydGllcztcblx0XHR2YXIgYnNtOk1hdHJpeDNEO1xuXG5cdFx0Ly8gUmVhZCBuYW1lIGFuZCBzdWIgY291bnRcblx0XHRuYW1lID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXHRcdHByaW1UeXBlID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cdFx0cHJvcHMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTAxOnRoaXMuX2dlb05yVHlwZSwgMTAyOnRoaXMuX2dlb05yVHlwZSwgMTAzOnRoaXMuX2dlb05yVHlwZSwgMTEwOnRoaXMuX2dlb05yVHlwZSwgMTExOnRoaXMuX2dlb05yVHlwZSwgMzAxOkFXRFBhcnNlci5VSU5UMTYsIDMwMjpBV0RQYXJzZXIuVUlOVDE2LCAzMDM6QVdEUGFyc2VyLlVJTlQxNiwgNzAxOkFXRFBhcnNlci5CT09MLCA3MDI6QVdEUGFyc2VyLkJPT0wsIDcwMzpBV0RQYXJzZXIuQk9PTCwgNzA0OkFXRFBhcnNlci5CT09MfSk7XG5cblx0XHR2YXIgcHJpbWl0aXZlVHlwZXM6QXJyYXk8c3RyaW5nPiA9IFtcIlVuc3VwcG9ydGVkIFR5cGUtSURcIiwgXCJQcmltaXRpdmVQbGFuZVByZWZhYlwiLCBcIlByaW1pdGl2ZUN1YmVQcmVmYWJcIiwgXCJQcmltaXRpdmVTcGhlcmVQcmVmYWJcIiwgXCJQcmltaXRpdmVDeWxpbmRlclByZWZhYlwiLCBcIlByaW1pdGl2ZXNDb25lUHJlZmFiXCIsIFwiUHJpbWl0aXZlc0NhcHN1bGVQcmVmYWJcIiwgXCJQcmltaXRpdmVzVG9ydXNQcmVmYWJcIl1cblxuXHRcdHN3aXRjaCAocHJpbVR5cGUpIHtcblx0XHRcdC8vIHRvIGRvLCBub3QgYWxsIHByb3BlcnRpZXMgYXJlIHNldCBvbiBhbGwgcHJpbWl0aXZlc1xuXG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHByZWZhYiA9IG5ldyBQcmltaXRpdmVQbGFuZVByZWZhYihwcm9wcy5nZXQoMTAxLCAxMDApLCBwcm9wcy5nZXQoMTAyLCAxMDApLCBwcm9wcy5nZXQoMzAxLCAxKSwgcHJvcHMuZ2V0KDMwMiwgMSksIHByb3BzLmdldCg3MDEsIHRydWUpLCBwcm9wcy5nZXQoNzAyLCBmYWxzZSkpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHRwcmVmYWIgPSBuZXcgUHJpbWl0aXZlQ3ViZVByZWZhYihwcm9wcy5nZXQoMTAxLCAxMDApLCBwcm9wcy5nZXQoMTAyLCAxMDApLCBwcm9wcy5nZXQoMTAzLCAxMDApLCBwcm9wcy5nZXQoMzAxLCAxKSwgcHJvcHMuZ2V0KDMwMiwgMSksIHByb3BzLmdldCgzMDMsIDEpLCBwcm9wcy5nZXQoNzAxLCB0cnVlKSk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIDM6XG5cdFx0XHRcdHByZWZhYiA9IG5ldyBQcmltaXRpdmVTcGhlcmVQcmVmYWIocHJvcHMuZ2V0KDEwMSwgNTApLCBwcm9wcy5nZXQoMzAxLCAxNiksIHByb3BzLmdldCgzMDIsIDEyKSwgcHJvcHMuZ2V0KDcwMSwgdHJ1ZSkpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSA0OlxuXHRcdFx0XHRwcmVmYWIgPSBuZXcgUHJpbWl0aXZlQ3lsaW5kZXJQcmVmYWIocHJvcHMuZ2V0KDEwMSwgNTApLCBwcm9wcy5nZXQoMTAyLCA1MCksIHByb3BzLmdldCgxMDMsIDEwMCksIHByb3BzLmdldCgzMDEsIDE2KSwgcHJvcHMuZ2V0KDMwMiwgMSksIHRydWUsIHRydWUsIHRydWUpOyAvLyBib29sNzAxLCBib29sNzAyLCBib29sNzAzLCBib29sNzA0KTtcblx0XHRcdFx0aWYgKCFwcm9wcy5nZXQoNzAxLCB0cnVlKSlcblx0XHRcdFx0XHQoPFByaW1pdGl2ZUN5bGluZGVyUHJlZmFiPnByZWZhYikudG9wQ2xvc2VkID0gZmFsc2U7XG5cdFx0XHRcdGlmICghcHJvcHMuZ2V0KDcwMiwgdHJ1ZSkpXG5cdFx0XHRcdFx0KDxQcmltaXRpdmVDeWxpbmRlclByZWZhYj5wcmVmYWIpLmJvdHRvbUNsb3NlZCA9IGZhbHNlO1xuXHRcdFx0XHRpZiAoIXByb3BzLmdldCg3MDMsIHRydWUpKVxuXHRcdFx0XHRcdCg8UHJpbWl0aXZlQ3lsaW5kZXJQcmVmYWI+cHJlZmFiKS55VXAgPSBmYWxzZTtcblxuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSA1OlxuXHRcdFx0XHRwcmVmYWIgPSBuZXcgUHJpbWl0aXZlQ29uZVByZWZhYihwcm9wcy5nZXQoMTAxLCA1MCksIHByb3BzLmdldCgxMDIsIDEwMCksIHByb3BzLmdldCgzMDEsIDE2KSwgcHJvcHMuZ2V0KDMwMiwgMSksIHByb3BzLmdldCg3MDEsIHRydWUpLCBwcm9wcy5nZXQoNzAyLCB0cnVlKSk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIDY6XG5cdFx0XHRcdHByZWZhYiA9IG5ldyBQcmltaXRpdmVDYXBzdWxlUHJlZmFiKHByb3BzLmdldCgxMDEsIDUwKSwgcHJvcHMuZ2V0KDEwMiwgMTAwKSwgcHJvcHMuZ2V0KDMwMSwgMTYpLCBwcm9wcy5nZXQoMzAyLCAxNSksIHByb3BzLmdldCg3MDEsIHRydWUpKTtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgNzpcblx0XHRcdFx0cHJlZmFiID0gbmV3IFByaW1pdGl2ZVRvcnVzUHJlZmFiKHByb3BzLmdldCgxMDEsIDUwKSwgcHJvcHMuZ2V0KDEwMiwgNTApLCBwcm9wcy5nZXQoMzAxLCAxNiksIHByb3BzLmdldCgzMDIsIDgpLCBwcm9wcy5nZXQoNzAxLCB0cnVlKSk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRwcmVmYWIgPSBuZXcgUHJlZmFiQmFzZSgpO1xuXHRcdFx0XHRjb25zb2xlLmxvZyhcIkVSUk9SOiBVTlNVUFBPUlRFRCBQUkVGQUJfVFlQRVwiKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0aWYgKChwcm9wcy5nZXQoMTEwLCAxKSAhPSAxKSB8fCAocHJvcHMuZ2V0KDExMSwgMSkgIT0gMSkpIHtcblx0XHRcdC8vZ2VvbS5zdWJHZW9tZXRyaWVzO1xuXHRcdFx0Ly9nZW9tLnNjYWxlVVYocHJvcHMuZ2V0KDExMCwgMSksIHByb3BzLmdldCgxMTEsIDEpKTsgLy9UT0RPIGFkZCBiYWNrIHNjYWxpbmcgdG8gcHJlZmFic1xuXHRcdH1cblxuXHRcdHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdHByZWZhYi5uYW1lID0gbmFtZTtcblx0XHR0aGlzLl9wRmluYWxpemVBc3NldChwcmVmYWIsIG5hbWUpO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gcHJlZmFiO1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRpZiAoKHByaW1UeXBlIDwgMCkgfHwgKHByaW1UeXBlID4gNykpIHtcblx0XHRcdFx0cHJpbVR5cGUgPSAwO1xuXHRcdFx0fVxuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBQcmltaXZpdGU6IE5hbWUgPSBcIiArIG5hbWUgKyBcInwgdHlwZSA9IFwiICsgcHJpbWl0aXZlVHlwZXNbcHJpbVR5cGVdKTtcblx0XHR9XG5cdH1cblxuXHQvLyBCbG9jayBJRCA9IDIyXG5cdHByaXZhdGUgcGFyc2VDb250YWluZXIoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBuYW1lOnN0cmluZztcblx0XHR2YXIgcGFyX2lkOm51bWJlcjtcblx0XHR2YXIgbXR4Ok1hdHJpeDNEO1xuXHRcdHZhciBjdHI6RGlzcGxheU9iamVjdENvbnRhaW5lcjtcblx0XHR2YXIgcGFyZW50OkRpc3BsYXlPYmplY3RDb250YWluZXI7XG5cblx0XHRwYXJfaWQgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdG10eCA9IHRoaXMucGFyc2VNYXRyaXgzRCgpO1xuXHRcdG5hbWUgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cblx0XHR2YXIgcGFyZW50TmFtZTpzdHJpbmcgPSBcIlJvb3QgKFRvcExldmVsKVwiO1xuXHRcdGN0ciA9IG5ldyBEaXNwbGF5T2JqZWN0Q29udGFpbmVyKCk7XG5cdFx0Y3RyLnRyYW5zZm9ybS5tYXRyaXgzRCA9IG10eDtcblxuXHRcdHZhciByZXR1cm5lZEFycmF5OkFycmF5PGFueT4gPSB0aGlzLmdldEFzc2V0QnlJRChwYXJfaWQsIFtBc3NldFR5cGUuQ09OVEFJTkVSLCBBc3NldFR5cGUuTElHSFQsIEFzc2V0VHlwZS5NRVNIXSk7XG5cblx0XHRpZiAocmV0dXJuZWRBcnJheVswXSkge1xuXHRcdFx0dmFyIG9iajpEaXNwbGF5T2JqZWN0ID0gKDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiByZXR1cm5lZEFycmF5WzFdKS5hZGRDaGlsZChjdHIpO1xuXHRcdFx0cGFyZW50TmFtZSA9ICg8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gcmV0dXJuZWRBcnJheVsxXSkubmFtZTtcblx0XHR9IGVsc2UgaWYgKHBhcl9pZCA+IDApIHtcblx0XHRcdHRoaXMuX2Jsb2Nrc1sgYmxvY2tJRCBdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgYSBwYXJlbnQgZm9yIHRoaXMgT2JqZWN0Q29udGFpbmVyM0RcIik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vYWRkIHRvIHRoZSBjb250ZW50IHByb3BlcnR5XG5cdFx0XHQoPERpc3BsYXlPYmplY3RDb250YWluZXI+IHRoaXMuX3BDb250ZW50KS5hZGRDaGlsZChjdHIpO1xuXHRcdH1cblxuXHRcdC8vIGluIEFXRCB2ZXJzaW9uIDIuMSB3ZSByZWFkIHRoZSBDb250YWluZXIgcHJvcGVydGllc1xuXHRcdGlmICgodGhpcy5fdmVyc2lvblswXSA9PSAyKSAmJiAodGhpcy5fdmVyc2lvblsxXSA9PSAxKSkge1xuXHRcdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTp0aGlzLl9tYXRyaXhOclR5cGUsIDI6dGhpcy5fbWF0cml4TnJUeXBlLCAzOnRoaXMuX21hdHJpeE5yVHlwZSwgNDpBV0RQYXJzZXIuVUlOVDh9KTtcblx0XHRcdGN0ci5waXZvdCA9IG5ldyBWZWN0b3IzRChwcm9wcy5nZXQoMSwgMCksIHByb3BzLmdldCgyLCAwKSwgcHJvcHMuZ2V0KDMsIDApKTtcblx0XHR9XG5cdFx0Ly8gaW4gb3RoZXIgdmVyc2lvbnMgd2UgZG8gbm90IHJlYWQgdGhlIENvbnRhaW5lciBwcm9wZXJ0aWVzXG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLnBhcnNlUHJvcGVydGllcyhudWxsKTtcblx0XHR9XG5cblx0XHQvLyB0aGUgZXh0cmFQcm9wZXJ0aWVzIHNob3VsZCBvbmx5IGJlIHNldCBmb3IgQVdEMi4xLUZpbGVzLCBidXQgaXMgcmVhZCBmb3IgYm90aCB2ZXJzaW9uc1xuXHRcdGN0ci5leHRyYSA9IHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gY3RyLCBuYW1lKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGN0cjtcblxuXHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBDb250YWluZXI6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgUGFyZW50LU5hbWUgPSBcIiArIHBhcmVudE5hbWUpO1xuXHRcdH1cblx0fVxuXG5cdC8vIEJsb2NrIElEID0gMjNcblx0cHJpdmF0ZSBwYXJzZU1lc2hJbnN0YW5jZShibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cdFx0dmFyIG51bV9tYXRlcmlhbHM6bnVtYmVyO1xuXHRcdHZhciBtYXRlcmlhbHNfcGFyc2VkOm51bWJlcjtcblx0XHR2YXIgcGFyZW50OkRpc3BsYXlPYmplY3RDb250YWluZXI7XG5cdFx0dmFyIHBhcl9pZDpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdHZhciBtdHg6TWF0cml4M0QgPSB0aGlzLnBhcnNlTWF0cml4M0QoKTtcblx0XHR2YXIgbmFtZTpzdHJpbmcgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cdFx0dmFyIHBhcmVudE5hbWU6c3RyaW5nID0gXCJSb290IChUb3BMZXZlbClcIjtcblx0XHR2YXIgZGF0YV9pZDpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdHZhciBnZW9tOkdlb21ldHJ5O1xuXHRcdHZhciByZXR1cm5lZEFycmF5R2VvbWV0cnk6QXJyYXk8YW55PiA9IHRoaXMuZ2V0QXNzZXRCeUlEKGRhdGFfaWQsIFtBc3NldFR5cGUuR0VPTUVUUlldKVxuXG5cdFx0aWYgKHJldHVybmVkQXJyYXlHZW9tZXRyeVswXSkge1xuXHRcdFx0Z2VvbSA9IDxHZW9tZXRyeT4gcmV0dXJuZWRBcnJheUdlb21ldHJ5WzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCBhIEdlb21ldHJ5IGZvciB0aGlzIE1lc2guIEEgZW1wdHkgR2VvbWV0cnkgaXMgY3JlYXRlZCFcIik7XG5cdFx0XHRnZW9tID0gbmV3IEdlb21ldHJ5KCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmdlb0lEID0gZGF0YV9pZDtcblx0XHR2YXIgbWF0ZXJpYWxzOkFycmF5PE1hdGVyaWFsQmFzZT4gPSBuZXcgQXJyYXk8TWF0ZXJpYWxCYXNlPigpO1xuXHRcdG51bV9tYXRlcmlhbHMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cblx0XHR2YXIgbWF0ZXJpYWxOYW1lczpBcnJheTxzdHJpbmc+ID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblx0XHRtYXRlcmlhbHNfcGFyc2VkID0gMDtcblxuXHRcdHZhciByZXR1cm5lZEFycmF5TWF0ZXJpYWw6QXJyYXk8YW55PjtcblxuXHRcdHdoaWxlIChtYXRlcmlhbHNfcGFyc2VkIDwgbnVtX21hdGVyaWFscykge1xuXHRcdFx0dmFyIG1hdF9pZDpudW1iZXI7XG5cdFx0XHRtYXRfaWQgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdFx0cmV0dXJuZWRBcnJheU1hdGVyaWFsID0gdGhpcy5nZXRBc3NldEJ5SUQobWF0X2lkLCBbQXNzZXRUeXBlLk1BVEVSSUFMXSlcblx0XHRcdGlmICgoIXJldHVybmVkQXJyYXlNYXRlcmlhbFswXSkgJiYgKG1hdF9pZCA+IDApKSB7XG5cdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIE1hdGVyaWFsIE5yIFwiICsgbWF0ZXJpYWxzX3BhcnNlZCArIFwiIChJRCA9IFwiICsgbWF0X2lkICsgXCIgKSBmb3IgdGhpcyBNZXNoXCIpO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbTpNYXRlcmlhbEJhc2UgPSA8TWF0ZXJpYWxCYXNlPiByZXR1cm5lZEFycmF5TWF0ZXJpYWxbMV07XG5cblx0XHRcdG1hdGVyaWFscy5wdXNoKG0pO1xuXHRcdFx0bWF0ZXJpYWxOYW1lcy5wdXNoKG0ubmFtZSk7XG5cblx0XHRcdG1hdGVyaWFsc19wYXJzZWQrKztcblx0XHR9XG5cblx0XHR2YXIgbWVzaDpNZXNoID0gbmV3IE1lc2goZ2VvbSwgbnVsbCk7XG5cdFx0bWVzaC50cmFuc2Zvcm0ubWF0cml4M0QgPSBtdHg7XG5cblx0XHR2YXIgcmV0dXJuZWRBcnJheVBhcmVudDpBcnJheTxhbnk+ID0gdGhpcy5nZXRBc3NldEJ5SUQocGFyX2lkLCBbQXNzZXRUeXBlLkNPTlRBSU5FUiwgQXNzZXRUeXBlLkxJR0hULCBBc3NldFR5cGUuTUVTSF0pXG5cblx0XHRpZiAocmV0dXJuZWRBcnJheVBhcmVudFswXSkge1xuXHRcdFx0dmFyIG9iakM6RGlzcGxheU9iamVjdENvbnRhaW5lciA9IDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiByZXR1cm5lZEFycmF5UGFyZW50WzFdO1xuXHRcdFx0b2JqQy5hZGRDaGlsZChtZXNoKTtcblx0XHRcdHBhcmVudE5hbWUgPSBvYmpDLm5hbWU7XG5cdFx0fSBlbHNlIGlmIChwYXJfaWQgPiAwKSB7XG5cdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCBhIHBhcmVudCBmb3IgdGhpcyBNZXNoXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL2FkZCB0byB0aGUgY29udGVudCBwcm9wZXJ0eVxuXHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiB0aGlzLl9wQ29udGVudCkuYWRkQ2hpbGQobWVzaCk7XG5cdFx0fVxuXG5cdFx0aWYgKG1hdGVyaWFscy5sZW5ndGggPj0gMSAmJiBtZXNoLnN1Yk1lc2hlcy5sZW5ndGggPT0gMSkge1xuXHRcdFx0bWVzaC5tYXRlcmlhbCA9IG1hdGVyaWFsc1swXTtcblx0XHR9IGVsc2UgaWYgKG1hdGVyaWFscy5sZW5ndGggPiAxKSB7XG5cdFx0XHR2YXIgaTpudW1iZXI7XG5cblx0XHRcdC8vIEFzc2lnbiBlYWNoIHN1Yi1tZXNoIGluIHRoZSBtZXNoIGEgbWF0ZXJpYWwgZnJvbSB0aGUgbGlzdC4gSWYgbW9yZSBzdWItbWVzaGVzXG5cdFx0XHQvLyB0aGFuIG1hdGVyaWFscywgcmVwZWF0IHRoZSBsYXN0IG1hdGVyaWFsIGZvciBhbGwgcmVtYWluaW5nIHN1Yi1tZXNoZXMuXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWVzaC5zdWJNZXNoZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0bWVzaC5zdWJNZXNoZXNbaV0ubWF0ZXJpYWwgPSBtYXRlcmlhbHNbTWF0aC5taW4obWF0ZXJpYWxzLmxlbmd0aCAtIDEsIGkpXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKCh0aGlzLl92ZXJzaW9uWzBdID09IDIpICYmICh0aGlzLl92ZXJzaW9uWzFdID09IDEpKSB7XG5cdFx0XHR2YXIgcHJvcHM6QVdEUHJvcGVydGllcyA9IHRoaXMucGFyc2VQcm9wZXJ0aWVzKHsxOnRoaXMuX21hdHJpeE5yVHlwZSwgMjp0aGlzLl9tYXRyaXhOclR5cGUsIDM6dGhpcy5fbWF0cml4TnJUeXBlLCA0OkFXRFBhcnNlci5VSU5UOCwgNTpBV0RQYXJzZXIuQk9PTH0pO1xuXHRcdFx0bWVzaC5waXZvdCA9IG5ldyBWZWN0b3IzRCg8bnVtYmVyPnByb3BzLmdldCgxLCAwKSwgPG51bWJlcj5wcm9wcy5nZXQoMiwgMCksIDxudW1iZXI+IHByb3BzLmdldCgzLCAwKSk7XG5cdFx0XHRtZXNoLmNhc3RzU2hhZG93cyA9IHByb3BzLmdldCg1LCB0cnVlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wYXJzZVByb3BlcnRpZXMobnVsbCk7XG5cdFx0fVxuXG5cdFx0bWVzaC5leHRyYSA9IHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gbWVzaCwgbmFtZSk7XG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBtZXNoO1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIE1lc2g6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgUGFyZW50LU5hbWUgPSBcIiArIHBhcmVudE5hbWUgKyBcInwgR2VvbWV0cnktTmFtZSA9IFwiICsgZ2VvbS5uYW1lICsgXCIgfCBTdWJNZXNoZXMgPSBcIiArIG1lc2guc3ViTWVzaGVzLmxlbmd0aCArIFwiIHwgTWF0LU5hbWVzID0gXCIgKyBtYXRlcmlhbE5hbWVzLnRvU3RyaW5nKCkpO1xuXHRcdH1cblx0fVxuXG5cblx0Ly9CbG9jayBJRCAzMVxuXHRwcml2YXRlIHBhcnNlU2t5Ym94SW5zdGFuY2UoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgY3ViZVRleEFkZHI6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdHZhciByZXR1cm5lZEFycmF5Q3ViZVRleDpBcnJheTxhbnk+ID0gdGhpcy5nZXRBc3NldEJ5SUQoY3ViZVRleEFkZHIsIFtBc3NldFR5cGUuVEVYVFVSRV0sIFwiQ3ViZVRleHR1cmVcIik7XG5cdFx0aWYgKCghcmV0dXJuZWRBcnJheUN1YmVUZXhbMF0pICYmIChjdWJlVGV4QWRkciAhPSAwKSlcblx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBDdWJldGV4dHVyZSAoSUQgPSBcIiArIGN1YmVUZXhBZGRyICsgXCIgKSBmb3IgdGhpcyBTa3lib3hcIik7XG5cdFx0dmFyIGFzc2V0OlNreWJveCA9IG5ldyBTa3lib3gobmV3IFNreWJveE1hdGVyaWFsKDxJbWFnZUN1YmVUZXh0dXJlPiByZXR1cm5lZEFycmF5Q3ViZVRleFsxXSkpO1xuXG5cdFx0dGhpcy5wYXJzZVByb3BlcnRpZXMobnVsbClcblx0XHRhc3NldC5leHRyYSA9IHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KGFzc2V0LCBuYW1lKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGFzc2V0O1xuXHRcdGlmICh0aGlzLl9kZWJ1Zylcblx0XHRcdGNvbnNvbGUubG9nKFwiUGFyc2VkIGEgU2t5Ym94OiBOYW1lID0gJ1wiICsgbmFtZSArIFwiJyB8IEN1YmVUZXh0dXJlLU5hbWUgPSBcIiArICg8SW1hZ2VDdWJlVGV4dHVyZT4gcmV0dXJuZWRBcnJheUN1YmVUZXhbMV0pLm5hbWUpO1xuXG5cdH1cblxuXHQvL0Jsb2NrIElEID0gNDFcblx0cHJpdmF0ZSBwYXJzZUxpZ2h0KGJsb2NrSUQ6bnVtYmVyKTp2b2lkXG5cdHtcblx0XHR2YXIgbGlnaHQ6TGlnaHRCYXNlO1xuXHRcdHZhciBuZXdTaGFkb3dNYXBwZXI6U2hhZG93TWFwcGVyQmFzZTtcblxuXHRcdHZhciBwYXJfaWQ6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHR2YXIgbXR4Ok1hdHJpeDNEID0gdGhpcy5wYXJzZU1hdHJpeDNEKCk7XG5cdFx0dmFyIG5hbWU6c3RyaW5nID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXHRcdHZhciBsaWdodFR5cGU6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTp0aGlzLl9wcm9wc05yVHlwZSwgMjp0aGlzLl9wcm9wc05yVHlwZSwgMzpBV0RQYXJzZXIuQ09MT1IsIDQ6dGhpcy5fcHJvcHNOclR5cGUsIDU6dGhpcy5fcHJvcHNOclR5cGUsIDY6QVdEUGFyc2VyLkJPT0wsIDc6QVdEUGFyc2VyLkNPTE9SLCA4OnRoaXMuX3Byb3BzTnJUeXBlLCA5OkFXRFBhcnNlci5VSU5UOCwgMTA6QVdEUGFyc2VyLlVJTlQ4LCAxMTp0aGlzLl9wcm9wc05yVHlwZSwgMTI6QVdEUGFyc2VyLlVJTlQxNiwgMjE6dGhpcy5fbWF0cml4TnJUeXBlLCAyMjp0aGlzLl9tYXRyaXhOclR5cGUsIDIzOnRoaXMuX21hdHJpeE5yVHlwZX0pO1xuXHRcdHZhciBzaGFkb3dNYXBwZXJUeXBlOm51bWJlciA9IHByb3BzLmdldCg5LCAwKTtcblx0XHR2YXIgcGFyZW50TmFtZTpzdHJpbmcgPSBcIlJvb3QgKFRvcExldmVsKVwiO1xuXHRcdHZhciBsaWdodFR5cGVzOkFycmF5PHN0cmluZz4gPSBbXCJVbnN1cHBvcnRlZCBMaWdodFR5cGVcIiwgXCJQb2ludExpZ2h0XCIsIFwiRGlyZWN0aW9uYWxMaWdodFwiXTtcblx0XHR2YXIgc2hhZG93TWFwcGVyVHlwZXM6QXJyYXk8c3RyaW5nPiA9IFtcIk5vIFNoYWRvd01hcHBlclwiLCBcIkRpcmVjdGlvbmFsU2hhZG93TWFwcGVyXCIsIFwiTmVhckRpcmVjdGlvbmFsU2hhZG93TWFwcGVyXCIsIFwiQ2FzY2FkZVNoYWRvd01hcHBlclwiLCBcIkN1YmVNYXBTaGFkb3dNYXBwZXJcIl07XG5cblx0XHRpZiAobGlnaHRUeXBlID09IDEpIHtcblx0XHRcdGxpZ2h0ID0gbmV3IFBvaW50TGlnaHQoKTtcblxuXHRcdFx0KDxQb2ludExpZ2h0PiBsaWdodCkucmFkaXVzID0gcHJvcHMuZ2V0KDEsIDkwMDAwKTtcblx0XHRcdCg8UG9pbnRMaWdodD4gbGlnaHQpLmZhbGxPZmYgPSBwcm9wcy5nZXQoMiwgMTAwMDAwKTtcblxuXHRcdFx0aWYgKHNoYWRvd01hcHBlclR5cGUgPiAwKSB7XG5cdFx0XHRcdGlmIChzaGFkb3dNYXBwZXJUeXBlID09IDQpIHtcblx0XHRcdFx0XHRuZXdTaGFkb3dNYXBwZXIgPSBuZXcgQ3ViZU1hcFNoYWRvd01hcHBlcigpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGxpZ2h0LnRyYW5zZm9ybS5tYXRyaXgzRCA9IG10eDtcblxuXHRcdH1cblxuXHRcdGlmIChsaWdodFR5cGUgPT0gMikge1xuXG5cdFx0XHRsaWdodCA9IG5ldyBEaXJlY3Rpb25hbExpZ2h0KHByb3BzLmdldCgyMSwgMCksIHByb3BzLmdldCgyMiwgLTEpLCBwcm9wcy5nZXQoMjMsIDEpKTtcblxuXHRcdFx0aWYgKHNoYWRvd01hcHBlclR5cGUgPiAwKSB7XG5cdFx0XHRcdGlmIChzaGFkb3dNYXBwZXJUeXBlID09IDEpIHtcblx0XHRcdFx0XHRuZXdTaGFkb3dNYXBwZXIgPSBuZXcgRGlyZWN0aW9uYWxTaGFkb3dNYXBwZXIoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vaWYgKHNoYWRvd01hcHBlclR5cGUgPT0gMilcblx0XHRcdFx0Ly8gIG5ld1NoYWRvd01hcHBlciA9IG5ldyBOZWFyRGlyZWN0aW9uYWxTaGFkb3dNYXBwZXIocHJvcHMuZ2V0KDExLCAwLjUpKTtcblx0XHRcdFx0Ly9pZiAoc2hhZG93TWFwcGVyVHlwZSA9PSAzKVxuXHRcdFx0XHQvLyAgIG5ld1NoYWRvd01hcHBlciA9IG5ldyBDYXNjYWRlU2hhZG93TWFwcGVyKHByb3BzLmdldCgxMiwgMykpO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cdFx0bGlnaHQuY29sb3IgPSBwcm9wcy5nZXQoMywgMHhmZmZmZmYpO1xuXHRcdGxpZ2h0LnNwZWN1bGFyID0gcHJvcHMuZ2V0KDQsIDEuMCk7XG5cdFx0bGlnaHQuZGlmZnVzZSA9IHByb3BzLmdldCg1LCAxLjApO1xuXHRcdGxpZ2h0LmFtYmllbnRDb2xvciA9IHByb3BzLmdldCg3LCAweGZmZmZmZik7XG5cdFx0bGlnaHQuYW1iaWVudCA9IHByb3BzLmdldCg4LCAwLjApO1xuXG5cdFx0Ly8gaWYgYSBzaGFkb3dNYXBwZXIgaGFzIGJlZW4gY3JlYXRlZCwgYWRqdXN0IHRoZSBkZXB0aE1hcFNpemUgaWYgbmVlZGVkLCBhc3NpZ24gdG8gbGlnaHQgYW5kIHNldCBjYXN0U2hhZG93cyB0byB0cnVlXG5cdFx0aWYgKG5ld1NoYWRvd01hcHBlcikge1xuXHRcdFx0aWYgKG5ld1NoYWRvd01hcHBlciBpbnN0YW5jZW9mIEN1YmVNYXBTaGFkb3dNYXBwZXIpIHtcblx0XHRcdFx0aWYgKHByb3BzLmdldCgxMCwgMSkgIT0gMSkge1xuXHRcdFx0XHRcdG5ld1NoYWRvd01hcHBlci5kZXB0aE1hcFNpemUgPSB0aGlzLl9kZXB0aFNpemVEaWNbcHJvcHMuZ2V0KDEwLCAxKV07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmIChwcm9wcy5nZXQoMTAsIDIpICE9IDIpIHtcblx0XHRcdFx0XHRuZXdTaGFkb3dNYXBwZXIuZGVwdGhNYXBTaXplID0gdGhpcy5fZGVwdGhTaXplRGljW3Byb3BzLmdldCgxMCwgMildO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGxpZ2h0LnNoYWRvd01hcHBlciA9IG5ld1NoYWRvd01hcHBlcjtcblx0XHRcdGxpZ2h0LmNhc3RzU2hhZG93cyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKHBhcl9pZCAhPSAwKSB7XG5cblx0XHRcdHZhciByZXR1cm5lZEFycmF5UGFyZW50OkFycmF5PGFueT4gPSB0aGlzLmdldEFzc2V0QnlJRChwYXJfaWQsIFtBc3NldFR5cGUuQ09OVEFJTkVSLCBBc3NldFR5cGUuTElHSFQsIEFzc2V0VHlwZS5NRVNIXSlcblxuXHRcdFx0aWYgKHJldHVybmVkQXJyYXlQYXJlbnRbMF0pIHtcblx0XHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiByZXR1cm5lZEFycmF5UGFyZW50WzFdKS5hZGRDaGlsZChsaWdodCk7XG5cdFx0XHRcdHBhcmVudE5hbWUgPSAoPERpc3BsYXlPYmplY3RDb250YWluZXI+IHJldHVybmVkQXJyYXlQYXJlbnRbMV0pLm5hbWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCBhIHBhcmVudCBmb3IgdGhpcyBMaWdodFwiKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly9hZGQgdG8gdGhlIGNvbnRlbnQgcHJvcGVydHlcblx0XHRcdCg8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gdGhpcy5fcENvbnRlbnQpLmFkZENoaWxkKGxpZ2h0KTtcblx0XHR9XG5cblx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblxuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KDwgSUFzc2V0PiBsaWdodCwgbmFtZSk7XG5cblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGxpZ2h0O1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKVxuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBMaWdodDogTmFtZSA9ICdcIiArIG5hbWUgKyBcIicgfCBUeXBlID0gXCIgKyBsaWdodFR5cGVzW2xpZ2h0VHlwZV0gKyBcIiB8IFBhcmVudC1OYW1lID0gXCIgKyBwYXJlbnROYW1lICsgXCIgfCBTaGFkb3dNYXBwZXItVHlwZSA9IFwiICsgc2hhZG93TWFwcGVyVHlwZXNbc2hhZG93TWFwcGVyVHlwZV0pO1xuXG5cdH1cblxuXHQvL0Jsb2NrIElEID0gNDNcblx0cHJpdmF0ZSBwYXJzZUNhbWVyYShibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cblx0XHR2YXIgcGFyX2lkOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0dmFyIG10eDpNYXRyaXgzRCA9IHRoaXMucGFyc2VNYXRyaXgzRCgpO1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgcGFyZW50TmFtZTpzdHJpbmcgPSBcIlJvb3QgKFRvcExldmVsKVwiO1xuXHRcdHZhciBwcm9qZWN0aW9uOlByb2plY3Rpb25CYXNlO1xuXG5cdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7IC8vc2V0IGFzIGFjdGl2ZSBjYW1lcmFcblx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRTaG9ydCgpOyAvL2xlbmd0aG9mIGxlbnNlcyAtIG5vdCB1c2VkIHlldFxuXG5cdFx0dmFyIHByb2plY3Rpb250eXBlOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFNob3J0KCk7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTAxOnRoaXMuX3Byb3BzTnJUeXBlLCAxMDI6dGhpcy5fcHJvcHNOclR5cGUsIDEwMzp0aGlzLl9wcm9wc05yVHlwZSwgMTA0OnRoaXMuX3Byb3BzTnJUeXBlfSk7XG5cblx0XHRzd2l0Y2ggKHByb2plY3Rpb250eXBlKSB7XG5cdFx0XHRjYXNlIDUwMDE6XG5cdFx0XHRcdHByb2plY3Rpb24gPSBuZXcgUGVyc3BlY3RpdmVQcm9qZWN0aW9uKHByb3BzLmdldCgxMDEsIDYwKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA1MDAyOlxuXHRcdFx0XHRwcm9qZWN0aW9uID0gbmV3IE9ydGhvZ3JhcGhpY1Byb2plY3Rpb24ocHJvcHMuZ2V0KDEwMSwgNTAwKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA1MDAzOlxuXHRcdFx0XHRwcm9qZWN0aW9uID0gbmV3IE9ydGhvZ3JhcGhpY09mZkNlbnRlclByb2plY3Rpb24ocHJvcHMuZ2V0KDEwMSwgLTQwMCksIHByb3BzLmdldCgxMDIsIDQwMCksIHByb3BzLmdldCgxMDMsIC0zMDApLCBwcm9wcy5nZXQoMTA0LCAzMDApKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRjb25zb2xlLmxvZyhcInVuc3VwcG9ydGVkTGVuc3R5cGVcIik7XG5cdFx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgY2FtZXJhOkNhbWVyYSA9IG5ldyBDYW1lcmEocHJvamVjdGlvbik7XG5cdFx0Y2FtZXJhLnRyYW5zZm9ybS5tYXRyaXgzRCA9IG10eDtcblxuXHRcdHZhciByZXR1cm5lZEFycmF5UGFyZW50OkFycmF5PGFueT4gPSB0aGlzLmdldEFzc2V0QnlJRChwYXJfaWQsIFtBc3NldFR5cGUuQ09OVEFJTkVSLCBBc3NldFR5cGUuTElHSFQsIEFzc2V0VHlwZS5NRVNIXSlcblxuXHRcdGlmIChyZXR1cm5lZEFycmF5UGFyZW50WzBdKSB7XG5cblx0XHRcdHZhciBvYmpDOkRpc3BsYXlPYmplY3RDb250YWluZXIgPSA8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gcmV0dXJuZWRBcnJheVBhcmVudFsxXTtcblx0XHRcdG9iakMuYWRkQ2hpbGQoY2FtZXJhKTtcblxuXHRcdFx0cGFyZW50TmFtZSA9IG9iakMubmFtZTtcblxuXHRcdH0gZWxzZSBpZiAocGFyX2lkID4gMCkge1xuXHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgYSBwYXJlbnQgZm9yIHRoaXMgQ2FtZXJhXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL2FkZCB0byB0aGUgY29udGVudCBwcm9wZXJ0eVxuXHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiB0aGlzLl9wQ29udGVudCkuYWRkQ2hpbGQoY2FtZXJhKTtcblx0XHR9XG5cblx0XHRjYW1lcmEubmFtZSA9IG5hbWU7XG5cdFx0cHJvcHMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTp0aGlzLl9tYXRyaXhOclR5cGUsIDI6dGhpcy5fbWF0cml4TnJUeXBlLCAzOnRoaXMuX21hdHJpeE5yVHlwZSwgNDpBV0RQYXJzZXIuVUlOVDh9KTtcblx0XHRjYW1lcmEucGl2b3QgPSBuZXcgVmVjdG9yM0QocHJvcHMuZ2V0KDEsIDApLCBwcm9wcy5nZXQoMiwgMCksIHByb3BzLmdldCgzLCAwKSk7XG5cdFx0Y2FtZXJhLmV4dHJhID0gdGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cblx0XHR0aGlzLl9wRmluYWxpemVBc3NldChjYW1lcmEsIG5hbWUpO1xuXG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBjYW1lcmFcblxuXHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBDYW1lcmE6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgUHJvamVjdGlvbnR5cGUgPSBcIiArIHByb2plY3Rpb24gKyBcIiB8IFBhcmVudC1OYW1lID0gXCIgKyBwYXJlbnROYW1lKTtcblx0XHR9XG5cblx0fVxuXG5cdC8vQmxvY2sgSUQgPSA1MVxuXHRwcml2YXRlIHBhcnNlTGlnaHRQaWNrZXIoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgbnVtTGlnaHRzOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHR2YXIgbGlnaHRzQXJyYXk6QXJyYXk8TGlnaHRCYXNlPiA9IG5ldyBBcnJheTxMaWdodEJhc2U+KCk7XG5cdFx0dmFyIGs6bnVtYmVyID0gMDtcblx0XHR2YXIgbGlnaHRJRDpudW1iZXIgPSAwO1xuXG5cdFx0dmFyIHJldHVybmVkQXJyYXlMaWdodDpBcnJheTxhbnk+O1xuXHRcdHZhciBsaWdodHNBcnJheU5hbWVzOkFycmF5PHN0cmluZz4gPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG5cdFx0Zm9yIChrID0gMDsgayA8IG51bUxpZ2h0czsgaysrKSB7XG5cdFx0XHRsaWdodElEID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHRcdHJldHVybmVkQXJyYXlMaWdodCA9IHRoaXMuZ2V0QXNzZXRCeUlEKGxpZ2h0SUQsIFtBc3NldFR5cGUuTElHSFRdKVxuXG5cdFx0XHRpZiAocmV0dXJuZWRBcnJheUxpZ2h0WzBdKSB7XG5cdFx0XHRcdGxpZ2h0c0FycmF5LnB1c2goPExpZ2h0QmFzZT4gcmV0dXJuZWRBcnJheUxpZ2h0WzFdKTtcblx0XHRcdFx0bGlnaHRzQXJyYXlOYW1lcy5wdXNoKCggPExpZ2h0QmFzZT4gcmV0dXJuZWRBcnJheUxpZ2h0WzFdKS5uYW1lKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgYSBMaWdodCBOciBcIiArIGsgKyBcIiAoSUQgPSBcIiArIGxpZ2h0SUQgKyBcIiApIGZvciB0aGlzIExpZ2h0UGlja2VyXCIpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChsaWdodHNBcnJheS5sZW5ndGggPT0gMCkge1xuXHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGNyZWF0ZSB0aGlzIExpZ2h0UGlja2VyLCBjYXVzZSBubyBMaWdodCB3YXMgZm91bmQuXCIpO1xuXHRcdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0XHRyZXR1cm47IC8vcmV0dXJuIHdpdGhvdXQgYW55IG1vcmUgcGFyc2luZyBmb3IgdGhpcyBibG9ja1xuXHRcdH1cblxuXHRcdHZhciBsaWdodFBpY2s6TGlnaHRQaWNrZXJCYXNlID0gbmV3IFN0YXRpY0xpZ2h0UGlja2VyKGxpZ2h0c0FycmF5KTtcblx0XHRsaWdodFBpY2submFtZSA9IG5hbWU7XG5cblx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHR0aGlzLl9wRmluYWxpemVBc3NldCg8SUFzc2V0PiBsaWdodFBpY2ssIG5hbWUpO1xuXG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBsaWdodFBpY2tcblx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiUGFyc2VkIGEgU3RhdGljTGlnaHRQaWNrZXI6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgVGV4dHVyZS1OYW1lID0gXCIgKyBsaWdodHNBcnJheU5hbWVzLnRvU3RyaW5nKCkpO1xuXHRcdH1cblx0fVxuXG5cdC8vQmxvY2sgSUQgPSA4MVxuXHRwcml2YXRlIHBhcnNlTWF0ZXJpYWwoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdC8vIFRPRE86IG5vdCB1c2VkXG5cdFx0Ly8vL2Jsb2NrTGVuZ3RoID0gYmxvY2subGVuO1xuXHRcdHZhciBuYW1lOnN0cmluZztcblx0XHR2YXIgdHlwZTpudW1iZXI7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXM7XG5cdFx0dmFyIG1hdDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXHRcdHZhciBhdHRyaWJ1dGVzOk9iamVjdDtcblx0XHR2YXIgZmluYWxpemU6Ym9vbGVhbjtcblx0XHR2YXIgbnVtX21ldGhvZHM6bnVtYmVyO1xuXHRcdHZhciBtZXRob2RzX3BhcnNlZDpudW1iZXI7XG5cdFx0dmFyIHJldHVybmVkQXJyYXk6QXJyYXk8YW55PjtcblxuXHRcdG5hbWUgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cdFx0dHlwZSA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdG51bV9tZXRob2RzID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cblx0XHQvLyBSZWFkIG1hdGVyaWFsIG51bWVyaWNhbCBwcm9wZXJ0aWVzXG5cdFx0Ly8gKDE9Y29sb3IsIDI9Yml0bWFwIHVybCwgMTA9YWxwaGEsIDExPWFscGhhX2JsZW5kaW5nLCAxMj1hbHBoYV90aHJlc2hvbGQsIDEzPXJlcGVhdClcblx0XHRwcm9wcyA9IHRoaXMucGFyc2VQcm9wZXJ0aWVzKHsgMTpBV0RQYXJzZXIuSU5UMzIsIDI6QVdEUGFyc2VyLkJBRERSLCAxMDp0aGlzLl9wcm9wc05yVHlwZSwgMTE6QVdEUGFyc2VyLkJPT0wsIDEyOnRoaXMuX3Byb3BzTnJUeXBlLCAxMzpBV0RQYXJzZXIuQk9PTH0pO1xuXG5cdFx0bWV0aG9kc19wYXJzZWQgPSAwO1xuXHRcdHdoaWxlIChtZXRob2RzX3BhcnNlZCA8IG51bV9tZXRob2RzKSB7XG5cdFx0XHR2YXIgbWV0aG9kX3R5cGU6bnVtYmVyO1xuXG5cdFx0XHRtZXRob2RfdHlwZSA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRcdHRoaXMucGFyc2VQcm9wZXJ0aWVzKG51bGwpO1xuXHRcdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0XHRtZXRob2RzX3BhcnNlZCArPSAxO1xuXHRcdH1cblx0XHR2YXIgZGVidWdTdHJpbmc6c3RyaW5nID0gXCJcIjtcblx0XHRhdHRyaWJ1dGVzID0gdGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0aWYgKHR5cGUgPT09IDEpIHsgLy8gQ29sb3IgbWF0ZXJpYWxcblx0XHRcdGRlYnVnU3RyaW5nICs9IFwiUGFyc2VkIGEgQ29sb3JNYXRlcmlhbChTaW5nbGVQYXNzKTogTmFtZSA9ICdcIiArIG5hbWUgKyBcIicgfCBcIjtcblx0XHRcdHZhciBjb2xvcjpudW1iZXI7XG5cdFx0XHRjb2xvciA9IHByb3BzLmdldCgxLCAweGZmZmZmZik7XG5cdFx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPCAyKSB7XG5cdFx0XHRcdG1hdCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKGNvbG9yLCBwcm9wcy5nZXQoMTAsIDEuMCkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0ID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwoY29sb3IpO1xuXHRcdFx0XHRtYXQubWF0ZXJpYWxNb2RlID0gVHJpYW5nbGVNYXRlcmlhbE1vZGUuTVVMVElfUEFTUztcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHR5cGUgPT09IDIpIHtcblx0XHRcdHZhciB0ZXhfYWRkcjpudW1iZXIgPSBwcm9wcy5nZXQoMiwgMCk7XG5cblx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRCh0ZXhfYWRkciwgW0Fzc2V0VHlwZS5URVhUVVJFXSk7XG5cblx0XHRcdGlmICgoIXJldHVybmVkQXJyYXlbMF0pICYmICh0ZXhfYWRkciA+IDApKVxuXHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgRGlmZnN1ZVRleHR1cmUgKElEID0gXCIgKyB0ZXhfYWRkciArIFwiICkgZm9yIHRoaXMgTWF0ZXJpYWxcIik7XG5cblx0XHRcdG1hdCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKDxUZXh0dXJlMkRCYXNlPiByZXR1cm5lZEFycmF5WzFdKTtcblxuXHRcdFx0aWYgKHRoaXMubWF0ZXJpYWxNb2RlIDwgMikge1xuXHRcdFx0XHRtYXQuYWxwaGFCbGVuZGluZyA9IHByb3BzLmdldCgxMSwgZmFsc2UpO1xuXHRcdFx0XHRtYXQuYWxwaGEgPSBwcm9wcy5nZXQoMTAsIDEuMCk7XG5cdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiUGFyc2VkIGEgVHJpYW5nbGVNZXRob2RNYXRlcmlhbChTaW5nbGVQYXNzKTogTmFtZSA9ICdcIiArIG5hbWUgKyBcIicgfCBUZXh0dXJlLU5hbWUgPSBcIiArIG1hdC5uYW1lO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Lm1hdGVyaWFsTW9kZSA9IFRyaWFuZ2xlTWF0ZXJpYWxNb2RlLk1VTFRJX1BBU1M7XG5cdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiUGFyc2VkIGEgVHJpYW5nbGVNZXRob2RNYXRlcmlhbChNdWx0aVBhc3MpOiBOYW1lID0gJ1wiICsgbmFtZSArIFwiJyB8IFRleHR1cmUtTmFtZSA9IFwiICsgbWF0Lm5hbWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0bWF0LmV4dHJhID0gYXR0cmlidXRlcztcblx0XHRtYXQuYWxwaGFUaHJlc2hvbGQgPSBwcm9wcy5nZXQoMTIsIDAuMCk7XG5cdFx0bWF0LnJlcGVhdCA9IHByb3BzLmdldCgxMywgZmFsc2UpO1xuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KDxJQXNzZXQ+IG1hdCwgbmFtZSk7XG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBtYXQ7XG5cblx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdGNvbnNvbGUubG9nKGRlYnVnU3RyaW5nKTtcblxuXHRcdH1cblx0fVxuXG5cdC8vIEJsb2NrIElEID0gODEgQVdEMi4xXG5cdHByaXZhdGUgcGFyc2VNYXRlcmlhbF92MShibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cdFx0dmFyIG1hdDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXHRcdHZhciBub3JtYWxUZXh0dXJlOlRleHR1cmUyREJhc2U7XG5cdFx0dmFyIHNwZWNUZXh0dXJlOlRleHR1cmUyREJhc2U7XG5cdFx0dmFyIHJldHVybmVkQXJyYXk6QXJyYXk8YW55PjtcblxuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgdHlwZTpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTtcblx0XHR2YXIgbnVtX21ldGhvZHM6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTpBV0RQYXJzZXIuVUlOVDMyLCAyOkFXRFBhcnNlci5CQUREUiwgMzpBV0RQYXJzZXIuQkFERFIsIDQ6QVdEUGFyc2VyLlVJTlQ4LCA1OkFXRFBhcnNlci5CT09MLCA2OkFXRFBhcnNlci5CT09MLCA3OkFXRFBhcnNlci5CT09MLCA4OkFXRFBhcnNlci5CT09MLCA5OkFXRFBhcnNlci5VSU5UOCwgMTA6dGhpcy5fcHJvcHNOclR5cGUsIDExOkFXRFBhcnNlci5CT09MLCAxMjp0aGlzLl9wcm9wc05yVHlwZSwgMTM6QVdEUGFyc2VyLkJPT0wsIDE1OnRoaXMuX3Byb3BzTnJUeXBlLCAxNjpBV0RQYXJzZXIuVUlOVDMyLCAxNzpBV0RQYXJzZXIuQkFERFIsIDE4OnRoaXMuX3Byb3BzTnJUeXBlLCAxOTp0aGlzLl9wcm9wc05yVHlwZSwgMjA6QVdEUGFyc2VyLlVJTlQzMiwgMjE6QVdEUGFyc2VyLkJBRERSLCAyMjpBV0RQYXJzZXIuQkFERFJ9KTtcblx0XHR2YXIgc3BlemlhbFR5cGU6bnVtYmVyID0gcHJvcHMuZ2V0KDQsIDApO1xuXHRcdHZhciBkZWJ1Z1N0cmluZzpzdHJpbmcgPSBcIlwiO1xuXG5cdFx0aWYgKHNwZXppYWxUeXBlID49IDIpIHsvL3RoaXMgaXMgbm8gc3VwcG9ydGVkIG1hdGVyaWFsXG5cdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJNYXRlcmlhbC1zcGV6aWFsVHlwZSAnXCIgKyBzcGV6aWFsVHlwZSArIFwiJyBpcyBub3Qgc3VwcG9ydGVkLCBjYW4gb25seSBiZSAwOnNpbmdsZVBhc3MsIDE6TXVsdGlQYXNzICFcIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMubWF0ZXJpYWxNb2RlID09IDEpXG5cdFx0XHRzcGV6aWFsVHlwZSA9IDA7XG5cdFx0ZWxzZSBpZiAodGhpcy5tYXRlcmlhbE1vZGUgPT0gMilcblx0XHRcdHNwZXppYWxUeXBlID0gMTtcblxuXHRcdGlmIChzcGV6aWFsVHlwZSA8IDIpIHsvL3RoaXMgaXMgU2luZ2xlUGFzcyBvciBNdWx0aVBhc3NcblxuXHRcdFx0aWYgKHR5cGUgPT0gMSkgey8vIENvbG9yIG1hdGVyaWFsXG5cdFx0XHRcdHZhciBjb2xvcjpudW1iZXIgPSBwcm9wcy5nZXQoMSwgMHhjY2NjY2MpOy8vVE9ETyB0ZW1wb3JhcmlseSBzd2FwcGVkIHNvIHRoYXQgZGlmZnVzZSBjb2xvciBnb2VzIHRvIGFtYmllbnRcblxuXHRcdFx0XHRpZiAoc3BlemlhbFR5cGUgPT0gMSkgey8vXHRNdWx0aVBhc3NNYXRlcmlhbFxuXHRcdFx0XHRcdG1hdCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKGNvbG9yKTtcblx0XHRcdFx0XHRtYXQubWF0ZXJpYWxNb2RlID0gVHJpYW5nbGVNYXRlcmlhbE1vZGUuTVVMVElfUEFTUztcblx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIlBhcnNlZCBhIENvbG9yTWF0ZXJpYWwoTXVsdGlQYXNzKTogTmFtZSA9ICdcIiArIG5hbWUgKyBcIicgfCBcIjtcblxuXHRcdFx0XHR9IGVsc2UgeyAvL1x0U2luZ2xlUGFzc01hdGVyaWFsXG5cdFx0XHRcdFx0bWF0ID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwoY29sb3IsIHByb3BzLmdldCgxMCwgMS4wKSk7XG5cdFx0XHRcdFx0bWF0LmFscGhhQmxlbmRpbmcgPSBwcm9wcy5nZXQoMTEsIGZhbHNlKTtcblx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIlBhcnNlZCBhIENvbG9yTWF0ZXJpYWwoU2luZ2xlUGFzcyk6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgXCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIGlmICh0eXBlID09IDIpIHsvLyB0ZXh0dXJlIG1hdGVyaWFsXG5cdFx0XHRcdHZhciB0ZXhfYWRkcjpudW1iZXIgPSBwcm9wcy5nZXQoMiwgMCk7Ly9UT0RPIHRlbXBvcmFyaWx5IHN3YXBwZWQgc28gdGhhdCBkaWZmdXNlIHRleHR1cmUgZ29lcyB0byBhbWJpZW50XG5cdFx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRCh0ZXhfYWRkciwgW0Fzc2V0VHlwZS5URVhUVVJFXSk7XG5cblx0XHRcdFx0aWYgKCghcmV0dXJuZWRBcnJheVswXSkgJiYgKHRleF9hZGRyID4gMCkpXG5cdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIEFtYmllbnRUZXh0dXJlIChJRCA9IFwiICsgdGV4X2FkZHIgKyBcIiApIGZvciB0aGlzIFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5cblx0XHRcdFx0dmFyIHRleHR1cmU6VGV4dHVyZTJEQmFzZSA9IHJldHVybmVkQXJyYXlbMV07XG5cblx0XHRcdFx0bWF0ID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwodGV4dHVyZSk7XG5cblx0XHRcdFx0aWYgKHNwZXppYWxUeXBlID09IDEpIHsvLyBNdWx0aVBhc3NNYXRlcmlhbFxuXHRcdFx0XHRcdG1hdC5tYXRlcmlhbE1vZGUgPSBUcmlhbmdsZU1hdGVyaWFsTW9kZS5NVUxUSV9QQVNTO1xuXG5cdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCJQYXJzZWQgYSBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKE11bHRpUGFzcyk6IE5hbWUgPSAnXCIgKyBuYW1lICsgXCInIHwgVGV4dHVyZS1OYW1lID0gXCIgKyB0ZXh0dXJlLm5hbWU7XG5cdFx0XHRcdH0gZWxzZSB7Ly9cdFNpbmdsZVBhc3NNYXRlcmlhbFxuXHRcdFx0XHRcdG1hdC5hbHBoYSA9IHByb3BzLmdldCgxMCwgMS4wKTtcblx0XHRcdFx0XHRtYXQuYWxwaGFCbGVuZGluZyA9IHByb3BzLmdldCgxMSwgZmFsc2UpO1xuXG5cdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCJQYXJzZWQgYSBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKFNpbmdsZVBhc3MpOiBOYW1lID0gJ1wiICsgbmFtZSArIFwiJyB8IFRleHR1cmUtTmFtZSA9IFwiICsgdGV4dHVyZS5uYW1lO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHZhciBkaWZmdXNlVGV4dHVyZTpUZXh0dXJlMkRCYXNlO1xuXHRcdFx0dmFyIGRpZmZ1c2VUZXhfYWRkcjpudW1iZXIgPSBwcm9wcy5nZXQoMTcsIDApO1xuXG5cdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQoZGlmZnVzZVRleF9hZGRyLCBbQXNzZXRUeXBlLlRFWFRVUkVdKTtcblxuXHRcdFx0aWYgKCghcmV0dXJuZWRBcnJheVswXSkgJiYgKGRpZmZ1c2VUZXhfYWRkciAhPSAwKSkge1xuXHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgRGlmZnVzZVRleHR1cmUgKElEID0gXCIgKyBkaWZmdXNlVGV4X2FkZHIgKyBcIiApIGZvciB0aGlzIFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0XHRkaWZmdXNlVGV4dHVyZSA9IHJldHVybmVkQXJyYXlbMV07XG5cblx0XHRcdGlmIChkaWZmdXNlVGV4dHVyZSkge1xuXHRcdFx0XHRtYXQuZGlmZnVzZVRleHR1cmUgPSBkaWZmdXNlVGV4dHVyZTtcblx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCIgfCBEaWZmdXNlVGV4dHVyZS1OYW1lID0gXCIgKyBkaWZmdXNlVGV4dHVyZS5uYW1lO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbm9ybWFsVGV4X2FkZHI6bnVtYmVyID0gcHJvcHMuZ2V0KDMsIDApO1xuXG5cdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQobm9ybWFsVGV4X2FkZHIsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXG5cdFx0XHRpZiAoKCFyZXR1cm5lZEFycmF5WzBdKSAmJiAobm9ybWFsVGV4X2FkZHIgIT0gMCkpIHtcblx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIE5vcm1hbFRleHR1cmUgKElEID0gXCIgKyBub3JtYWxUZXhfYWRkciArIFwiICkgZm9yIHRoaXMgVHJpYW5nbGVNZXRob2RNYXRlcmlhbFwiKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHJldHVybmVkQXJyYXlbMF0pIHtcblx0XHRcdFx0bm9ybWFsVGV4dHVyZSA9IHJldHVybmVkQXJyYXlbMV07XG5cdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiIHwgTm9ybWFsVGV4dHVyZS1OYW1lID0gXCIgKyBub3JtYWxUZXh0dXJlLm5hbWU7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBzcGVjVGV4X2FkZHI6bnVtYmVyID0gcHJvcHMuZ2V0KDIxLCAwKTtcblx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRChzcGVjVGV4X2FkZHIsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXG5cdFx0XHRpZiAoKCFyZXR1cm5lZEFycmF5WzBdKSAmJiAoc3BlY1RleF9hZGRyICE9IDApKSB7XG5cdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBTcGVjdWxhclRleHR1cmUgKElEID0gXCIgKyBzcGVjVGV4X2FkZHIgKyBcIiApIGZvciB0aGlzIFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5cdFx0XHR9XG5cdFx0XHRpZiAocmV0dXJuZWRBcnJheVswXSkge1xuXHRcdFx0XHRzcGVjVGV4dHVyZSA9IHJldHVybmVkQXJyYXlbMV07XG5cdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiIHwgU3BlY3VsYXJUZXh0dXJlLU5hbWUgPSBcIiArIHNwZWNUZXh0dXJlLm5hbWU7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBsaWdodFBpY2tlckFkZHI6bnVtYmVyID0gcHJvcHMuZ2V0KDIyLCAwKTtcblx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRChsaWdodFBpY2tlckFkZHIsIFtBc3NldFR5cGUuTElHSFRfUElDS0VSXSlcblxuXHRcdFx0aWYgKCghcmV0dXJuZWRBcnJheVswXSkgJiYgKGxpZ2h0UGlja2VyQWRkcikpIHtcblx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIExpZ2h0UGlja2VyIChJRCA9IFwiICsgbGlnaHRQaWNrZXJBZGRyICsgXCIgKSBmb3IgdGhpcyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsXCIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0LmxpZ2h0UGlja2VyID0gPExpZ2h0UGlja2VyQmFzZT4gcmV0dXJuZWRBcnJheVsxXTtcblx0XHRcdFx0Ly9kZWJ1Z1N0cmluZys9XCIgfCBMaWdodHBpY2tlci1OYW1lID0gXCIrTGlnaHRQaWNrZXJCYXNlKHJldHVybmVkQXJyYXlbMV0pLm5hbWU7XG5cdFx0XHR9XG5cblx0XHRcdG1hdC5zbW9vdGggPSBwcm9wcy5nZXQoNSwgdHJ1ZSk7XG5cdFx0XHRtYXQubWlwbWFwID0gcHJvcHMuZ2V0KDYsIHRydWUpO1xuXHRcdFx0bWF0LmJvdGhTaWRlcyA9IHByb3BzLmdldCg3LCBmYWxzZSk7XG5cdFx0XHRtYXQuYWxwaGFQcmVtdWx0aXBsaWVkID0gcHJvcHMuZ2V0KDgsIGZhbHNlKTtcblx0XHRcdG1hdC5ibGVuZE1vZGUgPSB0aGlzLmJsZW5kTW9kZURpY1twcm9wcy5nZXQoOSwgMCldO1xuXHRcdFx0bWF0LnJlcGVhdCA9IHByb3BzLmdldCgxMywgZmFsc2UpO1xuXG5cdFx0XHRpZiAobm9ybWFsVGV4dHVyZSlcblx0XHRcdFx0bWF0Lm5vcm1hbE1hcCA9IG5vcm1hbFRleHR1cmU7XG5cblx0XHRcdGlmIChzcGVjVGV4dHVyZSlcblx0XHRcdFx0bWF0LnNwZWN1bGFyTWFwID0gc3BlY1RleHR1cmU7XG5cblx0XHRcdG1hdC5hbHBoYVRocmVzaG9sZCA9IHByb3BzLmdldCgxMiwgMC4wKTtcblx0XHRcdG1hdC5hbWJpZW50ID0gcHJvcHMuZ2V0KDE1LCAxLjApO1xuXHRcdFx0bWF0LmRpZmZ1c2VDb2xvciA9IHByb3BzLmdldCgxNiwgMHhmZmZmZmYpO1xuXHRcdFx0bWF0LnNwZWN1bGFyID0gcHJvcHMuZ2V0KDE4LCAxLjApO1xuXHRcdFx0bWF0Lmdsb3NzID0gcHJvcHMuZ2V0KDE5LCA1MCk7XG5cdFx0XHRtYXQuc3BlY3VsYXJDb2xvciA9IHByb3BzLmdldCgyMCwgMHhmZmZmZmYpO1xuXG5cdFx0XHR2YXIgbWV0aG9kc19wYXJzZWQ6bnVtYmVyID0gMDtcblx0XHRcdHZhciB0YXJnZXRJRDpudW1iZXI7XG5cblx0XHRcdHdoaWxlIChtZXRob2RzX3BhcnNlZCA8IG51bV9tZXRob2RzKSB7XG5cdFx0XHRcdHZhciBtZXRob2RfdHlwZTpudW1iZXI7XG5cdFx0XHRcdG1ldGhvZF90eXBlID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXG5cdFx0XHRcdHByb3BzID0gdGhpcy5wYXJzZVByb3BlcnRpZXMoezE6QVdEUGFyc2VyLkJBRERSLCAyOkFXRFBhcnNlci5CQUREUiwgMzpBV0RQYXJzZXIuQkFERFIsIDEwMTp0aGlzLl9wcm9wc05yVHlwZSwgMTAyOnRoaXMuX3Byb3BzTnJUeXBlLCAxMDM6dGhpcy5fcHJvcHNOclR5cGUsIDIwMTpBV0RQYXJzZXIuVUlOVDMyLCAyMDI6QVdEUGFyc2VyLlVJTlQzMiwgMzAxOkFXRFBhcnNlci5VSU5UMTYsIDMwMjpBV0RQYXJzZXIuVUlOVDE2LCA0MDE6QVdEUGFyc2VyLlVJTlQ4LCA0MDI6QVdEUGFyc2VyLlVJTlQ4LCA2MDE6QVdEUGFyc2VyLkNPTE9SLCA2MDI6QVdEUGFyc2VyLkNPTE9SLCA3MDE6QVdEUGFyc2VyLkJPT0wsIDcwMjpBV0RQYXJzZXIuQk9PTCwgODAxOkFXRFBhcnNlci5NVFg0eDR9KTtcblxuXHRcdFx0XHRzd2l0Y2ggKG1ldGhvZF90eXBlKSB7XG5cdFx0XHRcdFx0Y2FzZSA5OTk6IC8vd3JhcHBlci1NZXRob2RzIHRoYXQgd2lsbCBsb2FkIGEgcHJldmlvdXMgcGFyc2VkIEVmZmVrdE1ldGhvZCByZXR1cm5lZFxuXG5cdFx0XHRcdFx0XHR0YXJnZXRJRCA9IHByb3BzLmdldCgxLCAwKTtcblx0XHRcdFx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRCh0YXJnZXRJRCwgW0Fzc2V0VHlwZS5FRkZFQ1RTX01FVEhPRF0pO1xuXG5cdFx0XHRcdFx0XHRpZiAoIXJldHVybmVkQXJyYXlbMF0pIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIEVmZmVjdE1ldGhvZCAoSUQgPSBcIiArIHRhcmdldElEICsgXCIgKSBmb3IgdGhpcyBNYXRlcmlhbFwiKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdG1hdC5hZGRFZmZlY3RNZXRob2QocmV0dXJuZWRBcnJheVsxXSk7XG5cblx0XHRcdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCIgfCBFZmZlY3RNZXRob2QtTmFtZSA9IFwiICsgKDxFZmZlY3RNZXRob2RCYXNlPiByZXR1cm5lZEFycmF5WzFdKS5uYW1lO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgOTk4OiAvL3dyYXBwZXItTWV0aG9kcyB0aGF0IHdpbGwgbG9hZCBhIHByZXZpb3VzIHBhcnNlZCBTaGFkb3dNYXBNZXRob2RcblxuXHRcdFx0XHRcdFx0dGFyZ2V0SUQgPSBwcm9wcy5nZXQoMSwgMCk7XG5cdFx0XHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuU0hBRE9XX01BUF9NRVRIT0RdKTtcblxuXHRcdFx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBTaGFkb3dNZXRob2QgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgTWF0ZXJpYWxcIik7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRtYXQuc2hhZG93TWV0aG9kID0gcmV0dXJuZWRBcnJheVsxXTtcblx0XHRcdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCIgfCBTaGFkb3dNZXRob2QtTmFtZSA9IFwiICsgKDxTaGFkb3dNZXRob2RCYXNlPiByZXR1cm5lZEFycmF5WzFdKS5uYW1lO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgMTogLy9FbnZNYXBBbWJpZW50TWV0aG9kXG5cdFx0XHRcdFx0XHR0YXJnZXRJRCA9IHByb3BzLmdldCgxLCAwKTtcblx0XHRcdFx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRCh0YXJnZXRJRCwgW0Fzc2V0VHlwZS5URVhUVVJFXSwgXCJDdWJlVGV4dHVyZVwiKTtcblx0XHRcdFx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSlcblx0XHRcdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIEVudk1hcCAoSUQgPSBcIiArIHRhcmdldElEICsgXCIgKSBmb3IgdGhpcyBFbnZNYXBBbWJpZW50TWV0aG9kTWF0ZXJpYWxcIik7XG5cdFx0XHRcdFx0XHRtYXQuYW1iaWVudE1ldGhvZCA9IG5ldyBBbWJpZW50RW52TWFwTWV0aG9kKHJldHVybmVkQXJyYXlbMV0pO1xuXHRcdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCIgfCBBbWJpZW50RW52TWFwTWV0aG9kIHwgRW52TWFwLU5hbWUgPVwiICsgKDxDdWJlVGV4dHVyZUJhc2U+IHJldHVybmVkQXJyYXlbMV0pLm5hbWU7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgNTE6IC8vRGVwdGhEaWZmdXNlTWV0aG9kXG5cdFx0XHRcdFx0XHRtYXQuZGlmZnVzZU1ldGhvZCA9IG5ldyBEaWZmdXNlRGVwdGhNZXRob2QoKTtcblx0XHRcdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiIHwgRGlmZnVzZURlcHRoTWV0aG9kXCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIDUyOiAvL0dyYWRpZW50RGlmZnVzZU1ldGhvZFxuXHRcdFx0XHRcdFx0dGFyZ2V0SUQgPSBwcm9wcy5nZXQoMSwgMCk7XG5cdFx0XHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXHRcdFx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0XHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgR3JhZGllbnREaWZmdXNlVGV4dHVyZSAoSUQgPSBcIiArIHRhcmdldElEICsgXCIgKSBmb3IgdGhpcyBHcmFkaWVudERpZmZ1c2VNZXRob2RcIik7XG5cdFx0XHRcdFx0XHRtYXQuZGlmZnVzZU1ldGhvZCA9IG5ldyBEaWZmdXNlR3JhZGllbnRNZXRob2QocmV0dXJuZWRBcnJheVsxXSk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IERpZmZ1c2VHcmFkaWVudE1ldGhvZCB8IEdyYWRpZW50RGlmZnVzZVRleHR1cmUtTmFtZSA9XCIgKyAoPFRleHR1cmUyREJhc2U+IHJldHVybmVkQXJyYXlbMV0pLm5hbWU7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIDUzOiAvL1dyYXBEaWZmdXNlTWV0aG9kXG5cdFx0XHRcdFx0XHRtYXQuZGlmZnVzZU1ldGhvZCA9IG5ldyBEaWZmdXNlV3JhcE1ldGhvZChwcm9wcy5nZXQoMTAxLCA1KSk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IERpZmZ1c2VXcmFwTWV0aG9kXCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIDU0OiAvL0xpZ2h0TWFwRGlmZnVzZU1ldGhvZFxuXHRcdFx0XHRcdFx0dGFyZ2V0SUQgPSBwcm9wcy5nZXQoMSwgMCk7XG5cdFx0XHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXHRcdFx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0XHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgTGlnaHRNYXAgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgTGlnaHRNYXBEaWZmdXNlTWV0aG9kXCIpO1xuXHRcdFx0XHRcdFx0bWF0LmRpZmZ1c2VNZXRob2QgPSBuZXcgRGlmZnVzZUxpZ2h0TWFwTWV0aG9kKHJldHVybmVkQXJyYXlbMV0sIHRoaXMuYmxlbmRNb2RlRGljW3Byb3BzLmdldCg0MDEsIDEwKV0sIGZhbHNlLCBtYXQuZGlmZnVzZU1ldGhvZCk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IERpZmZ1c2VMaWdodE1hcE1ldGhvZCB8IExpZ2h0TWFwVGV4dHVyZS1OYW1lID1cIiArICg8VGV4dHVyZTJEQmFzZT4gcmV0dXJuZWRBcnJheVsxXSkubmFtZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgNTU6IC8vQ2VsRGlmZnVzZU1ldGhvZFxuXHRcdFx0XHRcdFx0bWF0LmRpZmZ1c2VNZXRob2QgPSBuZXcgRGlmZnVzZUNlbE1ldGhvZChwcm9wcy5nZXQoNDAxLCAzKSwgbWF0LmRpZmZ1c2VNZXRob2QpO1xuXHRcdFx0XHRcdFx0KDxEaWZmdXNlQ2VsTWV0aG9kPiBtYXQuZGlmZnVzZU1ldGhvZCkuc21vb3RobmVzcyA9IHByb3BzLmdldCgxMDEsIDAuMSk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IERpZmZ1c2VDZWxNZXRob2RcIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgNTY6IC8vU3ViU3VyZmFjZVNjYXR0ZXJpbmdNZXRob2Rcbi8vXHRcdFx0XHRcdFx0XHRtYXQuZGlmZnVzZU1ldGhvZCA9IG5ldyBEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZCgpOyAvL2RlcHRoTWFwU2l6ZSBhbmQgZGVwdGhNYXBPZmZzZXQgP1xuLy9cdFx0XHRcdFx0XHRcdCg8RGlmZnVzZVN1YlN1cmZhY2VNZXRob2Q+IG1hdC5kaWZmdXNlTWV0aG9kKS5zY2F0dGVyaW5nID0gcHJvcHMuZ2V0KDEwMSwgMC4yKTtcbi8vXHRcdFx0XHRcdFx0XHQoPERpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kPiBtYXQuZGlmZnVzZU1ldGhvZCkudHJhbnNsdWNlbmN5ID0gcHJvcHMuZ2V0KDEwMiwgMSk7XG4vL1x0XHRcdFx0XHRcdFx0KDxEaWZmdXNlU3ViU3VyZmFjZU1ldGhvZD4gbWF0LmRpZmZ1c2VNZXRob2QpLnNjYXR0ZXJDb2xvciA9IHByb3BzLmdldCg2MDEsIDB4ZmZmZmZmKTtcbi8vXHRcdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IERpZmZ1c2VTdWJTdXJmYWNlTWV0aG9kXCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgMTAxOiAvL0FuaXNvdHJvcGljU3BlY3VsYXJNZXRob2Rcblx0XHRcdFx0XHRcdG1hdC5zcGVjdWxhck1ldGhvZCA9IG5ldyBTcGVjdWxhckFuaXNvdHJvcGljTWV0aG9kKCk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IFNwZWN1bGFyQW5pc290cm9waWNNZXRob2RcIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgMTAyOiAvL1NwZWN1bGFyUGhvbmdNZXRob2Rcblx0XHRcdFx0XHRcdG1hdC5zcGVjdWxhck1ldGhvZCA9IG5ldyBTcGVjdWxhclBob25nTWV0aG9kKCk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IFNwZWN1bGFyUGhvbmdNZXRob2RcIjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgMTAzOiAvL0NlbGxTcGVjdWxhck1ldGhvZFxuXHRcdFx0XHRcdFx0bWF0LnNwZWN1bGFyTWV0aG9kID0gbmV3IFNwZWN1bGFyQ2VsTWV0aG9kKHByb3BzLmdldCgxMDEsIDAuNSksIG1hdC5zcGVjdWxhck1ldGhvZCk7XG5cdFx0XHRcdFx0XHQoPFNwZWN1bGFyQ2VsTWV0aG9kPiBtYXQuc3BlY3VsYXJNZXRob2QpLnNtb290aG5lc3MgPSBwcm9wcy5nZXQoMTAyLCAwLjEpO1xuXHRcdFx0XHRcdFx0ZGVidWdTdHJpbmcgKz0gXCIgfCBTcGVjdWxhckNlbE1ldGhvZFwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAxMDQ6IC8vU3BlY3VsYXJGcmVzbmVsTWV0aG9kXG5cdFx0XHRcdFx0XHRtYXQuc3BlY3VsYXJNZXRob2QgPSBuZXcgU3BlY3VsYXJGcmVzbmVsTWV0aG9kKHByb3BzLmdldCg3MDEsIHRydWUpLCBtYXQuc3BlY3VsYXJNZXRob2QpO1xuXHRcdFx0XHRcdFx0KDxTcGVjdWxhckZyZXNuZWxNZXRob2Q+IG1hdC5zcGVjdWxhck1ldGhvZCkuZnJlc25lbFBvd2VyID0gcHJvcHMuZ2V0KDEwMSwgNSk7XG5cdFx0XHRcdFx0XHQoPFNwZWN1bGFyRnJlc25lbE1ldGhvZD4gbWF0LnNwZWN1bGFyTWV0aG9kKS5ub3JtYWxSZWZsZWN0YW5jZSA9IHByb3BzLmdldCgxMDIsIDAuMSk7XG5cdFx0XHRcdFx0XHRkZWJ1Z1N0cmluZyArPSBcIiB8IFNwZWN1bGFyRnJlc25lbE1ldGhvZFwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAxNTE6Ly9IZWlnaHRNYXBOb3JtYWxNZXRob2QgLSB0aGlvcyBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIG5vdywgYnV0IG1pZ2h0IGFwcGVhciBsYXRlclxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAxNTI6IC8vU2ltcGxlV2F0ZXJOb3JtYWxNZXRob2Rcblx0XHRcdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0XHRcdFx0cmV0dXJuZWRBcnJheSA9IHRoaXMuZ2V0QXNzZXRCeUlEKHRhcmdldElELCBbQXNzZXRUeXBlLlRFWFRVUkVdKTtcblx0XHRcdFx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSlcblx0XHRcdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIFNlY291bmROb3JtYWxNYXAgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgU2ltcGxlV2F0ZXJOb3JtYWxNZXRob2RcIik7XG5cdFx0XHRcdFx0XHRpZiAoIW1hdC5ub3JtYWxNYXApXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGEgbm9ybWFsIE1hcCBvbiB0aGlzIE1hdGVyaWFsIHRvIHVzZSB3aXRoIHRoaXMgU2ltcGxlV2F0ZXJOb3JtYWxNZXRob2RcIik7XG5cblx0XHRcdFx0XHRcdG1hdC5ub3JtYWxNYXAgPSByZXR1cm5lZEFycmF5WzFdO1xuXHRcdFx0XHRcdFx0bWF0Lm5vcm1hbE1ldGhvZCA9IG5ldyBOb3JtYWxTaW1wbGVXYXRlck1ldGhvZChtYXQubm9ybWFsTWFwLCByZXR1cm5lZEFycmF5WzFdKTtcblx0XHRcdFx0XHRcdGRlYnVnU3RyaW5nICs9IFwiIHwgTm9ybWFsU2ltcGxlV2F0ZXJNZXRob2QgfCBTZWNvbmQtTm9ybWFsVGV4dHVyZS1OYW1lID0gXCIgKyAoPFRleHR1cmUyREJhc2U+IHJldHVybmVkQXJyYXlbMV0pLm5hbWU7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHRcdFx0bWV0aG9kc19wYXJzZWQgKz0gMTtcblx0XHRcdH1cblx0XHR9XG5cdFx0bWF0LmV4dHJhID0gdGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gbWF0LCBuYW1lKTtcblxuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gbWF0O1xuXHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coZGVidWdTdHJpbmcpO1xuXHRcdH1cblx0fVxuXG5cdC8vQmxvY2sgSUQgPSA4MlxuXHRwcml2YXRlIHBhcnNlVGV4dHVyZShibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cblx0XHR2YXIgYXNzZXQ6VGV4dHVyZTJEQmFzZTtcblxuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5uYW1lID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXG5cdFx0dmFyIHR5cGU6bnVtYmVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cdFx0dmFyIGRhdGFfbGVuOm51bWJlcjtcblxuXHRcdHRoaXMuX3RleHR1cmVfdXNlcnNbdGhpcy5fY3VyX2Jsb2NrX2lkLnRvU3RyaW5nKCldID0gW107XG5cblx0XHQvLyBFeHRlcm5hbFxuXHRcdGlmICh0eXBlID09IDApIHtcblx0XHRcdGRhdGFfbGVuID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHRcdHZhciB1cmw6c3RyaW5nO1xuXHRcdFx0dXJsID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVVRGQnl0ZXMoZGF0YV9sZW4pO1xuXHRcdFx0dGhpcy5fcEFkZERlcGVuZGVuY3kodGhpcy5fY3VyX2Jsb2NrX2lkLnRvU3RyaW5nKCksIG5ldyBVUkxSZXF1ZXN0KHVybCksIGZhbHNlLCBudWxsLCB0cnVlKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRkYXRhX2xlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cblx0XHRcdHZhciBkYXRhOkJ5dGVBcnJheTtcblx0XHRcdGRhdGEgPSBuZXcgQnl0ZUFycmF5KCk7XG5cdFx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRCeXRlcyhkYXRhLCAwLCBkYXRhX2xlbik7XG5cblx0XHRcdC8vXG5cdFx0XHQvLyBBV0RQYXJzZXIgLSBGaXggZm9yIEZpcmVGb3ggQnVnOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD03MTUwNzUgLlxuXHRcdFx0Ly9cblx0XHRcdC8vIENvbnZlcnRpbmcgZGF0YSB0byBpbWFnZSBoZXJlIGluc3RlYWQgb2YgcGFyc2VyIC0gZml4IEZpcmVGb3ggYnVnIHdoZXJlIGltYWdlIHdpZHRoIC8gaGVpZ2h0IGlzIDAgd2hlbiBjcmVhdGVkIGZyb20gZGF0YVxuXHRcdFx0Ly8gVGhpcyBnaXZlcyB0aGUgYnJvd3NlciB0aW1lIHRvIGluaXRpYWxpc2UgaW1hZ2Ugd2lkdGggLyBoZWlnaHQuXG5cblx0XHRcdHRoaXMuX3BBZGREZXBlbmRlbmN5KHRoaXMuX2N1cl9ibG9ja19pZC50b1N0cmluZygpLCBudWxsLCBmYWxzZSwgUGFyc2VyVXRpbHMuYnl0ZUFycmF5VG9JbWFnZShkYXRhKSwgdHJ1ZSk7XG5cdFx0XHQvL3RoaXMuX3BBZGREZXBlbmRlbmN5KHRoaXMuX2N1cl9ibG9ja19pZC50b1N0cmluZygpLCBudWxsLCBmYWxzZSwgZGF0YSwgdHJ1ZSk7XG5cblx0XHR9XG5cblx0XHQvLyBJZ25vcmUgZm9yIG5vd1xuXHRcdHRoaXMucGFyc2VQcm9wZXJ0aWVzKG51bGwpO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5leHRyYXMgPSB0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHR0aGlzLl9wUGF1c2VBbmRSZXRyaWV2ZURlcGVuZGVuY2llcygpO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gYXNzZXQ7XG5cblx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdHZhciB0ZXh0dXJlU3R5bGVzTmFtZXM6QXJyYXk8c3RyaW5nPiA9IFtcImV4dGVybmFsXCIsIFwiZW1iZWRcIl1cblx0XHRcdGNvbnNvbGUubG9nKFwiU3RhcnQgcGFyc2luZyBhIFwiICsgdGV4dHVyZVN0eWxlc05hbWVzW3R5cGVdICsgXCIgQml0bWFwIGZvciBUZXh0dXJlXCIpO1xuXHRcdH1cblxuXHR9XG5cblx0Ly9CbG9jayBJRCA9IDgzXG5cdHByaXZhdGUgcGFyc2VDdWJlVGV4dHVyZShibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cdFx0Ly9ibG9ja0xlbmd0aCA9IGJsb2NrLmxlbjtcblx0XHR2YXIgZGF0YV9sZW46bnVtYmVyO1xuXHRcdHZhciBhc3NldDpDdWJlVGV4dHVyZUJhc2U7XG5cdFx0dmFyIGk6bnVtYmVyO1xuXG5cdFx0dGhpcy5fY3ViZVRleHR1cmVzID0gbmV3IEFycmF5PGFueT4oKTtcblx0XHR0aGlzLl90ZXh0dXJlX3VzZXJzWyB0aGlzLl9jdXJfYmxvY2tfaWQudG9TdHJpbmcoKSBdID0gW107XG5cblx0XHR2YXIgdHlwZTpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTtcblxuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5uYW1lID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IDY7IGkrKykge1xuXHRcdFx0dGhpcy5fdGV4dHVyZV91c2Vyc1t0aGlzLl9jdXJfYmxvY2tfaWQudG9TdHJpbmcoKV0gPSBbXTtcblx0XHRcdHRoaXMuX2N1YmVUZXh0dXJlcy5wdXNoKG51bGwpO1xuXG5cdFx0XHQvLyBFeHRlcm5hbFxuXHRcdFx0aWYgKHR5cGUgPT0gMCkge1xuXHRcdFx0XHRkYXRhX2xlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0XHRcdHZhciB1cmw6c3RyaW5nO1xuXHRcdFx0XHR1cmwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVVEZCeXRlcyhkYXRhX2xlbik7XG5cblx0XHRcdFx0dGhpcy5fcEFkZERlcGVuZGVuY3kodGhpcy5fY3VyX2Jsb2NrX2lkLnRvU3RyaW5nKCkgKyBcIiNcIiArIGksIG5ldyBVUkxSZXF1ZXN0KHVybCksIGZhbHNlLCBudWxsLCB0cnVlKTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0ZGF0YV9sZW4gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdFx0XHR2YXIgZGF0YTpCeXRlQXJyYXk7XG5cdFx0XHRcdGRhdGEgPSBuZXcgQnl0ZUFycmF5KCk7XG5cblx0XHRcdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkQnl0ZXMoZGF0YSwgMCwgZGF0YV9sZW4pO1xuXG5cdFx0XHRcdHRoaXMuX3BBZGREZXBlbmRlbmN5KHRoaXMuX2N1cl9ibG9ja19pZC50b1N0cmluZygpICsgXCIjXCIgKyBpLCBudWxsLCBmYWxzZSwgUGFyc2VyVXRpbHMuYnl0ZUFycmF5VG9JbWFnZShkYXRhKSwgdHJ1ZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSWdub3JlIGZvciBub3dcblx0XHR0aGlzLnBhcnNlUHJvcGVydGllcyhudWxsKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZXh0cmFzID0gdGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0dGhpcy5fcFBhdXNlQW5kUmV0cmlldmVEZXBlbmRlbmNpZXMoKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGFzc2V0O1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHR2YXIgdGV4dHVyZVN0eWxlc05hbWVzOkFycmF5PHN0cmluZz4gPSBbXCJleHRlcm5hbFwiLCBcImVtYmVkXCJdXG5cdFx0XHRjb25zb2xlLmxvZyhcIlN0YXJ0IHBhcnNpbmcgNiBcIiArIHRleHR1cmVTdHlsZXNOYW1lc1t0eXBlXSArIFwiIEJpdG1hcHMgZm9yIEN1YmVUZXh0dXJlXCIpO1xuXHRcdH1cblx0fVxuXG5cdC8vQmxvY2sgSUQgPSA5MVxuXHRwcml2YXRlIHBhcnNlU2hhcmVkTWV0aG9kQmxvY2soYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBhc3NldDpFZmZlY3RNZXRob2RCYXNlO1xuXG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLm5hbWUgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cdFx0YXNzZXQgPSB0aGlzLnBhcnNlU2hhcmVkTWV0aG9kTGlzdChibG9ja0lEKTtcblx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGFzc2V0O1xuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KDxJQXNzZXQ+IGFzc2V0LCB0aGlzLl9ibG9ja3NbYmxvY2tJRF0ubmFtZSk7XG5cdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmRhdGEgPSBhc3NldDtcblxuXHRcdGlmICh0aGlzLl9kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBFZmZlY3RNZXRob2Q6IE5hbWUgPSBcIiArIGFzc2V0Lm5hbWUgKyBcIiBUeXBlID0gXCIgKyBhc3NldCk7XG5cdFx0fVxuXHR9XG5cblx0Ly9CbG9jayBJRCA9IDkyXG5cdHByaXZhdGUgcGFyc2VTaGFkb3dNZXRob2RCbG9jayhibG9ja0lEOm51bWJlcik6dm9pZFxuXHR7XG5cdFx0dmFyIHR5cGU6bnVtYmVyO1xuXHRcdHZhciBkYXRhX2xlbjpudW1iZXI7XG5cdFx0dmFyIGFzc2V0OlNoYWRvd01ldGhvZEJhc2U7XG5cdFx0dmFyIHNoYWRvd0xpZ2h0SUQ6bnVtYmVyO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5uYW1lID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXG5cdFx0c2hhZG93TGlnaHRJRCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0dmFyIHJldHVybmVkQXJyYXk6QXJyYXk8YW55PiA9IHRoaXMuZ2V0QXNzZXRCeUlEKHNoYWRvd0xpZ2h0SUQsIFtBc3NldFR5cGUuTElHSFRdKTtcblxuXHRcdGlmICghcmV0dXJuZWRBcnJheVswXSkge1xuXHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIFRhcmdldExpZ2h0IChJRCA9IFwiICsgc2hhZG93TGlnaHRJRCArIFwiICkgZm9yIHRoaXMgU2hhZG93TWV0aG9kIC0gU2hhZG93TWV0aG9kIG5vdCBjcmVhdGVkXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGFzc2V0ID0gdGhpcy5wYXJzZVNoYWRvd01ldGhvZExpc3QoPExpZ2h0QmFzZT4gcmV0dXJuZWRBcnJheVsxXSwgYmxvY2tJRCk7XG5cblx0XHRpZiAoIWFzc2V0KVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7IC8vIElnbm9yZSBmb3Igbm93XG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gYXNzZXQsIHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5uYW1lKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGFzc2V0O1xuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIFNoYWRvd01hcE1ldGhvZE1ldGhvZDogTmFtZSA9IFwiICsgYXNzZXQubmFtZSArIFwiIHwgVHlwZSA9IFwiICsgYXNzZXQgKyBcIiB8IExpZ2h0LU5hbWUgPSBcIiwgKCA8TGlnaHRCYXNlPiByZXR1cm5lZEFycmF5WzFdICkubmFtZSk7XG5cdFx0fVxuXHR9XG5cblxuXHQvL0Jsb2NrIElEID0gMjUzXG5cdHByaXZhdGUgcGFyc2VDb21tYW5kKGJsb2NrSUQ6bnVtYmVyKTp2b2lkXG5cdHtcblx0XHR2YXIgaGFzQmxvY2tzOmJvb2xlYW4gPSAoIHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpID09IDEgKTtcblx0XHR2YXIgcGFyX2lkOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0dmFyIG10eDpNYXRyaXgzRCA9IHRoaXMucGFyc2VNYXRyaXgzRCgpO1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblxuXHRcdHZhciBwYXJlbnRPYmplY3Q6RGlzcGxheU9iamVjdENvbnRhaW5lcjtcblx0XHR2YXIgdGFyZ2V0T2JqZWN0OkRpc3BsYXlPYmplY3RDb250YWluZXI7XG5cblx0XHR2YXIgcmV0dXJuZWRBcnJheTpBcnJheTxhbnk+ID0gdGhpcy5nZXRBc3NldEJ5SUQocGFyX2lkLCBbQXNzZXRUeXBlLkNPTlRBSU5FUiwgQXNzZXRUeXBlLkxJR0hULCBBc3NldFR5cGUuTUVTSF0pO1xuXG5cdFx0aWYgKHJldHVybmVkQXJyYXlbMF0pIHtcblx0XHRcdHBhcmVudE9iamVjdCA9IDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiByZXR1cm5lZEFycmF5WzFdO1xuXHRcdH1cblxuXHRcdHZhciBudW1Db21tYW5kczpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRTaG9ydCgpO1xuXHRcdHZhciB0eXBlQ29tbWFuZDpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRTaG9ydCgpO1xuXG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTpBV0RQYXJzZXIuQkFERFJ9KTtcblxuXHRcdHN3aXRjaCAodHlwZUNvbW1hbmQpIHtcblx0XHRcdGNhc2UgMTpcblxuXHRcdFx0XHR2YXIgdGFyZ2V0SUQ6bnVtYmVyID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0XHR2YXIgcmV0dXJuZWRBcnJheVRhcmdldDpBcnJheTxhbnk+ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuTElHSFQsIEFzc2V0VHlwZS5URVhUVVJFX1BST0pFQ1RPUl0pOyAvL2ZvciBubyBvbmx5IGxpZ2h0IGlzIHJlcXVlc3RlZCEhISFcblxuXHRcdFx0XHRpZiAoKCFyZXR1cm5lZEFycmF5VGFyZ2V0WzBdKSAmJiAodGFyZ2V0SUQgIT0gMCkpIHtcblx0XHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgbGlnaHQgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICggZm9yIHRoaXMgQ29tbWFuZEJvY2shXCIpO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRhcmdldE9iamVjdCA9IHJldHVybmVkQXJyYXlUYXJnZXRbMV07XG5cblx0XHRcdFx0aWYgKHBhcmVudE9iamVjdCkge1xuXHRcdFx0XHRcdHBhcmVudE9iamVjdC5hZGRDaGlsZCh0YXJnZXRPYmplY3QpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGFyZ2V0T2JqZWN0LnRyYW5zZm9ybS5tYXRyaXgzRCA9IG10eDtcblxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRpZiAodGFyZ2V0T2JqZWN0KSB7XG5cdFx0XHRwcm9wcyA9IHRoaXMucGFyc2VQcm9wZXJ0aWVzKHsxOnRoaXMuX21hdHJpeE5yVHlwZSwgMjp0aGlzLl9tYXRyaXhOclR5cGUsIDM6dGhpcy5fbWF0cml4TnJUeXBlLCA0OkFXRFBhcnNlci5VSU5UOH0pO1xuXG5cdFx0XHR0YXJnZXRPYmplY3QucGl2b3QgPSBuZXcgVmVjdG9yM0QocHJvcHMuZ2V0KDEsIDApLCBwcm9wcy5nZXQoMiwgMCksIHByb3BzLmdldCgzLCAwKSk7XG5cdFx0XHR0YXJnZXRPYmplY3QuZXh0cmEgPSB0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblxuXHRcdH1cblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IHRhcmdldE9iamVjdFxuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIENvbW1hbmRCbG9jazogTmFtZSA9ICdcIiArIG5hbWUpO1xuXHRcdH1cblxuXHR9XG5cblx0Ly9ibG9ja0lEIDI1NVxuXHRwcml2YXRlIHBhcnNlTWV0YURhdGEoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBwcm9wczpBV0RQcm9wZXJ0aWVzID0gdGhpcy5wYXJzZVByb3BlcnRpZXMoezE6QVdEUGFyc2VyLlVJTlQzMiwgMjpBV0RQYXJzZXIuQVdEU1RSSU5HLCAzOkFXRFBhcnNlci5BV0RTVFJJTkcsIDQ6QVdEUGFyc2VyLkFXRFNUUklORywgNTpBV0RQYXJzZXIuQVdEU1RSSU5HfSk7XG5cblx0XHRpZiAodGhpcy5fZGVidWcpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiUGFyc2VkIGEgTWV0YURhdGFCbG9jazogVGltZVN0YW1wICAgICAgICAgPSBcIiArIHByb3BzLmdldCgxLCAwKSk7XG5cdFx0XHRjb25zb2xlLmxvZyhcIiAgICAgICAgICAgICAgICAgICAgICAgIEVuY29kZXJOYW1lICAgICAgID0gXCIgKyBwcm9wcy5nZXQoMiwgXCJ1bmtub3duXCIpKTtcblx0XHRcdGNvbnNvbGUubG9nKFwiICAgICAgICAgICAgICAgICAgICAgICAgRW5jb2RlclZlcnNpb24gICAgPSBcIiArIHByb3BzLmdldCgzLCBcInVua25vd25cIikpO1xuXHRcdFx0Y29uc29sZS5sb2coXCIgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JOYW1lICAgICA9IFwiICsgcHJvcHMuZ2V0KDQsIFwidW5rbm93blwiKSk7XG5cdFx0XHRjb25zb2xlLmxvZyhcIiAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvclZlcnNpb24gID0gXCIgKyBwcm9wcy5nZXQoNSwgXCJ1bmtub3duXCIpKTtcblx0XHR9XG5cdH1cblxuXHQvL2Jsb2NrSUQgMjU0XG5cdHByaXZhdGUgcGFyc2VOYW1lU3BhY2UoYmxvY2tJRDpudW1iZXIpOnZvaWRcblx0e1xuXHRcdHZhciBpZDpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTtcblx0XHR2YXIgbmFtZVNwYWNlU3RyaW5nOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHRpZiAodGhpcy5fZGVidWcpXG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIE5hbWVTcGFjZUJsb2NrOiBJRCA9IFwiICsgaWQgKyBcIiB8IFN0cmluZyA9IFwiICsgbmFtZVNwYWNlU3RyaW5nKTtcblx0fVxuXG5cdC8vLS1QYXJzZXIgVVRJTFMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHQvLyB0aGlzIGZ1bmN0aW9ucyByZWFkcyBhbmQgY3JlYXRlcyBhIFNoYWRvd01ldGhvZE1ldGhvZFxuXHRwcml2YXRlIHBhcnNlU2hhZG93TWV0aG9kTGlzdChsaWdodDpMaWdodEJhc2UsIGJsb2NrSUQ6bnVtYmVyKTpTaGFkb3dNZXRob2RCYXNlXG5cdHtcblxuXHRcdHZhciBtZXRob2RUeXBlOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHR2YXIgc2hhZG93TWV0aG9kOlNoYWRvd01ldGhvZEJhc2U7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTpBV0RQYXJzZXIuQkFERFIsIDI6QVdEUGFyc2VyLkJBRERSLCAzOkFXRFBhcnNlci5CQUREUiwgMTAxOnRoaXMuX3Byb3BzTnJUeXBlLCAxMDI6dGhpcy5fcHJvcHNOclR5cGUsIDEwMzp0aGlzLl9wcm9wc05yVHlwZSwgMjAxOkFXRFBhcnNlci5VSU5UMzIsIDIwMjpBV0RQYXJzZXIuVUlOVDMyLCAzMDE6QVdEUGFyc2VyLlVJTlQxNiwgMzAyOkFXRFBhcnNlci5VSU5UMTYsIDQwMTpBV0RQYXJzZXIuVUlOVDgsIDQwMjpBV0RQYXJzZXIuVUlOVDgsIDYwMTpBV0RQYXJzZXIuQ09MT1IsIDYwMjpBV0RQYXJzZXIuQ09MT1IsIDcwMTpBV0RQYXJzZXIuQk9PTCwgNzAyOkFXRFBhcnNlci5CT09MLCA4MDE6QVdEUGFyc2VyLk1UWDR4NH0pO1xuXG5cdFx0dmFyIHRhcmdldElEOm51bWJlcjtcblx0XHR2YXIgcmV0dXJuZWRBcnJheTpBcnJheTxhbnk+XG5cdFx0c3dpdGNoIChtZXRob2RUeXBlKSB7XG5cdFx0XHQvL1x0XHRcdFx0Y2FzZSAxMDAxOiAvL0Nhc2NhZGVTaGFkb3dNYXBNZXRob2Rcblx0XHRcdC8vXHRcdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0Ly9cdFx0XHRcdFx0cmV0dXJuZWRBcnJheSA9IGdldEFzc2V0QnlJRCh0YXJnZXRJRCwgW0Fzc2V0VHlwZS5TSEFET1dfTUFQX01FVEhPRF0pO1xuXHRcdFx0Ly9cdFx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKSB7XG5cdFx0XHQvL1x0XHRcdFx0XHRcdF9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgU2hhZG93QmFzZU1ldGhvZCAoSUQgPSBcIiArIHRhcmdldElEICsgXCIgKSBmb3IgdGhpcyBDYXNjYWRlU2hhZG93TWFwTWV0aG9kIC0gU2hhZG93TWV0aG9kIG5vdCBjcmVhdGVkXCIpO1xuXHRcdFx0Ly9cdFx0XHRcdFx0XHRyZXR1cm4gc2hhZG93TWV0aG9kO1xuXHRcdFx0Ly9cdFx0XHRcdFx0fVxuXHRcdFx0Ly9cdFx0XHRcdFx0c2hhZG93TWV0aG9kID0gbmV3IENhc2NhZGVTaGFkb3dNYXBNZXRob2QocmV0dXJuZWRBcnJheVsxXSk7XG5cdFx0XHQvL1x0XHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTAwMjogLy9TaGFkb3dOZWFyTWV0aG9kXG5cdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuU0hBRE9XX01BUF9NRVRIT0RdKTtcblx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKSB7XG5cdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIFNoYWRvd0Jhc2VNZXRob2QgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgU2hhZG93TmVhck1ldGhvZCAtIFNoYWRvd01ldGhvZCBub3QgY3JlYXRlZFwiKTtcblx0XHRcdFx0XHRyZXR1cm4gc2hhZG93TWV0aG9kO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHNoYWRvd01ldGhvZCA9IG5ldyBTaGFkb3dOZWFyTWV0aG9kKDxTaGFkb3dNZXRob2RCYXNlPiByZXR1cm5lZEFycmF5WzFdKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDExMDE6IC8vU2hhZG93RmlsdGVyZWRNZXRob2RcblxuXHRcdFx0XHRzaGFkb3dNZXRob2QgPSBuZXcgU2hhZG93RmlsdGVyZWRNZXRob2QoPERpcmVjdGlvbmFsTGlnaHQ+IGxpZ2h0KTtcblx0XHRcdFx0KDxTaGFkb3dGaWx0ZXJlZE1ldGhvZD4gc2hhZG93TWV0aG9kKS5hbHBoYSA9IHByb3BzLmdldCgxMDEsIDEpO1xuXHRcdFx0XHQoPFNoYWRvd0ZpbHRlcmVkTWV0aG9kPiBzaGFkb3dNZXRob2QpLmVwc2lsb24gPSBwcm9wcy5nZXQoMTAyLCAwLjAwMik7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIDExMDI6IC8vU2hhZG93RGl0aGVyZWRNZXRob2RcblxuXG5cdFx0XHRcdHNoYWRvd01ldGhvZCA9IG5ldyBTaGFkb3dEaXRoZXJlZE1ldGhvZCg8RGlyZWN0aW9uYWxMaWdodD4gbGlnaHQsIDxudW1iZXI+IHByb3BzLmdldCgyMDEsIDUpKTtcblx0XHRcdFx0KDxTaGFkb3dEaXRoZXJlZE1ldGhvZD4gc2hhZG93TWV0aG9kKS5hbHBoYSA9IHByb3BzLmdldCgxMDEsIDEpO1xuXHRcdFx0XHQoPFNoYWRvd0RpdGhlcmVkTWV0aG9kPiBzaGFkb3dNZXRob2QpLmVwc2lsb24gPSBwcm9wcy5nZXQoMTAyLCAwLjAwMik7XG5cdFx0XHRcdCg8U2hhZG93RGl0aGVyZWRNZXRob2Q+IHNoYWRvd01ldGhvZCkucmFuZ2UgPSBwcm9wcy5nZXQoMTAzLCAxKTtcblxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTEwMzogLy9TaGFkb3dTb2Z0TWV0aG9kXG5cblx0XHRcdFx0c2hhZG93TWV0aG9kID0gbmV3IFNoYWRvd1NvZnRNZXRob2QoPERpcmVjdGlvbmFsTGlnaHQ+IGxpZ2h0LCA8bnVtYmVyPiBwcm9wcy5nZXQoMjAxLCA1KSk7XG5cdFx0XHRcdCg8U2hhZG93U29mdE1ldGhvZD4gc2hhZG93TWV0aG9kKS5hbHBoYSA9IHByb3BzLmdldCgxMDEsIDEpO1xuXHRcdFx0XHQoPFNoYWRvd1NvZnRNZXRob2Q+IHNoYWRvd01ldGhvZCkuZXBzaWxvbiA9IHByb3BzLmdldCgxMDIsIDAuMDAyKTtcblx0XHRcdFx0KDxTaGFkb3dTb2Z0TWV0aG9kPiBzaGFkb3dNZXRob2QpLnJhbmdlID0gcHJvcHMuZ2V0KDEwMywgMSk7XG5cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDExMDQ6IC8vU2hhZG93SGFyZE1ldGhvZFxuXHRcdFx0XHRzaGFkb3dNZXRob2QgPSBuZXcgU2hhZG93SGFyZE1ldGhvZChsaWdodCk7XG5cdFx0XHRcdCg8U2hhZG93SGFyZE1ldGhvZD4gc2hhZG93TWV0aG9kKS5hbHBoYSA9IHByb3BzLmdldCgxMDEsIDEpO1xuXHRcdFx0XHQoPFNoYWRvd0hhcmRNZXRob2Q+IHNoYWRvd01ldGhvZCkuZXBzaWxvbiA9IHByb3BzLmdldCgxMDIsIDAuMDAyKTtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHR9XG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0cmV0dXJuIHNoYWRvd01ldGhvZDtcblx0fVxuXG5cdC8vQmxvY2sgSUQgMTAxXG5cdHByaXZhdGUgcGFyc2VTa2VsZXRvbihibG9ja0lEOm51bWJlciAvKnVpbnQqLyk6dm9pZFxuXHR7XG5cdFx0dmFyIG5hbWU6c3RyaW5nID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXHRcdHZhciBudW1fam9pbnRzOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHR2YXIgc2tlbGV0b246U2tlbGV0b24gPSBuZXcgU2tlbGV0b24oKTtcblx0XHR0aGlzLnBhcnNlUHJvcGVydGllcyhudWxsKTsgLy8gRGlzY2FyZCBwcm9wZXJ0aWVzIGZvciBub3dcdFx0XG5cblx0XHR2YXIgam9pbnRzX3BhcnNlZDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRcdHdoaWxlIChqb2ludHNfcGFyc2VkIDwgbnVtX2pvaW50cykge1xuXHRcdFx0dmFyIGpvaW50OlNrZWxldG9uSm9pbnQ7XG5cdFx0XHR2YXIgaWJwOk1hdHJpeDNEO1xuXHRcdFx0Ly8gSWdub3JlIGpvaW50IGlkXG5cdFx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRqb2ludCA9IG5ldyBTa2VsZXRvbkpvaW50KCk7XG5cdFx0XHRqb2ludC5wYXJlbnRJbmRleCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKSAtIDE7IC8vIDA9bnVsbCBpbiBBV0Rcblx0XHRcdGpvaW50Lm5hbWUgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cblx0XHRcdGlicCA9IHRoaXMucGFyc2VNYXRyaXgzRCgpO1xuXHRcdFx0am9pbnQuaW52ZXJzZUJpbmRQb3NlID0gaWJwLnJhd0RhdGE7XG5cdFx0XHQvLyBJZ25vcmUgam9pbnQgcHJvcHMvYXR0cmlidXRlcyBmb3Igbm93XG5cdFx0XHR0aGlzLnBhcnNlUHJvcGVydGllcyhudWxsKTtcblx0XHRcdHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdFx0c2tlbGV0b24uam9pbnRzLnB1c2goam9pbnQpO1xuXHRcdFx0am9pbnRzX3BhcnNlZCsrO1xuXHRcdH1cblxuXHRcdC8vIERpc2NhcmQgYXR0cmlidXRlcyBmb3Igbm93XG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoc2tlbGV0b24sIG5hbWUpO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gc2tlbGV0b247XG5cdFx0aWYgKHRoaXMuX2RlYnVnKVxuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBTa2VsZXRvbjogTmFtZSA9IFwiICsgc2tlbGV0b24ubmFtZSArIFwiIHwgTnVtYmVyIG9mIEpvaW50cyA9IFwiICsgam9pbnRzX3BhcnNlZCk7XG5cdH1cblxuXHQvL0Jsb2NrIElEID0gMTAyXG5cdHByaXZhdGUgcGFyc2VTa2VsZXRvblBvc2UoYmxvY2tJRDpudW1iZXIgLyp1aW50Ki8pOnZvaWRcblx0e1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgbnVtX2pvaW50czpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0dGhpcy5wYXJzZVByb3BlcnRpZXMobnVsbCk7IC8vIElnbm9yZSBwcm9wZXJ0aWVzIGZvciBub3dcblxuXHRcdHZhciBwb3NlOlNrZWxldG9uUG9zZSA9IG5ldyBTa2VsZXRvblBvc2UoKTtcblxuXHRcdHZhciBqb2ludHNfcGFyc2VkOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cdFx0d2hpbGUgKGpvaW50c19wYXJzZWQgPCBudW1fam9pbnRzKSB7XG5cdFx0XHR2YXIgam9pbnRfcG9zZTpKb2ludFBvc2U7XG5cdFx0XHR2YXIgaGFzX3RyYW5zZm9ybTpudW1iZXIgLyp1aW50Ki87XG5cdFx0XHRqb2ludF9wb3NlID0gbmV3IEpvaW50UG9zZSgpO1xuXHRcdFx0aGFzX3RyYW5zZm9ybSA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0aWYgKGhhc190cmFuc2Zvcm0gPT0gMSkge1xuXHRcdFx0XHR2YXIgbXR4X2RhdGE6QXJyYXk8bnVtYmVyPiA9IHRoaXMucGFyc2VNYXRyaXg0M1Jhd0RhdGEoKTtcblxuXHRcdFx0XHR2YXIgbXR4Ok1hdHJpeDNEID0gbmV3IE1hdHJpeDNEKG10eF9kYXRhKTtcblx0XHRcdFx0am9pbnRfcG9zZS5vcmllbnRhdGlvbi5mcm9tTWF0cml4KG10eCk7XG5cdFx0XHRcdGpvaW50X3Bvc2UudHJhbnNsYXRpb24uY29weUZyb20obXR4LnBvc2l0aW9uKTtcblxuXHRcdFx0XHRwb3NlLmpvaW50UG9zZXNbam9pbnRzX3BhcnNlZF0gPSBqb2ludF9wb3NlO1xuXHRcdFx0fVxuXHRcdFx0am9pbnRzX3BhcnNlZCsrO1xuXHRcdH1cblx0XHQvLyBTa2lwIGF0dHJpYnV0ZXMgZm9yIG5vd1xuXHRcdHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHBvc2UsIG5hbWUpO1xuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gcG9zZTtcblx0XHRpZiAodGhpcy5fZGVidWcpXG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIFNrZWxldG9uUG9zZTogTmFtZSA9IFwiICsgcG9zZS5uYW1lICsgXCIgfCBOdW1iZXIgb2YgSm9pbnRzID0gXCIgKyBqb2ludHNfcGFyc2VkKTtcblx0fVxuXG5cdC8vYmxvY2tJRCAxMDNcblx0cHJpdmF0ZSBwYXJzZVNrZWxldG9uQW5pbWF0aW9uKGJsb2NrSUQ6bnVtYmVyIC8qdWludCovKTp2b2lkXG5cdHtcblx0XHR2YXIgZnJhbWVfZHVyOm51bWJlcjtcblx0XHR2YXIgcG9zZV9hZGRyOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgbmFtZTpzdHJpbmcgPSB0aGlzLnBhcnNlVmFyU3RyKCk7XG5cdFx0dmFyIGNsaXA6U2tlbGV0b25DbGlwTm9kZSA9IG5ldyBTa2VsZXRvbkNsaXBOb2RlKCk7XG5cdFx0dmFyIG51bV9mcmFtZXM6bnVtYmVyIC8qdWludCovID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdHRoaXMucGFyc2VQcm9wZXJ0aWVzKG51bGwpOyAvLyBJZ25vcmUgcHJvcGVydGllcyBmb3Igbm93XG5cblx0XHR2YXIgZnJhbWVzX3BhcnNlZDpudW1iZXIgLyp1aW50Ki8gPSAwO1xuXHRcdHZhciByZXR1cm5lZEFycmF5OkFycmF5PGFueT47XG5cdFx0d2hpbGUgKGZyYW1lc19wYXJzZWQgPCBudW1fZnJhbWVzKSB7XG5cdFx0XHRwb3NlX2FkZHIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdFx0ZnJhbWVfZHVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdFx0cmV0dXJuZWRBcnJheSA9IHRoaXMuZ2V0QXNzZXRCeUlEKHBvc2VfYWRkciwgW0Fzc2V0VHlwZS5TS0VMRVRPTl9QT1NFXSk7XG5cdFx0XHRpZiAoIXJldHVybmVkQXJyYXlbMF0pXG5cdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBTa2VsZXRvblBvc2UgRnJhbWUgIyBcIiArIGZyYW1lc19wYXJzZWQgKyBcIiAoSUQgPSBcIiArIHBvc2VfYWRkciArIFwiICkgZm9yIHRoaXMgU2tlbGV0b25DbGlwTm9kZVwiKTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0Y2xpcC5hZGRGcmFtZSg8U2tlbGV0b25Qb3NlPiB0aGlzLl9ibG9ja3NbcG9zZV9hZGRyXS5kYXRhLCBmcmFtZV9kdXIpO1xuXHRcdFx0ZnJhbWVzX3BhcnNlZCsrO1xuXHRcdH1cblx0XHRpZiAoY2xpcC5mcmFtZXMubGVuZ3RoID09IDApIHtcblx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCB0aGlzIFNrZWxldG9uQ2xpcE5vZGUsIGJlY2F1c2Ugbm8gRnJhbWVzIHdoZXJlIHNldC5cIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdC8vIElnbm9yZSBhdHRyaWJ1dGVzIGZvciBub3dcblx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHR0aGlzLl9wRmluYWxpemVBc3NldChjbGlwLCBuYW1lKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IGNsaXA7XG5cdFx0aWYgKHRoaXMuX2RlYnVnKVxuXHRcdFx0Y29uc29sZS5sb2coXCJQYXJzZWQgYSBTa2VsZXRvbkNsaXBOb2RlOiBOYW1lID0gXCIgKyBjbGlwLm5hbWUgKyBcIiB8IE51bWJlciBvZiBGcmFtZXMgPSBcIiArIGNsaXAuZnJhbWVzLmxlbmd0aCk7XG5cdH1cblxuXHQvL0Jsb2NrIElEID0gMTExIC8gIEJsb2NrIElEID0gMTEyXG5cdHByaXZhdGUgcGFyc2VNZXNoUG9zZUFuaW1hdGlvbihibG9ja0lEOm51bWJlciAvKnVpbnQqLywgcG9zZU9ubHk6Ym9vbGVhbiA9IGZhbHNlKTp2b2lkXG5cdHtcblx0XHR2YXIgbnVtX2ZyYW1lczpudW1iZXIgLyp1aW50Ki8gPSAxO1xuXHRcdHZhciBudW1fc3VibWVzaGVzOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgZnJhbWVzX3BhcnNlZDpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIHN1Yk1lc2hQYXJzZWQ6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBmcmFtZV9kdXI6bnVtYmVyO1xuXHRcdHZhciB4Om51bWJlcjtcblx0XHR2YXIgeTpudW1iZXI7XG5cdFx0dmFyIHo6bnVtYmVyO1xuXHRcdHZhciBzdHJfbGVuOm51bWJlcjtcblx0XHR2YXIgc3RyX2VuZDpudW1iZXI7XG5cdFx0dmFyIGdlb21ldHJ5Okdlb21ldHJ5O1xuXHRcdHZhciBzdWJHZW9tOlRyaWFuZ2xlU3ViR2VvbWV0cnk7XG5cdFx0dmFyIGlkeDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdFx0dmFyIGNsaXA6VmVydGV4Q2xpcE5vZGUgPSBuZXcgVmVydGV4Q2xpcE5vZGUoKTtcblx0XHR2YXIgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovO1xuXHRcdHZhciB2ZXJ0czpBcnJheTxudW1iZXI+O1xuXHRcdHZhciBudW1fU3RyZWFtczpudW1iZXIgLyppbnQqLyA9IDA7XG5cdFx0dmFyIHN0cmVhbXNQYXJzZWQ6bnVtYmVyIC8qaW50Ki8gPSAwO1xuXHRcdHZhciBzdHJlYW10eXBlczpBcnJheTxudW1iZXI+IC8qaW50Ki8gPSBuZXcgQXJyYXk8bnVtYmVyPigpIC8qaW50Ki87XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXM7XG5cdFx0dmFyIHRoaXNHZW86R2VvbWV0cnk7XG5cdFx0dmFyIG5hbWU6c3RyaW5nID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXHRcdHZhciBnZW9BZHJlc3M6bnVtYmVyIC8qaW50Ki8gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdHZhciByZXR1cm5lZEFycmF5OkFycmF5PGFueT4gPSB0aGlzLmdldEFzc2V0QnlJRChnZW9BZHJlc3MsIFtBc3NldFR5cGUuR0VPTUVUUlldKTtcblx0XHRpZiAoIXJldHVybmVkQXJyYXlbMF0pIHtcblx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSB0YXJnZXQtR2VvbWV0cnktT2JqZWN0IFwiICsgZ2VvQWRyZXNzICsgXCIgKSBmb3IgdGhpcyBWZXJ0ZXhDbGlwTm9kZVwiKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dmFyIHV2czpBcnJheTxBcnJheTxudW1iZXI+PiA9IHRoaXMuZ2V0VVZGb3JWZXJ0ZXhBbmltYXRpb24oZ2VvQWRyZXNzKTtcblx0XHRpZiAoIXBvc2VPbmx5KVxuXHRcdFx0bnVtX2ZyYW1lcyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblxuXHRcdG51bV9zdWJtZXNoZXMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0bnVtX1N0cmVhbXMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0c3RyZWFtc1BhcnNlZCA9IDA7XG5cdFx0d2hpbGUgKHN0cmVhbXNQYXJzZWQgPCBudW1fU3RyZWFtcykge1xuXHRcdFx0c3RyZWFtdHlwZXMucHVzaCh0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCkpO1xuXHRcdFx0c3RyZWFtc1BhcnNlZCsrO1xuXHRcdH1cblx0XHRwcm9wcyA9IHRoaXMucGFyc2VQcm9wZXJ0aWVzKHsxOkFXRFBhcnNlci5CT09MLCAyOkFXRFBhcnNlci5CT09MfSk7XG5cblx0XHRjbGlwLmxvb3BpbmcgPSBwcm9wcy5nZXQoMSwgdHJ1ZSk7XG5cdFx0Y2xpcC5zdGl0Y2hGaW5hbEZyYW1lID0gcHJvcHMuZ2V0KDIsIGZhbHNlKTtcblxuXHRcdGZyYW1lc19wYXJzZWQgPSAwO1xuXHRcdHdoaWxlIChmcmFtZXNfcGFyc2VkIDwgbnVtX2ZyYW1lcykge1xuXHRcdFx0ZnJhbWVfZHVyID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdFx0Z2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoKTtcblx0XHRcdHN1Yk1lc2hQYXJzZWQgPSAwO1xuXHRcdFx0d2hpbGUgKHN1Yk1lc2hQYXJzZWQgPCBudW1fc3VibWVzaGVzKSB7XG5cdFx0XHRcdHN0cmVhbXNQYXJzZWQgPSAwO1xuXHRcdFx0XHRzdHJfbGVuID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHRcdFx0c3RyX2VuZCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gKyBzdHJfbGVuO1xuXHRcdFx0XHR3aGlsZSAoc3RyZWFtc1BhcnNlZCA8IG51bV9TdHJlYW1zKSB7XG5cdFx0XHRcdFx0aWYgKHN0cmVhbXR5cGVzW3N0cmVhbXNQYXJzZWRdID09IDEpIHtcblx0XHRcdFx0XHRcdGluZGljZXMgPSAoPEdlb21ldHJ5PiByZXR1cm5lZEFycmF5WzFdKS5zdWJHZW9tZXRyaWVzW3N1Yk1lc2hQYXJzZWRdLmluZGljZXM7XG5cdFx0XHRcdFx0XHR2ZXJ0cyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0XHRcdFx0XHRpZHggPSAwO1xuXHRcdFx0XHRcdFx0d2hpbGUgKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPCBzdHJfZW5kKSB7XG5cdFx0XHRcdFx0XHRcdHggPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lHZW8pXG5cdFx0XHRcdFx0XHRcdHkgPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lHZW8pXG5cdFx0XHRcdFx0XHRcdHogPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lHZW8pXG5cdFx0XHRcdFx0XHRcdHZlcnRzW2lkeCsrXSA9IHg7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW2lkeCsrXSA9IHk7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW2lkeCsrXSA9IHo7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRzdWJHZW9tID0gbmV3IFRyaWFuZ2xlU3ViR2VvbWV0cnkodHJ1ZSk7XG5cdFx0XHRcdFx0XHRzdWJHZW9tLnVwZGF0ZUluZGljZXMoaW5kaWNlcyk7XG5cdFx0XHRcdFx0XHRzdWJHZW9tLnVwZGF0ZVBvc2l0aW9ucyh2ZXJ0cyk7XG5cdFx0XHRcdFx0XHRzdWJHZW9tLnVwZGF0ZVVWcyh1dnNbc3ViTWVzaFBhcnNlZF0pO1xuXHRcdFx0XHRcdFx0c3ViR2VvbS51cGRhdGVWZXJ0ZXhOb3JtYWxzKG51bGwpO1xuXHRcdFx0XHRcdFx0c3ViR2VvbS51cGRhdGVWZXJ0ZXhUYW5nZW50cyhudWxsKTtcblx0XHRcdFx0XHRcdHN1Ykdlb20uYXV0b0Rlcml2ZU5vcm1hbHMgPSBmYWxzZTtcblx0XHRcdFx0XHRcdHN1Ykdlb20uYXV0b0Rlcml2ZVRhbmdlbnRzID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRzdWJNZXNoUGFyc2VkKys7XG5cdFx0XHRcdFx0XHRnZW9tZXRyeS5hZGRTdWJHZW9tZXRyeShzdWJHZW9tKVxuXHRcdFx0XHRcdH0gZWxzZVxuXHRcdFx0XHRcdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiA9IHN0cl9lbmQ7XG5cdFx0XHRcdFx0c3RyZWFtc1BhcnNlZCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjbGlwLmFkZEZyYW1lKGdlb21ldHJ5LCBmcmFtZV9kdXIpO1xuXHRcdFx0ZnJhbWVzX3BhcnNlZCsrO1xuXHRcdH1cblx0XHR0aGlzLnBhcnNlVXNlckF0dHJpYnV0ZXMoKTtcblx0XHR0aGlzLl9wRmluYWxpemVBc3NldChjbGlwLCBuYW1lKTtcblxuXHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gY2xpcDtcblx0XHRpZiAodGhpcy5fZGVidWcpXG5cdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIFZlcnRleENsaXBOb2RlOiBOYW1lID0gXCIgKyBjbGlwLm5hbWUgKyBcIiB8IFRhcmdldC1HZW9tZXRyeS1OYW1lID0gXCIgKyAoPEdlb21ldHJ5PiByZXR1cm5lZEFycmF5WzFdKS5uYW1lICsgXCIgfCBOdW1iZXIgb2YgRnJhbWVzID0gXCIgKyBjbGlwLmZyYW1lcy5sZW5ndGgpO1xuXHR9XG5cblx0Ly9CbG9ja0lEIDExM1xuXHRwcml2YXRlIHBhcnNlVmVydGV4QW5pbWF0aW9uU2V0KGJsb2NrSUQ6bnVtYmVyIC8qdWludCovKTp2b2lkXG5cdHtcblx0XHR2YXIgcG9zZUJsb2NrQWRyZXNzOm51bWJlciAvKmludCovXG5cdFx0dmFyIG91dHB1dFN0cmluZzpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBuYW1lOnN0cmluZyA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHR2YXIgbnVtX2ZyYW1lczpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTpBV0RQYXJzZXIuVUlOVDE2fSk7XG5cdFx0dmFyIGZyYW1lc19wYXJzZWQ6bnVtYmVyIC8qdWludCovID0gMDtcblx0XHR2YXIgc2tlbGV0b25GcmFtZXM6QXJyYXk8U2tlbGV0b25DbGlwTm9kZT4gPSBuZXcgQXJyYXk8U2tlbGV0b25DbGlwTm9kZT4oKTtcblx0XHR2YXIgdmVydGV4RnJhbWVzOkFycmF5PFZlcnRleENsaXBOb2RlPiA9IG5ldyBBcnJheTxWZXJ0ZXhDbGlwTm9kZT4oKTtcblx0XHR3aGlsZSAoZnJhbWVzX3BhcnNlZCA8IG51bV9mcmFtZXMpIHtcblx0XHRcdHBvc2VCbG9ja0FkcmVzcyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0XHR2YXIgcmV0dXJuZWRBcnJheTpBcnJheTxhbnk+ID0gdGhpcy5nZXRBc3NldEJ5SUQocG9zZUJsb2NrQWRyZXNzLCBbQXNzZXRUeXBlLkFOSU1BVElPTl9OT0RFXSk7XG5cdFx0XHRpZiAoIXJldHVybmVkQXJyYXlbMF0pXG5cdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBBbmltYXRpb25DbGlwTm9kZSBOciBcIiArIGZyYW1lc19wYXJzZWQgKyBcIiAoIFwiICsgcG9zZUJsb2NrQWRyZXNzICsgXCIgKSBmb3IgdGhpcyBBbmltYXRpb25TZXRcIik7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0aWYgKHJldHVybmVkQXJyYXlbMV0gaW5zdGFuY2VvZiBWZXJ0ZXhDbGlwTm9kZSlcblx0XHRcdFx0dmVydGV4RnJhbWVzLnB1c2gocmV0dXJuZWRBcnJheVsxXSlcblx0XHRcdFx0aWYgKHJldHVybmVkQXJyYXlbMV0gaW5zdGFuY2VvZiBTa2VsZXRvbkNsaXBOb2RlKVxuXHRcdFx0XHRza2VsZXRvbkZyYW1lcy5wdXNoKHJldHVybmVkQXJyYXlbMV0pXG5cdFx0XHR9XG5cdFx0XHRmcmFtZXNfcGFyc2VkKys7XG5cdFx0fVxuXHRcdGlmICgodmVydGV4RnJhbWVzLmxlbmd0aCA9PSAwKSAmJiAoc2tlbGV0b25GcmFtZXMubGVuZ3RoID09IDApKSB7XG5cdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgY3JlYXRlIHRoaXMgQW5pbWF0aW9uU2V0LCBiZWNhdXNlIGl0IGNvbnRhaW5zIG5vIGFuaW1hdGlvbnNcIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdGlmICh2ZXJ0ZXhGcmFtZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFyIG5ld1ZlcnRleEFuaW1hdGlvblNldDpWZXJ0ZXhBbmltYXRpb25TZXQgPSBuZXcgVmVydGV4QW5pbWF0aW9uU2V0KCk7XG5cdFx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IHZlcnRleEZyYW1lcy5sZW5ndGg7IGkrKylcblx0XHRcdFx0bmV3VmVydGV4QW5pbWF0aW9uU2V0LmFkZEFuaW1hdGlvbih2ZXJ0ZXhGcmFtZXNbaV0pO1xuXHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQobmV3VmVydGV4QW5pbWF0aW9uU2V0LCBuYW1lKTtcblx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gbmV3VmVydGV4QW5pbWF0aW9uU2V0O1xuXHRcdFx0aWYgKHRoaXMuX2RlYnVnKVxuXHRcdFx0XHRjb25zb2xlLmxvZyhcIlBhcnNlZCBhIFZlcnRleEFuaW1hdGlvblNldDogTmFtZSA9IFwiICsgbmFtZSArIFwiIHwgQW5pbWF0aW9ucyA9IFwiICsgbmV3VmVydGV4QW5pbWF0aW9uU2V0LmFuaW1hdGlvbnMubGVuZ3RoICsgXCIgfCBBbmltYXRpb24tTmFtZXMgPSBcIiArIG5ld1ZlcnRleEFuaW1hdGlvblNldC5hbmltYXRpb25OYW1lcy50b1N0cmluZygpKTtcblxuXHRcdH0gZWxzZSBpZiAoc2tlbGV0b25GcmFtZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuZWRBcnJheSA9IHRoaXMuZ2V0QXNzZXRCeUlEKHBvc2VCbG9ja0FkcmVzcywgW0Fzc2V0VHlwZS5BTklNQVRJT05fTk9ERV0pO1xuXHRcdFx0dmFyIG5ld1NrZWxldG9uQW5pbWF0aW9uU2V0OlNrZWxldG9uQW5pbWF0aW9uU2V0ID0gbmV3IFNrZWxldG9uQW5pbWF0aW9uU2V0KHByb3BzLmdldCgxLCA0KSk7IC8vcHJvcHMuZ2V0KDEsNCkpO1xuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCBza2VsZXRvbkZyYW1lcy5sZW5ndGg7IGkrKylcblx0XHRcdFx0bmV3U2tlbGV0b25BbmltYXRpb25TZXQuYWRkQW5pbWF0aW9uKHNrZWxldG9uRnJhbWVzW2ldKTtcblx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KG5ld1NrZWxldG9uQW5pbWF0aW9uU2V0LCBuYW1lKTtcblx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5kYXRhID0gbmV3U2tlbGV0b25BbmltYXRpb25TZXQ7XG5cdFx0XHRpZiAodGhpcy5fZGVidWcpXG5cdFx0XHRcdGNvbnNvbGUubG9nKFwiUGFyc2VkIGEgU2tlbGV0b25BbmltYXRpb25TZXQ6IE5hbWUgPSBcIiArIG5hbWUgKyBcIiB8IEFuaW1hdGlvbnMgPSBcIiArIG5ld1NrZWxldG9uQW5pbWF0aW9uU2V0LmFuaW1hdGlvbnMubGVuZ3RoICsgXCIgfCBBbmltYXRpb24tTmFtZXMgPSBcIiArIG5ld1NrZWxldG9uQW5pbWF0aW9uU2V0LmFuaW1hdGlvbk5hbWVzLnRvU3RyaW5nKCkpO1xuXG5cdFx0fVxuXHR9XG5cblx0Ly9CbG9ja0lEIDEyMlxuXHRwcml2YXRlIHBhcnNlQW5pbWF0b3JTZXQoYmxvY2tJRDpudW1iZXIgLyp1aW50Ki8pOnZvaWRcblx0e1xuXHRcdHZhciB0YXJnZXRNZXNoOk1lc2g7XG5cdFx0dmFyIGFuaW1TZXRCbG9ja0FkcmVzczpudW1iZXIgLyppbnQqL1xuXHRcdHZhciB0YXJnZXRBbmltYXRpb25TZXQ6QW5pbWF0aW9uU2V0QmFzZTtcblx0XHR2YXIgb3V0cHV0U3RyaW5nOnN0cmluZyA9IFwiXCI7XG5cdFx0dmFyIG5hbWU6c3RyaW5nID0gdGhpcy5wYXJzZVZhclN0cigpO1xuXHRcdHZhciB0eXBlOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblxuXHRcdHZhciBwcm9wczpBV0RQcm9wZXJ0aWVzID0gdGhpcy5wYXJzZVByb3BlcnRpZXMoezE6QVdEUGFyc2VyLkJBRERSfSk7XG5cblx0XHRhbmltU2V0QmxvY2tBZHJlc3MgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdHZhciB0YXJnZXRNZXNoTGVuZ3RoOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHR2YXIgbWVzaEFkcmVzc2VzOkFycmF5PG51bWJlcj4gLyp1aW50Ki8gPSBuZXcgQXJyYXk8bnVtYmVyPigpIC8qdWludCovO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qaW50Ki8gPSAwOyBpIDwgdGFyZ2V0TWVzaExlbmd0aDsgaSsrKVxuXHRcdFx0bWVzaEFkcmVzc2VzLnB1c2godGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKSk7XG5cblx0XHR2YXIgYWN0aXZlU3RhdGU6bnVtYmVyIC8qdWludCovID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdHZhciBhdXRvcGxheTpib29sZWFuID0gKCB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKSA9PSAxICk7XG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cdFx0dGhpcy5wYXJzZVVzZXJBdHRyaWJ1dGVzKCk7XG5cblx0XHR2YXIgcmV0dXJuZWRBcnJheTpBcnJheTxhbnk+O1xuXHRcdHZhciB0YXJnZXRNZXNoZXM6QXJyYXk8TWVzaD4gPSBuZXcgQXJyYXk8TWVzaD4oKTtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCBtZXNoQWRyZXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRChtZXNoQWRyZXNzZXNbaV0sIFtBc3NldFR5cGUuTUVTSF0pO1xuXHRcdFx0aWYgKHJldHVybmVkQXJyYXlbMF0pXG5cdFx0XHRcdHRhcmdldE1lc2hlcy5wdXNoKDxNZXNoPiByZXR1cm5lZEFycmF5WzFdKTtcblx0XHR9XG5cdFx0cmV0dXJuZWRBcnJheSA9IHRoaXMuZ2V0QXNzZXRCeUlEKGFuaW1TZXRCbG9ja0FkcmVzcywgW0Fzc2V0VHlwZS5BTklNQVRJT05fU0VUXSk7XG5cdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKSB7XG5cdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgQW5pbWF0aW9uU2V0ICggXCIgKyBhbmltU2V0QmxvY2tBZHJlc3MgKyBcIiApIGZvciB0aGlzIEFuaW1hdG9yXCIpOztcblx0XHRcdHJldHVyblxuXHRcdH1cblx0XHR0YXJnZXRBbmltYXRpb25TZXQgPSA8QW5pbWF0aW9uU2V0QmFzZT4gcmV0dXJuZWRBcnJheVsxXTtcblx0XHR2YXIgdGhpc0FuaW1hdG9yOkFuaW1hdG9yQmFzZTtcblx0XHRpZiAodHlwZSA9PSAxKSB7XG5cblx0XHRcdHJldHVybmVkQXJyYXkgPSB0aGlzLmdldEFzc2V0QnlJRChwcm9wcy5nZXQoMSwgMCksIFtBc3NldFR5cGUuU0tFTEVUT05dKTtcblx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSkge1xuXHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgU2tlbGV0b24gKCBcIiArIHByb3BzLmdldCgxLCAwKSArIFwiICkgZm9yIHRoaXMgQW5pbWF0b3JcIik7XG5cdFx0XHRcdHJldHVyblxuXHRcdFx0fVxuXHRcdFx0dGhpc0FuaW1hdG9yID0gbmV3IFNrZWxldG9uQW5pbWF0b3IoPFNrZWxldG9uQW5pbWF0aW9uU2V0PiB0YXJnZXRBbmltYXRpb25TZXQsIDxTa2VsZXRvbj4gcmV0dXJuZWRBcnJheVsxXSk7XG5cblx0XHR9IGVsc2UgaWYgKHR5cGUgPT0gMilcblx0XHRcdHRoaXNBbmltYXRvciA9IG5ldyBWZXJ0ZXhBbmltYXRvcig8VmVydGV4QW5pbWF0aW9uU2V0PiB0YXJnZXRBbmltYXRpb25TZXQpO1xuXG5cdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQodGhpc0FuaW1hdG9yLCBuYW1lKTtcblx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uZGF0YSA9IHRoaXNBbmltYXRvcjtcblx0XHRmb3IgKGkgPSAwOyBpIDwgdGFyZ2V0TWVzaGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAodHlwZSA9PSAxKVxuXHRcdFx0XHR0YXJnZXRNZXNoZXNbaV0uYW5pbWF0b3IgPSAoPFNrZWxldG9uQW5pbWF0b3I+IHRoaXNBbmltYXRvcik7XG5cdFx0XHRpZiAodHlwZSA9PSAyKVxuXHRcdFx0XHR0YXJnZXRNZXNoZXNbaV0uYW5pbWF0b3IgPSAoPFZlcnRleEFuaW1hdG9yPiB0aGlzQW5pbWF0b3IpO1xuXG5cdFx0fVxuXHRcdGlmICh0aGlzLl9kZWJ1Zylcblx0XHRcdGNvbnNvbGUubG9nKFwiUGFyc2VkIGEgQW5pbWF0b3I6IE5hbWUgPSBcIiArIG5hbWUpO1xuXHR9XG5cdFxuXHQvLyB0aGlzIGZ1bmN0aW9ucyByZWFkcyBhbmQgY3JlYXRlcyBhIEVmZmVjdE1ldGhvZFxuXHRwcml2YXRlIHBhcnNlU2hhcmVkTWV0aG9kTGlzdChibG9ja0lEOm51bWJlcik6RWZmZWN0TWV0aG9kQmFzZVxuXHR7XG5cblx0XHR2YXIgbWV0aG9kVHlwZTpudW1iZXIgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0dmFyIGVmZmVjdE1ldGhvZFJldHVybjpFZmZlY3RNZXRob2RCYXNlO1xuXG5cdFx0dmFyIHByb3BzOkFXRFByb3BlcnRpZXMgPSB0aGlzLnBhcnNlUHJvcGVydGllcyh7MTpBV0RQYXJzZXIuQkFERFIsIDI6QVdEUGFyc2VyLkJBRERSLCAzOkFXRFBhcnNlci5CQUREUiwgMTAxOnRoaXMuX3Byb3BzTnJUeXBlLCAxMDI6dGhpcy5fcHJvcHNOclR5cGUsIDEwMzp0aGlzLl9wcm9wc05yVHlwZSwgMTA0OnRoaXMuX3Byb3BzTnJUeXBlLCAxMDU6dGhpcy5fcHJvcHNOclR5cGUsIDEwNjp0aGlzLl9wcm9wc05yVHlwZSwgMTA3OnRoaXMuX3Byb3BzTnJUeXBlLCAyMDE6QVdEUGFyc2VyLlVJTlQzMiwgMjAyOkFXRFBhcnNlci5VSU5UMzIsIDMwMTpBV0RQYXJzZXIuVUlOVDE2LCAzMDI6QVdEUGFyc2VyLlVJTlQxNiwgNDAxOkFXRFBhcnNlci5VSU5UOCwgNDAyOkFXRFBhcnNlci5VSU5UOCwgNjAxOkFXRFBhcnNlci5DT0xPUiwgNjAyOkFXRFBhcnNlci5DT0xPUiwgNzAxOkFXRFBhcnNlci5CT09MLCA3MDI6QVdEUGFyc2VyLkJPT0x9KTtcblx0XHR2YXIgdGFyZ2V0SUQ6bnVtYmVyO1xuXHRcdHZhciByZXR1cm5lZEFycmF5OkFycmF5PGFueT47XG5cblx0XHRzd2l0Y2ggKG1ldGhvZFR5cGUpIHtcblx0XHRcdC8vIEVmZmVjdCBNZXRob2RzXG5cdFx0XHRjYXNlIDQwMTogLy9Db2xvck1hdHJpeFxuXHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgRWZmZWN0Q29sb3JNYXRyaXhNZXRob2QocHJvcHMuZ2V0KDEwMSwgbmV3IEFycmF5KDAsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDEpKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA0MDI6IC8vQ29sb3JUcmFuc2Zvcm1cblx0XHRcdFx0ZWZmZWN0TWV0aG9kUmV0dXJuID0gbmV3IEVmZmVjdENvbG9yVHJhbnNmb3JtTWV0aG9kKCk7XG5cdFx0XHRcdHZhciBvZmZDb2w6bnVtYmVyIC8qdWludCovID0gcHJvcHMuZ2V0KDYwMSwgMHgwMDAwMDAwMCk7XG5cdFx0XHRcdCg8RWZmZWN0Q29sb3JUcmFuc2Zvcm1NZXRob2Q+IGVmZmVjdE1ldGhvZFJldHVybikuY29sb3JUcmFuc2Zvcm0gPSBuZXcgQ29sb3JUcmFuc2Zvcm0ocHJvcHMuZ2V0KDEwMiwgMSksIHByb3BzLmdldCgxMDMsIDEpLCBwcm9wcy5nZXQoMTA0LCAxKSwgcHJvcHMuZ2V0KDEwMSwgMSksICgob2ZmQ29sID4+IDE2KSAmIDB4RkYpLCAoKG9mZkNvbCA+PiA4KSAmIDB4RkYpLCAob2ZmQ29sICYgMHhGRiksICgob2ZmQ29sID4+IDI0KSAmIDB4RkYpKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQwMzogLy9FbnZNYXBcblxuXHRcdFx0XHR0YXJnZXRJRCA9IHByb3BzLmdldCgxLCAwKTtcblx0XHRcdFx0Y29uc29sZS5sb2coJ0VOViBNQVAnLCB0YXJnZXRJRCk7XG5cblxuXHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFsgQXNzZXRUeXBlLlRFWFRVUkUgXSwgXCJDdWJlVGV4dHVyZVwiKTtcblx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBFbnZNYXAgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgRW52TWFwTWV0aG9kXCIpO1xuXHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgRWZmZWN0RW52TWFwTWV0aG9kKDxDdWJlVGV4dHVyZUJhc2U+IHJldHVybmVkQXJyYXlbMV0sIDxudW1iZXI+IHByb3BzLmdldCgxMDEsIDEpKTtcblx0XHRcdFx0dGFyZ2V0SUQgPSBwcm9wcy5nZXQoMiwgMCk7XG5cdFx0XHRcdGlmICh0YXJnZXRJRCA+IDApIHtcblx0XHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXHRcdFx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSlcblx0XHRcdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBNYXNrLXRleHR1cmUgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgRW52TWFwTWV0aG9kXCIpO1xuXG5cdFx0XHRcdFx0Ly8gVG9kbzogdGVzdCBtYXNrIHdpdGggRW52TWFwTWV0aG9kXG5cdFx0XHRcdFx0Ly8oPEVudk1hcE1ldGhvZD4gZWZmZWN0TWV0aG9kUmV0dXJuKS5tYXNrID0gPFRleHR1cmUyREJhc2U+IHJldHVybmVkQXJyYXlbMV07XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQwNDogLy9MaWdodE1hcE1ldGhvZFxuXHRcdFx0XHR0YXJnZXRJRCA9IHByb3BzLmdldCgxLCAwKTtcblx0XHRcdFx0cmV0dXJuZWRBcnJheSA9IHRoaXMuZ2V0QXNzZXRCeUlEKHRhcmdldElELCBbQXNzZXRUeXBlLlRFWFRVUkVdKTtcblx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0XHRcdHRoaXMuX2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBMaWdodE1hcCAoSUQgPSBcIiArIHRhcmdldElEICsgXCIgKSBmb3IgdGhpcyBMaWdodE1hcE1ldGhvZFwiKTtcblx0XHRcdFx0ZWZmZWN0TWV0aG9kUmV0dXJuID0gbmV3IEVmZmVjdExpZ2h0TWFwTWV0aG9kKHJldHVybmVkQXJyYXlbMV0sIHRoaXMuYmxlbmRNb2RlRGljW3Byb3BzLmdldCg0MDEsIDEwKV0pOyAvL3VzZXNlY29uZGFyeVVWIG5vdCBzZXRcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHQvL1x0XHRcdFx0Y2FzZSA0MDU6IC8vUHJvamVjdGl2ZVRleHR1cmVNZXRob2Rcblx0XHRcdC8vXHRcdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0Ly9cdFx0XHRcdFx0cmV0dXJuZWRBcnJheSA9IGdldEFzc2V0QnlJRCh0YXJnZXRJRCwgW0Fzc2V0VHlwZS5URVhUVVJFX1BST0pFQ1RPUl0pO1xuXHRcdFx0Ly9cdFx0XHRcdFx0aWYgKCFyZXR1cm5lZEFycmF5WzBdKVxuXHRcdFx0Ly9cdFx0XHRcdFx0XHRfYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIFRleHR1cmVQcm9qZWN0b3IgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgUHJvamVjdGl2ZVRleHR1cmVNZXRob2RcIik7XG5cdFx0XHQvL1x0XHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgUHJvamVjdGl2ZVRleHR1cmVNZXRob2QocmV0dXJuZWRBcnJheVsxXSwgYmxlbmRNb2RlRGljW3Byb3BzLmdldCg0MDEsIDEwKV0pO1xuXHRcdFx0Ly9cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQwNjogLy9SaW1MaWdodE1ldGhvZFxuXHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgRWZmZWN0UmltTGlnaHRNZXRob2QocHJvcHMuZ2V0KDYwMSwgMHhmZmZmZmYpLCBwcm9wcy5nZXQoMTAxLCAwLjQpLCBwcm9wcy5nZXQoMTAxLCAyKSk7IC8vYmxlbmRNb2RlXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA0MDc6IC8vQWxwaGFNYXNrTWV0aG9kXG5cdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuVEVYVFVSRV0pO1xuXHRcdFx0XHRpZiAoIXJldHVybmVkQXJyYXlbMF0pXG5cdFx0XHRcdFx0dGhpcy5fYmxvY2tzW2Jsb2NrSURdLmFkZEVycm9yKFwiQ291bGQgbm90IGZpbmQgdGhlIEFscGhhLXRleHR1cmUgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgQWxwaGFNYXNrTWV0aG9kXCIpO1xuXHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgRWZmZWN0QWxwaGFNYXNrTWV0aG9kKHJldHVybmVkQXJyYXlbMV0sIHByb3BzLmdldCg3MDEsIGZhbHNlKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Ly9cdFx0XHRcdGNhc2UgNDA4OiAvL1JlZnJhY3Rpb25FbnZNYXBNZXRob2Rcblx0XHRcdC8vXHRcdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0Ly9cdFx0XHRcdFx0cmV0dXJuZWRBcnJheSA9IGdldEFzc2V0QnlJRCh0YXJnZXRJRCwgW0Fzc2V0VHlwZS5URVhUVVJFXSwgXCJDdWJlVGV4dHVyZVwiKTtcblx0XHRcdC8vXHRcdFx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSlcblx0XHRcdC8vXHRcdFx0XHRcdFx0X2Jsb2Nrc1tibG9ja0lEXS5hZGRFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHRoZSBFbnZNYXAgKElEID0gXCIgKyB0YXJnZXRJRCArIFwiICkgZm9yIHRoaXMgUmVmcmFjdGlvbkVudk1hcE1ldGhvZFwiKTtcblx0XHRcdC8vXHRcdFx0XHRcdGVmZmVjdE1ldGhvZFJldHVybiA9IG5ldyBSZWZyYWN0aW9uRW52TWFwTWV0aG9kKHJldHVybmVkQXJyYXlbMV0sIHByb3BzLmdldCgxMDEsIDAuMSksIHByb3BzLmdldCgxMDIsIDAuMDEpLCBwcm9wcy5nZXQoMTAzLCAwLjAxKSwgcHJvcHMuZ2V0KDEwNCwgMC4wMSkpO1xuXHRcdFx0Ly9cdFx0XHRcdFx0UmVmcmFjdGlvbkVudk1hcE1ldGhvZChlZmZlY3RNZXRob2RSZXR1cm4pLmFscGhhID0gcHJvcHMuZ2V0KDEwNCwgMSk7XG5cdFx0XHQvL1x0XHRcdFx0XHRicmVhaztcblx0XHRcdC8vXHRcdFx0XHRjYXNlIDQwOTogLy9PdXRsaW5lTWV0aG9kXG5cdFx0XHQvL1x0XHRcdFx0XHRlZmZlY3RNZXRob2RSZXR1cm4gPSBuZXcgT3V0bGluZU1ldGhvZChwcm9wcy5nZXQoNjAxLCAweDAwMDAwMDAwKSwgcHJvcHMuZ2V0KDEwMSwgMSksIHByb3BzLmdldCg3MDEsIHRydWUpLCBwcm9wcy5nZXQoNzAyLCBmYWxzZSkpO1xuXHRcdFx0Ly9cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQxMDogLy9GcmVzbmVsRW52TWFwTWV0aG9kXG5cdFx0XHRcdHRhcmdldElEID0gcHJvcHMuZ2V0KDEsIDApO1xuXHRcdFx0XHRyZXR1cm5lZEFycmF5ID0gdGhpcy5nZXRBc3NldEJ5SUQodGFyZ2V0SUQsIFtBc3NldFR5cGUuVEVYVFVSRV0sIFwiQ3ViZVRleHR1cmVcIik7XG5cdFx0XHRcdGlmICghcmV0dXJuZWRBcnJheVswXSlcblx0XHRcdFx0XHR0aGlzLl9ibG9ja3NbYmxvY2tJRF0uYWRkRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0aGUgRW52TWFwIChJRCA9IFwiICsgdGFyZ2V0SUQgKyBcIiApIGZvciB0aGlzIEZyZXNuZWxFbnZNYXBNZXRob2RcIik7XG5cdFx0XHRcdGVmZmVjdE1ldGhvZFJldHVybiA9IG5ldyBFZmZlY3RGcmVzbmVsRW52TWFwTWV0aG9kKHJldHVybmVkQXJyYXlbMV0sIHByb3BzLmdldCgxMDEsIDEpKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQxMTogLy9Gb2dNZXRob2Rcblx0XHRcdFx0ZWZmZWN0TWV0aG9kUmV0dXJuID0gbmV3IEVmZmVjdEZvZ01ldGhvZChwcm9wcy5nZXQoMTAxLCAwKSwgcHJvcHMuZ2V0KDEwMiwgMTAwMCksIHByb3BzLmdldCg2MDEsIDB4ODA4MDgwKSk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0fVxuXHRcdHRoaXMucGFyc2VVc2VyQXR0cmlidXRlcygpO1xuXHRcdHJldHVybiBlZmZlY3RNZXRob2RSZXR1cm47XG5cblx0fVxuXG5cdHByaXZhdGUgcGFyc2VVc2VyQXR0cmlidXRlcygpOk9iamVjdFxuXHR7XG5cdFx0dmFyIGF0dHJpYnV0ZXM6T2JqZWN0O1xuXHRcdHZhciBsaXN0X2xlbjpudW1iZXI7XG5cdFx0dmFyIGF0dGlidXRlQ250Om51bWJlcjtcblxuXHRcdGxpc3RfbGVuID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdGlmIChsaXN0X2xlbiA+IDApIHtcblxuXHRcdFx0dmFyIGxpc3RfZW5kOm51bWJlcjtcblxuXHRcdFx0YXR0cmlidXRlcyA9IHt9O1xuXG5cdFx0XHRsaXN0X2VuZCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gKyBsaXN0X2xlbjtcblxuXHRcdFx0d2hpbGUgKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPCBsaXN0X2VuZCkge1xuXHRcdFx0XHR2YXIgbnNfaWQ6bnVtYmVyO1xuXHRcdFx0XHR2YXIgYXR0cl9rZXk6c3RyaW5nO1xuXHRcdFx0XHR2YXIgYXR0cl90eXBlOm51bWJlcjtcblx0XHRcdFx0dmFyIGF0dHJfbGVuOm51bWJlcjtcblx0XHRcdFx0dmFyIGF0dHJfdmFsOmFueTtcblxuXHRcdFx0XHQvLyBUT0RPOiBQcm9wZXJseSB0ZW5kIHRvIG5hbWVzcGFjZXMgaW4gYXR0cmlidXRlc1xuXHRcdFx0XHRuc19pZCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRhdHRyX2tleSA9IHRoaXMucGFyc2VWYXJTdHIoKTtcblx0XHRcdFx0YXR0cl90eXBlID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7XG5cdFx0XHRcdGF0dHJfbGVuID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdFx0XHRpZiAoKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gKyBhdHRyX2xlbikgPiBsaXN0X2VuZCkge1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiICAgICAgICAgICBFcnJvciBpbiByZWFkaW5nIGF0dHJpYnV0ZSAjIFwiICsgYXR0aWJ1dGVDbnQgKyBcIiA9IHNraXBwZWQgdG8gZW5kIG9mIGF0dHJpYnV0ZS1saXN0XCIpO1xuXHRcdFx0XHRcdHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPSBsaXN0X2VuZDtcblx0XHRcdFx0XHRyZXR1cm4gYXR0cmlidXRlcztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHN3aXRjaCAoYXR0cl90eXBlKSB7XG5cdFx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuQVdEU1RSSU5HOlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVVEZCeXRlcyhhdHRyX2xlbik7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIEFXRFBhcnNlci5JTlQ4OlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRCeXRlKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIEFXRFBhcnNlci5JTlQxNjpcblx0XHRcdFx0XHRcdGF0dHJfdmFsID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkU2hvcnQoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgQVdEUGFyc2VyLklOVDMyOlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRJbnQoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgQVdEUGFyc2VyLkJPT0w6XG5cdFx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuVUlOVDg6XG5cdFx0XHRcdFx0XHRhdHRyX3ZhbCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuVUlOVDE2OlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIEFXRFBhcnNlci5VSU5UMzI6XG5cdFx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuQkFERFI6XG5cdFx0XHRcdFx0XHRhdHRyX3ZhbCA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIEFXRFBhcnNlci5GTE9BVDMyOlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRGbG9hdCgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBBV0RQYXJzZXIuRkxPQVQ2NDpcblx0XHRcdFx0XHRcdGF0dHJfdmFsID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkRG91YmxlKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0YXR0cl92YWwgPSAndW5pbXBsZW1lbnRlZCBhdHRyaWJ1dGUgdHlwZSAnICsgYXR0cl90eXBlO1xuXHRcdFx0XHRcdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiArPSBhdHRyX2xlbjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXCJhdHRyaWJ1dGUgPSBuYW1lOiBcIiArIGF0dHJfa2V5ICsgXCIgIC8gdmFsdWUgPSBcIiArIGF0dHJfdmFsKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF0dHJpYnV0ZXNbYXR0cl9rZXldID0gYXR0cl92YWw7XG5cdFx0XHRcdGF0dGlidXRlQ250ICs9IDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGF0dHJpYnV0ZXM7XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlUHJvcGVydGllcyhleHBlY3RlZDpPYmplY3QpOkFXRFByb3BlcnRpZXNcblx0e1xuXHRcdHZhciBsaXN0X2VuZDpudW1iZXI7XG5cdFx0dmFyIGxpc3RfbGVuOm51bWJlcjtcblx0XHR2YXIgcHJvcGVydHlDbnQ6bnVtYmVyID0gMDtcblx0XHR2YXIgcHJvcHM6QVdEUHJvcGVydGllcyA9IG5ldyBBV0RQcm9wZXJ0aWVzKCk7XG5cblx0XHRsaXN0X2xlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0bGlzdF9lbmQgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uICsgbGlzdF9sZW47XG5cblx0XHRpZiAoZXhwZWN0ZWQpIHtcblxuXHRcdFx0d2hpbGUgKHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPCBsaXN0X2VuZCkge1xuXHRcdFx0XHR2YXIgbGVuOm51bWJlcjtcblx0XHRcdFx0dmFyIGtleTpudW1iZXI7XG5cdFx0XHRcdHZhciB0eXBlOm51bWJlcjtcblxuXHRcdFx0XHRrZXkgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRcdGxlbiA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkSW50KCk7XG5cblx0XHRcdFx0aWYgKCh0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uICsgbGVuKSA+IGxpc3RfZW5kKSB7XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXCIgICAgICAgICAgIEVycm9yIGluIHJlYWRpbmcgcHJvcGVydHkgIyBcIiArIHByb3BlcnR5Q250ICsgXCIgPSBza2lwcGVkIHRvIGVuZCBvZiBwcm9wZXJ0aWUtbGlzdFwiKTtcblx0XHRcdFx0XHR0aGlzLl9uZXdCbG9ja0J5dGVzLnBvc2l0aW9uID0gbGlzdF9lbmQ7XG5cdFx0XHRcdFx0cmV0dXJuIHByb3BzO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGV4cGVjdGVkLmhhc093blByb3BlcnR5KGtleS50b1N0cmluZygpKSkge1xuXHRcdFx0XHRcdHR5cGUgPSBleHBlY3RlZFtrZXldO1xuXHRcdFx0XHRcdHByb3BzLnNldChrZXksIHRoaXMucGFyc2VBdHRyVmFsdWUodHlwZSwgbGVuKSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fbmV3QmxvY2tCeXRlcy5wb3NpdGlvbiArPSBsZW47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwcm9wZXJ0eUNudCArPSAxO1xuXG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX25ld0Jsb2NrQnl0ZXMucG9zaXRpb24gPSBsaXN0X2VuZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gcHJvcHM7XG5cblx0fVxuXG5cdHByaXZhdGUgcGFyc2VBdHRyVmFsdWUodHlwZTpudW1iZXIsIGxlbjpudW1iZXIpOmFueVxuXHR7XG5cdFx0dmFyIGVsZW1fbGVuOm51bWJlcjtcblx0XHR2YXIgcmVhZF9mdW5jOkZ1bmN0aW9uO1xuXG5cdFx0c3dpdGNoICh0eXBlKSB7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLkJPT0w6XG5cdFx0XHRjYXNlIEFXRFBhcnNlci5JTlQ4OlxuXHRcdFx0XHRlbGVtX2xlbiA9IDE7XG5cdFx0XHRcdHJlYWRfZnVuYyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZEJ5dGU7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIEFXRFBhcnNlci5JTlQxNjpcblx0XHRcdFx0ZWxlbV9sZW4gPSAyO1xuXHRcdFx0XHRyZWFkX2Z1bmMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRTaG9ydDtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLklOVDMyOlxuXHRcdFx0XHRlbGVtX2xlbiA9IDQ7XG5cdFx0XHRcdHJlYWRfZnVuYyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZEludDtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLlVJTlQ4OlxuXHRcdFx0XHRlbGVtX2xlbiA9IDE7XG5cdFx0XHRcdHJlYWRfZnVuYyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkQnl0ZTtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLlVJTlQxNjpcblx0XHRcdFx0ZWxlbV9sZW4gPSAyO1xuXHRcdFx0XHRyZWFkX2Z1bmMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZFNob3J0O1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBBV0RQYXJzZXIuVUlOVDMyOlxuXHRcdFx0Y2FzZSBBV0RQYXJzZXIuQ09MT1I6XG5cdFx0XHRjYXNlIEFXRFBhcnNlci5CQUREUjpcblx0XHRcdFx0ZWxlbV9sZW4gPSA0O1xuXHRcdFx0XHRyZWFkX2Z1bmMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWRVbnNpZ25lZEludDtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLkZMT0FUMzI6XG5cdFx0XHRcdGVsZW1fbGVuID0gNDtcblx0XHRcdFx0cmVhZF9mdW5jID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkRmxvYXQ7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIEFXRFBhcnNlci5GTE9BVDY0OlxuXHRcdFx0XHRlbGVtX2xlbiA9IDg7XG5cdFx0XHRcdHJlYWRfZnVuYyA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZERvdWJsZTtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLkFXRFNUUklORzpcblx0XHRcdFx0cmV0dXJuIHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVURkJ5dGVzKGxlbik7XG5cblx0XHRcdGNhc2UgQVdEUGFyc2VyLlZFQ1RPUjJ4MTpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLlZFQ1RPUjN4MTpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLlZFQ1RPUjR4MTpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLk1UWDN4Mjpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLk1UWDN4Mzpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLk1UWDR4Mzpcblx0XHRcdGNhc2UgQVdEUGFyc2VyLk1UWDR4NDpcblx0XHRcdFx0ZWxlbV9sZW4gPSA4O1xuXHRcdFx0XHRyZWFkX2Z1bmMgPSB0aGlzLl9uZXdCbG9ja0J5dGVzLnJlYWREb3VibGU7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0fVxuXG5cdFx0aWYgKGVsZW1fbGVuIDwgbGVuKSB7XG5cdFx0XHR2YXIgbGlzdDpBcnJheTxhbnk+ID0gW107XG5cdFx0XHR2YXIgbnVtX3JlYWQ6bnVtYmVyID0gMDtcblx0XHRcdHZhciBudW1fZWxlbXM6bnVtYmVyID0gbGVuL2VsZW1fbGVuO1xuXG5cdFx0XHR3aGlsZSAobnVtX3JlYWQgPCBudW1fZWxlbXMpIHtcblx0XHRcdFx0bGlzdC5wdXNoKHJlYWRfZnVuYy5hcHBseSh0aGlzLl9uZXdCbG9ja0J5dGVzKSk7IC8vIGxpc3QucHVzaChyZWFkX2Z1bmMoKSk7XG5cdFx0XHRcdG51bV9yZWFkKys7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBsaXN0O1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHZhciB2YWw6YW55ID0gcmVhZF9mdW5jLmFwcGx5KHRoaXMuX25ld0Jsb2NrQnl0ZXMpOy8vcmVhZF9mdW5jKCk7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgcGFyc2VIZWFkZXIoKTp2b2lkXG5cdHtcblx0XHR2YXIgZmxhZ3M6bnVtYmVyO1xuXHRcdHZhciBib2R5X2xlbjpudW1iZXI7XG5cblx0XHR0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiA9IDM7IC8vIFNraXAgbWFnaWMgc3RyaW5nIGFuZCBwYXJzZSB2ZXJzaW9uXG5cblx0XHR0aGlzLl92ZXJzaW9uWzBdID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdHRoaXMuX3ZlcnNpb25bMV0gPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRCeXRlKCk7XG5cblx0XHRmbGFncyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7IC8vIFBhcnNlIGJpdCBmbGFnc1xuXG5cdFx0dGhpcy5fc3RyZWFtaW5nID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzEpO1xuXG5cdFx0aWYgKCh0aGlzLl92ZXJzaW9uWzBdID09IDIpICYmICh0aGlzLl92ZXJzaW9uWzFdID09IDEpKSB7XG5cdFx0XHR0aGlzLl9hY2N1cmFjeU1hdHJpeCA9IEJpdEZsYWdzLnRlc3QoZmxhZ3MsIEJpdEZsYWdzLkZMQUcyKTtcblx0XHRcdHRoaXMuX2FjY3VyYWN5R2VvID0gQml0RmxhZ3MudGVzdChmbGFncywgQml0RmxhZ3MuRkxBRzMpO1xuXHRcdFx0dGhpcy5fYWNjdXJhY3lQcm9wcyA9IEJpdEZsYWdzLnRlc3QoZmxhZ3MsIEJpdEZsYWdzLkZMQUc0KTtcblx0XHR9XG5cblx0XHQvLyBpZiB3ZSBzZXQgX2FjY3VyYWN5T25CbG9ja3MsIHRoZSBwcmVjaXNpb24tdmFsdWVzIGFyZSByZWFkIGZyb20gZWFjaCBibG9jay1oZWFkZXIuXG5cblx0XHQvLyBzZXQgc3RvcmFnZVByZWNpc2lvbiB0eXBlc1xuXHRcdHRoaXMuX2dlb05yVHlwZSA9IEFXRFBhcnNlci5GTE9BVDMyO1xuXG5cdFx0aWYgKHRoaXMuX2FjY3VyYWN5R2VvKSB7XG5cdFx0XHR0aGlzLl9nZW9OclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQ2NDtcblx0XHR9XG5cblx0XHR0aGlzLl9tYXRyaXhOclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQzMjtcblxuXHRcdGlmICh0aGlzLl9hY2N1cmFjeU1hdHJpeCkge1xuXHRcdFx0dGhpcy5fbWF0cml4TnJUeXBlID0gQVdEUGFyc2VyLkZMT0FUNjQ7XG5cdFx0fVxuXG5cdFx0dGhpcy5fcHJvcHNOclR5cGUgPSBBV0RQYXJzZXIuRkxPQVQzMjtcblxuXHRcdGlmICh0aGlzLl9hY2N1cmFjeVByb3BzKSB7XG5cdFx0XHR0aGlzLl9wcm9wc05yVHlwZSA9IEFXRFBhcnNlci5GTE9BVDY0O1xuXHRcdH1cblxuXHRcdHRoaXMuX2NvbXByZXNzaW9uID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpOyAvLyBjb21wcmVzc2lvblxuXG5cdFx0aWYgKHRoaXMuX2RlYnVnKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkltcG9ydCBBV0RGaWxlIG9mIHZlcnNpb24gPSBcIiArIHRoaXMuX3ZlcnNpb25bMF0gKyBcIiAtIFwiICsgdGhpcy5fdmVyc2lvblsxXSk7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkdsb2JhbCBTZXR0aW5ncyA9IENvbXByZXNzaW9uID0gXCIgKyB0aGlzLl9jb21wcmVzc2lvbiArIFwiIHwgU3RyZWFtaW5nID0gXCIgKyB0aGlzLl9zdHJlYW1pbmcgKyBcIiB8IE1hdHJpeC1QcmVjaXNpb24gPSBcIiArIHRoaXMuX2FjY3VyYWN5TWF0cml4ICsgXCIgfCBHZW9tZXRyeS1QcmVjaXNpb24gPSBcIiArIHRoaXMuX2FjY3VyYWN5R2VvICsgXCIgfCBQcm9wZXJ0aWVzLVByZWNpc2lvbiA9IFwiICsgdGhpcy5fYWNjdXJhY3lQcm9wcyk7XG5cdFx0fVxuXG5cdFx0Ly8gQ2hlY2sgZmlsZSBpbnRlZ3JpdHlcblx0XHRib2R5X2xlbiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdGlmICghdGhpcy5fc3RyZWFtaW5nICYmIGJvZHlfbGVuICE9IHRoaXMuX2J5dGVEYXRhLmdldEJ5dGVzQXZhaWxhYmxlKCkpIHtcblx0XHRcdHRoaXMuX3BEaWVXaXRoRXJyb3IoJ0FXRDIgYm9keSBsZW5ndGggZG9lcyBub3QgbWF0Y2ggaGVhZGVyIGludGVncml0eSBmaWVsZCcpO1xuXHRcdH1cblxuXHR9XG5cdC8vIEhlbHBlciAtIGZ1bmN0aW9uc1xuXHRwcml2YXRlIGdldFVWRm9yVmVydGV4QW5pbWF0aW9uKG1lc2hJRDpudW1iZXIgLyp1aW50Ki8pOkFycmF5PEFycmF5PG51bWJlcj4+XG5cdHtcblx0XHRpZiAodGhpcy5fYmxvY2tzW21lc2hJRF0uZGF0YSBpbnN0YW5jZW9mIE1lc2gpXG5cdFx0bWVzaElEID0gdGhpcy5fYmxvY2tzW21lc2hJRF0uZ2VvSUQ7XG5cdFx0aWYgKHRoaXMuX2Jsb2Nrc1ttZXNoSURdLnV2c0ZvclZlcnRleEFuaW1hdGlvbilcblx0XHRcdHJldHVybiB0aGlzLl9ibG9ja3NbbWVzaElEXS51dnNGb3JWZXJ0ZXhBbmltYXRpb247XG5cdFx0dmFyIGdlb21ldHJ5Okdlb21ldHJ5ID0gKDxHZW9tZXRyeT4gdGhpcy5fYmxvY2tzW21lc2hJRF0uZGF0YSk7XG5cdFx0dmFyIGdlb0NudDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdFx0dmFyIHVkOkFycmF5PG51bWJlcj47XG5cdFx0dmFyIHVTdHJpZGU6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciB1T2ZmczpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIG51bVBvaW50czpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIGk6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIG5ld1V2czpBcnJheTxudW1iZXI+O1xuXHRcdHZhciBzdWJfZ2VvbTpUcmlhbmdsZVN1Ykdlb21ldHJ5O1xuXHRcdHRoaXMuX2Jsb2Nrc1ttZXNoSURdLnV2c0ZvclZlcnRleEFuaW1hdGlvbiA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PigpO1xuXHRcdHdoaWxlIChnZW9DbnQgPCBnZW9tZXRyeS5zdWJHZW9tZXRyaWVzLmxlbmd0aCkge1xuXHRcdFx0bmV3VXZzID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHRcdHN1Yl9nZW9tID0gPFRyaWFuZ2xlU3ViR2VvbWV0cnk+IGdlb21ldHJ5LnN1Ykdlb21ldHJpZXNbZ2VvQ250XTtcblx0XHRcdG51bVBvaW50cyA9IHN1Yl9nZW9tLm51bVZlcnRpY2VzO1xuXHRcdFx0dWQgPSBzdWJfZ2VvbS51dnM7XG5cdFx0XHR1U3RyaWRlID0gc3ViX2dlb20uZ2V0U3RyaWRlKFRyaWFuZ2xlU3ViR2VvbWV0cnkuVVZfREFUQSk7XG5cdFx0XHR1T2ZmcyA9IHN1Yl9nZW9tLmdldE9mZnNldChUcmlhbmdsZVN1Ykdlb21ldHJ5LlVWX0RBVEEpO1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IG51bVBvaW50czsgaSsrKSB7XG5cdFx0XHRcdG5ld1V2cy5wdXNoKHVkW3VPZmZzICsgaSp1U3RyaWRlICsgMF0pO1xuXHRcdFx0XHRuZXdVdnMucHVzaCh1ZFt1T2ZmcyArIGkqdVN0cmlkZSArIDFdKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuX2Jsb2Nrc1ttZXNoSURdLnV2c0ZvclZlcnRleEFuaW1hdGlvbi5wdXNoKG5ld1V2cyk7XG5cdFx0XHRnZW9DbnQrKztcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuX2Jsb2Nrc1ttZXNoSURdLnV2c0ZvclZlcnRleEFuaW1hdGlvbjtcblx0fVxuXHRcblx0cHJpdmF0ZSBwYXJzZVZhclN0cigpOnN0cmluZ1xuXHR7XG5cblx0XHR2YXIgbGVuOm51bWJlciA9IHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRyZXR1cm4gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkVVRGQnl0ZXMobGVuKTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0QXNzZXRCeUlEKGFzc2V0SUQ6bnVtYmVyLCBhc3NldFR5cGVzVG9HZXQ6QXJyYXk8c3RyaW5nPiwgZXh0cmFUeXBlSW5mbzpzdHJpbmcgPSBcIlNpbmdsZVRleHR1cmVcIik6QXJyYXk8YW55PlxuXHR7XG5cdFx0dmFyIHJldHVybkFycmF5OkFycmF5PGFueT4gPSBuZXcgQXJyYXk8YW55PigpO1xuXHRcdHZhciB0eXBlQ250Om51bWJlciA9IDA7XG5cdFx0aWYgKGFzc2V0SUQgPiAwKSB7XG5cdFx0XHRpZiAodGhpcy5fYmxvY2tzW2Fzc2V0SURdKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9ibG9ja3NbYXNzZXRJRF0uZGF0YSkge1xuXHRcdFx0XHRcdHdoaWxlICh0eXBlQ250IDwgYXNzZXRUeXBlc1RvR2V0Lmxlbmd0aCkge1xuXG5cdFx0XHRcdFx0XHR2YXIgaWFzc2V0OklBc3NldCA9IDxJQXNzZXQ+IHRoaXMuX2Jsb2Nrc1thc3NldElEXS5kYXRhO1xuXG5cdFx0XHRcdFx0XHRpZiAoaWFzc2V0LmFzc2V0VHlwZSA9PSBhc3NldFR5cGVzVG9HZXRbdHlwZUNudF0pIHtcblx0XHRcdFx0XHRcdFx0Ly9pZiB0aGUgcmlnaHQgYXNzZXRUeXBlIHdhcyBmb3VuZFxuXHRcdFx0XHRcdFx0XHRpZiAoKGFzc2V0VHlwZXNUb0dldFt0eXBlQ250XSA9PSBBc3NldFR5cGUuVEVYVFVSRSkgJiYgKGV4dHJhVHlwZUluZm8gPT0gXCJDdWJlVGV4dHVyZVwiKSkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLl9ibG9ja3NbYXNzZXRJRF0uZGF0YSBpbnN0YW5jZW9mIEltYWdlQ3ViZVRleHR1cmUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybkFycmF5LnB1c2godHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5BcnJheS5wdXNoKHRoaXMuX2Jsb2Nrc1thc3NldElEXS5kYXRhKTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXR1cm5BcnJheTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYgKChhc3NldFR5cGVzVG9HZXRbdHlwZUNudF0gPT0gQXNzZXRUeXBlLlRFWFRVUkUpICYmIChleHRyYVR5cGVJbmZvID09IFwiU2luZ2xlVGV4dHVyZVwiKSkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLl9ibG9ja3NbYXNzZXRJRF0uZGF0YSBpbnN0YW5jZW9mIEltYWdlVGV4dHVyZSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuQXJyYXkucHVzaCh0cnVlKTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybkFycmF5LnB1c2godGhpcy5fYmxvY2tzW2Fzc2V0SURdLmRhdGEpO1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHJldHVybkFycmF5O1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm5BcnJheS5wdXNoKHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybkFycmF5LnB1c2godGhpcy5fYmxvY2tzW2Fzc2V0SURdLmRhdGEpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXR1cm5BcnJheTtcblxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHQvL2lmICgoYXNzZXRUeXBlc1RvR2V0W3R5cGVDbnRdID09IEFzc2V0VHlwZS5HRU9NRVRSWSkgJiYgKElBc3NldChfYmxvY2tzW2Fzc2V0SURdLmRhdGEpLmFzc2V0VHlwZSA9PSBBc3NldFR5cGUuTUVTSCkpIHtcblx0XHRcdFx0XHRcdGlmICgoYXNzZXRUeXBlc1RvR2V0W3R5cGVDbnRdID09IEFzc2V0VHlwZS5HRU9NRVRSWSkgJiYgKGlhc3NldC5hc3NldFR5cGUgPT0gQXNzZXRUeXBlLk1FU0gpKSB7XG5cblx0XHRcdFx0XHRcdFx0dmFyIG1lc2g6TWVzaCA9IDxNZXNoPiB0aGlzLl9ibG9ja3NbYXNzZXRJRF0uZGF0YVxuXG5cdFx0XHRcdFx0XHRcdHJldHVybkFycmF5LnB1c2godHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybkFycmF5LnB1c2gobWVzaC5nZW9tZXRyeSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiByZXR1cm5BcnJheTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR0eXBlQ250Kys7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIGlmIHRoZSBoYXMgbm90IHJldHVybmVkIGFueXRoaW5nIHlldCwgdGhlIGFzc2V0IGlzIG5vdCBmb3VuZCwgb3IgdGhlIGZvdW5kIGFzc2V0IGlzIG5vdCB0aGUgcmlnaHQgdHlwZS5cblx0XHRyZXR1cm5BcnJheS5wdXNoKGZhbHNlKTtcblx0XHRyZXR1cm5BcnJheS5wdXNoKHRoaXMuZ2V0RGVmYXVsdEFzc2V0KGFzc2V0VHlwZXNUb0dldFswXSwgZXh0cmFUeXBlSW5mbykpO1xuXHRcdHJldHVybiByZXR1cm5BcnJheTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0RGVmYXVsdEFzc2V0KGFzc2V0VHlwZTpzdHJpbmcsIGV4dHJhVHlwZUluZm86c3RyaW5nKTpJQXNzZXRcblx0e1xuXHRcdHN3aXRjaCAodHJ1ZSkge1xuXHRcdFx0Y2FzZSAoYXNzZXRUeXBlID09IEFzc2V0VHlwZS5URVhUVVJFKTpcblx0XHRcdFx0aWYgKGV4dHJhVHlwZUluZm8gPT0gXCJDdWJlVGV4dHVyZVwiKVxuXHRcdFx0XHRcdHJldHVybiB0aGlzLmdldERlZmF1bHRDdWJlVGV4dHVyZSgpO1xuXHRcdFx0XHRpZiAoZXh0cmFUeXBlSW5mbyA9PSBcIlNpbmdsZVRleHR1cmVcIilcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5nZXREZWZhdWx0VGV4dHVyZSgpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgKGFzc2V0VHlwZSA9PSBBc3NldFR5cGUuTUFURVJJQUwpOlxuXHRcdFx0XHRyZXR1cm4gdGhpcy5nZXREZWZhdWx0TWF0ZXJpYWwoKVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0cHJpdmF0ZSBnZXREZWZhdWx0TWF0ZXJpYWwoKTpJQXNzZXRcblx0e1xuXHRcdGlmICghdGhpcy5fZGVmYXVsdEJpdG1hcE1hdGVyaWFsKVxuXHRcdFx0dGhpcy5fZGVmYXVsdEJpdG1hcE1hdGVyaWFsID0gPFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWw+IERlZmF1bHRNYXRlcmlhbE1hbmFnZXIuZ2V0RGVmYXVsdE1hdGVyaWFsKCk7XG5cblx0XHRyZXR1cm4gIDxJQXNzZXQ+ICB0aGlzLl9kZWZhdWx0Qml0bWFwTWF0ZXJpYWw7XG5cdH1cblxuXHRwcml2YXRlIGdldERlZmF1bHRUZXh0dXJlKCk6SUFzc2V0XG5cdHtcblx0XHRpZiAoIXRoaXMuX2RlZmF1bHRUZXh0dXJlKVxuXHRcdFx0dGhpcy5fZGVmYXVsdFRleHR1cmUgPSBEZWZhdWx0TWF0ZXJpYWxNYW5hZ2VyLmdldERlZmF1bHRUZXh0dXJlKCk7XG5cblx0XHRyZXR1cm4gPElBc3NldD4gdGhpcy5fZGVmYXVsdFRleHR1cmU7XG5cblx0fVxuXG5cdHByaXZhdGUgZ2V0RGVmYXVsdEN1YmVUZXh0dXJlKCk6SUFzc2V0XG5cdHtcblx0XHRpZiAoIXRoaXMuX2RlZmF1bHRDdWJlVGV4dHVyZSkge1xuXHRcdFx0dmFyIGRlZmF1bHRCaXRtYXA6Qml0bWFwRGF0YSA9IERlZmF1bHRNYXRlcmlhbE1hbmFnZXIuY3JlYXRlQ2hlY2tlcmVkQml0bWFwRGF0YSgpO1xuXG5cdFx0XHR0aGlzLl9kZWZhdWx0Q3ViZVRleHR1cmUgPSBuZXcgQml0bWFwQ3ViZVRleHR1cmUoZGVmYXVsdEJpdG1hcCwgZGVmYXVsdEJpdG1hcCwgZGVmYXVsdEJpdG1hcCwgZGVmYXVsdEJpdG1hcCwgZGVmYXVsdEJpdG1hcCwgZGVmYXVsdEJpdG1hcCk7XG5cdFx0XHR0aGlzLl9kZWZhdWx0Q3ViZVRleHR1cmUubmFtZSA9IFwiZGVmYXVsdEN1YmVUZXh0dXJlXCI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIDxJQXNzZXQ+IHRoaXMuX2RlZmF1bHRDdWJlVGV4dHVyZTtcblx0fVxuXG5cdHByaXZhdGUgcmVhZE51bWJlcihwcmVjaXNpb246Ym9vbGVhbiA9IGZhbHNlKTpudW1iZXJcblx0e1xuXHRcdGlmIChwcmVjaXNpb24pXG5cdFx0XHRyZXR1cm4gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkRG91YmxlKCk7XG5cdFx0cmV0dXJuIHRoaXMuX25ld0Jsb2NrQnl0ZXMucmVhZEZsb2F0KCk7XG5cblx0fVxuXG5cdHByaXZhdGUgcGFyc2VNYXRyaXgzRCgpOk1hdHJpeDNEXG5cdHtcblx0XHRyZXR1cm4gbmV3IE1hdHJpeDNEKHRoaXMucGFyc2VNYXRyaXg0M1Jhd0RhdGEoKSk7XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlTWF0cml4MzJSYXdEYXRhKCk6QXJyYXk8bnVtYmVyPlxuXHR7XG5cdFx0dmFyIGk6bnVtYmVyO1xuXHRcdHZhciBtdHhfcmF3OkFycmF5PG51bWJlcj4gPSBuZXcgQXJyYXk8bnVtYmVyPig2KTtcblx0XHRmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7XG5cdFx0XHRtdHhfcmF3W2ldID0gdGhpcy5fbmV3QmxvY2tCeXRlcy5yZWFkRmxvYXQoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbXR4X3Jhdztcblx0fVxuXG5cdHByaXZhdGUgcGFyc2VNYXRyaXg0M1Jhd0RhdGEoKTpBcnJheTxudW1iZXI+XG5cdHtcblx0XHR2YXIgbXR4X3JhdzpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oMTYpO1xuXG5cdFx0bXR4X3Jhd1swXSA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeU1hdHJpeCk7XG5cdFx0bXR4X3Jhd1sxXSA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeU1hdHJpeCk7XG5cdFx0bXR4X3Jhd1syXSA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeU1hdHJpeCk7XG5cdFx0bXR4X3Jhd1szXSA9IDAuMDtcblx0XHRtdHhfcmF3WzRdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5TWF0cml4KTtcblx0XHRtdHhfcmF3WzVdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5TWF0cml4KTtcblx0XHRtdHhfcmF3WzZdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5TWF0cml4KTtcblx0XHRtdHhfcmF3WzddID0gMC4wO1xuXHRcdG10eF9yYXdbOF0gPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lNYXRyaXgpO1xuXHRcdG10eF9yYXdbOV0gPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lNYXRyaXgpO1xuXHRcdG10eF9yYXdbMTBdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5TWF0cml4KTtcblx0XHRtdHhfcmF3WzExXSA9IDAuMDtcblx0XHRtdHhfcmF3WzEyXSA9IHRoaXMucmVhZE51bWJlcih0aGlzLl9hY2N1cmFjeU1hdHJpeCk7XG5cdFx0bXR4X3Jhd1sxM10gPSB0aGlzLnJlYWROdW1iZXIodGhpcy5fYWNjdXJhY3lNYXRyaXgpO1xuXHRcdG10eF9yYXdbMTRdID0gdGhpcy5yZWFkTnVtYmVyKHRoaXMuX2FjY3VyYWN5TWF0cml4KTtcblx0XHRtdHhfcmF3WzE1XSA9IDEuMDtcblxuXHRcdC8vVE9ETzogZml4IG1heCBleHBvcnRlciB0byByZW1vdmUgTmFOIHZhbHVlcyBpbiBqb2ludCAwIGludmVyc2UgYmluZCBwb3NlXG5cblx0XHRpZiAoaXNOYU4obXR4X3Jhd1swXSkpIHtcblx0XHRcdG10eF9yYXdbMF0gPSAxO1xuXHRcdFx0bXR4X3Jhd1sxXSA9IDA7XG5cdFx0XHRtdHhfcmF3WzJdID0gMDtcblx0XHRcdG10eF9yYXdbNF0gPSAwO1xuXHRcdFx0bXR4X3Jhd1s1XSA9IDE7XG5cdFx0XHRtdHhfcmF3WzZdID0gMDtcblx0XHRcdG10eF9yYXdbOF0gPSAwO1xuXHRcdFx0bXR4X3Jhd1s5XSA9IDA7XG5cdFx0XHRtdHhfcmF3WzEwXSA9IDE7XG5cdFx0XHRtdHhfcmF3WzEyXSA9IDA7XG5cdFx0XHRtdHhfcmF3WzEzXSA9IDA7XG5cdFx0XHRtdHhfcmF3WzE0XSA9IDA7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gbXR4X3Jhdztcblx0fVxuXG59XG5cbmV4cG9ydCA9IEFXRFBhcnNlcjsiXX0= \ No newline at end of file diff --git a/lib/parsers/AWDParser.ts b/lib/parsers/AWDParser.ts new file mode 100644 index 000000000..4fe68a457 --- /dev/null +++ b/lib/parsers/AWDParser.ts @@ -0,0 +1,2820 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import BitmapData = require("awayjs-core/lib/core/base/BitmapData"); +import BlendMode = require("awayjs-core/lib/core/base/BlendMode"); +import DisplayObject = require("awayjs-core/lib/core/base/DisplayObject"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import LightBase = require("awayjs-core/lib/core/base/LightBase"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import ColorTransform = require("awayjs-core/lib/core/geom/ColorTransform"); +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +import AssetType = require("awayjs-core/lib/core/library/AssetType"); +import IAsset = require("awayjs-core/lib/core/library/IAsset"); +import DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +import PointLight = require("awayjs-core/lib/entities/PointLight"); +import Camera = require("awayjs-core/lib/entities/Camera"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import Skybox = require("awayjs-core/lib/entities/Skybox"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); +import LightPickerBase = require("awayjs-core/lib/materials/lightpickers/LightPickerBase"); +import StaticLightPicker = require("awayjs-core/lib/materials/lightpickers/StaticLightPicker"); +import CubeMapShadowMapper = require("awayjs-core/lib/materials/shadowmappers/CubeMapShadowMapper"); +import DirectionalShadowMapper = require("awayjs-core/lib/materials/shadowmappers/DirectionalShadowMapper"); +import ShadowMapperBase = require("awayjs-core/lib/materials/shadowmappers/ShadowMapperBase"); +import PrefabBase = require("awayjs-core/lib/prefabs/PrefabBase"); +import PrimitiveCapsulePrefab = require("awayjs-core/lib/prefabs/PrimitiveCapsulePrefab"); +import PrimitiveConePrefab = require("awayjs-core/lib/prefabs/PrimitiveConePrefab"); +import PrimitiveCubePrefab = require("awayjs-core/lib/prefabs/PrimitiveCubePrefab"); +import PrimitiveCylinderPrefab = require("awayjs-core/lib/prefabs/PrimitiveCylinderPrefab"); +import PrimitivePlanePrefab = require("awayjs-core/lib/prefabs/PrimitivePlanePrefab"); +import PrimitiveSpherePrefab = require("awayjs-core/lib/prefabs/PrimitiveSpherePrefab"); +import PrimitiveTorusPrefab = require("awayjs-core/lib/prefabs/PrimitiveTorusPrefab"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +import ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +import ResourceDependency = require("awayjs-core/lib/parsers/ResourceDependency"); +import ProjectionBase = require("awayjs-core/lib/projections/ProjectionBase"); +import PerspectiveProjection = require("awayjs-core/lib/projections/PerspectiveProjection"); +import OrthographicProjection = require("awayjs-core/lib/projections/OrthographicProjection"); +import OrthographicOffCenterProjection = require("awayjs-core/lib/projections/OrthographicOffCenterProjection"); +import BitmapCubeTexture = require("awayjs-core/lib/textures/BitmapCubeTexture"); +import BitmapTexture = require("awayjs-core/lib/textures/BitmapTexture"); +import CubeTextureBase = require("awayjs-core/lib/textures/CubeTextureBase"); +import ImageCubeTexture = require("awayjs-core/lib/textures/ImageCubeTexture"); +import ImageTexture = require("awayjs-core/lib/textures/ImageTexture"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); +import TextureProxyBase = require("awayjs-core/lib/textures/TextureProxyBase"); +import ByteArray = require("awayjs-core/lib/utils/ByteArray"); + +import AnimationSetBase = require("awayjs-stagegl/lib/animators/AnimationSetBase"); +import AnimatorBase = require("awayjs-stagegl/lib/animators/AnimatorBase"); +import SkyboxMaterial = require("awayjs-stagegl/lib/materials/SkyboxMaterial"); +import TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); +import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +import DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); + +import VertexAnimationSet = require("awayjs-renderergl/lib/animators/VertexAnimationSet"); +import VertexAnimator = require("awayjs-renderergl/lib/animators/VertexAnimator"); +import SkeletonAnimationSet = require("awayjs-renderergl/lib/animators/SkeletonAnimationSet"); +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 SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint"); +import SkeletonClipNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonClipNode"); +import VertexClipNode = require("awayjs-renderergl/lib/animators/nodes/VertexClipNode"); +import AmbientEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/AmbientEnvMapMethod"); +import DiffuseDepthMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseDepthMethod"); +import DiffuseCelMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseCelMethod"); +import DiffuseGradientMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseGradientMethod"); +import DiffuseLightMapMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseLightMapMethod"); +import DiffuseWrapMethod = require("awayjs-renderergl/lib/materials/methods/DiffuseWrapMethod"); +import EffectAlphaMaskMethod = require("awayjs-renderergl/lib/materials/methods/EffectAlphaMaskMethod"); +import EffectColorMatrixMethod = require("awayjs-renderergl/lib/materials/methods/EffectColorMatrixMethod"); +import EffectColorTransformMethod = require("awayjs-stagegl/lib/materials/methods/EffectColorTransformMethod"); +import EffectEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectEnvMapMethod"); +import EffectFogMethod = require("awayjs-renderergl/lib/materials/methods/EffectFogMethod"); +import EffectFresnelEnvMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectFresnelEnvMapMethod"); +import EffectLightMapMethod = require("awayjs-renderergl/lib/materials/methods/EffectLightMapMethod"); +import EffectMethodBase = require("awayjs-stagegl/lib/materials/methods/EffectMethodBase"); +import EffectRimLightMethod = require("awayjs-renderergl/lib/materials/methods/EffectRimLightMethod"); +import NormalSimpleWaterMethod = require("awayjs-renderergl/lib/materials/methods/NormalSimpleWaterMethod"); +import ShadowDitheredMethod = require("awayjs-renderergl/lib/materials/methods/ShadowDitheredMethod"); +import ShadowFilteredMethod = require("awayjs-renderergl/lib/materials/methods/ShadowFilteredMethod"); +import ShadowMethodBase = require("awayjs-stagegl/lib/materials/methods/ShadowMethodBase"); +import SpecularFresnelMethod = require("awayjs-renderergl/lib/materials/methods/SpecularFresnelMethod"); +import ShadowHardMethod = require("awayjs-stagegl/lib/materials/methods/ShadowHardMethod"); +import SpecularAnisotropicMethod = require("awayjs-renderergl/lib/materials/methods/SpecularAnisotropicMethod"); +import SpecularCelMethod = require("awayjs-renderergl/lib/materials/methods/SpecularCelMethod"); +import SpecularPhongMethod = require("awayjs-renderergl/lib/materials/methods/SpecularPhongMethod"); +import ShadowNearMethod = require("awayjs-renderergl/lib/materials/methods/ShadowNearMethod"); +import ShadowSoftMethod = require("awayjs-renderergl/lib/materials/methods/ShadowSoftMethod"); + +import AWDBlock = require("awayjs-renderergl/lib/parsers/data/AWDBlock"); +import AWDProperties = require("awayjs-renderergl/lib/parsers/data/AWDProperties"); +import BitFlags = require("awayjs-renderergl/lib/parsers/data/BitFlags"); + +/** + * AWDParser provides a parser for the AWD data type. + */ +class AWDParser extends ParserBase +{ + //set to "true" to have some console.logs in the Console + private _debug:boolean = false; + private _byteData:ByteArray; + private _startedParsing:boolean = false; + private _cur_block_id:number; + private _blocks:Array; + private _newBlockBytes:ByteArray; + private _version:Array; + private _compression:number; + private _accuracyOnBlocks:boolean; + private _accuracyMatrix:boolean; + private _accuracyGeo:boolean; + private _accuracyProps:boolean; + private _matrixNrType:number; + private _geoNrType:number; + private _propsNrType:number; + private _streaming:boolean; + private _texture_users:Object = {}; + private _parsed_header:boolean = false; + private _body:ByteArray; + private _defaultTexture:BitmapTexture; // HTML IMAGE TEXTURE >? ! + private _cubeTextures:Array; + private _defaultBitmapMaterial:TriangleMethodMaterial; + private _defaultCubeTexture:BitmapCubeTexture; + + public static COMPRESSIONMODE_LZMA:string = "lzma"; + public static UNCOMPRESSED:number = 0; + public static DEFLATE:number = 1; + public static LZMA:number = 2; + public static INT8:number = 1; + public static INT16:number = 2; + public static INT32:number = 3; + public static UINT8:number = 4; + public static UINT16:number = 5; + public static UINT32:number = 6; + public static FLOAT32:number = 7; + public static FLOAT64:number = 8; + public static BOOL:number = 21; + public static COLOR:number = 22; + public static BADDR:number = 23; + public static AWDSTRING:number = 31; + public static AWDBYTEARRAY:number = 32; + public static VECTOR2x1:number = 41; + public static VECTOR3x1:number = 42; + public static VECTOR4x1:number = 43; + public static MTX3x2:number = 44; + public static MTX3x3:number = 45; + public static MTX4x3:number = 46; + public static MTX4x4:number = 47; + + private blendModeDic:Array; + private _depthSizeDic:Array; + + /** + * Creates a new AWDParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + constructor() + { + super(URLLoaderDataFormat.ARRAY_BUFFER); + + this._blocks = new Array(); + this._blocks[0] = new AWDBlock(); + this._blocks[0].data = null; // Zero address means null in AWD + + this.blendModeDic = new Array(); // used to translate ints to blendMode-strings + this.blendModeDic.push(BlendMode.NORMAL); + this.blendModeDic.push(BlendMode.ADD); + this.blendModeDic.push(BlendMode.ALPHA); + this.blendModeDic.push(BlendMode.DARKEN); + this.blendModeDic.push(BlendMode.DIFFERENCE); + this.blendModeDic.push(BlendMode.ERASE); + this.blendModeDic.push(BlendMode.HARDLIGHT); + this.blendModeDic.push(BlendMode.INVERT); + this.blendModeDic.push(BlendMode.LAYER); + this.blendModeDic.push(BlendMode.LIGHTEN); + this.blendModeDic.push(BlendMode.MULTIPLY); + this.blendModeDic.push(BlendMode.NORMAL); + this.blendModeDic.push(BlendMode.OVERLAY); + this.blendModeDic.push(BlendMode.SCREEN); + this.blendModeDic.push(BlendMode.SHADER); + this.blendModeDic.push(BlendMode.OVERLAY); + + this._depthSizeDic = new Array(); // used to translate ints to depthSize-values + this._depthSizeDic.push(256); + this._depthSizeDic.push(512); + this._depthSizeDic.push(2048); + this._depthSizeDic.push(1024); + this._version = Array(); // will contain 2 int (major-version, minor-version) for awd-version-check + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "awd"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + return (ParserUtils.toString(data, 3) == 'AWD'); + } + + /** + * @inheritDoc + */ + public _iResolveDependency(resourceDependency:ResourceDependency):void + { + // this will be called when Dependency has finished loading. + // the Assets waiting for this Bitmap, can be Texture or CubeTexture. + // if the Bitmap is awaited by a CubeTexture, we need to check if its the last Bitmap of the CubeTexture, + // so we know if we have to finalize the Asset (CubeTexture) or not. + if (resourceDependency.assets.length == 1) { + var isCubeTextureArray:Array = resourceDependency.id.split("#"); + var ressourceID:string = isCubeTextureArray[0]; + var asset:TextureProxyBase; + var thisBitmapTexture:Texture2DBase; + var block:AWDBlock; + + if (isCubeTextureArray.length == 1) // Not a cube texture + { + asset = resourceDependency.assets[0]; + if (asset) { + var mat:TriangleMethodMaterial; + var users:Array; + + block = this._blocks[ resourceDependency.id ]; + block.data = asset; // Store finished asset + + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + block.name = asset.name; + // Finalize texture asset to dispatch texture event, which was + // previously suppressed while the dependency was loaded. + this._pFinalizeAsset( asset); + + if (this._debug) { + console.log("Successfully loaded Bitmap for texture"); + console.log("Parsed texture: Name = " + block.name); + } + } + } + + if (isCubeTextureArray.length > 1) // Cube Texture + { + thisBitmapTexture = resourceDependency.assets[0]; + + var tx:ImageTexture = thisBitmapTexture; + + this._cubeTextures[ isCubeTextureArray[1] ] = tx.htmlImageElement; // ? + this._texture_users[ressourceID].push(1); + + if (this._debug) { + console.log("Successfully loaded Bitmap " + this._texture_users[ressourceID].length + " / 6 for Cubetexture"); + } + if (this._texture_users[ressourceID].length == this._cubeTextures.length) { + + var posX:any = this._cubeTextures[0]; + var negX:any = this._cubeTextures[1]; + var posY:any = this._cubeTextures[2]; + var negY:any = this._cubeTextures[3]; + var posZ:any = this._cubeTextures[4]; + var negZ:any = this._cubeTextures[5]; + + asset = new ImageCubeTexture(posX, negX, posY, negY, posZ, negZ); + block = this._blocks[ressourceID]; + block.data = asset; // Store finished asset + + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + block.name = asset.name; + // Finalize texture asset to dispatch texture event, which was + // previously suppressed while the dependency was loaded. + this._pFinalizeAsset( asset); + if (this._debug) { + console.log("Parsed CubeTexture: Name = " + block.name); + } + } + } + + } + } + + /** + * @inheritDoc + */ + public _iResolveDependencyFailure(resourceDependency:ResourceDependency):void + { + //not used - if a dependcy fails, the awaiting Texture or CubeTexture will never be finalized, and the default-bitmaps will be used. + // this means, that if one Bitmap of a CubeTexture fails, the CubeTexture will have the DefaultTexture applied for all six Bitmaps. + } + + /** + * Resolve a dependency name + * + * @param resourceDependency The dependency to be resolved. + */ + public _iResolveDependencyName(resourceDependency:ResourceDependency, asset:IAsset):string + { + var oldName:string = asset.name; + + if (asset) { + var block:AWDBlock = this._blocks[parseInt(resourceDependency.id)]; + // Reset name of texture to the one defined in the AWD file, + // as opposed to whatever the image parser came up with. + asset.resetAssetPath(block.name, null, true); + } + + var newName:string = asset.name; + + asset.name = oldName; + + return newName; + + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + + if (!this._startedParsing) { + this._byteData = this._pGetByteData();//getByteData(); + this._startedParsing = true; + } + + if (!this._parsed_header) { + + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN; + //---------------------------------------------------------------------------- + + //---------------------------------------------------------------------------- + // Parse header and decompress body if needed + this.parseHeader(); + + switch (this._compression) { + + case AWDParser.DEFLATE: + case AWDParser.LZMA: + this._pDieWithError('Compressed AWD formats not yet supported'); + break; + + case AWDParser.UNCOMPRESSED: + this._body = this._byteData; + break; + + //---------------------------------------------------------------------------- + // Compressed AWD Formats not yet supported + //---------------------------------------------------------------------------- + + /* + case AWDParser.DEFLATE: + + this._body = new ByteArray(); + this._byteData.readBytes(this._body, 0, this._byteData.getBytesAvailable()); + this._body.uncompress(); + + break; + case AWDParser.LZMA: + + this._body = new ByteArray(); + this._byteData.readBytes(this._body, 0, this._byteData.getBytesAvailable()); + this._body.uncompress(COMPRESSIONMODE_LZMA); + + break; + //*/ + + } + + this._parsed_header = true; + + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._body.endian = Endian.LITTLE_ENDIAN;// Should be default + //---------------------------------------------------------------------------- + + } + + if (this._body) { + + while (this._body.getBytesAvailable() > 0 && !this.parsingPaused) //&& this._pHasTime() ) + { + this.parseNextBlock(); + + } + + //---------------------------------------------------------------------------- + // Return complete status + if (this._body.getBytesAvailable() == 0) { + this.dispose(); + return ParserBase.PARSING_DONE; + } else { + return ParserBase.MORE_TO_PARSE; + } + } else { + + switch (this._compression) { + + case AWDParser.DEFLATE: + case AWDParser.LZMA: + + if (this._debug) { + console.log("(!) AWDParser Error: Compressed AWD formats not yet supported (!)"); + } + + break; + + } + // Error - most likely _body not set because we do not support compression. + return ParserBase.PARSING_DONE; + + } + + } + + public _pStartParsing(frameLimit:number) + { + super._pStartParsing(frameLimit); + + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + } + + private dispose():void + { + + for (var c in this._blocks) { + + var b:AWDBlock = this._blocks[ c ]; + b.dispose(); + + } + + } + + private parseNextBlock():void + { + var block:AWDBlock; + var assetData:IAsset; + var isParsed:boolean = false; + var ns:number; + var type:number; + var flags:number; + var len:number; + + this._cur_block_id = this._body.readUnsignedInt(); + + ns = this._body.readUnsignedByte(); + type = this._body.readUnsignedByte(); + flags = this._body.readUnsignedByte(); + len = this._body.readUnsignedInt(); + + var blockCompression:boolean = BitFlags.test(flags, BitFlags.FLAG4); + var blockCompressionLZMA:boolean = BitFlags.test(flags, BitFlags.FLAG5); + + if (this._accuracyOnBlocks) { + this._accuracyMatrix = BitFlags.test(flags, BitFlags.FLAG1); + this._accuracyGeo = BitFlags.test(flags, BitFlags.FLAG2); + this._accuracyProps = BitFlags.test(flags, BitFlags.FLAG3); + this._geoNrType = AWDParser.FLOAT32; + + if (this._accuracyGeo) { + this._geoNrType = AWDParser.FLOAT64; + } + + this._matrixNrType = AWDParser.FLOAT32; + + if (this._accuracyMatrix) { + this._matrixNrType = AWDParser.FLOAT64; + } + + this._propsNrType = AWDParser.FLOAT32; + + if (this._accuracyProps) { + this._propsNrType = AWDParser.FLOAT64; + } + } + + var blockEndAll:number = this._body.position + len; + + if (len > this._body.getBytesAvailable()) { + this._pDieWithError('AWD2 block length is bigger than the bytes that are available!'); + this._body.position += this._body.getBytesAvailable(); + return; + } + this._newBlockBytes = new ByteArray(); + + + this._body.readBytes(this._newBlockBytes, 0, len); + + //---------------------------------------------------------------------------- + // Compressed AWD Formats not yet supported + + if (blockCompression) { + this._pDieWithError('Compressed AWD formats not yet supported'); + + /* + if (blockCompressionLZMA) + { + this._newBlockBytes.uncompress(AWDParser.COMPRESSIONMODE_LZMA); + } + else + { + this._newBlockBytes.uncompress(); + } + */ + + } + + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._newBlockBytes.endian = Endian.LITTLE_ENDIAN; + //---------------------------------------------------------------------------- + + this._newBlockBytes.position = 0; + block = new AWDBlock(); + block.len = this._newBlockBytes.position + len; + block.id = this._cur_block_id; + + var blockEndBlock:number = this._newBlockBytes.position + len; + + if (blockCompression) { + this._pDieWithError('Compressed AWD formats not yet supported'); + //blockEndBlock = this._newBlockBytes.position + this._newBlockBytes.length; + //block.len = blockEndBlock; + } + + if (this._debug) { + console.log("AWDBlock: ID = " + this._cur_block_id + " | TypeID = " + type + " | Compression = " + blockCompression + " | Matrix-Precision = " + this._accuracyMatrix + " | Geometry-Precision = " + this._accuracyGeo + " | Properties-Precision = " + this._accuracyProps); + } + + this._blocks[this._cur_block_id] = block; + + if ((this._version[0] == 2) && (this._version[1] == 1)) { + + switch (type) { + case 11: + this.parsePrimitves(this._cur_block_id); + isParsed = true; + break; + case 31: + this.parseSkyboxInstance(this._cur_block_id); + isParsed = true; + break; + case 41: + this.parseLight(this._cur_block_id); + isParsed = true; + break; + case 42: + this.parseCamera(this._cur_block_id); + isParsed = true; + break; + + // case 43: + // parseTextureProjector(_cur_block_id); + // isParsed = true; + // break; + + case 51: + this.parseLightPicker(this._cur_block_id); + isParsed = true; + break; + case 81: + this.parseMaterial_v1(this._cur_block_id); + isParsed = true; + break; + case 83: + this.parseCubeTexture(this._cur_block_id); + isParsed = true; + break; + case 91: + this.parseSharedMethodBlock(this._cur_block_id); + isParsed = true; + break; + case 92: + this.parseShadowMethodBlock(this._cur_block_id); + isParsed = true; + break; + case 111: + this.parseMeshPoseAnimation(this._cur_block_id, true); + isParsed = true; + break; + case 112: + this.parseMeshPoseAnimation(this._cur_block_id); + isParsed = true; + break; + case 113: + this.parseVertexAnimationSet(this._cur_block_id); + isParsed = true; + break; + case 122: + this.parseAnimatorSet(this._cur_block_id); + isParsed = true; + break; + case 253: + this.parseCommand(this._cur_block_id); + isParsed = true; + break; + } + //*/ + } + //* + if (isParsed == false) { + switch (type) { + + case 1: + this.parseTriangleGeometrieBlock(this._cur_block_id); + break; + case 22: + this.parseContainer(this._cur_block_id); + break; + case 23: + this.parseMeshInstance(this._cur_block_id); + break; + case 81: + this.parseMaterial(this._cur_block_id); + break; + case 82: + this.parseTexture(this._cur_block_id); + break; + case 101: + this.parseSkeleton(this._cur_block_id); + break; + case 102: + this.parseSkeletonPose(this._cur_block_id); + break; + case 103: + this.parseSkeletonAnimation(this._cur_block_id); + break; + case 121: + //this.parseUVAnimation(this._cur_block_id); + //break; + case 254: + this.parseNameSpace(this._cur_block_id); + break; + case 255: + this.parseMetaData(this._cur_block_id); + break; + default: + if (this._debug) { + console.log("AWDBlock: Unknown BlockType (BlockID = " + this._cur_block_id + ") - Skip " + len + " bytes"); + } + this._newBlockBytes.position += len; + break; + } + } + //*/ + + var msgCnt:number = 0; + if (this._newBlockBytes.position == blockEndBlock) { + if (this._debug) { + if (block.errorMessages) { + while (msgCnt < block.errorMessages.length) { + console.log(" (!) Error: " + block.errorMessages[msgCnt] + " (!)"); + msgCnt++; + } + } + } + if (this._debug) { + console.log("\n"); + } + } else { + if (this._debug) { + + console.log(" (!)(!)(!) Error while reading AWDBlock ID " + this._cur_block_id + " = skip to next block"); + + if (block.errorMessages) { + while (msgCnt < block.errorMessages.length) { + console.log(" (!) Error: " + block.errorMessages[msgCnt] + " (!)"); + msgCnt++; + } + } + } + } + + this._body.position = blockEndAll; + this._newBlockBytes = null; + + } + + + //--Parser Blocks--------------------------------------------------------------------------- + + //Block ID = 1 + private parseTriangleGeometrieBlock(blockID:number):void + { + + var geom:Geometry = new Geometry(); + + // Read name and sub count + var name:string = this.parseVarStr(); + var num_subs:number = this._newBlockBytes.readUnsignedShort(); + + // Read optional properties + var props:AWDProperties = this.parseProperties({1:this._geoNrType, 2:this._geoNrType}); + var geoScaleU:number = props.get(1, 1); + var geoScaleV:number = props.get(2, 1); + + // Loop through sub meshes + var subs_parsed:number = 0; + while (subs_parsed < num_subs) { + var i:number; + var sm_len:number, sm_end:number; + var sub_geom:TriangleSubGeometry; + var w_indices:Array; + var weights:Array; + + sm_len = this._newBlockBytes.readUnsignedInt(); + sm_end = this._newBlockBytes.position + sm_len; + + // Ignore for now + var subProps:AWDProperties = this.parseProperties({1:this._geoNrType, 2:this._geoNrType}); + // Loop through data streams + while (this._newBlockBytes.position < sm_end) { + var idx:number = 0; + var str_ftype:number, str_type:number, str_len:number, str_end:number; + + // Type, field type, length + str_type = this._newBlockBytes.readUnsignedByte(); + str_ftype = this._newBlockBytes.readUnsignedByte(); + str_len = this._newBlockBytes.readUnsignedInt(); + str_end = this._newBlockBytes.position + str_len; + + var x:number, y:number, z:number; + + if (str_type == 1) { + var verts:Array = new Array(); + + while (this._newBlockBytes.position < str_end) { + // TODO: Respect stream field type + x = this.readNumber(this._accuracyGeo); + y = this.readNumber(this._accuracyGeo); + z = this.readNumber(this._accuracyGeo); + + verts[idx++] = x; + verts[idx++] = y; + verts[idx++] = z; + } + } else if (str_type == 2) { + var indices:Array = new Array(); + + while (this._newBlockBytes.position < str_end) { + // TODO: Respect stream field type + indices[idx++] = this._newBlockBytes.readUnsignedShort(); + } + + } else if (str_type == 3) { + var uvs:Array = new Array(); + while (this._newBlockBytes.position < str_end) { + uvs[idx++] = this.readNumber(this._accuracyGeo); + + } + } else if (str_type == 4) { + + var normals:Array = new Array(); + + while (this._newBlockBytes.position < str_end) { + normals[idx++] = this.readNumber(this._accuracyGeo); + } + + } else if (str_type == 6) { + w_indices = Array(); + + while (this._newBlockBytes.position < str_end) { + w_indices[idx++] = this._newBlockBytes.readUnsignedShort()*3; // TODO: Respect stream field type + } + + } else if (str_type == 7) { + + weights = new Array(); + + while (this._newBlockBytes.position < str_end) { + weights[idx++] = this.readNumber(this._accuracyGeo); + } + } else { + this._newBlockBytes.position = str_end; + } + + } + + this.parseUserAttributes(); // Ignore sub-mesh attributes for now + + sub_geom = new TriangleSubGeometry(true); + if (weights) + sub_geom.jointsPerVertex = weights.length/(verts.length/3); + if (normals) + sub_geom.autoDeriveNormals = false; + if (uvs) + sub_geom.autoDeriveUVs = false; + sub_geom.updateIndices(indices); + sub_geom.updatePositions(verts); + sub_geom.updateVertexNormals(normals); + sub_geom.updateUVs(uvs); + sub_geom.updateVertexTangents(null); + sub_geom.updateJointWeights(weights); + sub_geom.updateJointIndices(w_indices); + + var scaleU:number = subProps.get(1, 1); + var scaleV:number = subProps.get(2, 1); + var setSubUVs:boolean = false; //this should remain false atm, because in AwayBuilder the uv is only scaled by the geometry + + if ((geoScaleU != scaleU) || (geoScaleV != scaleV)) { + setSubUVs = true; + scaleU = geoScaleU/scaleU; + scaleV = geoScaleV/scaleV; + } + + if (setSubUVs) + sub_geom.scaleUV(scaleU, scaleV); + + geom.addSubGeometry(sub_geom); + + // TODO: Somehow map in-sub to out-sub indices to enable look-up + // when creating meshes (and their material assignments.) + + subs_parsed++; + } + if ((geoScaleU != 1) || (geoScaleV != 1)) + geom.scaleUV(geoScaleU, geoScaleV); + this.parseUserAttributes(); + this._pFinalizeAsset( geom, name); + this._blocks[blockID].data = geom; + + if (this._debug) { + console.log("Parsed a TriangleGeometry: Name = " + name + "| Id = " + sub_geom.id); + } + + } + + //Block ID = 11 + private parsePrimitves(blockID:number):void + { + var name:string; + var prefab:PrefabBase; + var primType:number; + var subs_parsed:number; + var props:AWDProperties; + var bsm:Matrix3D; + + // Read name and sub count + name = this.parseVarStr(); + primType = this._newBlockBytes.readUnsignedByte(); + props = this.parseProperties({101:this._geoNrType, 102:this._geoNrType, 103:this._geoNrType, 110:this._geoNrType, 111:this._geoNrType, 301:AWDParser.UINT16, 302:AWDParser.UINT16, 303:AWDParser.UINT16, 701:AWDParser.BOOL, 702:AWDParser.BOOL, 703:AWDParser.BOOL, 704:AWDParser.BOOL}); + + var primitiveTypes:Array = ["Unsupported Type-ID", "PrimitivePlanePrefab", "PrimitiveCubePrefab", "PrimitiveSpherePrefab", "PrimitiveCylinderPrefab", "PrimitivesConePrefab", "PrimitivesCapsulePrefab", "PrimitivesTorusPrefab"] + + switch (primType) { + // to do, not all properties are set on all primitives + + case 1: + prefab = new PrimitivePlanePrefab(props.get(101, 100), props.get(102, 100), props.get(301, 1), props.get(302, 1), props.get(701, true), props.get(702, false)); + break; + + case 2: + prefab = new PrimitiveCubePrefab(props.get(101, 100), props.get(102, 100), props.get(103, 100), props.get(301, 1), props.get(302, 1), props.get(303, 1), props.get(701, true)); + break; + + case 3: + prefab = new PrimitiveSpherePrefab(props.get(101, 50), props.get(301, 16), props.get(302, 12), props.get(701, true)); + break; + + case 4: + prefab = new PrimitiveCylinderPrefab(props.get(101, 50), props.get(102, 50), props.get(103, 100), props.get(301, 16), props.get(302, 1), true, true, true); // bool701, bool702, bool703, bool704); + if (!props.get(701, true)) + (prefab).topClosed = false; + if (!props.get(702, true)) + (prefab).bottomClosed = false; + if (!props.get(703, true)) + (prefab).yUp = false; + + break; + + case 5: + prefab = new PrimitiveConePrefab(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 1), props.get(701, true), props.get(702, true)); + break; + + case 6: + prefab = new PrimitiveCapsulePrefab(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 15), props.get(701, true)); + break; + + case 7: + prefab = new PrimitiveTorusPrefab(props.get(101, 50), props.get(102, 50), props.get(301, 16), props.get(302, 8), props.get(701, true)); + break; + + default: + prefab = new PrefabBase(); + console.log("ERROR: UNSUPPORTED PREFAB_TYPE"); + break; + } + + if ((props.get(110, 1) != 1) || (props.get(111, 1) != 1)) { + //geom.subGeometries; + //geom.scaleUV(props.get(110, 1), props.get(111, 1)); //TODO add back scaling to prefabs + } + + this.parseUserAttributes(); + prefab.name = name; + this._pFinalizeAsset(prefab, name); + this._blocks[blockID].data = prefab; + + if (this._debug) { + if ((primType < 0) || (primType > 7)) { + primType = 0; + } + console.log("Parsed a Primivite: Name = " + name + "| type = " + primitiveTypes[primType]); + } + } + + // Block ID = 22 + private parseContainer(blockID:number):void + { + var name:string; + var par_id:number; + var mtx:Matrix3D; + var ctr:DisplayObjectContainer; + var parent:DisplayObjectContainer; + + par_id = this._newBlockBytes.readUnsignedInt(); + mtx = this.parseMatrix3D(); + name = this.parseVarStr(); + + var parentName:string = "Root (TopLevel)"; + ctr = new DisplayObjectContainer(); + ctr.transform.matrix3D = mtx; + + var returnedArray:Array = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + + if (returnedArray[0]) { + var obj:DisplayObject = ( returnedArray[1]).addChild(ctr); + parentName = ( returnedArray[1]).name; + } else if (par_id > 0) { + this._blocks[ blockID ].addError("Could not find a parent for this ObjectContainer3D"); + } else { + //add to the content property + ( this._pContent).addChild(ctr); + } + + // in AWD version 2.1 we read the Container properties + if ((this._version[0] == 2) && (this._version[1] == 1)) { + var props:AWDProperties = this.parseProperties({1:this._matrixNrType, 2:this._matrixNrType, 3:this._matrixNrType, 4:AWDParser.UINT8}); + ctr.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + } + // in other versions we do not read the Container properties + else { + this.parseProperties(null); + } + + // the extraProperties should only be set for AWD2.1-Files, but is read for both versions + ctr.extra = this.parseUserAttributes(); + + this._pFinalizeAsset( ctr, name); + this._blocks[blockID].data = ctr; + + if (this._debug) { + console.log("Parsed a Container: Name = '" + name + "' | Parent-Name = " + parentName); + } + } + + // Block ID = 23 + private parseMeshInstance(blockID:number):void + { + var num_materials:number; + var materials_parsed:number; + var parent:DisplayObjectContainer; + var par_id:number = this._newBlockBytes.readUnsignedInt(); + var mtx:Matrix3D = this.parseMatrix3D(); + var name:string = this.parseVarStr(); + var parentName:string = "Root (TopLevel)"; + var data_id:number = this._newBlockBytes.readUnsignedInt(); + var geom:Geometry; + var returnedArrayGeometry:Array = this.getAssetByID(data_id, [AssetType.GEOMETRY]) + + if (returnedArrayGeometry[0]) { + geom = returnedArrayGeometry[1]; + } else { + this._blocks[blockID].addError("Could not find a Geometry for this Mesh. A empty Geometry is created!"); + geom = new Geometry(); + } + + this._blocks[blockID].geoID = data_id; + var materials:Array = new Array(); + num_materials = this._newBlockBytes.readUnsignedShort(); + + var materialNames:Array = new Array(); + materials_parsed = 0; + + var returnedArrayMaterial:Array; + + while (materials_parsed < num_materials) { + var mat_id:number; + mat_id = this._newBlockBytes.readUnsignedInt(); + returnedArrayMaterial = this.getAssetByID(mat_id, [AssetType.MATERIAL]) + if ((!returnedArrayMaterial[0]) && (mat_id > 0)) { + this._blocks[blockID].addError("Could not find Material Nr " + materials_parsed + " (ID = " + mat_id + " ) for this Mesh"); + } + + var m:MaterialBase = returnedArrayMaterial[1]; + + materials.push(m); + materialNames.push(m.name); + + materials_parsed++; + } + + var mesh:Mesh = new Mesh(geom, null); + mesh.transform.matrix3D = mtx; + + var returnedArrayParent:Array = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]) + + if (returnedArrayParent[0]) { + var objC:DisplayObjectContainer = returnedArrayParent[1]; + objC.addChild(mesh); + parentName = objC.name; + } else if (par_id > 0) { + this._blocks[blockID].addError("Could not find a parent for this Mesh"); + } else { + //add to the content property + ( this._pContent).addChild(mesh); + } + + if (materials.length >= 1 && mesh.subMeshes.length == 1) { + mesh.material = materials[0]; + } else if (materials.length > 1) { + var i:number; + + // Assign each sub-mesh in the mesh a material from the list. If more sub-meshes + // than materials, repeat the last material for all remaining sub-meshes. + for (i = 0; i < mesh.subMeshes.length; i++) { + mesh.subMeshes[i].material = materials[Math.min(materials.length - 1, i)]; + } + } + if ((this._version[0] == 2) && (this._version[1] == 1)) { + var props:AWDProperties = this.parseProperties({1:this._matrixNrType, 2:this._matrixNrType, 3:this._matrixNrType, 4:AWDParser.UINT8, 5:AWDParser.BOOL}); + mesh.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + mesh.castsShadows = props.get(5, true); + } else { + this.parseProperties(null); + } + + mesh.extra = this.parseUserAttributes(); + + this._pFinalizeAsset( mesh, name); + this._blocks[blockID].data = mesh; + + if (this._debug) { + console.log("Parsed a Mesh: Name = '" + name + "' | Parent-Name = " + parentName + "| Geometry-Name = " + geom.name + " | SubMeshes = " + mesh.subMeshes.length + " | Mat-Names = " + materialNames.toString()); + } + } + + + //Block ID 31 + private parseSkyboxInstance(blockID:number):void + { + var name:string = this.parseVarStr(); + var cubeTexAddr:number = this._newBlockBytes.readUnsignedInt(); + + var returnedArrayCubeTex:Array = this.getAssetByID(cubeTexAddr, [AssetType.TEXTURE], "CubeTexture"); + if ((!returnedArrayCubeTex[0]) && (cubeTexAddr != 0)) + this._blocks[blockID].addError("Could not find the Cubetexture (ID = " + cubeTexAddr + " ) for this Skybox"); + var asset:Skybox = new Skybox(new SkyboxMaterial( returnedArrayCubeTex[1])); + + this.parseProperties(null) + asset.extra = this.parseUserAttributes(); + this._pFinalizeAsset(asset, name); + this._blocks[blockID].data = asset; + if (this._debug) + console.log("Parsed a Skybox: Name = '" + name + "' | CubeTexture-Name = " + ( returnedArrayCubeTex[1]).name); + + } + + //Block ID = 41 + private parseLight(blockID:number):void + { + var light:LightBase; + var newShadowMapper:ShadowMapperBase; + + var par_id:number = this._newBlockBytes.readUnsignedInt(); + var mtx:Matrix3D = this.parseMatrix3D(); + var name:string = this.parseVarStr(); + var lightType:number = this._newBlockBytes.readUnsignedByte(); + var props:AWDProperties = this.parseProperties({1:this._propsNrType, 2:this._propsNrType, 3:AWDParser.COLOR, 4:this._propsNrType, 5:this._propsNrType, 6:AWDParser.BOOL, 7:AWDParser.COLOR, 8:this._propsNrType, 9:AWDParser.UINT8, 10:AWDParser.UINT8, 11:this._propsNrType, 12:AWDParser.UINT16, 21:this._matrixNrType, 22:this._matrixNrType, 23:this._matrixNrType}); + var shadowMapperType:number = props.get(9, 0); + var parentName:string = "Root (TopLevel)"; + var lightTypes:Array = ["Unsupported LightType", "PointLight", "DirectionalLight"]; + var shadowMapperTypes:Array = ["No ShadowMapper", "DirectionalShadowMapper", "NearDirectionalShadowMapper", "CascadeShadowMapper", "CubeMapShadowMapper"]; + + if (lightType == 1) { + light = new PointLight(); + + ( light).radius = props.get(1, 90000); + ( light).fallOff = props.get(2, 100000); + + if (shadowMapperType > 0) { + if (shadowMapperType == 4) { + newShadowMapper = new CubeMapShadowMapper(); + } + } + + light.transform.matrix3D = mtx; + + } + + if (lightType == 2) { + + light = new DirectionalLight(props.get(21, 0), props.get(22, -1), props.get(23, 1)); + + if (shadowMapperType > 0) { + if (shadowMapperType == 1) { + newShadowMapper = new DirectionalShadowMapper(); + } + + //if (shadowMapperType == 2) + // newShadowMapper = new NearDirectionalShadowMapper(props.get(11, 0.5)); + //if (shadowMapperType == 3) + // newShadowMapper = new CascadeShadowMapper(props.get(12, 3)); + + } + + } + light.color = props.get(3, 0xffffff); + light.specular = props.get(4, 1.0); + light.diffuse = props.get(5, 1.0); + light.ambientColor = props.get(7, 0xffffff); + light.ambient = props.get(8, 0.0); + + // if a shadowMapper has been created, adjust the depthMapSize if needed, assign to light and set castShadows to true + if (newShadowMapper) { + if (newShadowMapper instanceof CubeMapShadowMapper) { + if (props.get(10, 1) != 1) { + newShadowMapper.depthMapSize = this._depthSizeDic[props.get(10, 1)]; + } + } else { + if (props.get(10, 2) != 2) { + newShadowMapper.depthMapSize = this._depthSizeDic[props.get(10, 2)]; + } + } + + light.shadowMapper = newShadowMapper; + light.castsShadows = true; + } + + if (par_id != 0) { + + var returnedArrayParent:Array = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]) + + if (returnedArrayParent[0]) { + ( returnedArrayParent[1]).addChild(light); + parentName = ( returnedArrayParent[1]).name; + } else { + this._blocks[blockID].addError("Could not find a parent for this Light"); + } + } else { + //add to the content property + ( this._pContent).addChild(light); + } + + this.parseUserAttributes(); + + this._pFinalizeAsset(< IAsset> light, name); + + this._blocks[blockID].data = light; + + if (this._debug) + console.log("Parsed a Light: Name = '" + name + "' | Type = " + lightTypes[lightType] + " | Parent-Name = " + parentName + " | ShadowMapper-Type = " + shadowMapperTypes[shadowMapperType]); + + } + + //Block ID = 43 + private parseCamera(blockID:number):void + { + + var par_id:number = this._newBlockBytes.readUnsignedInt(); + var mtx:Matrix3D = this.parseMatrix3D(); + var name:string = this.parseVarStr(); + var parentName:string = "Root (TopLevel)"; + var projection:ProjectionBase; + + this._newBlockBytes.readUnsignedByte(); //set as active camera + this._newBlockBytes.readShort(); //lengthof lenses - not used yet + + var projectiontype:number = this._newBlockBytes.readShort(); + var props:AWDProperties = this.parseProperties({101:this._propsNrType, 102:this._propsNrType, 103:this._propsNrType, 104:this._propsNrType}); + + switch (projectiontype) { + case 5001: + projection = new PerspectiveProjection(props.get(101, 60)); + break; + case 5002: + projection = new OrthographicProjection(props.get(101, 500)); + break; + case 5003: + projection = new OrthographicOffCenterProjection(props.get(101, -400), props.get(102, 400), props.get(103, -300), props.get(104, 300)); + break; + default: + console.log("unsupportedLenstype"); + return; + } + + var camera:Camera = new Camera(projection); + camera.transform.matrix3D = mtx; + + var returnedArrayParent:Array = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]) + + if (returnedArrayParent[0]) { + + var objC:DisplayObjectContainer = returnedArrayParent[1]; + objC.addChild(camera); + + parentName = objC.name; + + } else if (par_id > 0) { + this._blocks[blockID].addError("Could not find a parent for this Camera"); + } else { + //add to the content property + ( this._pContent).addChild(camera); + } + + camera.name = name; + props = this.parseProperties({1:this._matrixNrType, 2:this._matrixNrType, 3:this._matrixNrType, 4:AWDParser.UINT8}); + camera.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + camera.extra = this.parseUserAttributes(); + + this._pFinalizeAsset(camera, name); + + this._blocks[blockID].data = camera + + if (this._debug) { + console.log("Parsed a Camera: Name = '" + name + "' | Projectiontype = " + projection + " | Parent-Name = " + parentName); + } + + } + + //Block ID = 51 + private parseLightPicker(blockID:number):void + { + var name:string = this.parseVarStr(); + var numLights:number = this._newBlockBytes.readUnsignedShort(); + var lightsArray:Array = new Array(); + var k:number = 0; + var lightID:number = 0; + + var returnedArrayLight:Array; + var lightsArrayNames:Array = new Array(); + + for (k = 0; k < numLights; k++) { + lightID = this._newBlockBytes.readUnsignedInt(); + returnedArrayLight = this.getAssetByID(lightID, [AssetType.LIGHT]) + + if (returnedArrayLight[0]) { + lightsArray.push( returnedArrayLight[1]); + lightsArrayNames.push(( returnedArrayLight[1]).name); + + } else { + this._blocks[blockID].addError("Could not find a Light Nr " + k + " (ID = " + lightID + " ) for this LightPicker"); + } + } + + if (lightsArray.length == 0) { + this._blocks[blockID].addError("Could not create this LightPicker, cause no Light was found."); + this.parseUserAttributes(); + return; //return without any more parsing for this block + } + + var lightPick:LightPickerBase = new StaticLightPicker(lightsArray); + lightPick.name = name; + + this.parseUserAttributes(); + this._pFinalizeAsset( lightPick, name); + + this._blocks[blockID].data = lightPick + if (this._debug) { + console.log("Parsed a StaticLightPicker: Name = '" + name + "' | Texture-Name = " + lightsArrayNames.toString()); + } + } + + //Block ID = 81 + private parseMaterial(blockID:number):void + { + // TODO: not used + ////blockLength = block.len; + var name:string; + var type:number; + var props:AWDProperties; + var mat:TriangleMethodMaterial; + var attributes:Object; + var finalize:boolean; + var num_methods:number; + var methods_parsed:number; + var returnedArray:Array; + + name = this.parseVarStr(); + type = this._newBlockBytes.readUnsignedByte(); + num_methods = this._newBlockBytes.readUnsignedByte(); + + // Read material numerical properties + // (1=color, 2=bitmap url, 10=alpha, 11=alpha_blending, 12=alpha_threshold, 13=repeat) + props = this.parseProperties({ 1:AWDParser.INT32, 2:AWDParser.BADDR, 10:this._propsNrType, 11:AWDParser.BOOL, 12:this._propsNrType, 13:AWDParser.BOOL}); + + methods_parsed = 0; + while (methods_parsed < num_methods) { + var method_type:number; + + method_type = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); + this.parseUserAttributes(); + methods_parsed += 1; + } + var debugString:string = ""; + attributes = this.parseUserAttributes(); + if (type === 1) { // Color material + debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | "; + var color:number; + color = props.get(1, 0xffffff); + if (this.materialMode < 2) { + mat = new TriangleMethodMaterial(color, props.get(10, 1.0)); + } else { + mat = new TriangleMethodMaterial(color); + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + } + } else if (type === 2) { + var tex_addr:number = props.get(2, 0); + + returnedArray = this.getAssetByID(tex_addr, [AssetType.TEXTURE]); + + if ((!returnedArray[0]) && (tex_addr > 0)) + this._blocks[blockID].addError("Could not find the DiffsueTexture (ID = " + tex_addr + " ) for this Material"); + + mat = new TriangleMethodMaterial( returnedArray[1]); + + if (this.materialMode < 2) { + mat.alphaBlending = props.get(11, false); + mat.alpha = props.get(10, 1.0); + debugString += "Parsed a TriangleMethodMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + mat.name; + } else { + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + debugString += "Parsed a TriangleMethodMaterial(MultiPass): Name = '" + name + "' | Texture-Name = " + mat.name; + } + } + + mat.extra = attributes; + mat.alphaThreshold = props.get(12, 0.0); + mat.repeat = props.get(13, false); + this._pFinalizeAsset( mat, name); + this._blocks[blockID].data = mat; + + if (this._debug) { + console.log(debugString); + + } + } + + // Block ID = 81 AWD2.1 + private parseMaterial_v1(blockID:number):void + { + var mat:TriangleMethodMaterial; + var normalTexture:Texture2DBase; + var specTexture:Texture2DBase; + var returnedArray:Array; + + var name:string = this.parseVarStr(); + var type:number = this._newBlockBytes.readUnsignedByte(); + var num_methods:number = this._newBlockBytes.readUnsignedByte(); + var props:AWDProperties = this.parseProperties({1:AWDParser.UINT32, 2:AWDParser.BADDR, 3:AWDParser.BADDR, 4:AWDParser.UINT8, 5:AWDParser.BOOL, 6:AWDParser.BOOL, 7:AWDParser.BOOL, 8:AWDParser.BOOL, 9:AWDParser.UINT8, 10:this._propsNrType, 11:AWDParser.BOOL, 12:this._propsNrType, 13:AWDParser.BOOL, 15:this._propsNrType, 16:AWDParser.UINT32, 17:AWDParser.BADDR, 18:this._propsNrType, 19:this._propsNrType, 20:AWDParser.UINT32, 21:AWDParser.BADDR, 22:AWDParser.BADDR}); + var spezialType:number = props.get(4, 0); + var debugString:string = ""; + + if (spezialType >= 2) {//this is no supported material + this._blocks[blockID].addError("Material-spezialType '" + spezialType + "' is not supported, can only be 0:singlePass, 1:MultiPass !"); + return; + } + + if (this.materialMode == 1) + spezialType = 0; + else if (this.materialMode == 2) + spezialType = 1; + + if (spezialType < 2) {//this is SinglePass or MultiPass + + if (type == 1) {// Color material + var color:number = props.get(1, 0xcccccc);//TODO temporarily swapped so that diffuse color goes to ambient + + if (spezialType == 1) {// MultiPassMaterial + mat = new TriangleMethodMaterial(color); + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + debugString += "Parsed a ColorMaterial(MultiPass): Name = '" + name + "' | "; + + } else { // SinglePassMaterial + mat = new TriangleMethodMaterial(color, props.get(10, 1.0)); + mat.alphaBlending = props.get(11, false); + debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | "; + } + + } else if (type == 2) {// texture material + var tex_addr:number = props.get(2, 0);//TODO temporarily swapped so that diffuse texture goes to ambient + returnedArray = this.getAssetByID(tex_addr, [AssetType.TEXTURE]); + + if ((!returnedArray[0]) && (tex_addr > 0)) + this._blocks[blockID].addError("Could not find the AmbientTexture (ID = " + tex_addr + " ) for this TriangleMethodMaterial"); + + var texture:Texture2DBase = returnedArray[1]; + + mat = new TriangleMethodMaterial(texture); + + if (spezialType == 1) {// MultiPassMaterial + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + + debugString += "Parsed a TriangleMethodMaterial(MultiPass): Name = '" + name + "' | Texture-Name = " + texture.name; + } else {// SinglePassMaterial + mat.alpha = props.get(10, 1.0); + mat.alphaBlending = props.get(11, false); + + debugString += "Parsed a TriangleMethodMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + texture.name; + } + } + + var diffuseTexture:Texture2DBase; + var diffuseTex_addr:number = props.get(17, 0); + + returnedArray = this.getAssetByID(diffuseTex_addr, [AssetType.TEXTURE]); + + if ((!returnedArray[0]) && (diffuseTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the DiffuseTexture (ID = " + diffuseTex_addr + " ) for this TriangleMethodMaterial"); + } + + if (returnedArray[0]) + diffuseTexture = returnedArray[1]; + + if (diffuseTexture) { + mat.diffuseTexture = diffuseTexture; + debugString += " | DiffuseTexture-Name = " + diffuseTexture.name; + } + + var normalTex_addr:number = props.get(3, 0); + + returnedArray = this.getAssetByID(normalTex_addr, [AssetType.TEXTURE]); + + if ((!returnedArray[0]) && (normalTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the NormalTexture (ID = " + normalTex_addr + " ) for this TriangleMethodMaterial"); + } + + if (returnedArray[0]) { + normalTexture = returnedArray[1]; + debugString += " | NormalTexture-Name = " + normalTexture.name; + } + + var specTex_addr:number = props.get(21, 0); + returnedArray = this.getAssetByID(specTex_addr, [AssetType.TEXTURE]); + + if ((!returnedArray[0]) && (specTex_addr != 0)) { + this._blocks[blockID].addError("Could not find the SpecularTexture (ID = " + specTex_addr + " ) for this TriangleMethodMaterial"); + } + if (returnedArray[0]) { + specTexture = returnedArray[1]; + debugString += " | SpecularTexture-Name = " + specTexture.name; + } + + var lightPickerAddr:number = props.get(22, 0); + returnedArray = this.getAssetByID(lightPickerAddr, [AssetType.LIGHT_PICKER]) + + if ((!returnedArray[0]) && (lightPickerAddr)) { + this._blocks[blockID].addError("Could not find the LightPicker (ID = " + lightPickerAddr + " ) for this TriangleMethodMaterial"); + } else { + mat.lightPicker = returnedArray[1]; + //debugString+=" | Lightpicker-Name = "+LightPickerBase(returnedArray[1]).name; + } + + mat.smooth = props.get(5, true); + mat.mipmap = props.get(6, true); + mat.bothSides = props.get(7, false); + mat.alphaPremultiplied = props.get(8, false); + mat.blendMode = this.blendModeDic[props.get(9, 0)]; + mat.repeat = props.get(13, false); + + if (normalTexture) + mat.normalMap = normalTexture; + + if (specTexture) + mat.specularMap = specTexture; + + mat.alphaThreshold = props.get(12, 0.0); + mat.ambient = props.get(15, 1.0); + mat.diffuseColor = props.get(16, 0xffffff); + mat.specular = props.get(18, 1.0); + mat.gloss = props.get(19, 50); + mat.specularColor = props.get(20, 0xffffff); + + var methods_parsed:number = 0; + var targetID:number; + + while (methods_parsed < num_methods) { + var method_type:number; + method_type = this._newBlockBytes.readUnsignedShort(); + + props = this.parseProperties({1:AWDParser.BADDR, 2:AWDParser.BADDR, 3:AWDParser.BADDR, 101:this._propsNrType, 102:this._propsNrType, 103:this._propsNrType, 201:AWDParser.UINT32, 202:AWDParser.UINT32, 301:AWDParser.UINT16, 302:AWDParser.UINT16, 401:AWDParser.UINT8, 402:AWDParser.UINT8, 601:AWDParser.COLOR, 602:AWDParser.COLOR, 701:AWDParser.BOOL, 702:AWDParser.BOOL, 801:AWDParser.MTX4x4}); + + switch (method_type) { + case 999: //wrapper-Methods that will load a previous parsed EffektMethod returned + + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.EFFECTS_METHOD]); + + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the EffectMethod (ID = " + targetID + " ) for this Material"); + } else { + mat.addEffectMethod(returnedArray[1]); + + debugString += " | EffectMethod-Name = " + ( returnedArray[1]).name; + } + + break; + + case 998: //wrapper-Methods that will load a previous parsed ShadowMapMethod + + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]); + + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the ShadowMethod (ID = " + targetID + " ) for this Material"); + } else { + mat.shadowMethod = returnedArray[1]; + debugString += " | ShadowMethod-Name = " + ( returnedArray[1]).name; + } + + break; + + case 1: //EnvMapAmbientMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this EnvMapAmbientMethodMaterial"); + mat.ambientMethod = new AmbientEnvMapMethod(returnedArray[1]); + debugString += " | AmbientEnvMapMethod | EnvMap-Name =" + ( returnedArray[1]).name; + break; + + case 51: //DepthDiffuseMethod + mat.diffuseMethod = new DiffuseDepthMethod(); + debugString += " | DiffuseDepthMethod"; + break; + case 52: //GradientDiffuseMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the GradientDiffuseTexture (ID = " + targetID + " ) for this GradientDiffuseMethod"); + mat.diffuseMethod = new DiffuseGradientMethod(returnedArray[1]); + debugString += " | DiffuseGradientMethod | GradientDiffuseTexture-Name =" + ( returnedArray[1]).name; + break; + case 53: //WrapDiffuseMethod + mat.diffuseMethod = new DiffuseWrapMethod(props.get(101, 5)); + debugString += " | DiffuseWrapMethod"; + break; + case 54: //LightMapDiffuseMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the LightMap (ID = " + targetID + " ) for this LightMapDiffuseMethod"); + mat.diffuseMethod = new DiffuseLightMapMethod(returnedArray[1], this.blendModeDic[props.get(401, 10)], false, mat.diffuseMethod); + debugString += " | DiffuseLightMapMethod | LightMapTexture-Name =" + ( returnedArray[1]).name; + break; + case 55: //CelDiffuseMethod + mat.diffuseMethod = new DiffuseCelMethod(props.get(401, 3), mat.diffuseMethod); + ( mat.diffuseMethod).smoothness = props.get(101, 0.1); + debugString += " | DiffuseCelMethod"; + break; + case 56: //SubSurfaceScatteringMethod +// mat.diffuseMethod = new DiffuseSubSurfaceMethod(); //depthMapSize and depthMapOffset ? +// ( mat.diffuseMethod).scattering = props.get(101, 0.2); +// ( mat.diffuseMethod).translucency = props.get(102, 1); +// ( mat.diffuseMethod).scatterColor = props.get(601, 0xffffff); +// debugString += " | DiffuseSubSurfaceMethod"; + break; + + case 101: //AnisotropicSpecularMethod + mat.specularMethod = new SpecularAnisotropicMethod(); + debugString += " | SpecularAnisotropicMethod"; + break; + case 102: //SpecularPhongMethod + mat.specularMethod = new SpecularPhongMethod(); + debugString += " | SpecularPhongMethod"; + break; + case 103: //CellSpecularMethod + mat.specularMethod = new SpecularCelMethod(props.get(101, 0.5), mat.specularMethod); + ( mat.specularMethod).smoothness = props.get(102, 0.1); + debugString += " | SpecularCelMethod"; + break; + case 104: //SpecularFresnelMethod + mat.specularMethod = new SpecularFresnelMethod(props.get(701, true), mat.specularMethod); + ( mat.specularMethod).fresnelPower = props.get(101, 5); + ( mat.specularMethod).normalReflectance = props.get(102, 0.1); + debugString += " | SpecularFresnelMethod"; + break; + case 151://HeightMapNormalMethod - thios is not implemented for now, but might appear later + break; + case 152: //SimpleWaterNormalMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the SecoundNormalMap (ID = " + targetID + " ) for this SimpleWaterNormalMethod"); + if (!mat.normalMap) + this._blocks[blockID].addError("Could not find a normal Map on this Material to use with this SimpleWaterNormalMethod"); + + mat.normalMap = returnedArray[1]; + mat.normalMethod = new NormalSimpleWaterMethod(mat.normalMap, returnedArray[1]); + debugString += " | NormalSimpleWaterMethod | Second-NormalTexture-Name = " + ( returnedArray[1]).name; + break; + } + this.parseUserAttributes(); + methods_parsed += 1; + } + } + mat.extra = this.parseUserAttributes(); + this._pFinalizeAsset( mat, name); + + this._blocks[blockID].data = mat; + if (this._debug) { + console.log(debugString); + } + } + + //Block ID = 82 + private parseTexture(blockID:number):void + { + + var asset:Texture2DBase; + + this._blocks[blockID].name = this.parseVarStr(); + + var type:number = this._newBlockBytes.readUnsignedByte(); + var data_len:number; + + this._texture_users[this._cur_block_id.toString()] = []; + + // External + if (type == 0) { + data_len = this._newBlockBytes.readUnsignedInt(); + var url:string; + url = this._newBlockBytes.readUTFBytes(data_len); + this._pAddDependency(this._cur_block_id.toString(), new URLRequest(url), false, null, true); + + } else { + data_len = this._newBlockBytes.readUnsignedInt(); + + var data:ByteArray; + data = new ByteArray(); + this._newBlockBytes.readBytes(data, 0, data_len); + + // + // AWDParser - Fix for FireFox Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=715075 . + // + // Converting data to image here instead of parser - fix FireFox bug where image width / height is 0 when created from data + // This gives the browser time to initialise image width / height. + + this._pAddDependency(this._cur_block_id.toString(), null, false, ParserUtils.byteArrayToImage(data), true); + //this._pAddDependency(this._cur_block_id.toString(), null, false, data, true); + + } + + // Ignore for now + this.parseProperties(null); + this._blocks[blockID].extras = this.parseUserAttributes(); + this._pPauseAndRetrieveDependencies(); + this._blocks[blockID].data = asset; + + if (this._debug) { + var textureStylesNames:Array = ["external", "embed"] + console.log("Start parsing a " + textureStylesNames[type] + " Bitmap for Texture"); + } + + } + + //Block ID = 83 + private parseCubeTexture(blockID:number):void + { + //blockLength = block.len; + var data_len:number; + var asset:CubeTextureBase; + var i:number; + + this._cubeTextures = new Array(); + this._texture_users[ this._cur_block_id.toString() ] = []; + + var type:number = this._newBlockBytes.readUnsignedByte(); + + this._blocks[blockID].name = this.parseVarStr(); + + for (i = 0; i < 6; i++) { + this._texture_users[this._cur_block_id.toString()] = []; + this._cubeTextures.push(null); + + // External + if (type == 0) { + data_len = this._newBlockBytes.readUnsignedInt(); + var url:string; + url = this._newBlockBytes.readUTFBytes(data_len); + + this._pAddDependency(this._cur_block_id.toString() + "#" + i, new URLRequest(url), false, null, true); + } else { + + data_len = this._newBlockBytes.readUnsignedInt(); + var data:ByteArray; + data = new ByteArray(); + + this._newBlockBytes.readBytes(data, 0, data_len); + + this._pAddDependency(this._cur_block_id.toString() + "#" + i, null, false, ParserUtils.byteArrayToImage(data), true); + } + } + + // Ignore for now + this.parseProperties(null); + this._blocks[blockID].extras = this.parseUserAttributes(); + this._pPauseAndRetrieveDependencies(); + this._blocks[blockID].data = asset; + + if (this._debug) { + var textureStylesNames:Array = ["external", "embed"] + console.log("Start parsing 6 " + textureStylesNames[type] + " Bitmaps for CubeTexture"); + } + } + + //Block ID = 91 + private parseSharedMethodBlock(blockID:number):void + { + var asset:EffectMethodBase; + + this._blocks[blockID].name = this.parseVarStr(); + asset = this.parseSharedMethodList(blockID); + this.parseUserAttributes(); + this._blocks[blockID].data = asset; + this._pFinalizeAsset( asset, this._blocks[blockID].name); + this._blocks[blockID].data = asset; + + if (this._debug) { + console.log("Parsed a EffectMethod: Name = " + asset.name + " Type = " + asset); + } + } + + //Block ID = 92 + private parseShadowMethodBlock(blockID:number):void + { + var type:number; + var data_len:number; + var asset:ShadowMethodBase; + var shadowLightID:number; + this._blocks[blockID].name = this.parseVarStr(); + + shadowLightID = this._newBlockBytes.readUnsignedInt(); + var returnedArray:Array = this.getAssetByID(shadowLightID, [AssetType.LIGHT]); + + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the TargetLight (ID = " + shadowLightID + " ) for this ShadowMethod - ShadowMethod not created"); + return; + } + + asset = this.parseShadowMethodList( returnedArray[1], blockID); + + if (!asset) + return; + + this.parseUserAttributes(); // Ignore for now + this._pFinalizeAsset( asset, this._blocks[blockID].name); + this._blocks[blockID].data = asset; + + if (this._debug) { + console.log("Parsed a ShadowMapMethodMethod: Name = " + asset.name + " | Type = " + asset + " | Light-Name = ", ( returnedArray[1] ).name); + } + } + + + //Block ID = 253 + private parseCommand(blockID:number):void + { + var hasBlocks:boolean = ( this._newBlockBytes.readUnsignedByte() == 1 ); + var par_id:number = this._newBlockBytes.readUnsignedInt(); + var mtx:Matrix3D = this.parseMatrix3D(); + var name:string = this.parseVarStr(); + + var parentObject:DisplayObjectContainer; + var targetObject:DisplayObjectContainer; + + var returnedArray:Array = this.getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH]); + + if (returnedArray[0]) { + parentObject = returnedArray[1]; + } + + var numCommands:number = this._newBlockBytes.readShort(); + var typeCommand:number = this._newBlockBytes.readShort(); + + var props:AWDProperties = this.parseProperties({1:AWDParser.BADDR}); + + switch (typeCommand) { + case 1: + + var targetID:number = props.get(1, 0); + var returnedArrayTarget:Array = this.getAssetByID(targetID, [AssetType.LIGHT, AssetType.TEXTURE_PROJECTOR]); //for no only light is requested!!!! + + if ((!returnedArrayTarget[0]) && (targetID != 0)) { + this._blocks[blockID].addError("Could not find the light (ID = " + targetID + " ( for this CommandBock!"); + return; + } + + targetObject = returnedArrayTarget[1]; + + if (parentObject) { + parentObject.addChild(targetObject); + } + + targetObject.transform.matrix3D = mtx; + + break; + } + + if (targetObject) { + props = this.parseProperties({1:this._matrixNrType, 2:this._matrixNrType, 3:this._matrixNrType, 4:AWDParser.UINT8}); + + targetObject.pivot = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0)); + targetObject.extra = this.parseUserAttributes(); + + } + this._blocks[blockID].data = targetObject + + if (this._debug) { + console.log("Parsed a CommandBlock: Name = '" + name); + } + + } + + //blockID 255 + private parseMetaData(blockID:number):void + { + var props:AWDProperties = this.parseProperties({1:AWDParser.UINT32, 2:AWDParser.AWDSTRING, 3:AWDParser.AWDSTRING, 4:AWDParser.AWDSTRING, 5:AWDParser.AWDSTRING}); + + if (this._debug) { + console.log("Parsed a MetaDataBlock: TimeStamp = " + props.get(1, 0)); + console.log(" EncoderName = " + props.get(2, "unknown")); + console.log(" EncoderVersion = " + props.get(3, "unknown")); + console.log(" GeneratorName = " + props.get(4, "unknown")); + console.log(" GeneratorVersion = " + props.get(5, "unknown")); + } + } + + //blockID 254 + private parseNameSpace(blockID:number):void + { + var id:number = this._newBlockBytes.readUnsignedByte(); + var nameSpaceString:string = this.parseVarStr(); + if (this._debug) + console.log("Parsed a NameSpaceBlock: ID = " + id + " | String = " + nameSpaceString); + } + + //--Parser UTILS--------------------------------------------------------------------------- + + // this functions reads and creates a ShadowMethodMethod + private parseShadowMethodList(light:LightBase, blockID:number):ShadowMethodBase + { + + var methodType:number = this._newBlockBytes.readUnsignedShort(); + var shadowMethod:ShadowMethodBase; + var props:AWDProperties = this.parseProperties({1:AWDParser.BADDR, 2:AWDParser.BADDR, 3:AWDParser.BADDR, 101:this._propsNrType, 102:this._propsNrType, 103:this._propsNrType, 201:AWDParser.UINT32, 202:AWDParser.UINT32, 301:AWDParser.UINT16, 302:AWDParser.UINT16, 401:AWDParser.UINT8, 402:AWDParser.UINT8, 601:AWDParser.COLOR, 602:AWDParser.COLOR, 701:AWDParser.BOOL, 702:AWDParser.BOOL, 801:AWDParser.MTX4x4}); + + var targetID:number; + var returnedArray:Array + switch (methodType) { + // case 1001: //CascadeShadowMapMethod + // targetID = props.get(1, 0); + // returnedArray = getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]); + // if (!returnedArray[0]) { + // _blocks[blockID].addError("Could not find the ShadowBaseMethod (ID = " + targetID + " ) for this CascadeShadowMapMethod - ShadowMethod not created"); + // return shadowMethod; + // } + // shadowMethod = new CascadeShadowMapMethod(returnedArray[1]); + // break; + case 1002: //ShadowNearMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the ShadowBaseMethod (ID = " + targetID + " ) for this ShadowNearMethod - ShadowMethod not created"); + return shadowMethod; + } + shadowMethod = new ShadowNearMethod( returnedArray[1]); + break; + case 1101: //ShadowFilteredMethod + + shadowMethod = new ShadowFilteredMethod( light); + ( shadowMethod).alpha = props.get(101, 1); + ( shadowMethod).epsilon = props.get(102, 0.002); + break; + + case 1102: //ShadowDitheredMethod + + + shadowMethod = new ShadowDitheredMethod( light, props.get(201, 5)); + ( shadowMethod).alpha = props.get(101, 1); + ( shadowMethod).epsilon = props.get(102, 0.002); + ( shadowMethod).range = props.get(103, 1); + + break; + case 1103: //ShadowSoftMethod + + shadowMethod = new ShadowSoftMethod( light, props.get(201, 5)); + ( shadowMethod).alpha = props.get(101, 1); + ( shadowMethod).epsilon = props.get(102, 0.002); + ( shadowMethod).range = props.get(103, 1); + + break; + case 1104: //ShadowHardMethod + shadowMethod = new ShadowHardMethod(light); + ( shadowMethod).alpha = props.get(101, 1); + ( shadowMethod).epsilon = props.get(102, 0.002); + break; + + } + this.parseUserAttributes(); + return shadowMethod; + } + + //Block ID 101 + private parseSkeleton(blockID:number /*uint*/):void + { + var name:string = this.parseVarStr(); + var num_joints:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + var skeleton:Skeleton = new Skeleton(); + this.parseProperties(null); // Discard properties for now + + var joints_parsed:number /*uint*/ = 0; + while (joints_parsed < num_joints) { + var joint:SkeletonJoint; + var ibp:Matrix3D; + // Ignore joint id + this._newBlockBytes.readUnsignedShort(); + joint = new SkeletonJoint(); + joint.parentIndex = this._newBlockBytes.readUnsignedShort() - 1; // 0=null in AWD + joint.name = this.parseVarStr(); + + ibp = this.parseMatrix3D(); + joint.inverseBindPose = ibp.rawData; + // Ignore joint props/attributes for now + this.parseProperties(null); + this.parseUserAttributes(); + skeleton.joints.push(joint); + joints_parsed++; + } + + // Discard attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(skeleton, name); + this._blocks[blockID].data = skeleton; + if (this._debug) + console.log("Parsed a Skeleton: Name = " + skeleton.name + " | Number of Joints = " + joints_parsed); + } + + //Block ID = 102 + private parseSkeletonPose(blockID:number /*uint*/):void + { + var name:string = this.parseVarStr(); + var num_joints:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); // Ignore properties for now + + var pose:SkeletonPose = new SkeletonPose(); + + var joints_parsed:number /*uint*/ = 0; + while (joints_parsed < num_joints) { + var joint_pose:JointPose; + var has_transform:number /*uint*/; + joint_pose = new JointPose(); + has_transform = this._newBlockBytes.readUnsignedByte(); + if (has_transform == 1) { + var mtx_data:Array = this.parseMatrix43RawData(); + + var mtx:Matrix3D = new Matrix3D(mtx_data); + joint_pose.orientation.fromMatrix(mtx); + joint_pose.translation.copyFrom(mtx.position); + + pose.jointPoses[joints_parsed] = joint_pose; + } + joints_parsed++; + } + // Skip attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(pose, name); + this._blocks[blockID].data = pose; + if (this._debug) + console.log("Parsed a SkeletonPose: Name = " + pose.name + " | Number of Joints = " + joints_parsed); + } + + //blockID 103 + private parseSkeletonAnimation(blockID:number /*uint*/):void + { + var frame_dur:number; + var pose_addr:number /*uint*/; + var name:string = this.parseVarStr(); + var clip:SkeletonClipNode = new SkeletonClipNode(); + var num_frames:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + this.parseProperties(null); // Ignore properties for now + + var frames_parsed:number /*uint*/ = 0; + var returnedArray:Array; + while (frames_parsed < num_frames) { + pose_addr = this._newBlockBytes.readUnsignedInt(); + frame_dur = this._newBlockBytes.readUnsignedShort(); + returnedArray = this.getAssetByID(pose_addr, [AssetType.SKELETON_POSE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the SkeletonPose Frame # " + frames_parsed + " (ID = " + pose_addr + " ) for this SkeletonClipNode"); + else + clip.addFrame( this._blocks[pose_addr].data, frame_dur); + frames_parsed++; + } + if (clip.frames.length == 0) { + this._blocks[blockID].addError("Could not this SkeletonClipNode, because no Frames where set."); + return; + } + // Ignore attributes for now + this.parseUserAttributes(); + this._pFinalizeAsset(clip, name); + this._blocks[blockID].data = clip; + if (this._debug) + console.log("Parsed a SkeletonClipNode: Name = " + clip.name + " | Number of Frames = " + clip.frames.length); + } + + //Block ID = 111 / Block ID = 112 + private parseMeshPoseAnimation(blockID:number /*uint*/, poseOnly:boolean = false):void + { + var num_frames:number /*uint*/ = 1; + var num_submeshes:number /*uint*/; + var frames_parsed:number /*uint*/; + var subMeshParsed:number /*uint*/; + var frame_dur:number; + var x:number; + var y:number; + var z:number; + var str_len:number; + var str_end:number; + var geometry:Geometry; + var subGeom:TriangleSubGeometry; + var idx:number /*int*/ = 0; + var clip:VertexClipNode = new VertexClipNode(); + var indices:Array /*uint*/; + var verts:Array; + var num_Streams:number /*int*/ = 0; + var streamsParsed:number /*int*/ = 0; + var streamtypes:Array /*int*/ = new Array() /*int*/; + var props:AWDProperties; + var thisGeo:Geometry; + var name:string = this.parseVarStr(); + var geoAdress:number /*int*/ = this._newBlockBytes.readUnsignedInt(); + var returnedArray:Array = this.getAssetByID(geoAdress, [AssetType.GEOMETRY]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the target-Geometry-Object " + geoAdress + " ) for this VertexClipNode"); + return; + } + var uvs:Array> = this.getUVForVertexAnimation(geoAdress); + if (!poseOnly) + num_frames = this._newBlockBytes.readUnsignedShort(); + + num_submeshes = this._newBlockBytes.readUnsignedShort(); + num_Streams = this._newBlockBytes.readUnsignedShort(); + streamsParsed = 0; + while (streamsParsed < num_Streams) { + streamtypes.push(this._newBlockBytes.readUnsignedShort()); + streamsParsed++; + } + props = this.parseProperties({1:AWDParser.BOOL, 2:AWDParser.BOOL}); + + clip.looping = props.get(1, true); + clip.stitchFinalFrame = props.get(2, false); + + frames_parsed = 0; + while (frames_parsed < num_frames) { + frame_dur = this._newBlockBytes.readUnsignedShort(); + geometry = new Geometry(); + subMeshParsed = 0; + while (subMeshParsed < num_submeshes) { + streamsParsed = 0; + str_len = this._newBlockBytes.readUnsignedInt(); + str_end = this._newBlockBytes.position + str_len; + while (streamsParsed < num_Streams) { + if (streamtypes[streamsParsed] == 1) { + indices = ( returnedArray[1]).subGeometries[subMeshParsed].indices; + verts = new Array(); + idx = 0; + while (this._newBlockBytes.position < str_end) { + x = this.readNumber(this._accuracyGeo) + y = this.readNumber(this._accuracyGeo) + z = this.readNumber(this._accuracyGeo) + verts[idx++] = x; + verts[idx++] = y; + verts[idx++] = z; + } + subGeom = new TriangleSubGeometry(true); + subGeom.updateIndices(indices); + subGeom.updatePositions(verts); + subGeom.updateUVs(uvs[subMeshParsed]); + subGeom.updateVertexNormals(null); + subGeom.updateVertexTangents(null); + subGeom.autoDeriveNormals = false; + subGeom.autoDeriveTangents = false; + subMeshParsed++; + geometry.addSubGeometry(subGeom) + } else + this._newBlockBytes.position = str_end; + streamsParsed++; + } + } + clip.addFrame(geometry, frame_dur); + frames_parsed++; + } + this.parseUserAttributes(); + this._pFinalizeAsset(clip, name); + + this._blocks[blockID].data = clip; + if (this._debug) + console.log("Parsed a VertexClipNode: Name = " + clip.name + " | Target-Geometry-Name = " + ( returnedArray[1]).name + " | Number of Frames = " + clip.frames.length); + } + + //BlockID 113 + private parseVertexAnimationSet(blockID:number /*uint*/):void + { + var poseBlockAdress:number /*int*/ + var outputString:string = ""; + var name:string = this.parseVarStr(); + var num_frames:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + var props:AWDProperties = this.parseProperties({1:AWDParser.UINT16}); + var frames_parsed:number /*uint*/ = 0; + var skeletonFrames:Array = new Array(); + var vertexFrames:Array = new Array(); + while (frames_parsed < num_frames) { + poseBlockAdress = this._newBlockBytes.readUnsignedInt(); + var returnedArray:Array = this.getAssetByID(poseBlockAdress, [AssetType.ANIMATION_NODE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the AnimationClipNode Nr " + frames_parsed + " ( " + poseBlockAdress + " ) for this AnimationSet"); + else { + if (returnedArray[1] instanceof VertexClipNode) + vertexFrames.push(returnedArray[1]) + if (returnedArray[1] instanceof SkeletonClipNode) + skeletonFrames.push(returnedArray[1]) + } + frames_parsed++; + } + if ((vertexFrames.length == 0) && (skeletonFrames.length == 0)) { + this._blocks[blockID].addError("Could not create this AnimationSet, because it contains no animations"); + return; + } + this.parseUserAttributes(); + if (vertexFrames.length > 0) { + var newVertexAnimationSet:VertexAnimationSet = new VertexAnimationSet(); + for (var i:number /*int*/ = 0; i < vertexFrames.length; i++) + newVertexAnimationSet.addAnimation(vertexFrames[i]); + this._pFinalizeAsset(newVertexAnimationSet, name); + this._blocks[blockID].data = newVertexAnimationSet; + if (this._debug) + console.log("Parsed a VertexAnimationSet: Name = " + name + " | Animations = " + newVertexAnimationSet.animations.length + " | Animation-Names = " + newVertexAnimationSet.animationNames.toString()); + + } else if (skeletonFrames.length > 0) { + returnedArray = this.getAssetByID(poseBlockAdress, [AssetType.ANIMATION_NODE]); + var newSkeletonAnimationSet:SkeletonAnimationSet = new SkeletonAnimationSet(props.get(1, 4)); //props.get(1,4)); + for (var i:number /*int*/ = 0; i < skeletonFrames.length; i++) + newSkeletonAnimationSet.addAnimation(skeletonFrames[i]); + this._pFinalizeAsset(newSkeletonAnimationSet, name); + this._blocks[blockID].data = newSkeletonAnimationSet; + if (this._debug) + console.log("Parsed a SkeletonAnimationSet: Name = " + name + " | Animations = " + newSkeletonAnimationSet.animations.length + " | Animation-Names = " + newSkeletonAnimationSet.animationNames.toString()); + + } + } + + //BlockID 122 + private parseAnimatorSet(blockID:number /*uint*/):void + { + var targetMesh:Mesh; + var animSetBlockAdress:number /*int*/ + var targetAnimationSet:AnimationSetBase; + var outputString:string = ""; + var name:string = this.parseVarStr(); + var type:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + + var props:AWDProperties = this.parseProperties({1:AWDParser.BADDR}); + + animSetBlockAdress = this._newBlockBytes.readUnsignedInt(); + var targetMeshLength:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + var meshAdresses:Array /*uint*/ = new Array() /*uint*/; + for (var i:number /*int*/ = 0; i < targetMeshLength; i++) + meshAdresses.push(this._newBlockBytes.readUnsignedInt()); + + var activeState:number /*uint*/ = this._newBlockBytes.readUnsignedShort(); + var autoplay:boolean = ( this._newBlockBytes.readUnsignedByte() == 1 ); + this.parseUserAttributes(); + this.parseUserAttributes(); + + var returnedArray:Array; + var targetMeshes:Array = new Array(); + + for (i = 0; i < meshAdresses.length; i++) { + returnedArray = this.getAssetByID(meshAdresses[i], [AssetType.MESH]); + if (returnedArray[0]) + targetMeshes.push( returnedArray[1]); + } + returnedArray = this.getAssetByID(animSetBlockAdress, [AssetType.ANIMATION_SET]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the AnimationSet ( " + animSetBlockAdress + " ) for this Animator");; + return + } + targetAnimationSet = returnedArray[1]; + var thisAnimator:AnimatorBase; + if (type == 1) { + + returnedArray = this.getAssetByID(props.get(1, 0), [AssetType.SKELETON]); + if (!returnedArray[0]) { + this._blocks[blockID].addError("Could not find the Skeleton ( " + props.get(1, 0) + " ) for this Animator"); + return + } + thisAnimator = new SkeletonAnimator( targetAnimationSet, returnedArray[1]); + + } else if (type == 2) + thisAnimator = new VertexAnimator( targetAnimationSet); + + this._pFinalizeAsset(thisAnimator, name); + this._blocks[blockID].data = thisAnimator; + for (i = 0; i < targetMeshes.length; i++) { + if (type == 1) + targetMeshes[i].animator = ( thisAnimator); + if (type == 2) + targetMeshes[i].animator = ( thisAnimator); + + } + if (this._debug) + console.log("Parsed a Animator: Name = " + name); + } + + // this functions reads and creates a EffectMethod + private parseSharedMethodList(blockID:number):EffectMethodBase + { + + var methodType:number = this._newBlockBytes.readUnsignedShort(); + var effectMethodReturn:EffectMethodBase; + + var props:AWDProperties = this.parseProperties({1:AWDParser.BADDR, 2:AWDParser.BADDR, 3:AWDParser.BADDR, 101:this._propsNrType, 102:this._propsNrType, 103:this._propsNrType, 104:this._propsNrType, 105:this._propsNrType, 106:this._propsNrType, 107:this._propsNrType, 201:AWDParser.UINT32, 202:AWDParser.UINT32, 301:AWDParser.UINT16, 302:AWDParser.UINT16, 401:AWDParser.UINT8, 402:AWDParser.UINT8, 601:AWDParser.COLOR, 602:AWDParser.COLOR, 701:AWDParser.BOOL, 702:AWDParser.BOOL}); + var targetID:number; + var returnedArray:Array; + + switch (methodType) { + // Effect Methods + case 401: //ColorMatrix + effectMethodReturn = new EffectColorMatrixMethod(props.get(101, new Array(0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))); + break; + case 402: //ColorTransform + effectMethodReturn = new EffectColorTransformMethod(); + var offCol:number /*uint*/ = props.get(601, 0x00000000); + ( effectMethodReturn).colorTransform = new ColorTransform(props.get(102, 1), props.get(103, 1), props.get(104, 1), props.get(101, 1), ((offCol >> 16) & 0xFF), ((offCol >> 8) & 0xFF), (offCol & 0xFF), ((offCol >> 24) & 0xFF)); + break; + case 403: //EnvMap + + targetID = props.get(1, 0); + console.log('ENV MAP', targetID); + + + returnedArray = this.getAssetByID(targetID, [ AssetType.TEXTURE ], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this EnvMapMethod"); + effectMethodReturn = new EffectEnvMapMethod( returnedArray[1], props.get(101, 1)); + targetID = props.get(2, 0); + if (targetID > 0) { + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the Mask-texture (ID = " + targetID + " ) for this EnvMapMethod"); + + // Todo: test mask with EnvMapMethod + //( effectMethodReturn).mask = returnedArray[1]; + } + break; + case 404: //LightMapMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the LightMap (ID = " + targetID + " ) for this LightMapMethod"); + effectMethodReturn = new EffectLightMapMethod(returnedArray[1], this.blendModeDic[props.get(401, 10)]); //usesecondaryUV not set + break; + // case 405: //ProjectiveTextureMethod + // targetID = props.get(1, 0); + // returnedArray = getAssetByID(targetID, [AssetType.TEXTURE_PROJECTOR]); + // if (!returnedArray[0]) + // _blocks[blockID].addError("Could not find the TextureProjector (ID = " + targetID + " ) for this ProjectiveTextureMethod"); + // effectMethodReturn = new ProjectiveTextureMethod(returnedArray[1], blendModeDic[props.get(401, 10)]); + // break; + case 406: //RimLightMethod + effectMethodReturn = new EffectRimLightMethod(props.get(601, 0xffffff), props.get(101, 0.4), props.get(101, 2)); //blendMode + break; + case 407: //AlphaMaskMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE]); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the Alpha-texture (ID = " + targetID + " ) for this AlphaMaskMethod"); + effectMethodReturn = new EffectAlphaMaskMethod(returnedArray[1], props.get(701, false)); + break; + // case 408: //RefractionEnvMapMethod + // targetID = props.get(1, 0); + // returnedArray = getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + // if (!returnedArray[0]) + // _blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this RefractionEnvMapMethod"); + // effectMethodReturn = new RefractionEnvMapMethod(returnedArray[1], props.get(101, 0.1), props.get(102, 0.01), props.get(103, 0.01), props.get(104, 0.01)); + // RefractionEnvMapMethod(effectMethodReturn).alpha = props.get(104, 1); + // break; + // case 409: //OutlineMethod + // effectMethodReturn = new OutlineMethod(props.get(601, 0x00000000), props.get(101, 1), props.get(701, true), props.get(702, false)); + // break; + case 410: //FresnelEnvMapMethod + targetID = props.get(1, 0); + returnedArray = this.getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture"); + if (!returnedArray[0]) + this._blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this FresnelEnvMapMethod"); + effectMethodReturn = new EffectFresnelEnvMapMethod(returnedArray[1], props.get(101, 1)); + break; + case 411: //FogMethod + effectMethodReturn = new EffectFogMethod(props.get(101, 0), props.get(102, 1000), props.get(601, 0x808080)); + break; + + } + this.parseUserAttributes(); + return effectMethodReturn; + + } + + private parseUserAttributes():Object + { + var attributes:Object; + var list_len:number; + var attibuteCnt:number; + + list_len = this._newBlockBytes.readUnsignedInt(); + + if (list_len > 0) { + + var list_end:number; + + attributes = {}; + + list_end = this._newBlockBytes.position + list_len; + + while (this._newBlockBytes.position < list_end) { + var ns_id:number; + var attr_key:string; + var attr_type:number; + var attr_len:number; + var attr_val:any; + + // TODO: Properly tend to namespaces in attributes + ns_id = this._newBlockBytes.readUnsignedByte(); + attr_key = this.parseVarStr(); + attr_type = this._newBlockBytes.readUnsignedByte(); + attr_len = this._newBlockBytes.readUnsignedInt(); + + if ((this._newBlockBytes.position + attr_len) > list_end) { + console.log(" Error in reading attribute # " + attibuteCnt + " = skipped to end of attribute-list"); + this._newBlockBytes.position = list_end; + return attributes; + } + + switch (attr_type) { + case AWDParser.AWDSTRING: + attr_val = this._newBlockBytes.readUTFBytes(attr_len); + break; + case AWDParser.INT8: + attr_val = this._newBlockBytes.readByte(); + break; + case AWDParser.INT16: + attr_val = this._newBlockBytes.readShort(); + break; + case AWDParser.INT32: + attr_val = this._newBlockBytes.readInt(); + break; + case AWDParser.BOOL: + case AWDParser.UINT8: + attr_val = this._newBlockBytes.readUnsignedByte(); + break; + case AWDParser.UINT16: + attr_val = this._newBlockBytes.readUnsignedShort(); + break; + case AWDParser.UINT32: + case AWDParser.BADDR: + attr_val = this._newBlockBytes.readUnsignedInt(); + break; + case AWDParser.FLOAT32: + attr_val = this._newBlockBytes.readFloat(); + break; + case AWDParser.FLOAT64: + attr_val = this._newBlockBytes.readDouble(); + break; + default: + attr_val = 'unimplemented attribute type ' + attr_type; + this._newBlockBytes.position += attr_len; + break; + } + + if (this._debug) { + console.log("attribute = name: " + attr_key + " / value = " + attr_val); + } + + attributes[attr_key] = attr_val; + attibuteCnt += 1; + } + } + + return attributes; + } + + private parseProperties(expected:Object):AWDProperties + { + var list_end:number; + var list_len:number; + var propertyCnt:number = 0; + var props:AWDProperties = new AWDProperties(); + + list_len = this._newBlockBytes.readUnsignedInt(); + list_end = this._newBlockBytes.position + list_len; + + if (expected) { + + while (this._newBlockBytes.position < list_end) { + var len:number; + var key:number; + var type:number; + + key = this._newBlockBytes.readUnsignedShort(); + len = this._newBlockBytes.readUnsignedInt(); + + if ((this._newBlockBytes.position + len) > list_end) { + console.log(" Error in reading property # " + propertyCnt + " = skipped to end of propertie-list"); + this._newBlockBytes.position = list_end; + return props; + } + + if (expected.hasOwnProperty(key.toString())) { + type = expected[key]; + props.set(key, this.parseAttrValue(type, len)); + } else { + this._newBlockBytes.position += len; + } + + propertyCnt += 1; + + } + } else { + this._newBlockBytes.position = list_end; + } + + return props; + + } + + private parseAttrValue(type:number, len:number):any + { + var elem_len:number; + var read_func:Function; + + switch (type) { + + case AWDParser.BOOL: + case AWDParser.INT8: + elem_len = 1; + read_func = this._newBlockBytes.readByte; + break; + + case AWDParser.INT16: + elem_len = 2; + read_func = this._newBlockBytes.readShort; + break; + + case AWDParser.INT32: + elem_len = 4; + read_func = this._newBlockBytes.readInt; + break; + + case AWDParser.UINT8: + elem_len = 1; + read_func = this._newBlockBytes.readUnsignedByte; + break; + + case AWDParser.UINT16: + elem_len = 2; + read_func = this._newBlockBytes.readUnsignedShort; + break; + + case AWDParser.UINT32: + case AWDParser.COLOR: + case AWDParser.BADDR: + elem_len = 4; + read_func = this._newBlockBytes.readUnsignedInt; + break; + + case AWDParser.FLOAT32: + elem_len = 4; + read_func = this._newBlockBytes.readFloat; + break; + + case AWDParser.FLOAT64: + elem_len = 8; + read_func = this._newBlockBytes.readDouble; + break; + + case AWDParser.AWDSTRING: + return this._newBlockBytes.readUTFBytes(len); + + case AWDParser.VECTOR2x1: + case AWDParser.VECTOR3x1: + case AWDParser.VECTOR4x1: + case AWDParser.MTX3x2: + case AWDParser.MTX3x3: + case AWDParser.MTX4x3: + case AWDParser.MTX4x4: + elem_len = 8; + read_func = this._newBlockBytes.readDouble; + break; + + } + + if (elem_len < len) { + var list:Array = []; + var num_read:number = 0; + var num_elems:number = len/elem_len; + + while (num_read < num_elems) { + list.push(read_func.apply(this._newBlockBytes)); // list.push(read_func()); + num_read++; + } + + return list; + } else { + + var val:any = read_func.apply(this._newBlockBytes);//read_func(); + return val; + } + } + + private parseHeader():void + { + var flags:number; + var body_len:number; + + this._byteData.position = 3; // Skip magic string and parse version + + this._version[0] = this._byteData.readUnsignedByte(); + this._version[1] = this._byteData.readUnsignedByte(); + + flags = this._byteData.readUnsignedShort(); // Parse bit flags + + this._streaming = BitFlags.test(flags, BitFlags.FLAG1); + + if ((this._version[0] == 2) && (this._version[1] == 1)) { + this._accuracyMatrix = BitFlags.test(flags, BitFlags.FLAG2); + this._accuracyGeo = BitFlags.test(flags, BitFlags.FLAG3); + this._accuracyProps = BitFlags.test(flags, BitFlags.FLAG4); + } + + // if we set _accuracyOnBlocks, the precision-values are read from each block-header. + + // set storagePrecision types + this._geoNrType = AWDParser.FLOAT32; + + if (this._accuracyGeo) { + this._geoNrType = AWDParser.FLOAT64; + } + + this._matrixNrType = AWDParser.FLOAT32; + + if (this._accuracyMatrix) { + this._matrixNrType = AWDParser.FLOAT64; + } + + this._propsNrType = AWDParser.FLOAT32; + + if (this._accuracyProps) { + this._propsNrType = AWDParser.FLOAT64; + } + + this._compression = this._byteData.readUnsignedByte(); // compression + + if (this._debug) { + console.log("Import AWDFile of version = " + this._version[0] + " - " + this._version[1]); + console.log("Global Settings = Compression = " + this._compression + " | Streaming = " + this._streaming + " | Matrix-Precision = " + this._accuracyMatrix + " | Geometry-Precision = " + this._accuracyGeo + " | Properties-Precision = " + this._accuracyProps); + } + + // Check file integrity + body_len = this._byteData.readUnsignedInt(); + if (!this._streaming && body_len != this._byteData.getBytesAvailable()) { + this._pDieWithError('AWD2 body length does not match header integrity field'); + } + + } + // Helper - functions + private getUVForVertexAnimation(meshID:number /*uint*/):Array> + { + if (this._blocks[meshID].data instanceof Mesh) + meshID = this._blocks[meshID].geoID; + if (this._blocks[meshID].uvsForVertexAnimation) + return this._blocks[meshID].uvsForVertexAnimation; + var geometry:Geometry = ( this._blocks[meshID].data); + var geoCnt:number /*int*/ = 0; + var ud:Array; + var uStride:number /*uint*/; + var uOffs:number /*uint*/; + var numPoints:number /*uint*/; + var i:number /*int*/; + var newUvs:Array; + var sub_geom:TriangleSubGeometry; + this._blocks[meshID].uvsForVertexAnimation = new Array>(); + while (geoCnt < geometry.subGeometries.length) { + newUvs = new Array(); + sub_geom = geometry.subGeometries[geoCnt]; + numPoints = sub_geom.numVertices; + ud = sub_geom.uvs; + uStride = sub_geom.getStride(TriangleSubGeometry.UV_DATA); + uOffs = sub_geom.getOffset(TriangleSubGeometry.UV_DATA); + for (i = 0; i < numPoints; i++) { + newUvs.push(ud[uOffs + i*uStride + 0]); + newUvs.push(ud[uOffs + i*uStride + 1]); + } + this._blocks[meshID].uvsForVertexAnimation.push(newUvs); + geoCnt++; + } + return this._blocks[meshID].uvsForVertexAnimation; + } + + private parseVarStr():string + { + + var len:number = this._newBlockBytes.readUnsignedShort(); + return this._newBlockBytes.readUTFBytes(len); + } + + private getAssetByID(assetID:number, assetTypesToGet:Array, extraTypeInfo:string = "SingleTexture"):Array + { + var returnArray:Array = new Array(); + var typeCnt:number = 0; + if (assetID > 0) { + if (this._blocks[assetID]) { + if (this._blocks[assetID].data) { + while (typeCnt < assetTypesToGet.length) { + + var iasset:IAsset = this._blocks[assetID].data; + + if (iasset.assetType == assetTypesToGet[typeCnt]) { + //if the right assetType was found + if ((assetTypesToGet[typeCnt] == AssetType.TEXTURE) && (extraTypeInfo == "CubeTexture")) { + if (this._blocks[assetID].data instanceof ImageCubeTexture) { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + } + } + if ((assetTypesToGet[typeCnt] == AssetType.TEXTURE) && (extraTypeInfo == "SingleTexture")) { + if (this._blocks[assetID].data instanceof ImageTexture) { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + } + } else { + returnArray.push(true); + returnArray.push(this._blocks[assetID].data); + return returnArray; + + } + } + //if ((assetTypesToGet[typeCnt] == AssetType.GEOMETRY) && (IAsset(_blocks[assetID].data).assetType == AssetType.MESH)) { + if ((assetTypesToGet[typeCnt] == AssetType.GEOMETRY) && (iasset.assetType == AssetType.MESH)) { + + var mesh:Mesh = this._blocks[assetID].data + + returnArray.push(true); + returnArray.push(mesh.geometry); + return returnArray; + + } + + typeCnt++; + } + } + } + } + // if the has not returned anything yet, the asset is not found, or the found asset is not the right type. + returnArray.push(false); + returnArray.push(this.getDefaultAsset(assetTypesToGet[0], extraTypeInfo)); + return returnArray; + } + + private getDefaultAsset(assetType:string, extraTypeInfo:string):IAsset + { + switch (true) { + case (assetType == AssetType.TEXTURE): + if (extraTypeInfo == "CubeTexture") + return this.getDefaultCubeTexture(); + if (extraTypeInfo == "SingleTexture") + return this.getDefaultTexture(); + break; + case (assetType == AssetType.MATERIAL): + return this.getDefaultMaterial() + break; + default: + break; + } + + return null; + } + + private getDefaultMaterial():IAsset + { + if (!this._defaultBitmapMaterial) + this._defaultBitmapMaterial = DefaultMaterialManager.getDefaultMaterial(); + + return this._defaultBitmapMaterial; + } + + private getDefaultTexture():IAsset + { + if (!this._defaultTexture) + this._defaultTexture = DefaultMaterialManager.getDefaultTexture(); + + return this._defaultTexture; + + } + + private getDefaultCubeTexture():IAsset + { + if (!this._defaultCubeTexture) { + var defaultBitmap:BitmapData = DefaultMaterialManager.createCheckeredBitmapData(); + + this._defaultCubeTexture = new BitmapCubeTexture(defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap, defaultBitmap); + this._defaultCubeTexture.name = "defaultCubeTexture"; + } + + return this._defaultCubeTexture; + } + + private readNumber(precision:boolean = false):number + { + if (precision) + return this._newBlockBytes.readDouble(); + return this._newBlockBytes.readFloat(); + + } + + private parseMatrix3D():Matrix3D + { + return new Matrix3D(this.parseMatrix43RawData()); + } + + private parseMatrix32RawData():Array + { + var i:number; + var mtx_raw:Array = new Array(6); + for (i = 0; i < 6; i++) { + mtx_raw[i] = this._newBlockBytes.readFloat(); + } + + return mtx_raw; + } + + private parseMatrix43RawData():Array + { + var mtx_raw:Array = new Array(16); + + mtx_raw[0] = this.readNumber(this._accuracyMatrix); + mtx_raw[1] = this.readNumber(this._accuracyMatrix); + mtx_raw[2] = this.readNumber(this._accuracyMatrix); + mtx_raw[3] = 0.0; + mtx_raw[4] = this.readNumber(this._accuracyMatrix); + mtx_raw[5] = this.readNumber(this._accuracyMatrix); + mtx_raw[6] = this.readNumber(this._accuracyMatrix); + mtx_raw[7] = 0.0; + mtx_raw[8] = this.readNumber(this._accuracyMatrix); + mtx_raw[9] = this.readNumber(this._accuracyMatrix); + mtx_raw[10] = this.readNumber(this._accuracyMatrix); + mtx_raw[11] = 0.0; + mtx_raw[12] = this.readNumber(this._accuracyMatrix); + mtx_raw[13] = this.readNumber(this._accuracyMatrix); + mtx_raw[14] = this.readNumber(this._accuracyMatrix); + mtx_raw[15] = 1.0; + + //TODO: fix max exporter to remove NaN values in joint 0 inverse bind pose + + if (isNaN(mtx_raw[0])) { + mtx_raw[0] = 1; + mtx_raw[1] = 0; + mtx_raw[2] = 0; + mtx_raw[4] = 0; + mtx_raw[5] = 1; + mtx_raw[6] = 0; + mtx_raw[8] = 0; + mtx_raw[9] = 0; + mtx_raw[10] = 1; + mtx_raw[12] = 0; + mtx_raw[13] = 0; + mtx_raw[14] = 0; + + } + + return mtx_raw; + } + +} + +export = AWDParser; \ No newline at end of file diff --git a/lib/parsers/MD2Parser.js b/lib/parsers/MD2Parser.js new file mode 100755 index 000000000..9671b39df --- /dev/null +++ b/lib/parsers/MD2Parser.js @@ -0,0 +1,390 @@ +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 DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +var DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); +var VertexClipNode = require("awayjs-renderergl/lib/animators/nodes/VertexClipNode"); +var VertexAnimationSet = require("awayjs-renderergl/lib/animators/VertexAnimationSet"); +/** + * MD2Parser provides a parser for the MD2 data type. + */ +var MD2Parser = (function (_super) { + __extends(MD2Parser, _super); + /** + * Creates a new MD2Parser object. + * @param textureType The extension of the texture (e.g. jpg/png/...) + * @param ignoreTexturePath If true, the path of the texture is ignored + */ + function MD2Parser(textureType, ignoreTexturePath) { + if (textureType === void 0) { textureType = "jpg"; } + if (ignoreTexturePath === void 0) { ignoreTexturePath = true; } + _super.call(this, URLLoaderDataFormat.ARRAY_BUFFER); + this._clipNodes = new Object(); + // the current subgeom being built + this._animationSet = new VertexAnimationSet(); + this.materialFinal = false; + this.geoCreated = false; + this._textureType = textureType; + this._ignoreTexturePath = ignoreTexturePath; + } + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + MD2Parser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "md2"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + MD2Parser.supportsData = function (data) { + return (ParserUtils.toString(data, 4) == 'IDP2'); + }; + /** + * @inheritDoc + */ + MD2Parser.prototype._iResolveDependency = function (resourceDependency) { + if (resourceDependency.assets.length != 1) + return; + var asset = resourceDependency.assets[0]; + if (asset) { + var material = new TriangleMethodMaterial(asset); + if (this.materialMode >= 2) + material.materialMode = TriangleMaterialMode.MULTI_PASS; + //add to the content property + this._pContent.addChild(this._mesh); + material.name = this._mesh.material.name; + this._mesh.material = material; + this._pFinalizeAsset(material); + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + } + this.materialFinal = true; + }; + /** + * @inheritDoc + */ + MD2Parser.prototype._iResolveDependencyFailure = function (resourceDependency) { + // apply system default + if (this.materialMode < 2) { + this._mesh.material = DefaultMaterialManager.getDefaultMaterial(); + } + else { + this._mesh.material = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + this._mesh.material.materialMode = TriangleMaterialMode.MULTI_PASS; + } + //add to the content property + this._pContent.addChild(this._mesh); + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + this.materialFinal = true; + }; + /** + * @inheritDoc + */ + MD2Parser.prototype._pProceedParsing = function () { + if (!this._startedParsing) { + this._byteData = this._pGetByteData(); + this._startedParsing = true; + // Reset bytearray read position (which may have been + // moved forward by the supportsData() function.) + this._byteData.position = 0; + } + while (this._pHasTime()) { + if (!this._parsedHeader) { + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN; + // TODO: Create a mesh only when encountered (if it makes sense + // for this file format) and return it using this._pFinalizeAsset() + this._geometry = new Geometry(); + this._mesh = new Mesh(this._geometry, null); + if (this.materialMode < 2) { + this._mesh.material = DefaultMaterialManager.getDefaultMaterial(); + } + else { + this._mesh.material = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + this._mesh.material.materialMode = TriangleMaterialMode.MULTI_PASS; + } + //_geometry.animation = new VertexAnimation(2, VertexAnimationMode.ABSOLUTE); + //_animator = new VertexAnimator(VertexAnimationState(_mesh.animationState)); + // Parse header and decompress body + this.parseHeader(); + this.parseMaterialNames(); + } + else if (!this._parsedUV) { + this.parseUV(); + } + else if (!this._parsedFaces) { + this.parseFaces(); + } + else if (!this._parsedFrames) { + this.parseFrames(); + } + else if ((this.geoCreated) && (this.materialFinal)) { + return ParserBase.PARSING_DONE; + } + else if (!this.geoCreated) { + this.geoCreated = true; + //create default subgeometry + this._geometry.addSubGeometry(this._firstSubGeom.clone()); + // Force name to be chosen by this._pFinalizeAsset() + this._mesh.name = ""; + if (this.materialFinal) { + //add to the content property + this._pContent.addChild(this._mesh); + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + } + this._pPauseAndRetrieveDependencies(); + } + } + return ParserBase.MORE_TO_PARSE; + }; + MD2Parser.prototype._pStartParsing = function (frameLimit) { + _super.prototype._pStartParsing.call(this, frameLimit); + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + }; + /** + * Reads in all that MD2 Header data that is declared as private variables. + * I know its a lot, and it looks ugly, but only way to do it in Flash + */ + MD2Parser.prototype.parseHeader = function () { + this._ident = this._byteData.readInt(); + this._version = this._byteData.readInt(); + this._skinWidth = this._byteData.readInt(); + this._skinHeight = this._byteData.readInt(); + //skip this._frameSize + this._byteData.readInt(); + this._numSkins = this._byteData.readInt(); + this._numVertices = this._byteData.readInt(); + this._numST = this._byteData.readInt(); + this._numTris = this._byteData.readInt(); + //skip this._numGlCmds + this._byteData.readInt(); + this._numFrames = this._byteData.readInt(); + this._offsetSkins = this._byteData.readInt(); + this._offsetST = this._byteData.readInt(); + this._offsetTris = this._byteData.readInt(); + this._offsetFrames = this._byteData.readInt(); + //skip this._offsetGlCmds + this._byteData.readInt(); + this._offsetEnd = this._byteData.readInt(); + this._parsedHeader = true; + }; + /** + * Parses the file names for the materials. + */ + MD2Parser.prototype.parseMaterialNames = function () { + var url; + var name; + var extIndex /*int*/; + var slashIndex /*int*/; + this._materialNames = new Array(); + this._byteData.position = this._offsetSkins; + var regExp = new RegExp("[^a-zA-Z0-9\\_\/.]", "g"); + for (var i = 0; i < this._numSkins; ++i) { + name = this._byteData.readUTFBytes(64); + name = name.replace(regExp, ""); + extIndex = name.lastIndexOf("."); + if (this._ignoreTexturePath) + slashIndex = name.lastIndexOf("/"); + if (name.toLowerCase().indexOf(".jpg") == -1 && name.toLowerCase().indexOf(".png") == -1) { + name = name.substring(slashIndex + 1, extIndex); + url = name + "." + this._textureType; + } + else { + url = name; + } + this._materialNames[i] = name; + // only support 1 skin TODO: really? + if (this.dependencies.length == 0) + this._pAddDependency(name, new URLRequest(url)); + } + if (this._materialNames.length > 0) + this._mesh.material.name = this._materialNames[0]; + else + this.materialFinal = true; + }; + /** + * Parses the uv data for the mesh. + */ + MD2Parser.prototype.parseUV = function () { + var j = 0; + this._uvs = new Array(this._numST * 2); + this._byteData.position = this._offsetST; + for (var i = 0; i < this._numST; i++) { + this._uvs[j++] = this._byteData.readShort() / this._skinWidth; + this._uvs[j++] = this._byteData.readShort() / this._skinHeight; + } + this._parsedUV = true; + }; + /** + * Parses unique indices for the faces. + */ + MD2Parser.prototype.parseFaces = function () { + var a /*uint*/, b /*uint*/, c /*uint*/, ta /*uint*/, tb /*uint*/, tc /*uint*/; + var i /*uint*/; + this._vertIndices = new Array(); + this._uvIndices = new Array(); + this._indices = new Array(); + this._byteData.position = this._offsetTris; + for (i = 0; i < this._numTris; i++) { + //collect vertex indices + a = this._byteData.readUnsignedShort(); + b = this._byteData.readUnsignedShort(); + c = this._byteData.readUnsignedShort(); + //collect uv indices + ta = this._byteData.readUnsignedShort(); + tb = this._byteData.readUnsignedShort(); + tc = this._byteData.readUnsignedShort(); + this.addIndex(a, ta); + this.addIndex(b, tb); + this.addIndex(c, tc); + } + var len = this._uvIndices.length; + this._finalUV = new Array(len * 2); + for (i = 0; i < len; ++i) { + this._finalUV[i << 1] = this._uvs[this._uvIndices[i] << 1]; + this._finalUV[(i << 1) + 1] = this._uvs[(this._uvIndices[i] << 1) + 1]; + } + this._parsedFaces = true; + }; + /** + * Adds a face index to the list if it doesn't exist yet, based on vertexIndex and uvIndex, and adds the + * corresponding vertex and uv data in the correct location. + * @param vertexIndex The original index in the vertex list. + * @param uvIndex The original index in the uv list. + */ + MD2Parser.prototype.addIndex = function (vertexIndex /*uint*/, uvIndex /*uint*/) { + var index = this.findIndex(vertexIndex, uvIndex); + if (index == -1) { + this._indices.push(this._vertIndices.length); + this._vertIndices.push(vertexIndex); + this._uvIndices.push(uvIndex); + } + else + this._indices.push(index); + }; + /** + * Finds the final index corresponding to the original MD2's vertex and uv indices. Returns -1 if it wasn't added yet. + * @param vertexIndex The original index in the vertex list. + * @param uvIndex The original index in the uv list. + * @return The index of the final mesh corresponding to the original vertex and uv index. -1 if it doesn't exist yet. + */ + MD2Parser.prototype.findIndex = function (vertexIndex /*uint*/, uvIndex /*uint*/) { + var len = this._vertIndices.length; + for (var i = 0; i < len; ++i) { + if (this._vertIndices[i] == vertexIndex && this._uvIndices[i] == uvIndex) + return i; + } + return -1; + }; + /** + * Parses all the frame geometries. + */ + MD2Parser.prototype.parseFrames = function () { + var sx, sy, sz; + var tx, ty, tz; + var geometry; + var subGeom; + var vertLen = this._vertIndices.length; + var fvertices; + var tvertices; + var i /*uint*/, j /*int*/, k /*uint*/; + //var ch : number /*uint*/; + var name = ""; + var prevClip = null; + this._byteData.position = this._offsetFrames; + for (i = 0; i < this._numFrames; i++) { + tvertices = new Array(); + fvertices = new Array(vertLen * 3); + sx = this._byteData.readFloat(); + sy = this._byteData.readFloat(); + sz = this._byteData.readFloat(); + tx = this._byteData.readFloat(); + ty = this._byteData.readFloat(); + tz = this._byteData.readFloat(); + name = this.readFrameName(); + for (j = 0; j < this._numVertices; j++, this._byteData.position++) + tvertices.push(sx * this._byteData.readUnsignedByte() + tx, sy * this._byteData.readUnsignedByte() + ty, sz * this._byteData.readUnsignedByte() + tz); + k = 0; + for (j = 0; j < vertLen; j++) { + fvertices[k++] = tvertices[this._vertIndices[j] * 3]; + fvertices[k++] = tvertices[this._vertIndices[j] * 3 + 2]; + fvertices[k++] = tvertices[this._vertIndices[j] * 3 + 1]; + } + subGeom = new TriangleSubGeometry(true); + if (this._firstSubGeom == null) + this._firstSubGeom = subGeom; + geometry = new Geometry(); + geometry.addSubGeometry(subGeom); + subGeom.updateIndices(this._indices); + subGeom.updatePositions(fvertices); + subGeom.updateUVs(this._finalUV); + subGeom.vertexNormals; + subGeom.vertexTangents; + subGeom.autoDeriveNormals = false; + subGeom.autoDeriveTangents = false; + var clip = this._clipNodes[name]; + if (!clip) { + // If another sequence was parsed before this one, starting + // a new state means the previous one is complete and can + // hence be finalized. + if (prevClip) { + this._pFinalizeAsset(prevClip); + this._animationSet.addAnimation(prevClip); + } + clip = new VertexClipNode(); + clip.name = name; + clip.stitchFinalFrame = true; + this._clipNodes[name] = clip; + prevClip = clip; + } + clip.addFrame(geometry, 1000 / MD2Parser.FPS); + } + // Finalize the last state + if (prevClip) { + this._pFinalizeAsset(prevClip); + this._animationSet.addAnimation(prevClip); + } + // Force this._pFinalizeAsset() to decide name + this._pFinalizeAsset(this._animationSet); + this._parsedFrames = true; + }; + MD2Parser.prototype.readFrameName = function () { + var name = ""; + var k = 0; + for (var j = 0; j < 16; j++) { + var ch = this._byteData.readUnsignedByte(); + if (Math.floor(ch) > 0x39 && Math.floor(ch) <= 0x7A && k == 0) + name += String.fromCharCode(ch); + if (Math.floor(ch) >= 0x30 && Math.floor(ch) <= 0x39) + k++; + } + return name; + }; + MD2Parser.FPS = 6; + return MD2Parser; +})(ParserBase); +module.exports = MD2Parser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvbWQycGFyc2VyLnRzIl0sIm5hbWVzIjpbIk1EMlBhcnNlciIsIk1EMlBhcnNlci5jb25zdHJ1Y3RvciIsIk1EMlBhcnNlci5zdXBwb3J0c1R5cGUiLCJNRDJQYXJzZXIuc3VwcG9ydHNEYXRhIiwiTUQyUGFyc2VyLl9pUmVzb2x2ZURlcGVuZGVuY3kiLCJNRDJQYXJzZXIuX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUiLCJNRDJQYXJzZXIuX3BQcm9jZWVkUGFyc2luZyIsIk1EMlBhcnNlci5fcFN0YXJ0UGFyc2luZyIsIk1EMlBhcnNlci5wYXJzZUhlYWRlciIsIk1EMlBhcnNlci5wYXJzZU1hdGVyaWFsTmFtZXMiLCJNRDJQYXJzZXIucGFyc2VVViIsIk1EMlBhcnNlci5wYXJzZUZhY2VzIiwiTUQyUGFyc2VyLmFkZEluZGV4IiwiTUQyUGFyc2VyLmZpbmRJbmRleCIsIk1EMlBhcnNlci5wYXJzZUZyYW1lcyIsIk1EMlBhcnNlci5yZWFkRnJhbWVOYW1lIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLHNCQUFzQixXQUFhLG1EQUFtRCxDQUFDLENBQUM7QUFHL0YsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFDdEUsSUFBTyxtQkFBbUIsV0FBYywrQ0FBK0MsQ0FBQyxDQUFDO0FBRXpGLElBQU8sbUJBQW1CLFdBQWMsOENBQThDLENBQUMsQ0FBQztBQUN4RixJQUFPLFVBQVUsV0FBZ0IscUNBQXFDLENBQUMsQ0FBQztBQUV4RSxJQUFPLElBQUksV0FBa0IsK0JBQStCLENBQUMsQ0FBQztBQUM5RCxJQUFPLFVBQVUsV0FBZ0Isb0NBQW9DLENBQUMsQ0FBQztBQUN2RSxJQUFPLFdBQVcsV0FBZ0IscUNBQXFDLENBQUMsQ0FBQztBQUt6RSxJQUFPLHNCQUFzQixXQUFhLDJEQUEyRCxDQUFDLENBQUM7QUFDdkcsSUFBTyxzQkFBc0IsV0FBYSxxREFBcUQsQ0FBQyxDQUFDO0FBQ2pHLElBQU8sb0JBQW9CLFdBQWMsbURBQW1ELENBQUMsQ0FBQztBQUU5RixJQUFPLGNBQWMsV0FBZSxzREFBc0QsQ0FBQyxDQUFDO0FBQzVGLElBQU8sa0JBQWtCLFdBQWMsb0RBQW9ELENBQUMsQ0FBQztBQUU3RixBQUdBOztHQURHO0lBQ0csU0FBUztJQUFTQSxVQUFsQkEsU0FBU0EsVUFBbUJBO0lBaURqQ0E7Ozs7T0FJR0E7SUFDSEEsU0F0REtBLFNBQVNBLENBc0RGQSxXQUEwQkEsRUFBRUEsaUJBQWdDQTtRQUE1REMsMkJBQTBCQSxHQUExQkEsbUJBQTBCQTtRQUFFQSxpQ0FBZ0NBLEdBQWhDQSx3QkFBZ0NBO1FBRXZFQSxrQkFBTUEsbUJBQW1CQSxDQUFDQSxZQUFZQSxDQUFDQSxDQUFDQTtRQXBEakNBLGVBQVVBLEdBQVVBLElBQUlBLE1BQU1BLEVBQUVBLENBQUNBO1FBOEJ6Q0Esa0NBQWtDQTtRQUMxQkEsa0JBQWFBLEdBQXNCQSxJQUFJQSxrQkFBa0JBLEVBQUVBLENBQUNBO1FBVzVEQSxrQkFBYUEsR0FBV0EsS0FBS0EsQ0FBQ0E7UUFDOUJBLGVBQVVBLEdBQVdBLEtBQUtBLENBQUNBO1FBVWxDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxXQUFXQSxDQUFDQTtRQUNoQ0EsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxHQUFHQSxpQkFBaUJBLENBQUNBO0lBQzdDQSxDQUFDQTtJQUVERDs7OztPQUlHQTtJQUNXQSxzQkFBWUEsR0FBMUJBLFVBQTJCQSxTQUFnQkE7UUFFMUNFLFNBQVNBLEdBQUdBLFNBQVNBLENBQUNBLFdBQVdBLEVBQUVBLENBQUNBO1FBQ3BDQSxNQUFNQSxDQUFDQSxTQUFTQSxJQUFJQSxLQUFLQSxDQUFDQTtJQUMzQkEsQ0FBQ0E7SUFFREY7Ozs7T0FJR0E7SUFDV0Esc0JBQVlBLEdBQTFCQSxVQUEyQkEsSUFBUUE7UUFFbENHLE1BQU1BLENBQUNBLENBQUNBLFdBQVdBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLE1BQU1BLENBQUNBLENBQUNBO0lBQ2xEQSxDQUFDQTtJQUVESDs7T0FFR0E7SUFDSUEsdUNBQW1CQSxHQUExQkEsVUFBMkJBLGtCQUFxQ0E7UUFFL0RJLEVBQUVBLENBQUNBLENBQUNBLGtCQUFrQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsTUFBTUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDekNBLE1BQU1BLENBQUNBO1FBRVJBLElBQUlBLEtBQUtBLEdBQWlDQSxrQkFBa0JBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBRXZFQSxFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNYQSxJQUFJQSxRQUFRQSxHQUEwQkEsSUFBSUEsc0JBQXNCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUV4RUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzFCQSxRQUFRQSxDQUFDQSxZQUFZQSxHQUFHQSxvQkFBb0JBLENBQUNBLFVBQVVBLENBQUNBO1lBRXpEQSxBQUNBQSw2QkFENkJBO1lBQ0hBLElBQUlBLENBQUNBLFNBQVVBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1lBRS9EQSxRQUFRQSxDQUFDQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQTtZQUN6Q0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsR0FBR0EsUUFBUUEsQ0FBQ0E7WUFDL0JBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBO1lBQy9CQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtZQUMxQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDbENBLENBQUNBO1FBQ0RBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO0lBQzNCQSxDQUFDQTtJQUVESjs7T0FFR0E7SUFDSUEsOENBQTBCQSxHQUFqQ0EsVUFBa0NBLGtCQUFxQ0E7UUFFdEVLLEFBQ0FBLHVCQUR1QkE7UUFDdkJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzNCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxHQUFHQSxzQkFBc0JBLENBQUNBLGtCQUFrQkEsRUFBRUEsQ0FBQ0E7UUFDbkVBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLEdBQUdBLElBQUlBLHNCQUFzQkEsQ0FBQ0Esc0JBQXNCQSxDQUFDQSxpQkFBaUJBLEVBQUVBLENBQUNBLENBQUNBO1lBQ25FQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFTQSxDQUFDQSxZQUFZQSxHQUFHQSxvQkFBb0JBLENBQUNBLFVBQVVBLENBQUNBO1FBQy9GQSxDQUFDQTtRQUVEQSxBQUNBQSw2QkFENkJBO1FBQ0hBLElBQUlBLENBQUNBLFNBQVVBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBRS9EQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7UUFDakNBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO0lBRTNCQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDSUEsb0NBQWdCQSxHQUF2QkE7UUFFQ00sRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDM0JBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLEVBQUVBLENBQUNBO1lBQ3RDQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUU1QkEsQUFFQUEscURBRnFEQTtZQUNyREEsaURBQWlEQTtZQUNqREEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsUUFBUUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLENBQUNBO1FBRURBLE9BQU9BLElBQUlBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQ3pCQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDekJBLEFBT0FBLDhFQVA4RUE7Z0JBQzlFQSx5RUFBeUVBO2dCQUN6RUEsOEVBQThFQTtnQkFDOUVBLCtDQUErQ0E7Z0JBRS9DQSwrREFBK0RBO2dCQUMvREEsbUVBQW1FQTtnQkFDbkVBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO2dCQUNoQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzVDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxZQUFZQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDM0JBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLEdBQUdBLHNCQUFzQkEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxDQUFDQTtnQkFDbkVBLENBQUNBO2dCQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtvQkFDUEEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsR0FBR0EsSUFBSUEsc0JBQXNCQSxDQUFDQSxzQkFBc0JBLENBQUNBLGlCQUFpQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0E7b0JBQ25FQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFTQSxDQUFDQSxZQUFZQSxHQUFHQSxvQkFBb0JBLENBQUNBLFVBQVVBLENBQUNBO2dCQUMvRkEsQ0FBQ0E7Z0JBRURBLEFBSUFBLDZFQUo2RUE7Z0JBQzdFQSw2RUFBNkVBO2dCQUU3RUEsbUNBQW1DQTtnQkFDbkNBLElBQUlBLENBQUNBLFdBQVdBLEVBQUVBLENBQUNBO2dCQUNuQkEsSUFBSUEsQ0FBQ0Esa0JBQWtCQSxFQUFFQSxDQUFDQTtZQUMzQkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzVCQSxJQUFJQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtZQUNoQkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9CQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxDQUFDQTtZQUNuQkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2hDQSxJQUFJQSxDQUFDQSxXQUFXQSxFQUFFQSxDQUFDQTtZQUNwQkEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ3REQSxNQUFNQSxDQUFDQSxVQUFVQSxDQUFDQSxZQUFZQSxDQUFDQTtZQUNoQ0EsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzdCQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQTtnQkFDdkJBLEFBQ0FBLDRCQUQ0QkE7Z0JBQzVCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxjQUFjQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQSxDQUFDQTtnQkFDMURBLEFBQ0FBLG9EQURvREE7Z0JBQ3BEQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxHQUFHQSxFQUFFQSxDQUFDQTtnQkFDckJBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLENBQUNBLENBQUNBO29CQUN4QkEsQUFDQUEsNkJBRDZCQTtvQkFDSEEsSUFBSUEsQ0FBQ0EsU0FBVUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBRS9EQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtvQkFDMUNBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO2dCQUNsQ0EsQ0FBQ0E7Z0JBRURBLElBQUlBLENBQUNBLDhCQUE4QkEsRUFBRUEsQ0FBQ0E7WUFDdkNBLENBQUNBO1FBQ0ZBLENBQUNBO1FBRURBLE1BQU1BLENBQUNBLFVBQVVBLENBQUNBLGFBQWFBLENBQUNBO0lBQ2pDQSxDQUFDQTtJQUVNTixrQ0FBY0EsR0FBckJBLFVBQXNCQSxVQUFpQkE7UUFFdENPLGdCQUFLQSxDQUFDQSxjQUFjQSxZQUFDQSxVQUFVQSxDQUFDQSxDQUFDQTtRQUVqQ0EsQUFDQUEscUNBRHFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsc0JBQXNCQSxFQUFFQSxDQUFDQTtJQUMvQ0EsQ0FBQ0E7SUFFRFA7OztPQUdHQTtJQUNLQSwrQkFBV0EsR0FBbkJBO1FBRUNRLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQ3ZDQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtRQUN6Q0EsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFDM0NBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQzVDQSxBQUNBQSxzQkFEc0JBO1FBQ3RCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtRQUN6QkEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFDMUNBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQzdDQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtRQUN2Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFDekNBLEFBQ0FBLHNCQURzQkE7UUFDdEJBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQ3pCQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtRQUMzQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsT0FBT0EsRUFBRUEsQ0FBQ0E7UUFDN0NBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE9BQU9BLEVBQUVBLENBQUNBO1FBQzFDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxPQUFPQSxFQUFFQSxDQUFDQTtRQUM1Q0EsSUFB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TUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDbENBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQUNBLElBQUlBO1lBQ3ZEQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUM1QkEsQ0FBQ0E7SUFFRFQ7O09BRUdBO0lBQ0tBLDJCQUFPQSxHQUFmQTtRQUVDVSxJQUFJQSxDQUFDQSxHQUFtQkEsQ0FBQ0EsQ0FBQ0E7UUFFMUJBLElBQUlBLENBQUNBLElBQUlBLEdBQUdBLElBQUlBLEtBQUtBLENBQVNBLElBQUlBLENBQUNBLE1BQU1BLEdBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQzdDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUN6Q0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBbUJBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQ3REQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxHQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQTtZQUM1REEsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsR0FBQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0E7UUFDOURBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBO0lBQ3ZCQSxDQUFDQTtJQUVEVjs7T0FFR0E7SUFDS0EsOEJBQVVBLEdBQWxCQTtRQUVDVyxJQUFJQSxDQUFDQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxDQUFDQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxDQUFDQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxFQUFFQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxFQUFFQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxFQUFFQSxDQUFRQSxRQUFEQSxBQUFTQSxDQUFDQTtRQUN4SEEsSUFBSUEsQ0FBQ0EsQ0FBUUEsUUFBREEsQUFBU0EsQ0FBQ0E7UUFFdEJBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLElBQUlBLEtBQUtBLEVBQVVBLENBQUNBO1FBQ3hDQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxLQUFLQSxFQUFVQSxDQUFDQTtRQUN0Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBVUE7UUFFN0NBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBO1FBRTNDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxRQUFRQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUNwQ0EsQUFDQUEsd0JBRHdCQTtZQUN4QkEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUN2Q0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUN2Q0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUV2Q0EsQUFDQUEsb0JBRG9CQTtZQUNwQkEsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUN4Q0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUN4Q0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtZQUV4Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0E7WUFDckJBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBLENBQUNBO1lBQ3JCQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUN0QkEsQ0FBQ0E7UUFFREEsSUFBSUEsR0FBR0EsR0FBbUJBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLE1BQU1BLENBQUNBO1FBQ2pEQSxJQUFJQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxLQUFLQSxDQUFTQSxHQUFHQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUV6Q0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDMUJBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO1lBQzNEQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUN4RUEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsWUFBWUEsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDMUJBLENBQUNBO0lBRURYOzs7OztPQUtHQTtJQUNLQSw0QkFBUUEsR0FBaEJBLFVBQWlCQSxXQUFXQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxPQUFPQSxDQUFRQSxRQUFEQSxBQUFTQTtRQUVwRVksSUFBSUEsS0FBS0EsR0FBa0JBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEVBQUVBLE9BQU9BLENBQUNBLENBQUNBO1FBRWhFQSxFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNqQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7WUFDN0NBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO1lBQ3BDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUMvQkEsQ0FBQ0E7UUFBQ0EsSUFBSUE7WUFDTEEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7SUFDNUJBLENBQUNBO0lBRURaOzs7OztPQUtHQTtJQUNLQSw2QkFBU0EsR0FBakJBLFVBQWtCQSxXQUFXQSxDQUFRQSxRQUFEQSxBQUFTQSxFQUFFQSxPQUFPQSxDQUFRQSxRQUFEQSxBQUFTQTtRQUVyRWEsSUFBSUEsR0FBR0EsR0FBbUJBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLE1BQU1BLENBQUNBO1FBRW5EQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFtQkEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDOUNBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLFdBQVdBLElBQUlBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLE9BQU9BLENBQUNBO2dCQUN4RUEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDWEEsQ0FBQ0E7UUFFREEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7SUFDWEEsQ0FBQ0E7SUFFRGI7O09BRUdBO0lBQ0tBLCtCQUFXQSxHQUFuQkE7UUFFQ2MsSUFBSUEsRUFBU0EsRUFBRUEsRUFBU0EsRUFBRUEsRUFBU0EsQ0FBQ0E7UUFDcENBLElBQUlBLEVBQVNBLEVBQUVBLEVBQVNBLEVBQUVBLEVBQVNBLENBQUNBO1FBQ3BDQSxJQUFJQSxRQUFpQkEsQ0FBQ0E7UUFDdEJBLElBQUlBLE9BQTJCQSxDQUFDQTtRQUNoQ0EsSUFBSUEsT0FBT0EsR0FBbUJBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBLE1BQU1BLENBQUNBO1FBQ3ZEQSxJQUFJQSxTQUF1QkEsQ0FBQ0E7UUFDNUJBLElBQUlBLFNBQXVCQSxDQUFDQTtRQUM1QkEsSUFBSUEsQ0FBQ0EsQ0FBUUEsUUFBREEsQUFBU0EsRUFBRUEsQ0FBQ0EsQ0FBUUEsT0FBREEsQUFBUUEsRUFBRUEsQ0FBQ0EsQ0FBUUEsUUFBREEsQUFBU0EsQ0FBQ0E7UUFDM0RBLEFBQ0FBLDJCQUQyQkE7WUFDdkJBLElBQUlBLEdBQVVBLEVBQUVBLENBQUNBO1FBQ3JCQSxJQUFJQSxRQUFRQSxHQUFrQkEsSUFBSUEsQ0FBQ0E7UUFFbkNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1FBRTdDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUV0Q0EsU0FBU0EsR0FBR0EsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBQ0E7WUFDaENBLFNBQVNBLEdBQUdBLElBQUlBLEtBQUtBLENBQVNBLE9BQU9BLEdBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBRXpDQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxDQUFDQTtZQUNoQ0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFDaENBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBO1lBRWhDQSxFQUFFQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxDQUFDQTtZQUNoQ0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0E7WUFDaENBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBO1lBRWhDQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxFQUFFQSxDQUFDQTtZQUk1QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsWUFBWUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsUUFBUUEsRUFBRUE7Z0JBQ2hFQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFDQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLEdBQUdBLEVBQUVBLEVBQUVBLEVBQUVBLEdBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGdCQUFnQkEsRUFBRUEsR0FBR0EsRUFBRUEsRUFBRUEsRUFBRUEsR0FBQ0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsZ0JBQWdCQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUVqSkEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDTkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0Es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LE1BQU1BLENBQUNBLElBQUlBLENBQUNBO0lBQ2JBLENBQUNBO0lBN2RhZixhQUFHQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7SUE4ZHRDQSxnQkFBQ0E7QUFBREEsQ0FoZUEsQUFnZUNBLEVBaGV1QixVQUFVLEVBZ2VqQztBQUVELEFBQW1CLGlCQUFWLFNBQVMsQ0FBQyIsImZpbGUiOiJwYXJzZXJzL01EMlBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEaXNwbGF5T2JqZWN0Q29udGFpbmVyXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvRGlzcGxheU9iamVjdENvbnRhaW5lclwiKTtcbmltcG9ydCBCaXRtYXBEYXRhXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9CaXRtYXBEYXRhXCIpO1xuaW1wb3J0IERpc3BsYXlPYmplY3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9EaXNwbGF5T2JqZWN0XCIpO1xuaW1wb3J0IEdlb21ldHJ5XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0dlb21ldHJ5XCIpO1xuaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBVUkxMb2FkZXJEYXRhRm9ybWF0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMTG9hZGVyRGF0YUZvcm1hdFwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTFJlcXVlc3RcIik7XG5pbXBvcnQgQ2FtZXJhXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQ2FtZXJhXCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgUGFyc2VyQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1BhcnNlckJhc2VcIik7XG5pbXBvcnQgUGFyc2VyVXRpbHNcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9QYXJzZXJVdGlsc1wiKTtcbmltcG9ydCBSZXNvdXJjZURlcGVuZGVuY3lcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1Jlc291cmNlRGVwZW5kZW5jeVwiKTtcbmltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlMkRCYXNlXCIpO1xuaW1wb3J0IEJ5dGVBcnJheVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9CeXRlQXJyYXlcIik7XG5cbmltcG9ydCBEZWZhdWx0TWF0ZXJpYWxNYW5hZ2VyXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy91dGlscy9EZWZhdWx0TWF0ZXJpYWxNYW5hZ2VyXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5pbXBvcnQgVHJpYW5nbGVNYXRlcmlhbE1vZGVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvVHJpYW5nbGVNYXRlcmlhbE1vZGVcIik7XG5cbmltcG9ydCBWZXJ0ZXhDbGlwTm9kZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1ZlcnRleENsaXBOb2RlXCIpO1xuaW1wb3J0IFZlcnRleEFuaW1hdGlvblNldFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2FuaW1hdG9ycy9WZXJ0ZXhBbmltYXRpb25TZXRcIik7XG5cbi8qKlxuICogTUQyUGFyc2VyIHByb3ZpZGVzIGEgcGFyc2VyIGZvciB0aGUgTUQyIGRhdGEgdHlwZS5cbiAqL1xuY2xhc3MgTUQyUGFyc2VyIGV4dGVuZHMgUGFyc2VyQmFzZVxue1xuXHRwdWJsaWMgc3RhdGljIEZQUzpudW1iZXIgLyppbnQqLyA9IDY7XG5cblx0cHJpdmF0ZSBfY2xpcE5vZGVzOk9iamVjdCA9IG5ldyBPYmplY3QoKTtcblx0cHJpdmF0ZSBfYnl0ZURhdGE6Qnl0ZUFycmF5O1xuXHRwcml2YXRlIF9zdGFydGVkUGFyc2luZzpib29sZWFuO1xuXHRwcml2YXRlIF9wYXJzZWRIZWFkZXI6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfcGFyc2VkVVY6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfcGFyc2VkRmFjZXM6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfcGFyc2VkRnJhbWVzOmJvb2xlYW47XG5cblx0cHJpdmF0ZSBfaWRlbnQ6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF92ZXJzaW9uOm51bWJlciAvKnVpbnQqLztcblx0cHJpdmF0ZSBfc2tpbldpZHRoOm51bWJlciAvKnVpbnQqLztcblx0cHJpdmF0ZSBfc2tpbkhlaWdodDpudW1iZXIgLyp1aW50Ki87XG5cdC8vcHJpdmF0ZSBfZnJhbWVTaXplIDogbnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9udW1Ta2luczpudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX251bVZlcnRpY2VzOm51bWJlciAvKnVpbnQqLztcblx0cHJpdmF0ZSBfbnVtU1Q6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9udW1UcmlzOm51bWJlciAvKnVpbnQqLztcblx0Ly9wcml2YXRlIF9udW1HbENtZHMgOiBudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX251bUZyYW1lczpudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX29mZnNldFNraW5zOm51bWJlciAvKnVpbnQqLztcblx0cHJpdmF0ZSBfb2Zmc2V0U1Q6bnVtYmVyIC8qdWludCovO1xuXHRwcml2YXRlIF9vZmZzZXRUcmlzOm51bWJlciAvKnVpbnQqLztcblx0cHJpdmF0ZSBfb2Zmc2V0RnJhbWVzOm51bWJlciAvKnVpbnQqLztcblx0Ly9wcml2YXRlIF9vZmZzZXRHbENtZHMgOiBudW1iZXIgLyp1aW50Ki87XG5cdHByaXZhdGUgX29mZnNldEVuZDpudW1iZXIgLyp1aW50Ki87XG5cblx0cHJpdmF0ZSBfdXZJbmRpY2VzOkFycmF5PG51bWJlcj47XG5cdHByaXZhdGUgX2luZGljZXM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLztcblx0cHJpdmF0ZSBfdmVydEluZGljZXM6QXJyYXk8bnVtYmVyPjtcblxuXHQvLyB0aGUgY3VycmVudCBzdWJnZW9tIGJlaW5nIGJ1aWx0XG5cdHByaXZhdGUgX2FuaW1hdGlvblNldDpWZXJ0ZXhBbmltYXRpb25TZXQgPSBuZXcgVmVydGV4QW5pbWF0aW9uU2V0KCk7XG5cdHByaXZhdGUgX2ZpcnN0U3ViR2VvbTpUcmlhbmdsZVN1Ykdlb21ldHJ5O1xuXHRwcml2YXRlIF91dnM6QXJyYXk8bnVtYmVyPjtcblx0cHJpdmF0ZSBfZmluYWxVVjpBcnJheTxudW1iZXI+O1xuXG5cdHByaXZhdGUgX21hdGVyaWFsTmFtZXM6QXJyYXk8c3RyaW5nPjtcblx0cHJpdmF0ZSBfdGV4dHVyZVR5cGU6c3RyaW5nO1xuXHRwcml2YXRlIF9pZ25vcmVUZXh0dXJlUGF0aDpib29sZWFuO1xuXHRwcml2YXRlIF9tZXNoOk1lc2g7XG5cdHByaXZhdGUgX2dlb21ldHJ5Okdlb21ldHJ5O1xuXG5cdHByaXZhdGUgbWF0ZXJpYWxGaW5hbDpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgZ2VvQ3JlYXRlZDpib29sZWFuID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgTUQyUGFyc2VyIG9iamVjdC5cblx0ICogQHBhcmFtIHRleHR1cmVUeXBlIFRoZSBleHRlbnNpb24gb2YgdGhlIHRleHR1cmUgKGUuZy4ganBnL3BuZy8uLi4pXG5cdCAqIEBwYXJhbSBpZ25vcmVUZXh0dXJlUGF0aCBJZiB0cnVlLCB0aGUgcGF0aCBvZiB0aGUgdGV4dHVyZSBpcyBpZ25vcmVkXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih0ZXh0dXJlVHlwZTpzdHJpbmcgPSBcImpwZ1wiLCBpZ25vcmVUZXh0dXJlUGF0aDpib29sZWFuID0gdHJ1ZSlcblx0e1xuXHRcdHN1cGVyKFVSTExvYWRlckRhdGFGb3JtYXQuQVJSQVlfQlVGRkVSKTtcblx0XHR0aGlzLl90ZXh0dXJlVHlwZSA9IHRleHR1cmVUeXBlO1xuXHRcdHRoaXMuX2lnbm9yZVRleHR1cmVQYXRoID0gaWdub3JlVGV4dHVyZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gZmlsZSBleHRlbnNpb24gaXMgc3VwcG9ydGVkIGJ5IHRoZSBwYXJzZXIuXG5cdCAqIEBwYXJhbSBleHRlbnNpb24gVGhlIGZpbGUgZXh0ZW5zaW9uIG9mIGEgcG90ZW50aWFsIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBmaWxlIHR5cGUgaXMgc3VwcG9ydGVkLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBzdXBwb3J0c1R5cGUoZXh0ZW5zaW9uOnN0cmluZyk6Ym9vbGVhblxuXHR7XG5cdFx0ZXh0ZW5zaW9uID0gZXh0ZW5zaW9uLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIGV4dGVuc2lvbiA9PSBcIm1kMlwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gKFBhcnNlclV0aWxzLnRvU3RyaW5nKGRhdGEsIDQpID09ICdJRFAyJyk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfaVJlc29sdmVEZXBlbmRlbmN5KHJlc291cmNlRGVwZW5kZW5jeTpSZXNvdXJjZURlcGVuZGVuY3kpOnZvaWRcblx0e1xuXHRcdGlmIChyZXNvdXJjZURlcGVuZGVuY3kuYXNzZXRzLmxlbmd0aCAhPSAxKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dmFyIGFzc2V0OlRleHR1cmUyREJhc2UgPSA8VGV4dHVyZTJEQmFzZT4gcmVzb3VyY2VEZXBlbmRlbmN5LmFzc2V0c1swXTtcblxuXHRcdGlmIChhc3NldCkge1xuXHRcdFx0dmFyIG1hdGVyaWFsOlRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbChhc3NldCk7XG5cblx0XHRcdGlmICh0aGlzLm1hdGVyaWFsTW9kZSA+PSAyKVxuXHRcdFx0XHRtYXRlcmlhbC5tYXRlcmlhbE1vZGUgPSBUcmlhbmdsZU1hdGVyaWFsTW9kZS5NVUxUSV9QQVNTO1xuXG5cdFx0XHQvL2FkZCB0byB0aGUgY29udGVudCBwcm9wZXJ0eVxuXHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiB0aGlzLl9wQ29udGVudCkuYWRkQ2hpbGQodGhpcy5fbWVzaCk7XG5cblx0XHRcdG1hdGVyaWFsLm5hbWUgPSB0aGlzLl9tZXNoLm1hdGVyaWFsLm5hbWU7XG5cdFx0XHR0aGlzLl9tZXNoLm1hdGVyaWFsID0gbWF0ZXJpYWw7XG5cdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldChtYXRlcmlhbCk7XG5cdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldCh0aGlzLl9tZXNoLmdlb21ldHJ5KTtcblx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX21lc2gpO1xuXHRcdH1cblx0XHR0aGlzLm1hdGVyaWFsRmluYWwgPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUocmVzb3VyY2VEZXBlbmRlbmN5OlJlc291cmNlRGVwZW5kZW5jeSk6dm9pZFxuXHR7XG5cdFx0Ly8gYXBwbHkgc3lzdGVtIGRlZmF1bHRcblx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPCAyKSB7XG5cdFx0XHR0aGlzLl9tZXNoLm1hdGVyaWFsID0gRGVmYXVsdE1hdGVyaWFsTWFuYWdlci5nZXREZWZhdWx0TWF0ZXJpYWwoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fbWVzaC5tYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKERlZmF1bHRNYXRlcmlhbE1hbmFnZXIuZ2V0RGVmYXVsdFRleHR1cmUoKSk7XG5cdFx0XHQoPFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWw+IHRoaXMuX21lc2gubWF0ZXJpYWwpLm1hdGVyaWFsTW9kZSA9IFRyaWFuZ2xlTWF0ZXJpYWxNb2RlLk1VTFRJX1BBU1M7XG5cdFx0fVxuXG5cdFx0Ly9hZGQgdG8gdGhlIGNvbnRlbnQgcHJvcGVydHlcblx0XHQoPERpc3BsYXlPYmplY3RDb250YWluZXI+IHRoaXMuX3BDb250ZW50KS5hZGRDaGlsZCh0aGlzLl9tZXNoKTtcblxuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX21lc2guZ2VvbWV0cnkpO1xuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX21lc2gpO1xuXHRcdHRoaXMubWF0ZXJpYWxGaW5hbCA9IHRydWU7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wUHJvY2VlZFBhcnNpbmcoKTpib29sZWFuXG5cdHtcblx0XHRpZiAoIXRoaXMuX3N0YXJ0ZWRQYXJzaW5nKSB7XG5cdFx0XHR0aGlzLl9ieXRlRGF0YSA9IHRoaXMuX3BHZXRCeXRlRGF0YSgpO1xuXHRcdFx0dGhpcy5fc3RhcnRlZFBhcnNpbmcgPSB0cnVlO1xuXG5cdFx0XHQvLyBSZXNldCBieXRlYXJyYXkgcmVhZCBwb3NpdGlvbiAod2hpY2ggbWF5IGhhdmUgYmVlblxuXHRcdFx0Ly8gbW92ZWQgZm9yd2FyZCBieSB0aGUgc3VwcG9ydHNEYXRhKCkgZnVuY3Rpb24uKVxuXHRcdFx0dGhpcy5fYnl0ZURhdGEucG9zaXRpb24gPSAwO1xuXHRcdH1cblxuXHRcdHdoaWxlICh0aGlzLl9wSGFzVGltZSgpKSB7XG5cdFx0XHRpZiAoIXRoaXMuX3BhcnNlZEhlYWRlcikge1xuXHRcdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdFx0Ly8gTElUVExFX0VORElBTiAtIERlZmF1bHQgZm9yIEFycmF5QnVmZmVyIC8gTm90IGltcGxlbWVudGVkIGluIEJ5dGVBcnJheVxuXHRcdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdFx0Ly90aGlzLl9ieXRlRGF0YS5lbmRpYW4gPSBFbmRpYW4uTElUVExFX0VORElBTjtcblxuXHRcdFx0XHQvLyBUT0RPOiBDcmVhdGUgYSBtZXNoIG9ubHkgd2hlbiBlbmNvdW50ZXJlZCAoaWYgaXQgbWFrZXMgc2Vuc2Vcblx0XHRcdFx0Ly8gZm9yIHRoaXMgZmlsZSBmb3JtYXQpIGFuZCByZXR1cm4gaXQgdXNpbmcgdGhpcy5fcEZpbmFsaXplQXNzZXQoKVxuXHRcdFx0XHR0aGlzLl9nZW9tZXRyeSA9IG5ldyBHZW9tZXRyeSgpO1xuXHRcdFx0XHR0aGlzLl9tZXNoID0gbmV3IE1lc2godGhpcy5fZ2VvbWV0cnksIG51bGwpO1xuXHRcdFx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPCAyKSB7XG5cdFx0XHRcdFx0dGhpcy5fbWVzaC5tYXRlcmlhbCA9IERlZmF1bHRNYXRlcmlhbE1hbmFnZXIuZ2V0RGVmYXVsdE1hdGVyaWFsKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fbWVzaC5tYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKERlZmF1bHRNYXRlcmlhbE1hbmFnZXIuZ2V0RGVmYXVsdFRleHR1cmUoKSk7XG5cdFx0XHRcdFx0KDxUcmlhbmdsZU1ldGhvZE1hdGVyaWFsPiB0aGlzLl9tZXNoLm1hdGVyaWFsKS5tYXRlcmlhbE1vZGUgPSBUcmlhbmdsZU1hdGVyaWFsTW9kZS5NVUxUSV9QQVNTO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9fZ2VvbWV0cnkuYW5pbWF0aW9uID0gbmV3IFZlcnRleEFuaW1hdGlvbigyLCBWZXJ0ZXhBbmltYXRpb25Nb2RlLkFCU09MVVRFKTtcblx0XHRcdFx0Ly9fYW5pbWF0b3IgPSBuZXcgVmVydGV4QW5pbWF0b3IoVmVydGV4QW5pbWF0aW9uU3RhdGUoX21lc2guYW5pbWF0aW9uU3RhdGUpKTtcblxuXHRcdFx0XHQvLyBQYXJzZSBoZWFkZXIgYW5kIGRlY29tcHJlc3MgYm9keVxuXHRcdFx0XHR0aGlzLnBhcnNlSGVhZGVyKCk7XG5cdFx0XHRcdHRoaXMucGFyc2VNYXRlcmlhbE5hbWVzKCk7XG5cdFx0XHR9IGVsc2UgaWYgKCF0aGlzLl9wYXJzZWRVVikge1xuXHRcdFx0XHR0aGlzLnBhcnNlVVYoKTtcblx0XHRcdH0gZWxzZSBpZiAoIXRoaXMuX3BhcnNlZEZhY2VzKSB7XG5cdFx0XHRcdHRoaXMucGFyc2VGYWNlcygpO1xuXHRcdFx0fSBlbHNlIGlmICghdGhpcy5fcGFyc2VkRnJhbWVzKSB7XG5cdFx0XHRcdHRoaXMucGFyc2VGcmFtZXMoKTtcblx0XHRcdH0gZWxzZSBpZiAoKHRoaXMuZ2VvQ3JlYXRlZCkgJiYgKHRoaXMubWF0ZXJpYWxGaW5hbCkpIHtcblx0XHRcdFx0cmV0dXJuIFBhcnNlckJhc2UuUEFSU0lOR19ET05FO1xuXHRcdFx0fSBlbHNlIGlmICghdGhpcy5nZW9DcmVhdGVkKSB7XG5cdFx0XHRcdHRoaXMuZ2VvQ3JlYXRlZCA9IHRydWU7XG5cdFx0XHRcdC8vY3JlYXRlIGRlZmF1bHQgc3ViZ2VvbWV0cnlcblx0XHRcdFx0dGhpcy5fZ2VvbWV0cnkuYWRkU3ViR2VvbWV0cnkodGhpcy5fZmlyc3RTdWJHZW9tLmNsb25lKCkpO1xuXHRcdFx0XHQvLyBGb3JjZSBuYW1lIHRvIGJlIGNob3NlbiBieSB0aGlzLl9wRmluYWxpemVBc3NldCgpXG5cdFx0XHRcdHRoaXMuX21lc2gubmFtZSA9IFwiXCI7XG5cdFx0XHRcdGlmICh0aGlzLm1hdGVyaWFsRmluYWwpIHtcblx0XHRcdFx0XHQvL2FkZCB0byB0aGUgY29udGVudCBwcm9wZXJ0eVxuXHRcdFx0XHRcdCg8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gdGhpcy5fcENvbnRlbnQpLmFkZENoaWxkKHRoaXMuX21lc2gpO1xuXG5cdFx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQodGhpcy5fbWVzaC5nZW9tZXRyeSk7XG5cdFx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQodGhpcy5fbWVzaCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLl9wUGF1c2VBbmRSZXRyaWV2ZURlcGVuZGVuY2llcygpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBQYXJzZXJCYXNlLk1PUkVfVE9fUEFSU0U7XG5cdH1cblxuXHRwdWJsaWMgX3BTdGFydFBhcnNpbmcoZnJhbWVMaW1pdDpudW1iZXIpXG5cdHtcblx0XHRzdXBlci5fcFN0YXJ0UGFyc2luZyhmcmFtZUxpbWl0KTtcblxuXHRcdC8vY3JlYXRlIGEgY29udGVudCBvYmplY3QgZm9yIExvYWRlcnNcblx0XHR0aGlzLl9wQ29udGVudCA9IG5ldyBEaXNwbGF5T2JqZWN0Q29udGFpbmVyKCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVhZHMgaW4gYWxsIHRoYXQgTUQyIEhlYWRlciBkYXRhIHRoYXQgaXMgZGVjbGFyZWQgYXMgcHJpdmF0ZSB2YXJpYWJsZXMuXG5cdCAqIEkga25vdyBpdHMgYSBsb3QsIGFuZCBpdCBsb29rcyB1Z2x5LCBidXQgb25seSB3YXkgdG8gZG8gaXQgaW4gRmxhc2hcblx0ICovXG5cdHByaXZhdGUgcGFyc2VIZWFkZXIoKTp2b2lkXG5cdHtcblx0XHR0aGlzLl9pZGVudCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHR0aGlzLl92ZXJzaW9uID0gdGhpcy5fYnl0ZURhdGEucmVhZEludCgpO1xuXHRcdHRoaXMuX3NraW5XaWR0aCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHR0aGlzLl9za2luSGVpZ2h0ID0gdGhpcy5fYnl0ZURhdGEucmVhZEludCgpO1xuXHRcdC8vc2tpcCB0aGlzLl9mcmFtZVNpemVcblx0XHR0aGlzLl9ieXRlRGF0YS5yZWFkSW50KCk7XG5cdFx0dGhpcy5fbnVtU2tpbnMgPSB0aGlzLl9ieXRlRGF0YS5yZWFkSW50KCk7XG5cdFx0dGhpcy5fbnVtVmVydGljZXMgPSB0aGlzLl9ieXRlRGF0YS5yZWFkSW50KCk7XG5cdFx0dGhpcy5fbnVtU1QgPSB0aGlzLl9ieXRlRGF0YS5yZWFkSW50KCk7XG5cdFx0dGhpcy5fbnVtVHJpcyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHQvL3NraXAgdGhpcy5fbnVtR2xDbWRzXG5cdFx0dGhpcy5fYnl0ZURhdGEucmVhZEludCgpO1xuXHRcdHRoaXMuX251bUZyYW1lcyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHR0aGlzLl9vZmZzZXRTa2lucyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHR0aGlzLl9vZmZzZXRTVCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHR0aGlzLl9vZmZzZXRUcmlzID0gdGhpcy5fYnl0ZURhdGEucmVhZEludCgpO1xuXHRcdHRoaXMuX29mZnNldEZyYW1lcyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblx0XHQvL3NraXAgdGhpcy5fb2Zmc2V0R2xDbWRzXG5cdFx0dGhpcy5fYnl0ZURhdGEucmVhZEludCgpO1xuXHRcdHRoaXMuX29mZnNldEVuZCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRJbnQoKTtcblxuXHRcdHRoaXMuX3BhcnNlZEhlYWRlciA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBmaWxlIG5hbWVzIGZvciB0aGUgbWF0ZXJpYWxzLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZU1hdGVyaWFsTmFtZXMoKTp2b2lkXG5cdHtcblx0XHR2YXIgdXJsOnN0cmluZztcblx0XHR2YXIgbmFtZTpzdHJpbmc7XG5cdFx0dmFyIGV4dEluZGV4Om51bWJlciAvKmludCovO1xuXHRcdHZhciBzbGFzaEluZGV4Om51bWJlciAvKmludCovO1xuXHRcdHRoaXMuX21hdGVyaWFsTmFtZXMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uID0gdGhpcy5fb2Zmc2V0U2tpbnM7XG5cblx0XHR2YXIgcmVnRXhwOlJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJbXmEtekEtWjAtOVxcXFxfXFwvLl1cIiwgXCJnXCIpO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qdWludCovID0gMDsgaSA8IHRoaXMuX251bVNraW5zOyArK2kpIHtcblx0XHRcdG5hbWUgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVVRGQnl0ZXMoNjQpO1xuXHRcdFx0bmFtZSA9IG5hbWUucmVwbGFjZShyZWdFeHAsIFwiXCIpO1xuXHRcdFx0ZXh0SW5kZXggPSBuYW1lLmxhc3RJbmRleE9mKFwiLlwiKTtcblx0XHRcdGlmICh0aGlzLl9pZ25vcmVUZXh0dXJlUGF0aClcblx0XHRcdFx0c2xhc2hJbmRleCA9IG5hbWUubGFzdEluZGV4T2YoXCIvXCIpO1xuXHRcdFx0aWYgKG5hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwiLmpwZ1wiKSA9PSAtMSAmJiBuYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihcIi5wbmdcIikgPT0gLTEpIHtcblx0XHRcdFx0bmFtZSA9IG5hbWUuc3Vic3RyaW5nKHNsYXNoSW5kZXggKyAxLCBleHRJbmRleCk7XG5cdFx0XHRcdHVybCA9IG5hbWUgKyBcIi5cIiArIHRoaXMuX3RleHR1cmVUeXBlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dXJsID0gbmFtZTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fbWF0ZXJpYWxOYW1lc1tpXSA9IG5hbWU7XG5cblx0XHRcdC8vIG9ubHkgc3VwcG9ydCAxIHNraW4gVE9ETzogcmVhbGx5P1xuXHRcdFx0aWYgKHRoaXMuZGVwZW5kZW5jaWVzLmxlbmd0aCA9PSAwKVxuXHRcdFx0XHR0aGlzLl9wQWRkRGVwZW5kZW5jeShuYW1lLCBuZXcgVVJMUmVxdWVzdCh1cmwpKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fbWF0ZXJpYWxOYW1lcy5sZW5ndGggPiAwKVxuXHRcdFx0dGhpcy5fbWVzaC5tYXRlcmlhbC5uYW1lID0gdGhpcy5fbWF0ZXJpYWxOYW1lc1swXTsgZWxzZVxuXHRcdFx0dGhpcy5tYXRlcmlhbEZpbmFsID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgdGhlIHV2IGRhdGEgZm9yIHRoZSBtZXNoLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVVWKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGo6bnVtYmVyIC8qdWludCovID0gMDtcblxuXHRcdHRoaXMuX3V2cyA9IG5ldyBBcnJheTxudW1iZXI+KHRoaXMuX251bVNUKjIpO1xuXHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uID0gdGhpcy5fb2Zmc2V0U1Q7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwOyBpIDwgdGhpcy5fbnVtU1Q7IGkrKykge1xuXHRcdFx0dGhpcy5fdXZzW2orK10gPSB0aGlzLl9ieXRlRGF0YS5yZWFkU2hvcnQoKS90aGlzLl9za2luV2lkdGg7XG5cdFx0XHR0aGlzLl91dnNbaisrXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRTaG9ydCgpL3RoaXMuX3NraW5IZWlnaHQ7XG5cdFx0fVxuXG5cdFx0dGhpcy5fcGFyc2VkVVYgPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBhcnNlcyB1bmlxdWUgaW5kaWNlcyBmb3IgdGhlIGZhY2VzLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZUZhY2VzKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGE6bnVtYmVyIC8qdWludCovLCBiOm51bWJlciAvKnVpbnQqLywgYzpudW1iZXIgLyp1aW50Ki8sIHRhOm51bWJlciAvKnVpbnQqLywgdGI6bnVtYmVyIC8qdWludCovLCB0YzpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXG5cdFx0dGhpcy5fdmVydEluZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdHRoaXMuX3V2SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0dGhpcy5faW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KCkgLyp1aW50Ki87XG5cblx0XHR0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiA9IHRoaXMuX29mZnNldFRyaXM7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgdGhpcy5fbnVtVHJpczsgaSsrKSB7XG5cdFx0XHQvL2NvbGxlY3QgdmVydGV4IGluZGljZXNcblx0XHRcdGEgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdFx0YiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRjID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblxuXHRcdFx0Ly9jb2xsZWN0IHV2IGluZGljZXNcblx0XHRcdHRhID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRcdHRiID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRcdHRjID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblxuXHRcdFx0dGhpcy5hZGRJbmRleChhLCB0YSk7XG5cdFx0XHR0aGlzLmFkZEluZGV4KGIsIHRiKTtcblx0XHRcdHRoaXMuYWRkSW5kZXgoYywgdGMpO1xuXHRcdH1cblxuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gdGhpcy5fdXZJbmRpY2VzLmxlbmd0aDtcblx0XHR0aGlzLl9maW5hbFVWID0gbmV3IEFycmF5PG51bWJlcj4obGVuKjIpO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG5cdFx0XHR0aGlzLl9maW5hbFVWW2kgPDwgMV0gPSB0aGlzLl91dnNbdGhpcy5fdXZJbmRpY2VzW2ldIDw8IDFdO1xuXHRcdFx0dGhpcy5fZmluYWxVVlsoaSA8PCAxKSArIDFdID0gdGhpcy5fdXZzWyh0aGlzLl91dkluZGljZXNbaV0gPDwgMSkgKyAxXTtcblx0XHR9XG5cblx0XHR0aGlzLl9wYXJzZWRGYWNlcyA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGZhY2UgaW5kZXggdG8gdGhlIGxpc3QgaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQsIGJhc2VkIG9uIHZlcnRleEluZGV4IGFuZCB1dkluZGV4LCBhbmQgYWRkcyB0aGVcblx0ICogY29ycmVzcG9uZGluZyB2ZXJ0ZXggYW5kIHV2IGRhdGEgaW4gdGhlIGNvcnJlY3QgbG9jYXRpb24uXG5cdCAqIEBwYXJhbSB2ZXJ0ZXhJbmRleCBUaGUgb3JpZ2luYWwgaW5kZXggaW4gdGhlIHZlcnRleCBsaXN0LlxuXHQgKiBAcGFyYW0gdXZJbmRleCBUaGUgb3JpZ2luYWwgaW5kZXggaW4gdGhlIHV2IGxpc3QuXG5cdCAqL1xuXHRwcml2YXRlIGFkZEluZGV4KHZlcnRleEluZGV4Om51bWJlciAvKnVpbnQqLywgdXZJbmRleDpudW1iZXIgLyp1aW50Ki8pOnZvaWRcblx0e1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IHRoaXMuZmluZEluZGV4KHZlcnRleEluZGV4LCB1dkluZGV4KTtcblxuXHRcdGlmIChpbmRleCA9PSAtMSkge1xuXHRcdFx0dGhpcy5faW5kaWNlcy5wdXNoKHRoaXMuX3ZlcnRJbmRpY2VzLmxlbmd0aCk7XG5cdFx0XHR0aGlzLl92ZXJ0SW5kaWNlcy5wdXNoKHZlcnRleEluZGV4KTtcblx0XHRcdHRoaXMuX3V2SW5kaWNlcy5wdXNoKHV2SW5kZXgpO1xuXHRcdH0gZWxzZVxuXHRcdFx0dGhpcy5faW5kaWNlcy5wdXNoKGluZGV4KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaW5kcyB0aGUgZmluYWwgaW5kZXggY29ycmVzcG9uZGluZyB0byB0aGUgb3JpZ2luYWwgTUQyJ3MgdmVydGV4IGFuZCB1diBpbmRpY2VzLiBSZXR1cm5zIC0xIGlmIGl0IHdhc24ndCBhZGRlZCB5ZXQuXG5cdCAqIEBwYXJhbSB2ZXJ0ZXhJbmRleCBUaGUgb3JpZ2luYWwgaW5kZXggaW4gdGhlIHZlcnRleCBsaXN0LlxuXHQgKiBAcGFyYW0gdXZJbmRleCBUaGUgb3JpZ2luYWwgaW5kZXggaW4gdGhlIHV2IGxpc3QuXG5cdCAqIEByZXR1cm4gVGhlIGluZGV4IG9mIHRoZSBmaW5hbCBtZXNoIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIHZlcnRleCBhbmQgdXYgaW5kZXguIC0xIGlmIGl0IGRvZXNuJ3QgZXhpc3QgeWV0LlxuXHQgKi9cblx0cHJpdmF0ZSBmaW5kSW5kZXgodmVydGV4SW5kZXg6bnVtYmVyIC8qdWludCovLCB1dkluZGV4Om51bWJlciAvKnVpbnQqLyk6bnVtYmVyIC8qaW50Ki9cblx0e1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovID0gdGhpcy5fdmVydEluZGljZXMubGVuZ3RoO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyp1aW50Ki8gPSAwOyBpIDwgbGVuOyArK2kpIHtcblx0XHRcdGlmICh0aGlzLl92ZXJ0SW5kaWNlc1tpXSA9PSB2ZXJ0ZXhJbmRleCAmJiB0aGlzLl91dkluZGljZXNbaV0gPT0gdXZJbmRleClcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBhcnNlcyBhbGwgdGhlIGZyYW1lIGdlb21ldHJpZXMuXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlRnJhbWVzKCk6dm9pZFxuXHR7XG5cdFx0dmFyIHN4Om51bWJlciwgc3k6bnVtYmVyLCBzejpudW1iZXI7XG5cdFx0dmFyIHR4Om51bWJlciwgdHk6bnVtYmVyLCB0ejpudW1iZXI7XG5cdFx0dmFyIGdlb21ldHJ5Okdlb21ldHJ5O1xuXHRcdHZhciBzdWJHZW9tOlRyaWFuZ2xlU3ViR2VvbWV0cnk7XG5cdFx0dmFyIHZlcnRMZW46bnVtYmVyIC8qdWludCovID0gdGhpcy5fdmVydEluZGljZXMubGVuZ3RoO1xuXHRcdHZhciBmdmVydGljZXM6QXJyYXk8bnVtYmVyPjtcblx0XHR2YXIgdHZlcnRpY2VzOkFycmF5PG51bWJlcj47XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovLCBqOm51bWJlciAvKmludCovLCBrOm51bWJlciAvKnVpbnQqLztcblx0XHQvL3ZhciBjaCA6IG51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgbmFtZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBwcmV2Q2xpcDpWZXJ0ZXhDbGlwTm9kZSA9IG51bGw7XG5cblx0XHR0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiA9IHRoaXMuX29mZnNldEZyYW1lcztcblxuXHRcdGZvciAoaSA9IDA7IGkgPCB0aGlzLl9udW1GcmFtZXM7IGkrKykge1xuXG5cdFx0XHR0dmVydGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdFx0ZnZlcnRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4odmVydExlbiozKTtcblxuXHRcdFx0c3ggPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKTtcblx0XHRcdHN5ID0gdGhpcy5fYnl0ZURhdGEucmVhZEZsb2F0KCk7XG5cdFx0XHRzeiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXG5cdFx0XHR0eCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdFx0dHkgPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKTtcblx0XHRcdHR6ID0gdGhpcy5fYnl0ZURhdGEucmVhZEZsb2F0KCk7XG5cblx0XHRcdG5hbWUgPSB0aGlzLnJlYWRGcmFtZU5hbWUoKTtcblxuXHRcdFx0Ly8gTm90ZSwgdGhlIGV4dHJhIGRhdGEucG9zaXRpb24rKyBpbiB0aGUgZm9yIGxvb3AgaXMgdGhlcmVcblx0XHRcdC8vIHRvIHNraXAgb3ZlciBhIGJ5dGUgdGhhdCBob2xkcyB0aGUgXCJ2ZXJ0ZXggbm9ybWFsIGluZGV4XCJcblx0XHRcdGZvciAoaiA9IDA7IGogPCB0aGlzLl9udW1WZXJ0aWNlczsgaisrLCB0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbisrKVxuXHRcdFx0XHR0dmVydGljZXMucHVzaChzeCp0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRCeXRlKCkgKyB0eCwgc3kqdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpICsgdHksIHN6KnRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZEJ5dGUoKSArIHR6KTtcblxuXHRcdFx0ayA9IDA7XG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgdmVydExlbjsgaisrKSB7XG5cdFx0XHRcdGZ2ZXJ0aWNlc1trKytdID0gdHZlcnRpY2VzW3RoaXMuX3ZlcnRJbmRpY2VzW2pdKjNdO1xuXHRcdFx0XHRmdmVydGljZXNbaysrXSA9IHR2ZXJ0aWNlc1t0aGlzLl92ZXJ0SW5kaWNlc1tqXSozICsgMl07XG5cdFx0XHRcdGZ2ZXJ0aWNlc1trKytdID0gdHZlcnRpY2VzW3RoaXMuX3ZlcnRJbmRpY2VzW2pdKjMgKyAxXTtcblx0XHRcdH1cblxuXHRcdFx0c3ViR2VvbSA9IG5ldyBUcmlhbmdsZVN1Ykdlb21ldHJ5KHRydWUpO1xuXG5cdFx0XHRpZiAodGhpcy5fZmlyc3RTdWJHZW9tID09IG51bGwpXG5cdFx0XHRcdHRoaXMuX2ZpcnN0U3ViR2VvbSA9IHN1Ykdlb207XG5cblx0XHRcdGdlb21ldHJ5ID0gbmV3IEdlb21ldHJ5KCk7XG5cdFx0XHRnZW9tZXRyeS5hZGRTdWJHZW9tZXRyeShzdWJHZW9tKTtcblxuXHRcdFx0c3ViR2VvbS51cGRhdGVJbmRpY2VzKHRoaXMuX2luZGljZXMpO1xuXHRcdFx0c3ViR2VvbS51cGRhdGVQb3NpdGlvbnMoZnZlcnRpY2VzKTtcblx0XHRcdHN1Ykdlb20udXBkYXRlVVZzKHRoaXMuX2ZpbmFsVVYpO1xuXHRcdFx0c3ViR2VvbS52ZXJ0ZXhOb3JtYWxzO1xuXHRcdFx0c3ViR2VvbS52ZXJ0ZXhUYW5nZW50cztcblx0XHRcdHN1Ykdlb20uYXV0b0Rlcml2ZU5vcm1hbHMgPSBmYWxzZTtcblx0XHRcdHN1Ykdlb20uYXV0b0Rlcml2ZVRhbmdlbnRzID0gZmFsc2U7XG5cblx0XHRcdHZhciBjbGlwOlZlcnRleENsaXBOb2RlID0gdGhpcy5fY2xpcE5vZGVzW25hbWVdO1xuXG5cdFx0XHRpZiAoIWNsaXApIHtcblx0XHRcdFx0Ly8gSWYgYW5vdGhlciBzZXF1ZW5jZSB3YXMgcGFyc2VkIGJlZm9yZSB0aGlzIG9uZSwgc3RhcnRpbmdcblx0XHRcdFx0Ly8gYSBuZXcgc3RhdGUgbWVhbnMgdGhlIHByZXZpb3VzIG9uZSBpcyBjb21wbGV0ZSBhbmQgY2FuXG5cdFx0XHRcdC8vIGhlbmNlIGJlIGZpbmFsaXplZC5cblx0XHRcdFx0aWYgKHByZXZDbGlwKSB7XG5cdFx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQocHJldkNsaXApO1xuXHRcdFx0XHRcdHRoaXMuX2FuaW1hdGlvblNldC5hZGRBbmltYXRpb24ocHJldkNsaXApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y2xpcCA9IG5ldyBWZXJ0ZXhDbGlwTm9kZSgpO1xuXHRcdFx0XHRjbGlwLm5hbWUgPSBuYW1lO1xuXHRcdFx0XHRjbGlwLnN0aXRjaEZpbmFsRnJhbWUgPSB0cnVlO1xuXG5cdFx0XHRcdHRoaXMuX2NsaXBOb2Rlc1tuYW1lXSA9IGNsaXA7XG5cblx0XHRcdFx0cHJldkNsaXAgPSBjbGlwO1xuXHRcdFx0fVxuXHRcdFx0Y2xpcC5hZGRGcmFtZShnZW9tZXRyeSwgMTAwMC9NRDJQYXJzZXIuRlBTKTtcblx0XHR9XG5cblx0XHQvLyBGaW5hbGl6ZSB0aGUgbGFzdCBzdGF0ZVxuXHRcdGlmIChwcmV2Q2xpcCkge1xuXHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQocHJldkNsaXApO1xuXHRcdFx0dGhpcy5fYW5pbWF0aW9uU2V0LmFkZEFuaW1hdGlvbihwcmV2Q2xpcCk7XG5cdFx0fVxuXG5cdFx0Ly8gRm9yY2UgdGhpcy5fcEZpbmFsaXplQXNzZXQoKSB0byBkZWNpZGUgbmFtZVxuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX2FuaW1hdGlvblNldCk7XG5cblx0XHR0aGlzLl9wYXJzZWRGcmFtZXMgPSB0cnVlO1xuXHR9XG5cblx0cHJpdmF0ZSByZWFkRnJhbWVOYW1lKCk6c3RyaW5nXG5cdHtcblx0XHR2YXIgbmFtZTpzdHJpbmcgPSBcIlwiO1xuXHRcdHZhciBrOm51bWJlciAvKnVpbnQqLyA9IDA7XG5cdFx0Zm9yICh2YXIgajpudW1iZXIgLyp1aW50Ki8gPSAwOyBqIDwgMTY7IGorKykge1xuXHRcdFx0dmFyIGNoOm51bWJlciAvKnVpbnQqLyA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZEJ5dGUoKTtcblxuXHRcdFx0aWYgKE1hdGguZmxvb3IoY2gpID4gMHgzOSAmJiBNYXRoLmZsb29yKGNoKSA8PSAweDdBICYmIGsgPT0gMClcblx0XHRcdFx0bmFtZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKTtcblxuXHRcdFx0aWYgKE1hdGguZmxvb3IoY2gpID49IDB4MzAgJiYgTWF0aC5mbG9vcihjaCkgPD0gMHgzOSlcblx0XHRcdFx0aysrO1xuXHRcdH1cblx0XHRyZXR1cm4gbmFtZTtcblx0fVxufVxuXG5leHBvcnQgPSBNRDJQYXJzZXI7Il19 \ No newline at end of file diff --git a/lib/parsers/MD2Parser.ts b/lib/parsers/MD2Parser.ts new file mode 100644 index 000000000..bdeb0811c --- /dev/null +++ b/lib/parsers/MD2Parser.ts @@ -0,0 +1,509 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import BitmapData = require("awayjs-core/lib/core/base/BitmapData"); +import DisplayObject = require("awayjs-core/lib/core/base/DisplayObject"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +import Camera = require("awayjs-core/lib/entities/Camera"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +import ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +import ResourceDependency = require("awayjs-core/lib/parsers/ResourceDependency"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); +import ByteArray = require("awayjs-core/lib/utils/ByteArray"); + +import DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +import TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); + +import VertexClipNode = require("awayjs-renderergl/lib/animators/nodes/VertexClipNode"); +import VertexAnimationSet = require("awayjs-renderergl/lib/animators/VertexAnimationSet"); + +/** + * MD2Parser provides a parser for the MD2 data type. + */ +class MD2Parser extends ParserBase +{ + public static FPS:number /*int*/ = 6; + + private _clipNodes:Object = new Object(); + private _byteData:ByteArray; + private _startedParsing:boolean; + private _parsedHeader:boolean; + private _parsedUV:boolean; + private _parsedFaces:boolean; + private _parsedFrames:boolean; + + private _ident:number /*uint*/; + private _version:number /*uint*/; + private _skinWidth:number /*uint*/; + private _skinHeight:number /*uint*/; + //private _frameSize : number /*uint*/; + private _numSkins:number /*uint*/; + private _numVertices:number /*uint*/; + private _numST:number /*uint*/; + private _numTris:number /*uint*/; + //private _numGlCmds : number /*uint*/; + private _numFrames:number /*uint*/; + private _offsetSkins:number /*uint*/; + private _offsetST:number /*uint*/; + private _offsetTris:number /*uint*/; + private _offsetFrames:number /*uint*/; + //private _offsetGlCmds : number /*uint*/; + private _offsetEnd:number /*uint*/; + + private _uvIndices:Array; + private _indices:Array /*uint*/; + private _vertIndices:Array; + + // the current subgeom being built + private _animationSet:VertexAnimationSet = new VertexAnimationSet(); + private _firstSubGeom:TriangleSubGeometry; + private _uvs:Array; + private _finalUV:Array; + + private _materialNames:Array; + private _textureType:string; + private _ignoreTexturePath:boolean; + private _mesh:Mesh; + private _geometry:Geometry; + + private materialFinal:boolean = false; + private geoCreated:boolean = false; + + /** + * Creates a new MD2Parser object. + * @param textureType The extension of the texture (e.g. jpg/png/...) + * @param ignoreTexturePath If true, the path of the texture is ignored + */ + constructor(textureType:string = "jpg", ignoreTexturePath:boolean = true) + { + super(URLLoaderDataFormat.ARRAY_BUFFER); + this._textureType = textureType; + this._ignoreTexturePath = ignoreTexturePath; + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "md2"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + return (ParserUtils.toString(data, 4) == 'IDP2'); + } + + /** + * @inheritDoc + */ + public _iResolveDependency(resourceDependency:ResourceDependency):void + { + if (resourceDependency.assets.length != 1) + return; + + var asset:Texture2DBase = resourceDependency.assets[0]; + + if (asset) { + var material:TriangleMethodMaterial = new TriangleMethodMaterial(asset); + + if (this.materialMode >= 2) + material.materialMode = TriangleMaterialMode.MULTI_PASS; + + //add to the content property + ( this._pContent).addChild(this._mesh); + + material.name = this._mesh.material.name; + this._mesh.material = material; + this._pFinalizeAsset(material); + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + } + this.materialFinal = true; + } + + /** + * @inheritDoc + */ + public _iResolveDependencyFailure(resourceDependency:ResourceDependency):void + { + // apply system default + if (this.materialMode < 2) { + this._mesh.material = DefaultMaterialManager.getDefaultMaterial(); + } else { + this._mesh.material = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + ( this._mesh.material).materialMode = TriangleMaterialMode.MULTI_PASS; + } + + //add to the content property + ( this._pContent).addChild(this._mesh); + + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + this.materialFinal = true; + + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + if (!this._startedParsing) { + this._byteData = this._pGetByteData(); + this._startedParsing = true; + + // Reset bytearray read position (which may have been + // moved forward by the supportsData() function.) + this._byteData.position = 0; + } + + while (this._pHasTime()) { + if (!this._parsedHeader) { + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN; + + // TODO: Create a mesh only when encountered (if it makes sense + // for this file format) and return it using this._pFinalizeAsset() + this._geometry = new Geometry(); + this._mesh = new Mesh(this._geometry, null); + if (this.materialMode < 2) { + this._mesh.material = DefaultMaterialManager.getDefaultMaterial(); + } else { + this._mesh.material = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + ( this._mesh.material).materialMode = TriangleMaterialMode.MULTI_PASS; + } + + //_geometry.animation = new VertexAnimation(2, VertexAnimationMode.ABSOLUTE); + //_animator = new VertexAnimator(VertexAnimationState(_mesh.animationState)); + + // Parse header and decompress body + this.parseHeader(); + this.parseMaterialNames(); + } else if (!this._parsedUV) { + this.parseUV(); + } else if (!this._parsedFaces) { + this.parseFaces(); + } else if (!this._parsedFrames) { + this.parseFrames(); + } else if ((this.geoCreated) && (this.materialFinal)) { + return ParserBase.PARSING_DONE; + } else if (!this.geoCreated) { + this.geoCreated = true; + //create default subgeometry + this._geometry.addSubGeometry(this._firstSubGeom.clone()); + // Force name to be chosen by this._pFinalizeAsset() + this._mesh.name = ""; + if (this.materialFinal) { + //add to the content property + ( this._pContent).addChild(this._mesh); + + this._pFinalizeAsset(this._mesh.geometry); + this._pFinalizeAsset(this._mesh); + } + + this._pPauseAndRetrieveDependencies(); + } + } + + return ParserBase.MORE_TO_PARSE; + } + + public _pStartParsing(frameLimit:number) + { + super._pStartParsing(frameLimit); + + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + } + + /** + * Reads in all that MD2 Header data that is declared as private variables. + * I know its a lot, and it looks ugly, but only way to do it in Flash + */ + private parseHeader():void + { + this._ident = this._byteData.readInt(); + this._version = this._byteData.readInt(); + this._skinWidth = this._byteData.readInt(); + this._skinHeight = this._byteData.readInt(); + //skip this._frameSize + this._byteData.readInt(); + this._numSkins = this._byteData.readInt(); + this._numVertices = this._byteData.readInt(); + this._numST = this._byteData.readInt(); + this._numTris = this._byteData.readInt(); + //skip this._numGlCmds + this._byteData.readInt(); + this._numFrames = this._byteData.readInt(); + this._offsetSkins = this._byteData.readInt(); + this._offsetST = this._byteData.readInt(); + this._offsetTris = this._byteData.readInt(); + this._offsetFrames = this._byteData.readInt(); + //skip this._offsetGlCmds + this._byteData.readInt(); + this._offsetEnd = this._byteData.readInt(); + + this._parsedHeader = true; + } + + /** + * Parses the file names for the materials. + */ + private parseMaterialNames():void + { + var url:string; + var name:string; + var extIndex:number /*int*/; + var slashIndex:number /*int*/; + this._materialNames = new Array(); + this._byteData.position = this._offsetSkins; + + var regExp:RegExp = new RegExp("[^a-zA-Z0-9\\_\/.]", "g"); + for (var i:number /*uint*/ = 0; i < this._numSkins; ++i) { + name = this._byteData.readUTFBytes(64); + name = name.replace(regExp, ""); + extIndex = name.lastIndexOf("."); + if (this._ignoreTexturePath) + slashIndex = name.lastIndexOf("/"); + if (name.toLowerCase().indexOf(".jpg") == -1 && name.toLowerCase().indexOf(".png") == -1) { + name = name.substring(slashIndex + 1, extIndex); + url = name + "." + this._textureType; + } else { + url = name; + } + + this._materialNames[i] = name; + + // only support 1 skin TODO: really? + if (this.dependencies.length == 0) + this._pAddDependency(name, new URLRequest(url)); + } + + if (this._materialNames.length > 0) + this._mesh.material.name = this._materialNames[0]; else + this.materialFinal = true; + } + + /** + * Parses the uv data for the mesh. + */ + private parseUV():void + { + var j:number /*uint*/ = 0; + + this._uvs = new Array(this._numST*2); + this._byteData.position = this._offsetST; + for (var i:number /*uint*/ = 0; i < this._numST; i++) { + this._uvs[j++] = this._byteData.readShort()/this._skinWidth; + this._uvs[j++] = this._byteData.readShort()/this._skinHeight; + } + + this._parsedUV = true; + } + + /** + * Parses unique indices for the faces. + */ + private parseFaces():void + { + var a:number /*uint*/, b:number /*uint*/, c:number /*uint*/, ta:number /*uint*/, tb:number /*uint*/, tc:number /*uint*/; + var i:number /*uint*/; + + this._vertIndices = new Array(); + this._uvIndices = new Array(); + this._indices = new Array() /*uint*/; + + this._byteData.position = this._offsetTris; + + for (i = 0; i < this._numTris; i++) { + //collect vertex indices + a = this._byteData.readUnsignedShort(); + b = this._byteData.readUnsignedShort(); + c = this._byteData.readUnsignedShort(); + + //collect uv indices + ta = this._byteData.readUnsignedShort(); + tb = this._byteData.readUnsignedShort(); + tc = this._byteData.readUnsignedShort(); + + this.addIndex(a, ta); + this.addIndex(b, tb); + this.addIndex(c, tc); + } + + var len:number /*uint*/ = this._uvIndices.length; + this._finalUV = new Array(len*2); + + for (i = 0; i < len; ++i) { + this._finalUV[i << 1] = this._uvs[this._uvIndices[i] << 1]; + this._finalUV[(i << 1) + 1] = this._uvs[(this._uvIndices[i] << 1) + 1]; + } + + this._parsedFaces = true; + } + + /** + * Adds a face index to the list if it doesn't exist yet, based on vertexIndex and uvIndex, and adds the + * corresponding vertex and uv data in the correct location. + * @param vertexIndex The original index in the vertex list. + * @param uvIndex The original index in the uv list. + */ + private addIndex(vertexIndex:number /*uint*/, uvIndex:number /*uint*/):void + { + var index:number /*int*/ = this.findIndex(vertexIndex, uvIndex); + + if (index == -1) { + this._indices.push(this._vertIndices.length); + this._vertIndices.push(vertexIndex); + this._uvIndices.push(uvIndex); + } else + this._indices.push(index); + } + + /** + * Finds the final index corresponding to the original MD2's vertex and uv indices. Returns -1 if it wasn't added yet. + * @param vertexIndex The original index in the vertex list. + * @param uvIndex The original index in the uv list. + * @return The index of the final mesh corresponding to the original vertex and uv index. -1 if it doesn't exist yet. + */ + private findIndex(vertexIndex:number /*uint*/, uvIndex:number /*uint*/):number /*int*/ + { + var len:number /*uint*/ = this._vertIndices.length; + + for (var i:number /*uint*/ = 0; i < len; ++i) { + if (this._vertIndices[i] == vertexIndex && this._uvIndices[i] == uvIndex) + return i; + } + + return -1; + } + + /** + * Parses all the frame geometries. + */ + private parseFrames():void + { + var sx:number, sy:number, sz:number; + var tx:number, ty:number, tz:number; + var geometry:Geometry; + var subGeom:TriangleSubGeometry; + var vertLen:number /*uint*/ = this._vertIndices.length; + var fvertices:Array; + var tvertices:Array; + var i:number /*uint*/, j:number /*int*/, k:number /*uint*/; + //var ch : number /*uint*/; + var name:string = ""; + var prevClip:VertexClipNode = null; + + this._byteData.position = this._offsetFrames; + + for (i = 0; i < this._numFrames; i++) { + + tvertices = new Array(); + fvertices = new Array(vertLen*3); + + sx = this._byteData.readFloat(); + sy = this._byteData.readFloat(); + sz = this._byteData.readFloat(); + + tx = this._byteData.readFloat(); + ty = this._byteData.readFloat(); + tz = this._byteData.readFloat(); + + name = this.readFrameName(); + + // Note, the extra data.position++ in the for loop is there + // to skip over a byte that holds the "vertex normal index" + for (j = 0; j < this._numVertices; j++, this._byteData.position++) + tvertices.push(sx*this._byteData.readUnsignedByte() + tx, sy*this._byteData.readUnsignedByte() + ty, sz*this._byteData.readUnsignedByte() + tz); + + k = 0; + for (j = 0; j < vertLen; j++) { + fvertices[k++] = tvertices[this._vertIndices[j]*3]; + fvertices[k++] = tvertices[this._vertIndices[j]*3 + 2]; + fvertices[k++] = tvertices[this._vertIndices[j]*3 + 1]; + } + + subGeom = new TriangleSubGeometry(true); + + if (this._firstSubGeom == null) + this._firstSubGeom = subGeom; + + geometry = new Geometry(); + geometry.addSubGeometry(subGeom); + + subGeom.updateIndices(this._indices); + subGeom.updatePositions(fvertices); + subGeom.updateUVs(this._finalUV); + subGeom.vertexNormals; + subGeom.vertexTangents; + subGeom.autoDeriveNormals = false; + subGeom.autoDeriveTangents = false; + + var clip:VertexClipNode = this._clipNodes[name]; + + if (!clip) { + // If another sequence was parsed before this one, starting + // a new state means the previous one is complete and can + // hence be finalized. + if (prevClip) { + this._pFinalizeAsset(prevClip); + this._animationSet.addAnimation(prevClip); + } + + clip = new VertexClipNode(); + clip.name = name; + clip.stitchFinalFrame = true; + + this._clipNodes[name] = clip; + + prevClip = clip; + } + clip.addFrame(geometry, 1000/MD2Parser.FPS); + } + + // Finalize the last state + if (prevClip) { + this._pFinalizeAsset(prevClip); + this._animationSet.addAnimation(prevClip); + } + + // Force this._pFinalizeAsset() to decide name + this._pFinalizeAsset(this._animationSet); + + this._parsedFrames = true; + } + + private readFrameName():string + { + var name:string = ""; + var k:number /*uint*/ = 0; + for (var j:number /*uint*/ = 0; j < 16; j++) { + var ch:number /*uint*/ = this._byteData.readUnsignedByte(); + + if (Math.floor(ch) > 0x39 && Math.floor(ch) <= 0x7A && k == 0) + name += String.fromCharCode(ch); + + if (Math.floor(ch) >= 0x30 && Math.floor(ch) <= 0x39) + k++; + } + return name; + } +} + +export = MD2Parser; \ No newline at end of file diff --git a/lib/parsers/MD5AnimParser.js b/lib/parsers/MD5AnimParser.js new file mode 100755 index 000000000..8cf1968db --- /dev/null +++ b/lib/parsers/MD5AnimParser.js @@ -0,0 +1,492 @@ +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 Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var JointPose = require("awayjs-renderergl/lib/animators/data/JointPose"); +var SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose"); +var SkeletonClipNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonClipNode"); +var BaseFrameData = require("awayjs-renderergl/lib/parsers/data/BaseFrameData"); +var BoundsData = require("awayjs-renderergl/lib/parsers/data/BoundsData"); +var FrameData = require("awayjs-renderergl/lib/parsers/data/FrameData"); +var HierarchyData = require("awayjs-renderergl/lib/parsers/data/HierarchyData"); +/** + * MD5AnimParser provides a parser for the md5anim data type, providing an animation sequence for the md5 format. + * + * todo: optimize + */ +var MD5AnimParser = (function (_super) { + __extends(MD5AnimParser, _super); + /** + * Creates a new MD5AnimParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + function MD5AnimParser(additionalRotationAxis, additionalRotationRadians) { + if (additionalRotationAxis === void 0) { additionalRotationAxis = null; } + if (additionalRotationRadians === void 0) { additionalRotationRadians = 0; } + _super.call(this, URLLoaderDataFormat.TEXT); + this._parseIndex = 0; + this._line = 0; + this._charLineIndex = 0; + this._rotationQuat = new Quaternion(); + var t1 = new Quaternion(); + var t2 = new Quaternion(); + t1.fromAxisAngle(Vector3D.X_AXIS, -Math.PI * .5); + t2.fromAxisAngle(Vector3D.Y_AXIS, -Math.PI * .5); + this._rotationQuat.multiply(t2, t1); + if (additionalRotationAxis) { + this._rotationQuat.multiply(t2, t1); + t1.fromAxisAngle(additionalRotationAxis, additionalRotationRadians); + this._rotationQuat.multiply(t1, this._rotationQuat); + } + } + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + MD5AnimParser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "md5anim"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + MD5AnimParser.supportsData = function (data) { + return false; + }; + /** + * @inheritDoc + */ + MD5AnimParser.prototype._pProceedParsing = function () { + var token; + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + this._startedParsing = true; + } + while (this._pHasTime()) { + token = this.getNextToken(); + switch (token) { + case MD5AnimParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case "": + break; + case MD5AnimParser.VERSION_TOKEN: + this._version = this.getNextInt(); + if (this._version != 10) + throw new Error("Unknown version number encountered!"); + break; + case MD5AnimParser.COMMAND_LINE_TOKEN: + this.parseCMD(); + break; + case MD5AnimParser.NUM_FRAMES_TOKEN: + this._numFrames = this.getNextInt(); + this._bounds = new Array(); + this._frameData = new Array(); + break; + case MD5AnimParser.NUM_JOINTS_TOKEN: + this._numJoints = this.getNextInt(); + this._hierarchy = new Array(this._numJoints); + this._baseFrameData = new Array(this._numJoints); + break; + case MD5AnimParser.FRAME_RATE_TOKEN: + this._frameRate = this.getNextInt(); + break; + case MD5AnimParser.NUM_ANIMATED_COMPONENTS_TOKEN: + this._numAnimatedComponents = this.getNextInt(); + break; + case MD5AnimParser.HIERARCHY_TOKEN: + this.parseHierarchy(); + break; + case MD5AnimParser.BOUNDS_TOKEN: + this.parseBounds(); + break; + case MD5AnimParser.BASE_FRAME_TOKEN: + this.parseBaseFrame(); + break; + case MD5AnimParser.FRAME_TOKEN: + this.parseFrame(); + break; + default: + if (!this._reachedEOF) + this.sendUnknownKeywordError(); + } + if (this._reachedEOF) { + this._clip = new SkeletonClipNode(); + this.translateClip(); + this._pFinalizeAsset(this._clip); + return ParserBase.PARSING_DONE; + } + } + return ParserBase.MORE_TO_PARSE; + }; + /** + * Converts all key frame data to an SkinnedAnimationSequence. + */ + MD5AnimParser.prototype.translateClip = function () { + for (var i = 0; i < this._numFrames; ++i) + this._clip.addFrame(this.translatePose(this._frameData[i]), 1000 / this._frameRate); + }; + /** + * Converts a single key frame data to a SkeletonPose. + * @param frameData The actual frame data. + * @return A SkeletonPose containing the frame data's pose. + */ + MD5AnimParser.prototype.translatePose = function (frameData) { + var hierarchy; + var pose; + var base; + var flags /*int*/; + var j /*int*/; + var translate = new Vector3D(); + var orientation = new Quaternion(); + var components = frameData.components; + var skelPose = new SkeletonPose(); + var jointPoses = skelPose.jointPoses; + for (var i = 0; i < this._numJoints; ++i) { + j = 0; + pose = new JointPose(); + hierarchy = this._hierarchy[i]; + base = this._baseFrameData[i]; + flags = hierarchy.flags; + translate.x = base.position.x; + translate.y = base.position.y; + translate.z = base.position.z; + orientation.x = base.orientation.x; + orientation.y = base.orientation.y; + orientation.z = base.orientation.z; + if (flags & 1) + translate.x = components[hierarchy.startIndex + (j++)]; + if (flags & 2) + translate.y = components[hierarchy.startIndex + (j++)]; + if (flags & 4) + translate.z = components[hierarchy.startIndex + (j++)]; + if (flags & 8) + orientation.x = components[hierarchy.startIndex + (j++)]; + if (flags & 16) + orientation.y = components[hierarchy.startIndex + (j++)]; + if (flags & 32) + orientation.z = components[hierarchy.startIndex + (j++)]; + var w = 1 - orientation.x * orientation.x - orientation.y * orientation.y - orientation.z * orientation.z; + orientation.w = w < 0 ? 0 : -Math.sqrt(w); + if (hierarchy.parentIndex < 0) { + pose.orientation.multiply(this._rotationQuat, orientation); + pose.translation = this._rotationQuat.rotatePoint(translate); + } + else { + pose.orientation.copyFrom(orientation); + pose.translation.x = translate.x; + pose.translation.y = translate.y; + pose.translation.z = translate.z; + } + pose.orientation.y = -pose.orientation.y; + pose.orientation.z = -pose.orientation.z; + pose.translation.x = -pose.translation.x; + jointPoses[i] = pose; + } + return skelPose; + }; + /** + * Parses the skeleton's hierarchy data. + */ + MD5AnimParser.prototype.parseHierarchy = function () { + var ch; + var data; + var token = this.getNextToken(); + var i = 0; + if (token != "{") + this.sendUnknownKeywordError(); + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new HierarchyData(); + data.name = this.parseLiteralstring(); + data.parentIndex = this.getNextInt(); + data.flags = this.getNextInt(); + data.startIndex = this.getNextInt(); + this._hierarchy[i++] = data; + ch = this.getNextChar(); + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + if (ch != "}") + this.putBack(); + } while (ch != "}"); + }; + /** + * Parses frame bounds. + */ + MD5AnimParser.prototype.parseBounds = function () { + var ch; + var data; + var token = this.getNextToken(); + var i = 0; + if (token != "{") + this.sendUnknownKeywordError(); + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new BoundsData(); + data.min = this.parseVector3D(); + data.max = this.parseVector3D(); + this._bounds[i++] = data; + ch = this.getNextChar(); + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + if (ch != "}") + this.putBack(); + } while (ch != "}"); + }; + /** + * Parses the base frame. + */ + MD5AnimParser.prototype.parseBaseFrame = function () { + var ch; + var data; + var token = this.getNextToken(); + var i = 0; + if (token != "{") + this.sendUnknownKeywordError(); + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new BaseFrameData(); + data.position = this.parseVector3D(); + data.orientation = this.parseQuaternion(); + this._baseFrameData[i++] = data; + ch = this.getNextChar(); + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + if (ch != "}") + this.putBack(); + } while (ch != "}"); + }; + /** + * Parses a single frame. + */ + MD5AnimParser.prototype.parseFrame = function () { + var ch; + var data; + var token; + var frameIndex /*int*/; + frameIndex = this.getNextInt(); + token = this.getNextToken(); + if (token != "{") + this.sendUnknownKeywordError(); + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new FrameData(); + data.components = new Array(this._numAnimatedComponents); + for (var i = 0; i < this._numAnimatedComponents; ++i) + data.components[i] = this.getNextNumber(); + this._frameData[frameIndex] = data; + ch = this.getNextChar(); + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + if (ch != "}") + this.putBack(); + } while (ch != "}"); + }; + /** + * Puts back the last read character into the data stream. + */ + MD5AnimParser.prototype.putBack = function () { + this._parseIndex--; + this._charLineIndex--; + this._reachedEOF = this._parseIndex >= this._textData.length; + }; + /** + * Gets the next token in the data stream. + */ + MD5AnimParser.prototype.getNextToken = function () { + var ch; + var token = ""; + while (!this._reachedEOF) { + ch = this.getNextChar(); + if (ch == " " || ch == "\r" || ch == "\n" || ch == "\t") { + if (token != MD5AnimParser.COMMENT_TOKEN) + this.skipWhiteSpace(); + if (token != "") + return token; + } + else + token += ch; + if (token == MD5AnimParser.COMMENT_TOKEN) + return token; + } + return token; + }; + /** + * Skips all whitespace in the data stream. + */ + MD5AnimParser.prototype.skipWhiteSpace = function () { + var ch; + do + ch = this.getNextChar(); + while (ch == "\n" || ch == " " || ch == "\r" || ch == "\t"); + this.putBack(); + }; + /** + * Skips to the next line. + */ + MD5AnimParser.prototype.ignoreLine = function () { + var ch; + while (!this._reachedEOF && ch != "\n") + ch = this.getNextChar(); + }; + /** + * Retrieves the next single character in the data stream. + */ + MD5AnimParser.prototype.getNextChar = function () { + var ch = this._textData.charAt(this._parseIndex++); + if (ch == "\n") { + ++this._line; + this._charLineIndex = 0; + } + else if (ch != "\r") + ++this._charLineIndex; + if (this._parseIndex == this._textData.length) + this._reachedEOF = true; + return ch; + }; + /** + * Retrieves the next integer in the data stream. + */ + MD5AnimParser.prototype.getNextInt = function () { + var i = parseInt(this.getNextToken()); + if (isNaN(i)) + this.sendParseError("int type"); + return i; + }; + /** + * Retrieves the next floating point number in the data stream. + */ + MD5AnimParser.prototype.getNextNumber = function () { + var f = parseFloat(this.getNextToken()); + if (isNaN(f)) + this.sendParseError("float type"); + return f; + }; + /** + * Retrieves the next 3d vector in the data stream. + */ + MD5AnimParser.prototype.parseVector3D = function () { + var vec = new Vector3D(); + var ch = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + vec.x = this.getNextNumber(); + vec.y = this.getNextNumber(); + vec.z = this.getNextNumber(); + if (this.getNextToken() != ")") + this.sendParseError(")"); + return vec; + }; + /** + * Retrieves the next quaternion in the data stream. + */ + MD5AnimParser.prototype.parseQuaternion = function () { + var quat = new Quaternion(); + var ch = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + quat.x = this.getNextNumber(); + quat.y = this.getNextNumber(); + quat.z = this.getNextNumber(); + // quat supposed to be unit length + var t = 1 - (quat.x * quat.x) - (quat.y * quat.y) - (quat.z * quat.z); + quat.w = t < 0 ? 0 : -Math.sqrt(t); + if (this.getNextToken() != ")") + this.sendParseError(")"); + return quat; + }; + /** + * Parses the command line data. + */ + MD5AnimParser.prototype.parseCMD = function () { + // just ignore the command line property + this.parseLiteralstring(); + }; + /** + * Retrieves the next literal string in the data stream. A literal string is a sequence of characters bounded + * by double quotes. + */ + MD5AnimParser.prototype.parseLiteralstring = function () { + this.skipWhiteSpace(); + var ch = this.getNextChar(); + var str = ""; + if (ch != "\"") + this.sendParseError("\""); + do { + if (this._reachedEOF) + this.sendEOFError(); + ch = this.getNextChar(); + if (ch != "\"") + str += ch; + } while (ch != "\""); + return str; + }; + /** + * Throws an end-of-file error when a premature end of file was encountered. + */ + MD5AnimParser.prototype.sendEOFError = function () { + throw new Error("Unexpected end of file"); + }; + /** + * Throws an error when an unexpected token was encountered. + * @param expected The token type that was actually expected. + */ + MD5AnimParser.prototype.sendParseError = function (expected) { + throw new Error("Unexpected token at line " + (this._line + 1) + ", character " + this._charLineIndex + ". " + expected + " expected, but " + this._textData.charAt(this._parseIndex - 1) + " encountered"); + }; + /** + * Throws an error when an unknown keyword was encountered. + */ + MD5AnimParser.prototype.sendUnknownKeywordError = function () { + throw new Error("Unknown keyword at line " + (this._line + 1) + ", character " + this._charLineIndex + ". "); + }; + MD5AnimParser.VERSION_TOKEN = "MD5Version"; + MD5AnimParser.COMMAND_LINE_TOKEN = "commandline"; + MD5AnimParser.NUM_FRAMES_TOKEN = "numFrames"; + MD5AnimParser.NUM_JOINTS_TOKEN = "numJoints"; + MD5AnimParser.FRAME_RATE_TOKEN = "frameRate"; + MD5AnimParser.NUM_ANIMATED_COMPONENTS_TOKEN = "numAnimatedComponents"; + MD5AnimParser.HIERARCHY_TOKEN = "hierarchy"; + MD5AnimParser.BOUNDS_TOKEN = "bounds"; + MD5AnimParser.BASE_FRAME_TOKEN = "baseframe"; + MD5AnimParser.FRAME_TOKEN = "frame"; + MD5AnimParser.COMMENT_TOKEN = "//"; + return MD5AnimParser; +})(ParserBase); +module.exports = MD5AnimParser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvbWQ1YW5pbXBhcnNlci50cyJdLCJuYW1lcyI6WyJNRDVBbmltUGFyc2VyIiwiTUQ1QW5pbVBhcnNlci5jb25zdHJ1Y3RvciIsIk1ENUFuaW1QYXJzZXIuc3VwcG9ydHNUeXBlIiwiTUQ1QW5pbVBhcnNlci5zdXBwb3J0c0RhdGEiLCJNRDVBbmltUGFyc2VyLl9wUHJvY2VlZFBhcnNpbmciLCJNRDVBbmltUGFyc2VyLnRyYW5zbGF0ZUNsaXAiLCJNRDVBbmltUGFyc2VyLnRyYW5zbGF0ZVBvc2UiLCJNRDVBbmltUGFyc2VyLnBhcnNlSGllcmFyY2h5IiwiTUQ1QW5pbVBhcnNlci5wYXJzZUJvdW5kcyIsIk1ENUFuaW1QYXJzZXIucGFyc2VCYXNlRnJhbWUiLCJNRDVBbmltUGFyc2VyLnBhcnNlRnJhbWUiLCJNRDVBbmltUGFyc2VyLnB1dEJhY2siLCJNRDVBbmltUGFyc2VyLmdldE5leHRUb2tlbiIsIk1ENUFuaW1QYXJzZXIuc2tpcFdoaXRlU3BhY2UiLCJNRDVBbmltUGFyc2VyLmlnbm9yZUxpbmUiLCJNRDVBbmltUGFyc2VyLmdldE5leHRDaGFyIiwiTUQ1QW5pbVBhcnNlci5nZXROZXh0SW50IiwiTUQ1QW5pbVBhcnNlci5nZXROZXh0TnVtYmVyIiwiTUQ1QW5pbVBhcnNlci5wYXJzZVZlY3RvcjNEIiwiTUQ1QW5pbVBhcnNlci5wYXJzZVF1YXRlcm5pb24iLCJNRDVBbmltUGFyc2VyLnBhcnNlQ01EIiwiTUQ1QW5pbVBhcnNlci5wYXJzZUxpdGVyYWxzdHJpbmciLCJNRDVBbmltUGFyc2VyLnNlbmRFT0ZFcnJvciIsIk1ENUFuaW1QYXJzZXIuc2VuZFBhcnNlRXJyb3IiLCJNRDVBbmltUGFyc2VyLnNlbmRVbmtub3duS2V5d29yZEVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFVBQVUsV0FBZ0Isc0NBQXNDLENBQUMsQ0FBQztBQUN6RSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUN0RSxJQUFPLG1C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QUFDQSxDQUFDQSxDQUFDQTtZQUMxREEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsR0FBR0EsRUFBRUEsQ0FBQ0E7Z0JBQ2RBLFdBQVdBLENBQUNBLENBQUNBLEdBQUdBLFVBQVVBLENBQUNBLFNBQVNBLENBQUNBLFVBQVVBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1lBRTFEQSxJQUFJQSxDQUFDQSxHQUFVQSxDQUFDQSxHQUFHQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMzR0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFekNBLEVBQUVBLENBQUNBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUMvQkEsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsV0FBV0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzNEQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxXQUFXQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtZQUM5REEsQ0FBQ0E7WUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ1BBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFFBQVFBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO2dCQUN2Q0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2pDQSxJQUFJQSxDQUFDQSxXQUFX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QUFDQTtJQXlqQjNDQSxvQkFBQ0E7QUFBREEsQ0F6a0JBLEFBeWtCQ0EsRUF6a0IyQixVQUFVLEVBeWtCckM7QUFFRCxBQUF1QixpQkFBZCxhQUFhLENBQUMiLCJmaWxlIjoicGFyc2Vycy9NRDVBbmltUGFyc2VyLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFF1YXRlcm5pb25cdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1F1YXRlcm5pb25cIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgVVJMTG9hZGVyRGF0YUZvcm1hdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTExvYWRlckRhdGFGb3JtYXRcIik7XG5pbXBvcnQgUGFyc2VyQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1BhcnNlckJhc2VcIik7XG5cbmltcG9ydCBKb2ludFBvc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvSm9pbnRQb3NlXCIpO1xuaW1wb3J0IFNrZWxldG9uUG9zZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvblBvc2VcIik7XG5pbXBvcnQgU2tlbGV0b25DbGlwTm9kZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL25vZGVzL1NrZWxldG9uQ2xpcE5vZGVcIik7XG5pbXBvcnQgQmFzZUZyYW1lRGF0YVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9kYXRhL0Jhc2VGcmFtZURhdGFcIik7XG5pbXBvcnQgQm91bmRzRGF0YVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL2RhdGEvQm91bmRzRGF0YVwiKTtcbmltcG9ydCBGcmFtZURhdGFcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9kYXRhL0ZyYW1lRGF0YVwiKTtcbmltcG9ydCBIaWVyYXJjaHlEYXRhXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL2RhdGEvSGllcmFyY2h5RGF0YVwiKTtcblxuLyoqXG4gKiBNRDVBbmltUGFyc2VyIHByb3ZpZGVzIGEgcGFyc2VyIGZvciB0aGUgbWQ1YW5pbSBkYXRhIHR5cGUsIHByb3ZpZGluZyBhbiBhbmltYXRpb24gc2VxdWVuY2UgZm9yIHRoZSBtZDUgZm9ybWF0LlxuICpcbiAqIHRvZG86IG9wdGltaXplXG4gKi9cbmNsYXNzIE1ENUFuaW1QYXJzZXIgZXh0ZW5kcyBQYXJzZXJCYXNlXG57XG5cdHByaXZhdGUgX3RleHREYXRhOnN0cmluZztcblx0cHJpdmF0ZSBfc3RhcnRlZFBhcnNpbmc6Ym9vbGVhbjtcblx0cHVibGljIHN0YXRpYyBWRVJTSU9OX1RPS0VOOnN0cmluZyA9IFwiTUQ1VmVyc2lvblwiO1xuXHRwdWJsaWMgc3RhdGljIENPTU1BTkRfTElORV9UT0tFTjpzdHJpbmcgPSBcImNvbW1hbmRsaW5lXCI7XG5cdHB1YmxpYyBzdGF0aWMgTlVNX0ZSQU1FU19UT0tFTjpzdHJpbmcgPSBcIm51bUZyYW1lc1wiO1xuXHRwdWJsaWMgc3RhdGljIE5VTV9KT0lOVFNfVE9LRU46c3RyaW5nID0gXCJudW1Kb2ludHNcIjtcblx0cHVibGljIHN0YXRpYyBGUkFNRV9SQVRFX1RPS0VOOnN0cmluZyA9IFwiZnJhbWVSYXRlXCI7XG5cdHB1YmxpYyBzdGF0aWMgTlVNX0FOSU1BVEVEX0NPTVBPTkVOVFNfVE9LRU46c3RyaW5nID0gXCJudW1BbmltYXRlZENvbXBvbmVudHNcIjtcblxuXHRwdWJsaWMgc3RhdGljIEhJRVJBUkNIWV9UT0tFTjpzdHJpbmcgPSBcImhpZXJhcmNoeVwiO1xuXHRwdWJsaWMgc3RhdGljIEJPVU5EU19UT0tFTjpzdHJpbmcgPSBcImJvdW5kc1wiO1xuXHRwdWJsaWMgc3RhdGljIEJBU0VfRlJBTUVfVE9LRU46c3RyaW5nID0gXCJiYXNlZnJhbWVcIjtcblx0cHVibGljIHN0YXRpYyBGUkFNRV9UT0tFTjpzdHJpbmcgPSBcImZyYW1lXCI7XG5cblx0cHVibGljIHN0YXRpYyBDT01NRU5UX1RPS0VOOnN0cmluZyA9IFwiLy9cIjtcblxuXHRwcml2YXRlIF9wYXJzZUluZGV4Om51bWJlciAvKmludCovID0gMDtcblx0cHJpdmF0ZSBfcmVhY2hlZEVPRjpib29sZWFuO1xuXHRwcml2YXRlIF9saW5lOm51bWJlciAvKmludCovID0gMDtcblx0cHJpdmF0ZSBfY2hhckxpbmVJbmRleDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdHByaXZhdGUgX3ZlcnNpb246bnVtYmVyIC8qaW50Ki87XG5cdHByaXZhdGUgX2ZyYW1lUmF0ZTpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBfbnVtRnJhbWVzOm51bWJlciAvKmludCovO1xuXHRwcml2YXRlIF9udW1Kb2ludHM6bnVtYmVyIC8qaW50Ki87XG5cdHByaXZhdGUgX251bUFuaW1hdGVkQ29tcG9uZW50czpudW1iZXIgLyppbnQqLztcblxuXHRwcml2YXRlIF9oaWVyYXJjaHk6QXJyYXk8SGllcmFyY2h5RGF0YT47XG5cdHByaXZhdGUgX2JvdW5kczpBcnJheTxCb3VuZHNEYXRhPjtcblx0cHJpdmF0ZSBfZnJhbWVEYXRhOkFycmF5PEZyYW1lRGF0YT47XG5cdHByaXZhdGUgX2Jhc2VGcmFtZURhdGE6QXJyYXk8QmFzZUZyYW1lRGF0YT47XG5cblx0cHJpdmF0ZSBfcm90YXRpb25RdWF0OlF1YXRlcm5pb247XG5cdHByaXZhdGUgX2NsaXA6U2tlbGV0b25DbGlwTm9kZTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBNRDVBbmltUGFyc2VyIG9iamVjdC5cblx0ICogQHBhcmFtIHVyaSBUaGUgdXJsIG9yIGlkIG9mIHRoZSBkYXRhIG9yIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcGFyYW0gZXh0cmEgVGhlIGhvbGRlciBmb3IgZXh0cmEgY29udGV4dHVhbCBkYXRhIHRoYXQgdGhlIHBhcnNlciBtaWdodCBuZWVkLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoYWRkaXRpb25hbFJvdGF0aW9uQXhpczpWZWN0b3IzRCA9IG51bGwsIGFkZGl0aW9uYWxSb3RhdGlvblJhZGlhbnM6bnVtYmVyID0gMClcblx0e1xuXHRcdHN1cGVyKFVSTExvYWRlckRhdGFGb3JtYXQuVEVYVCk7XG5cdFx0dGhpcy5fcm90YXRpb25RdWF0ID0gbmV3IFF1YXRlcm5pb24oKTtcblx0XHR2YXIgdDE6UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdFx0dmFyIHQyOlF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXG5cdFx0dDEuZnJvbUF4aXNBbmdsZShWZWN0b3IzRC5YX0FYSVMsIC1NYXRoLlBJKi41KTtcblx0XHR0Mi5mcm9tQXhpc0FuZ2xlKFZlY3RvcjNELllfQVhJUywgLU1hdGguUEkqLjUpO1xuXG5cdFx0dGhpcy5fcm90YXRpb25RdWF0Lm11bHRpcGx5KHQyLCB0MSk7XG5cblx0XHRpZiAoYWRkaXRpb25hbFJvdGF0aW9uQXhpcykge1xuXHRcdFx0dGhpcy5fcm90YXRpb25RdWF0Lm11bHRpcGx5KHQyLCB0MSk7XG5cdFx0XHR0MS5mcm9tQXhpc0FuZ2xlKGFkZGl0aW9uYWxSb3RhdGlvbkF4aXMsIGFkZGl0aW9uYWxSb3RhdGlvblJhZGlhbnMpO1xuXHRcdFx0dGhpcy5fcm90YXRpb25RdWF0Lm11bHRpcGx5KHQxLCB0aGlzLl9yb3RhdGlvblF1YXQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgYSBnaXZlbiBmaWxlIGV4dGVuc2lvbiBpcyBzdXBwb3J0ZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGV4dGVuc2lvbiBUaGUgZmlsZSBleHRlbnNpb24gb2YgYSBwb3RlbnRpYWwgZmlsZSB0byBiZSBwYXJzZWQuXG5cdCAqIEByZXR1cm4gV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGZpbGUgdHlwZSBpcyBzdXBwb3J0ZWQuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIHN1cHBvcnRzVHlwZShleHRlbnNpb246c3RyaW5nKTpib29sZWFuXG5cdHtcblx0XHRleHRlbnNpb24gPSBleHRlbnNpb24udG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gZXh0ZW5zaW9uID09IFwibWQ1YW5pbVwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFByb2NlZWRQYXJzaW5nKCk6Ym9vbGVhblxuXHR7XG5cdFx0dmFyIHRva2VuOnN0cmluZztcblxuXHRcdGlmICghdGhpcy5fc3RhcnRlZFBhcnNpbmcpIHtcblx0XHRcdHRoaXMuX3RleHREYXRhID0gdGhpcy5fcEdldFRleHREYXRhKCk7XG5cdFx0XHR0aGlzLl9zdGFydGVkUGFyc2luZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0d2hpbGUgKHRoaXMuX3BIYXNUaW1lKCkpIHtcblx0XHRcdHRva2VuID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHRcdHN3aXRjaCAodG9rZW4pIHtcblx0XHRcdFx0Y2FzZSBNRDVBbmltUGFyc2VyLkNPTU1FTlRfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5pZ25vcmVMaW5lKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJcIjpcblx0XHRcdFx0XHQvLyBjYW4gb2NjdXIgYXQgdGhlIGVuZCBvZiBhIGZpbGVcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVBbmltUGFyc2VyLlZFUlNJT05fVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5fdmVyc2lvbiA9IHRoaXMuZ2V0TmV4dEludCgpO1xuXHRcdFx0XHRcdGlmICh0aGlzLl92ZXJzaW9uICE9IDEwKVxuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biB2ZXJzaW9uIG51bWJlciBlbmNvdW50ZXJlZCFcIik7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1QW5pbVBhcnNlci5DT01NQU5EX0xJTkVfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUNNRCgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENUFuaW1QYXJzZXIuTlVNX0ZSQU1FU19UT0tFTjpcblx0XHRcdFx0XHR0aGlzLl9udW1GcmFtZXMgPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdFx0XHR0aGlzLl9ib3VuZHMgPSBuZXcgQXJyYXk8Qm91bmRzRGF0YT4oKTtcblx0XHRcdFx0XHR0aGlzLl9mcmFtZURhdGEgPSBuZXcgQXJyYXk8RnJhbWVEYXRhPigpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENUFuaW1QYXJzZXIuTlVNX0pPSU5UU19UT0tFTjpcblx0XHRcdFx0XHR0aGlzLl9udW1Kb2ludHMgPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdFx0XHR0aGlzLl9oaWVyYXJjaHkgPSBuZXcgQXJyYXk8SGllcmFyY2h5RGF0YT4odGhpcy5fbnVtSm9pbnRzKTtcblx0XHRcdFx0XHR0aGlzLl9iYXNlRnJhbWVEYXRhID0gbmV3IEFycmF5PEJhc2VGcmFtZURhdGE+KHRoaXMuX251bUpvaW50cyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1QW5pbVBhcnNlci5GUkFNRV9SQVRFX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMuX2ZyYW1lUmF0ZSA9IHRoaXMuZ2V0TmV4dEludCgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENUFuaW1QYXJzZXIuTlVNX0FOSU1BVEVEX0NPTVBPTkVOVFNfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5fbnVtQW5pbWF0ZWRDb21wb25lbnRzID0gdGhpcy5nZXROZXh0SW50KCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1QW5pbVBhcnNlci5ISUVSQVJDSFlfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUhpZXJhcmNoeSgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENUFuaW1QYXJzZXIuQk9VTkRTX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VCb3VuZHMoKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVBbmltUGFyc2VyLkJBU0VfRlJBTUVfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUJhc2VGcmFtZSgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENUFuaW1QYXJzZXIuRlJBTUVfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5wYXJzZUZyYW1lKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0aWYgKCF0aGlzLl9yZWFjaGVkRU9GKVxuXHRcdFx0XHRcdFx0dGhpcy5zZW5kVW5rbm93bktleXdvcmRFcnJvcigpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5fcmVhY2hlZEVPRikge1xuXHRcdFx0XHR0aGlzLl9jbGlwID0gbmV3IFNrZWxldG9uQ2xpcE5vZGUoKTtcblx0XHRcdFx0dGhpcy50cmFuc2xhdGVDbGlwKCk7XG5cdFx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX2NsaXApO1xuXHRcdFx0XHRyZXR1cm4gUGFyc2VyQmFzZS5QQVJTSU5HX0RPTkU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBQYXJzZXJCYXNlLk1PUkVfVE9fUEFSU0U7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYWxsIGtleSBmcmFtZSBkYXRhIHRvIGFuIFNraW5uZWRBbmltYXRpb25TZXF1ZW5jZS5cblx0ICovXG5cdHByaXZhdGUgdHJhbnNsYXRlQ2xpcCgpOnZvaWRcblx0e1xuXHRcdGZvciAodmFyIGk6bnVtYmVyIC8qaW50Ki8gPSAwOyBpIDwgdGhpcy5fbnVtRnJhbWVzOyArK2kpXG5cdFx0XHR0aGlzLl9jbGlwLmFkZEZyYW1lKHRoaXMudHJhbnNsYXRlUG9zZSh0aGlzLl9mcmFtZURhdGFbaV0pLCAxMDAwL3RoaXMuX2ZyYW1lUmF0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBzaW5nbGUga2V5IGZyYW1lIGRhdGEgdG8gYSBTa2VsZXRvblBvc2UuXG5cdCAqIEBwYXJhbSBmcmFtZURhdGEgVGhlIGFjdHVhbCBmcmFtZSBkYXRhLlxuXHQgKiBAcmV0dXJuIEEgU2tlbGV0b25Qb3NlIGNvbnRhaW5pbmcgdGhlIGZyYW1lIGRhdGEncyBwb3NlLlxuXHQgKi9cblx0cHJpdmF0ZSB0cmFuc2xhdGVQb3NlKGZyYW1lRGF0YTpGcmFtZURhdGEpOlNrZWxldG9uUG9zZVxuXHR7XG5cdFx0dmFyIGhpZXJhcmNoeTpIaWVyYXJjaHlEYXRhO1xuXHRcdHZhciBwb3NlOkpvaW50UG9zZTtcblx0XHR2YXIgYmFzZTpCYXNlRnJhbWVEYXRhO1xuXHRcdHZhciBmbGFnczpudW1iZXIgLyppbnQqLztcblx0XHR2YXIgajpudW1iZXIgLyppbnQqLztcblx0XHR2YXIgdHJhbnNsYXRlOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEKCk7XG5cdFx0dmFyIG9yaWVudGF0aW9uOlF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXHRcdHZhciBjb21wb25lbnRzOkFycmF5PG51bWJlcj4gPSBmcmFtZURhdGEuY29tcG9uZW50cztcblx0XHR2YXIgc2tlbFBvc2U6U2tlbGV0b25Qb3NlID0gbmV3IFNrZWxldG9uUG9zZSgpO1xuXHRcdHZhciBqb2ludFBvc2VzOkFycmF5PEpvaW50UG9zZT4gPSBza2VsUG9zZS5qb2ludFBvc2VzO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCB0aGlzLl9udW1Kb2ludHM7ICsraSkge1xuXHRcdFx0aiA9IDA7XG5cdFx0XHRwb3NlID0gbmV3IEpvaW50UG9zZSgpO1xuXHRcdFx0aGllcmFyY2h5ID0gdGhpcy5faGllcmFyY2h5W2ldO1xuXHRcdFx0YmFzZSA9IHRoaXMuX2Jhc2VGcmFtZURhdGFbaV07XG5cdFx0XHRmbGFncyA9IGhpZXJhcmNoeS5mbGFncztcblx0XHRcdHRyYW5zbGF0ZS54ID0gYmFzZS5wb3NpdGlvbi54O1xuXHRcdFx0dHJhbnNsYXRlLnkgPSBiYXNlLnBvc2l0aW9uLnk7XG5cdFx0XHR0cmFuc2xhdGUueiA9IGJhc2UucG9zaXRpb24uejtcblx0XHRcdG9yaWVudGF0aW9uLnggPSBiYXNlLm9yaWVudGF0aW9uLng7XG5cdFx0XHRvcmllbnRhdGlvbi55ID0gYmFzZS5vcmllbnRhdGlvbi55O1xuXHRcdFx0b3JpZW50YXRpb24ueiA9IGJhc2Uub3JpZW50YXRpb24uejtcblxuXHRcdFx0aWYgKGZsYWdzICYgMSlcblx0XHRcdFx0dHJhbnNsYXRlLnggPSBjb21wb25lbnRzW2hpZXJhcmNoeS5zdGFydEluZGV4ICsgKGorKyldO1xuXHRcdFx0aWYgKGZsYWdzICYgMilcblx0XHRcdFx0dHJhbnNsYXRlLnkgPSBjb21wb25lbnRzW2hpZXJhcmNoeS5zdGFydEluZGV4ICsgKGorKyldO1xuXHRcdFx0aWYgKGZsYWdzICYgNClcblx0XHRcdFx0dHJhbnNsYXRlLnogPSBjb21wb25lbnRzW2hpZXJhcmNoeS5zdGFydEluZGV4ICsgKGorKyldO1xuXHRcdFx0aWYgKGZsYWdzICYgOClcblx0XHRcdFx0b3JpZW50YXRpb24ueCA9IGNvbXBvbmVudHNbaGllcmFyY2h5LnN0YXJ0SW5kZXggKyAoaisrKV07XG5cdFx0XHRpZiAoZmxhZ3MgJiAxNilcblx0XHRcdFx0b3JpZW50YXRpb24ueSA9IGNvbXBvbmVudHNbaGllcmFyY2h5LnN0YXJ0SW5kZXggKyAoaisrKV07XG5cdFx0XHRpZiAoZmxhZ3MgJiAzMilcblx0XHRcdFx0b3JpZW50YXRpb24ueiA9IGNvbXBvbmVudHNbaGllcmFyY2h5LnN0YXJ0SW5kZXggKyAoaisrKV07XG5cblx0XHRcdHZhciB3Om51bWJlciA9IDEgLSBvcmllbnRhdGlvbi54Km9yaWVudGF0aW9uLnggLSBvcmllbnRhdGlvbi55Km9yaWVudGF0aW9uLnkgLSBvcmllbnRhdGlvbi56Km9yaWVudGF0aW9uLno7XG5cdFx0XHRvcmllbnRhdGlvbi53ID0gdyA8IDA/IDAgOiAtTWF0aC5zcXJ0KHcpO1xuXG5cdFx0XHRpZiAoaGllcmFyY2h5LnBhcmVudEluZGV4IDwgMCkge1xuXHRcdFx0XHRwb3NlLm9yaWVudGF0aW9uLm11bHRpcGx5KHRoaXMuX3JvdGF0aW9uUXVhdCwgb3JpZW50YXRpb24pO1xuXHRcdFx0XHRwb3NlLnRyYW5zbGF0aW9uID0gdGhpcy5fcm90YXRpb25RdWF0LnJvdGF0ZVBvaW50KHRyYW5zbGF0ZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwb3NlLm9yaWVudGF0aW9uLmNvcHlGcm9tKG9yaWVudGF0aW9uKTtcblx0XHRcdFx0cG9zZS50cmFuc2xhdGlvbi54ID0gdHJhbnNsYXRlLng7XG5cdFx0XHRcdHBvc2UudHJhbnNsYXRpb24ueSA9IHRyYW5zbGF0ZS55O1xuXHRcdFx0XHRwb3NlLnRyYW5zbGF0aW9uLnogPSB0cmFuc2xhdGUuejtcblx0XHRcdH1cblx0XHRcdHBvc2Uub3JpZW50YXRpb24ueSA9IC1wb3NlLm9yaWVudGF0aW9uLnk7XG5cdFx0XHRwb3NlLm9yaWVudGF0aW9uLnogPSAtcG9zZS5vcmllbnRhdGlvbi56O1xuXHRcdFx0cG9zZS50cmFuc2xhdGlvbi54ID0gLXBvc2UudHJhbnNsYXRpb24ueDtcblxuXHRcdFx0am9pbnRQb3Nlc1tpXSA9IHBvc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHNrZWxQb3NlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBhcnNlcyB0aGUgc2tlbGV0b24ncyBoaWVyYXJjaHkgZGF0YS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VIaWVyYXJjaHkoKTp2b2lkXG5cdHtcblx0XHR2YXIgY2g6c3RyaW5nO1xuXHRcdHZhciBkYXRhOkhpZXJhcmNoeURhdGE7XG5cdFx0dmFyIHRva2VuOnN0cmluZyA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cdFx0dmFyIGk6bnVtYmVyIC8qaW50Ki8gPSAwO1xuXG5cdFx0aWYgKHRva2VuICE9IFwie1wiKVxuXHRcdFx0dGhpcy5zZW5kVW5rbm93bktleXdvcmRFcnJvcigpO1xuXG5cdFx0ZG8ge1xuXHRcdFx0aWYgKHRoaXMuX3JlYWNoZWRFT0YpXG5cdFx0XHRcdHRoaXMuc2VuZEVPRkVycm9yKCk7XG5cdFx0XHRkYXRhID0gbmV3IEhpZXJhcmNoeURhdGEoKTtcblx0XHRcdGRhdGEubmFtZSA9IHRoaXMucGFyc2VMaXRlcmFsc3RyaW5nKCk7XG5cdFx0XHRkYXRhLnBhcmVudEluZGV4ID0gdGhpcy5nZXROZXh0SW50KCk7XG5cdFx0XHRkYXRhLmZsYWdzID0gdGhpcy5nZXROZXh0SW50KCk7XG5cdFx0XHRkYXRhLnN0YXJ0SW5kZXggPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdHRoaXMuX2hpZXJhcmNoeVtpKytdID0gZGF0YTtcblxuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cblx0XHRcdGlmIChjaCA9PSBcIi9cIikge1xuXHRcdFx0XHR0aGlzLnB1dEJhY2soKTtcblx0XHRcdFx0Y2ggPSB0aGlzLmdldE5leHRUb2tlbigpO1xuXHRcdFx0XHRpZiAoY2ggPT0gTUQ1QW5pbVBhcnNlci5DT01NRU5UX1RPS0VOKVxuXHRcdFx0XHRcdHRoaXMuaWdub3JlTGluZSgpO1xuXHRcdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dENoYXIoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNoICE9IFwifVwiKVxuXHRcdFx0XHR0aGlzLnB1dEJhY2soKTtcblxuXHRcdH0gd2hpbGUgKGNoICE9IFwifVwiKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgZnJhbWUgYm91bmRzLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZUJvdW5kcygpOnZvaWRcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIGRhdGE6Qm91bmRzRGF0YTtcblx0XHR2YXIgdG9rZW46c3RyaW5nID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHR2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0XHRpZiAodG9rZW4gIT0gXCJ7XCIpXG5cdFx0XHR0aGlzLnNlbmRVbmtub3duS2V5d29yZEVycm9yKCk7XG5cblx0XHRkbyB7XG5cdFx0XHRpZiAodGhpcy5fcmVhY2hlZEVPRilcblx0XHRcdFx0dGhpcy5zZW5kRU9GRXJyb3IoKTtcblx0XHRcdGRhdGEgPSBuZXcgQm91bmRzRGF0YSgpO1xuXHRcdFx0ZGF0YS5taW4gPSB0aGlzLnBhcnNlVmVjdG9yM0QoKTtcblx0XHRcdGRhdGEubWF4ID0gdGhpcy5wYXJzZVZlY3RvcjNEKCk7XG5cdFx0XHR0aGlzLl9ib3VuZHNbaSsrXSA9IGRhdGE7XG5cblx0XHRcdGNoID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXG5cdFx0XHRpZiAoY2ggPT0gXCIvXCIpIHtcblx0XHRcdFx0dGhpcy5wdXRCYWNrKCk7XG5cdFx0XHRcdGNoID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHRcdFx0aWYgKGNoID09IE1ENUFuaW1QYXJzZXIuQ09NTUVOVF9UT0tFTilcblx0XHRcdFx0XHR0aGlzLmlnbm9yZUxpbmUoKTtcblx0XHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChjaCAhPSBcIn1cIilcblx0XHRcdFx0dGhpcy5wdXRCYWNrKCk7XG5cblx0XHR9IHdoaWxlIChjaCAhPSBcIn1cIik7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBiYXNlIGZyYW1lLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZUJhc2VGcmFtZSgpOnZvaWRcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIGRhdGE6QmFzZUZyYW1lRGF0YTtcblx0XHR2YXIgdG9rZW46c3RyaW5nID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHR2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7XG5cblx0XHRpZiAodG9rZW4gIT0gXCJ7XCIpXG5cdFx0XHR0aGlzLnNlbmRVbmtub3duS2V5d29yZEVycm9yKCk7XG5cblx0XHRkbyB7XG5cdFx0XHRpZiAodGhpcy5fcmVhY2hlZEVPRilcblx0XHRcdFx0dGhpcy5zZW5kRU9GRXJyb3IoKTtcblx0XHRcdGRhdGEgPSBuZXcgQmFzZUZyYW1lRGF0YSgpO1xuXHRcdFx0ZGF0YS5wb3NpdGlvbiA9IHRoaXMucGFyc2VWZWN0b3IzRCgpO1xuXHRcdFx0ZGF0YS5vcmllbnRhdGlvbiA9IHRoaXMucGFyc2VRdWF0ZXJuaW9uKCk7XG5cdFx0XHR0aGlzLl9iYXNlRnJhbWVEYXRhW2krK10gPSBkYXRhO1xuXG5cdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dENoYXIoKTtcblxuXHRcdFx0aWYgKGNoID09IFwiL1wiKSB7XG5cdFx0XHRcdHRoaXMucHV0QmFjaygpO1xuXHRcdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cdFx0XHRcdGlmIChjaCA9PSBNRDVBbmltUGFyc2VyLkNPTU1FTlRfVE9LRU4pXG5cdFx0XHRcdFx0dGhpcy5pZ25vcmVMaW5lKCk7XG5cdFx0XHRcdGNoID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoY2ggIT0gXCJ9XCIpXG5cdFx0XHRcdHRoaXMucHV0QmFjaygpO1xuXG5cdFx0fSB3aGlsZSAoY2ggIT0gXCJ9XCIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBhcnNlcyBhIHNpbmdsZSBmcmFtZS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VGcmFtZSgpOnZvaWRcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIGRhdGE6RnJhbWVEYXRhO1xuXHRcdHZhciB0b2tlbjpzdHJpbmc7XG5cdFx0dmFyIGZyYW1lSW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cblx0XHRmcmFtZUluZGV4ID0gdGhpcy5nZXROZXh0SW50KCk7XG5cblx0XHR0b2tlbiA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cdFx0aWYgKHRva2VuICE9IFwie1wiKVxuXHRcdFx0dGhpcy5zZW5kVW5rbm93bktleXdvcmRFcnJvcigpO1xuXG5cdFx0ZG8ge1xuXHRcdFx0aWYgKHRoaXMuX3JlYWNoZWRFT0YpXG5cdFx0XHRcdHRoaXMuc2VuZEVPRkVycm9yKCk7XG5cdFx0XHRkYXRhID0gbmV3IEZyYW1lRGF0YSgpO1xuXHRcdFx0ZGF0YS5jb21wb25lbnRzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5fbnVtQW5pbWF0ZWRDb21wb25lbnRzKTtcblxuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCB0aGlzLl9udW1BbmltYXRlZENvbXBvbmVudHM7ICsraSlcblx0XHRcdFx0ZGF0YS5jb21wb25lbnRzW2ldID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cblx0XHRcdHRoaXMuX2ZyYW1lRGF0YVtmcmFtZUluZGV4XSA9IGRhdGE7XG5cblx0XHRcdGNoID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXG5cdFx0XHRpZiAoY2ggPT0gXCIvXCIpIHtcblx0XHRcdFx0dGhpcy5wdXRCYWNrKCk7XG5cdFx0XHRcdGNoID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHRcdFx0aWYgKGNoID09IE1ENUFuaW1QYXJzZXIuQ09NTUVOVF9UT0tFTilcblx0XHRcdFx0XHR0aGlzLmlnbm9yZUxpbmUoKTtcblx0XHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChjaCAhPSBcIn1cIilcblx0XHRcdFx0dGhpcy5wdXRCYWNrKCk7XG5cblx0XHR9IHdoaWxlIChjaCAhPSBcIn1cIik7XG5cdH1cblxuXHQvKipcblx0ICogUHV0cyBiYWNrIHRoZSBsYXN0IHJlYWQgY2hhcmFjdGVyIGludG8gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBwdXRCYWNrKCk6dm9pZFxuXHR7XG5cdFx0dGhpcy5fcGFyc2VJbmRleC0tO1xuXHRcdHRoaXMuX2NoYXJMaW5lSW5kZXgtLTtcblx0XHR0aGlzLl9yZWFjaGVkRU9GID0gdGhpcy5fcGFyc2VJbmRleCA+PSB0aGlzLl90ZXh0RGF0YS5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbmV4dCB0b2tlbiBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIGdldE5leHRUb2tlbigpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNoOnN0cmluZztcblx0XHR2YXIgdG9rZW46c3RyaW5nID0gXCJcIjtcblxuXHRcdHdoaWxlICghdGhpcy5fcmVhY2hlZEVPRikge1xuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cdFx0XHRpZiAoY2ggPT0gXCIgXCIgfHwgY2ggPT0gXCJcXHJcIiB8fCBjaCA9PSBcIlxcblwiIHx8IGNoID09IFwiXFx0XCIpIHtcblx0XHRcdFx0aWYgKHRva2VuICE9IE1ENUFuaW1QYXJzZXIuQ09NTUVOVF9UT0tFTilcblx0XHRcdFx0XHR0aGlzLnNraXBXaGl0ZVNwYWNlKCk7XG5cdFx0XHRcdGlmICh0b2tlbiAhPSBcIlwiKVxuXHRcdFx0XHRcdHJldHVybiB0b2tlbjtcblx0XHRcdH0gZWxzZVxuXHRcdFx0XHR0b2tlbiArPSBjaDtcblxuXHRcdFx0aWYgKHRva2VuID09IE1ENUFuaW1QYXJzZXIuQ09NTUVOVF9UT0tFTilcblx0XHRcdFx0cmV0dXJuIHRva2VuO1xuXHRcdH1cblxuXHRcdHJldHVybiB0b2tlbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTa2lwcyBhbGwgd2hpdGVzcGFjZSBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIHNraXBXaGl0ZVNwYWNlKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGNoOnN0cmluZztcblxuXHRcdGRvXG5cdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dENoYXIoKTsgd2hpbGUgKGNoID09IFwiXFxuXCIgfHwgY2ggPT0gXCIgXCIgfHwgY2ggPT0gXCJcXHJcIiB8fCBjaCA9PSBcIlxcdFwiKTtcblxuXHRcdHRoaXMucHV0QmFjaygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNraXBzIHRvIHRoZSBuZXh0IGxpbmUuXG5cdCAqL1xuXHRwcml2YXRlIGlnbm9yZUxpbmUoKTp2b2lkXG5cdHtcblx0XHR2YXIgY2g6c3RyaW5nO1xuXHRcdHdoaWxlICghdGhpcy5fcmVhY2hlZEVPRiAmJiBjaCAhPSBcIlxcblwiKVxuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBuZXh0IHNpbmdsZSBjaGFyYWN0ZXIgaW4gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBnZXROZXh0Q2hhcigpOnN0cmluZ1xuXHR7XG5cdFx0dmFyIGNoOnN0cmluZyA9IHRoaXMuX3RleHREYXRhLmNoYXJBdCh0aGlzLl9wYXJzZUluZGV4KyspO1xuXG5cdFx0aWYgKGNoID09IFwiXFxuXCIpIHtcblx0XHRcdCsrdGhpcy5fbGluZTtcblx0XHRcdHRoaXMuX2NoYXJMaW5lSW5kZXggPSAwO1xuXHRcdH0gZWxzZSBpZiAoY2ggIT0gXCJcXHJcIilcblx0XHRcdCsrdGhpcy5fY2hhckxpbmVJbmRleDtcblxuXHRcdGlmICh0aGlzLl9wYXJzZUluZGV4ID09IHRoaXMuX3RleHREYXRhLmxlbmd0aClcblx0XHRcdHRoaXMuX3JlYWNoZWRFT0YgPSB0cnVlO1xuXG5cdFx0cmV0dXJuIGNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCBpbnRlZ2VyIGluIHRoZSBkYXRhIHN0cmVhbS5cblx0ICovXG5cdHByaXZhdGUgZ2V0TmV4dEludCgpOm51bWJlciAvKmludCovXG5cdHtcblx0XHR2YXIgaTpudW1iZXIgPSBwYXJzZUludCh0aGlzLmdldE5leHRUb2tlbigpKTtcblx0XHRpZiAoaXNOYU4oaSkpXG5cdFx0XHR0aGlzLnNlbmRQYXJzZUVycm9yKFwiaW50IHR5cGVcIik7XG5cdFx0cmV0dXJuIGk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBuZXh0IGZsb2F0aW5nIHBvaW50IG51bWJlciBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIGdldE5leHROdW1iZXIoKTpudW1iZXJcblx0e1xuXHRcdHZhciBmOm51bWJlciA9IHBhcnNlRmxvYXQodGhpcy5nZXROZXh0VG9rZW4oKSk7XG5cdFx0aWYgKGlzTmFOKGYpKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcImZsb2F0IHR5cGVcIik7XG5cdFx0cmV0dXJuIGY7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBuZXh0IDNkIHZlY3RvciBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlVmVjdG9yM0QoKTpWZWN0b3IzRFxuXHR7XG5cdFx0dmFyIHZlYzpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCgpO1xuXHRcdHZhciBjaDpzdHJpbmcgPSB0aGlzLmdldE5leHRUb2tlbigpO1xuXG5cdFx0aWYgKGNoICE9IFwiKFwiKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcIihcIik7XG5cdFx0dmVjLnggPSB0aGlzLmdldE5leHROdW1iZXIoKTtcblx0XHR2ZWMueSA9IHRoaXMuZ2V0TmV4dE51bWJlcigpO1xuXHRcdHZlYy56ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cblx0XHRpZiAodGhpcy5nZXROZXh0VG9rZW4oKSAhPSBcIilcIilcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCIpXCIpO1xuXG5cdFx0cmV0dXJuIHZlYztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIG5leHQgcXVhdGVybmlvbiBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlUXVhdGVybmlvbigpOlF1YXRlcm5pb25cblx0e1xuXHRcdHZhciBxdWF0OlF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXHRcdHZhciBjaDpzdHJpbmcgPSB0aGlzLmdldE5leHRUb2tlbigpO1xuXG5cdFx0aWYgKGNoICE9IFwiKFwiKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcIihcIik7XG5cdFx0cXVhdC54ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0cXVhdC55ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0cXVhdC56ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cblx0XHQvLyBxdWF0IHN1cHBvc2VkIHRvIGJlIHVuaXQgbGVuZ3RoXG5cdFx0dmFyIHQ6bnVtYmVyID0gMSAtIChxdWF0LngqcXVhdC54KSAtIChxdWF0LnkqcXVhdC55KSAtIChxdWF0LnoqcXVhdC56KTtcblx0XHRxdWF0LncgPSB0IDwgMD8gMCA6IC1NYXRoLnNxcnQodCk7XG5cblx0XHRpZiAodGhpcy5nZXROZXh0VG9rZW4oKSAhPSBcIilcIilcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCIpXCIpO1xuXG5cdFx0cmV0dXJuIHF1YXQ7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBjb21tYW5kIGxpbmUgZGF0YS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VDTUQoKTp2b2lkXG5cdHtcblx0XHQvLyBqdXN0IGlnbm9yZSB0aGUgY29tbWFuZCBsaW5lIHByb3BlcnR5XG5cdFx0dGhpcy5wYXJzZUxpdGVyYWxzdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIG5leHQgbGl0ZXJhbCBzdHJpbmcgaW4gdGhlIGRhdGEgc3RyZWFtLiBBIGxpdGVyYWwgc3RyaW5nIGlzIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBib3VuZGVkXG5cdCAqIGJ5IGRvdWJsZSBxdW90ZXMuXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlTGl0ZXJhbHN0cmluZygpOnN0cmluZ1xuXHR7XG5cdFx0dGhpcy5za2lwV2hpdGVTcGFjZSgpO1xuXG5cdFx0dmFyIGNoOnN0cmluZyA9IHRoaXMuZ2V0TmV4dENoYXIoKTtcblx0XHR2YXIgc3RyOnN0cmluZyA9IFwiXCI7XG5cblx0XHRpZiAoY2ggIT0gXCJcXFwiXCIpXG5cdFx0XHR0aGlzLnNlbmRQYXJzZUVycm9yKFwiXFxcIlwiKTtcblxuXHRcdGRvIHtcblx0XHRcdGlmICh0aGlzLl9yZWFjaGVkRU9GKVxuXHRcdFx0XHR0aGlzLnNlbmRFT0ZFcnJvcigpO1xuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cdFx0XHRpZiAoY2ggIT0gXCJcXFwiXCIpXG5cdFx0XHRcdHN0ciArPSBjaDtcblx0XHR9IHdoaWxlIChjaCAhPSBcIlxcXCJcIik7XG5cblx0XHRyZXR1cm4gc3RyO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRocm93cyBhbiBlbmQtb2YtZmlsZSBlcnJvciB3aGVuIGEgcHJlbWF0dXJlIGVuZCBvZiBmaWxlIHdhcyBlbmNvdW50ZXJlZC5cblx0ICovXG5cdHByaXZhdGUgc2VuZEVPRkVycm9yKCk6dm9pZFxuXHR7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBlbmQgb2YgZmlsZVwiKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaHJvd3MgYW4gZXJyb3Igd2hlbiBhbiB1bmV4cGVjdGVkIHRva2VuIHdhcyBlbmNvdW50ZXJlZC5cblx0ICogQHBhcmFtIGV4cGVjdGVkIFRoZSB0b2tlbiB0eXBlIHRoYXQgd2FzIGFjdHVhbGx5IGV4cGVjdGVkLlxuXHQgKi9cblx0cHJpdmF0ZSBzZW5kUGFyc2VFcnJvcihleHBlY3RlZDpzdHJpbmcpOnZvaWRcblx0e1xuXHRcdHRocm93IG5ldyBFcnJvcihcIlVuZXhwZWN0ZWQgdG9rZW4gYXQgbGluZSBcIiArICh0aGlzLl9saW5lICsgMSkgKyBcIiwgY2hhcmFjdGVyIFwiICsgdGhpcy5fY2hhckxpbmVJbmRleCArIFwiLiBcIiArIGV4cGVjdGVkICsgXCIgZXhwZWN0ZWQsIGJ1dCBcIiArIHRoaXMuX3RleHREYXRhLmNoYXJBdCh0aGlzLl9wYXJzZUluZGV4IC0gMSkgKyBcIiBlbmNvdW50ZXJlZFwiKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaHJvd3MgYW4gZXJyb3Igd2hlbiBhbiB1bmtub3duIGtleXdvcmQgd2FzIGVuY291bnRlcmVkLlxuXHQgKi9cblx0cHJpdmF0ZSBzZW5kVW5rbm93bktleXdvcmRFcnJvcigpOnZvaWRcblx0e1xuXHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24ga2V5d29yZCBhdCBsaW5lIFwiICsgKHRoaXMuX2xpbmUgKyAxKSArIFwiLCBjaGFyYWN0ZXIgXCIgKyB0aGlzLl9jaGFyTGluZUluZGV4ICsgXCIuIFwiKTtcblx0fVxufVxuXG5leHBvcnQgPSBNRDVBbmltUGFyc2VyOyJdfQ== \ No newline at end of file diff --git a/lib/parsers/MD5AnimParser.ts b/lib/parsers/MD5AnimParser.ts new file mode 100644 index 000000000..c4f5d6be3 --- /dev/null +++ b/lib/parsers/MD5AnimParser.ts @@ -0,0 +1,606 @@ +import Quaternion = require("awayjs-core/lib/core/geom/Quaternion"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); + +import JointPose = require("awayjs-renderergl/lib/animators/data/JointPose"); +import SkeletonPose = require("awayjs-renderergl/lib/animators/data/SkeletonPose"); +import SkeletonClipNode = require("awayjs-renderergl/lib/animators/nodes/SkeletonClipNode"); +import BaseFrameData = require("awayjs-renderergl/lib/parsers/data/BaseFrameData"); +import BoundsData = require("awayjs-renderergl/lib/parsers/data/BoundsData"); +import FrameData = require("awayjs-renderergl/lib/parsers/data/FrameData"); +import HierarchyData = require("awayjs-renderergl/lib/parsers/data/HierarchyData"); + +/** + * MD5AnimParser provides a parser for the md5anim data type, providing an animation sequence for the md5 format. + * + * todo: optimize + */ +class MD5AnimParser extends ParserBase +{ + private _textData:string; + private _startedParsing:boolean; + public static VERSION_TOKEN:string = "MD5Version"; + public static COMMAND_LINE_TOKEN:string = "commandline"; + public static NUM_FRAMES_TOKEN:string = "numFrames"; + public static NUM_JOINTS_TOKEN:string = "numJoints"; + public static FRAME_RATE_TOKEN:string = "frameRate"; + public static NUM_ANIMATED_COMPONENTS_TOKEN:string = "numAnimatedComponents"; + + public static HIERARCHY_TOKEN:string = "hierarchy"; + public static BOUNDS_TOKEN:string = "bounds"; + public static BASE_FRAME_TOKEN:string = "baseframe"; + public static FRAME_TOKEN:string = "frame"; + + public static COMMENT_TOKEN:string = "//"; + + private _parseIndex:number /*int*/ = 0; + private _reachedEOF:boolean; + private _line:number /*int*/ = 0; + private _charLineIndex:number /*int*/ = 0; + private _version:number /*int*/; + private _frameRate:number /*int*/; + private _numFrames:number /*int*/; + private _numJoints:number /*int*/; + private _numAnimatedComponents:number /*int*/; + + private _hierarchy:Array; + private _bounds:Array; + private _frameData:Array; + private _baseFrameData:Array; + + private _rotationQuat:Quaternion; + private _clip:SkeletonClipNode; + + /** + * Creates a new MD5AnimParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + constructor(additionalRotationAxis:Vector3D = null, additionalRotationRadians:number = 0) + { + super(URLLoaderDataFormat.TEXT); + this._rotationQuat = new Quaternion(); + var t1:Quaternion = new Quaternion(); + var t2:Quaternion = new Quaternion(); + + t1.fromAxisAngle(Vector3D.X_AXIS, -Math.PI*.5); + t2.fromAxisAngle(Vector3D.Y_AXIS, -Math.PI*.5); + + this._rotationQuat.multiply(t2, t1); + + if (additionalRotationAxis) { + this._rotationQuat.multiply(t2, t1); + t1.fromAxisAngle(additionalRotationAxis, additionalRotationRadians); + this._rotationQuat.multiply(t1, this._rotationQuat); + } + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "md5anim"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + return false; + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + var token:string; + + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + this._startedParsing = true; + } + + while (this._pHasTime()) { + token = this.getNextToken(); + switch (token) { + case MD5AnimParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case "": + // can occur at the end of a file + break; + case MD5AnimParser.VERSION_TOKEN: + this._version = this.getNextInt(); + if (this._version != 10) + throw new Error("Unknown version number encountered!"); + break; + case MD5AnimParser.COMMAND_LINE_TOKEN: + this.parseCMD(); + break; + case MD5AnimParser.NUM_FRAMES_TOKEN: + this._numFrames = this.getNextInt(); + this._bounds = new Array(); + this._frameData = new Array(); + break; + case MD5AnimParser.NUM_JOINTS_TOKEN: + this._numJoints = this.getNextInt(); + this._hierarchy = new Array(this._numJoints); + this._baseFrameData = new Array(this._numJoints); + break; + case MD5AnimParser.FRAME_RATE_TOKEN: + this._frameRate = this.getNextInt(); + break; + case MD5AnimParser.NUM_ANIMATED_COMPONENTS_TOKEN: + this._numAnimatedComponents = this.getNextInt(); + break; + case MD5AnimParser.HIERARCHY_TOKEN: + this.parseHierarchy(); + break; + case MD5AnimParser.BOUNDS_TOKEN: + this.parseBounds(); + break; + case MD5AnimParser.BASE_FRAME_TOKEN: + this.parseBaseFrame(); + break; + case MD5AnimParser.FRAME_TOKEN: + this.parseFrame(); + break; + default: + if (!this._reachedEOF) + this.sendUnknownKeywordError(); + } + + if (this._reachedEOF) { + this._clip = new SkeletonClipNode(); + this.translateClip(); + this._pFinalizeAsset(this._clip); + return ParserBase.PARSING_DONE; + } + } + return ParserBase.MORE_TO_PARSE; + } + + /** + * Converts all key frame data to an SkinnedAnimationSequence. + */ + private translateClip():void + { + for (var i:number /*int*/ = 0; i < this._numFrames; ++i) + this._clip.addFrame(this.translatePose(this._frameData[i]), 1000/this._frameRate); + } + + /** + * Converts a single key frame data to a SkeletonPose. + * @param frameData The actual frame data. + * @return A SkeletonPose containing the frame data's pose. + */ + private translatePose(frameData:FrameData):SkeletonPose + { + var hierarchy:HierarchyData; + var pose:JointPose; + var base:BaseFrameData; + var flags:number /*int*/; + var j:number /*int*/; + var translate:Vector3D = new Vector3D(); + var orientation:Quaternion = new Quaternion(); + var components:Array = frameData.components; + var skelPose:SkeletonPose = new SkeletonPose(); + var jointPoses:Array = skelPose.jointPoses; + + for (var i:number /*int*/ = 0; i < this._numJoints; ++i) { + j = 0; + pose = new JointPose(); + hierarchy = this._hierarchy[i]; + base = this._baseFrameData[i]; + flags = hierarchy.flags; + translate.x = base.position.x; + translate.y = base.position.y; + translate.z = base.position.z; + orientation.x = base.orientation.x; + orientation.y = base.orientation.y; + orientation.z = base.orientation.z; + + if (flags & 1) + translate.x = components[hierarchy.startIndex + (j++)]; + if (flags & 2) + translate.y = components[hierarchy.startIndex + (j++)]; + if (flags & 4) + translate.z = components[hierarchy.startIndex + (j++)]; + if (flags & 8) + orientation.x = components[hierarchy.startIndex + (j++)]; + if (flags & 16) + orientation.y = components[hierarchy.startIndex + (j++)]; + if (flags & 32) + orientation.z = components[hierarchy.startIndex + (j++)]; + + var w:number = 1 - orientation.x*orientation.x - orientation.y*orientation.y - orientation.z*orientation.z; + orientation.w = w < 0? 0 : -Math.sqrt(w); + + if (hierarchy.parentIndex < 0) { + pose.orientation.multiply(this._rotationQuat, orientation); + pose.translation = this._rotationQuat.rotatePoint(translate); + } else { + pose.orientation.copyFrom(orientation); + pose.translation.x = translate.x; + pose.translation.y = translate.y; + pose.translation.z = translate.z; + } + pose.orientation.y = -pose.orientation.y; + pose.orientation.z = -pose.orientation.z; + pose.translation.x = -pose.translation.x; + + jointPoses[i] = pose; + } + + return skelPose; + } + + /** + * Parses the skeleton's hierarchy data. + */ + private parseHierarchy():void + { + var ch:string; + var data:HierarchyData; + var token:string = this.getNextToken(); + var i:number /*int*/ = 0; + + if (token != "{") + this.sendUnknownKeywordError(); + + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new HierarchyData(); + data.name = this.parseLiteralstring(); + data.parentIndex = this.getNextInt(); + data.flags = this.getNextInt(); + data.startIndex = this.getNextInt(); + this._hierarchy[i++] = data; + + ch = this.getNextChar(); + + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + + if (ch != "}") + this.putBack(); + + } while (ch != "}"); + } + + /** + * Parses frame bounds. + */ + private parseBounds():void + { + var ch:string; + var data:BoundsData; + var token:string = this.getNextToken(); + var i:number /*int*/ = 0; + + if (token != "{") + this.sendUnknownKeywordError(); + + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new BoundsData(); + data.min = this.parseVector3D(); + data.max = this.parseVector3D(); + this._bounds[i++] = data; + + ch = this.getNextChar(); + + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + + if (ch != "}") + this.putBack(); + + } while (ch != "}"); + } + + /** + * Parses the base frame. + */ + private parseBaseFrame():void + { + var ch:string; + var data:BaseFrameData; + var token:string = this.getNextToken(); + var i:number /*int*/ = 0; + + if (token != "{") + this.sendUnknownKeywordError(); + + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new BaseFrameData(); + data.position = this.parseVector3D(); + data.orientation = this.parseQuaternion(); + this._baseFrameData[i++] = data; + + ch = this.getNextChar(); + + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + + if (ch != "}") + this.putBack(); + + } while (ch != "}"); + } + + /** + * Parses a single frame. + */ + private parseFrame():void + { + var ch:string; + var data:FrameData; + var token:string; + var frameIndex:number /*int*/; + + frameIndex = this.getNextInt(); + + token = this.getNextToken(); + if (token != "{") + this.sendUnknownKeywordError(); + + do { + if (this._reachedEOF) + this.sendEOFError(); + data = new FrameData(); + data.components = new Array(this._numAnimatedComponents); + + for (var i:number /*int*/ = 0; i < this._numAnimatedComponents; ++i) + data.components[i] = this.getNextNumber(); + + this._frameData[frameIndex] = data; + + ch = this.getNextChar(); + + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5AnimParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + + if (ch != "}") + this.putBack(); + + } while (ch != "}"); + } + + /** + * Puts back the last read character into the data stream. + */ + private putBack():void + { + this._parseIndex--; + this._charLineIndex--; + this._reachedEOF = this._parseIndex >= this._textData.length; + } + + /** + * Gets the next token in the data stream. + */ + private getNextToken():string + { + var ch:string; + var token:string = ""; + + while (!this._reachedEOF) { + ch = this.getNextChar(); + if (ch == " " || ch == "\r" || ch == "\n" || ch == "\t") { + if (token != MD5AnimParser.COMMENT_TOKEN) + this.skipWhiteSpace(); + if (token != "") + return token; + } else + token += ch; + + if (token == MD5AnimParser.COMMENT_TOKEN) + return token; + } + + return token; + } + + /** + * Skips all whitespace in the data stream. + */ + private skipWhiteSpace():void + { + var ch:string; + + do + ch = this.getNextChar(); while (ch == "\n" || ch == " " || ch == "\r" || ch == "\t"); + + this.putBack(); + } + + /** + * Skips to the next line. + */ + private ignoreLine():void + { + var ch:string; + while (!this._reachedEOF && ch != "\n") + ch = this.getNextChar(); + } + + /** + * Retrieves the next single character in the data stream. + */ + private getNextChar():string + { + var ch:string = this._textData.charAt(this._parseIndex++); + + if (ch == "\n") { + ++this._line; + this._charLineIndex = 0; + } else if (ch != "\r") + ++this._charLineIndex; + + if (this._parseIndex == this._textData.length) + this._reachedEOF = true; + + return ch; + } + + /** + * Retrieves the next integer in the data stream. + */ + private getNextInt():number /*int*/ + { + var i:number = parseInt(this.getNextToken()); + if (isNaN(i)) + this.sendParseError("int type"); + return i; + } + + /** + * Retrieves the next floating point number in the data stream. + */ + private getNextNumber():number + { + var f:number = parseFloat(this.getNextToken()); + if (isNaN(f)) + this.sendParseError("float type"); + return f; + } + + /** + * Retrieves the next 3d vector in the data stream. + */ + private parseVector3D():Vector3D + { + var vec:Vector3D = new Vector3D(); + var ch:string = this.getNextToken(); + + if (ch != "(") + this.sendParseError("("); + vec.x = this.getNextNumber(); + vec.y = this.getNextNumber(); + vec.z = this.getNextNumber(); + + if (this.getNextToken() != ")") + this.sendParseError(")"); + + return vec; + } + + /** + * Retrieves the next quaternion in the data stream. + */ + private parseQuaternion():Quaternion + { + var quat:Quaternion = new Quaternion(); + var ch:string = this.getNextToken(); + + if (ch != "(") + this.sendParseError("("); + quat.x = this.getNextNumber(); + quat.y = this.getNextNumber(); + quat.z = this.getNextNumber(); + + // quat supposed to be unit length + var t:number = 1 - (quat.x*quat.x) - (quat.y*quat.y) - (quat.z*quat.z); + quat.w = t < 0? 0 : -Math.sqrt(t); + + if (this.getNextToken() != ")") + this.sendParseError(")"); + + return quat; + } + + /** + * Parses the command line data. + */ + private parseCMD():void + { + // just ignore the command line property + this.parseLiteralstring(); + } + + /** + * Retrieves the next literal string in the data stream. A literal string is a sequence of characters bounded + * by double quotes. + */ + private parseLiteralstring():string + { + this.skipWhiteSpace(); + + var ch:string = this.getNextChar(); + var str:string = ""; + + if (ch != "\"") + this.sendParseError("\""); + + do { + if (this._reachedEOF) + this.sendEOFError(); + ch = this.getNextChar(); + if (ch != "\"") + str += ch; + } while (ch != "\""); + + return str; + } + + /** + * Throws an end-of-file error when a premature end of file was encountered. + */ + private sendEOFError():void + { + throw new Error("Unexpected end of file"); + } + + /** + * Throws an error when an unexpected token was encountered. + * @param expected The token type that was actually expected. + */ + private sendParseError(expected:string):void + { + throw new Error("Unexpected token at line " + (this._line + 1) + ", character " + this._charLineIndex + ". " + expected + " expected, but " + this._textData.charAt(this._parseIndex - 1) + " encountered"); + } + + /** + * Throws an error when an unknown keyword was encountered. + */ + private sendUnknownKeywordError():void + { + throw new Error("Unknown keyword at line " + (this._line + 1) + ", character " + this._charLineIndex + ". "); + } +} + +export = MD5AnimParser; \ No newline at end of file diff --git a/lib/parsers/MD5MeshParser.js b/lib/parsers/MD5MeshParser.js new file mode 100755 index 000000000..4853e8379 --- /dev/null +++ b/lib/parsers/MD5MeshParser.js @@ -0,0 +1,549 @@ +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 DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Quaternion = require("awayjs-core/lib/core/geom/Quaternion"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var SkeletonAnimationSet = require("awayjs-renderergl/lib/animators/SkeletonAnimationSet"); +var Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton"); +var SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint"); +// todo: create animation system, parse skeleton +/** + * MD5MeshParser provides a parser for the md5mesh data type, providing the geometry of the md5 format. + * + * todo: optimize + */ +var MD5MeshParser = (function (_super) { + __extends(MD5MeshParser, _super); + /** + * Creates a new MD5MeshParser object. + */ + function MD5MeshParser(additionalRotationAxis, additionalRotationRadians) { + if (additionalRotationAxis === void 0) { additionalRotationAxis = null; } + if (additionalRotationRadians === void 0) { additionalRotationRadians = 0; } + _super.call(this, URLLoaderDataFormat.TEXT); + this._parseIndex = 0; + this._line = 0; + this._charLineIndex = 0; + this._rotationQuat = new Quaternion(); + this._rotationQuat.fromAxisAngle(Vector3D.X_AXIS, -Math.PI * .5); + if (additionalRotationAxis) { + var quat = new Quaternion(); + quat.fromAxisAngle(additionalRotationAxis, additionalRotationRadians); + this._rotationQuat.multiply(this._rotationQuat, quat); + } + } + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + MD5MeshParser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "md5mesh"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + MD5MeshParser.supportsData = function (data) { + return false; + }; + /** + * @inheritDoc + */ + MD5MeshParser.prototype._pProceedParsing = function () { + var token; + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + this._startedParsing = true; + } + while (this._pHasTime()) { + token = this.getNextToken(); + switch (token) { + case MD5MeshParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case MD5MeshParser.VERSION_TOKEN: + this._version = this.getNextInt(); + if (this._version != 10) + throw new Error("Unknown version number encountered!"); + break; + case MD5MeshParser.COMMAND_LINE_TOKEN: + this.parseCMD(); + break; + case MD5MeshParser.NUM_JOINTS_TOKEN: + this._numJoints = this.getNextInt(); + this._bindPoses = new Array(this._numJoints); + break; + case MD5MeshParser.NUM_MESHES_TOKEN: + this._numMeshes = this.getNextInt(); + break; + case MD5MeshParser.JOINTS_TOKEN: + this.parseJoints(); + break; + case MD5MeshParser.MESH_TOKEN: + this.parseMesh(); + break; + default: + if (!this._reachedEOF) + this.sendUnknownKeywordError(); + } + if (this._reachedEOF) { + this.calculateMaxJointCount(); + this._animationSet = new SkeletonAnimationSet(this._maxJointCount); + this._mesh = new Mesh(new Geometry(), null); + this._geometry = this._mesh.geometry; + for (var i = 0; i < this._meshData.length; ++i) + this._geometry.addSubGeometry(this.translateGeom(this._meshData[i].vertexData, this._meshData[i].weightData, this._meshData[i].indices)); + //_geometry.animation = _animation; + // _mesh.animationController = _animationController; + //add to the content property + this._pContent.addChild(this._mesh); + this._pFinalizeAsset(this._geometry); + this._pFinalizeAsset(this._mesh); + this._pFinalizeAsset(this._skeleton); + this._pFinalizeAsset(this._animationSet); + return ParserBase.PARSING_DONE; + } + } + return ParserBase.MORE_TO_PARSE; + }; + MD5MeshParser.prototype._pStartParsing = function (frameLimit) { + _super.prototype._pStartParsing.call(this, frameLimit); + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + }; + MD5MeshParser.prototype.calculateMaxJointCount = function () { + this._maxJointCount = 0; + var numMeshData = this._meshData.length; + for (var i = 0; i < numMeshData; ++i) { + var meshData = this._meshData[i]; + var vertexData = meshData.vertexData; + var numVerts = vertexData.length; + for (var j = 0; j < numVerts; ++j) { + var zeroWeights = this.countZeroWeightJoints(vertexData[j], meshData.weightData); + var totalJoints = vertexData[j].countWeight - zeroWeights; + if (totalJoints > this._maxJointCount) + this._maxJointCount = totalJoints; + } + } + }; + MD5MeshParser.prototype.countZeroWeightJoints = function (vertex, weights) { + var start = vertex.startWeight; + var end = vertex.startWeight + vertex.countWeight; + var count = 0; + var weight; + for (var i = start; i < end; ++i) { + weight = weights[i].bias; + if (weight == 0) + ++count; + } + return count; + }; + /** + * Parses the skeleton's joints. + */ + MD5MeshParser.prototype.parseJoints = function () { + var ch; + var joint; + var pos; + var quat; + var i = 0; + var token = this.getNextToken(); + if (token != "{") + this.sendUnknownKeywordError(); + this._skeleton = new Skeleton(); + do { + if (this._reachedEOF) + this.sendEOFError(); + joint = new SkeletonJoint(); + joint.name = this.parseLiteralstring(); + joint.parentIndex = this.getNextInt(); + pos = this.parseVector3D(); + pos = this._rotationQuat.rotatePoint(pos); + quat = this.parseQuaternion(); + // todo: check if this is correct, or maybe we want to actually store it as quats? + this._bindPoses[i] = quat.toMatrix3D(); + this._bindPoses[i].appendTranslation(pos.x, pos.y, pos.z); + var inv = this._bindPoses[i].clone(); + inv.invert(); + joint.inverseBindPose = inv.rawData; + this._skeleton.joints[i++] = joint; + ch = this.getNextChar(); + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5MeshParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + } + if (ch != "}") + this.putBack(); + } while (ch != "}"); + }; + /** + * Puts back the last read character into the data stream. + */ + MD5MeshParser.prototype.putBack = function () { + this._parseIndex--; + this._charLineIndex--; + this._reachedEOF = this._parseIndex >= this._textData.length; + }; + /** + * Parses the mesh geometry. + */ + MD5MeshParser.prototype.parseMesh = function () { + var token = this.getNextToken(); + var ch; + var vertexData; + var weights; + var indices /*uint*/; + if (token != "{") + this.sendUnknownKeywordError(); + if (this._shaders == null) + this._shaders = new Array(); + while (ch != "}") { + ch = this.getNextToken(); + switch (ch) { + case MD5MeshParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case MD5MeshParser.MESH_SHADER_TOKEN: + this._shaders.push(this.parseLiteralstring()); + break; + case MD5MeshParser.MESH_NUM_VERTS_TOKEN: + vertexData = new Array(this.getNextInt()); + break; + case MD5MeshParser.MESH_NUM_TRIS_TOKEN: + indices = new Array(this.getNextInt() * 3); + break; + case MD5MeshParser.MESH_NUM_WEIGHTS_TOKEN: + weights = new Array(this.getNextInt()); + break; + case MD5MeshParser.MESH_VERT_TOKEN: + this.parseVertex(vertexData); + break; + case MD5MeshParser.MESH_TRI_TOKEN: + this.parseTri(indices); + break; + case MD5MeshParser.MESH_WEIGHT_TOKEN: + this.parseJoint(weights); + break; + } + } + if (this._meshData == null) + this._meshData = new Array(); + var i = this._meshData.length; + this._meshData[i] = new MeshData(); + this._meshData[i].vertexData = vertexData; + this._meshData[i].weightData = weights; + this._meshData[i].indices = indices; + }; + /** + * Converts the mesh data to a SkinnedSub instance. + * @param vertexData The mesh's vertices. + * @param weights The joint weights per vertex. + * @param indices The indices for the faces. + * @return A SubGeometry instance containing all geometrical data for the current mesh. + */ + MD5MeshParser.prototype.translateGeom = function (vertexData, weights, indices /*uint*/) { + var len = vertexData.length; + var v1 /*int*/, v2 /*int*/, v3 /*int*/; + var vertex; + var weight; + var bindPose; + var pos; + var subGeom = new TriangleSubGeometry(true); + var uvs = new Array(len * 2); + var vertices = new Array(len * 3); + var jointIndices = new Array(len * this._maxJointCount); + var jointWeights = new Array(len * this._maxJointCount); + var l = 0; + var nonZeroWeights /*int*/; + for (var i = 0; i < len; ++i) { + vertex = vertexData[i]; + v1 = vertex.index * 3; + v2 = v1 + 1; + v3 = v1 + 2; + vertices[v1] = vertices[v2] = vertices[v3] = 0; + nonZeroWeights = 0; + for (var j = 0; j < vertex.countWeight; ++j) { + weight = weights[vertex.startWeight + j]; + if (weight.bias > 0) { + bindPose = this._bindPoses[weight.joint]; + pos = bindPose.transformVector(weight.pos); + vertices[v1] += pos.x * weight.bias; + vertices[v2] += pos.y * weight.bias; + vertices[v3] += pos.z * weight.bias; + // indices need to be multiplied by 3 (amount of matrix registers) + jointIndices[l] = weight.joint * 3; + jointWeights[l++] = weight.bias; + ++nonZeroWeights; + } + } + for (j = nonZeroWeights; j < this._maxJointCount; ++j) { + jointIndices[l] = 0; + jointWeights[l++] = 0; + } + v1 = vertex.index << 1; + uvs[v1++] = vertex.s; + uvs[v1] = vertex.t; + } + subGeom.jointsPerVertex = this._maxJointCount; + subGeom.updateIndices(indices); + subGeom.updatePositions(vertices); + subGeom.updateUVs(uvs); + subGeom.updateJointIndices(jointIndices); + subGeom.updateJointWeights(jointWeights); + // cause explicit updates + subGeom.vertexNormals; + subGeom.vertexTangents; + // turn auto updates off because they may be animated and set explicitly + subGeom.autoDeriveTangents = false; + subGeom.autoDeriveNormals = false; + return subGeom; + }; + /** + * Retrieve the next triplet of vertex indices that form a face. + * @param indices The index list in which to store the read data. + */ + MD5MeshParser.prototype.parseTri = function (indices /*uint*/) { + var index = this.getNextInt() * 3; + indices[index] = this.getNextInt(); + indices[index + 1] = this.getNextInt(); + indices[index + 2] = this.getNextInt(); + }; + /** + * Reads a new joint data set for a single joint. + * @param weights the target list to contain the weight data. + */ + MD5MeshParser.prototype.parseJoint = function (weights) { + var weight = new JointData(); + weight.index = this.getNextInt(); + weight.joint = this.getNextInt(); + weight.bias = this.getNextNumber(); + weight.pos = this.parseVector3D(); + weights[weight.index] = weight; + }; + /** + * Reads the data for a single vertex. + * @param vertexData The list to contain the vertex data. + */ + MD5MeshParser.prototype.parseVertex = function (vertexData) { + var vertex = new VertexData(); + vertex.index = this.getNextInt(); + this.parseUV(vertex); + vertex.startWeight = this.getNextInt(); + vertex.countWeight = this.getNextInt(); + // if (vertex.countWeight > _maxJointCount) _maxJointCount = vertex.countWeight; + vertexData[vertex.index] = vertex; + }; + /** + * Reads the next uv coordinate. + * @param vertexData The vertexData to contain the UV coordinates. + */ + MD5MeshParser.prototype.parseUV = function (vertexData) { + var ch = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + vertexData.s = this.getNextNumber(); + vertexData.t = this.getNextNumber(); + if (this.getNextToken() != ")") + this.sendParseError(")"); + }; + /** + * Gets the next token in the data stream. + */ + MD5MeshParser.prototype.getNextToken = function () { + var ch; + var token = ""; + while (!this._reachedEOF) { + ch = this.getNextChar(); + if (ch == " " || ch == "\r" || ch == "\n" || ch == "\t") { + if (token != MD5MeshParser.COMMENT_TOKEN) + this.skipWhiteSpace(); + if (token != "") + return token; + } + else + token += ch; + if (token == MD5MeshParser.COMMENT_TOKEN) + return token; + } + return token; + }; + /** + * Skips all whitespace in the data stream. + */ + MD5MeshParser.prototype.skipWhiteSpace = function () { + var ch; + do + ch = this.getNextChar(); + while (ch == "\n" || ch == " " || ch == "\r" || ch == "\t"); + this.putBack(); + }; + /** + * Skips to the next line. + */ + MD5MeshParser.prototype.ignoreLine = function () { + var ch; + while (!this._reachedEOF && ch != "\n") + ch = this.getNextChar(); + }; + /** + * Retrieves the next single character in the data stream. + */ + MD5MeshParser.prototype.getNextChar = function () { + var ch = this._textData.charAt(this._parseIndex++); + if (ch == "\n") { + ++this._line; + this._charLineIndex = 0; + } + else if (ch != "\r") + ++this._charLineIndex; + if (this._parseIndex >= this._textData.length) + this._reachedEOF = true; + return ch; + }; + /** + * Retrieves the next integer in the data stream. + */ + MD5MeshParser.prototype.getNextInt = function () { + var i = parseInt(this.getNextToken()); + if (isNaN(i)) + this.sendParseError("int type"); + return i; + }; + /** + * Retrieves the next floating point number in the data stream. + */ + MD5MeshParser.prototype.getNextNumber = function () { + var f = parseFloat(this.getNextToken()); + if (isNaN(f)) + this.sendParseError("float type"); + return f; + }; + /** + * Retrieves the next 3d vector in the data stream. + */ + MD5MeshParser.prototype.parseVector3D = function () { + var vec = new Vector3D(); + var ch = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + vec.x = -this.getNextNumber(); + vec.y = this.getNextNumber(); + vec.z = this.getNextNumber(); + if (this.getNextToken() != ")") + this.sendParseError(")"); + return vec; + }; + /** + * Retrieves the next quaternion in the data stream. + */ + MD5MeshParser.prototype.parseQuaternion = function () { + var quat = new Quaternion(); + var ch = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + quat.x = this.getNextNumber(); + quat.y = -this.getNextNumber(); + quat.z = -this.getNextNumber(); + // quat supposed to be unit length + var t = 1 - quat.x * quat.x - quat.y * quat.y - quat.z * quat.z; + quat.w = t < 0 ? 0 : -Math.sqrt(t); + if (this.getNextToken() != ")") + this.sendParseError(")"); + var rotQuat = new Quaternion(); + rotQuat.multiply(this._rotationQuat, quat); + return rotQuat; + }; + /** + * Parses the command line data. + */ + MD5MeshParser.prototype.parseCMD = function () { + // just ignore the command line property + this.parseLiteralstring(); + }; + /** + * Retrieves the next literal string in the data stream. A literal string is a sequence of characters bounded + * by double quotes. + */ + MD5MeshParser.prototype.parseLiteralstring = function () { + this.skipWhiteSpace(); + var ch = this.getNextChar(); + var str = ""; + if (ch != "\"") + this.sendParseError("\""); + do { + if (this._reachedEOF) + this.sendEOFError(); + ch = this.getNextChar(); + if (ch != "\"") + str += ch; + } while (ch != "\""); + return str; + }; + /** + * Throws an end-of-file error when a premature end of file was encountered. + */ + MD5MeshParser.prototype.sendEOFError = function () { + throw new Error("Unexpected end of file"); + }; + /** + * Throws an error when an unexpected token was encountered. + * @param expected The token type that was actually expected. + */ + MD5MeshParser.prototype.sendParseError = function (expected) { + throw new Error("Unexpected token at line " + (this._line + 1) + ", character " + this._charLineIndex + ". " + expected + " expected, but " + this._textData.charAt(this._parseIndex - 1) + " encountered"); + }; + /** + * Throws an error when an unknown keyword was encountered. + */ + MD5MeshParser.prototype.sendUnknownKeywordError = function () { + throw new Error("Unknown keyword at line " + (this._line + 1) + ", character " + this._charLineIndex + ". "); + }; + MD5MeshParser.VERSION_TOKEN = "MD5Version"; + MD5MeshParser.COMMAND_LINE_TOKEN = "commandline"; + MD5MeshParser.NUM_JOINTS_TOKEN = "numJoints"; + MD5MeshParser.NUM_MESHES_TOKEN = "numMeshes"; + MD5MeshParser.COMMENT_TOKEN = "//"; + MD5MeshParser.JOINTS_TOKEN = "joints"; + MD5MeshParser.MESH_TOKEN = "mesh"; + MD5MeshParser.MESH_SHADER_TOKEN = "shader"; + MD5MeshParser.MESH_NUM_VERTS_TOKEN = "numverts"; + MD5MeshParser.MESH_VERT_TOKEN = "vert"; + MD5MeshParser.MESH_NUM_TRIS_TOKEN = "numtris"; + MD5MeshParser.MESH_TRI_TOKEN = "tri"; + MD5MeshParser.MESH_NUM_WEIGHTS_TOKEN = "numweights"; + MD5MeshParser.MESH_WEIGHT_TOKEN = "weight"; + return MD5MeshParser; +})(ParserBase); +var VertexData = (function () { + function VertexData() { + } + return VertexData; +})(); +var JointData = (function () { + function JointData() { + } + return JointData; +})(); +var MeshData = (function () { + function MeshData() { + } + return MeshData; +})(); +module.exports = MD5MeshParser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvbWQ1bWVzaHBhcnNlci50cyJdLCJuYW1lcyI6WyJNRDVNZXNoUGFyc2VyIiwiTUQ1TWVzaFBhcnNlci5jb25zdHJ1Y3RvciIsIk1ENU1lc2hQYXJzZXIuc3VwcG9ydHNUeXBlIiwiTUQ1TWVzaFBhcnNlci5zdXBwb3J0c0RhdGEiLCJNRDVNZXNoUGFyc2VyLl9wUHJvY2VlZFBhcnNpbmciLCJNRDVNZXNoUGFyc2VyLl9wU3RhcnRQYXJzaW5nIiwiTUQ1TWVzaFBhcnNlci5jYWxjdWxhdGVNYXhKb2ludENvdW50IiwiTUQ1TWVzaFBhcnNlci5jb3VudFplcm9XZWlnaHRKb2ludHMiLCJNRDVNZXNoUGFyc2VyLnBhcnNlSm9pbnRzIiwiTUQ1TWVzaFBhcnNlci5wdXRCYWNrIiwiTUQ1TWVzaFBhcnNlci5wYXJzZU1lc2giLCJNRDVNZXNoUGFyc2VyLnRyYW5zbGF0ZUdlb20iLCJNRDVNZXNoUGFyc2VyLnBhcnNlVHJpIiwiTUQ1TWVzaFBhcnNlci5wYXJzZUpvaW50IiwiTUQ1TWVzaFBhcnNlci5wYXJzZVZlcnRleCIsIk1ENU1lc2hQYXJzZXIucGFyc2VVViIsIk1ENU1lc2hQYXJzZXIuZ2V0TmV4dFRva2VuIiwiTUQ1TWVzaFBhcnNlci5za2lwV2hpdGVTcGFjZSIsIk1ENU1lc2hQYXJzZXIuaWdub3JlTGluZSIsIk1ENU1lc2hQYXJzZXIuZ2V0TmV4dENoYXIiLCJNRDVNZXNoUGFyc2VyLmdldE5leHRJbnQiLCJNRDVNZXNoUGFyc2VyLmdldE5leHROdW1iZXIiLCJNRDVNZXNoUGFyc2VyLnBhcnNlVmVjdG9yM0QiLCJNRDVNZXNoUGFyc2VyLnBhcnNlUXVhdGVybmlvbiIsIk1ENU1lc2hQYXJzZXIucGFyc2VDTUQiLCJNRDVNZXNoUGFyc2VyLnBhcnNlTGl0ZXJhbHN0cmluZyIsIk1ENU1lc2hQYXJzZXIuc2VuZEVPRkVycm9yIiwiTUQ1TWVzaFBhcnNlci5zZW5kUGFyc2VFcnJvciIsIk1ENU1lc2hQYXJzZXIuc2VuZFVua25vd25LZXl3b3JkRXJyb3IiLCJWZXJ0ZXhEYXRhIiwiVmVydGV4RGF0YS5jb25zdHJ1Y3RvciIsIkpvaW50RGF0YSIsIkpvaW50RGF0YS5jb25zdHJ1Y3RvciIsIk1lc2hEYXRhIiwiTWVzaERhdGEuY29uc3RydWN0b3IiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQU8sc0JBQXNCLFdBQWEsbURBQW1ELENBQUMsQ0FBQztBQUMvRixJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUN0RSxJQUFPLG1CQUFtQixXQUFjLCtDQUErQyxDQUFDLENBQUM7QUFFekYsSUFBTyxVQUFVLFdBQWdCLHNDQUFzQyxDQUFDLENBQUM7QUFDekUsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFDdEUsSUFBTyxtQkFBbUIsV0FBYyw4Q0FBOEMsQ0FBQyxDQUFDO0FBQ3hGLElBQU8sSUFBSSxXQUFrQiwrQkFBK0IsQ0FBQyxDQUFDO0FBQzlELElBQU8sVUFBVSxXQUFnQixvQ0FBb0MsQ0FBQyxDQUFDO0FBRXZFLElBQU8sb0JBQW9CLFdBQWMsc0RBQXNELENBQUMsQ0FBQztBQUNqRyxJQUFPLFFBQVEsV0FBaUIsK0NBQStDLENBQUMsQ0FBQztBQUNqRixJQUFPLGFBQWEsV0FBZSxvREFBb0QsQ0FBQyxDQUFDO0FBRXpGLEFBT0EsZ0RBUGdEO0FBRWhEOzs7O0dBSUc7SUFDRyxhQUFhO0lBQVNBLFVBQXRCQSxhQUFhQSxVQUFtQkE7SUF5Q3JDQTs7T0FFR0E7SUFDSEEsU0E1Q0tBLGFBQWFBLENBNENOQSxzQkFBc0NBLEVBQUVBLHlCQUFvQ0E7UUFBNUVDLHNDQUFzQ0EsR0FBdENBLDZCQUFzQ0E7UUFBRUEseUNBQW9DQSxHQUFwQ0EsNkJBQW9DQTtRQUV2RkEsa0JBQU1BLG1CQUFtQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUExQnpCQSxnQkFBV0EsR0FBa0JBLENBQUNBLENBQUNBO1FBRS9CQSxVQUFLQSxHQUFrQkEsQ0FBQ0EsQ0FBQ0E7UUFDekJBLG1CQUFjQSxHQUFrQkEsQ0FBQ0EsQ0FB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LENBQUNBO0lBQzVCQSwwQkFBWUEsR0FBVUEsUUFBUUEsQ0FBQ0E7SUFDL0JBLHdCQUFVQSxHQUFVQSxNQUFNQSxDQUFDQTtJQUUzQkEsK0JBQWlCQSxHQUFVQSxRQUFRQSxDQUFDQTtJQUNwQ0Esa0NBQW9CQSxHQUFVQSxVQUFVQSxDQUFDQTtJQUN6Q0EsNkJBQWVBLEdBQVVBLE1BQU1BLENBQUNBO0lBQ2hDQSxpQ0FBbUJBLEdBQVVBLFNBQVNBLENBQUNBO0lBQ3ZDQSw0QkFBY0EsR0FBVUEsS0FBS0EsQ0FBQ0E7SUFDOUJBLG9DQUFzQkEsR0FBVUEsWUFBWUEsQ0FBQ0E7SUFDN0NBLCtCQUFpQkEsR0FBVUEsUUFBUUEsQ0FBQ0E7SUF3bUJuREEsb0JBQUNBO0FBQURBLENBMW5CQSxBQTBuQkNBLEVBMW5CMkIsVUFBVSxFQTBuQnJDO0FBS0QsSUFBTSxVQUFVO0lBQWhCNkIsU0FBTUEsVUFBVUE7SUFPaEJDLENBQUNBO0lBQURELGlCQUFDQTtBQUFEQSxDQVBBLEFBT0NBLElBQUE7QUFFRCxJQUFNLFNBQVM7SUFBZkUsU0FBTUEsU0FBU0E7SUFNZkMsQ0FBQ0E7SUFBREQsZ0JBQUNBO0FBQURBLENBTkEsQUFNQ0EsSUFBQTtBQUVELElBQU0sUUFBUTtJQUFkRSxTQUFNQSxRQUFRQTtJQUtkQyxDQUFDQTtJQUFERCxlQUFDQTtBQUFEQSxDQUxBLEFBS0NBLElBQUE7QUF6QkQsaUJBQVMsYUFBYSxDQUFDIiwiZmlsZSI6InBhcnNlcnMvTUQ1TWVzaFBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEaXNwbGF5T2JqZWN0Q29udGFpbmVyXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvRGlzcGxheU9iamVjdENvbnRhaW5lclwiKTtcbmltcG9ydCBHZW9tZXRyeVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9HZW9tZXRyeVwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL1RyaWFuZ2xlU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgTWF0cml4M0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RcIik7XG5pbXBvcnQgUXVhdGVybmlvblx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vUXVhdGVybmlvblwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBVUkxMb2FkZXJEYXRhRm9ybWF0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMTG9hZGVyRGF0YUZvcm1hdFwiKTtcbmltcG9ydCBNZXNoXHRcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IFBhcnNlckJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9QYXJzZXJCYXNlXCIpO1xuXG5pbXBvcnQgU2tlbGV0b25BbmltYXRpb25TZXRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvU2tlbGV0b25BbmltYXRpb25TZXRcIik7XG5pbXBvcnQgU2tlbGV0b25cdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvblwiKTtcbmltcG9ydCBTa2VsZXRvbkpvaW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9hbmltYXRvcnMvZGF0YS9Ta2VsZXRvbkpvaW50XCIpO1xuXG4vLyB0b2RvOiBjcmVhdGUgYW5pbWF0aW9uIHN5c3RlbSwgcGFyc2Ugc2tlbGV0b25cblxuLyoqXG4gKiBNRDVNZXNoUGFyc2VyIHByb3ZpZGVzIGEgcGFyc2VyIGZvciB0aGUgbWQ1bWVzaCBkYXRhIHR5cGUsIHByb3ZpZGluZyB0aGUgZ2VvbWV0cnkgb2YgdGhlIG1kNSBmb3JtYXQuXG4gKlxuICogdG9kbzogb3B0aW1pemVcbiAqL1xuY2xhc3MgTUQ1TWVzaFBhcnNlciBleHRlbmRzIFBhcnNlckJhc2Vcbntcblx0cHJpdmF0ZSBfdGV4dERhdGE6c3RyaW5nO1xuXHRwcml2YXRlIF9zdGFydGVkUGFyc2luZzpib29sZWFuO1xuXHRwdWJsaWMgc3RhdGljIFZFUlNJT05fVE9LRU46c3RyaW5nID0gXCJNRDVWZXJzaW9uXCI7XG5cdHB1YmxpYyBzdGF0aWMgQ09NTUFORF9MSU5FX1RPS0VOOnN0cmluZyA9IFwiY29tbWFuZGxpbmVcIjtcblx0cHVibGljIHN0YXRpYyBOVU1fSk9JTlRTX1RPS0VOOnN0cmluZyA9IFwibnVtSm9pbnRzXCI7XG5cdHB1YmxpYyBzdGF0aWMgTlVNX01FU0hFU19UT0tFTjpzdHJpbmcgPSBcIm51bU1lc2hlc1wiO1xuXHRwdWJsaWMgc3RhdGljIENPTU1FTlRfVE9LRU46c3RyaW5nID0gXCIvL1wiO1xuXHRwdWJsaWMgc3RhdGljIEpPSU5UU19UT0tFTjpzdHJpbmcgPSBcImpvaW50c1wiO1xuXHRwdWJsaWMgc3RhdGljIE1FU0hfVE9LRU46c3RyaW5nID0gXCJtZXNoXCI7XG5cblx0cHVibGljIHN0YXRpYyBNRVNIX1NIQURFUl9UT0tFTjpzdHJpbmcgPSBcInNoYWRlclwiO1xuXHRwdWJsaWMgc3RhdGljIE1FU0hfTlVNX1ZFUlRTX1RPS0VOOnN0cmluZyA9IFwibnVtdmVydHNcIjtcblx0cHVibGljIHN0YXRpYyBNRVNIX1ZFUlRfVE9LRU46c3RyaW5nID0gXCJ2ZXJ0XCI7XG5cdHB1YmxpYyBzdGF0aWMgTUVTSF9OVU1fVFJJU19UT0tFTjpzdHJpbmcgPSBcIm51bXRyaXNcIjtcblx0cHVibGljIHN0YXRpYyBNRVNIX1RSSV9UT0tFTjpzdHJpbmcgPSBcInRyaVwiO1xuXHRwdWJsaWMgc3RhdGljIE1FU0hfTlVNX1dFSUdIVFNfVE9LRU46c3RyaW5nID0gXCJudW13ZWlnaHRzXCI7XG5cdHB1YmxpYyBzdGF0aWMgTUVTSF9XRUlHSFRfVE9LRU46c3RyaW5nID0gXCJ3ZWlnaHRcIjtcblxuXHRwcml2YXRlIF9wYXJzZUluZGV4Om51bWJlciAvKmludCovID0gMDtcblx0cHJpdmF0ZSBfcmVhY2hlZEVPRjpib29sZWFuO1xuXHRwcml2YXRlIF9saW5lOm51bWJlciAvKmludCovID0gMDtcblx0cHJpdmF0ZSBfY2hhckxpbmVJbmRleDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdHByaXZhdGUgX3ZlcnNpb246bnVtYmVyIC8qaW50Ki87XG5cdHByaXZhdGUgX251bUpvaW50czpudW1iZXIgLyppbnQqLztcblx0cHJpdmF0ZSBfbnVtTWVzaGVzOm51bWJlciAvKmludCovO1xuXG5cdHByaXZhdGUgX21lc2g6TWVzaDtcblx0cHJpdmF0ZSBfc2hhZGVyczpBcnJheTxzdHJpbmc+O1xuXG5cdHByaXZhdGUgX21heEpvaW50Q291bnQ6bnVtYmVyIC8qaW50Ki87XG5cdHByaXZhdGUgX21lc2hEYXRhOkFycmF5PE1lc2hEYXRhPjtcblx0cHJpdmF0ZSBfYmluZFBvc2VzOkFycmF5PE1hdHJpeDNEPjtcblx0cHJpdmF0ZSBfZ2VvbWV0cnk6R2VvbWV0cnk7XG5cblx0cHJpdmF0ZSBfc2tlbGV0b246U2tlbGV0b247XG5cdHByaXZhdGUgX2FuaW1hdGlvblNldDpTa2VsZXRvbkFuaW1hdGlvblNldDtcblxuXHRwcml2YXRlIF9yb3RhdGlvblF1YXQ6UXVhdGVybmlvbjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBNRDVNZXNoUGFyc2VyIG9iamVjdC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGFkZGl0aW9uYWxSb3RhdGlvbkF4aXM6VmVjdG9yM0QgPSBudWxsLCBhZGRpdGlvbmFsUm90YXRpb25SYWRpYW5zOm51bWJlciA9IDApXG5cdHtcblx0XHRzdXBlcihVUkxMb2FkZXJEYXRhRm9ybWF0LlRFWFQpO1xuXHRcdHRoaXMuX3JvdGF0aW9uUXVhdCA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cblx0XHR0aGlzLl9yb3RhdGlvblF1YXQuZnJvbUF4aXNBbmdsZShWZWN0b3IzRC5YX0FYSVMsIC1NYXRoLlBJKi41KTtcblxuXHRcdGlmIChhZGRpdGlvbmFsUm90YXRpb25BeGlzKSB7XG5cdFx0XHR2YXIgcXVhdDpRdWF0ZXJuaW9uID0gbmV3IFF1YXRlcm5pb24oKTtcblx0XHRcdHF1YXQuZnJvbUF4aXNBbmdsZShhZGRpdGlvbmFsUm90YXRpb25BeGlzLCBhZGRpdGlvbmFsUm90YXRpb25SYWRpYW5zKTtcblx0XHRcdHRoaXMuX3JvdGF0aW9uUXVhdC5tdWx0aXBseSh0aGlzLl9yb3RhdGlvblF1YXQsIHF1YXQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgYSBnaXZlbiBmaWxlIGV4dGVuc2lvbiBpcyBzdXBwb3J0ZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGV4dGVuc2lvbiBUaGUgZmlsZSBleHRlbnNpb24gb2YgYSBwb3RlbnRpYWwgZmlsZSB0byBiZSBwYXJzZWQuXG5cdCAqIEByZXR1cm4gV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGZpbGUgdHlwZSBpcyBzdXBwb3J0ZWQuXG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIHN1cHBvcnRzVHlwZShleHRlbnNpb246c3RyaW5nKTpib29sZWFuXG5cdHtcblx0XHRleHRlbnNpb24gPSBleHRlbnNpb24udG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gZXh0ZW5zaW9uID09IFwibWQ1bWVzaFwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFByb2NlZWRQYXJzaW5nKCk6Ym9vbGVhblxuXHR7XG5cdFx0dmFyIHRva2VuOnN0cmluZztcblxuXHRcdGlmICghdGhpcy5fc3RhcnRlZFBhcnNpbmcpIHtcblx0XHRcdHRoaXMuX3RleHREYXRhID0gdGhpcy5fcEdldFRleHREYXRhKCk7XG5cdFx0XHR0aGlzLl9zdGFydGVkUGFyc2luZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0d2hpbGUgKHRoaXMuX3BIYXNUaW1lKCkpIHtcblx0XHRcdHRva2VuID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblx0XHRcdHN3aXRjaCAodG9rZW4pIHtcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLkNPTU1FTlRfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5pZ25vcmVMaW5lKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1TWVzaFBhcnNlci5WRVJTSU9OX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMuX3ZlcnNpb24gPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdFx0XHRpZiAodGhpcy5fdmVyc2lvbiAhPSAxMClcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdmVyc2lvbiBudW1iZXIgZW5jb3VudGVyZWQhXCIpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENU1lc2hQYXJzZXIuQ09NTUFORF9MSU5FX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VDTUQoKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLk5VTV9KT0lOVFNfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5fbnVtSm9pbnRzID0gdGhpcy5nZXROZXh0SW50KCk7XG5cdFx0XHRcdFx0dGhpcy5fYmluZFBvc2VzID0gbmV3IEFycmF5PE1hdHJpeDNEPih0aGlzLl9udW1Kb2ludHMpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENU1lc2hQYXJzZXIuTlVNX01FU0hFU19UT0tFTjpcblx0XHRcdFx0XHR0aGlzLl9udW1NZXNoZXMgPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLkpPSU5UU19UT0tFTjpcblx0XHRcdFx0XHR0aGlzLnBhcnNlSm9pbnRzKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1TWVzaFBhcnNlci5NRVNIX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VNZXNoKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0aWYgKCF0aGlzLl9yZWFjaGVkRU9GKVxuXHRcdFx0XHRcdFx0dGhpcy5zZW5kVW5rbm93bktleXdvcmRFcnJvcigpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5fcmVhY2hlZEVPRikge1xuXHRcdFx0XHR0aGlzLmNhbGN1bGF0ZU1heEpvaW50Q291bnQoKTtcblx0XHRcdFx0dGhpcy5fYW5pbWF0aW9uU2V0ID0gbmV3IFNrZWxldG9uQW5pbWF0aW9uU2V0KHRoaXMuX21heEpvaW50Q291bnQpO1xuXG5cdFx0XHRcdHRoaXMuX21lc2ggPSBuZXcgTWVzaChuZXcgR2VvbWV0cnkoKSwgbnVsbCk7XG5cdFx0XHRcdHRoaXMuX2dlb21ldHJ5ID0gdGhpcy5fbWVzaC5nZW9tZXRyeTtcblxuXHRcdFx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gMDsgaSA8IHRoaXMuX21lc2hEYXRhLmxlbmd0aDsgKytpKVxuXHRcdFx0XHRcdHRoaXMuX2dlb21ldHJ5LmFkZFN1Ykdlb21ldHJ5KHRoaXMudHJhbnNsYXRlR2VvbSh0aGlzLl9tZXNoRGF0YVtpXS52ZXJ0ZXhEYXRhLCB0aGlzLl9tZXNoRGF0YVtpXS53ZWlnaHREYXRhLCB0aGlzLl9tZXNoRGF0YVtpXS5pbmRpY2VzKSk7XG5cblx0XHRcdFx0Ly9fZ2VvbWV0cnkuYW5pbWF0aW9uID0gX2FuaW1hdGlvbjtcblx0XHRcdFx0Ly9cdFx0XHRcdFx0X21lc2guYW5pbWF0aW9uQ29udHJvbGxlciA9IF9hbmltYXRpb25Db250cm9sbGVyO1xuXG5cdFx0XHRcdC8vYWRkIHRvIHRoZSBjb250ZW50IHByb3BlcnR5XG5cdFx0XHRcdCg8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gdGhpcy5fcENvbnRlbnQpLmFkZENoaWxkKHRoaXMuX21lc2gpO1xuXG5cdFx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX2dlb21ldHJ5KTtcblx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQodGhpcy5fbWVzaCk7XG5cdFx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KHRoaXMuX3NrZWxldG9uKTtcblx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQodGhpcy5fYW5pbWF0aW9uU2V0KTtcblx0XHRcdFx0cmV0dXJuIFBhcnNlckJhc2UuUEFSU0lOR19ET05FO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gUGFyc2VyQmFzZS5NT1JFX1RPX1BBUlNFO1xuXHR9XG5cblx0cHVibGljIF9wU3RhcnRQYXJzaW5nKGZyYW1lTGltaXQ6bnVtYmVyKVxuXHR7XG5cdFx0c3VwZXIuX3BTdGFydFBhcnNpbmcoZnJhbWVMaW1pdCk7XG5cblx0XHQvL2NyZWF0ZSBhIGNvbnRlbnQgb2JqZWN0IGZvciBMb2FkZXJzXG5cdFx0dGhpcy5fcENvbnRlbnQgPSBuZXcgRGlzcGxheU9iamVjdENvbnRhaW5lcigpO1xuXHR9XG5cblx0cHJpdmF0ZSBjYWxjdWxhdGVNYXhKb2ludENvdW50KCk6dm9pZFxuXHR7XG5cdFx0dGhpcy5fbWF4Sm9pbnRDb3VudCA9IDA7XG5cblx0XHR2YXIgbnVtTWVzaERhdGE6bnVtYmVyIC8qaW50Ki8gPSB0aGlzLl9tZXNoRGF0YS5sZW5ndGg7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCBudW1NZXNoRGF0YTsgKytpKSB7XG5cdFx0XHR2YXIgbWVzaERhdGE6TWVzaERhdGEgPSB0aGlzLl9tZXNoRGF0YVtpXTtcblx0XHRcdHZhciB2ZXJ0ZXhEYXRhOkFycmF5PFZlcnRleERhdGE+ID0gbWVzaERhdGEudmVydGV4RGF0YTtcblx0XHRcdHZhciBudW1WZXJ0czpudW1iZXIgLyppbnQqLyA9IHZlcnRleERhdGEubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKHZhciBqOm51bWJlciAvKmludCovID0gMDsgaiA8IG51bVZlcnRzOyArK2opIHtcblx0XHRcdFx0dmFyIHplcm9XZWlnaHRzOm51bWJlciAvKmludCovID0gdGhpcy5jb3VudFplcm9XZWlnaHRKb2ludHModmVydGV4RGF0YVtqXSwgbWVzaERhdGEud2VpZ2h0RGF0YSk7XG5cdFx0XHRcdHZhciB0b3RhbEpvaW50czpudW1iZXIgLyppbnQqLyA9IHZlcnRleERhdGFbal0uY291bnRXZWlnaHQgLSB6ZXJvV2VpZ2h0cztcblx0XHRcdFx0aWYgKHRvdGFsSm9pbnRzID4gdGhpcy5fbWF4Sm9pbnRDb3VudClcblx0XHRcdFx0XHR0aGlzLl9tYXhKb2ludENvdW50ID0gdG90YWxKb2ludHM7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBjb3VudFplcm9XZWlnaHRKb2ludHModmVydGV4OlZlcnRleERhdGEsIHdlaWdodHM6QXJyYXk8Sm9pbnREYXRhPik6bnVtYmVyIC8qaW50Ki9cblx0e1xuXHRcdHZhciBzdGFydDpudW1iZXIgLyppbnQqLyA9IHZlcnRleC5zdGFydFdlaWdodDtcblx0XHR2YXIgZW5kOm51bWJlciAvKmludCovID0gdmVydGV4LnN0YXJ0V2VpZ2h0ICsgdmVydGV4LmNvdW50V2VpZ2h0O1xuXHRcdHZhciBjb3VudDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdFx0dmFyIHdlaWdodDpudW1iZXI7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciAvKmludCovID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuXHRcdFx0d2VpZ2h0ID0gd2VpZ2h0c1tpXS5iaWFzO1xuXHRcdFx0aWYgKHdlaWdodCA9PSAwKVxuXHRcdFx0XHQrK2NvdW50O1xuXHRcdH1cblxuXHRcdHJldHVybiBjb3VudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgdGhlIHNrZWxldG9uJ3Mgam9pbnRzLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZUpvaW50cygpOnZvaWRcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIGpvaW50OlNrZWxldG9uSm9pbnQ7XG5cdFx0dmFyIHBvczpWZWN0b3IzRDtcblx0XHR2YXIgcXVhdDpRdWF0ZXJuaW9uO1xuXHRcdHZhciBpOm51bWJlciAvKmludCovID0gMDtcblx0XHR2YXIgdG9rZW46c3RyaW5nID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblxuXHRcdGlmICh0b2tlbiAhPSBcIntcIilcblx0XHRcdHRoaXMuc2VuZFVua25vd25LZXl3b3JkRXJyb3IoKTtcblxuXHRcdHRoaXMuX3NrZWxldG9uID0gbmV3IFNrZWxldG9uKCk7XG5cblx0XHRkbyB7XG5cdFx0XHRpZiAodGhpcy5fcmVhY2hlZEVPRilcblx0XHRcdFx0dGhpcy5zZW5kRU9GRXJyb3IoKTtcblx0XHRcdGpvaW50ID0gbmV3IFNrZWxldG9uSm9pbnQoKTtcblx0XHRcdGpvaW50Lm5hbWUgPSB0aGlzLnBhcnNlTGl0ZXJhbHN0cmluZygpO1xuXHRcdFx0am9pbnQucGFyZW50SW5kZXggPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRcdHBvcyA9IHRoaXMucGFyc2VWZWN0b3IzRCgpO1xuXHRcdFx0cG9zID0gdGhpcy5fcm90YXRpb25RdWF0LnJvdGF0ZVBvaW50KHBvcyk7XG5cdFx0XHRxdWF0ID0gdGhpcy5wYXJzZVF1YXRlcm5pb24oKTtcblxuXHRcdFx0Ly8gdG9kbzogY2hlY2sgaWYgdGhpcyBpcyBjb3JyZWN0LCBvciBtYXliZSB3ZSB3YW50IHRvIGFjdHVhbGx5IHN0b3JlIGl0IGFzIHF1YXRzP1xuXHRcdFx0dGhpcy5fYmluZFBvc2VzW2ldID0gcXVhdC50b01hdHJpeDNEKCk7XG5cdFx0XHR0aGlzLl9iaW5kUG9zZXNbaV0uYXBwZW5kVHJhbnNsYXRpb24ocG9zLngsIHBvcy55LCBwb3Mueik7XG5cdFx0XHR2YXIgaW52Ok1hdHJpeDNEID0gdGhpcy5fYmluZFBvc2VzW2ldLmNsb25lKCk7XG5cdFx0XHRpbnYuaW52ZXJ0KCk7XG5cdFx0XHRqb2ludC5pbnZlcnNlQmluZFBvc2UgPSBpbnYucmF3RGF0YTtcblxuXHRcdFx0dGhpcy5fc2tlbGV0b24uam9pbnRzW2krK10gPSBqb2ludDtcblxuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7XG5cblx0XHRcdGlmIChjaCA9PSBcIi9cIikge1xuXHRcdFx0XHR0aGlzLnB1dEJhY2soKTtcblx0XHRcdFx0Y2ggPSB0aGlzLmdldE5leHRUb2tlbigpO1xuXHRcdFx0XHRpZiAoY2ggPT0gTUQ1TWVzaFBhcnNlci5DT01NRU5UX1RPS0VOKVxuXHRcdFx0XHRcdHRoaXMuaWdub3JlTGluZSgpO1xuXHRcdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dENoYXIoKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoY2ggIT0gXCJ9XCIpXG5cdFx0XHRcdHRoaXMucHV0QmFjaygpO1xuXHRcdH0gd2hpbGUgKGNoICE9IFwifVwiKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQdXRzIGJhY2sgdGhlIGxhc3QgcmVhZCBjaGFyYWN0ZXIgaW50byB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIHB1dEJhY2soKTp2b2lkXG5cdHtcblx0XHR0aGlzLl9wYXJzZUluZGV4LS07XG5cdFx0dGhpcy5fY2hhckxpbmVJbmRleC0tO1xuXHRcdHRoaXMuX3JlYWNoZWRFT0YgPSB0aGlzLl9wYXJzZUluZGV4ID49IHRoaXMuX3RleHREYXRhLmxlbmd0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgdGhlIG1lc2ggZ2VvbWV0cnkuXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlTWVzaCgpOnZvaWRcblx0e1xuXHRcdHZhciB0b2tlbjpzdHJpbmcgPSB0aGlzLmdldE5leHRUb2tlbigpO1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIHZlcnRleERhdGE6QXJyYXk8VmVydGV4RGF0YT47XG5cdFx0dmFyIHdlaWdodHM6QXJyYXk8Sm9pbnREYXRhPjtcblx0XHR2YXIgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovO1xuXG5cdFx0aWYgKHRva2VuICE9IFwie1wiKVxuXHRcdFx0dGhpcy5zZW5kVW5rbm93bktleXdvcmRFcnJvcigpO1xuXG5cdFx0aWYgKHRoaXMuX3NoYWRlcnMgPT0gbnVsbClcblx0XHRcdHRoaXMuX3NoYWRlcnMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG5cdFx0d2hpbGUgKGNoICE9IFwifVwiKSB7XG5cdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cdFx0XHRzd2l0Y2ggKGNoKSB7XG5cdFx0XHRcdGNhc2UgTUQ1TWVzaFBhcnNlci5DT01NRU5UX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMuaWdub3JlTGluZSgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENU1lc2hQYXJzZXIuTUVTSF9TSEFERVJfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5fc2hhZGVycy5wdXNoKHRoaXMucGFyc2VMaXRlcmFsc3RyaW5nKCkpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENU1lc2hQYXJzZXIuTUVTSF9OVU1fVkVSVFNfVE9LRU46XG5cdFx0XHRcdFx0dmVydGV4RGF0YSA9IG5ldyBBcnJheTxWZXJ0ZXhEYXRhPih0aGlzLmdldE5leHRJbnQoKSk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgTUQ1TWVzaFBhcnNlci5NRVNIX05VTV9UUklTX1RPS0VOOlxuXHRcdFx0XHRcdGluZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmdldE5leHRJbnQoKSozKSAvKnVpbnQqLztcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLk1FU0hfTlVNX1dFSUdIVFNfVE9LRU46XG5cdFx0XHRcdFx0d2VpZ2h0cyA9IG5ldyBBcnJheTxKb2ludERhdGE+KHRoaXMuZ2V0TmV4dEludCgpKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLk1FU0hfVkVSVF9UT0tFTjpcblx0XHRcdFx0XHR0aGlzLnBhcnNlVmVydGV4KHZlcnRleERhdGEpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIE1ENU1lc2hQYXJzZXIuTUVTSF9UUklfVE9LRU46XG5cdFx0XHRcdFx0dGhpcy5wYXJzZVRyaShpbmRpY2VzKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBNRDVNZXNoUGFyc2VyLk1FU0hfV0VJR0hUX1RPS0VOOlxuXHRcdFx0XHRcdHRoaXMucGFyc2VKb2ludCh3ZWlnaHRzKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5fbWVzaERhdGEgPT0gbnVsbClcblx0XHRcdHRoaXMuX21lc2hEYXRhID0gbmV3IEFycmF5PE1lc2hEYXRhPigpO1xuXG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovID0gdGhpcy5fbWVzaERhdGEubGVuZ3RoO1xuXHRcdHRoaXMuX21lc2hEYXRhW2ldID0gbmV3IE1lc2hEYXRhKCk7XG5cdFx0dGhpcy5fbWVzaERhdGFbaV0udmVydGV4RGF0YSA9IHZlcnRleERhdGE7XG5cdFx0dGhpcy5fbWVzaERhdGFbaV0ud2VpZ2h0RGF0YSA9IHdlaWdodHM7XG5cdFx0dGhpcy5fbWVzaERhdGFbaV0uaW5kaWNlcyA9IGluZGljZXM7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgdGhlIG1lc2ggZGF0YSB0byBhIFNraW5uZWRTdWIgaW5zdGFuY2UuXG5cdCAqIEBwYXJhbSB2ZXJ0ZXhEYXRhIFRoZSBtZXNoJ3MgdmVydGljZXMuXG5cdCAqIEBwYXJhbSB3ZWlnaHRzIFRoZSBqb2ludCB3ZWlnaHRzIHBlciB2ZXJ0ZXguXG5cdCAqIEBwYXJhbSBpbmRpY2VzIFRoZSBpbmRpY2VzIGZvciB0aGUgZmFjZXMuXG5cdCAqIEByZXR1cm4gQSBTdWJHZW9tZXRyeSBpbnN0YW5jZSBjb250YWluaW5nIGFsbCBnZW9tZXRyaWNhbCBkYXRhIGZvciB0aGUgY3VycmVudCBtZXNoLlxuXHQgKi9cblx0cHJpdmF0ZSB0cmFuc2xhdGVHZW9tKHZlcnRleERhdGE6QXJyYXk8VmVydGV4RGF0YT4sIHdlaWdodHM6QXJyYXk8Sm9pbnREYXRhPiwgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovKTpUcmlhbmdsZVN1Ykdlb21ldHJ5XG5cdHtcblx0XHR2YXIgbGVuOm51bWJlciAvKmludCovID0gdmVydGV4RGF0YS5sZW5ndGg7XG5cdFx0dmFyIHYxOm51bWJlciAvKmludCovLCB2MjpudW1iZXIgLyppbnQqLywgdjM6bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIHZlcnRleDpWZXJ0ZXhEYXRhO1xuXHRcdHZhciB3ZWlnaHQ6Sm9pbnREYXRhO1xuXHRcdHZhciBiaW5kUG9zZTpNYXRyaXgzRDtcblx0XHR2YXIgcG9zOlZlY3RvcjNEO1xuXHRcdHZhciBzdWJHZW9tOlRyaWFuZ2xlU3ViR2VvbWV0cnkgPSBuZXcgVHJpYW5nbGVTdWJHZW9tZXRyeSh0cnVlKTtcblx0XHR2YXIgdXZzOkFycmF5PG51bWJlcj4gPSBuZXcgQXJyYXk8bnVtYmVyPihsZW4qMik7XG5cdFx0dmFyIHZlcnRpY2VzOkFycmF5PG51bWJlcj4gPSBuZXcgQXJyYXk8bnVtYmVyPihsZW4qMyk7XG5cdFx0dmFyIGpvaW50SW5kaWNlczpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4obGVuKnRoaXMuX21heEpvaW50Q291bnQpO1xuXHRcdHZhciBqb2ludFdlaWdodHM6QXJyYXk8bnVtYmVyPiA9IG5ldyBBcnJheTxudW1iZXI+KGxlbip0aGlzLl9tYXhKb2ludENvdW50KTtcblx0XHR2YXIgbDpudW1iZXIgLyppbnQqLyA9IDA7XG5cdFx0dmFyIG5vblplcm9XZWlnaHRzOm51bWJlciAvKmludCovO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgLyppbnQqLyA9IDA7IGkgPCBsZW47ICsraSkge1xuXHRcdFx0dmVydGV4ID0gdmVydGV4RGF0YVtpXTtcblx0XHRcdHYxID0gdmVydGV4LmluZGV4KjM7XG5cdFx0XHR2MiA9IHYxICsgMTtcblx0XHRcdHYzID0gdjEgKyAyO1xuXHRcdFx0dmVydGljZXNbdjFdID0gdmVydGljZXNbdjJdID0gdmVydGljZXNbdjNdID0gMDtcblxuXHRcdFx0bm9uWmVyb1dlaWdodHMgPSAwO1xuXHRcdFx0Zm9yICh2YXIgajpudW1iZXIgLyppbnQqLyA9IDA7IGogPCB2ZXJ0ZXguY291bnRXZWlnaHQ7ICsraikge1xuXHRcdFx0XHR3ZWlnaHQgPSB3ZWlnaHRzW3ZlcnRleC5zdGFydFdlaWdodCArIGpdO1xuXHRcdFx0XHRpZiAod2VpZ2h0LmJpYXMgPiAwKSB7XG5cdFx0XHRcdFx0YmluZFBvc2UgPSB0aGlzLl9iaW5kUG9zZXNbd2VpZ2h0LmpvaW50XTtcblx0XHRcdFx0XHRwb3MgPSBiaW5kUG9zZS50cmFuc2Zvcm1WZWN0b3Iod2VpZ2h0LnBvcyk7XG5cdFx0XHRcdFx0dmVydGljZXNbdjFdICs9IHBvcy54KndlaWdodC5iaWFzO1xuXHRcdFx0XHRcdHZlcnRpY2VzW3YyXSArPSBwb3MueSp3ZWlnaHQuYmlhcztcblx0XHRcdFx0XHR2ZXJ0aWNlc1t2M10gKz0gcG9zLnoqd2VpZ2h0LmJpYXM7XG5cblx0XHRcdFx0XHQvLyBpbmRpY2VzIG5lZWQgdG8gYmUgbXVsdGlwbGllZCBieSAzIChhbW91bnQgb2YgbWF0cml4IHJlZ2lzdGVycylcblx0XHRcdFx0XHRqb2ludEluZGljZXNbbF0gPSB3ZWlnaHQuam9pbnQqMztcblx0XHRcdFx0XHRqb2ludFdlaWdodHNbbCsrXSA9IHdlaWdodC5iaWFzO1xuXHRcdFx0XHRcdCsrbm9uWmVyb1dlaWdodHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yIChqID0gbm9uWmVyb1dlaWdodHM7IGogPCB0aGlzLl9tYXhKb2ludENvdW50OyArK2opIHtcblx0XHRcdFx0am9pbnRJbmRpY2VzW2xdID0gMDtcblx0XHRcdFx0am9pbnRXZWlnaHRzW2wrK10gPSAwO1xuXHRcdFx0fVxuXG5cdFx0XHR2MSA9IHZlcnRleC5pbmRleCA8PCAxO1xuXHRcdFx0dXZzW3YxKytdID0gdmVydGV4LnM7XG5cdFx0XHR1dnNbdjFdID0gdmVydGV4LnQ7XG5cdFx0fVxuXG5cdFx0c3ViR2VvbS5qb2ludHNQZXJWZXJ0ZXggPSB0aGlzLl9tYXhKb2ludENvdW50O1xuXHRcdHN1Ykdlb20udXBkYXRlSW5kaWNlcyhpbmRpY2VzKTtcblx0XHRzdWJHZW9tLnVwZGF0ZVBvc2l0aW9ucyh2ZXJ0aWNlcyk7XG5cdFx0c3ViR2VvbS51cGRhdGVVVnModXZzKTtcblx0XHRzdWJHZW9tLnVwZGF0ZUpvaW50SW5kaWNlcyhqb2ludEluZGljZXMpO1xuXHRcdHN1Ykdlb20udXBkYXRlSm9pbnRXZWlnaHRzKGpvaW50V2VpZ2h0cyk7XG5cdFx0Ly8gY2F1c2UgZXhwbGljaXQgdXBkYXRlc1xuXHRcdHN1Ykdlb20udmVydGV4Tm9ybWFscztcblx0XHRzdWJHZW9tLnZlcnRleFRhbmdlbnRzO1xuXHRcdC8vIHR1cm4gYXV0byB1cGRhdGVzIG9mZiBiZWNhdXNlIHRoZXkgbWF5IGJlIGFuaW1hdGVkIGFuZCBzZXQgZXhwbGljaXRseVxuXHRcdHN1Ykdlb20uYXV0b0Rlcml2ZVRhbmdlbnRzID0gZmFsc2U7XG5cdFx0c3ViR2VvbS5hdXRvRGVyaXZlTm9ybWFscyA9IGZhbHNlO1xuXG5cdFx0cmV0dXJuIHN1Ykdlb207XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmUgdGhlIG5leHQgdHJpcGxldCBvZiB2ZXJ0ZXggaW5kaWNlcyB0aGF0IGZvcm0gYSBmYWNlLlxuXHQgKiBAcGFyYW0gaW5kaWNlcyBUaGUgaW5kZXggbGlzdCBpbiB3aGljaCB0byBzdG9yZSB0aGUgcmVhZCBkYXRhLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVRyaShpbmRpY2VzOkFycmF5PG51bWJlcj4gLyp1aW50Ki8pOnZvaWRcblx0e1xuXHRcdHZhciBpbmRleDpudW1iZXIgLyppbnQqLyA9IHRoaXMuZ2V0TmV4dEludCgpKjM7XG5cdFx0aW5kaWNlc1tpbmRleF0gPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRpbmRpY2VzW2luZGV4ICsgMV0gPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHRpbmRpY2VzW2luZGV4ICsgMl0gPSB0aGlzLmdldE5leHRJbnQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWFkcyBhIG5ldyBqb2ludCBkYXRhIHNldCBmb3IgYSBzaW5nbGUgam9pbnQuXG5cdCAqIEBwYXJhbSB3ZWlnaHRzIHRoZSB0YXJnZXQgbGlzdCB0byBjb250YWluIHRoZSB3ZWlnaHQgZGF0YS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VKb2ludCh3ZWlnaHRzOkFycmF5PEpvaW50RGF0YT4pOnZvaWRcblx0e1xuXHRcdHZhciB3ZWlnaHQ6Sm9pbnREYXRhID0gbmV3IEpvaW50RGF0YSgpO1xuXHRcdHdlaWdodC5pbmRleCA9IHRoaXMuZ2V0TmV4dEludCgpO1xuXHRcdHdlaWdodC5qb2ludCA9IHRoaXMuZ2V0TmV4dEludCgpO1xuXHRcdHdlaWdodC5iaWFzID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0d2VpZ2h0LnBvcyA9IHRoaXMucGFyc2VWZWN0b3IzRCgpO1xuXHRcdHdlaWdodHNbd2VpZ2h0LmluZGV4XSA9IHdlaWdodDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWFkcyB0aGUgZGF0YSBmb3IgYSBzaW5nbGUgdmVydGV4LlxuXHQgKiBAcGFyYW0gdmVydGV4RGF0YSBUaGUgbGlzdCB0byBjb250YWluIHRoZSB2ZXJ0ZXggZGF0YS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VWZXJ0ZXgodmVydGV4RGF0YTpBcnJheTxWZXJ0ZXhEYXRhPik6dm9pZFxuXHR7XG5cdFx0dmFyIHZlcnRleDpWZXJ0ZXhEYXRhID0gbmV3IFZlcnRleERhdGEoKTtcblx0XHR2ZXJ0ZXguaW5kZXggPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHR0aGlzLnBhcnNlVVYodmVydGV4KTtcblx0XHR2ZXJ0ZXguc3RhcnRXZWlnaHQgPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHR2ZXJ0ZXguY291bnRXZWlnaHQgPSB0aGlzLmdldE5leHRJbnQoKTtcblx0XHQvL1x0XHRcdGlmICh2ZXJ0ZXguY291bnRXZWlnaHQgPiBfbWF4Sm9pbnRDb3VudCkgX21heEpvaW50Q291bnQgPSB2ZXJ0ZXguY291bnRXZWlnaHQ7XG5cdFx0dmVydGV4RGF0YVt2ZXJ0ZXguaW5kZXhdID0gdmVydGV4O1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlYWRzIHRoZSBuZXh0IHV2IGNvb3JkaW5hdGUuXG5cdCAqIEBwYXJhbSB2ZXJ0ZXhEYXRhIFRoZSB2ZXJ0ZXhEYXRhIHRvIGNvbnRhaW4gdGhlIFVWIGNvb3JkaW5hdGVzLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVVWKHZlcnRleERhdGE6VmVydGV4RGF0YSk6dm9pZFxuXHR7XG5cdFx0dmFyIGNoOnN0cmluZyA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cdFx0aWYgKGNoICE9IFwiKFwiKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcIihcIik7XG5cdFx0dmVydGV4RGF0YS5zID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0dmVydGV4RGF0YS50ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cblx0XHRpZiAodGhpcy5nZXROZXh0VG9rZW4oKSAhPSBcIilcIilcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCIpXCIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5leHQgdG9rZW4gaW4gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBnZXROZXh0VG9rZW4oKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cdFx0dmFyIHRva2VuOnN0cmluZyA9IFwiXCI7XG5cblx0XHR3aGlsZSAoIXRoaXMuX3JlYWNoZWRFT0YpIHtcblx0XHRcdGNoID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXHRcdFx0aWYgKGNoID09IFwiIFwiIHx8IGNoID09IFwiXFxyXCIgfHwgY2ggPT0gXCJcXG5cIiB8fCBjaCA9PSBcIlxcdFwiKSB7XG5cdFx0XHRcdGlmICh0b2tlbiAhPSBNRDVNZXNoUGFyc2VyLkNPTU1FTlRfVE9LRU4pXG5cdFx0XHRcdFx0dGhpcy5za2lwV2hpdGVTcGFjZSgpO1xuXHRcdFx0XHRpZiAodG9rZW4gIT0gXCJcIilcblx0XHRcdFx0XHRyZXR1cm4gdG9rZW47XG5cdFx0XHR9IGVsc2Vcblx0XHRcdFx0dG9rZW4gKz0gY2g7XG5cblx0XHRcdGlmICh0b2tlbiA9PSBNRDVNZXNoUGFyc2VyLkNPTU1FTlRfVE9LRU4pXG5cdFx0XHRcdHJldHVybiB0b2tlbjtcblx0XHR9XG5cblx0XHRyZXR1cm4gdG9rZW47XG5cdH1cblxuXHQvKipcblx0ICogU2tpcHMgYWxsIHdoaXRlc3BhY2UgaW4gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBza2lwV2hpdGVTcGFjZSgpOnZvaWRcblx0e1xuXHRcdHZhciBjaDpzdHJpbmc7XG5cblx0XHRkb1xuXHRcdFx0Y2ggPSB0aGlzLmdldE5leHRDaGFyKCk7IHdoaWxlIChjaCA9PSBcIlxcblwiIHx8IGNoID09IFwiIFwiIHx8IGNoID09IFwiXFxyXCIgfHwgY2ggPT0gXCJcXHRcIik7XG5cblx0XHR0aGlzLnB1dEJhY2soKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTa2lwcyB0byB0aGUgbmV4dCBsaW5lLlxuXHQgKi9cblx0cHJpdmF0ZSBpZ25vcmVMaW5lKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGNoOnN0cmluZztcblx0XHR3aGlsZSAoIXRoaXMuX3JlYWNoZWRFT0YgJiYgY2ggIT0gXCJcXG5cIilcblx0XHRcdGNoID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCBzaW5nbGUgY2hhcmFjdGVyIGluIHRoZSBkYXRhIHN0cmVhbS5cblx0ICovXG5cdHByaXZhdGUgZ2V0TmV4dENoYXIoKTpzdHJpbmdcblx0e1xuXHRcdHZhciBjaDpzdHJpbmcgPSB0aGlzLl90ZXh0RGF0YS5jaGFyQXQodGhpcy5fcGFyc2VJbmRleCsrKTtcblxuXHRcdGlmIChjaCA9PSBcIlxcblwiKSB7XG5cdFx0XHQrK3RoaXMuX2xpbmU7XG5cdFx0XHR0aGlzLl9jaGFyTGluZUluZGV4ID0gMDtcblx0XHR9IGVsc2UgaWYgKGNoICE9IFwiXFxyXCIpXG5cdFx0XHQrK3RoaXMuX2NoYXJMaW5lSW5kZXg7XG5cblx0XHRpZiAodGhpcy5fcGFyc2VJbmRleCA+PSB0aGlzLl90ZXh0RGF0YS5sZW5ndGgpXG5cdFx0XHR0aGlzLl9yZWFjaGVkRU9GID0gdHJ1ZTtcblxuXHRcdHJldHVybiBjaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIG5leHQgaW50ZWdlciBpbiB0aGUgZGF0YSBzdHJlYW0uXG5cdCAqL1xuXHRwcml2YXRlIGdldE5leHRJbnQoKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0dmFyIGk6bnVtYmVyID0gcGFyc2VJbnQodGhpcy5nZXROZXh0VG9rZW4oKSk7XG5cdFx0aWYgKGlzTmFOKGkpKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcImludCB0eXBlXCIpO1xuXHRcdHJldHVybiBpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCBmbG9hdGluZyBwb2ludCBudW1iZXIgaW4gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBnZXROZXh0TnVtYmVyKCk6bnVtYmVyXG5cdHtcblx0XHR2YXIgZjpudW1iZXIgPSBwYXJzZUZsb2F0KHRoaXMuZ2V0TmV4dFRva2VuKCkpO1xuXHRcdGlmIChpc05hTihmKSlcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCJmbG9hdCB0eXBlXCIpO1xuXHRcdHJldHVybiBmO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCAzZCB2ZWN0b3IgaW4gdGhlIGRhdGEgc3RyZWFtLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVZlY3RvcjNEKCk6VmVjdG9yM0Rcblx0e1xuXHRcdHZhciB2ZWM6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0XHR2YXIgY2g6c3RyaW5nID0gdGhpcy5nZXROZXh0VG9rZW4oKTtcblxuXHRcdGlmIChjaCAhPSBcIihcIilcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCIoXCIpO1xuXHRcdHZlYy54ID0gLXRoaXMuZ2V0TmV4dE51bWJlcigpO1xuXHRcdHZlYy55ID0gdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0dmVjLnogPSB0aGlzLmdldE5leHROdW1iZXIoKTtcblxuXHRcdGlmICh0aGlzLmdldE5leHRUb2tlbigpICE9IFwiKVwiKVxuXHRcdFx0dGhpcy5zZW5kUGFyc2VFcnJvcihcIilcIik7XG5cblx0XHRyZXR1cm4gdmVjO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCBxdWF0ZXJuaW9uIGluIHRoZSBkYXRhIHN0cmVhbS5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VRdWF0ZXJuaW9uKCk6UXVhdGVybmlvblxuXHR7XG5cdFx0dmFyIHF1YXQ6UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdFx0dmFyIGNoOnN0cmluZyA9IHRoaXMuZ2V0TmV4dFRva2VuKCk7XG5cblx0XHRpZiAoY2ggIT0gXCIoXCIpXG5cdFx0XHR0aGlzLnNlbmRQYXJzZUVycm9yKFwiKFwiKTtcblx0XHRxdWF0LnggPSB0aGlzLmdldE5leHROdW1iZXIoKTtcblx0XHRxdWF0LnkgPSAtdGhpcy5nZXROZXh0TnVtYmVyKCk7XG5cdFx0cXVhdC56ID0gLXRoaXMuZ2V0TmV4dE51bWJlcigpO1xuXG5cdFx0Ly8gcXVhdCBzdXBwb3NlZCB0byBiZSB1bml0IGxlbmd0aFxuXHRcdHZhciB0Om51bWJlciA9IDEgLSBxdWF0LngqcXVhdC54IC0gcXVhdC55KnF1YXQueSAtIHF1YXQueipxdWF0Lno7XG5cdFx0cXVhdC53ID0gdCA8IDA/IDAgOiAtTWF0aC5zcXJ0KHQpO1xuXG5cdFx0aWYgKHRoaXMuZ2V0TmV4dFRva2VuKCkgIT0gXCIpXCIpXG5cdFx0XHR0aGlzLnNlbmRQYXJzZUVycm9yKFwiKVwiKTtcblxuXHRcdHZhciByb3RRdWF0OlF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXHRcdHJvdFF1YXQubXVsdGlwbHkodGhpcy5fcm90YXRpb25RdWF0LCBxdWF0KTtcblx0XHRyZXR1cm4gcm90UXVhdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgdGhlIGNvbW1hbmQgbGluZSBkYXRhLlxuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZUNNRCgpOnZvaWRcblx0e1xuXHRcdC8vIGp1c3QgaWdub3JlIHRoZSBjb21tYW5kIGxpbmUgcHJvcGVydHlcblx0XHR0aGlzLnBhcnNlTGl0ZXJhbHN0cmluZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyB0aGUgbmV4dCBsaXRlcmFsIHN0cmluZyBpbiB0aGUgZGF0YSBzdHJlYW0uIEEgbGl0ZXJhbCBzdHJpbmcgaXMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGJvdW5kZWRcblx0ICogYnkgZG91YmxlIHF1b3Rlcy5cblx0ICovXG5cdHByaXZhdGUgcGFyc2VMaXRlcmFsc3RyaW5nKCk6c3RyaW5nXG5cdHtcblx0XHR0aGlzLnNraXBXaGl0ZVNwYWNlKCk7XG5cblx0XHR2YXIgY2g6c3RyaW5nID0gdGhpcy5nZXROZXh0Q2hhcigpO1xuXHRcdHZhciBzdHI6c3RyaW5nID0gXCJcIjtcblxuXHRcdGlmIChjaCAhPSBcIlxcXCJcIilcblx0XHRcdHRoaXMuc2VuZFBhcnNlRXJyb3IoXCJcXFwiXCIpO1xuXG5cdFx0ZG8ge1xuXHRcdFx0aWYgKHRoaXMuX3JlYWNoZWRFT0YpXG5cdFx0XHRcdHRoaXMuc2VuZEVPRkVycm9yKCk7XG5cdFx0XHRjaCA9IHRoaXMuZ2V0TmV4dENoYXIoKTtcblx0XHRcdGlmIChjaCAhPSBcIlxcXCJcIilcblx0XHRcdFx0c3RyICs9IGNoO1xuXHRcdH0gd2hpbGUgKGNoICE9IFwiXFxcIlwiKTtcblxuXHRcdHJldHVybiBzdHI7XG5cdH1cblxuXHQvKipcblx0ICogVGhyb3dzIGFuIGVuZC1vZi1maWxlIGVycm9yIHdoZW4gYSBwcmVtYXR1cmUgZW5kIG9mIGZpbGUgd2FzIGVuY291bnRlcmVkLlxuXHQgKi9cblx0cHJpdmF0ZSBzZW5kRU9GRXJyb3IoKTp2b2lkXG5cdHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGVuZCBvZiBmaWxlXCIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRocm93cyBhbiBlcnJvciB3aGVuIGFuIHVuZXhwZWN0ZWQgdG9rZW4gd2FzIGVuY291bnRlcmVkLlxuXHQgKiBAcGFyYW0gZXhwZWN0ZWQgVGhlIHRva2VuIHR5cGUgdGhhdCB3YXMgYWN0dWFsbHkgZXhwZWN0ZWQuXG5cdCAqL1xuXHRwcml2YXRlIHNlbmRQYXJzZUVycm9yKGV4cGVjdGVkOnN0cmluZyk6dm9pZFxuXHR7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCB0b2tlbiBhdCBsaW5lIFwiICsgKHRoaXMuX2xpbmUgKyAxKSArIFwiLCBjaGFyYWN0ZXIgXCIgKyB0aGlzLl9jaGFyTGluZUluZGV4ICsgXCIuIFwiICsgZXhwZWN0ZWQgKyBcIiBleHBlY3RlZCwgYnV0IFwiICsgdGhpcy5fdGV4dERhdGEuY2hhckF0KHRoaXMuX3BhcnNlSW5kZXggLSAxKSArIFwiIGVuY291bnRlcmVkXCIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRocm93cyBhbiBlcnJvciB3aGVuIGFuIHVua25vd24ga2V5d29yZCB3YXMgZW5jb3VudGVyZWQuXG5cdCAqL1xuXHRwcml2YXRlIHNlbmRVbmtub3duS2V5d29yZEVycm9yKCk6dm9pZFxuXHR7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBrZXl3b3JkIGF0IGxpbmUgXCIgKyAodGhpcy5fbGluZSArIDEpICsgXCIsIGNoYXJhY3RlciBcIiArIHRoaXMuX2NoYXJMaW5lSW5kZXggKyBcIi4gXCIpO1xuXHR9XG59XG5cbmV4cG9ydCA9IE1ENU1lc2hQYXJzZXI7XG5cblxuY2xhc3MgVmVydGV4RGF0YVxue1xuXHRwdWJsaWMgaW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyBzOm51bWJlcjtcblx0cHVibGljIHQ6bnVtYmVyO1xuXHRwdWJsaWMgc3RhcnRXZWlnaHQ6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyBjb3VudFdlaWdodDpudW1iZXIgLyppbnQqLztcbn1cblxuY2xhc3MgSm9pbnREYXRhXG57XG5cdHB1YmxpYyBpbmRleDpudW1iZXIgLyppbnQqLztcblx0cHVibGljIGpvaW50Om51bWJlciAvKmludCovO1xuXHRwdWJsaWMgYmlhczpudW1iZXI7XG5cdHB1YmxpYyBwb3M6VmVjdG9yM0Q7XG59XG5cbmNsYXNzIE1lc2hEYXRhXG57XG5cdHB1YmxpYyB2ZXJ0ZXhEYXRhOkFycmF5PFZlcnRleERhdGE+O1xuXHRwdWJsaWMgd2VpZ2h0RGF0YTpBcnJheTxKb2ludERhdGE+O1xuXHRwdWJsaWMgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovO1xufVxuIl19 \ No newline at end of file diff --git a/lib/parsers/MD5MeshParser.ts b/lib/parsers/MD5MeshParser.ts new file mode 100644 index 000000000..2eb85b19d --- /dev/null +++ b/lib/parsers/MD5MeshParser.ts @@ -0,0 +1,683 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +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"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); + +import SkeletonAnimationSet = require("awayjs-renderergl/lib/animators/SkeletonAnimationSet"); +import Skeleton = require("awayjs-renderergl/lib/animators/data/Skeleton"); +import SkeletonJoint = require("awayjs-renderergl/lib/animators/data/SkeletonJoint"); + +// todo: create animation system, parse skeleton + +/** + * MD5MeshParser provides a parser for the md5mesh data type, providing the geometry of the md5 format. + * + * todo: optimize + */ +class MD5MeshParser extends ParserBase +{ + private _textData:string; + private _startedParsing:boolean; + public static VERSION_TOKEN:string = "MD5Version"; + public static COMMAND_LINE_TOKEN:string = "commandline"; + public static NUM_JOINTS_TOKEN:string = "numJoints"; + public static NUM_MESHES_TOKEN:string = "numMeshes"; + public static COMMENT_TOKEN:string = "//"; + public static JOINTS_TOKEN:string = "joints"; + public static MESH_TOKEN:string = "mesh"; + + public static MESH_SHADER_TOKEN:string = "shader"; + public static MESH_NUM_VERTS_TOKEN:string = "numverts"; + public static MESH_VERT_TOKEN:string = "vert"; + public static MESH_NUM_TRIS_TOKEN:string = "numtris"; + public static MESH_TRI_TOKEN:string = "tri"; + public static MESH_NUM_WEIGHTS_TOKEN:string = "numweights"; + public static MESH_WEIGHT_TOKEN:string = "weight"; + + private _parseIndex:number /*int*/ = 0; + private _reachedEOF:boolean; + private _line:number /*int*/ = 0; + private _charLineIndex:number /*int*/ = 0; + private _version:number /*int*/; + private _numJoints:number /*int*/; + private _numMeshes:number /*int*/; + + private _mesh:Mesh; + private _shaders:Array; + + private _maxJointCount:number /*int*/; + private _meshData:Array; + private _bindPoses:Array; + private _geometry:Geometry; + + private _skeleton:Skeleton; + private _animationSet:SkeletonAnimationSet; + + private _rotationQuat:Quaternion; + + /** + * Creates a new MD5MeshParser object. + */ + constructor(additionalRotationAxis:Vector3D = null, additionalRotationRadians:number = 0) + { + super(URLLoaderDataFormat.TEXT); + this._rotationQuat = new Quaternion(); + + this._rotationQuat.fromAxisAngle(Vector3D.X_AXIS, -Math.PI*.5); + + if (additionalRotationAxis) { + var quat:Quaternion = new Quaternion(); + quat.fromAxisAngle(additionalRotationAxis, additionalRotationRadians); + this._rotationQuat.multiply(this._rotationQuat, quat); + } + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "md5mesh"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + return false; + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + var token:string; + + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + this._startedParsing = true; + } + + while (this._pHasTime()) { + token = this.getNextToken(); + switch (token) { + case MD5MeshParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case MD5MeshParser.VERSION_TOKEN: + this._version = this.getNextInt(); + if (this._version != 10) + throw new Error("Unknown version number encountered!"); + break; + case MD5MeshParser.COMMAND_LINE_TOKEN: + this.parseCMD(); + break; + case MD5MeshParser.NUM_JOINTS_TOKEN: + this._numJoints = this.getNextInt(); + this._bindPoses = new Array(this._numJoints); + break; + case MD5MeshParser.NUM_MESHES_TOKEN: + this._numMeshes = this.getNextInt(); + break; + case MD5MeshParser.JOINTS_TOKEN: + this.parseJoints(); + break; + case MD5MeshParser.MESH_TOKEN: + this.parseMesh(); + break; + default: + if (!this._reachedEOF) + this.sendUnknownKeywordError(); + } + + if (this._reachedEOF) { + this.calculateMaxJointCount(); + this._animationSet = new SkeletonAnimationSet(this._maxJointCount); + + this._mesh = new Mesh(new Geometry(), null); + this._geometry = this._mesh.geometry; + + for (var i:number /*int*/ = 0; i < this._meshData.length; ++i) + this._geometry.addSubGeometry(this.translateGeom(this._meshData[i].vertexData, this._meshData[i].weightData, this._meshData[i].indices)); + + //_geometry.animation = _animation; + // _mesh.animationController = _animationController; + + //add to the content property + ( this._pContent).addChild(this._mesh); + + this._pFinalizeAsset(this._geometry); + this._pFinalizeAsset(this._mesh); + this._pFinalizeAsset(this._skeleton); + this._pFinalizeAsset(this._animationSet); + return ParserBase.PARSING_DONE; + } + } + return ParserBase.MORE_TO_PARSE; + } + + public _pStartParsing(frameLimit:number) + { + super._pStartParsing(frameLimit); + + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + } + + private calculateMaxJointCount():void + { + this._maxJointCount = 0; + + var numMeshData:number /*int*/ = this._meshData.length; + for (var i:number /*int*/ = 0; i < numMeshData; ++i) { + var meshData:MeshData = this._meshData[i]; + var vertexData:Array = meshData.vertexData; + var numVerts:number /*int*/ = vertexData.length; + + for (var j:number /*int*/ = 0; j < numVerts; ++j) { + var zeroWeights:number /*int*/ = this.countZeroWeightJoints(vertexData[j], meshData.weightData); + var totalJoints:number /*int*/ = vertexData[j].countWeight - zeroWeights; + if (totalJoints > this._maxJointCount) + this._maxJointCount = totalJoints; + } + } + } + + private countZeroWeightJoints(vertex:VertexData, weights:Array):number /*int*/ + { + var start:number /*int*/ = vertex.startWeight; + var end:number /*int*/ = vertex.startWeight + vertex.countWeight; + var count:number /*int*/ = 0; + var weight:number; + + for (var i:number /*int*/ = start; i < end; ++i) { + weight = weights[i].bias; + if (weight == 0) + ++count; + } + + return count; + } + + /** + * Parses the skeleton's joints. + */ + private parseJoints():void + { + var ch:string; + var joint:SkeletonJoint; + var pos:Vector3D; + var quat:Quaternion; + var i:number /*int*/ = 0; + var token:string = this.getNextToken(); + + if (token != "{") + this.sendUnknownKeywordError(); + + this._skeleton = new Skeleton(); + + do { + if (this._reachedEOF) + this.sendEOFError(); + joint = new SkeletonJoint(); + joint.name = this.parseLiteralstring(); + joint.parentIndex = this.getNextInt(); + pos = this.parseVector3D(); + pos = this._rotationQuat.rotatePoint(pos); + quat = this.parseQuaternion(); + + // todo: check if this is correct, or maybe we want to actually store it as quats? + this._bindPoses[i] = quat.toMatrix3D(); + this._bindPoses[i].appendTranslation(pos.x, pos.y, pos.z); + var inv:Matrix3D = this._bindPoses[i].clone(); + inv.invert(); + joint.inverseBindPose = inv.rawData; + + this._skeleton.joints[i++] = joint; + + ch = this.getNextChar(); + + if (ch == "/") { + this.putBack(); + ch = this.getNextToken(); + if (ch == MD5MeshParser.COMMENT_TOKEN) + this.ignoreLine(); + ch = this.getNextChar(); + + } + + if (ch != "}") + this.putBack(); + } while (ch != "}"); + } + + /** + * Puts back the last read character into the data stream. + */ + private putBack():void + { + this._parseIndex--; + this._charLineIndex--; + this._reachedEOF = this._parseIndex >= this._textData.length; + } + + /** + * Parses the mesh geometry. + */ + private parseMesh():void + { + var token:string = this.getNextToken(); + var ch:string; + var vertexData:Array; + var weights:Array; + var indices:Array /*uint*/; + + if (token != "{") + this.sendUnknownKeywordError(); + + if (this._shaders == null) + this._shaders = new Array(); + + while (ch != "}") { + ch = this.getNextToken(); + switch (ch) { + case MD5MeshParser.COMMENT_TOKEN: + this.ignoreLine(); + break; + case MD5MeshParser.MESH_SHADER_TOKEN: + this._shaders.push(this.parseLiteralstring()); + break; + case MD5MeshParser.MESH_NUM_VERTS_TOKEN: + vertexData = new Array(this.getNextInt()); + break; + case MD5MeshParser.MESH_NUM_TRIS_TOKEN: + indices = new Array(this.getNextInt()*3) /*uint*/; + break; + case MD5MeshParser.MESH_NUM_WEIGHTS_TOKEN: + weights = new Array(this.getNextInt()); + break; + case MD5MeshParser.MESH_VERT_TOKEN: + this.parseVertex(vertexData); + break; + case MD5MeshParser.MESH_TRI_TOKEN: + this.parseTri(indices); + break; + case MD5MeshParser.MESH_WEIGHT_TOKEN: + this.parseJoint(weights); + break; + } + } + + if (this._meshData == null) + this._meshData = new Array(); + + var i:number /*uint*/ = this._meshData.length; + this._meshData[i] = new MeshData(); + this._meshData[i].vertexData = vertexData; + this._meshData[i].weightData = weights; + this._meshData[i].indices = indices; + } + + /** + * Converts the mesh data to a SkinnedSub instance. + * @param vertexData The mesh's vertices. + * @param weights The joint weights per vertex. + * @param indices The indices for the faces. + * @return A SubGeometry instance containing all geometrical data for the current mesh. + */ + private translateGeom(vertexData:Array, weights:Array, indices:Array /*uint*/):TriangleSubGeometry + { + var len:number /*int*/ = vertexData.length; + var v1:number /*int*/, v2:number /*int*/, v3:number /*int*/; + var vertex:VertexData; + var weight:JointData; + var bindPose:Matrix3D; + var pos:Vector3D; + var subGeom:TriangleSubGeometry = new TriangleSubGeometry(true); + var uvs:Array = new Array(len*2); + var vertices:Array = new Array(len*3); + var jointIndices:Array = new Array(len*this._maxJointCount); + var jointWeights:Array = new Array(len*this._maxJointCount); + var l:number /*int*/ = 0; + var nonZeroWeights:number /*int*/; + + for (var i:number /*int*/ = 0; i < len; ++i) { + vertex = vertexData[i]; + v1 = vertex.index*3; + v2 = v1 + 1; + v3 = v1 + 2; + vertices[v1] = vertices[v2] = vertices[v3] = 0; + + nonZeroWeights = 0; + for (var j:number /*int*/ = 0; j < vertex.countWeight; ++j) { + weight = weights[vertex.startWeight + j]; + if (weight.bias > 0) { + bindPose = this._bindPoses[weight.joint]; + pos = bindPose.transformVector(weight.pos); + vertices[v1] += pos.x*weight.bias; + vertices[v2] += pos.y*weight.bias; + vertices[v3] += pos.z*weight.bias; + + // indices need to be multiplied by 3 (amount of matrix registers) + jointIndices[l] = weight.joint*3; + jointWeights[l++] = weight.bias; + ++nonZeroWeights; + } + } + + for (j = nonZeroWeights; j < this._maxJointCount; ++j) { + jointIndices[l] = 0; + jointWeights[l++] = 0; + } + + v1 = vertex.index << 1; + uvs[v1++] = vertex.s; + uvs[v1] = vertex.t; + } + + subGeom.jointsPerVertex = this._maxJointCount; + subGeom.updateIndices(indices); + subGeom.updatePositions(vertices); + subGeom.updateUVs(uvs); + subGeom.updateJointIndices(jointIndices); + subGeom.updateJointWeights(jointWeights); + // cause explicit updates + subGeom.vertexNormals; + subGeom.vertexTangents; + // turn auto updates off because they may be animated and set explicitly + subGeom.autoDeriveTangents = false; + subGeom.autoDeriveNormals = false; + + return subGeom; + } + + /** + * Retrieve the next triplet of vertex indices that form a face. + * @param indices The index list in which to store the read data. + */ + private parseTri(indices:Array /*uint*/):void + { + var index:number /*int*/ = this.getNextInt()*3; + indices[index] = this.getNextInt(); + indices[index + 1] = this.getNextInt(); + indices[index + 2] = this.getNextInt(); + } + + /** + * Reads a new joint data set for a single joint. + * @param weights the target list to contain the weight data. + */ + private parseJoint(weights:Array):void + { + var weight:JointData = new JointData(); + weight.index = this.getNextInt(); + weight.joint = this.getNextInt(); + weight.bias = this.getNextNumber(); + weight.pos = this.parseVector3D(); + weights[weight.index] = weight; + } + + /** + * Reads the data for a single vertex. + * @param vertexData The list to contain the vertex data. + */ + private parseVertex(vertexData:Array):void + { + var vertex:VertexData = new VertexData(); + vertex.index = this.getNextInt(); + this.parseUV(vertex); + vertex.startWeight = this.getNextInt(); + vertex.countWeight = this.getNextInt(); + // if (vertex.countWeight > _maxJointCount) _maxJointCount = vertex.countWeight; + vertexData[vertex.index] = vertex; + } + + /** + * Reads the next uv coordinate. + * @param vertexData The vertexData to contain the UV coordinates. + */ + private parseUV(vertexData:VertexData):void + { + var ch:string = this.getNextToken(); + if (ch != "(") + this.sendParseError("("); + vertexData.s = this.getNextNumber(); + vertexData.t = this.getNextNumber(); + + if (this.getNextToken() != ")") + this.sendParseError(")"); + } + + /** + * Gets the next token in the data stream. + */ + private getNextToken():string + { + var ch:string; + var token:string = ""; + + while (!this._reachedEOF) { + ch = this.getNextChar(); + if (ch == " " || ch == "\r" || ch == "\n" || ch == "\t") { + if (token != MD5MeshParser.COMMENT_TOKEN) + this.skipWhiteSpace(); + if (token != "") + return token; + } else + token += ch; + + if (token == MD5MeshParser.COMMENT_TOKEN) + return token; + } + + return token; + } + + /** + * Skips all whitespace in the data stream. + */ + private skipWhiteSpace():void + { + var ch:string; + + do + ch = this.getNextChar(); while (ch == "\n" || ch == " " || ch == "\r" || ch == "\t"); + + this.putBack(); + } + + /** + * Skips to the next line. + */ + private ignoreLine():void + { + var ch:string; + while (!this._reachedEOF && ch != "\n") + ch = this.getNextChar(); + } + + /** + * Retrieves the next single character in the data stream. + */ + private getNextChar():string + { + var ch:string = this._textData.charAt(this._parseIndex++); + + if (ch == "\n") { + ++this._line; + this._charLineIndex = 0; + } else if (ch != "\r") + ++this._charLineIndex; + + if (this._parseIndex >= this._textData.length) + this._reachedEOF = true; + + return ch; + } + + /** + * Retrieves the next integer in the data stream. + */ + private getNextInt():number /*int*/ + { + var i:number = parseInt(this.getNextToken()); + if (isNaN(i)) + this.sendParseError("int type"); + return i; + } + + /** + * Retrieves the next floating point number in the data stream. + */ + private getNextNumber():number + { + var f:number = parseFloat(this.getNextToken()); + if (isNaN(f)) + this.sendParseError("float type"); + return f; + } + + /** + * Retrieves the next 3d vector in the data stream. + */ + private parseVector3D():Vector3D + { + var vec:Vector3D = new Vector3D(); + var ch:string = this.getNextToken(); + + if (ch != "(") + this.sendParseError("("); + vec.x = -this.getNextNumber(); + vec.y = this.getNextNumber(); + vec.z = this.getNextNumber(); + + if (this.getNextToken() != ")") + this.sendParseError(")"); + + return vec; + } + + /** + * Retrieves the next quaternion in the data stream. + */ + private parseQuaternion():Quaternion + { + var quat:Quaternion = new Quaternion(); + var ch:string = this.getNextToken(); + + if (ch != "(") + this.sendParseError("("); + quat.x = this.getNextNumber(); + quat.y = -this.getNextNumber(); + quat.z = -this.getNextNumber(); + + // quat supposed to be unit length + var t:number = 1 - quat.x*quat.x - quat.y*quat.y - quat.z*quat.z; + quat.w = t < 0? 0 : -Math.sqrt(t); + + if (this.getNextToken() != ")") + this.sendParseError(")"); + + var rotQuat:Quaternion = new Quaternion(); + rotQuat.multiply(this._rotationQuat, quat); + return rotQuat; + } + + /** + * Parses the command line data. + */ + private parseCMD():void + { + // just ignore the command line property + this.parseLiteralstring(); + } + + /** + * Retrieves the next literal string in the data stream. A literal string is a sequence of characters bounded + * by double quotes. + */ + private parseLiteralstring():string + { + this.skipWhiteSpace(); + + var ch:string = this.getNextChar(); + var str:string = ""; + + if (ch != "\"") + this.sendParseError("\""); + + do { + if (this._reachedEOF) + this.sendEOFError(); + ch = this.getNextChar(); + if (ch != "\"") + str += ch; + } while (ch != "\""); + + return str; + } + + /** + * Throws an end-of-file error when a premature end of file was encountered. + */ + private sendEOFError():void + { + throw new Error("Unexpected end of file"); + } + + /** + * Throws an error when an unexpected token was encountered. + * @param expected The token type that was actually expected. + */ + private sendParseError(expected:string):void + { + throw new Error("Unexpected token at line " + (this._line + 1) + ", character " + this._charLineIndex + ". " + expected + " expected, but " + this._textData.charAt(this._parseIndex - 1) + " encountered"); + } + + /** + * Throws an error when an unknown keyword was encountered. + */ + private sendUnknownKeywordError():void + { + throw new Error("Unknown keyword at line " + (this._line + 1) + ", character " + this._charLineIndex + ". "); + } +} + +export = MD5MeshParser; + + +class VertexData +{ + public index:number /*int*/; + public s:number; + public t:number; + public startWeight:number /*int*/; + public countWeight:number /*int*/; +} + +class JointData +{ + public index:number /*int*/; + public joint:number /*int*/; + public bias:number; + public pos:Vector3D; +} + +class MeshData +{ + public vertexData:Array; + public weightData:Array; + public indices:Array /*uint*/; +} diff --git a/lib/parsers/Max3DSParser.js b/lib/parsers/Max3DSParser.js new file mode 100755 index 000000000..5e0b3b58b --- /dev/null +++ b/lib/parsers/Max3DSParser.js @@ -0,0 +1,651 @@ +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 DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +var DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); +var FaceVO = require("awayjs-renderergl/lib/parsers/data/FaceVO"); +var MaterialVO = require("awayjs-renderergl/lib/parsers/data/MaterialVO"); +var ObjectVO = require("awayjs-renderergl/lib/parsers/data/ObjectVO"); +var TextureVO = require("awayjs-renderergl/lib/parsers/data/TextureVO"); +var VertexVO = require("awayjs-renderergl/lib/parsers/data/VertexVO"); +/** + * Max3DSParser provides a parser for the 3ds data type. + */ +var Max3DSParser = (function (_super) { + __extends(Max3DSParser, _super); + /** + * Creates a new Max3DSParser object. + * + * @param useSmoothingGroups Determines whether the parser looks for smoothing groups in the 3ds file or assumes uniform smoothing. Defaults to true. + */ + function Max3DSParser(useSmoothingGroups) { + if (useSmoothingGroups === void 0) { useSmoothingGroups = true; } + _super.call(this, URLLoaderDataFormat.ARRAY_BUFFER); + this._useSmoothingGroups = useSmoothingGroups; + } + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + Max3DSParser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "3ds"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + Max3DSParser.supportsData = function (data) { + var ba; + ba = ParserUtils.toByteArray(data); + if (ba) { + ba.position = 0; + if (ba.readShort() == 0x4d4d) + return true; + } + return false; + }; + /** + * @inheritDoc + */ + Max3DSParser.prototype._iResolveDependency = function (resourceDependency) { + if (resourceDependency.assets.length == 1) { + var asset; + asset = resourceDependency.assets[0]; + if (asset.assetType == AssetType.TEXTURE) { + var tex; + tex = this._textures[resourceDependency.id]; + tex.texture = asset; + } + } + }; + /** + * @inheritDoc + */ + Max3DSParser.prototype._iResolveDependencyFailure = function (resourceDependency) { + // TODO: Implement + }; + /** + * @inheritDoc + */ + Max3DSParser.prototype._pProceedParsing = function () { + if (!this._byteData) { + this._byteData = this._pGetByteData(); + this._byteData.position = 0; + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN;// Should be default + //---------------------------------------------------------------------------- + this._textures = {}; + this._materials = {}; + this._unfinalized_objects = {}; + } + while (this._pHasTime()) { + // If we are currently working on an object, and the most recent chunk was + // the last one in that object, finalize the current object. + if (this._cur_mat && this._byteData.position >= this._cur_mat_end) + this.finalizeCurrentMaterial(); + else if (this._cur_obj && this._byteData.position >= this._cur_obj_end) { + // Can't finalize at this point, because we have to wait until the full + // animation section has been parsed for any potential pivot definitions + this._unfinalized_objects[this._cur_obj.name] = this._cur_obj; + this._cur_obj_end = Number.MAX_VALUE; + this._cur_obj = null; + } + if (this._byteData.getBytesAvailable() > 0) { + var cid /*uint*/; + var len /*uint*/; + var end /*uint*/; + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + end = this._byteData.position + (len - 6); + switch (cid) { + case 0x4D4D: + case 0x3D3D: + case 0xB000: + continue; + break; + case 0xAFFF: + this._cur_mat_end = end; + this._cur_mat = this.parseMaterial(); + break; + case 0x4000: + this._cur_obj_end = end; + this._cur_obj = new ObjectVO(); + this._cur_obj.name = this.readNulTermstring(); + this._cur_obj.materials = new Array(); + this._cur_obj.materialFaces = {}; + break; + case 0x4100: + this._cur_obj.type = AssetType.MESH; + break; + case 0x4110: + this.parseVertexList(); + break; + case 0x4120: + this.parseFaceList(); + break; + case 0x4140: + this.parseUVList(); + break; + case 0x4130: + this.parseFaceMaterialList(); + break; + case 0x4160: + this._cur_obj.transform = this.readTransform(); + break; + case 0xB002: + this.parseObjectAnimation(end); + break; + case 0x4150: + this.parseSmoothingGroups(); + break; + default: + // Skip this (unknown) chunk + this._byteData.position += (len - 6); + break; + } + // Pause parsing if there were any dependencies found during this + // iteration (i.e. if there are any dependencies that need to be + // retrieved at this time.) + if (this.dependencies.length) { + this._pPauseAndRetrieveDependencies(); + break; + } + } + } + // More parsing is required if the entire byte array has not yet + // been read, or if there is a currently non-finalized object in + // the pipeline. + if (this._byteData.getBytesAvailable() || this._cur_obj || this._cur_mat) { + return ParserBase.MORE_TO_PARSE; + } + else { + var name; + for (name in this._unfinalized_objects) { + var obj; + obj = this.constructObject(this._unfinalized_objects[name]); + if (obj) { + //add to the content property + this._pContent.addChild(obj); + this._pFinalizeAsset(obj, name); + } + } + return ParserBase.PARSING_DONE; + } + }; + Max3DSParser.prototype._pStartParsing = function (frameLimit) { + _super.prototype._pStartParsing.call(this, frameLimit); + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + }; + Max3DSParser.prototype.parseMaterial = function () { + var mat; + mat = new MaterialVO(); + while (this._byteData.position < this._cur_mat_end) { + var cid /*uint*/; + var len /*uint*/; + var end /*uint*/; + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + end = this._byteData.position + (len - 6); + switch (cid) { + case 0xA000: + mat.name = this.readNulTermstring(); + break; + case 0xA010: + mat.ambientColor = this.readColor(); + break; + case 0xA020: + mat.diffuseColor = this.readColor(); + break; + case 0xA030: + mat.specularColor = this.readColor(); + break; + case 0xA081: + mat.twoSided = true; + break; + case 0xA200: + mat.colorMap = this.parseTexture(end); + break; + case 0xA204: + mat.specularMap = this.parseTexture(end); + break; + default: + this._byteData.position = end; + break; + } + } + return mat; + }; + Max3DSParser.prototype.parseTexture = function (end /*uint*/) { + var tex; + tex = new TextureVO(); + while (this._byteData.position < end) { + var cid /*uint*/; + var len /*uint*/; + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + switch (cid) { + case 0xA300: + tex.url = this.readNulTermstring(); + break; + default: + // Skip this unknown texture sub-chunk + this._byteData.position += (len - 6); + break; + } + } + this._textures[tex.url] = tex; + this._pAddDependency(tex.url, new URLRequest(tex.url)); + return tex; + }; + Max3DSParser.prototype.parseVertexList = function () { + var i /*uint*/; + var len /*uint*/; + var count /*uint*/; + count = this._byteData.readUnsignedShort(); + this._cur_obj.verts = new Array(count * 3); + i = 0; + len = this._cur_obj.verts.length; + while (i < len) { + var x, y, z; + x = this._byteData.readFloat(); + y = this._byteData.readFloat(); + z = this._byteData.readFloat(); + this._cur_obj.verts[i++] = x; + this._cur_obj.verts[i++] = z; + this._cur_obj.verts[i++] = y; + } + }; + Max3DSParser.prototype.parseFaceList = function () { + var i /*uint*/; + var len /*uint*/; + var count /*uint*/; + count = this._byteData.readUnsignedShort(); + this._cur_obj.indices = new Array(count * 3); + i = 0; + len = this._cur_obj.indices.length; + while (i < len) { + var i0 /*uint*/, i1 /*uint*/, i2 /*uint*/; + i0 = this._byteData.readUnsignedShort(); + i1 = this._byteData.readUnsignedShort(); + i2 = this._byteData.readUnsignedShort(); + this._cur_obj.indices[i++] = i0; + this._cur_obj.indices[i++] = i2; + this._cur_obj.indices[i++] = i1; + // Skip "face info", irrelevant in Away3D + this._byteData.position += 2; + } + this._cur_obj.smoothingGroups = new Array(count); + }; + Max3DSParser.prototype.parseSmoothingGroups = function () { + var len = this._cur_obj.indices.length / 3; + var i = 0; + while (i < len) { + this._cur_obj.smoothingGroups[i] = this._byteData.readUnsignedInt(); + i++; + } + }; + Max3DSParser.prototype.parseUVList = function () { + var i /*uint*/; + var len /*uint*/; + var count /*uint*/; + count = this._byteData.readUnsignedShort(); + this._cur_obj.uvs = new Array(count * 2); + i = 0; + len = this._cur_obj.uvs.length; + while (i < len) { + this._cur_obj.uvs[i++] = this._byteData.readFloat(); + this._cur_obj.uvs[i++] = 1.0 - this._byteData.readFloat(); + } + }; + Max3DSParser.prototype.parseFaceMaterialList = function () { + var mat; + var count /*uint*/; + var i /*uint*/; + var faces /*uint*/; + mat = this.readNulTermstring(); + count = this._byteData.readUnsignedShort(); + faces = new Array(count); + i = 0; + while (i < faces.length) + faces[i++] = this._byteData.readUnsignedShort(); + this._cur_obj.materials.push(mat); + this._cur_obj.materialFaces[mat] = faces; + }; + Max3DSParser.prototype.parseObjectAnimation = function (end) { + var vo; + var obj; + var pivot; + var name; + var hier /*uint*/; + // Pivot defaults to origin + pivot = new Vector3D; + while (this._byteData.position < end) { + var cid /*uint*/; + var len /*uint*/; + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + switch (cid) { + case 0xb010: + name = this.readNulTermstring(); + this._byteData.position += 4; + hier = this._byteData.readShort(); + break; + case 0xb013: + pivot.x = this._byteData.readFloat(); + pivot.z = this._byteData.readFloat(); + pivot.y = this._byteData.readFloat(); + break; + default: + this._byteData.position += (len - 6); + break; + } + } + // If name is "$$$DUMMY" this is an empty object (e.g. a container) + // and will be ignored in this version of the parser + // TODO: Implement containers in 3DS parser. + if (name != '$$$DUMMY' && this._unfinalized_objects.hasOwnProperty(name)) { + vo = this._unfinalized_objects[name]; + obj = this.constructObject(vo, pivot); + if (obj) { + //add to the content property + this._pContent.addChild(obj); + this._pFinalizeAsset(obj, vo.name); + } + delete this._unfinalized_objects[name]; + } + }; + Max3DSParser.prototype.constructObject = function (obj, pivot) { + if (pivot === void 0) { pivot = null; } + if (obj.type == AssetType.MESH) { + var i /*uint*/; + var sub; + var geom; + var mat; + var mesh; + var mtx; + var vertices; + var faces; + if (obj.materials.length > 1) + console.log("The Away3D 3DS parser does not support multiple materials per mesh at this point."); + // Ignore empty objects + if (!obj.indices || obj.indices.length == 0) + return null; + vertices = new Array(obj.verts.length / 3); + faces = new Array(obj.indices.length / 3); + this.prepareData(vertices, faces, obj); + if (this._useSmoothingGroups) + this.applySmoothGroups(vertices, faces); + obj.verts = new Array(vertices.length * 3); + for (i = 0; i < vertices.length; i++) { + obj.verts[i * 3] = vertices[i].x; + obj.verts[i * 3 + 1] = vertices[i].y; + obj.verts[i * 3 + 2] = vertices[i].z; + } + obj.indices = new Array(faces.length * 3); + for (i = 0; i < faces.length; i++) { + obj.indices[i * 3] = faces[i].a; + obj.indices[i * 3 + 1] = faces[i].b; + obj.indices[i * 3 + 2] = faces[i].c; + } + if (obj.uvs) { + // If the object had UVs to start with, use UVs generated by + // smoothing group splitting algorithm. Otherwise those UVs + // will be nonsense and should be skipped. + obj.uvs = new Array(vertices.length * 2); + for (i = 0; i < vertices.length; i++) { + obj.uvs[i * 2] = vertices[i].u; + obj.uvs[i * 2 + 1] = vertices[i].v; + } + } + geom = new Geometry(); + // Construct sub-geometries (potentially splitting buffers) + // and add them to geometry. + sub = new TriangleSubGeometry(true); + sub.updateIndices(obj.indices); + sub.updatePositions(obj.verts); + sub.updateUVs(obj.uvs); + geom.addSubGeometry(sub); + if (obj.materials.length > 0) { + var mname; + mname = obj.materials[0]; + mat = this._materials[mname].material; + } + // Apply pivot translation to geometry if a pivot was + // found while parsing the keyframe chunk earlier. + if (pivot) { + if (obj.transform) { + // If a transform was found while parsing the + // object chunk, use it to find the local pivot vector + var dat = obj.transform.concat(); + dat[12] = 0; + dat[13] = 0; + dat[14] = 0; + mtx = new Matrix3D(dat); + pivot = mtx.transformVector(pivot); + } + pivot.scaleBy(-1); + mtx = new Matrix3D(); + mtx.appendTranslation(pivot.x, pivot.y, pivot.z); + geom.applyTransformation(mtx); + } + // Apply transformation to geometry if a transformation + // was found while parsing the object chunk earlier. + if (obj.transform) { + mtx = new Matrix3D(obj.transform); + mtx.invert(); + geom.applyTransformation(mtx); + } + // Final transform applied to geometry. Finalize the geometry, + // which will no longer be modified after this point. + this._pFinalizeAsset(geom, obj.name.concat('_geom')); + // Build mesh and return it + mesh = new Mesh(geom, mat); + mesh.transform.matrix3D = new Matrix3D(obj.transform); + return mesh; + } + // If reached, unknown + return null; + }; + Max3DSParser.prototype.prepareData = function (vertices, faces, obj) { + // convert raw ObjectVO's data to structured VertexVO and FaceVO + var i /*int*/; + var j /*int*/; + var k /*int*/; + var len = obj.verts.length; + for (i = 0, j = 0, k = 0; i < len;) { + var v = new VertexVO; + v.x = obj.verts[i++]; + v.y = obj.verts[i++]; + v.z = obj.verts[i++]; + if (obj.uvs) { + v.u = obj.uvs[j++]; + v.v = obj.uvs[j++]; + } + vertices[k++] = v; + } + len = obj.indices.length; + for (i = 0, k = 0; i < len;) { + var f = new FaceVO(); + f.a = obj.indices[i++]; + f.b = obj.indices[i++]; + f.c = obj.indices[i++]; + f.smoothGroup = obj.smoothingGroups[k] || 0; + faces[k++] = f; + } + }; + Max3DSParser.prototype.applySmoothGroups = function (vertices, faces) { + // clone vertices according to following rule: + // clone if vertex's in faces from groups 1+2 and 3 + // don't clone if vertex's in faces from groups 1+2, 3 and 1+3 + var i /*int*/; + var j /*int*/; + var k /*int*/; + var l /*int*/; + var len /*int*/; + var numVerts = vertices.length; + var numFaces = faces.length; + // extract groups data for vertices + var vGroups = new Array(numVerts) /*uint*/; + for (i = 0; i < numVerts; i++) + vGroups[i] = new Array(); + for (i = 0; i < numFaces; i++) { + var face = faces[i]; + for (j = 0; j < 3; j++) { + var groups = vGroups[(j == 0) ? face.a : ((j == 1) ? face.b : face.c)]; + var group = face.smoothGroup; + for (k = groups.length - 1; k >= 0; k--) { + if ((group & groups[k]) > 0) { + group |= groups[k]; + groups.splice(k, 1); + k = groups.length - 1; + } + } + groups.push(group); + } + } + // clone vertices + var vClones = new Array(numVerts) /*uint*/; + for (i = 0; i < numVerts; i++) { + if ((len = vGroups[i].length) < 1) + continue; + var clones = new Array(len) /*uint*/; + vClones[i] = clones; + clones[0] = i; + var v0 = vertices[i]; + for (j = 1; j < len; j++) { + var v1 = new VertexVO; + v1.x = v0.x; + v1.y = v0.y; + v1.z = v0.z; + v1.u = v0.u; + v1.v = v0.v; + clones[j] = vertices.length; + vertices.push(v1); + } + } + numVerts = vertices.length; + for (i = 0; i < numFaces; i++) { + face = faces[i]; + group = face.smoothGroup; + for (j = 0; j < 3; j++) { + k = (j == 0) ? face.a : ((j == 1) ? face.b : face.c); + groups = vGroups[k]; + len = groups.length; + clones = vClones[k]; + for (l = 0; l < len; l++) { + if (((group == 0) && (groups[l] == 0)) || ((group & groups[l]) > 0)) { + var index = clones[l]; + if (group == 0) { + // vertex is unique if no smoothGroup found + groups.splice(l, 1); + clones.splice(l, 1); + } + if (j == 0) + face.a = index; + else if (j == 1) + face.b = index; + else + face.c = index; + l = len; + } + } + } + } + }; + Max3DSParser.prototype.finalizeCurrentMaterial = function () { + var mat; + if (this._cur_mat.colorMap) + mat = new TriangleMethodMaterial(this._cur_mat.colorMap.texture || DefaultMaterialManager.getDefaultTexture()); + else + mat = new TriangleMethodMaterial(this._cur_mat.ambientColor); + mat.diffuseColor = this._cur_mat.diffuseColor; + mat.specularColor = this._cur_mat.specularColor; + if (this.materialMode >= 2) + mat.materialMode = TriangleMaterialMode.MULTI_PASS; + mat.bothSides = this._cur_mat.twoSided; + this._pFinalizeAsset(mat, this._cur_mat.name); + this._materials[this._cur_mat.name] = this._cur_mat; + this._cur_mat.material = mat; + this._cur_mat = null; + }; + Max3DSParser.prototype.readNulTermstring = function () { + var chr /*int*/; + var str = ""; + while ((chr = this._byteData.readUnsignedByte()) > 0) + str += String.fromCharCode(chr); + return str; + }; + Max3DSParser.prototype.readTransform = function () { + var data; + data = new Array(16); + // X axis + data[0] = this._byteData.readFloat(); // X + data[2] = this._byteData.readFloat(); // Z + data[1] = this._byteData.readFloat(); // Y + data[3] = 0; + // Z axis + data[8] = this._byteData.readFloat(); // X + data[10] = this._byteData.readFloat(); // Z + data[9] = this._byteData.readFloat(); // Y + data[11] = 0; + // Y Axis + data[4] = this._byteData.readFloat(); // X + data[6] = this._byteData.readFloat(); // Z + data[5] = this._byteData.readFloat(); // Y + data[7] = 0; + // Translation + data[12] = this._byteData.readFloat(); // X + data[14] = this._byteData.readFloat(); // Z + data[13] = this._byteData.readFloat(); // Y + data[15] = 1; + return data; + }; + Max3DSParser.prototype.readColor = function () { + var cid /*int*/; + var len /*int*/; + var r /*int*/, g /*int*/, b /*int*/; + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + switch (cid) { + case 0x0010: + r = this._byteData.readFloat() * 255; + g = this._byteData.readFloat() * 255; + b = this._byteData.readFloat() * 255; + break; + case 0x0011: + r = this._byteData.readUnsignedByte(); + g = this._byteData.readUnsignedByte(); + b = this._byteData.readUnsignedByte(); + break; + default: + this._byteData.position += (len - 6); + break; + } + return (r << 16) | (g << 8) | b; + }; + return Max3DSParser; +})(ParserBase); +module.exports = Max3DSParser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvbWF4M2RzcGFyc2VyLnRzIl0sIm5hbWVzIjpbIk1heDNEU1BhcnNlciIsIk1heDNEU1BhcnNlci5jb25zdHJ1Y3RvciIsIk1heDNEU1BhcnNlci5zdXBwb3J0c1R5cGUiLCJNYXgzRFNQYXJzZXIuc3VwcG9ydHNEYXRhIiwiTWF4M0RTUGFyc2VyLl9pUmVzb2x2ZURlcGVuZGVuY3kiLCJNYXgzRFNQYXJzZXIuX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUiLCJNYXgzRFNQYXJzZXIuX3BQcm9jZWVkUGFyc2luZyIsIk1heDNEU1BhcnNlci5fcFN0YXJ0UGFyc2luZyIsIk1heDNEU1BhcnNlci5wYXJzZU1hdGVyaWFsIiwiTWF4M0RTUGFyc2VyLnBhcnNlVGV4dHVyZSIsIk1heDNEU1BhcnNlci5wYXJzZVZlcnRleExpc3QiLCJNYXgzRFNQYXJzZXIucGFyc2VGYWNlTGlzdCIsIk1heDNEU1BhcnNlci5wYXJzZVNtb290aGluZ0dyb3VwcyIsIk1heDNEU1BhcnNlci5wYXJzZVVWTGlzdCIsIk1heDNEU1BhcnNlci5wYXJzZUZhY2VNYXRlcmlhbExpc3QiLCJNYXgzRFNQYXJzZXIucGFyc2VPYmplY3RBbmltYXRpb24iLCJNYXgzRFNQYXJzZXIuY29uc3RydWN0T2JqZWN0IiwiTWF4M0RTUGFyc2VyLnByZXBhcmVEYXRhIiwiTWF4M0RTUGFyc2VyLmFwcGx5U21vb3RoR3JvdXBzIiwiTWF4M0RTUGFyc2VyLmZpbmFsaXplQ3VycmVudE1hdGVyaWFsIiwiTWF4M0RTUGFyc2VyLnJlYWROdWxUZXJtc3RyaW5nIiwiTWF4M0RTUGFyc2VyLnJlYWRUcmFuc2Zvcm0iLCJNYXgzRFNQYXJzZXIucmVhZENvbG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLHNCQUFzQixXQUFhLG1EQUFtRCxDQUFDLENBQUM7QUFDL0YsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFDdEUsSUFBTyxtQkFBbUIsV0FBYywrQ0FBK0MsQ0FBQyxD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LEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEdBQUdBLENBQUNBLENBQUNBO2dCQUM1QkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsbUZBQW1GQSxDQUFDQSxDQUFDQTtZQUVsR0EsQUFDQUEsdUJBRHVCQTtZQUN2QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsT0FBT0EsSUFBSUEsR0FBR0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsTUFBTUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQzNDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtZQUViQSxRQUFRQSxHQUFHQSxJQUFJQSxLQUFLQSxDQUFXQSxHQUFHQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNuREEsS0FBS0EsR0FBR0EsSUFBSUEsS0FBS0EsQ0FBU0EsR0FBR0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsTUFBTUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFaERBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFFBQVFBLEVBQUVBLEtBQUtBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBO1lBRXZDQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxtQkFBbUJBLENBQUNBO2dCQUM1QkEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQTtZQUV6Q0EsR0FBR0EsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsS0FBS0EsQ0FBU0EsUUFBUUEsQ0FBQ0EsTUFBTUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDakRBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFFBQVFBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO2dCQUN0Q0EsR0FBR0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9CQSxHQUFHQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDbkNBLEdBQUdBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3BDQSxDQUFDQTtZQUNEQSxHQUFHQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxLQUFLQSxDQUFTQSxLQUFLQSxDQUFDQSxNQUFNQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFVQTtZQUV6REEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQ25DQSxHQUFHQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDOUJBLEdBQUdBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNsQ0EsR0FBR0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbkNBLENBQUNBO1lBRURBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO2dCQUNiQSxBQUdBQSw0REFINERBO2dCQUM1REEsMkRBQTJEQTtnQkFDM0RBLDBDQUEwQ0E7Z0JBQzFDQSxHQUFHQSxDQUFDQSxHQUFHQSxHQUFHQSxJQUFJQSxLQUFLQSxDQUFTQSxRQUFRQSxDQUFDQSxNQUFNQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDL0NBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFFBQVFBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO29CQUN0Q0EsR0FBR0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzdCQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDbENBLENBQUNBO1lBQ0ZBLENBQUNBO1lBRURBLElBQUlBLEdBQUdBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO1lBRXRCQSxBQUVBQSwyREFGMkRBO1lBQzNEQSw0QkFBNEJBO1lBQzVCQSxHQUFHQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ3BDQSxHQUFHQSxDQUFDQSxhQUFhQSxDQUFDQSxHQUFHQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtZQUMvQkEsR0FBR0EsQ0FBQ0EsZUFBZUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBRXZCQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUV6QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzlCQSxJQUFJQSxLQUFZQSxDQUFDQTtnQkFDakJBLEtBQUtBLEdBQUdBLEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUN6QkEsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsUUFBUUEsQ0FBQ0E7WUFDdkNBLENBQUNBO1lBRURBLEFBRUFBLHFEQUZxREE7WUFDckRBLGtEQUFrREE7WUFDbERBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO2dCQUNYQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDbkJBLEFBRUFBLDZDQUY2Q0E7b0JBQzdDQSxzREFBc0RBO3dCQUNsREEsR0FBR0EsR0FBaUJBLEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBO29CQUMvQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ1pBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO29CQUNaQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFDWkEsR0FBR0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3hCQSxLQUFLQSxHQUFHQSxHQUFHQSxDQUFDQSxlQUFlQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtnQkFDcENBLENBQUNBO2dCQUVEQSxLQUFLQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFFbEJBLEdBQUdBLEdBQUdBLElBQUlBLFFBQVFBLEVBQUVBLENBQUNBO2dCQUNyQkEsR0FBR0EsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDakRBLElBQUlBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLENBQUNBO1lBRURBLEFBRUFBLHVEQUZ1REE7WUFDdkRBLG9EQUFvREE7WUFDcERBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNuQkEsR0FBR0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2xDQSxHQUFHQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQTtnQkFDYkEsSUFBSUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUMvQkEsQ0FBQ0E7WUFFREEsQUFFQUEsOERBRjhEQTtZQUM5REEscURBQXFEQTtZQUNyREEsSUFBSUEsQ0FBQ0EsZUFBZUEsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFFckRBLEFBQ0FBLDJCQUQyQkE7WUFDM0JBLElBQUlBLEdBQUdBLElBQUlBLElBQUlBLENBQUNBLElBQUlBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBO1lBQzNCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxHQUFHQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtZQUN0REEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7UUFDYkEsQ0FBQ0E7UUFFREEsQUFDQUEsc0JBRHNCQTtRQUN0QkEsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0E7SUFDYkEsQ0FBQ0E7SUFFT2hCLGtDQUFXQSxHQUFuQkEsVUFBb0JBLFFBQXdCQSxFQUFFQSxLQUFtQkEsRUFBRUEsR0FBWUE7UUFFOUVpQixBQUNBQSxnRUFEZ0VBO1lBQzVEQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUNyQkEsSUFBSUEsQ0FBQ0EsQ0FBUUEsT0FBREEsQUFBUUEsQ0FBQ0E7UUFDckJBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3JCQSxJQUFJQSxHQUFHQSxHQUFrQkEsR0FBR0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFDMUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBO1lBQ3BDQSxJQUFJQSxDQUFDQSxHQUFZQSxJQUFJQSxRQUFRQSxDQUFDQTtZQUM5QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7WUFDckJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ3JCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUNyQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ2JBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO2dCQUNuQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7WUFDcEJBLENBQUNBO1lBQ0RBLFFBQVFBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ25CQSxDQUFDQTtRQUNEQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxPQUFPQSxDQUFDQSxNQUFNQSxDQUFDQTtRQUN6QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsR0FBR0EsR0FBR0EsQ0FBQ0E7WUFDN0JBLElBQUlBLENBQUNBLEdBQVVBLElBQUlBLE1BQU1BLEVBQUVBLENBQUNBO1lBQzVCQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUN2QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsR0FBR0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7WUFDdkJBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLE9BQU9BLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ3ZCQSxDQUFDQSxDQUFDQSxXQUFXQSxHQUFHQSxHQUFHQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUM1Q0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDaEJBLENBQUNBO0lBQ0ZBLENBQUNBO0lBRU9qQix3Q0FBaUJBLEdBQXpCQSxVQUEwQkEsUUFBd0JBLEVBQUVBLEtBQW1CQTtRQUV0RWtCLDhDQUE4Q0E7UUFDOUNBLG1EQUFtREE7UUFDbkRBLDhEQUE4REE7UUFFOURBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3JCQSxJQUFJQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUNyQkEsSUFBSUEsQ0FBQ0EsQ0FBUUEsT0FBREEsQUFBUUEsQ0FBQ0E7UUFDckJBLElBQUlBLENBQUNBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3JCQSxJQUFJQSxHQUFHQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUN2QkEsSUFBSUEsUUFBUUEsR0FBbUJBLFFBQVFBLENBQUNBLE1BQU1BLENBQUNBO1FBQy9DQSxJQUFJQSxRQUFRQSxHQUFtQkEsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0E7UUFFNUNBLEFBQ0FBLG1DQURtQ0E7WUFDL0JBLE9BQU9BLEdBQWlDQSxJQUFJQSxLQUFLQSxDQUFnQkEsUUFBUUEsQ0FBQ0EsQ0FBQ0EsUUFBREEsQUFBU0EsQ0FBQ0E7UUFDeEZBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFFBQVFBLEVBQUVBLENBQUNBLEVBQUVBO1lBQzVCQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxLQUFLQSxFQUFVQSxDQUFVQTtRQUMzQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsUUFBUUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFDL0JBLElBQUlBLElBQUlBLEdBQVVBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzNCQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtnQkFDeEJBLElBQUlBLE1BQU1BLEdBQTBCQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDNUZBLElBQUlBLEtBQUtBLEdBQW1CQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtnQkFDN0NBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLE1BQU1BLENBQUNBLE1BQU1BLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO29CQUN6Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7d0JBQzdCQSxLQUFLQSxJQUFJQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTt3QkFDbkJBLE1BQU1BLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO3dCQUNwQkEsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZCQSxDQUFDQTtnQkFDRkEsQ0FBQ0E7Z0JBQ0RBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1lBQ3BCQSxDQUFDQTtRQUNGQSxDQUFDQTtRQUNEQSxBQUNBQSxpQkFEaUJBO1lBQ2JBLE9BQU9BLEdBQWlDQSxJQUFJQSxLQUFLQSxDQUFnQkEsUUFBUUEsQ0FBQ0EsQ0FBQ0EsUUFBREEsQUFBU0EsQ0FBQ0E7UUFDeEZBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLFFBQVFBLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQy9CQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxNQUFNQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtnQkFDakNBLFFBQVFBLENBQUNBO1lBQ1ZBLElBQUlBLE1BQU1BLEdBQTBCQSxJQUFJQSxLQUFLQSxDQUFTQSxHQUFHQSxDQUFDQSxDQUFDQSxRQUFEQSxBQUFTQSxDQUFDQTtZQUNwRUEsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsTUFBTUEsQ0FBQ0E7WUFDcEJBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ2RBLElBQUlBLEVBQUVBLEdBQVlBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQzlCQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxHQUFHQSxFQUFFQSxDQUFDQSxFQUFFQSxFQUFFQSxDQUFDQTtnQkFDMUJBLElBQUlBLEVBQUVBLEdBQVlBLElBQUlBLFFBQVFBLENBQUNBO2dCQUMvQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1pBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNaQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDWkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQ1pBLEVBQUVBLENBQUNBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO2dCQUNaQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxRQUFRQSxDQUFDQSxNQUFNQSxDQUFDQTtnQkFDNUJBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO1lBQ25CQSxDQUFDQTtRQUNGQSxDQUFDQTtRQUNEQSxRQUFRQSxHQUFHQSxRQUFRQSxDQUFDQSxNQUFNQSxDQUFDQTtRQUUzQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsUUFBUUEsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFDL0JBLElBQUlBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ2hCQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQTtZQUN6QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7Z0JBQ3hCQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFFQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDbkRBLE1BQU1BLEdBQUdBLE9BQU9BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUNwQkEsR0FBR0EsR0FBR0EsTUFBTUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7Z0JBQ3BCQSxNQUFNQSxHQUFHQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDcEJBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLEdBQUdBLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO29CQUMxQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7d0JBQ3JFQSxJQUFJQSxLQUFLQSxHQUFtQkEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7d0JBQ3RDQSxFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTs0QkFDaEJBLEFBQ0FBLDJDQUQyQ0E7NEJBQzNDQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTs0QkFD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QUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxJQUFJQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsRUFBRUEsSUFBSUE7UUFDMUNBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLElBQUlBO1FBQzFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVaQSxBQUNBQSxTQURTQTtRQUNUQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxJQUFJQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsRUFBRUEsSUFBSUE7UUFDM0NBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLElBQUlBO1FBQzFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUViQSxBQUNBQSxTQURTQTtRQUNUQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxJQUFJQTtRQUMxQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsRUFBRUEsSUFBSUE7UUFDMUNBLElBQUlBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLElBQUlBO1FBQzFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVaQSxBQUNBQSxjQURjQTtRQUNkQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxJQUFJQTtRQUMzQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsRUFBRUEsSUFBSUE7UUFDM0NBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLEVBQUVBLElBQUlBO1FBQzNDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUViQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQTtJQUNiQSxDQUFDQTtJQUVPckIsZ0NBQVNBLEdBQWpCQTtRQUVDc0IsSUFBSUEsR0FBR0EsQ0FBUUEsT0FBREEsQUFBUUEsQ0FBQ0E7UUFDdkJBLElBQUlBLEdBQUdBLENBQVFBLE9BQURBLEFBQVFBLENBQUNBO1FBQ3ZCQSxJQUFJQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxFQUFFQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxFQUFFQSxDQUFDQSxDQUFRQSxPQUFEQSxBQUFRQSxDQUFDQTtRQUV6REEsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxDQUFDQTtRQUN6Q0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsZUFBZUEsRUFBRUEsQ0FBQ0E7UUFFdkNBLE1BQU1BLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO1lBQ2JBLEtBQUtBLE1BQU1BO2dCQUNWQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxTQUFTQSxFQUFFQSxHQUFDQSxHQUFHQSxDQUFDQTtnQkFDbkNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLEVBQUVBLEdBQUNBLEdBQUdBLENBQUNBO2dCQUNuQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsU0FBU0EsRUFBRUEsR0FBQ0EsR0FBR0EsQ0FBQ0E7Z0JBQ25DQSxLQUFLQSxDQUFDQTtZQUNQQSxLQUFLQSxNQUFNQTtnQkFDVkEsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsZ0JBQWdCQSxFQUFFQSxDQUFDQTtnQkFDdENBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLGdCQUFnQkEsRUFBRUEsQ0FBQ0E7Z0JBQ3RDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxnQkFBZ0JBLEVBQUVBLENBQUNBO2dCQUN0Q0EsS0FBS0EsQ0FBQ0E7WUFDUEE7Z0JBQ0NBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFFBQVFBLElBQUlBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO2dCQUNyQ0EsS0FBS0EsQ0FBQ0E7UUFDUkEsQ0FBQ0E7UUFFREEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7SUFDakNBLENBQUNBO0lBQ0Z0QixtQkFBQ0E7QUFBREEsQ0ExeEJBLEFBMHhCQ0EsRUExeEIwQixVQUFVLEVBMHhCcEM7QUFFRCxBQUFzQixpQkFBYixZQUFZLENBQUMiLCJmaWxlIjoicGFyc2Vycy9NYXgzRFNQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGlzcGxheU9iamVjdENvbnRhaW5lclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL0Rpc3BsYXlPYmplY3RDb250YWluZXJcIik7XG5pbXBvcnQgR2VvbWV0cnlcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvR2VvbWV0cnlcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9UcmlhbmdsZVN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IE1hdHJpeDNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeDNEXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9JQXNzZXRcIik7XG5pbXBvcnQgVVJMTG9hZGVyRGF0YUZvcm1hdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTExvYWRlckRhdGFGb3JtYXRcIik7XG5pbXBvcnQgVVJMUmVxdWVzdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgUGFyc2VyQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1BhcnNlckJhc2VcIik7XG5pbXBvcnQgUGFyc2VyVXRpbHNcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9QYXJzZXJVdGlsc1wiKTtcbmltcG9ydCBSZXNvdXJjZURlcGVuZGVuY3lcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1Jlc291cmNlRGVwZW5kZW5jeVwiKTtcbmltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlMkRCYXNlXCIpO1xuaW1wb3J0IFRleHR1cmVQcm94eUJhc2VcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL1RleHR1cmVQcm94eUJhc2VcIik7XG5pbXBvcnQgQnl0ZUFycmF5XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL0J5dGVBcnJheVwiKTtcbmltcG9ydCBNYXRlcmlhbEJhc2VcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL01hdGVyaWFsQmFzZVwiKTtcblxuaW1wb3J0IERlZmF1bHRNYXRlcmlhbE1hbmFnZXJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL3V0aWxzL0RlZmF1bHRNYXRlcmlhbE1hbmFnZXJcIik7XG5pbXBvcnQgVHJpYW5nbGVNZXRob2RNYXRlcmlhbFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvVHJpYW5nbGVNZXRob2RNYXRlcmlhbFwiKTtcbmltcG9ydCBUcmlhbmdsZU1hdGVyaWFsTW9kZVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9UcmlhbmdsZU1hdGVyaWFsTW9kZVwiKTtcblxuaW1wb3J0IEZhY2VWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvZGF0YS9GYWNlVk9cIik7XG5pbXBvcnQgTWF0ZXJpYWxWT1x0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL2RhdGEvTWF0ZXJpYWxWT1wiKTtcbmltcG9ydCBPYmplY3RWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvZGF0YS9PYmplY3RWT1wiKTtcbmltcG9ydCBUZXh0dXJlVk9cdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9kYXRhL1RleHR1cmVWT1wiKTtcbmltcG9ydCBWZXJ0ZXhWT1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvZGF0YS9WZXJ0ZXhWT1wiKTtcblxuLyoqXG4gKiBNYXgzRFNQYXJzZXIgcHJvdmlkZXMgYSBwYXJzZXIgZm9yIHRoZSAzZHMgZGF0YSB0eXBlLlxuICovXG5jbGFzcyBNYXgzRFNQYXJzZXIgZXh0ZW5kcyBQYXJzZXJCYXNlXG57XG5cdHByaXZhdGUgX2J5dGVEYXRhOkJ5dGVBcnJheTtcblxuXHRwcml2YXRlIF90ZXh0dXJlczpPYmplY3Q7XG5cdHByaXZhdGUgX21hdGVyaWFsczpPYmplY3Q7XG5cdHByaXZhdGUgX3VuZmluYWxpemVkX29iamVjdHM6T2JqZWN0O1xuXG5cdHByaXZhdGUgX2N1cl9vYmpfZW5kOm51bWJlcjtcblx0cHJpdmF0ZSBfY3VyX29iajpPYmplY3RWTztcblxuXHRwcml2YXRlIF9jdXJfbWF0X2VuZDpudW1iZXI7XG5cdHByaXZhdGUgX2N1cl9tYXQ6TWF0ZXJpYWxWTztcblx0cHJpdmF0ZSBfdXNlU21vb3RoaW5nR3JvdXBzOmJvb2xlYW47XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+TWF4M0RTUGFyc2VyPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB1c2VTbW9vdGhpbmdHcm91cHMgRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwYXJzZXIgbG9va3MgZm9yIHNtb290aGluZyBncm91cHMgaW4gdGhlIDNkcyBmaWxlIG9yIGFzc3VtZXMgdW5pZm9ybSBzbW9vdGhpbmcuIERlZmF1bHRzIHRvIHRydWUuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih1c2VTbW9vdGhpbmdHcm91cHM6Ym9vbGVhbiA9IHRydWUpXG5cdHtcblx0XHRzdXBlcihVUkxMb2FkZXJEYXRhRm9ybWF0LkFSUkFZX0JVRkZFUik7XG5cblx0XHR0aGlzLl91c2VTbW9vdGhpbmdHcm91cHMgPSB1c2VTbW9vdGhpbmdHcm91cHM7XG5cdH1cblxuXHQvKipcblx0ICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gZmlsZSBleHRlbnNpb24gaXMgc3VwcG9ydGVkIGJ5IHRoZSBwYXJzZXIuXG5cdCAqIEBwYXJhbSBleHRlbnNpb24gVGhlIGZpbGUgZXh0ZW5zaW9uIG9mIGEgcG90ZW50aWFsIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBmaWxlIHR5cGUgaXMgc3VwcG9ydGVkLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBzdXBwb3J0c1R5cGUoZXh0ZW5zaW9uOnN0cmluZyk6Ym9vbGVhblxuXHR7XG5cdFx0ZXh0ZW5zaW9uID0gZXh0ZW5zaW9uLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIGV4dGVuc2lvbiA9PSBcIjNkc1wiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHR2YXIgYmE6Qnl0ZUFycmF5O1xuXG5cdFx0YmEgPSBQYXJzZXJVdGlscy50b0J5dGVBcnJheShkYXRhKTtcblx0XHRpZiAoYmEpIHtcblx0XHRcdGJhLnBvc2l0aW9uID0gMDtcblx0XHRcdGlmIChiYS5yZWFkU2hvcnQoKSA9PSAweDRkNGQpXG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9pUmVzb2x2ZURlcGVuZGVuY3kocmVzb3VyY2VEZXBlbmRlbmN5OlJlc291cmNlRGVwZW5kZW5jeSk6dm9pZFxuXHR7XG5cdFx0aWYgKHJlc291cmNlRGVwZW5kZW5jeS5hc3NldHMubGVuZ3RoID09IDEpIHtcblx0XHRcdHZhciBhc3NldDpJQXNzZXQ7XG5cblx0XHRcdGFzc2V0ID0gcmVzb3VyY2VEZXBlbmRlbmN5LmFzc2V0c1swXTtcblx0XHRcdGlmIChhc3NldC5hc3NldFR5cGUgPT0gQXNzZXRUeXBlLlRFWFRVUkUpIHtcblx0XHRcdFx0dmFyIHRleDpUZXh0dXJlVk87XG5cblx0XHRcdFx0dGV4ID0gdGhpcy5fdGV4dHVyZXNbcmVzb3VyY2VEZXBlbmRlbmN5LmlkXTtcblx0XHRcdFx0dGV4LnRleHR1cmUgPSA8VGV4dHVyZTJEQmFzZT4gYXNzZXQ7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUocmVzb3VyY2VEZXBlbmRlbmN5OlJlc291cmNlRGVwZW5kZW5jeSk6dm9pZFxuXHR7XG5cdFx0Ly8gVE9ETzogSW1wbGVtZW50XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHB1YmxpYyBfcFByb2NlZWRQYXJzaW5nKCk6Ym9vbGVhblxuXHR7XG5cdFx0aWYgKCF0aGlzLl9ieXRlRGF0YSkge1xuXHRcdFx0dGhpcy5fYnl0ZURhdGEgPSB0aGlzLl9wR2V0Qnl0ZURhdGEoKTtcblx0XHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uID0gMDtcblxuXHRcdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0XHQvLyBMSVRUTEVfRU5ESUFOIC0gRGVmYXVsdCBmb3IgQXJyYXlCdWZmZXIgLyBOb3QgaW1wbGVtZW50ZWQgaW4gQnl0ZUFycmF5XG5cdFx0XHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRcdC8vdGhpcy5fYnl0ZURhdGEuZW5kaWFuID0gRW5kaWFuLkxJVFRMRV9FTkRJQU47Ly8gU2hvdWxkIGJlIGRlZmF1bHRcblx0XHRcdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdFx0XHR0aGlzLl90ZXh0dXJlcyA9IHt9O1xuXHRcdFx0dGhpcy5fbWF0ZXJpYWxzID0ge307XG5cdFx0XHR0aGlzLl91bmZpbmFsaXplZF9vYmplY3RzID0ge307XG5cdFx0fVxuXG5cdFx0Ly8gVE9ETzogV2l0aCB0aGlzIGNvbnN0cnVjdCwgdGhlIGxvb3Agd2lsbCBydW4gbm8tb3AgZm9yIGFzIGxvbmdcblx0XHQvLyBhcyB0aGVyZSBpcyB0aW1lIG9uY2UgZmlsZSBoYXMgZmluaXNoZWQgcmVhZGluZy4gQ29uc2lkZXIgYSBuaWNlXG5cdFx0Ly8gd2F5IHRvIHN0b3AgbG9vcCB3aGVuIGJ5dGUgYXJyYXkgaXMgZW1wdHksIHdpdGhvdXQgcHV0dGluZyBpdCBpblxuXHRcdC8vIHRoZSB3aGlsZS1jb25kaXRpb25hbCwgd2hpY2ggd2lsbCBwcmV2ZW50IGZpbmFsaXphdGlvbnMgZnJvbVxuXHRcdC8vIGhhcHBlbmluZyBhZnRlciB0aGUgbGFzdCBjaHVuay5cblx0XHR3aGlsZSAodGhpcy5fcEhhc1RpbWUoKSkge1xuXG5cdFx0XHQvLyBJZiB3ZSBhcmUgY3VycmVudGx5IHdvcmtpbmcgb24gYW4gb2JqZWN0LCBhbmQgdGhlIG1vc3QgcmVjZW50IGNodW5rIHdhc1xuXHRcdFx0Ly8gdGhlIGxhc3Qgb25lIGluIHRoYXQgb2JqZWN0LCBmaW5hbGl6ZSB0aGUgY3VycmVudCBvYmplY3QuXG5cdFx0XHRpZiAodGhpcy5fY3VyX21hdCAmJiB0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiA+PSB0aGlzLl9jdXJfbWF0X2VuZClcblx0XHRcdFx0dGhpcy5maW5hbGl6ZUN1cnJlbnRNYXRlcmlhbCgpO1xuXHRcdFx0ZWxzZSBpZiAodGhpcy5fY3VyX29iaiAmJiB0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiA+PSB0aGlzLl9jdXJfb2JqX2VuZCkge1xuXHRcdFx0XHQvLyBDYW4ndCBmaW5hbGl6ZSBhdCB0aGlzIHBvaW50LCBiZWNhdXNlIHdlIGhhdmUgdG8gd2FpdCB1bnRpbCB0aGUgZnVsbFxuXHRcdFx0XHQvLyBhbmltYXRpb24gc2VjdGlvbiBoYXMgYmVlbiBwYXJzZWQgZm9yIGFueSBwb3RlbnRpYWwgcGl2b3QgZGVmaW5pdGlvbnNcblx0XHRcdFx0dGhpcy5fdW5maW5hbGl6ZWRfb2JqZWN0c1t0aGlzLl9jdXJfb2JqLm5hbWVdID0gdGhpcy5fY3VyX29iajtcblx0XHRcdFx0dGhpcy5fY3VyX29ial9lbmQgPSBOdW1iZXIuTUFYX1ZBTFVFIC8qdWludCovO1xuXHRcdFx0XHR0aGlzLl9jdXJfb2JqID0gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuX2J5dGVEYXRhLmdldEJ5dGVzQXZhaWxhYmxlKCkgPiAwKSB7XG5cdFx0XHRcdHZhciBjaWQ6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLztcblx0XHRcdFx0dmFyIGVuZDpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRcdFx0Y2lkID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRcdFx0bGVuID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkSW50KCk7XG5cdFx0XHRcdGVuZCA9IHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uICsgKGxlbiAtIDYpO1xuXG5cdFx0XHRcdHN3aXRjaCAoY2lkKSB7XG5cdFx0XHRcdFx0Y2FzZSAweDRENEQ6IC8vIE1BSU4zRFNcblx0XHRcdFx0XHRjYXNlIDB4M0QzRDogLy8gRURJVDNEU1xuXHRcdFx0XHRcdGNhc2UgMHhCMDAwOiAvLyBLRVlGM0RTXG5cdFx0XHRcdFx0XHQvLyBUaGlzIHR5cGVzIGFyZSBcImNvbnRhaW5lciBjaHVua3NcIiBhbmQgY29udGFpbiBvbmx5XG5cdFx0XHRcdFx0XHQvLyBzdWItY2h1bmtzIChubyBkYXRhIG9uIHRoZWlyIG93bi4pIFRoaXMgbWVhbnMgdGhhdFxuXHRcdFx0XHRcdFx0Ly8gdGhlcmUgaXMgbm90aGluZyBtb3JlIHRvIHBhcnNlIGF0IHRoaXMgcG9pbnQsIGFuZFxuXHRcdFx0XHRcdFx0Ly8gaW5zdGVhZCB3ZSBzaG91bGQgcHJvZ3Jlc3MgdG8gdGhlIG5leHQgY2h1bmssIHdoaWNoXG5cdFx0XHRcdFx0XHQvLyB3aWxsIGJlIHRoZSBmaXJzdCBzdWItY2h1bmsgb2YgdGhpcyBvbmUuXG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0Y2FzZSAweEFGRkY6IC8vIE1BVEVSSUFMXG5cdFx0XHRcdFx0XHR0aGlzLl9jdXJfbWF0X2VuZCA9IGVuZDtcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9tYXQgPSB0aGlzLnBhcnNlTWF0ZXJpYWwoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0Y2FzZSAweDQwMDA6IC8vIEVESVRfT0JKRUNUXG5cdFx0XHRcdFx0XHR0aGlzLl9jdXJfb2JqX2VuZCA9IGVuZDtcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9vYmogPSBuZXcgT2JqZWN0Vk8oKTtcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9vYmoubmFtZSA9IHRoaXMucmVhZE51bFRlcm1zdHJpbmcoKTtcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9vYmoubWF0ZXJpYWxzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9vYmoubWF0ZXJpYWxGYWNlcyA9IHt9O1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4NDEwMDogLy8gT0JKX1RSSU1FU0hcblx0XHRcdFx0XHRcdHRoaXMuX2N1cl9vYmoudHlwZSA9IEFzc2V0VHlwZS5NRVNIO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4NDExMDogLy8gVFJJX1ZFUlRFWExcblx0XHRcdFx0XHRcdHRoaXMucGFyc2VWZXJ0ZXhMaXN0KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgMHg0MTIwOiAvLyBUUklfRkFDRUxJU1Rcblx0XHRcdFx0XHRcdHRoaXMucGFyc2VGYWNlTGlzdCgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4NDE0MDogLy8gVFJJX01BUFBJTkdDT09SRFNcblx0XHRcdFx0XHRcdHRoaXMucGFyc2VVVkxpc3QoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0Y2FzZSAweDQxMzA6IC8vIEZhY2UgbWF0ZXJpYWxzXG5cdFx0XHRcdFx0XHR0aGlzLnBhcnNlRmFjZU1hdGVyaWFsTGlzdCgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4NDE2MDogLy8gVHJhbnNmb3JtXG5cdFx0XHRcdFx0XHR0aGlzLl9jdXJfb2JqLnRyYW5zZm9ybSA9IHRoaXMucmVhZFRyYW5zZm9ybSgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4QjAwMjogLy8gT2JqZWN0IGFuaW1hdGlvbiAoaW5jbHVkaW5nIHBpdm90KVxuXHRcdFx0XHRcdFx0dGhpcy5wYXJzZU9iamVjdEFuaW1hdGlvbihlbmQpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIDB4NDE1MDogLy8gU21vb3RoaW5nIGdyb3Vwc1xuXHRcdFx0XHRcdFx0dGhpcy5wYXJzZVNtb290aGluZ0dyb3VwcygpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0Ly8gU2tpcCB0aGlzICh1bmtub3duKSBjaHVua1xuXHRcdFx0XHRcdFx0dGhpcy5fYnl0ZURhdGEucG9zaXRpb24gKz0gKGxlbiAtIDYpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBQYXVzZSBwYXJzaW5nIGlmIHRoZXJlIHdlcmUgYW55IGRlcGVuZGVuY2llcyBmb3VuZCBkdXJpbmcgdGhpc1xuXHRcdFx0XHQvLyBpdGVyYXRpb24gKGkuZS4gaWYgdGhlcmUgYXJlIGFueSBkZXBlbmRlbmNpZXMgdGhhdCBuZWVkIHRvIGJlXG5cdFx0XHRcdC8vIHJldHJpZXZlZCBhdCB0aGlzIHRpbWUuKVxuXHRcdFx0XHRpZiAodGhpcy5kZXBlbmRlbmNpZXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0dGhpcy5fcFBhdXNlQW5kUmV0cmlldmVEZXBlbmRlbmNpZXMoKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE1vcmUgcGFyc2luZyBpcyByZXF1aXJlZCBpZiB0aGUgZW50aXJlIGJ5dGUgYXJyYXkgaGFzIG5vdCB5ZXRcblx0XHQvLyBiZWVuIHJlYWQsIG9yIGlmIHRoZXJlIGlzIGEgY3VycmVudGx5IG5vbi1maW5hbGl6ZWQgb2JqZWN0IGluXG5cdFx0Ly8gdGhlIHBpcGVsaW5lLlxuXHRcdGlmICh0aGlzLl9ieXRlRGF0YS5nZXRCeXRlc0F2YWlsYWJsZSgpIHx8IHRoaXMuX2N1cl9vYmogfHwgdGhpcy5fY3VyX21hdCkge1xuXHRcdFx0cmV0dXJuIFBhcnNlckJhc2UuTU9SRV9UT19QQVJTRTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIG5hbWU6c3RyaW5nO1xuXG5cdFx0XHQvLyBGaW5hbGl6ZSBhbnkgcmVtYWluaW5nIG9iamVjdHMgYmVmb3JlIGVuZGluZy5cblx0XHRcdGZvciAobmFtZSBpbiB0aGlzLl91bmZpbmFsaXplZF9vYmplY3RzKSB7XG5cdFx0XHRcdHZhciBvYmo6RGlzcGxheU9iamVjdENvbnRhaW5lcjtcblx0XHRcdFx0b2JqID0gdGhpcy5jb25zdHJ1Y3RPYmplY3QodGhpcy5fdW5maW5hbGl6ZWRfb2JqZWN0c1tuYW1lXSk7XG5cdFx0XHRcdGlmIChvYmopIHtcblx0XHRcdFx0XHQvL2FkZCB0byB0aGUgY29udGVudCBwcm9wZXJ0eVxuXHRcdFx0XHRcdCg8RGlzcGxheU9iamVjdENvbnRhaW5lcj4gdGhpcy5fcENvbnRlbnQpLmFkZENoaWxkKG9iaik7XG5cblx0XHRcdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldChvYmosIG5hbWUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBQYXJzZXJCYXNlLlBBUlNJTkdfRE9ORTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgX3BTdGFydFBhcnNpbmcoZnJhbWVMaW1pdDpudW1iZXIpXG5cdHtcblx0XHRzdXBlci5fcFN0YXJ0UGFyc2luZyhmcmFtZUxpbWl0KTtcblxuXHRcdC8vY3JlYXRlIGEgY29udGVudCBvYmplY3QgZm9yIExvYWRlcnNcblx0XHR0aGlzLl9wQ29udGVudCA9IG5ldyBEaXNwbGF5T2JqZWN0Q29udGFpbmVyKCk7XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlTWF0ZXJpYWwoKTpNYXRlcmlhbFZPXG5cdHtcblx0XHR2YXIgbWF0Ok1hdGVyaWFsVk87XG5cblx0XHRtYXQgPSBuZXcgTWF0ZXJpYWxWTygpO1xuXG5cdFx0d2hpbGUgKHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uIDwgdGhpcy5fY3VyX21hdF9lbmQpIHtcblx0XHRcdHZhciBjaWQ6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki87XG5cdFx0XHR2YXIgZW5kOm51bWJlciAvKnVpbnQqLztcblxuXHRcdFx0Y2lkID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRcdGxlbiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZEludCgpO1xuXHRcdFx0ZW5kID0gdGhpcy5fYnl0ZURhdGEucG9zaXRpb24gKyAobGVuIC0gNik7XG5cblx0XHRcdHN3aXRjaCAoY2lkKSB7XG5cdFx0XHRcdGNhc2UgMHhBMDAwOiAvLyBNYXRlcmlhbCBuYW1lXG5cdFx0XHRcdFx0bWF0Lm5hbWUgPSB0aGlzLnJlYWROdWxUZXJtc3RyaW5nKCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAweEEwMTA6IC8vIEFtYmllbnQgY29sb3Jcblx0XHRcdFx0XHRtYXQuYW1iaWVudENvbG9yID0gdGhpcy5yZWFkQ29sb3IoKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlIDB4QTAyMDogLy8gRGlmZnVzZSBjb2xvclxuXHRcdFx0XHRcdG1hdC5kaWZmdXNlQ29sb3IgPSB0aGlzLnJlYWRDb2xvcigpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgMHhBMDMwOiAvLyBTcGVjdWxhciBjb2xvclxuXHRcdFx0XHRcdG1hdC5zcGVjdWxhckNvbG9yID0gdGhpcy5yZWFkQ29sb3IoKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlIDB4QTA4MTogLy8gVHdvLXNpZGVkLCBleGlzdGVuY2UgaW5kaWNhdGVzIFwidHJ1ZVwiXG5cdFx0XHRcdFx0bWF0LnR3b1NpZGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlIDB4QTIwMDogLy8gTWFpbiAoY29sb3IpIHRleHR1cmVcblx0XHRcdFx0XHRtYXQuY29sb3JNYXAgPSB0aGlzLnBhcnNlVGV4dHVyZShlbmQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgMHhBMjA0OiAvLyBTcGVjdWxhciBtYXBcblx0XHRcdFx0XHRtYXQuc3BlY3VsYXJNYXAgPSB0aGlzLnBhcnNlVGV4dHVyZShlbmQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0dGhpcy5fYnl0ZURhdGEucG9zaXRpb24gPSBlbmQ7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdDtcblx0fVxuXG5cdHByaXZhdGUgcGFyc2VUZXh0dXJlKGVuZDpudW1iZXIgLyp1aW50Ki8pOlRleHR1cmVWT1xuXHR7XG5cdFx0dmFyIHRleDpUZXh0dXJlVk87XG5cblx0XHR0ZXggPSBuZXcgVGV4dHVyZVZPKCk7XG5cblx0XHR3aGlsZSAodGhpcy5fYnl0ZURhdGEucG9zaXRpb24gPCBlbmQpIHtcblx0XHRcdHZhciBjaWQ6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRcdGNpZCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRsZW4gPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdFx0c3dpdGNoIChjaWQpIHtcblx0XHRcdFx0Y2FzZSAweEEzMDA6XG5cdFx0XHRcdFx0dGV4LnVybCA9IHRoaXMucmVhZE51bFRlcm1zdHJpbmcoKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdC8vIFNraXAgdGhpcyB1bmtub3duIHRleHR1cmUgc3ViLWNodW5rXG5cdFx0XHRcdFx0dGhpcy5fYnl0ZURhdGEucG9zaXRpb24gKz0gKGxlbiAtIDYpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuX3RleHR1cmVzW3RleC51cmxdID0gdGV4O1xuXHRcdHRoaXMuX3BBZGREZXBlbmRlbmN5KHRleC51cmwsIG5ldyBVUkxSZXF1ZXN0KHRleC51cmwpKTtcblxuXHRcdHJldHVybiB0ZXg7XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlVmVydGV4TGlzdCgpOnZvaWRcblx0e1xuXHRcdHZhciBpOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgY291bnQ6bnVtYmVyIC8qdWludCovO1xuXG5cdFx0Y291bnQgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdHRoaXMuX2N1cl9vYmoudmVydHMgPSBuZXcgQXJyYXk8bnVtYmVyPihjb3VudCozKTtcblxuXHRcdGkgPSAwO1xuXHRcdGxlbiA9IHRoaXMuX2N1cl9vYmoudmVydHMubGVuZ3RoO1xuXHRcdHdoaWxlIChpIDwgbGVuKSB7XG5cdFx0XHR2YXIgeDpudW1iZXIsIHk6bnVtYmVyLCB6Om51bWJlcjtcblxuXHRcdFx0eCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdFx0eSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdFx0eiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXG5cdFx0XHR0aGlzLl9jdXJfb2JqLnZlcnRzW2krK10gPSB4O1xuXHRcdFx0dGhpcy5fY3VyX29iai52ZXJ0c1tpKytdID0gejtcblx0XHRcdHRoaXMuX2N1cl9vYmoudmVydHNbaSsrXSA9IHk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBwYXJzZUZhY2VMaXN0KCk6dm9pZFxuXHR7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBjb3VudDpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRjb3VudCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0dGhpcy5fY3VyX29iai5pbmRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4oY291bnQqMykgLyp1aW50Ki87XG5cblx0XHRpID0gMDtcblx0XHRsZW4gPSB0aGlzLl9jdXJfb2JqLmluZGljZXMubGVuZ3RoO1xuXHRcdHdoaWxlIChpIDwgbGVuKSB7XG5cdFx0XHR2YXIgaTA6bnVtYmVyIC8qdWludCovLCBpMTpudW1iZXIgLyp1aW50Ki8sIGkyOm51bWJlciAvKnVpbnQqLztcblxuXHRcdFx0aTAgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdFx0aTEgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXHRcdFx0aTIgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXG5cdFx0XHR0aGlzLl9jdXJfb2JqLmluZGljZXNbaSsrXSA9IGkwO1xuXHRcdFx0dGhpcy5fY3VyX29iai5pbmRpY2VzW2krK10gPSBpMjtcblx0XHRcdHRoaXMuX2N1cl9vYmouaW5kaWNlc1tpKytdID0gaTE7XG5cblx0XHRcdC8vIFNraXAgXCJmYWNlIGluZm9cIiwgaXJyZWxldmFudCBpbiBBd2F5M0Rcblx0XHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uICs9IDI7XG5cdFx0fVxuXG5cdFx0dGhpcy5fY3VyX29iai5zbW9vdGhpbmdHcm91cHMgPSBuZXcgQXJyYXk8bnVtYmVyPihjb3VudCkgLyp1aW50Ki87XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlU21vb3RoaW5nR3JvdXBzKCk6dm9pZFxuXHR7XG5cdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki8gPSB0aGlzLl9jdXJfb2JqLmluZGljZXMubGVuZ3RoLzM7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovID0gMDtcblx0XHR3aGlsZSAoaSA8IGxlbikge1xuXHRcdFx0dGhpcy5fY3VyX29iai5zbW9vdGhpbmdHcm91cHNbaV0gPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRJbnQoKTtcblx0XHRcdGkrKztcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHBhcnNlVVZMaXN0KCk6dm9pZFxuXHR7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBjb3VudDpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRjb3VudCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0dGhpcy5fY3VyX29iai51dnMgPSBuZXcgQXJyYXk8bnVtYmVyPihjb3VudCoyKTtcblxuXHRcdGkgPSAwO1xuXHRcdGxlbiA9IHRoaXMuX2N1cl9vYmoudXZzLmxlbmd0aDtcblx0XHR3aGlsZSAoaSA8IGxlbikge1xuXHRcdFx0dGhpcy5fY3VyX29iai51dnNbaSsrXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdFx0dGhpcy5fY3VyX29iai51dnNbaSsrXSA9IDEuMCAtIHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgcGFyc2VGYWNlTWF0ZXJpYWxMaXN0KCk6dm9pZFxuXHR7XG5cdFx0dmFyIG1hdDpzdHJpbmc7XG5cdFx0dmFyIGNvdW50Om51bWJlciAvKnVpbnQqLztcblx0XHR2YXIgaTpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIGZhY2VzOkFycmF5PG51bWJlcj4gLyp1aW50Ki87XG5cblx0XHRtYXQgPSB0aGlzLnJlYWROdWxUZXJtc3RyaW5nKCk7XG5cdFx0Y291bnQgPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRTaG9ydCgpO1xuXG5cdFx0ZmFjZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjb3VudCkgLyp1aW50Ki87XG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKGkgPCBmYWNlcy5sZW5ndGgpXG5cdFx0XHRmYWNlc1tpKytdID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblxuXHRcdHRoaXMuX2N1cl9vYmoubWF0ZXJpYWxzLnB1c2gobWF0KTtcblx0XHR0aGlzLl9jdXJfb2JqLm1hdGVyaWFsRmFjZXNbbWF0XSA9IGZhY2VzO1xuXHR9XG5cblx0cHJpdmF0ZSBwYXJzZU9iamVjdEFuaW1hdGlvbihlbmQ6bnVtYmVyKTp2b2lkXG5cdHtcblx0XHR2YXIgdm86T2JqZWN0Vk87XG5cdFx0dmFyIG9iajpEaXNwbGF5T2JqZWN0Q29udGFpbmVyO1xuXHRcdHZhciBwaXZvdDpWZWN0b3IzRDtcblx0XHR2YXIgbmFtZTpzdHJpbmc7XG5cdFx0dmFyIGhpZXI6bnVtYmVyIC8qdWludCovO1xuXG5cdFx0Ly8gUGl2b3QgZGVmYXVsdHMgdG8gb3JpZ2luXG5cdFx0cGl2b3QgPSBuZXcgVmVjdG9yM0Q7XG5cblx0XHR3aGlsZSAodGhpcy5fYnl0ZURhdGEucG9zaXRpb24gPCBlbmQpIHtcblx0XHRcdHZhciBjaWQ6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRcdGNpZCA9IHRoaXMuX2J5dGVEYXRhLnJlYWRVbnNpZ25lZFNob3J0KCk7XG5cdFx0XHRsZW4gPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdFx0c3dpdGNoIChjaWQpIHtcblx0XHRcdFx0Y2FzZSAweGIwMTA6IC8vIE5hbWUvaGllcmFyY2h5XG5cdFx0XHRcdFx0bmFtZSA9IHRoaXMucmVhZE51bFRlcm1zdHJpbmcoKTtcblx0XHRcdFx0XHR0aGlzLl9ieXRlRGF0YS5wb3NpdGlvbiArPSA0O1xuXHRcdFx0XHRcdGhpZXIgPSB0aGlzLl9ieXRlRGF0YS5yZWFkU2hvcnQoKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlIDB4YjAxMzogLy8gUGl2b3Rcblx0XHRcdFx0XHRwaXZvdC54ID0gdGhpcy5fYnl0ZURhdGEucmVhZEZsb2F0KCk7XG5cdFx0XHRcdFx0cGl2b3QueiA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpO1xuXHRcdFx0XHRcdHBpdm90LnkgPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uICs9IChsZW4gLSA2KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJZiBuYW1lIGlzIFwiJCQkRFVNTVlcIiB0aGlzIGlzIGFuIGVtcHR5IG9iamVjdCAoZS5nLiBhIGNvbnRhaW5lcilcblx0XHQvLyBhbmQgd2lsbCBiZSBpZ25vcmVkIGluIHRoaXMgdmVyc2lvbiBvZiB0aGUgcGFyc2VyXG5cdFx0Ly8gVE9ETzogSW1wbGVtZW50IGNvbnRhaW5lcnMgaW4gM0RTIHBhcnNlci5cblx0XHRpZiAobmFtZSAhPSAnJCQkRFVNTVknICYmIHRoaXMuX3VuZmluYWxpemVkX29iamVjdHMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcblx0XHRcdHZvID0gdGhpcy5fdW5maW5hbGl6ZWRfb2JqZWN0c1tuYW1lXTtcblx0XHRcdG9iaiA9IHRoaXMuY29uc3RydWN0T2JqZWN0KHZvLCBwaXZvdCk7XG5cblx0XHRcdGlmIChvYmopIHtcblx0XHRcdFx0Ly9hZGQgdG8gdGhlIGNvbnRlbnQgcHJvcGVydHlcblx0XHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiB0aGlzLl9wQ29udGVudCkuYWRkQ2hpbGQob2JqKTtcblxuXHRcdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldChvYmosIHZvLm5hbWUpO1xuXHRcdFx0fVxuXG5cblx0XHRcdGRlbGV0ZSB0aGlzLl91bmZpbmFsaXplZF9vYmplY3RzW25hbWVdO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgY29uc3RydWN0T2JqZWN0KG9iajpPYmplY3RWTywgcGl2b3Q6VmVjdG9yM0QgPSBudWxsKTpEaXNwbGF5T2JqZWN0Q29udGFpbmVyXG5cdHtcblx0XHRpZiAob2JqLnR5cGUgPT0gQXNzZXRUeXBlLk1FU0gpIHtcblx0XHRcdHZhciBpOm51bWJlciAvKnVpbnQqLztcblx0XHRcdHZhciBzdWI6VHJpYW5nbGVTdWJHZW9tZXRyeTtcblx0XHRcdHZhciBnZW9tOkdlb21ldHJ5O1xuXHRcdFx0dmFyIG1hdDpNYXRlcmlhbEJhc2U7XG5cdFx0XHR2YXIgbWVzaDpNZXNoO1xuXHRcdFx0dmFyIG10eDpNYXRyaXgzRDtcblx0XHRcdHZhciB2ZXJ0aWNlczpBcnJheTxWZXJ0ZXhWTz47XG5cdFx0XHR2YXIgZmFjZXM6QXJyYXk8RmFjZVZPPjtcblxuXHRcdFx0aWYgKG9iai5tYXRlcmlhbHMubGVuZ3RoID4gMSlcblx0XHRcdFx0Y29uc29sZS5sb2coXCJUaGUgQXdheTNEIDNEUyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBtdWx0aXBsZSBtYXRlcmlhbHMgcGVyIG1lc2ggYXQgdGhpcyBwb2ludC5cIik7XG5cblx0XHRcdC8vIElnbm9yZSBlbXB0eSBvYmplY3RzXG5cdFx0XHRpZiAoIW9iai5pbmRpY2VzIHx8IG9iai5pbmRpY2VzLmxlbmd0aCA9PSAwKVxuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdFx0dmVydGljZXMgPSBuZXcgQXJyYXk8VmVydGV4Vk8+KG9iai52ZXJ0cy5sZW5ndGgvMyk7XG5cdFx0XHRmYWNlcyA9IG5ldyBBcnJheTxGYWNlVk8+KG9iai5pbmRpY2VzLmxlbmd0aC8zKTtcblxuXHRcdFx0dGhpcy5wcmVwYXJlRGF0YSh2ZXJ0aWNlcywgZmFjZXMsIG9iaik7XG5cblx0XHRcdGlmICh0aGlzLl91c2VTbW9vdGhpbmdHcm91cHMpXG5cdFx0XHRcdHRoaXMuYXBwbHlTbW9vdGhHcm91cHModmVydGljZXMsIGZhY2VzKTtcblxuXHRcdFx0b2JqLnZlcnRzID0gbmV3IEFycmF5PG51bWJlcj4odmVydGljZXMubGVuZ3RoKjMpO1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IHZlcnRpY2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdG9iai52ZXJ0c1tpKjNdID0gdmVydGljZXNbaV0ueDtcblx0XHRcdFx0b2JqLnZlcnRzW2kqMyArIDFdID0gdmVydGljZXNbaV0ueTtcblx0XHRcdFx0b2JqLnZlcnRzW2kqMyArIDJdID0gdmVydGljZXNbaV0uejtcblx0XHRcdH1cblx0XHRcdG9iai5pbmRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4oZmFjZXMubGVuZ3RoKjMpIC8qdWludCovO1xuXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgZmFjZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0b2JqLmluZGljZXNbaSozXSA9IGZhY2VzW2ldLmE7XG5cdFx0XHRcdG9iai5pbmRpY2VzW2kqMyArIDFdID0gZmFjZXNbaV0uYjtcblx0XHRcdFx0b2JqLmluZGljZXNbaSozICsgMl0gPSBmYWNlc1tpXS5jO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAob2JqLnV2cykge1xuXHRcdFx0XHQvLyBJZiB0aGUgb2JqZWN0IGhhZCBVVnMgdG8gc3RhcnQgd2l0aCwgdXNlIFVWcyBnZW5lcmF0ZWQgYnlcblx0XHRcdFx0Ly8gc21vb3RoaW5nIGdyb3VwIHNwbGl0dGluZyBhbGdvcml0aG0uIE90aGVyd2lzZSB0aG9zZSBVVnNcblx0XHRcdFx0Ly8gd2lsbCBiZSBub25zZW5zZSBhbmQgc2hvdWxkIGJlIHNraXBwZWQuXG5cdFx0XHRcdG9iai51dnMgPSBuZXcgQXJyYXk8bnVtYmVyPih2ZXJ0aWNlcy5sZW5ndGgqMik7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCB2ZXJ0aWNlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdG9iai51dnNbaSoyXSA9IHZlcnRpY2VzW2ldLnU7XG5cdFx0XHRcdFx0b2JqLnV2c1tpKjIgKyAxXSA9IHZlcnRpY2VzW2ldLnY7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Z2VvbSA9IG5ldyBHZW9tZXRyeSgpO1xuXG5cdFx0XHQvLyBDb25zdHJ1Y3Qgc3ViLWdlb21ldHJpZXMgKHBvdGVudGlhbGx5IHNwbGl0dGluZyBidWZmZXJzKVxuXHRcdFx0Ly8gYW5kIGFkZCB0aGVtIHRvIGdlb21ldHJ5LlxuXHRcdFx0c3ViID0gbmV3IFRyaWFuZ2xlU3ViR2VvbWV0cnkodHJ1ZSk7XG5cdFx0XHRzdWIudXBkYXRlSW5kaWNlcyhvYmouaW5kaWNlcyk7XG5cdFx0XHRzdWIudXBkYXRlUG9zaXRpb25zKG9iai52ZXJ0cyk7XG5cdFx0XHRzdWIudXBkYXRlVVZzKG9iai51dnMpO1xuXG5cdFx0XHRnZW9tLmFkZFN1Ykdlb21ldHJ5KHN1Yik7XG5cblx0XHRcdGlmIChvYmoubWF0ZXJpYWxzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0dmFyIG1uYW1lOnN0cmluZztcblx0XHRcdFx0bW5hbWUgPSBvYmoubWF0ZXJpYWxzWzBdO1xuXHRcdFx0XHRtYXQgPSB0aGlzLl9tYXRlcmlhbHNbbW5hbWVdLm1hdGVyaWFsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBcHBseSBwaXZvdCB0cmFuc2xhdGlvbiB0byBnZW9tZXRyeSBpZiBhIHBpdm90IHdhc1xuXHRcdFx0Ly8gZm91bmQgd2hpbGUgcGFyc2luZyB0aGUga2V5ZnJhbWUgY2h1bmsgZWFybGllci5cblx0XHRcdGlmIChwaXZvdCkge1xuXHRcdFx0XHRpZiAob2JqLnRyYW5zZm9ybSkge1xuXHRcdFx0XHRcdC8vIElmIGEgdHJhbnNmb3JtIHdhcyBmb3VuZCB3aGlsZSBwYXJzaW5nIHRoZVxuXHRcdFx0XHRcdC8vIG9iamVjdCBjaHVuaywgdXNlIGl0IHRvIGZpbmQgdGhlIGxvY2FsIHBpdm90IHZlY3RvclxuXHRcdFx0XHRcdHZhciBkYXQ6QXJyYXk8bnVtYmVyPiA9IG9iai50cmFuc2Zvcm0uY29uY2F0KCk7XG5cdFx0XHRcdFx0ZGF0WzEyXSA9IDA7XG5cdFx0XHRcdFx0ZGF0WzEzXSA9IDA7XG5cdFx0XHRcdFx0ZGF0WzE0XSA9IDA7XG5cdFx0XHRcdFx0bXR4ID0gbmV3IE1hdHJpeDNEKGRhdCk7XG5cdFx0XHRcdFx0cGl2b3QgPSBtdHgudHJhbnNmb3JtVmVjdG9yKHBpdm90KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHBpdm90LnNjYWxlQnkoLTEpO1xuXG5cdFx0XHRcdG10eCA9IG5ldyBNYXRyaXgzRCgpO1xuXHRcdFx0XHRtdHguYXBwZW5kVHJhbnNsYXRpb24ocGl2b3QueCwgcGl2b3QueSwgcGl2b3Queik7XG5cdFx0XHRcdGdlb20uYXBwbHlUcmFuc2Zvcm1hdGlvbihtdHgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBcHBseSB0cmFuc2Zvcm1hdGlvbiB0byBnZW9tZXRyeSBpZiBhIHRyYW5zZm9ybWF0aW9uXG5cdFx0XHQvLyB3YXMgZm91bmQgd2hpbGUgcGFyc2luZyB0aGUgb2JqZWN0IGNodW5rIGVhcmxpZXIuXG5cdFx0XHRpZiAob2JqLnRyYW5zZm9ybSkge1xuXHRcdFx0XHRtdHggPSBuZXcgTWF0cml4M0Qob2JqLnRyYW5zZm9ybSk7XG5cdFx0XHRcdG10eC5pbnZlcnQoKTtcblx0XHRcdFx0Z2VvbS5hcHBseVRyYW5zZm9ybWF0aW9uKG10eCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZpbmFsIHRyYW5zZm9ybSBhcHBsaWVkIHRvIGdlb21ldHJ5LiBGaW5hbGl6ZSB0aGUgZ2VvbWV0cnksXG5cdFx0XHQvLyB3aGljaCB3aWxsIG5vIGxvbmdlciBiZSBtb2RpZmllZCBhZnRlciB0aGlzIHBvaW50LlxuXHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoZ2VvbSwgb2JqLm5hbWUuY29uY2F0KCdfZ2VvbScpKTtcblxuXHRcdFx0Ly8gQnVpbGQgbWVzaCBhbmQgcmV0dXJuIGl0XG5cdFx0XHRtZXNoID0gbmV3IE1lc2goZ2VvbSwgbWF0KTtcblx0XHRcdG1lc2gudHJhbnNmb3JtLm1hdHJpeDNEID0gbmV3IE1hdHJpeDNEKG9iai50cmFuc2Zvcm0pO1xuXHRcdFx0cmV0dXJuIG1lc2g7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgcmVhY2hlZCwgdW5rbm93blxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0cHJpdmF0ZSBwcmVwYXJlRGF0YSh2ZXJ0aWNlczpBcnJheTxWZXJ0ZXhWTz4sIGZhY2VzOkFycmF5PEZhY2VWTz4sIG9iajpPYmplY3RWTyk6dm9pZFxuXHR7XG5cdFx0Ly8gY29udmVydCByYXcgT2JqZWN0Vk8ncyBkYXRhIHRvIHN0cnVjdHVyZWQgVmVydGV4Vk8gYW5kIEZhY2VWT1xuXHRcdHZhciBpOm51bWJlciAvKmludCovO1xuXHRcdHZhciBqOm51bWJlciAvKmludCovO1xuXHRcdHZhciBrOm51bWJlciAvKmludCovO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qaW50Ki8gPSBvYmoudmVydHMubGVuZ3RoO1xuXHRcdGZvciAoaSA9IDAsIGogPSAwLCBrID0gMDsgaSA8IGxlbjspIHtcblx0XHRcdHZhciB2OlZlcnRleFZPID0gbmV3IFZlcnRleFZPO1xuXHRcdFx0di54ID0gb2JqLnZlcnRzW2krK107XG5cdFx0XHR2LnkgPSBvYmoudmVydHNbaSsrXTtcblx0XHRcdHYueiA9IG9iai52ZXJ0c1tpKytdO1xuXHRcdFx0aWYgKG9iai51dnMpIHtcblx0XHRcdFx0di51ID0gb2JqLnV2c1tqKytdO1xuXHRcdFx0XHR2LnYgPSBvYmoudXZzW2orK107XG5cdFx0XHR9XG5cdFx0XHR2ZXJ0aWNlc1trKytdID0gdjtcblx0XHR9XG5cdFx0bGVuID0gb2JqLmluZGljZXMubGVuZ3RoO1xuXHRcdGZvciAoaSA9IDAsIGsgPSAwOyBpIDwgbGVuOykge1xuXHRcdFx0dmFyIGY6RmFjZVZPID0gbmV3IEZhY2VWTygpO1xuXHRcdFx0Zi5hID0gb2JqLmluZGljZXNbaSsrXTtcblx0XHRcdGYuYiA9IG9iai5pbmRpY2VzW2krK107XG5cdFx0XHRmLmMgPSBvYmouaW5kaWNlc1tpKytdO1xuXHRcdFx0Zi5zbW9vdGhHcm91cCA9IG9iai5zbW9vdGhpbmdHcm91cHNba10gfHwgMDtcblx0XHRcdGZhY2VzW2srK10gPSBmO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgYXBwbHlTbW9vdGhHcm91cHModmVydGljZXM6QXJyYXk8VmVydGV4Vk8+LCBmYWNlczpBcnJheTxGYWNlVk8+KTp2b2lkXG5cdHtcblx0XHQvLyBjbG9uZSB2ZXJ0aWNlcyBhY2NvcmRpbmcgdG8gZm9sbG93aW5nIHJ1bGU6XG5cdFx0Ly8gY2xvbmUgaWYgdmVydGV4J3MgaW4gZmFjZXMgZnJvbSBncm91cHMgMSsyIGFuZCAzXG5cdFx0Ly8gZG9uJ3QgY2xvbmUgaWYgdmVydGV4J3MgaW4gZmFjZXMgZnJvbSBncm91cHMgMSsyLCAzIGFuZCAxKzNcblxuXHRcdHZhciBpOm51bWJlciAvKmludCovO1xuXHRcdHZhciBqOm51bWJlciAvKmludCovO1xuXHRcdHZhciBrOm51bWJlciAvKmludCovO1xuXHRcdHZhciBsOm51bWJlciAvKmludCovO1xuXHRcdHZhciBsZW46bnVtYmVyIC8qaW50Ki87XG5cdFx0dmFyIG51bVZlcnRzOm51bWJlciAvKnVpbnQqLyA9IHZlcnRpY2VzLmxlbmd0aDtcblx0XHR2YXIgbnVtRmFjZXM6bnVtYmVyIC8qdWludCovID0gZmFjZXMubGVuZ3RoO1xuXG5cdFx0Ly8gZXh0cmFjdCBncm91cHMgZGF0YSBmb3IgdmVydGljZXNcblx0XHR2YXIgdkdyb3VwczpBcnJheTxBcnJheTxudW1iZXI+PiAvKnVpbnQqLyA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PihudW1WZXJ0cykgLyp1aW50Ki87XG5cdFx0Zm9yIChpID0gMDsgaSA8IG51bVZlcnRzOyBpKyspXG5cdFx0XHR2R3JvdXBzW2ldID0gbmV3IEFycmF5PG51bWJlcj4oKSAvKnVpbnQqLztcblx0XHRmb3IgKGkgPSAwOyBpIDwgbnVtRmFjZXM7IGkrKykge1xuXHRcdFx0dmFyIGZhY2U6RmFjZVZPID0gZmFjZXNbaV07XG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgMzsgaisrKSB7XG5cdFx0XHRcdHZhciBncm91cHM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLyA9IHZHcm91cHNbKGogPT0gMCk/IGZhY2UuYSA6ICgoaiA9PSAxKT8gZmFjZS5iIDogZmFjZS5jKV07XG5cdFx0XHRcdHZhciBncm91cDpudW1iZXIgLyp1aW50Ki8gPSBmYWNlLnNtb290aEdyb3VwO1xuXHRcdFx0XHRmb3IgKGsgPSBncm91cHMubGVuZ3RoIC0gMTsgayA+PSAwOyBrLS0pIHtcblx0XHRcdFx0XHRpZiAoKGdyb3VwICYgZ3JvdXBzW2tdKSA+IDApIHtcblx0XHRcdFx0XHRcdGdyb3VwIHw9IGdyb3Vwc1trXTtcblx0XHRcdFx0XHRcdGdyb3Vwcy5zcGxpY2UoaywgMSk7XG5cdFx0XHRcdFx0XHRrID0gZ3JvdXBzLmxlbmd0aCAtIDE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGdyb3Vwcy5wdXNoKGdyb3VwKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gY2xvbmUgdmVydGljZXNcblx0XHR2YXIgdkNsb25lczpBcnJheTxBcnJheTxudW1iZXI+PiAvKnVpbnQqLyA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PihudW1WZXJ0cykgLyp1aW50Ki87XG5cdFx0Zm9yIChpID0gMDsgaSA8IG51bVZlcnRzOyBpKyspIHtcblx0XHRcdGlmICgobGVuID0gdkdyb3Vwc1tpXS5sZW5ndGgpIDwgMSlcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR2YXIgY2xvbmVzOkFycmF5PG51bWJlcj4gLyp1aW50Ki8gPSBuZXcgQXJyYXk8bnVtYmVyPihsZW4pIC8qdWludCovO1xuXHRcdFx0dkNsb25lc1tpXSA9IGNsb25lcztcblx0XHRcdGNsb25lc1swXSA9IGk7XG5cdFx0XHR2YXIgdjA6VmVydGV4Vk8gPSB2ZXJ0aWNlc1tpXTtcblx0XHRcdGZvciAoaiA9IDE7IGogPCBsZW47IGorKykge1xuXHRcdFx0XHR2YXIgdjE6VmVydGV4Vk8gPSBuZXcgVmVydGV4Vk87XG5cdFx0XHRcdHYxLnggPSB2MC54O1xuXHRcdFx0XHR2MS55ID0gdjAueTtcblx0XHRcdFx0djEueiA9IHYwLno7XG5cdFx0XHRcdHYxLnUgPSB2MC51O1xuXHRcdFx0XHR2MS52ID0gdjAudjtcblx0XHRcdFx0Y2xvbmVzW2pdID0gdmVydGljZXMubGVuZ3RoO1xuXHRcdFx0XHR2ZXJ0aWNlcy5wdXNoKHYxKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0bnVtVmVydHMgPSB2ZXJ0aWNlcy5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgbnVtRmFjZXM7IGkrKykge1xuXHRcdFx0ZmFjZSA9IGZhY2VzW2ldO1xuXHRcdFx0Z3JvdXAgPSBmYWNlLnNtb290aEdyb3VwO1xuXHRcdFx0Zm9yIChqID0gMDsgaiA8IDM7IGorKykge1xuXHRcdFx0XHRrID0gKGogPT0gMCk/IGZhY2UuYSA6ICgoaiA9PSAxKT8gZmFjZS5iIDogZmFjZS5jKTtcblx0XHRcdFx0Z3JvdXBzID0gdkdyb3Vwc1trXTtcblx0XHRcdFx0bGVuID0gZ3JvdXBzLmxlbmd0aDtcblx0XHRcdFx0Y2xvbmVzID0gdkNsb25lc1trXTtcblx0XHRcdFx0Zm9yIChsID0gMDsgbCA8IGxlbjsgbCsrKSB7XG5cdFx0XHRcdFx0aWYgKCgoZ3JvdXAgPT0gMCkgJiYgKGdyb3Vwc1tsXSA9PSAwKSkgfHwgKChncm91cCAmIGdyb3Vwc1tsXSkgPiAwKSkge1xuXHRcdFx0XHRcdFx0dmFyIGluZGV4Om51bWJlciAvKnVpbnQqLyA9IGNsb25lc1tsXTtcblx0XHRcdFx0XHRcdGlmIChncm91cCA9PSAwKSB7XG5cdFx0XHRcdFx0XHRcdC8vIHZlcnRleCBpcyB1bmlxdWUgaWYgbm8gc21vb3RoR3JvdXAgZm91bmRcblx0XHRcdFx0XHRcdFx0Z3JvdXBzLnNwbGljZShsLCAxKTtcblx0XHRcdFx0XHRcdFx0Y2xvbmVzLnNwbGljZShsLCAxKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChqID09IDApXG5cdFx0XHRcdFx0XHRcdGZhY2UuYSA9IGluZGV4OyBlbHNlIGlmIChqID09IDEpXG5cdFx0XHRcdFx0XHRcdGZhY2UuYiA9IGluZGV4OyBlbHNlXG5cdFx0XHRcdFx0XHRcdGZhY2UuYyA9IGluZGV4O1xuXHRcdFx0XHRcdFx0bCA9IGxlbjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGZpbmFsaXplQ3VycmVudE1hdGVyaWFsKCk6dm9pZFxuXHR7XG5cdFx0dmFyIG1hdDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXG5cdFx0aWYgKHRoaXMuX2N1cl9tYXQuY29sb3JNYXApXG5cdFx0XHRtYXQgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbCh0aGlzLl9jdXJfbWF0LmNvbG9yTWFwLnRleHR1cmUgfHwgRGVmYXVsdE1hdGVyaWFsTWFuYWdlci5nZXREZWZhdWx0VGV4dHVyZSgpKTtcblx0XHRlbHNlXG5cdFx0XHRtYXQgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbCh0aGlzLl9jdXJfbWF0LmFtYmllbnRDb2xvcik7XG5cblx0XHRtYXQuZGlmZnVzZUNvbG9yID0gdGhpcy5fY3VyX21hdC5kaWZmdXNlQ29sb3I7XG5cdFx0bWF0LnNwZWN1bGFyQ29sb3IgPSB0aGlzLl9jdXJfbWF0LnNwZWN1bGFyQ29sb3I7XG5cblx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPj0gMilcblx0XHRcdG1hdC5tYXRlcmlhbE1vZGUgPSBUcmlhbmdsZU1hdGVyaWFsTW9kZS5NVUxUSV9QQVNTXG5cblx0XHRtYXQuYm90aFNpZGVzID0gdGhpcy5fY3VyX21hdC50d29TaWRlZDtcblxuXHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KG1hdCwgdGhpcy5fY3VyX21hdC5uYW1lKTtcblxuXHRcdHRoaXMuX21hdGVyaWFsc1t0aGlzLl9jdXJfbWF0Lm5hbWVdID0gdGhpcy5fY3VyX21hdDtcblx0XHR0aGlzLl9jdXJfbWF0Lm1hdGVyaWFsID0gbWF0O1xuXG5cdFx0dGhpcy5fY3VyX21hdCA9IG51bGw7XG5cdH1cblxuXHRwcml2YXRlIHJlYWROdWxUZXJtc3RyaW5nKCk6c3RyaW5nXG5cdHtcblx0XHR2YXIgY2hyOm51bWJlciAvKmludCovO1xuXHRcdHZhciBzdHI6c3RyaW5nID0gXCJcIjtcblxuXHRcdHdoaWxlICgoY2hyID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpKSA+IDApXG5cdFx0XHRzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaHIpO1xuXG5cdFx0cmV0dXJuIHN0cjtcblx0fVxuXG5cdHByaXZhdGUgcmVhZFRyYW5zZm9ybSgpOkFycmF5PG51bWJlcj5cblx0e1xuXHRcdHZhciBkYXRhOkFycmF5PG51bWJlcj47XG5cblx0XHRkYXRhID0gbmV3IEFycmF5PG51bWJlcj4oMTYpO1xuXG5cdFx0Ly8gWCBheGlzXG5cdFx0ZGF0YVswXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBYXG5cdFx0ZGF0YVsyXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBaXG5cdFx0ZGF0YVsxXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBZXG5cdFx0ZGF0YVszXSA9IDA7XG5cblx0XHQvLyBaIGF4aXNcblx0XHRkYXRhWzhdID0gdGhpcy5fYnl0ZURhdGEucmVhZEZsb2F0KCk7IC8vIFhcblx0XHRkYXRhWzEwXSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBaXG5cdFx0ZGF0YVs5XSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBZXG5cdFx0ZGF0YVsxMV0gPSAwO1xuXG5cdFx0Ly8gWSBBeGlzXG5cdFx0ZGF0YVs0XSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBYXG5cdFx0ZGF0YVs2XSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBaXG5cdFx0ZGF0YVs1XSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBZXG5cdFx0ZGF0YVs3XSA9IDA7XG5cblx0XHQvLyBUcmFuc2xhdGlvblxuXHRcdGRhdGFbMTJdID0gdGhpcy5fYnl0ZURhdGEucmVhZEZsb2F0KCk7IC8vIFhcblx0XHRkYXRhWzE0XSA9IHRoaXMuX2J5dGVEYXRhLnJlYWRGbG9hdCgpOyAvLyBaXG5cdFx0ZGF0YVsxM10gPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKTsgLy8gWVxuXHRcdGRhdGFbMTVdID0gMTtcblxuXHRcdHJldHVybiBkYXRhO1xuXHR9XG5cblx0cHJpdmF0ZSByZWFkQ29sb3IoKTpudW1iZXIgLyppbnQqL1xuXHR7XG5cdFx0dmFyIGNpZDpudW1iZXIgLyppbnQqLztcblx0XHR2YXIgbGVuOm51bWJlciAvKmludCovO1xuXHRcdHZhciByOm51bWJlciAvKmludCovLCBnOm51bWJlciAvKmludCovLCBiOm51bWJlciAvKmludCovO1xuXG5cdFx0Y2lkID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkU2hvcnQoKTtcblx0XHRsZW4gPSB0aGlzLl9ieXRlRGF0YS5yZWFkVW5zaWduZWRJbnQoKTtcblxuXHRcdHN3aXRjaCAoY2lkKSB7XG5cdFx0XHRjYXNlIDB4MDAxMDogLy8gRmxvYXRzXG5cdFx0XHRcdHIgPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKSoyNTU7XG5cdFx0XHRcdGcgPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKSoyNTU7XG5cdFx0XHRcdGIgPSB0aGlzLl9ieXRlRGF0YS5yZWFkRmxvYXQoKSoyNTU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAweDAwMTE6IC8vIDI0LWJpdCBjb2xvclxuXHRcdFx0XHRyID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRnID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRiID0gdGhpcy5fYnl0ZURhdGEucmVhZFVuc2lnbmVkQnl0ZSgpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHRoaXMuX2J5dGVEYXRhLnBvc2l0aW9uICs9IChsZW4gLSA2KTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIChyIDw8IDE2KSB8IChnIDw8IDgpIHwgYjtcblx0fVxufVxuXG5leHBvcnQgPSBNYXgzRFNQYXJzZXI7XG5cblxuIl19 \ No newline at end of file diff --git a/lib/parsers/Max3DSParser.ts b/lib/parsers/Max3DSParser.ts new file mode 100644 index 000000000..89cc3e442 --- /dev/null +++ b/lib/parsers/Max3DSParser.ts @@ -0,0 +1,830 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +import AssetType = require("awayjs-core/lib/core/library/AssetType"); +import IAsset = require("awayjs-core/lib/core/library/IAsset"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +import ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +import ResourceDependency = require("awayjs-core/lib/parsers/ResourceDependency"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); +import TextureProxyBase = require("awayjs-core/lib/textures/TextureProxyBase"); +import ByteArray = require("awayjs-core/lib/utils/ByteArray"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); + +import DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +import TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); + +import FaceVO = require("awayjs-renderergl/lib/parsers/data/FaceVO"); +import MaterialVO = require("awayjs-renderergl/lib/parsers/data/MaterialVO"); +import ObjectVO = require("awayjs-renderergl/lib/parsers/data/ObjectVO"); +import TextureVO = require("awayjs-renderergl/lib/parsers/data/TextureVO"); +import VertexVO = require("awayjs-renderergl/lib/parsers/data/VertexVO"); + +/** + * Max3DSParser provides a parser for the 3ds data type. + */ +class Max3DSParser extends ParserBase +{ + private _byteData:ByteArray; + + private _textures:Object; + private _materials:Object; + private _unfinalized_objects:Object; + + private _cur_obj_end:number; + private _cur_obj:ObjectVO; + + private _cur_mat_end:number; + private _cur_mat:MaterialVO; + private _useSmoothingGroups:boolean; + + /** + * Creates a new Max3DSParser object. + * + * @param useSmoothingGroups Determines whether the parser looks for smoothing groups in the 3ds file or assumes uniform smoothing. Defaults to true. + */ + constructor(useSmoothingGroups:boolean = true) + { + super(URLLoaderDataFormat.ARRAY_BUFFER); + + this._useSmoothingGroups = useSmoothingGroups; + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "3ds"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + var ba:ByteArray; + + ba = ParserUtils.toByteArray(data); + if (ba) { + ba.position = 0; + if (ba.readShort() == 0x4d4d) + return true; + } + + return false; + } + + /** + * @inheritDoc + */ + public _iResolveDependency(resourceDependency:ResourceDependency):void + { + if (resourceDependency.assets.length == 1) { + var asset:IAsset; + + asset = resourceDependency.assets[0]; + if (asset.assetType == AssetType.TEXTURE) { + var tex:TextureVO; + + tex = this._textures[resourceDependency.id]; + tex.texture = asset; + } + } + } + + /** + * @inheritDoc + */ + public _iResolveDependencyFailure(resourceDependency:ResourceDependency):void + { + // TODO: Implement + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + if (!this._byteData) { + this._byteData = this._pGetByteData(); + this._byteData.position = 0; + + //---------------------------------------------------------------------------- + // LITTLE_ENDIAN - Default for ArrayBuffer / Not implemented in ByteArray + //---------------------------------------------------------------------------- + //this._byteData.endian = Endian.LITTLE_ENDIAN;// Should be default + //---------------------------------------------------------------------------- + + this._textures = {}; + this._materials = {}; + this._unfinalized_objects = {}; + } + + // TODO: With this construct, the loop will run no-op for as long + // as there is time once file has finished reading. Consider a nice + // way to stop loop when byte array is empty, without putting it in + // the while-conditional, which will prevent finalizations from + // happening after the last chunk. + while (this._pHasTime()) { + + // If we are currently working on an object, and the most recent chunk was + // the last one in that object, finalize the current object. + if (this._cur_mat && this._byteData.position >= this._cur_mat_end) + this.finalizeCurrentMaterial(); + else if (this._cur_obj && this._byteData.position >= this._cur_obj_end) { + // Can't finalize at this point, because we have to wait until the full + // animation section has been parsed for any potential pivot definitions + this._unfinalized_objects[this._cur_obj.name] = this._cur_obj; + this._cur_obj_end = Number.MAX_VALUE /*uint*/; + this._cur_obj = null; + } + + if (this._byteData.getBytesAvailable() > 0) { + var cid:number /*uint*/; + var len:number /*uint*/; + var end:number /*uint*/; + + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + end = this._byteData.position + (len - 6); + + switch (cid) { + case 0x4D4D: // MAIN3DS + case 0x3D3D: // EDIT3DS + case 0xB000: // KEYF3DS + // This types are "container chunks" and contain only + // sub-chunks (no data on their own.) This means that + // there is nothing more to parse at this point, and + // instead we should progress to the next chunk, which + // will be the first sub-chunk of this one. + continue; + break; + + case 0xAFFF: // MATERIAL + this._cur_mat_end = end; + this._cur_mat = this.parseMaterial(); + break; + + case 0x4000: // EDIT_OBJECT + this._cur_obj_end = end; + this._cur_obj = new ObjectVO(); + this._cur_obj.name = this.readNulTermstring(); + this._cur_obj.materials = new Array(); + this._cur_obj.materialFaces = {}; + break; + + case 0x4100: // OBJ_TRIMESH + this._cur_obj.type = AssetType.MESH; + break; + + case 0x4110: // TRI_VERTEXL + this.parseVertexList(); + break; + + case 0x4120: // TRI_FACELIST + this.parseFaceList(); + break; + + case 0x4140: // TRI_MAPPINGCOORDS + this.parseUVList(); + break; + + case 0x4130: // Face materials + this.parseFaceMaterialList(); + break; + + case 0x4160: // Transform + this._cur_obj.transform = this.readTransform(); + break; + + case 0xB002: // Object animation (including pivot) + this.parseObjectAnimation(end); + break; + + case 0x4150: // Smoothing groups + this.parseSmoothingGroups(); + break; + + default: + // Skip this (unknown) chunk + this._byteData.position += (len - 6); + break; + } + + // Pause parsing if there were any dependencies found during this + // iteration (i.e. if there are any dependencies that need to be + // retrieved at this time.) + if (this.dependencies.length) { + this._pPauseAndRetrieveDependencies(); + break; + } + } + } + + // More parsing is required if the entire byte array has not yet + // been read, or if there is a currently non-finalized object in + // the pipeline. + if (this._byteData.getBytesAvailable() || this._cur_obj || this._cur_mat) { + return ParserBase.MORE_TO_PARSE; + } else { + var name:string; + + // Finalize any remaining objects before ending. + for (name in this._unfinalized_objects) { + var obj:DisplayObjectContainer; + obj = this.constructObject(this._unfinalized_objects[name]); + if (obj) { + //add to the content property + ( this._pContent).addChild(obj); + + this._pFinalizeAsset(obj, name); + } + } + + return ParserBase.PARSING_DONE; + } + } + + public _pStartParsing(frameLimit:number) + { + super._pStartParsing(frameLimit); + + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + } + + private parseMaterial():MaterialVO + { + var mat:MaterialVO; + + mat = new MaterialVO(); + + while (this._byteData.position < this._cur_mat_end) { + var cid:number /*uint*/; + var len:number /*uint*/; + var end:number /*uint*/; + + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + end = this._byteData.position + (len - 6); + + switch (cid) { + case 0xA000: // Material name + mat.name = this.readNulTermstring(); + break; + + case 0xA010: // Ambient color + mat.ambientColor = this.readColor(); + break; + + case 0xA020: // Diffuse color + mat.diffuseColor = this.readColor(); + break; + + case 0xA030: // Specular color + mat.specularColor = this.readColor(); + break; + + case 0xA081: // Two-sided, existence indicates "true" + mat.twoSided = true; + break; + + case 0xA200: // Main (color) texture + mat.colorMap = this.parseTexture(end); + break; + + case 0xA204: // Specular map + mat.specularMap = this.parseTexture(end); + break; + + default: + this._byteData.position = end; + break; + } + } + + return mat; + } + + private parseTexture(end:number /*uint*/):TextureVO + { + var tex:TextureVO; + + tex = new TextureVO(); + + while (this._byteData.position < end) { + var cid:number /*uint*/; + var len:number /*uint*/; + + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + + switch (cid) { + case 0xA300: + tex.url = this.readNulTermstring(); + break; + + default: + // Skip this unknown texture sub-chunk + this._byteData.position += (len - 6); + break; + } + } + + this._textures[tex.url] = tex; + this._pAddDependency(tex.url, new URLRequest(tex.url)); + + return tex; + } + + private parseVertexList():void + { + var i:number /*uint*/; + var len:number /*uint*/; + var count:number /*uint*/; + + count = this._byteData.readUnsignedShort(); + this._cur_obj.verts = new Array(count*3); + + i = 0; + len = this._cur_obj.verts.length; + while (i < len) { + var x:number, y:number, z:number; + + x = this._byteData.readFloat(); + y = this._byteData.readFloat(); + z = this._byteData.readFloat(); + + this._cur_obj.verts[i++] = x; + this._cur_obj.verts[i++] = z; + this._cur_obj.verts[i++] = y; + } + } + + private parseFaceList():void + { + var i:number /*uint*/; + var len:number /*uint*/; + var count:number /*uint*/; + + count = this._byteData.readUnsignedShort(); + this._cur_obj.indices = new Array(count*3) /*uint*/; + + i = 0; + len = this._cur_obj.indices.length; + while (i < len) { + var i0:number /*uint*/, i1:number /*uint*/, i2:number /*uint*/; + + i0 = this._byteData.readUnsignedShort(); + i1 = this._byteData.readUnsignedShort(); + i2 = this._byteData.readUnsignedShort(); + + this._cur_obj.indices[i++] = i0; + this._cur_obj.indices[i++] = i2; + this._cur_obj.indices[i++] = i1; + + // Skip "face info", irrelevant in Away3D + this._byteData.position += 2; + } + + this._cur_obj.smoothingGroups = new Array(count) /*uint*/; + } + + private parseSmoothingGroups():void + { + var len:number /*uint*/ = this._cur_obj.indices.length/3; + var i:number /*uint*/ = 0; + while (i < len) { + this._cur_obj.smoothingGroups[i] = this._byteData.readUnsignedInt(); + i++; + } + } + + private parseUVList():void + { + var i:number /*uint*/; + var len:number /*uint*/; + var count:number /*uint*/; + + count = this._byteData.readUnsignedShort(); + this._cur_obj.uvs = new Array(count*2); + + i = 0; + len = this._cur_obj.uvs.length; + while (i < len) { + this._cur_obj.uvs[i++] = this._byteData.readFloat(); + this._cur_obj.uvs[i++] = 1.0 - this._byteData.readFloat(); + } + } + + private parseFaceMaterialList():void + { + var mat:string; + var count:number /*uint*/; + var i:number /*uint*/; + var faces:Array /*uint*/; + + mat = this.readNulTermstring(); + count = this._byteData.readUnsignedShort(); + + faces = new Array(count) /*uint*/; + i = 0; + while (i < faces.length) + faces[i++] = this._byteData.readUnsignedShort(); + + this._cur_obj.materials.push(mat); + this._cur_obj.materialFaces[mat] = faces; + } + + private parseObjectAnimation(end:number):void + { + var vo:ObjectVO; + var obj:DisplayObjectContainer; + var pivot:Vector3D; + var name:string; + var hier:number /*uint*/; + + // Pivot defaults to origin + pivot = new Vector3D; + + while (this._byteData.position < end) { + var cid:number /*uint*/; + var len:number /*uint*/; + + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + + switch (cid) { + case 0xb010: // Name/hierarchy + name = this.readNulTermstring(); + this._byteData.position += 4; + hier = this._byteData.readShort(); + break; + + case 0xb013: // Pivot + pivot.x = this._byteData.readFloat(); + pivot.z = this._byteData.readFloat(); + pivot.y = this._byteData.readFloat(); + break; + + default: + this._byteData.position += (len - 6); + break; + } + } + + // If name is "$$$DUMMY" this is an empty object (e.g. a container) + // and will be ignored in this version of the parser + // TODO: Implement containers in 3DS parser. + if (name != '$$$DUMMY' && this._unfinalized_objects.hasOwnProperty(name)) { + vo = this._unfinalized_objects[name]; + obj = this.constructObject(vo, pivot); + + if (obj) { + //add to the content property + ( this._pContent).addChild(obj); + + this._pFinalizeAsset(obj, vo.name); + } + + + delete this._unfinalized_objects[name]; + } + } + + private constructObject(obj:ObjectVO, pivot:Vector3D = null):DisplayObjectContainer + { + if (obj.type == AssetType.MESH) { + var i:number /*uint*/; + var sub:TriangleSubGeometry; + var geom:Geometry; + var mat:MaterialBase; + var mesh:Mesh; + var mtx:Matrix3D; + var vertices:Array; + var faces:Array; + + if (obj.materials.length > 1) + console.log("The Away3D 3DS parser does not support multiple materials per mesh at this point."); + + // Ignore empty objects + if (!obj.indices || obj.indices.length == 0) + return null; + + vertices = new Array(obj.verts.length/3); + faces = new Array(obj.indices.length/3); + + this.prepareData(vertices, faces, obj); + + if (this._useSmoothingGroups) + this.applySmoothGroups(vertices, faces); + + obj.verts = new Array(vertices.length*3); + for (i = 0; i < vertices.length; i++) { + obj.verts[i*3] = vertices[i].x; + obj.verts[i*3 + 1] = vertices[i].y; + obj.verts[i*3 + 2] = vertices[i].z; + } + obj.indices = new Array(faces.length*3) /*uint*/; + + for (i = 0; i < faces.length; i++) { + obj.indices[i*3] = faces[i].a; + obj.indices[i*3 + 1] = faces[i].b; + obj.indices[i*3 + 2] = faces[i].c; + } + + if (obj.uvs) { + // If the object had UVs to start with, use UVs generated by + // smoothing group splitting algorithm. Otherwise those UVs + // will be nonsense and should be skipped. + obj.uvs = new Array(vertices.length*2); + for (i = 0; i < vertices.length; i++) { + obj.uvs[i*2] = vertices[i].u; + obj.uvs[i*2 + 1] = vertices[i].v; + } + } + + geom = new Geometry(); + + // Construct sub-geometries (potentially splitting buffers) + // and add them to geometry. + sub = new TriangleSubGeometry(true); + sub.updateIndices(obj.indices); + sub.updatePositions(obj.verts); + sub.updateUVs(obj.uvs); + + geom.addSubGeometry(sub); + + if (obj.materials.length > 0) { + var mname:string; + mname = obj.materials[0]; + mat = this._materials[mname].material; + } + + // Apply pivot translation to geometry if a pivot was + // found while parsing the keyframe chunk earlier. + if (pivot) { + if (obj.transform) { + // If a transform was found while parsing the + // object chunk, use it to find the local pivot vector + var dat:Array = obj.transform.concat(); + dat[12] = 0; + dat[13] = 0; + dat[14] = 0; + mtx = new Matrix3D(dat); + pivot = mtx.transformVector(pivot); + } + + pivot.scaleBy(-1); + + mtx = new Matrix3D(); + mtx.appendTranslation(pivot.x, pivot.y, pivot.z); + geom.applyTransformation(mtx); + } + + // Apply transformation to geometry if a transformation + // was found while parsing the object chunk earlier. + if (obj.transform) { + mtx = new Matrix3D(obj.transform); + mtx.invert(); + geom.applyTransformation(mtx); + } + + // Final transform applied to geometry. Finalize the geometry, + // which will no longer be modified after this point. + this._pFinalizeAsset(geom, obj.name.concat('_geom')); + + // Build mesh and return it + mesh = new Mesh(geom, mat); + mesh.transform.matrix3D = new Matrix3D(obj.transform); + return mesh; + } + + // If reached, unknown + return null; + } + + private prepareData(vertices:Array, faces:Array, obj:ObjectVO):void + { + // convert raw ObjectVO's data to structured VertexVO and FaceVO + var i:number /*int*/; + var j:number /*int*/; + var k:number /*int*/; + var len:number /*int*/ = obj.verts.length; + for (i = 0, j = 0, k = 0; i < len;) { + var v:VertexVO = new VertexVO; + v.x = obj.verts[i++]; + v.y = obj.verts[i++]; + v.z = obj.verts[i++]; + if (obj.uvs) { + v.u = obj.uvs[j++]; + v.v = obj.uvs[j++]; + } + vertices[k++] = v; + } + len = obj.indices.length; + for (i = 0, k = 0; i < len;) { + var f:FaceVO = new FaceVO(); + f.a = obj.indices[i++]; + f.b = obj.indices[i++]; + f.c = obj.indices[i++]; + f.smoothGroup = obj.smoothingGroups[k] || 0; + faces[k++] = f; + } + } + + private applySmoothGroups(vertices:Array, faces:Array):void + { + // clone vertices according to following rule: + // clone if vertex's in faces from groups 1+2 and 3 + // don't clone if vertex's in faces from groups 1+2, 3 and 1+3 + + var i:number /*int*/; + var j:number /*int*/; + var k:number /*int*/; + var l:number /*int*/; + var len:number /*int*/; + var numVerts:number /*uint*/ = vertices.length; + var numFaces:number /*uint*/ = faces.length; + + // extract groups data for vertices + var vGroups:Array> /*uint*/ = new Array>(numVerts) /*uint*/; + for (i = 0; i < numVerts; i++) + vGroups[i] = new Array() /*uint*/; + for (i = 0; i < numFaces; i++) { + var face:FaceVO = faces[i]; + for (j = 0; j < 3; j++) { + var groups:Array /*uint*/ = vGroups[(j == 0)? face.a : ((j == 1)? face.b : face.c)]; + var group:number /*uint*/ = face.smoothGroup; + for (k = groups.length - 1; k >= 0; k--) { + if ((group & groups[k]) > 0) { + group |= groups[k]; + groups.splice(k, 1); + k = groups.length - 1; + } + } + groups.push(group); + } + } + // clone vertices + var vClones:Array> /*uint*/ = new Array>(numVerts) /*uint*/; + for (i = 0; i < numVerts; i++) { + if ((len = vGroups[i].length) < 1) + continue; + var clones:Array /*uint*/ = new Array(len) /*uint*/; + vClones[i] = clones; + clones[0] = i; + var v0:VertexVO = vertices[i]; + for (j = 1; j < len; j++) { + var v1:VertexVO = new VertexVO; + v1.x = v0.x; + v1.y = v0.y; + v1.z = v0.z; + v1.u = v0.u; + v1.v = v0.v; + clones[j] = vertices.length; + vertices.push(v1); + } + } + numVerts = vertices.length; + + for (i = 0; i < numFaces; i++) { + face = faces[i]; + group = face.smoothGroup; + for (j = 0; j < 3; j++) { + k = (j == 0)? face.a : ((j == 1)? face.b : face.c); + groups = vGroups[k]; + len = groups.length; + clones = vClones[k]; + for (l = 0; l < len; l++) { + if (((group == 0) && (groups[l] == 0)) || ((group & groups[l]) > 0)) { + var index:number /*uint*/ = clones[l]; + if (group == 0) { + // vertex is unique if no smoothGroup found + groups.splice(l, 1); + clones.splice(l, 1); + } + if (j == 0) + face.a = index; else if (j == 1) + face.b = index; else + face.c = index; + l = len; + } + } + } + } + } + + private finalizeCurrentMaterial():void + { + var mat:TriangleMethodMaterial; + + if (this._cur_mat.colorMap) + mat = new TriangleMethodMaterial(this._cur_mat.colorMap.texture || DefaultMaterialManager.getDefaultTexture()); + else + mat = new TriangleMethodMaterial(this._cur_mat.ambientColor); + + mat.diffuseColor = this._cur_mat.diffuseColor; + mat.specularColor = this._cur_mat.specularColor; + + if (this.materialMode >= 2) + mat.materialMode = TriangleMaterialMode.MULTI_PASS + + mat.bothSides = this._cur_mat.twoSided; + + this._pFinalizeAsset(mat, this._cur_mat.name); + + this._materials[this._cur_mat.name] = this._cur_mat; + this._cur_mat.material = mat; + + this._cur_mat = null; + } + + private readNulTermstring():string + { + var chr:number /*int*/; + var str:string = ""; + + while ((chr = this._byteData.readUnsignedByte()) > 0) + str += String.fromCharCode(chr); + + return str; + } + + private readTransform():Array + { + var data:Array; + + data = new Array(16); + + // X axis + data[0] = this._byteData.readFloat(); // X + data[2] = this._byteData.readFloat(); // Z + data[1] = this._byteData.readFloat(); // Y + data[3] = 0; + + // Z axis + data[8] = this._byteData.readFloat(); // X + data[10] = this._byteData.readFloat(); // Z + data[9] = this._byteData.readFloat(); // Y + data[11] = 0; + + // Y Axis + data[4] = this._byteData.readFloat(); // X + data[6] = this._byteData.readFloat(); // Z + data[5] = this._byteData.readFloat(); // Y + data[7] = 0; + + // Translation + data[12] = this._byteData.readFloat(); // X + data[14] = this._byteData.readFloat(); // Z + data[13] = this._byteData.readFloat(); // Y + data[15] = 1; + + return data; + } + + private readColor():number /*int*/ + { + var cid:number /*int*/; + var len:number /*int*/; + var r:number /*int*/, g:number /*int*/, b:number /*int*/; + + cid = this._byteData.readUnsignedShort(); + len = this._byteData.readUnsignedInt(); + + switch (cid) { + case 0x0010: // Floats + r = this._byteData.readFloat()*255; + g = this._byteData.readFloat()*255; + b = this._byteData.readFloat()*255; + break; + case 0x0011: // 24-bit color + r = this._byteData.readUnsignedByte(); + g = this._byteData.readUnsignedByte(); + b = this._byteData.readUnsignedByte(); + break; + default: + this._byteData.position += (len - 6); + break; + } + + return (r << 16) | (g << 8) | b; + } +} + +export = Max3DSParser; + + diff --git a/lib/parsers/OBJParser.js b/lib/parsers/OBJParser.js new file mode 100755 index 000000000..c5d26b38d --- /dev/null +++ b/lib/parsers/OBJParser.js @@ -0,0 +1,911 @@ +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 DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +var ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +var ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +var DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +var SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); +/** + * OBJParser provides a parser for the OBJ data type. + */ +var OBJParser = (function (_super) { + __extends(OBJParser, _super); + /** + * Creates a new OBJParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + function OBJParser(scale) { + if (scale === void 0) { scale = 1; } + _super.call(this, URLLoaderDataFormat.TEXT); + this._mtlLibLoaded = true; + this._activeMaterialID = ""; + this._scale = scale; + } + Object.defineProperty(OBJParser.prototype, "scale", { + /** + * Scaling factor applied directly to vertices data + * @param value The scaling factor. + */ + set: function (value) { + this._scale = value; + }, + enumerable: true, + configurable: true + }); + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + OBJParser.supportsType = function (extension) { + extension = extension.toLowerCase(); + return extension == "obj"; + }; + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + OBJParser.supportsData = function (data) { + var content = ParserUtils.toString(data); + var hasV = false; + var hasF = false; + if (content) { + hasV = content.indexOf("\nv ") != -1; + hasF = content.indexOf("\nf ") != -1; + } + return hasV && hasF; + }; + /** + * @inheritDoc + */ + OBJParser.prototype._iResolveDependency = function (resourceDependency) { + if (resourceDependency.id == 'mtl') { + var str = ParserUtils.toString(resourceDependency.data); + this.parseMtl(str); + } + else { + var asset; + if (resourceDependency.assets.length != 1) { + return; + } + asset = resourceDependency.assets[0]; + if (asset.assetType == AssetType.TEXTURE) { + var lm = new LoadedMaterial(); + lm.materialID = resourceDependency.id; + lm.texture = asset; + this._materialLoaded.push(lm); + if (this._meshes.length > 0) { + this.applyMaterial(lm); + } + } + } + }; + /** + * @inheritDoc + */ + OBJParser.prototype._iResolveDependencyFailure = function (resourceDependency) { + if (resourceDependency.id == "mtl") { + this._mtlLib = false; + this._mtlLibLoaded = false; + } + else { + var lm = new LoadedMaterial(); + lm.materialID = resourceDependency.id; + this._materialLoaded.push(lm); + } + if (this._meshes.length > 0) + this.applyMaterial(lm); + }; + /** + * @inheritDoc + */ + OBJParser.prototype._pProceedParsing = function () { + var line; + var creturn = String.fromCharCode(10); + var trunk; + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + // Merge linebreaks that are immediately preceeded by + // the "escape" backward slash into single lines. + this._textData = this._textData.replace(/\\[\r\n]+\s*/gm, ' '); + } + if (this._textData.indexOf(creturn) == -1) + creturn = String.fromCharCode(13); + if (!this._startedParsing) { + this._startedParsing = true; + this._vertices = new Array(); + this._vertexNormals = new Array(); + this._materialIDs = new Array(); + this._materialLoaded = new Array(); + this._meshes = new Array(); + this._uvs = new Array(); + this._stringLength = this._textData.length; + this._charIndex = this._textData.indexOf(creturn, 0); + this._oldIndex = 0; + this._objects = new Array(); + this._objectIndex = 0; + } + while (this._charIndex < this._stringLength && this._pHasTime()) { + this._charIndex = this._textData.indexOf(creturn, this._oldIndex); + if (this._charIndex == -1) + this._charIndex = this._stringLength; + line = this._textData.substring(this._oldIndex, this._charIndex); + line = line.split('\r').join(""); + line = line.replace(" ", " "); + trunk = line.split(" "); + this._oldIndex = this._charIndex + 1; + this.parseLine(trunk); + // If whatever was parsed on this line resulted in the + // parsing being paused to retrieve dependencies, break + // here and do not continue parsing until un-paused. + if (this.parsingPaused) { + return ParserBase.MORE_TO_PARSE; + } + } + if (this._charIndex >= this._stringLength) { + if (this._mtlLib && !this._mtlLibLoaded) { + return ParserBase.MORE_TO_PARSE; + } + this.translate(); + this.applyMaterials(); + return ParserBase.PARSING_DONE; + } + return ParserBase.MORE_TO_PARSE; + }; + OBJParser.prototype._pStartParsing = function (frameLimit) { + _super.prototype._pStartParsing.call(this, frameLimit); + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + }; + /** + * Parses a single line in the OBJ file. + */ + OBJParser.prototype.parseLine = function (trunk) { + switch (trunk[0]) { + case "mtllib": + this._mtlLib = true; + this._mtlLibLoaded = false; + this.loadMtl(trunk[1]); + break; + case "g": + this.createGroup(trunk); + break; + case "o": + this.createObject(trunk); + break; + case "usemtl": + if (this._mtlLib) { + if (!trunk[1]) + trunk[1] = "def000"; + this._materialIDs.push(trunk[1]); + this._activeMaterialID = trunk[1]; + if (this._currentGroup) + this._currentGroup.materialID = this._activeMaterialID; + } + break; + case "v": + this.parseVertex(trunk); + break; + case "vt": + this.parseUV(trunk); + break; + case "vn": + this.parseVertexNormal(trunk); + break; + case "f": + this.parseFace(trunk); + } + }; + /** + * Converts the parsed data into an Away3D scenegraph structure + */ + OBJParser.prototype.translate = function () { + for (var objIndex = 0; objIndex < this._objects.length; ++objIndex) { + var groups = this._objects[objIndex].groups; + var numGroups = groups.length; + var materialGroups; + var numMaterialGroups; + var geometry; + var mesh; + var m; + var sm; + var bmMaterial; + for (var g = 0; g < numGroups; ++g) { + geometry = new Geometry(); + materialGroups = groups[g].materialGroups; + numMaterialGroups = materialGroups.length; + for (m = 0; m < numMaterialGroups; ++m) + this.translateMaterialGroup(materialGroups[m], geometry); + if (geometry.subGeometries.length == 0) + continue; + // Finalize and force type-based name + this._pFinalizeAsset(geometry); //, ""); + bmMaterial = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + //check for multipass + if (this.materialMode >= 2) + bmMaterial.materialMode = TriangleMaterialMode.MULTI_PASS; + mesh = new Mesh(geometry, bmMaterial); + if (this._objects[objIndex].name) { + // this is a full independent object ('o' tag in OBJ file) + mesh.name = this._objects[objIndex].name; + } + else if (groups[g].name) { + // this is a group so the sub groups contain the actual mesh object names ('g' tag in OBJ file) + mesh.name = groups[g].name; + } + else { + // No name stored. Use empty string which will force it + // to be overridden by finalizeAsset() to type default. + mesh.name = ""; + } + this._meshes.push(mesh); + if (groups[g].materialID != "") + bmMaterial.name = groups[g].materialID + "~" + mesh.name; + else + bmMaterial.name = this._lastMtlID + "~" + mesh.name; + if (mesh.subMeshes.length > 1) { + for (sm = 1; sm < mesh.subMeshes.length; ++sm) + mesh.subMeshes[sm].material = bmMaterial; + } + //add to the content property + this._pContent.addChild(mesh); + this._pFinalizeAsset(mesh); + } + } + }; + /** + * Translates an obj's material group to a subgeometry. + * @param materialGroup The material group data to convert. + * @param geometry The Geometry to contain the converted SubGeometry. + */ + OBJParser.prototype.translateMaterialGroup = function (materialGroup, geometry) { + var faces = materialGroup.faces; + var face; + var numFaces = faces.length; + var numVerts; + var sub; + var vertices = new Array(); + var uvs = new Array(); + var normals = new Array(); + var indices = new Array(); + this._realIndices = []; + this._vertexIndex = 0; + var j; + for (var i = 0; i < numFaces; ++i) { + face = faces[i]; + numVerts = face.indexIds.length - 1; + for (j = 1; j < numVerts; ++j) { + this.translateVertexData(face, j, vertices, uvs, indices, normals); + this.translateVertexData(face, 0, vertices, uvs, indices, normals); + this.translateVertexData(face, j + 1, vertices, uvs, indices, normals); + } + } + if (vertices.length > 0) { + sub = new TriangleSubGeometry(true); + sub.autoDeriveNormals = normals.length ? false : true; + sub.updateIndices(indices); + sub.updatePositions(vertices); + sub.updateVertexNormals(normals); + sub.updateUVs(uvs); + geometry.addSubGeometry(sub); + } + }; + OBJParser.prototype.translateVertexData = function (face, vertexIndex, vertices, uvs, indices /*uint*/, normals) { + var index; + var vertex; + var vertexNormal; + var uv; + if (!this._realIndices[face.indexIds[vertexIndex]]) { + index = this._vertexIndex; + this._realIndices[face.indexIds[vertexIndex]] = ++this._vertexIndex; + vertex = this._vertices[face.vertexIndices[vertexIndex] - 1]; + vertices.push(vertex.x * this._scale, vertex.y * this._scale, vertex.z * this._scale); + if (face.normalIndices.length > 0) { + vertexNormal = this._vertexNormals[face.normalIndices[vertexIndex] - 1]; + normals.push(vertexNormal.x, vertexNormal.y, vertexNormal.z); + } + if (face.uvIndices.length > 0) { + try { + uv = this._uvs[face.uvIndices[vertexIndex] - 1]; + uvs.push(uv.u, uv.v); + } + catch (e) { + switch (vertexIndex) { + case 0: + uvs.push(0, 1); + break; + case 1: + uvs.push(.5, 0); + break; + case 2: + uvs.push(1, 1); + } + } + } + } + else { + index = this._realIndices[face.indexIds[vertexIndex]] - 1; + } + indices.push(index); + }; + /** + * Creates a new object group. + * @param trunk The data block containing the object tag and its parameters + */ + OBJParser.prototype.createObject = function (trunk) { + this._currentGroup = null; + this._currentMaterialGroup = null; + this._objects.push(this._currentObject = new ObjectGroup()); + if (trunk) + this._currentObject.name = trunk[1]; + }; + /** + * Creates a new group. + * @param trunk The data block containing the group tag and its parameters + */ + OBJParser.prototype.createGroup = function (trunk) { + if (!this._currentObject) + this.createObject(null); + this._currentGroup = new Group(); + this._currentGroup.materialID = this._activeMaterialID; + if (trunk) + this._currentGroup.name = trunk[1]; + this._currentObject.groups.push(this._currentGroup); + this.createMaterialGroup(null); + }; + /** + * Creates a new material group. + * @param trunk The data block containing the material tag and its parameters + */ + OBJParser.prototype.createMaterialGroup = function (trunk) { + this._currentMaterialGroup = new MaterialGroup(); + if (trunk) + this._currentMaterialGroup.url = trunk[1]; + this._currentGroup.materialGroups.push(this._currentMaterialGroup); + }; + /** + * Reads the next vertex coordinates. + * @param trunk The data block containing the vertex tag and its parameters + */ + OBJParser.prototype.parseVertex = function (trunk) { + //for the very rare cases of other delimiters/charcodes seen in some obj files + var v1, v2, v3; + if (trunk.length > 4) { + var nTrunk = []; + var val; + for (var i = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + v1 = nTrunk[0]; + v2 = nTrunk[1]; + v3 = -nTrunk[2]; + this._vertices.push(new Vertex(v1, v2, v3)); + } + else { + v1 = parseFloat(trunk[1]); + v2 = parseFloat(trunk[2]); + v3 = -parseFloat(trunk[3]); + this._vertices.push(new Vertex(v1, v2, v3)); + } + }; + /** + * Reads the next uv coordinates. + * @param trunk The data block containing the uv tag and its parameters + */ + OBJParser.prototype.parseUV = function (trunk) { + if (trunk.length > 3) { + var nTrunk = []; + var val; + for (var i = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + this._uvs.push(new UV(nTrunk[0], 1 - nTrunk[1])); + } + else { + this._uvs.push(new UV(parseFloat(trunk[1]), 1 - parseFloat(trunk[2]))); + } + }; + /** + * Reads the next vertex normal coordinates. + * @param trunk The data block containing the vertex normal tag and its parameters + */ + OBJParser.prototype.parseVertexNormal = function (trunk) { + if (trunk.length > 4) { + var nTrunk = []; + var val; + for (var i = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + this._vertexNormals.push(new Vertex(nTrunk[0], nTrunk[1], -nTrunk[2])); + } + else { + this._vertexNormals.push(new Vertex(parseFloat(trunk[1]), parseFloat(trunk[2]), -parseFloat(trunk[3]))); + } + }; + /** + * Reads the next face's indices. + * @param trunk The data block containing the face tag and its parameters + */ + OBJParser.prototype.parseFace = function (trunk) { + var len = trunk.length; + var face = new FaceData(); + if (!this._currentGroup) { + this.createGroup(null); + } + var indices; + for (var i = 1; i < len; ++i) { + if (trunk[i] == "") { + continue; + } + indices = trunk[i].split("/"); + face.vertexIndices.push(this.parseIndex(parseInt(indices[0]), this._vertices.length)); + if (indices[1] && String(indices[1]).length > 0) + face.uvIndices.push(this.parseIndex(parseInt(indices[1]), this._uvs.length)); + if (indices[2] && String(indices[2]).length > 0) + face.normalIndices.push(this.parseIndex(parseInt(indices[2]), this._vertexNormals.length)); + face.indexIds.push(trunk[i]); + } + this._currentMaterialGroup.faces.push(face); + }; + /** + * This is a hack around negative face coords + */ + OBJParser.prototype.parseIndex = function (index, length) { + if (index < 0) + return index + length + 1; + else + return index; + }; + OBJParser.prototype.parseMtl = function (data) { + var materialDefinitions = data.split('newmtl'); + var lines; + var trunk; + var j; + var basicSpecularMethod; + var useSpecular; + var useColor; + var diffuseColor; + var color; + var specularColor; + var specular; + var alpha; + var mapkd; + for (var i = 0; i < materialDefinitions.length; ++i) { + lines = (materialDefinitions[i].split('\r')).join("").split('\n'); + //lines = (materialDefinitions[i].split('\r') as Array).join("").split('\n'); + if (lines.length == 1) + lines = materialDefinitions[i].split(String.fromCharCode(13)); + diffuseColor = color = specularColor = 0xFFFFFF; + specular = 0; + useSpecular = false; + useColor = false; + alpha = 1; + mapkd = ""; + for (j = 0; j < lines.length; ++j) { + lines[j] = lines[j].replace(/\s+$/, ""); + if (lines[j].substring(0, 1) != "#" && (j == 0 || lines[j] != "")) { + trunk = lines[j].split(" "); + if (String(trunk[0]).charCodeAt(0) == 9 || String(trunk[0]).charCodeAt(0) == 32) + trunk[0] = trunk[0].substring(1, trunk[0].length); + if (j == 0) { + this._lastMtlID = trunk.join(""); + this._lastMtlID = (this._lastMtlID == "") ? "def000" : this._lastMtlID; + } + else { + switch (trunk[0]) { + case "Ka": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) + color = trunk[1] * 255 << 16 | trunk[2] * 255 << 8 | trunk[3] * 255; + break; + case "Ks": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) { + specularColor = trunk[1] * 255 << 16 | trunk[2] * 255 << 8 | trunk[3] * 255; + useSpecular = true; + } + break; + case "Ns": + if (trunk[1] && !isNaN(Number(trunk[1]))) + specular = Number(trunk[1]) * 0.001; + if (specular == 0) + useSpecular = false; + break; + case "Kd": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) { + diffuseColor = trunk[1] * 255 << 16 | trunk[2] * 255 << 8 | trunk[3] * 255; + useColor = true; + } + break; + case "tr": + case "d": + if (trunk[1] && !isNaN(Number(trunk[1]))) + alpha = Number(trunk[1]); + break; + case "map_Kd": + mapkd = this.parseMapKdString(trunk); + mapkd = mapkd.replace(/\\/g, "/"); + } + } + } + } + if (mapkd != "") { + if (useSpecular) { + basicSpecularMethod = new SpecularBasicMethod(); + basicSpecularMethod.specularColor = specularColor; + basicSpecularMethod.specular = specular; + var specularData = new SpecularData(); + specularData.alpha = alpha; + specularData.basicSpecularMethod = basicSpecularMethod; + specularData.materialID = this._lastMtlID; + if (!this._materialSpecularData) + this._materialSpecularData = new Array(); + this._materialSpecularData.push(specularData); + } + this._pAddDependency(this._lastMtlID, new URLRequest(mapkd)); + } + else if (useColor && !isNaN(color)) { + var lm = new LoadedMaterial(); + lm.materialID = this._lastMtlID; + if (alpha == 0) + console.log("Warning: an alpha value of 0 was found in mtl color tag (Tr or d) ref:" + this._lastMtlID + ", mesh(es) using it will be invisible!"); + var cm; + if (this.materialMode < 2) { + cm = new TriangleMethodMaterial(color); + var colorMat = cm; + colorMat.alpha = alpha; + colorMat.diffuseColor = diffuseColor; + colorMat.repeat = true; + if (useSpecular) { + colorMat.specularColor = specularColor; + colorMat.specular = specular; + } + } + else { + cm = new TriangleMethodMaterial(color); + cm.materialMode = TriangleMaterialMode.MULTI_PASS; + var colorMultiMat = cm; + colorMultiMat.diffuseColor = diffuseColor; + colorMultiMat.repeat = true; + if (useSpecular) { + colorMultiMat.specularColor = specularColor; + colorMultiMat.specular = specular; + } + } + lm.cm = cm; + this._materialLoaded.push(lm); + if (this._meshes.length > 0) + this.applyMaterial(lm); + } + } + this._mtlLibLoaded = true; + }; + OBJParser.prototype.parseMapKdString = function (trunk) { + var url = ""; + var i; + var breakflag; + for (i = 1; i < trunk.length;) { + switch (trunk[i]) { + case "-blendu": + case "-blendv": + case "-cc": + case "-clamp": + case "-texres": + i += 2; //Skip ahead 1 attribute + break; + case "-mm": + i += 3; //Skip ahead 2 attributes + break; + case "-o": + case "-s": + case "-t": + i += 4; //Skip ahead 3 attributes + continue; + default: + breakflag = true; + break; + } + if (breakflag) + break; + } + for (i; i < trunk.length; i++) { + url += trunk[i]; + url += " "; + } + //Remove the extraneous space and/or newline from the right side + url = url.replace(/\s+$/, ""); + return url; + }; + OBJParser.prototype.loadMtl = function (mtlurl) { + // Add raw-data dependency to queue and load dependencies now, + // which will pause the parsing in the meantime. + this._pAddDependency('mtl', new URLRequest(mtlurl), true); + this._pPauseAndRetrieveDependencies(); // + }; + OBJParser.prototype.applyMaterial = function (lm) { + var decomposeID; + var mesh; + var tm; + var j; + var specularData; + for (var i = 0; i < this._meshes.length; ++i) { + mesh = this._meshes[i]; + decomposeID = mesh.material.name.split("~"); + if (decomposeID[0] == lm.materialID) { + if (lm.cm) { + if (mesh.material) + mesh.material = null; + mesh.material = lm.cm; + } + else if (lm.texture) { + if (this.materialMode < 2) { + tm = mesh.material; + tm.texture = lm.texture; + tm.color = lm.color; + tm.alpha = lm.alpha; + tm.repeat = true; + if (lm.specularMethod) { + // By setting the specularMethod property to null before assigning + // the actual method instance, we avoid having the properties of + // the new method being overridden with the settings from the old + // one, which is default behavior of the setter. + tm.specularMethod = null; + tm.specularMethod = lm.specularMethod; + } + else if (this._materialSpecularData) { + for (j = 0; j < this._materialSpecularData.length; ++j) { + specularData = this._materialSpecularData[j]; + if (specularData.materialID == lm.materialID) { + tm.specularMethod = null; // Prevent property overwrite (see above) + tm.specularMethod = specularData.basicSpecularMethod; + tm.color = specularData.color; + tm.alpha = specularData.alpha; + break; + } + } + } + } + else { + tm = mesh.material; + tm.materialMode = TriangleMaterialMode.MULTI_PASS; + tm.texture = lm.texture; + tm.color = lm.color; + tm.repeat = true; + if (lm.specularMethod) { + // By setting the specularMethod property to null before assigning + // the actual method instance, we avoid having the properties of + // the new method being overridden with the settings from the old + // one, which is default behavior of the setter. + tm.specularMethod = null; + tm.specularMethod = lm.specularMethod; + } + else if (this._materialSpecularData) { + for (j = 0; j < this._materialSpecularData.length; ++j) { + specularData = this._materialSpecularData[j]; + if (specularData.materialID == lm.materialID) { + tm.specularMethod = null; // Prevent property overwrite (see above) + tm.specularMethod = specularData.basicSpecularMethod; + tm.color = specularData.color; + break; + } + } + } + } + } + mesh.material.name = decomposeID[1] ? decomposeID[1] : decomposeID[0]; + this._meshes.splice(i, 1); + --i; + } + } + if (lm.cm || tm) + this._pFinalizeAsset(lm.cm || tm); + }; + OBJParser.prototype.applyMaterials = function () { + if (this._materialLoaded.length == 0) + return; + for (var i = 0; i < this._materialLoaded.length; ++i) + this.applyMaterial(this._materialLoaded[i]); + }; + return OBJParser; +})(ParserBase); +var ObjectGroup = (function () { + function ObjectGroup() { + this.groups = new Array(); + } + return ObjectGroup; +})(); +var Group = (function () { + function Group() { + this.materialGroups = new Array(); + } + return Group; +})(); +var MaterialGroup = (function () { + function MaterialGroup() { + this.faces = new Array(); + } + return MaterialGroup; +})(); +var SpecularData = (function () { + function SpecularData() { + this.color = 0xFFFFFF; + this.alpha = 1; + } + return SpecularData; +})(); +var LoadedMaterial = (function () { + function LoadedMaterial() { + this.color = 0xFFFFFF; + this.alpha = 1; + } + return LoadedMaterial; +})(); +var FaceData = (function () { + function FaceData() { + this.vertexIndices = new Array(); + this.uvIndices = new Array(); + this.normalIndices = new Array(); + this.indexIds = new Array(); // used for real index lookups + } + return FaceData; +})(); +/** +* Texture coordinates value object. +*/ +var UV = (function () { + /** + * Creates a new UV object. + * + * @param u [optional] The horizontal coordinate of the texture value. Defaults to 0. + * @param v [optional] The vertical coordinate of the texture value. Defaults to 0. + */ + function UV(u, v) { + if (u === void 0) { u = 0; } + if (v === void 0) { v = 0; } + this._u = u; + this._v = v; + } + Object.defineProperty(UV.prototype, "v", { + /** + * Defines the vertical coordinate of the texture value. + */ + get: function () { + return this._v; + }, + set: function (value) { + this._v = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UV.prototype, "u", { + /** + * Defines the horizontal coordinate of the texture value. + */ + get: function () { + return this._u; + }, + set: function (value) { + this._u = value; + }, + enumerable: true, + configurable: true + }); + /** + * returns a new UV value Object + */ + UV.prototype.clone = function () { + return new UV(this._u, this._v); + }; + /** + * returns the value object as a string for trace/debug purpose + */ + UV.prototype.toString = function () { + return this._u + "," + this._v; + }; + return UV; +})(); +var Vertex = (function () { + /** + * Creates a new Vertex value object. + * + * @param x [optional] The x value. Defaults to 0. + * @param y [optional] The y value. Defaults to 0. + * @param z [optional] The z value. Defaults to 0. + * @param index [optional] The index value. Defaults is NaN. + */ + function Vertex(x, y, z, index) { + if (x === void 0) { x = 0; } + if (y === void 0) { y = 0; } + if (z === void 0) { z = 0; } + if (index === void 0) { index = 0; } + this._x = x; + this._y = y; + this._z = z; + this._index = index; + } + Object.defineProperty(Vertex.prototype, "index", { + get: function () { + return this._index; + }, + /** + * To define/store the index of value object + * @param ind The index + */ + set: function (ind) { + this._index = ind; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vertex.prototype, "x", { + /** + * To define/store the x value of the value object + * @param value The x value + */ + get: function () { + return this._x; + }, + set: function (value) { + this._x = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vertex.prototype, "y", { + /** + * To define/store the y value of the value object + * @param value The y value + */ + get: function () { + return this._y; + }, + set: function (value) { + this._y = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vertex.prototype, "z", { + /** + * To define/store the z value of the value object + * @param value The z value + */ + get: function () { + return this._z; + }, + set: function (value) { + this._z = value; + }, + enumerable: true, + configurable: true + }); + /** + * returns a new Vertex value Object + */ + Vertex.prototype.clone = function () { + return new Vertex(this._x, this._y, this._z); + }; + return Vertex; +})(); +module.exports = OBJParser; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvb2JqcGFyc2VyLnRzIl0sIm5hbWVzIjpbIk9CSlBhcnNlciIsIk9CSlBhcnNlci5jb25zdHJ1Y3RvciIsIk9CSlBhcnNlci5zY2FsZSIsIk9CSlBhcnNlci5zdXBwb3J0c1R5cGUiLCJPQkpQYXJzZXIuc3VwcG9ydHNEYXRhIiwiT0JKUGFyc2VyLl9pUmVzb2x2ZURlcGVuZGVuY3kiLCJPQkpQYXJzZXIuX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUiLCJPQkpQYXJzZXIuX3BQcm9jZWVkUGFyc2luZyIsIk9CSlBhcnNlci5fcFN0YXJ0UGFyc2luZyIsIk9CSlBhcnNlci5wYXJzZUxpbmUiLCJPQkpQYXJzZXIudHJhbnNsYXRlIiwiT0JKUGFyc2VyLnRyYW5zbGF0ZU1hdGVyaWFsR3JvdXAiLCJPQkpQYXJzZXIudHJhbnNsYXRlVmVydGV4RGF0YSIsIk9CSlBhcnNlci5jcmVhdGVPYmplY3QiLCJPQkpQYXJzZXIuY3JlYXRlR3JvdXAiLCJPQkpQYXJzZXIuY3JlYXRlTWF0ZXJpYWxHcm91cCIsIk9CSlBhcnNlci5wYXJzZVZlcnRleCIsIk9CSlBhcnNlci5wYXJzZVVWIiwiT0JKUGFyc2VyLnBhcnNlVmVydGV4Tm9ybWFsIiwiT0JKUGFyc2VyLnBhcnNlRmFjZSIsIk9CSlBhcnNlci5wYXJzZUluZGV4IiwiT0JKUGFyc2VyLnBhcnNlTXRsIiwiT0JKUGFyc2VyLnBhcnNlTWFwS2RTdHJpbmciLCJPQkpQYXJzZXIubG9hZE10bCIsIk9CSlBhcnNlci5hcHBseU1hdGVyaWFsIiwiT0JKUGFyc2VyLmFwcGx5TWF0ZXJpYWxzIiwiT2JqZWN0R3JvdXAiLCJPYmplY3RHcm91cC5jb25zdHJ1Y3RvciIsIkdyb3VwIiwiR3JvdXAuY29uc3RydWN0b3IiLCJNYXRlcmlhbEdyb3VwIiwiTWF0ZXJpYWxHcm91cC5jb25zdHJ1Y3RvciIsIlNwZWN1bGFyRGF0YSIsIlNwZWN1bGFyRGF0YS5jb25zdHJ1Y3RvciIsIkxvYWRlZE1hdGVyaWFsIiwiTG9hZGVkTWF0ZXJpYWwuY29uc3RydWN0b3IiLCJGYWNlRGF0YSIsIkZhY2VEYXRhLmNvbnN0cnVjdG9yIiwiVVYiLCJVVi5jb25zdHJ1Y3RvciIsIlVWLnYiLCJVVi51IiwiVVYuY2xvbmUiLCJVVi50b1N0cmluZyIsIlZlcnRleCIsIlZlcnRleC5jb25zdHJ1Y3RvciIsIlZlcnRleC5pbmRleCIsIlZlcnRleC54IiwiVmVydGV4LnkiLCJWZXJ0ZXgueiIsIlZlcnRleC5jbG9uZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxzQkFBc0IsV0FBYSxtREFBbUQsQ0FBQyxDQUFDO0FBQy9GLElBQU8sbUJBQW1CLFdBQWMsK0NBQStDLENBQUMsQ0FBQztBQUN6RixJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUl0RSxJQUFPLFNBQVMsV0FBZ0Isd0NBQXdDLENBQUMsQ0FBQztBQUUxRSxJQUFPLG1CQUFtQixXQUFjLDhDQUE4QyxDQUFDLENBQUM7QUFDeEYsSUFBTyxVQUFVLFdBQWdCLHFDQUFxQyxDQUFDLENBQUM7QUFDeEUsSUFBTyxJQUFJLFdBQWtCLCtCQUErQixDQUFDLENBQUM7QUFFOUQsSUFBTyxVQUFVLFdBQWdCLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxXQUFXLFdBQWdCLHFDQUFxQyxDQUFDLENBQUM7QUFJekUsSUFBTyxzQkFBc0IsV0FBYSwyREFBMkQsQ0FBQyxDQUFDO0FBQ3ZHLElBQU8sbUJBQW1CLFdBQWMsMERBQTBELENBQUMsQ0FBQztBQUNwRyxJQUFPLHNCQUFzQixXQUFhLHFEQUFxRCxDQUFDLENBQUM7QUFDakcsSUFBTyxvQkFBb0IsV0FBYyxtREFBbUQsQ0FBQyxDQUFDO0FBRTlGLEFBR0E7O0dBREc7SUFDRyxTQUFTO0lBQVNBLFVBQWxCQSxTQUFTQSxVQUFtQkE7SUEyQmpDQTs7OztPQUlHQTtJQUNIQSxTQWhDS0EsU0FBU0EsQ0FnQ0ZBLEtBQWdCQTtRQUFoQkMscUJBQWdCQSxHQUFoQkEsU0FBZ0JBO1FBRTNCQSxrQkFBTUEsbUJBQW1CQSxDQUFD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LENBQUNBO1lBQ3JEQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNuQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBR0EsSUFBSUEsS0FBS0EsRUFBZUEsQ0FBQ0E7WUFDekNBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3ZCQSxDQUFDQTtRQUVEQSxPQUFPQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxJQUFJQSxJQUFJQSxDQUFDQSxTQUFTQSxFQUFFQSxFQUFFQSxDQUFDQTtZQUNqRUEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsT0FBT0EsRUFBRUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0E7WUFFbEVBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFVBQVVBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO2dCQUN6QkEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0E7WUFFdENBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFNBQVNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLEVBQUVBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBO1lBQ2pFQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtZQUNqQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsSUFBSUEsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDL0JBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ3hCQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNyQ0EsSUFB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QUEsMERBRDBEQTtvQkFDMURBLElBQUlBLENBQUNBLElBQUlBLEdBQUdBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLElBQUlBLENBQUNBO2dCQUUxQ0EsQ0FBQ0E7Z0JBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLENBQUNBO29CQUUzQkEsQUFDQUEsK0ZBRCtGQTtvQkFDL0ZBLElBQUlBLENBQUNBLElBQUlBLEdBQUdBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBO2dCQUU1QkEsQ0FBQ0E7Z0JBQUNBLElBQUlBLENBQUNBLENBQUNBO29CQUNQQSxBQUVBQSx1REFGdURBO29CQUN2REEsdURBQXVEQTtvQkFDdkRBLElBQUlBLENBQUNBLElBQUlBLEdBQUdBLEVBQUVBLENBQUNBO2dCQUNoQkEsQ0FBQ0E7Z0JBRURBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO2dCQUV4QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsVUFBVUEsSUFBSUEsRUFBRUEsQ0FBQ0E7b0JBQzlCQSxVQUFVQSxDQUFDQSxJQUFJQSxHQUFHQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQTtnQkFBQ0EsSUFBSUE7b0JBQzlEQSxVQUFVQSxDQUFDQSxJQUFJQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxHQUFHQSxHQUFHQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQTtnQkFFckRBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUMvQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0Es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LEdBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLE1BQU1BLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLE1BQU1BLENBQUNBLENBQUNBLEdBQUNBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBO1lBRWhGQSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxNQUFNQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDbkNBLFlBQVlBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFdBQVdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO2dCQUN4RUEsT0FBT0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsWUFBWUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsWUFBWUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDOURBLENBQUNBO1lBRURBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUUvQkEsSUFBQUEsQ0FBQ0E7b0JBQ0FBLEVBQUVBLEdBQUdBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLFdBQVdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUNoREEsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBRXRCQSxDQUFFQTtnQkFBQUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBVEEsQ0FBQ0E7b0JBRUZBLE1BQU1BLENBQUNBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO3dCQUNyQkEsS0FBS0EsQ0FBQ0E7NEJBQ0xBLEdBQUdBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBOzRCQUNmQSxLQUFLQSxDQUFDQTt3QkFDUEEsS0FBS0EsQ0FBQ0E7NEJBQ0xBLEdBQUdBLENBQUNBLElBQUlBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBOzRCQUNoQkEsS0FBS0EsQ0FBQ0E7d0JBQ1BBLEtBQUtBLENBQUNBOzRCQUNMQSxHQUFHQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDakJBLENBQUNBO2dCQUNGQSxDQUFDQTtZQUVGQSxDQUFDQTtRQUVGQSxDQUFDQTtRQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNQQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUMzREEsQ0FBQ0E7UUFFREEsT0FBT0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7SUFDckJBLENBQUNBO0lBRURaOzs7T0FHR0E7SUFDS0EsZ0NBQVlBLEdBQXBCQSxVQUFxQkEsS0FBS0E7UUFFekJhLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxxQkFBcUJBLEdBQUdBLElBQUlBLENBQUNBO1FBQ2xDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxXQUFXQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUU1REEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0E7WUFDVEEsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsSUFBSUEsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7SUFDdENBLENBQUNBO0lBRURiOzs7T0FHR0E7SUFDS0EsK0JBQVdBLEdBQW5CQSxVQUFvQkEsS0FBS0E7UUFFeEJjLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBO1lBQ3hCQSxJQUFJQSxDQUFDQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUN6QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsS0FBS0EsRUFBRUEsQ0FBQ0E7UUFFakNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFVBQVVBLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0E7UUFFdkRBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBO1lBQ1RBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1FBQ3BDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxDQUFDQTtRQUVwREEsSUFBSUEsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtJQUNoQ0EsQ0FBQ0E7SUFFRGQ7OztPQUdHQTtJQUNLQSx1Q0FBbUJBLEdBQTNCQSxVQUE0QkEsS0FBS0E7UUFFaENlLElBQUlBLENBQUNBLHFCQUFxQkEsR0FBR0EsSUFBSUEsYUFBYUEsRUFBRUEsQ0FBQ0E7UUFDakRBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBO1lBQ1RBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsR0FBR0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDM0NBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLGNBQWNBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsQ0FBQ0E7SUFDcEVBLENBQUNBO0lBRURmOzs7T0FHR0E7SUFDS0EsK0JBQVdBLEdBQW5CQSxVQUFvQkEsS0FBS0E7UUFFeEJnQiw4RUFBOEVBO1FBRTlFQSxJQUFJQSxFQUFTQSxFQUFFQSxFQUFTQSxFQUFHQSxFQUFTQSxDQUFDQTtRQUNyQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdEJBLElBQUlBLE1BQU1BLEdBQUdBLEVBQUVBLENBQUNBO1lBQ2hCQSxJQUFJQSxHQUFVQSxDQUFDQTtZQUVmQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFVQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxNQUFNQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtnQkFDOUNBLEdBQUdBLEdBQUdBLFVBQVVBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO2dCQUMzQkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2ZBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ25CQSxDQUFDQTtZQUVEQSxFQUFFQSxHQUFZQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN4QkEsRUFBRUEsR0FBWUEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDeEJBLEVBQUVBLEdBQVlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ3pCQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxNQUFNQSxDQUFDQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUU3Q0EsQ0FBQ0E7UUFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7WUFDUEEsRUFBRUEsR0FBWUEsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDbkNBLEVBQUVBLEdBQVlBLFVBQVVBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBQ25DQSxFQUFFQSxHQUFZQSxDQUFDQSxV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QUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUV0RkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsTUFBTUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9DQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxRQUFRQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUU5RUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsTUFBTUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7Z0JBQy9DQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxRQUFRQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxFQUFFQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUU1RkEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDOUJBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLHFCQUFxQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7SUFDN0NBLENBQUNBO0lBRURuQjs7T0FFR0E7SUFDS0EsOEJBQVVBLEdBQWxCQSxVQUFtQkEsS0FBWUEsRUFBRUEsTUFBYUE7UUFFN0NvQixFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNiQSxNQUFNQSxDQUFDQSxLQUFLQSxHQUFHQSxNQUFNQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUFDQSxJQUFJQTtZQUMvQkEsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0E7SUFDZkEsQ0FBQ0E7SUFFT3BCLDRCQUFRQSxHQUFoQkEsVUFBaUJBLElBQVdBO1FBRTNCcUIsSUFBSUEsbUJBQW1CQSxHQUFHQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtRQUMvQ0EsSUFBSUEsS0FBS0EsQ0FBQ0E7UUFDVkEsSUFBSUEsS0FBS0EsQ0FBQ0E7UUFDVkEsSUFBSUEsQ0FBUUEsQ0FBQ0E7UUFFYkEsSUFBSUEsbUJBQXVDQSxDQUFDQTtRQUM1Q0EsSUFBSUEsV0FBbUJBLENBQUNBO1FBQ3hCQSxJQUFJQSxRQUFnQkEsQ0FBQ0E7UUFDckJBLElBQUlBLFlBQW1CQSxDQUFDQTtRQUN4QkEsSUFBSUEsS0FBWUEsQ0FBQ0E7UUFDakJBLElBQUlBLGFBQW9CQSxDQUFDQTtRQUN6QkEsSUFBSUEsUUFBZUEsQ0FBQ0E7UUFDcEJBLElBQUlBLEtBQVlBLENBQUNBO1FBQ2pCQSxJQUFJQSxLQUFZQSxDQUFDQTtRQUVqQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBVUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsbUJBQW1CQSxDQUFDQSxNQUFNQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtZQUc1REEsS0FBS0EsR0FBR0EsQ0FBQ0EsbUJBQW1CQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUNsRUEsQUFFQUEsNkVBRjZFQTtZQUU3RUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7Z0JBQ3JCQSxLQUFLQSxHQUFHQSxtQkFBbUJBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLFlBQVlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1lBRS9EQSxZQUFZQSxHQUFHQSxLQUFLQSxHQUFHQSxhQUFhQSxHQUFHQSxRQUFRQSxDQUFDQTtZQUNoREEsUUFBUUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7WUFDYkEsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0E7WUFDcEJBLFFBQVFBLEdBQUdBLEtBQUtBLENBQUNBO1lBQ2pCQSxLQUFLQSxHQUFHQSxDQUFDQSxDQUFDQTtZQUNWQSxLQUFLQSxHQUFHQSxFQUFFQSxDQUFDQTtZQUVYQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxNQUFNQSxFQUFFQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQTtnQkFFbkNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLE9BQU9BLENBQUNBLE1BQU1BLEVBQUVBLEVBQUVBLENBQUNBLENBQUNBO2dCQUV4Q0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ25FQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtvQkFFNUJBLEVBQUVBLENBQUNBLENBQUNBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLFVBQVVBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBO3dCQUMvRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7b0JBRW5EQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTt3QkFDWkEsSUFBSUEsQ0FBQ0EsVUFBVUEsR0FBR0EsS0FBS0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0E7d0JBQ2pDQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxJQUFJQSxDQUFDQSxVQUFVQSxJQUFJQSxFQUFFQSxDQUFDQSxHQUFFQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQTtvQkFFdkVBLENBQUNBO29CQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTt3QkFFUEEsTUFBTUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7NEJBRWxCQSxLQUFLQSxJQUFJQTtnQ0FDUkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0NBQ3hIQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxJQUFJQSxFQUFFQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQTtnQ0FDL0RBLEtBQUtBLENBQUNBOzRCQUVQQSxLQUFLQSxJQUFJQTtnQ0FDUkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0NBQzFIQSxhQUFhQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxJQUFJQSxFQUFFQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxHQUFHQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxHQUFHQSxDQUFDQTtvQ0FDdEVBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBO2dDQUNwQkEsQ0FBQ0E7Z0NBQ0RBLEtBQUtBLENBQUNBOzRCQUVQQSxLQUFLQSxJQUFJQTtnQ0FDUkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0NBQ3hDQSxRQUFRQSxHQUFHQSxNQUFNQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFDQSxLQUFLQSxDQUFDQTtnQ0FDbkNBLEVBQUVBLENBQUNBLENBQUNBLFFBQVFBLElBQUlBLENBQUNBLENBQUNBO29DQUNqQkEsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0E7Z0NBQ3JCQSxLQUFLQSxDQUFDQTs0QkFFUEEsS0FBS0EsSUFBSUE7Z0NBQ1JBLEVBQUVBLENBQUNBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29DQUMxSEEsWUFBWUEsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsSUFBSUEsRUFBRUEsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsR0FBR0EsQ0FBQ0E7b0NBQ3JFQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtnQ0FDakJBLENBQUNBO2dDQUNEQSxLQUFLQSxDQUFDQTs0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QUNBO29CQUN2QkEsUUFBUUEsQ0FBQ0EsWUFBWUEsR0FBR0EsWUFBWUEsQ0FBQ0E7b0JBQ3JDQSxRQUFRQSxDQUFDQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQTtvQkFFdkJBLEVBQUVBLENBQUNBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO3dCQUNqQkEsUUFBUUEsQ0FBQ0EsYUFBYUEsR0FBR0EsYUFBYUEsQ0FBQ0E7d0JBQ3ZDQSxRQUFRQSxDQUFDQSxRQUFRQSxHQUFHQSxRQUFRQSxDQUFDQTtvQkFDOUJBLENBQUNBO2dCQUVGQSxDQUFDQTtnQkFBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7b0JBQ1BBLEVBQUVBLEdBQUdBLElBQUlBLHNCQUFzQkEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7b0JBQ3ZDQSxFQUFFQSxDQUFDQSxZQUFZQSxHQUFHQSxvQkFBb0JBLENBQUNBLFVBQVVBLENBQUNBO29CQUVsREEsSUFBSUEsYUFBYUEsR0FBbURBLEVBQUVBLENBQUNBO29CQUd2RUEsYUFBYUEsQ0FBQ0EsWUFBWUEsR0FBR0EsWUFBWUEsQ0FBQ0E7b0JBQzFDQSxhQUFhQSxDQUFDQSxNQUFNQSxHQUFHQSxJQUFJQSxDQUFDQTtvQkFFNUJBLEVBQUVBLENBQUNBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO3dCQUNqQkEsYUFBYUEsQ0FBQ0EsYUFBYUEsR0FBR0EsYUFBYUEsQ0FBQ0E7d0JBQzVDQSxhQUFhQSxDQUFDQSxRQUFRQSxHQUFHQSxRQUFRQSxDQUFDQTtvQkFDbkNBLENBQUNBO2dCQUNGQSxDQUFDQTtnQkFFREEsRUFBRUEsQ0FBQ0EsRUFBRUEsR0FBR0EsRUFBRUEsQ0FBQ0E7Z0JBRVhBLElBQUlBLENBQUNBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBLENBQUNBO2dCQUU5QkEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsTUFBTUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBQzNCQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxF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RUFBRUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDakJBLENBQUNBOzs7T0FMQUo7SUFXREEsc0JBQVdBLHFCQUFDQTtRQUpaQTs7O1dBR0dBO2FBQ0hBO1lBRUNLLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLEVBQUVBLENBQUNBO1FBQ2hCQSxDQUFDQTthQUVETCxVQUFhQSxLQUFZQTtZQUV4QkssSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFDakJBLENBQUNBOzs7T0FMQUw7SUFPREE7O09BRUdBO0lBQ0lBLHNCQUFLQSxHQUFaQTtRQUVDTSxNQUFNQSxDQUFDQSxJQUFJQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxFQUFFQSxFQUFFQSxJQUFJQSxDQUFDQSxFQUFFQSxFQUFFQSxJQUFJQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQTtJQUM5Q0EsQ0FBQ0E7SUFDRk4sYUFBQ0E7QUFBREEsQ0F0RkEsQUFzRkNBLElBQUE7QUFwTUQsaUJBQVMsU0FBUyxDQUFDIiwiZmlsZSI6InBhcnNlcnMvT0JKUGFyc2VyLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpc3BsYXlPYmplY3RDb250YWluZXJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9EaXNwbGF5T2JqZWN0Q29udGFpbmVyXCIpO1xuaW1wb3J0IFRyaWFuZ2xlU3ViR2VvbWV0cnlcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvVHJpYW5nbGVTdWJHZW9tZXRyeVwiKTtcbmltcG9ydCBHZW9tZXRyeVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9HZW9tZXRyeVwiKTtcbmltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBRdWF0ZXJuaW9uXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9RdWF0ZXJuaW9uXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9JQXNzZXRcIik7XG5pbXBvcnQgVVJMTG9hZGVyRGF0YUZvcm1hdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTExvYWRlckRhdGFGb3JtYXRcIik7XG5pbXBvcnQgVVJMUmVxdWVzdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTWF0ZXJpYWxCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9NYXRlcmlhbEJhc2VcIik7XG5pbXBvcnQgUGFyc2VyQmFzZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1BhcnNlckJhc2VcIik7XG5pbXBvcnQgUGFyc2VyVXRpbHNcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcGFyc2Vycy9QYXJzZXJVdGlsc1wiKTtcbmltcG9ydCBSZXNvdXJjZURlcGVuZGVuY3lcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wYXJzZXJzL1Jlc291cmNlRGVwZW5kZW5jeVwiKTtcbmltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9UZXh0dXJlMkRCYXNlXCIpO1xuXG5pbXBvcnQgRGVmYXVsdE1hdGVyaWFsTWFuYWdlclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvdXRpbHMvRGVmYXVsdE1hdGVyaWFsTWFuYWdlclwiKTtcbmltcG9ydCBTcGVjdWxhckJhc2ljTWV0aG9kXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL21ldGhvZHMvU3BlY3VsYXJCYXNpY01ldGhvZFwiKTtcbmltcG9ydCBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9UcmlhbmdsZU1ldGhvZE1hdGVyaWFsXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWF0ZXJpYWxNb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWF0ZXJpYWxNb2RlXCIpO1xuXG4vKipcbiAqIE9CSlBhcnNlciBwcm92aWRlcyBhIHBhcnNlciBmb3IgdGhlIE9CSiBkYXRhIHR5cGUuXG4gKi9cbmNsYXNzIE9CSlBhcnNlciBleHRlbmRzIFBhcnNlckJhc2Vcbntcblx0cHJpdmF0ZSBfdGV4dERhdGE6c3RyaW5nO1xuXHRwcml2YXRlIF9zdGFydGVkUGFyc2luZzpib29sZWFuO1xuXHRwcml2YXRlIF9jaGFySW5kZXg6bnVtYmVyO1xuXHRwcml2YXRlIF9vbGRJbmRleDpudW1iZXI7XG5cdHByaXZhdGUgX3N0cmluZ0xlbmd0aDpudW1iZXI7XG5cdHByaXZhdGUgX2N1cnJlbnRPYmplY3Q6T2JqZWN0R3JvdXA7XG5cdHByaXZhdGUgX2N1cnJlbnRHcm91cDpHcm91cDtcblx0cHJpdmF0ZSBfY3VycmVudE1hdGVyaWFsR3JvdXA6TWF0ZXJpYWxHcm91cDtcblx0cHJpdmF0ZSBfb2JqZWN0czpBcnJheTxPYmplY3RHcm91cD47XG5cdHByaXZhdGUgX21hdGVyaWFsSURzOnN0cmluZ1tdO1xuXHRwcml2YXRlIF9tYXRlcmlhbExvYWRlZDpBcnJheTxMb2FkZWRNYXRlcmlhbD47XG5cdHByaXZhdGUgX21hdGVyaWFsU3BlY3VsYXJEYXRhOkFycmF5PFNwZWN1bGFyRGF0YT47XG5cdHByaXZhdGUgX21lc2hlczpBcnJheTxNZXNoPjtcblx0cHJpdmF0ZSBfbGFzdE10bElEOnN0cmluZztcblx0cHJpdmF0ZSBfb2JqZWN0SW5kZXg6bnVtYmVyO1xuXHRwcml2YXRlIF9yZWFsSW5kaWNlcztcblx0cHJpdmF0ZSBfdmVydGV4SW5kZXg6bnVtYmVyO1xuXHRwcml2YXRlIF92ZXJ0aWNlczpBcnJheTxWZXJ0ZXg+O1xuXHRwcml2YXRlIF92ZXJ0ZXhOb3JtYWxzOkFycmF5PFZlcnRleD47XG5cdHByaXZhdGUgX3V2czpBcnJheTxVVj47XG5cdHByaXZhdGUgX3NjYWxlOm51bWJlcjtcblx0cHJpdmF0ZSBfbXRsTGliOmJvb2xlYW47XG5cdHByaXZhdGUgX210bExpYkxvYWRlZDpib29sZWFuID0gdHJ1ZTtcblx0cHJpdmF0ZSBfYWN0aXZlTWF0ZXJpYWxJRDpzdHJpbmcgPSBcIlwiO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IE9CSlBhcnNlciBvYmplY3QuXG5cdCAqIEBwYXJhbSB1cmkgVGhlIHVybCBvciBpZCBvZiB0aGUgZGF0YSBvciBmaWxlIHRvIGJlIHBhcnNlZC5cblx0ICogQHBhcmFtIGV4dHJhIFRoZSBob2xkZXIgZm9yIGV4dHJhIGNvbnRleHR1YWwgZGF0YSB0aGF0IHRoZSBwYXJzZXIgbWlnaHQgbmVlZC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHNjYWxlOm51bWJlciA9IDEpXG5cdHtcblx0XHRzdXBlcihVUkxMb2FkZXJEYXRhRm9ybWF0LlRFWFQpO1xuXHRcdHRoaXMuX3NjYWxlID0gc2NhbGU7XG5cdH1cblxuXHQvKipcblx0ICogU2NhbGluZyBmYWN0b3IgYXBwbGllZCBkaXJlY3RseSB0byB2ZXJ0aWNlcyBkYXRhXG5cdCAqIEBwYXJhbSB2YWx1ZSBUaGUgc2NhbGluZyBmYWN0b3IuXG5cdCAqL1xuXHRwdWJsaWMgc2V0IHNjYWxlKHZhbHVlOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX3NjYWxlID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gZmlsZSBleHRlbnNpb24gaXMgc3VwcG9ydGVkIGJ5IHRoZSBwYXJzZXIuXG5cdCAqIEBwYXJhbSBleHRlbnNpb24gVGhlIGZpbGUgZXh0ZW5zaW9uIG9mIGEgcG90ZW50aWFsIGZpbGUgdG8gYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBmaWxlIHR5cGUgaXMgc3VwcG9ydGVkLlxuXHQgKi9cblx0cHVibGljIHN0YXRpYyBzdXBwb3J0c1R5cGUoZXh0ZW5zaW9uOnN0cmluZyk6Ym9vbGVhblxuXHR7XG5cdFx0ZXh0ZW5zaW9uID0gZXh0ZW5zaW9uLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIGV4dGVuc2lvbiA9PSBcIm9ialwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHdoZXRoZXIgYSBkYXRhIGJsb2NrIGNhbiBiZSBwYXJzZWQgYnkgdGhlIHBhcnNlci5cblx0ICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYmxvY2sgdG8gcG90ZW50aWFsbHkgYmUgcGFyc2VkLlxuXHQgKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBkYXRhIGlzIHN1cHBvcnRlZC5cblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgc3VwcG9ydHNEYXRhKGRhdGE6YW55KTpib29sZWFuXG5cdHtcblx0XHR2YXIgY29udGVudDpzdHJpbmcgPSBQYXJzZXJVdGlscy50b1N0cmluZyhkYXRhKTtcblx0XHR2YXIgaGFzVjpib29sZWFuID0gZmFsc2U7XG5cdFx0dmFyIGhhc0Y6Ym9vbGVhbiA9IGZhbHNlO1xuXG5cdFx0aWYgKGNvbnRlbnQpIHtcblx0XHRcdGhhc1YgPSBjb250ZW50LmluZGV4T2YoXCJcXG52IFwiKSAhPSAtMTtcblx0XHRcdGhhc0YgPSBjb250ZW50LmluZGV4T2YoXCJcXG5mIFwiKSAhPSAtMTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFzViAmJiBoYXNGO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lSZXNvbHZlRGVwZW5kZW5jeShyZXNvdXJjZURlcGVuZGVuY3k6UmVzb3VyY2VEZXBlbmRlbmN5KVxuXHR7XG5cdFx0aWYgKHJlc291cmNlRGVwZW5kZW5jeS5pZCA9PSAnbXRsJykge1xuXHRcdFx0dmFyIHN0cjpzdHJpbmcgPSBQYXJzZXJVdGlscy50b1N0cmluZyhyZXNvdXJjZURlcGVuZGVuY3kuZGF0YSk7XG5cdFx0XHR0aGlzLnBhcnNlTXRsKHN0cik7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIGFzc2V0OklBc3NldDtcblxuXHRcdFx0aWYgKHJlc291cmNlRGVwZW5kZW5jeS5hc3NldHMubGVuZ3RoICE9IDEpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRhc3NldCA9IHJlc291cmNlRGVwZW5kZW5jeS5hc3NldHNbMF07XG5cblx0XHRcdGlmIChhc3NldC5hc3NldFR5cGUgPT0gQXNzZXRUeXBlLlRFWFRVUkUpIHtcblxuXHRcdFx0XHR2YXIgbG06TG9hZGVkTWF0ZXJpYWwgPSBuZXcgTG9hZGVkTWF0ZXJpYWwoKTtcblx0XHRcdFx0bG0ubWF0ZXJpYWxJRCA9IHJlc291cmNlRGVwZW5kZW5jeS5pZDtcblx0XHRcdFx0bG0udGV4dHVyZSA9IDxUZXh0dXJlMkRCYXNlPiBhc3NldDtcblxuXHRcdFx0XHR0aGlzLl9tYXRlcmlhbExvYWRlZC5wdXNoKGxtKTtcblxuXHRcdFx0XHRpZiAodGhpcy5fbWVzaGVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHR0aGlzLmFwcGx5TWF0ZXJpYWwobG0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRwdWJsaWMgX2lSZXNvbHZlRGVwZW5kZW5jeUZhaWx1cmUocmVzb3VyY2VEZXBlbmRlbmN5OlJlc291cmNlRGVwZW5kZW5jeSlcblx0e1xuXHRcdGlmIChyZXNvdXJjZURlcGVuZGVuY3kuaWQgPT0gXCJtdGxcIikge1xuXHRcdFx0dGhpcy5fbXRsTGliID0gZmFsc2U7XG5cdFx0XHR0aGlzLl9tdGxMaWJMb2FkZWQgPSBmYWxzZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIGxtOkxvYWRlZE1hdGVyaWFsID0gbmV3IExvYWRlZE1hdGVyaWFsKCk7XG5cdFx0XHRsbS5tYXRlcmlhbElEID0gcmVzb3VyY2VEZXBlbmRlbmN5LmlkO1xuXHRcdFx0dGhpcy5fbWF0ZXJpYWxMb2FkZWQucHVzaChsbSk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX21lc2hlcy5sZW5ndGggPiAwKVxuXHRcdFx0dGhpcy5hcHBseU1hdGVyaWFsKGxtKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cHVibGljIF9wUHJvY2VlZFBhcnNpbmcoKTpib29sZWFuXG5cdHtcblx0XHR2YXIgbGluZTpzdHJpbmc7XG5cdFx0dmFyIGNyZXR1cm46c3RyaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMCk7XG5cdFx0dmFyIHRydW5rO1xuXG5cdFx0aWYgKCF0aGlzLl9zdGFydGVkUGFyc2luZykge1xuXHRcdFx0dGhpcy5fdGV4dERhdGEgPSB0aGlzLl9wR2V0VGV4dERhdGEoKTtcblx0XHRcdC8vIE1lcmdlIGxpbmVicmVha3MgdGhhdCBhcmUgaW1tZWRpYXRlbHkgcHJlY2VlZGVkIGJ5XG5cdFx0XHQvLyB0aGUgXCJlc2NhcGVcIiBiYWNrd2FyZCBzbGFzaCBpbnRvIHNpbmdsZSBsaW5lcy5cblx0XHRcdHRoaXMuX3RleHREYXRhID0gdGhpcy5fdGV4dERhdGEucmVwbGFjZSgvXFxcXFtcXHJcXG5dK1xccyovZ20sICcgJyk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3RleHREYXRhLmluZGV4T2YoY3JldHVybikgPT0gLTEpXG5cdFx0XHRjcmV0dXJuID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMyk7XG5cblx0XHRpZiAoIXRoaXMuX3N0YXJ0ZWRQYXJzaW5nKSB7XG5cdFx0XHR0aGlzLl9zdGFydGVkUGFyc2luZyA9IHRydWU7XG5cdFx0XHR0aGlzLl92ZXJ0aWNlcyA9IG5ldyBBcnJheTxWZXJ0ZXg+KCk7XG5cdFx0XHR0aGlzLl92ZXJ0ZXhOb3JtYWxzID0gbmV3IEFycmF5PFZlcnRleD4oKTtcblx0XHRcdHRoaXMuX21hdGVyaWFsSURzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblx0XHRcdHRoaXMuX21hdGVyaWFsTG9hZGVkID0gbmV3IEFycmF5PExvYWRlZE1hdGVyaWFsPigpO1xuXHRcdFx0dGhpcy5fbWVzaGVzID0gbmV3IEFycmF5PE1lc2g+KCk7XG5cdFx0XHR0aGlzLl91dnMgPSBuZXcgQXJyYXk8VVY+KCk7XG5cdFx0XHR0aGlzLl9zdHJpbmdMZW5ndGggPSB0aGlzLl90ZXh0RGF0YS5sZW5ndGg7XG5cdFx0XHR0aGlzLl9jaGFySW5kZXggPSB0aGlzLl90ZXh0RGF0YS5pbmRleE9mKGNyZXR1cm4sIDApO1xuXHRcdFx0dGhpcy5fb2xkSW5kZXggPSAwO1xuXHRcdFx0dGhpcy5fb2JqZWN0cyA9IG5ldyBBcnJheTxPYmplY3RHcm91cD4oKTtcblx0XHRcdHRoaXMuX29iamVjdEluZGV4ID0gMDtcblx0XHR9XG5cblx0XHR3aGlsZSAodGhpcy5fY2hhckluZGV4IDwgdGhpcy5fc3RyaW5nTGVuZ3RoICYmIHRoaXMuX3BIYXNUaW1lKCkpIHtcblx0XHRcdHRoaXMuX2NoYXJJbmRleCA9IHRoaXMuX3RleHREYXRhLmluZGV4T2YoY3JldHVybiwgdGhpcy5fb2xkSW5kZXgpO1xuXG5cdFx0XHRpZiAodGhpcy5fY2hhckluZGV4ID09IC0xKVxuXHRcdFx0XHR0aGlzLl9jaGFySW5kZXggPSB0aGlzLl9zdHJpbmdMZW5ndGg7XG5cblx0XHRcdGxpbmUgPSB0aGlzLl90ZXh0RGF0YS5zdWJzdHJpbmcodGhpcy5fb2xkSW5kZXgsIHRoaXMuX2NoYXJJbmRleCk7XG5cdFx0XHRsaW5lID0gbGluZS5zcGxpdCgnXFxyJykuam9pbihcIlwiKTtcblx0XHRcdGxpbmUgPSBsaW5lLnJlcGxhY2UoXCIgIFwiLCBcIiBcIik7XG5cdFx0XHR0cnVuayA9IGxpbmUuc3BsaXQoXCIgXCIpO1xuXHRcdFx0dGhpcy5fb2xkSW5kZXggPSB0aGlzLl9jaGFySW5kZXggKyAxO1xuXHRcdFx0dGhpcy5wYXJzZUxpbmUodHJ1bmspO1xuXG5cdFx0XHQvLyBJZiB3aGF0ZXZlciB3YXMgcGFyc2VkIG9uIHRoaXMgbGluZSByZXN1bHRlZCBpbiB0aGVcblx0XHRcdC8vIHBhcnNpbmcgYmVpbmcgcGF1c2VkIHRvIHJldHJpZXZlIGRlcGVuZGVuY2llcywgYnJlYWtcblx0XHRcdC8vIGhlcmUgYW5kIGRvIG5vdCBjb250aW51ZSBwYXJzaW5nIHVudGlsIHVuLXBhdXNlZC5cblx0XHRcdGlmICh0aGlzLnBhcnNpbmdQYXVzZWQpIHtcblx0XHRcdFx0cmV0dXJuIFBhcnNlckJhc2UuTU9SRV9UT19QQVJTRTtcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9jaGFySW5kZXggPj0gdGhpcy5fc3RyaW5nTGVuZ3RoKSB7XG5cblx0XHRcdGlmICh0aGlzLl9tdGxMaWIgJiYgIXRoaXMuX210bExpYkxvYWRlZCkge1xuXHRcdFx0XHRyZXR1cm4gUGFyc2VyQmFzZS5NT1JFX1RPX1BBUlNFO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnRyYW5zbGF0ZSgpO1xuXHRcdFx0dGhpcy5hcHBseU1hdGVyaWFscygpO1xuXG5cdFx0XHRyZXR1cm4gUGFyc2VyQmFzZS5QQVJTSU5HX0RPTkU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFBhcnNlckJhc2UuTU9SRV9UT19QQVJTRTtcblx0fVxuXG5cdHB1YmxpYyBfcFN0YXJ0UGFyc2luZyhmcmFtZUxpbWl0Om51bWJlcilcblx0e1xuXHRcdHN1cGVyLl9wU3RhcnRQYXJzaW5nKGZyYW1lTGltaXQpO1xuXG5cdFx0Ly9jcmVhdGUgYSBjb250ZW50IG9iamVjdCBmb3IgTG9hZGVyc1xuXHRcdHRoaXMuX3BDb250ZW50ID0gbmV3IERpc3BsYXlPYmplY3RDb250YWluZXIoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgYSBzaW5nbGUgbGluZSBpbiB0aGUgT0JKIGZpbGUuXG5cdCAqL1xuXHRwcml2YXRlIHBhcnNlTGluZSh0cnVuaylcblx0e1xuXHRcdHN3aXRjaCAodHJ1bmtbMF0pIHtcblxuXHRcdFx0Y2FzZSBcIm10bGxpYlwiOlxuXG5cdFx0XHRcdHRoaXMuX210bExpYiA9IHRydWU7XG5cdFx0XHRcdHRoaXMuX210bExpYkxvYWRlZCA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLmxvYWRNdGwodHJ1bmtbMV0pO1xuXG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIFwiZ1wiOlxuXG5cdFx0XHRcdHRoaXMuY3JlYXRlR3JvdXAodHJ1bmspO1xuXG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIFwib1wiOlxuXG5cdFx0XHRcdHRoaXMuY3JlYXRlT2JqZWN0KHRydW5rKTtcblxuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBcInVzZW10bFwiOlxuXG5cdFx0XHRcdGlmICh0aGlzLl9tdGxMaWIpIHtcblxuXHRcdFx0XHRcdGlmICghdHJ1bmtbMV0pXG5cdFx0XHRcdFx0XHR0cnVua1sxXSA9IFwiZGVmMDAwXCI7XG5cblx0XHRcdFx0XHR0aGlzLl9tYXRlcmlhbElEcy5wdXNoKHRydW5rWzFdKTtcblx0XHRcdFx0XHR0aGlzLl9hY3RpdmVNYXRlcmlhbElEID0gdHJ1bmtbMV07XG5cblx0XHRcdFx0XHRpZiAodGhpcy5fY3VycmVudEdyb3VwKVxuXHRcdFx0XHRcdFx0dGhpcy5fY3VycmVudEdyb3VwLm1hdGVyaWFsSUQgPSB0aGlzLl9hY3RpdmVNYXRlcmlhbElEO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJ2XCI6XG5cblx0XHRcdFx0dGhpcy5wYXJzZVZlcnRleCh0cnVuayk7XG5cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJ2dFwiOlxuXG5cdFx0XHRcdHRoaXMucGFyc2VVVih0cnVuayk7XG5cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJ2blwiOlxuXG5cdFx0XHRcdHRoaXMucGFyc2VWZXJ0ZXhOb3JtYWwodHJ1bmspO1xuXG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIFwiZlwiOlxuXG5cdFx0XHRcdHRoaXMucGFyc2VGYWNlKHRydW5rKTtcblxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgcGFyc2VkIGRhdGEgaW50byBhbiBBd2F5M0Qgc2NlbmVncmFwaCBzdHJ1Y3R1cmVcblx0ICovXG5cdHByaXZhdGUgdHJhbnNsYXRlKClcblx0e1xuXHRcdGZvciAodmFyIG9iakluZGV4Om51bWJlciA9IDA7IG9iakluZGV4IDwgdGhpcy5fb2JqZWN0cy5sZW5ndGg7ICsrb2JqSW5kZXgpIHtcblx0XHRcdHZhciBncm91cHM6QXJyYXk8R3JvdXA+ID0gdGhpcy5fb2JqZWN0c1tvYmpJbmRleF0uZ3JvdXBzO1xuXHRcdFx0dmFyIG51bUdyb3VwczpudW1iZXIgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0dmFyIG1hdGVyaWFsR3JvdXBzOkFycmF5PE1hdGVyaWFsR3JvdXA+O1xuXHRcdFx0dmFyIG51bU1hdGVyaWFsR3JvdXBzOm51bWJlcjtcblx0XHRcdHZhciBnZW9tZXRyeTpHZW9tZXRyeTtcblx0XHRcdHZhciBtZXNoOk1lc2g7XG5cblx0XHRcdHZhciBtOm51bWJlcjtcblx0XHRcdHZhciBzbTpudW1iZXI7XG5cdFx0XHR2YXIgYm1NYXRlcmlhbDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXG5cdFx0XHRmb3IgKHZhciBnOm51bWJlciA9IDA7IGcgPCBudW1Hcm91cHM7ICsrZykge1xuXHRcdFx0XHRnZW9tZXRyeSA9IG5ldyBHZW9tZXRyeSgpO1xuXHRcdFx0XHRtYXRlcmlhbEdyb3VwcyA9IGdyb3Vwc1tnXS5tYXRlcmlhbEdyb3Vwcztcblx0XHRcdFx0bnVtTWF0ZXJpYWxHcm91cHMgPSBtYXRlcmlhbEdyb3Vwcy5sZW5ndGg7XG5cblx0XHRcdFx0Zm9yIChtID0gMDsgbSA8IG51bU1hdGVyaWFsR3JvdXBzOyArK20pXG5cdFx0XHRcdFx0dGhpcy50cmFuc2xhdGVNYXRlcmlhbEdyb3VwKG1hdGVyaWFsR3JvdXBzW21dLCBnZW9tZXRyeSk7XG5cblx0XHRcdFx0aWYgKGdlb21ldHJ5LnN1Ykdlb21ldHJpZXMubGVuZ3RoID09IDApXG5cdFx0XHRcdFx0Y29udGludWU7XG5cblx0XHRcdFx0Ly8gRmluYWxpemUgYW5kIGZvcmNlIHR5cGUtYmFzZWQgbmFtZVxuXHRcdFx0XHR0aGlzLl9wRmluYWxpemVBc3NldCg8SUFzc2V0PiBnZW9tZXRyeSk7Ly8sIFwiXCIpO1xuXG5cdFx0XHRcdGJtTWF0ZXJpYWwgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbChEZWZhdWx0TWF0ZXJpYWxNYW5hZ2VyLmdldERlZmF1bHRUZXh0dXJlKCkpO1xuXG5cdFx0XHRcdC8vY2hlY2sgZm9yIG11bHRpcGFzc1xuXHRcdFx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPj0gMilcblx0XHRcdFx0XHRibU1hdGVyaWFsLm1hdGVyaWFsTW9kZSA9IFRyaWFuZ2xlTWF0ZXJpYWxNb2RlLk1VTFRJX1BBU1M7XG5cblx0XHRcdFx0bWVzaCA9IG5ldyBNZXNoKGdlb21ldHJ5LCBibU1hdGVyaWFsKTtcblxuXHRcdFx0XHRpZiAodGhpcy5fb2JqZWN0c1tvYmpJbmRleF0ubmFtZSkge1xuXHRcdFx0XHRcdC8vIHRoaXMgaXMgYSBmdWxsIGluZGVwZW5kZW50IG9iamVjdCAoJ28nIHRhZyBpbiBPQkogZmlsZSlcblx0XHRcdFx0XHRtZXNoLm5hbWUgPSB0aGlzLl9vYmplY3RzW29iakluZGV4XS5uYW1lO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAoZ3JvdXBzW2ddLm5hbWUpIHtcblxuXHRcdFx0XHRcdC8vIHRoaXMgaXMgYSBncm91cCBzbyB0aGUgc3ViIGdyb3VwcyBjb250YWluIHRoZSBhY3R1YWwgbWVzaCBvYmplY3QgbmFtZXMgKCdnJyB0YWcgaW4gT0JKIGZpbGUpXG5cdFx0XHRcdFx0bWVzaC5uYW1lID0gZ3JvdXBzW2ddLm5hbWU7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBObyBuYW1lIHN0b3JlZC4gVXNlIGVtcHR5IHN0cmluZyB3aGljaCB3aWxsIGZvcmNlIGl0XG5cdFx0XHRcdFx0Ly8gdG8gYmUgb3ZlcnJpZGRlbiBieSBmaW5hbGl6ZUFzc2V0KCkgdG8gdHlwZSBkZWZhdWx0LlxuXHRcdFx0XHRcdG1lc2gubmFtZSA9IFwiXCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLl9tZXNoZXMucHVzaChtZXNoKTtcblxuXHRcdFx0XHRpZiAoZ3JvdXBzW2ddLm1hdGVyaWFsSUQgIT0gXCJcIilcblx0XHRcdFx0XHRibU1hdGVyaWFsLm5hbWUgPSBncm91cHNbZ10ubWF0ZXJpYWxJRCArIFwiflwiICsgbWVzaC5uYW1lOyBlbHNlXG5cdFx0XHRcdFx0Ym1NYXRlcmlhbC5uYW1lID0gdGhpcy5fbGFzdE10bElEICsgXCJ+XCIgKyBtZXNoLm5hbWU7XG5cblx0XHRcdFx0aWYgKG1lc2guc3ViTWVzaGVzLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0XHRmb3IgKHNtID0gMTsgc20gPCBtZXNoLnN1Yk1lc2hlcy5sZW5ndGg7ICsrc20pXG5cdFx0XHRcdFx0XHRtZXNoLnN1Yk1lc2hlc1tzbV0ubWF0ZXJpYWwgPSBibU1hdGVyaWFsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9hZGQgdG8gdGhlIGNvbnRlbnQgcHJvcGVydHlcblx0XHRcdFx0KDxEaXNwbGF5T2JqZWN0Q29udGFpbmVyPiB0aGlzLl9wQ29udGVudCkuYWRkQ2hpbGQobWVzaCk7XG5cblx0XHRcdFx0dGhpcy5fcEZpbmFsaXplQXNzZXQoPElBc3NldD4gbWVzaCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyYW5zbGF0ZXMgYW4gb2JqJ3MgbWF0ZXJpYWwgZ3JvdXAgdG8gYSBzdWJnZW9tZXRyeS5cblx0ICogQHBhcmFtIG1hdGVyaWFsR3JvdXAgVGhlIG1hdGVyaWFsIGdyb3VwIGRhdGEgdG8gY29udmVydC5cblx0ICogQHBhcmFtIGdlb21ldHJ5IFRoZSBHZW9tZXRyeSB0byBjb250YWluIHRoZSBjb252ZXJ0ZWQgU3ViR2VvbWV0cnkuXG5cdCAqL1xuXHRwcml2YXRlIHRyYW5zbGF0ZU1hdGVyaWFsR3JvdXAobWF0ZXJpYWxHcm91cDpNYXRlcmlhbEdyb3VwLCBnZW9tZXRyeTpHZW9tZXRyeSlcblx0e1xuXHRcdHZhciBmYWNlczpBcnJheTxGYWNlRGF0YT4gPSBtYXRlcmlhbEdyb3VwLmZhY2VzO1xuXHRcdHZhciBmYWNlOkZhY2VEYXRhO1xuXHRcdHZhciBudW1GYWNlczpudW1iZXIgPSBmYWNlcy5sZW5ndGg7XG5cdFx0dmFyIG51bVZlcnRzOm51bWJlcjtcblx0XHR2YXIgc3ViOlRyaWFuZ2xlU3ViR2VvbWV0cnk7XG5cblx0XHR2YXIgdmVydGljZXM6QXJyYXk8bnVtYmVyPiA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdFx0dmFyIHV2czpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHR2YXIgbm9ybWFsczpBcnJheTxudW1iZXI+ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHR2YXIgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuXHRcdHRoaXMuX3JlYWxJbmRpY2VzID0gW107XG5cdFx0dGhpcy5fdmVydGV4SW5kZXggPSAwO1xuXG5cdFx0dmFyIGo6bnVtYmVyO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IG51bUZhY2VzOyArK2kpIHtcblxuXHRcdFx0ZmFjZSA9IGZhY2VzW2ldO1xuXHRcdFx0bnVtVmVydHMgPSBmYWNlLmluZGV4SWRzLmxlbmd0aCAtIDE7XG5cblx0XHRcdGZvciAoaiA9IDE7IGogPCBudW1WZXJ0czsgKytqKSB7XG5cblx0XHRcdFx0dGhpcy50cmFuc2xhdGVWZXJ0ZXhEYXRhKGZhY2UsIGosIHZlcnRpY2VzLCB1dnMsIGluZGljZXMsIG5vcm1hbHMpO1xuXHRcdFx0XHR0aGlzLnRyYW5zbGF0ZVZlcnRleERhdGEoZmFjZSwgMCwgdmVydGljZXMsIHV2cywgaW5kaWNlcywgbm9ybWFscyk7XG5cdFx0XHRcdHRoaXMudHJhbnNsYXRlVmVydGV4RGF0YShmYWNlLCBqICsgMSwgdmVydGljZXMsIHV2cywgaW5kaWNlcywgbm9ybWFscyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICh2ZXJ0aWNlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRzdWIgPSBuZXcgVHJpYW5nbGVTdWJHZW9tZXRyeSh0cnVlKTtcblx0XHRcdHN1Yi5hdXRvRGVyaXZlTm9ybWFscyA9IG5vcm1hbHMubGVuZ3RoPyBmYWxzZSA6IHRydWU7XG5cdFx0XHRzdWIudXBkYXRlSW5kaWNlcyhpbmRpY2VzKTtcblx0XHRcdHN1Yi51cGRhdGVQb3NpdGlvbnModmVydGljZXMpO1xuXHRcdFx0c3ViLnVwZGF0ZVZlcnRleE5vcm1hbHMobm9ybWFscyk7XG5cdFx0XHRzdWIudXBkYXRlVVZzKHV2cyk7XG5cblx0XHRcdGdlb21ldHJ5LmFkZFN1Ykdlb21ldHJ5KHN1Yik7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSB0cmFuc2xhdGVWZXJ0ZXhEYXRhKGZhY2U6RmFjZURhdGEsIHZlcnRleEluZGV4Om51bWJlciwgdmVydGljZXM6QXJyYXk8bnVtYmVyPiwgdXZzOkFycmF5PG51bWJlcj4sIGluZGljZXM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLywgbm9ybWFsczpBcnJheTxudW1iZXI+KVxuXHR7XG5cdFx0dmFyIGluZGV4Om51bWJlcjtcblx0XHR2YXIgdmVydGV4OlZlcnRleDtcblx0XHR2YXIgdmVydGV4Tm9ybWFsOlZlcnRleDtcblx0XHR2YXIgdXY6VVY7XG5cblx0XHRpZiAoIXRoaXMuX3JlYWxJbmRpY2VzW2ZhY2UuaW5kZXhJZHNbdmVydGV4SW5kZXhdXSkge1xuXG5cdFx0XHRpbmRleCA9IHRoaXMuX3ZlcnRleEluZGV4O1xuXHRcdFx0dGhpcy5fcmVhbEluZGljZXNbZmFjZS5pbmRleElkc1t2ZXJ0ZXhJbmRleF1dID0gKyt0aGlzLl92ZXJ0ZXhJbmRleDtcblx0XHRcdHZlcnRleCA9IHRoaXMuX3ZlcnRpY2VzW2ZhY2UudmVydGV4SW5kaWNlc1t2ZXJ0ZXhJbmRleF0gLSAxXTtcblx0XHRcdHZlcnRpY2VzLnB1c2godmVydGV4LngqdGhpcy5fc2NhbGUsIHZlcnRleC55KnRoaXMuX3NjYWxlLCB2ZXJ0ZXgueip0aGlzLl9zY2FsZSk7XG5cblx0XHRcdGlmIChmYWNlLm5vcm1hbEluZGljZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWwgPSB0aGlzLl92ZXJ0ZXhOb3JtYWxzW2ZhY2Uubm9ybWFsSW5kaWNlc1t2ZXJ0ZXhJbmRleF0gLSAxXTtcblx0XHRcdFx0bm9ybWFscy5wdXNoKHZlcnRleE5vcm1hbC54LCB2ZXJ0ZXhOb3JtYWwueSwgdmVydGV4Tm9ybWFsLnopO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoZmFjZS51dkluZGljZXMubGVuZ3RoID4gMCkge1xuXG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0dXYgPSB0aGlzLl91dnNbZmFjZS51dkluZGljZXNbdmVydGV4SW5kZXhdIC0gMV07XG5cdFx0XHRcdFx0dXZzLnB1c2godXYudSwgdXYudik7XG5cblx0XHRcdFx0fSBjYXRjaCAoZSkge1xuXG5cdFx0XHRcdFx0c3dpdGNoICh2ZXJ0ZXhJbmRleCkge1xuXHRcdFx0XHRcdFx0Y2FzZSAwOlxuXHRcdFx0XHRcdFx0XHR1dnMucHVzaCgwLCAxKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIDE6XG5cdFx0XHRcdFx0XHRcdHV2cy5wdXNoKC41LCAwKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIDI6XG5cdFx0XHRcdFx0XHRcdHV2cy5wdXNoKDEsIDEpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0aW5kZXggPSB0aGlzLl9yZWFsSW5kaWNlc1tmYWNlLmluZGV4SWRzW3ZlcnRleEluZGV4XV0gLSAxO1xuXHRcdH1cblxuXHRcdGluZGljZXMucHVzaChpbmRleCk7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBvYmplY3QgZ3JvdXAuXG5cdCAqIEBwYXJhbSB0cnVuayBUaGUgZGF0YSBibG9jayBjb250YWluaW5nIHRoZSBvYmplY3QgdGFnIGFuZCBpdHMgcGFyYW1ldGVyc1xuXHQgKi9cblx0cHJpdmF0ZSBjcmVhdGVPYmplY3QodHJ1bmspXG5cdHtcblx0XHR0aGlzLl9jdXJyZW50R3JvdXAgPSBudWxsO1xuXHRcdHRoaXMuX2N1cnJlbnRNYXRlcmlhbEdyb3VwID0gbnVsbDtcblx0XHR0aGlzLl9vYmplY3RzLnB1c2godGhpcy5fY3VycmVudE9iamVjdCA9IG5ldyBPYmplY3RHcm91cCgpKTtcblxuXHRcdGlmICh0cnVuaylcblx0XHRcdHRoaXMuX2N1cnJlbnRPYmplY3QubmFtZSA9IHRydW5rWzFdO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgZ3JvdXAuXG5cdCAqIEBwYXJhbSB0cnVuayBUaGUgZGF0YSBibG9jayBjb250YWluaW5nIHRoZSBncm91cCB0YWcgYW5kIGl0cyBwYXJhbWV0ZXJzXG5cdCAqL1xuXHRwcml2YXRlIGNyZWF0ZUdyb3VwKHRydW5rKVxuXHR7XG5cdFx0aWYgKCF0aGlzLl9jdXJyZW50T2JqZWN0KVxuXHRcdFx0dGhpcy5jcmVhdGVPYmplY3QobnVsbCk7XG5cdFx0dGhpcy5fY3VycmVudEdyb3VwID0gbmV3IEdyb3VwKCk7XG5cblx0XHR0aGlzLl9jdXJyZW50R3JvdXAubWF0ZXJpYWxJRCA9IHRoaXMuX2FjdGl2ZU1hdGVyaWFsSUQ7XG5cblx0XHRpZiAodHJ1bmspXG5cdFx0XHR0aGlzLl9jdXJyZW50R3JvdXAubmFtZSA9IHRydW5rWzFdO1xuXHRcdHRoaXMuX2N1cnJlbnRPYmplY3QuZ3JvdXBzLnB1c2godGhpcy5fY3VycmVudEdyb3VwKTtcblxuXHRcdHRoaXMuY3JlYXRlTWF0ZXJpYWxHcm91cChudWxsKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IG1hdGVyaWFsIGdyb3VwLlxuXHQgKiBAcGFyYW0gdHJ1bmsgVGhlIGRhdGEgYmxvY2sgY29udGFpbmluZyB0aGUgbWF0ZXJpYWwgdGFnIGFuZCBpdHMgcGFyYW1ldGVyc1xuXHQgKi9cblx0cHJpdmF0ZSBjcmVhdGVNYXRlcmlhbEdyb3VwKHRydW5rKVxuXHR7XG5cdFx0dGhpcy5fY3VycmVudE1hdGVyaWFsR3JvdXAgPSBuZXcgTWF0ZXJpYWxHcm91cCgpO1xuXHRcdGlmICh0cnVuaylcblx0XHRcdHRoaXMuX2N1cnJlbnRNYXRlcmlhbEdyb3VwLnVybCA9IHRydW5rWzFdO1xuXHRcdHRoaXMuX2N1cnJlbnRHcm91cC5tYXRlcmlhbEdyb3Vwcy5wdXNoKHRoaXMuX2N1cnJlbnRNYXRlcmlhbEdyb3VwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWFkcyB0aGUgbmV4dCB2ZXJ0ZXggY29vcmRpbmF0ZXMuXG5cdCAqIEBwYXJhbSB0cnVuayBUaGUgZGF0YSBibG9jayBjb250YWluaW5nIHRoZSB2ZXJ0ZXggdGFnIGFuZCBpdHMgcGFyYW1ldGVyc1xuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVZlcnRleCh0cnVuaylcblx0e1xuXHRcdC8vZm9yIHRoZSB2ZXJ5IHJhcmUgY2FzZXMgb2Ygb3RoZXIgZGVsaW1pdGVycy9jaGFyY29kZXMgc2VlbiBpbiBzb21lIG9iaiBmaWxlc1xuXG5cdFx0dmFyIHYxOm51bWJlciwgdjI6bnVtYmVyICwgdjM6bnVtYmVyO1xuXHRcdGlmICh0cnVuay5sZW5ndGggPiA0KSB7XG5cdFx0XHR2YXIgblRydW5rID0gW107XG5cdFx0XHR2YXIgdmFsOm51bWJlcjtcblxuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgPSAxOyBpIDwgdHJ1bmsubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dmFsID0gcGFyc2VGbG9hdCh0cnVua1tpXSk7XG5cdFx0XHRcdGlmICghaXNOYU4odmFsKSlcblx0XHRcdFx0XHRuVHJ1bmsucHVzaCh2YWwpO1xuXHRcdFx0fVxuXG5cdFx0XHR2MSA9IDxudW1iZXI+IG5UcnVua1swXTtcblx0XHRcdHYyID0gPG51bWJlcj4gblRydW5rWzFdO1xuXHRcdFx0djMgPSA8bnVtYmVyPiAtblRydW5rWzJdO1xuXHRcdFx0dGhpcy5fdmVydGljZXMucHVzaChuZXcgVmVydGV4KHYxLCB2MiwgdjMpKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHR2MSA9IDxudW1iZXI+IHBhcnNlRmxvYXQodHJ1bmtbMV0pO1xuXHRcdFx0djIgPSA8bnVtYmVyPiBwYXJzZUZsb2F0KHRydW5rWzJdKTtcblx0XHRcdHYzID0gPG51bWJlcj4gLXBhcnNlRmxvYXQodHJ1bmtbM10pO1xuXG5cdFx0XHR0aGlzLl92ZXJ0aWNlcy5wdXNoKG5ldyBWZXJ0ZXgodjEsIHYyLCB2MykpO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqIFJlYWRzIHRoZSBuZXh0IHV2IGNvb3JkaW5hdGVzLlxuXHQgKiBAcGFyYW0gdHJ1bmsgVGhlIGRhdGEgYmxvY2sgY29udGFpbmluZyB0aGUgdXYgdGFnIGFuZCBpdHMgcGFyYW1ldGVyc1xuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVVWKHRydW5rKVxuXHR7XG5cdFx0aWYgKHRydW5rLmxlbmd0aCA+IDMpIHtcblx0XHRcdHZhciBuVHJ1bmsgPSBbXTtcblx0XHRcdHZhciB2YWw6bnVtYmVyO1xuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXIgPSAxOyBpIDwgdHJ1bmsubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dmFsID0gcGFyc2VGbG9hdCh0cnVua1tpXSk7XG5cdFx0XHRcdGlmICghaXNOYU4odmFsKSlcblx0XHRcdFx0XHRuVHJ1bmsucHVzaCh2YWwpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5fdXZzLnB1c2gobmV3IFVWKG5UcnVua1swXSwgMSAtIG5UcnVua1sxXSkpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3V2cy5wdXNoKG5ldyBVVihwYXJzZUZsb2F0KHRydW5rWzFdKSwgMSAtIHBhcnNlRmxvYXQodHJ1bmtbMl0pKSk7XG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICogUmVhZHMgdGhlIG5leHQgdmVydGV4IG5vcm1hbCBjb29yZGluYXRlcy5cblx0ICogQHBhcmFtIHRydW5rIFRoZSBkYXRhIGJsb2NrIGNvbnRhaW5pbmcgdGhlIHZlcnRleCBub3JtYWwgdGFnIGFuZCBpdHMgcGFyYW1ldGVyc1xuXHQgKi9cblx0cHJpdmF0ZSBwYXJzZVZlcnRleE5vcm1hbCh0cnVuaylcblx0e1xuXHRcdGlmICh0cnVuay5sZW5ndGggPiA0KSB7XG5cdFx0XHR2YXIgblRydW5rID0gW107XG5cdFx0XHR2YXIgdmFsOm51bWJlcjtcblx0XHRcdGZvciAodmFyIGk6bnVtYmVyID0gMTsgaSA8IHRydW5rLmxlbmd0aDsgKytpKSB7XG5cdFx0XHRcdHZhbCA9IHBhcnNlRmxvYXQodHJ1bmtbaV0pO1xuXHRcdFx0XHRpZiAoIWlzTmFOKHZhbCkpXG5cdFx0XHRcdFx0blRydW5rLnB1c2godmFsKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuX3ZlcnRleE5vcm1hbHMucHVzaChuZXcgVmVydGV4KG5UcnVua1swXSwgblRydW5rWzFdLCAtblRydW5rWzJdKSk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fdmVydGV4Tm9ybWFscy5wdXNoKG5ldyBWZXJ0ZXgocGFyc2VGbG9hdCh0cnVua1sxXSksIHBhcnNlRmxvYXQodHJ1bmtbMl0pLCAtcGFyc2VGbG9hdCh0cnVua1szXSkpKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVhZHMgdGhlIG5leHQgZmFjZSdzIGluZGljZXMuXG5cdCAqIEBwYXJhbSB0cnVuayBUaGUgZGF0YSBibG9jayBjb250YWluaW5nIHRoZSBmYWNlIHRhZyBhbmQgaXRzIHBhcmFtZXRlcnNcblx0ICovXG5cdHByaXZhdGUgcGFyc2VGYWNlKHRydW5rKVxuXHR7XG5cdFx0dmFyIGxlbjpudW1iZXIgPSB0cnVuay5sZW5ndGg7XG5cdFx0dmFyIGZhY2U6RmFjZURhdGEgPSBuZXcgRmFjZURhdGEoKTtcblxuXHRcdGlmICghdGhpcy5fY3VycmVudEdyb3VwKSB7XG5cdFx0XHR0aGlzLmNyZWF0ZUdyb3VwKG51bGwpO1xuXHRcdH1cblxuXHRcdHZhciBpbmRpY2VzO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMTsgaSA8IGxlbjsgKytpKSB7XG5cblx0XHRcdGlmICh0cnVua1tpXSA9PSBcIlwiKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpbmRpY2VzID0gdHJ1bmtbaV0uc3BsaXQoXCIvXCIpO1xuXHRcdFx0ZmFjZS52ZXJ0ZXhJbmRpY2VzLnB1c2godGhpcy5wYXJzZUluZGV4KHBhcnNlSW50KGluZGljZXNbMF0pLCB0aGlzLl92ZXJ0aWNlcy5sZW5ndGgpKTtcblxuXHRcdFx0aWYgKGluZGljZXNbMV0gJiYgU3RyaW5nKGluZGljZXNbMV0pLmxlbmd0aCA+IDApXG5cdFx0XHRcdGZhY2UudXZJbmRpY2VzLnB1c2godGhpcy5wYXJzZUluZGV4KHBhcnNlSW50KGluZGljZXNbMV0pLCB0aGlzLl91dnMubGVuZ3RoKSk7XG5cblx0XHRcdGlmIChpbmRpY2VzWzJdICYmIFN0cmluZyhpbmRpY2VzWzJdKS5sZW5ndGggPiAwKVxuXHRcdFx0XHRmYWNlLm5vcm1hbEluZGljZXMucHVzaCh0aGlzLnBhcnNlSW5kZXgocGFyc2VJbnQoaW5kaWNlc1syXSksIHRoaXMuX3ZlcnRleE5vcm1hbHMubGVuZ3RoKSk7XG5cblx0XHRcdGZhY2UuaW5kZXhJZHMucHVzaCh0cnVua1tpXSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fY3VycmVudE1hdGVyaWFsR3JvdXAuZmFjZXMucHVzaChmYWNlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIGlzIGEgaGFjayBhcm91bmQgbmVnYXRpdmUgZmFjZSBjb29yZHNcblx0ICovXG5cdHByaXZhdGUgcGFyc2VJbmRleChpbmRleDpudW1iZXIsIGxlbmd0aDpudW1iZXIpOm51bWJlclxuXHR7XG5cdFx0aWYgKGluZGV4IDwgMClcblx0XHRcdHJldHVybiBpbmRleCArIGxlbmd0aCArIDE7IGVsc2Vcblx0XHRcdHJldHVybiBpbmRleDtcblx0fVxuXG5cdHByaXZhdGUgcGFyc2VNdGwoZGF0YTpzdHJpbmcpXG5cdHtcblx0XHR2YXIgbWF0ZXJpYWxEZWZpbml0aW9ucyA9IGRhdGEuc3BsaXQoJ25ld210bCcpO1xuXHRcdHZhciBsaW5lcztcblx0XHR2YXIgdHJ1bms7XG5cdFx0dmFyIGo6bnVtYmVyO1xuXG5cdFx0dmFyIGJhc2ljU3BlY3VsYXJNZXRob2Q6U3BlY3VsYXJCYXNpY01ldGhvZDtcblx0XHR2YXIgdXNlU3BlY3VsYXI6Ym9vbGVhbjtcblx0XHR2YXIgdXNlQ29sb3I6Ym9vbGVhbjtcblx0XHR2YXIgZGlmZnVzZUNvbG9yOm51bWJlcjtcblx0XHR2YXIgY29sb3I6bnVtYmVyO1xuXHRcdHZhciBzcGVjdWxhckNvbG9yOm51bWJlcjtcblx0XHR2YXIgc3BlY3VsYXI6bnVtYmVyO1xuXHRcdHZhciBhbHBoYTpudW1iZXI7XG5cdFx0dmFyIG1hcGtkOnN0cmluZztcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IG1hdGVyaWFsRGVmaW5pdGlvbnMubGVuZ3RoOyArK2kpIHtcblxuXG5cdFx0XHRsaW5lcyA9IChtYXRlcmlhbERlZmluaXRpb25zW2ldLnNwbGl0KCdcXHInKSkuam9pbihcIlwiKS5zcGxpdCgnXFxuJyk7XG5cdFx0XHQvL2xpbmVzID0gKG1hdGVyaWFsRGVmaW5pdGlvbnNbaV0uc3BsaXQoJ1xccicpIGFzIEFycmF5KS5qb2luKFwiXCIpLnNwbGl0KCdcXG4nKTtcblxuXHRcdFx0aWYgKGxpbmVzLmxlbmd0aCA9PSAxKVxuXHRcdFx0XHRsaW5lcyA9IG1hdGVyaWFsRGVmaW5pdGlvbnNbaV0uc3BsaXQoU3RyaW5nLmZyb21DaGFyQ29kZSgxMykpO1xuXG5cdFx0XHRkaWZmdXNlQ29sb3IgPSBjb2xvciA9IHNwZWN1bGFyQ29sb3IgPSAweEZGRkZGRjtcblx0XHRcdHNwZWN1bGFyID0gMDtcblx0XHRcdHVzZVNwZWN1bGFyID0gZmFsc2U7XG5cdFx0XHR1c2VDb2xvciA9IGZhbHNlO1xuXHRcdFx0YWxwaGEgPSAxO1xuXHRcdFx0bWFwa2QgPSBcIlwiO1xuXG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgbGluZXMubGVuZ3RoOyArK2opIHtcblxuXHRcdFx0XHRsaW5lc1tqXSA9IGxpbmVzW2pdLnJlcGxhY2UoL1xccyskLywgXCJcIik7XG5cblx0XHRcdFx0aWYgKGxpbmVzW2pdLnN1YnN0cmluZygwLCAxKSAhPSBcIiNcIiAmJiAoaiA9PSAwIHx8IGxpbmVzW2pdICE9IFwiXCIpKSB7XG5cdFx0XHRcdFx0dHJ1bmsgPSBsaW5lc1tqXS5zcGxpdChcIiBcIik7XG5cblx0XHRcdFx0XHRpZiAoU3RyaW5nKHRydW5rWzBdKS5jaGFyQ29kZUF0KDApID09IDkgfHwgU3RyaW5nKHRydW5rWzBdKS5jaGFyQ29kZUF0KDApID09IDMyKVxuXHRcdFx0XHRcdFx0dHJ1bmtbMF0gPSB0cnVua1swXS5zdWJzdHJpbmcoMSwgdHJ1bmtbMF0ubGVuZ3RoKTtcblxuXHRcdFx0XHRcdGlmIChqID09IDApIHtcblx0XHRcdFx0XHRcdHRoaXMuX2xhc3RNdGxJRCA9IHRydW5rLmpvaW4oXCJcIik7XG5cdFx0XHRcdFx0XHR0aGlzLl9sYXN0TXRsSUQgPSAodGhpcy5fbGFzdE10bElEID09IFwiXCIpPyBcImRlZjAwMFwiIDogdGhpcy5fbGFzdE10bElEO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0c3dpdGNoICh0cnVua1swXSkge1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgXCJLYVwiOlxuXHRcdFx0XHRcdFx0XHRcdGlmICh0cnVua1sxXSAmJiAhaXNOYU4oTnVtYmVyKHRydW5rWzFdKSkgJiYgdHJ1bmtbMl0gJiYgIWlzTmFOKE51bWJlcih0cnVua1syXSkpICYmIHRydW5rWzNdICYmICFpc05hTihOdW1iZXIodHJ1bmtbM10pKSlcblx0XHRcdFx0XHRcdFx0XHRcdGNvbG9yID0gdHJ1bmtbMV0qMjU1IDw8IDE2IHwgdHJ1bmtbMl0qMjU1IDw8IDggfCB0cnVua1szXSoyNTU7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRcdFx0Y2FzZSBcIktzXCI6XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRydW5rWzFdICYmICFpc05hTihOdW1iZXIodHJ1bmtbMV0pKSAmJiB0cnVua1syXSAmJiAhaXNOYU4oTnVtYmVyKHRydW5rWzJdKSkgJiYgdHJ1bmtbM10gJiYgIWlzTmFOKE51bWJlcih0cnVua1szXSkpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRzcGVjdWxhckNvbG9yID0gdHJ1bmtbMV0qMjU1IDw8IDE2IHwgdHJ1bmtbMl0qMjU1IDw8IDggfCB0cnVua1szXSoyNTU7XG5cdFx0XHRcdFx0XHRcdFx0XHR1c2VTcGVjdWxhciA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgXCJOc1wiOlxuXHRcdFx0XHRcdFx0XHRcdGlmICh0cnVua1sxXSAmJiAhaXNOYU4oTnVtYmVyKHRydW5rWzFdKSkpXG5cdFx0XHRcdFx0XHRcdFx0XHRzcGVjdWxhciA9IE51bWJlcih0cnVua1sxXSkqMC4wMDE7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNwZWN1bGFyID09IDApXG5cdFx0XHRcdFx0XHRcdFx0XHR1c2VTcGVjdWxhciA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgXCJLZFwiOlxuXHRcdFx0XHRcdFx0XHRcdGlmICh0cnVua1sxXSAmJiAhaXNOYU4oTnVtYmVyKHRydW5rWzFdKSkgJiYgdHJ1bmtbMl0gJiYgIWlzTmFOKE51bWJlcih0cnVua1syXSkpICYmIHRydW5rWzNdICYmICFpc05hTihOdW1iZXIodHJ1bmtbM10pKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGlmZnVzZUNvbG9yID0gdHJ1bmtbMV0qMjU1IDw8IDE2IHwgdHJ1bmtbMl0qMjU1IDw8IDggfCB0cnVua1szXSoyNTU7XG5cdFx0XHRcdFx0XHRcdFx0XHR1c2VDb2xvciA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgXCJ0clwiOlxuXHRcdFx0XHRcdFx0XHRjYXNlIFwiZFwiOlxuXHRcdFx0XHRcdFx0XHRcdGlmICh0cnVua1sxXSAmJiAhaXNOYU4oTnVtYmVyKHRydW5rWzFdKSkpXG5cdFx0XHRcdFx0XHRcdFx0XHRhbHBoYSA9IE51bWJlcih0cnVua1sxXSk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRcdFx0Y2FzZSBcIm1hcF9LZFwiOlxuXHRcdFx0XHRcdFx0XHRcdG1hcGtkID0gdGhpcy5wYXJzZU1hcEtkU3RyaW5nKHRydW5rKTtcblx0XHRcdFx0XHRcdFx0XHRtYXBrZCA9IG1hcGtkLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAobWFwa2QgIT0gXCJcIikge1xuXG5cdFx0XHRcdGlmICh1c2VTcGVjdWxhcikge1xuXG5cdFx0XHRcdFx0YmFzaWNTcGVjdWxhck1ldGhvZCA9IG5ldyBTcGVjdWxhckJhc2ljTWV0aG9kKCk7XG5cdFx0XHRcdFx0YmFzaWNTcGVjdWxhck1ldGhvZC5zcGVjdWxhckNvbG9yID0gc3BlY3VsYXJDb2xvcjtcblx0XHRcdFx0XHRiYXNpY1NwZWN1bGFyTWV0aG9kLnNwZWN1bGFyID0gc3BlY3VsYXI7XG5cblx0XHRcdFx0XHR2YXIgc3BlY3VsYXJEYXRhOlNwZWN1bGFyRGF0YSA9IG5ldyBTcGVjdWxhckRhdGEoKTtcblx0XHRcdFx0XHRzcGVjdWxhckRhdGEuYWxwaGEgPSBhbHBoYTtcblx0XHRcdFx0XHRzcGVjdWxhckRhdGEuYmFzaWNTcGVjdWxhck1ldGhvZCA9IGJhc2ljU3BlY3VsYXJNZXRob2Q7XG5cdFx0XHRcdFx0c3BlY3VsYXJEYXRhLm1hdGVyaWFsSUQgPSB0aGlzLl9sYXN0TXRsSUQ7XG5cblx0XHRcdFx0XHRpZiAoIXRoaXMuX21hdGVyaWFsU3BlY3VsYXJEYXRhKVxuXHRcdFx0XHRcdFx0dGhpcy5fbWF0ZXJpYWxTcGVjdWxhckRhdGEgPSBuZXcgQXJyYXk8U3BlY3VsYXJEYXRhPigpO1xuXG5cdFx0XHRcdFx0dGhpcy5fbWF0ZXJpYWxTcGVjdWxhckRhdGEucHVzaChzcGVjdWxhckRhdGEpO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLl9wQWRkRGVwZW5kZW5jeSh0aGlzLl9sYXN0TXRsSUQsIG5ldyBVUkxSZXF1ZXN0KG1hcGtkKSk7XG5cblx0XHRcdH0gZWxzZSBpZiAodXNlQ29sb3IgJiYgIWlzTmFOKGNvbG9yKSkge1xuXG5cdFx0XHRcdHZhciBsbTpMb2FkZWRNYXRlcmlhbCA9IG5ldyBMb2FkZWRNYXRlcmlhbCgpO1xuXHRcdFx0XHRsbS5tYXRlcmlhbElEID0gdGhpcy5fbGFzdE10bElEO1xuXG5cdFx0XHRcdGlmIChhbHBoYSA9PSAwKVxuXHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiV2FybmluZzogYW4gYWxwaGEgdmFsdWUgb2YgMCB3YXMgZm91bmQgaW4gbXRsIGNvbG9yIHRhZyAoVHIgb3IgZCkgcmVmOlwiICsgdGhpcy5fbGFzdE10bElEICsgXCIsIG1lc2goZXMpIHVzaW5nIGl0IHdpbGwgYmUgaW52aXNpYmxlIVwiKTtcblxuXHRcdFx0XHR2YXIgY206VHJpYW5nbGVNZXRob2RNYXRlcmlhbDtcblxuXHRcdFx0XHRpZiAodGhpcy5tYXRlcmlhbE1vZGUgPCAyKSB7XG5cdFx0XHRcdFx0Y20gPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbChjb2xvcik7XG5cblx0XHRcdFx0XHR2YXIgY29sb3JNYXQ6VHJpYW5nbGVNZXRob2RNYXRlcmlhbCA9IDxUcmlhbmdsZU1ldGhvZE1hdGVyaWFsPiBjbTtcblxuXHRcdFx0XHRcdGNvbG9yTWF0LmFscGhhID0gYWxwaGE7XG5cdFx0XHRcdFx0Y29sb3JNYXQuZGlmZnVzZUNvbG9yID0gZGlmZnVzZUNvbG9yO1xuXHRcdFx0XHRcdGNvbG9yTWF0LnJlcGVhdCA9IHRydWU7XG5cblx0XHRcdFx0XHRpZiAodXNlU3BlY3VsYXIpIHtcblx0XHRcdFx0XHRcdGNvbG9yTWF0LnNwZWN1bGFyQ29sb3IgPSBzcGVjdWxhckNvbG9yO1xuXHRcdFx0XHRcdFx0Y29sb3JNYXQuc3BlY3VsYXIgPSBzcGVjdWxhcjtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjbSA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKGNvbG9yKTtcblx0XHRcdFx0XHRjbS5tYXRlcmlhbE1vZGUgPSBUcmlhbmdsZU1hdGVyaWFsTW9kZS5NVUxUSV9QQVNTO1xuXG5cdFx0XHRcdFx0dmFyIGNvbG9yTXVsdGlNYXQ6VHJpYW5nbGVNZXRob2RNYXRlcmlhbCA9IDxUcmlhbmdsZU1ldGhvZE1hdGVyaWFsPiBjbTtcblxuXG5cdFx0XHRcdFx0Y29sb3JNdWx0aU1hdC5kaWZmdXNlQ29sb3IgPSBkaWZmdXNlQ29sb3I7XG5cdFx0XHRcdFx0Y29sb3JNdWx0aU1hdC5yZXBlYXQgPSB0cnVlO1xuXG5cdFx0XHRcdFx0aWYgKHVzZVNwZWN1bGFyKSB7XG5cdFx0XHRcdFx0XHRjb2xvck11bHRpTWF0LnNwZWN1bGFyQ29sb3IgPSBzcGVjdWxhckNvbG9yO1xuXHRcdFx0XHRcdFx0Y29sb3JNdWx0aU1hdC5zcGVjdWxhciA9IHNwZWN1bGFyO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGxtLmNtID0gY207XG5cblx0XHRcdFx0dGhpcy5fbWF0ZXJpYWxMb2FkZWQucHVzaChsbSk7XG5cblx0XHRcdFx0aWYgKHRoaXMuX21lc2hlcy5sZW5ndGggPiAwKVxuXHRcdFx0XHRcdHRoaXMuYXBwbHlNYXRlcmlhbChsbSk7XG5cblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLl9tdGxMaWJMb2FkZWQgPSB0cnVlO1xuXHR9XG5cblx0cHJpdmF0ZSBwYXJzZU1hcEtkU3RyaW5nKHRydW5rKTpzdHJpbmdcblx0e1xuXHRcdHZhciB1cmw6c3RyaW5nID0gXCJcIjtcblx0XHR2YXIgaTpudW1iZXI7XG5cdFx0dmFyIGJyZWFrZmxhZzpib29sZWFuO1xuXG5cdFx0Zm9yIChpID0gMTsgaSA8IHRydW5rLmxlbmd0aDspIHtcblx0XHRcdHN3aXRjaCAodHJ1bmtbaV0pIHtcblx0XHRcdFx0Y2FzZSBcIi1ibGVuZHVcIjpcblx0XHRcdFx0Y2FzZSBcIi1ibGVuZHZcIjpcblx0XHRcdFx0Y2FzZSBcIi1jY1wiOlxuXHRcdFx0XHRjYXNlIFwiLWNsYW1wXCI6XG5cdFx0XHRcdGNhc2UgXCItdGV4cmVzXCI6XG5cdFx0XHRcdFx0aSArPSAyOyAvL1NraXAgYWhlYWQgMSBhdHRyaWJ1dGVcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBcIi1tbVwiOlxuXHRcdFx0XHRcdGkgKz0gMzsgLy9Ta2lwIGFoZWFkIDIgYXR0cmlidXRlc1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwiLW9cIjpcblx0XHRcdFx0Y2FzZSBcIi1zXCI6XG5cdFx0XHRcdGNhc2UgXCItdFwiOlxuXHRcdFx0XHRcdGkgKz0gNDsgLy9Ta2lwIGFoZWFkIDMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdGJyZWFrZmxhZyA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChicmVha2ZsYWcpXG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdC8vUmVjb25zdHJ1Y3QgVVJML2ZpbGVuYW1lXG5cdFx0Zm9yIChpOyBpIDwgdHJ1bmsubGVuZ3RoOyBpKyspIHtcblx0XHRcdHVybCArPSB0cnVua1tpXTtcblx0XHRcdHVybCArPSBcIiBcIjtcblx0XHR9XG5cblx0XHQvL1JlbW92ZSB0aGUgZXh0cmFuZW91cyBzcGFjZSBhbmQvb3IgbmV3bGluZSBmcm9tIHRoZSByaWdodCBzaWRlXG5cdFx0dXJsID0gdXJsLnJlcGxhY2UoL1xccyskLywgXCJcIik7XG5cblx0XHRyZXR1cm4gdXJsO1xuXHR9XG5cblx0cHJpdmF0ZSBsb2FkTXRsKG10bHVybDpzdHJpbmcpXG5cdHtcblx0XHQvLyBBZGQgcmF3LWRhdGEgZGVwZW5kZW5jeSB0byBxdWV1ZSBhbmQgbG9hZCBkZXBlbmRlbmNpZXMgbm93LFxuXHRcdC8vIHdoaWNoIHdpbGwgcGF1c2UgdGhlIHBhcnNpbmcgaW4gdGhlIG1lYW50aW1lLlxuXHRcdHRoaXMuX3BBZGREZXBlbmRlbmN5KCdtdGwnLCBuZXcgVVJMUmVxdWVzdChtdGx1cmwpLCB0cnVlKTtcblx0XHR0aGlzLl9wUGF1c2VBbmRSZXRyaWV2ZURlcGVuZGVuY2llcygpOy8vXG5cdH1cblxuXHRwcml2YXRlIGFwcGx5TWF0ZXJpYWwobG06TG9hZGVkTWF0ZXJpYWwpXG5cdHtcblx0XHR2YXIgZGVjb21wb3NlSUQ7XG5cdFx0dmFyIG1lc2g6TWVzaDtcblx0XHR2YXIgdG06VHJpYW5nbGVNZXRob2RNYXRlcmlhbDtcblx0XHR2YXIgajpudW1iZXI7XG5cdFx0dmFyIHNwZWN1bGFyRGF0YTpTcGVjdWxhckRhdGE7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCB0aGlzLl9tZXNoZXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdG1lc2ggPSB0aGlzLl9tZXNoZXNbaV07XG5cdFx0XHRkZWNvbXBvc2VJRCA9IG1lc2gubWF0ZXJpYWwubmFtZS5zcGxpdChcIn5cIik7XG5cblx0XHRcdGlmIChkZWNvbXBvc2VJRFswXSA9PSBsbS5tYXRlcmlhbElEKSB7XG5cblx0XHRcdFx0aWYgKGxtLmNtKSB7XG5cdFx0XHRcdFx0aWYgKG1lc2gubWF0ZXJpYWwpXG5cdFx0XHRcdFx0XHRtZXNoLm1hdGVyaWFsID0gbnVsbDtcblx0XHRcdFx0XHRtZXNoLm1hdGVyaWFsID0gbG0uY207XG5cblx0XHRcdFx0fSBlbHNlIGlmIChsbS50ZXh0dXJlKSB7XG5cdFx0XHRcdFx0aWYgKHRoaXMubWF0ZXJpYWxNb2RlIDwgMikgeyAvLyBpZiBtYXRlcmlhbE1vZGUgaXMgMCBvciAxLCB3ZSBjcmVhdGUgYSBTaW5nbGVQYXNzXG5cdFx0XHRcdFx0XHR0bSA9IDxUcmlhbmdsZU1ldGhvZE1hdGVyaWFsID4gbWVzaC5tYXRlcmlhbDtcblxuXHRcdFx0XHRcdFx0dG0udGV4dHVyZSA9IGxtLnRleHR1cmU7XG5cdFx0XHRcdFx0XHR0bS5jb2xvciA9IGxtLmNvbG9yO1xuXHRcdFx0XHRcdFx0dG0uYWxwaGEgPSBsbS5hbHBoYTtcblx0XHRcdFx0XHRcdHRtLnJlcGVhdCA9IHRydWU7XG5cblx0XHRcdFx0XHRcdGlmIChsbS5zcGVjdWxhck1ldGhvZCkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEJ5IHNldHRpbmcgdGhlIHNwZWN1bGFyTWV0aG9kIHByb3BlcnR5IHRvIG51bGwgYmVmb3JlIGFzc2lnbmluZ1xuXHRcdFx0XHRcdFx0XHQvLyB0aGUgYWN0dWFsIG1ldGhvZCBpbnN0YW5jZSwgd2UgYXZvaWQgaGF2aW5nIHRoZSBwcm9wZXJ0aWVzIG9mXG5cdFx0XHRcdFx0XHRcdC8vIHRoZSBuZXcgbWV0aG9kIGJlaW5nIG92ZXJyaWRkZW4gd2l0aCB0aGUgc2V0dGluZ3MgZnJvbSB0aGUgb2xkXG5cdFx0XHRcdFx0XHRcdC8vIG9uZSwgd2hpY2ggaXMgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgc2V0dGVyLlxuXHRcdFx0XHRcdFx0XHR0bS5zcGVjdWxhck1ldGhvZCA9IG51bGw7XG5cdFx0XHRcdFx0XHRcdHRtLnNwZWN1bGFyTWV0aG9kID0gbG0uc3BlY3VsYXJNZXRob2Q7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5fbWF0ZXJpYWxTcGVjdWxhckRhdGEpIHtcblxuXHRcdFx0XHRcdFx0XHRmb3IgKGogPSAwOyBqIDwgdGhpcy5fbWF0ZXJpYWxTcGVjdWxhckRhdGEubGVuZ3RoOyArK2opIHtcblx0XHRcdFx0XHRcdFx0XHRzcGVjdWxhckRhdGEgPSB0aGlzLl9tYXRlcmlhbFNwZWN1bGFyRGF0YVtqXTtcblxuXHRcdFx0XHRcdFx0XHRcdGlmIChzcGVjdWxhckRhdGEubWF0ZXJpYWxJRCA9PSBsbS5tYXRlcmlhbElEKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0bS5zcGVjdWxhck1ldGhvZCA9IG51bGw7IC8vIFByZXZlbnQgcHJvcGVydHkgb3ZlcndyaXRlIChzZWUgYWJvdmUpXG5cdFx0XHRcdFx0XHRcdFx0XHR0bS5zcGVjdWxhck1ldGhvZCA9IHNwZWN1bGFyRGF0YS5iYXNpY1NwZWN1bGFyTWV0aG9kO1xuXHRcdFx0XHRcdFx0XHRcdFx0dG0uY29sb3IgPSBzcGVjdWxhckRhdGEuY29sb3I7XG5cdFx0XHRcdFx0XHRcdFx0XHR0bS5hbHBoYSA9IHNwZWN1bGFyRGF0YS5hbHBoYTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7IC8vaWYgbWF0ZXJpYWxNb2RlPT0yIHRoaXMgaXMgYSBNdWx0aVBhc3NUZXh0dXJlXG5cdFx0XHRcdFx0XHR0bSA9IDxUcmlhbmdsZU1ldGhvZE1hdGVyaWFsPiBtZXNoLm1hdGVyaWFsO1xuXHRcdFx0XHRcdFx0dG0ubWF0ZXJpYWxNb2RlID0gVHJpYW5nbGVNYXRlcmlhbE1vZGUuTVVMVElfUEFTUztcblxuXHRcdFx0XHRcdFx0dG0udGV4dHVyZSA9IGxtLnRleHR1cmU7XG5cdFx0XHRcdFx0XHR0bS5jb2xvciA9IGxtLmNvbG9yO1xuXHRcdFx0XHRcdFx0dG0ucmVwZWF0ID0gdHJ1ZTtcblxuXHRcdFx0XHRcdFx0aWYgKGxtLnNwZWN1bGFyTWV0aG9kKSB7XG5cdFx0XHRcdFx0XHRcdC8vIEJ5IHNldHRpbmcgdGhlIHNwZWN1bGFyTWV0aG9kIHByb3BlcnR5IHRvIG51bGwgYmVmb3JlIGFzc2lnbmluZ1xuXHRcdFx0XHRcdFx0XHQvLyB0aGUgYWN0dWFsIG1ldGhvZCBpbnN0YW5jZSwgd2UgYXZvaWQgaGF2aW5nIHRoZSBwcm9wZXJ0aWVzIG9mXG5cdFx0XHRcdFx0XHRcdC8vIHRoZSBuZXcgbWV0aG9kIGJlaW5nIG92ZXJyaWRkZW4gd2l0aCB0aGUgc2V0dGluZ3MgZnJvbSB0aGUgb2xkXG5cdFx0XHRcdFx0XHRcdC8vIG9uZSwgd2hpY2ggaXMgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgc2V0dGVyLlxuXHRcdFx0XHRcdFx0XHR0bS5zcGVjdWxhck1ldGhvZCA9IG51bGw7XG5cdFx0XHRcdFx0XHRcdHRtLnNwZWN1bGFyTWV0aG9kID0gbG0uc3BlY3VsYXJNZXRob2Q7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuX21hdGVyaWFsU3BlY3VsYXJEYXRhKSB7XG5cdFx0XHRcdFx0XHRcdGZvciAoaiA9IDA7IGogPCB0aGlzLl9tYXRlcmlhbFNwZWN1bGFyRGF0YS5sZW5ndGg7ICsraikge1xuXHRcdFx0XHRcdFx0XHRcdHNwZWN1bGFyRGF0YSA9IHRoaXMuX21hdGVyaWFsU3BlY3VsYXJEYXRhW2pdO1xuXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNwZWN1bGFyRGF0YS5tYXRlcmlhbElEID09IGxtLm1hdGVyaWFsSUQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRtLnNwZWN1bGFyTWV0aG9kID0gbnVsbDsgLy8gUHJldmVudCBwcm9wZXJ0eSBvdmVyd3JpdGUgKHNlZSBhYm92ZSlcblx0XHRcdFx0XHRcdFx0XHRcdHRtLnNwZWN1bGFyTWV0aG9kID0gc3BlY3VsYXJEYXRhLmJhc2ljU3BlY3VsYXJNZXRob2Q7XG5cdFx0XHRcdFx0XHRcdFx0XHR0bS5jb2xvciA9IHNwZWN1bGFyRGF0YS5jb2xvcjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRtZXNoLm1hdGVyaWFsLm5hbWUgPSBkZWNvbXBvc2VJRFsxXT8gZGVjb21wb3NlSURbMV0gOiBkZWNvbXBvc2VJRFswXTtcblx0XHRcdFx0dGhpcy5fbWVzaGVzLnNwbGljZShpLCAxKTtcblx0XHRcdFx0LS1pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChsbS5jbSB8fCB0bSlcblx0XHRcdHRoaXMuX3BGaW5hbGl6ZUFzc2V0KGxtLmNtIHx8IHRtKTtcblx0fVxuXG5cdHByaXZhdGUgYXBwbHlNYXRlcmlhbHMoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX21hdGVyaWFsTG9hZGVkLmxlbmd0aCA9PSAwKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgPSAwOyBpIDwgdGhpcy5fbWF0ZXJpYWxMb2FkZWQubGVuZ3RoOyArK2kpXG5cdFx0XHR0aGlzLmFwcGx5TWF0ZXJpYWwodGhpcy5fbWF0ZXJpYWxMb2FkZWRbaV0pO1xuXHR9XG59XG5cbmV4cG9ydCA9IE9CSlBhcnNlcjtcblxuY2xhc3MgT2JqZWN0R3JvdXBcbntcblx0cHVibGljIG5hbWU6c3RyaW5nO1xuXHRwdWJsaWMgZ3JvdXBzOkdyb3VwW10gPSBuZXcgQXJyYXk8R3JvdXA+KCk7XG59XG5cbmNsYXNzIEdyb3VwXG57XG5cdHB1YmxpYyBuYW1lOnN0cmluZztcblx0cHVibGljIG1hdGVyaWFsSUQ6c3RyaW5nO1xuXHRwdWJsaWMgbWF0ZXJpYWxHcm91cHM6TWF0ZXJpYWxHcm91cFtdID0gbmV3IEFycmF5PE1hdGVyaWFsR3JvdXA+KCk7XG59XG5cbmNsYXNzIE1hdGVyaWFsR3JvdXBcbntcblx0cHVibGljIHVybDpzdHJpbmc7XG5cdHB1YmxpYyBmYWNlczpGYWNlRGF0YVtdID0gbmV3IEFycmF5PEZhY2VEYXRhPigpO1xufVxuXG5jbGFzcyBTcGVjdWxhckRhdGFcbntcblx0cHVibGljIG1hdGVyaWFsSUQ6c3RyaW5nO1xuXHRwdWJsaWMgYmFzaWNTcGVjdWxhck1ldGhvZDpTcGVjdWxhckJhc2ljTWV0aG9kO1xuXHRwdWJsaWMgY29sb3I6bnVtYmVyID0gMHhGRkZGRkY7XG5cdHB1YmxpYyBhbHBoYTpudW1iZXIgPSAxO1xufVxuXG5jbGFzcyBMb2FkZWRNYXRlcmlhbFxue1xuXHRwdWJsaWMgbWF0ZXJpYWxJRDpzdHJpbmc7XG5cdHB1YmxpYyB0ZXh0dXJlOlRleHR1cmUyREJhc2U7XG5cdHB1YmxpYyBjbTpNYXRlcmlhbEJhc2U7XG5cdHB1YmxpYyBzcGVjdWxhck1ldGhvZDpTcGVjdWxhckJhc2ljTWV0aG9kO1xuXHRwdWJsaWMgY29sb3I6bnVtYmVyID0gMHhGRkZGRkY7XG5cdHB1YmxpYyBhbHBoYTpudW1iZXIgPSAxO1xufVxuXG5jbGFzcyBGYWNlRGF0YVxue1xuXHRwdWJsaWMgdmVydGV4SW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0cHVibGljIHV2SW5kaWNlczpBcnJheTxudW1iZXI+IC8qdWludCovID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0cHVibGljIG5vcm1hbEluZGljZXM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdHB1YmxpYyBpbmRleElkczpzdHJpbmdbXSA9IG5ldyBBcnJheTxzdHJpbmc+KCk7IC8vIHVzZWQgZm9yIHJlYWwgaW5kZXggbG9va3Vwc1xufVxuXG4vKipcbiogVGV4dHVyZSBjb29yZGluYXRlcyB2YWx1ZSBvYmplY3QuXG4qL1xuY2xhc3MgVVZcbntcblx0cHJpdmF0ZSBfdTpudW1iZXI7XG5cdHByaXZhdGUgX3Y6bnVtYmVyO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlVWPC9jb2RlPiBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSAgICB1ICAgICAgICBbb3B0aW9uYWxdICAgIFRoZSBob3Jpem9udGFsIGNvb3JkaW5hdGUgb2YgdGhlIHRleHR1cmUgdmFsdWUuIERlZmF1bHRzIHRvIDAuXG5cdCAqIEBwYXJhbSAgICB2ICAgICAgICBbb3B0aW9uYWxdICAgIFRoZSB2ZXJ0aWNhbCBjb29yZGluYXRlIG9mIHRoZSB0ZXh0dXJlIHZhbHVlLiBEZWZhdWx0cyB0byAwLlxuXHQgKi9cblx0Y29uc3RydWN0b3IodTpudW1iZXIgPSAwLCB2Om51bWJlciA9IDApXG5cdHtcblx0XHR0aGlzLl91ID0gdTtcblx0XHR0aGlzLl92ID0gdjtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWZpbmVzIHRoZSB2ZXJ0aWNhbCBjb29yZGluYXRlIG9mIHRoZSB0ZXh0dXJlIHZhbHVlLlxuXHQgKi9cblx0cHVibGljIGdldCB2KCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdjtcblx0fVxuXG5cdHB1YmxpYyBzZXQgdih2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl92ID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogRGVmaW5lcyB0aGUgaG9yaXpvbnRhbCBjb29yZGluYXRlIG9mIHRoZSB0ZXh0dXJlIHZhbHVlLlxuXHQgKi9cblx0cHVibGljIGdldCB1KCk6bnVtYmVyXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgdSh2YWx1ZTpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl91ID0gdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogcmV0dXJucyBhIG5ldyBVViB2YWx1ZSBPYmplY3Rcblx0ICovXG5cdHB1YmxpYyBjbG9uZSgpOlVWXG5cdHtcblx0XHRyZXR1cm4gbmV3IFVWKHRoaXMuX3UsIHRoaXMuX3YpO1xuXHR9XG5cblx0LyoqXG5cdCAqIHJldHVybnMgdGhlIHZhbHVlIG9iamVjdCBhcyBhIHN0cmluZyBmb3IgdHJhY2UvZGVidWcgcHVycG9zZVxuXHQgKi9cblx0cHVibGljIHRvU3RyaW5nKCk6c3RyaW5nXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdSArIFwiLFwiICsgdGhpcy5fdjtcblx0fVxufVxuXG5jbGFzcyBWZXJ0ZXhcbntcblx0cHJpdmF0ZSBfeDpudW1iZXI7XG5cdHByaXZhdGUgX3k6bnVtYmVyO1xuXHRwcml2YXRlIF96Om51bWJlcjtcblx0cHJpdmF0ZSBfaW5kZXg6bnVtYmVyO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlZlcnRleDwvY29kZT4gdmFsdWUgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgeCAgICAgICAgICAgIFtvcHRpb25hbF0gICAgVGhlIHggdmFsdWUuIERlZmF1bHRzIHRvIDAuXG5cdCAqIEBwYXJhbSAgICB5ICAgICAgICAgICAgW29wdGlvbmFsXSAgICBUaGUgeSB2YWx1ZS4gRGVmYXVsdHMgdG8gMC5cblx0ICogQHBhcmFtICAgIHogICAgICAgICAgICBbb3B0aW9uYWxdICAgIFRoZSB6IHZhbHVlLiBEZWZhdWx0cyB0byAwLlxuXHQgKiBAcGFyYW0gICAgaW5kZXggICAgICAgIFtvcHRpb25hbF0gICAgVGhlIGluZGV4IHZhbHVlLiBEZWZhdWx0cyBpcyBOYU4uXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcih4Om51bWJlciA9IDAsIHk6bnVtYmVyID0gMCwgejpudW1iZXIgPSAwLCBpbmRleDpudW1iZXIgPSAwKVxuXHR7XG5cdFx0dGhpcy5feCA9IHg7XG5cdFx0dGhpcy5feSA9IHk7XG5cdFx0dGhpcy5feiA9IHo7XG5cdFx0dGhpcy5faW5kZXggPSBpbmRleDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUbyBkZWZpbmUvc3RvcmUgdGhlIGluZGV4IG9mIHZhbHVlIG9iamVjdFxuXHQgKiBAcGFyYW0gICAgaW5kICAgICAgICBUaGUgaW5kZXhcblx0ICovXG5cdHB1YmxpYyBzZXQgaW5kZXgoaW5kOm51bWJlcilcblx0e1xuXHRcdHRoaXMuX2luZGV4ID0gaW5kO1xuXHR9XG5cblx0cHVibGljIGdldCBpbmRleCgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2luZGV4O1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvIGRlZmluZS9zdG9yZSB0aGUgeCB2YWx1ZSBvZiB0aGUgdmFsdWUgb2JqZWN0XG5cdCAqIEBwYXJhbSAgICB2YWx1ZSAgICAgICAgVGhlIHggdmFsdWVcblx0ICovXG5cdHB1YmxpYyBnZXQgeCgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3g7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHgodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5feCA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvIGRlZmluZS9zdG9yZSB0aGUgeSB2YWx1ZSBvZiB0aGUgdmFsdWUgb2JqZWN0XG5cdCAqIEBwYXJhbSAgICB2YWx1ZSAgICAgICAgVGhlIHkgdmFsdWVcblx0ICovXG5cdHB1YmxpYyBnZXQgeSgpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3k7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHkodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5feSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvIGRlZmluZS9zdG9yZSB0aGUgeiB2YWx1ZSBvZiB0aGUgdmFsdWUgb2JqZWN0XG5cdCAqIEBwYXJhbSAgICB2YWx1ZSAgICAgICAgVGhlIHogdmFsdWVcblx0ICovXG5cdHB1YmxpYyBnZXQgeigpOm51bWJlclxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3o7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHoodmFsdWU6bnVtYmVyKVxuXHR7XG5cdFx0dGhpcy5feiA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIHJldHVybnMgYSBuZXcgVmVydGV4IHZhbHVlIE9iamVjdFxuXHQgKi9cblx0cHVibGljIGNsb25lKCk6VmVydGV4XG5cdHtcblx0XHRyZXR1cm4gbmV3IFZlcnRleCh0aGlzLl94LCB0aGlzLl95LCB0aGlzLl96KTtcblx0fVxufSJdfQ== \ No newline at end of file diff --git a/lib/parsers/OBJParser.ts b/lib/parsers/OBJParser.ts new file mode 100644 index 000000000..30591f9a1 --- /dev/null +++ b/lib/parsers/OBJParser.ts @@ -0,0 +1,1152 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +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"); +import AssetType = require("awayjs-core/lib/core/library/AssetType"); +import IAsset = require("awayjs-core/lib/core/library/IAsset"); +import URLLoaderDataFormat = require("awayjs-core/lib/core/net/URLLoaderDataFormat"); +import URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); +import ParserBase = require("awayjs-core/lib/parsers/ParserBase"); +import ParserUtils = require("awayjs-core/lib/parsers/ParserUtils"); +import ResourceDependency = require("awayjs-core/lib/parsers/ResourceDependency"); +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); + +import DefaultMaterialManager = require("awayjs-stagegl/lib/materials/utils/DefaultMaterialManager"); +import SpecularBasicMethod = require("awayjs-stagegl/lib/materials/methods/SpecularBasicMethod"); +import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +import TriangleMaterialMode = require("awayjs-stagegl/lib/materials/TriangleMaterialMode"); + +/** + * OBJParser provides a parser for the OBJ data type. + */ +class OBJParser extends ParserBase +{ + private _textData:string; + private _startedParsing:boolean; + private _charIndex:number; + private _oldIndex:number; + private _stringLength:number; + private _currentObject:ObjectGroup; + private _currentGroup:Group; + private _currentMaterialGroup:MaterialGroup; + private _objects:Array; + private _materialIDs:string[]; + private _materialLoaded:Array; + private _materialSpecularData:Array; + private _meshes:Array; + private _lastMtlID:string; + private _objectIndex:number; + private _realIndices; + private _vertexIndex:number; + private _vertices:Array; + private _vertexNormals:Array; + private _uvs:Array; + private _scale:number; + private _mtlLib:boolean; + private _mtlLibLoaded:boolean = true; + private _activeMaterialID:string = ""; + + /** + * Creates a new OBJParser object. + * @param uri The url or id of the data or file to be parsed. + * @param extra The holder for extra contextual data that the parser might need. + */ + constructor(scale:number = 1) + { + super(URLLoaderDataFormat.TEXT); + this._scale = scale; + } + + /** + * Scaling factor applied directly to vertices data + * @param value The scaling factor. + */ + public set scale(value:number) + { + this._scale = value; + } + + /** + * Indicates whether or not a given file extension is supported by the parser. + * @param extension The file extension of a potential file to be parsed. + * @return Whether or not the given file type is supported. + */ + public static supportsType(extension:string):boolean + { + extension = extension.toLowerCase(); + return extension == "obj"; + } + + /** + * Tests whether a data block can be parsed by the parser. + * @param data The data block to potentially be parsed. + * @return Whether or not the given data is supported. + */ + public static supportsData(data:any):boolean + { + var content:string = ParserUtils.toString(data); + var hasV:boolean = false; + var hasF:boolean = false; + + if (content) { + hasV = content.indexOf("\nv ") != -1; + hasF = content.indexOf("\nf ") != -1; + } + + return hasV && hasF; + } + + /** + * @inheritDoc + */ + public _iResolveDependency(resourceDependency:ResourceDependency) + { + if (resourceDependency.id == 'mtl') { + var str:string = ParserUtils.toString(resourceDependency.data); + this.parseMtl(str); + + } else { + var asset:IAsset; + + if (resourceDependency.assets.length != 1) { + return; + } + + asset = resourceDependency.assets[0]; + + if (asset.assetType == AssetType.TEXTURE) { + + var lm:LoadedMaterial = new LoadedMaterial(); + lm.materialID = resourceDependency.id; + lm.texture = asset; + + this._materialLoaded.push(lm); + + if (this._meshes.length > 0) { + this.applyMaterial(lm); + } + } + } + } + + /** + * @inheritDoc + */ + public _iResolveDependencyFailure(resourceDependency:ResourceDependency) + { + if (resourceDependency.id == "mtl") { + this._mtlLib = false; + this._mtlLibLoaded = false; + } else { + var lm:LoadedMaterial = new LoadedMaterial(); + lm.materialID = resourceDependency.id; + this._materialLoaded.push(lm); + } + + if (this._meshes.length > 0) + this.applyMaterial(lm); + } + + /** + * @inheritDoc + */ + public _pProceedParsing():boolean + { + var line:string; + var creturn:string = String.fromCharCode(10); + var trunk; + + if (!this._startedParsing) { + this._textData = this._pGetTextData(); + // Merge linebreaks that are immediately preceeded by + // the "escape" backward slash into single lines. + this._textData = this._textData.replace(/\\[\r\n]+\s*/gm, ' '); + } + + if (this._textData.indexOf(creturn) == -1) + creturn = String.fromCharCode(13); + + if (!this._startedParsing) { + this._startedParsing = true; + this._vertices = new Array(); + this._vertexNormals = new Array(); + this._materialIDs = new Array(); + this._materialLoaded = new Array(); + this._meshes = new Array(); + this._uvs = new Array(); + this._stringLength = this._textData.length; + this._charIndex = this._textData.indexOf(creturn, 0); + this._oldIndex = 0; + this._objects = new Array(); + this._objectIndex = 0; + } + + while (this._charIndex < this._stringLength && this._pHasTime()) { + this._charIndex = this._textData.indexOf(creturn, this._oldIndex); + + if (this._charIndex == -1) + this._charIndex = this._stringLength; + + line = this._textData.substring(this._oldIndex, this._charIndex); + line = line.split('\r').join(""); + line = line.replace(" ", " "); + trunk = line.split(" "); + this._oldIndex = this._charIndex + 1; + this.parseLine(trunk); + + // If whatever was parsed on this line resulted in the + // parsing being paused to retrieve dependencies, break + // here and do not continue parsing until un-paused. + if (this.parsingPaused) { + return ParserBase.MORE_TO_PARSE; + } + + } + + if (this._charIndex >= this._stringLength) { + + if (this._mtlLib && !this._mtlLibLoaded) { + return ParserBase.MORE_TO_PARSE; + } + + this.translate(); + this.applyMaterials(); + + return ParserBase.PARSING_DONE; + } + + return ParserBase.MORE_TO_PARSE; + } + + public _pStartParsing(frameLimit:number) + { + super._pStartParsing(frameLimit); + + //create a content object for Loaders + this._pContent = new DisplayObjectContainer(); + } + + /** + * Parses a single line in the OBJ file. + */ + private parseLine(trunk) + { + switch (trunk[0]) { + + case "mtllib": + + this._mtlLib = true; + this._mtlLibLoaded = false; + this.loadMtl(trunk[1]); + + break; + + case "g": + + this.createGroup(trunk); + + break; + + case "o": + + this.createObject(trunk); + + break; + + case "usemtl": + + if (this._mtlLib) { + + if (!trunk[1]) + trunk[1] = "def000"; + + this._materialIDs.push(trunk[1]); + this._activeMaterialID = trunk[1]; + + if (this._currentGroup) + this._currentGroup.materialID = this._activeMaterialID; + } + + break; + + case "v": + + this.parseVertex(trunk); + + break; + + case "vt": + + this.parseUV(trunk); + + break; + + case "vn": + + this.parseVertexNormal(trunk); + + break; + + case "f": + + this.parseFace(trunk); + + } + } + + /** + * Converts the parsed data into an Away3D scenegraph structure + */ + private translate() + { + for (var objIndex:number = 0; objIndex < this._objects.length; ++objIndex) { + var groups:Array = this._objects[objIndex].groups; + var numGroups:number = groups.length; + var materialGroups:Array; + var numMaterialGroups:number; + var geometry:Geometry; + var mesh:Mesh; + + var m:number; + var sm:number; + var bmMaterial:TriangleMethodMaterial; + + for (var g:number = 0; g < numGroups; ++g) { + geometry = new Geometry(); + materialGroups = groups[g].materialGroups; + numMaterialGroups = materialGroups.length; + + for (m = 0; m < numMaterialGroups; ++m) + this.translateMaterialGroup(materialGroups[m], geometry); + + if (geometry.subGeometries.length == 0) + continue; + + // Finalize and force type-based name + this._pFinalizeAsset( geometry);//, ""); + + bmMaterial = new TriangleMethodMaterial(DefaultMaterialManager.getDefaultTexture()); + + //check for multipass + if (this.materialMode >= 2) + bmMaterial.materialMode = TriangleMaterialMode.MULTI_PASS; + + mesh = new Mesh(geometry, bmMaterial); + + if (this._objects[objIndex].name) { + // this is a full independent object ('o' tag in OBJ file) + mesh.name = this._objects[objIndex].name; + + } else if (groups[g].name) { + + // this is a group so the sub groups contain the actual mesh object names ('g' tag in OBJ file) + mesh.name = groups[g].name; + + } else { + // No name stored. Use empty string which will force it + // to be overridden by finalizeAsset() to type default. + mesh.name = ""; + } + + this._meshes.push(mesh); + + if (groups[g].materialID != "") + bmMaterial.name = groups[g].materialID + "~" + mesh.name; else + bmMaterial.name = this._lastMtlID + "~" + mesh.name; + + if (mesh.subMeshes.length > 1) { + for (sm = 1; sm < mesh.subMeshes.length; ++sm) + mesh.subMeshes[sm].material = bmMaterial; + } + + //add to the content property + ( this._pContent).addChild(mesh); + + this._pFinalizeAsset( mesh); + } + } + } + + /** + * Translates an obj's material group to a subgeometry. + * @param materialGroup The material group data to convert. + * @param geometry The Geometry to contain the converted SubGeometry. + */ + private translateMaterialGroup(materialGroup:MaterialGroup, geometry:Geometry) + { + var faces:Array = materialGroup.faces; + var face:FaceData; + var numFaces:number = faces.length; + var numVerts:number; + var sub:TriangleSubGeometry; + + var vertices:Array = new Array(); + var uvs:Array = new Array(); + var normals:Array = new Array(); + var indices:Array /*uint*/ = new Array(); + + this._realIndices = []; + this._vertexIndex = 0; + + var j:number; + for (var i:number = 0; i < numFaces; ++i) { + + face = faces[i]; + numVerts = face.indexIds.length - 1; + + for (j = 1; j < numVerts; ++j) { + + this.translateVertexData(face, j, vertices, uvs, indices, normals); + this.translateVertexData(face, 0, vertices, uvs, indices, normals); + this.translateVertexData(face, j + 1, vertices, uvs, indices, normals); + } + } + if (vertices.length > 0) { + sub = new TriangleSubGeometry(true); + sub.autoDeriveNormals = normals.length? false : true; + sub.updateIndices(indices); + sub.updatePositions(vertices); + sub.updateVertexNormals(normals); + sub.updateUVs(uvs); + + geometry.addSubGeometry(sub); + } + } + + private translateVertexData(face:FaceData, vertexIndex:number, vertices:Array, uvs:Array, indices:Array /*uint*/, normals:Array) + { + var index:number; + var vertex:Vertex; + var vertexNormal:Vertex; + var uv:UV; + + if (!this._realIndices[face.indexIds[vertexIndex]]) { + + index = this._vertexIndex; + this._realIndices[face.indexIds[vertexIndex]] = ++this._vertexIndex; + vertex = this._vertices[face.vertexIndices[vertexIndex] - 1]; + vertices.push(vertex.x*this._scale, vertex.y*this._scale, vertex.z*this._scale); + + if (face.normalIndices.length > 0) { + vertexNormal = this._vertexNormals[face.normalIndices[vertexIndex] - 1]; + normals.push(vertexNormal.x, vertexNormal.y, vertexNormal.z); + } + + if (face.uvIndices.length > 0) { + + try { + uv = this._uvs[face.uvIndices[vertexIndex] - 1]; + uvs.push(uv.u, uv.v); + + } catch (e) { + + switch (vertexIndex) { + case 0: + uvs.push(0, 1); + break; + case 1: + uvs.push(.5, 0); + break; + case 2: + uvs.push(1, 1); + } + } + + } + + } else { + index = this._realIndices[face.indexIds[vertexIndex]] - 1; + } + + indices.push(index); + } + + /** + * Creates a new object group. + * @param trunk The data block containing the object tag and its parameters + */ + private createObject(trunk) + { + this._currentGroup = null; + this._currentMaterialGroup = null; + this._objects.push(this._currentObject = new ObjectGroup()); + + if (trunk) + this._currentObject.name = trunk[1]; + } + + /** + * Creates a new group. + * @param trunk The data block containing the group tag and its parameters + */ + private createGroup(trunk) + { + if (!this._currentObject) + this.createObject(null); + this._currentGroup = new Group(); + + this._currentGroup.materialID = this._activeMaterialID; + + if (trunk) + this._currentGroup.name = trunk[1]; + this._currentObject.groups.push(this._currentGroup); + + this.createMaterialGroup(null); + } + + /** + * Creates a new material group. + * @param trunk The data block containing the material tag and its parameters + */ + private createMaterialGroup(trunk) + { + this._currentMaterialGroup = new MaterialGroup(); + if (trunk) + this._currentMaterialGroup.url = trunk[1]; + this._currentGroup.materialGroups.push(this._currentMaterialGroup); + } + + /** + * Reads the next vertex coordinates. + * @param trunk The data block containing the vertex tag and its parameters + */ + private parseVertex(trunk) + { + //for the very rare cases of other delimiters/charcodes seen in some obj files + + var v1:number, v2:number , v3:number; + if (trunk.length > 4) { + var nTrunk = []; + var val:number; + + for (var i:number = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + + v1 = nTrunk[0]; + v2 = nTrunk[1]; + v3 = -nTrunk[2]; + this._vertices.push(new Vertex(v1, v2, v3)); + + } else { + v1 = parseFloat(trunk[1]); + v2 = parseFloat(trunk[2]); + v3 = -parseFloat(trunk[3]); + + this._vertices.push(new Vertex(v1, v2, v3)); + } + + } + + /** + * Reads the next uv coordinates. + * @param trunk The data block containing the uv tag and its parameters + */ + private parseUV(trunk) + { + if (trunk.length > 3) { + var nTrunk = []; + var val:number; + for (var i:number = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + this._uvs.push(new UV(nTrunk[0], 1 - nTrunk[1])); + + } else { + this._uvs.push(new UV(parseFloat(trunk[1]), 1 - parseFloat(trunk[2]))); + } + + } + + /** + * Reads the next vertex normal coordinates. + * @param trunk The data block containing the vertex normal tag and its parameters + */ + private parseVertexNormal(trunk) + { + if (trunk.length > 4) { + var nTrunk = []; + var val:number; + for (var i:number = 1; i < trunk.length; ++i) { + val = parseFloat(trunk[i]); + if (!isNaN(val)) + nTrunk.push(val); + } + this._vertexNormals.push(new Vertex(nTrunk[0], nTrunk[1], -nTrunk[2])); + + } else { + this._vertexNormals.push(new Vertex(parseFloat(trunk[1]), parseFloat(trunk[2]), -parseFloat(trunk[3]))); + } + } + + /** + * Reads the next face's indices. + * @param trunk The data block containing the face tag and its parameters + */ + private parseFace(trunk) + { + var len:number = trunk.length; + var face:FaceData = new FaceData(); + + if (!this._currentGroup) { + this.createGroup(null); + } + + var indices; + for (var i:number = 1; i < len; ++i) { + + if (trunk[i] == "") { + continue; + } + + indices = trunk[i].split("/"); + face.vertexIndices.push(this.parseIndex(parseInt(indices[0]), this._vertices.length)); + + if (indices[1] && String(indices[1]).length > 0) + face.uvIndices.push(this.parseIndex(parseInt(indices[1]), this._uvs.length)); + + if (indices[2] && String(indices[2]).length > 0) + face.normalIndices.push(this.parseIndex(parseInt(indices[2]), this._vertexNormals.length)); + + face.indexIds.push(trunk[i]); + } + + this._currentMaterialGroup.faces.push(face); + } + + /** + * This is a hack around negative face coords + */ + private parseIndex(index:number, length:number):number + { + if (index < 0) + return index + length + 1; else + return index; + } + + private parseMtl(data:string) + { + var materialDefinitions = data.split('newmtl'); + var lines; + var trunk; + var j:number; + + var basicSpecularMethod:SpecularBasicMethod; + var useSpecular:boolean; + var useColor:boolean; + var diffuseColor:number; + var color:number; + var specularColor:number; + var specular:number; + var alpha:number; + var mapkd:string; + + for (var i:number = 0; i < materialDefinitions.length; ++i) { + + + lines = (materialDefinitions[i].split('\r')).join("").split('\n'); + //lines = (materialDefinitions[i].split('\r') as Array).join("").split('\n'); + + if (lines.length == 1) + lines = materialDefinitions[i].split(String.fromCharCode(13)); + + diffuseColor = color = specularColor = 0xFFFFFF; + specular = 0; + useSpecular = false; + useColor = false; + alpha = 1; + mapkd = ""; + + for (j = 0; j < lines.length; ++j) { + + lines[j] = lines[j].replace(/\s+$/, ""); + + if (lines[j].substring(0, 1) != "#" && (j == 0 || lines[j] != "")) { + trunk = lines[j].split(" "); + + if (String(trunk[0]).charCodeAt(0) == 9 || String(trunk[0]).charCodeAt(0) == 32) + trunk[0] = trunk[0].substring(1, trunk[0].length); + + if (j == 0) { + this._lastMtlID = trunk.join(""); + this._lastMtlID = (this._lastMtlID == "")? "def000" : this._lastMtlID; + + } else { + + switch (trunk[0]) { + + case "Ka": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) + color = trunk[1]*255 << 16 | trunk[2]*255 << 8 | trunk[3]*255; + break; + + case "Ks": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) { + specularColor = trunk[1]*255 << 16 | trunk[2]*255 << 8 | trunk[3]*255; + useSpecular = true; + } + break; + + case "Ns": + if (trunk[1] && !isNaN(Number(trunk[1]))) + specular = Number(trunk[1])*0.001; + if (specular == 0) + useSpecular = false; + break; + + case "Kd": + if (trunk[1] && !isNaN(Number(trunk[1])) && trunk[2] && !isNaN(Number(trunk[2])) && trunk[3] && !isNaN(Number(trunk[3]))) { + diffuseColor = trunk[1]*255 << 16 | trunk[2]*255 << 8 | trunk[3]*255; + useColor = true; + } + break; + + case "tr": + case "d": + if (trunk[1] && !isNaN(Number(trunk[1]))) + alpha = Number(trunk[1]); + break; + + case "map_Kd": + mapkd = this.parseMapKdString(trunk); + mapkd = mapkd.replace(/\\/g, "/"); + } + } + } + } + + if (mapkd != "") { + + if (useSpecular) { + + basicSpecularMethod = new SpecularBasicMethod(); + basicSpecularMethod.specularColor = specularColor; + basicSpecularMethod.specular = specular; + + var specularData:SpecularData = new SpecularData(); + specularData.alpha = alpha; + specularData.basicSpecularMethod = basicSpecularMethod; + specularData.materialID = this._lastMtlID; + + if (!this._materialSpecularData) + this._materialSpecularData = new Array(); + + this._materialSpecularData.push(specularData); + + } + + this._pAddDependency(this._lastMtlID, new URLRequest(mapkd)); + + } else if (useColor && !isNaN(color)) { + + var lm:LoadedMaterial = new LoadedMaterial(); + lm.materialID = this._lastMtlID; + + if (alpha == 0) + console.log("Warning: an alpha value of 0 was found in mtl color tag (Tr or d) ref:" + this._lastMtlID + ", mesh(es) using it will be invisible!"); + + var cm:TriangleMethodMaterial; + + if (this.materialMode < 2) { + cm = new TriangleMethodMaterial(color); + + var colorMat:TriangleMethodMaterial = cm; + + colorMat.alpha = alpha; + colorMat.diffuseColor = diffuseColor; + colorMat.repeat = true; + + if (useSpecular) { + colorMat.specularColor = specularColor; + colorMat.specular = specular; + } + + } else { + cm = new TriangleMethodMaterial(color); + cm.materialMode = TriangleMaterialMode.MULTI_PASS; + + var colorMultiMat:TriangleMethodMaterial = cm; + + + colorMultiMat.diffuseColor = diffuseColor; + colorMultiMat.repeat = true; + + if (useSpecular) { + colorMultiMat.specularColor = specularColor; + colorMultiMat.specular = specular; + } + } + + lm.cm = cm; + + this._materialLoaded.push(lm); + + if (this._meshes.length > 0) + this.applyMaterial(lm); + + } + } + + this._mtlLibLoaded = true; + } + + private parseMapKdString(trunk):string + { + var url:string = ""; + var i:number; + var breakflag:boolean; + + for (i = 1; i < trunk.length;) { + switch (trunk[i]) { + case "-blendu": + case "-blendv": + case "-cc": + case "-clamp": + case "-texres": + i += 2; //Skip ahead 1 attribute + break; + case "-mm": + i += 3; //Skip ahead 2 attributes + break; + case "-o": + case "-s": + case "-t": + i += 4; //Skip ahead 3 attributes + continue; + default: + breakflag = true; + break; + } + + if (breakflag) + break; + } + + //Reconstruct URL/filename + for (i; i < trunk.length; i++) { + url += trunk[i]; + url += " "; + } + + //Remove the extraneous space and/or newline from the right side + url = url.replace(/\s+$/, ""); + + return url; + } + + private loadMtl(mtlurl:string) + { + // Add raw-data dependency to queue and load dependencies now, + // which will pause the parsing in the meantime. + this._pAddDependency('mtl', new URLRequest(mtlurl), true); + this._pPauseAndRetrieveDependencies();// + } + + private applyMaterial(lm:LoadedMaterial) + { + var decomposeID; + var mesh:Mesh; + var tm:TriangleMethodMaterial; + var j:number; + var specularData:SpecularData; + + for (var i:number = 0; i < this._meshes.length; ++i) { + mesh = this._meshes[i]; + decomposeID = mesh.material.name.split("~"); + + if (decomposeID[0] == lm.materialID) { + + if (lm.cm) { + if (mesh.material) + mesh.material = null; + mesh.material = lm.cm; + + } else if (lm.texture) { + if (this.materialMode < 2) { // if materialMode is 0 or 1, we create a SinglePass + tm = mesh.material; + + tm.texture = lm.texture; + tm.color = lm.color; + tm.alpha = lm.alpha; + tm.repeat = true; + + if (lm.specularMethod) { + + // By setting the specularMethod property to null before assigning + // the actual method instance, we avoid having the properties of + // the new method being overridden with the settings from the old + // one, which is default behavior of the setter. + tm.specularMethod = null; + tm.specularMethod = lm.specularMethod; + + } else if (this._materialSpecularData) { + + for (j = 0; j < this._materialSpecularData.length; ++j) { + specularData = this._materialSpecularData[j]; + + if (specularData.materialID == lm.materialID) { + tm.specularMethod = null; // Prevent property overwrite (see above) + tm.specularMethod = specularData.basicSpecularMethod; + tm.color = specularData.color; + tm.alpha = specularData.alpha; + break; + } + } + } + } else { //if materialMode==2 this is a MultiPassTexture + tm = mesh.material; + tm.materialMode = TriangleMaterialMode.MULTI_PASS; + + tm.texture = lm.texture; + tm.color = lm.color; + tm.repeat = true; + + if (lm.specularMethod) { + // By setting the specularMethod property to null before assigning + // the actual method instance, we avoid having the properties of + // the new method being overridden with the settings from the old + // one, which is default behavior of the setter. + tm.specularMethod = null; + tm.specularMethod = lm.specularMethod; + } else if (this._materialSpecularData) { + for (j = 0; j < this._materialSpecularData.length; ++j) { + specularData = this._materialSpecularData[j]; + + if (specularData.materialID == lm.materialID) { + tm.specularMethod = null; // Prevent property overwrite (see above) + tm.specularMethod = specularData.basicSpecularMethod; + tm.color = specularData.color; + + break; + + } + } + } + } + } + + mesh.material.name = decomposeID[1]? decomposeID[1] : decomposeID[0]; + this._meshes.splice(i, 1); + --i; + } + } + + if (lm.cm || tm) + this._pFinalizeAsset(lm.cm || tm); + } + + private applyMaterials() + { + if (this._materialLoaded.length == 0) + return; + + for (var i:number = 0; i < this._materialLoaded.length; ++i) + this.applyMaterial(this._materialLoaded[i]); + } +} + +export = OBJParser; + +class ObjectGroup +{ + public name:string; + public groups:Group[] = new Array(); +} + +class Group +{ + public name:string; + public materialID:string; + public materialGroups:MaterialGroup[] = new Array(); +} + +class MaterialGroup +{ + public url:string; + public faces:FaceData[] = new Array(); +} + +class SpecularData +{ + public materialID:string; + public basicSpecularMethod:SpecularBasicMethod; + public color:number = 0xFFFFFF; + public alpha:number = 1; +} + +class LoadedMaterial +{ + public materialID:string; + public texture:Texture2DBase; + public cm:MaterialBase; + public specularMethod:SpecularBasicMethod; + public color:number = 0xFFFFFF; + public alpha:number = 1; +} + +class FaceData +{ + public vertexIndices:Array /*uint*/ = new Array(); + public uvIndices:Array /*uint*/ = new Array(); + public normalIndices:Array /*uint*/ = new Array(); + public indexIds:string[] = new Array(); // used for real index lookups +} + +/** +* Texture coordinates value object. +*/ +class UV +{ + private _u:number; + private _v:number; + + /** + * Creates a new UV object. + * + * @param u [optional] The horizontal coordinate of the texture value. Defaults to 0. + * @param v [optional] The vertical coordinate of the texture value. Defaults to 0. + */ + constructor(u:number = 0, v:number = 0) + { + this._u = u; + this._v = v; + } + + /** + * Defines the vertical coordinate of the texture value. + */ + public get v():number + { + return this._v; + } + + public set v(value:number) + { + this._v = value; + } + + /** + * Defines the horizontal coordinate of the texture value. + */ + public get u():number + { + return this._u; + } + + public set u(value:number) + { + this._u = value; + } + + /** + * returns a new UV value Object + */ + public clone():UV + { + return new UV(this._u, this._v); + } + + /** + * returns the value object as a string for trace/debug purpose + */ + public toString():string + { + return this._u + "," + this._v; + } +} + +class Vertex +{ + private _x:number; + private _y:number; + private _z:number; + private _index:number; + + /** + * Creates a new Vertex value object. + * + * @param x [optional] The x value. Defaults to 0. + * @param y [optional] The y value. Defaults to 0. + * @param z [optional] The z value. Defaults to 0. + * @param index [optional] The index value. Defaults is NaN. + */ + constructor(x:number = 0, y:number = 0, z:number = 0, index:number = 0) + { + this._x = x; + this._y = y; + this._z = z; + this._index = index; + } + + /** + * To define/store the index of value object + * @param ind The index + */ + public set index(ind:number) + { + this._index = ind; + } + + public get index():number + { + return this._index; + } + + /** + * To define/store the x value of the value object + * @param value The x value + */ + public get x():number + { + return this._x; + } + + public set x(value:number) + { + this._x = value; + } + + /** + * To define/store the y value of the value object + * @param value The y value + */ + public get y():number + { + return this._y; + } + + public set y(value:number) + { + this._y = value; + } + + /** + * To define/store the z value of the value object + * @param value The z value + */ + public get z():number + { + return this._z; + } + + public set z(value:number) + { + this._z = value; + } + + /** + * returns a new Vertex value Object + */ + public clone():Vertex + { + return new Vertex(this._x, this._y, this._z); + } +} \ No newline at end of file diff --git a/lib/parsers/Parsers.js b/lib/parsers/Parsers.js new file mode 100755 index 000000000..7cb8d3a02 --- /dev/null +++ b/lib/parsers/Parsers.js @@ -0,0 +1,62 @@ +var AssetLoader = require("awayjs-core/lib/core/library/AssetLoader"); +var AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +var Max3DSParser = require("awayjs-renderergl/lib/parsers/Max3DSParser"); +var MD2Parser = require("awayjs-renderergl/lib/parsers/MD2Parser"); +var OBJParser = require("awayjs-renderergl/lib/parsers/OBJParser"); +/** + * + */ +var Parsers = (function () { + function Parsers() { + } + /** + * Short-hand function to enable all bundled parsers for auto-detection. In practice, + * this is the same as invoking enableParsers(Parsers.ALL_BUNDLED) on any of the + * loader classes SingleFileLoader, AssetLoader, AssetLibrary or Loader3D. + * + * See notes about file size in the documentation for the ALL_BUNDLED constant. + * + * @see away.parsers.Parsers.ALL_BUNDLED + */ + Parsers.enableAllBundled = function () { + AssetLoader.enableParsers(Parsers.ALL_BUNDLED); + }; + /** + * A list of all parsers that come bundled with Away3D. Use this to quickly + * enable support for all bundled parsers to the file format auto-detection + * feature, using any of the enableParsers() methods on loaders, e.g.: + * + * AssetLibrary.enableParsers(Parsers.ALL_BUNDLED); + * + * Beware however that this requires all parser classes to be included in the + * SWF file, which will add 50-100 kb to the file. When only a limited set of + * file formats are used, SWF file size can be saved by adding the parsers + * individually using AssetLibrary.enableParser() + * + * A third way is to specify a parser for each loaded file, thereby bypassing + * the auto-detection mechanisms altogether, while at the same time allowing + * any properties that are unique to that parser to be set for that load. + * + * The bundled parsers are: + * + *
    + *
  • AC3D (.ac)
  • + *
  • Away Data version 1 ASCII and version 2 binary (.awd). AWD1 BSP unsupported
  • + *
  • 3DMax (.3ds)
  • + *
  • DXF (.dxf)
  • + *
  • Quake 2 MD2 models (.md2)
  • + *
  • Doom 3 MD5 animation clips (.md5anim)
  • + *
  • Doom 3 MD5 meshes (.md5mesh)
  • + *
  • Wavefront OBJ (.obj)
  • + *
  • Collada (.dae)
  • + *
  • Images (.jpg, .png)
  • + *
+ * + * @see away.library.AssetLibrary.enableParser + */ + Parsers.ALL_BUNDLED = Array(AWDParser, Max3DSParser, MD2Parser, OBJParser); + return Parsers; +})(); +module.exports = Parsers; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvcGFyc2Vycy50cyJdLCJuYW1lcyI6WyJQYXJzZXJzIiwiUGFyc2Vycy5jb25zdHJ1Y3RvciIsIlBhcnNlcnMuZW5hYmxlQWxsQnVuZGxlZCJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTyxXQUFXLFdBQWdCLDBDQUEwQyxDQUFDLENBQUM7QUFFOUUsSUFBTyxTQUFTLFdBQWdCLHlDQUF5QyxDQUFDLENBQUM7QUFDM0UsSUFBTyxZQUFZLFdBQWdCLDRDQUE0QyxDQUFDLENBQUM7QUFDakYsSUFBTyxTQUFTLFdBQWdCLHlDQUF5QyxDQUFDLENBQUM7QUFDM0UsSUFBTyxTQUFTLFdBQWdCLHlDQUF5QyxDQUFDLENBQUM7QUFFM0UsQUFHQTs7R0FERztJQUNHLE9BQU87SUFBYkEsU0FBTUEsT0FBT0E7SUFrRGJDLENBQUNBO0lBYkFEOzs7Ozs7OztPQVFHQTtJQUNXQSx3QkFBZ0JBLEdBQTlCQTtRQUVDRSxXQUFXQSxDQUFDQSxhQUFhQSxDQUFDQSxPQUFPQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtJQUNoREEsQ0FBQ0E7SUEvQ0RGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWdDR0E7SUFDV0EsbUJBQVdBLEdBQWlCQSxLQUFLQSxDQUFTQSxTQUFTQSxFQUFFQSxZQUFZQSxFQUFFQSxTQUFTQSxFQUFFQSxTQUFTQSxDQUFDQSxDQUFDQTtJQWV4R0EsY0FBQ0E7QUFBREEsQ0FsREEsQUFrRENBLElBQUE7QUFFRCxBQUFpQixpQkFBUixPQUFPLENBQUMiLCJmaWxlIjoicGFyc2Vycy9QYXJzZXJzLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFzc2V0TG9hZGVyXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclwiKTtcblxuaW1wb3J0IEFXRFBhcnNlclx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL0FXRFBhcnNlclwiKTtcbmltcG9ydCBNYXgzRFNQYXJzZXJcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9NYXgzRFNQYXJzZXJcIik7XG5pbXBvcnQgTUQyUGFyc2VyXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvTUQyUGFyc2VyXCIpO1xuaW1wb3J0IE9CSlBhcnNlclx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL09CSlBhcnNlclwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBQYXJzZXJzXG57XG5cdC8qKlxuXHQgKiBBIGxpc3Qgb2YgYWxsIHBhcnNlcnMgdGhhdCBjb21lIGJ1bmRsZWQgd2l0aCBBd2F5M0QuIFVzZSB0aGlzIHRvIHF1aWNrbHlcblx0ICogZW5hYmxlIHN1cHBvcnQgZm9yIGFsbCBidW5kbGVkIHBhcnNlcnMgdG8gdGhlIGZpbGUgZm9ybWF0IGF1dG8tZGV0ZWN0aW9uXG5cdCAqIGZlYXR1cmUsIHVzaW5nIGFueSBvZiB0aGUgZW5hYmxlUGFyc2VycygpIG1ldGhvZHMgb24gbG9hZGVycywgZS5nLjpcblx0ICpcblx0ICogPGNvZGU+QXNzZXRMaWJyYXJ5LmVuYWJsZVBhcnNlcnMoUGFyc2Vycy5BTExfQlVORExFRCk7PC9jb2RlPlxuXHQgKlxuXHQgKiBCZXdhcmUgaG93ZXZlciB0aGF0IHRoaXMgcmVxdWlyZXMgYWxsIHBhcnNlciBjbGFzc2VzIHRvIGJlIGluY2x1ZGVkIGluIHRoZVxuXHQgKiBTV0YgZmlsZSwgd2hpY2ggd2lsbCBhZGQgNTAtMTAwIGtiIHRvIHRoZSBmaWxlLiBXaGVuIG9ubHkgYSBsaW1pdGVkIHNldCBvZlxuXHQgKiBmaWxlIGZvcm1hdHMgYXJlIHVzZWQsIFNXRiBmaWxlIHNpemUgY2FuIGJlIHNhdmVkIGJ5IGFkZGluZyB0aGUgcGFyc2Vyc1xuXHQgKiBpbmRpdmlkdWFsbHkgdXNpbmcgQXNzZXRMaWJyYXJ5LmVuYWJsZVBhcnNlcigpXG5cdCAqXG5cdCAqIEEgdGhpcmQgd2F5IGlzIHRvIHNwZWNpZnkgYSBwYXJzZXIgZm9yIGVhY2ggbG9hZGVkIGZpbGUsIHRoZXJlYnkgYnlwYXNzaW5nXG5cdCAqIHRoZSBhdXRvLWRldGVjdGlvbiBtZWNoYW5pc21zIGFsdG9nZXRoZXIsIHdoaWxlIGF0IHRoZSBzYW1lIHRpbWUgYWxsb3dpbmdcblx0ICogYW55IHByb3BlcnRpZXMgdGhhdCBhcmUgdW5pcXVlIHRvIHRoYXQgcGFyc2VyIHRvIGJlIHNldCBmb3IgdGhhdCBsb2FkLlxuXHQgKlxuXHQgKiBUaGUgYnVuZGxlZCBwYXJzZXJzIGFyZTpcblx0ICpcblx0ICogPHVsPlxuXHQgKiA8bGk+QUMzRCAoLmFjKTwvbGk+XG5cdCAqIDxsaT5Bd2F5IERhdGEgdmVyc2lvbiAxIEFTQ0lJIGFuZCB2ZXJzaW9uIDIgYmluYXJ5ICguYXdkKS4gQVdEMSBCU1AgdW5zdXBwb3J0ZWQ8L2xpPlxuXHQgKiA8bGk+M0RNYXggKC4zZHMpPC9saT5cblx0ICogPGxpPkRYRiAoLmR4Zik8L2xpPlxuXHQgKiA8bGk+UXVha2UgMiBNRDIgbW9kZWxzICgubWQyKTwvbGk+XG5cdCAqIDxsaT5Eb29tIDMgTUQ1IGFuaW1hdGlvbiBjbGlwcyAoLm1kNWFuaW0pPC9saT5cblx0ICogPGxpPkRvb20gMyBNRDUgbWVzaGVzICgubWQ1bWVzaCk8L2xpPlxuXHQgKiA8bGk+V2F2ZWZyb250IE9CSiAoLm9iaik8L2xpPlxuXHQgKiA8bGk+Q29sbGFkYSAoLmRhZSk8L2xpPlxuXHQgKiA8bGk+SW1hZ2VzICguanBnLCAucG5nKTwvbGk+XG5cdCAqIDwvdWw+XG5cdCAqXG5cdCAqIEBzZWUgYXdheS5saWJyYXJ5LkFzc2V0TGlicmFyeS5lbmFibGVQYXJzZXJcblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgQUxMX0JVTkRMRUQ6QXJyYXk8T2JqZWN0PiA9IEFycmF5PE9iamVjdD4oQVdEUGFyc2VyLCBNYXgzRFNQYXJzZXIsIE1EMlBhcnNlciwgT0JKUGFyc2VyKTtcblxuXHQvKipcblx0ICogU2hvcnQtaGFuZCBmdW5jdGlvbiB0byBlbmFibGUgYWxsIGJ1bmRsZWQgcGFyc2VycyBmb3IgYXV0by1kZXRlY3Rpb24uIEluIHByYWN0aWNlLFxuXHQgKiB0aGlzIGlzIHRoZSBzYW1lIGFzIGludm9raW5nIGVuYWJsZVBhcnNlcnMoUGFyc2Vycy5BTExfQlVORExFRCkgb24gYW55IG9mIHRoZVxuXHQgKiBsb2FkZXIgY2xhc3NlcyBTaW5nbGVGaWxlTG9hZGVyLCBBc3NldExvYWRlciwgQXNzZXRMaWJyYXJ5IG9yIExvYWRlcjNELlxuXHQgKlxuXHQgKiBTZWUgbm90ZXMgYWJvdXQgZmlsZSBzaXplIGluIHRoZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgQUxMX0JVTkRMRUQgY29uc3RhbnQuXG5cdCAqXG5cdCAqIEBzZWUgYXdheS5wYXJzZXJzLlBhcnNlcnMuQUxMX0JVTkRMRURcblx0ICovXG5cdHB1YmxpYyBzdGF0aWMgZW5hYmxlQWxsQnVuZGxlZCgpOnZvaWRcblx0e1xuXHRcdEFzc2V0TG9hZGVyLmVuYWJsZVBhcnNlcnMoUGFyc2Vycy5BTExfQlVORExFRCk7XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFyc2VyczsiXX0= \ No newline at end of file diff --git a/lib/parsers/Parsers.ts b/lib/parsers/Parsers.ts new file mode 100644 index 000000000..ae5b2590d --- /dev/null +++ b/lib/parsers/Parsers.ts @@ -0,0 +1,63 @@ +import AssetLoader = require("awayjs-core/lib/core/library/AssetLoader"); + +import AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +import Max3DSParser = require("awayjs-renderergl/lib/parsers/Max3DSParser"); +import MD2Parser = require("awayjs-renderergl/lib/parsers/MD2Parser"); +import OBJParser = require("awayjs-renderergl/lib/parsers/OBJParser"); + +/** + * + */ +class Parsers +{ + /** + * A list of all parsers that come bundled with Away3D. Use this to quickly + * enable support for all bundled parsers to the file format auto-detection + * feature, using any of the enableParsers() methods on loaders, e.g.: + * + * AssetLibrary.enableParsers(Parsers.ALL_BUNDLED); + * + * Beware however that this requires all parser classes to be included in the + * SWF file, which will add 50-100 kb to the file. When only a limited set of + * file formats are used, SWF file size can be saved by adding the parsers + * individually using AssetLibrary.enableParser() + * + * A third way is to specify a parser for each loaded file, thereby bypassing + * the auto-detection mechanisms altogether, while at the same time allowing + * any properties that are unique to that parser to be set for that load. + * + * The bundled parsers are: + * + *
    + *
  • AC3D (.ac)
  • + *
  • Away Data version 1 ASCII and version 2 binary (.awd). AWD1 BSP unsupported
  • + *
  • 3DMax (.3ds)
  • + *
  • DXF (.dxf)
  • + *
  • Quake 2 MD2 models (.md2)
  • + *
  • Doom 3 MD5 animation clips (.md5anim)
  • + *
  • Doom 3 MD5 meshes (.md5mesh)
  • + *
  • Wavefront OBJ (.obj)
  • + *
  • Collada (.dae)
  • + *
  • Images (.jpg, .png)
  • + *
+ * + * @see away.library.AssetLibrary.enableParser + */ + public static ALL_BUNDLED:Array = Array(AWDParser, Max3DSParser, MD2Parser, OBJParser); + + /** + * Short-hand function to enable all bundled parsers for auto-detection. In practice, + * this is the same as invoking enableParsers(Parsers.ALL_BUNDLED) on any of the + * loader classes SingleFileLoader, AssetLoader, AssetLibrary or Loader3D. + * + * See notes about file size in the documentation for the ALL_BUNDLED constant. + * + * @see away.parsers.Parsers.ALL_BUNDLED + */ + public static enableAllBundled():void + { + AssetLoader.enableParsers(Parsers.ALL_BUNDLED); + } +} + +export = Parsers; \ No newline at end of file diff --git a/lib/parsers/data/AWDBlock.js b/lib/parsers/data/AWDBlock.js new file mode 100755 index 000000000..279d78b75 --- /dev/null +++ b/lib/parsers/data/AWDBlock.js @@ -0,0 +1,22 @@ +/** + * + */ +var AWDBlock = (function () { + function AWDBlock() { + } + AWDBlock.prototype.dispose = function () { + this.id = null; + this.bytes = null; + this.errorMessages = null; + this.uvsForVertexAnimation = null; + }; + AWDBlock.prototype.addError = function (errorMsg) { + if (!this.errorMessages) + this.errorMessages = new Array(); + this.errorMessages.push(errorMsg); + }; + return AWDBlock; +})(); +module.exports = AWDBlock; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9hd2RibG9jay50cyJdLCJuYW1lcyI6WyJBV0RCbG9jayIsIkFXREJsb2NrLmNvbnN0cnVjdG9yIiwiQVdEQmxvY2suZGlzcG9zZSIsIkFXREJsb2NrLmFkZEVycm9yIl0sIm1hcHBpbmdzIjoiQUFFQSxBQUdBOztHQURHO0lBQ0csUUFBUTtJQVliQSxTQVpLQSxRQUFRQTtJQWNiQyxDQUFDQTtJQUVNRCwwQkFBT0EsR0FBZEE7UUFHQ0UsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDZkEsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDbEJBLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO1FBQzFCQSxJQUFJQSxDQUFDQSxxQkFBcUJBLEdBQUdBLElBQUlBLENBQUNBO0lBRW5DQSxDQUFDQTtJQUVNRiwyQkFBUUEsR0FBZkEsVUFBZ0JBLFFBQWVBO1FBRTlCRyxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtZQUN2QkEsSUFBSUEsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBQ0E7UUFFMUNBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBO0lBQ25DQSxDQUFDQTtJQUNGSCxlQUFDQTtBQUFEQSxDQWpDQSxBQWlDQ0EsSUFBQTtBQUVELEFBQWtCLGlCQUFULFFBQVEsQ0FBQyIsImZpbGUiOiJwYXJzZXJzL2RhdGEvQVdEQmxvY2suanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQnl0ZUFycmF5XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL0J5dGVBcnJheVwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBBV0RCbG9ja1xue1xuXHRwdWJsaWMgaWQ6bnVtYmVyO1xuXHRwdWJsaWMgbmFtZTpzdHJpbmc7XG5cdHB1YmxpYyBkYXRhOmFueTtcblx0cHVibGljIGxlbjphbnk7XG5cdHB1YmxpYyBnZW9JRDpudW1iZXI7XG5cdHB1YmxpYyBleHRyYXM6T2JqZWN0O1xuXHRwdWJsaWMgYnl0ZXM6Qnl0ZUFycmF5O1xuXHRwdWJsaWMgZXJyb3JNZXNzYWdlczpBcnJheTxzdHJpbmc+O1xuXHRwdWJsaWMgdXZzRm9yVmVydGV4QW5pbWF0aW9uOkFycmF5PEFycmF5PG51bWJlcj4+O1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHR9XG5cblx0cHVibGljIGRpc3Bvc2UoKVxuXHR7XG5cblx0XHR0aGlzLmlkID0gbnVsbDtcblx0XHR0aGlzLmJ5dGVzID0gbnVsbDtcblx0XHR0aGlzLmVycm9yTWVzc2FnZXMgPSBudWxsO1xuXHRcdHRoaXMudXZzRm9yVmVydGV4QW5pbWF0aW9uID0gbnVsbDtcblxuXHR9XG5cblx0cHVibGljIGFkZEVycm9yKGVycm9yTXNnOnN0cmluZyk6dm9pZFxuXHR7XG5cdFx0aWYgKCF0aGlzLmVycm9yTWVzc2FnZXMpXG5cdFx0XHR0aGlzLmVycm9yTWVzc2FnZXMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG5cdFx0dGhpcy5lcnJvck1lc3NhZ2VzLnB1c2goZXJyb3JNc2cpO1xuXHR9XG59XG5cbmV4cG9ydCA9IEFXREJsb2NrOyJdfQ== \ No newline at end of file diff --git a/lib/parsers/data/AWDBlock.ts b/lib/parsers/data/AWDBlock.ts new file mode 100644 index 000000000..107b252e6 --- /dev/null +++ b/lib/parsers/data/AWDBlock.ts @@ -0,0 +1,41 @@ +import ByteArray = require("awayjs-core/lib/utils/ByteArray"); + +/** + * + */ +class AWDBlock +{ + public id:number; + public name:string; + public data:any; + public len:any; + public geoID:number; + public extras:Object; + public bytes:ByteArray; + public errorMessages:Array; + public uvsForVertexAnimation:Array>; + + constructor() + { + } + + public dispose() + { + + this.id = null; + this.bytes = null; + this.errorMessages = null; + this.uvsForVertexAnimation = null; + + } + + public addError(errorMsg:string):void + { + if (!this.errorMessages) + this.errorMessages = new Array(); + + this.errorMessages.push(errorMsg); + } +} + +export = AWDBlock; \ No newline at end of file diff --git a/lib/parsers/data/AWDProperties.js b/lib/parsers/data/AWDProperties.js new file mode 100755 index 000000000..3724a3e7b --- /dev/null +++ b/lib/parsers/data/AWDProperties.js @@ -0,0 +1,19 @@ +var AWDProperties = (function () { + function AWDProperties() { + } + AWDProperties.prototype.set = function (key, value) { + this[key.toString()] = value; + }; + AWDProperties.prototype.get = function (key, fallback) { + if (this.hasOwnProperty(key.toString())) { + return this[key.toString()]; + } + else { + return fallback; + } + }; + return AWDProperties; +})(); +module.exports = AWDProperties; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9hd2Rwcm9wZXJ0aWVzLnRzIl0sIm5hbWVzIjpbIkFXRFByb3BlcnRpZXMiLCJBV0RQcm9wZXJ0aWVzLmNvbnN0cnVjdG9yIiwiQVdEUHJvcGVydGllcy5zZXQiLCJBV0RQcm9wZXJ0aWVzLmdldCJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTSxhQUFhO0lBQW5CQSxTQUFNQSxhQUFhQTtJQWVuQkMsQ0FBQ0E7SUFiT0QsMkJBQUdBLEdBQVZBLFVBQVdBLEdBQVVBLEVBQUVBLEtBQVNBO1FBRS9CRSxJQUFJQSxDQUFFQSxHQUFHQSxDQUFDQSxRQUFRQSxFQUFFQSxDQUFFQSxHQUFHQSxLQUFLQSxDQUFDQTtJQUNoQ0EsQ0FBQ0E7SUFFTUYsMkJBQUdBLEdBQVZBLFVBQVdBLEdBQVVBLEVBQUVBLFFBQVlBO1FBRWxDRyxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxHQUFHQSxDQUFDQSxRQUFRQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUN6Q0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsUUFBUUEsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLENBQUNBO1FBQUNBLElBQUlBLENBQUNBLENBQUNBO1lBQ1BBLE1BQU1BLENBQUNBLFFBQVFBLENBQUNBO1FBQ2pCQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUNGSCxvQkFBQ0E7QUFBREEsQ0FmQSxBQWVDQSxJQUFBO0FBRUQsQUFBdUIsaUJBQWQsYUFBYSxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9BV0RQcm9wZXJ0aWVzLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgQVdEUHJvcGVydGllc1xue1xuXHRwdWJsaWMgc2V0KGtleTpudW1iZXIsIHZhbHVlOmFueSk6dm9pZFxuXHR7XG5cdFx0dGhpc1sga2V5LnRvU3RyaW5nKCkgXSA9IHZhbHVlO1xuXHR9XG5cblx0cHVibGljIGdldChrZXk6bnVtYmVyLCBmYWxsYmFjazphbnkpOmFueVxuXHR7XG5cdFx0aWYgKHRoaXMuaGFzT3duUHJvcGVydHkoa2V5LnRvU3RyaW5nKCkpKSB7XG5cdFx0XHRyZXR1cm4gdGhpc1trZXkudG9TdHJpbmcoKV07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmYWxsYmFjaztcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0ID0gQVdEUHJvcGVydGllczsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/AWDProperties.ts b/lib/parsers/data/AWDProperties.ts new file mode 100644 index 000000000..214081e9b --- /dev/null +++ b/lib/parsers/data/AWDProperties.ts @@ -0,0 +1,18 @@ +class AWDProperties +{ + public set(key:number, value:any):void + { + this[ key.toString() ] = value; + } + + public get(key:number, fallback:any):any + { + if (this.hasOwnProperty(key.toString())) { + return this[key.toString()]; + } else { + return fallback; + } + } +} + +export = AWDProperties; \ No newline at end of file diff --git a/lib/parsers/data/BaseFrameData.js b/lib/parsers/data/BaseFrameData.js new file mode 100755 index 000000000..81d8cefbf --- /dev/null +++ b/lib/parsers/data/BaseFrameData.js @@ -0,0 +1,11 @@ +/** + * + */ +var BaseFrameData = (function () { + function BaseFrameData() { + } + return BaseFrameData; +})(); +module.exports = BaseFrameData; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9iYXNlZnJhbWVkYXRhLnRzIl0sIm5hbWVzIjpbIkJhc2VGcmFtZURhdGEiLCJCYXNlRnJhbWVEYXRhLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFHQSxBQUdBOztHQURHO0lBQ0csYUFBYTtJQUFuQkEsU0FBTUEsYUFBYUE7SUFXbkJDLENBQUNBO0lBQURELG9CQUFDQTtBQUFEQSxDQVhBLEFBV0NBLElBQUE7QUFFRCxBQUF1QixpQkFBZCxhQUFhLENBQUMiLCJmaWxlIjoicGFyc2Vycy9kYXRhL0Jhc2VGcmFtZURhdGEuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUXVhdGVybmlvblx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vUXVhdGVybmlvblwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuLyoqXG4gKiBcbiAqL1xuY2xhc3MgQmFzZUZyYW1lRGF0YVxue1xuXHQvKipcblx0ICpcblx0ICovXG5cdHB1YmxpYyBwb3NpdGlvbjpWZWN0b3IzRDtcblxuXHQvKipcblx0ICpcblx0ICovXG5cdHB1YmxpYyBvcmllbnRhdGlvbjpRdWF0ZXJuaW9uO1xufVxuXG5leHBvcnQgPSBCYXNlRnJhbWVEYXRhOyJdfQ== \ No newline at end of file diff --git a/lib/parsers/data/BaseFrameData.ts b/lib/parsers/data/BaseFrameData.ts new file mode 100644 index 000000000..7076ace64 --- /dev/null +++ b/lib/parsers/data/BaseFrameData.ts @@ -0,0 +1,20 @@ +import Quaternion = require("awayjs-core/lib/core/geom/Quaternion"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); + +/** + * + */ +class BaseFrameData +{ + /** + * + */ + public position:Vector3D; + + /** + * + */ + public orientation:Quaternion; +} + +export = BaseFrameData; \ No newline at end of file diff --git a/lib/parsers/data/BitFlags.js b/lib/parsers/data/BitFlags.js new file mode 100755 index 000000000..2177d07af --- /dev/null +++ b/lib/parsers/data/BitFlags.js @@ -0,0 +1,30 @@ +/** + * + */ +var BitFlags = (function () { + function BitFlags() { + } + BitFlags.test = function (flags, testFlag) { + return (flags & testFlag) == testFlag; + }; + BitFlags.FLAG1 = 1; + BitFlags.FLAG2 = 2; + BitFlags.FLAG3 = 4; + BitFlags.FLAG4 = 8; + BitFlags.FLAG5 = 16; + BitFlags.FLAG6 = 32; + BitFlags.FLAG7 = 64; + BitFlags.FLAG8 = 128; + BitFlags.FLAG9 = 256; + BitFlags.FLAG10 = 512; + BitFlags.FLAG11 = 1024; + BitFlags.FLAG12 = 2048; + BitFlags.FLAG13 = 4096; + BitFlags.FLAG14 = 8192; + BitFlags.FLAG15 = 16384; + BitFlags.FLAG16 = 32768; + return BitFlags; +})(); +module.exports = BitFlags; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9iaXRmbGFncy50cyJdLCJuYW1lcyI6WyJCaXRGbGFncyIsIkJpdEZsYWdzLmNvbnN0cnVjdG9yIiwiQml0RmxhZ3MudGVzdCJdLCJtYXBwaW5ncyI6IkFBQUEsQUFHQTs7R0FERztJQUNHLFFBQVE7SUFBZEEsU0FBTUEsUUFBUUE7SUF1QmRDLENBQUNBO0lBSmNELGFBQUlBLEdBQWxCQSxVQUFtQkEsS0FBWUEsRUFBRUEsUUFBZUE7UUFFL0NFLE1BQU1BLENBQUNBLENBQUNBLEtBQUtBLEdBQUdBLFFBQVFBLENBQUNBLElBQUlBLFFBQVFBLENBQUNBO0lBQ3ZDQSxDQUFDQTtJQXBCYUYsY0FBS0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7SUFDakJBLGNBQUtBLEdBQVVBLENBQUNBLENBQUNBO0lBQ2pCQSxjQUFLQSxHQUFVQSxDQUFDQSxDQUFDQTtJQUNqQkEsY0FBS0EsR0FBVUEsQ0FBQ0EsQ0FBQ0E7SUFDakJBLGNBQUtBLEdBQVVBLEVBQUVBLENBQUNBO0lBQ2xCQSxjQUFLQSxHQUFVQSxFQUFFQSxDQUFDQTtJQUNsQkEsY0FBS0EsR0FBVUEsRUFBRUEsQ0FBQ0E7SUFDbEJBLGNBQUtBLEdBQVVBLEdBQUdBLENBQUNBO0lBQ25CQSxjQUFLQSxHQUFVQSxHQUFHQSxDQUFDQTtJQUNuQkEsZUFBTUEsR0FBVUEsR0FBR0EsQ0FBQ0E7SUFDcEJBLGVBQU1BLEdBQVVBLElBQUlBLENBQUNBO0lBQ3JCQSxlQUFNQSxHQUFVQSxJQUFJQSxDQUFDQTtJQUNyQkEsZUFBTUEsR0FBVUEsSUFBSUEsQ0FBQ0E7SUFDckJBLGVBQU1BLEdBQVVBLElBQUlBLENBQUNBO0lBQ3JCQSxlQUFNQSxHQUFVQSxLQUFLQSxDQUFDQTtJQUN0QkEsZUFBTUEsR0FBVUEsS0FBS0EsQ0FBQ0E7SUFNckNBLGVBQUNBO0FBQURBLENBdkJBLEFBdUJDQSxJQUFBO0FBRUQsQUFBa0IsaUJBQVQsUUFBUSxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9CaXRGbGFncy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICpcbiAqL1xuY2xhc3MgQml0RmxhZ3Ncbntcblx0cHVibGljIHN0YXRpYyBGTEFHMTpudW1iZXIgPSAxO1xuXHRwdWJsaWMgc3RhdGljIEZMQUcyOm51bWJlciA9IDI7XG5cdHB1YmxpYyBzdGF0aWMgRkxBRzM6bnVtYmVyID0gNDtcblx0cHVibGljIHN0YXRpYyBGTEFHNDpudW1iZXIgPSA4O1xuXHRwdWJsaWMgc3RhdGljIEZMQUc1Om51bWJlciA9IDE2O1xuXHRwdWJsaWMgc3RhdGljIEZMQUc2Om51bWJlciA9IDMyO1xuXHRwdWJsaWMgc3RhdGljIEZMQUc3Om51bWJlciA9IDY0O1xuXHRwdWJsaWMgc3RhdGljIEZMQUc4Om51bWJlciA9IDEyODtcblx0cHVibGljIHN0YXRpYyBGTEFHOTpudW1iZXIgPSAyNTY7XG5cdHB1YmxpYyBzdGF0aWMgRkxBRzEwOm51bWJlciA9IDUxMjtcblx0cHVibGljIHN0YXRpYyBGTEFHMTE6bnVtYmVyID0gMTAyNDtcblx0cHVibGljIHN0YXRpYyBGTEFHMTI6bnVtYmVyID0gMjA0ODtcblx0cHVibGljIHN0YXRpYyBGTEFHMTM6bnVtYmVyID0gNDA5Njtcblx0cHVibGljIHN0YXRpYyBGTEFHMTQ6bnVtYmVyID0gODE5Mjtcblx0cHVibGljIHN0YXRpYyBGTEFHMTU6bnVtYmVyID0gMTYzODQ7XG5cdHB1YmxpYyBzdGF0aWMgRkxBRzE2Om51bWJlciA9IDMyNzY4O1xuXG5cdHB1YmxpYyBzdGF0aWMgdGVzdChmbGFnczpudW1iZXIsIHRlc3RGbGFnOm51bWJlcik6Ym9vbGVhblxuXHR7XG5cdFx0cmV0dXJuIChmbGFncyAmIHRlc3RGbGFnKSA9PSB0ZXN0RmxhZztcblx0fVxufVxuXG5leHBvcnQgPSBCaXRGbGFnczsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/BitFlags.ts b/lib/parsers/data/BitFlags.ts new file mode 100644 index 000000000..968468dbb --- /dev/null +++ b/lib/parsers/data/BitFlags.ts @@ -0,0 +1,29 @@ +/** + * + */ +class BitFlags +{ + public static FLAG1:number = 1; + public static FLAG2:number = 2; + public static FLAG3:number = 4; + public static FLAG4:number = 8; + public static FLAG5:number = 16; + public static FLAG6:number = 32; + public static FLAG7:number = 64; + public static FLAG8:number = 128; + public static FLAG9:number = 256; + public static FLAG10:number = 512; + public static FLAG11:number = 1024; + public static FLAG12:number = 2048; + public static FLAG13:number = 4096; + public static FLAG14:number = 8192; + public static FLAG15:number = 16384; + public static FLAG16:number = 32768; + + public static test(flags:number, testFlag:number):boolean + { + return (flags & testFlag) == testFlag; + } +} + +export = BitFlags; \ No newline at end of file diff --git a/lib/parsers/data/BoundsData.js b/lib/parsers/data/BoundsData.js new file mode 100755 index 000000000..46ac6b1e4 --- /dev/null +++ b/lib/parsers/data/BoundsData.js @@ -0,0 +1,11 @@ +/** + * + */ +var BoundsData = (function () { + function BoundsData() { + } + return BoundsData; +})(); +module.exports = BoundsData; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9ib3VuZHNkYXRhLnRzIl0sIm5hbWVzIjpbIkJvdW5kc0RhdGEiLCJCb3VuZHNEYXRhLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFFQSxBQUdBOztHQURHO0lBQ0csVUFBVTtJQUFoQkEsU0FBTUEsVUFBVUE7SUFXaEJDLENBQUNBO0lBQURELGlCQUFDQTtBQUFEQSxDQVhBLEFBV0NBLElBQUE7QUFFRCxBQUFvQixpQkFBWCxVQUFVLENBQUMiLCJmaWxlIjoicGFyc2Vycy9kYXRhL0JvdW5kc0RhdGEuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5cbi8qKlxuICogXG4gKi9cbmNsYXNzIEJvdW5kc0RhdGFcbntcblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgbWluOlZlY3RvcjNEO1xuXG5cdC8qKlxuXHQgKlxuXHQgKi9cblx0cHVibGljIG1heDpWZWN0b3IzRDtcbn1cblxuZXhwb3J0ID0gQm91bmRzRGF0YTsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/BoundsData.ts b/lib/parsers/data/BoundsData.ts new file mode 100644 index 000000000..92dc77501 --- /dev/null +++ b/lib/parsers/data/BoundsData.ts @@ -0,0 +1,19 @@ +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); + +/** + * + */ +class BoundsData +{ + /** + * + */ + public min:Vector3D; + + /** + * + */ + public max:Vector3D; +} + +export = BoundsData; \ No newline at end of file diff --git a/lib/parsers/data/FaceVO.js b/lib/parsers/data/FaceVO.js new file mode 100755 index 000000000..e98944040 --- /dev/null +++ b/lib/parsers/data/FaceVO.js @@ -0,0 +1,11 @@ +/** + * + */ +var FaceVO = (function () { + function FaceVO() { + } + return FaceVO; +})(); +module.exports = FaceVO; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9mYWNldm8udHMiXSwibmFtZXMiOlsiRmFjZVZPIiwiRmFjZVZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQSxBQUdBOztHQURHO0lBQ0csTUFBTTtJQUFaQSxTQUFNQSxNQUFNQTtJQU1aQyxDQUFDQTtJQUFERCxhQUFDQTtBQUFEQSxDQU5BLEFBTUNBLElBQUE7QUFFRCxBQUFnQixpQkFBUCxNQUFNLENBQUMiLCJmaWxlIjoicGFyc2Vycy9kYXRhL0ZhY2VWTy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICpcbiAqL1xuY2xhc3MgRmFjZVZPXG57XG5cdHB1YmxpYyBhOm51bWJlciAvKmludCovO1xuXHRwdWJsaWMgYjpudW1iZXIgLyppbnQqLztcblx0cHVibGljIGM6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyBzbW9vdGhHcm91cDpudW1iZXIgLyppbnQqLztcbn1cblxuZXhwb3J0ID0gRmFjZVZPOyJdfQ== \ No newline at end of file diff --git a/lib/parsers/data/FaceVO.ts b/lib/parsers/data/FaceVO.ts new file mode 100644 index 000000000..3474416d8 --- /dev/null +++ b/lib/parsers/data/FaceVO.ts @@ -0,0 +1,12 @@ +/** + * + */ +class FaceVO +{ + public a:number /*int*/; + public b:number /*int*/; + public c:number /*int*/; + public smoothGroup:number /*int*/; +} + +export = FaceVO; \ No newline at end of file diff --git a/lib/parsers/data/FrameData.js b/lib/parsers/data/FrameData.js new file mode 100755 index 000000000..83ede906b --- /dev/null +++ b/lib/parsers/data/FrameData.js @@ -0,0 +1,11 @@ +/** + * + */ +var FrameData = (function () { + function FrameData() { + } + return FrameData; +})(); +module.exports = FrameData; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9mcmFtZWRhdGEudHMiXSwibmFtZXMiOlsiRnJhbWVEYXRhIiwiRnJhbWVEYXRhLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQSxBQUdBOztHQURHO0lBQ0csU0FBUztJQUFmQSxTQUFNQSxTQUFTQTtJQVdmQyxDQUFDQTtJQUFERCxnQkFBQ0E7QUFBREEsQ0FYQSxBQVdDQSxJQUFBO0FBRUQsQUFBbUIsaUJBQVYsU0FBUyxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9GcmFtZURhdGEuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqXG4gKi9cbmNsYXNzIEZyYW1lRGF0YVxue1xuXHQvKipcblx0ICpcblx0ICovXG5cdHB1YmxpYyBpbmRleDpudW1iZXIgLyppbnQqLztcblxuXHQvKipcblx0ICpcblx0ICovXG5cdHB1YmxpYyBjb21wb25lbnRzOkFycmF5PG51bWJlcj47XG59XG5cbmV4cG9ydCA9IEZyYW1lRGF0YTsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/FrameData.ts b/lib/parsers/data/FrameData.ts new file mode 100644 index 000000000..9ca2e1328 --- /dev/null +++ b/lib/parsers/data/FrameData.ts @@ -0,0 +1,17 @@ +/** + * + */ +class FrameData +{ + /** + * + */ + public index:number /*int*/; + + /** + * + */ + public components:Array; +} + +export = FrameData; \ No newline at end of file diff --git a/lib/parsers/data/HierarchyData.js b/lib/parsers/data/HierarchyData.js new file mode 100755 index 000000000..35dfd619e --- /dev/null +++ b/lib/parsers/data/HierarchyData.js @@ -0,0 +1,11 @@ +/** + * + */ +var HierarchyData = (function () { + function HierarchyData() { + } + return HierarchyData; +})(); +module.exports = HierarchyData; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9oaWVyYXJjaHlkYXRhLnRzIl0sIm5hbWVzIjpbIkhpZXJhcmNoeURhdGEiLCJIaWVyYXJjaHlEYXRhLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQSxBQUdBOztHQURHO0lBQ0csYUFBYTtJQUFuQkEsU0FBTUEsYUFBYUE7SUFxQm5CQyxDQUFDQTtJQUFERCxvQkFBQ0E7QUFBREEsQ0FyQkEsQUFxQkNBLElBQUE7QUFFRCxBQUF1QixpQkFBZCxhQUFhLENBQUMiLCJmaWxlIjoicGFyc2Vycy9kYXRhL0hpZXJhcmNoeURhdGEuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqXG4gKi9cbmNsYXNzIEhpZXJhcmNoeURhdGFcbntcblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgbmFtZTpzdHJpbmc7XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgcGFyZW50SW5kZXg6bnVtYmVyIC8qaW50Ki87XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgZmxhZ3M6bnVtYmVyIC8qaW50Ki87XG5cblx0LyoqXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgc3RhcnRJbmRleDpudW1iZXIgLyppbnQqLztcbn1cblxuZXhwb3J0ID0gSGllcmFyY2h5RGF0YTsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/HierarchyData.ts b/lib/parsers/data/HierarchyData.ts new file mode 100644 index 000000000..ed06ddce7 --- /dev/null +++ b/lib/parsers/data/HierarchyData.ts @@ -0,0 +1,27 @@ +/** + * + */ +class HierarchyData +{ + /** + * + */ + public name:string; + + /** + * + */ + public parentIndex:number /*int*/; + + /** + * + */ + public flags:number /*int*/; + + /** + * + */ + public startIndex:number /*int*/; +} + +export = HierarchyData; \ No newline at end of file diff --git a/lib/parsers/data/MaterialVO.js b/lib/parsers/data/MaterialVO.js new file mode 100755 index 000000000..d66542769 --- /dev/null +++ b/lib/parsers/data/MaterialVO.js @@ -0,0 +1,11 @@ +/** + * + */ +var MaterialVO = (function () { + function MaterialVO() { + } + return MaterialVO; +})(); +module.exports = MaterialVO; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9tYXRlcmlhbHZvLnRzIl0sIm5hbWVzIjpbIk1hdGVyaWFsVk8iLCJNYXRlcmlhbFZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFJQSxBQUdBOztHQURHO0lBQ0csVUFBVTtJQUFoQkEsU0FBTUEsVUFBVUE7SUFVaEJDLENBQUNBO0lBQURELGlCQUFDQTtBQUFEQSxDQVZBLEFBVUNBLElBQUE7QUFFRCxBQUFvQixpQkFBWCxVQUFVLENBQUMiLCJmaWxlIjoicGFyc2Vycy9kYXRhL01hdGVyaWFsVk8uanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTWF0ZXJpYWxCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9NYXRlcmlhbEJhc2VcIik7XG5cbmltcG9ydCBUZXh0dXJlVk9cdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9kYXRhL1RleHR1cmVWT1wiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBNYXRlcmlhbFZPXG57XG5cdHB1YmxpYyBuYW1lOnN0cmluZztcblx0cHVibGljIGFtYmllbnRDb2xvcjpudW1iZXIgLyppbnQqLztcblx0cHVibGljIGRpZmZ1c2VDb2xvcjpudW1iZXIgLyppbnQqLztcblx0cHVibGljIHNwZWN1bGFyQ29sb3I6bnVtYmVyIC8qaW50Ki87XG5cdHB1YmxpYyB0d29TaWRlZDpib29sZWFuO1xuXHRwdWJsaWMgY29sb3JNYXA6VGV4dHVyZVZPO1xuXHRwdWJsaWMgc3BlY3VsYXJNYXA6VGV4dHVyZVZPO1xuXHRwdWJsaWMgbWF0ZXJpYWw6TWF0ZXJpYWxCYXNlO1xufVxuXG5leHBvcnQgPSBNYXRlcmlhbFZPOyJdfQ== \ No newline at end of file diff --git a/lib/parsers/data/MaterialVO.ts b/lib/parsers/data/MaterialVO.ts new file mode 100644 index 000000000..dd7b0592a --- /dev/null +++ b/lib/parsers/data/MaterialVO.ts @@ -0,0 +1,20 @@ +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); + +import TextureVO = require("awayjs-renderergl/lib/parsers/data/TextureVO"); + +/** + * + */ +class MaterialVO +{ + public name:string; + public ambientColor:number /*int*/; + public diffuseColor:number /*int*/; + public specularColor:number /*int*/; + public twoSided:boolean; + public colorMap:TextureVO; + public specularMap:TextureVO; + public material:MaterialBase; +} + +export = MaterialVO; \ No newline at end of file diff --git a/lib/parsers/data/ObjectVO.js b/lib/parsers/data/ObjectVO.js new file mode 100755 index 000000000..9f925e3e5 --- /dev/null +++ b/lib/parsers/data/ObjectVO.js @@ -0,0 +1,8 @@ +var ObjectVO = (function () { + function ObjectVO() { + } + return ObjectVO; +})(); +module.exports = ObjectVO; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS9vYmplY3R2by50cyJdLCJuYW1lcyI6WyJPYmplY3RWTyIsIk9iamVjdFZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNLFFBQVE7SUFBZEEsU0FBTUEsUUFBUUE7SUFjZEMsQ0FBQ0E7SUFBREQsZUFBQ0E7QUFBREEsQ0FkQSxBQWNDQSxJQUFBO0FBRUQsQUFBa0IsaUJBQVQsUUFBUSxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9PYmplY3RWTy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIE9iamVjdFZPXG57XG5cdHB1YmxpYyBuYW1lOnN0cmluZztcblx0cHVibGljIHR5cGU6c3RyaW5nO1xuXHRwdWJsaWMgcGl2b3RYOm51bWJlcjtcblx0cHVibGljIHBpdm90WTpudW1iZXI7XG5cdHB1YmxpYyBwaXZvdFo6bnVtYmVyO1xuXHRwdWJsaWMgdHJhbnNmb3JtOkFycmF5PG51bWJlcj47XG5cdHB1YmxpYyB2ZXJ0czpBcnJheTxudW1iZXI+O1xuXHRwdWJsaWMgaW5kaWNlczpBcnJheTxudW1iZXI+IC8qaW50Ki87XG5cdHB1YmxpYyB1dnM6QXJyYXk8bnVtYmVyPjtcblx0cHVibGljIG1hdGVyaWFsRmFjZXM6T2JqZWN0O1xuXHRwdWJsaWMgbWF0ZXJpYWxzOkFycmF5PHN0cmluZz47XG5cdHB1YmxpYyBzbW9vdGhpbmdHcm91cHM6QXJyYXk8bnVtYmVyPiAvKmludCovO1xufVxuXG5leHBvcnQgPSBPYmplY3RWTzsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/ObjectVO.ts b/lib/parsers/data/ObjectVO.ts new file mode 100644 index 000000000..11a211d5a --- /dev/null +++ b/lib/parsers/data/ObjectVO.ts @@ -0,0 +1,17 @@ +class ObjectVO +{ + public name:string; + public type:string; + public pivotX:number; + public pivotY:number; + public pivotZ:number; + public transform:Array; + public verts:Array; + public indices:Array /*int*/; + public uvs:Array; + public materialFaces:Object; + public materials:Array; + public smoothingGroups:Array /*int*/; +} + +export = ObjectVO; \ No newline at end of file diff --git a/lib/parsers/data/TextureVO.js b/lib/parsers/data/TextureVO.js new file mode 100755 index 000000000..ee24c4af4 --- /dev/null +++ b/lib/parsers/data/TextureVO.js @@ -0,0 +1,11 @@ +/** + * + */ +var TextureVO = (function () { + function TextureVO() { + } + return TextureVO; +})(); +module.exports = TextureVO; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS90ZXh0dXJldm8udHMiXSwibmFtZXMiOlsiVGV4dHVyZVZPIiwiVGV4dHVyZVZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFFQSxBQUdBOztHQURHO0lBQ0csU0FBUztJQUFmQSxTQUFNQSxTQUFTQTtJQUlmQyxDQUFDQTtJQUFERCxnQkFBQ0E7QUFBREEsQ0FKQSxBQUlDQSxJQUFBO0FBRUQsQUFBbUIsaUJBQVYsU0FBUyxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9UZXh0dXJlVk8uanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVGV4dHVyZTJEQmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcblxuLyoqXG4gKlxuICovXG5jbGFzcyBUZXh0dXJlVk9cbntcblx0cHVibGljIHVybDpzdHJpbmc7XG5cdHB1YmxpYyB0ZXh0dXJlOlRleHR1cmUyREJhc2U7XG59XG5cbmV4cG9ydCA9IFRleHR1cmVWTzsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/TextureVO.ts b/lib/parsers/data/TextureVO.ts new file mode 100644 index 000000000..7a60d0e4c --- /dev/null +++ b/lib/parsers/data/TextureVO.ts @@ -0,0 +1,12 @@ +import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase"); + +/** + * + */ +class TextureVO +{ + public url:string; + public texture:Texture2DBase; +} + +export = TextureVO; \ No newline at end of file diff --git a/lib/parsers/data/VertexVO.js b/lib/parsers/data/VertexVO.js new file mode 100755 index 000000000..87165a1de --- /dev/null +++ b/lib/parsers/data/VertexVO.js @@ -0,0 +1,8 @@ +var VertexVO = (function () { + function VertexVO() { + } + return VertexVO; +})(); +module.exports = VertexVO; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvZGF0YS92ZXJ0ZXh2by50cyJdLCJuYW1lcyI6WyJWZXJ0ZXhWTyIsIlZlcnRleFZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFFQSxJQUFNLFFBQVE7SUFBZEEsU0FBTUEsUUFBUUE7SUFTZEMsQ0FBQ0E7SUFBREQsZUFBQ0E7QUFBREEsQ0FUQSxBQVNDQSxJQUFBO0FBRUQsQUFBa0IsaUJBQVQsUUFBUSxDQUFDIiwiZmlsZSI6InBhcnNlcnMvZGF0YS9WZXJ0ZXhWTy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuY2xhc3MgVmVydGV4Vk9cbntcblx0cHVibGljIHg6bnVtYmVyO1xuXHRwdWJsaWMgeTpudW1iZXI7XG5cdHB1YmxpYyB6Om51bWJlcjtcblx0cHVibGljIHU6bnVtYmVyO1xuXHRwdWJsaWMgdjpudW1iZXI7XG5cdHB1YmxpYyBub3JtYWw6VmVjdG9yM0Q7XG5cdHB1YmxpYyB0YW5nZW50OlZlY3RvcjNEO1xufVxuXG5leHBvcnQgPSBWZXJ0ZXhWTzsiXX0= \ No newline at end of file diff --git a/lib/parsers/data/VertexVO.ts b/lib/parsers/data/VertexVO.ts new file mode 100644 index 000000000..5ee4473e2 --- /dev/null +++ b/lib/parsers/data/VertexVO.ts @@ -0,0 +1,14 @@ +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); + +class VertexVO +{ + public x:number; + public y:number; + public z:number; + public u:number; + public v:number; + public normal:Vector3D; + public tangent:Vector3D; +} + +export = VertexVO; \ No newline at end of file diff --git a/lib/tools/commands/Merge.js b/lib/tools/commands/Merge.js new file mode 100755 index 000000000..c69224cdb --- /dev/null +++ b/lib/tools/commands/Merge.js @@ -0,0 +1,293 @@ +var Geometry = require("awayjs-core/lib/core/base/Geometry"); +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Matrix3DUtils = require("awayjs-core/lib/core/geom/Matrix3DUtils"); +var Mesh = require("awayjs-core/lib/entities/Mesh"); +/** + * Class Merge merges two or more static meshes into one.Merge + */ +var Merge = (function () { + /** + * @param keepMaterial [optional] Determines if the merged object uses the recevier mesh material information or keeps its source material(s). Defaults to false. + * If false and receiver object has multiple materials, the last material found in receiver submeshes is applied to the merged submesh(es). + * @param disposeSources [optional] Determines if the mesh and geometry source(s) used for the merging are disposed. Defaults to false. + * If true, only receiver geometry and resulting mesh are kept in memory. + * @param objectSpace [optional] Determines if source mesh(es) is/are merged using objectSpace or worldspace. Defaults to false. + */ + function Merge(keepMaterial, disposeSources, objectSpace) { + if (keepMaterial === void 0) { keepMaterial = false; } + if (disposeSources === void 0) { disposeSources = false; } + if (objectSpace === void 0) { objectSpace = false; } + this._keepMaterial = keepMaterial; + this._disposeSources = disposeSources; + this._objectSpace = objectSpace; + } + Object.defineProperty(Merge.prototype, "disposeSources", { + get: function () { + return this._disposeSources; + }, + /** + * Determines if the mesh and geometry source(s) used for the merging are disposed. Defaults to false. + */ + set: function (b) { + this._disposeSources = b; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Merge.prototype, "keepMaterial", { + get: function () { + return this._keepMaterial; + }, + /** + * Determines if the material source(s) used for the merging are disposed. Defaults to false. + */ + set: function (b) { + this._keepMaterial = b; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Merge.prototype, "objectSpace", { + get: function () { + return this._objectSpace; + }, + /** + * Determines if source mesh(es) is/are merged using objectSpace or worldspace. Defaults to false. + */ + set: function (b) { + this._objectSpace = b; + }, + enumerable: true, + configurable: true + }); + /** + * Merges all the children of a container into a single Mesh. If no Mesh object is found, method returns the receiver without modification. + * + * @param receiver The Mesh to receive the merged contents of the container. + * @param objectContainer The DisplayObjectContainer holding the meshes to be mergd. + * + * @return The merged Mesh instance. + */ + Merge.prototype.applyToContainer = function (receiver, objectContainer) { + this.reset(); + //collect container meshes + this.parseContainer(receiver, objectContainer); + //collect receiver + this.collect(receiver, false); + //merge to receiver + this.merge(receiver, this._disposeSources); + }; + /** + * Merges all the meshes found in the Array<Mesh> into a single Mesh. + * + * @param receiver The Mesh to receive the merged contents of the meshes. + * @param meshes A series of Meshes to be merged with the reciever mesh. + */ + Merge.prototype.applyToMeshes = function (receiver, meshes) { + this.reset(); + if (!meshes.length) + return; + for (var i = 0; i < meshes.length; i++) + if (meshes[i] != receiver) + this.collect(meshes[i], this._disposeSources); + //collect receiver + this.collect(receiver, false); + //merge to receiver + this.merge(receiver, this._disposeSources); + }; + /** + * Merges 2 meshes into one. It is recommand to use apply when 2 meshes are to be merged. If more need to be merged, use either applyToMeshes or applyToContainer methods. + * + * @param receiver The Mesh to receive the merged contents of both meshes. + * @param mesh The Mesh to be merged with the receiver mesh + */ + Merge.prototype.apply = function (receiver, mesh) { + this.reset(); + //collect mesh + this.collect(mesh, this._disposeSources); + //collect receiver + this.collect(receiver, false); + //merge to receiver + this.merge(receiver, this._disposeSources); + }; + Merge.prototype.reset = function () { + this._toDispose = new Array(); + this._geomVOs = new Array(); + }; + Merge.prototype.merge = function (destMesh, dispose) { + var i /*uint*/; + var subIdx /*uint*/; + var oldGeom; + var destGeom; + var useSubMaterials; + oldGeom = destMesh.geometry; + destGeom = destMesh.geometry = new Geometry(); + subIdx = destMesh.subMeshes.length; + // Only apply materials directly to sub-meshes if necessary, + // i.e. if there is more than one material available. + useSubMaterials = (this._geomVOs.length > 1); + for (i = 0; i < this._geomVOs.length; i++) { + var s /*uint*/; + var data; + var sub = new TriangleSubGeometry(true); + sub.autoDeriveNormals = false; + sub.autoDeriveTangents = false; + data = this._geomVOs[i]; + sub.updateIndices(data.indices); + sub.updatePositions(data.vertices); + sub.updateVertexNormals(data.normals); + sub.updateVertexTangents(data.tangents); + sub.updateUVs(data.uvs); + destGeom.addSubGeometry(sub); + if (this._keepMaterial && useSubMaterials) + destMesh.subMeshes[subIdx].material = data.material; + } + if (this._keepMaterial && !useSubMaterials && this._geomVOs.length) + destMesh.material = this._geomVOs[0].material; + if (dispose) { + var m; + var len = this._toDispose.length; + for (var i; i < len; i++) { + m = this._toDispose[i]; + m.geometry.dispose(); + m.dispose(); + } + //dispose of the original receiver geometry + oldGeom.dispose(); + } + this._toDispose = null; + }; + Merge.prototype.collect = function (mesh, dispose) { + if (mesh.geometry) { + var subIdx /*uint*/; + var subGeometries = mesh.geometry.subGeometries; + var calc /*uint*/; + for (subIdx = 0; subIdx < subGeometries.length; subIdx++) { + var i /*uint*/; + var len /*uint*/; + var iIdx /*uint*/, vIdx /*uint*/, nIdx /*uint*/, tIdx /*uint*/, uIdx /*uint*/; + var indexOffset /*uint*/; + var subGeom; + var vo; + var vertices; + var normals; + var tangents; + var pd, nd, td, ud; + subGeom = subGeometries[subIdx]; + pd = subGeom.positions; + nd = subGeom.vertexNormals; + td = subGeom.vertexTangents; + ud = subGeom.uvs; + // Get (or create) a VO for this material + vo = this.getSubGeomData(mesh.subMeshes[subIdx].material || mesh.material); + // Vertices and normals are copied to temporary vectors, to be transformed + // before concatenated onto those of the data. This is unnecessary if no + // transformation will be performed, i.e. for object space merging. + vertices = (this._objectSpace) ? vo.vertices : new Array(); + normals = (this._objectSpace) ? vo.normals : new Array(); + tangents = (this._objectSpace) ? vo.tangents : new Array(); + // Copy over vertex attributes + vIdx = vertices.length; + nIdx = normals.length; + tIdx = tangents.length; + uIdx = vo.uvs.length; + len = subGeom.numVertices; + for (i = 0; i < len; i++) { + calc = i * 3; + // Position + vertices[vIdx++] = pd[calc]; + vertices[vIdx++] = pd[calc + 1]; + vertices[vIdx++] = pd[calc + 2]; + // Normal + normals[nIdx++] = nd[calc]; + normals[nIdx++] = nd[calc + 1]; + normals[nIdx++] = nd[calc + 2]; + // Tangent + tangents[tIdx++] = td[calc]; + tangents[tIdx++] = td[calc + 1]; + tangents[tIdx++] = td[calc + 2]; + // UV + vo.uvs[uIdx++] = ud[i * 2]; + vo.uvs[uIdx++] = ud[i * 2 + 1]; + } + // Copy over triangle indices + indexOffset = (!this._objectSpace) ? vo.vertices.length / 3 : 0; + iIdx = vo.indices.length; + len = subGeom.numTriangles; + for (i = 0; i < len; i++) { + calc = i * 3; + vo.indices[iIdx++] = subGeom.indices[calc] + indexOffset; + vo.indices[iIdx++] = subGeom.indices[calc + 1] + indexOffset; + vo.indices[iIdx++] = subGeom.indices[calc + 2] + indexOffset; + } + if (!this._objectSpace) { + mesh.sceneTransform.transformVectors(vertices, vertices); + Matrix3DUtils.deltaTransformVectors(mesh.sceneTransform, normals, normals); + Matrix3DUtils.deltaTransformVectors(mesh.sceneTransform, tangents, tangents); + // Copy vertex data from temporary (transformed) vectors + vIdx = vo.vertices.length; + nIdx = vo.normals.length; + tIdx = vo.tangents.length; + len = vertices.length; + for (i = 0; i < len; i++) { + vo.vertices[vIdx++] = vertices[i]; + vo.normals[nIdx++] = normals[i]; + vo.tangents[tIdx++] = tangents[i]; + } + } + } + if (dispose) + this._toDispose.push(mesh); + } + }; + Merge.prototype.getSubGeomData = function (material) { + var data; + if (this._keepMaterial) { + var i /*uint*/; + var len /*uint*/; + len = this._geomVOs.length; + for (i = 0; i < len; i++) { + if (this._geomVOs[i].material == material) { + data = this._geomVOs[i]; + break; + } + } + } + else if (this._geomVOs.length) { + // If materials are not to be kept, all data can be + // put into a single VO, so return that one. + data = this._geomVOs[0]; + } + // No data (for this material) found, create new. + if (!data) { + data = new GeometryVO(); + data.vertices = new Array(); + data.normals = new Array(); + data.tangents = new Array(); + data.uvs = new Array(); + data.indices = new Array(); + data.material = material; + this._geomVOs.push(data); + } + return data; + }; + Merge.prototype.parseContainer = function (receiver, object) { + var child; + var i /*uint*/; + if (object instanceof Mesh && object != receiver) + this.collect(object, this._disposeSources); + for (i = 0; i < object.numChildren; ++i) { + child = object.getChildAt(i); + this.parseContainer(receiver, child); + } + }; + return Merge; +})(); +var GeometryVO = (function () { + function GeometryVO() { + } + return GeometryVO; +})(); +module.exports = Merge; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRvb2xzL2NvbW1hbmRzL21lcmdlLnRzIl0sIm5hbWVzIjpbIk1lcmdlIiwiTWVyZ2UuY29uc3RydWN0b3IiLCJNZXJnZS5kaXNwb3NlU291cmNlcyIsIk1lcmdlLmtlZXBNYXRlcmlhbCIsIk1lcmdlLm9iamVjdFNwYWNlIiwiTWVyZ2UuYXBwbHlUb0NvbnRhaW5lciIsIk1lcmdlLmFwcGx5VG9NZXNoZXMiLCJNZXJnZS5hcHBseSIsIk1lcmdlLnJlc2V0IiwiTWVyZ2UubWVyZ2UiLCJNZXJnZS5jb2xsZWN0IiwiTWVyZ2UuZ2V0U3ViR2VvbURhdGEiLCJNZXJnZS5wYXJzZUNvbnRhaW5lciIsIkdlb21ldHJ5Vk8iLCJHZW9tZXRyeVZPLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFDQSxJQUFPLFFBQVEsV0FBaUIsb0NBQW9DLENBQUMsQ0FBQztBQUN0RSxJQUFPLG1CQUFtQixXQUFjLCtDQUErQyxDQUFDLENBQUM7QUFDekYsSUFBTyxhQUFhLFdBQWUseUNBQXlDLENBQUMsQ0FBQztBQUM5RSxJQUFPLElBQUksV0FBa0IsK0JBQStCLENBQUMsQ0FBQztBQUc5RCxBQUdBOztHQURHO0lBQ0csS0FBSztJQVVWQTs7Ozs7O09BTUdBO0lBQ0hBLFNBakJLQSxLQUFLQSxDQWlCRUEsWUFBNEJBLEVBQUVBLGNBQThCQSxFQUFFQSxXQUEyQkE7UUFBekZDLDRCQUE0QkEsR0FBNUJBLG9CQUE0QkE7UUFBRUEsOEJBQThCQSxHQUE5QkEsc0JBQThCQTtRQUFFQSwyQkFBMkJBLEdBQTNCQSxtQkFBMkJBO1FBRXBHQSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxZQUFZQSxDQUFDQTtRQUNsQ0EsSUFBSUEsQ0FBQ0EsZUFBZUEsR0FBR0EsY0FBY0EsQ0FBQ0E7UUFDdENBLElBQUlBLENBQUNBLFlBQVlBLEdBQUdBLFdBQVdBLENBQUNBO0lBQ2pDQSxDQUFDQTtJQUtERCxzQkFBV0EsaUNBQWNBO2FBS3pCQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxl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SUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBRWhDQSxBQUNBQSxTQURTQTtvQkFDVEEsT0FBT0EsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7b0JBQzNCQSxPQUFPQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDL0JBLE9BQU9BLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO29CQUUvQkEsQUFDQUEsVUFEVUE7b0JBQ1ZBLFFBQVFBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLElBQUlBLENBQUNBLENBQUNBO29CQUM1QkEsUUFBUUEsQ0FBQ0EsSUFBSUEsRUFBRUEsQ0FBQ0EsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQ2hDQSxRQUFRQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxJQUFJQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFFaENBLEFBQ0FBLEtBREtBO29CQUNMQSxFQUFFQSxDQUFDQSxHQUFHQSxDQUFDQSxJQUFJQSxFQUFFQSxDQUFDQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxHQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtvQkFDekJBLEVBQUVBLENBQUNBLEdBQUdBLENBQUNBLElBQUlBLEVBQUVBLENBQUNBLEdBQUdBLEVBQUVBLENBQUNBLENBQUNBLEdBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBO2dCQUM5QkEsQ0FBQ0E7Z0JBRURBLEFBQ0FBLDZCQUQ2QkE7Z0JBQzdCQSxXQUFXQSxHQUFHQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFD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QUFDQTtJQUNGWixZQUFDQTtBQUFEQSxDQWxWQSxBQWtWQ0EsSUFBQTtBQUlELElBQU0sVUFBVTtJQUFoQmEsU0FBTUEsVUFBVUE7SUFRaEJDLENBQUNBO0lBQURELGlCQUFDQTtBQUFEQSxDQVJBLEFBUUNBLElBQUE7QUFWRCxpQkFBUyxLQUFLLENBQUMiLCJmaWxlIjoidG9vbHMvY29tbWFuZHMvTWVyZ2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGlzcGxheU9iamVjdENvbnRhaW5lclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL0Rpc3BsYXlPYmplY3RDb250YWluZXJcIik7XG5pbXBvcnQgR2VvbWV0cnlcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvR2VvbWV0cnlcIik7XG5pbXBvcnQgVHJpYW5nbGVTdWJHZW9tZXRyeVx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9UcmlhbmdsZVN1Ykdlb21ldHJ5XCIpO1xuaW1wb3J0IE1hdHJpeDNEVXRpbHNcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFV0aWxzXCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTWF0ZXJpYWxCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9NYXRlcmlhbEJhc2VcIik7XG5cbi8qKlxuICogIENsYXNzIE1lcmdlIG1lcmdlcyB0d28gb3IgbW9yZSBzdGF0aWMgbWVzaGVzIGludG8gb25lLjxjb2RlPk1lcmdlPC9jb2RlPlxuICovXG5jbGFzcyBNZXJnZVxue1xuXG5cdC8vcHJpdmF0ZSBjb25zdCBMSU1JVDp1aW50ID0gMTk2NjA1O1xuXHRwcml2YXRlIF9vYmplY3RTcGFjZTpib29sZWFuO1xuXHRwcml2YXRlIF9rZWVwTWF0ZXJpYWw6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfZGlzcG9zZVNvdXJjZXM6Ym9vbGVhbjtcblx0cHJpdmF0ZSBfZ2VvbVZPczpBcnJheTxHZW9tZXRyeVZPPjtcblx0cHJpdmF0ZSBfdG9EaXNwb3NlOkFycmF5PE1lc2g+O1xuXG5cdC8qKlxuXHQgKiBAcGFyYW0gICAga2VlcE1hdGVyaWFsICAgIFtvcHRpb25hbF0gICAgRGV0ZXJtaW5lcyBpZiB0aGUgbWVyZ2VkIG9iamVjdCB1c2VzIHRoZSByZWNldmllciBtZXNoIG1hdGVyaWFsIGluZm9ybWF0aW9uIG9yIGtlZXBzIGl0cyBzb3VyY2UgbWF0ZXJpYWwocykuIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKiBJZiBmYWxzZSBhbmQgcmVjZWl2ZXIgb2JqZWN0IGhhcyBtdWx0aXBsZSBtYXRlcmlhbHMsIHRoZSBsYXN0IG1hdGVyaWFsIGZvdW5kIGluIHJlY2VpdmVyIHN1Ym1lc2hlcyBpcyBhcHBsaWVkIHRvIHRoZSBtZXJnZWQgc3VibWVzaChlcykuXG5cdCAqIEBwYXJhbSAgICBkaXNwb3NlU291cmNlcyAgW29wdGlvbmFsXSAgICBEZXRlcm1pbmVzIGlmIHRoZSBtZXNoIGFuZCBnZW9tZXRyeSBzb3VyY2UocykgdXNlZCBmb3IgdGhlIG1lcmdpbmcgYXJlIGRpc3Bvc2VkLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICogSWYgdHJ1ZSwgb25seSByZWNlaXZlciBnZW9tZXRyeSBhbmQgcmVzdWx0aW5nIG1lc2ggYXJlIGtlcHQgaW4gIG1lbW9yeS5cblx0ICogQHBhcmFtICAgIG9iamVjdFNwYWNlICAgICBbb3B0aW9uYWxdICAgIERldGVybWluZXMgaWYgc291cmNlIG1lc2goZXMpIGlzL2FyZSBtZXJnZWQgdXNpbmcgb2JqZWN0U3BhY2Ugb3Igd29ybGRzcGFjZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihrZWVwTWF0ZXJpYWw6Ym9vbGVhbiA9IGZhbHNlLCBkaXNwb3NlU291cmNlczpib29sZWFuID0gZmFsc2UsIG9iamVjdFNwYWNlOmJvb2xlYW4gPSBmYWxzZSlcblx0e1xuXHRcdHRoaXMuX2tlZXBNYXRlcmlhbCA9IGtlZXBNYXRlcmlhbDtcblx0XHR0aGlzLl9kaXNwb3NlU291cmNlcyA9IGRpc3Bvc2VTb3VyY2VzO1xuXHRcdHRoaXMuX29iamVjdFNwYWNlID0gb2JqZWN0U3BhY2U7XG5cdH1cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lcyBpZiB0aGUgbWVzaCBhbmQgZ2VvbWV0cnkgc291cmNlKHMpIHVzZWQgZm9yIHRoZSBtZXJnaW5nIGFyZSBkaXNwb3NlZC4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqL1xuXHRwdWJsaWMgc2V0IGRpc3Bvc2VTb3VyY2VzKGI6Ym9vbGVhbilcblx0e1xuXHRcdHRoaXMuX2Rpc3Bvc2VTb3VyY2VzID0gYjtcblx0fVxuXG5cdHB1YmxpYyBnZXQgZGlzcG9zZVNvdXJjZXMoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZGlzcG9zZVNvdXJjZXM7XG5cdH1cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lcyBpZiB0aGUgbWF0ZXJpYWwgc291cmNlKHMpIHVzZWQgZm9yIHRoZSBtZXJnaW5nIGFyZSBkaXNwb3NlZC4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqL1xuXHRwdWJsaWMgc2V0IGtlZXBNYXRlcmlhbChiOmJvb2xlYW4pXG5cdHtcblx0XHR0aGlzLl9rZWVwTWF0ZXJpYWwgPSBiO1xuXHR9XG5cblx0cHVibGljIGdldCBrZWVwTWF0ZXJpYWwoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fa2VlcE1hdGVyaWFsO1xuXHR9XG5cblx0LyoqXG5cdCAqIERldGVybWluZXMgaWYgc291cmNlIG1lc2goZXMpIGlzL2FyZSBtZXJnZWQgdXNpbmcgb2JqZWN0U3BhY2Ugb3Igd29ybGRzcGFjZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqL1xuXHRwdWJsaWMgc2V0IG9iamVjdFNwYWNlKGI6Ym9vbGVhbilcblx0e1xuXHRcdHRoaXMuX29iamVjdFNwYWNlID0gYjtcblx0fVxuXG5cdHB1YmxpYyBnZXQgb2JqZWN0U3BhY2UoKTpib29sZWFuXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fb2JqZWN0U3BhY2U7XG5cdH1cblxuXHQvKipcblx0ICogTWVyZ2VzIGFsbCB0aGUgY2hpbGRyZW4gb2YgYSBjb250YWluZXIgaW50byBhIHNpbmdsZSBNZXNoLiBJZiBubyBNZXNoIG9iamVjdCBpcyBmb3VuZCwgbWV0aG9kIHJldHVybnMgdGhlIHJlY2VpdmVyIHdpdGhvdXQgbW9kaWZpY2F0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gICAgcmVjZWl2ZXIgICAgICAgICAgIFRoZSBNZXNoIHRvIHJlY2VpdmUgdGhlIG1lcmdlZCBjb250ZW50cyBvZiB0aGUgY29udGFpbmVyLlxuXHQgKiBAcGFyYW0gICAgb2JqZWN0Q29udGFpbmVyICAgIFRoZSBEaXNwbGF5T2JqZWN0Q29udGFpbmVyIGhvbGRpbmcgdGhlIG1lc2hlcyB0byBiZSBtZXJnZC5cblx0ICpcblx0ICogQHJldHVybiBUaGUgbWVyZ2VkIE1lc2ggaW5zdGFuY2UuXG5cdCAqL1xuXHRwdWJsaWMgYXBwbHlUb0NvbnRhaW5lcihyZWNlaXZlcjpNZXNoLCBvYmplY3RDb250YWluZXI6RGlzcGxheU9iamVjdENvbnRhaW5lcilcblx0e1xuXHRcdHRoaXMucmVzZXQoKTtcblxuXHRcdC8vY29sbGVjdCBjb250YWluZXIgbWVzaGVzXG5cdFx0dGhpcy5wYXJzZUNvbnRhaW5lcihyZWNlaXZlciwgb2JqZWN0Q29udGFpbmVyKTtcblxuXHRcdC8vY29sbGVjdCByZWNlaXZlclxuXHRcdHRoaXMuY29sbGVjdChyZWNlaXZlciwgZmFsc2UpO1xuXG5cdFx0Ly9tZXJnZSB0byByZWNlaXZlclxuXHRcdHRoaXMubWVyZ2UocmVjZWl2ZXIsIHRoaXMuX2Rpc3Bvc2VTb3VyY2VzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNZXJnZXMgYWxsIHRoZSBtZXNoZXMgZm91bmQgaW4gdGhlIEFycmF5Jmx0O01lc2gmZ3Q7IGludG8gYSBzaW5nbGUgTWVzaC5cblx0ICpcblx0ICogQHBhcmFtICAgIHJlY2VpdmVyICAgIFRoZSBNZXNoIHRvIHJlY2VpdmUgdGhlIG1lcmdlZCBjb250ZW50cyBvZiB0aGUgbWVzaGVzLlxuXHQgKiBAcGFyYW0gICAgbWVzaGVzICAgICAgQSBzZXJpZXMgb2YgTWVzaGVzIHRvIGJlIG1lcmdlZCB3aXRoIHRoZSByZWNpZXZlciBtZXNoLlxuXHQgKi9cblx0cHVibGljIGFwcGx5VG9NZXNoZXMocmVjZWl2ZXI6TWVzaCwgbWVzaGVzOkFycmF5PE1lc2g+KVxuXHR7XG5cdFx0dGhpcy5yZXNldCgpO1xuXG5cdFx0aWYgKCFtZXNoZXMubGVuZ3RoKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0Ly9jb2xsZWN0IG1lc2hlcyBpbiB2ZWN0b3Jcblx0XHRmb3IgKHZhciBpOm51bWJlciAvKnVpbnQqLyA9IDA7IGkgPCBtZXNoZXMubGVuZ3RoOyBpKyspXG5cdFx0XHRpZiAobWVzaGVzW2ldICE9IHJlY2VpdmVyKVxuXHRcdFx0XHR0aGlzLmNvbGxlY3QobWVzaGVzW2ldLCB0aGlzLl9kaXNwb3NlU291cmNlcyk7XG5cblx0XHQvL2NvbGxlY3QgcmVjZWl2ZXJcblx0XHR0aGlzLmNvbGxlY3QocmVjZWl2ZXIsIGZhbHNlKTtcblxuXHRcdC8vbWVyZ2UgdG8gcmVjZWl2ZXJcblx0XHR0aGlzLm1lcmdlKHJlY2VpdmVyLCB0aGlzLl9kaXNwb3NlU291cmNlcyk7XG5cdH1cblxuXHQvKipcblx0ICogIE1lcmdlcyAyIG1lc2hlcyBpbnRvIG9uZS4gSXQgaXMgcmVjb21tYW5kIHRvIHVzZSBhcHBseSB3aGVuIDIgbWVzaGVzIGFyZSB0byBiZSBtZXJnZWQuIElmIG1vcmUgbmVlZCB0byBiZSBtZXJnZWQsIHVzZSBlaXRoZXIgYXBwbHlUb01lc2hlcyBvciBhcHBseVRvQ29udGFpbmVyIG1ldGhvZHMuXG5cdCAqXG5cdCAqIEBwYXJhbSAgICByZWNlaXZlciAgICBUaGUgTWVzaCB0byByZWNlaXZlIHRoZSBtZXJnZWQgY29udGVudHMgb2YgYm90aCBtZXNoZXMuXG5cdCAqIEBwYXJhbSAgICBtZXNoICAgICAgICBUaGUgTWVzaCB0byBiZSBtZXJnZWQgd2l0aCB0aGUgcmVjZWl2ZXIgbWVzaFxuXHQgKi9cblx0cHVibGljIGFwcGx5KHJlY2VpdmVyOk1lc2gsIG1lc2g6TWVzaClcblx0e1xuXHRcdHRoaXMucmVzZXQoKTtcblxuXHRcdC8vY29sbGVjdCBtZXNoXG5cdFx0dGhpcy5jb2xsZWN0KG1lc2gsIHRoaXMuX2Rpc3Bvc2VTb3VyY2VzKTtcblxuXHRcdC8vY29sbGVjdCByZWNlaXZlclxuXHRcdHRoaXMuY29sbGVjdChyZWNlaXZlciwgZmFsc2UpO1xuXG5cdFx0Ly9tZXJnZSB0byByZWNlaXZlclxuXHRcdHRoaXMubWVyZ2UocmVjZWl2ZXIsIHRoaXMuX2Rpc3Bvc2VTb3VyY2VzKTtcblx0fVxuXG5cdHByaXZhdGUgcmVzZXQoKVxuXHR7XG5cdFx0dGhpcy5fdG9EaXNwb3NlICA9IG5ldyBBcnJheTxNZXNoPigpO1xuXHRcdHRoaXMuX2dlb21WT3MgPSBuZXcgQXJyYXk8R2VvbWV0cnlWTz4oKTtcblx0fVxuXG5cdHByaXZhdGUgbWVyZ2UoZGVzdE1lc2g6TWVzaCwgZGlzcG9zZTpib29sZWFuKVxuXHR7XG5cdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBzdWJJZHg6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBvbGRHZW9tOkdlb21ldHJ5O1xuXHRcdHZhciBkZXN0R2VvbTpHZW9tZXRyeTtcblx0XHR2YXIgdXNlU3ViTWF0ZXJpYWxzOmJvb2xlYW47XG5cblx0XHRvbGRHZW9tID0gZGVzdE1lc2guZ2VvbWV0cnk7XG5cdFx0ZGVzdEdlb20gPSBkZXN0TWVzaC5nZW9tZXRyeSA9IG5ldyBHZW9tZXRyeSgpO1xuXHRcdHN1YklkeCA9IGRlc3RNZXNoLnN1Yk1lc2hlcy5sZW5ndGg7XG5cblx0XHQvLyBPbmx5IGFwcGx5IG1hdGVyaWFscyBkaXJlY3RseSB0byBzdWItbWVzaGVzIGlmIG5lY2Vzc2FyeSxcblx0XHQvLyBpLmUuIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgbWF0ZXJpYWwgYXZhaWxhYmxlLlxuXHRcdHVzZVN1Yk1hdGVyaWFscyA9ICh0aGlzLl9nZW9tVk9zLmxlbmd0aCA+IDEpO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHRoaXMuX2dlb21WT3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBzOm51bWJlciAvKnVpbnQqLztcblx0XHRcdHZhciBkYXRhOkdlb21ldHJ5Vk87XG5cdFx0XHR2YXIgc3ViOlRyaWFuZ2xlU3ViR2VvbWV0cnkgPSBuZXcgVHJpYW5nbGVTdWJHZW9tZXRyeSh0cnVlKTtcblx0XHRcdHN1Yi5hdXRvRGVyaXZlTm9ybWFscyA9IGZhbHNlO1xuXHRcdFx0c3ViLmF1dG9EZXJpdmVUYW5nZW50cyA9IGZhbHNlO1xuXG5cdFx0XHRkYXRhID0gdGhpcy5fZ2VvbVZPc1tpXTtcblx0XHRcdHN1Yi51cGRhdGVJbmRpY2VzKGRhdGEuaW5kaWNlcyk7XG5cdFx0XHRzdWIudXBkYXRlUG9zaXRpb25zKGRhdGEudmVydGljZXMpO1xuXHRcdFx0c3ViLnVwZGF0ZVZlcnRleE5vcm1hbHMoZGF0YS5ub3JtYWxzKTtcblx0XHRcdHN1Yi51cGRhdGVWZXJ0ZXhUYW5nZW50cyhkYXRhLnRhbmdlbnRzKTtcblx0XHRcdHN1Yi51cGRhdGVVVnMoZGF0YS51dnMpO1xuXG5cdFx0XHRkZXN0R2VvbS5hZGRTdWJHZW9tZXRyeShzdWIpO1xuXG5cdFx0XHRpZiAodGhpcy5fa2VlcE1hdGVyaWFsICYmIHVzZVN1Yk1hdGVyaWFscylcblx0XHRcdFx0ZGVzdE1lc2guc3ViTWVzaGVzW3N1YklkeF0ubWF0ZXJpYWwgPSBkYXRhLm1hdGVyaWFsO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9rZWVwTWF0ZXJpYWwgJiYgIXVzZVN1Yk1hdGVyaWFscyAmJiB0aGlzLl9nZW9tVk9zLmxlbmd0aClcblx0XHRcdGRlc3RNZXNoLm1hdGVyaWFsID0gdGhpcy5fZ2VvbVZPc1swXS5tYXRlcmlhbDtcblxuXHRcdGlmIChkaXNwb3NlKSB7XG5cdFx0XHR2YXIgbTpNZXNoO1xuXHRcdFx0dmFyIGxlbjpudW1iZXIgPSB0aGlzLl90b0Rpc3Bvc2UubGVuZ3RoO1xuXHRcdFx0Zm9yICh2YXIgaTpudW1iZXI7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRtID0gdGhpcy5fdG9EaXNwb3NlW2ldO1xuXHRcdFx0XHRtLmdlb21ldHJ5LmRpc3Bvc2UoKTtcblx0XHRcdFx0bS5kaXNwb3NlKCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vZGlzcG9zZSBvZiB0aGUgb3JpZ2luYWwgcmVjZWl2ZXIgZ2VvbWV0cnlcblx0XHRcdG9sZEdlb20uZGlzcG9zZSgpO1xuXHRcdH1cblxuXHRcdHRoaXMuX3RvRGlzcG9zZSA9IG51bGw7XG5cdH1cblxuXHRwcml2YXRlIGNvbGxlY3QobWVzaDpNZXNoLCBkaXNwb3NlOmJvb2xlYW4pXG5cdHtcblx0XHRpZiAobWVzaC5nZW9tZXRyeSkge1xuXHRcdFx0dmFyIHN1YklkeDpudW1iZXIgLyp1aW50Ki87XG5cdFx0XHR2YXIgc3ViR2VvbWV0cmllczpBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5PiA9IDxBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5Pj4gbWVzaC5nZW9tZXRyeS5zdWJHZW9tZXRyaWVzO1xuXHRcdFx0dmFyIGNhbGM6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0Zm9yIChzdWJJZHggPSAwOyBzdWJJZHggPCBzdWJHZW9tZXRyaWVzLmxlbmd0aDsgc3ViSWR4KyspIHtcblx0XHRcdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0XHR2YXIgbGVuOm51bWJlciAvKnVpbnQqLztcblx0XHRcdFx0dmFyIGlJZHg6bnVtYmVyIC8qdWludCovLCB2SWR4Om51bWJlciAvKnVpbnQqLywgbklkeDpudW1iZXIgLyp1aW50Ki8sIHRJZHg6bnVtYmVyIC8qdWludCovLCB1SWR4Om51bWJlciAvKnVpbnQqLztcblx0XHRcdFx0dmFyIGluZGV4T2Zmc2V0Om51bWJlciAvKnVpbnQqLztcblx0XHRcdFx0dmFyIHN1Ykdlb206VHJpYW5nbGVTdWJHZW9tZXRyeTtcblx0XHRcdFx0dmFyIHZvOkdlb21ldHJ5Vk87XG5cdFx0XHRcdHZhciB2ZXJ0aWNlczpBcnJheTxudW1iZXI+O1xuXHRcdFx0XHR2YXIgbm9ybWFsczpBcnJheTxudW1iZXI+O1xuXHRcdFx0XHR2YXIgdGFuZ2VudHM6QXJyYXk8bnVtYmVyPjtcblx0XHRcdFx0dmFyIHBkOkFycmF5PG51bWJlcj4sIG5kOkFycmF5PG51bWJlcj4sIHRkOkFycmF5PG51bWJlcj4sIHVkOkFycmF5PG51bWJlcj47XG5cblx0XHRcdFx0c3ViR2VvbSA9IHN1Ykdlb21ldHJpZXNbc3ViSWR4XTtcblx0XHRcdFx0cGQgPSBzdWJHZW9tLnBvc2l0aW9ucztcblx0XHRcdFx0bmQgPSBzdWJHZW9tLnZlcnRleE5vcm1hbHM7XG5cdFx0XHRcdHRkID0gc3ViR2VvbS52ZXJ0ZXhUYW5nZW50cztcblx0XHRcdFx0dWQgPSBzdWJHZW9tLnV2cztcblxuXHRcdFx0XHQvLyBHZXQgKG9yIGNyZWF0ZSkgYSBWTyBmb3IgdGhpcyBtYXRlcmlhbFxuXHRcdFx0XHR2byA9IHRoaXMuZ2V0U3ViR2VvbURhdGEobWVzaC5zdWJNZXNoZXNbc3ViSWR4XS5tYXRlcmlhbCB8fCBtZXNoLm1hdGVyaWFsKTtcblxuXHRcdFx0XHQvLyBWZXJ0aWNlcyBhbmQgbm9ybWFscyBhcmUgY29waWVkIHRvIHRlbXBvcmFyeSB2ZWN0b3JzLCB0byBiZSB0cmFuc2Zvcm1lZFxuXHRcdFx0XHQvLyBiZWZvcmUgY29uY2F0ZW5hdGVkIG9udG8gdGhvc2Ugb2YgdGhlIGRhdGEuIFRoaXMgaXMgdW5uZWNlc3NhcnkgaWYgbm9cblx0XHRcdFx0Ly8gdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBwZXJmb3JtZWQsIGkuZS4gZm9yIG9iamVjdCBzcGFjZSBtZXJnaW5nLlxuXHRcdFx0XHR2ZXJ0aWNlcyA9ICh0aGlzLl9vYmplY3RTcGFjZSk/IHZvLnZlcnRpY2VzIDogbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHRcdFx0bm9ybWFscyA9ICh0aGlzLl9vYmplY3RTcGFjZSk/IHZvLm5vcm1hbHMgOiBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdFx0XHR0YW5nZW50cyA9ICh0aGlzLl9vYmplY3RTcGFjZSk/IHZvLnRhbmdlbnRzIDogbmV3IEFycmF5PG51bWJlcj4oKTtcblxuXHRcdFx0XHQvLyBDb3B5IG92ZXIgdmVydGV4IGF0dHJpYnV0ZXNcblx0XHRcdFx0dklkeCA9IHZlcnRpY2VzLmxlbmd0aDtcblx0XHRcdFx0bklkeCA9IG5vcm1hbHMubGVuZ3RoO1xuXHRcdFx0XHR0SWR4ID0gdGFuZ2VudHMubGVuZ3RoO1xuXHRcdFx0XHR1SWR4ID0gdm8udXZzLmxlbmd0aDtcblx0XHRcdFx0bGVuID0gc3ViR2VvbS5udW1WZXJ0aWNlcztcblx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdFx0Y2FsYyA9IGkqMztcblxuXHRcdFx0XHRcdC8vIFBvc2l0aW9uXG5cdFx0XHRcdFx0dmVydGljZXNbdklkeCsrXSA9IHBkW2NhbGNdO1xuXHRcdFx0XHRcdHZlcnRpY2VzW3ZJZHgrK10gPSBwZFtjYWxjICsgMV07XG5cdFx0XHRcdFx0dmVydGljZXNbdklkeCsrXSA9IHBkW2NhbGMgKyAyXTtcblxuXHRcdFx0XHRcdC8vIE5vcm1hbFxuXHRcdFx0XHRcdG5vcm1hbHNbbklkeCsrXSA9IG5kW2NhbGNdO1xuXHRcdFx0XHRcdG5vcm1hbHNbbklkeCsrXSA9IG5kW2NhbGMgKyAxXTtcblx0XHRcdFx0XHRub3JtYWxzW25JZHgrK10gPSBuZFtjYWxjICsgMl07XG5cblx0XHRcdFx0XHQvLyBUYW5nZW50XG5cdFx0XHRcdFx0dGFuZ2VudHNbdElkeCsrXSA9IHRkW2NhbGNdO1xuXHRcdFx0XHRcdHRhbmdlbnRzW3RJZHgrK10gPSB0ZFtjYWxjICsgMV07XG5cdFx0XHRcdFx0dGFuZ2VudHNbdElkeCsrXSA9IHRkW2NhbGMgKyAyXTtcblxuXHRcdFx0XHRcdC8vIFVWXG5cdFx0XHRcdFx0dm8udXZzW3VJZHgrK10gPSB1ZFtpKjJdO1xuXHRcdFx0XHRcdHZvLnV2c1t1SWR4KytdID0gdWRbaSoyICsgMV07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDb3B5IG92ZXIgdHJpYW5nbGUgaW5kaWNlc1xuXHRcdFx0XHRpbmRleE9mZnNldCA9ICghdGhpcy5fb2JqZWN0U3BhY2UpPyB2by52ZXJ0aWNlcy5sZW5ndGgvMyA6MDtcblx0XHRcdFx0aUlkeCA9IHZvLmluZGljZXMubGVuZ3RoO1xuXHRcdFx0XHRsZW4gPSBzdWJHZW9tLm51bVRyaWFuZ2xlcztcblx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdFx0Y2FsYyA9IGkqMztcblx0XHRcdFx0XHR2by5pbmRpY2VzW2lJZHgrK10gPSBzdWJHZW9tLmluZGljZXNbY2FsY10gKyBpbmRleE9mZnNldDtcblx0XHRcdFx0XHR2by5pbmRpY2VzW2lJZHgrK10gPSBzdWJHZW9tLmluZGljZXNbY2FsYyArIDFdICsgaW5kZXhPZmZzZXQ7XG5cdFx0XHRcdFx0dm8uaW5kaWNlc1tpSWR4KytdID0gc3ViR2VvbS5pbmRpY2VzW2NhbGMgKyAyXSArIGluZGV4T2Zmc2V0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCF0aGlzLl9vYmplY3RTcGFjZSkge1xuXHRcdFx0XHRcdG1lc2guc2NlbmVUcmFuc2Zvcm0udHJhbnNmb3JtVmVjdG9ycyh2ZXJ0aWNlcywgdmVydGljZXMpO1xuXHRcdFx0XHRcdE1hdHJpeDNEVXRpbHMuZGVsdGFUcmFuc2Zvcm1WZWN0b3JzKG1lc2guc2NlbmVUcmFuc2Zvcm0sIG5vcm1hbHMsIG5vcm1hbHMpO1xuXHRcdFx0XHRcdE1hdHJpeDNEVXRpbHMuZGVsdGFUcmFuc2Zvcm1WZWN0b3JzKG1lc2guc2NlbmVUcmFuc2Zvcm0sIHRhbmdlbnRzLCB0YW5nZW50cyk7XG5cblx0XHRcdFx0XHQvLyBDb3B5IHZlcnRleCBkYXRhIGZyb20gdGVtcG9yYXJ5ICh0cmFuc2Zvcm1lZCkgdmVjdG9yc1xuXHRcdFx0XHRcdHZJZHggPSB2by52ZXJ0aWNlcy5sZW5ndGg7XG5cdFx0XHRcdFx0bklkeCA9IHZvLm5vcm1hbHMubGVuZ3RoO1xuXHRcdFx0XHRcdHRJZHggPSB2by50YW5nZW50cy5sZW5ndGg7XG5cdFx0XHRcdFx0bGVuID0gdmVydGljZXMubGVuZ3RoO1xuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRcdFx0dm8udmVydGljZXNbdklkeCsrXSA9IHZlcnRpY2VzW2ldO1xuXHRcdFx0XHRcdFx0dm8ubm9ybWFsc1tuSWR4KytdID0gbm9ybWFsc1tpXTtcblx0XHRcdFx0XHRcdHZvLnRhbmdlbnRzW3RJZHgrK10gPSB0YW5nZW50c1tpXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKGRpc3Bvc2UpXG5cdFx0XHRcdHRoaXMuX3RvRGlzcG9zZS5wdXNoKG1lc2gpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgZ2V0U3ViR2VvbURhdGEobWF0ZXJpYWw6TWF0ZXJpYWxCYXNlKTpHZW9tZXRyeVZPXG5cdHtcblx0XHR2YXIgZGF0YTpHZW9tZXRyeVZPO1xuXG5cdFx0aWYgKHRoaXMuX2tlZXBNYXRlcmlhbCkge1xuXHRcdFx0dmFyIGk6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0dmFyIGxlbjpudW1iZXIgLyp1aW50Ki87XG5cblx0XHRcdGxlbiA9IHRoaXMuX2dlb21WT3MubGVuZ3RoO1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9nZW9tVk9zW2ldLm1hdGVyaWFsID09IG1hdGVyaWFsKSB7XG5cdFx0XHRcdFx0ZGF0YSA9IHRoaXMuX2dlb21WT3NbaV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHRoaXMuX2dlb21WT3MubGVuZ3RoKSB7XG5cdFx0XHQvLyBJZiBtYXRlcmlhbHMgYXJlIG5vdCB0byBiZSBrZXB0LCBhbGwgZGF0YSBjYW4gYmVcblx0XHRcdC8vIHB1dCBpbnRvIGEgc2luZ2xlIFZPLCBzbyByZXR1cm4gdGhhdCBvbmUuXG5cdFx0XHRkYXRhID0gdGhpcy5fZ2VvbVZPc1swXTtcblx0XHR9XG5cblx0XHQvLyBObyBkYXRhIChmb3IgdGhpcyBtYXRlcmlhbCkgZm91bmQsIGNyZWF0ZSBuZXcuXG5cdFx0aWYgKCFkYXRhKSB7XG5cdFx0XHRkYXRhID0gbmV3IEdlb21ldHJ5Vk8oKTtcblx0XHRcdGRhdGEudmVydGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdFx0ZGF0YS5ub3JtYWxzID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblx0XHRcdGRhdGEudGFuZ2VudHMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdFx0ZGF0YS51dnMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXHRcdFx0ZGF0YS5pbmRpY2VzID0gbmV3IEFycmF5PG51bWJlciAvKnVpbnQqLz4oKTtcblx0XHRcdGRhdGEubWF0ZXJpYWwgPSBtYXRlcmlhbDtcblxuXHRcdFx0dGhpcy5fZ2VvbVZPcy5wdXNoKGRhdGEpO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhO1xuXHR9XG5cblx0cHJpdmF0ZSBwYXJzZUNvbnRhaW5lcihyZWNlaXZlcjpNZXNoLCBvYmplY3Q6RGlzcGxheU9iamVjdENvbnRhaW5lcilcblx0e1xuXHRcdHZhciBjaGlsZDpEaXNwbGF5T2JqZWN0Q29udGFpbmVyO1xuXHRcdHZhciBpOm51bWJlciAvKnVpbnQqLztcblxuXHRcdGlmIChvYmplY3QgaW5zdGFuY2VvZiBNZXNoICYmIG9iamVjdCAhPSAoPERpc3BsYXlPYmplY3RDb250YWluZXI+IHJlY2VpdmVyKSlcblx0XHRcdHRoaXMuY29sbGVjdCg8TWVzaD4gb2JqZWN0LCB0aGlzLl9kaXNwb3NlU291cmNlcyk7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgb2JqZWN0Lm51bUNoaWxkcmVuOyArK2kpIHtcblx0XHRcdGNoaWxkID0gPERpc3BsYXlPYmplY3RDb250YWluZXI+IG9iamVjdC5nZXRDaGlsZEF0KGkpO1xuXHRcdFx0dGhpcy5wYXJzZUNvbnRhaW5lcihyZWNlaXZlciwgY2hpbGQpO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgPSBNZXJnZTtcblxuY2xhc3MgR2VvbWV0cnlWT1xue1xuXHRwdWJsaWMgdXZzOkFycmF5PG51bWJlcj47XG5cdHB1YmxpYyB2ZXJ0aWNlczpBcnJheTxudW1iZXI+O1xuXHRwdWJsaWMgbm9ybWFsczpBcnJheTxudW1iZXI+O1xuXHRwdWJsaWMgdGFuZ2VudHM6QXJyYXk8bnVtYmVyPjtcblx0cHVibGljIGluZGljZXM6QXJyYXk8bnVtYmVyIC8qdWludCovPjtcblx0cHVibGljIG1hdGVyaWFsOk1hdGVyaWFsQmFzZTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/tools/commands/Merge.ts b/lib/tools/commands/Merge.ts new file mode 100644 index 000000000..2255db97b --- /dev/null +++ b/lib/tools/commands/Merge.ts @@ -0,0 +1,361 @@ +import DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Matrix3DUtils = require("awayjs-core/lib/core/geom/Matrix3DUtils"); +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); + +/** + * Class Merge merges two or more static meshes into one.Merge + */ +class Merge +{ + + //private const LIMIT:uint = 196605; + private _objectSpace:boolean; + private _keepMaterial:boolean; + private _disposeSources:boolean; + private _geomVOs:Array; + private _toDispose:Array; + + /** + * @param keepMaterial [optional] Determines if the merged object uses the recevier mesh material information or keeps its source material(s). Defaults to false. + * If false and receiver object has multiple materials, the last material found in receiver submeshes is applied to the merged submesh(es). + * @param disposeSources [optional] Determines if the mesh and geometry source(s) used for the merging are disposed. Defaults to false. + * If true, only receiver geometry and resulting mesh are kept in memory. + * @param objectSpace [optional] Determines if source mesh(es) is/are merged using objectSpace or worldspace. Defaults to false. + */ + constructor(keepMaterial:boolean = false, disposeSources:boolean = false, objectSpace:boolean = false) + { + this._keepMaterial = keepMaterial; + this._disposeSources = disposeSources; + this._objectSpace = objectSpace; + } + + /** + * Determines if the mesh and geometry source(s) used for the merging are disposed. Defaults to false. + */ + public set disposeSources(b:boolean) + { + this._disposeSources = b; + } + + public get disposeSources():boolean + { + return this._disposeSources; + } + + /** + * Determines if the material source(s) used for the merging are disposed. Defaults to false. + */ + public set keepMaterial(b:boolean) + { + this._keepMaterial = b; + } + + public get keepMaterial():boolean + { + return this._keepMaterial; + } + + /** + * Determines if source mesh(es) is/are merged using objectSpace or worldspace. Defaults to false. + */ + public set objectSpace(b:boolean) + { + this._objectSpace = b; + } + + public get objectSpace():boolean + { + return this._objectSpace; + } + + /** + * Merges all the children of a container into a single Mesh. If no Mesh object is found, method returns the receiver without modification. + * + * @param receiver The Mesh to receive the merged contents of the container. + * @param objectContainer The DisplayObjectContainer holding the meshes to be mergd. + * + * @return The merged Mesh instance. + */ + public applyToContainer(receiver:Mesh, objectContainer:DisplayObjectContainer) + { + this.reset(); + + //collect container meshes + this.parseContainer(receiver, objectContainer); + + //collect receiver + this.collect(receiver, false); + + //merge to receiver + this.merge(receiver, this._disposeSources); + } + + /** + * Merges all the meshes found in the Array<Mesh> into a single Mesh. + * + * @param receiver The Mesh to receive the merged contents of the meshes. + * @param meshes A series of Meshes to be merged with the reciever mesh. + */ + public applyToMeshes(receiver:Mesh, meshes:Array) + { + this.reset(); + + if (!meshes.length) + return; + + //collect meshes in vector + for (var i:number /*uint*/ = 0; i < meshes.length; i++) + if (meshes[i] != receiver) + this.collect(meshes[i], this._disposeSources); + + //collect receiver + this.collect(receiver, false); + + //merge to receiver + this.merge(receiver, this._disposeSources); + } + + /** + * Merges 2 meshes into one. It is recommand to use apply when 2 meshes are to be merged. If more need to be merged, use either applyToMeshes or applyToContainer methods. + * + * @param receiver The Mesh to receive the merged contents of both meshes. + * @param mesh The Mesh to be merged with the receiver mesh + */ + public apply(receiver:Mesh, mesh:Mesh) + { + this.reset(); + + //collect mesh + this.collect(mesh, this._disposeSources); + + //collect receiver + this.collect(receiver, false); + + //merge to receiver + this.merge(receiver, this._disposeSources); + } + + private reset() + { + this._toDispose = new Array(); + this._geomVOs = new Array(); + } + + private merge(destMesh:Mesh, dispose:boolean) + { + var i:number /*uint*/; + var subIdx:number /*uint*/; + var oldGeom:Geometry; + var destGeom:Geometry; + var useSubMaterials:boolean; + + oldGeom = destMesh.geometry; + destGeom = destMesh.geometry = new Geometry(); + subIdx = destMesh.subMeshes.length; + + // Only apply materials directly to sub-meshes if necessary, + // i.e. if there is more than one material available. + useSubMaterials = (this._geomVOs.length > 1); + + for (i = 0; i < this._geomVOs.length; i++) { + var s:number /*uint*/; + var data:GeometryVO; + var sub:TriangleSubGeometry = new TriangleSubGeometry(true); + sub.autoDeriveNormals = false; + sub.autoDeriveTangents = false; + + data = this._geomVOs[i]; + sub.updateIndices(data.indices); + sub.updatePositions(data.vertices); + sub.updateVertexNormals(data.normals); + sub.updateVertexTangents(data.tangents); + sub.updateUVs(data.uvs); + + destGeom.addSubGeometry(sub); + + if (this._keepMaterial && useSubMaterials) + destMesh.subMeshes[subIdx].material = data.material; + } + + if (this._keepMaterial && !useSubMaterials && this._geomVOs.length) + destMesh.material = this._geomVOs[0].material; + + if (dispose) { + var m:Mesh; + var len:number = this._toDispose.length; + for (var i:number; i < len; i++) { + m = this._toDispose[i]; + m.geometry.dispose(); + m.dispose(); + } + + //dispose of the original receiver geometry + oldGeom.dispose(); + } + + this._toDispose = null; + } + + private collect(mesh:Mesh, dispose:boolean) + { + if (mesh.geometry) { + var subIdx:number /*uint*/; + var subGeometries:Array = > mesh.geometry.subGeometries; + var calc:number /*uint*/; + for (subIdx = 0; subIdx < subGeometries.length; subIdx++) { + var i:number /*uint*/; + var len:number /*uint*/; + var iIdx:number /*uint*/, vIdx:number /*uint*/, nIdx:number /*uint*/, tIdx:number /*uint*/, uIdx:number /*uint*/; + var indexOffset:number /*uint*/; + var subGeom:TriangleSubGeometry; + var vo:GeometryVO; + var vertices:Array; + var normals:Array; + var tangents:Array; + var pd:Array, nd:Array, td:Array, ud:Array; + + subGeom = subGeometries[subIdx]; + pd = subGeom.positions; + nd = subGeom.vertexNormals; + td = subGeom.vertexTangents; + ud = subGeom.uvs; + + // Get (or create) a VO for this material + vo = this.getSubGeomData(mesh.subMeshes[subIdx].material || mesh.material); + + // Vertices and normals are copied to temporary vectors, to be transformed + // before concatenated onto those of the data. This is unnecessary if no + // transformation will be performed, i.e. for object space merging. + vertices = (this._objectSpace)? vo.vertices : new Array(); + normals = (this._objectSpace)? vo.normals : new Array(); + tangents = (this._objectSpace)? vo.tangents : new Array(); + + // Copy over vertex attributes + vIdx = vertices.length; + nIdx = normals.length; + tIdx = tangents.length; + uIdx = vo.uvs.length; + len = subGeom.numVertices; + for (i = 0; i < len; i++) { + calc = i*3; + + // Position + vertices[vIdx++] = pd[calc]; + vertices[vIdx++] = pd[calc + 1]; + vertices[vIdx++] = pd[calc + 2]; + + // Normal + normals[nIdx++] = nd[calc]; + normals[nIdx++] = nd[calc + 1]; + normals[nIdx++] = nd[calc + 2]; + + // Tangent + tangents[tIdx++] = td[calc]; + tangents[tIdx++] = td[calc + 1]; + tangents[tIdx++] = td[calc + 2]; + + // UV + vo.uvs[uIdx++] = ud[i*2]; + vo.uvs[uIdx++] = ud[i*2 + 1]; + } + + // Copy over triangle indices + indexOffset = (!this._objectSpace)? vo.vertices.length/3 :0; + iIdx = vo.indices.length; + len = subGeom.numTriangles; + for (i = 0; i < len; i++) { + calc = i*3; + vo.indices[iIdx++] = subGeom.indices[calc] + indexOffset; + vo.indices[iIdx++] = subGeom.indices[calc + 1] + indexOffset; + vo.indices[iIdx++] = subGeom.indices[calc + 2] + indexOffset; + } + + if (!this._objectSpace) { + mesh.sceneTransform.transformVectors(vertices, vertices); + Matrix3DUtils.deltaTransformVectors(mesh.sceneTransform, normals, normals); + Matrix3DUtils.deltaTransformVectors(mesh.sceneTransform, tangents, tangents); + + // Copy vertex data from temporary (transformed) vectors + vIdx = vo.vertices.length; + nIdx = vo.normals.length; + tIdx = vo.tangents.length; + len = vertices.length; + for (i = 0; i < len; i++) { + vo.vertices[vIdx++] = vertices[i]; + vo.normals[nIdx++] = normals[i]; + vo.tangents[tIdx++] = tangents[i]; + } + } + } + + if (dispose) + this._toDispose.push(mesh); + } + } + + private getSubGeomData(material:MaterialBase):GeometryVO + { + var data:GeometryVO; + + if (this._keepMaterial) { + var i:number /*uint*/; + var len:number /*uint*/; + + len = this._geomVOs.length; + for (i = 0; i < len; i++) { + if (this._geomVOs[i].material == material) { + data = this._geomVOs[i]; + break; + } + } + } else if (this._geomVOs.length) { + // If materials are not to be kept, all data can be + // put into a single VO, so return that one. + data = this._geomVOs[0]; + } + + // No data (for this material) found, create new. + if (!data) { + data = new GeometryVO(); + data.vertices = new Array(); + data.normals = new Array(); + data.tangents = new Array(); + data.uvs = new Array(); + data.indices = new Array(); + data.material = material; + + this._geomVOs.push(data); + } + + return data; + } + + private parseContainer(receiver:Mesh, object:DisplayObjectContainer) + { + var child:DisplayObjectContainer; + var i:number /*uint*/; + + if (object instanceof Mesh && object != ( receiver)) + this.collect( object, this._disposeSources); + + for (i = 0; i < object.numChildren; ++i) { + child = object.getChildAt(i); + this.parseContainer(receiver, child); + } + } +} + +export = Merge; + +class GeometryVO +{ + public uvs:Array; + public vertices:Array; + public normals:Array; + public tangents:Array; + public indices:Array; + public material:MaterialBase; +} diff --git a/lib/tools/data/ParticleGeometryTransform.js b/lib/tools/data/ParticleGeometryTransform.js new file mode 100755 index 000000000..55ead879d --- /dev/null +++ b/lib/tools/data/ParticleGeometryTransform.js @@ -0,0 +1,41 @@ +/** + * ... + */ +var ParticleGeometryTransform = (function () { + function ParticleGeometryTransform() { + } + Object.defineProperty(ParticleGeometryTransform.prototype, "vertexTransform", { + get: function () { + return this._defaultVertexTransform; + }, + set: function (value) { + this._defaultVertexTransform = value; + this._defaultInvVertexTransform = value.clone(); + this._defaultInvVertexTransform.invert(); + this._defaultInvVertexTransform.transpose(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ParticleGeometryTransform.prototype, "UVTransform", { + get: function () { + return this._defaultUVTransform; + }, + set: function (value) { + this._defaultUVTransform = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ParticleGeometryTransform.prototype, "invVertexTransform", { + get: function () { + return this._defaultInvVertexTransform; + }, + enumerable: true, + configurable: true + }); + return ParticleGeometryTransform; +})(); +module.exports = ParticleGeometryTransform; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRvb2xzL2RhdGEvcGFydGljbGVnZW9tZXRyeXRyYW5zZm9ybS50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtIiwiUGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybS5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlR2VvbWV0cnlUcmFuc2Zvcm0udmVydGV4VHJhbnNmb3JtIiwiUGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybS5VVlRyYW5zZm9ybSIsIlBhcnRpY2xlR2VvbWV0cnlUcmFuc2Zvcm0uaW52VmVydGV4VHJhbnNmb3JtIl0sIm1hcHBpbmdzIjoiQUFHQSxBQUdBOztHQURHO0lBQ0cseUJBQXlCO0lBQS9CQSxTQUFNQSx5QkFBeUJBO0lBaUMvQkMsQ0FBQ0E7SUEzQkFELHNCQUFXQSxzREFBZUE7YUFrQjFCQTtZQUVDRSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSx1QkFBdUJBLENBQUNBO1FBQ3JDQSxDQUFDQTthQXJCREYsVUFBMkJBLEtBQWNBO1lBRXhDRSxJQUFJQSxDQUFDQSx1QkFBdUJBLEdBQUdBLEtBQUtBLENBQUNBO1lBQ3JDQSxJQUFJQSxDQUFDQSwwQkFBMEJBLEdBQUdBLEtBQUtBLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBO1lBQ2hEQSxJQUFJQSxDQUFDQSwwQkFBMEJBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBO1lBQ3pDQSxJQUFJQSxDQUFDQSwwQkFBMEJBLENBQUNBLFNBQVNBLEVBQUVBLENBQUNBO1FBQzdDQSxDQUFDQTs7O09BQUFGO0lBRURBLHNCQUFXQSxrREFBV0E7YUFLdEJBO1lBRUNHLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLG1CQUFtQkEsQ0FBQ0E7UUFDakNBLENBQUNBO2FBUkRILFVBQXVCQSxLQUFZQTtZQUVsQ0csSUFBSUEsQ0FBQ0EsbUJBQW1CQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUNsQ0EsQ0FBQ0E7OztPQUFBSDtJQVlEQSxzQkFBV0EseURBQWtCQTthQUE3QkE7WUFFQ0ksTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsMEJBQTBCQSxDQUFDQTtRQUN4Q0EsQ0FBQ0E7OztPQUFBSjtJQUNGQSxnQ0FBQ0E7QUFBREEsQ0FqQ0EsQUFpQ0NBLElBQUE7QUFFRCxBQUFtQyxpQkFBMUIseUJBQXlCLENBQUMiLCJmaWxlIjoidG9vbHMvZGF0YS9QYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE1hdHJpeFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXhcIik7XG5pbXBvcnQgTWF0cml4M0RcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vTWF0cml4M0RcIik7XG5cbi8qKlxuICogLi4uXG4gKi9cbmNsYXNzIFBhcnRpY2xlR2VvbWV0cnlUcmFuc2Zvcm1cbntcblx0cHJpdmF0ZSBfZGVmYXVsdFZlcnRleFRyYW5zZm9ybTpNYXRyaXgzRDtcblx0cHJpdmF0ZSBfZGVmYXVsdEludlZlcnRleFRyYW5zZm9ybTpNYXRyaXgzRDtcblx0cHJpdmF0ZSBfZGVmYXVsdFVWVHJhbnNmb3JtOk1hdHJpeDtcblxuXHRwdWJsaWMgc2V0IHZlcnRleFRyYW5zZm9ybSh2YWx1ZTpNYXRyaXgzRClcblx0e1xuXHRcdHRoaXMuX2RlZmF1bHRWZXJ0ZXhUcmFuc2Zvcm0gPSB2YWx1ZTtcblx0XHR0aGlzLl9kZWZhdWx0SW52VmVydGV4VHJhbnNmb3JtID0gdmFsdWUuY2xvbmUoKTtcblx0XHR0aGlzLl9kZWZhdWx0SW52VmVydGV4VHJhbnNmb3JtLmludmVydCgpO1xuXHRcdHRoaXMuX2RlZmF1bHRJbnZWZXJ0ZXhUcmFuc2Zvcm0udHJhbnNwb3NlKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0IFVWVHJhbnNmb3JtKHZhbHVlOk1hdHJpeClcblx0e1xuXHRcdHRoaXMuX2RlZmF1bHRVVlRyYW5zZm9ybSA9IHZhbHVlO1xuXHR9XG5cblx0cHVibGljIGdldCBVVlRyYW5zZm9ybSgpOk1hdHJpeFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2RlZmF1bHRVVlRyYW5zZm9ybTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgdmVydGV4VHJhbnNmb3JtKCk6TWF0cml4M0Rcblx0e1xuXHRcdHJldHVybiB0aGlzLl9kZWZhdWx0VmVydGV4VHJhbnNmb3JtO1xuXHR9XG5cblx0cHVibGljIGdldCBpbnZWZXJ0ZXhUcmFuc2Zvcm0oKTpNYXRyaXgzRFxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2RlZmF1bHRJbnZWZXJ0ZXhUcmFuc2Zvcm07XG5cdH1cbn1cblxuZXhwb3J0ID0gUGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybTsiXX0= \ No newline at end of file diff --git a/lib/tools/data/ParticleGeometryTransform.ts b/lib/tools/data/ParticleGeometryTransform.ts new file mode 100644 index 000000000..f431de15e --- /dev/null +++ b/lib/tools/data/ParticleGeometryTransform.ts @@ -0,0 +1,42 @@ +import Matrix = require("awayjs-core/lib/core/geom/Matrix"); +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); + +/** + * ... + */ +class ParticleGeometryTransform +{ + private _defaultVertexTransform:Matrix3D; + private _defaultInvVertexTransform:Matrix3D; + private _defaultUVTransform:Matrix; + + public set vertexTransform(value:Matrix3D) + { + this._defaultVertexTransform = value; + this._defaultInvVertexTransform = value.clone(); + this._defaultInvVertexTransform.invert(); + this._defaultInvVertexTransform.transpose(); + } + + public set UVTransform(value:Matrix) + { + this._defaultUVTransform = value; + } + + public get UVTransform():Matrix + { + return this._defaultUVTransform; + } + + public get vertexTransform():Matrix3D + { + return this._defaultVertexTransform; + } + + public get invVertexTransform():Matrix3D + { + return this._defaultInvVertexTransform; + } +} + +export = ParticleGeometryTransform; \ No newline at end of file diff --git a/lib/tools/helpers/ParticleGeometryHelper.js b/lib/tools/helpers/ParticleGeometryHelper.js new file mode 100755 index 000000000..ae954cad7 --- /dev/null +++ b/lib/tools/helpers/ParticleGeometryHelper.js @@ -0,0 +1,180 @@ +var TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +var Point = require("awayjs-core/lib/core/geom/Point"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var ParticleData = require("awayjs-renderergl/lib/animators/data/ParticleData"); +var ParticleGeometry = require("awayjs-renderergl/lib/core/base/ParticleGeometry"); +/** + * ... + */ +var ParticleGeometryHelper = (function () { + function ParticleGeometryHelper() { + } + ParticleGeometryHelper.generateGeometry = function (geometries, transforms) { + if (transforms === void 0) { transforms = null; } + var indicesVector = new Array() /*uint*/; + var positionsVector = new Array(); + var normalsVector = new Array(); + var tangentsVector = new Array(); + var uvsVector = new Array(); + var vertexCounters = new Array() /*uint*/; + var particles = new Array(); + var subGeometries = new Array(); + var numParticles = geometries.length; + var sourceSubGeometries; + var sourceSubGeometry; + var numSubGeometries /*uint*/; + var indices /*uint*/; + var positions; + var normals; + var tangents; + var uvs; + var vertexCounter /*uint*/; + var subGeometry; + var i /*int*/; + var j /*int*/; + var sub2SubMap = new Array() /*int*/; + var tempVertex = new Vector3D; + var tempNormal = new Vector3D; + var tempTangents = new Vector3D; + var tempUV = new Point; + for (i = 0; i < numParticles; i++) { + sourceSubGeometries = geometries[i].subGeometries; + numSubGeometries = sourceSubGeometries.length; + for (var srcIndex = 0; srcIndex < numSubGeometries; srcIndex++) { + //create a different particle subgeometry group for each source subgeometry in a particle. + if (sub2SubMap.length <= srcIndex) { + sub2SubMap.push(subGeometries.length); + indicesVector.push(new Array()); + positionsVector.push(new Array()); + normalsVector.push(new Array()); + tangentsVector.push(new Array()); + uvsVector.push(new Array()); + subGeometries.push(new TriangleSubGeometry(true)); + vertexCounters.push(0); + } + sourceSubGeometry = sourceSubGeometries[srcIndex]; + //add a new particle subgeometry if this source subgeometry will take us over the maxvertex limit + if (sourceSubGeometry.numVertices + vertexCounters[sub2SubMap[srcIndex]] > ParticleGeometryHelper.MAX_VERTEX) { + //update submap and add new subgeom vectors + sub2SubMap[srcIndex] = subGeometries.length; + indicesVector.push(new Array()); + positionsVector.push(new Array()); + normalsVector.push(new Array()); + tangentsVector.push(new Array()); + uvsVector.push(new Array()); + subGeometries.push(new TriangleSubGeometry(true)); + vertexCounters.push(0); + } + j = sub2SubMap[srcIndex]; + //select the correct vector + indices = indicesVector[j]; + positions = positionsVector[j]; + normals = normalsVector[j]; + tangents = tangentsVector[j]; + uvs = uvsVector[j]; + vertexCounter = vertexCounters[j]; + subGeometry = subGeometries[j]; + var particleData = new ParticleData(); + particleData.numVertices = sourceSubGeometry.numVertices; + particleData.startVertexIndex = vertexCounter; + particleData.particleIndex = i; + particleData.subGeometry = subGeometry; + particles.push(particleData); + vertexCounters[j] += sourceSubGeometry.numVertices; + var k /*int*/; + var tempLen /*int*/; + var compact = sourceSubGeometry; + var product /*uint*/; + var sourcePositions; + var sourceNormals; + var sourceTangents; + var sourceUVs; + if (compact) { + tempLen = compact.numVertices; + compact.numTriangles; + sourcePositions = compact.positions; + sourceNormals = compact.vertexNormals; + sourceTangents = compact.vertexTangents; + sourceUVs = compact.uvs; + if (transforms) { + var particleGeometryTransform = transforms[i]; + var vertexTransform = particleGeometryTransform.vertexTransform; + var invVertexTransform = particleGeometryTransform.invVertexTransform; + var UVTransform = particleGeometryTransform.UVTransform; + for (k = 0; k < tempLen; k++) { + /* + * 0 - 2: vertex position X, Y, Z + * 3 - 5: normal X, Y, Z + * 6 - 8: tangent X, Y, Z + * 9 - 10: U V + * 11 - 12: Secondary U V*/ + product = k * 3; + tempVertex.x = sourcePositions[product]; + tempVertex.y = sourcePositions[product + 1]; + tempVertex.z = sourcePositions[product + 2]; + tempNormal.x = sourceNormals[product]; + tempNormal.y = sourceNormals[product + 1]; + tempNormal.z = sourceNormals[product + 2]; + tempTangents.x = sourceTangents[product]; + tempTangents.y = sourceTangents[product + 1]; + tempTangents.z = sourceTangents[product + 2]; + tempUV.x = sourceUVs[k * 2]; + tempUV.y = sourceUVs[k * 2 + 1]; + if (vertexTransform) { + tempVertex = vertexTransform.transformVector(tempVertex); + tempNormal = invVertexTransform.deltaTransformVector(tempNormal); + tempTangents = invVertexTransform.deltaTransformVector(tempNormal); + } + if (UVTransform) + tempUV = UVTransform.transformPoint(tempUV); + //this is faster than that only push one data + sourcePositions.push(tempVertex.x, tempVertex.y, tempVertex.z); + sourceNormals.push(tempNormal.x, tempNormal.y, tempNormal.z); + sourceTangents.push(tempTangents.x, tempTangents.y, tempTangents.z); + sourceUVs.push(tempUV.x, tempUV.y); + } + } + else { + for (k = 0; k < tempLen; k++) { + product = k * 3; + //this is faster than that only push one data + positions.push(sourcePositions[product], sourcePositions[product + 1], sourcePositions[product + 2]); + normals.push(sourceNormals[product], sourceNormals[product + 1], sourceNormals[product + 2]); + tangents.push(sourceTangents[product], sourceTangents[product + 1], sourceTangents[product + 2]); + uvs.push(sourceUVs[k * 2], sourceUVs[k * 2 + 1]); + } + } + } + else { + } + var sourceIndices = sourceSubGeometry.indices; + tempLen = sourceSubGeometry.numTriangles; + for (k = 0; k < tempLen; k++) { + product = k * 3; + indices.push(sourceIndices[product] + vertexCounter, sourceIndices[product + 1] + vertexCounter, sourceIndices[product + 2] + vertexCounter); + } + } + } + var particleGeometry = new ParticleGeometry(); + particleGeometry.particles = particles; + particleGeometry.numParticles = numParticles; + numParticles = subGeometries.length; + for (i = 0; i < numParticles; i++) { + subGeometry = subGeometries[i]; + subGeometry.autoDeriveNormals = false; + subGeometry.autoDeriveTangents = false; + subGeometry.updateIndices(indicesVector[i]); + subGeometry.updatePositions(positionsVector[i]); + subGeometry.updateVertexNormals(normalsVector[i]); + subGeometry.updateVertexTangents(tangentsVector[i]); + subGeometry.updateUVs(uvsVector[i]); + particleGeometry.addSubGeometry(subGeometry); + } + return particleGeometry; + }; + ParticleGeometryHelper.MAX_VERTEX = 65535; + return ParticleGeometryHelper; +})(); +module.exports = ParticleGeometryHelper; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRvb2xzL2hlbHBlcnMvcGFydGljbGVnZW9tZXRyeWhlbHBlci50cyJdLCJuYW1lcyI6WyJQYXJ0aWNsZUdlb21ldHJ5SGVscGVyIiwiUGFydGljbGVHZW9tZXRyeUhlbHBlci5jb25zdHJ1Y3RvciIsIlBhcnRpY2xlR2VvbWV0cnlIZWxwZXIuZ2VuZXJhdGVHZW9tZXRyeSJdLCJtYXBwaW5ncyI6IkFBQ0EsSUFBTyxtQkFBbUIsV0FBYywrQ0FBK0MsQ0FBQyxDQUFDO0FBR3pGLElBQU8sS0FBSyxXQUFpQixpQ0FBaUMsQ0FBQyxDQUFDO0FBQ2hFLElBQU8sUUFBUSxXQUFpQixvQ0FBb0MsQ0FBQyxDQUFDO0FBS3RFLElBQU8sWUFBWSxXQUFnQixtREFBbUQsQ0FBQyxDQUFDO0FBQ3hGLElBQU8sZ0JBQWdCLFdBQWUsa0RBQWtELENBQUMsQ0FBQztBQUcxRixBQUdBOztHQURHO0lBQ0csc0JBQXNCO0lBQTVCQSxTQUFNQSxzQkFBc0JBO0lBdUw1QkMsQ0FBQ0E7SUFuTGNELHVDQUFnQkEsR0FBOUJBLFVBQStCQSxVQUEwQkEsRUFBRUEsVUFBa0RBO1FBQWxERSwwQkFBa0RBLEdBQWxEQSxpQkFBa0RBO1FBRTVHQSxJQUFJQSxhQUFhQSxHQUFpQ0EsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBLFFBQURBLEFBQVNBLENBQUNBO1FBQ3RGQSxJQUFJQSxlQUFlQSxHQUF3QkEsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBO1FBQ3RFQSxJQUFJQSxhQUFhQSxHQUF3QkEsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBO1FBQ3BFQSxJQUFJQSxjQUFjQSxHQUF3QkEsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBO1FBQ3JFQSxJQUFJQSxTQUFTQSxHQUF3QkEsSUFBSUEsS0FBS0EsRUFBaUJBLENBQUNBO1FBQ2hFQSxJQUFJQSxjQUFjQSxHQUEwQkEsSUFBSUEsS0FBS0EsRUFBVUEsQ0FBQ0EsUUFBREEsQUFBU0EsQ0FBQ0E7UUFDekVBLElBQUlBLFNBQVNBLEdBQXVCQSxJ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dUxDQSxJQUFBO0FBRUQsQUFBZ0MsaUJBQXZCLHNCQUFzQixDQUFDIiwiZmlsZSI6InRvb2xzL2hlbHBlcnMvUGFydGljbGVHZW9tZXRyeUhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBHZW9tZXRyeVx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvYmFzZS9HZW9tZXRyeVwiKTtcbmltcG9ydCBUcmlhbmdsZVN1Ykdlb21ldHJ5XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL1RyaWFuZ2xlU3ViR2VvbWV0cnlcIik7XG5pbXBvcnQgTWF0cml4XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeFwiKTtcbmltcG9ydCBNYXRyaXgzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9NYXRyaXgzRFwiKTtcbmltcG9ydCBQb2ludFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9Qb2ludFwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcblxuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTWF0ZXJpYWxCYXNlXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9NYXRlcmlhbEJhc2VcIik7XG5cbmltcG9ydCBQYXJ0aWNsZURhdGFcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvYW5pbWF0b3JzL2RhdGEvUGFydGljbGVEYXRhXCIpO1xuaW1wb3J0IFBhcnRpY2xlR2VvbWV0cnlcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL2NvcmUvYmFzZS9QYXJ0aWNsZUdlb21ldHJ5XCIpO1xuaW1wb3J0IFBhcnRpY2xlR2VvbWV0cnlUcmFuc2Zvcm1cdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3Rvb2xzL2RhdGEvUGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybVwiKTtcblxuLyoqXG4gKiAuLi5cbiAqL1xuY2xhc3MgUGFydGljbGVHZW9tZXRyeUhlbHBlclxue1xuXHRwdWJsaWMgc3RhdGljIE1BWF9WRVJURVg6bnVtYmVyIC8qaW50Ki8gPSA2NTUzNTtcblxuXHRwdWJsaWMgc3RhdGljIGdlbmVyYXRlR2VvbWV0cnkoZ2VvbWV0cmllczpBcnJheTxHZW9tZXRyeT4sIHRyYW5zZm9ybXM6QXJyYXk8UGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybT4gPSBudWxsKTpQYXJ0aWNsZUdlb21ldHJ5XG5cdHtcblx0XHR2YXIgaW5kaWNlc1ZlY3RvcjpBcnJheTxBcnJheTxudW1iZXI+PiAvKnVpbnQqLyA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PigpIC8qdWludCovO1xuXHRcdHZhciBwb3NpdGlvbnNWZWN0b3I6QXJyYXk8QXJyYXk8bnVtYmVyPj4gPSBuZXcgQXJyYXk8QXJyYXk8bnVtYmVyPj4oKTtcblx0XHR2YXIgbm9ybWFsc1ZlY3RvcjpBcnJheTxBcnJheTxudW1iZXI+PiA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PigpO1xuXHRcdHZhciB0YW5nZW50c1ZlY3RvcjpBcnJheTxBcnJheTxudW1iZXI+PiA9IG5ldyBBcnJheTxBcnJheTxudW1iZXI+PigpO1xuXHRcdHZhciB1dnNWZWN0b3I6QXJyYXk8QXJyYXk8bnVtYmVyPj4gPSBuZXcgQXJyYXk8QXJyYXk8bnVtYmVyPj4oKTtcblx0XHR2YXIgdmVydGV4Q291bnRlcnM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLyA9IG5ldyBBcnJheTxudW1iZXI+KCkgLyp1aW50Ki87XG5cdFx0dmFyIHBhcnRpY2xlczpBcnJheTxQYXJ0aWNsZURhdGE+ID0gbmV3IEFycmF5PFBhcnRpY2xlRGF0YT4oKTtcblx0XHR2YXIgc3ViR2VvbWV0cmllczpBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5PiA9IG5ldyBBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5PigpO1xuXHRcdHZhciBudW1QYXJ0aWNsZXM6bnVtYmVyIC8qdWludCovID0gZ2VvbWV0cmllcy5sZW5ndGg7XG5cblx0XHR2YXIgc291cmNlU3ViR2VvbWV0cmllczpBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5Pjtcblx0XHR2YXIgc291cmNlU3ViR2VvbWV0cnk6VHJpYW5nbGVTdWJHZW9tZXRyeTtcblx0XHR2YXIgbnVtU3ViR2VvbWV0cmllczpudW1iZXIgLyp1aW50Ki87XG5cdFx0dmFyIGluZGljZXM6QXJyYXk8bnVtYmVyPiAvKnVpbnQqLztcblx0XHR2YXIgcG9zaXRpb25zOkFycmF5PG51bWJlcj47XG5cdFx0dmFyIG5vcm1hbHM6QXJyYXk8bnVtYmVyPjtcblx0XHR2YXIgdGFuZ2VudHM6QXJyYXk8bnVtYmVyPjtcblx0XHR2YXIgdXZzOkFycmF5PG51bWJlcj47XG5cdFx0dmFyIHZlcnRleENvdW50ZXI6bnVtYmVyIC8qdWludCovO1xuXHRcdHZhciBzdWJHZW9tZXRyeTpUcmlhbmdsZVN1Ykdlb21ldHJ5O1xuXHRcdHZhciBpOm51bWJlciAvKmludCovO1xuXHRcdHZhciBqOm51bWJlciAvKmludCovO1xuXHRcdHZhciBzdWIyU3ViTWFwOkFycmF5PG51bWJlcj4gLyppbnQqLyA9IG5ldyBBcnJheTxudW1iZXI+KCkgLyppbnQqLztcblxuXHRcdHZhciB0ZW1wVmVydGV4OlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEO1xuXHRcdHZhciB0ZW1wTm9ybWFsOlZlY3RvcjNEID0gbmV3IFZlY3RvcjNEO1xuXHRcdHZhciB0ZW1wVGFuZ2VudHM6VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0Q7XG5cdFx0dmFyIHRlbXBVVjpQb2ludCA9IG5ldyBQb2ludDtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCBudW1QYXJ0aWNsZXM7IGkrKykge1xuXHRcdFx0c291cmNlU3ViR2VvbWV0cmllcyA9IDxBcnJheTxUcmlhbmdsZVN1Ykdlb21ldHJ5Pj4gZ2VvbWV0cmllc1tpXS5zdWJHZW9tZXRyaWVzO1xuXHRcdFx0bnVtU3ViR2VvbWV0cmllcyA9IHNvdXJjZVN1Ykdlb21ldHJpZXMubGVuZ3RoO1xuXHRcdFx0Zm9yICh2YXIgc3JjSW5kZXg6bnVtYmVyIC8qaW50Ki8gPSAwOyBzcmNJbmRleCA8IG51bVN1Ykdlb21ldHJpZXM7IHNyY0luZGV4KyspIHtcblx0XHRcdFx0Ly9jcmVhdGUgYSBkaWZmZXJlbnQgcGFydGljbGUgc3ViZ2VvbWV0cnkgZ3JvdXAgZm9yIGVhY2ggc291cmNlIHN1Ymdlb21ldHJ5IGluIGEgcGFydGljbGUuXG5cdFx0XHRcdGlmIChzdWIyU3ViTWFwLmxlbmd0aCA8PSBzcmNJbmRleCkge1xuXHRcdFx0XHRcdHN1YjJTdWJNYXAucHVzaChzdWJHZW9tZXRyaWVzLmxlbmd0aCk7XG5cdFx0XHRcdFx0aW5kaWNlc1ZlY3Rvci5wdXNoKG5ldyBBcnJheTxudW1iZXI+KCkgLyp1aW50Ki8pO1xuXHRcdFx0XHRcdHBvc2l0aW9uc1ZlY3Rvci5wdXNoKG5ldyBBcnJheTxudW1iZXI+KCkpO1xuXHRcdFx0XHRcdG5vcm1hbHNWZWN0b3IucHVzaChuZXcgQXJyYXk8bnVtYmVyPigpKTtcblx0XHRcdFx0XHR0YW5nZW50c1ZlY3Rvci5wdXNoKG5ldyBBcnJheTxudW1iZXI+KCkpO1xuXHRcdFx0XHRcdHV2c1ZlY3Rvci5wdXNoKG5ldyBBcnJheTxudW1iZXI+KCkpO1xuXHRcdFx0XHRcdHN1Ykdlb21ldHJpZXMucHVzaChuZXcgVHJpYW5nbGVTdWJHZW9tZXRyeSh0cnVlKSk7XG5cdFx0XHRcdFx0dmVydGV4Q291bnRlcnMucHVzaCgwKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNvdXJjZVN1Ykdlb21ldHJ5ID0gc291cmNlU3ViR2VvbWV0cmllc1tzcmNJbmRleF07XG5cblx0XHRcdFx0Ly9hZGQgYSBuZXcgcGFydGljbGUgc3ViZ2VvbWV0cnkgaWYgdGhpcyBzb3VyY2Ugc3ViZ2VvbWV0cnkgd2lsbCB0YWtlIHVzIG92ZXIgdGhlIG1heHZlcnRleCBsaW1pdFxuXHRcdFx0XHRpZiAoc291cmNlU3ViR2VvbWV0cnkubnVtVmVydGljZXMgKyB2ZXJ0ZXhDb3VudGVyc1tzdWIyU3ViTWFwW3NyY0luZGV4XV0gPiBQYXJ0aWNsZUdlb21ldHJ5SGVscGVyLk1BWF9WRVJURVgpIHtcblx0XHRcdFx0XHQvL3VwZGF0ZSBzdWJtYXAgYW5kIGFkZCBuZXcgc3ViZ2VvbSB2ZWN0b3JzXG5cdFx0XHRcdFx0c3ViMlN1Yk1hcFtzcmNJbmRleF0gPSBzdWJHZW9tZXRyaWVzLmxlbmd0aDtcblx0XHRcdFx0XHRpbmRpY2VzVmVjdG9yLnB1c2gobmV3IEFycmF5PG51bWJlcj4oKSAvKnVpbnQqLyk7XG5cdFx0XHRcdFx0cG9zaXRpb25zVmVjdG9yLnB1c2gobmV3IEFycmF5PG51bWJlcj4oKSk7XG5cdFx0XHRcdFx0bm9ybWFsc1ZlY3Rvci5wdXNoKG5ldyBBcnJheTxudW1iZXI+KCkpO1xuXHRcdFx0XHRcdHRhbmdlbnRzVmVjdG9yLnB1c2gobmV3IEFycmF5PG51bWJlcj4oKSk7XG5cdFx0XHRcdFx0dXZzVmVjdG9yLnB1c2gobmV3IEFycmF5PG51bWJlcj4oKSk7XG5cdFx0XHRcdFx0c3ViR2VvbWV0cmllcy5wdXNoKG5ldyBUcmlhbmdsZVN1Ykdlb21ldHJ5KHRydWUpKTtcblx0XHRcdFx0XHR2ZXJ0ZXhDb3VudGVycy5wdXNoKDApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aiA9IHN1YjJTdWJNYXBbc3JjSW5kZXhdO1xuXG5cdFx0XHRcdC8vc2VsZWN0IHRoZSBjb3JyZWN0IHZlY3RvclxuXHRcdFx0XHRpbmRpY2VzID0gaW5kaWNlc1ZlY3RvcltqXTtcblx0XHRcdFx0cG9zaXRpb25zID0gcG9zaXRpb25zVmVjdG9yW2pdO1xuXHRcdFx0XHRub3JtYWxzID0gbm9ybWFsc1ZlY3RvcltqXTtcblx0XHRcdFx0dGFuZ2VudHMgPSB0YW5nZW50c1ZlY3RvcltqXTtcblx0XHRcdFx0dXZzID0gdXZzVmVjdG9yW2pdO1xuXHRcdFx0XHR2ZXJ0ZXhDb3VudGVyID0gdmVydGV4Q291bnRlcnNbal07XG5cdFx0XHRcdHN1Ykdlb21ldHJ5ID0gc3ViR2VvbWV0cmllc1tqXTtcblxuXHRcdFx0XHR2YXIgcGFydGljbGVEYXRhOlBhcnRpY2xlRGF0YSA9IG5ldyBQYXJ0aWNsZURhdGEoKTtcblx0XHRcdFx0cGFydGljbGVEYXRhLm51bVZlcnRpY2VzID0gc291cmNlU3ViR2VvbWV0cnkubnVtVmVydGljZXM7XG5cdFx0XHRcdHBhcnRpY2xlRGF0YS5zdGFydFZlcnRleEluZGV4ID0gdmVydGV4Q291bnRlcjtcblx0XHRcdFx0cGFydGljbGVEYXRhLnBhcnRpY2xlSW5kZXggPSBpO1xuXHRcdFx0XHRwYXJ0aWNsZURhdGEuc3ViR2VvbWV0cnkgPSBzdWJHZW9tZXRyeTtcblx0XHRcdFx0cGFydGljbGVzLnB1c2gocGFydGljbGVEYXRhKTtcblxuXHRcdFx0XHR2ZXJ0ZXhDb3VudGVyc1tqXSArPSBzb3VyY2VTdWJHZW9tZXRyeS5udW1WZXJ0aWNlcztcblxuXHRcdFx0XHR2YXIgazpudW1iZXIgLyppbnQqLztcblx0XHRcdFx0dmFyIHRlbXBMZW46bnVtYmVyIC8qaW50Ki87XG5cdFx0XHRcdHZhciBjb21wYWN0OlRyaWFuZ2xlU3ViR2VvbWV0cnkgPSBzb3VyY2VTdWJHZW9tZXRyeTtcblx0XHRcdFx0dmFyIHByb2R1Y3Q6bnVtYmVyIC8qdWludCovO1xuXHRcdFx0XHR2YXIgc291cmNlUG9zaXRpb25zOkFycmF5PG51bWJlcj47XG5cdFx0XHRcdHZhciBzb3VyY2VOb3JtYWxzOkFycmF5PG51bWJlcj47XG5cdFx0XHRcdHZhciBzb3VyY2VUYW5nZW50czpBcnJheTxudW1iZXI+O1xuXHRcdFx0XHR2YXIgc291cmNlVVZzOkFycmF5PG51bWJlcj47XG5cblx0XHRcdFx0aWYgKGNvbXBhY3QpIHtcblx0XHRcdFx0XHR0ZW1wTGVuID0gY29tcGFjdC5udW1WZXJ0aWNlcztcblx0XHRcdFx0XHRjb21wYWN0Lm51bVRyaWFuZ2xlcztcblx0XHRcdFx0XHRzb3VyY2VQb3NpdGlvbnMgPSBjb21wYWN0LnBvc2l0aW9ucztcblx0XHRcdFx0XHRzb3VyY2VOb3JtYWxzID0gY29tcGFjdC52ZXJ0ZXhOb3JtYWxzO1xuXHRcdFx0XHRcdHNvdXJjZVRhbmdlbnRzID0gY29tcGFjdC52ZXJ0ZXhUYW5nZW50cztcblx0XHRcdFx0XHRzb3VyY2VVVnMgPSBjb21wYWN0LnV2cztcblxuXHRcdFx0XHRcdGlmICh0cmFuc2Zvcm1zKSB7XG5cdFx0XHRcdFx0XHR2YXIgcGFydGljbGVHZW9tZXRyeVRyYW5zZm9ybTpQYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtID0gdHJhbnNmb3Jtc1tpXTtcblx0XHRcdFx0XHRcdHZhciB2ZXJ0ZXhUcmFuc2Zvcm06TWF0cml4M0QgPSBwYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtLnZlcnRleFRyYW5zZm9ybTtcblx0XHRcdFx0XHRcdHZhciBpbnZWZXJ0ZXhUcmFuc2Zvcm06TWF0cml4M0QgPSBwYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtLmludlZlcnRleFRyYW5zZm9ybTtcblx0XHRcdFx0XHRcdHZhciBVVlRyYW5zZm9ybTpNYXRyaXggPSBwYXJ0aWNsZUdlb21ldHJ5VHJhbnNmb3JtLlVWVHJhbnNmb3JtO1xuXG5cdFx0XHRcdFx0XHRmb3IgKGsgPSAwOyBrIDwgdGVtcExlbjsgaysrKSB7XG5cdFx0XHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0XHRcdCAqIDAgLSAyOiB2ZXJ0ZXggcG9zaXRpb24gWCwgWSwgWlxuXHRcdFx0XHRcdFx0XHQgKiAzIC0gNTogbm9ybWFsIFgsIFksIFpcblx0XHRcdFx0XHRcdFx0ICogNiAtIDg6IHRhbmdlbnQgWCwgWSwgWlxuXHRcdFx0XHRcdFx0XHQgKiA5IC0gMTA6IFUgVlxuXHRcdFx0XHRcdFx0XHQgKiAxMSAtIDEyOiBTZWNvbmRhcnkgVSBWKi9cblx0XHRcdFx0XHRcdFx0cHJvZHVjdCA9IGsqMztcblx0XHRcdFx0XHRcdFx0dGVtcFZlcnRleC54ID0gc291cmNlUG9zaXRpb25zW3Byb2R1Y3RdO1xuXHRcdFx0XHRcdFx0XHR0ZW1wVmVydGV4LnkgPSBzb3VyY2VQb3NpdGlvbnNbcHJvZHVjdCArIDFdO1xuXHRcdFx0XHRcdFx0XHR0ZW1wVmVydGV4LnogPSBzb3VyY2VQb3NpdGlvbnNbcHJvZHVjdCArIDJdO1xuXHRcdFx0XHRcdFx0XHR0ZW1wTm9ybWFsLnggPSBzb3VyY2VOb3JtYWxzW3Byb2R1Y3RdO1xuXHRcdFx0XHRcdFx0XHR0ZW1wTm9ybWFsLnkgPSBzb3VyY2VOb3JtYWxzW3Byb2R1Y3QgKyAxXTtcblx0XHRcdFx0XHRcdFx0dGVtcE5vcm1hbC56ID0gc291cmNlTm9ybWFsc1twcm9kdWN0ICsgMl07XG5cdFx0XHRcdFx0XHRcdHRlbXBUYW5nZW50cy54ID0gc291cmNlVGFuZ2VudHNbcHJvZHVjdF07XG5cdFx0XHRcdFx0XHRcdHRlbXBUYW5nZW50cy55ID0gc291cmNlVGFuZ2VudHNbcHJvZHVjdCArIDFdO1xuXHRcdFx0XHRcdFx0XHR0ZW1wVGFuZ2VudHMueiA9IHNvdXJjZVRhbmdlbnRzW3Byb2R1Y3QgKyAyXTtcblx0XHRcdFx0XHRcdFx0dGVtcFVWLnggPSBzb3VyY2VVVnNbayoyXTtcblx0XHRcdFx0XHRcdFx0dGVtcFVWLnkgPSBzb3VyY2VVVnNbayoyICsgMV07XG5cdFx0XHRcdFx0XHRcdGlmICh2ZXJ0ZXhUcmFuc2Zvcm0pIHtcblx0XHRcdFx0XHRcdFx0XHR0ZW1wVmVydGV4ID0gdmVydGV4VHJhbnNmb3JtLnRyYW5zZm9ybVZlY3Rvcih0ZW1wVmVydGV4KTtcblx0XHRcdFx0XHRcdFx0XHR0ZW1wTm9ybWFsID0gaW52VmVydGV4VHJhbnNmb3JtLmRlbHRhVHJhbnNmb3JtVmVjdG9yKHRlbXBOb3JtYWwpO1xuXHRcdFx0XHRcdFx0XHRcdHRlbXBUYW5nZW50cyA9IGludlZlcnRleFRyYW5zZm9ybS5kZWx0YVRyYW5zZm9ybVZlY3Rvcih0ZW1wTm9ybWFsKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZiAoVVZUcmFuc2Zvcm0pXG5cdFx0XHRcdFx0XHRcdFx0dGVtcFVWID0gVVZUcmFuc2Zvcm0udHJhbnNmb3JtUG9pbnQodGVtcFVWKTtcblx0XHRcdFx0XHRcdFx0Ly90aGlzIGlzIGZhc3RlciB0aGFuIHRoYXQgb25seSBwdXNoIG9uZSBkYXRhXG5cdFx0XHRcdFx0XHRcdHNvdXJjZVBvc2l0aW9ucy5wdXNoKHRlbXBWZXJ0ZXgueCwgdGVtcFZlcnRleC55LCB0ZW1wVmVydGV4LnopO1xuXHRcdFx0XHRcdFx0XHRzb3VyY2VOb3JtYWxzLnB1c2godGVtcE5vcm1hbC54LCB0ZW1wTm9ybWFsLnksIHRlbXBOb3JtYWwueik7XG5cdFx0XHRcdFx0XHRcdHNvdXJjZVRhbmdlbnRzLnB1c2godGVtcFRhbmdlbnRzLngsIHRlbXBUYW5nZW50cy55LCB0ZW1wVGFuZ2VudHMueik7XG5cdFx0XHRcdFx0XHRcdHNvdXJjZVVWcy5wdXNoKHRlbXBVVi54LCB0ZW1wVVYueSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGZvciAoayA9IDA7IGsgPCB0ZW1wTGVuOyBrKyspIHtcblx0XHRcdFx0XHRcdFx0cHJvZHVjdCA9IGsqMztcblx0XHRcdFx0XHRcdFx0Ly90aGlzIGlzIGZhc3RlciB0aGFuIHRoYXQgb25seSBwdXNoIG9uZSBkYXRhXG5cdFx0XHRcdFx0XHRcdHBvc2l0aW9ucy5wdXNoKHNvdXJjZVBvc2l0aW9uc1twcm9kdWN0XSwgc291cmNlUG9zaXRpb25zW3Byb2R1Y3QgKyAxXSwgc291cmNlUG9zaXRpb25zW3Byb2R1Y3QgKyAyXSk7XG5cdFx0XHRcdFx0XHRcdG5vcm1hbHMucHVzaChzb3VyY2VOb3JtYWxzW3Byb2R1Y3RdLCBzb3VyY2VOb3JtYWxzW3Byb2R1Y3QgKyAxXSwgc291cmNlTm9ybWFsc1twcm9kdWN0ICsgMl0pO1xuXHRcdFx0XHRcdFx0XHR0YW5nZW50cy5wdXNoKHNvdXJjZVRhbmdlbnRzW3Byb2R1Y3RdLCBzb3VyY2VUYW5nZW50c1twcm9kdWN0ICsgMV0sIHNvdXJjZVRhbmdlbnRzW3Byb2R1Y3QgKyAyXSk7XG5cdFx0XHRcdFx0XHRcdHV2cy5wdXNoKHNvdXJjZVVWc1trKjJdLCBzb3VyY2VVVnNbayoyICsgMV0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvL1RvZG9cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBzb3VyY2VJbmRpY2VzOkFycmF5PG51bWJlcj4gLyp1aW50Ki8gPSBzb3VyY2VTdWJHZW9tZXRyeS5pbmRpY2VzO1xuXHRcdFx0XHR0ZW1wTGVuID0gc291cmNlU3ViR2VvbWV0cnkubnVtVHJpYW5nbGVzO1xuXHRcdFx0XHRmb3IgKGsgPSAwOyBrIDwgdGVtcExlbjsgaysrKSB7XG5cdFx0XHRcdFx0cHJvZHVjdCA9IGsqMztcblx0XHRcdFx0XHRpbmRpY2VzLnB1c2goc291cmNlSW5kaWNlc1twcm9kdWN0XSArIHZlcnRleENvdW50ZXIsIHNvdXJjZUluZGljZXNbcHJvZHVjdCArIDFdICsgdmVydGV4Q291bnRlciwgc291cmNlSW5kaWNlc1twcm9kdWN0ICsgMl0gKyB2ZXJ0ZXhDb3VudGVyKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBwYXJ0aWNsZUdlb21ldHJ5OlBhcnRpY2xlR2VvbWV0cnkgPSBuZXcgUGFydGljbGVHZW9tZXRyeSgpO1xuXHRcdHBhcnRpY2xlR2VvbWV0cnkucGFydGljbGVzID0gcGFydGljbGVzO1xuXHRcdHBhcnRpY2xlR2VvbWV0cnkubnVtUGFydGljbGVzID0gbnVtUGFydGljbGVzO1xuXG5cdFx0bnVtUGFydGljbGVzID0gc3ViR2VvbWV0cmllcy5sZW5ndGg7XG5cdFx0Zm9yIChpID0gMDsgaSA8IG51bVBhcnRpY2xlczsgaSsrKSB7XG5cdFx0XHRzdWJHZW9tZXRyeSA9IHN1Ykdlb21ldHJpZXNbaV07XG5cdFx0XHRzdWJHZW9tZXRyeS5hdXRvRGVyaXZlTm9ybWFscyA9IGZhbHNlO1xuXHRcdFx0c3ViR2VvbWV0cnkuYXV0b0Rlcml2ZVRhbmdlbnRzID0gZmFsc2U7XG5cdFx0XHRzdWJHZW9tZXRyeS51cGRhdGVJbmRpY2VzKGluZGljZXNWZWN0b3JbaV0pO1xuXHRcdFx0c3ViR2VvbWV0cnkudXBkYXRlUG9zaXRpb25zKHBvc2l0aW9uc1ZlY3RvcltpXSk7XG5cdFx0XHRzdWJHZW9tZXRyeS51cGRhdGVWZXJ0ZXhOb3JtYWxzKG5vcm1hbHNWZWN0b3JbaV0pO1xuXHRcdFx0c3ViR2VvbWV0cnkudXBkYXRlVmVydGV4VGFuZ2VudHModGFuZ2VudHNWZWN0b3JbaV0pO1xuXHRcdFx0c3ViR2VvbWV0cnkudXBkYXRlVVZzKHV2c1ZlY3RvcltpXSk7XG5cdFx0XHRwYXJ0aWNsZUdlb21ldHJ5LmFkZFN1Ykdlb21ldHJ5KHN1Ykdlb21ldHJ5KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcGFydGljbGVHZW9tZXRyeTtcblx0fVxufVxuXG5leHBvcnQgPSBQYXJ0aWNsZUdlb21ldHJ5SGVscGVyOyJdfQ== \ No newline at end of file diff --git a/lib/tools/helpers/ParticleGeometryHelper.ts b/lib/tools/helpers/ParticleGeometryHelper.ts new file mode 100644 index 000000000..4ad4057c1 --- /dev/null +++ b/lib/tools/helpers/ParticleGeometryHelper.ts @@ -0,0 +1,203 @@ +import Geometry = require("awayjs-core/lib/core/base/Geometry"); +import TriangleSubGeometry = require("awayjs-core/lib/core/base/TriangleSubGeometry"); +import Matrix = require("awayjs-core/lib/core/geom/Matrix"); +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); +import Point = require("awayjs-core/lib/core/geom/Point"); +import Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); + +import Mesh = require("awayjs-core/lib/entities/Mesh"); +import MaterialBase = require("awayjs-core/lib/materials/MaterialBase"); + +import ParticleData = require("awayjs-renderergl/lib/animators/data/ParticleData"); +import ParticleGeometry = require("awayjs-renderergl/lib/core/base/ParticleGeometry"); +import ParticleGeometryTransform = require("awayjs-renderergl/lib/tools/data/ParticleGeometryTransform"); + +/** + * ... + */ +class ParticleGeometryHelper +{ + public static MAX_VERTEX:number /*int*/ = 65535; + + public static generateGeometry(geometries:Array, transforms:Array = null):ParticleGeometry + { + var indicesVector:Array> /*uint*/ = new Array>() /*uint*/; + var positionsVector:Array> = new Array>(); + var normalsVector:Array> = new Array>(); + var tangentsVector:Array> = new Array>(); + var uvsVector:Array> = new Array>(); + var vertexCounters:Array /*uint*/ = new Array() /*uint*/; + var particles:Array = new Array(); + var subGeometries:Array = new Array(); + var numParticles:number /*uint*/ = geometries.length; + + var sourceSubGeometries:Array; + var sourceSubGeometry:TriangleSubGeometry; + var numSubGeometries:number /*uint*/; + var indices:Array /*uint*/; + var positions:Array; + var normals:Array; + var tangents:Array; + var uvs:Array; + var vertexCounter:number /*uint*/; + var subGeometry:TriangleSubGeometry; + var i:number /*int*/; + var j:number /*int*/; + var sub2SubMap:Array /*int*/ = new Array() /*int*/; + + var tempVertex:Vector3D = new Vector3D; + var tempNormal:Vector3D = new Vector3D; + var tempTangents:Vector3D = new Vector3D; + var tempUV:Point = new Point; + + for (i = 0; i < numParticles; i++) { + sourceSubGeometries = > geometries[i].subGeometries; + numSubGeometries = sourceSubGeometries.length; + for (var srcIndex:number /*int*/ = 0; srcIndex < numSubGeometries; srcIndex++) { + //create a different particle subgeometry group for each source subgeometry in a particle. + if (sub2SubMap.length <= srcIndex) { + sub2SubMap.push(subGeometries.length); + indicesVector.push(new Array() /*uint*/); + positionsVector.push(new Array()); + normalsVector.push(new Array()); + tangentsVector.push(new Array()); + uvsVector.push(new Array()); + subGeometries.push(new TriangleSubGeometry(true)); + vertexCounters.push(0); + } + + sourceSubGeometry = sourceSubGeometries[srcIndex]; + + //add a new particle subgeometry if this source subgeometry will take us over the maxvertex limit + if (sourceSubGeometry.numVertices + vertexCounters[sub2SubMap[srcIndex]] > ParticleGeometryHelper.MAX_VERTEX) { + //update submap and add new subgeom vectors + sub2SubMap[srcIndex] = subGeometries.length; + indicesVector.push(new Array() /*uint*/); + positionsVector.push(new Array()); + normalsVector.push(new Array()); + tangentsVector.push(new Array()); + uvsVector.push(new Array()); + subGeometries.push(new TriangleSubGeometry(true)); + vertexCounters.push(0); + } + + j = sub2SubMap[srcIndex]; + + //select the correct vector + indices = indicesVector[j]; + positions = positionsVector[j]; + normals = normalsVector[j]; + tangents = tangentsVector[j]; + uvs = uvsVector[j]; + vertexCounter = vertexCounters[j]; + subGeometry = subGeometries[j]; + + var particleData:ParticleData = new ParticleData(); + particleData.numVertices = sourceSubGeometry.numVertices; + particleData.startVertexIndex = vertexCounter; + particleData.particleIndex = i; + particleData.subGeometry = subGeometry; + particles.push(particleData); + + vertexCounters[j] += sourceSubGeometry.numVertices; + + var k:number /*int*/; + var tempLen:number /*int*/; + var compact:TriangleSubGeometry = sourceSubGeometry; + var product:number /*uint*/; + var sourcePositions:Array; + var sourceNormals:Array; + var sourceTangents:Array; + var sourceUVs:Array; + + if (compact) { + tempLen = compact.numVertices; + compact.numTriangles; + sourcePositions = compact.positions; + sourceNormals = compact.vertexNormals; + sourceTangents = compact.vertexTangents; + sourceUVs = compact.uvs; + + if (transforms) { + var particleGeometryTransform:ParticleGeometryTransform = transforms[i]; + var vertexTransform:Matrix3D = particleGeometryTransform.vertexTransform; + var invVertexTransform:Matrix3D = particleGeometryTransform.invVertexTransform; + var UVTransform:Matrix = particleGeometryTransform.UVTransform; + + for (k = 0; k < tempLen; k++) { + /* + * 0 - 2: vertex position X, Y, Z + * 3 - 5: normal X, Y, Z + * 6 - 8: tangent X, Y, Z + * 9 - 10: U V + * 11 - 12: Secondary U V*/ + product = k*3; + tempVertex.x = sourcePositions[product]; + tempVertex.y = sourcePositions[product + 1]; + tempVertex.z = sourcePositions[product + 2]; + tempNormal.x = sourceNormals[product]; + tempNormal.y = sourceNormals[product + 1]; + tempNormal.z = sourceNormals[product + 2]; + tempTangents.x = sourceTangents[product]; + tempTangents.y = sourceTangents[product + 1]; + tempTangents.z = sourceTangents[product + 2]; + tempUV.x = sourceUVs[k*2]; + tempUV.y = sourceUVs[k*2 + 1]; + if (vertexTransform) { + tempVertex = vertexTransform.transformVector(tempVertex); + tempNormal = invVertexTransform.deltaTransformVector(tempNormal); + tempTangents = invVertexTransform.deltaTransformVector(tempNormal); + } + if (UVTransform) + tempUV = UVTransform.transformPoint(tempUV); + //this is faster than that only push one data + sourcePositions.push(tempVertex.x, tempVertex.y, tempVertex.z); + sourceNormals.push(tempNormal.x, tempNormal.y, tempNormal.z); + sourceTangents.push(tempTangents.x, tempTangents.y, tempTangents.z); + sourceUVs.push(tempUV.x, tempUV.y); + } + } else { + for (k = 0; k < tempLen; k++) { + product = k*3; + //this is faster than that only push one data + positions.push(sourcePositions[product], sourcePositions[product + 1], sourcePositions[product + 2]); + normals.push(sourceNormals[product], sourceNormals[product + 1], sourceNormals[product + 2]); + tangents.push(sourceTangents[product], sourceTangents[product + 1], sourceTangents[product + 2]); + uvs.push(sourceUVs[k*2], sourceUVs[k*2 + 1]); + } + } + } else { + //Todo + } + + var sourceIndices:Array /*uint*/ = sourceSubGeometry.indices; + tempLen = sourceSubGeometry.numTriangles; + for (k = 0; k < tempLen; k++) { + product = k*3; + indices.push(sourceIndices[product] + vertexCounter, sourceIndices[product + 1] + vertexCounter, sourceIndices[product + 2] + vertexCounter); + } + } + } + + var particleGeometry:ParticleGeometry = new ParticleGeometry(); + particleGeometry.particles = particles; + particleGeometry.numParticles = numParticles; + + numParticles = subGeometries.length; + for (i = 0; i < numParticles; i++) { + subGeometry = subGeometries[i]; + subGeometry.autoDeriveNormals = false; + subGeometry.autoDeriveTangents = false; + subGeometry.updateIndices(indicesVector[i]); + subGeometry.updatePositions(positionsVector[i]); + subGeometry.updateVertexNormals(normalsVector[i]); + subGeometry.updateVertexTangents(tangentsVector[i]); + subGeometry.updateUVs(uvsVector[i]); + particleGeometry.addSubGeometry(subGeometry); + } + + return particleGeometry; + } +} + +export = ParticleGeometryHelper; \ No newline at end of file diff --git a/lib/utils/PerspectiveMatrix3D.js b/lib/utils/PerspectiveMatrix3D.js new file mode 100755 index 000000000..e39b0516d --- /dev/null +++ b/lib/utils/PerspectiveMatrix3D.js @@ -0,0 +1,26 @@ +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 PerspectiveMatrix3D = (function (_super) { + __extends(PerspectiveMatrix3D, _super); + function PerspectiveMatrix3D(v) { + if (v === void 0) { v = null; } + _super.call(this, v); + } + PerspectiveMatrix3D.prototype.perspectiveFieldOfViewLH = function (fieldOfViewY, aspectRatio, zNear, zFar) { + var yScale = 1 / Math.tan(fieldOfViewY / 2); + var xScale = yScale / aspectRatio; + this.copyRawDataFrom([xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, zFar / (zFar - zNear), 1.0, 0.0, 0.0, (zNear * zFar) / (zNear - zFar), 0.0]); + }; + return PerspectiveMatrix3D; +})(Matrix3D); +module.exports = PerspectiveMatrix3D; + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInV0aWxzL3BlcnNwZWN0aXZlbWF0cml4M2QudHMiXSwibmFtZXMiOlsiUGVyc3BlY3RpdmVNYXRyaXgzRCIsIlBlcnNwZWN0aXZlTWF0cml4M0QuY29uc3RydWN0b3IiLCJQZXJzcGVjdGl2ZU1hdHJpeDNELnBlcnNwZWN0aXZlRmllbGRPZlZpZXdMSCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBTyxRQUFRLFdBQWlCLG9DQUFvQyxDQUFDLENBQUM7QUFFdEUsQUFHQTs7R0FERztJQUNHLG1CQUFtQjtJQUFTQSxVQUE1QkEsbUJBQW1CQSxVQUFpQkE7SUFFekNBLFNBRktBLG1CQUFtQkEsQ0FFWkEsQ0FBc0JBO1FBQXRCQyxpQkFBc0JBLEdBQXRCQSxRQUFzQkE7UUFFakNBLGtCQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUNWQSxDQUFDQTtJQUVNRCxzREFBd0JBLEdBQS9CQSxVQUFnQ0EsWUFBbUJBLEVBQUVBLFdBQWtCQSxFQUFFQSxLQUFZQSxFQUFFQSxJQUFXQTtRQUVqR0UsSUFBSUEsTUFBTUEsR0FBVUEsQ0FBQ0EsR0FBQ0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsWUFBWUEsR0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDL0NBLElBQUlBLE1BQU1BLEdBQVVBLE1BQU1BLEdBQUNBLFdBQVdBLENBQUNBO1FBRXZDQSxJQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxDQUFDQSxNQUFNQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxNQUFNQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxJQUFJQSxHQUFDQSxDQUFDQSxJQUFJQSxHQUFHQSxLQUFLQSxDQUFDQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxLQUFLQSxHQUFDQSxJQUFJQSxDQUFDQSxHQUFDQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQSxFQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUN0SkEsQ0FBQ0E7SUFDRkYsMEJBQUNBO0FBQURBLENBZEEsQUFjQ0EsRUFkaUMsUUFBUSxFQWN6QztBQUVELEFBQTZCLGlCQUFwQixtQkFBbUIsQ0FBQyIsImZpbGUiOiJ1dGlscy9QZXJzcGVjdGl2ZU1hdHJpeDNELmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE1hdHJpeDNEXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL01hdHJpeDNEXCIpO1xuXG4vKipcbiAqXG4gKi9cbmNsYXNzIFBlcnNwZWN0aXZlTWF0cml4M0QgZXh0ZW5kcyBNYXRyaXgzRFxue1xuXHRjb25zdHJ1Y3Rvcih2OkFycmF5PG51bWJlcj4gPSBudWxsKVxuXHR7XG5cdFx0c3VwZXIodik7XG5cdH1cblxuXHRwdWJsaWMgcGVyc3BlY3RpdmVGaWVsZE9mVmlld0xIKGZpZWxkT2ZWaWV3WTpudW1iZXIsIGFzcGVjdFJhdGlvOm51bWJlciwgek5lYXI6bnVtYmVyLCB6RmFyOm51bWJlcilcblx0e1xuXHRcdHZhciB5U2NhbGU6bnVtYmVyID0gMS9NYXRoLnRhbihmaWVsZE9mVmlld1kvMik7XG5cdFx0dmFyIHhTY2FsZTpudW1iZXIgPSB5U2NhbGUvYXNwZWN0UmF0aW87XG5cblx0XHR0aGlzLmNvcHlSYXdEYXRhRnJvbShbeFNjYWxlLCAwLjAsIDAuMCwgMC4wLCAwLjAsIHlTY2FsZSwgMC4wLCAwLjAsIDAuMCwgMC4wLCB6RmFyLyh6RmFyIC0gek5lYXIpLCAxLjAsIDAuMCwgMC4wLCAoek5lYXIqekZhcikvKHpOZWFyIC0gekZhciksIDAuMF0pO1xuXHR9XG59XG5cbmV4cG9ydCA9IFBlcnNwZWN0aXZlTWF0cml4M0Q7Il19 \ No newline at end of file diff --git a/lib/utils/PerspectiveMatrix3D.ts b/lib/utils/PerspectiveMatrix3D.ts new file mode 100644 index 000000000..3a0b622b6 --- /dev/null +++ b/lib/utils/PerspectiveMatrix3D.ts @@ -0,0 +1,22 @@ +import Matrix3D = require("awayjs-core/lib/core/geom/Matrix3D"); + +/** + * + */ +class PerspectiveMatrix3D extends Matrix3D +{ + constructor(v:Array = null) + { + super(v); + } + + public perspectiveFieldOfViewLH(fieldOfViewY:number, aspectRatio:number, zNear:number, zFar:number) + { + var yScale:number = 1/Math.tan(fieldOfViewY/2); + var xScale:number = yScale/aspectRatio; + + this.copyRawDataFrom([xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, zFar/(zFar - zNear), 1.0, 0.0, 0.0, (zNear*zFar)/(zNear - zFar), 0.0]); + } +} + +export = PerspectiveMatrix3D; \ No newline at end of file diff --git a/tests/AppHarness.js b/tests/AppHarness.js new file mode 100755 index 000000000..f8ca7b36c --- /dev/null +++ b/tests/AppHarness.js @@ -0,0 +1,343 @@ +var away; +(function (away) { + //--------------------------------------------------- + // Application Harness + var AppHarness = (function () { + //------------------------------------------------------------------------------ + function AppHarness() { + var _this = this; + //------------------------------------------------------------------------------ + this.tests = new Array(); + this.counter = 0; + this.sourceVisible = false; + this.loadDefault = true; + this.initFrameSet(); + this.initInterface(); + this.previousBtn.onclick = function () { return _this.nagigateBy(-1); }; + this.nextBtn.onclick = function () { return _this.nagigateBy(1); }; + this.sourceBtn.onclick = function () { return _this.toggleSource(); }; + this.dropDown.onchange = function (e) { return _this.dropDownChange(e); }; + } + //------------------------------------------------------------------------------ + /** + * + * Load a test + * + * @param classPath - Module and Class path of test + * @param js Path to JavaScript file + * @param ts Path to Typescript file ( not yet used - reserved for future show source ) + */ + AppHarness.prototype.load = function (classPath, js, ts) { + this.loadFromURL(); + if (this.loadDefault) { + window.history.pushState(js, js, '?test=' + js); + this.testIframe.src = 'frame.html?name=' + classPath + '&js=' + js; + this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML(ts); + } + }; + /** + * + * Add a test to the AppHarness + * + * @param name Name of test + * @param classPath - Module and Class path of test + * @param js Path to JavaScript file + * @param ts Path to Typescript file ( not yet used - reserved for future show source ) + */ + AppHarness.prototype.addTest = function (name, classpath, js, ts) { + this.tests.push(new TestData(name, classpath, js, ts)); + }; + /** + * + * Add a separator to the menu + * + * @param name + */ + AppHarness.prototype.addSeperator = function (name) { + if (name === void 0) { name = ''; } + this.tests.push(new TestData('-- ' + name, '', '', '')); + }; + /** + * + * Start the application harness + * + */ + AppHarness.prototype.start = function (slideshowMode) { + var _this = this; + if (slideshowMode === void 0) { slideshowMode = false; } + for (var c = 0; c < this.tests.length; c++) { + var option = new Option(this.tests[c].name, String(c)); + this.dropDown.add(option); + } + if (slideshowMode) { + setInterval(function () { return _this.nagigateBy(1); }, 15000); + } + }; + //------------------------------------------------------------------------------ + AppHarness.prototype.loadFromURL = function () { + var queryParams = Utils.getQueryParams(document.location.search); + if (queryParams.test != null) { + var l = this.tests.length; + for (var c = 0; c < l; c++) { + if (this.tests[c].js == queryParams.test) { + console.log('======>>>> LOAD TEST'); + this.navigateToSection(this.tests[c]); + this.loadDefault = false; + } + } + } + }; + /** + * + */ + AppHarness.prototype.initInterface = function () { + var testSelector = document.createElement('div'); + testSelector.style.cssFloat = 'none'; + testSelector.style.position = 'absolute'; + testSelector.style.bottom = '15px'; + testSelector.style.width = '600px'; + testSelector.style.left = '50%'; + testSelector.style.marginLeft = '-300px'; + testSelector.style.textAlign = 'center'; + this.dropDown = document.createElement('select'); + this.dropDown.name = "selectTestDropDown"; + this.dropDown.id = "selectTest"; + this.sourceBtn = document.createElement('button'); + this.sourceBtn.innerHTML = 'Show Source'; + this.sourceBtn.id = 'previous'; + this.previousBtn = document.createElement('button'); + this.previousBtn.innerHTML = '<<'; + this.previousBtn.id = 'previous'; + this.nextBtn = document.createElement('button'); + this.nextBtn.innerHTML = '>>'; + this.nextBtn.id = 'next'; + testSelector.appendChild(this.sourceBtn); + testSelector.appendChild(this.previousBtn); + testSelector.appendChild(this.dropDown); + testSelector.appendChild(this.nextBtn); + document.body.appendChild(testSelector); + }; + /** + * + */ + AppHarness.prototype.initFrameSet = function () { + var iframeContainer = document.createElement('div'); + iframeContainer.style.width = '100%'; + iframeContainer.style.height = '100%'; + this.testIframe = document.createElement('iframe'); + this.testIframe.id = 'testContainer'; + this.testIframe.style.backgroundColor = '#9e9e9e'; + this.testIframe.style.cssFloat = 'none'; + this.testIframe.style.position = 'absolute'; + this.testIframe.style.top = '0px'; + this.testIframe.style.left = '0px'; + this.testIframe.style.border = '0px'; + this.testIframe.style.width = '100%'; + this.testIframe.style.height = '100%'; + //bottom: 120px; + this.srcIframe = document.createElement('iframe'); + this.srcIframe.id = 'testSourceContainer'; + this.srcIframe.style.backgroundColor = '#9e9e9e'; + this.srcIframe.style.cssFloat = 'none'; + this.srcIframe.style.position = 'absolute'; + this.srcIframe.style.right = '0px'; + this.srcIframe.style.top = '0px'; + this.srcIframe.style.bottom = '0px'; + this.srcIframe.style.border = '0px'; + this.srcIframe.style.width = '0%'; + this.srcIframe.style.height = '100%'; + iframeContainer.appendChild(this.testIframe); + iframeContainer.appendChild(this.srcIframe); + document.body.appendChild(iframeContainer); + }; + /** + * + * Selectnext / previous menu item + * + * @param direction + */ + AppHarness.prototype.nagigateBy = function (direction) { + if (direction === void 0) { direction = 1; } + var l = this.tests.length; + var nextCounter = this.counter + direction; + if (nextCounter < 0) { + nextCounter = this.tests.length - 1; + } + else if (nextCounter > this.tests.length - 1) { + nextCounter = 0; + } + var testData = this.tests[nextCounter]; + if (testData.name.indexOf('--') != -1) { + this.counter = nextCounter; + this.nagigateBy(direction); + } + else { + this.navigateToSection(testData); + this.dropDown.selectedIndex = nextCounter; + this.counter = nextCounter; + } + }; + /** + * + * Navigate to a section + * + * @param testData + */ + AppHarness.prototype.navigateToSection = function (testData) { + window.history.pushState(testData.js, testData.js, '?test=' + testData.js); + this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML(testData.src); + this.testIframe.src = 'frame.html?name=' + testData.classpath + '&js=' + testData.js; + }; + AppHarness.prototype.toggleSource = function () { + if (this.sourceVisible) { + this.testIframe.style.width = '100%'; + this.srcIframe.style.width = '0%'; + this.sourceBtn.innerHTML = 'Show Source'; + } + else { + this.testIframe.style.width = '20%'; + this.srcIframe.style.width = '80%'; + this.sourceBtn.innerHTML = 'Hide Source'; + } + this.sourceVisible = !this.sourceVisible; + }; + AppHarness.prototype.createSourceViewHTML = function (url) { + var html = ''; + html += ''; + html += ''; + html += ' '; + html += ' '; + html += ' '; + html += ' '; + html += ''; + html += ''; + html += ''; + html += ''; + return html; + }; + //------------------------------------------------------------------------------ + // Utils + /** + * + * Util function - get Element by ID + * + * @param id + * @returns {HTMLElement} + */ + AppHarness.prototype.getId = function (id) { + return document.getElementById(id); + }; + //------------------------------------------------------------------------------ + // Events + /** + * + * Dropbox event handler + * + * @param e + */ + AppHarness.prototype.dropDownChange = function (e) { + this.dropDown.options[this.dropDown.selectedIndex].value; + this.counter = this.dropDown.selectedIndex; + var dataIndex = parseInt(this.dropDown.options[this.dropDown.selectedIndex].value); + if (!isNaN(dataIndex)) { + this.navigateToSection(this.tests[dataIndex]); + } + }; + return AppHarness; + })(); + away.AppHarness = AppHarness; + //--------------------------------------------------- + // Application Frame + var AppFrame = (function () { + function AppFrame() { + this.classPath = ''; + this.jsPath = ''; + var queryParams = Utils.getQueryParams(document.location.search); + if (queryParams.js != undefined && queryParams.name != undefined) { + this.jsPath = queryParams.js; + this.classPath = queryParams.name; + this.loadJS(this.jsPath); + } + } + /** + * + * Load a JavaScript file + * + * @param url - URL of JavaScript file + */ + AppFrame.prototype.loadJS = function (url) { + var _this = this; + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = url; + script.onload = function () { return _this.jsLoaded(); }; + head.appendChild(script); + }; + /** + * + * Event Handler for loaded JavaScript files + * + */ + AppFrame.prototype.jsLoaded = function () { + var createPath = this.classPath.split('.'); // Split the classpath + var obj; + for (var c = 0; c < createPath.length; c++) { + if (obj == null) { + obj = window[createPath[c]]; // reference base module ( will be a child of the window ) + } + else { + obj = obj[createPath[c]]; // reference sub module / Class + } + } + if (obj != null) { + new obj(); // if Class has been found - start the test + } + }; + return AppFrame; + })(); + away.AppFrame = AppFrame; + //--------------------------------------------------- + // Common Utilities + var Utils = (function () { + function Utils() { + } + /** + * + * Utility function - Parse a Query formatted string + * + * @param qs + * @returns {{}} + */ + Utils.getQueryParams = function (qs) { + qs = qs.split("+").join(" "); + var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g; + while (tokens = re.exec(qs)) { + params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]); + } + return params; + }; + return Utils; + })(); + away.Utils = Utils; + //--------------------------------------------------- + // Data + var TestData = (function () { + function TestData(name, classpath, js, src) { + this.js = js; + this.classpath = classpath; + this.src = src; + this.name = name; + } + return TestData; + })(); +})(away || (away = {})); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcGhhcm5lc3MudHMiXSwibmFtZXMiOlsiYXdheSIsImF3YXkuQXBwSGFybmVzcyIsImF3YXkuQXBwSGFybmVzcy5jb25zdHJ1Y3RvciIsImF3YXkuQXBwSGFybmVzcy5sb2FkIiwiYXdheS5BcHBIYXJuZXNzLmFkZFRlc3QiLCJhd2F5LkFwcEhhcm5lc3MuYWRkU2VwZXJhdG9yIiwiYXdheS5BcHBIYXJuZXNzLnN0YXJ0IiwiYXdheS5BcHBIYXJuZXNzLmxvYWRGcm9tVVJMIiwiYXdheS5BcHBIYXJuZXNzLmluaXRJbnRlcmZhY2UiLCJhd2F5LkFwcEhhcm5lc3MuaW5pdEZyYW1lU2V0IiwiYXdheS5BcHBIYXJuZXNzLm5hZ2lnYXRlQnkiLCJhd2F5LkFwcEhhcm5lc3MubmF2aWdhdGVUb1NlY3Rpb24iLCJhd2F5LkFwcEhhcm5lc3MudG9nZ2xlU291cmNlIiwiYXdheS5BcHBIYXJuZXNzLmNyZWF0ZVNvdXJjZVZpZXdIVE1MIiwiYXdheS5BcHBIYXJuZXNzLmdldElkIiwiYXdheS5BcHBIYXJuZXNzLmRyb3BEb3duQ2hhbmdlIiwiYXdheS5BcHBGcmFtZSIsImF3YXkuQXBwRnJhbWUuY29uc3RydWN0b3IiLCJhd2F5LkFwcEZyYW1lLmxvYWRKUyIsImF3YXkuQXBwRnJhbWUuanNMb2FkZWQiLCJhd2F5LlV0aWxzIiwiYXdheS5VdGlscy5jb25zdHJ1Y3RvciIsImF3YXkuVXRpbHMuZ2V0UXVlcnlQYXJhbXMiLCJhd2F5LlRlc3REYXRhIiwiYXdheS5UZXN0RGF0YS5jb25zdHJ1Y3RvciJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTyxJQUFJLENBb2RWO0FBcGRELFdBQU8sSUFBSSxFQUNYLENBQUM7SUFFR0EsQUFHQUEscURBSHFEQTtJQUNyREEsc0JBQXNCQTtRQUVUQSxVQUFVQTtRQWdCbkJDLGdGQUFnRkE7UUFFaEZBLFNBbEJTQSxVQUFVQTtZQUF2QkMsaUJBK1VDQTtZQTVVR0EsZ0ZBQWdGQTtZQUV4RUEsVUFBS0EsR0FBK0JBLElBQUlBLEtBQUtB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R0FBcEJBO1lBR0lRLElBQUlBLGVBQWVBLEdBQXdDQSxRQUFRQSxDQUFDQSxhQUFhQSxDQUFFQSxLQUFLQSxDQUFFQSxDQUFDQTtZQUN2RkEsZUFBZUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsR0FBV0EsTUFBTUEsQ0FBQ0E7WUFDN0NBLGVBQWVBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLEdBQVVBLE1BQU1BLENBQUNBO1lBRWpEQSxJQUFJQSxDQUFDQSxVQUFVQSxHQUE0Q0EsUUFBUUEsQ0FBQ0EsYUFBYUEsQ0FBRUEsUUFBUUEsQ0FBRUEsQ0FBQ0E7WUFDOUZBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLEVBQUVBLEdBQXFCQSxlQUFlQSxDQUFDQTtZQUN2REEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsZUFBZUEsR0FBR0EsU0FBU0EsQ0FBQ0E7WUFDbERBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLEdBQVNBLE1BQU1BLENBQUNBO1lBQzlDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxHQUFTQSxVQUFVQSxDQUFDQTtZQUNsREEsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsR0FBR0EsR0FBY0EsS0FBS0EsQ0FBQ0E7WUFDN0NBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLEtBQUtBLENBQUNBLElBQUlBLEdBQWFBLEtBQUtBLENBQUNBO1lBQzdDQSxJQUFJQSxDQUFDQSxVQUFVQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxHQUFXQSxLQUFLQSxDQUFDQTtZQUM3Q0EsSUFBSUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsR0FBWUEsTUFBTUEsQ0FBQ0E7WUFDOUNBLElBQUlBLENBQUNBLFVBQVVBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLEdBQVdBLE1BQU1BLENBQUNBO1lBQzlDQSxBQUVBQSxnQkFGZ0JBO1lBRWhCQSxJQUFJQSxDQUFDQSxTQUFTQSxHQUFn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LENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBRTdCQSxJQUFJQSxNQUFNQSxHQUFHQSxFQUFFQSxFQUFFQSxNQUFNQSxFQUN0QkEsRUFBRUEsR0FBR0EsdUJBQXVCQSxDQUFDQTtZQUU5QkEsT0FBT0EsTUFBTUEsR0FBR0EsRUFBRUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7Z0JBQzdCQSxNQUFNQSxDQUFDQSxrQkFBa0JBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLEdBQUdBLGtCQUFrQkEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDdkVBLENBQUNBO1lBRURBLE1BQU1BLENBQUNBLE1BQU1BLENBQUNBO1FBQ2ZBLENBQUNBO1FBQ0ZGLFlBQUNBO0lBQURBLENBdEJBcEIsQUFzQkNvQixJQUFBcEI7SUF0QllBLFVBQUtBLEdBQUxBLEtBc0JaQSxDQUFBQTtJQUVFQSxBQUdBQSxxREFIcURBO0lBQ3JEQSxPQUFPQTtRQUVEQSxRQUFRQTtRQU9WdUIsU0FQRUEsUUFBUUEsQ0FPR0EsSUFBYUEsRUFBR0EsU0FBa0JBLEVBQUdBLEVBQVdBLEVBQUdBLEdBQVlBO1lBRXhFQyxJQUFJQSxDQUFDQSxFQUFFQSxHQUFXQSxFQUFFQSxDQUFDQTtZQUNyQkEsSUFBSUEsQ0FBQ0EsU0FBU0EsR0FBSUEsU0FBU0EsQ0FBQ0E7WUFDNUJBLElBQUlBLENBQUNBLEdBQUdBLEdBQVVBLEdBQUdBLENBQUNBO1lBQ3RCQSxJQUFJQSxDQUFDQSxJQUFJQSxHQUFTQSxJQUFJQSxDQUFDQTtRQUMzQkEsQ0FBQ0E7UUFDTEQsZUFBQ0E7SUFBREEsQ0FkQXZCLEFBY0N1QixJQUFBdkI7QUFDTEEsQ0FBQ0EsRUFwZE0sSUFBSSxLQUFKLElBQUksUUFvZFYiLCJmaWxlIjoiQXBwSGFybmVzcy5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZSBhd2F5XG57XG5cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFwcGxpY2F0aW9uIEhhcm5lc3NcblxuICAgIGV4cG9ydCBjbGFzcyBBcHBIYXJuZXNzXG4gICAge1xuXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgcHJpdmF0ZSB0ZXN0cyAgICAgICAgICAgOiBBcnJheTxUZXN0RGF0YT4gPSBuZXcgQXJyYXk8VGVzdERhdGE+KCk7XG4gICAgICAgIHByaXZhdGUgZHJvcERvd24gICAgICAgIDogSFRNTFNlbGVjdEVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgcHJldmlvdXNCdG4gICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgbmV4dEJ0biAgICAgICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgc291cmNlQnRuICAgICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgdGVzdElmcmFtZSAgICAgIDogSFRNTElGcmFtZUVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgc3JjSWZyYW1lICAgICAgIDogSFRNTElGcmFtZUVsZW1lbnQ7XG4gICAgICAgIHByaXZhdGUgY291bnRlciAgICAgICAgIDogbnVtYmVyID0gMDtcbiAgICAgICAgcHJpdmF0ZSBzb3VyY2VWaXNpYmxlICAgOiBib29sZWFuID0gZmFsc2U7XG5cdCAgICBwcml2YXRlIGxvYWREZWZhdWx0ICAgICA6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3RydWN0b3IoKVxuICAgICAgICB7XG5cbiAgICAgICAgICAgIHRoaXMuaW5pdEZyYW1lU2V0KCk7XG4gICAgICAgICAgICB0aGlzLmluaXRJbnRlcmZhY2UoKTtcblxuXG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzQnRuLm9uY2xpY2sgICA9ICgpID0+IHRoaXMubmFnaWdhdGVCeSggLTEgKTtcbiAgICAgICAgICAgIHRoaXMubmV4dEJ0bi5vbmNsaWNrICAgICAgID0gKCkgPT4gdGhpcy5uYWdpZ2F0ZUJ5KCAxICk7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ0bi5vbmNsaWNrICAgICA9ICgpID0+IHRoaXMudG9nZ2xlU291cmNlKCk7XG4gICAgICAgICAgICB0aGlzLmRyb3BEb3duLm9uY2hhbmdlICAgICAgPSAoIGUgKSA9PiB0aGlzLmRyb3BEb3duQ2hhbmdlKCBlICk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqIExvYWQgYSB0ZXN0XG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBjbGFzc1BhdGggLSBNb2R1bGUgYW5kIENsYXNzIHBhdGggb2YgdGVzdFxuICAgICAgICAgKiBAcGFyYW0ganMgUGF0aCB0byBKYXZhU2NyaXB0IGZpbGVcbiAgICAgICAgICogQHBhcmFtIHRzIFBhdGggdG8gVHlwZXNjcmlwdCBmaWxlICggbm90IHlldCB1c2VkIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSBzaG93IHNvdXJjZSApXG4gICAgICAgICAqL1xuICAgICAgICBwdWJsaWMgbG9hZCggY2xhc3NQYXRoIDogc3RyaW5nICwganMgOiBzdHJpbmcgLCB0cyA6IHN0cmluZyApIDogdm9pZFxuICAgICAgICB7XG5cblx0ICAgICAgICB0aGlzLmxvYWRGcm9tVVJMKCk7XG5cblx0ICAgICAgICBpZiAoIHRoaXMubG9hZERlZmF1bHQgKVxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKGpzLCBqcywgJz90ZXN0PScgKyBqcyk7XG5cdCAgICAgICAgICAgIHRoaXMudGVzdElmcmFtZS5zcmMgPSAnZnJhbWUuaHRtbD9uYW1lPScgKyBjbGFzc1BhdGggKyAnJmpzPScgKyBqcztcbiAgICAgICAgICAgICAgICB0aGlzLnNyY0lmcmFtZS5zcmMgPSBcImRhdGE6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgsXCIgKyB0aGlzLmNyZWF0ZVNvdXJjZVZpZXdIVE1MKCB0cyApO1xuXG5cdCAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqIEFkZCBhIHRlc3QgdG8gdGhlIEFwcEhhcm5lc3NcbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0ZXN0XG4gICAgICAgICAqIEBwYXJhbSBjbGFzc1BhdGggLSBNb2R1bGUgYW5kIENsYXNzIHBhdGggb2YgdGVzdFxuICAgICAgICAgKiBAcGFyYW0ganMgUGF0aCB0byBKYXZhU2NyaXB0IGZpbGVcbiAgICAgICAgICogQHBhcmFtIHRzIFBhdGggdG8gVHlwZXNjcmlwdCBmaWxlICggbm90IHlldCB1c2VkIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSBzaG93IHNvdXJjZSApXG4gICAgICAgICAqL1xuICAgICAgICBwdWJsaWMgYWRkVGVzdCggbmFtZSA6IHN0cmluZyAsIGNsYXNzcGF0aCA6IHN0cmluZyAsIGpzIDogc3RyaW5nICwgdHMgOiBzdHJpbmcgKSA6IHZvaWRcbiAgICAgICAge1xuICAgICAgICAgICAgdGhpcy50ZXN0cy5wdXNoICggbmV3IFRlc3REYXRhKCBuYW1lICwgY2xhc3NwYXRoICwganMgLCB0cyApICk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogQWRkIGEgc2VwYXJhdG9yIHRvIHRoZSBtZW51XG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBuYW1lXG4gICAgICAgICAqL1xuICAgICAgICBwdWJsaWMgYWRkU2VwZXJhdG9yKCBuYW1lIDogc3RyaW5nID0gJycgKSA6IHZvaWRcbiAgICAgICAge1xuICAgICAgICAgICAgdGhpcy50ZXN0cy5wdXNoICggbmV3IFRlc3REYXRhKCAnLS0gJyArIG5hbWUgLCAnJyAsICcnICwgJycpICk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogU3RhcnQgdGhlIGFwcGxpY2F0aW9uIGhhcm5lc3NcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIHB1YmxpYyBzdGFydCggc2xpZGVzaG93TW9kZSA6IGJvb2xlYW4gPSBmYWxzZSApIDogdm9pZFxuICAgICAgICB7XG4gICAgICAgICAgICBmb3IgKCB2YXIgYyA6IG51bWJlciA9IDAgOyBjIDwgdGhpcy50ZXN0cy5sZW5ndGggOyBjICsrICApXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdmFyIG9wdGlvbiA6IEhUTUxPcHRpb25FbGVtZW50ID0gPEhUTUxPcHRpb25FbGVtZW50PiBuZXcgT3B0aW9uKCB0aGlzLnRlc3RzW2NdLm5hbWUgLCBTdHJpbmcoIGMgKSApO1xuICAgICAgICAgICAgICAgIHRoaXMuZHJvcERvd24uYWRkKCBvcHRpb24gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCBzbGlkZXNob3dNb2RlIClcbiAgICAgICAgICAgIHtcblxuICAgICAgICAgICAgICAgIHNldEludGVydmFsKCAoKSA9PiB0aGlzLm5hZ2lnYXRlQnkoIDEgKSAsIDE1MDAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0ICAgIHByaXZhdGUgbG9hZEZyb21VUkwoKSA6IHZvaWRcblx0ICAgIHtcblx0XHQgICAgdmFyIHF1ZXJ5UGFyYW1zIDogYW55ID0gVXRpbHMuZ2V0UXVlcnlQYXJhbXMoIGRvY3VtZW50LmxvY2F0aW9uLnNlYXJjaCApO1xuXG5cdFx0ICAgIGlmICggcXVlcnlQYXJhbXMudGVzdCAhPSBudWxsIClcblx0XHQgICAge1xuXHRcdFx0ICAgIHZhciBsIDogbnVtYmVyID0gIHRoaXMudGVzdHMubGVuZ3RoO1xuXG5cdFx0XHQgICAgZm9yICggdmFyIGMgOiBudW1iZXIgPSAwIDsgYyA8IGwgOyBjICsrIClcblx0XHRcdCAgICB7XG5cdFx0XHRcdCAgICBpZiAoIHRoaXMudGVzdHNbY10uanMgPT0gcXVlcnlQYXJhbXMudGVzdCApXG5cdFx0XHRcdCAgICB7XG5cdFx0XHRcdFx0ICAgIGNvbnNvbGUubG9nICggJz09PT09PT4+Pj4gTE9BRCBURVNUJyk7XG5cblx0XHRcdFx0XHQgICAgdGhpcy5uYXZpZ2F0ZVRvU2VjdGlvbiggdGhpcy50ZXN0c1tjXSApO1xuXHRcdFx0XHRcdCAgICB0aGlzLmxvYWREZWZhdWx0ID0gZmFsc2U7XG5cdFx0XHRcdCAgICB9XG5cdFx0XHQgICAgfVxuXHRcdCAgICB9XG5cdCAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgcHJpdmF0ZSBpbml0SW50ZXJmYWNlKCkgOiB2b2lkXG4gICAgICAgIHtcblxuICAgICAgICAgICAgdmFyIHRlc3RTZWxlY3RvciA6IEhUTUxEaXZFbGVtZW50ICAgPSA8SFRNTERpdkVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdkaXYnICk7XG4gICAgICAgICAgICAgICAgdGVzdFNlbGVjdG9yLnN0eWxlLmNzc0Zsb2F0ICAgICA9ICdub25lJztcbiAgICAgICAgICAgICAgICB0ZXN0U2VsZWN0b3Iuc3R5bGUucG9zaXRpb24gICAgID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgICAgICB0ZXN0U2VsZWN0b3Iuc3R5bGUuYm90dG9tICAgICAgID0gJzE1cHgnO1xuICAgICAgICAgICAgICAgIHRlc3RTZWxlY3Rvci5zdHlsZS53aWR0aCAgICAgICAgPSAnNjAwcHgnO1xuICAgICAgICAgICAgICAgIHRlc3RTZWxlY3Rvci5zdHlsZS5sZWZ0ICAgICAgICAgPSAnNTAlJztcbiAgICAgICAgICAgICAgICB0ZXN0U2VsZWN0b3Iuc3R5bGUubWFyZ2luTGVmdCAgID0gJy0zMDBweCdcbiAgICAgICAgICAgICAgICB0ZXN0U2VsZWN0b3Iuc3R5bGUudGV4dEFsaWduICAgID0gJ2NlbnRlcic7XG5cblxuICAgICAgICAgICAgdGhpcy5kcm9wRG93biAgICAgICAgICAgICAgICAgICAgICAgPSA8SFRNTFNlbGVjdEVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdzZWxlY3QnICk7XG4gICAgICAgICAgICB0aGlzLmRyb3BEb3duLm5hbWUgICAgICAgICAgICAgICAgICA9IFwic2VsZWN0VGVzdERyb3BEb3duXCJcbiAgICAgICAgICAgIHRoaXMuZHJvcERvd24uaWQgICAgICAgICAgICAgICAgICAgID0gXCJzZWxlY3RUZXN0XCJcblxuICAgICAgICAgICAgdGhpcy5zb3VyY2VCdG4gICAgICAgICAgICAgICAgICAgICAgPSA8SFRNTEJ1dHRvbkVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdidXR0b24nICk7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ0bi5pbm5lckhUTUwgICAgICAgICAgICA9ICdTaG93IFNvdXJjZSc7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ0bi5pZCAgICAgICAgICAgICAgICAgICA9ICdwcmV2aW91cyc7XG5cbiAgICAgICAgICAgIHRoaXMucHJldmlvdXNCdG4gICAgICAgICAgICAgICAgICAgID0gPEhUTUxCdXR0b25FbGVtZW50PiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnYnV0dG9uJyApO1xuICAgICAgICAgICAgdGhpcy5wcmV2aW91c0J0bi5pbm5lckhUTUwgICAgICAgICAgPSAnPDwnO1xuICAgICAgICAgICAgdGhpcy5wcmV2aW91c0J0bi5pZCAgICAgICAgICAgICAgICAgPSAncHJldmlvdXMnO1xuXG4gICAgICAgICAgICB0aGlzLm5leHRCdG4gICAgICAgICAgICAgICAgICAgICAgICA9IDxIVE1MQnV0dG9uRWxlbWVudD4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2J1dHRvbicgKTtcbiAgICAgICAgICAgIHRoaXMubmV4dEJ0bi5pbm5lckhUTUwgICAgICAgICAgICAgID0gJz4+JztcbiAgICAgICAgICAgIHRoaXMubmV4dEJ0bi5pZCAgICAgICAgICAgICAgICAgICAgID0gJ25leHQnO1xuXG5cbiAgICAgICAgICAgIHRlc3RTZWxlY3Rvci5hcHBlbmRDaGlsZCggdGhpcy5zb3VyY2VCdG4gKTtcbiAgICAgICAgICAgIHRlc3RTZWxlY3Rvci5hcHBlbmRDaGlsZCggdGhpcy5wcmV2aW91c0J0biApO1xuICAgICAgICAgICAgdGVzdFNlbGVjdG9yLmFwcGVuZENoaWxkKCB0aGlzLmRyb3BEb3duICk7XG4gICAgICAgICAgICB0ZXN0U2VsZWN0b3IuYXBwZW5kQ2hpbGQoIHRoaXMubmV4dEJ0biApO1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggdGVzdFNlbGVjdG9yICk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBwcml2YXRlIGluaXRGcmFtZVNldCgpIDogdm9pZFxuICAgICAgICB7XG5cbiAgICAgICAgICAgIHZhciBpZnJhbWVDb250YWluZXIgOiBIVE1MRGl2RWxlbWVudCAgICA9IDxIVE1MRGl2RWxlbWVudD4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcbiAgICAgICAgICAgICAgICBpZnJhbWVDb250YWluZXIuc3R5bGUud2lkdGggICAgICAgICA9ICcxMDAlJztcbiAgICAgICAgICAgICAgICBpZnJhbWVDb250YWluZXIuc3R5bGUuaGVpZ2h0ICAgICAgICA9ICcxMDAlJztcblxuICAgICAgICAgICAgdGhpcy50ZXN0SWZyYW1lICAgICAgICAgICAgICAgICAgICAgID0gPEhUTUxJRnJhbWVFbGVtZW50PiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnaWZyYW1lJyApO1xuICAgICAgICAgICAgdGhpcy50ZXN0SWZyYW1lLmlkICAgICAgICAgICAgICAgICAgID0gJ3Rlc3RDb250YWluZXInO1xuICAgICAgICAgICAgdGhpcy50ZXN0SWZyYW1lLnN0eWxlLmJhY2tncm91bmRDb2xvciA9ICcjOWU5ZTllJztcbiAgICAgICAgICAgIHRoaXMudGVzdElmcmFtZS5zdHlsZS5jc3NGbG9hdCAgICAgICA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMudGVzdElmcmFtZS5zdHlsZS5wb3NpdGlvbiAgICAgICA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICB0aGlzLnRlc3RJZnJhbWUuc3R5bGUudG9wICAgICAgICAgICAgPSAnMHB4JztcbiAgICAgICAgICAgIHRoaXMudGVzdElmcmFtZS5zdHlsZS5sZWZ0ICAgICAgICAgICA9ICcwcHgnO1xuICAgICAgICAgICAgdGhpcy50ZXN0SWZyYW1lLnN0eWxlLmJvcmRlciAgICAgICAgID0gJzBweCc7XG4gICAgICAgICAgICB0aGlzLnRlc3RJZnJhbWUuc3R5bGUud2lkdGggICAgICAgICAgPSAnMTAwJSc7XG4gICAgICAgICAgICB0aGlzLnRlc3RJZnJhbWUuc3R5bGUuaGVpZ2h0ICAgICAgICAgPSAnMTAwJSc7XG4gICAgICAgICAgICAvL2JvdHRvbTogMTIwcHg7XG5cbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lICAgICAgICAgICAgICAgICAgICAgICAgICA9IDxIVE1MSUZyYW1lRWxlbWVudD4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2lmcmFtZScgKTtcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLmlkICAgICAgICAgICAgICAgICAgICAgICA9ICd0ZXN0U291cmNlQ29udGFpbmVyJztcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLnN0eWxlLmJhY2tncm91bmRDb2xvciAgICA9ICcjOWU5ZTllJztcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLnN0eWxlLmNzc0Zsb2F0ICAgICAgICAgICA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLnN0eWxlLnBvc2l0aW9uICAgICAgICAgICA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICB0aGlzLnNyY0lmcmFtZS5zdHlsZS5yaWdodCAgICAgICAgICAgICAgPSAnMHB4JztcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLnN0eWxlLnRvcCAgICAgICAgICAgICAgICA9ICcwcHgnO1xuICAgICAgICAgICAgdGhpcy5zcmNJZnJhbWUuc3R5bGUuYm90dG9tICAgICAgICAgICAgID0gJzBweCc7XG4gICAgICAgICAgICB0aGlzLnNyY0lmcmFtZS5zdHlsZS5ib3JkZXIgICAgICAgICAgICAgPSAnMHB4JztcbiAgICAgICAgICAgIHRoaXMuc3JjSWZyYW1lLnN0eWxlLndpZHRoICAgICAgICAgICAgICA9ICcwJSc7XG4gICAgICAgICAgICB0aGlzLnNyY0lmcmFtZS5zdHlsZS5oZWlnaHQgICAgICAgICAgICAgPSAnMTAwJSc7XG5cbiAgICAgICAgICAgIGlmcmFtZUNvbnRhaW5lci5hcHBlbmRDaGlsZCggdGhpcy50ZXN0SWZyYW1lICk7XG4gICAgICAgICAgICBpZnJhbWVDb250YWluZXIuYXBwZW5kQ2hpbGQoIHRoaXMuc3JjSWZyYW1lICk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIGlmcmFtZUNvbnRhaW5lciApO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogU2VsZWN0bmV4dCAvIHByZXZpb3VzIG1lbnUgaXRlbVxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZGlyZWN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICBwcml2YXRlIG5hZ2lnYXRlQnkoIGRpcmVjdGlvbiA6IG51bWJlciA9IDEgKSA6IHZvaWRcbiAgICAgICAge1xuXG4gICAgICAgICAgICB2YXIgbCA6IG51bWJlciAgPSB0aGlzLnRlc3RzLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBuZXh0Q291bnRlciA9IHRoaXMuY291bnRlciArIGRpcmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKCBuZXh0Q291bnRlciA8IDAgKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5leHRDb3VudGVyID0gdGhpcy50ZXN0cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIG5leHRDb3VudGVyID4gdGhpcy50ZXN0cy5sZW5ndGggLSAxIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuZXh0Q291bnRlciA9IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0ZXN0RGF0YSA6IFRlc3REYXRhID0gdGhpcy50ZXN0c1tuZXh0Q291bnRlcl07XG5cbiAgICAgICAgICAgIGlmICggdGVzdERhdGEubmFtZS5pbmRleE9mICgnLS0nKSAhPSAtMSApIC8vIHNraXAgc2VjdGlvbiBoZWFkZXJzXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb3VudGVyID0gbmV4dENvdW50ZXI7XG4gICAgICAgICAgICAgICAgdGhpcy5uYWdpZ2F0ZUJ5KCBkaXJlY3Rpb24gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRlVG9TZWN0aW9uKCB0ZXN0RGF0YSApO1xuICAgICAgICAgICAgICAgIHRoaXMuZHJvcERvd24uc2VsZWN0ZWRJbmRleCA9IG5leHRDb3VudGVyO1xuICAgICAgICAgICAgICAgIHRoaXMuY291bnRlciA9IG5leHRDb3VudGVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogTmF2aWdhdGUgdG8gYSBzZWN0aW9uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB0ZXN0RGF0YVxuICAgICAgICAgKi9cbiAgICAgICAgcHJpdmF0ZSBuYXZpZ2F0ZVRvU2VjdGlvbiAoIHRlc3REYXRhIDogVGVzdERhdGEgKSA6IHZvaWRcbiAgICAgICAge1xuXHQgICAgICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh0ZXN0RGF0YS5qcywgdGVzdERhdGEuanMsICc/dGVzdD0nICsgdGVzdERhdGEuanMpO1xuICAgICAgICAgICAgdGhpcy5zcmNJZnJhbWUuc3JjID0gXCJkYXRhOnRleHQvaHRtbDtjaGFyc2V0PXV0Zi04LFwiICsgdGhpcy5jcmVhdGVTb3VyY2VWaWV3SFRNTCggdGVzdERhdGEuc3JjICk7XG4gICAgICAgICAgICB0aGlzLnRlc3RJZnJhbWUuc3JjID0gJ2ZyYW1lLmh0bWw/bmFtZT0nICsgdGVzdERhdGEuY2xhc3NwYXRoICsgJyZqcz0nICsgdGVzdERhdGEuanM7XG4gICAgICAgIH1cblxuICAgICAgICBwcml2YXRlIHRvZ2dsZVNvdXJjZSgpIDogdm9pZFxuICAgICAgICB7XG5cbiAgICAgICAgICAgIGlmICggdGhpcy5zb3VyY2VWaXNpYmxlIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRlc3RJZnJhbWUuc3R5bGUud2lkdGggICAgICAgICA9ICcxMDAlJztcbiAgICAgICAgICAgICAgICB0aGlzLnNyY0lmcmFtZS5zdHlsZS53aWR0aCAgICAgICAgICA9ICcwJSc7XG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VCdG4uaW5uZXJIVE1MICAgICAgICAgICAgPSAnU2hvdyBTb3VyY2UnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRoaXMudGVzdElmcmFtZS5zdHlsZS53aWR0aCAgICAgICAgID0gJzIwJSc7XG4gICAgICAgICAgICAgICAgdGhpcy5zcmNJZnJhbWUuc3R5bGUud2lkdGggICAgICAgICAgPSAnODAlJztcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUJ0bi5pbm5lckhUTUwgICAgICAgICAgICA9ICdIaWRlIFNvdXJjZSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc291cmNlVmlzaWJsZSA9ICF0aGlzLnNvdXJjZVZpc2libGU7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIHByaXZhdGUgY3JlYXRlU291cmNlVmlld0hUTUwgKCB1cmwgOiBzdHJpbmcgKSA6IHN0cmluZ1xuICAgICAgICB7XG5cbiAgICAgICAgICAgIHZhciBodG1sIDogc3RyaW5nID0gJyc7XG5cbiAgICAgICAgICAgIGh0bWwgKz0gJzwhRE9DVFlQRSBodG1sPic7XG4gICAgICAgICAgICBodG1sICs9ICc8aHRtbD4nO1xuICAgICAgICAgICAgaHRtbCArPSAnICAgPGhlYWQ+JztcbiAgICAgICAgICAgIGh0bWwgKz0gJyAgICAgICA8dGl0bGU+PC90aXRsZT4nO1xuICAgICAgICAgICAgaHRtbCArPSAnICAgICAgIDxzdHlsZT4nO1xuICAgICAgICAgICAgaHRtbCArPSAnICAgICAgICAgICBodG1sJztcbiAgICAgICAgICAgIGh0bWwgKz0gJyAgICAgICAgICAgeyc7XG4gICAgICAgICAgICBodG1sICs9ICcgICAgICAgICAgICAgICBoZWlnaHQ6IDEwMCU7JztcbiAgICAgICAgICAgIGh0bWwgKz0gJyAgICAgICAgICAgICAgIGJvcmRlcjogMHB4Oyc7XG4gICAgICAgICAgICBodG1sICs9ICcgICAgICAgICAgICAgICBwYWRkaW5nOiAwcHg7JztcbiAgICAgICAgICAgIGh0bWwgKz0gJyAgICAgICAgICB9JztcbiAgICAgICAgICAgIGh0bWwgKz0gJyAgICAgICA8L3N0eWxlPic7XG5cdCAgICAgICAgaHRtbCArPSAnICAgPHNjcmlwdCBzcmM9XCJodHRwOi8vZ2lzdC1pdC5hcHBzcG90LmNvbS9naXRodWIvYXdheWpzL2F3YXlqcy1jb3JlLXRzL3RyZWUvbWFzdGVyL3Rlc3RzLycgKyB1cmwgKyAnP2Zvb3Rlcj1ub1wiPjwvc2NyaXB0Pic7XG4gICAgICAgICAgICBodG1sICs9ICc8L2hlYWQ+JztcbiAgICAgICAgICAgIGh0bWwgKz0gJzxib2R5Pic7XG4gICAgICAgICAgICBodG1sICs9ICc8L2JvZHk+JztcbiAgICAgICAgICAgIGh0bWwgKz0gJzwvaHRtbD4nO1xuXG4gICAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFV0aWxzXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqIFV0aWwgZnVuY3Rpb24gLSBnZXQgRWxlbWVudCBieSBJRFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gaWRcbiAgICAgICAgICogQHJldHVybnMge0hUTUxFbGVtZW50fVxuICAgICAgICAgKi9cbiAgICAgICAgcHJpdmF0ZSBnZXRJZChpZCA6IHN0cmluZyApIDogSFRNTEVsZW1lbnRcbiAgICAgICAge1xuICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gRXZlbnRzXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqIERyb3Bib3ggZXZlbnQgaGFuZGxlclxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZVxuICAgICAgICAgKi9cbiAgICAgICAgcHJpdmF0ZSBkcm9wRG93bkNoYW5nZSggZSApIDogdm9pZFxuICAgICAgICB7XG4gICAgICAgICAgICB0aGlzLmRyb3BEb3duLm9wdGlvbnNbdGhpcy5kcm9wRG93bi5zZWxlY3RlZEluZGV4XS52YWx1ZVxuICAgICAgICAgICAgdGhpcy5jb3VudGVyID0gdGhpcy5kcm9wRG93bi5zZWxlY3RlZEluZGV4O1xuICAgICAgICAgICAgdmFyIGRhdGFJbmRleCA6IG51bWJlciA9IHBhcnNlSW50KCB0aGlzLmRyb3BEb3duLm9wdGlvbnNbdGhpcy5kcm9wRG93bi5zZWxlY3RlZEluZGV4XS52YWx1ZSApIDtcblxuICAgICAgICAgICAgaWYgKCAhIGlzTmFOKCBkYXRhSW5kZXggKSApXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGhpcy5uYXZpZ2F0ZVRvU2VjdGlvbiggdGhpcy50ZXN0c1tkYXRhSW5kZXhdICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQXBwbGljYXRpb24gRnJhbWVcblxuICAgIGV4cG9ydCBjbGFzcyBBcHBGcmFtZVxuICAgIHtcblxuICAgICAgICBwcml2YXRlIGNsYXNzUGF0aCAgIDogc3RyaW5nID0gJyc7XG4gICAgICAgIHByaXZhdGUganNQYXRoICAgICAgOiBzdHJpbmcgPSAnJztcblxuICAgICAgICBjb25zdHJ1Y3RvciggKVxuICAgICAgICB7XG5cbiAgICAgICAgICAgIHZhciBxdWVyeVBhcmFtcyA6IGFueSA9IFV0aWxzLmdldFF1ZXJ5UGFyYW1zKCBkb2N1bWVudC5sb2NhdGlvbi5zZWFyY2ggKTtcblxuICAgICAgICAgICAgaWYgKCBxdWVyeVBhcmFtcy5qcyAhPSB1bmRlZmluZWQgJiYgcXVlcnlQYXJhbXMubmFtZSAhPSB1bmRlZmluZWQgKVxuICAgICAgICAgICAge1xuXG4gICAgICAgICAgICAgICAgdGhpcy5qc1BhdGggICAgID0gcXVlcnlQYXJhbXMuanM7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc1BhdGggID0gcXVlcnlQYXJhbXMubmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRKUyggdGhpcy5qc1BhdGggKTtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogTG9hZCBhIEphdmFTY3JpcHQgZmlsZVxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gdXJsIC0gVVJMIG9mIEphdmFTY3JpcHQgZmlsZVxuICAgICAgICAgKi9cbiAgICAgICAgcHJpdmF0ZSBsb2FkSlModXJsIDogc3RyaW5nIClcbiAgICAgICAge1xuXG4gICAgICAgICAgICB2YXIgaGVhZCA6IEhUTUxFbGVtZW50ID0gPEhUTUxFbGVtZW50PiBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF07XG4gICAgICAgICAgICB2YXIgc2NyaXB0IDogSFRNTFNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuICAgICAgICAgICAgc2NyaXB0LnR5cGUgICAgID0gXCJ0ZXh0L2phdmFzY3JpcHRcIjtcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgICAgICA9IHVybDtcbiAgICAgICAgICAgIHNjcmlwdC5vbmxvYWQgICA9ICgpID0+IHRoaXMuanNMb2FkZWQoKTtcblxuICAgICAgICAgICAgaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqXG4gICAgICAgICAqIEV2ZW50IEhhbmRsZXIgZm9yIGxvYWRlZCBKYXZhU2NyaXB0IGZpbGVzXG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBwcml2YXRlIGpzTG9hZGVkKClcbiAgICAgICAge1xuXG4gICAgICAgICAgICB2YXIgY3JlYXRlUGF0aCA6IEFycmF5PHN0cmluZz4gPSB0aGlzLmNsYXNzUGF0aC5zcGxpdCgnLicpOyAvLyBTcGxpdCB0aGUgY2xhc3NwYXRoXG4gICAgICAgICAgICB2YXIgb2JqICAgICAgICAgOiBhbnk7XG5cbiAgICAgICAgICAgIGZvciAoIHZhciBjIDogbnVtYmVyID0gMCA7IGMgPCBjcmVhdGVQYXRoLmxlbmd0aCA7IGMrKyApXG4gICAgICAgICAgICB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIG9iaiA9PSBudWxsIClcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9iaiA9IHdpbmRvd1tjcmVhdGVQYXRoW2NdXTsgLy8gcmVmZXJlbmNlIGJhc2UgbW9kdWxlICggd2lsbCBiZSBhIGNoaWxkIG9mIHRoZSB3aW5kb3cgKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvYmogPSBvYmpbY3JlYXRlUGF0aFtjXV07IC8vIHJlZmVyZW5jZSBzdWIgbW9kdWxlIC8gQ2xhc3NcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIG9iaiAhPSBudWxsIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuZXcgb2JqKCk7IC8vIGlmIENsYXNzIGhhcyBiZWVuIGZvdW5kIC0gc3RhcnQgdGhlIHRlc3RcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG5cblxuXG4gICAgfVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIENvbW1vbiBVdGlsaXRpZXNcblxuXHRleHBvcnQgY2xhc3MgVXRpbHNcblx0e1xuXHRcdC8qKlxuXHRcdCAqXG5cdFx0ICogVXRpbGl0eSBmdW5jdGlvbiAtIFBhcnNlIGEgUXVlcnkgZm9ybWF0dGVkIHN0cmluZ1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHFzXG5cdFx0ICogQHJldHVybnMge3t9fVxuXHRcdCAqL1xuXHRcdHN0YXRpYyBnZXRRdWVyeVBhcmFtcyggcXMgKSA6IE9iamVjdCB7XG5cblx0XHRcdHFzID0gcXMuc3BsaXQoXCIrXCIpLmpvaW4oXCIgXCIpO1xuXG5cdFx0XHR2YXIgcGFyYW1zID0ge30sIHRva2Vucyxcblx0XHRcdFx0cmUgPSAvWz8mXT8oW149XSspPShbXiZdKikvZztcblxuXHRcdFx0d2hpbGUgKHRva2VucyA9IHJlLmV4ZWMocXMpKSB7XG5cdFx0XHRcdHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQodG9rZW5zWzFdKV0gPSBkZWNvZGVVUklDb21wb25lbnQodG9rZW5zWzJdKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHBhcmFtcztcblx0XHR9XG5cdH1cblxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gRGF0YVxuXG4gICAgY2xhc3MgVGVzdERhdGFcbiAgICB7XG4gICAgICAgIHB1YmxpYyBqcyAgICAgICAgICAgOiBzdHJpbmc7XG4gICAgICAgIHB1YmxpYyBjbGFzc3BhdGggICAgOiBzdHJpbmc7XG4gICAgICAgIHB1YmxpYyBzcmMgICAgICAgICAgOiBzdHJpbmc7XG4gICAgICAgIHB1YmxpYyBuYW1lICAgICAgICAgOiBzdHJpbmc7XG5cbiAgICAgICAgY29uc3RydWN0b3IoIG5hbWUgOiBzdHJpbmcgLCBjbGFzc3BhdGggOiBzdHJpbmcgLCBqcyA6IHN0cmluZyAsIHNyYyA6IHN0cmluZyApXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRoaXMuanMgICAgICAgICA9IGpzO1xuICAgICAgICAgICAgdGhpcy5jbGFzc3BhdGggID0gY2xhc3NwYXRoO1xuICAgICAgICAgICAgdGhpcy5zcmMgICAgICAgID0gc3JjO1xuICAgICAgICAgICAgdGhpcy5uYW1lICAgICAgID0gbmFtZTtcbiAgICAgICAgfVxuICAgIH1cbn0iXX0= \ No newline at end of file diff --git a/tests/lights/LightsShadowTest.js b/tests/lights/LightsShadowTest.js new file mode 100755 index 000000000..41c1aaede --- /dev/null +++ b/tests/lights/LightsShadowTest.js @@ -0,0 +1,112 @@ +var View = require("awayjs-core/lib/containers/View"); +var HoverController = require("awayjs-core/lib/controllers/HoverController"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var AssetEvent = require("awayjs-core/lib/events/AssetEvent"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +var LightsShadowTest = (function () { + function LightsShadowTest() { + var _this = this; + this.lookAtPosition = new Vector3D(); + this._move = false; + Debug.LOG_PI_ERRORS = true; + Debug.THROW_ERRORS = false; + AssetLibrary.enableParser(AWDParser); + this._token = AssetLibrary.load(new URLRequest('assets/ShadowTest.awd')); + this._token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this._token.addEventListener(AssetEvent.ASSET_COMPLETE, function (event) { return _this.onAssetComplete(event); }); + this._view = new View(new DefaultRenderer()); + this._view.camera.projection.far = 5000; + this._view.camera.y = 100; + this._timer = new RequestAnimationFrame(this.render, this); + this._cameraController = new HoverController(this._view.camera, null, 45, 20, 2000, 5); + document.onmousedown = function (event) { return _this.onMouseDown(event); }; + document.onmouseup = function (event) { return _this.onMouseUp(event); }; + document.onmousemove = function (event) { return _this.onMouseMove(event); }; + document.onmousewheel = function (event) { return _this.onMouseWheel(event); }; + window.onresize = function (event) { return _this.resize(event); }; + } + LightsShadowTest.prototype.resize = function (event) { + if (event === void 0) { event = null; } + this._view.y = 0; + this._view.x = 0; + this._view.width = window.innerWidth; + this._view.height = window.innerHeight; + }; + LightsShadowTest.prototype.render = function (dt) { + if (this._view.camera) + this._view.camera.lookAt(this.lookAtPosition); + if (this._awdMesh) + this._awdMesh.rotationY += 0.2; + this._view.render(); + }; + LightsShadowTest.prototype.onAssetComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('AssetEvent.ASSET_COMPLETE', AssetLibrary.getAsset(event.asset.name)); + console.log('------------------------------------------------------------------------------'); + }; + LightsShadowTest.prototype.onResourceComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('LoaderEvent.RESOURCE_COMPLETE', event); + console.log('------------------------------------------------------------------------------'); + var loader = event.target; + var numAssets = loader.baseDependency.assets.length; + for (var i = 0; i < numAssets; ++i) { + var asset = loader.baseDependency.assets[i]; + switch (asset.assetType) { + case AssetType.MESH: + this._awdMesh = asset; + this._view.scene.addChild(this._awdMesh); + this.resize(); + break; + case AssetType.LIGHT: + this._view.scene.addChild(asset); + break; + case AssetType.MATERIAL: + break; + } + } + this._timer.start(); + }; + /** + * Mouse down listener for navigation + */ + LightsShadowTest.prototype.onMouseDown = function (event) { + this._lastPanAngle = this._cameraController.panAngle; + this._lastTiltAngle = this._cameraController.tiltAngle; + this._lastMouseX = event.clientX; + this._lastMouseY = event.clientY; + this._move = true; + }; + /** + * Mouse up listener for navigation + */ + LightsShadowTest.prototype.onMouseUp = function (event) { + this._move = false; + }; + LightsShadowTest.prototype.onMouseMove = function (event) { + if (this._move) { + this._cameraController.panAngle = 0.3 * (event.clientX - this._lastMouseX) + this._lastPanAngle; + this._cameraController.tiltAngle = 0.3 * (event.clientY - this._lastMouseY) + this._lastTiltAngle; + } + }; + /** + * Mouse wheel listener for navigation + */ + LightsShadowTest.prototype.onMouseWheel = function (event) { + this._cameraController.distance -= event.wheelDelta * 2; + if (this._cameraController.distance < 100) + this._cameraController.distance = 100; + else if (this._cameraController.distance > 2000) + this._cameraController.distance = 2000; + }; + return LightsShadowTest; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpZ2h0cy9saWdodHNzaGFkb3d0ZXN0LnRzIl0sIm5hbWVzIjpbIkxpZ2h0c1NoYWRvd1Rlc3QiLCJMaWdodHNTaGFkb3dUZXN0LmNvbnN0cnVjdG9yIiwiTGlnaHRzU2hhZG93VGVzdC5yZXNpemUiLCJMaWdodHNTaGFkb3dUZXN0LnJlbmRlciIsIkxpZ2h0c1NoYWRvd1Rlc3Qub25Bc3NldENvbXBsZXRlIiwiTGlnaHRzU2hhZG93VGVzdC5vblJlc291cmNlQ29tcGxldGUiLCJMaWdodHNTaGFkb3dUZXN0Lm9uTW91c2VEb3duIiwiTGlnaHRzU2hhZG93VGVzdC5vbk1vdXNlVXAiLCJMaWdodHNTaGFkb3dUZXN0Lm9uTW91c2VNb3ZlIiwiTGlnaHRzU2hhZG93VGVzdC5vbk1vdXNlV2hlZWwiXSwibWFwcGluZ3MiOiJBQUFBLElBQU8sSUFBSSxXQUFpQixpQ0FBaUMsQ0FBQyxDQUFDO0FBQy9ELElBQU8sZUFBZSxXQUFjLDZDQUE2QyxDQUFDLENBQUM7QUFFbkYsSUFBTyxRQUFRLFdBQWdCLG9DQUFvQyxDQUFDLENBQUM7QUFDckUsSUFBTyxZQUFZLFdBQWUsMkNBQTJDLENBQUMsQ0FBQztBQUcvRSxJQUFPLFNBQVMsV0FBZSx3Q0FBd0MsQ0FBQyxDQUFDO0FBRXpFLElBQU8sVUFBVSxXQUFlLHFDQUFxQyxDQUFDLENBQUM7QUFFdkUsSUFBTyxVQUFVLFdBQWUsbUNBQW1DLENBQUMsQ0FBQztBQUNyRSxJQUFPLFdBQVcsV0FBZSxvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3ZFLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBRXRGLElBQU8sU0FBUyxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFFMUUsSUFBTSxnQkFBZ0I7SUFlckJBLFNBZktBLGdCQUFnQkE7UUFBdEJDLGlCQThJQ0E7UUF4SVFBLG1CQUFjQSxHQUFZQSxJQUFJQSxRQUFRQSxFQUFFQSxDQUFDQTtRQUd6Q0EsVUFBS0EsR0FBV0EsS0FBS0EsQ0FBQ0E7UUFRN0JBLEtBQUtBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBO1FBQzNCQSxLQUFLQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUUzQkEsWUFBWUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0E7UUFFckNBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLFlBQVlBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLFVBQVVBLENBQUNBLHVCQUF1QkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFFekVBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLGdCQUFnQkEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsaUJBQWlCQSxFQUFFQSxVQUFDQSxLQUFpQkEsSUFBS0EsT0FBQUEsS0FBSUEsQ0FBQ0Esa0JBQWtCQSxDQUFDQSxLQUFLQSxDQUFDQSxFQUE5QkEsQ0FBOEJBLENBQUNBLENBQUNBO1FBQ25IQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxnQkFBZ0JBLENBQUNBLFVBQVVBLENBQUNBLGNBQWNBLEVBQUVBLFVBQUNBLEtBQWdCQSxJQUFLQSxPQUFBQSxLQUFJQSxDQUFDQSxlQUFlQSxDQUFDQSxLQUFLQSxDQUFDQSxFQUEzQkEsQ0FBMkJBLENBQUNBLENBQUNBO1FBRTNHQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxJQUFJQSxDQUFDQSxJQUFJQSxlQUFlQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUM3Q0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0EsR0FBR0EsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDeENBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBO1FBRTFCQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxJQUFJQSxxQkFBcUJBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLElBQUlBLENBQUNBLENBQUNBO1FBRTNEQSxJQUFJQSxDQUFDQSxpQkFBaUJBLEdBQUdBLElBQUlBLGVBQWVBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLEVBQUVBLElBQUlBLEVBQUVBLEVBQUVBLEVBQUVBLEVBQUVBLEVBQUVBLElBQUlBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBO1FBRXZGQSxRQUFRQSxDQUFDQSxXQUFXQSxHQUFHQSxVQUFDQSxLQUFnQkEsSUFBS0EsT0FBQUEsS0FBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsRUFBdkJBLENBQXVCQSxDQUFDQTtRQUNyRUEsUUFBUUEsQ0FBQ0EsU0FBU0EsR0FBR0EsVUFBQ0EsS0FBZ0JBLElBQUtBLE9BQUFBLEtBQUlBLENBQUNBLFNBQVNBLENBQUNBLEtBQUtBLENBQUNBLEVBQXJCQSxDQUFxQkEsQ0FBQ0E7UUFDakVBLFFBQVFBLENBQUNBLFdBQVdBLEdBQUdBLFVBQUNBLEtBQWdCQSxJQUFLQSxPQUFBQSxLQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxLQUFLQSxDQUFDQSxFQUF2QkEsQ0FBdUJBLENBQUNBO1FBQ3JFQSxRQUFRQSxDQUFDQSxZQUFZQSxHQUFHQSxVQUFDQSxLQUFxQkEsSUFBS0EsT0FBQUEsS0FBSUEsQ0FBQ0EsWUFBWUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsRUFBeEJBLENBQXdCQSxDQUFDQTtRQUU1RUEsTUFBTUEsQ0FBQ0EsUUFBUUEsR0FBR0EsVUFBQ0EsS0FBYUEsSUFBS0EsT0FBQUEsS0FBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsRUFBbEJBLENBQWtCQSxDQUFDQTtJQUN6REEsQ0FBQ0E7SUFFT0QsaUNBQU1BLEdBQWRBLFVBQWVBLEtBQW9CQTtRQUFwQkUscUJBQW9CQSxHQUFwQkEsWUFBb0JBO1FBRWxDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUNqQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDakJBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBLFVBQVVBLENBQUNBO1FBQ3JDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxHQUFHQSxNQUFNQSxDQUFDQSxXQUFXQSxDQUFDQTtJQUN4Q0EsQ0FBQ0E7SUFFT0YsaUNBQU1BLEdBQWRBLFVBQWVBLEVBQVNBO1FBRXZCRyxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxDQUFDQTtZQUNyQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0EsQ0FBQ0E7UUFFL0NBLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBO1lBQ2pCQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxTQUFTQSxJQUFJQSxHQUFHQSxDQUFDQTtRQUUvQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0E7SUFDdEJBLENBQUNBO0lBRU1ILDBDQUFlQSxHQUF0QkEsVUFBdUJBLEtBQWdCQTtRQUV0Q0ksT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUM5RkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsMkJBQTJCQSxFQUFHQSxZQUFZQSxDQUFDQSxRQUFRQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNuRkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtJQUMvRkEsQ0FBQ0E7SUFFTUosNkNBQWtCQSxHQUF6QkEsVUFBMEJBLEtBQWlCQTtRQUcxQ0ssT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUM5RkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsK0JBQStCQSxFQUFHQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUNyREEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUU5RkEsSUFBSUEsTUFBTUEsR0FBNkJBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBO1FBQ3BEQSxJQUFJQSxTQUFTQSxHQUFVQSxNQUFNQSxDQUFDQSxjQUFjQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQTtRQUUzREEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBVUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsU0FBU0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDM0NBLElBQUlBLEtBQUtBLEdBQVVBLE1BQU1BLENBQUNBLGNBQWNBLENBQUNBLE1BQU1BLENBQUVBLENBQUNBLENBQUVBLENBQUNBO1lBRXJEQSxNQUFNQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDekJBLEtBQUtBLFNBQVNBLENBQUNBLElBQUlBO29CQUNsQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBVUEsS0FBS0EsQ0FBQ0E7b0JBQzdCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtvQkFDekNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBO29CQUNkQSxLQUFLQSxDQUFDQTtnQkFFUEEsS0FBS0EsU0FBU0EsQ0FBQ0EsS0FBS0E7b0JBQ25CQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFhQSxLQUFLQSxDQUFDQSxDQUFDQTtvQkFDN0NBLEtBQUtBLENBQUNBO2dCQUVQQSxLQUFLQSxTQUFTQSxDQUFDQSxRQUFRQTtvQkFDdEJBLEtBQUtBLENBQUNBO1lBRVJBLENBQUNBO1FBQ0ZBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLEtBQUtBLEVBQUVBLENBQUNBO0lBQ3JCQSxDQUFDQTtJQUVETDs7T0FFR0E7SUFDS0Esc0NBQVdBLEdBQW5CQSxVQUFvQkEsS0FBS0E7UUFFeEJNLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsUUFBUUEsQ0FBQ0E7UUFDckRBLElBQUlBLENBQUNBLGNBQWNBLEdBQUdBLElBQUlBLENBQUNBLGlCQUFpQkEsQ0FBQ0EsU0FBU0EsQ0FBQ0E7UUFDdkRBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEtBQUtBLENBQUNBLE9BQU9BLENBQUNBO1FBQ2pDQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQSxPQUFPQSxDQUFDQTtRQUNqQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsQ0FBQ0E7SUFDbkJBLENBQUNBO0lBRUROOztPQUVHQTtJQUNLQSxvQ0FBU0EsR0FBakJBLFVBQWtCQSxLQUFLQTtRQUV0Qk8sSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsS0FBS0EsQ0FBQ0E7SUFDcEJBLENBQUNBO0lBRU9QLHNDQUFXQSxHQUFuQkEsVUFBb0JBLEtBQUtBO1FBRXhCUSxFQUFFQSxDQUFDQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNoQkEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxHQUFHQSxHQUFHQSxHQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtZQUM5RkEsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxTQUFTQSxHQUFHQSxHQUFHQSxHQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQTtRQUNqR0EsQ0FBQ0E7SUFDRkEsQ0FBQ0E7SUFFRFI7O09BRUdBO0lBQ0tBLHVDQUFZQSxHQUFwQkEsVUFBcUJBLEtBQXFCQTtRQUV6Q1MsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxJQUFJQSxLQUFLQSxDQUFDQSxVQUFVQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUV4REEsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxHQUFHQSxHQUFHQSxDQUFDQTtZQUN6Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxHQUFHQSxHQUFHQSxDQUFDQTtRQUN2Q0EsSUFBSUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtZQUMvQ0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUN6Q0EsQ0FBQ0E7SUFDRlQsdUJBQUNBO0FBQURBLENBOUlBLEFBOElDQSxJQUFBIiwiZmlsZSI6ImxpZ2h0cy9MaWdodHNTaGFkb3dUZXN0LmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXJlbmRlcmVyZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZpZXdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL1ZpZXdcIik7XG5pbXBvcnQgSG92ZXJDb250cm9sbGVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udHJvbGxlcnMvSG92ZXJDb250cm9sbGVyXCIpO1xuaW1wb3J0IExpZ2h0QmFzZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0xpZ2h0QmFzZVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQXNzZXRMaWJyYXJ5XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMaWJyYXJ5XCIpO1xuaW1wb3J0IEFzc2V0TG9hZGVyXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMb2FkZXJcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJUb2tlblx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclRva2VuXCIpO1xuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0VHlwZVwiKTtcbmltcG9ydCBJQXNzZXRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0lBc3NldFwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IEFzc2V0RXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Bc3NldEV2ZW50XCIpO1xuaW1wb3J0IExvYWRlckV2ZW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvTG9hZGVyRXZlbnRcIik7XG5pbXBvcnQgRGVidWdcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvRGVidWdcIik7XG5pbXBvcnQgUmVxdWVzdEFuaW1hdGlvbkZyYW1lXHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9SZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIik7XG5cbmltcG9ydCBEZWZhdWx0UmVuZGVyZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3JlbmRlci9EZWZhdWx0UmVuZGVyZXJcIik7XG5cbmltcG9ydCBBV0RQYXJzZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvQVdEUGFyc2VyXCIpO1xuXG5jbGFzcyBMaWdodHNTaGFkb3dUZXN0XG57XG5cblx0cHJpdmF0ZSBfdmlldzpWaWV3O1xuXHRwcml2YXRlIF90b2tlbjpBc3NldExvYWRlclRva2VuO1xuXHRwcml2YXRlIF90aW1lcjpSZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XG5cdHByaXZhdGUgbG9va0F0UG9zaXRpb246VmVjdG9yM0QgPSBuZXcgVmVjdG9yM0QoKTtcblx0cHJpdmF0ZSBfYXdkTWVzaDpNZXNoO1xuXHRwcml2YXRlIF9jYW1lcmFDb250cm9sbGVyOkhvdmVyQ29udHJvbGxlcjtcblx0cHJpdmF0ZSBfbW92ZTpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgX2xhc3RQYW5BbmdsZTpudW1iZXI7XG5cdHByaXZhdGUgX2xhc3RUaWx0QW5nbGU6bnVtYmVyO1xuXHRwcml2YXRlIF9sYXN0TW91c2VYOm51bWJlcjtcblx0cHJpdmF0ZSBfbGFzdE1vdXNlWTpudW1iZXI7XG5cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0RGVidWcuTE9HX1BJX0VSUk9SUyA9IHRydWU7XG5cdFx0RGVidWcuVEhST1dfRVJST1JTID0gZmFsc2U7XG5cblx0XHRBc3NldExpYnJhcnkuZW5hYmxlUGFyc2VyKEFXRFBhcnNlcik7XG5cblx0XHR0aGlzLl90b2tlbiA9IEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KCdhc3NldHMvU2hhZG93VGVzdC5hd2QnKSk7XG5cblx0XHR0aGlzLl90b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFLCAoZXZlbnQ6TG9hZGVyRXZlbnQpID0+IHRoaXMub25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50KSk7XG5cdFx0dGhpcy5fdG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihBc3NldEV2ZW50LkFTU0VUX0NPTVBMRVRFLCAoZXZlbnQ6QXNzZXRFdmVudCkgPT4gdGhpcy5vbkFzc2V0Q29tcGxldGUoZXZlbnQpKTtcblxuXHRcdHRoaXMuX3ZpZXcgPSBuZXcgVmlldyhuZXcgRGVmYXVsdFJlbmRlcmVyKCkpO1xuXHRcdHRoaXMuX3ZpZXcuY2FtZXJhLnByb2plY3Rpb24uZmFyID0gNTAwMDtcblx0XHR0aGlzLl92aWV3LmNhbWVyYS55ID0gMTAwO1xuXG5cdFx0dGhpcy5fdGltZXIgPSBuZXcgUmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLCB0aGlzKTtcblxuXHRcdHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIgPSBuZXcgSG92ZXJDb250cm9sbGVyKHRoaXMuX3ZpZXcuY2FtZXJhLCBudWxsLCA0NSwgMjAsIDIwMDAsIDUpO1xuXG5cdFx0ZG9jdW1lbnQub25tb3VzZWRvd24gPSAoZXZlbnQ6TW91c2VFdmVudCkgPT4gdGhpcy5vbk1vdXNlRG93bihldmVudCk7XG5cdFx0ZG9jdW1lbnQub25tb3VzZXVwID0gKGV2ZW50Ok1vdXNlRXZlbnQpID0+IHRoaXMub25Nb3VzZVVwKGV2ZW50KTtcblx0XHRkb2N1bWVudC5vbm1vdXNlbW92ZSA9IChldmVudDpNb3VzZUV2ZW50KSA9PiB0aGlzLm9uTW91c2VNb3ZlKGV2ZW50KTtcblx0XHRkb2N1bWVudC5vbm1vdXNld2hlZWwgPSAoZXZlbnQ6TW91c2VXaGVlbEV2ZW50KSA9PiB0aGlzLm9uTW91c2VXaGVlbChldmVudCk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgPSAoZXZlbnQ6VUlFdmVudCkgPT4gdGhpcy5yZXNpemUoZXZlbnQpO1xuXHR9XG5cblx0cHJpdmF0ZSByZXNpemUoZXZlbnQ6VUlFdmVudCA9IG51bGwpXG5cdHtcblx0XHR0aGlzLl92aWV3LnkgPSAwO1xuXHRcdHRoaXMuX3ZpZXcueCA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKSAvL2FuaW1hdGUgYmFzZWQgb24gZHQgZm9yIGZpcmVmb3hcblx0e1xuXHRcdGlmICh0aGlzLl92aWV3LmNhbWVyYSlcblx0XHRcdHRoaXMuX3ZpZXcuY2FtZXJhLmxvb2tBdCh0aGlzLmxvb2tBdFBvc2l0aW9uKTtcblxuXHRcdGlmICh0aGlzLl9hd2RNZXNoKVxuXHRcdFx0dGhpcy5fYXdkTWVzaC5yb3RhdGlvblkgKz0gMC4yO1xuXG5cdFx0IHRoaXMuX3ZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgb25Bc3NldENvbXBsZXRlKGV2ZW50OkFzc2V0RXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ0Fzc2V0RXZlbnQuQVNTRVRfQ09NUExFVEUnICwgQXNzZXRMaWJyYXJ5LmdldEFzc2V0KGV2ZW50LmFzc2V0Lm5hbWUpKTtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdH1cblxuXHRwdWJsaWMgb25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50OkxvYWRlckV2ZW50KVxuXHR7XG5cblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ0xvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFJyAsIGV2ZW50KTtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cblx0XHR2YXIgbG9hZGVyOkFzc2V0TG9hZGVyID0gPEFzc2V0TG9hZGVyPiBldmVudC50YXJnZXQ7XG5cdFx0dmFyIG51bUFzc2V0czpudW1iZXIgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzLmxlbmd0aDtcblxuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IG51bUFzc2V0czsgKytpKSB7XG5cdFx0XHR2YXIgYXNzZXQ6SUFzc2V0ID0gbG9hZGVyLmJhc2VEZXBlbmRlbmN5LmFzc2V0c1sgaSBdO1xuXG5cdFx0XHRzd2l0Y2ggKGFzc2V0LmFzc2V0VHlwZSkge1xuXHRcdFx0XHRjYXNlIEFzc2V0VHlwZS5NRVNIOlxuXHRcdFx0XHRcdHRoaXMuX2F3ZE1lc2ggPSA8TWVzaD4gYXNzZXQ7XG5cdFx0XHRcdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZCh0aGlzLl9hd2RNZXNoKTtcblx0XHRcdFx0XHR0aGlzLnJlc2l6ZSgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLkxJR0hUOlxuXHRcdFx0XHRcdHRoaXMuX3ZpZXcuc2NlbmUuYWRkQ2hpbGQoPExpZ2h0QmFzZT4gYXNzZXQpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLk1BVEVSSUFMOlxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5fdGltZXIuc3RhcnQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNb3VzZSBkb3duIGxpc3RlbmVyIGZvciBuYXZpZ2F0aW9uXG5cdCAqL1xuXHRwcml2YXRlIG9uTW91c2VEb3duKGV2ZW50KTp2b2lkXG5cdHtcblx0XHR0aGlzLl9sYXN0UGFuQW5nbGUgPSB0aGlzLl9jYW1lcmFDb250cm9sbGVyLnBhbkFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RUaWx0QW5nbGUgPSB0aGlzLl9jYW1lcmFDb250cm9sbGVyLnRpbHRBbmdsZTtcblx0XHR0aGlzLl9sYXN0TW91c2VYID0gZXZlbnQuY2xpZW50WDtcblx0XHR0aGlzLl9sYXN0TW91c2VZID0gZXZlbnQuY2xpZW50WTtcblx0XHR0aGlzLl9tb3ZlID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNb3VzZSB1cCBsaXN0ZW5lciBmb3IgbmF2aWdhdGlvblxuXHQgKi9cblx0cHJpdmF0ZSBvbk1vdXNlVXAoZXZlbnQpOnZvaWRcblx0e1xuXHRcdHRoaXMuX21vdmUgPSBmYWxzZTtcblx0fVxuXG5cdHByaXZhdGUgb25Nb3VzZU1vdmUoZXZlbnQpXG5cdHtcblx0XHRpZiAodGhpcy5fbW92ZSkge1xuXHRcdFx0dGhpcy5fY2FtZXJhQ29udHJvbGxlci5wYW5BbmdsZSA9IDAuMyooZXZlbnQuY2xpZW50WCAtIHRoaXMuX2xhc3RNb3VzZVgpICsgdGhpcy5fbGFzdFBhbkFuZ2xlO1xuXHRcdFx0dGhpcy5fY2FtZXJhQ29udHJvbGxlci50aWx0QW5nbGUgPSAwLjMqKGV2ZW50LmNsaWVudFkgLSB0aGlzLl9sYXN0TW91c2VZKSArIHRoaXMuX2xhc3RUaWx0QW5nbGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1vdXNlIHdoZWVsIGxpc3RlbmVyIGZvciBuYXZpZ2F0aW9uXG5cdCAqL1xuXHRwcml2YXRlIG9uTW91c2VXaGVlbChldmVudDpNb3VzZVdoZWVsRXZlbnQpOnZvaWRcblx0e1xuXHRcdHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIuZGlzdGFuY2UgLT0gZXZlbnQud2hlZWxEZWx0YSAqIDI7XG5cblx0XHRpZiAodGhpcy5fY2FtZXJhQ29udHJvbGxlci5kaXN0YW5jZSA8IDEwMClcblx0XHRcdHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIuZGlzdGFuY2UgPSAxMDA7XG5cdFx0ZWxzZSBpZiAodGhpcy5fY2FtZXJhQ29udHJvbGxlci5kaXN0YW5jZSA+IDIwMDApXG5cdFx0XHR0aGlzLl9jYW1lcmFDb250cm9sbGVyLmRpc3RhbmNlID0gMjAwMDtcblx0fVxufSJdfQ== \ No newline at end of file diff --git a/tests/materials/MaterialAlphaTest.js b/tests/materials/MaterialAlphaTest.js new file mode 100755 index 000000000..d042d2828 --- /dev/null +++ b/tests/materials/MaterialAlphaTest.js @@ -0,0 +1,153 @@ +var View = require("awayjs-core/lib/containers/View"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var StaticLightPicker = require("awayjs-core/lib/materials/lightpickers/StaticLightPicker"); +var PrimitiveTorusPrefab = require("awayjs-core/lib/prefabs/PrimitiveTorusPrefab"); +var PrimitiveCubePrefab = require("awayjs-core/lib/prefabs/PrimitiveCubePrefab"); +var PrimitiveCapsulePrefab = require("awayjs-core/lib/prefabs/PrimitiveCapsulePrefab"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var OBJParser = require("awayjs-renderergl/lib/parsers/OBJParser"); +var MaterialAlphaTest = (function () { + function MaterialAlphaTest() { + var _this = this; + this.height = 0; + this.meshes = new Array(); + this.aValues = Array(0, .1, .5, .8, .9, .99, 1); + this.aValuesP = 0; + Debug.LOG_PI_ERRORS = false; + Debug.THROW_ERRORS = false; + this.view = new View(new DefaultRenderer()); + this.raf = new RequestAnimationFrame(this.render, this); + this.onResize(); + this.light = new DirectionalLight(); + this.light.color = 0xFFFFFF; + this.light.direction = new Vector3D(1, 1, 0); + this.light.ambient = 0; + this.light.ambientColor = 0xFFFFFF; + this.light.diffuse = 1; + this.light.specular = 1; + this.lightB = new DirectionalLight(); + this.lightB.color = 0xFF0000; + this.lightB.direction = new Vector3D(-1, 0, 1); + this.lightB.ambient = 0; + this.lightB.ambientColor = 0xFFFFFF; + this.lightB.diffuse = 1; + this.lightB.specular = 1; + this.view.scene.addChild(this.light); + this.view.scene.addChild(this.lightB); + this.view.backgroundColor = 0x222222; + AssetLibrary.enableParser(OBJParser); + this.token = AssetLibrary.load(new URLRequest('assets/platonic.obj')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this.token = AssetLibrary.load(new URLRequest('assets/dots.png')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + window.onresize = function (event) { return _this.onResize(event); }; + document.onmousedown = function (event) { return _this.onMouseDown(event); }; + } + MaterialAlphaTest.prototype.onMouseDown = function (event) { + this.cubeColorMaterial.alpha = this.torusTextureMaterial.alpha = this.loadedMeshMaterial.alpha = this.aValues[this.aValuesP]; + alert('Alpha: ' + this.aValues[this.aValuesP]); + this.aValuesP++; + if (this.aValuesP > this.aValues.length - 1) + this.aValuesP = 0; + }; + MaterialAlphaTest.prototype.render = function (dt) { + if (this.meshes) + for (var c = 0; c < this.meshes.length; c++) + this.meshes[c].rotationY += .35; + this.view.render(); + }; + MaterialAlphaTest.prototype.onResourceComplete = function (event) { + var loader = event.target; + var l = loader.baseDependency.assets.length; + for (var c = 0; c < l; c++) { + var d = loader.baseDependency.assets[c]; + console.log(d.name); + switch (d.assetType) { + case AssetType.MESH: + var mesh = d; + this.loadedMesh = mesh; + if (d.name == 'Mesh_g0') { + this.loadedMesh = mesh; + mesh.y = -400; + mesh.transform.scale = new Vector3D(5, 5, 5); + } + else { + mesh.transform.scale = new Vector3D(3.5, 3.5, 3.5); + } + if (this.loadedMeshMaterial) + mesh.material = this.loadedMeshMaterial; + this.view.scene.addChild(mesh); + this.meshes.push(mesh); + this.raf.start(); + break; + case AssetType.TEXTURE: + // Loaded Texture + var tx = d; + // Light Picker + this.staticLightPicker = new StaticLightPicker([this.light, this.lightB]); + // Material for loaded mesh + this.loadedMeshMaterial = new TriangleMethodMaterial(tx, true, true, false); + this.loadedMeshMaterial.lightPicker = this.staticLightPicker; + this.loadedMeshMaterial.alpha = 1; + this.loadedMeshMaterial.bothSides = true; + if (this.loadedMesh) + this.loadedMesh.material = this.loadedMeshMaterial; + // Torus + var torus = new PrimitiveTorusPrefab(150, 50, 64, 64); + // Torus Texture Material + this.torusTextureMaterial = new TriangleMethodMaterial(tx, true, true, false); + this.torusTextureMaterial.lightPicker = this.staticLightPicker; + this.torusTextureMaterial.bothSides = true; + this.torusTextureMaterial.alpha = .8; + torus.material = this.torusTextureMaterial; + // Torus Mesh ( left ) + var torusMesh = torus.getNewObject(); + torusMesh.rotationX = 90; + torusMesh.x = 600; + this.meshes.push(torusMesh); + this.view.scene.addChild(torusMesh); + var cube = new PrimitiveCubePrefab(300, 300, 300, 20, 20, 20); + // Torus Color Material + this.cubeColorMaterial = new TriangleMethodMaterial(0x0090ff); + this.cubeColorMaterial.lightPicker = this.staticLightPicker; + this.cubeColorMaterial.alpha = .8; + this.cubeColorMaterial.bothSides = true; + cube.material = this.cubeColorMaterial; + // Torus Mesh ( right ) + var cubeMesh = cube.getNewObject(); + cubeMesh.rotationX = 90; + cubeMesh.x = -600; + this.meshes.push(cubeMesh); + this.view.scene.addChild(cubeMesh); + this.capsuleColorMaterial = new TriangleMethodMaterial(0x00ffff); + this.capsuleColorMaterial.lightPicker = this.staticLightPicker; + var capsule = new PrimitiveCapsulePrefab(100, 200); + capsule.material = this.capsuleColorMaterial; + // Torus Mesh ( right ) + var capsuleMesh = capsule.getNewObject(); + this.meshes.push(capsuleMesh); + this.view.scene.addChild(capsuleMesh); + this.cubeColorMaterial.alpha = this.torusTextureMaterial.alpha = this.loadedMeshMaterial.alpha = 1; + break; + } + } + }; + MaterialAlphaTest.prototype.onResize = function (event) { + if (event === void 0) { event = null; } + this.view.y = 0; + this.view.x = 0; + this.view.width = window.innerWidth; + this.view.height = window.innerHeight; + }; + return MaterialAlphaTest; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tYXRlcmlhbGFscGhhdGVzdC50cyJdLCJuYW1lcyI6WyJNYXRlcmlhbEFscGhhVGVzdCIsIk1hdGVyaWFsQWxwaGFUZXN0LmNvbnN0cnVjdG9yIiwiTWF0ZXJpYWxBbHBoYVRlc3Qub25Nb3VzZURvd24iLCJNYXRlcmlhbEFscGhhVGVzdC5yZW5kZXIiLCJNYXRlcmlhbEFscGhhVGVzdC5vblJlc291cmNlQ29tcGxldGUiLCJNYXRlcmlhbEFscGhhVGVzdC5vblJlc2l6ZSJdLCJtYXBwaW5ncyI6IkFBQ0EsSUFBTyxJQUFJLFdBQWlCLGlDQUFpQyxDQUFDLENBQUM7QUFFL0QsSUFBTyxRQUFRLFdBQWdCLG9DQUFvQyxDQUFDLENBQUM7QUFDckUsSUFBTyxZQUFZLFdBQWUsMkNBQTJDLENBQUMsQ0FBQztBQUcvRSxJQUFPLFNBQVMsV0FBZSx3Q0FBd0MsQ0FBQyxDQUFDO0FBSXpFLElBQU8sVUFBVSxXQUFlLHFDQUFxQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxnQkFBZ0IsV0FBYywyQ0FBMkMsQ0FBQyxDQUFDO0FBRWxGLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxpQkFBaUIsV0FBYSwwREFBMEQsQ0FBQyxDQUFDO0FBQ2pHLElBQU8sb0JBQW9CLFdBQWEsOENBQThDLENBQUMsQ0FBQztBQUN4RixJQUFPLG1CQUFtQixXQUFhLDZDQUE2QyxDQUFDLENBQUM7QUFDdEYsSUFBTyxzQkFBc0IsV0FBWSxnREFBZ0QsQ0FBQyxDQUFDO0FBRzNGLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBQ3RGLElBQU8sc0JBQXNCLFdBQVkscURBQXFELENBQUMsQ0FBQztBQUVoRyxJQUFPLFNBQVMsV0FBZSx5Q0FBeUMsQ0FBQyxDQUFDO0FBRTFFLElBQU0saUJBQWlCO0lBc0J0QkEsU0F0QktBLGlCQUFpQkE7UUFBdkJDLGlCQW9NQ0E7UUFqTVFBLFdBQU1BLEdBQVlBLENBQUNBLENBQUNBO1FBS3BCQSxXQUFNQSxHQUFrQkEsSUFBSUEsS0FBS0EsRUFBUUEsQ0FBQ0E7UUFNMUNBLFlBQU9BLEdBQWlCQSxLQUFLQSxDQUFTQSxDQUFDQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxFQUFFQSxHQUFHQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNqRUEsYUFBUUEsR0FBVUEsQ0FBQ0EsQ0FBQ0E7UUFTM0JBLEtBQUtBLENBQUNBLGFBQWFBLEdBQUdBLEtBQUtBLENBQUNBO1FBQzVCQSxLQUFLQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUUzQkEsSUFBSUEsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsSUFBSUEsQ0FBQ0EsSUFBSUEsZUFBZUEsRUFBRUEsQ0FBQ0EsQ0FBQ0E7UUFDNUNBLElBQUlBLENBQUNBLEdBQUdBLEdBQUdBLElBQUlBLHFCQUFxQkEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsRUFBRUEsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDeERBLElBQUlBLENBQUNBLFFBQVFBLEVBQUVBLENBQUNBO1FBRWhCQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxnQkFBZ0JBLEVBQUVBLENBQUNBO1FBQ3BDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUM1QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDN0NBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE9BQU9BLEdBQUdBLENBQUNBLENBQUNBO1FBQ3ZCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxZQUFZQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUNuQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDdkJBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLEdBQUdBLENBQUNBLENBQUNBO1FBRXhCQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxJQUFJQSxnQkFBZ0JBLEVBQUVBLENBQUNBO1FBQ3JDQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxLQUFLQSxHQUFFQSxRQUFRQSxDQUFDQTtRQUM1QkEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsU0FBU0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDL0NBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLE9BQU9BLEdBQUdBLENBQUNBLENBQUNBO1FBQ3hCQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxZQUFZQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUNwQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsT0FBT0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFDeEJBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLFFBQVFBLEdBQUdBLENBQUNBLENBQUNBO1FBRXpCQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0E7UUFFdENBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLGVBQWVBLEdBQUdBLFFBQVFBLENBQUNBO1FBRXJDQSxZQUFZQSxDQUFDQSxZQUFZQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUVyQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsWUFBWUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsVUFBVUEsQ0FBQ0EscUJBQXFCQSxDQUFDQSxD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QSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQTtvQkFDOUJBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBO29CQUV0Q0EsSUFBSUEsQ0FBQ0EsaUJBQWlCQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQSxvQkFBb0JBLENBQUNBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBLGtCQUFrQkEsQ0FBQ0EsS0FBS0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBRW5HQSxLQUFLQSxDQUFDQTtZQUNSQSxDQUFDQTtRQUNGQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVNSixvQ0FBUUEsR0FBZkEsVUFBZ0JBLEtBQW9CQTtRQUFwQksscUJBQW9CQSxHQUFwQkEsWUFBb0JBO1FBRW5DQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUNoQkEsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFFaEJBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLE1BQU1BLENBQUNBLFVBQVVBLENBQUNBO1FBQ3BDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxNQUFNQSxDQUFDQSxXQUFXQSxDQUFDQTtJQUN2Q0EsQ0FBQ0E7SUFDRkwsd0JBQUNBO0FBQURBLENBcE1BLEFBb01DQSxJQUFBIiwiZmlsZSI6Im1hdGVyaWFscy9NYXRlcmlhbEFscGhhVGVzdC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBTY2VuZVx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL1NjZW5lXCIpO1xuaW1wb3J0IFZpZXdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL1ZpZXdcIik7XG5pbXBvcnQgQmxlbmRNb2RlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvQmxlbmRNb2RlXCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBBc3NldExpYnJhcnlcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExpYnJhcnlcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclwiKTtcbmltcG9ydCBBc3NldExvYWRlclRva2VuXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TG9hZGVyVG9rZW5cIik7XG5pbXBvcnQgQXNzZXRUeXBlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IFVSTExvYWRlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMTG9hZGVyXCIpO1xuaW1wb3J0IFVSTExvYWRlckRhdGFGb3JtYXRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMTG9hZGVyRGF0YUZvcm1hdFwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IERpcmVjdGlvbmFsTGlnaHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9EaXJlY3Rpb25hbExpZ2h0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IExvYWRlckV2ZW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvTG9hZGVyRXZlbnRcIik7XG5pbXBvcnQgU3RhdGljTGlnaHRQaWNrZXJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvbWF0ZXJpYWxzL2xpZ2h0cGlja2Vycy9TdGF0aWNMaWdodFBpY2tlclwiKTtcbmltcG9ydCBQcmltaXRpdmVUb3J1c1ByZWZhYlx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZVRvcnVzUHJlZmFiXCIpO1xuaW1wb3J0IFByaW1pdGl2ZUN1YmVQcmVmYWJcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJlZmFicy9QcmltaXRpdmVDdWJlUHJlZmFiXCIpO1xuaW1wb3J0IFByaW1pdGl2ZUNhcHN1bGVQcmVmYWJcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3ByZWZhYnMvUHJpbWl0aXZlQ2Fwc3VsZVByZWZhYlwiKTtcbmltcG9ydCBQZXJzcGVjdGl2ZVByb2plY3Rpb25cdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3Byb2plY3Rpb25zL1BlcnNwZWN0aXZlUHJvamVjdGlvblwiKTtcbmltcG9ydCBJbWFnZVRleHR1cmVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL0ltYWdlVGV4dHVyZVwiKTtcbmltcG9ydCBEZWJ1Z1x0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9EZWJ1Z1wiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcbmltcG9ydCBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsXHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvVHJpYW5nbGVNZXRob2RNYXRlcmlhbFwiKTtcblxuaW1wb3J0IE9CSlBhcnNlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9PQkpQYXJzZXJcIik7XG5cbmNsYXNzIE1hdGVyaWFsQWxwaGFUZXN0XG57XG5cblx0cHJpdmF0ZSBoZWlnaHQgOiBudW1iZXIgPSAwO1xuXG5cdHByaXZhdGUgdG9rZW46QXNzZXRMb2FkZXJUb2tlbjtcblx0cHJpdmF0ZSB2aWV3OlZpZXc7XG5cdHByaXZhdGUgcmFmOlJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0cHJpdmF0ZSBtZXNoZXMgIDogQXJyYXk8TWVzaD4gPSBuZXcgQXJyYXk8TWVzaD4oKTtcblx0cHJpdmF0ZSBsb2FkZWRNZXNoTWF0ZXJpYWw6VHJpYW5nbGVNZXRob2RNYXRlcmlhbDtcblx0cHJpdmF0ZSBsaWdodDpEaXJlY3Rpb25hbExpZ2h0O1xuXHRwcml2YXRlIGxpZ2h0QjpEaXJlY3Rpb25hbExpZ2h0O1xuXHRwcml2YXRlIGxvYWRlZE1lc2g6TWVzaDtcblxuXHRwcml2YXRlIGFWYWx1ZXM6QXJyYXk8bnVtYmVyPiA9IEFycmF5PG51bWJlcj4oMCwgLjEsIC41LCAuOCwgLjksIC45OSwgMSk7XG5cdHByaXZhdGUgYVZhbHVlc1A6bnVtYmVyID0gMDtcblxuXHRwcml2YXRlIHRvcnVzVGV4dHVyZU1hdGVyaWFsOlRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWw7XG5cdHByaXZhdGUgY3ViZUNvbG9yTWF0ZXJpYWw6VHJpYW5nbGVNZXRob2RNYXRlcmlhbDtcblx0cHJpdmF0ZSBjYXBzdWxlQ29sb3JNYXRlcmlhbDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXHRwcml2YXRlIHN0YXRpY0xpZ2h0UGlja2VyOlN0YXRpY0xpZ2h0UGlja2VyO1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdERlYnVnLkxPR19QSV9FUlJPUlMgPSBmYWxzZTtcblx0XHREZWJ1Zy5USFJPV19FUlJPUlMgPSBmYWxzZTtcblxuXHRcdHRoaXMudmlldyA9IG5ldyBWaWV3KG5ldyBEZWZhdWx0UmVuZGVyZXIoKSk7XG5cdFx0dGhpcy5yYWYgPSBuZXcgUmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLCB0aGlzKTtcblx0XHR0aGlzLm9uUmVzaXplKCk7XG5cblx0XHR0aGlzLmxpZ2h0ID0gbmV3IERpcmVjdGlvbmFsTGlnaHQoKTtcblx0XHR0aGlzLmxpZ2h0LmNvbG9yID0gMHhGRkZGRkY7XG5cdFx0dGhpcy5saWdodC5kaXJlY3Rpb24gPSBuZXcgVmVjdG9yM0QoMSwgMSwgMCk7XG5cdFx0dGhpcy5saWdodC5hbWJpZW50ID0gMDtcblx0XHR0aGlzLmxpZ2h0LmFtYmllbnRDb2xvciA9IDB4RkZGRkZGO1xuXHRcdHRoaXMubGlnaHQuZGlmZnVzZSA9IDE7XG5cdFx0dGhpcy5saWdodC5zcGVjdWxhciA9IDE7XG5cblx0XHR0aGlzLmxpZ2h0QiA9IG5ldyBEaXJlY3Rpb25hbExpZ2h0KCk7XG5cdFx0dGhpcy5saWdodEIuY29sb3I9IDB4RkYwMDAwO1xuXHRcdHRoaXMubGlnaHRCLmRpcmVjdGlvbiA9IG5ldyBWZWN0b3IzRCgtMSwgMCwgMSk7XG5cdFx0dGhpcy5saWdodEIuYW1iaWVudCA9IDA7XG5cdFx0dGhpcy5saWdodEIuYW1iaWVudENvbG9yID0gMHhGRkZGRkY7XG5cdFx0dGhpcy5saWdodEIuZGlmZnVzZSA9IDE7XG5cdFx0dGhpcy5saWdodEIuc3BlY3VsYXIgPSAxO1xuXG5cdFx0dGhpcy52aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMubGlnaHQpO1xuXHRcdHRoaXMudmlldy5zY2VuZS5hZGRDaGlsZCh0aGlzLmxpZ2h0Qik7XG5cblx0XHR0aGlzLnZpZXcuYmFja2dyb3VuZENvbG9yID0gMHgyMjIyMjI7XG5cblx0XHRBc3NldExpYnJhcnkuZW5hYmxlUGFyc2VyKE9CSlBhcnNlcik7XG5cblx0XHR0aGlzLnRva2VuID0gQXNzZXRMaWJyYXJ5LmxvYWQobmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy9wbGF0b25pYy5vYmonKSk7XG5cdFx0dGhpcy50b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFICwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXG5cdFx0dGhpcy50b2tlbiA9IEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KCdhc3NldHMvZG90cy5wbmcnKSApO1xuXHRcdHRoaXMudG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXG5cdFx0d2luZG93Lm9ucmVzaXplID0gKGV2ZW50OlVJRXZlbnQpID0+IHRoaXMub25SZXNpemUoZXZlbnQpO1xuXHRcdGRvY3VtZW50Lm9ubW91c2Vkb3duID0gKGV2ZW50Ok1vdXNlRXZlbnQpID0+IHRoaXMub25Nb3VzZURvd24oZXZlbnQpO1xuXHR9XG5cblx0cHJpdmF0ZSBvbk1vdXNlRG93bihldmVudDpNb3VzZUV2ZW50KVxuXHR7XG5cdFx0dGhpcy5jdWJlQ29sb3JNYXRlcmlhbC5hbHBoYSA9IHRoaXMudG9ydXNUZXh0dXJlTWF0ZXJpYWwuYWxwaGEgPSB0aGlzLmxvYWRlZE1lc2hNYXRlcmlhbC5hbHBoYSA9IHRoaXMuYVZhbHVlc1t0aGlzLmFWYWx1ZXNQXTtcblxuXHRcdGFsZXJ0KCAnQWxwaGE6ICcgKyB0aGlzLmFWYWx1ZXNbdGhpcy5hVmFsdWVzUF0pO1xuXG5cdFx0dGhpcy5hVmFsdWVzUCsrO1xuXG5cdFx0aWYgKHRoaXMuYVZhbHVlc1AgPiB0aGlzLmFWYWx1ZXMubGVuZ3RoIC0xKVxuXHRcdFx0dGhpcy5hVmFsdWVzUCAgPSAwO1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKVxuXHR7XG5cdFx0aWYgKHRoaXMubWVzaGVzKVxuXHRcdFx0Zm9yICh2YXIgYzpudW1iZXIgPSAwOyBjIDwgdGhpcy5tZXNoZXMubGVuZ3RoOyBjKyspXG5cdFx0XHRcdHRoaXMubWVzaGVzW2NdLnJvdGF0aW9uWSArPSAuMzU7XG5cblx0XHR0aGlzLnZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgb25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50OkxvYWRlckV2ZW50KVxuXHR7XG5cdFx0dmFyIGxvYWRlcjpBc3NldExvYWRlciA9IDxBc3NldExvYWRlcj4gZXZlbnQudGFyZ2V0O1xuXHRcdHZhciBsOm51bWJlciA9IGxvYWRlci5iYXNlRGVwZW5kZW5jeS5hc3NldHMubGVuZ3RoXG5cblx0XHRmb3IgKHZhciBjOm51bWJlciA9IDA7IGMgPCBsOyBjICsrKSB7XG5cblx0XHRcdHZhciBkOklBc3NldCA9IGxvYWRlci5iYXNlRGVwZW5kZW5jeS5hc3NldHNbY107XG5cblx0XHRcdGNvbnNvbGUubG9nKCBkLm5hbWUpO1xuXG5cdFx0XHRzd2l0Y2ggKGQuYXNzZXRUeXBlKSB7XG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLk1FU0g6XG5cdFx0XHRcdFx0dmFyIG1lc2g6TWVzaCA9IDxNZXNoPiBkO1xuXG5cdFx0XHRcdFx0dGhpcy5sb2FkZWRNZXNoID0gbWVzaDtcblxuXHRcdFx0XHRcdGlmIChkLm5hbWUgPT0gJ01lc2hfZzAnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvYWRlZE1lc2ggPSBtZXNoO1xuXHRcdFx0XHRcdFx0bWVzaC55ID0gLTQwMDtcblx0XHRcdFx0XHRcdG1lc2gudHJhbnNmb3JtLnNjYWxlID0gbmV3IFZlY3RvcjNEKDUsIDUsIDUpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRtZXNoLnRyYW5zZm9ybS5zY2FsZSA9IG5ldyBWZWN0b3IzRCgzLjUsIDMuNSwgMy41KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAodGhpcy5sb2FkZWRNZXNoTWF0ZXJpYWwpXG5cdFx0XHRcdFx0XHRtZXNoLm1hdGVyaWFsID0gdGhpcy5sb2FkZWRNZXNoTWF0ZXJpYWw7XG5cblx0XHRcdFx0XHR0aGlzLnZpZXcuc2NlbmUuYWRkQ2hpbGQobWVzaCk7XG5cdFx0XHRcdFx0dGhpcy5tZXNoZXMucHVzaChtZXNoKTtcblxuXHRcdFx0XHRcdHRoaXMucmFmLnN0YXJ0KCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLlRFWFRVUkU6XG5cdFx0XHRcdFx0Ly8gTG9hZGVkIFRleHR1cmVcblx0XHRcdFx0XHR2YXIgdHg6SW1hZ2VUZXh0dXJlID0gPEltYWdlVGV4dHVyZT4gZDtcblxuXHRcdFx0XHRcdC8vIExpZ2h0IFBpY2tlclxuXHRcdFx0XHRcdHRoaXMuc3RhdGljTGlnaHRQaWNrZXIgPSBuZXcgU3RhdGljTGlnaHRQaWNrZXIoIFt0aGlzLmxpZ2h0ICwgdGhpcy5saWdodEIgXSApO1xuXG5cdFx0XHRcdFx0Ly8gTWF0ZXJpYWwgZm9yIGxvYWRlZCBtZXNoXG5cdFx0XHRcdFx0dGhpcy5sb2FkZWRNZXNoTWF0ZXJpYWwgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbCggdHgsIHRydWUsIHRydWUsIGZhbHNlICk7XG5cdFx0XHRcdFx0dGhpcy5sb2FkZWRNZXNoTWF0ZXJpYWwubGlnaHRQaWNrZXIgPSB0aGlzLnN0YXRpY0xpZ2h0UGlja2VyO1xuXHRcdFx0XHRcdHRoaXMubG9hZGVkTWVzaE1hdGVyaWFsLmFscGhhID0gMTtcblx0XHRcdFx0XHR0aGlzLmxvYWRlZE1lc2hNYXRlcmlhbC5ib3RoU2lkZXMgPSB0cnVlO1xuXG5cdFx0XHRcdFx0aWYgKHRoaXMubG9hZGVkTWVzaClcblx0XHRcdFx0XHRcdHRoaXMubG9hZGVkTWVzaC5tYXRlcmlhbCA9IHRoaXMubG9hZGVkTWVzaE1hdGVyaWFsO1xuXG5cdFx0XHRcdFx0Ly8gVG9ydXNcblx0XHRcdFx0XHR2YXIgdG9ydXM6UHJpbWl0aXZlVG9ydXNQcmVmYWIgPSBuZXcgUHJpbWl0aXZlVG9ydXNQcmVmYWIoMTUwICwgNTAgLCA2NCAsIDY0KTtcblxuXHRcdFx0XHRcdC8vIFRvcnVzIFRleHR1cmUgTWF0ZXJpYWxcblx0XHRcdFx0XHR0aGlzLnRvcnVzVGV4dHVyZU1hdGVyaWFsID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwodHgsIHRydWUsIHRydWUsIGZhbHNlKTtcblx0XHRcdFx0XHR0aGlzLnRvcnVzVGV4dHVyZU1hdGVyaWFsLmxpZ2h0UGlja2VyID0gdGhpcy5zdGF0aWNMaWdodFBpY2tlciA7XG5cdFx0XHRcdFx0dGhpcy50b3J1c1RleHR1cmVNYXRlcmlhbC5ib3RoU2lkZXMgPSB0cnVlO1xuXHRcdFx0XHRcdHRoaXMudG9ydXNUZXh0dXJlTWF0ZXJpYWwuYWxwaGEgPSAuODtcblxuXHRcdFx0XHRcdHRvcnVzLm1hdGVyaWFsID0gdGhpcy50b3J1c1RleHR1cmVNYXRlcmlhbDtcblxuXHRcdFx0XHRcdC8vIFRvcnVzIE1lc2ggKCBsZWZ0IClcblx0XHRcdFx0XHR2YXIgdG9ydXNNZXNoOk1lc2ggPSA8TWVzaD4gdG9ydXMuZ2V0TmV3T2JqZWN0KCk7XG5cdFx0XHRcdFx0dG9ydXNNZXNoLnJvdGF0aW9uWCA9IDkwO1xuXHRcdFx0XHRcdHRvcnVzTWVzaC54ID0gNjAwO1xuXHRcdFx0XHRcdHRoaXMubWVzaGVzLnB1c2godG9ydXNNZXNoKTtcblx0XHRcdFx0XHR0aGlzLnZpZXcuc2NlbmUuYWRkQ2hpbGQodG9ydXNNZXNoKTtcblxuXHRcdFx0XHRcdHZhciBjdWJlOlByaW1pdGl2ZUN1YmVQcmVmYWIgPSBuZXcgUHJpbWl0aXZlQ3ViZVByZWZhYigzMDAsIDMwMCwgMzAwLCAyMCwgMjAsIDIwKTtcblxuXHRcdFx0XHRcdC8vIFRvcnVzIENvbG9yIE1hdGVyaWFsXG5cdFx0XHRcdFx0dGhpcy5jdWJlQ29sb3JNYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKDB4MDA5MGZmKTtcblx0XHRcdFx0XHR0aGlzLmN1YmVDb2xvck1hdGVyaWFsLmxpZ2h0UGlja2VyID0gdGhpcy5zdGF0aWNMaWdodFBpY2tlciA7XG5cdFx0XHRcdFx0dGhpcy5jdWJlQ29sb3JNYXRlcmlhbC5hbHBoYSA9IC44O1xuXHRcdFx0XHRcdHRoaXMuY3ViZUNvbG9yTWF0ZXJpYWwuYm90aFNpZGVzID0gdHJ1ZTtcblxuXHRcdFx0XHRcdGN1YmUubWF0ZXJpYWwgPSB0aGlzLmN1YmVDb2xvck1hdGVyaWFsO1xuXG5cdFx0XHRcdFx0Ly8gVG9ydXMgTWVzaCAoIHJpZ2h0IClcblx0XHRcdFx0XHR2YXIgY3ViZU1lc2g6TWVzaCA9IDxNZXNoPiBjdWJlLmdldE5ld09iamVjdCgpO1xuXHRcdFx0XHRcdGN1YmVNZXNoLnJvdGF0aW9uWCA9IDkwO1xuXHRcdFx0XHRcdGN1YmVNZXNoLnggPSAtNjAwO1xuXHRcdFx0XHRcdHRoaXMubWVzaGVzLnB1c2goY3ViZU1lc2gpO1xuXHRcdFx0XHRcdHRoaXMudmlldy5zY2VuZS5hZGRDaGlsZChjdWJlTWVzaCk7XG5cblx0XHRcdFx0XHR0aGlzLmNhcHN1bGVDb2xvck1hdGVyaWFsID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwoMHgwMGZmZmYpO1xuXHRcdFx0XHRcdHRoaXMuY2Fwc3VsZUNvbG9yTWF0ZXJpYWwubGlnaHRQaWNrZXIgPSB0aGlzLnN0YXRpY0xpZ2h0UGlja2VyO1xuXG5cdFx0XHRcdFx0dmFyIGNhcHN1bGU6UHJpbWl0aXZlQ2Fwc3VsZVByZWZhYiA9IG5ldyBQcmltaXRpdmVDYXBzdWxlUHJlZmFiKDEwMCwgMjAwKTtcblxuXHRcdFx0XHRcdGNhcHN1bGUubWF0ZXJpYWwgPSB0aGlzLmNhcHN1bGVDb2xvck1hdGVyaWFsO1xuXG5cdFx0XHRcdFx0Ly8gVG9ydXMgTWVzaCAoIHJpZ2h0IClcblx0XHRcdFx0XHR2YXIgY2Fwc3VsZU1lc2g6TWVzaCA9IDxNZXNoPiBjYXBzdWxlLmdldE5ld09iamVjdCgpO1xuXHRcdFx0XHRcdHRoaXMubWVzaGVzLnB1c2goY2Fwc3VsZU1lc2gpO1xuXHRcdFx0XHRcdHRoaXMudmlldy5zY2VuZS5hZGRDaGlsZChjYXBzdWxlTWVzaCk7XG5cblx0XHRcdFx0XHR0aGlzLmN1YmVDb2xvck1hdGVyaWFsLmFscGhhID0gdGhpcy50b3J1c1RleHR1cmVNYXRlcmlhbC5hbHBoYSA9IHRoaXMubG9hZGVkTWVzaE1hdGVyaWFsLmFscGhhID0gMTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBvblJlc2l6ZShldmVudDpVSUV2ZW50ID0gbnVsbClcblx0e1xuXHRcdHRoaXMudmlldy55ID0gMDtcblx0XHR0aGlzLnZpZXcueCA9IDA7XG5cblx0XHR0aGlzLnZpZXcud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcblx0XHR0aGlzLnZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG59Il19 \ No newline at end of file diff --git a/tests/materials/MaterialEnvMapTest.js b/tests/materials/MaterialEnvMapTest.js new file mode 100755 index 000000000..cc0ef05cf --- /dev/null +++ b/tests/materials/MaterialEnvMapTest.js @@ -0,0 +1,75 @@ +var View = require("awayjs-core/lib/containers/View"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var AssetEvent = require("awayjs-core/lib/events/AssetEvent"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +/** + * + */ +var MaterialEnvMapTest = (function () { + function MaterialEnvMapTest() { + var _this = this; + Debug.LOG_PI_ERRORS = true; + Debug.THROW_ERRORS = false; + AssetLibrary.enableParser(AWDParser); + this._token = AssetLibrary.load(new URLRequest('assets/EnvMapTest.awd')); + this._token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this._token.addEventListener(AssetEvent.ASSET_COMPLETE, function (event) { return _this.onAssetComplete(event); }); + this._view = new View(new DefaultRenderer()); + this._timer = new RequestAnimationFrame(this.render, this); + window.onresize = function () { return _this.resize(); }; + this._timer.start(); + this.resize(); + } + MaterialEnvMapTest.prototype.resize = function (event) { + if (event === void 0) { event = null; } + this._view.y = 0; + this._view.x = 0; + this._view.width = window.innerWidth; + this._view.height = window.innerHeight; + }; + MaterialEnvMapTest.prototype.render = function (dt) { + if (this._torus) + this._torus.rotationY += 1; + this._view.render(); + this._view.camera.z = -2000; + }; + MaterialEnvMapTest.prototype.onAssetComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('away.events.AssetEvent.ASSET_COMPLETE', AssetLibrary.getAsset(event.asset.name)); + console.log('------------------------------------------------------------------------------'); + }; + MaterialEnvMapTest.prototype.onResourceComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('away.events.LoaderEvent.RESOURCE_COMPLETE', event); + console.log('------------------------------------------------------------------------------'); + var loader = event.target; + var numAssets = loader.baseDependency.assets.length; + for (var i = 0; i < numAssets; ++i) { + var asset = loader.baseDependency.assets[i]; + console.log(asset.assetType); + switch (asset.assetType) { + case AssetType.SKYBOX: + var skybox = asset; + this._view.scene.addChild(skybox); + break; + case AssetType.MESH: + this._torus = asset; + this._view.scene.addChild(this._torus); + break; + case AssetType.GEOMETRY: + break; + case AssetType.MATERIAL: + break; + } + } + }; + return MaterialEnvMapTest; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1hdGVyaWFscy9tYXRlcmlhbGVudm1hcHRlc3QudHMiXSwibmFtZXMiOlsiTWF0ZXJpYWxFbnZNYXBUZXN0IiwiTWF0ZXJpYWxFbnZNYXBUZXN0LmNvbnN0cnVjdG9yIiwiTWF0ZXJpYWxFbnZNYXBUZXN0LnJlc2l6ZSIsIk1hdGVyaWFsRW52TWFwVGVzdC5yZW5kZXIiLCJNYXRlcmlhbEVudk1hcFRlc3Qub25Bc3NldENvbXBsZXRlIiwiTWF0ZXJpYWxFbnZNYXBUZXN0Lm9uUmVzb3VyY2VDb21wbGV0ZSJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTyxJQUFJLFdBQWlCLGlDQUFpQyxDQUFDLENBQUM7QUFFL0QsSUFBTyxZQUFZLFdBQWUsMkNBQTJDLENBQUMsQ0FBQztBQUcvRSxJQUFPLFNBQVMsV0FBZSx3Q0FBd0MsQ0FBQyxDQUFDO0FBRXpFLElBQU8sVUFBVSxXQUFlLHFDQUFxQyxDQUFDLENBQUM7QUFHdkUsSUFBTyxVQUFVLFdBQWUsbUNBQW1DLENBQUMsQ0FBQztBQUNyRSxJQUFPLFdBQVcsV0FBZSxvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3ZFLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBRXRGLElBQU8sU0FBUyxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFFMUUsQUFHQTs7R0FERztJQUNHLGtCQUFrQjtJQU92QkEsU0FQS0Esa0JBQWtCQTtRQUF4QkMsaUJBd0ZDQTtRQS9FQ0EsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsSUFBSUEsQ0FBQ0E7UUFDM0JBLEtBQUtBLENBQUNBLFlBQVlBLEdBQUdBLEtBQUtBLENBQUNBO1FBRTNCQSxZQUFZQSxDQUFDQSxZQUFZQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFFQTtRQUV0Q0EsSUFBSUEsQ0FBQ0EsTUFBTUEsR0FBR0EsWUFBWUEsQ0FBQ0EsSUFBSUEs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QUNBO0FBQURBLENBeEZBLEFBd0ZDQSxJQUFBIiwiZmlsZSI6Im1hdGVyaWFscy9NYXRlcmlhbEVudk1hcFRlc3QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQXNzZXRMaWJyYXJ5XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMaWJyYXJ5XCIpO1xuaW1wb3J0IEFzc2V0TG9hZGVyXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMb2FkZXJcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJUb2tlblx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclRva2VuXCIpO1xuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0VHlwZVwiKTtcbmltcG9ydCBJQXNzZXRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0lBc3NldFwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IFNreWJveFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9Ta3lib3hcIik7XG5pbXBvcnQgQXNzZXRFdmVudFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZXZlbnRzL0Fzc2V0RXZlbnRcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBEZWJ1Z1x0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9EZWJ1Z1wiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcblxuaW1wb3J0IEFXRFBhcnNlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9BV0RQYXJzZXJcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgTWF0ZXJpYWxFbnZNYXBUZXN0XG57XG5cdHByaXZhdGUgX3ZpZXc6Vmlldztcblx0cHJpdmF0ZSBfdG9rZW46QXNzZXRMb2FkZXJUb2tlbjtcblx0cHJpdmF0ZSBfdGltZXI6UmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuXHRwcml2YXRlIF90b3J1czpNZXNoO1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdERlYnVnLkxPR19QSV9FUlJPUlMgPSB0cnVlO1xuXHRcdERlYnVnLlRIUk9XX0VSUk9SUyA9IGZhbHNlO1xuXG5cdFx0QXNzZXRMaWJyYXJ5LmVuYWJsZVBhcnNlcihBV0RQYXJzZXIpIDtcblxuXHRcdHRoaXMuX3Rva2VuID0gQXNzZXRMaWJyYXJ5LmxvYWQobmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy9FbnZNYXBUZXN0LmF3ZCcpKTtcblx0XHR0aGlzLl90b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFLCAoZXZlbnQ6TG9hZGVyRXZlbnQpID0+IHRoaXMub25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50KSk7XG5cdFx0dGhpcy5fdG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihBc3NldEV2ZW50LkFTU0VUX0NPTVBMRVRFLCAoZXZlbnQ6QXNzZXRFdmVudCkgPT4gdGhpcy5vbkFzc2V0Q29tcGxldGUoZXZlbnQpKTtcblxuXHRcdHRoaXMuX3ZpZXcgPSBuZXcgVmlldyhuZXcgRGVmYXVsdFJlbmRlcmVyKCkpO1xuXHRcdHRoaXMuX3RpbWVyID0gbmV3IFJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlciwgdGhpcyk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgPSAoKSA9PiB0aGlzLnJlc2l6ZSgpO1xuXG5cdFx0dGhpcy5fdGltZXIuc3RhcnQoKTtcblx0XHR0aGlzLnJlc2l6ZSgpO1xuXHR9XG5cblx0cHJpdmF0ZSByZXNpemUoZXZlbnQ6VUlFdmVudCA9IG51bGwpXG5cdHtcblx0XHR0aGlzLl92aWV3LnkgPSAwO1xuXHRcdHRoaXMuX3ZpZXcueCA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKSAvL2FuaW1hdGUgYmFzZWQgb24gZHQgZm9yIGZpcmVmb3hcblx0e1xuXHRcdGlmICh0aGlzLl90b3J1cylcblx0XHRcdHRoaXMuX3RvcnVzLnJvdGF0aW9uWSArPSAxO1xuXG5cdFx0dGhpcy5fdmlldy5yZW5kZXIoKTtcblx0XHR0aGlzLl92aWV3LmNhbWVyYS56ID0gLTIwMDA7XG5cdH1cblxuXHRwdWJsaWMgb25Bc3NldENvbXBsZXRlKGV2ZW50OkFzc2V0RXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2F3YXkuZXZlbnRzLkFzc2V0RXZlbnQuQVNTRVRfQ09NUExFVEUnLCBBc3NldExpYnJhcnkuZ2V0QXNzZXQoZXZlbnQuYXNzZXQubmFtZSkpO1xuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblx0fVxuXG5cdHB1YmxpYyBvblJlc291cmNlQ29tcGxldGUoZXZlbnQ6TG9hZGVyRXZlbnQpXG5cdHtcblxuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblx0XHRjb25zb2xlLmxvZygnYXdheS5ldmVudHMuTG9hZGVyRXZlbnQuUkVTT1VSQ0VfQ09NUExFVEUnLCBldmVudCk7XG5cdFx0Y29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuXG5cdFx0dmFyIGxvYWRlcjpBc3NldExvYWRlciA9IDxBc3NldExvYWRlcj4gZXZlbnQudGFyZ2V0O1xuXHRcdHZhciBudW1Bc3NldHM6bnVtYmVyID0gbG9hZGVyLmJhc2VEZXBlbmRlbmN5LmFzc2V0cy5sZW5ndGg7XG5cblx0XHRmb3IgKHZhciBpOm51bWJlciA9IDA7IGkgPCBudW1Bc3NldHM7ICsraSkge1xuXHRcdFx0dmFyIGFzc2V0OklBc3NldCA9IGxvYWRlci5iYXNlRGVwZW5kZW5jeS5hc3NldHNbaV07XG5cblx0XHRcdGNvbnNvbGUubG9nKGFzc2V0LmFzc2V0VHlwZSk7XG5cblx0XHRcdHN3aXRjaCAoYXNzZXQuYXNzZXRUeXBlKSB7XG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLlNLWUJPWDpcblxuXHRcdFx0XHRcdHZhciBza3lib3g6U2t5Ym94ID0gPFNreWJveD4gYXNzZXQ7XG5cdFx0XHRcdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZChza3lib3gpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLk1FU0g6XG5cblx0XHRcdFx0XHR0aGlzLl90b3J1cyA9IDxNZXNoPiBhc3NldDtcblx0XHRcdFx0XHR0aGlzLl92aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMuX3RvcnVzKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLkdFT01FVFJZOlxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQXNzZXRUeXBlLk1BVEVSSUFMOlxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSJdfQ== \ No newline at end of file diff --git a/tests/parsers/AWDParserTest.js b/tests/parsers/AWDParserTest.js new file mode 100755 index 000000000..dbdfce80d --- /dev/null +++ b/tests/parsers/AWDParserTest.js @@ -0,0 +1,69 @@ +var View = require("awayjs-core/lib/containers/View"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var AssetEvent = require("awayjs-core/lib/events/AssetEvent"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +var AWDParserTest = (function () { + function AWDParserTest() { + var _this = this; + Debug.LOG_PI_ERRORS = true; + Debug.THROW_ERRORS = false; + AssetLibrary.enableParser(AWDParser); + this._token = AssetLibrary.load(new URLRequest('assets/suzanne.awd')); + this._token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this._token.addEventListener(AssetEvent.ASSET_COMPLETE, function (event) { return _this.onAssetComplete(event); }); + this._view = new View(new DefaultRenderer()); + this._timer = new RequestAnimationFrame(this.render, this); + window.onresize = function (event) { return _this.resize(event); }; + this._timer.start(); + this.resize(); + } + AWDParserTest.prototype.resize = function (event) { + if (event === void 0) { event = null; } + this._view.y = 0; + this._view.x = 0; + this._view.width = window.innerWidth; + this._view.height = window.innerHeight; + }; + AWDParserTest.prototype.render = function (dt) { + if (this._suzanne) + this._suzanne.rotationY += 1; + this._view.render(); + this._view.camera.z = -2000; + }; + AWDParserTest.prototype.onAssetComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('events.AssetEvent.ASSET_COMPLETE', AssetLibrary.getAsset(event.asset.name)); + console.log('------------------------------------------------------------------------------'); + }; + AWDParserTest.prototype.onResourceComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('events.LoaderEvent.RESOURCE_COMPLETE', event); + console.log('------------------------------------------------------------------------------'); + var loader = event.target; + var numAssets = loader.baseDependency.assets.length; + for (var i = 0; i < numAssets; ++i) { + var asset = loader.baseDependency.assets[i]; + switch (asset.assetType) { + case AssetType.MESH: + this._suzanne = asset; + this._suzanne.transform.scale = new Vector3D(600, 600, 600); + this._view.scene.addChild(this._suzanne); + break; + case AssetType.GEOMETRY: + break; + case AssetType.MATERIAL: + break; + } + } + }; + return AWDParserTest; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvYXdkcGFyc2VydGVzdC50cyJdLCJuYW1lcyI6WyJBV0RQYXJzZXJUZXN0IiwiQVdEUGFyc2VyVGVzdC5jb25zdHJ1Y3RvciIsIkFXRFBhcnNlclRlc3QucmVzaXplIiwiQVdEUGFyc2VyVGVzdC5yZW5kZXIiLCJBV0RQYXJzZXJUZXN0Lm9uQXNzZXRDb21wbGV0ZSIsIkFXRFBhcnNlclRlc3Qub25SZXNvdXJjZUNvbXBsZXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUMvRCxJQUFPLFFBQVEsV0FBZ0Isb0NBQW9DLENBQUMsQ0FBQztBQUNyRSxJQUFPLFlBQVksV0FBZSwyQ0FBMkMsQ0FBQyxDQUFDO0FBRy9FLElBQU8sU0FBUyxXQUFlLHdDQUF3QyxDQUFDLENBQUM7QUFFekUsSUFBTyxVQUFVLFdBQWUscUNBQXFDLENBQUMsQ0FBQztBQUV2RSxJQUFPLFVBQVUsV0FBZSxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ3JFLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxLQUFLLFdBQWdCLDZCQUE2QixDQUFDLENBQUM7QUFDM0QsSUFBTyxxQkFBcUIsV0FBWSw2Q0FBNkMsQ0FBQyxDQUFDO0FBRXZGLElBQU8sZUFBZSxXQUFjLGdEQUFnRCxDQUFDLENBQUM7QUFHdEYsSUFBTyxTQUFTLFdBQWUseUNBQXlDLENBQUMsQ0FBQztBQUUxRSxJQUFNLGFBQWE7SUFRbEJBLFNBUktBLGFBQWFBO1FBQW5CQyxpQkFrRkNBO1FBeEVDQSxLQUFLQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzQkEsS0FBS0EsQ0FBQ0EsWUFBWUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFM0JBLFlBQVlBLENBQUNBLFlBQVlBLENBQUNBLFNBQVNBLENBQUNBLENBQUVBO1FBRXRDQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxV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V2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQXNzZXRMaWJyYXJ5XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMaWJyYXJ5XCIpO1xuaW1wb3J0IEFzc2V0TG9hZGVyXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMb2FkZXJcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJUb2tlblx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclRva2VuXCIpO1xuaW1wb3J0IEFzc2V0VHlwZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0VHlwZVwiKTtcbmltcG9ydCBJQXNzZXRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0lBc3NldFwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IEFzc2V0RXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Bc3NldEV2ZW50XCIpO1xuaW1wb3J0IExvYWRlckV2ZW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvTG9hZGVyRXZlbnRcIik7XG5pbXBvcnQgRGVidWdcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvRGVidWdcIik7XG5pbXBvcnQgUmVxdWVzdEFuaW1hdGlvbkZyYW1lXHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9SZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIik7XG5cbmltcG9ydCBEZWZhdWx0UmVuZGVyZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3JlbmRlci9EZWZhdWx0UmVuZGVyZXJcIik7XG5pbXBvcnQgVHJpYW5nbGVNZXRob2RNYXRlcmlhbFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5cbmltcG9ydCBBV0RQYXJzZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvQVdEUGFyc2VyXCIpO1xuXG5jbGFzcyBBV0RQYXJzZXJUZXN0XG57XG5cblx0cHJpdmF0ZSBfdmlldzpWaWV3O1xuXHRwcml2YXRlIF90b2tlbjpBc3NldExvYWRlclRva2VuO1xuXHRwcml2YXRlIF90aW1lcjpSZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XG5cdHByaXZhdGUgX3N1emFubmU6TWVzaDtcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHREZWJ1Zy5MT0dfUElfRVJST1JTID0gdHJ1ZTtcblx0XHREZWJ1Zy5USFJPV19FUlJPUlMgPSBmYWxzZTtcblxuXHRcdEFzc2V0TGlicmFyeS5lbmFibGVQYXJzZXIoQVdEUGFyc2VyKSA7XG5cblx0XHR0aGlzLl90b2tlbiA9IEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KCdhc3NldHMvc3V6YW5uZS5hd2QnKSk7XG5cdFx0dGhpcy5fdG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXHRcdHRoaXMuX3Rva2VuLmFkZEV2ZW50TGlzdGVuZXIoQXNzZXRFdmVudC5BU1NFVF9DT01QTEVURSwgKGV2ZW50OkFzc2V0RXZlbnQpID0+IHRoaXMub25Bc3NldENvbXBsZXRlKGV2ZW50KSk7XG5cblx0XHR0aGlzLl92aWV3ID0gbmV3IFZpZXcobmV3IERlZmF1bHRSZW5kZXJlcigpKTtcblx0XHR0aGlzLl90aW1lciA9IG5ldyBSZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5yZW5kZXIsIHRoaXMpO1xuXG5cdFx0d2luZG93Lm9ucmVzaXplID0gKGV2ZW50OlVJRXZlbnQpID0+IHRoaXMucmVzaXplKGV2ZW50KTtcblxuXHRcdHRoaXMuX3RpbWVyLnN0YXJ0KCk7XG5cdFx0dGhpcy5yZXNpemUoKTtcblx0fVxuXG5cdHByaXZhdGUgcmVzaXplKGV2ZW50OlVJRXZlbnQgPSBudWxsKVxuXHR7XG5cdFx0dGhpcy5fdmlldy55ID0gMDtcblx0XHR0aGlzLl92aWV3LnggPSAwO1xuXHRcdHRoaXMuX3ZpZXcud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcblx0XHR0aGlzLl92aWV3LmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblx0fVxuXG5cdHByaXZhdGUgcmVuZGVyKGR0Om51bWJlcikgLy9hbmltYXRlIGJhc2VkIG9uIGR0IGZvciBmaXJlZm94XG5cdHtcblx0XHRpZiAodGhpcy5fc3V6YW5uZSlcblx0XHRcdHRoaXMuX3N1emFubmUucm90YXRpb25ZICs9IDE7XG5cblx0XHR0aGlzLl92aWV3LnJlbmRlcigpO1xuXHRcdHRoaXMuX3ZpZXcuY2FtZXJhLnogPSAtMjAwMDtcblx0fVxuXG5cdHB1YmxpYyBvbkFzc2V0Q29tcGxldGUoZXZlbnQ6QXNzZXRFdmVudClcblx0e1xuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblx0XHRjb25zb2xlLmxvZygnZXZlbnRzLkFzc2V0RXZlbnQuQVNTRVRfQ09NUExFVEUnLCBBc3NldExpYnJhcnkuZ2V0QXNzZXQoZXZlbnQuYXNzZXQubmFtZSkpO1xuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblx0fVxuXG5cdHB1YmxpYyBvblJlc291cmNlQ29tcGxldGUoZXZlbnQ6TG9hZGVyRXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2V2ZW50cy5Mb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURScgLCBldmVudCk7XG5cdFx0Y29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuXG5cdFx0dmFyIGxvYWRlcjpBc3NldExvYWRlciA9IDxBc3NldExvYWRlcj4gZXZlbnQudGFyZ2V0O1xuXHRcdHZhciBudW1Bc3NldHM6bnVtYmVyID0gbG9hZGVyLmJhc2VEZXBlbmRlbmN5LmFzc2V0cy5sZW5ndGg7XG5cblx0XHRmb3IodmFyIGk6bnVtYmVyID0gMDsgaSA8IG51bUFzc2V0czsgKytpKSB7XG5cdFx0XHR2YXIgYXNzZXQ6SUFzc2V0ID0gbG9hZGVyLmJhc2VEZXBlbmRlbmN5LmFzc2V0c1tpXTtcblxuXHRcdFx0c3dpdGNoIChhc3NldC5hc3NldFR5cGUpIHtcblx0XHRcdFx0Y2FzZSBBc3NldFR5cGUuTUVTSDpcblxuXHRcdFx0XHRcdHRoaXMuX3N1emFubmUgPSA8TWVzaD4gYXNzZXQ7XG5cdFx0XHRcdFx0dGhpcy5fc3V6YW5uZS50cmFuc2Zvcm0uc2NhbGUgPSBuZXcgVmVjdG9yM0QoNjAwLCA2MDAsIDYwMCk7XG5cblx0XHRcdFx0XHR0aGlzLl92aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMuX3N1emFubmUpO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBBc3NldFR5cGUuR0VPTUVUUlk6XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBBc3NldFR5cGUuTUFURVJJQUw6XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59Il19 \ No newline at end of file diff --git a/tests/parsers/AWDSuzanne.js b/tests/parsers/AWDSuzanne.js new file mode 100755 index 000000000..8526aa1e6 --- /dev/null +++ b/tests/parsers/AWDSuzanne.js @@ -0,0 +1,103 @@ +var View = require("awayjs-core/lib/containers/View"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +var AssetEvent = require("awayjs-core/lib/events/AssetEvent"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var StaticLightPicker = require("awayjs-core/lib/materials/lightpickers/StaticLightPicker"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var AWDParser = require("awayjs-renderergl/lib/parsers/AWDParser"); +var AWDSuzanne = (function () { + function AWDSuzanne() { + var _this = this; + this.lookAtPosition = new Vector3D(); + this._cameraIncrement = 0; + Debug.LOG_PI_ERRORS = true; + Debug.THROW_ERRORS = false; + AssetLibrary.enableParser(AWDParser); + this._token = AssetLibrary.load(new URLRequest('assets/suzanne.awd')); + this._token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this._token.addEventListener(AssetEvent.ASSET_COMPLETE, function (event) { return _this.onAssetComplete(event); }); + this._view = new View(new DefaultRenderer()); + this._view.camera.projection.far = 6000; + this._timer = new RequestAnimationFrame(this.render, this); + this._light = new DirectionalLight(); + this._light.color = 0x683019; //683019; + this._light.direction = new Vector3D(1, 0, 0); + this._light.ambient = 0.1; //0.05;//.4; + this._light.ambientColor = 0x85b2cd; //4F6877;//313D51; + this._light.diffuse = 2.8; + this._light.specular = 1.8; + this._view.scene.addChild(this._light); + this._lightPicker = new StaticLightPicker([this._light]); + window.onresize = function (event) { return _this.resize(event); }; + this._timer.start(); + this.resize(); + } + AWDSuzanne.prototype.resize = function (event) { + if (event === void 0) { event = null; } + this._view.y = 0; + this._view.x = 0; + this._view.width = window.innerWidth; + this._view.height = window.innerHeight; + }; + AWDSuzanne.prototype.render = function (dt) { + if (this._view.camera) { + this._view.camera.lookAt(this.lookAtPosition); + this._cameraIncrement += 0.01; + this._view.camera.x = Math.cos(this._cameraIncrement) * 1400; + this._view.camera.z = Math.sin(this._cameraIncrement) * 1400; + this._light.x = Math.cos(this._cameraIncrement) * 1400; + this._light.y = Math.sin(this._cameraIncrement) * 1400; + } + this._view.render(); + }; + AWDSuzanne.prototype.onAssetComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('away.events.AssetEvent.ASSET_COMPLETE', AssetLibrary.getAsset(event.asset.name)); + console.log('------------------------------------------------------------------------------'); + }; + AWDSuzanne.prototype.onResourceComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('away.events.LoaderEvent.RESOURCE_COMPLETE', event); + console.log('------------------------------------------------------------------------------'); + var loader = event.target; + var numAssets = loader.baseDependency.assets.length; + for (var i = 0; i < numAssets; ++i) { + var asset = loader.baseDependency.assets[i]; + switch (asset.assetType) { + case AssetType.MESH: + this._suzanne = asset; + this._suzanne.material.lightPicker = this._lightPicker; + this._suzanne.y = -100; + for (var c = 0; c < 80; c++) { + var scale = this.getRandom(50, 200); + var clone = this._suzanne.clone(); + clone.x = this.getRandom(-2000, 2000); + clone.y = this.getRandom(-2000, 2000); + clone.z = this.getRandom(-2000, 2000); + clone.transform.scale = new Vector3D(scale, scale, scale); + clone.rotationY = this.getRandom(0, 360); + this._view.scene.addChild(clone); + } + this._suzanne.transform.scale = new Vector3D(500, 500, 500); + this._view.scene.addChild(this._suzanne); + break; + case AssetType.GEOMETRY: + break; + case AssetType.MATERIAL: + break; + } + } + }; + AWDSuzanne.prototype.getRandom = function (min, max) { + return Math.random() * (max - min) + min; + }; + return AWDSuzanne; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvYXdkc3V6YW5uZS50cyJdLCJuYW1lcyI6WyJBV0RTdXphbm5lIiwiQVdEU3V6YW5uZS5jb25zdHJ1Y3RvciIsIkFXRFN1emFubmUucmVzaXplIiwiQVdEU3V6YW5uZS5yZW5kZXIiLCJBV0RTdXphbm5lLm9uQXNzZXRDb21wbGV0ZSIsIkFXRFN1emFubmUub25SZXNvdXJjZUNvbXBsZXRlIiwiQVdEU3V6YW5uZS5nZXRSYW5kb20iXSwibWFwcGluZ3MiOiJBQUFBLElBQU8sSUFBSSxXQUFpQixpQ0FBaUMsQ0FBQyxDQUFDO0FBQy9ELElBQU8sUUFBUSxXQUFnQixvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3JFLElBQU8sWUFBWSxXQUFlLDJDQUEyQyxDQUFDLENBQUM7QUFHL0UsSUFBTyxTQUFTLFdBQWUsd0NBQXdDLENBQUMsQ0FBQztBQUV6RSxJQUFPLFVBQVUsV0FBZSxxQ0FBcUMsQ0FBQyxDQUFDO0FBQ3ZFLElBQU8sZ0JBQWdCLFdBQWMsMkNBQTJDLENBQUMsQ0FBQztBQUVsRixJQUFPLFVBQVUsV0FBZSxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ3JFLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxpQkFBaUIsV0FBYSwwREFBMEQsQ0FBQyxDQUFDO0FBQ2pHLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBR3RGLElBQU8sU0FBUyxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFFMUUsSUFBTSxVQUFVO0lBV2ZBLFNBWEtBLFVBQVVBO1FBQWhCQyxpQkErSENBO1FBdkhRQSxtQkFBY0EsR0FBWUEsSUFBSUEsUUFBUUEsRUFBRUEsQ0FBQ0E7UUFDekNBLHFCQUFnQkEsR0FBVUEsQ0FBQ0EsQ0FBQ0E7UUFJbkNBLEtBQUtBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENB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Q0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDckNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLEdBQUdBLE1BQU1BLENBQUNBLFdBQVdBLENBQUNBO0lBQ3hDQSxDQUFDQTtJQUVPRiwyQkFBTUEsR0FBZEEsVUFBZUEsRUFBU0E7UUFFdkJHLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBO1lBQ3ZCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxjQUFjQSxDQUFDQSxDQUFFQTtZQUMvQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxJQUFJQSxJQUFJQSxDQUFDQTtZQUM5QkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQTtZQUMzREEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQTtZQUUzREEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQTtZQUNyREEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsZ0JBQWdCQSxDQUFDQSxHQUFDQSxJQUFJQSxDQUFDQTtRQUN0REEsQ0FBQ0E7UUFFREEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsRUFBRUEsQ0FBQ0E7SUFDckJBLENBQUNBO0lBRU1ILG9DQUFlQSxHQUF0QkEsVUFBdUJBLEtBQWdCQTtRQUV0Q0ksT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUM5RkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsdUNBQXVDQSxFQUFFQSxZQUFZQSxDQUFDQSxRQUFRQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUM5RkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtJQUMvRkEsQ0FBQ0E7SUFFTUosdUNBQWtCQSxHQUF6QkEsVUFBMEJBLEtBQWlCQTtRQUUxQ0ssT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUM5RkEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsMkNBQTJDQSxFQUFHQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUNqRUEsT0FBT0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsZ0ZBQWdGQSxDQUFDQSxDQUFDQTtRQUU5RkEsSUFBSUEsTUFBTUEsR0FBNkJBLEtBQUtBLENBQUNBLE1BQU1BLENBQUNBO1FBQ3BEQSxJQUFJQSxTQUFTQSxHQUFVQSxNQUFNQSxDQUFDQSxjQUFjQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQTtRQUUzREEsR0FBR0EsQ0FBQUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBVUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsU0FBU0EsRUFBRUEsRUFBRUEsQ0FBQ0EsRUFBRUEsQ0FBQ0E7WUFDMUNBLElBQUlBLEtBQUtBLEdBQVVBLE1BQU1BLENBQUNBLGNBQWNBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBO1lBRW5EQSxNQUFNQSxDQUFDQSxDQUFDQSxLQUFLQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDekJBLEtBQUtBLFNBQVNBLENBQUNBLElBQUlBO29CQUVsQkEsSUFBSUEsQ0FBQ0EsUUFBUUEsR0FBVUEsS0FBS0EsQ0FBQ0E7b0JBRUhBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLFFBQVNBLENBQUNBLFdBQVdBLEdBQUdBLElBQUlBLENBQUNBLFlBQVlBLENBQUNBO29CQUNsRkEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsR0FBR0EsQ0FBQ0E7b0JBR3ZCQSxHQUFHQSxDQUFDQSxDQUFFQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFZQSxDQUFDQSxFQUFHQSxDQUFDQSxHQUFHQSxFQUFFQSxFQUFHQSxDQUFDQSxFQUFHQSxFQUN4Q0EsQ0FBQ0E7d0JBQ0FBLElBQUlBLEtBQUtBLEdBQVVBLElBQUlBLENBQUNBLFNBQVNBLENBQUVBLEVBQUVBLEVBQUdBLEdBQUdBLENBQUVBLENBQUNBO3dCQUM5Q0EsSUFBSUEsS0FBS0EsR0FBZUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0E7d0JBQzdDQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxJQUFJQSxFQUFHQSxJQUFJQSxDQUFDQSxDQUFDQTt3QkFDdkNBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLElBQUlBLEVBQUdBLElBQUlBLENBQUNBLENBQUNBO3dCQUN2Q0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsSUFBSUEsRUFBR0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7d0JBQ3ZDQSxLQUFLQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxLQUFLQSxFQUFFQSxLQUFLQSxFQUFFQSxLQUFLQSxDQUFDQSxDQUFDQTt3QkFDMURBLEtBQUtBLENBQUNBLFNBQVNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEVBQUdBLEdBQUdBLENBQUNBLENBQUNBO3dCQUMzQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsQ0FBRUEsS0FBS0EsQ0FBRUEsQ0FBQ0E7b0JBRXBDQSxDQUFDQTtvQkFFREEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsR0FBR0EsRUFBRUEsR0FBR0EsRUFBRUEsR0FBR0EsQ0FBQ0EsQ0FBQ0E7b0JBRTVEQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxDQUFDQTtvQkFFekNBLEtBQUtBLENBQUNBO2dCQUVQQSxLQUFLQSxTQUFTQSxDQUFDQSxRQUFRQTtvQkFDdEJBLEtBQUtBLENBQUNBO2dCQUVQQSxLQUFLQSxTQUFTQSxDQUFDQSxRQUFRQTtvQkFFdEJBLEtBQUtBLENBQUNBO1lBQ1JBLENBQUNBO1FBQ0ZBLENBQUNBO0lBQ0ZBLENBQUNBO0lBRU9MLDhCQUFTQSxHQUFqQkEsVUFBa0JBLEdBQVVBLEVBQUVBLEdBQVVBO1FBRXZDTSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxHQUFDQSxDQUFDQSxHQUFHQSxHQUFHQSxHQUFHQSxDQUFDQSxHQUFHQSxHQUFHQSxDQUFDQTtJQUN4Q0EsQ0FBQ0E7SUFDRk4saUJBQUNBO0FBQURBLENBL0hBLEFBK0hDQSxJQUFBIiwiZmlsZSI6InBhcnNlcnMvQVdEU3V6YW5uZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1yZW5kZXJlcmdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWaWV3XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9WaWV3XCIpO1xuaW1wb3J0IFZlY3RvcjNEXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvZ2VvbS9WZWN0b3IzRFwiKTtcbmltcG9ydCBBc3NldExpYnJhcnlcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExpYnJhcnlcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclwiKTtcbmltcG9ydCBBc3NldExvYWRlclRva2VuXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TG9hZGVyVG9rZW5cIik7XG5pbXBvcnQgQXNzZXRUeXBlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IFVSTFJlcXVlc3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTFJlcXVlc3RcIik7XG5pbXBvcnQgRGlyZWN0aW9uYWxMaWdodFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL0RpcmVjdGlvbmFsTGlnaHRcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgQXNzZXRFdmVudFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZXZlbnRzL0Fzc2V0RXZlbnRcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBTdGF0aWNMaWdodFBpY2tlclx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9tYXRlcmlhbHMvbGlnaHRwaWNrZXJzL1N0YXRpY0xpZ2h0UGlja2VyXCIpO1xuaW1wb3J0IERlYnVnXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL0RlYnVnXCIpO1xuaW1wb3J0IFJlcXVlc3RBbmltYXRpb25GcmFtZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvUmVxdWVzdEFuaW1hdGlvbkZyYW1lXCIpO1xuXG5pbXBvcnQgRGVmYXVsdFJlbmRlcmVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9yZW5kZXIvRGVmYXVsdFJlbmRlcmVyXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9UcmlhbmdsZU1ldGhvZE1hdGVyaWFsXCIpO1xuXG5pbXBvcnQgQVdEUGFyc2VyXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1yZW5kZXJlcmdsL2xpYi9wYXJzZXJzL0FXRFBhcnNlclwiKTtcblxuY2xhc3MgQVdEU3V6YW5uZVxue1xuXHRwcml2YXRlIF92aWV3OlZpZXc7XG5cdHByaXZhdGUgX3Rva2VuOkFzc2V0TG9hZGVyVG9rZW47XG5cdHByaXZhdGUgX3RpbWVyOlJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0cHJpdmF0ZSBfc3V6YW5uZTpNZXNoO1xuXHRwcml2YXRlIF9saWdodDpEaXJlY3Rpb25hbExpZ2h0O1xuXHRwcml2YXRlIF9saWdodFBpY2tlcjpTdGF0aWNMaWdodFBpY2tlcjtcblx0cHJpdmF0ZSBsb29rQXRQb3NpdGlvbjpWZWN0b3IzRCA9IG5ldyBWZWN0b3IzRCgpO1xuXHRwcml2YXRlIF9jYW1lcmFJbmNyZW1lbnQ6bnVtYmVyID0gMDtcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHREZWJ1Zy5MT0dfUElfRVJST1JTID0gdHJ1ZTtcblx0XHREZWJ1Zy5USFJPV19FUlJPUlMgPSBmYWxzZTtcblxuXHRcdEFzc2V0TGlicmFyeS5lbmFibGVQYXJzZXIoQVdEUGFyc2VyKSA7XG5cblx0XHR0aGlzLl90b2tlbiA9IEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KCdhc3NldHMvc3V6YW5uZS5hd2QnKSk7XG5cdFx0dGhpcy5fdG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXHRcdHRoaXMuX3Rva2VuLmFkZEV2ZW50TGlzdGVuZXIoQXNzZXRFdmVudC5BU1NFVF9DT01QTEVURSwgKGV2ZW50OkFzc2V0RXZlbnQpID0+IHRoaXMub25Bc3NldENvbXBsZXRlKGV2ZW50KSk7XG5cblx0XHR0aGlzLl92aWV3ID0gbmV3IFZpZXcobmV3IERlZmF1bHRSZW5kZXJlcigpKTtcblx0XHR0aGlzLl92aWV3LmNhbWVyYS5wcm9qZWN0aW9uLmZhciAgPSA2MDAwO1xuXHRcdHRoaXMuX3RpbWVyID0gbmV3IFJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlciwgdGhpcyk7XG5cblx0XHR0aGlzLl9saWdodCA9IG5ldyBEaXJlY3Rpb25hbExpZ2h0KCk7XG5cdFx0dGhpcy5fbGlnaHQuY29sb3IgPSAweDY4MzAxOTsvLzY4MzAxOTtcblx0XHR0aGlzLl9saWdodC5kaXJlY3Rpb24gPSBuZXcgVmVjdG9yM0QoIDEgLCAwICwwICk7XG5cdFx0dGhpcy5fbGlnaHQuYW1iaWVudCA9IDAuMTsvLzAuMDU7Ly8uNDtcblx0XHR0aGlzLl9saWdodC5hbWJpZW50Q29sb3IgPSAweDg1YjJjZDsvLzRGNjg3NzsvLzMxM0Q1MTtcblx0XHR0aGlzLl9saWdodC5kaWZmdXNlID0gMi44O1xuXHRcdHRoaXMuX2xpZ2h0LnNwZWN1bGFyID0gMS44O1xuXHRcdHRoaXMuX3ZpZXcuc2NlbmUuYWRkQ2hpbGQodGhpcy5fbGlnaHQpO1xuXG5cdFx0dGhpcy5fbGlnaHRQaWNrZXIgPSBuZXcgU3RhdGljTGlnaHRQaWNrZXIoW3RoaXMuX2xpZ2h0XSk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgPSAoZXZlbnQ6VUlFdmVudCkgPT4gdGhpcy5yZXNpemUoZXZlbnQpO1xuXG5cdFx0dGhpcy5fdGltZXIuc3RhcnQoKTtcblx0XHR0aGlzLnJlc2l6ZSgpO1xuXHR9XG5cblx0cHJpdmF0ZSByZXNpemUoZXZlbnQ6VUlFdmVudCA9IG51bGwpXG5cdHtcblx0XHR0aGlzLl92aWV3LnkgPSAwO1xuXHRcdHRoaXMuX3ZpZXcueCA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKSAvL2FuaW1hdGUgYmFzZWQgb24gZHQgZm9yIGZpcmVmb3hcblx0e1xuXHRcdGlmICh0aGlzLl92aWV3LmNhbWVyYSkge1xuXHRcdFx0dGhpcy5fdmlldy5jYW1lcmEubG9va0F0KHRoaXMubG9va0F0UG9zaXRpb24pIDtcblx0XHRcdHRoaXMuX2NhbWVyYUluY3JlbWVudCArPSAwLjAxO1xuXHRcdFx0dGhpcy5fdmlldy5jYW1lcmEueCA9IE1hdGguY29zKHRoaXMuX2NhbWVyYUluY3JlbWVudCkqMTQwMDtcblx0XHRcdHRoaXMuX3ZpZXcuY2FtZXJhLnogPSBNYXRoLnNpbih0aGlzLl9jYW1lcmFJbmNyZW1lbnQpKjE0MDA7XG5cblx0XHRcdHRoaXMuX2xpZ2h0LnggPSBNYXRoLmNvcyh0aGlzLl9jYW1lcmFJbmNyZW1lbnQpKjE0MDA7XG5cdFx0XHR0aGlzLl9saWdodC55ID0gTWF0aC5zaW4odGhpcy5fY2FtZXJhSW5jcmVtZW50KSoxNDAwO1xuXHRcdH1cblxuXHRcdHRoaXMuX3ZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgb25Bc3NldENvbXBsZXRlKGV2ZW50OkFzc2V0RXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2F3YXkuZXZlbnRzLkFzc2V0RXZlbnQuQVNTRVRfQ09NUExFVEUnLCBBc3NldExpYnJhcnkuZ2V0QXNzZXQoZXZlbnQuYXNzZXQubmFtZSkpO1xuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblx0fVxuXG5cdHB1YmxpYyBvblJlc291cmNlQ29tcGxldGUoZXZlbnQ6TG9hZGVyRXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2F3YXkuZXZlbnRzLkxvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFJyAsIGV2ZW50KTtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cblx0XHR2YXIgbG9hZGVyOkFzc2V0TG9hZGVyID0gPEFzc2V0TG9hZGVyPiBldmVudC50YXJnZXQ7XG5cdFx0dmFyIG51bUFzc2V0czpudW1iZXIgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzLmxlbmd0aDtcblxuXHRcdGZvcih2YXIgaTpudW1iZXIgPSAwOyBpIDwgbnVtQXNzZXRzOyArK2kpIHtcblx0XHRcdHZhciBhc3NldDpJQXNzZXQgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzW2ldO1xuXG5cdFx0XHRzd2l0Y2ggKGFzc2V0LmFzc2V0VHlwZSkge1xuXHRcdFx0XHRjYXNlIEFzc2V0VHlwZS5NRVNIOlxuXG5cdFx0XHRcdFx0dGhpcy5fc3V6YW5uZSA9IDxNZXNoPiBhc3NldDtcblxuXHRcdFx0XHRcdCg8VHJpYW5nbGVNZXRob2RNYXRlcmlhbD4gdGhpcy5fc3V6YW5uZS5tYXRlcmlhbCkubGlnaHRQaWNrZXIgPSB0aGlzLl9saWdodFBpY2tlcjtcblx0XHRcdFx0XHR0aGlzLl9zdXphbm5lLnkgPSAtMTAwO1xuXG5cblx0XHRcdFx0XHRmb3IgKCB2YXIgYyA6IG51bWJlciA9IDAgOyBjIDwgODAgOyBjICsrIClcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHR2YXIgc2NhbGU6bnVtYmVyID0gdGhpcy5nZXRSYW5kb20oIDUwICwgMjAwICk7XG5cdFx0XHRcdFx0XHR2YXIgY2xvbmU6TWVzaCA9IDxNZXNoPiB0aGlzLl9zdXphbm5lLmNsb25lKCk7XG5cdFx0XHRcdFx0XHRcdGNsb25lLnggPSB0aGlzLmdldFJhbmRvbSgtMjAwMCAsIDIwMDApO1xuXHRcdFx0XHRcdFx0XHRjbG9uZS55ID0gdGhpcy5nZXRSYW5kb20oLTIwMDAgLCAyMDAwKTtcblx0XHRcdFx0XHRcdFx0Y2xvbmUueiA9IHRoaXMuZ2V0UmFuZG9tKC0yMDAwICwgMjAwMCk7XG5cdFx0XHRcdFx0XHRcdGNsb25lLnRyYW5zZm9ybS5zY2FsZSA9IG5ldyBWZWN0b3IzRChzY2FsZSwgc2NhbGUsIHNjYWxlKTtcblx0XHRcdFx0XHRcdFx0Y2xvbmUucm90YXRpb25ZID0gdGhpcy5nZXRSYW5kb20oMCAsIDM2MCk7XG5cdFx0XHRcdFx0XHR0aGlzLl92aWV3LnNjZW5lLmFkZENoaWxkKCBjbG9uZSApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGhpcy5fc3V6YW5uZS50cmFuc2Zvcm0uc2NhbGUgPSBuZXcgVmVjdG9yM0QoNTAwLCA1MDAsIDUwMCk7XG5cblx0XHRcdFx0XHR0aGlzLl92aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMuX3N1emFubmUpO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBBc3NldFR5cGUuR0VPTUVUUlk6XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBBc3NldFR5cGUuTUFURVJJQUw6XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGdldFJhbmRvbShtaW46bnVtYmVyLCBtYXg6bnVtYmVyKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiBNYXRoLnJhbmRvbSgpKihtYXggLSBtaW4pICsgbWluO1xuXHR9XG59Il19 \ No newline at end of file diff --git a/tests/parsers/ObjChiefTestDay.js b/tests/parsers/ObjChiefTestDay.js new file mode 100755 index 000000000..14969a683 --- /dev/null +++ b/tests/parsers/ObjChiefTestDay.js @@ -0,0 +1,119 @@ +var DisplayObjectContainer = require("awayjs-core/lib/containers/DisplayObjectContainer"); +var View = require("awayjs-core/lib/containers/View"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var AssetType = require("awayjs-core/lib/core/library/AssetType"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var DirectionalLight = require("awayjs-core/lib/entities/DirectionalLight"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var StaticLightPicker = require("awayjs-core/lib/materials/lightpickers/StaticLightPicker"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial"); +var OBJParser = require("awayjs-renderergl/lib/parsers/OBJParser"); +/** + * + */ +var ObjChiefTestDay = (function () { + function ObjChiefTestDay() { + var _this = this; + this.meshes = new Array(); + this.spartan = new DisplayObjectContainer(); + this.spartanFlag = false; + this.terrainObjFlag = false; + Debug.LOG_PI_ERRORS = false; + Debug.THROW_ERRORS = false; + this.view = new View(new DefaultRenderer()); + this.view.camera.z = -50; + this.view.camera.y = 20; + this.view.camera.projection.near = 0.1; + this.view.backgroundColor = 0xCEC8C6; + this.raf = new RequestAnimationFrame(this.render, this); + this.light = new DirectionalLight(); + this.light.color = 0xc1582d; + this.light.direction = new Vector3D(1, 0, 0); + this.light.ambient = 0.4; + this.light.ambientColor = 0x85b2cd; + this.light.diffuse = 2.8; + this.light.specular = 1.8; + this.spartan.transform.scale = new Vector3D(.25, .25, .25); + this.spartan.y = 0; + this.view.scene.addChild(this.light); + AssetLibrary.enableParser(OBJParser); + this.token = AssetLibrary.load(new URLRequest('assets/Halo_3_SPARTAN4.obj')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this.token = AssetLibrary.load(new URLRequest('assets/terrain.obj')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this.token = AssetLibrary.load(new URLRequest('assets/masterchief_base.png')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this.token = AssetLibrary.load(new URLRequest('assets/stone_tx.jpg')); + this.token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + window.onresize = function (event) { return _this.onResize(); }; + this.raf.start(); + } + ObjChiefTestDay.prototype.render = function () { + if (this.terrain) + this.terrain.rotationY += 0.4; + this.spartan.rotationY += 0.4; + this.view.render(); + }; + ObjChiefTestDay.prototype.onResourceComplete = function (event) { + var loader = event.target; + var l = loader.baseDependency.assets.length; + console.log('------------------------------------------------------------------------------'); + console.log('events.LoaderEvent.RESOURCE_COMPLETE', event, l, loader); + console.log('------------------------------------------------------------------------------'); + var loader = event.target; + var l = loader.baseDependency.assets.length; + for (var c = 0; c < l; c++) { + var d = loader.baseDependency.assets[c]; + console.log(d.name, event.url); + switch (d.assetType) { + case AssetType.MESH: + if (event.url == 'assets/Halo_3_SPARTAN4.obj') { + var mesh = d; + this.spartan.addChild(mesh); + this.spartanFlag = true; + this.meshes.push(mesh); + } + else if (event.url == 'assets/terrain.obj') { + this.terrainObjFlag = true; + this.terrain = d; + this.terrain.y = 98; + this.view.scene.addChild(this.terrain); + } + break; + case AssetType.TEXTURE: + if (event.url == 'assets/masterchief_base.png') { + this.mat = new TriangleMethodMaterial(d, true, true, false); + this.mat.lightPicker = new StaticLightPicker([this.light]); + } + else if (event.url == 'assets/stone_tx.jpg') { + this.terrainMaterial = new TriangleMethodMaterial(d, true, true, false); + this.terrainMaterial.lightPicker = new StaticLightPicker([this.light]); + } + break; + } + } + if (this.terrainObjFlag && this.terrainMaterial) { + this.terrain.material = this.terrainMaterial; + this.terrain.geometry.scaleUV(20, 20); + } + if (this.mat && this.spartanFlag) + for (var c = 0; c < this.meshes.length; c++) + this.meshes[c].material = this.mat; + this.view.scene.addChild(this.spartan); + this.onResize(); + }; + ObjChiefTestDay.prototype.onResize = function (event) { + if (event === void 0) { event = null; } + this.view.y = 0; + this.view.x = 0; + this.view.width = window.innerWidth; + this.view.height = window.innerHeight; + }; + return ObjChiefTestDay; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvb2JqY2hpZWZ0ZXN0ZGF5LnRzIl0sIm5hbWVzIjpbIk9iakNoaWVmVGVzdERheSIsIk9iakNoaWVmVGVzdERheS5jb25zdHJ1Y3RvciIsIk9iakNoaWVmVGVzdERheS5yZW5kZXIiLCJPYmpDaGllZlRlc3REYXkub25SZXNvdXJjZUNvbXBsZXRlIiwiT2JqQ2hpZWZUZXN0RGF5Lm9uUmVzaXplIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLHNCQUFzQixXQUFZLG1EQUFtRCxDQUFDLENBQUM7QUFDOUYsSUFBTyxJQUFJLFdBQWlCLGlDQUFpQyxDQUFDLENBQUM7QUFDL0QsSUFBTyxRQUFRLFdBQWdCLG9DQUFvQyxDQUFDLENBQUM7QUFDckUsSUFBTyxZQUFZLFdBQWUsMkNBQTJDLENBQUMsQ0FBQztBQUcvRSxJQUFPLFNBQVMsV0FBZSx3Q0FBd0MsQ0FBQyxDQUFDO0FBRXpFLElBQU8sVUFBVSxXQUFlLHFDQUFxQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxnQkFBZ0IsV0FBYywyQ0FBMkMsQ0FBQyxDQUFDO0FBRWxGLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxpQkFBaUIsV0FBYSwwREFBMEQsQ0FBQyxDQUFDO0FBRWpHLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBQ3RGLElBQU8sc0JBQXNCLFdBQVkscURBQXFELENBQUMsQ0FBQztBQUVoRyxJQUFPLFNBQVMsV0FBZSx5Q0FBeUMsQ0FBQyxDQUFDO0FBRTFFLEFBR0E7O0dBREc7SUFDRyxlQUFlO0lBa0JwQkEsU0FsQktBLGVBQWVBO1FBQXJCQyxpQkE0SUNBO1FBdklRQSxXQUFNQSxHQUFlQSxJQUFJQSxLQUFLQSxFQUFRQSxDQUFDQTtRQU92Q0EsWUFBT0EsR0FBMEJBLElBQUlBLHNCQUFzQkEsRUFB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LElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLENBQUNBLENBQUNBLFFBQVFBLEdBQUdBLElBQUlBLENBQUNBLEdBQUdBLENBQUNBO1FBRXJDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQTtRQUN2Q0EsSUFBSUEsQ0FBQ0EsUUFBUUEsRUFBRUEsQ0FBQ0E7SUFDakJBLENBQUNBO0lBRU1ILGtDQUFRQSxHQUFmQSxVQUFnQkEsS0FBb0JBO1FBQXBCSSxxQkFBb0JBLEdBQXBCQSxZQUFvQkE7UUFFbkNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ2hCQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVoQkEsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDcENBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLE1BQU1BLENBQUNBLFdBQVdBLENBQUNBO0lBQ3ZDQSxDQUFDQTtJQUNGSixzQkFBQ0E7QUFBREEsQ0E1SUEsQUE0SUNBLElBQUEiLCJmaWxlIjoicGFyc2Vycy9PYmpDaGllZlRlc3REYXkuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGlzcGxheU9iamVjdENvbnRhaW5lclx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9EaXNwbGF5T2JqZWN0Q29udGFpbmVyXCIpO1xuaW1wb3J0IFZpZXdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL1ZpZXdcIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IEFzc2V0TGlicmFyeVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TGlicmFyeVwiKTtcbmltcG9ydCBBc3NldExvYWRlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TG9hZGVyXCIpO1xuaW1wb3J0IEFzc2V0TG9hZGVyVG9rZW5cdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMb2FkZXJUb2tlblwiKTtcbmltcG9ydCBBc3NldFR5cGVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldFR5cGVcIik7XG5pbXBvcnQgSUFzc2V0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9JQXNzZXRcIik7XG5pbXBvcnQgVVJMUmVxdWVzdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMUmVxdWVzdFwiKTtcbmltcG9ydCBEaXJlY3Rpb25hbExpZ2h0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvRGlyZWN0aW9uYWxMaWdodFwiKTtcbmltcG9ydCBNZXNoXHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvTWVzaFwiKTtcbmltcG9ydCBMb2FkZXJFdmVudFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZXZlbnRzL0xvYWRlckV2ZW50XCIpO1xuaW1wb3J0IFN0YXRpY0xpZ2h0UGlja2VyXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL21hdGVyaWFscy9saWdodHBpY2tlcnMvU3RhdGljTGlnaHRQaWNrZXJcIik7XG5pbXBvcnQgSW1hZ2VUZXh0dXJlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9JbWFnZVRleHR1cmVcIik7XG5pbXBvcnQgRGVidWdcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvRGVidWdcIik7XG5pbXBvcnQgUmVxdWVzdEFuaW1hdGlvbkZyYW1lXHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9SZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIik7XG5cbmltcG9ydCBEZWZhdWx0UmVuZGVyZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9jb3JlL3JlbmRlci9EZWZhdWx0UmVuZGVyZXJcIik7XG5pbXBvcnQgVHJpYW5nbGVNZXRob2RNYXRlcmlhbFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvbWF0ZXJpYWxzL1RyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcIik7XG5cbmltcG9ydCBPQkpQYXJzZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXJlbmRlcmVyZ2wvbGliL3BhcnNlcnMvT0JKUGFyc2VyXCIpO1xuXG4vKipcbiAqIFxuICovXG5jbGFzcyBPYmpDaGllZlRlc3REYXlcbntcblx0cHJpdmF0ZSB0b2tlbjpBc3NldExvYWRlclRva2VuO1xuXHRwcml2YXRlIHZpZXc6Vmlldztcblx0cHJpdmF0ZSByYWY6UmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuXHRwcml2YXRlIG1lc2hlczpBcnJheTxNZXNoPiA9IG5ldyBBcnJheTxNZXNoPigpO1xuXHRwcml2YXRlIG1hdDpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsO1xuXG5cdHByaXZhdGUgdGVycmFpbk1hdGVyaWFsOlRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWw7XG5cblx0cHJpdmF0ZSBsaWdodDpEaXJlY3Rpb25hbExpZ2h0O1xuXG5cdHByaXZhdGUgc3BhcnRhbjpEaXNwbGF5T2JqZWN0Q29udGFpbmVyID0gbmV3IERpc3BsYXlPYmplY3RDb250YWluZXIoKTtcblx0cHJpdmF0ZSB0ZXJyYWluOk1lc2g7XG5cblx0cHJpdmF0ZSBzcGFydGFuRmxhZzpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgdGVycmFpbk9iakZsYWc6Ym9vbGVhbiA9IGZhbHNlO1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdERlYnVnLkxPR19QSV9FUlJPUlMgPSBmYWxzZTtcblx0XHREZWJ1Zy5USFJPV19FUlJPUlMgPSBmYWxzZTtcblxuXHRcdHRoaXMudmlldyA9IG5ldyBWaWV3KG5ldyBEZWZhdWx0UmVuZGVyZXIoKSk7XG5cdFx0dGhpcy52aWV3LmNhbWVyYS56ID0gLTUwO1xuXHRcdHRoaXMudmlldy5jYW1lcmEueSA9IDIwO1xuXHRcdHRoaXMudmlldy5jYW1lcmEucHJvamVjdGlvbi5uZWFyID0gMC4xO1xuXHRcdHRoaXMudmlldy5iYWNrZ3JvdW5kQ29sb3IgPSAweENFQzhDNjtcblxuXHRcdHRoaXMucmFmID0gbmV3IFJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlciwgdGhpcyk7XG5cblx0XHR0aGlzLmxpZ2h0ID0gbmV3IERpcmVjdGlvbmFsTGlnaHQoKTtcblx0XHR0aGlzLmxpZ2h0LmNvbG9yID0gMHhjMTU4MmQ7XG5cdFx0dGhpcy5saWdodC5kaXJlY3Rpb24gPSBuZXcgVmVjdG9yM0QoMSwgMCwgMCk7XG5cdFx0dGhpcy5saWdodC5hbWJpZW50ID0gMC40O1xuXHRcdHRoaXMubGlnaHQuYW1iaWVudENvbG9yID0gMHg4NWIyY2Q7XG5cdFx0dGhpcy5saWdodC5kaWZmdXNlID0gMi44O1xuXHRcdHRoaXMubGlnaHQuc3BlY3VsYXIgPSAxLjg7XG5cblx0XHR0aGlzLnNwYXJ0YW4udHJhbnNmb3JtLnNjYWxlID0gbmV3IFZlY3RvcjNEKC4yNSwgLjI1LCAuMjUpO1xuXHRcdHRoaXMuc3BhcnRhbi55ID0gMDtcblxuXHRcdHRoaXMudmlldy5zY2VuZS5hZGRDaGlsZCh0aGlzLmxpZ2h0KTtcblxuXHRcdEFzc2V0TGlicmFyeS5lbmFibGVQYXJzZXIoT0JKUGFyc2VyKTtcblxuXHRcdHRoaXMudG9rZW4gPSBBc3NldExpYnJhcnkubG9hZChuZXcgVVJMUmVxdWVzdCgnYXNzZXRzL0hhbG9fM19TUEFSVEFONC5vYmonKSk7XG5cdFx0dGhpcy50b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFLCAoZXZlbnQ6TG9hZGVyRXZlbnQpID0+IHRoaXMub25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50KSk7XG5cblx0XHR0aGlzLnRva2VuID0gQXNzZXRMaWJyYXJ5LmxvYWQobmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy90ZXJyYWluLm9iaicpKTtcblx0XHR0aGlzLnRva2VuLmFkZEV2ZW50TGlzdGVuZXIoTG9hZGVyRXZlbnQuUkVTT1VSQ0VfQ09NUExFVEUsIChldmVudDpMb2FkZXJFdmVudCkgPT4gdGhpcy5vblJlc291cmNlQ29tcGxldGUoZXZlbnQpKTtcblxuXHRcdHRoaXMudG9rZW4gPSBBc3NldExpYnJhcnkubG9hZChuZXcgVVJMUmVxdWVzdCgnYXNzZXRzL21hc3RlcmNoaWVmX2Jhc2UucG5nJykpO1xuXHRcdHRoaXMudG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXG5cdFx0dGhpcy50b2tlbiA9IEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KCdhc3NldHMvc3RvbmVfdHguanBnJykpO1xuXHRcdHRoaXMudG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXG5cdFx0d2luZG93Lm9ucmVzaXplID0gKGV2ZW50OlVJRXZlbnQpID0+IHRoaXMub25SZXNpemUoKTtcblxuXHRcdHRoaXMucmFmLnN0YXJ0KCk7XG5cdH1cblxuXHRwcml2YXRlIHJlbmRlcigpXG5cdHtcblx0XHRpZiAoIHRoaXMudGVycmFpbilcblx0XHRcdHRoaXMudGVycmFpbi5yb3RhdGlvblkgKz0gMC40O1xuXG5cdFx0dGhpcy5zcGFydGFuLnJvdGF0aW9uWSArPSAwLjQ7XG5cdFx0dGhpcy52aWV3LnJlbmRlcigpO1xuXHR9XG5cblx0cHVibGljIG9uUmVzb3VyY2VDb21wbGV0ZSAoZXZlbnQ6TG9hZGVyRXZlbnQpXG5cdHtcblx0XHR2YXIgbG9hZGVyOkFzc2V0TG9hZGVyID0gPEFzc2V0TG9hZGVyPiBldmVudC50YXJnZXQ7XG5cdFx0dmFyIGw6bnVtYmVyID0gbG9hZGVyLmJhc2VEZXBlbmRlbmN5LmFzc2V0cy5sZW5ndGg7XG5cblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2V2ZW50cy5Mb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURScsIGV2ZW50LCBsLCBsb2FkZXIpO1xuXHRcdGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKTtcblxuXHRcdHZhciBsb2FkZXI6QXNzZXRMb2FkZXIgPSA8QXNzZXRMb2FkZXI+IGV2ZW50LnRhcmdldDtcblx0XHR2YXIgbDpudW1iZXIgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzLmxlbmd0aDtcblxuXHRcdGZvciAodmFyIGM6bnVtYmVyID0gMDsgYyA8IGw7IGMrKykge1xuXG5cdFx0XHR2YXIgZDpJQXNzZXQgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzW2NdO1xuXG5cdFx0XHRjb25zb2xlLmxvZyggZC5uYW1lICwgZXZlbnQudXJsKTtcblxuXHRcdFx0c3dpdGNoIChkLmFzc2V0VHlwZSkge1xuXHRcdFx0XHRjYXNlIEFzc2V0VHlwZS5NRVNIOlxuXHRcdFx0XHRcdGlmIChldmVudC51cmwgPT0nYXNzZXRzL0hhbG9fM19TUEFSVEFONC5vYmonKSB7XG5cdFx0XHRcdFx0XHR2YXIgbWVzaDpNZXNoID0gPE1lc2g+IGQ7XG5cblx0XHRcdFx0XHRcdHRoaXMuc3BhcnRhbi5hZGRDaGlsZChtZXNoKTtcblx0XHRcdFx0XHRcdHRoaXMuc3BhcnRhbkZsYWcgPSB0cnVlO1xuXHRcdFx0XHRcdFx0dGhpcy5tZXNoZXMucHVzaChtZXNoKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGV2ZW50LnVybCA9PSdhc3NldHMvdGVycmFpbi5vYmonKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRlcnJhaW5PYmpGbGFnID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHRoaXMudGVycmFpbiA9IDxNZXNoPiBkO1xuXHRcdFx0XHRcdFx0dGhpcy50ZXJyYWluLnkgPSA5ODtcblx0XHRcdFx0XHRcdHRoaXMudmlldy5zY2VuZS5hZGRDaGlsZCh0aGlzLnRlcnJhaW4pO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIEFzc2V0VHlwZS5URVhUVVJFIDpcblx0XHRcdFx0XHRpZiAoZXZlbnQudXJsID09ICdhc3NldHMvbWFzdGVyY2hpZWZfYmFzZS5wbmcnICkge1xuXHRcdFx0XHRcdFx0dGhpcy5tYXQgPSBuZXcgVHJpYW5nbGVNZXRob2RNYXRlcmlhbCggPEltYWdlVGV4dHVyZT4gZCwgdHJ1ZSwgdHJ1ZSwgZmFsc2UgKTtcblx0XHRcdFx0XHRcdHRoaXMubWF0LmxpZ2h0UGlja2VyID0gbmV3IFN0YXRpY0xpZ2h0UGlja2VyKFt0aGlzLmxpZ2h0XSk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChldmVudC51cmwgPT0gJ2Fzc2V0cy9zdG9uZV90eC5qcGcnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRlcnJhaW5NYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKDxJbWFnZVRleHR1cmU+IGQsIHRydWUsIHRydWUsIGZhbHNlKTtcblx0XHRcdFx0XHRcdHRoaXMudGVycmFpbk1hdGVyaWFsLmxpZ2h0UGlja2VyID0gbmV3IFN0YXRpY0xpZ2h0UGlja2VyKFt0aGlzLmxpZ2h0XSk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMudGVycmFpbk9iakZsYWcgJiYgdGhpcy50ZXJyYWluTWF0ZXJpYWwpIHtcblx0XHRcdHRoaXMudGVycmFpbi5tYXRlcmlhbCA9IHRoaXMudGVycmFpbk1hdGVyaWFsO1xuXHRcdFx0dGhpcy50ZXJyYWluLmdlb21ldHJ5LnNjYWxlVVYoMjAsIDIwKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5tYXQgJiYgdGhpcy5zcGFydGFuRmxhZylcblx0XHRcdGZvciAodmFyIGM6bnVtYmVyID0gMDsgYyA8IHRoaXMubWVzaGVzLmxlbmd0aDsgYysrKVxuXHRcdFx0XHR0aGlzLm1lc2hlc1tjXS5tYXRlcmlhbCA9IHRoaXMubWF0O1xuXG5cdFx0dGhpcy52aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMuc3BhcnRhbik7XG5cdFx0dGhpcy5vblJlc2l6ZSgpO1xuXHR9XG5cblx0cHVibGljIG9uUmVzaXplKGV2ZW50OlVJRXZlbnQgPSBudWxsKVxuXHR7XG5cdFx0dGhpcy52aWV3LnkgPSAwO1xuXHRcdHRoaXMudmlldy54ID0gMDtcblxuXHRcdHRoaXMudmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMudmlldy5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cdH1cbn0iXX0= \ No newline at end of file diff --git a/tests/parsers/ObjParserTest.js b/tests/parsers/ObjParserTest.js new file mode 100755 index 000000000..c63e91ff4 --- /dev/null +++ b/tests/parsers/ObjParserTest.js @@ -0,0 +1,59 @@ +var View = require("awayjs-core/lib/containers/View"); +var Vector3D = require("awayjs-core/lib/core/geom/Vector3D"); +var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary"); +var URLRequest = require("awayjs-core/lib/core/net/URLRequest"); +var AssetEvent = require("awayjs-core/lib/events/AssetEvent"); +var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent"); +var Debug = require("awayjs-core/lib/utils/Debug"); +var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame"); +var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer"); +var OBJParser = require("awayjs-renderergl/lib/parsers/OBJParser"); +/** + * + */ +var ObjParserTest = (function () { + function ObjParserTest() { + var _this = this; + Debug.LOG_PI_ERRORS = true; + Debug.THROW_ERRORS = false; + AssetLibrary.enableParser(OBJParser); + this._token = AssetLibrary.load(new URLRequest('assets/t800.obj')); + this._token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); }); + this._token.addEventListener(AssetEvent.ASSET_COMPLETE, function (event) { return _this.onAssetComplete(event); }); + this._view = new View(new DefaultRenderer()); + this._timer = new RequestAnimationFrame(this.render, this); + window.onresize = function (event) { return _this.resize(event); }; + this._timer.start(); + this.resize(); + } + ObjParserTest.prototype.resize = function (event) { + if (event === void 0) { event = null; } + this._view.y = 0; + this._view.x = 0; + this._view.width = window.innerWidth; + this._view.height = window.innerHeight; + }; + ObjParserTest.prototype.render = function (dt) { + if (this._t800) + this._t800.rotationY += 1; + this._view.render(); + }; + ObjParserTest.prototype.onAssetComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('events.AssetEvent.ASSET_COMPLETE', AssetLibrary.getAsset(event.asset.name)); + console.log('------------------------------------------------------------------------------'); + }; + ObjParserTest.prototype.onResourceComplete = function (event) { + console.log('------------------------------------------------------------------------------'); + console.log('events.LoaderEvent.RESOURCE_COMPLETE', event); + console.log('------------------------------------------------------------------------------'); + console.log(AssetLibrary.getAsset('Mesh_g0')); + this._t800 = AssetLibrary.getAsset('Mesh_g0'); + this._t800.y = -200; + this._t800.transform.scale = new Vector3D(4, 4, 4); + this._view.scene.addChild(this._t800); + }; + return ObjParserTest; +})(); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlcnMvb2JqcGFyc2VydGVzdC50cyJdLCJuYW1lcyI6WyJPYmpQYXJzZXJUZXN0IiwiT2JqUGFyc2VyVGVzdC5jb25zdHJ1Y3RvciIsIk9ialBhcnNlclRlc3QucmVzaXplIiwiT2JqUGFyc2VyVGVzdC5yZW5kZXIiLCJPYmpQYXJzZXJUZXN0Lm9uQXNzZXRDb21wbGV0ZSIsIk9ialBhcnNlclRlc3Qub25SZXNvdXJjZUNvbXBsZXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUMvRCxJQUFPLFFBQVEsV0FBZ0Isb0NBQW9DLENBQUMsQ0FBQztBQUNyRSxJQUFPLFlBQVksV0FBZSwyQ0FBMkMsQ0FBQyxDQUFDO0FBRy9FLElBQU8sVUFBVSxXQUFlLHFDQUFxQyxDQUFDLENBQUM7QUFFdkUsSUFBTyxVQUFVLFdBQWUsbUNBQW1DLENBQUMsQ0FBQztBQUNyRSxJQUFPLFdBQVcsV0FBZSxvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3ZFLElBQU8sS0FBSyxXQUFnQiw2QkFBNkIsQ0FBQyxDQUFDO0FBQzNELElBQU8scUJBQXFCLFdBQVksNkNBQTZDLENBQUMsQ0FBQztBQUV2RixJQUFPLGVBQWUsV0FBYyxnREFBZ0QsQ0FBQyxDQUFDO0FBRXRGLElBQU8sU0FBUyxXQUFlLHlDQUF5QyxDQUFDLENBQUM7QUFFMUUsQUFHQTs7R0FERztJQUNHLGFBQWE7SUFPbEJBLFNBUEtBLGFBQWFBO1FBQW5CQyxpQkFnRUNBO1FBdkRDQSxLQUFLQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUMzQkEsS0FBS0EsQ0FBQ0EsWUFBWUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFM0JBLFlBQVlBLENBQUNBLFlBQVlBLENBQUNBLFNBQVNBLENBQUNBLENBQUVBO1FBRXRDQSxJQUFJQSxDQUFDQSxNQUFNQSxHQUFHQSxZQUFZQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxVQUFVQSxDQUFDQSxpQkFBaUJBLENBQUNBLENB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WUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0E7UUFDckRBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBO1FBQ3BCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxRQUFRQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxFQUFFQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUVuREEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0E7SUFDdkNBLENBQUNBO0lBQ0ZMLG9CQUFDQTtBQUFEQSxDQWhFQSxBQWdFQ0EsSUFBQSIsImZpbGUiOiJwYXJzZXJzL09ialBhcnNlclRlc3QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtcmVuZGVyZXJnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQXNzZXRMaWJyYXJ5XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMaWJyYXJ5XCIpO1xuaW1wb3J0IEFzc2V0TG9hZGVyXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMb2FkZXJcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJUb2tlblx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclRva2VuXCIpO1xuaW1wb3J0IFVSTFJlcXVlc3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTFJlcXVlc3RcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgQXNzZXRFdmVudFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZXZlbnRzL0Fzc2V0RXZlbnRcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBEZWJ1Z1x0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi91dGlscy9EZWJ1Z1wiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcblxuaW1wb3J0IE9CSlBhcnNlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtcmVuZGVyZXJnbC9saWIvcGFyc2Vycy9PQkpQYXJzZXJcIik7XG5cbi8qKlxuICpcbiAqL1xuY2xhc3MgT2JqUGFyc2VyVGVzdFxue1xuXHRwcml2YXRlIF92aWV3OlZpZXc7XG5cdHByaXZhdGUgX3Rva2VuOkFzc2V0TG9hZGVyVG9rZW47XG5cdHByaXZhdGUgX3RpbWVyOlJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0cHJpdmF0ZSBfdDgwMDpNZXNoO1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdERlYnVnLkxPR19QSV9FUlJPUlMgPSB0cnVlO1xuXHRcdERlYnVnLlRIUk9XX0VSUk9SUyA9IGZhbHNlO1xuXG5cdFx0QXNzZXRMaWJyYXJ5LmVuYWJsZVBhcnNlcihPQkpQYXJzZXIpIDtcblxuXHRcdHRoaXMuX3Rva2VuID0gQXNzZXRMaWJyYXJ5LmxvYWQobmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy90ODAwLm9iaicpKTtcblx0XHR0aGlzLl90b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFLCAoZXZlbnQ6TG9hZGVyRXZlbnQpID0+IHRoaXMub25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50KSk7XG5cdFx0dGhpcy5fdG9rZW4uYWRkRXZlbnRMaXN0ZW5lcihBc3NldEV2ZW50LkFTU0VUX0NPTVBMRVRFLCAoZXZlbnQ6QXNzZXRFdmVudCkgPT4gdGhpcy5vbkFzc2V0Q29tcGxldGUoZXZlbnQpKTtcblxuXHRcdHRoaXMuX3ZpZXcgPSBuZXcgVmlldyhuZXcgRGVmYXVsdFJlbmRlcmVyKCkpO1xuXHRcdHRoaXMuX3RpbWVyID0gbmV3IFJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlciwgdGhpcyk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgPSAoZXZlbnQ6VUlFdmVudCkgPT4gdGhpcy5yZXNpemUoZXZlbnQpO1xuXG5cdFx0dGhpcy5fdGltZXIuc3RhcnQoKTtcblx0XHR0aGlzLnJlc2l6ZSgpO1xuXHR9XG5cblx0cHJpdmF0ZSByZXNpemUoZXZlbnQ6VUlFdmVudCA9IG51bGwpXG5cdHtcblx0XHR0aGlzLl92aWV3LnkgPSAwO1xuXHRcdHRoaXMuX3ZpZXcueCA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKSAvL2FuaW1hdGUgYmFzZWQgb24gZHQgZm9yIGZpcmVmb3hcblx0e1xuXHRcdGlmICh0aGlzLl90ODAwKVxuXHRcdFx0dGhpcy5fdDgwMC5yb3RhdGlvblkgKz0gMTtcblxuXHRcdHRoaXMuX3ZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgb25Bc3NldENvbXBsZXRlKGV2ZW50OkFzc2V0RXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdFx0Y29uc29sZS5sb2coJ2V2ZW50cy5Bc3NldEV2ZW50LkFTU0VUX0NPTVBMRVRFJywgQXNzZXRMaWJyYXJ5LmdldEFzc2V0KGV2ZW50LmFzc2V0Lm5hbWUpKTtcblx0XHRjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG5cdH1cblxuXHRwdWJsaWMgb25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50OkxvYWRlckV2ZW50KVxuXHR7XG5cdFx0Y29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuXHRcdGNvbnNvbGUubG9nKCdldmVudHMuTG9hZGVyRXZlbnQuUkVTT1VSQ0VfQ09NUExFVEUnLCBldmVudCk7XG5cdFx0Y29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuXG5cdFx0Y29uc29sZS5sb2coQXNzZXRMaWJyYXJ5LmdldEFzc2V0KCdNZXNoX2cwJykpO1xuXG5cdFx0dGhpcy5fdDgwMCA9IDxNZXNoPiBBc3NldExpYnJhcnkuZ2V0QXNzZXQoJ01lc2hfZzAnKTtcblx0XHR0aGlzLl90ODAwLnkgPSAtMjAwO1xuXHRcdHRoaXMuX3Q4MDAudHJhbnNmb3JtLnNjYWxlID0gbmV3IFZlY3RvcjNEKDQsIDQsIDQpO1xuXG5cdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZCh0aGlzLl90ODAwKTtcblx0fVxufSJdfQ== \ No newline at end of file