topical media & game development
mobile-query-three-vendor-threex-threex.sparks.js / js
// This THREEx helper makes it even easier to use spark.js with three.js
// * FIXME This is currently only with WebGL
//
// # Code
//
var THREEx = THREEx || {};
THREEx.Sparks = function(opts)
{
opts = opts || {};
this._maxParticles = opts.maxParticles || console.assert(false);
this._texture = opts.texture || this._buildDefaultTexture();
var counter = opts.counter || console.assert(false);
var vertexIndexPool = {
__pools: [],
// Get a new Vector
get: function() {
if( this.__pools.length > 0 ) return this.__pools.pop();
console.assert(false, "pool ran out!")
return null;
},
// Release a vector back into the pool
add: function(v){ this.__pools.push(v); }
};
var particles = new THREE.Geometry();
var vertices = particles.vertices;
for ( i = 0; i < this._maxParticles; i++ ) {
var position = new THREE.Vector3(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
vertices.push(new THREE.Vertex(position));
vertexIndexPool.add(i);
}
// to handle window resize
this._onWindowResize, false);
var attributes = this._attributes = {
size : { type: 'f', value: [] },
aColor : { type: 'c', value: [] }
};
var uniforms = this._uniforms = {
texture : { type: "t", texture: this._texture },
color : { type: "c", value: new THREE.Color(0xffffff) },
sizeRatio : { type: "f", value: this._computeSizeRatio() }
};
// fill attributes array
var valuesSize = this._attributes.size.value;
var valuesColor = this._attributes.aColor.value;
for(var v = 0; v < particles.vertices.length; v++ ){
valuesSize[v] = 99;
valuesColor[v] = new THREE.Color( 0x000000 );
}
var material = new THREE.ShaderMaterial( {
uniforms : this._uniforms,
attributes : this._attributes,
vertexShader : THREEx.Sparks.vertexShaderText,
fragmentShader : THREEx.Sparks.fragmentShaderText,
blending : THREE.AdditiveBlending,
depthWrite : false,
transparent : true
});
this._group = new THREE.ParticleSystem( particles, material );
//this._group.dynamic = true;
//this._group.sortParticles = true; // TODO is this needed ?
/ EMITTER STUFF
var setTargetParticle = function() {
var vertexIdx = vertexIndexPool.get();
var target = {
vertexIdx : vertexIdx,
size : function(value){ valuesSize[vertexIdx] = value; },
color : function(){ return valuesColor[vertexIdx]; }
};
return target;
};
var onParticleCreated = function(particle) {
var vertexIdx = particle.target.vertexIdx;
// copy particle position into three.js geometry
vertices[vertexIdx].position = particle.position;
};
var onParticleDead = function(particle) {
var vertexIdx = particle.target.vertexIdx;
// Hide the particle
valuesColor[vertexIdx].setHex( 0x000000 );
vertices[vertexIdx].position.set(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
// Mark particle system as available by returning to pool
vertexIndexPool.add( vertexIdx );
};
var emitter = this._emitter = new SPARKS.Emitter(counter);
emitter.addInitializer(new SPARKS.Target(null, setTargetParticle));
emitter.addCallback("created" , onParticleCreated );
emitter.addCallback("dead" , onParticleDead );
}
THREEx.Sparks.prototype.destroy = function()
{
window.removeEventListener('resize', this._
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.