122 lines
5.8 KiB
C
122 lines
5.8 KiB
C
/*
|
|
*
|
|
* Singe 3
|
|
* Copyright (C) 2006-2026 Scott Duensing <scott@kangaroopunch.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 3
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
// Singe - Particles: emitters that spawn, move and age particles for the 2D overlay and the 3D scene.
|
|
|
|
#ifndef PARTICLES_H
|
|
#define PARTICLES_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <SDL3/SDL.h>
|
|
#include "math3d.h"
|
|
|
|
#define PARTICLES_QUEUE_MAX 256 // 2D emitters that may be queued for drawing in one frame
|
|
|
|
typedef enum ParticleBlendE {
|
|
PARTICLE_ALPHA = 0, // Normal alpha blending
|
|
PARTICLE_ADD = 1 // Additive: light on light
|
|
} ParticleBlendE;
|
|
|
|
typedef enum ParticleLayerE {
|
|
PARTICLE_OVER = 0, // 2D: drawn above the overlay
|
|
PARTICLE_UNDER = 1 // 2D: drawn beneath the overlay, above the video and the scene
|
|
} ParticleLayerE;
|
|
|
|
typedef enum ParticleCollideE {
|
|
COLLIDE_NONE = 0,
|
|
COLLIDE_FLOOR = 1, // A horizontal plane at a given height
|
|
COLLIDE_SCENE = 2 // The physics world, by ray casts (3D only, capped per frame)
|
|
} ParticleCollideE;
|
|
|
|
// One particle, as handed to a renderer: world or overlay position, size, rotation, tint and frame.
|
|
typedef struct ParticleViewT {
|
|
Vec3T position;
|
|
float size;
|
|
float angle; // Degrees
|
|
float colour[4]; // 0..1
|
|
int32_t frame;
|
|
} ParticleViewT;
|
|
|
|
// Renderers ask an emitter for its live particles; the texture per frame is theirs to keep.
|
|
typedef struct EmitterViewT {
|
|
int32_t id;
|
|
int32_t node; // -1 for a 2D emitter
|
|
ParticleBlendE blend;
|
|
ParticleLayerE layer;
|
|
int32_t frameCount;
|
|
SDL_Surface **frames; // frameCount surfaces (the built-in disc when no sprite is set)
|
|
uint32_t textureVersion; // Bumped whenever the frames change
|
|
int32_t count;
|
|
ParticleViewT *particles; // count entries, valid until the next update
|
|
bool lit; // 3D: shaded by the scene's lights
|
|
float softness; // 3D: distance over which a particle fades where it meets geometry; 0 for none
|
|
int32_t trailLength; // Points kept behind each particle; 0 for no trails
|
|
float trailWidth; // World or overlay units
|
|
const float *trailPoints; // Per particle, trailLength points of x, y, z, oldest first
|
|
const int32_t *trailCounts; // Per particle, how many of those are valid
|
|
Vec3T trailOffset; // Added to trail points (a local emitter's origin)
|
|
} EmitterViewT;
|
|
|
|
void particlesClearQueue2D(void);
|
|
void particlesInit(void);
|
|
void particlesQueue2D(int32_t emitter); // Draw this emitter this frame
|
|
int32_t particlesQueued2D(ParticleLayerE layer, int32_t *emitters, int32_t max);
|
|
void particlesQuit(void);
|
|
void particlesUpdate(bool advance);
|
|
int32_t particlesView3D(EmitterViewT *views, int32_t max); // Every 3D emitter with live particles, up to max; returns how many
|
|
bool particlesViewEmitter(int32_t emitter, EmitterViewT *view);
|
|
|
|
void emitterBurst(int32_t emitter, int32_t count);
|
|
void emitterClear(int32_t emitter);
|
|
void emitterDelete(int32_t emitter);
|
|
int32_t emitterGetCount(int32_t emitter);
|
|
bool emitterIs3D(int32_t emitter);
|
|
bool emitterIsActive(int32_t emitter);
|
|
int32_t emitterNew(int32_t node);
|
|
void emitterSetBlend(int32_t emitter, ParticleBlendE blend);
|
|
void emitterSetCollide(int32_t emitter, ParticleCollideE mode, float bounce, float friction, float floor);
|
|
void emitterSetColor(int32_t emitter, const float *start, const float *finish);
|
|
void emitterSetDirection(int32_t emitter, Vec3T direction);
|
|
void emitterSetDrag(int32_t emitter, float perSecond);
|
|
void emitterSetFrames(int32_t emitter, int32_t first, int32_t last);
|
|
void emitterSetGravity(int32_t emitter, Vec3T acceleration);
|
|
void emitterSetLayer(int32_t emitter, ParticleLayerE layer);
|
|
void emitterSetLife(int32_t emitter, float minSeconds, float maxSeconds);
|
|
void emitterSetLit(int32_t emitter, bool lit);
|
|
void emitterSetLocal(int32_t emitter, bool local);
|
|
void emitterSetMax(int32_t emitter, int32_t count);
|
|
void emitterSetPosition(int32_t emitter, Vec3T position);
|
|
void emitterSetRadius(int32_t emitter, float radius);
|
|
void emitterSetRate(int32_t emitter, float perSecond);
|
|
void emitterSetSize(int32_t emitter, float start, float finish, float variation);
|
|
void emitterSetSoftness(int32_t emitter, float distance);
|
|
void emitterSetSpeed(int32_t emitter, float min, float max);
|
|
void emitterSetSpin(int32_t emitter, float min, float max);
|
|
void emitterSetSpread(int32_t emitter, float degrees);
|
|
void emitterSetTexture(int32_t emitter, SDL_Surface **frames, int32_t frameCount); // Copies the surfaces; NULL restores the disc
|
|
void emitterSetTrail(int32_t emitter, int32_t length, float width);
|
|
void emitterStart(int32_t emitter);
|
|
void emitterStop(int32_t emitter);
|
|
bool emitterValid(int32_t emitter);
|
|
|
|
#endif
|