forked from LeenkxTeam/LNXSDK
moisesjpelaez - Physics Improvements
This commit is contained in:
parent
9824dc5a44
commit
2e77f67683
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user