moisesjpelaez - Physics Improvements
This commit is contained in:
		| @ -2,6 +2,7 @@ package iron.object; | ||||
|  | ||||
| #if lnx_particles | ||||
|  | ||||
| import kha.FastFloat; | ||||
| import kha.graphics4.Usage; | ||||
| import kha.arrays.Float32Array; | ||||
| import iron.data.Data; | ||||
| @ -16,39 +17,45 @@ import iron.math.Vec4; | ||||
| class ParticleSystem { | ||||
| 	public var data: ParticleData; | ||||
| 	public var speed = 1.0; | ||||
| 	var currentSpeed = 0.0; | ||||
| 	var particles: Array<Particle>; | ||||
| 	var ready: Bool; | ||||
| 	public var frameRate = 24; | ||||
| 	public var lifetime = 0.0; | ||||
| 	public var animtime = 0.0; | ||||
| 	public var time = 0.0; | ||||
| 	public var spawnRate = 0.0; | ||||
| 	var frameRate = 24; | ||||
| 	var lifetime = 0.0; | ||||
| 	var animtime = 0.0; | ||||
| 	var time = 0.0; | ||||
| 	var spawnRate = 0.0; | ||||
| 	var looptime = 0.0; | ||||
| 	var seed = 0; | ||||
|  | ||||
| 	public var r: TParticleData; | ||||
| 	public var gx: Float; | ||||
| 	public var gy: Float; | ||||
| 	public var gz: Float; | ||||
| 	public var alignx: Float; | ||||
| 	public var aligny: Float; | ||||
| 	public var alignz: Float; | ||||
| 	var r: TParticleData; | ||||
| 	var gx: Float; | ||||
| 	var gy: Float; | ||||
| 	var gz: Float; | ||||
| 	var alignx: Float; | ||||
| 	var aligny: Float; | ||||
| 	var alignz: Float; | ||||
| 	var dimx: Float; | ||||
| 	var dimy: Float; | ||||
| 	var tilesx: Int; | ||||
| 	var tilesy: Int; | ||||
| 	var tilesFramerate: Int; | ||||
|  | ||||
| 	public var count = 0; | ||||
| 	public var lap = 0; | ||||
| 	public var lapTime = 0.0; | ||||
| 	var count = 0; | ||||
| 	var lap = 0; | ||||
| 	var lapTime = 0.0; | ||||
| 	var m = Mat4.identity(); | ||||
|  | ||||
| 	var ownerLoc = new Vec4(); | ||||
| 	var ownerRot = new Quat(); | ||||
| 	var ownerScl = new Vec4(); | ||||
| 	 | ||||
| 	var random = 0.0; | ||||
|  | ||||
| 	public function new(sceneName: String, pref: TParticleReference) { | ||||
| 		seed = pref.seed; | ||||
| 		currentSpeed = speed; | ||||
| 		speed = 0; | ||||
| 		particles = []; | ||||
| 		ready = false; | ||||
| 		 | ||||
| @ -65,34 +72,61 @@ class ParticleSystem { | ||||
| 				gy = 0; | ||||
| 				gz = -9.81 * r.weight_gravity; | ||||
| 			} | ||||
| 			alignx = r.object_align_factor[0] / 2; | ||||
| 			aligny = r.object_align_factor[1] / 2; | ||||
| 			alignz = r.object_align_factor[2] / 2; | ||||
| 			alignx = r.object_align_factor[0]; | ||||
| 			aligny = r.object_align_factor[1]; | ||||
| 			alignz = r.object_align_factor[2]; | ||||
| 			looptime = (r.frame_end - r.frame_start) / frameRate; | ||||
| 			lifetime = r.lifetime / frameRate; | ||||
| 			animtime = (r.frame_end - r.frame_start) / frameRate; | ||||
| 			animtime = r.loop ? looptime : looptime + lifetime; | ||||
| 			spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate; | ||||
|  | ||||
| 			for (i in 0...r.count) { | ||||
| 				var particle = new Particle(i); | ||||
| 				particle.sr = 1 - Math.random() * r.size_random; | ||||
| 				particles.push(particle); | ||||
| 				particles.push(new Particle(i)); | ||||
| 			} | ||||
|  | ||||
| 			ready = true; | ||||
| 			if (r.auto_start){ | ||||
| 				start(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	public function start() { | ||||
| 		if (r.is_unique) random = Math.random(); | ||||
| 		lifetime = r.lifetime / frameRate; | ||||
| 		time = 0; | ||||
| 		lap = 0; | ||||
| 		lapTime = 0; | ||||
| 		speed = currentSpeed; | ||||
| 	} | ||||
|  | ||||
| 	public function pause() { | ||||
| 		lifetime = 0; | ||||
| 		speed = 0; | ||||
| 	} | ||||
|  | ||||
| 	public function resume() { | ||||
| 		lifetime = r.lifetime / frameRate; | ||||
| 		speed = currentSpeed; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	// TODO: interrupt smoothly | ||||
| 	public function stop() { | ||||
| 		end(); | ||||
| 	} | ||||
|  | ||||
| 	function end() { | ||||
| 		lifetime = 0; | ||||
| 		speed = 0; | ||||
| 		lap = 0; | ||||
| 	} | ||||
| 	 | ||||
| 	public function update(object: MeshObject, owner: MeshObject) { | ||||
| 		if (!ready || object == null || speed == 0.0) return; | ||||
|  | ||||
| 		var prevLap = lap; | ||||
|  | ||||
| 		// Copy owner world transform but discard scale | ||||
| 		owner.transform.world.decompose(ownerLoc, ownerRot, ownerScl); | ||||
| 		object.transform.loc = ownerLoc; | ||||
| @ -115,17 +149,21 @@ class ParticleSystem { | ||||
| 		} | ||||
|  | ||||
| 		// Animate | ||||
| 		time += Time.delta * speed; | ||||
| 		time += Time.renderDelta * speed; | ||||
| 		lap = Std.int(time / animtime); | ||||
| 		lapTime = time - lap * animtime; | ||||
| 		count = Std.int(lapTime / spawnRate); | ||||
|  | ||||
| 		if (lap > prevLap && !r.loop) { | ||||
| 			end(); | ||||
| 		} | ||||
| 		 | ||||
| 		updateGpu(object, owner); | ||||
| 	} | ||||
|  | ||||
| 	public function getData(): Mat4 { | ||||
| 		var hair = r.type == 1; | ||||
| 		m._00 = r.loop ? animtime : -animtime; | ||||
| 		m._00 = animtime; | ||||
| 		m._01 = hair ? 1 / particles.length : spawnRate; | ||||
| 		m._02 = hair ? 1 : lifetime; | ||||
| 		m._03 = particles.length; | ||||
| @ -133,9 +171,9 @@ class ParticleSystem { | ||||
| 		m._11 = hair ? 0 : aligny; | ||||
| 		m._12 = hair ? 0 : alignz; | ||||
| 		m._13 = hair ? 0 : r.factor_random; | ||||
| 		m._20 = hair ? 0 : gx * r.mass; | ||||
| 		m._21 = hair ? 0 : gy * r.mass; | ||||
| 		m._22 = hair ? 0 : gz * r.mass; | ||||
| 		m._20 = hair ? 0 : gx; | ||||
| 		m._21 = hair ? 0 : gy; | ||||
| 		m._22 = hair ? 0 : gz; | ||||
| 		m._23 = hair ? 0 : r.lifetime_random; | ||||
| 		m._30 = tilesx; | ||||
| 		m._31 = tilesy; | ||||
| @ -144,13 +182,25 @@ class ParticleSystem { | ||||
| 		return m; | ||||
| 	} | ||||
|  | ||||
| 	public function getSizeRandom(): FastFloat { | ||||
| 		return r.size_random; | ||||
| 	} | ||||
|  | ||||
| 	public function getRandom(): FastFloat { | ||||
| 		return random; | ||||
| 	} | ||||
|  | ||||
| 	public function getSize(): FastFloat { | ||||
| 		return r.particle_size; | ||||
| 	} | ||||
|  | ||||
| 	function updateGpu(object: MeshObject, owner: MeshObject) { | ||||
| 		if (!object.data.geom.instanced) setupGeomGpu(object, owner); | ||||
| 		// GPU particles transform is attached to owner object | ||||
| 	} | ||||
|  | ||||
| 	public function setupGeomGpu(object: MeshObject, owner: MeshObject) { | ||||
| 		var instancedData = new Float32Array(particles.length * 6); | ||||
| 	function setupGeomGpu(object: MeshObject, owner: MeshObject) { | ||||
| 		var instancedData = new Float32Array(particles.length * 3); | ||||
| 		var i = 0; | ||||
|  | ||||
| 		var normFactor = 1 / 32767; // pa.values are not normalized | ||||
| @ -169,10 +219,6 @@ class ParticleSystem { | ||||
| 					instancedData.set(i, pa.values[j * pa.size    ] * normFactor * scaleFactor.x); i++; | ||||
| 					instancedData.set(i, pa.values[j * pa.size + 1] * normFactor * scaleFactor.y); i++; | ||||
| 					instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); i++; | ||||
|  | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 				} | ||||
|  | ||||
| 			case 1: // Face | ||||
| @ -196,10 +242,6 @@ class ParticleSystem { | ||||
| 					instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++; | ||||
| 					instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++; | ||||
| 					instancedData.set(i, pos.z * normFactor * scaleFactor.z); i++; | ||||
|  | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 				} | ||||
|  | ||||
| 			case 2: // Volume | ||||
| @ -210,13 +252,9 @@ class ParticleSystem { | ||||
| 					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.x); i++; | ||||
| 					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); i++; | ||||
| 					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z); i++; | ||||
|  | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 					instancedData.set(i, p.sr); i++; | ||||
| 				} | ||||
| 		} | ||||
| 		object.data.geom.setupInstanced(instancedData, 3, Usage.StaticUsage); | ||||
| 		object.data.geom.setupInstanced(instancedData, 1, Usage.StaticUsage); | ||||
| 	} | ||||
|  | ||||
| 	function fhash(n: Int): Float { | ||||
| @ -255,10 +293,11 @@ class ParticleSystem { | ||||
|  | ||||
| class Particle { | ||||
| 	public var i: Int; | ||||
| 	public var px = 0.0; | ||||
| 	public var py = 0.0; | ||||
| 	public var pz = 0.0; | ||||
| 	public var sr = 1.0; // Size random | ||||
| 	 | ||||
| 	public var x = 0.0; | ||||
| 	public var y = 0.0; | ||||
| 	public var z = 0.0; | ||||
|  | ||||
| 	public var cameraDistance: Float; | ||||
|  | ||||
| 	public function new(i: Int) { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user