<commit_before>Fireworks.ComboEmitter.Flamethrower	= function(opts){
	this._container	= opts.container|| console.assert(false, "container MUST be defined");
	this._emitter	= null;	
	this._onReady	= opts.onReady	|| function(comboEmitter){};
	
	if( WebAudio.isAvailable ){
		this._webaudio	= opts.webaudio	|| new WebAudio();
		this._baseSound	= null;
		this._sound	= null;		
	}
	
	this._source3D	= null;
	this._target3D	= null;
	
	// data to handle attackTime/releaseTime
	this._state	= 'stopped';
	this._lastStart	= 0;
	this._lastStop	= 0;
	this._attackTime	= 1.0;
	this._releaseTime	= 0.3;
	
	// contruct each parts
	this._emitterCtor();
	WebAudio.isAvailable && this._soundCtor();

	// update the emitter in rendering loop
	this._$loopCb	= world.loop().hook(this._loopCb.bind(this));
}

Fireworks.ComboEmitter.Flamethrower.prototype._destroy	= function()
{
	world.loop().unhook(this._$loopCb);
	this._emitterDtor();
	WebAudio.isAvailable && this._soundDtor();
}

// inherit from Fireworks.ComboEmitter
Fireworks.ComboEmitter.Flamethrower.prototype			= new Fireworks.ComboEmitter();
Fireworks.ComboEmitter.Flamethrower.prototype.constructor	= Fireworks.ComboEmitter.Flamethrower;

//////////////////////////////////////////////////////////////////////////////////
//		Getter								//
//////////////////////////////////////////////////////////////////////////////////

Fireworks.ComboEmitter.Flamethrower.prototype.start	= function(){
	if( this._state === 'started' )	return;
	console.assert( this._state === 'stopped' )
	this._state	= 'started';
	this._lastStart	= Date.now()/1000;
}

Fireworks.ComboEmitter.Flamethrower.prototype.stop	= function(){
	if( this._state === 'stopped' )	return;
	console.assert( this._state === 'started' );
	this._state	= 'stopped';
	this._lastStop	= Date.now()/1000;
};

Fireworks.ComboEmitter.Flamethrower.prototype.ungracefullStop	= function(){
	this._state	= 'stopped';
	this._lastStop	= 0;
};

/**
 * @return {boolean} true if it is ready, false otherwise
*/
Fireworks.ComboEmitter.Flamethrower.prototype.isReady	= function(){
	// test if the sound has been loaded
	if( !this._baseSound.isPlayable() )	return false;
	// test the spritesheet has been loaded
	if( !this._emitter )			return false;
	// if all previous tests passed, it is ready
	return true;
};

Fireworks.ComboEmitter.Flamethrower.prototype._notifyReadyIfPossible	= function(){
	if( this.isReady() === false )	return;
	this._onReady(this);
};

//////////////////////////////////////////////////////////////////////////////////
//		Getter								//
//////////////////////////////////////////////////////////////////////////////////

Fireworks.ComboEmitter.Flamethrower.prototype.object3D	= function(){
	return this._container;
};

Fireworks.ComboEmitter.Flamethrower.prototype.sound	= function(){
	return this._baseSound;
};

Fireworks.ComboEmitter.Flamethrower.prototype.source3D	= function(value){
	if( value === undefined )	return this._source3D;
	console.assert(value instanceof THREE.Object3D);
	this._source3D	= value;
	return this;
};

Fireworks.ComboEmitter.Flamethrower.prototype.target3D	= function(value){
	if( value === undefined )	return this._source3D;
	console.assert(value instanceof THREE.Object3D);
	this._target3D	= value;
	return this;
};

//////////////////////////////////////////////////////////////////////////////////
//		rendering loop function						//
//////////////////////////////////////////////////////////////////////////////////


Fireworks.ComboEmitter.Flamethrower.prototype._loopCb	= function(delta, now){
	// if this.is_ready() is false, return now
	if( this.isReady() === false ) return;
	
	// update and render this._emitter
	this._emitter.update(delta).render();

	// handle intensity depending on attackTime/releaseTime
	console.assert( this._state === 'started' || this._state === 'stopped' );	
	var present	= Date.now()/1000;
	if( this._state === 'started' ){
		if( present - this._lastStart <= this._attackTime ){
			var intensity	= (present - this._lastStart) / this._attackTime;		
		}else{
			var intensity	= 1;
		}
		this._emitter.intensity( intensity );
	}else if( this._state === 'stopped' ){
		if( present - this._lastStop <= this._releaseTime ){
			var intensity	= 1 - (present - this._lastStop) / this._releaseTime;			
		}else{
			var intensity	= 0;
		}
		this._emitter.intensity( intensity );
	}

	if( this._target3D && this._source3D ){
		// TODO should i recompute the matrix ??
		var posSource	= this._source3D.matrixWorld.getPosition().clone();
		var posTarget	= this._target3D.matrixWorld.getPosition().clone();
		var velocity	= posTarget.subSelf(posSource);
		this._emitter.effect('velocity').opts.shape.position.copy(velocity);	
	}

	// if this._source3D is defined use it for setting position
	if( this._source3D ){
		// TODO should i recompute the matrix ??
		var posSource	= this._source3D.matrixWorld.getPosition().clone();
		var posContainer= this._container.matrixWorld.getPosition().clone();
		var position	= posSource.subSelf(posContainer);
		this._emitter.effect('position').opts.shape.position.copy(position);	
	}


	// set gravity in local space
	var effect	= this._emitter.effect('gravity');
	var position	= effect.opts.shape.position.set(0, 10, 0);
	// TODO should i recompute the matrix ??
	var matrix	= this._container.matrixWorld.clone().setPosition({x:0,y:0,z:0}).transpose();
	matrix.multiplyVector3(position);
}<commit_msg>more on particle in world space - fix #50<commit_after>Fireworks.ComboEmitter.Flamethrower	= function(opts){
	this._container	= opts.container|| console.assert(false, "container MUST be defined");
	this._emitter	= null;	
	this._onReady	= opts.onReady	|| function(comboEmitter){};
	
	if( WebAudio.isAvailable ){
		this._webaudio	= opts.webaudio	|| new WebAudio();
		this._baseSound	= null;
		this._sound	= null;		
	}
	
	this._source3D	= null;
	this._target3D	= null;
	
	// data to handle attackTime/releaseTime
	this._state	= 'stopped';
	this._lastStart	= 0;
	this._lastStop	= 0;
	this._attackTime	= 1.0;
	this._releaseTime	= 0.3;
	
	// contruct each parts
	this._emitterCtor();
	WebAudio.isAvailable && this._soundCtor();

	// update the emitter in rendering loop
	this._$loopCb	= world.loop().hook(this._loopCb.bind(this));
}

Fireworks.ComboEmitter.Flamethrower.prototype._destroy	= function()
{
	world.loop().unhook(this._$loopCb);
	this._emitterDtor();
	WebAudio.isAvailable && this._soundDtor();
}

// inherit from Fireworks.ComboEmitter
Fireworks.ComboEmitter.Flamethrower.prototype			= new Fireworks.ComboEmitter();
Fireworks.ComboEmitter.Flamethrower.prototype.constructor	= Fireworks.ComboEmitter.Flamethrower;

//////////////////////////////////////////////////////////////////////////////////
//		Getter								//
//////////////////////////////////////////////////////////////////////////////////

Fireworks.ComboEmitter.Flamethrower.prototype.start	= function(){
	if( this._state === 'started' )	return;
	console.assert( this._state === 'stopped' )
	this._state	= 'started';
	this._lastStart	= Date.now()/1000;
}

Fireworks.ComboEmitter.Flamethrower.prototype.stop	= function(){
	if( this._state === 'stopped' )	return;
	console.assert( this._state === 'started' );
	this._state	= 'stopped';
	this._lastStop	= Date.now()/1000;
};

Fireworks.ComboEmitter.Flamethrower.prototype.ungracefullStop	= function(){
	this._state	= 'stopped';
	this._lastStop	= 0;
};

/**
 * @return {boolean} true if it is ready, false otherwise
*/
Fireworks.ComboEmitter.Flamethrower.prototype.isReady	= function(){
	// test if the sound has been loaded
	if( !this._baseSound.isPlayable() )	return false;
	// test the spritesheet has been loaded
	if( !this._emitter )			return false;
	// if all previous tests passed, it is ready
	return true;
};

Fireworks.ComboEmitter.Flamethrower.prototype._notifyReadyIfPossible	= function(){
	if( this.isReady() === false )	return;
	this._onReady(this);
};

//////////////////////////////////////////////////////////////////////////////////
//		Getter								//
//////////////////////////////////////////////////////////////////////////////////

Fireworks.ComboEmitter.Flamethrower.prototype.object3D	= function(){
	return this._container;
};

Fireworks.ComboEmitter.Flamethrower.prototype.sound	= function(){
	return this._baseSound;
};

Fireworks.ComboEmitter.Flamethrower.prototype.source3D	= function(value){
	if( value === undefined )	return this._source3D;
	console.assert(value instanceof THREE.Object3D);
	this._source3D	= value;
	return this;
};

Fireworks.ComboEmitter.Flamethrower.prototype.target3D	= function(value){
	if( value === undefined )	return this._source3D;
	console.assert(value instanceof THREE.Object3D);
	this._target3D	= value;
	return this;
};

//////////////////////////////////////////////////////////////////////////////////
//		rendering loop function						//
//////////////////////////////////////////////////////////////////////////////////


Fireworks.ComboEmitter.Flamethrower.prototype._loopCb	= function(delta, now){
	// if this.is_ready() is false, return now
	if( this.isReady() === false ) return;
	
	// update and render this._emitter
	this._emitter.update(delta).render();

	// handle intensity depending on attackTime/releaseTime
	console.assert( this._state === 'started' || this._state === 'stopped' );	
	var present	= Date.now()/1000;
	if( this._state === 'started' ){
		if( present - this._lastStart <= this._attackTime ){
			var intensity	= (present - this._lastStart) / this._attackTime;		
		}else{
			var intensity	= 1;
		}
		this._emitter.intensity( intensity );
	}else if( this._state === 'stopped' ){
		if( present - this._lastStop <= this._releaseTime ){
			var intensity	= 1 - (present - this._lastStop) / this._releaseTime;			
		}else{
			var intensity	= 0;
		}
		this._emitter.intensity( intensity );
	}

	// if target3D and source3D are defined, use it to set velocity
	// TODO should i recompute the matrixWorld ??
	if( this._target3D && this._source3D ){
		var posSource	= this._source3D.matrixWorld.getPosition().clone();
		var posTarget	= this._target3D.matrixWorld.getPosition().clone();
		var velocity	= posTarget.subSelf(posSource);
		this._emitter.effect('velocity').opts.shape.position.copy(velocity);	
	}

	// if this._source3D is defined, use it for setting position
	// TODO should i recompute the matrixWorld ??
	if( this._source3D ){
		var posSource	= this._source3D.matrixWorld.getPosition().clone();
		var posContainer= this._container.matrixWorld.getPosition().clone();
		var position	= posSource.subSelf(posContainer);
		this._emitter.effect('position').opts.shape.position.copy(position);	
	}


	// set gravity in local space
	// TODO should i recompute the matrix ??
	var effect	= this._emitter.effect('gravity');
	var position	= effect.opts.shape.position.set(0, 10, 0);
	var matrix	= this._container.matrixWorld.clone().setPosition({x:0,y:0,z:0}).transpose();
	matrix.multiplyVector3(position);
}
{'fraction_non_alphanumeric': 0.21790168745414526, 'fraction_numerical': 0.009170946441672781, 'mean_word_length': 2.8384371700105597, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1556499', 'n_tokens_mistral': 3551, 'n_tokens_neox': 3388, 'n_words': 678}