particles have more switches: day/night visibility , alternating value , radiusBasedStartenergy ( can be disabled now! )

This commit is contained in:
Titus Tscharntke
2011-03-13 23:16:07 +00:00
parent 28f74a15f7
commit c54174061f
9 changed files with 428 additions and 299 deletions

View File

@@ -35,6 +35,7 @@ namespace Glest{ namespace Game{
ParticleSystemType::ParticleSystemType() { ParticleSystemType::ParticleSystemType() {
teamcolorNoEnergy=false; teamcolorNoEnergy=false;
teamcolorEnergy=false; teamcolorEnergy=false;
alternations=false;
texture=NULL; texture=NULL;
model=NULL; model=NULL;
} }
@@ -141,7 +142,11 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy"); const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy");
teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue(); teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue();
} }
//alternations
if(particleSystemNode->hasChild("alternations")){
const XmlNode *alternatingNode= particleSystemNode->getChild("alternations");
alternations= alternatingNode->getAttribute("value")->getIntValue();
}
//mode //mode
if(particleSystemNode->hasChild("mode")){ if(particleSystemNode->hasChild("mode")){
const XmlNode *modeNode= particleSystemNode->getChild("mode"); const XmlNode *modeNode= particleSystemNode->getChild("mode");
@@ -169,6 +174,7 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){
ats->setModel(model); ats->setModel(model);
ats->setTeamcolorNoEnergy(teamcolorNoEnergy); ats->setTeamcolorNoEnergy(teamcolorNoEnergy);
ats->setTeamcolorEnergy(teamcolorEnergy); ats->setTeamcolorEnergy(teamcolorEnergy);
ats->setAlternations(alternations);
ats->setBlendMode(ParticleSystem::strToBlendMode(mode)); ats->setBlendMode(ParticleSystem::strToBlendMode(mode));
} }

View File

@@ -63,6 +63,7 @@ protected:
string mode; string mode;
bool teamcolorNoEnergy; bool teamcolorNoEnergy;
bool teamcolorEnergy; bool teamcolorEnergy;
int alternations;
public: public:
ParticleSystemType(); ParticleSystemType();

View File

@@ -63,6 +63,33 @@ void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const strin
staticParticleCount=0; staticParticleCount=0;
} }
//isVisibleAtNight
if(particleSystemNode->hasChild("isVisibleAtNight")){
const XmlNode *isVisibleAtNightNode= particleSystemNode->getChild("isVisibleAtNight");
isVisibleAtNight= isVisibleAtNightNode->getAttribute("value")->getBoolValue();
}
else {
isVisibleAtNight=true;
}
//isVisibleAtDay
if(particleSystemNode->hasChild("isVisibleAtDay")){
const XmlNode *isVisibleAtDayNode= particleSystemNode->getChild("isVisibleAtDay");
isVisibleAtDay= isVisibleAtDayNode->getAttribute("value")->getBoolValue();
}
else {
isVisibleAtDay=true;
}
//radiusBasedStartenergy
if(particleSystemNode->hasChild("radiusBasedStartenergy")){
const XmlNode *isVisibleAtDayNode= particleSystemNode->getChild("radiusBasedStartenergy");
radiusBasedStartenergy= isVisibleAtDayNode->getAttribute("value")->getBoolValue();
}
else{
radiusBasedStartenergy= true;
}
//fixed //fixed
const XmlNode *fixedNode= particleSystemNode->getChild("fixed"); const XmlNode *fixedNode= particleSystemNode->getChild("fixed");
fixed= fixedNode->getAttribute("value")->getBoolValue(); fixed= fixedNode->getAttribute("value")->getBoolValue();
@@ -87,9 +114,14 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
ups->setRelativeDirection(relativeDirection); ups->setRelativeDirection(relativeDirection);
ups->setTeamcolorNoEnergy(teamcolorNoEnergy); ups->setTeamcolorNoEnergy(teamcolorNoEnergy);
ups->setTeamcolorEnergy(teamcolorEnergy); ups->setTeamcolorEnergy(teamcolorEnergy);
ups->setAlternations(alternations);
ups->setIsVisibleAtNight(isVisibleAtNight);
ups->setIsVisibleAtDay(isVisibleAtDay);
ups->setStaticParticleCount(staticParticleCount); ups->setStaticParticleCount(staticParticleCount);
ups->setRadius(radius); ups->setRadius(radius);
ups->setBlendMode(ParticleSystem::strToBlendMode(mode)); ups->setBlendMode(ParticleSystem::strToBlendMode(mode));
ups->setRadiusBasedStartenergy(radiusBasedStartenergy);
//prepare system for given staticParticleCount //prepare system for given staticParticleCount
if(staticParticleCount>0) if(staticParticleCount>0)
{ {

View File

@@ -51,6 +51,9 @@ protected:
bool relativeDirection; bool relativeDirection;
bool fixed; bool fixed;
int staticParticleCount; int staticParticleCount;
bool isVisibleAtNight;
bool isVisibleAtDay;
bool radiusBasedStartenergy;
public: public:
void load(const XmlNode *particleSystemNode, const string &dir, RendererInterface *newTexture); void load(const XmlNode *particleSystemNode, const string &dir, RendererInterface *newTexture);

View File

@@ -56,6 +56,7 @@ void TimeFlow::update() {
//day //day
if(lastTime<dawn && time>=dawn){ if(lastTime<dawn && time>=dawn){
soundRenderer.stopAmbient(ambientSounds->getNight()); soundRenderer.stopAmbient(ambientSounds->getNight());
UnitParticleSystem::isNight=false;
} }
if((lastTime<dawn && time>=dawn) || firstTime){ if((lastTime<dawn && time>=dawn) || firstTime){
@@ -75,6 +76,7 @@ void TimeFlow::update() {
//night //night
if(lastTime<dusk && time>=dusk){ if(lastTime<dusk && time>=dusk){
soundRenderer.stopAmbient(ambientSounds->getDay()); soundRenderer.stopAmbient(ambientSounds->getDay());
UnitParticleSystem::isNight=true;
} }
if(lastTime<dusk && time>=dusk){ if(lastTime<dusk && time>=dusk){

View File

@@ -1332,6 +1332,19 @@ void UnitUpdater::updateRepair(Unit *unit) {
//repairPos = command->getPos()-Vec2i(1); //repairPos = command->getPos()-Vec2i(1);
} }
if(startRepairing == false && repaired == NULL) {
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// we have a repair command to the ground! We must find first units in visible range of target point.
startRepairing = damagedRepairableUnitOnRange(rct, repairPos, unit->getType()->getSight(), &repaired);
//if(startRepairing) command->setPos(repaired->getCenteredPos());
if(repaired != NULL){
startRepairing = true;
nextToRepaired = repaired != NULL && map->isNextTo(unit->getPos(), repaired);
repairPos=repaired->getCenteredPos();
command->setPos(repairPos);
}
}
//if not repairing //if not repairing
if(startRepairing == true) { if(startRepairing == true) {
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@@ -1836,6 +1849,40 @@ void UnitUpdater::findEnemiesForCell(const AttackSkillType *ast, Cell *cell, con
} }
} }
bool UnitUpdater::damagedRepairableUnitOnRange(const RepairCommandType* rct, Vec2i repairPos, int range, Unit **unitToRepair){
Vec2f floatRepairPos = Vec2f(repairPos.x, repairPos.y);
Unit* damagedUnit=NULL;
int bestDistanced=-1;
for(int i=repairPos.x-range; i<repairPos.x+range+1; ++i){
for(int j=repairPos.y-range; j<repairPos.y+range+1; ++j){
//cells inside map and in range
#ifdef USE_STREFLOP
if(map->isInside(i, j) && streflop::floor(floatRepairPos.dist(Vec2f((float)i, (float)j))) <= (range+1)){
#else
if(map->isInside(i, j) && floor(floatRepairPos.dist(Vec2f((float)i, (float)j))) <= (range+1)){
#endif
Cell *cell = map->getCell(i,j);
for(int k = 0; k < fieldCount; k++) {
Field f= static_cast<Field>(k);
Unit *possibleUnit = cell->getUnit(f);
if( possibleUnit != NULL &&
possibleUnit->getTeam()==world->getThisTeamIndex() &&
rct->isRepairableUnitType(possibleUnit->getType()) &&
possibleUnit->isDamaged()) {
// possible unit!
*unitToRepair=possibleUnit;
return true;
// TODO choose nearest to repair unit
}
}
}
}
}
return false;
}
//if the unit has any enemy on range //if the unit has any enemy on range
bool UnitUpdater::unitOnRange(const Unit *unit, int range, Unit **rangedPtr, bool UnitUpdater::unitOnRange(const Unit *unit, int range, Unit **rangedPtr,
const AttackSkillType *ast){ const AttackSkillType *ast){

View File

@@ -126,6 +126,7 @@ private:
bool attackableOnRange(const Unit *unit, Unit **enemyPtr, const AttackSkillType *ast); bool attackableOnRange(const Unit *unit, Unit **enemyPtr, const AttackSkillType *ast);
bool unitOnRange(const Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast); bool unitOnRange(const Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast);
void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector<Unit*> &enemies); void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector<Unit*> &enemies);
bool damagedRepairableUnitOnRange(const RepairCommandType* rct, Vec2i repairPos, int range, Unit **unitToRepair);
Unit * findPeerUnitBuilder(Unit *unit); Unit * findPeerUnitBuilder(Unit *unit);
void SwapActiveCommand(Unit *unitSrc, Unit *unitDest); void SwapActiveCommand(Unit *unitSrc, Unit *unitDest);

View File

@@ -131,6 +131,7 @@ protected:
Vec3f factionColor; Vec3f factionColor;
bool teamcolorNoEnergy; bool teamcolorNoEnergy;
bool teamcolorEnergy; bool teamcolorEnergy;
int alternations;
ParticleObserver *particleObserver; ParticleObserver *particleObserver;
@@ -154,7 +155,7 @@ public:
const Particle *getParticle(int i) const {return &particles[i];} const Particle *getParticle(int i) const {return &particles[i];}
int getAliveParticleCount() const {return aliveParticleCount;} int getAliveParticleCount() const {return aliveParticleCount;}
bool getActive() const {return active;} bool getActive() const {return active;}
bool getVisible() const {return visible;} virtual bool getVisible() const {return visible;}
//set //set
void setState(State state); void setState(State state);
@@ -173,6 +174,7 @@ public:
void setBlendMode(BlendMode blendMode) {this->blendMode= blendMode;} void setBlendMode(BlendMode blendMode) {this->blendMode= blendMode;}
void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {this->teamcolorNoEnergy= teamcolorNoEnergy;} void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {this->teamcolorNoEnergy= teamcolorNoEnergy;}
void setTeamcolorEnergy(bool teamcolorEnergy) {this->teamcolorEnergy= teamcolorEnergy;} void setTeamcolorEnergy(bool teamcolorEnergy) {this->teamcolorEnergy= teamcolorEnergy;}
void setAlternations(int alternations) {this->alternations= alternations;}
virtual void setFactionColor(Vec3f factionColor); virtual void setFactionColor(Vec3f factionColor);
static BlendMode strToBlendMode(const string &str); static BlendMode strToBlendMode(const string &str);
@@ -219,6 +221,8 @@ public:
// ===================================================== // =====================================================
class UnitParticleSystem: public ParticleSystem{ class UnitParticleSystem: public ParticleSystem{
public:
static bool isNight;
private: private:
float radius; float radius;
Vec3f windSpeed; Vec3f windSpeed;
@@ -242,6 +246,10 @@ public:
float sizeNoEnergy; float sizeNoEnergy;
float gravity; float gravity;
float rotation; float rotation;
bool isVisibleAtNight;
bool isVisibleAtDay;
bool radiusBasedStartenergy;
int staticParticleCount; int staticParticleCount;
public: public:
@@ -254,6 +262,7 @@ public:
virtual void updateParticle(Particle *p); virtual void updateParticle(Particle *p);
virtual void update(); virtual void update();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr); virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
virtual bool getVisible() const;
//set params //set params
void setRadius(float radius); void setRadius(float radius);
@@ -269,6 +278,9 @@ public:
void setFixed(bool fixed) {this->fixed= fixed;} void setFixed(bool fixed) {this->fixed= fixed;}
void setPrimitive(Primitive primitive) {this->primitive= primitive;} void setPrimitive(Primitive primitive) {this->primitive= primitive;}
void setStaticParticleCount(int staticParticleCount){this->staticParticleCount= staticParticleCount;} void setStaticParticleCount(int staticParticleCount){this->staticParticleCount= staticParticleCount;}
void setIsVisibleAtNight(bool value) {this->isVisibleAtNight= value;}
void setIsVisibleAtDay(bool value) {this->isVisibleAtDay= value;}
void setRadiusBasedStartenergy(bool value) {this->radiusBasedStartenergy= value;}
static Primitive strToPrimitive(const string &str); static Primitive strToPrimitive(const string &str);

View File

@@ -26,22 +26,23 @@ using namespace std;
using namespace Shared::Util; using namespace Shared::Util;
using namespace Shared::PlatformCommon; using namespace Shared::PlatformCommon;
namespace Shared{ namespace Graphics{ namespace Shared {
namespace Graphics {
// ===================================================== // =====================================================
// class ParticleSystem // class ParticleSystem
// ===================================================== // =====================================================
ParticleSystem::ParticleSystem(int particleCount) { ParticleSystem::ParticleSystem(int particleCount){
//init particle vector //init particle vector
blendMode = bmOne; blendMode= bmOne;
//particles= new Particle[particleCount]; //particles= new Particle[particleCount];
particles.clear(); particles.clear();
//particles.reserve(particleCount); //particles.reserve(particleCount);
particles.resize(particleCount); particles.resize(particleCount);
state= sPlay; state= sPlay;
aliveParticleCount=0; aliveParticleCount= 0;
active= true; active= true;
visible= true; visible= true;
@@ -60,8 +61,9 @@ ParticleSystem::ParticleSystem(int particleCount) {
emissionRate= 15.0f; emissionRate= 15.0f;
emissionState= 1.0f; // initialized with 1 because we must have at least one particle in the beginning! emissionState= 1.0f; // initialized with 1 because we must have at least one particle in the beginning!
speed= 1.0f; speed= 1.0f;
teamcolorNoEnergy=false; teamcolorNoEnergy= false;
teamcolorEnergy=false; teamcolorEnergy= false;
alternations= 0;
} }
ParticleSystem::~ParticleSystem(){ ParticleSystem::~ParticleSystem(){
@@ -69,39 +71,38 @@ ParticleSystem::~ParticleSystem(){
particles.clear(); particles.clear();
} }
// =============== VIRTUAL ====================== // =============== VIRTUAL ======================
//updates all living particles and creates new ones //updates all living particles and creates new ones
void ParticleSystem::update() { void ParticleSystem::update(){
if(aliveParticleCount > (int)particles.size()) { if(aliveParticleCount > (int) particles.size()){
throw runtime_error("aliveParticleCount >= particles.size()"); throw runtime_error("aliveParticleCount >= particles.size()");
} }
if(state != sPause){ if(state != sPause){
for(int i = 0; i< aliveParticleCount; ++i) { for(int i= 0; i < aliveParticleCount; ++i){
updateParticle(&particles[i]); updateParticle(&particles[i]);
if(deathTest(&particles[i])) { if(deathTest(&particles[i])){
//kill the particle //kill the particle
killParticle(&particles[i]); killParticle(&particles[i]);
//maintain alive particles at front of the array //maintain alive particles at front of the array
if(aliveParticleCount > 0) { if(aliveParticleCount > 0){
particles[i] = particles[aliveParticleCount]; particles[i]= particles[aliveParticleCount];
} }
} }
} }
if(state != ParticleSystem::sFade){ if(state != ParticleSystem::sFade){
emissionState=emissionState+emissionRate; emissionState= emissionState + emissionRate;
int emissionIntValue=(int)emissionState; int emissionIntValue= (int) emissionState;
for(int i = 0; i < emissionIntValue; i++){ for(int i= 0; i < emissionIntValue; i++){
Particle *p = createParticle(); Particle *p= createParticle();
initParticle(p, i); initParticle(p, i);
} }
emissionState=emissionState-(float)emissionIntValue; emissionState= emissionState - (float) emissionIntValue;
} }
} }
} }
@@ -113,10 +114,10 @@ void ParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
} }
ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){ ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
if(str=="normal"){ if(str == "normal"){
return bmOne; return bmOne;
} }
else if(str=="black"){ else if(str == "black"){
return bmOneMinusAlpha; return bmOneMinusAlpha;
} }
else{ else{
@@ -124,7 +125,6 @@ ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
} }
} }
// =============== SET ========================== // =============== SET ==========================
void ParticleSystem::setState(State state){ void ParticleSystem::setState(State state){
@@ -180,19 +180,19 @@ void ParticleSystem::setVisible(bool visible){
} }
// =============== MISC ========================= // =============== MISC =========================
void ParticleSystem::fade() { void ParticleSystem::fade(){
if(particleObserver != NULL) { if(particleObserver != NULL){
assert(state == sPlay); assert(state == sPlay);
} }
state= sFade; state= sFade;
if(particleObserver!=NULL){ if(particleObserver != NULL){
particleObserver->update(this); particleObserver->update(this);
} }
} }
int ParticleSystem::isEmpty() const{ int ParticleSystem::isEmpty() const{
assert(aliveParticleCount>=0); assert(aliveParticleCount>=0);
return aliveParticleCount==0 && state!=sPause; return aliveParticleCount == 0 && state != sPause;
} }
// =============== PROTECTED ========================= // =============== PROTECTED =========================
@@ -202,24 +202,24 @@ int ParticleSystem::isEmpty() const{
Particle * ParticleSystem::createParticle(){ Particle * ParticleSystem::createParticle(){
//if any dead particles //if any dead particles
if(aliveParticleCount < particleCount) { if(aliveParticleCount < particleCount){
++aliveParticleCount; ++aliveParticleCount;
return &particles[aliveParticleCount-1]; return &particles[aliveParticleCount - 1];
} }
//if not //if not
int minEnergy = particles[0].energy; int minEnergy= particles[0].energy;
int minEnergyParticle = 0; int minEnergyParticle= 0;
for(int i = 0; i < particleCount; ++i){ for(int i= 0; i < particleCount; ++i){
if(particles[i].energy < minEnergy){ if(particles[i].energy < minEnergy){
minEnergy = particles[i].energy; minEnergy= particles[i].energy;
minEnergyParticle = i; minEnergyParticle= i;
} }
} }
return &particles[minEnergyParticle]; return &particles[minEnergyParticle];
/* /*
//if any dead particles //if any dead particles
if(aliveParticleCount < particleCount) { if(aliveParticleCount < particleCount) {
++aliveParticleCount; ++aliveParticleCount;
@@ -238,7 +238,7 @@ Particle * ParticleSystem::createParticle(){
} }
return &particles[minEnergyParticle]; return &particles[minEnergyParticle];
*/ */
} }
void ParticleSystem::initParticle(Particle *p, int particleIndex){ void ParticleSystem::initParticle(Particle *p, int particleIndex){
@@ -267,26 +267,24 @@ void ParticleSystem::killParticle(Particle *p){
} }
void ParticleSystem::setFactionColor(Vec3f factionColor){ void ParticleSystem::setFactionColor(Vec3f factionColor){
this->factionColor=factionColor; this->factionColor= factionColor;
Vec3f tmpCol; Vec3f tmpCol;
if(teamcolorEnergy) if(teamcolorEnergy){
{ this->color= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->color.w);
this->color=Vec4f(factionColor.x,factionColor.y,factionColor.z,this->color.w);
} }
if(teamcolorNoEnergy) if(teamcolorNoEnergy){
{ this->colorNoEnergy= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->colorNoEnergy.w);
this->colorNoEnergy=Vec4f(factionColor.x,factionColor.y,factionColor.z,this->colorNoEnergy.w);
} }
} }
// =========================================================================== // ===========================================================================
// FireParticleSystem // FireParticleSystem
// =========================================================================== // ===========================================================================
FireParticleSystem::FireParticleSystem(int particleCount): ParticleSystem(particleCount){ FireParticleSystem::FireParticleSystem(int particleCount) :
ParticleSystem(particleCount){
radius= 0.5f; radius= 0.5f;
speed= 0.01f; speed= 0.01f;
@@ -299,7 +297,7 @@ FireParticleSystem::FireParticleSystem(int particleCount): ParticleSystem(partic
void FireParticleSystem::initParticle(Particle *p, int particleIndex){ void FireParticleSystem::initParticle(Particle *p, int particleIndex){
ParticleSystem::initParticle(p, particleIndex); ParticleSystem::initParticle(p, particleIndex);
float ang= random.randRange(-2.0f*pi, 2.0f*pi); float ang= random.randRange(-2.0f * pi, 2.0f * pi);
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
float mod= streflop::fabsf(random.randRange(-radius, radius)); float mod= streflop::fabsf(random.randRange(-radius, radius));
@@ -310,33 +308,34 @@ void FireParticleSystem::initParticle(Particle *p, int particleIndex){
#else #else
float mod= fabsf(random.randRange(-radius, radius)); float mod= fabsf(random.randRange(-radius, radius));
float x= sinf(ang)*mod; float x= sinf(ang) * mod;
float y= cosf(ang)*mod; float y= cosf(ang) * mod;
float radRatio= sqrtf(sqrtf(mod/radius)); float radRatio= sqrtf(sqrtf(mod / radius));
#endif #endif
p->color= colorNoEnergy*0.5f + colorNoEnergy*0.5f*radRatio; p->color= colorNoEnergy * 0.5f + colorNoEnergy * 0.5f * radRatio;
p->energy= static_cast<int>(maxParticleEnergy*radRatio) + random.randRange(-varParticleEnergy, varParticleEnergy); p->energy= static_cast<int> (maxParticleEnergy * radRatio)
p->pos= Vec3f(pos.x+x, pos.y+random.randRange(-radius/2, radius/2), pos.z+y); + 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->lastPos= pos;
p->size= particleSize; p->size= particleSize;
p->speed= Vec3f(0, speed+speed*random.randRange(-0.5f, 0.5f), 0) + windSpeed; p->speed= Vec3f(0, speed + speed * random.randRange(-0.5f, 0.5f), 0) + windSpeed;
} }
void FireParticleSystem::updateParticle(Particle *p){ void FireParticleSystem::updateParticle(Particle *p){
p->lastPos= p->pos; p->lastPos= p->pos;
p->pos= p->pos+p->speed; p->pos= p->pos + p->speed;
p->energy--; p->energy--;
if(p->color.x>0.0f) if(p->color.x > 0.0f)
p->color.x*= 0.98f; p->color.x*= 0.98f;
if(p->color.y>0.0f) if(p->color.y > 0.0f)
p->color.y*= 0.98f; p->color.y*= 0.98f;
if(p->color.w>0.0f) if(p->color.w > 0.0f)
p->color.w*= 0.98f; p->color.w*= 0.98f;
p->speed.x*=1.001f; p->speed.x*= 1.001f;
} }
@@ -352,19 +351,19 @@ void FireParticleSystem::setWind(float windAngle, float windSpeed){
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed;
#else #else
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed;
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed;
#endif #endif
} }
// =========================================================================== // ===========================================================================
// UnitParticleSystem // UnitParticleSystem
// =========================================================================== // ===========================================================================
bool UnitParticleSystem::isNight= false;
UnitParticleSystem::UnitParticleSystem(int particleCount): ParticleSystem(particleCount){ UnitParticleSystem::UnitParticleSystem(int particleCount) :
ParticleSystem(particleCount){
radius= 0.5f; radius= 0.5f;
speed= 0.01f; speed= 0.01f;
windSpeed= Vec3f(0.0f); windSpeed= Vec3f(0.0f);
@@ -374,26 +373,38 @@ UnitParticleSystem::UnitParticleSystem(int particleCount): ParticleSystem(partic
primitive= pQuad; primitive= pQuad;
offset= Vec3f(0.0f); offset= Vec3f(0.0f);
direction= Vec3f(0.0f,1.0f,0.0f); direction= Vec3f(0.0f, 1.0f, 0.0f);
gravity= 0.0f; gravity= 0.0f;
fixed=false; fixed= false;
rotation=0.0f; rotation= 0.0f;
relativeDirection=true; relativeDirection= true;
relative=false; relative= false;
staticParticleCount=0; staticParticleCount= 0;
cRotation= Vec3f(1.0f,1.0f,1.0f); isVisibleAtNight= true;
fixedAddition = Vec3f(0.0f,0.0f,0.0f); isVisibleAtDay= true;
cRotation= Vec3f(1.0f, 1.0f, 1.0f);
fixedAddition= Vec3f(0.0f, 0.0f, 0.0f);
//prepare system for given staticParticleCount //prepare system for given staticParticleCount
if(staticParticleCount>0) if(staticParticleCount > 0){
{ emissionState= (float) staticParticleCount;
emissionState= (float)staticParticleCount;
} }
energyUp=false; energyUp= false;
} }
void UnitParticleSystem::render(ParticleRenderer *pr,ModelRenderer *mr){ bool UnitParticleSystem::getVisible() const{
if((isNight==true) && (isVisibleAtNight==true)){
return visible;
}
else if((isNight==false) && (isVisibleAtDay==true)){
return visible;
}
else return false;
}
void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
//if(active){ //if(active){
switch(primitive){ switch(primitive){
case pQuad: case pQuad:
@@ -409,10 +420,10 @@ void UnitParticleSystem::render(ParticleRenderer *pr,ModelRenderer *mr){
} }
UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &str){ UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &str){
if(str=="quad"){ if(str == "quad"){
return pQuad; return pQuad;
} }
else if(str=="line"){ else if(str == "line"){
return pLine; return pLine;
} }
else{ else{
@@ -420,11 +431,10 @@ UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &s
} }
} }
void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
ParticleSystem::initParticle(p, particleIndex); ParticleSystem::initParticle(p, particleIndex);
float ang= random.randRange(-2.0f*pi, 2.0f*pi); float ang= random.randRange(-2.0f * pi, 2.0f * pi);
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
float mod= streflop::fabsf(random.randRange(-radius, radius)); float mod= streflop::fabsf(random.randRange(-radius, radius));
@@ -435,41 +445,48 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
#else #else
float mod= fabsf(random.randRange(-radius, radius)); float mod= fabsf(random.randRange(-radius, radius));
float x= sinf(ang)*mod; float x= sinf(ang) * mod;
float y= cosf(ang)*mod; float y= cosf(ang) * mod;
float radRatio= sqrtf(sqrtf(mod/radius)); float radRatio= sqrtf(sqrtf(mod / radius));
#endif #endif
//p->color= color*0.5f + color*0.5f*radRatio; //p->color= color*0.5f + color*0.5f*radRatio;
p->color=color; p->color= color;
p->energy= static_cast<int>(maxParticleEnergy*radRatio) + random.randRange(-varParticleEnergy, varParticleEnergy); if(radiusBasedStartenergy == true){
p->energy= static_cast<int> (maxParticleEnergy * radRatio) + random.randRange(-varParticleEnergy,
varParticleEnergy);
}
else{
p->energy= static_cast<int> (maxParticleEnergy) + random.randRange(-varParticleEnergy, varParticleEnergy);
}
p->lastPos= pos; p->lastPos= pos;
oldPosition=pos; oldPosition= pos;
p->size= particleSize; p->size= particleSize;
p->speed= Vec3f(direction.x+direction.x*random.randRange(-0.5f, 0.5f), p->speed= Vec3f(direction.x + direction.x * random.randRange(-0.5f, 0.5f), direction.y + direction.y
direction.y+direction.y*random.randRange(-0.5f, 0.5f), * random.randRange(-0.5f, 0.5f), direction.z + direction.z * random.randRange(-0.5f, 0.5f));
direction.z+direction.z*random.randRange(-0.5f, 0.5f));
p->speed= p->speed * speed; p->speed= p->speed * speed;
p->accel= Vec3f(0.0f, -gravity, 0.0f); p->accel= Vec3f(0.0f, -gravity, 0.0f);
if(relative == false) { if(relative == false){
p->pos= Vec3f(pos.x+x+offset.x, pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+offset.z); p->pos= Vec3f(pos.x + x + offset.x, pos.y + random.randRange(-radius / 2, radius / 2) + offset.y, pos.z + y
+ offset.z);
} }
else else{// rotate it according to rotation
{// rotate it according to rotation float rad= degToRad(rotation);
float rad=degToRad(rotation);
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
p->pos= Vec3f(pos.x+x+offset.z*streflop::sinf(rad)+offset.x*streflop::cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*streflop::cosf(rad)-offset.x*streflop::sinf(rad))); p->pos= Vec3f(pos.x+x+offset.z*streflop::sinf(rad)+offset.x*streflop::cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*streflop::cosf(rad)-offset.x*streflop::sinf(rad)));
if(relativeDirection){ if(relativeDirection){
p->speed=Vec3f(p->speed.z*streflop::sinf(rad)+p->speed.x*streflop::cosf(rad),p->speed.y,(p->speed.z*streflop::cosf(rad)-p->speed.x*streflop::sinf(rad))); p->speed=Vec3f(p->speed.z*streflop::sinf(rad)+p->speed.x*streflop::cosf(rad),p->speed.y,(p->speed.z*streflop::cosf(rad)-p->speed.x*streflop::sinf(rad)));
} }
#else #else
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))); 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){ 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))); 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)));
} }
#endif #endif
@@ -477,48 +494,57 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
} }
void UnitParticleSystem::update(){ void UnitParticleSystem::update(){
if(fixed) if(fixed){
{ fixedAddition= Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z);
fixedAddition= Vec3f(pos.x-oldPosition.x,pos.y-oldPosition.y,pos.z-oldPosition.z); oldPosition= pos;
oldPosition=pos;
} }
ParticleSystem::update(); ParticleSystem::update();
} }
void UnitParticleSystem::updateParticle(Particle *p){ void UnitParticleSystem::updateParticle(Particle *p){
float energyRatio;
if(alternations > 0){
int interval= (maxParticleEnergy / alternations);
float moduloValue= static_cast<int> (static_cast<float> (p->energy)) % interval;
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f); if(moduloValue < interval / 2){
energyRatio= (interval - moduloValue) / interval;
}
else{
energyRatio= moduloValue / interval;
}
energyRatio= clamp(energyRatio, 0.f, 1.f);
}
else{
energyRatio= clamp(static_cast<float> (p->energy) / maxParticleEnergy, 0.f, 1.f);
}
p->lastPos+= p->speed; p->lastPos+= p->speed;
p->pos+= p->speed; p->pos+= p->speed;
if(fixed) if(fixed){
{
p->lastPos+= fixedAddition; p->lastPos+= fixedAddition;
p->pos+= fixedAddition; p->pos+= fixedAddition;
} }
p->speed+= p->accel; p->speed+= p->accel;
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio); p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio);
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio); p->size= particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio);
if(state == ParticleSystem::sFade || staticParticleCount<1) if(state == ParticleSystem::sFade || staticParticleCount < 1){
{
p->energy--; p->energy--;
} }
else else{
{ if(maxParticleEnergy > 2){
if(maxParticleEnergy>2)
{
if(energyUp){ if(energyUp){
p->energy++; p->energy++;
} }
else { else{
p->energy--; p->energy--;
} }
if(p->energy==1){ if(p->energy == 1){
energyUp=true; energyUp= true;
} }
if(p->energy==maxParticleEnergy){ if(p->energy == maxParticleEnergy){
energyUp=false; energyUp= false;
} }
} }
} }
@@ -536,21 +562,19 @@ void UnitParticleSystem::setWind(float windAngle, float windSpeed){
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed;
#else #else
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed;
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed;
#endif #endif
} }
// =========================================================================== // ===========================================================================
// RainParticleSystem // RainParticleSystem
// =========================================================================== // ===========================================================================
RainParticleSystem::RainParticleSystem(int particleCount):ParticleSystem(particleCount){ RainParticleSystem::RainParticleSystem(int particleCount) :
ParticleSystem(particleCount){
setWind(0.0f, 0.0f); setWind(0.0f, 0.0f);
setRadius(20.0f); setRadius(20.0f);
@@ -572,13 +596,14 @@ void RainParticleSystem::initParticle(Particle *p, int particleIndex){
p->color= color; p->color= color;
p->energy= 10000; p->energy= 10000;
p->pos= Vec3f(pos.x+x, pos.y, pos.z+y); p->pos= Vec3f(pos.x + x, pos.y, pos.z + y);
p->lastPos= p->pos; p->lastPos= p->pos;
p->speed= Vec3f(random.randRange(-speed/10, speed/10), -speed, random.randRange(-speed/10, speed/10)) + windSpeed; p->speed= Vec3f(random.randRange(-speed / 10, speed / 10), -speed, random.randRange(-speed / 10, speed / 10))
+ windSpeed;
} }
bool RainParticleSystem::deathTest(Particle *p){ bool RainParticleSystem::deathTest(Particle *p){
return p->pos.y<0; return p->pos.y < 0;
} }
void RainParticleSystem::setRadius(float radius){ void RainParticleSystem::setRadius(float radius){
@@ -592,9 +617,9 @@ void RainParticleSystem::setWind(float windAngle, float windSpeed){
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed;
#else #else
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed;
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed;
#endif #endif
} }
@@ -602,7 +627,8 @@ void RainParticleSystem::setWind(float windAngle, float windSpeed){
// SnowParticleSystem // SnowParticleSystem
// =========================================================================== // ===========================================================================
SnowParticleSystem::SnowParticleSystem(int particleCount):ParticleSystem(particleCount){ SnowParticleSystem::SnowParticleSystem(int particleCount) :
ParticleSystem(particleCount){
setWind(0.0f, 0.0f); setWind(0.0f, 0.0f);
setRadius(30.0f); setRadius(30.0f);
@@ -621,7 +647,7 @@ void SnowParticleSystem::initParticle(Particle *p, int particleIndex){
p->color= color; p->color= color;
p->energy= 10000; p->energy= 10000;
p->pos= Vec3f(pos.x+x, pos.y, pos.z+y); p->pos= Vec3f(pos.x + x, pos.y, pos.z + y);
p->lastPos= p->pos; p->lastPos= p->pos;
p->speed= Vec3f(0.0f, -speed, 0.0f) + windSpeed; p->speed= Vec3f(0.0f, -speed, 0.0f) + windSpeed;
p->speed.x+= random.randRange(-0.005f, 0.005f); p->speed.x+= random.randRange(-0.005f, 0.005f);
@@ -629,7 +655,7 @@ void SnowParticleSystem::initParticle(Particle *p, int particleIndex){
} }
bool SnowParticleSystem::deathTest(Particle *p){ bool SnowParticleSystem::deathTest(Particle *p){
return p->pos.y<0; return p->pos.y < 0;
} }
void SnowParticleSystem::setRadius(float radius){ void SnowParticleSystem::setRadius(float radius){
@@ -642,9 +668,9 @@ void SnowParticleSystem::setWind(float windAngle, float windSpeed){
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed;
#else #else
this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed;
this->windSpeed.y= 0.0f; this->windSpeed.y= 0.0f;
this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed;
#endif #endif
} }
@@ -652,7 +678,8 @@ void SnowParticleSystem::setWind(float windAngle, float windSpeed){
// AttackParticleSystem // AttackParticleSystem
// =========================================================================== // ===========================================================================
AttackParticleSystem::AttackParticleSystem(int particleCount): ParticleSystem(particleCount){ AttackParticleSystem::AttackParticleSystem(int particleCount) :
ParticleSystem(particleCount){
model= NULL; model= NULL;
primitive= pQuad; primitive= pQuad;
offset= Vec3f(0.0f); offset= Vec3f(0.0f);
@@ -662,7 +689,7 @@ AttackParticleSystem::AttackParticleSystem(int particleCount): ParticleSystem(pa
void AttackParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){ void AttackParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
if(active){ if(active){
if(model!=NULL){ if(model != NULL){
pr->renderSingleModel(this, mr); pr->renderSingleModel(this, mr);
} }
switch(primitive){ switch(primitive){
@@ -679,10 +706,10 @@ void AttackParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
} }
AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const string &str){ AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const string &str){
if(str=="quad"){ if(str == "quad"){
return pQuad; return pQuad;
} }
else if(str=="line"){ else if(str == "line"){
return pLine; return pLine;
} }
else{ else{
@@ -694,7 +721,8 @@ AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const strin
// ProjectileParticleSystem // ProjectileParticleSystem
// =========================================================================== // ===========================================================================
ProjectileParticleSystem::ProjectileParticleSystem(int particleCount): AttackParticleSystem(particleCount){ ProjectileParticleSystem::ProjectileParticleSystem(int particleCount) :
AttackParticleSystem(particleCount){
setEmissionRate(20.0f); setEmissionRate(20.0f);
setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f)); setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f));
setMaxParticleEnergy(100); setMaxParticleEnergy(100);
@@ -705,13 +733,13 @@ ProjectileParticleSystem::ProjectileParticleSystem(int particleCount): AttackPar
trajectory= tLinear; trajectory= tLinear;
trajectorySpeed= 1.0f; trajectorySpeed= 1.0f;
trajectoryScale= 1.0f; trajectoryScale= 1.0f;
trajectoryFrequency = 1.0f; trajectoryFrequency= 1.0f;
nextParticleSystem= NULL; nextParticleSystem= NULL;
} }
ProjectileParticleSystem::~ProjectileParticleSystem(){ ProjectileParticleSystem::~ProjectileParticleSystem(){
if(nextParticleSystem!=NULL){ if(nextParticleSystem != NULL){
nextParticleSystem->prevParticleSystem= NULL; nextParticleSystem->prevParticleSystem= NULL;
} }
} }
@@ -724,7 +752,7 @@ void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem){
void ProjectileParticleSystem::update(){ void ProjectileParticleSystem::update(){
if(state==sPlay){ if(state == sPlay){
lastPos= pos; lastPos= pos;
flatPos+= zVector * trajectorySpeed; flatPos+= zVector * trajectorySpeed;
@@ -736,31 +764,28 @@ void ProjectileParticleSystem::update(){
// trajectory // trajectory
switch(trajectory){ switch(trajectory){
case tLinear: case tLinear: {
{
pos= flatPos; pos= flatPos;
} }
break; break;
case tParabolic: case tParabolic: {
{ float scaledT= 2.0f * (t - 0.5f);
float scaledT= 2.0f * (t-0.5f); float paraboleY= (1.0f - scaledT * scaledT) * trajectoryScale;
float paraboleY= (1.0f-scaledT*scaledT) * trajectoryScale;
pos = flatPos; pos= flatPos;
pos.y+= paraboleY; pos.y+= paraboleY;
} }
break; break;
case tSpiral: case tSpiral: {
{
pos= flatPos; pos= flatPos;
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
pos+= xVector * streflop::cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale; pos+= xVector * streflop::cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
pos+= yVector * streflop::sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale; pos+= yVector * streflop::sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
#else #else
pos+= xVector * cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale; pos+= xVector * cos(t * trajectoryFrequency * targetVector.length()) * trajectoryScale;
pos+= yVector * sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale; pos+= yVector * sin(t * trajectoryFrequency * targetVector.length()) * trajectoryScale;
#endif #endif
} }
break; break;
@@ -773,15 +798,15 @@ void ProjectileParticleSystem::update(){
direction.normalize(); direction.normalize();
//arrive destination //arrive destination
if( flatPos.dist(endPos)<0.5f ){ if(flatPos.dist(endPos) < 0.5f){
state= sFade; state= sFade;
model= NULL; model= NULL;
if(particleObserver!=NULL){ if(particleObserver != NULL){
particleObserver->update(this); particleObserver->update(this);
} }
if(nextParticleSystem!=NULL){ if(nextParticleSystem != NULL){
nextParticleSystem->setState(sPlay); nextParticleSystem->setState(sPlay);
nextParticleSystem->setPos(endPos); nextParticleSystem->setPos(endPos);
} }
@@ -795,24 +820,25 @@ void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){
ParticleSystem::initParticle(p, particleIndex); ParticleSystem::initParticle(p, particleIndex);
float t= static_cast<float>(particleIndex)/emissionRate; float t= static_cast<float> (particleIndex) / emissionRate;
p->pos= pos + (lastPos - pos) * t; p->pos= pos + (lastPos - pos) * t;
p->lastPos= lastPos; 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->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); p->accel= Vec3f(0.0f, -gravity, 0.0f);
updateParticle(p); updateParticle(p);
} }
void ProjectileParticleSystem::updateParticle(Particle *p){ void ProjectileParticleSystem::updateParticle(Particle *p){
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f); float energyRatio= clamp(static_cast<float> (p->energy) / maxParticleEnergy, 0.f, 1.f);
p->lastPos+= p->speed; p->lastPos+= p->speed;
p->pos+= p->speed; p->pos+= p->speed;
p->speed+= p->accel; p->speed+= p->accel;
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio); p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio);
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio); p->size= particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio);
p->energy--; p->energy--;
} }
@@ -845,13 +871,13 @@ void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos){
} }
ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){ ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){
if(str=="linear"){ if(str == "linear"){
return tLinear; return tLinear;
} }
else if(str=="parabolic"){ else if(str == "parabolic"){
return tParabolic; return tParabolic;
} }
else if(str=="spiral"){ else if(str == "spiral"){
return tSpiral; return tSpiral;
} }
else{ else{
@@ -863,7 +889,8 @@ ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(c
// SplashParticleSystem // SplashParticleSystem
// =========================================================================== // ===========================================================================
SplashParticleSystem::SplashParticleSystem(int particleCount): AttackParticleSystem(particleCount){ SplashParticleSystem::SplashParticleSystem(int particleCount) :
AttackParticleSystem(particleCount){
setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f)); setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f));
setMaxParticleEnergy(100); setMaxParticleEnergy(100);
setVarParticleEnergy(50); setVarParticleEnergy(50);
@@ -880,17 +907,16 @@ SplashParticleSystem::SplashParticleSystem(int particleCount): AttackParticleSys
} }
SplashParticleSystem::~SplashParticleSystem(){ SplashParticleSystem::~SplashParticleSystem(){
if(prevParticleSystem!=NULL){ if(prevParticleSystem != NULL){
prevParticleSystem->nextParticleSystem= NULL; prevParticleSystem->nextParticleSystem= NULL;
} }
} }
void SplashParticleSystem::update(){ void SplashParticleSystem::update(){
ParticleSystem::update(); ParticleSystem::update();
if(state!=sPause){ if(state != sPause){
emissionRate-= emissionRateFade; emissionRate-= emissionRateFade;
if(emissionRate<0.0f) if(emissionRate < 0.0f){//otherwise this system lives forever!
{//otherwise this system lives forever!
fade(); fade();
} }
} }
@@ -903,10 +929,9 @@ void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
p->size= particleSize; p->size= particleSize;
p->color= color; p->color= color;
p->speed= Vec3f( p->speed= Vec3f(horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, verticalSpreadA
horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, * random.randRange(-1.0f, 1.0f) + verticalSpreadB, horizontalSpreadA * random.randRange(-1.0f, 1.0f)
verticalSpreadA * random.randRange(-1.0f, 1.0f) + verticalSpreadB, + horizontalSpreadB);
horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB);
p->speed.normalize(); p->speed.normalize();
p->speed= p->speed * speed; p->speed= p->speed * speed;
@@ -914,14 +939,14 @@ void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
} }
void SplashParticleSystem::updateParticle(Particle *p){ void SplashParticleSystem::updateParticle(Particle *p){
float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f); float energyRatio= clamp(static_cast<float> (p->energy) / maxParticleEnergy, 0.f, 1.f);
p->lastPos= p->pos; p->lastPos= p->pos;
p->pos= p->pos + p->speed; p->pos= p->pos + p->speed;
p->speed= p->speed + p->accel; p->speed= p->speed + p->accel;
p->energy--; p->energy--;
p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio); p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio);
p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio); p->size= particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio);
} }
// =========================================================================== // ===========================================================================
@@ -933,37 +958,36 @@ ParticleManager::~ParticleManager(){
} }
void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{ void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
if(ps != NULL && ps->getVisible()) { if(ps != NULL && ps->getVisible()){
ps->render(pr, mr); ps->render(pr, mr);
} }
} }
} }
bool ParticleManager::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const { bool ParticleManager::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const{
bool result = false; bool result= false;
size_t particleSystemCount = particleSystems.size(); size_t particleSystemCount= particleSystems.size();
int currentParticleCount = 0; int currentParticleCount= 0;
vector<ParticleSystem *> cleanupParticleSystemsList; vector<ParticleSystem *> cleanupParticleSystemsList;
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
if(ps != NULL) { if(ps != NULL){
currentParticleCount += ps->getAliveParticleCount(); currentParticleCount+= ps->getAliveParticleCount();
bool showParticle = true; bool showParticle= true;
if( dynamic_cast<UnitParticleSystem *>(ps) != NULL || if(dynamic_cast<UnitParticleSystem *> (ps) != NULL || dynamic_cast<FireParticleSystem *> (ps) != NULL){
dynamic_cast<FireParticleSystem *>(ps) != NULL ) { showParticle= ps->getVisible() || (ps->getState() == ParticleSystem::sFade);
showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade);
} }
if(showParticle == true) { if(showParticle == true){
//printf("Looking for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); //printf("Looking for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i);
if(type == ParticleSystem::pst_All || type == ps->getParticleSystemType()) { if(type == ParticleSystem::pst_All || type == ps->getParticleSystemType()){
//printf("FOUND particle system type match for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); //printf("FOUND particle system type match for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i);
result = true; result= true;
break; break;
} }
} }
@@ -973,27 +997,26 @@ bool ParticleManager::hasActiveParticleSystem(ParticleSystem::ParticleSystemType
return result; return result;
} }
void ParticleManager::update(int renderFps) { void ParticleManager::update(int renderFps){
Chrono chrono; Chrono chrono;
chrono.start(); chrono.start();
size_t particleSystemCount = particleSystems.size(); size_t particleSystemCount= particleSystems.size();
int currentParticleCount = 0; int currentParticleCount= 0;
vector<ParticleSystem *> cleanupParticleSystemsList; vector<ParticleSystem *> cleanupParticleSystemsList;
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
if(ps != NULL) { if(ps != NULL){
currentParticleCount += ps->getAliveParticleCount(); currentParticleCount+= ps->getAliveParticleCount();
bool showParticle = true; bool showParticle= true;
if( dynamic_cast<UnitParticleSystem *>(ps) != NULL || if(dynamic_cast<UnitParticleSystem *> (ps) != NULL || dynamic_cast<FireParticleSystem *> (ps) != NULL){
dynamic_cast<FireParticleSystem *>(ps) != NULL ) { showParticle= ps->getVisible() || (ps->getState() == ParticleSystem::sFade);
showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade);
} }
if(showParticle == true) { if(showParticle == true){
ps->update(); ps->update();
if(ps->isEmpty()) { if(ps->isEmpty()){
//delete ps; //delete ps;
//*it= NULL; //*it= NULL;
cleanupParticleSystemsList.push_back(ps); cleanupParticleSystemsList.push_back(ps);
@@ -1004,39 +1027,40 @@ void ParticleManager::update(int renderFps) {
//particleSystems.remove(NULL); //particleSystems.remove(NULL);
cleanupParticleSystems(cleanupParticleSystemsList); cleanupParticleSystems(cleanupParticleSystemsList);
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, currentParticleCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),particleSystemCount,currentParticleCount); if(chrono.getMillis() > 0)
SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, currentParticleCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),particleSystemCount,currentParticleCount);
} }
bool ParticleManager::validateParticleSystemStillExists(ParticleSystem * particleSystem) const { bool ParticleManager::validateParticleSystemStillExists(ParticleSystem * particleSystem) const{
int index = findParticleSystems(particleSystem, this->particleSystems); int index= findParticleSystems(particleSystem, this->particleSystems);
return (index >= 0); return (index >= 0);
} }
int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector<ParticleSystem *> &particleSystems) const { int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector<ParticleSystem *> &particleSystems) const{
int result = -1; int result= -1;
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
if(ps != NULL && psFind != NULL && psFind == ps) { if(ps != NULL && psFind != NULL && psFind == ps){
result = i; result= i;
break; break;
} }
} }
return result; return result;
} }
void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) { void ParticleManager::cleanupParticleSystems(ParticleSystem *ps){
int index = findParticleSystems(ps, this->particleSystems); int index= findParticleSystems(ps, this->particleSystems);
if(ps != NULL && index >= 0) { if(ps != NULL && index >= 0){
delete ps; delete ps;
this->particleSystems.erase(this->particleSystems.begin() + index); this->particleSystems.erase(this->particleSystems.begin() + index);
} }
} }
void ParticleManager::cleanupParticleSystems(vector<ParticleSystem *> &particleSystems) { void ParticleManager::cleanupParticleSystems(vector<ParticleSystem *> &particleSystems){
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
cleanupParticleSystems(ps); cleanupParticleSystems(ps);
} }
@@ -1044,25 +1068,26 @@ void ParticleManager::cleanupParticleSystems(vector<ParticleSystem *> &particleS
//this->particleSystems.remove(NULL); //this->particleSystems.remove(NULL);
} }
void ParticleManager::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems) { void ParticleManager::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems){
for (unsigned int i = 0; i < particleSystems.size(); i++) { for(unsigned int i= 0; i < particleSystems.size(); i++){
ParticleSystem *ps = particleSystems[i]; ParticleSystem *ps= particleSystems[i];
cleanupParticleSystems(ps); cleanupParticleSystems(ps);
} }
particleSystems.clear(); particleSystems.clear();
//this->particleSystems.remove(NULL); //this->particleSystems.remove(NULL);
} }
void ParticleManager::manage(ParticleSystem *ps) { void ParticleManager::manage(ParticleSystem *ps){
particleSystems.push_back(ps); particleSystems.push_back(ps);
} }
void ParticleManager::end() { void ParticleManager::end(){
while(particleSystems.empty() == false) { while(particleSystems.empty() == false){
delete particleSystems.back(); delete particleSystems.back();
particleSystems.pop_back(); particleSystems.pop_back();
} }
} }
}}//end namespace }
}//end namespace