new switch <rotationAllowed value="false" /> for buildings
new switch <relativeDirection value="false" /> for UnitParticleSystems
This commit is contained in:
parent
7d75f5cc97
commit
c1ec8f97df
204
source/glest_game/graphics/unit_particle_type.cpp
Normal file
204
source/glest_game/graphics/unit_particle_type.cpp
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// ==============================================================
|
||||||
|
// This file is part of Glest (www.glest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2008 Marti<74>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
|
||||||
|
// ==============================================================
|
||||||
|
|
||||||
|
#include "unit_particle_type.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "core_data.h"
|
||||||
|
#include "xml_parser.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "game_constants.h"
|
||||||
|
|
||||||
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
|
using namespace Shared::Xml;
|
||||||
|
using namespace Shared::Graphics;
|
||||||
|
|
||||||
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class UnitParticleSystemType
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
UnitParticleSystemType::UnitParticleSystemType(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir){
|
||||||
|
|
||||||
|
Renderer &renderer= Renderer::getInstance();
|
||||||
|
|
||||||
|
//texture
|
||||||
|
const XmlNode *textureNode= particleSystemNode->getChild("texture");
|
||||||
|
bool textureEnabled= textureNode->getAttribute("value")->getBoolValue();
|
||||||
|
if(textureEnabled){
|
||||||
|
texture= renderer.newTexture2D(rsGame);
|
||||||
|
if(textureNode->getAttribute("luminance")->getBoolValue()){
|
||||||
|
texture->setFormat(Texture::fAlpha);
|
||||||
|
texture->getPixmap()->init(1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
texture->getPixmap()->init(4);
|
||||||
|
}
|
||||||
|
texture->load(dir + "/" + textureNode->getAttribute("path")->getRestrictedValue());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
texture= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//primitive
|
||||||
|
const XmlNode *primitiveNode= particleSystemNode->getChild("primitive");
|
||||||
|
primitive= primitiveNode->getAttribute("value")->getRestrictedValue();
|
||||||
|
|
||||||
|
//offset
|
||||||
|
const XmlNode *offsetNode= particleSystemNode->getChild("offset");
|
||||||
|
offset.x= offsetNode->getAttribute("x")->getFloatValue();
|
||||||
|
offset.y= offsetNode->getAttribute("y")->getFloatValue();
|
||||||
|
offset.z= offsetNode->getAttribute("z")->getFloatValue();
|
||||||
|
|
||||||
|
//direction
|
||||||
|
const XmlNode *directionNode= particleSystemNode->getChild("direction");
|
||||||
|
direction.x= directionNode->getAttribute("x")->getFloatValue();
|
||||||
|
direction.y= directionNode->getAttribute("y")->getFloatValue();
|
||||||
|
direction.z= directionNode->getAttribute("z")->getFloatValue();
|
||||||
|
|
||||||
|
//color
|
||||||
|
const XmlNode *colorNode= particleSystemNode->getChild("color");
|
||||||
|
color.x= colorNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
||||||
|
color.y= colorNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
||||||
|
color.z= colorNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
||||||
|
color.w= colorNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
||||||
|
|
||||||
|
//color
|
||||||
|
const XmlNode *colorNoEnergyNode= particleSystemNode->getChild("color-no-energy");
|
||||||
|
colorNoEnergy.x= colorNoEnergyNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
||||||
|
colorNoEnergy.y= colorNoEnergyNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
||||||
|
colorNoEnergy.z= colorNoEnergyNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
||||||
|
colorNoEnergy.w= colorNoEnergyNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
||||||
|
|
||||||
|
//radius
|
||||||
|
const XmlNode *radiusNode= particleSystemNode->getChild("radius");
|
||||||
|
radius= radiusNode->getAttribute("value")->getFloatValue();
|
||||||
|
|
||||||
|
//size
|
||||||
|
const XmlNode *sizeNode= particleSystemNode->getChild("size");
|
||||||
|
size= sizeNode->getAttribute("value")->getFloatValue();
|
||||||
|
|
||||||
|
//sizeNoEnergy
|
||||||
|
const XmlNode *sizeNoEnergyNode= particleSystemNode->getChild("size-no-energy");
|
||||||
|
sizeNoEnergy= sizeNoEnergyNode->getAttribute("value")->getFloatValue();
|
||||||
|
|
||||||
|
//speed
|
||||||
|
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
||||||
|
speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
||||||
|
|
||||||
|
//gravity
|
||||||
|
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
||||||
|
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
||||||
|
|
||||||
|
//emission rate
|
||||||
|
const XmlNode *emissionRateNode= particleSystemNode->getChild("emission-rate");
|
||||||
|
emissionRate= emissionRateNode->getAttribute("value")->getIntValue();
|
||||||
|
|
||||||
|
//energy max
|
||||||
|
const XmlNode *energyMaxNode= particleSystemNode->getChild("energy-max");
|
||||||
|
energyMax= energyMaxNode->getAttribute("value")->getIntValue();
|
||||||
|
|
||||||
|
//speed
|
||||||
|
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
||||||
|
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
||||||
|
|
||||||
|
//relative
|
||||||
|
const XmlNode *relativeNode= particleSystemNode->getChild("relative");
|
||||||
|
relative= relativeNode->getAttribute("value")->getBoolValue();
|
||||||
|
|
||||||
|
//relativeDirection
|
||||||
|
if(particleSystemNode->hasChild("relativeDirection")){
|
||||||
|
const XmlNode *relativeDirectionNode= particleSystemNode->getChild("relativeDirection");
|
||||||
|
relativeDirection= relativeDirectionNode->getAttribute("value")->getBoolValue();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
relativeDirection=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//fixed
|
||||||
|
const XmlNode *fixedNode= particleSystemNode->getChild("fixed");
|
||||||
|
fixed= fixedNode->getAttribute("value")->getBoolValue();
|
||||||
|
|
||||||
|
//teamcolorNoEnergy
|
||||||
|
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
||||||
|
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
||||||
|
teamcolorNoEnergy= teamcolorNoEnergyNode->getAttribute("value")->getBoolValue();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
teamcolorNoEnergy=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//teamcolorEnergy
|
||||||
|
if(particleSystemNode->hasChild("teamcolorEnergy")){
|
||||||
|
const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy");
|
||||||
|
teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
teamcolorEnergy=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mode
|
||||||
|
if(particleSystemNode->hasChild("mode")){
|
||||||
|
const XmlNode *modeNode= particleSystemNode->getChild("mode");
|
||||||
|
mode= modeNode->getAttribute("value")->getRestrictedValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode="normal";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
|
||||||
|
ups->setTexture(texture);
|
||||||
|
ups->setPrimitive(UnitParticleSystem::strToPrimitive(primitive));
|
||||||
|
ups->setOffset(offset);
|
||||||
|
ups->setDirection(direction);
|
||||||
|
ups->setColor(color);
|
||||||
|
ups->setColorNoEnergy(colorNoEnergy);
|
||||||
|
ups->setSpeed(speed);
|
||||||
|
ups->setGravity(gravity);
|
||||||
|
ups->setParticleSize(size);
|
||||||
|
ups->setSizeNoEnergy(sizeNoEnergy);
|
||||||
|
ups->setEmissionRate(emissionRate);
|
||||||
|
ups->setMaxParticleEnergy(energyMax);
|
||||||
|
ups->setVarParticleEnergy(energyVar);
|
||||||
|
ups->setFixed(fixed);
|
||||||
|
ups->setRelative(relative);
|
||||||
|
ups->setRelativeDirection(relativeDirection);
|
||||||
|
ups->setTeamcolorNoEnergy(teamcolorNoEnergy);
|
||||||
|
ups->setTeamcolorEnergy(teamcolorEnergy);
|
||||||
|
ups->setRadius(radius);
|
||||||
|
ups->setBlendMode(ParticleSystem::strToBlendMode(mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystemType::load(const string &dir, const string &path){
|
||||||
|
|
||||||
|
try{
|
||||||
|
XmlTree xmlTree;
|
||||||
|
xmlTree.load(path);
|
||||||
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
||||||
|
|
||||||
|
UnitParticleSystemType::load(particleSystemNode, dir);
|
||||||
|
}
|
||||||
|
catch(const exception &e){
|
||||||
|
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}//end mamespace
|
74
source/glest_game/graphics/unit_particle_type.h
Normal file
74
source/glest_game/graphics/unit_particle_type.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// ==============================================================
|
||||||
|
// This file is part of Glest (www.glest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2008 Marti<74>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 _GLEST_GAME_UNITPARTICLETYPE_H_
|
||||||
|
#define _GLEST_GAME_UNITPARTICLETYPE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "particle.h"
|
||||||
|
#include "factory.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "xml_parser.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
|
using Shared::Graphics::ParticleSystem;
|
||||||
|
using Shared::Graphics::UnitParticleSystem;
|
||||||
|
using Shared::Graphics::Texture2D;
|
||||||
|
using Shared::Graphics::Vec3f;
|
||||||
|
using Shared::Graphics::Vec4f;
|
||||||
|
using Shared::Util::MultiFactory;
|
||||||
|
using Shared::Xml::XmlNode;
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// class ParticleSystemType
|
||||||
|
//
|
||||||
|
/// A type of particle system
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
class UnitParticleSystemType{
|
||||||
|
protected:
|
||||||
|
string type;
|
||||||
|
Texture2D *texture;
|
||||||
|
string primitive;
|
||||||
|
Vec3f offset;
|
||||||
|
Vec3f direction;
|
||||||
|
Vec4f color;
|
||||||
|
Vec4f colorNoEnergy;
|
||||||
|
float radius;
|
||||||
|
float size;
|
||||||
|
float sizeNoEnergy;
|
||||||
|
float speed;
|
||||||
|
float gravity;
|
||||||
|
int emissionRate;
|
||||||
|
int energyMax;
|
||||||
|
int energyVar;
|
||||||
|
bool relative;
|
||||||
|
bool relativeDirection;
|
||||||
|
bool fixed;
|
||||||
|
bool teamcolorNoEnergy;
|
||||||
|
bool teamcolorEnergy;
|
||||||
|
string mode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnitParticleSystemType();
|
||||||
|
void load(const XmlNode *particleSystemNode, const string &dir);
|
||||||
|
void load(const string &dir, const string &path);
|
||||||
|
void setValues(UnitParticleSystem *uts);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}//end namespace
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,7 +2,7 @@
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
// This file is part of Glest (www.glest.org)
|
// This file is part of Glest (www.glest.org)
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
|
@ -333,8 +333,10 @@ void Gui::hotKey(char key){
|
||||||
else if(key=='R'){
|
else if(key=='R'){
|
||||||
// Here the user triggers a unit rotation while placing a unit
|
// Here the user triggers a unit rotation while placing a unit
|
||||||
if(allowRotateUnits == true && isPlacingBuilding()) {
|
if(allowRotateUnits == true && isPlacingBuilding()) {
|
||||||
|
if(getBuilding()->getRotationAllowed()){
|
||||||
++selectedBuildingFacing;
|
++selectedBuildingFacing;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
selectInterestingUnit(iutProducer);
|
selectInterestingUnit(iutProducer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,17 @@ void UnitType::load(int id,const string &dir, const TechTree *techTree, const Fa
|
||||||
lightColor.z= lightNode->getAttribute("blue")->getFloatValue(0.f, 1.f);
|
lightColor.z= lightNode->getAttribute("blue")->getFloatValue(0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//rotationAllowed
|
||||||
|
if(parametersNode->hasChild("rotationAllowed")){
|
||||||
|
const XmlNode *rotationAllowedNode= parametersNode->getChild("rotationAllowed");
|
||||||
|
rotationAllowed= rotationAllowedNode->getAttribute("value")->getBoolValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rotationAllowed=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//unit requirements
|
//unit requirements
|
||||||
const XmlNode *unitRequirementsNode= parametersNode->getChild("unit-requirements");
|
const XmlNode *unitRequirementsNode= parametersNode->getChild("unit-requirements");
|
||||||
for(int i=0; i<unitRequirementsNode->getChildCount(); ++i){
|
for(int i=0; i<unitRequirementsNode->getChildCount(); ++i){
|
||||||
|
|
|
@ -97,6 +97,7 @@ private:
|
||||||
int size; //size in cells
|
int size; //size in cells
|
||||||
int height;
|
int height;
|
||||||
float rotatedBuildPos;
|
float rotatedBuildPos;
|
||||||
|
bool rotationAllowed;
|
||||||
|
|
||||||
//cellmap
|
//cellmap
|
||||||
bool *cellMap;
|
bool *cellMap;
|
||||||
|
@ -143,6 +144,7 @@ public:
|
||||||
int getCommandTypeCount() const {return commandTypes.size();}
|
int getCommandTypeCount() const {return commandTypes.size();}
|
||||||
int getLevelCount() const {return levels.size();}
|
int getLevelCount() const {return levels.size();}
|
||||||
bool getLight() const {return light;}
|
bool getLight() const {return light;}
|
||||||
|
bool getRotationAllowed() const {return rotationAllowed;}
|
||||||
Vec3f getLightColor() const {return lightColor;}
|
Vec3f getLightColor() const {return lightColor;}
|
||||||
bool getMultiSelect() const {return multiSelect;}
|
bool getMultiSelect() const {return multiSelect;}
|
||||||
int getSight() const {return sight;}
|
int getSight() const {return sight;}
|
||||||
|
|
437
source/shared_lib/include/graphics/particle.h
Normal file
437
source/shared_lib/include/graphics/particle.h
Normal file
|
@ -0,0 +1,437 @@
|
||||||
|
// ==============================================================
|
||||||
|
// This file is part of Glest Shared Library (www.glest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2008 Marti<74>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 "random.h"
|
||||||
|
|
||||||
|
using std::list;
|
||||||
|
using Shared::Util::Random;
|
||||||
|
|
||||||
|
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;
|
||||||
|
Vec3f accel;
|
||||||
|
Vec4f color;
|
||||||
|
float size;
|
||||||
|
int energy;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//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;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ParticleSystem;
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class ParticleObserver
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class ParticleObserver{
|
||||||
|
public:
|
||||||
|
virtual ~ParticleObserver(){};
|
||||||
|
virtual void update(ParticleSystem *particleSystem)= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class ParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class ParticleSystem{
|
||||||
|
public:
|
||||||
|
enum BlendMode{
|
||||||
|
bmOne,
|
||||||
|
bmOneMinusAlpha
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum State{
|
||||||
|
sPause, // No updates
|
||||||
|
sPlay,
|
||||||
|
sFade // No new particles
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Particle *particles;
|
||||||
|
Random random;
|
||||||
|
|
||||||
|
BlendMode blendMode;
|
||||||
|
State state;
|
||||||
|
bool active;
|
||||||
|
bool visible;
|
||||||
|
int aliveParticleCount;
|
||||||
|
int particleCount;
|
||||||
|
|
||||||
|
|
||||||
|
Texture *texture;
|
||||||
|
Vec3f pos;
|
||||||
|
Vec4f color;
|
||||||
|
Vec4f colorNoEnergy;
|
||||||
|
int emissionRate;
|
||||||
|
int maxParticleEnergy;
|
||||||
|
int varParticleEnergy;
|
||||||
|
float particleSize;
|
||||||
|
float speed;
|
||||||
|
Vec3f factionColor;
|
||||||
|
bool teamcolorNoEnergy;
|
||||||
|
bool teamcolorEnergy;
|
||||||
|
|
||||||
|
ParticleObserver *particleObserver;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//conmstructor and destructor
|
||||||
|
ParticleSystem(int particleCount);
|
||||||
|
virtual ~ParticleSystem();
|
||||||
|
|
||||||
|
//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;}
|
||||||
|
bool getVisible() const {return visible;}
|
||||||
|
|
||||||
|
//set
|
||||||
|
void setState(State state);
|
||||||
|
void setTexture(Texture *texture);
|
||||||
|
void setPos(Vec3f pos);
|
||||||
|
void setColor(Vec4f color);
|
||||||
|
void setColorNoEnergy(Vec4f color);
|
||||||
|
void setEmissionRate(int emissionRate);
|
||||||
|
void setMaxParticleEnergy(int maxParticleEnergy);
|
||||||
|
void setVarParticleEnergy(int varParticleEnergy);
|
||||||
|
void setParticleSize(float particleSize);
|
||||||
|
void setSpeed(float speed);
|
||||||
|
void setActive(bool active);
|
||||||
|
void setObserver(ParticleObserver *particleObserver);
|
||||||
|
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;}
|
||||||
|
virtual void setFactionColor(Vec3f factionColor);
|
||||||
|
|
||||||
|
static BlendMode strToBlendMode(const string &str);
|
||||||
|
//misc
|
||||||
|
void fade();
|
||||||
|
int isEmpty() const;
|
||||||
|
|
||||||
|
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
|
||||||
|
virtual void initParticle(Particle *p, int particleIndex);
|
||||||
|
virtual void updateParticle(Particle *p);
|
||||||
|
|
||||||
|
//set params
|
||||||
|
void setRadius(float radius);
|
||||||
|
void setWind(float windAngle, float windSpeed);
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class UnitParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class UnitParticleSystem: public ParticleSystem{
|
||||||
|
private:
|
||||||
|
float radius;
|
||||||
|
Vec3f windSpeed;
|
||||||
|
Vec3f cRotation;
|
||||||
|
Vec3f fixedAddition;
|
||||||
|
Vec3f oldPosition;
|
||||||
|
public:
|
||||||
|
enum Primitive{
|
||||||
|
pQuad,
|
||||||
|
pLine,
|
||||||
|
pLineAlpha
|
||||||
|
};
|
||||||
|
bool relative;
|
||||||
|
bool relativeDirection;
|
||||||
|
bool fixed;
|
||||||
|
Model *model;
|
||||||
|
Primitive primitive;
|
||||||
|
Vec3f offset;
|
||||||
|
Vec3f direction;
|
||||||
|
float sizeNoEnergy;
|
||||||
|
float gravity;
|
||||||
|
float rotation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnitParticleSystem(int particleCount= 2000);
|
||||||
|
|
||||||
|
//virtual
|
||||||
|
virtual void initParticle(Particle *p, int particleIndex);
|
||||||
|
virtual void updateParticle(Particle *p);
|
||||||
|
virtual void update();
|
||||||
|
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
|
||||||
|
|
||||||
|
//set params
|
||||||
|
void setRadius(float radius);
|
||||||
|
void setWind(float windAngle, float windSpeed);
|
||||||
|
|
||||||
|
void setOffset(Vec3f offset) {this->offset= offset;}
|
||||||
|
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) {this->rotation= rotation;}
|
||||||
|
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;}
|
||||||
|
|
||||||
|
static Primitive strToPrimitive(const string &str);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class RainParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class RainParticleSystem: public ParticleSystem{
|
||||||
|
private:
|
||||||
|
Vec3f windSpeed;
|
||||||
|
float radius;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RainParticleSystem(int particleCount= 4000);
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class SnowParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class SnowParticleSystem: public ParticleSystem{
|
||||||
|
private:
|
||||||
|
Vec3f windSpeed;
|
||||||
|
float radius;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SnowParticleSystem(int particleCount= 4000);
|
||||||
|
|
||||||
|
virtual void initParticle(Particle *p, int particleIndex);
|
||||||
|
virtual bool deathTest(Particle *p);
|
||||||
|
|
||||||
|
void setRadius(float radius);
|
||||||
|
void setWind(float windAngle, float windSpeed);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// AttackParticleSystem
|
||||||
|
//
|
||||||
|
/// Base class for Projectiles and Splashes
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
class AttackParticleSystem: public ParticleSystem{
|
||||||
|
public:
|
||||||
|
enum Primitive{
|
||||||
|
pQuad,
|
||||||
|
pLine,
|
||||||
|
pLineAlpha
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Model *model;
|
||||||
|
Primitive primitive;
|
||||||
|
Vec3f offset;
|
||||||
|
float sizeNoEnergy;
|
||||||
|
float gravity;
|
||||||
|
|
||||||
|
Vec3f direction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AttackParticleSystem(int particleCount);
|
||||||
|
|
||||||
|
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
|
||||||
|
|
||||||
|
Model *getModel() const {return model;}
|
||||||
|
Vec3f getDirection() const {return direction;}
|
||||||
|
|
||||||
|
void setModel(Model *model) {this->model= model;}
|
||||||
|
void setOffset(Vec3f offset) {this->offset= offset;}
|
||||||
|
void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;}
|
||||||
|
void setGravity(float gravity) {this->gravity= gravity;}
|
||||||
|
void setPrimitive(Primitive primitive) {this->primitive= primitive;}
|
||||||
|
|
||||||
|
static Primitive strToPrimitive(const string &str);
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProjectileParticleSystem(int particleCount= 1000);
|
||||||
|
virtual ~ProjectileParticleSystem();
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class SplashParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class SplashParticleSystem: public AttackParticleSystem{
|
||||||
|
public:
|
||||||
|
friend class ProjectileParticleSystem;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProjectileParticleSystem *prevParticleSystem;
|
||||||
|
|
||||||
|
int emissionRateFade;
|
||||||
|
float verticalSpreadA;
|
||||||
|
float verticalSpreadB;
|
||||||
|
float horizontalSpreadA;
|
||||||
|
float horizontalSpreadB;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SplashParticleSystem(int particleCount= 1000);
|
||||||
|
virtual ~SplashParticleSystem();
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
virtual void initParticle(Particle *p, int particleIndex);
|
||||||
|
virtual void updateParticle(Particle *p);
|
||||||
|
|
||||||
|
void setEmissionRateFade(int 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;}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class ParticleManager
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class ParticleManager{
|
||||||
|
private:
|
||||||
|
list<ParticleSystem*> particleSystems;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ParticleManager();
|
||||||
|
void update();
|
||||||
|
void render(ParticleRenderer *pr, ModelRenderer *mr) const;
|
||||||
|
void manage(ParticleSystem *ps);
|
||||||
|
void end();
|
||||||
|
};
|
||||||
|
|
||||||
|
}}//end namespace
|
||||||
|
|
||||||
|
#endif
|
859
source/shared_lib/sources/graphics/particle.cpp
Normal file
859
source/shared_lib/sources/graphics/particle.cpp
Normal file
|
@ -0,0 +1,859 @@
|
||||||
|
// ==============================================================
|
||||||
|
// This file is part of Glest Shared Library (www.glest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2008 Marti<74>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
|
||||||
|
// ==============================================================
|
||||||
|
|
||||||
|
#include "particle.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "particle_renderer.h"
|
||||||
|
#include "math_util.h"
|
||||||
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
|
using namespace Shared::Util;
|
||||||
|
|
||||||
|
namespace Shared{ namespace Graphics{
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class ParticleSystem
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
ParticleSystem::ParticleSystem(int particleCount){
|
||||||
|
|
||||||
|
//init particle vector
|
||||||
|
blendMode = bmOne;
|
||||||
|
particles= new Particle[particleCount];
|
||||||
|
state= sPlay;
|
||||||
|
aliveParticleCount=0;
|
||||||
|
active= true;
|
||||||
|
visible= true;
|
||||||
|
|
||||||
|
//vars
|
||||||
|
texture= NULL;
|
||||||
|
particleObserver= NULL;
|
||||||
|
|
||||||
|
//params
|
||||||
|
this->particleCount= particleCount;
|
||||||
|
maxParticleEnergy= 250;
|
||||||
|
varParticleEnergy= 50;
|
||||||
|
pos= Vec3f(0.0f);
|
||||||
|
color= Vec4f(1.0f);
|
||||||
|
colorNoEnergy= Vec4f(0.0f);
|
||||||
|
emissionRate= 15;
|
||||||
|
speed= 1.0f;
|
||||||
|
teamcolorNoEnergy=false;
|
||||||
|
teamcolorEnergy=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystem::~ParticleSystem(){
|
||||||
|
delete [] particles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============== VIRTUAL ======================
|
||||||
|
|
||||||
|
//updates all living particles and creates new ones
|
||||||
|
void ParticleSystem::update(){
|
||||||
|
|
||||||
|
if(state!=sPause){
|
||||||
|
for(int i=0; i<aliveParticleCount; ++i){
|
||||||
|
updateParticle(&particles[i]);
|
||||||
|
|
||||||
|
if(deathTest(&particles[i])){
|
||||||
|
|
||||||
|
//kill the particle
|
||||||
|
killParticle(&particles[i]);
|
||||||
|
|
||||||
|
//mantain alive particles at front of the array
|
||||||
|
if(aliveParticleCount>0){
|
||||||
|
particles[i]= particles[aliveParticleCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state!=sFade){
|
||||||
|
for(int i=0; i<emissionRate; ++i){
|
||||||
|
Particle *p= createParticle();
|
||||||
|
initParticle(p, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
|
||||||
|
if(active){
|
||||||
|
pr->renderSystem(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
|
||||||
|
if(str=="normal"){
|
||||||
|
return bmOne;
|
||||||
|
}
|
||||||
|
else if(str=="black"){
|
||||||
|
return bmOneMinusAlpha;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw "Unknown particle mode: " + str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============== SET ==========================
|
||||||
|
|
||||||
|
void ParticleSystem::setState(State state){
|
||||||
|
this->state= state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setTexture(Texture *texture){
|
||||||
|
this->texture= texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setPos(Vec3f pos){
|
||||||
|
this->pos= pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setColor(Vec4f color){
|
||||||
|
this->color= color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setColorNoEnergy(Vec4f colorNoEnergy){
|
||||||
|
this->colorNoEnergy= colorNoEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setEmissionRate(int emissionRate){
|
||||||
|
this->emissionRate= emissionRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setMaxParticleEnergy(int maxParticleEnergy){
|
||||||
|
this->maxParticleEnergy= maxParticleEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setVarParticleEnergy(int varParticleEnergy){
|
||||||
|
this->varParticleEnergy= varParticleEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setParticleSize(float particleSize){
|
||||||
|
this->particleSize= particleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setSpeed(float speed){
|
||||||
|
this->speed= speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setActive(bool active){
|
||||||
|
this->active= active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setObserver(ParticleObserver *particleObserver){
|
||||||
|
this->particleObserver= particleObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setVisible(bool visible){
|
||||||
|
this->visible= visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============== MISC =========================
|
||||||
|
void ParticleSystem::fade(){
|
||||||
|
assert(state==sPlay);
|
||||||
|
state= sFade;
|
||||||
|
if(particleObserver!=NULL){
|
||||||
|
particleObserver->update(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParticleSystem::isEmpty() const{
|
||||||
|
assert(aliveParticleCount>=0);
|
||||||
|
return aliveParticleCount==0 && state!=sPause;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============== PROTECTED =========================
|
||||||
|
|
||||||
|
// if there is one dead particle it returns it else, return the particle with
|
||||||
|
// less energy
|
||||||
|
Particle * ParticleSystem::createParticle(){
|
||||||
|
|
||||||
|
//if any dead particles
|
||||||
|
if(aliveParticleCount<particleCount){
|
||||||
|
++aliveParticleCount;
|
||||||
|
return &particles[aliveParticleCount-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//if not
|
||||||
|
int minEnergy= particles[0].energy;
|
||||||
|
int minEnergyParticle= 0;
|
||||||
|
|
||||||
|
for(int i=0; i<particleCount; ++i){
|
||||||
|
if(particles[i].energy<minEnergy){
|
||||||
|
minEnergy= particles[i].energy;
|
||||||
|
minEnergyParticle= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &particles[minEnergyParticle];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
p->pos= pos;
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->speed= Vec3f(0.0f);
|
||||||
|
p->accel= Vec3f(0.0f);
|
||||||
|
p->color= Vec4f(1.0f, 1.0f, 1.0f, 1.0);
|
||||||
|
p->size= particleSize;
|
||||||
|
p->energy= maxParticleEnergy + random.randRange(-varParticleEnergy, varParticleEnergy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::updateParticle(Particle *p){
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->pos= p->pos + p->speed;
|
||||||
|
p->speed= p->speed + p->accel;
|
||||||
|
p->energy--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParticleSystem::deathTest(Particle *p){
|
||||||
|
return p->energy <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::killParticle(Particle *p){
|
||||||
|
aliveParticleCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::setFactionColor(Vec3f factionColor){
|
||||||
|
this->factionColor=factionColor;
|
||||||
|
Vec3f tmpCol;
|
||||||
|
|
||||||
|
if(teamcolorEnergy)
|
||||||
|
{
|
||||||
|
this->color=Vec4f(factionColor.x,factionColor.y,factionColor.z,this->color.w);
|
||||||
|
}
|
||||||
|
if(teamcolorNoEnergy)
|
||||||
|
{
|
||||||
|
this->colorNoEnergy=Vec4f(factionColor.x,factionColor.y,factionColor.z,this->colorNoEnergy.w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// FireParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
FireParticleSystem::FireParticleSystem(int particleCount): ParticleSystem(particleCount){
|
||||||
|
|
||||||
|
radius= 0.5f;
|
||||||
|
speed= 0.01f;
|
||||||
|
windSpeed= Vec3f(0.0f);
|
||||||
|
|
||||||
|
setParticleSize(0.6f);
|
||||||
|
setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
ParticleSystem::initParticle(p, particleIndex);
|
||||||
|
|
||||||
|
float ang= random.randRange(-2.0f*pi, 2.0f*pi);
|
||||||
|
float mod= fabsf(random.randRange(-radius, radius));
|
||||||
|
|
||||||
|
float x= sinf(ang)*mod;
|
||||||
|
float y= cosf(ang)*mod;
|
||||||
|
|
||||||
|
float radRatio= sqrtf(sqrtf(mod/radius));
|
||||||
|
|
||||||
|
p->color= colorNoEnergy*0.5f + colorNoEnergy*0.5f*radRatio;
|
||||||
|
p->energy= static_cast<int>(maxParticleEnergy*radRatio) + random.randRange(-varParticleEnergy, varParticleEnergy);
|
||||||
|
p->pos= Vec3f(pos.x+x, pos.y+random.randRange(-radius/2, radius/2), pos.z+y);
|
||||||
|
p->lastPos= pos;
|
||||||
|
p->size= particleSize;
|
||||||
|
p->speed= Vec3f(0, speed+speed*random.randRange(-0.5f, 0.5f), 0) + windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireParticleSystem::updateParticle(Particle *p){
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->pos= p->pos+p->speed;
|
||||||
|
p->energy--;
|
||||||
|
|
||||||
|
if(p->color.x>0.0f)
|
||||||
|
p->color.x*= 0.98f;
|
||||||
|
if(p->color.y>0.0f)
|
||||||
|
p->color.y*= 0.98f;
|
||||||
|
if(p->color.w>0.0f)
|
||||||
|
p->color.w*= 0.98f;
|
||||||
|
|
||||||
|
p->speed.x*=1.001f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= SET PARAMS ====================
|
||||||
|
|
||||||
|
void FireParticleSystem::setRadius(float radius){
|
||||||
|
this->radius= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireParticleSystem::setWind(float windAngle, float windSpeed){
|
||||||
|
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed;
|
||||||
|
this->windSpeed.y= 0.0f;
|
||||||
|
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// UnitParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
UnitParticleSystem::UnitParticleSystem(int particleCount): ParticleSystem(particleCount){
|
||||||
|
|
||||||
|
radius= 0.5f;
|
||||||
|
speed= 0.01f;
|
||||||
|
windSpeed= Vec3f(0.0f);
|
||||||
|
|
||||||
|
setParticleSize(0.6f);
|
||||||
|
setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
primitive= pQuad;
|
||||||
|
offset= Vec3f(0.0f);
|
||||||
|
direction= Vec3f(0.0f,1.0f,0.0f);
|
||||||
|
gravity= 0.0f;
|
||||||
|
|
||||||
|
fixed=false;
|
||||||
|
rotation=0.0f;
|
||||||
|
relativeDirection=true;
|
||||||
|
|
||||||
|
cRotation= Vec3f(1.0f,1.0f,1.0f);
|
||||||
|
fixedAddition = Vec3f(0.0f,0.0f,0.0f);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystem::render(ParticleRenderer *pr,ModelRenderer *mr){
|
||||||
|
//if(active){
|
||||||
|
switch(primitive){
|
||||||
|
case pQuad:
|
||||||
|
pr->renderSystem(this);
|
||||||
|
break;
|
||||||
|
case pLine:
|
||||||
|
pr->renderSystemLine(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &str){
|
||||||
|
if(str=="quad"){
|
||||||
|
return pQuad;
|
||||||
|
}
|
||||||
|
else if(str=="line"){
|
||||||
|
return pLine;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw "Unknown particle primitive: " + str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
ParticleSystem::initParticle(p, particleIndex);
|
||||||
|
|
||||||
|
float ang= random.randRange(-2.0f*pi, 2.0f*pi);
|
||||||
|
float mod= fabsf(random.randRange(-radius, radius));
|
||||||
|
|
||||||
|
float x= sinf(ang)*mod;
|
||||||
|
float y= cosf(ang)*mod;
|
||||||
|
|
||||||
|
float radRatio= sqrtf(sqrtf(mod/radius));
|
||||||
|
|
||||||
|
//p->color= color*0.5f + color*0.5f*radRatio;
|
||||||
|
p->color=color;
|
||||||
|
p->energy= static_cast<int>(maxParticleEnergy*radRatio) + random.randRange(-varParticleEnergy, varParticleEnergy);
|
||||||
|
|
||||||
|
p->lastPos= pos;
|
||||||
|
oldPosition=pos;
|
||||||
|
p->size= particleSize;
|
||||||
|
|
||||||
|
p->speed= Vec3f(direction.x+direction.x*random.randRange(-0.5f, 0.5f),
|
||||||
|
direction.y+direction.y*random.randRange(-0.5f, 0.5f),
|
||||||
|
direction.z+direction.z*random.randRange(-0.5f, 0.5f));
|
||||||
|
p->speed= p->speed * speed;
|
||||||
|
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
||||||
|
|
||||||
|
if(!relative){
|
||||||
|
p->pos= Vec3f(pos.x+x+offset.x, pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+offset.z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// rotate it according to rotation
|
||||||
|
float rad=degToRad(rotation);
|
||||||
|
p->pos= Vec3f(pos.x+x+offset.z*sinf(rad)+offset.x*cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*cosf(rad)-offset.x*sinf(rad)));
|
||||||
|
if(relativeDirection){
|
||||||
|
p->speed=Vec3f(p->speed.z*sinf(rad)+p->speed.x*cosf(rad),p->speed.y,(p->speed.z*cosf(rad)-p->speed.x*sinf(rad)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystem::update(){
|
||||||
|
if(fixed)
|
||||||
|
{
|
||||||
|
fixedAddition= Vec3f(pos.x-oldPosition.x,pos.y-oldPosition.y,pos.z-oldPosition.z);
|
||||||
|
oldPosition=pos;
|
||||||
|
}
|
||||||
|
ParticleSystem::update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystem::updateParticle(Particle *p){
|
||||||
|
|
||||||
|
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f);
|
||||||
|
|
||||||
|
p->lastPos+= p->speed;
|
||||||
|
p->pos+= p->speed;
|
||||||
|
if(fixed)
|
||||||
|
{
|
||||||
|
p->lastPos+= fixedAddition;
|
||||||
|
p->pos+= fixedAddition;
|
||||||
|
}
|
||||||
|
p->speed+= p->accel;
|
||||||
|
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio);
|
||||||
|
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio);
|
||||||
|
p->energy--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->pos= p->pos+p->speed;
|
||||||
|
p->energy--;
|
||||||
|
|
||||||
|
if(p->color.x>0.0f)
|
||||||
|
p->color.x*= 0.98f;
|
||||||
|
if(p->color.y>0.0f)
|
||||||
|
p->color.y*= 0.98f;
|
||||||
|
if(p->color.w>0.0f)
|
||||||
|
p->color.w*= 0.98f;
|
||||||
|
|
||||||
|
p->speed.x*=1.001f;
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= SET PARAMS ====================
|
||||||
|
|
||||||
|
void UnitParticleSystem::setRadius(float radius){
|
||||||
|
this->radius= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitParticleSystem::setWind(float windAngle, float windSpeed){
|
||||||
|
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed;
|
||||||
|
this->windSpeed.y= 0.0f;
|
||||||
|
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// RainParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
RainParticleSystem::RainParticleSystem(int particleCount):ParticleSystem(particleCount){
|
||||||
|
setWind(0.0f, 0.0f);
|
||||||
|
setRadius(20.0f);
|
||||||
|
|
||||||
|
setEmissionRate(25);
|
||||||
|
setParticleSize(3.0f);
|
||||||
|
setColor(Vec4f(0.5f, 0.5f, 0.5f, 0.3f));
|
||||||
|
setSpeed(0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RainParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
|
||||||
|
pr->renderSystemLineAlpha(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RainParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
ParticleSystem::initParticle(p, particleIndex);
|
||||||
|
|
||||||
|
float x= random.randRange(-radius, radius);
|
||||||
|
float y= random.randRange(-radius, radius);
|
||||||
|
|
||||||
|
p->color= color;
|
||||||
|
p->energy= 10000;
|
||||||
|
p->pos= Vec3f(pos.x+x, pos.y, pos.z+y);
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->speed= Vec3f(random.randRange(-speed/10, speed/10), -speed, random.randRange(-speed/10, speed/10)) + windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RainParticleSystem::deathTest(Particle *p){
|
||||||
|
return p->pos.y<0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RainParticleSystem::setRadius(float radius){
|
||||||
|
this->radius= radius;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RainParticleSystem::setWind(float windAngle, float windSpeed){
|
||||||
|
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed;
|
||||||
|
this->windSpeed.y= 0.0f;
|
||||||
|
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// SnowParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
SnowParticleSystem::SnowParticleSystem(int particleCount):ParticleSystem(particleCount){
|
||||||
|
setWind(0.0f, 0.0f);
|
||||||
|
setRadius(30.0f);
|
||||||
|
|
||||||
|
setEmissionRate(2);
|
||||||
|
setParticleSize(0.2f);
|
||||||
|
setColor(Vec4f(0.8f, 0.8f, 0.8f, 0.8f));
|
||||||
|
setSpeed(0.05f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SnowParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
|
||||||
|
ParticleSystem::initParticle(p, particleIndex);
|
||||||
|
|
||||||
|
float x= random.randRange(-radius, radius);
|
||||||
|
float y= random.randRange(-radius, radius);
|
||||||
|
|
||||||
|
p->color= color;
|
||||||
|
p->energy= 10000;
|
||||||
|
p->pos= Vec3f(pos.x+x, pos.y, pos.z+y);
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->speed= Vec3f(0.0f, -speed, 0.0f) + windSpeed;
|
||||||
|
p->speed.x+= random.randRange(-0.005f, 0.005f);
|
||||||
|
p->speed.y+= random.randRange(-0.005f, 0.005f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SnowParticleSystem::deathTest(Particle *p){
|
||||||
|
return p->pos.y<0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SnowParticleSystem::setRadius(float radius){
|
||||||
|
this->radius= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SnowParticleSystem::setWind(float windAngle, float windSpeed){
|
||||||
|
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed;
|
||||||
|
this->windSpeed.y= 0.0f;
|
||||||
|
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// AttackParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
AttackParticleSystem::AttackParticleSystem(int particleCount): ParticleSystem(particleCount){
|
||||||
|
model= NULL;
|
||||||
|
primitive= pQuad;
|
||||||
|
offset= Vec3f(0.0f);
|
||||||
|
gravity= 0.0f;
|
||||||
|
direction= Vec3f(1.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttackParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
|
||||||
|
if(active){
|
||||||
|
if(model!=NULL){
|
||||||
|
pr->renderSingleModel(this, mr);
|
||||||
|
}
|
||||||
|
switch(primitive){
|
||||||
|
case pQuad:
|
||||||
|
pr->renderSystem(this);
|
||||||
|
break;
|
||||||
|
case pLine:
|
||||||
|
pr->renderSystemLine(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const string &str){
|
||||||
|
if(str=="quad"){
|
||||||
|
return pQuad;
|
||||||
|
}
|
||||||
|
else if(str=="line"){
|
||||||
|
return pLine;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw "Unknown particle primitive: " + str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// ProjectileParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
ProjectileParticleSystem::ProjectileParticleSystem(int particleCount): AttackParticleSystem(particleCount){
|
||||||
|
setEmissionRate(20);
|
||||||
|
setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f));
|
||||||
|
setMaxParticleEnergy(100);
|
||||||
|
setVarParticleEnergy(50);
|
||||||
|
setParticleSize(0.4f);
|
||||||
|
setSpeed(0.14f);
|
||||||
|
|
||||||
|
trajectory= tLinear;
|
||||||
|
trajectorySpeed= 1.0f;
|
||||||
|
trajectoryScale= 1.0f;
|
||||||
|
trajectoryFrequency = 1.0f;
|
||||||
|
|
||||||
|
nextParticleSystem= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectileParticleSystem::~ProjectileParticleSystem(){
|
||||||
|
if(nextParticleSystem!=NULL){
|
||||||
|
nextParticleSystem->prevParticleSystem= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem){
|
||||||
|
nextParticleSystem= particleSystem;
|
||||||
|
nextParticleSystem->setState(sPause);
|
||||||
|
nextParticleSystem->prevParticleSystem= this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectileParticleSystem::update(){
|
||||||
|
|
||||||
|
if(state==sPlay){
|
||||||
|
|
||||||
|
lastPos= pos;
|
||||||
|
flatPos+= zVector * trajectorySpeed;
|
||||||
|
Vec3f targetVector= endPos - startPos;
|
||||||
|
Vec3f currentVector= flatPos - startPos;
|
||||||
|
|
||||||
|
// ratio
|
||||||
|
float t= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// trajectory
|
||||||
|
switch(trajectory){
|
||||||
|
case tLinear:
|
||||||
|
{
|
||||||
|
pos= flatPos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tParabolic:
|
||||||
|
{
|
||||||
|
float scaledT= 2.0f * (t-0.5f);
|
||||||
|
float paraboleY= (1.0f-scaledT*scaledT) * trajectoryScale;
|
||||||
|
|
||||||
|
pos = flatPos;
|
||||||
|
pos.y+= paraboleY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tSpiral:
|
||||||
|
{
|
||||||
|
pos= flatPos;
|
||||||
|
pos+= xVector * cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
|
||||||
|
pos+= yVector * sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
direction= pos - lastPos;
|
||||||
|
direction.normalize();
|
||||||
|
|
||||||
|
//arrive destination
|
||||||
|
if( flatPos.dist(endPos)<0.5f ){
|
||||||
|
state= sFade;
|
||||||
|
model= NULL;
|
||||||
|
|
||||||
|
if(particleObserver!=NULL){
|
||||||
|
particleObserver->update(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nextParticleSystem!=NULL){
|
||||||
|
nextParticleSystem->setState(sPlay);
|
||||||
|
nextParticleSystem->setPos(endPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystem::update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
|
||||||
|
ParticleSystem::initParticle(p, particleIndex);
|
||||||
|
|
||||||
|
float t= static_cast<float>(particleIndex)/emissionRate;
|
||||||
|
|
||||||
|
p->pos= pos + (lastPos - pos) * t;
|
||||||
|
p->lastPos= lastPos;
|
||||||
|
p->speed= Vec3f(random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f)) * speed;
|
||||||
|
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
||||||
|
|
||||||
|
updateParticle(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectileParticleSystem::updateParticle(Particle *p){
|
||||||
|
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f);
|
||||||
|
|
||||||
|
p->lastPos+= p->speed;
|
||||||
|
p->pos+= p->speed;
|
||||||
|
p->speed+= p->accel;
|
||||||
|
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio);
|
||||||
|
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio);
|
||||||
|
p->energy--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos){
|
||||||
|
|
||||||
|
//compute axis
|
||||||
|
zVector= endPos - startPos;
|
||||||
|
zVector.normalize();
|
||||||
|
yVector= Vec3f(0.0f, 1.0f, 0.0f);
|
||||||
|
xVector= zVector.cross(yVector);
|
||||||
|
|
||||||
|
//apply offset
|
||||||
|
startPos+= xVector * offset.x;
|
||||||
|
startPos+= yVector * offset.y;
|
||||||
|
startPos+= zVector * offset.z;
|
||||||
|
|
||||||
|
pos= startPos;
|
||||||
|
lastPos= startPos;
|
||||||
|
flatPos= startPos;
|
||||||
|
|
||||||
|
//recompute axis
|
||||||
|
zVector= endPos - startPos;
|
||||||
|
zVector.normalize();
|
||||||
|
yVector= Vec3f(0.0f, 1.0f, 0.0f);
|
||||||
|
xVector= zVector.cross(yVector);
|
||||||
|
|
||||||
|
// set members
|
||||||
|
this->startPos= startPos;
|
||||||
|
this->endPos= endPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){
|
||||||
|
if(str=="linear"){
|
||||||
|
return tLinear;
|
||||||
|
}
|
||||||
|
else if(str=="parabolic"){
|
||||||
|
return tParabolic;
|
||||||
|
}
|
||||||
|
else if(str=="spiral"){
|
||||||
|
return tSpiral;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw "Unknown particle system trajectory: " + str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// SplashParticleSystem
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
SplashParticleSystem::SplashParticleSystem(int particleCount): AttackParticleSystem(particleCount){
|
||||||
|
setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f));
|
||||||
|
setMaxParticleEnergy(100);
|
||||||
|
setVarParticleEnergy(50);
|
||||||
|
setParticleSize(1.0f);
|
||||||
|
setSpeed(0.003f);
|
||||||
|
|
||||||
|
prevParticleSystem= NULL;
|
||||||
|
|
||||||
|
emissionRateFade= 1;
|
||||||
|
verticalSpreadA= 1.0f;
|
||||||
|
verticalSpreadB= 0.0f;
|
||||||
|
horizontalSpreadA= 1.0f;
|
||||||
|
horizontalSpreadB= 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
SplashParticleSystem::~SplashParticleSystem(){
|
||||||
|
if(prevParticleSystem!=NULL){
|
||||||
|
prevParticleSystem->nextParticleSystem= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashParticleSystem::update(){
|
||||||
|
ParticleSystem::update();
|
||||||
|
if(state!=sPause){
|
||||||
|
emissionRate-= emissionRateFade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
|
p->pos= pos;
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->energy= maxParticleEnergy;
|
||||||
|
p->size= particleSize;
|
||||||
|
p->color= color;
|
||||||
|
|
||||||
|
p->speed= Vec3f(
|
||||||
|
horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB,
|
||||||
|
verticalSpreadA * random.randRange(-1.0f, 1.0f) + verticalSpreadB,
|
||||||
|
horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB);
|
||||||
|
p->speed.normalize();
|
||||||
|
p->speed= p->speed * speed;
|
||||||
|
|
||||||
|
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashParticleSystem::updateParticle(Particle *p){
|
||||||
|
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f);
|
||||||
|
|
||||||
|
p->lastPos= p->pos;
|
||||||
|
p->pos= p->pos + p->speed;
|
||||||
|
p->speed= p->speed + p->accel;
|
||||||
|
p->energy--;
|
||||||
|
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio);
|
||||||
|
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// ParticleManager
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
ParticleManager::~ParticleManager(){
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{
|
||||||
|
list<ParticleSystem*>::const_iterator it;
|
||||||
|
|
||||||
|
for (it=particleSystems.begin(); it!=particleSystems.end(); it++){
|
||||||
|
if((*it)->getVisible()){
|
||||||
|
(*it)->render(pr, mr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleManager::update(){
|
||||||
|
list<ParticleSystem*>::iterator it;
|
||||||
|
|
||||||
|
for (it=particleSystems.begin(); it!=particleSystems.end(); it++){
|
||||||
|
(*it)->update();
|
||||||
|
if((*it)->isEmpty()){
|
||||||
|
delete *it;
|
||||||
|
*it= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
particleSystems.remove(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleManager::manage(ParticleSystem *ps){
|
||||||
|
particleSystems.push_back(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleManager::end(){
|
||||||
|
while(!particleSystems.empty()){
|
||||||
|
delete particleSystems.front();
|
||||||
|
particleSystems.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}}//end namespace
|
Loading…
Reference in New Issue
Block a user