starling-framework
Version:
A fast, productive library for 2D cross-platform development.
385 lines (369 loc) • 14.5 kB
JavaScript
// Class: starling.extensions.ParticleSystem
var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this
$global.Object.defineProperty(exports, "__esModule", {value: true});
var __map_reserved = {};
// Imports
var $hxClasses = require("./../../hxClasses_stub").default;
var $hxEnums = require("./../../hxEnums_stub").default;
var $import = require("./../../import_stub").default;
var $bind = require("./../../bind_stub").default;
var $extend = require("./../../extend_stub").default;
function starling_animation_IAnimatable() {return require("./../../starling/animation/IAnimatable");}
function starling_display_Mesh() {return require("./../../starling/display/Mesh");}
function starling_display_BlendMode() {return require("./../../starling/display/BlendMode");}
function starling_extensions_Particle() {return require("./../../starling/extensions/Particle");}
function Std() {return require("./../../Std");}
function openfl_geom_Rectangle() {return $import(require("openfl/geom/Rectangle"));}
function starling_utils_MatrixUtil() {return require("./../../starling/utils/MatrixUtil");}
function openfl__$Vector_Vector_$Impl_$() {return require("./../../openfl/_Vector/Vector_Impl_");}
function starling_rendering_VertexData() {return require("./../../starling/rendering/VertexData");}
function openfl_geom_Matrix() {return $import(require("openfl/geom/Matrix"));}
function openfl_geom_Point() {return $import(require("openfl/geom/Point"));}
function starling_utils_MeshSubset() {return require("./../../starling/utils/MeshSubset");}
function starling_rendering_IndexData() {return require("./../../starling/rendering/IndexData");}
// Constructor
var ParticleSystem = function(texture) {
this._numParticles = 0;
this._vertexData = new (starling_rendering_VertexData().default)();
this._indexData = new (starling_rendering_IndexData().default)();
(starling_display_Mesh().default).call(this,this._vertexData,this._indexData);
this._particles = (openfl__$Vector_Vector_$Impl_$().default)._new(0,false);
this._frameTime = 0.0;
this._emitterX = this._emitterY = 0.0;
this._emissionTime = 0.0;
this._emissionRate = 10;
this._blendFactorSource = "one";
this._blendFactorDestination = "oneMinusSourceAlpha";
this._batchable = false;
this.set_capacity(128);
this.set_texture(texture);
this.updateBlendMode();
}
// Meta
ParticleSystem.__name__ = "starling.extensions.ParticleSystem";
ParticleSystem.__isInterface__ = false;
ParticleSystem.__interfaces__ = [(starling_animation_IAnimatable().default)];
ParticleSystem.__super__ = (starling_display_Mesh().default);
ParticleSystem.prototype = $extend((starling_display_Mesh().default).prototype, {
dispose: function() {
this._effect.dispose();
(starling_display_Mesh().default).prototype.dispose.call(this);
},
hitTest: function(localPoint) {
return null;
},
updateBlendMode: function() {
var pma = this.get_texture() != null ? this.get_texture().get_premultipliedAlpha() : true;
if(this._blendFactorSource == "one" && this._blendFactorDestination == "oneMinusSourceAlpha") {
this._vertexData.set_premultipliedAlpha(pma);
if(!pma) {
this._blendFactorSource = "sourceAlpha";
}
} else {
this._vertexData.set_premultipliedAlpha(false);
}
var registeredBlendMode = (starling_display_BlendMode().default).getByFactors(this._blendFactorSource,this._blendFactorDestination);
if(registeredBlendMode != null) {
this.set_blendMode(registeredBlendMode.get_name());
} else {
this.set_blendMode(this._blendFactorSource + ", " + this._blendFactorDestination);
(starling_display_BlendMode().default).register(this.get_blendMode(),this._blendFactorSource,this._blendFactorDestination);
}
},
createParticle: function() {
return new (starling_extensions_Particle().default)();
},
initParticle: function(particle) {
particle.x = this._emitterX;
particle.y = this._emitterY;
particle.currentTime = 0;
particle.totalTime = 1;
particle.color = (Std().default).int(Math.random() * 16777215);
},
advanceParticle: function(particle,passedTime) {
particle.y += passedTime * 250;
particle.alpha = 1.0 - particle.currentTime / particle.totalTime;
particle.currentTime += passedTime;
},
setRequiresSync: function(_) {
this._requiresSync = true;
},
syncBuffers: function() {
this._effect.uploadVertexData(this._vertexData);
this._effect.uploadIndexData(this._indexData);
this._requiresSync = false;
},
start: function(duration) {
if(duration == null) {
duration = 1.79e+308;
}
if(this._emissionRate != 0) {
this._emissionTime = duration;
}
},
stop: function(clearParticles) {
if(clearParticles == null) {
clearParticles = false;
}
this._emissionTime = 0.0;
if(clearParticles) {
this.clear();
}
},
clear: function() {
this._numParticles = 0;
},
getBounds: function(targetSpace,resultRect) {
if(resultRect == null) {
resultRect = new (openfl_geom_Rectangle().default)();
}
this.getTransformationMatrix(targetSpace,ParticleSystem.sHelperMatrix);
(starling_utils_MatrixUtil().default).transformCoords(ParticleSystem.sHelperMatrix,0,0,ParticleSystem.sHelperPoint);
resultRect.x = ParticleSystem.sHelperPoint.x;
resultRect.y = ParticleSystem.sHelperPoint.y;
resultRect.width = resultRect.height = 0;
return resultRect;
},
advanceTime: function(passedTime) {
this.setRequiresRedraw();
this.setRequiresSync();
var particleIndex = 0;
var particle;
var maxNumParticles = this.get_capacity();
while(particleIndex < this._numParticles) {
particle = this._particles[particleIndex];
if(particle.currentTime < particle.totalTime) {
this.advanceParticle(particle,passedTime);
++particleIndex;
} else {
if(particleIndex != this._numParticles - 1) {
var nextParticle = this._particles[(Std().default).int(this._numParticles - 1)];
(openfl__$Vector_Vector_$Impl_$().default).set(this._particles,(Std().default).int(this._numParticles - 1),particle);
(openfl__$Vector_Vector_$Impl_$().default).set(this._particles,particleIndex,nextParticle);
}
--this._numParticles;
if(this._numParticles == 0 && this._emissionTime == 0) {
this.dispatchEventWith("complete");
}
}
}
if(this._emissionTime > 0) {
var timeBetweenParticles = 1.0 / this._emissionRate;
this._frameTime += passedTime;
while(this._frameTime > 0) {
if(this._numParticles < maxNumParticles) {
particle = this._particles[this._numParticles];
this.initParticle(particle);
if(particle.totalTime > 0.0) {
this.advanceParticle(particle,this._frameTime);
++this._numParticles;
}
}
this._frameTime -= timeBetweenParticles;
}
if(this._emissionTime != 1.79e+308) {
this._emissionTime = this._emissionTime > passedTime ? this._emissionTime - passedTime : 0.0;
}
if(this._numParticles == 0 && this._emissionTime == 0) {
this.dispatchEventWith("complete");
}
}
var vertexID = 0;
var rotation;
var x;
var y;
var offsetX;
var offsetY;
var pivotX = this.get_texture() != null ? this.get_texture().get_width() / 2 : 5;
var pivotY = this.get_texture() != null ? this.get_texture().get_height() / 2 : 5;
var _g = 0;
var _g1 = this._numParticles;
while(_g < _g1) {
var i = _g++;
vertexID = i * 4;
particle = this._particles[i];
rotation = particle.rotation;
offsetX = pivotX * particle.scale;
offsetY = pivotY * particle.scale;
x = particle.x;
y = particle.y;
this._vertexData.colorize("color",particle.color,particle.alpha,vertexID,4);
if(rotation != 0) {
var cos = Math.cos(rotation);
var sin = Math.sin(rotation);
var cosX = cos * offsetX;
var cosY = cos * offsetY;
var sinX = sin * offsetX;
var sinY = sin * offsetY;
this._vertexData.setPoint(vertexID,"position",x - cosX + sinY,y - sinX - cosY);
this._vertexData.setPoint(vertexID + 1,"position",x + cosX + sinY,y + sinX - cosY);
this._vertexData.setPoint(vertexID + 2,"position",x - cosX - sinY,y - sinX + cosY);
this._vertexData.setPoint(vertexID + 3,"position",x + cosX - sinY,y + sinX + cosY);
} else {
this._vertexData.setPoint(vertexID,"position",x - offsetX,y - offsetY);
this._vertexData.setPoint(vertexID + 1,"position",x + offsetX,y - offsetY);
this._vertexData.setPoint(vertexID + 2,"position",x - offsetX,y + offsetY);
this._vertexData.setPoint(vertexID + 3,"position",x + offsetX,y + offsetY);
}
}
},
render: function(painter) {
if(this._numParticles != 0) {
if(this._batchable) {
ParticleSystem.sSubset.setTo(0,this._numParticles * 4,0,this._numParticles * 6);
painter.batchMesh(this,ParticleSystem.sSubset);
} else {
painter.finishMeshBatch();
var _g = painter;
_g.set_drawCount(_g.get_drawCount() + 1);
painter.prepareToDraw();
painter.excludeFromCache(this);
if(this._requiresSync) {
this.syncBuffers();
}
this.get_style().updateEffect(this._effect,painter.get_state());
this._effect.render(0,this._numParticles * 2);
}
}
},
populate: function(count) {
var maxNumParticles = this.get_capacity();
count = (Std().default).int(Math.min(count,maxNumParticles - this._numParticles));
var p;
var _g = 0;
var _g1 = count;
while(_g < _g1) {
var i = _g++;
p = this._particles[this._numParticles + i];
this.initParticle(p);
this.advanceParticle(p,Math.random() * p.totalTime);
}
this._numParticles += count;
},
get_capacity: function() {
return (Std().default).int(this._vertexData.get_numVertices() / 4);
},
set_capacity: function(value) {
var i;
var oldCapacity = this.get_capacity();
var newCapacity = value > 16383 ? 16383 : value;
var baseVertexData = new (starling_rendering_VertexData().default)(this.get_style().get_vertexFormat(),4);
var texture = this.get_texture();
if(texture != null) {
texture.setupVertexPositions(baseVertexData);
texture.setupTextureCoordinates(baseVertexData);
} else {
baseVertexData.setPoint(0,"position",0,0);
baseVertexData.setPoint(1,"position",10,0);
baseVertexData.setPoint(2,"position",0,10);
baseVertexData.setPoint(3,"position",10,10);
}
var _g = oldCapacity;
var _g1 = newCapacity;
while(_g < _g1) {
var i1 = _g++;
var numVertices = i1 * 4;
baseVertexData.copyTo(this._vertexData,numVertices);
this._indexData.addQuad(numVertices,numVertices + 1,numVertices + 2,numVertices + 3);
(openfl__$Vector_Vector_$Impl_$().default).set(this._particles,i1,this.createParticle());
}
if(newCapacity < oldCapacity) {
this._particles.length = newCapacity;
this._indexData.set_numIndices(newCapacity * 6);
this._vertexData.set_numVertices(newCapacity * 4);
if(this._numParticles > newCapacity) {
this._numParticles = newCapacity;
}
}
this._indexData.trim();
this._vertexData.trim();
this.setRequiresSync();
return value;
},
get_isEmitting: function() {
if(this._emissionTime > 0) {
return this._emissionRate > 0;
} else {
return false;
}
},
get_numParticles: function() {
return this._numParticles;
},
get_emissionRate: function() {
return this._emissionRate;
},
set_emissionRate: function(value) {
return this._emissionRate = value;
},
get_emitterX: function() {
return this._emitterX;
},
set_emitterX: function(value) {
return this._emitterX = value;
},
get_emitterY: function() {
return this._emitterY;
},
set_emitterY: function(value) {
return this._emitterY = value;
},
get_blendFactorSource: function() {
return this._blendFactorSource;
},
set_blendFactorSource: function(value) {
this._blendFactorSource = value;
this.updateBlendMode();
return value;
},
get_blendFactorDestination: function() {
return this._blendFactorDestination;
},
set_blendFactorDestination: function(value) {
this._blendFactorDestination = value;
this.updateBlendMode();
return value;
},
set_texture: function(value) {
(starling_display_Mesh().default).prototype.set_texture.call(this,value);
if(value != null) {
var i = this._vertexData.get_numVertices() - 4;
while(i >= 0) {
value.setupVertexPositions(this._vertexData,i);
value.setupTextureCoordinates(this._vertexData,i);
i -= 4;
}
}
this.updateBlendMode();
return value;
},
setStyle: function(meshStyle,mergeWithPredecessor) {
if(mergeWithPredecessor == null) {
mergeWithPredecessor = true;
}
(starling_display_Mesh().default).prototype.setStyle.call(this,meshStyle,mergeWithPredecessor);
if(this._effect != null) {
this._effect.dispose();
}
this._effect = this.get_style().createEffect();
this._effect.set_onRestore($bind(this,this.setRequiresSync));
},
get_batchable: function() {
return this._batchable;
},
set_batchable: function(value) {
this._batchable = value;
this.setRequiresRedraw();
return value;
}
});
ParticleSystem.prototype.__class__ = ParticleSystem.prototype.constructor = $hxClasses["starling.extensions.ParticleSystem"] = ParticleSystem;
// Init
Object.defineProperties(ParticleSystem.prototype,{ capacity : { get : function () { return this.get_capacity (); }, set : function (v) { return this.set_capacity (v); }}, isEmitting : { get : function () { return this.get_isEmitting (); }}, numParticles : { get : function () { return this.get_numParticles (); }}, emissionRate : { get : function () { return this.get_emissionRate (); }, set : function (v) { return this.set_emissionRate (v); }}, emitterX : { get : function () { return this.get_emitterX (); }, set : function (v) { return this.set_emitterX (v); }}, emitterY : { get : function () { return this.get_emitterY (); }, set : function (v) { return this.set_emitterY (v); }}, blendFactorSource : { get : function () { return this.get_blendFactorSource (); }, set : function (v) { return this.set_blendFactorSource (v); }}, blendFactorDestination : { get : function () { return this.get_blendFactorDestination (); }, set : function (v) { return this.set_blendFactorDestination (v); }}, batchable : { get : function () { return this.get_batchable (); }, set : function (v) { return this.set_batchable (v); }}});
// Statics
ParticleSystem.MAX_NUM_PARTICLES = 16383
ParticleSystem.sHelperMatrix = new (openfl_geom_Matrix().default)()
ParticleSystem.sHelperPoint = new (openfl_geom_Point().default)()
ParticleSystem.sSubset = new (starling_utils_MeshSubset().default)()
// Export
exports.default = ParticleSystem;