attempt make work on js, and much faster particles

This commit is contained in:
RandomityGuy 2022-11-25 12:47:46 +05:30
parent ee73aacdba
commit 16939ccc44
2 changed files with 48 additions and 63 deletions

View file

@ -1,5 +1,8 @@
package src; package src;
import shaders.DtsTexture;
import h3d.parts.Particles;
import h3d.Matrix;
import src.TimeState; import src.TimeState;
import h3d.prim.UV; import h3d.prim.UV;
import h3d.parts.Data.BlendMode; import h3d.parts.Data.BlendMode;
@ -17,6 +20,7 @@ import h3d.mat.Material;
import h3d.Vector; import h3d.Vector;
import h3d.scene.MeshBatch; import h3d.scene.MeshBatch;
import h3d.scene.Mesh; import h3d.scene.Mesh;
import src.ResourceLoader;
@:publicFields @:publicFields
class ParticleData { class ParticleData {
@ -28,6 +32,8 @@ class ParticleData {
@:publicFields @:publicFields
class Particle { class Particle {
public var part:h3d.parts.Particle;
var data:ParticleData; var data:ParticleData;
var manager:ParticleManager; var manager:ParticleManager;
var o:ParticleOptions; var o:ParticleOptions;
@ -53,6 +59,8 @@ class Particle {
this.lifeTime = this.o.lifetime + this.o.lifetimeVariance * (Math.random() * 2 - 1); this.lifeTime = this.o.lifetime + this.o.lifetimeVariance * (Math.random() * 2 - 1);
this.initialSpin = Util.lerp(this.o.spinRandomMin, this.o.spinRandomMax, Math.random()); this.initialSpin = Util.lerp(this.o.spinRandomMin, this.o.spinRandomMax, Math.random());
this.part = new h3d.parts.Particle();
} }
public function update(time:Float, dt:Float) { public function update(time:Float, dt:Float) {
@ -134,6 +142,15 @@ class Particle {
// Adjust sizing // Adjust sizing
this.scale = Util.lerp(this.o.sizes[indexLow], this.o.sizes[indexHigh], t); this.scale = Util.lerp(this.o.sizes[indexLow], this.o.sizes[indexHigh], t);
this.part.x = this.position.x;
this.part.y = this.position.y;
this.part.z = this.position.z;
this.part.r = this.color.r;
this.part.g = this.color.g;
this.part.b = this.color.b;
this.part.ratio = 1;
this.part.size = this.scale;
} }
} }
@ -269,12 +286,15 @@ class ParticleEmitter {
} }
class ParticleManager { class ParticleManager {
var particlebatches:Array<ParticleBatch> = []; // var particlebatches:Array<ParticleBatch> = [];
var particlebatchMap:Map<String, Int> = []; // var particlebatchMap:Map<String, Int> = [];
var level:MarbleWorld; var level:MarbleWorld;
var scene:Scene; var scene:Scene;
var currentTime:Float; var currentTime:Float;
var particleGroups:Map<String, Particles> = [];
var particles:Array<Particle> = [];
var emitters:Array<ParticleEmitter> = []; var emitters:Array<ParticleEmitter> = [];
public function new(level:MarbleWorld) { public function new(level:MarbleWorld) {
@ -284,76 +304,36 @@ class ParticleManager {
public function update(currentTime:Float, dt:Float) { public function update(currentTime:Float, dt:Float) {
this.currentTime = currentTime; this.currentTime = currentTime;
for (batch in particlebatches) { for (particle in this.particles) {
for (instance in batch.instances) particle.update(currentTime, dt);
instance.update(currentTime, dt);
} }
this.tick(dt); this.tick(dt);
for (batch in particlebatches) {
batch.meshBatch.begin(batch.instances.length);
for (instance in batch.instances) {
if (instance.currentAge != 0) {
batch.meshBatch.setPosition(instance.position.x, instance.position.y, instance.position.z);
var particleShader = batch.meshBatch.material.mainPass.getShader(Billboard);
particleShader.scale = instance.scale;
particleShader.rotation = instance.rotation;
particleShader.color = instance.color;
batch.meshBatch.material.blendMode = instance.o.blending;
batch.meshBatch.material.mainPass.depthWrite = false;
// batch.meshBatch.material.mainPass.setPassName("overlay");
// batch.meshBatch.material.color.load(instance.color);
batch.meshBatch.shadersChanged = true;
batch.meshBatch.setScale(instance.scale);
batch.meshBatch.emitInstance();
}
}
}
} }
public function addParticle(particleData:ParticleData, particle:Particle) { public function addParticle(particleData:ParticleData, particle:Particle) {
if (particlebatchMap.exists(particleData.identifier)) { if (particleGroups.exists(particleData.identifier)) {
particlebatches[particlebatchMap.get(particleData.identifier)].instances.push(particle); particleGroups[particleData.identifier].add(particle.part);
} else { } else {
var pts = [ var pGroup = new Particles(particle.data.texture, this.scene);
new Point(-0.5, -0.5, 0), pGroup.hasColor = true;
new Point(-0.5, 0.5, 0), pGroup.material.setDefaultProps("ui");
new Point(0.5, -0.5, 0), // var pdts = new DtsTexture(pGroup.material.texture);
new Point(0.5, 0.5) // pdts.currentOpacity = 1;
]; pGroup.material.blendMode = particle.o.blending;
var prim = new Polygon(pts); pGroup.material.mainPass.depthWrite = false;
prim.idx = new IndexBuffer(); // pGroup.material.mainPass.removeShader(pGroup.material.textureShader);
prim.idx.push(0); // pGroup.material.mainPass.addShader(pdts);
prim.idx.push(1); pGroup.add(particle.part);
prim.idx.push(2); particleGroups.set(particleData.identifier, pGroup);
prim.idx.push(1);
prim.idx.push(3);
prim.idx.push(2);
prim.uvs = [new UV(0, 0), new UV(0, 1), new UV(1, 0), new UV(1, 1)];
prim.addNormals();
var mat = Material.create(particleData.texture);
// matshader.texture = mat.texture;
mat.mainPass.enableLights = false;
// mat.mainPass.setPassName("overlay");
// mat.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
mat.shadows = false;
mat.texture.wrap = Wrap.Repeat;
var billboardShader = new Billboard();
mat.mainPass.addShader(billboardShader);
var mb = new MeshBatch(prim, mat, this.scene);
var batch:ParticleBatch = {
instances: [particle],
meshBatch: mb
};
var curidx = particlebatches.length;
particlebatches.push(batch);
particlebatchMap.set(particleData.identifier, curidx);
} }
this.particles.push(particle);
} }
public function removeParticle(particleData:ParticleData, particle:Particle) { public function removeParticle(particleData:ParticleData, particle:Particle) {
if (particlebatchMap.exists(particleData.identifier)) { if (particleGroups.exists(particleData.identifier)) {
particlebatches[particlebatchMap.get(particleData.identifier)].instances.remove(particle); @:privateAccess particleGroups[particleData.identifier].kill(particle.part);
} }
this.particles.remove(particle);
} }
public function getTime() { public function getTime() {
@ -377,9 +357,10 @@ class ParticleManager {
} }
public function removeEverything() { public function removeEverything() {
for (particle in this.particlebatches) { for (ident => particles in this.particleGroups) {
particle.instances = []; particles.remove();
} }
this.particleGroups = [];
for (emitter in this.emitters) for (emitter in this.emitters)
this.removeEmitter(emitter); this.removeEmitter(emitter);
} }

View file

@ -196,6 +196,10 @@ class ResourceLoader {
} }
} }
} }
var teleportPad = fileSystem.get("interiors_mbp/teleportpad.dts");
var teleportTexture = fileSystem.get("interiors_mbp/repairbay.jpg");
toloadfiles.push(teleportPad); // Because its not in the shapes folder like wtf
toloadfiles.push(teleportTexture);
var worker = new ResourceLoaderWorker(onFinish); var worker = new ResourceLoaderWorker(onFinish);
for (file in toloadfiles) { for (file in toloadfiles) {
worker.addTaskParallel((fwd) -> file.load(fwd)); worker.addTaskParallel((fwd) -> file.load(fwd));