Repe [T3DU] Update - 31f26d171bba0355ce2a77031e3aad4c64dbc7e9

This commit is contained in:
2026-09-04 10:46:13 -07:00
parent c915312901
commit 0460b9d587
482 changed files with 27797 additions and 3226 deletions

View File

@ -8,6 +8,7 @@ import iron.data.SceneFormat;
import iron.math.Quat;
import iron.math.Vec3;
import iron.math.Vec4;
import iron.object.CurveObject;
import iron.object.MeshObject;
import iron.object.Object;
import iron.system.Time;
@ -19,6 +20,10 @@ import kha.arrays.Uint32Array;
class ParticleSystemCPU {
public var data: ParticleData;
public var speed: FastFloat = 1.0; // Not used yet. Added to go in hand with `ParticleSystemGPU`
public var curveGuides: Array<CurveObject> = [];
public var curveGuideStrength: FastFloat = 1.0;
public var curveGuideSpeed: FastFloat = 1.0;
var paused: Bool = false;
var r: TParticleData;
// Format
@ -37,6 +42,7 @@ class ParticleSystemCPU {
// Velocity
var velocity: Vec3 = new Vec3(0.0, 0.0, 1.0); // object_align_factor: Float32Array
var velocityRandom: FastFloat = 0.0; // factor_random
var normalFactor: FastFloat = 0.0;
// Rotation
var rotation: Bool = false; // use_rotations
@ -114,11 +120,12 @@ class ParticleSystemCPU {
scale = r.particle_size;
scaleRandom = r.size_random;
velocity = new Vec3(r.object_align_factor[0], r.object_align_factor[1], r.object_align_factor[2]).mult(frameRate / baseFrameRate).mult(1 / scale);
velocity = new Vec3(r.object_align_factor[0], r.object_align_factor[1], r.object_align_factor[2]).mult(frameRate / baseFrameRate);
velocityRandom = r.factor_random * (frameRate / baseFrameRate);
normalFactor = r.normal_factor * (frameRate / baseFrameRate);
if (Scene.active.raw.gravity != null) {
gravity = new Vec3(Scene.active.raw.gravity[0], Scene.active.raw.gravity[1], Scene.active.raw.gravity[2]).mult(frameRate / baseFrameRate).mult(1 / scale);
gravity = new Vec3(Scene.active.raw.gravity[0], Scene.active.raw.gravity[1], Scene.active.raw.gravity[2]).mult(frameRate / baseFrameRate);
}
gravityFactor = r.weight_gravity * (frameRate / baseFrameRate);
textureFactor = r.weight_texture;
@ -139,39 +146,36 @@ class ParticleSystemCPU {
scaleElementsCount = getRampElementsLength();
scaleRampSizeFactor = getRampSizeFactor();
switch (type) {
case 0: // Emission
loopAnim = {
tick: function () {
spawnTime += Time.delta * Time.scale;
var expected: Int = Math.floor(spawnTime / spawnRate);
while (spawnedParticles < expected && spawnedParticles < count) {
spawnParticle();
spawnedParticles++;
}
updateParticles();
},
target: null,
props: null,
duration: loop ? lifetimeSeconds : lifetimeSeconds * 2,
done: function () {
if (loop) start();
}
}
Scene.active.notifyOnInit(function () {
if (autoStart) start();
});
case 1: // Hair
Scene.active.notifyOnInit(function () {
for (i in 0...count) spawnParticle();
});
default:
}
Scene.active.notifyOnInit(function () {
for (i in 0...count) addToPool();
switch (type) {
case 0: // Emission
loopAnim = {
tick: function () {
if (paused) return;
spawnTime += Time.delta;
var expected: Int = Math.floor(spawnTime / spawnRate);
while (spawnedParticles < expected && spawnedParticles < count) {
spawnParticle();
spawnedParticles++;
}
updateParticles();
},
target: null,
props: null,
duration: loop ? lifetimeSeconds : lifetimeSeconds * 2,
done: function () {
if (loop) start();
}
}
if (autoStart) start();
case 1: // Hair
for (i in 0...count) spawnParticle();
default:
}
});
});
}
@ -182,14 +186,12 @@ class ParticleSystemCPU {
Tween.to(loopAnim);
}
// TODO
public function pause() {
paused = true;
}
// TODO
public function resume() {
paused = false;
}
public function stop() {
@ -246,6 +248,8 @@ class ParticleSystemCPU {
var scalePos: FastFloat = owner.data.scalePos;
var scalePosParticle: FastFloat = cast(o, MeshObject).data.scalePos;
var normDir: Vec3 = new Vec3();
// TODO: add all properties from Blender's UI
switch (emitFrom) {
case 0: // Vertices
@ -253,6 +257,8 @@ class ParticleSystemCPU {
var i: Int = Std.int(Math.random() * (pa.values.length / pa.size));
var loc: Vec4 = new Vec4(pa.values[i * pa.size] * normFactor, pa.values[i * pa.size + 1] * normFactor, pa.values[i * pa.size + 2] * normFactor, 1);
if (normalFactor != 0.0) normDir = new Vec3(loc.x, loc.y, loc.z).normalize();
if (!localCoords) {
loc.applyQuat(objectRot);
loc.add(objectPos);
@ -274,6 +280,9 @@ class ParticleSystemCPU {
var pos: Vec3 = randomPointInTriangle(v0, v1, v2);
var loc: Vec4 = new Vec4(pos.x, pos.y, pos.z, 1).mult(normFactor);
if (normalFactor != 0.0) normDir = new Vec3(loc.x, loc.y, loc.z).normalize();
if (!localCoords) {
loc.applyQuat(objectRot);
loc.add(objectPos);
@ -285,6 +294,8 @@ class ParticleSystemCPU {
scaleFactorVolume.mult(0.5);
var loc: Vec4 = new Vec4((Math.random() * 2.0 - 1.0) * scaleFactorVolume.x, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z, 1);
if (normalFactor != 0.0) normDir = new Vec3(loc.x, loc.y, loc.z).normalize();
if (!localCoords) {
loc.applyQuat(objectRot);
loc.add(objectPos);
@ -310,7 +321,9 @@ class ParticleSystemCPU {
var randomZ: FastFloat = (Math.random() * 2 / (scale * particleScale) - 1 / (scale * particleScale)) * velocityRandom;
var g: Vec3 = new Vec3();
var rotatedVelocity: Vec4 = new Vec4(velocity.x + randomX, velocity.y + randomY, velocity.z + randomZ, 1);
if (normalFactor != 0.0) normDir = normDir.mult(normalFactor);
var rotatedVelocity: Vec4 = new Vec4(velocity.x + randomX + normDir.x, velocity.y + randomY + normDir.y, velocity.z + randomZ + normDir.z, 1);
if (!localCoords) rotatedVelocity.applyQuat(objectRot);
if (rotation) {
@ -371,7 +384,7 @@ class ParticleSystemCPU {
function updateParticles() {
for (particle => physics in particlePhysics) {
physics.age += Time.delta * Time.scale;
physics.age += Time.delta;
if (physics.age >= physics.lifetime) {
particlePhysics.remove(particle);
@ -379,14 +392,63 @@ class ParticleSystemCPU {
continue;
}
physics.velocity.x += physics.gravity.x * Time.delta * Time.scale;
physics.velocity.y += physics.gravity.y * Time.delta * Time.scale;
physics.velocity.z += physics.gravity.z * Time.delta * Time.scale;
physics.velocity.x += physics.gravity.x * Time.delta;
physics.velocity.y += physics.gravity.y * Time.delta;
physics.velocity.z += physics.gravity.z * Time.delta;
if (curveGuides != null && curveGuides.length > 0) {
var curveVelX: FastFloat = 0.0;
var curveVelY: FastFloat = 0.0;
var curveVelZ: FastFloat = 0.0;
var validCurves: Int = 0;
for (curve in curveGuides) {
if (curve != null && curve.data != null && curve.data.splines != null && curve.splinesLength > 0) {
var t = physics.age / physics.lifetime;
var tangent = curve.getTangent(t, 0);
tangent.w = 0.0;
tangent.applymat4(curve.transform.world);
tangent.normalize();
var curveLen = curve.getLength(0);
var speed = (curveLen / physics.lifetime) * curveGuideSpeed;
var tgtX = tangent.x * speed;
var tgtY = tangent.y * speed;
var tgtZ = tangent.z * speed;
if (localCoords) {
var targetVel = new Vec4(tgtX, tgtY, tgtZ, 0.0);
var invOwnerRot = new Quat(-owner.transform.rot.x, -owner.transform.rot.y, -owner.transform.rot.z, owner.transform.rot.w);
targetVel.applyQuat(invOwnerRot);
tgtX = targetVel.x;
tgtY = targetVel.y;
tgtZ = targetVel.z;
}
curveVelX += tgtX;
curveVelY += tgtY;
curveVelZ += tgtZ;
validCurves++;
}
}
if (validCurves > 0) {
curveVelX /= validCurves;
curveVelY /= validCurves;
curveVelZ /= validCurves;
physics.velocity.x += (curveVelX - physics.velocity.x) * curveGuideStrength;
physics.velocity.y += (curveVelY - physics.velocity.y) * curveGuideStrength;
physics.velocity.z += (curveVelZ - physics.velocity.z) * curveGuideStrength;
}
}
particle.transform.translate(
physics.velocity.x * Time.delta * Time.scale,
physics.velocity.y * Time.delta * Time.scale,
physics.velocity.z * Time.delta * Time.scale
physics.velocity.x * Time.delta,
physics.velocity.y * Time.delta,
physics.velocity.z * Time.delta
);
if (rotation && dynamicRotation && orientationAxis == 3) setVelocityHair(particle, physics.velocity, randQuat, phaseQuat);