Files
glest-source/source/shared_lib/include/graphics/particle.h
2018-05-06 00:01:36 +02:00

832 lines
21 KiB
C++

// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_GRAPHICS_PARTICLE_H_
#define _SHARED_GRAPHICS_PARTICLE_H_
#include <list>
#include <cassert>
#include "vec.h"
#include "pixmap.h"
#include "texture_manager.h"
#include "randomgen.h"
#include "xml_parser.h"
#include "leak_dumper.h"
#include "interpolation.h"
using std::list;
using Shared::Util::RandomGen;
using Shared::Xml::XmlNode;
namespace Shared {
namespace Graphics {
class ParticleSystem;
class FireParticleSystem;
class UnitParticleSystem;
class RainParticleSystem;
class SnowParticleSystem;
class ProjectileParticleSystem;
class SplashParticleSystem;
class ParticleRenderer;
class ModelRenderer;
class Model;
// =====================================================
// class Particle
// =====================================================
class Particle {
public:
//attributes
Vec3f pos;
Vec3f lastPos;
Vec3f speed;
float speedUpRelative;
Vec3f speedUpConstant;
Vec3f accel;
Vec4f color;
float size;
int energy;
public:
Particle() {
speedUpRelative = 0;
size = 0;
energy = 0;
}
//get
Vec3f getPos() const {
return pos;
}
Vec3f getLastPos() const {
return lastPos;
}
Vec3f getSpeed() const {
return speed;
}
Vec3f getAccel() const {
return accel;
}
Vec4f getColor() const {
return color;
}
float getSize() const {
return size;
}
int getEnergy() const {
return energy;
}
void saveGame(XmlNode *rootNode);
void loadGame(const XmlNode *rootNode);
};
// =====================================================
// class ParticleObserver
// =====================================================
class ParticleObserver {
public:
virtual ~ParticleObserver() {
};
virtual void update(ParticleSystem *particleSystem) = 0;
virtual void saveGame(XmlNode *rootNode) = 0;
virtual void loadGame(const XmlNode *rootNode, void *genericData) = 0;
};
class ParticleOwner {
public:
virtual ~ParticleOwner() {
}
virtual void end(ParticleSystem *particleSystem) = 0;
virtual void logParticleInfo(string info) = 0;
};
class ParticleSystemTypeInterface {
public:
ParticleSystemTypeInterface() {
};
virtual ~ParticleSystemTypeInterface() {
};
virtual bool getMinmaxEnabled() const = 0;
virtual int getMinHp() const = 0;
virtual int getMaxHp() const = 0;
virtual bool getMinmaxIsPercent() const = 0;
};
// =====================================================
// class ParticleSystem
// =====================================================
class ParticleSystem {
public:
enum State {
sPause, // No updates
sPlay,
sFade // No new particles
};
enum BlendMode {
bmOne,
bmOneMinusAlpha
};
enum ParticleSystemType {
pst_All,
pst_FireParticleSystem,
pst_UnitParticleSystem,
pst_RainParticleSystem,
pst_SnowParticleSystem,
pst_ProjectileParticleSystem,
pst_SplashParticleSystem,
};
protected:
std::vector<Particle> particles;
RandomGen random;
BlendMode blendMode;
State state;
bool active;
bool visible;
int aliveParticleCount;
int particleCount;
string textureFileLoadDeferred;
int textureFileLoadDeferredSystemId;
Texture::Format textureFileLoadDeferredFormat;
int textureFileLoadDeferredComponents;
Texture *texture;
Vec3f pos;
Vec4f color;
Vec4f colorNoEnergy;
float emissionRate;
float emissionState;
int maxParticleEnergy;
int varParticleEnergy;
float particleSize;
float speed;
float speedUpRelative;
float speedUpConstant;
Vec3f factionColor;
bool teamcolorNoEnergy;
bool teamcolorEnergy;
int alternations;
int particleSystemStartDelay;
ParticleObserver *particleObserver;
ParticleOwner *particleOwner;
public:
//conmstructor and destructor
ParticleSystem(int particleCount);
virtual ~ParticleSystem();
virtual ParticleSystemType getParticleSystemType() const = 0;
//public
virtual void update();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
//get
State getState() const {
return state;
}
BlendMode getBlendMode() const {
return blendMode;
}
Texture *getTexture() const {
return texture;
}
Vec3f getPos() const {
return pos;
}
Particle *getParticle(int i) {
return &particles[i];
}
const Particle *getParticle(int i) const {
return &particles[i];
}
int getAliveParticleCount() const {
return aliveParticleCount;
}
bool getActive() const {
return active;
}
virtual bool getVisible() const {
return visible;
}
virtual string getTextureFileLoadDeferred();
virtual int getTextureFileLoadDeferredSystemId();
virtual Texture::Format getTextureFileLoadDeferredFormat();
virtual int getTextureFileLoadDeferredComponents();
//set
virtual void setState(State state);
void setTexture(Texture *texture);
virtual void setPos(Vec3f pos);
void setColor(Vec4f color);
void setColorNoEnergy(Vec4f color);
void setEmissionRate(float emissionRate);
void setMaxParticleEnergy(int maxParticleEnergy);
void setVarParticleEnergy(int varParticleEnergy);
void setParticleSize(float particleSize);
void setSpeed(float speed);
void setSpeedUpRelative(float speedUpRelative);
void setSpeedUpConstant(float speedUpConstant);
virtual void setActive(bool active);
void setObserver(ParticleObserver *particleObserver);
virtual void setVisible(bool visible);
void setBlendMode(BlendMode blendMode) {
this->blendMode = blendMode;
}
void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {
this->teamcolorNoEnergy = teamcolorNoEnergy;
}
void setTeamcolorEnergy(bool teamcolorEnergy) {
this->teamcolorEnergy = teamcolorEnergy;
}
void setAlternations(int alternations) {
this->alternations = alternations;
}
void setParticleSystemStartDelay(int delay) {
this->particleSystemStartDelay = delay;
}
virtual void setFactionColor(Vec3f factionColor);
static BlendMode strToBlendMode(const string &str);
//misc
virtual void fade();
int isEmpty() const;
virtual void setParticleOwner(ParticleOwner *particleOwner) {
this->particleOwner = particleOwner;
}
virtual ParticleOwner * getParticleOwner() {
return this->particleOwner;
}
virtual void callParticleOwnerEnd(ParticleSystem *particleSystem);
//children
virtual int getChildCount() {
return 0;
}
virtual ParticleSystem* getChild(int i);
virtual string toString() const;
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual Checksum getCRC();
protected:
//protected
Particle *createParticle();
void killParticle(Particle *p);
//virtual protected
virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p);
virtual bool deathTest(Particle *p);
};
// =====================================================
// class FireParticleSystem
// =====================================================
class FireParticleSystem : public ParticleSystem {
private:
float radius;
Vec3f windSpeed;
public:
FireParticleSystem(int particleCount = 2000);
virtual ParticleSystemType getParticleSystemType() const {
return pst_FireParticleSystem;
}
//virtual
virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p);
//set params
void setRadius(float radius);
void setWind(float windAngle, float windSpeed);
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class GameParticleSystem
/// base-class for unit and attack systems
// =====================================================
class UnitParticleSystem;
class GameParticleSystem : public ParticleSystem {
public:
enum Primitive {
pQuad,
pLine,
pLineAlpha
};
static Primitive strToPrimitive(const string &str);
virtual ~GameParticleSystem();
int getChildCount();
ParticleSystem* getChild(int i);
void addChild(UnitParticleSystem* child);
void removeChild(UnitParticleSystem* child);
void setPos(Vec3f pos);
void setOffset(Vec3f offset);
void setModel(Model *model) {
this->model = model;
}
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
float getTween() {
return tween;
} // 0.0 -> 1.0 for animation of model
Model *getModel() const {
return model;
}
virtual string getModelFileLoadDeferred();
void setPrimitive(Primitive primitive) {
this->primitive = primitive;
}
Vec3f getDirection() const {
return direction;
}
void setModelCycle(float modelCycle) {
this->modelCycle = modelCycle;
}
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
protected:
typedef std::vector<UnitParticleSystem*> Children;
Children children;
Primitive primitive;
string modelFileLoadDeferred;
Model *model;
float modelCycle;
Vec3f offset;
Vec3f direction;
float tween;
GameParticleSystem(int particleCount);
void positionChildren();
void setTween(float relative, float absolute);
};
// =====================================================
// class UnitParticleSystem
// =====================================================
class UnitParticleSystem : public GameParticleSystem {
public:
static bool isNight;
static Vec3f lightColor;
private:
float radius;
float minRadius;
Vec3f windSpeed;
Vec3f cRotation;
Vec3f fixedAddition;
Vec3f oldPosition;
bool energyUp;
float startTime;
float endTime;
ParticleSystemTypeInterface *particleSystemType;
public:
enum Shape {
sLinear, // generated in a sphere, flying in direction
sSpherical, // generated in a sphere, flying away from center
sConical, // generated in a cone at angle from direction
};
bool relative;
bool relativeDirection;
bool fixed;
Shape shape;
float angle;
float sizeNoEnergy;
float gravity;
float rotation;
const Model *unitModel;
Vec3f meshPos;
string meshName;
bool isVisibleAtNight;
bool isVisibleAtDay;
bool isDaylightAffected;
bool radiusBasedStartenergy;
int staticParticleCount;
int delay;
int lifetime;
float emissionRateFade;
GameParticleSystem* parent;
public:
UnitParticleSystem(int particleCount = 2000);
~UnitParticleSystem();
virtual ParticleSystemType getParticleSystemType() const {
return pst_UnitParticleSystem;
}
ParticleSystemTypeInterface * getParticleType() const {
return particleSystemType;
}
void setParticleType(ParticleSystemTypeInterface *type) {
particleSystemType = type;
}
//virtual
virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p);
virtual void update();
virtual bool getVisible() const;
virtual void fade();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
virtual void setStartTime(float startTime) {
this->startTime = startTime;
}
virtual float getStartTime() const {
return this->startTime;
}
virtual void setEndTime(float endTime) {
this->endTime = endTime;
}
virtual float getEndTime() const {
return this->endTime;
}
//set params
void setRadius(float radius) {
this->radius = radius;
}
void setMinRadius(float minRadius) {
this->minRadius = minRadius;
}
void setEmissionRateFade(float emissionRateFade) {
this->emissionRateFade = emissionRateFade;
}
void setWind(float windAngle, float windSpeed);
void setDirection(Vec3f direction) {
this->direction = direction;
}
void setSizeNoEnergy(float sizeNoEnergy) {
this->sizeNoEnergy = sizeNoEnergy;
}
void setGravity(float gravity) {
this->gravity = gravity;
}
void setRotation(float rotation);
void setMeshPos(Vec3f meshPos) {
this->meshPos = meshPos;
}
string getMeshName() {
return meshName;
}
void setMeshName(string meshName) {
this->meshName = meshName;
}
void setRelative(bool relative) {
this->relative = relative;
}
void setRelativeDirection(bool relativeDirection) {
this->relativeDirection = relativeDirection;
}
void setFixed(bool fixed) {
this->fixed = fixed;
}
void setPrimitive(Primitive primitive) {
this->primitive = primitive;
}
void setStaticParticleCount(int staticParticleCount) {
this->staticParticleCount = staticParticleCount;
}
void setIsVisibleAtNight(bool value) {
this->isVisibleAtNight = value;
}
void setIsDaylightAffected(bool value) {
this->isDaylightAffected = value;
}
void setIsVisibleAtDay(bool value) {
this->isVisibleAtDay = value;
}
void setRadiusBasedStartenergy(bool value) {
this->radiusBasedStartenergy = value;
}
void setShape(Shape shape) {
this->shape = shape;
}
void setAngle(float angle) {
this->angle = angle;
}
void setDelay(int delay) {
this->delay = delay;
}
void setLifetime(int lifetime) {
this->lifetime = lifetime;
}
void setParent(GameParticleSystem* parent) {
this->parent = parent;
}
GameParticleSystem* getParent() const {
return parent;
}
void setParentDirection(Vec3f parentDirection);
static Shape strToShape(const string& str);
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class RainParticleSystem
// =====================================================
class RainParticleSystem : public ParticleSystem {
private:
Vec3f windSpeed;
float radius;
public:
RainParticleSystem(int particleCount = 4000);
virtual ParticleSystemType getParticleSystemType() const {
return pst_RainParticleSystem;
}
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
virtual void initParticle(Particle *p, int particleIndex);
virtual bool deathTest(Particle *p);
void setRadius(float radius);
void setWind(float windAngle, float windSpeed);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class SnowParticleSystem
// =====================================================
class SnowParticleSystem : public ParticleSystem {
private:
Vec3f windSpeed;
float radius;
public:
SnowParticleSystem(int particleCount = 4000);
virtual ParticleSystemType getParticleSystemType() const {
return pst_SnowParticleSystem;
}
virtual void initParticle(Particle *p, int particleIndex);
virtual bool deathTest(Particle *p);
void setRadius(float radius);
void setWind(float windAngle, float windSpeed);
virtual string toString() const;
virtual Checksum getCRC();
};
// ===========================================================================
// AttackParticleSystem
//
/// Base class for Projectiles and Splashes
// ===========================================================================
class AttackParticleSystem : public GameParticleSystem {
protected:
float sizeNoEnergy;
float gravity;
public:
AttackParticleSystem(int particleCount);
virtual ParticleSystemType getParticleSystemType() const {
return pst_ProjectileParticleSystem;
}
void setSizeNoEnergy(float sizeNoEnergy) {
this->sizeNoEnergy = sizeNoEnergy;
}
void setGravity(float gravity) {
this->gravity = gravity;
}
virtual void initParticleSystem() {
} // opportunity to do any initialization when the system has been created and all settings set
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class ProjectileParticleSystem
// =====================================================
class ProjectileParticleSystem : public AttackParticleSystem {
public:
friend class SplashParticleSystem;
enum Trajectory {
tLinear,
tParabolic,
tSpiral
};
private:
SplashParticleSystem *nextParticleSystem;
Vec3f lastPos;
Vec3f startPos;
Vec3f endPos;
Vec3f flatPos;
Vec3f xVector;
Vec3f yVector;
Vec3f zVector;
Trajectory trajectory;
float trajectorySpeed;
//parabolic
float trajectoryScale;
float trajectoryFrequency;
float arriveDestinationDistance;
void rotateChildren();
public:
ProjectileParticleSystem(int particleCount = 1000);
virtual ~ProjectileParticleSystem();
virtual ParticleSystemType getParticleSystemType() const {
return pst_SplashParticleSystem;
}
void link(SplashParticleSystem *particleSystem);
virtual void update();
virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p);
void setTrajectory(Trajectory trajectory) {
this->trajectory = trajectory;
}
void setTrajectorySpeed(float trajectorySpeed) {
this->trajectorySpeed = trajectorySpeed;
}
void setTrajectoryScale(float trajectoryScale) {
this->trajectoryScale = trajectoryScale;
}
void setTrajectoryFrequency(float trajectoryFrequency) {
this->trajectoryFrequency = trajectoryFrequency;
}
void setPath(Vec3f startPos, Vec3f endPos);
static Trajectory strToTrajectory(const string &str);
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class SplashParticleSystem
// =====================================================
class SplashParticleSystem : public AttackParticleSystem {
public:
friend class ProjectileParticleSystem;
private:
ProjectileParticleSystem *prevParticleSystem;
float emissionRateFade;
float verticalSpreadA;
float verticalSpreadB;
float horizontalSpreadA;
float horizontalSpreadB;
float startEmissionRate;
public:
SplashParticleSystem(int particleCount = 1000);
virtual ~SplashParticleSystem();
virtual void update();
virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p);
virtual void initParticleSystem();
void setEmissionRateFade(float emissionRateFade) {
this->emissionRateFade = emissionRateFade;
}
void setVerticalSpreadA(float verticalSpreadA) {
this->verticalSpreadA = verticalSpreadA;
}
void setVerticalSpreadB(float verticalSpreadB) {
this->verticalSpreadB = verticalSpreadB;
}
void setHorizontalSpreadA(float horizontalSpreadA) {
this->horizontalSpreadA = horizontalSpreadA;
}
void setHorizontalSpreadB(float horizontalSpreadB) {
this->horizontalSpreadB = horizontalSpreadB;
}
virtual void saveGame(XmlNode *rootNode);
virtual void loadGame(const XmlNode *rootNode);
virtual string toString() const;
virtual Checksum getCRC();
};
// =====================================================
// class ParticleManager
// =====================================================
class ParticleManager {
private:
vector<ParticleSystem *> particleSystems;
public:
ParticleManager();
~ParticleManager();
void update(int renderFps = -1);
void render(ParticleRenderer *pr, ModelRenderer *mr) const;
void manage(ParticleSystem *ps);
void end();
void cleanupParticleSystems(ParticleSystem *ps);
void cleanupParticleSystems(vector<ParticleSystem *> &particleSystems);
void cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems);
int findParticleSystems(ParticleSystem *psFind, const vector<ParticleSystem *> &particleSystems) const;
bool validateParticleSystemStillExists(ParticleSystem * particleSystem) const;
void removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner);
bool hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const;
};
}
}//end namespace
#endif