space-game001/SparkEmitter.h
2025-12-17 17:05:40 +06:00

86 lines
2.4 KiB
C++

#pragma once
#include "ZLMath.h"
#include "Renderer.h"
#include "TextureManager.h"
#include <vector>
#include <chrono>
#include <string>
namespace ZL {
struct SparkParticle {
Vector3f position;
Vector3f velocity;
float scale;
float lifeTime;
float maxLifeTime;
bool active;
int emitterIndex;
SparkParticle() : position({ 0,0,0 }), velocity({ 0,0,0 }), scale(1.0f),
lifeTime(0), maxLifeTime(1000.0f), active(false), emitterIndex(0) {
}
};
class SparkEmitter {
private:
std::vector<SparkParticle> particles;
std::vector<Vector3f> emissionPoints;
std::chrono::steady_clock::time_point lastEmissionTime;
float emissionRate;
bool isActive;
std::vector<Vector3f> drawPositions;
std::vector<Vector2f> drawTexCoords;
bool drawDataDirty;
VertexRenderStruct sparkQuad;
std::shared_ptr<Texture> texture;
int maxParticles;
float particleSize;
float biasX;
// Ranges (used when config supplies intervals)
struct FloatRange { float min; float max; };
FloatRange speedRange; // XY speed
FloatRange zSpeedRange; // Z speed
FloatRange scaleRange;
FloatRange lifeTimeRange;
std::string shaderProgramName;
void prepareDrawData();
public:
SparkEmitter();
SparkEmitter(const std::vector<Vector3f>& positions, float rate = 100.0f);
SparkEmitter(const std::vector<Vector3f>& positions,
std::shared_ptr<Texture> tex,
float rate = 100.0f);
void setEmissionPoints(const std::vector<Vector3f>& positions);
void setTexture(std::shared_ptr<Texture> tex);
void setEmissionRate(float rate) { emissionRate = rate; }
void setShaderProgramName(const std::string& name) { shaderProgramName = name; }
void setMaxParticles(int max) { maxParticles = max; particles.resize(maxParticles); }
void setParticleSize(float size) { particleSize = size; }
void setBiasX(float bias) { biasX = bias; }
bool loadFromJsonFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
void update(float deltaTimeMs);
void emit();
void draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight);
const std::vector<SparkParticle>& getParticles() const;
size_t getActiveParticleCount() const;
std::shared_ptr<Texture> getTexture() const { return texture; }
private:
void initParticle(SparkParticle& particle, int emitterIndex);
Vector3f getRandomVelocity(int emitterIndex);
};
} // namespace ZL