<commit_before>package com.babylonhx.particles;

import com.babylonhx.materials.Effect;
import com.babylonhx.materials.textures.Texture;
import com.babylonhx.math.Color4;
import com.babylonhx.math.Matrix;
import com.babylonhx.math.Vector3;
import com.babylonhx.mesh.BabylonBuffer;
import com.babylonhx.particles.Particle;
import com.babylonhx.tools.Tools;

#if nme
import nme.utils.Float32Array;
#elseif openfl
import openfl.utils.Float32Array;
#elseif snow
import snow.utils.Float32Array;
#elseif kha

#end


/**
 * ...
 * @author <NAME>
 */

class ParticleSystem implements IDisposable {
	
	// Statics
	public static var BLENDMODE_ONEONE:Int = 0;
	public static var BLENDMODE_STANDARD:Int = 1;

	// Members
	public var name:String;
	public var id:String;
	public var renderingGroupId:Int = 0;
	public var emitter:Dynamic = null;
	public var emitRate:Int = 10;
	public var manualEmitCount:Int = -1;
	public var updateSpeed:Float = 0.01;
	public var targetStopDuration:Float = 0;
	public var disposeOnStop:Bool = false;
	
	public var __smartArrayFlags:Array<Int>;

	public var minEmitPower:Float = 1;
	public var maxEmitPower:Float = 1;

	public var minLifeTime:Float = 1;
	public var maxLifeTime:Float = 1;

	public var minSize:Float = 1;
	public var maxSize:Float = 1;
	public var minAngularSpeed:Float = 0;
	public var maxAngularSpeed:Float = 0;

	public var particleTexture:Texture;

	public var onDispose:Void->Void;
	public var updateFunction:Array<Particle>->Void;

	public var blendMode:Int = ParticleSystem.BLENDMODE_ONEONE;

	public var forceDepthWrite:Bool = false;

	public var gravity:Vector3 = Vector3.Zero();
	public var direction1:Vector3 = new Vector3(0, 1.0, 0);
	public var direction2:Vector3 = new Vector3(0, 1.0, 0);
	public var minEmitBox:Vector3 = new Vector3(-0.5, -0.5, -0.5);
	public var maxEmitBox:Vector3 = new Vector3(0.5, 0.5, 0.5);
	public var color1:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var color2:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var colorDead:Color4 = new Color4(0, 0, 0, 1.0);
	public var textureMask:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var startDirectionFunction:Float->Matrix->Vector3->Void;
	public var startPositionFunction:Matrix->Vector3->Void;

	private var particles:Array<Particle> = [];
	private var particle:Particle;

	private var _capacity:Int;
	private var _scene:Scene;
	private var _vertexDeclaration:Array<Int> = [3, 4, 4];
	private var _vertexStrideSize:Int = 11 * 4; // 11 floats per particle (x, y, z, r, g, b, a, angle, size, offsetX, offsetY)
	private var _stockParticles:Array<Particle> = [];
	private var _newPartsExcess:Int = 0;
	private var _vertexBuffer:BabylonBuffer;
	private var _indexBuffer:BabylonBuffer;
	#if html5
	public var _vertices:Float32Array;
	#else
    public var _vertices:Array<Float>;
    #end
	private var _effect:Effect;
	private var _customEffect:Effect;
	private var _cachedDefines:String;

	private var _scaledColorStep:Color4 = new Color4(0, 0, 0, 0);
	private var _colorDiff:Color4 = new Color4(0, 0, 0, 0);
	private var _scaledDirection:Vector3 = Vector3.Zero();
	private var _scaledGravity:Vector3 = Vector3.Zero();
	private var _currentRenderId:Int = -1;

	private var _alive:Bool = true;
	private var _started:Bool = false;
	private var _stopped:Bool = false;
	private var _actualFrame:Int = 0;
	private var _scaledUpdateSpeed:Float;

	public function new(name:String, capacity:Int, scene:Scene, ?customEffect:Effect) {
		this.name = name;
		this.id = name;
		this._capacity = capacity;
		
		this._scene = scene;
		
		this._customEffect = customEffect;
		
		scene.particleSystems.push(this);
		
		// VBO
		this._vertexBuffer = scene.getEngine().createDynamicVertexBuffer(capacity * this._vertexStrideSize * 4);
		
		var indices:Array<Int> = [];
		var index:Int = 0;
		for (count in 0...capacity) {
			indices.push(index);
			indices.push(index + 1);
			indices.push(index + 2);
			indices.push(index);
			indices.push(index + 2);
			indices.push(index + 3);
			index += 4;
		}
		
		this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
		
		#if html5
		this._vertices = new Float32Array(capacity * this._vertexStrideSize);
		#else
        this._vertices = [];
        #end
		
		// Default behaviors
		this.startDirectionFunction = function(emitPower:Float, worldMatrix:Matrix, directionToUpdate:Vector3):Void {
			var randX = randomNumber(this.direction1.x, this.direction2.x);
			var randY = randomNumber(this.direction1.y, this.direction2.y);
			var randZ = randomNumber(this.direction1.z, this.direction2.z);
			
			Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
		}
		
		this.startPositionFunction = function(worldMatrix:Matrix, positionToUpdate:Vector3):Void {
			var randX = randomNumber(this.minEmitBox.x, this.maxEmitBox.x);
			var randY = randomNumber(this.minEmitBox.y, this.maxEmitBox.y);
			var randZ = randomNumber(this.minEmitBox.z, this.maxEmitBox.z);
			
			Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
		}
		
		this.updateFunction = function(particles:Array<Particle>):Void {
			var index:Int = 0;
			while (index < particles.length) {
				var particle = particles[index];
				particle.age += this._scaledUpdateSpeed;
				
				if (particle.age >= particle.lifeTime) { // Recycle
					particles.splice(index, 1);
					this._stockParticles.push(particle);
					index--;
					continue;
				}
				else {
					particle.colorStep.scaleToRef(this._scaledUpdateSpeed, this._scaledColorStep);
					particle.color.addInPlace(this._scaledColorStep);
					
					if (particle.color.a < 0) {
						particle.color.a = 0;
					}
					
					particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
					
					particle.direction.scaleToRef(this._scaledUpdateSpeed, this._scaledDirection);
					particle.position.addInPlace(this._scaledDirection);
					
					this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
					particle.direction.addInPlace(this._scaledGravity);
				}
				
				index++;
			}
		}
	}

	public function getCapacity():Int {
		return this._capacity;
	}<commit_msg>Fixing particles<commit_after>package com.babylonhx.particles;

import com.babylonhx.materials.Effect;
import com.babylonhx.materials.textures.Texture;
import com.babylonhx.math.Color4;
import com.babylonhx.math.Matrix;
import com.babylonhx.math.Vector3;
import com.babylonhx.mesh.BabylonBuffer;
import com.babylonhx.particles.Particle;
import com.babylonhx.tools.Tools;

#if nme
import nme.utils.Float32Array;
#elseif openfl
import openfl.utils.Float32Array;
#elseif snow
import snow.utils.Float32Array;
#elseif kha

#end


/**
 * ...
 * @author <NAME>
 */

class ParticleSystem implements IDisposable {
	
	// Statics
	public static var BLENDMODE_ONEONE:Int = 0;
	public static var BLENDMODE_STANDARD:Int = 1;

	// Members
	public var name:String;
	public var id:String;
	public var renderingGroupId:Int = 0;
	public var emitter:Dynamic = null;
	public var emitRate:Int = 10;
	public var manualEmitCount:Int = -1;
	public var updateSpeed:Float = 0.01;
	public var targetStopDuration:Float = 0;
	public var disposeOnStop:Bool = false;
	
	public var __smartArrayFlags:Array<Int>;

	public var minEmitPower:Float = 1;
	public var maxEmitPower:Float = 1;

	public var minLifeTime:Float = 1;
	public var maxLifeTime:Float = 1;

	public var minSize:Float = 1;
	public var maxSize:Float = 1;
	public var minAngularSpeed:Float = 0;
	public var maxAngularSpeed:Float = 0;

	public var particleTexture:Texture;

	public var onDispose:Void->Void;
	public var updateFunction:Array<Particle>->Void;

	public var blendMode:Int = ParticleSystem.BLENDMODE_ONEONE;

	public var forceDepthWrite:Bool = false;

	public var gravity:Vector3 = Vector3.Zero();
	public var direction1:Vector3 = new Vector3(0, 1.0, 0);
	public var direction2:Vector3 = new Vector3(0, 1.0, 0);
	public var minEmitBox:Vector3 = new Vector3(-0.5, -0.5, -0.5);
	public var maxEmitBox:Vector3 = new Vector3(0.5, 0.5, 0.5);
	public var color1:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var color2:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var colorDead:Color4 = new Color4(0, 0, 0, 1.0);
	public var textureMask:Color4 = new Color4(1.0, 1.0, 1.0, 1.0);
	public var startDirectionFunction:Float->Matrix->Vector3->Void;
	public var startPositionFunction:Matrix->Vector3->Void;

	private var particles:Array<Particle> = [];
	private var particle:Particle;

	private var _capacity:Int;
	private var _scene:Scene;
	private var _vertexDeclaration:Array<Int> = [3, 4, 4];
	private var _vertexStrideSize:Int = 11 * 4; // 11 floats per particle (x, y, z, r, g, b, a, angle, size, offsetX, offsetY)
	private var _stockParticles:Array<Particle> = [];
	private var _newPartsExcess:Int = 0;
	private var _vertexBuffer:BabylonBuffer;
	private var _indexBuffer:BabylonBuffer;
	#if html5
	public var _vertices:Float32Array;
	#else
    public var _vertices:Array<Float>;
    #end
	private var _effect:Effect;
	private var _customEffect:Effect;
	private var _cachedDefines:String;

	private var _scaledColorStep:Color4 = new Color4(0, 0, 0, 0);
	private var _colorDiff:Color4 = new Color4(0, 0, 0, 0);
	private var _scaledDirection:Vector3 = Vector3.Zero();
	private var _scaledGravity:Vector3 = Vector3.Zero();
	private var _currentRenderId:Int = -1;

	private var _alive:Bool = true;
	private var _started:Bool = false;
	private var _stopped:Bool = false;
	private var _actualFrame:Int = 0;
	private var _scaledUpdateSpeed:Float;

	public function new(name:String, capacity:Int, scene:Scene, ?customEffect:Effect) {
		this.name = name;
		this.id = name;
		this._capacity = capacity;
		
		this._scene = scene;
		
		this._customEffect = customEffect;
		
		scene.particleSystems.push(this);
		
		// VBO
		this._vertexBuffer = scene.getEngine().createDynamicVertexBuffer(capacity * this._vertexStrideSize * 4);
		
		var indices:Array<Int> = [];
		var index:Int = 0;
		for (count in 0...capacity) {
			indices.push(index);
			indices.push(index + 1);
			indices.push(index + 2);
			indices.push(index);
			indices.push(index + 2);
			indices.push(index + 3);
			index += 4;
		}
		
		this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
		
		#if html5
		this._vertices = new Float32Array(capacity * this._vertexStrideSize);
		#else
        this._vertices = [];
        #end
		
		// Default behaviors
		this.startDirectionFunction = function(emitPower:Float, worldMatrix:Matrix, directionToUpdate:Vector3):Void {
			var randX = randomNumber(this.direction1.x, this.direction2.x);
			var randY = randomNumber(this.direction1.y, this.direction2.y);
			var randZ = randomNumber(this.direction1.z, this.direction2.z);
			
			Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
		}
		
		this.startPositionFunction = function(worldMatrix:Matrix, positionToUpdate:Vector3):Void {
			var randX = randomNumber(this.minEmitBox.x, this.maxEmitBox.x);
			var randY = randomNumber(this.minEmitBox.y, this.maxEmitBox.y);
			var randZ = randomNumber(this.minEmitBox.z, this.maxEmitBox.z);
			
			Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
		}
		
		this.updateFunction = function(particles:Array<Particle>):Void {
			var index:Int = 0;
			while (index < particles.length) {
				var particle = particles[index];
				particle.age += this._scaledUpdateSpeed;
				
				if (particle.age >= particle.lifeTime) { // Recycle
					particles.splice(index, 1);
					this._stockParticles.push(particle);
				}
				else {
					particle.colorStep.scaleToRef(this._scaledUpdateSpeed, this._scaledColorStep);
					particle.color.addInPlace(this._scaledColorStep);
					
					if (particle.color.a < 0) {
						particle.color.a = 0;
					}
					
					particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
					
					particle.direction.scaleToRef(this._scaledUpdateSpeed, this._scaledDirection);
					particle.position.addInPlace(this._scaledDirection);
					
					this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
					particle.direction.addInPlace(this._scaledGravity);
					index++;
				}
			}
		}
	}

	public function getCapacity():Int {
		return this._capacity;
	}
{'fraction_non_alphanumeric': 0.11456814130610922, 'fraction_numerical': 0.024955436720142603, 'mean_word_length': 4.343290043290043, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, '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': '920240', 'n_tokens_mistral': 4725, 'n_tokens_neox': 4136, 'n_words': 939}