2010-03-27 04:09:11 +01:00
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
2011-12-14 08:40:48 +01:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-27 04:09:11 +01:00
//
// 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
// ==============================================================
2010-05-01 22:14:25 +02:00
# include "math_wrapper.h"
2010-03-27 04:09:11 +01:00
# include "particle.h"
2010-08-24 03:21:34 +02:00
# include <stdexcept>
2010-03-27 04:09:11 +01:00
# include <cassert>
# include <algorithm>
# include "util.h"
# include "particle_renderer.h"
# include "math_util.h"
2010-08-24 03:21:34 +02:00
# include "platform_common.h"
2012-03-10 04:27:25 +01:00
# include "conversion.h"
2012-03-13 22:58:31 +01:00
# include "model.h"
2012-03-19 22:35:54 +01:00
# include "texture.h"
2012-04-14 23:21:09 +02:00
# include "platform_util.h"
2010-03-27 04:09:11 +01:00
# include "leak_dumper.h"
2010-08-24 03:21:34 +02:00
using namespace std ;
2010-03-27 04:09:11 +01:00
using namespace Shared : : Util ;
2010-08-24 03:21:34 +02:00
using namespace Shared : : PlatformCommon ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
namespace Shared {
namespace Graphics {
2010-03-27 04:09:11 +01:00
// =====================================================
// class ParticleSystem
// =====================================================
2011-07-06 07:16:25 +02:00
const bool checkMemory = false ;
static map < void * , int > memoryObjectList ;
2012-03-10 04:27:25 +01:00
void Particle : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * particleNode = rootNode - > addChild ( " Particle " ) ;
// Vec3f pos;
particleNode - > addAttribute ( " pos " , pos . getString ( ) , mapTagReplacements ) ;
// Vec3f lastPos;
particleNode - > addAttribute ( " lastPos " , lastPos . getString ( ) , mapTagReplacements ) ;
// Vec3f speed;
particleNode - > addAttribute ( " speed " , speed . getString ( ) , mapTagReplacements ) ;
2014-07-26 13:56:29 +02:00
// Vec3f speedUpRelative;
particleNode - > addAttribute ( " speedUpRelative " , floatToStr ( speedUpRelative , 6 ) , mapTagReplacements ) ;
// Vec3f speedUpConstant;
particleNode - > addAttribute ( " speedUpConstant " , speedUpConstant . getString ( ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// Vec3f accel;
particleNode - > addAttribute ( " accel " , accel . getString ( ) , mapTagReplacements ) ;
// Vec4f color;
particleNode - > addAttribute ( " color " , color . getString ( ) , mapTagReplacements ) ;
// float size;
2013-10-02 22:22:10 +02:00
particleNode - > addAttribute ( " size " , floatToStr ( size , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// int energy;
particleNode - > addAttribute ( " energy " , intToStr ( energy ) , mapTagReplacements ) ;
}
2012-03-13 22:58:31 +01:00
void Particle : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * particleNode = rootNode ;
//particleNode = aiNode->getAttribute("startLoc")->getIntValue();
// Vec3f pos;
2013-10-02 22:22:10 +02:00
pos = Vec3f : : strToVec3 ( particleNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec3f lastPos;
2013-10-02 22:22:10 +02:00
lastPos = Vec3f : : strToVec3 ( particleNode - > getAttribute ( " lastPos " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec3f speed;
2013-10-02 22:22:10 +02:00
speed = Vec3f : : strToVec3 ( particleNode - > getAttribute ( " speed " ) - > getValue ( ) ) ;
2014-07-26 13:56:29 +02:00
// Vec3f speed;
speedUpRelative = particleNode - > getAttribute ( " speedUpRelative " ) - > getFloatValue ( ) ;
// Vec3f speed;
speedUpConstant = Vec3f : : strToVec3 ( particleNode - > getAttribute ( " speedUpConstant " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec3f accel;
2013-10-02 22:22:10 +02:00
accel = Vec3f : : strToVec3 ( particleNode - > getAttribute ( " accel " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec4f color;
2013-09-26 18:37:32 +02:00
color = Vec4f : : strToVec4 ( particleNode - > getAttribute ( " color " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// float size;
size = particleNode - > getAttribute ( " size " ) - > getFloatValue ( ) ;
// int energy;
energy = particleNode - > getAttribute ( " energy " ) - > getIntValue ( ) ;
}
2011-06-25 22:44:46 +02:00
ParticleSystem : : ParticleSystem ( int particleCount ) {
2011-07-06 07:16:25 +02:00
if ( checkMemory ) {
printf ( " ++ Create ParticleSystem [%p] \n " , this ) ;
memoryObjectList [ this ] + + ;
}
2011-06-25 22:44:46 +02:00
2012-03-19 22:35:54 +01:00
textureFileLoadDeferred = " " ;
textureFileLoadDeferredSystemId = 0 ;
textureFileLoadDeferredFormat = Texture : : fAuto ;
textureFileLoadDeferredComponents = 0 ;
2011-12-02 23:04:02 +01:00
2010-03-27 04:09:11 +01:00
//init particle vector
2011-03-14 00:16:07 +01:00
blendMode = bmOne ;
2010-08-24 03:21:34 +02:00
//particles= new Particle[particleCount];
particles . clear ( ) ;
2010-08-26 03:25:27 +02:00
//particles.reserve(particleCount);
particles . resize ( particleCount ) ;
2010-08-24 03:21:34 +02:00
2010-03-27 04:09:11 +01:00
state = sPlay ;
2011-03-14 00:16:07 +01:00
aliveParticleCount = 0 ;
2010-03-27 04:09:11 +01:00
active = true ;
visible = true ;
//vars
texture = NULL ;
particleObserver = NULL ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
//params
2010-10-06 19:04:51 +02:00
this - > particleCount = particleCount ;
2010-08-24 03:21:34 +02:00
//this->particleCount= particles.size();
2010-03-27 04:09:11 +01:00
maxParticleEnergy = 250 ;
varParticleEnergy = 50 ;
2013-10-02 22:22:10 +02:00
pos = Vec3f ( 0.0f ) ;
2013-09-26 18:37:32 +02:00
color = Vec4f ( 1.0f ) ;
colorNoEnergy = Vec4f ( 0.0f ) ;
2010-09-24 18:36:59 +02:00
emissionRate = 15.0f ;
2010-09-25 16:38:00 +02:00
emissionState = 1.0f ; // initialized with 1 because we must have at least one particle in the beginning!
2010-03-27 04:09:11 +01:00
speed = 1.0f ;
2011-03-14 00:16:07 +01:00
teamcolorNoEnergy = false ;
teamcolorEnergy = false ;
alternations = 0 ;
2012-01-07 21:24:54 +01:00
particleSystemStartDelay = 0 ;
2013-09-23 19:16:34 +02:00
this - > particleOwner = NULL ;
2013-12-14 08:04:12 +01:00
this - > particleSize = 0.0f ;
2010-03-27 04:09:11 +01:00
}
2013-09-23 19:16:34 +02:00
ParticleSystem : : ~ ParticleSystem ( ) {
2011-07-06 07:16:25 +02:00
if ( checkMemory ) {
printf ( " -- Delete ParticleSystem [%p] \n " , this ) ;
memoryObjectList [ this ] - - ;
assert ( memoryObjectList [ this ] = = 0 ) ;
}
2011-06-25 22:44:46 +02:00
2010-08-24 03:21:34 +02:00
//delete [] particles;
particles . clear ( ) ;
2011-09-28 08:57:42 +02:00
delete particleObserver ;
particleObserver = NULL ;
2010-03-27 04:09:11 +01:00
}
2013-09-23 19:16:34 +02:00
void ParticleSystem : : callParticleOwnerEnd ( ParticleSystem * particleSystem ) {
if ( this - > particleOwner ! = NULL ) {
this - > particleOwner - > end ( particleSystem ) ;
}
}
Checksum ParticleSystem : : getCRC ( ) {
Checksum crcForParticleSystem ;
//std::vector<Particle> particles;
crcForParticleSystem . addInt ( random . getLastNumber ( ) ) ;
crcForParticleSystem . addInt ( blendMode ) ;
crcForParticleSystem . addInt ( state ) ;
crcForParticleSystem . addInt ( active ) ;
2013-10-18 06:55:29 +02:00
//crcForParticleSystem.addInt(visible);
2013-09-23 19:16:34 +02:00
crcForParticleSystem . addInt ( aliveParticleCount ) ;
crcForParticleSystem . addInt ( particleCount ) ;
//string textureFileLoadDeferred;
//int textureFileLoadDeferredSystemId;
//Texture::Format textureFileLoadDeferredFormat;
//int textureFileLoadDeferredComponents;
//Texture *texture;
//Vec3f pos;
//Vec4f color;
//Vec4f colorNoEnergy;
//float emissionRate;
//float emissionState;
crcForParticleSystem . addInt ( maxParticleEnergy ) ;
crcForParticleSystem . addInt ( varParticleEnergy ) ;
//float particleSize;
//float speed;
//Vec3f factionColor;
crcForParticleSystem . addInt ( teamcolorNoEnergy ) ;
crcForParticleSystem . addInt ( teamcolorEnergy ) ;
crcForParticleSystem . addInt ( alternations ) ;
crcForParticleSystem . addInt ( particleSystemStartDelay ) ;
//ParticleObserver *particleObserver;
return crcForParticleSystem ;
}
2010-03-27 04:09:11 +01:00
// =============== VIRTUAL ======================
//updates all living particles and creates new ones
2013-09-30 19:38:26 +02:00
void ParticleSystem : : update ( ) {
if ( aliveParticleCount > ( int ) particles . size ( ) ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " aliveParticleCount >= particles.size() " ) ;
2010-08-24 03:21:34 +02:00
}
2013-09-30 19:38:26 +02:00
if ( particleSystemStartDelay > 0 ) {
2012-01-07 21:24:54 +01:00
particleSystemStartDelay - - ;
}
2013-09-30 19:38:26 +02:00
else if ( state ! = sPause ) {
for ( int i = 0 ; i < aliveParticleCount ; + + i ) {
2010-03-27 04:09:11 +01:00
updateParticle ( & particles [ i ] ) ;
2013-09-30 19:38:26 +02:00
if ( deathTest ( & particles [ i ] ) ) {
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
//kill the particle
killParticle ( & particles [ i ] ) ;
2010-08-24 03:21:34 +02:00
//maintain alive particles at front of the array
2013-09-30 19:38:26 +02:00
if ( aliveParticleCount > 0 ) {
2011-03-14 00:16:07 +01:00
particles [ i ] = particles [ aliveParticleCount ] ;
2010-03-27 04:09:11 +01:00
}
}
}
2013-09-30 19:38:26 +02:00
if ( state ! = ParticleSystem : : sFade ) {
2011-03-14 00:16:07 +01:00
emissionState = emissionState + emissionRate ;
int emissionIntValue = ( int ) emissionState ;
for ( int i = 0 ; i < emissionIntValue ; i + + ) {
Particle * p = createParticle ( ) ;
2010-03-27 04:09:11 +01:00
initParticle ( p , i ) ;
}
2013-10-02 22:22:10 +02:00
emissionState = emissionState - ( float ) emissionIntValue ;
emissionState = truncateDecimal < float > ( emissionState , 6 ) ;
2010-03-27 04:09:11 +01:00
}
}
}
void ParticleSystem : : render ( ParticleRenderer * pr , ModelRenderer * mr ) {
2013-09-30 19:38:26 +02:00
if ( active ) {
2010-03-27 04:09:11 +01:00
pr - > renderSystem ( this ) ;
}
}
ParticleSystem : : BlendMode ParticleSystem : : strToBlendMode ( const string & str ) {
2013-09-30 19:38:26 +02:00
if ( str = = " normal " ) {
2010-03-27 04:09:11 +01:00
return bmOne ;
}
2013-09-30 19:38:26 +02:00
else if ( str = = " black " ) {
2010-03-27 04:09:11 +01:00
return bmOneMinusAlpha ;
}
else {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Unknown particle mode: " + str ) ;
2010-03-27 04:09:11 +01:00
}
}
// =============== SET ==========================
void ParticleSystem : : setState ( State state ) {
this - > state = state ;
2011-07-07 00:23:51 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - )
getChild ( i ) - > setState ( state ) ;
2010-03-27 04:09:11 +01:00
}
void ParticleSystem : : setTexture ( Texture * texture ) {
this - > texture = texture ;
}
2013-10-02 22:22:10 +02:00
void ParticleSystem : : setPos ( Vec3f pos ) {
2010-03-27 04:09:11 +01:00
this - > pos = pos ;
2011-07-07 00:23:51 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - )
getChild ( i ) - > setPos ( pos ) ;
2010-03-27 04:09:11 +01:00
}
2013-09-26 18:37:32 +02:00
void ParticleSystem : : setColor ( Vec4f color ) {
2010-03-27 04:09:11 +01:00
this - > color = color ;
}
2013-09-26 18:37:32 +02:00
void ParticleSystem : : setColorNoEnergy ( Vec4f colorNoEnergy ) {
2010-03-27 04:09:11 +01:00
this - > colorNoEnergy = colorNoEnergy ;
}
2013-10-02 22:22:10 +02:00
void ParticleSystem : : setEmissionRate ( float emissionRate ) {
2010-03-27 04:09:11 +01:00
this - > emissionRate = emissionRate ;
2013-10-02 22:22:10 +02:00
this - > emissionRate = truncateDecimal < float > ( this - > emissionRate , 6 ) ;
2010-03-27 04:09:11 +01:00
}
void ParticleSystem : : setMaxParticleEnergy ( int maxParticleEnergy ) {
2011-03-14 00:16:07 +01:00
this - > maxParticleEnergy = maxParticleEnergy ;
2010-03-27 04:09:11 +01:00
}
void ParticleSystem : : setVarParticleEnergy ( int varParticleEnergy ) {
this - > varParticleEnergy = varParticleEnergy ;
}
2013-10-02 22:22:10 +02:00
void ParticleSystem : : setParticleSize ( float particleSize ) {
2010-03-27 04:09:11 +01:00
this - > particleSize = particleSize ;
2013-10-02 22:22:10 +02:00
this - > particleSize = truncateDecimal < float > ( this - > particleSize , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2013-10-02 22:22:10 +02:00
void ParticleSystem : : setSpeed ( float speed ) {
2010-03-27 04:09:11 +01:00
this - > speed = speed ;
2013-10-02 22:22:10 +02:00
this - > speed = truncateDecimal < float > ( this - > speed , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2014-07-26 13:56:29 +02:00
void ParticleSystem : : setSpeedUpRelative ( float speedUpRelative ) {
this - > speedUpRelative = speedUpRelative ;
this - > speedUpRelative = truncateDecimal < float > ( this - > speedUpRelative , 6 ) ;
}
void ParticleSystem : : setSpeedUpConstant ( float speedUpConstant ) {
this - > speedUpConstant = speedUpConstant ;
this - > speedUpConstant = truncateDecimal < float > ( this - > speedUpConstant , 6 ) ;
}
2010-03-27 04:09:11 +01:00
void ParticleSystem : : setActive ( bool active ) {
this - > active = active ;
2011-07-07 00:23:51 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - )
getChild ( i ) - > setActive ( active ) ;
2010-03-27 04:09:11 +01:00
}
void ParticleSystem : : setObserver ( ParticleObserver * particleObserver ) {
this - > particleObserver = particleObserver ;
}
2011-07-07 00:23:51 +02:00
ParticleSystem * ParticleSystem : : getChild ( int i ) {
throw std : : out_of_range ( " ParticleSystem::getChild bad " ) ;
}
2010-03-27 04:09:11 +01:00
void ParticleSystem : : setVisible ( bool visible ) {
this - > visible = visible ;
2013-09-30 19:38:26 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - ) {
2011-07-07 00:23:51 +02:00
getChild ( i ) - > setVisible ( visible ) ;
2013-09-30 19:38:26 +02:00
}
2010-03-27 04:09:11 +01:00
}
2012-03-19 22:35:54 +01:00
string ParticleSystem : : toString ( ) const {
2013-09-23 19:16:34 +02:00
string result = " ParticleSystem " ;
2012-03-19 22:35:54 +01:00
result + = " particles = " + intToStr ( particles . size ( ) ) ;
// for(unsigned int i = 0; i < particles.size(); ++i) {
// Particle &particle = particles[i];
//
// }
result + = " \n random = " + intToStr ( random . getLastNumber ( ) ) ;
result + = " \n blendMode = " + intToStr ( blendMode ) ;
result + = " \n state = " + intToStr ( state ) ;
result + = " \n active = " + intToStr ( active ) ;
2013-10-18 06:55:29 +02:00
//result += "\nvisible = " + intToStr(visible);
2012-03-19 22:35:54 +01:00
result + = " \n aliveParticleCount = " + intToStr ( aliveParticleCount ) ;
result + = " \n particleCount = " + intToStr ( particleCount ) ;
result + = " \n textureFileLoadDeferred = " + textureFileLoadDeferred ;
result + = " \n textureFileLoadDeferredFormat = " + intToStr ( textureFileLoadDeferredFormat ) ;
result + = " \n textureFileLoadDeferredComponents = " + intToStr ( textureFileLoadDeferredComponents ) ;
if ( texture ! = NULL ) {
2013-09-25 02:17:11 +02:00
result + = " \n texture = " + extractFileFromDirectoryPath ( texture - > getPath ( ) ) ;
2012-03-19 22:35:54 +01:00
}
result + = " \n pos = " + pos . getString ( ) ;
result + = " \n color = " + color . getString ( ) ;
result + = " \n colorNoEnergy = " + colorNoEnergy . getString ( ) ;
2013-10-02 22:22:10 +02:00
result + = " \n emissionRate = " + floatToStr ( emissionRate , 6 ) ;
result + = " \n emissionState = " + floatToStr ( emissionState , 6 ) ;
2012-03-19 22:35:54 +01:00
result + = " \n maxParticleEnergy = " + intToStr ( maxParticleEnergy ) ;
result + = " \n varParticleEnergy = " + intToStr ( varParticleEnergy ) ;
2013-10-02 22:22:10 +02:00
result + = " \n particleSize = " + floatToStr ( particleSize , 6 ) ;
result + = " \n speed = " + floatToStr ( speed , 6 ) ;
2012-03-19 22:35:54 +01:00
result + = " \n factionColor = " + factionColor . getString ( ) ;
result + = " \n teamcolorNoEnergy = " + intToStr ( teamcolorNoEnergy ) ;
result + = " \n teamcolorEnergy = " + intToStr ( teamcolorEnergy ) ;
result + = " \n alternations = " + intToStr ( alternations ) ;
result + = " \n particleSystemStartDelay = " + intToStr ( particleSystemStartDelay ) ;
//ParticleObserver *particleObserver;
return result ;
}
2012-03-10 04:27:25 +01:00
void ParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * particleSystemNode = rootNode - > addChild ( " ParticleSystem " ) ;
// std::vector<Particle> particles;
2012-03-17 23:26:50 +01:00
// for(unsigned int i = 0; i < particles.size(); ++i) {
// Particle &particle = particles[i];
// particle.saveGame(particleSystemNode);
// }
2012-03-10 04:27:25 +01:00
// RandomGen random;
particleSystemNode - > addAttribute ( " random " , intToStr ( random . getLastNumber ( ) ) , mapTagReplacements ) ;
// BlendMode blendMode;
particleSystemNode - > addAttribute ( " blendMode " , intToStr ( blendMode ) , mapTagReplacements ) ;
// State state;
particleSystemNode - > addAttribute ( " state " , intToStr ( state ) , mapTagReplacements ) ;
// bool active;
particleSystemNode - > addAttribute ( " active " , intToStr ( active ) , mapTagReplacements ) ;
// bool visible;
particleSystemNode - > addAttribute ( " visible " , intToStr ( visible ) , mapTagReplacements ) ;
// int aliveParticleCount;
particleSystemNode - > addAttribute ( " aliveParticleCount " , intToStr ( aliveParticleCount ) , mapTagReplacements ) ;
// int particleCount;
particleSystemNode - > addAttribute ( " particleCount " , intToStr ( particleCount ) , mapTagReplacements ) ;
//
// Texture *texture;
2012-03-14 08:23:41 +01:00
if ( texture ! = NULL ) {
particleSystemNode - > addAttribute ( " texture " , texture - > getPath ( ) , mapTagReplacements ) ;
2012-03-19 22:35:54 +01:00
particleSystemNode - > addAttribute ( " textureid " , intToStr ( texture - > getTextureSystemId ( ) ) , mapTagReplacements ) ;
particleSystemNode - > addAttribute ( " textureFormat " , intToStr ( texture - > getFormat ( ) ) , mapTagReplacements ) ;
Texture2D * t2d = dynamic_cast < Texture2D * > ( texture ) ;
if ( t2d ! = NULL & & t2d - > getPixmapConst ( ) ! = NULL ) {
particleSystemNode - > addAttribute ( " textureComponents " , intToStr ( t2d - > getPixmapConst ( ) - > getComponents ( ) ) , mapTagReplacements ) ;
}
2012-03-14 08:23:41 +01:00
}
2012-03-10 04:27:25 +01:00
// Vec3f pos;
particleSystemNode - > addAttribute ( " pos " , pos . getString ( ) , mapTagReplacements ) ;
// Vec4f color;
particleSystemNode - > addAttribute ( " color " , color . getString ( ) , mapTagReplacements ) ;
// Vec4f colorNoEnergy;
particleSystemNode - > addAttribute ( " colorNoEnergy " , colorNoEnergy . getString ( ) , mapTagReplacements ) ;
// float emissionRate;
2013-10-02 22:22:10 +02:00
particleSystemNode - > addAttribute ( " emissionRate " , floatToStr ( emissionRate , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// float emissionState;
2013-10-02 22:22:10 +02:00
particleSystemNode - > addAttribute ( " emissionState " , floatToStr ( emissionState , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// int maxParticleEnergy;
particleSystemNode - > addAttribute ( " maxParticleEnergy " , intToStr ( maxParticleEnergy ) , mapTagReplacements ) ;
// int varParticleEnergy;
particleSystemNode - > addAttribute ( " varParticleEnergy " , intToStr ( varParticleEnergy ) , mapTagReplacements ) ;
// float particleSize;
2013-10-02 22:22:10 +02:00
particleSystemNode - > addAttribute ( " particleSize " , floatToStr ( particleSize , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// float speed;
2013-10-02 22:22:10 +02:00
particleSystemNode - > addAttribute ( " speed " , floatToStr ( speed , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// Vec3f factionColor;
particleSystemNode - > addAttribute ( " factionColor " , factionColor . getString ( ) , mapTagReplacements ) ;
// bool teamcolorNoEnergy;
particleSystemNode - > addAttribute ( " teamcolorNoEnergy " , intToStr ( teamcolorNoEnergy ) , mapTagReplacements ) ;
// bool teamcolorEnergy;
particleSystemNode - > addAttribute ( " teamcolorEnergy " , intToStr ( teamcolorEnergy ) , mapTagReplacements ) ;
// int alternations;
particleSystemNode - > addAttribute ( " alternations " , intToStr ( alternations ) , mapTagReplacements ) ;
// int particleSystemStartDelay;
particleSystemNode - > addAttribute ( " particleSystemStartDelay " , intToStr ( particleSystemStartDelay ) , mapTagReplacements ) ;
// ParticleObserver *particleObserver;
if ( particleObserver ! = NULL ) {
particleObserver - > saveGame ( particleSystemNode ) ;
}
}
2012-03-13 22:58:31 +01:00
2012-03-14 08:23:41 +01:00
string ParticleSystem : : getTextureFileLoadDeferred ( ) {
return textureFileLoadDeferred ;
}
2012-03-19 22:35:54 +01:00
int ParticleSystem : : getTextureFileLoadDeferredSystemId ( ) {
return textureFileLoadDeferredSystemId ;
}
Texture : : Format ParticleSystem : : getTextureFileLoadDeferredFormat ( ) {
return textureFileLoadDeferredFormat ;
}
int ParticleSystem : : getTextureFileLoadDeferredComponents ( ) {
return textureFileLoadDeferredComponents ;
}
2012-03-14 08:23:41 +01:00
2012-03-13 22:58:31 +01:00
void ParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * particleSystemNode = rootNode - > getChild ( " ParticleSystem " ) ;
2012-03-19 22:35:54 +01:00
particleCount = particleSystemNode - > getAttribute ( " particleCount " ) - > getIntValue ( ) ;
//printf("Load Smoke particle (ParticleSystem)\n");
2012-03-13 22:58:31 +01:00
// std::vector<Particle> particles;
// for(unsigned int i = 0; i < particles.size(); ++i) {
// Particle &particle = particles[i];
// particle.saveGame(particleSystemNode);
// }
2012-03-19 22:35:54 +01:00
particles . clear ( ) ;
particles . resize ( particleCount ) ;
// vector<XmlNode *> particleNodeList = particleSystemNode->getChildList("Particle");
// for(unsigned int i = 0; i < particleNodeList.size(); ++i) {
// XmlNode *node = particleNodeList[i];
//
// //printf("Load Smoke particle (Particle = %d)\n",i);
//
// Particle particle;
// particle.loadGame(node);
// particles.push_back(particle);
// }
2012-03-13 22:58:31 +01:00
// RandomGen random;
random . setLastNumber ( particleSystemNode - > getAttribute ( " random " ) - > getIntValue ( ) ) ;
// BlendMode blendMode;
blendMode = static_cast < BlendMode > ( particleSystemNode - > getAttribute ( " blendMode " ) - > getIntValue ( ) ) ;
// State state;
state = static_cast < State > ( particleSystemNode - > getAttribute ( " state " ) - > getIntValue ( ) ) ;
// bool active;
2012-04-16 22:15:57 +02:00
active = particleSystemNode - > getAttribute ( " active " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 22:58:31 +01:00
// bool visible;
2012-04-16 22:15:57 +02:00
visible = particleSystemNode - > getAttribute ( " visible " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 22:58:31 +01:00
// int aliveParticleCount;
aliveParticleCount = particleSystemNode - > getAttribute ( " aliveParticleCount " ) - > getIntValue ( ) ;
// int particleCount;
particleCount = particleSystemNode - > getAttribute ( " particleCount " ) - > getIntValue ( ) ;
//
// Texture *texture;
2012-03-14 08:23:41 +01:00
if ( particleSystemNode - > hasAttribute ( " texture " ) = = true ) {
textureFileLoadDeferred = particleSystemNode - > getAttribute ( " texture " ) - > getValue ( ) ;
2012-03-19 22:35:54 +01:00
textureFileLoadDeferredSystemId = particleSystemNode - > getAttribute ( " textureid " ) - > getIntValue ( ) ;
textureFileLoadDeferredFormat = static_cast < Texture : : Format > ( particleSystemNode - > getAttribute ( " textureFormat " ) - > getIntValue ( ) ) ;
if ( particleSystemNode - > hasAttribute ( " textureComponents " ) = = true ) {
textureFileLoadDeferredComponents = particleSystemNode - > getAttribute ( " textureComponents " ) - > getIntValue ( ) ;
}
2012-03-14 08:23:41 +01:00
}
2012-03-13 22:58:31 +01:00
// Vec3f pos;
2013-10-02 22:22:10 +02:00
pos = Vec3f : : strToVec3 ( particleSystemNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec4f color;
2013-09-26 18:37:32 +02:00
color = Vec4f : : strToVec4 ( particleSystemNode - > getAttribute ( " color " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec4f colorNoEnergy;
2013-09-26 18:37:32 +02:00
colorNoEnergy = Vec4f : : strToVec4 ( particleSystemNode - > getAttribute ( " colorNoEnergy " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// float emissionRate;
emissionRate = particleSystemNode - > getAttribute ( " emissionRate " ) - > getFloatValue ( ) ;
// float emissionState;
emissionState = particleSystemNode - > getAttribute ( " emissionState " ) - > getFloatValue ( ) ;
// int maxParticleEnergy;
maxParticleEnergy = particleSystemNode - > getAttribute ( " maxParticleEnergy " ) - > getIntValue ( ) ;
// int varParticleEnergy;
varParticleEnergy = particleSystemNode - > getAttribute ( " varParticleEnergy " ) - > getIntValue ( ) ;
// float particleSize;
particleSize = particleSystemNode - > getAttribute ( " particleSize " ) - > getFloatValue ( ) ;
// float speed;
speed = particleSystemNode - > getAttribute ( " speed " ) - > getFloatValue ( ) ;
// Vec3f factionColor;
2013-09-26 18:37:32 +02:00
factionColor = Vec3f : : strToVec3 ( particleSystemNode - > getAttribute ( " factionColor " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// bool teamcolorNoEnergy;
2012-04-16 22:15:57 +02:00
teamcolorNoEnergy = particleSystemNode - > getAttribute ( " teamcolorNoEnergy " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 22:58:31 +01:00
// bool teamcolorEnergy;
2012-04-16 22:15:57 +02:00
teamcolorEnergy = particleSystemNode - > getAttribute ( " teamcolorEnergy " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 22:58:31 +01:00
// int alternations;
alternations = particleSystemNode - > getAttribute ( " alternations " ) - > getIntValue ( ) ;
// int particleSystemStartDelay;
particleSystemStartDelay = particleSystemNode - > getAttribute ( " particleSystemStartDelay " ) - > getIntValue ( ) ;
2012-03-19 22:35:54 +01:00
2012-03-13 22:58:31 +01:00
// ParticleObserver *particleObserver;
//if(particleObserver != NULL) {
// particleObserver->loadGame(particleSystemNode);
//}
}
2010-03-27 04:09:11 +01:00
// =============== MISC =========================
2011-03-14 00:16:07 +01:00
void ParticleSystem : : fade ( ) {
2012-03-19 22:35:54 +01:00
//printf("**************Fading particle System:\n[%s]\n",this->toString().c_str());
2013-09-23 19:16:34 +02:00
bool alreadyFading = ( state = = sFade ) ;
2011-03-14 00:16:07 +01:00
if ( particleObserver ! = NULL ) {
2011-06-25 22:44:46 +02:00
if ( state ! = sPlay ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-09-23 19:16:34 +02:00
snprintf ( szBuf , 8096 , " state != sPlay, state = [%d] \n " , state ) ;
2012-04-14 23:21:09 +02:00
//throw megaglest_runtime_error(szBuf);
2011-06-25 22:44:46 +02:00
//printf(szBuf);
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " %s " , szBuf ) ;
}
2013-09-23 19:16:34 +02:00
//assert(state == sPlay);
2010-11-09 10:06:52 +01:00
}
2013-09-23 19:16:34 +02:00
2010-03-27 04:09:11 +01:00
state = sFade ;
2013-09-23 19:16:34 +02:00
if ( alreadyFading = = false ) {
if ( particleObserver ! = NULL ) {
particleObserver - > update ( this ) ;
particleObserver = NULL ;
}
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - ) {
getChild ( i ) - > fade ( ) ;
}
2010-03-27 04:09:11 +01:00
}
}
2013-09-30 19:38:26 +02:00
int ParticleSystem : : isEmpty ( ) const {
//assert(aliveParticleCount>=0);
2011-03-14 00:16:07 +01:00
return aliveParticleCount = = 0 & & state ! = sPause ;
2010-03-27 04:09:11 +01:00
}
// =============== PROTECTED =========================
// if there is one dead particle it returns it else, return the particle with
// less energy
2013-09-30 19:38:26 +02:00
Particle * ParticleSystem : : createParticle ( ) {
2010-03-27 04:09:11 +01:00
//if any dead particles
2013-09-30 19:38:26 +02:00
if ( aliveParticleCount < particleCount ) {
2010-03-27 04:09:11 +01:00
+ + aliveParticleCount ;
2011-03-14 00:16:07 +01:00
return & particles [ aliveParticleCount - 1 ] ;
2010-03-27 04:09:11 +01:00
}
//if not
2011-03-14 00:16:07 +01:00
int minEnergy = particles [ 0 ] . energy ;
int minEnergyParticle = 0 ;
2010-10-06 19:04:51 +02:00
2011-03-14 00:16:07 +01:00
for ( int i = 0 ; i < particleCount ; + + i ) {
2010-10-06 19:04:51 +02:00
if ( particles [ i ] . energy < minEnergy ) {
2011-03-14 00:16:07 +01:00
minEnergy = particles [ i ] . energy ;
minEnergyParticle = i ;
2010-10-06 19:04:51 +02:00
}
}
2010-08-24 03:21:34 +02:00
return & particles [ minEnergyParticle ] ;
2010-03-27 04:09:11 +01:00
}
2013-09-30 19:38:26 +02:00
void ParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
2010-03-27 04:09:11 +01:00
p - > pos = pos ;
p - > lastPos = p - > pos ;
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( 0.0f ) ;
p - > accel = Vec3f ( 0.0f ) ;
2013-09-26 18:37:32 +02:00
p - > color = Vec4f ( 1.0f , 1.0f , 1.0f , 1.0 ) ;
2010-03-27 04:09:11 +01:00
p - > size = particleSize ;
2013-10-02 22:22:10 +02:00
p - > size = truncateDecimal < float > ( p - > size , 6 ) ;
2010-03-27 04:09:11 +01:00
p - > energy = maxParticleEnergy + random . randRange ( - varParticleEnergy , varParticleEnergy ) ;
}
2013-09-30 19:38:26 +02:00
void ParticleSystem : : updateParticle ( Particle * p ) {
2010-03-27 04:09:11 +01:00
p - > lastPos = p - > pos ;
p - > pos = p - > pos + p - > speed ;
p - > speed = p - > speed + p - > accel ;
p - > energy - - ;
}
2013-09-30 19:38:26 +02:00
bool ParticleSystem : : deathTest ( Particle * p ) {
2010-03-27 04:09:11 +01:00
return p - > energy < = 0 ;
}
2013-09-30 19:38:26 +02:00
void ParticleSystem : : killParticle ( Particle * p ) {
2010-03-27 04:09:11 +01:00
aliveParticleCount - - ;
}
2013-09-26 18:37:32 +02:00
void ParticleSystem : : setFactionColor ( Vec3f factionColor ) {
2011-03-14 00:16:07 +01:00
this - > factionColor = factionColor ;
2013-09-26 18:37:32 +02:00
Vec3f tmpCol ;
2011-03-14 00:16:07 +01:00
if ( teamcolorEnergy ) {
2013-09-26 18:37:32 +02:00
this - > color = Vec4f ( factionColor . x , factionColor . y , factionColor . z , this - > color . w ) ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
if ( teamcolorNoEnergy ) {
2013-09-26 18:37:32 +02:00
this - > colorNoEnergy = Vec4f ( factionColor . x , factionColor . y , factionColor . z , this - > colorNoEnergy . w ) ;
2010-03-27 04:09:11 +01:00
}
2011-07-07 00:23:51 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - )
getChild ( i ) - > setFactionColor ( factionColor ) ;
2010-03-27 04:09:11 +01:00
}
// ===========================================================================
// FireParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
FireParticleSystem : : FireParticleSystem ( int particleCount ) :
ParticleSystem ( particleCount ) {
2010-03-27 04:09:11 +01:00
radius = 0.5f ;
speed = 0.01f ;
2013-10-02 22:22:10 +02:00
windSpeed = Vec3f ( 0.0f ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
setParticleSize ( 0.6f ) ;
2013-09-26 18:37:32 +02:00
setColorNoEnergy ( Vec4f ( 1.0f , 0.5f , 0.0f , 1.0f ) ) ;
2010-03-27 04:09:11 +01:00
}
void FireParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
ParticleSystem : : initParticle ( p , particleIndex ) ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
float ang = random . randRange ( - 2.0f * pi , 2.0f * pi ) ;
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2013-10-02 22:22:10 +02:00
float mod = streflop : : fabsf ( static_cast < streflop : : Simple > ( random . randRange ( - radius , radius ) ) ) ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
float x = streflop : : sinf ( static_cast < streflop : : Simple > ( ang ) ) * mod ;
float y = streflop : : cosf ( static_cast < streflop : : Simple > ( ang ) ) * mod ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
float radRatio = streflop : : sqrtf ( static_cast < streflop : : Simple > ( mod / radius ) ) ;
2010-05-01 22:14:25 +02:00
# else
2013-10-02 22:22:10 +02:00
float mod = fabsf ( random . randRange ( - radius , radius ) ) ;
2010-05-01 22:14:25 +02:00
2013-10-02 22:22:10 +02:00
float x = sinf ( ang ) * mod ;
float y = cosf ( ang ) * mod ;
2010-05-01 22:14:25 +02:00
2013-10-02 22:22:10 +02:00
float radRatio = sqrtf ( ( mod / radius ) ) ;
2010-05-01 22:14:25 +02:00
# endif
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
p - > color = colorNoEnergy * 0.5f + colorNoEnergy * 0.5f * radRatio ;
p - > energy = static_cast < int > ( maxParticleEnergy * radRatio )
+ random . randRange ( - varParticleEnergy , varParticleEnergy ) ;
2013-10-02 22:22:10 +02:00
p - > pos = Vec3f ( pos . x + x , pos . y + random . randRange ( - radius / 2 , radius / 2 ) , pos . z + y ) ;
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
p - > lastPos = pos ;
p - > size = particleSize ;
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( 0 , speed + speed * random . randRange ( - 0.5f , 0.5f ) , 0 ) + windSpeed ;
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
}
void FireParticleSystem : : updateParticle ( Particle * p ) {
p - > lastPos = p - > pos ;
2011-03-14 00:16:07 +01:00
p - > pos = p - > pos + p - > speed ;
2010-03-27 04:09:11 +01:00
p - > energy - - ;
2011-03-14 00:16:07 +01:00
if ( p - > color . x > 0.0f )
2010-03-27 04:09:11 +01:00
p - > color . x * = 0.98f ;
2011-03-14 00:16:07 +01:00
if ( p - > color . y > 0.0f )
2010-03-27 04:09:11 +01:00
p - > color . y * = 0.98f ;
2011-03-14 00:16:07 +01:00
if ( p - > color . w > 0.0f )
2010-03-27 04:09:11 +01:00
p - > color . w * = 0.98f ;
2011-03-14 00:16:07 +01:00
p - > speed . x * = 1.001f ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2013-09-23 19:16:34 +02:00
string FireParticleSystem : : toString ( ) const {
string result = ParticleSystem : : toString ( ) ;
result + = " \n FireParticleSystem " ;
2013-10-02 22:22:10 +02:00
result + = " \n radius = " + floatToStr ( radius ) ;
2013-09-23 19:16:34 +02:00
result + = " \n windSpeed = " + windSpeed . getString ( ) ;
return result ;
}
2010-03-27 04:09:11 +01:00
// ================= SET PARAMS ====================
2013-10-02 22:22:10 +02:00
void FireParticleSystem : : setRadius ( float radius ) {
2010-03-27 04:09:11 +01:00
this - > radius = radius ;
}
2013-10-02 22:22:10 +02:00
void FireParticleSystem : : setWind ( float windAngle , float windSpeed ) {
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
this - > windSpeed . x = streflop : : sinf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-03-27 04:09:11 +01:00
this - > windSpeed . y = 0.0f ;
2012-02-10 07:21:06 +01:00
this - > windSpeed . z = streflop : : cosf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# else
2011-03-14 00:16:07 +01:00
this - > windSpeed . x = sinf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
this - > windSpeed . y = 0.0f ;
2011-03-14 00:16:07 +01:00
this - > windSpeed . z = cosf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
this - > windSpeed . x = truncateDecimal < float > ( this - > windSpeed . x , 6 ) ;
this - > windSpeed . y = truncateDecimal < float > ( this - > windSpeed . y , 6 ) ;
this - > windSpeed . z = truncateDecimal < float > ( this - > windSpeed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2012-03-13 22:58:31 +01:00
void FireParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * fireParticleSystemNode = rootNode - > addChild ( " FireParticleSystem " ) ;
ParticleSystem : : saveGame ( fireParticleSystemNode ) ;
// float radius;
2013-10-02 22:22:10 +02:00
fireParticleSystemNode - > addAttribute ( " radius " , floatToStr ( radius , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f windSpeed;
fireParticleSystemNode - > addAttribute ( " windSpeed " , windSpeed . getString ( ) , mapTagReplacements ) ;
}
void FireParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * fireParticleSystemNode = rootNode ;
ParticleSystem : : loadGame ( fireParticleSystemNode ) ;
// float radius;
radius = fireParticleSystemNode - > getAttribute ( " radius " ) - > getFloatValue ( ) ;
// Vec3f windSpeed;
2013-10-02 22:22:10 +02:00
windSpeed = Vec3f : : strToVec3 ( fireParticleSystemNode - > getAttribute ( " windSpeed " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
}
2013-09-23 19:16:34 +02:00
Checksum FireParticleSystem : : getCRC ( ) {
Checksum crcForParticleSystem = ParticleSystem : : getCRC ( ) ;
//float radius;
//Vec3f windSpeed;
return crcForParticleSystem ;
}
2011-07-07 00:23:51 +02:00
// ===========================================================================
// GameParticleSystem
// ===========================================================================
GameParticleSystem : : GameParticleSystem ( int particleCount ) :
ParticleSystem ( particleCount ) ,
primitive ( pQuad ) ,
model ( NULL ) ,
modelCycle ( 0.0f ) ,
offset ( 0.0f ) ,
2013-11-19 07:14:06 +01:00
direction ( 0.0f , 1.0f , 0.0f ) ,
tween ( 0.0f )
2011-07-07 00:23:51 +02:00
{ }
GameParticleSystem : : ~ GameParticleSystem ( ) {
2011-09-01 03:11:23 +02:00
for ( Children : : iterator it = children . begin ( ) ; it ! = children . end ( ) ; + + it ) {
2011-07-07 00:23:51 +02:00
( * it ) - > setParent ( NULL ) ;
( * it ) - > fade ( ) ;
}
}
GameParticleSystem : : Primitive GameParticleSystem : : strToPrimitive ( const string & str ) {
if ( str = = " quad " ) {
return pQuad ;
}
else if ( str = = " line " ) {
return pLine ;
}
else {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Unknown particle primitive: " + str ) ;
2011-07-07 00:23:51 +02:00
}
}
int GameParticleSystem : : getChildCount ( ) {
2013-11-03 02:51:20 +01:00
return ( int ) children . size ( ) ;
2011-07-07 00:23:51 +02:00
}
ParticleSystem * GameParticleSystem : : getChild ( int i ) {
return children . at ( i ) ; // does bounds checking
}
void GameParticleSystem : : addChild ( UnitParticleSystem * child ) {
assert ( ! child - > getParent ( ) ) ;
child - > setParent ( this ) ;
children . push_back ( child ) ;
}
void GameParticleSystem : : removeChild ( UnitParticleSystem * child ) {
assert ( this = = child - > getParent ( ) ) ;
Children : : iterator it = std : : find ( children . begin ( ) , children . end ( ) , child ) ;
assert ( it ! = children . end ( ) ) ;
children . erase ( it ) ;
}
2013-10-02 22:22:10 +02:00
void GameParticleSystem : : setPos ( Vec3f pos ) {
2011-07-07 00:23:51 +02:00
this - > pos = pos ;
positionChildren ( ) ;
}
void GameParticleSystem : : positionChildren ( ) {
2013-10-02 22:22:10 +02:00
Vec3f child_pos = pos - offset ;
2011-07-07 00:23:51 +02:00
for ( int i = getChildCount ( ) - 1 ; i > = 0 ; i - - )
getChild ( i ) - > setPos ( child_pos ) ;
}
2013-10-02 22:22:10 +02:00
void GameParticleSystem : : setOffset ( Vec3f offset ) {
2011-07-07 00:23:51 +02:00
this - > offset = offset ;
positionChildren ( ) ;
}
void GameParticleSystem : : render ( ParticleRenderer * pr , ModelRenderer * mr ) {
if ( active ) {
if ( model ! = NULL ) {
pr - > renderModel ( this , mr ) ;
}
switch ( primitive ) {
case pQuad :
pr - > renderSystem ( this ) ;
break ;
case pLine :
pr - > renderSystemLine ( this ) ;
break ;
default :
assert ( false ) ;
2012-09-22 22:13:57 +02:00
break ;
2011-07-07 00:23:51 +02:00
}
}
}
2013-10-02 22:22:10 +02:00
void GameParticleSystem : : setTween ( float relative , float absolute ) {
2012-04-05 01:43:31 +02:00
if ( model ) {
2011-07-07 00:23:51 +02:00
// animation?
2012-04-05 01:43:31 +02:00
//printf("#1 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute);
2011-07-07 00:23:51 +02:00
if ( modelCycle = = 0.0f ) {
tween = relative ;
}
else {
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
if ( streflop : : fabs ( static_cast < streflop : : Simple > ( absolute ) ) < = 0.00001f ) {
2011-07-07 00:23:51 +02:00
# else
2012-04-05 01:43:31 +02:00
if ( fabs ( absolute ) < = 0.00001f ) {
2011-07-07 00:23:51 +02:00
# endif
tween = 0.0f ;
}
else {
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
tween = streflop : : fmod ( static_cast < streflop : : Simple > ( absolute ) , static_cast < streflop : : Simple > ( modelCycle ) ) ;
2011-07-07 00:23:51 +02:00
# else
tween = fmod ( absolute , modelCycle ) ;
# endif
tween / = modelCycle ;
}
}
2011-09-10 05:57:51 +02:00
2013-10-02 22:22:10 +02:00
tween = truncateDecimal < float > ( tween , 6 ) ;
2011-07-19 01:46:11 +02:00
if ( tween < 0.0f | | tween > 1.0f ) {
2011-09-22 07:14:20 +02:00
//printf("In [%s::%s Line: %d] WARNING setting tween to [%f] clamping tween, modelCycle [%f] absolute [%f] relative [%f]\n",__FILE__,__FUNCTION__,__LINE__,tween,modelCycle,absolute,relative);
2011-08-31 18:12:02 +02:00
//assert(tween >= 0.0f && tween <= 1.0f);
2011-07-19 01:46:11 +02:00
}
2011-07-19 02:17:32 +02:00
2011-07-07 00:23:51 +02:00
tween = clamp ( tween , 0.0f , 1.0f ) ;
2012-04-05 01:43:31 +02:00
//printf("#2 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute);
2011-07-07 00:23:51 +02:00
}
2012-04-05 01:43:31 +02:00
for ( Children : : iterator it = children . begin ( ) ; it ! = children . end ( ) ; + + it ) {
2011-07-07 00:23:51 +02:00
( * it ) - > setTween ( relative , absolute ) ;
2012-04-05 01:43:31 +02:00
}
2011-07-07 00:23:51 +02:00
}
2012-03-14 08:23:41 +01:00
string GameParticleSystem : : getModelFileLoadDeferred ( ) {
return modelFileLoadDeferred ;
}
2012-03-13 22:58:31 +01:00
void GameParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * gameParticleSystemNode = rootNode - > addChild ( " GameParticleSystem " ) ;
ParticleSystem : : saveGame ( gameParticleSystemNode ) ;
// Children children;
for ( unsigned int i = 0 ; i < children . size ( ) ; + + i ) {
2012-03-13 23:37:47 +01:00
if ( children [ i ] ! = NULL ) {
children [ i ] - > saveGame ( gameParticleSystemNode ) ;
}
2012-03-13 22:58:31 +01:00
}
// Primitive primitive;
gameParticleSystemNode - > addAttribute ( " primitive " , intToStr ( primitive ) , mapTagReplacements ) ;
// Model *model;
if ( model ! = NULL ) {
gameParticleSystemNode - > addAttribute ( " model " , model - > getFileName ( ) , mapTagReplacements ) ;
}
// float modelCycle;
2013-10-02 22:22:10 +02:00
gameParticleSystemNode - > addAttribute ( " modelCycle " , floatToStr ( modelCycle , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f offset;
gameParticleSystemNode - > addAttribute ( " offset " , offset . getString ( ) , mapTagReplacements ) ;
// Vec3f direction;
gameParticleSystemNode - > addAttribute ( " direction " , direction . getString ( ) , mapTagReplacements ) ;
// float tween;
2013-10-02 22:22:10 +02:00
gameParticleSystemNode - > addAttribute ( " tween " , floatToStr ( tween , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
}
void GameParticleSystem : : loadGame ( const XmlNode * rootNode ) {
2012-03-19 22:35:54 +01:00
const XmlNode * gameParticleSystemNode = rootNode - > getChild ( " GameParticleSystem " ) ;
2012-03-13 22:58:31 +01:00
2012-03-19 22:35:54 +01:00
//printf("Load Smoke particle (GameParticleSystem)\n");
2012-03-13 22:58:31 +01:00
ParticleSystem : : loadGame ( gameParticleSystemNode ) ;
// Children children;
// for(unsigned int i = 0; i < children.size(); ++i) {
// children[i]->saveGame(gameParticleSystemNode);
// }
vector < XmlNode * > childrenNodeList = gameParticleSystemNode - > getChildList ( " UnitParticleSystem " ) ;
for ( unsigned int i = 0 ; i < childrenNodeList . size ( ) ; + + i ) {
XmlNode * node = childrenNodeList [ i ] ;
UnitParticleSystem * ups = new UnitParticleSystem ( ) ;
2013-09-23 19:16:34 +02:00
//ups->setParticleOwner(!!!);
2012-03-13 22:58:31 +01:00
ups - > loadGame ( node ) ;
2012-03-14 08:23:41 +01:00
//children.push_back(ups);
addChild ( ups ) ;
2012-03-13 22:58:31 +01:00
}
// Primitive primitive;
primitive = static_cast < Primitive > ( gameParticleSystemNode - > getAttribute ( " primitive " ) - > getIntValue ( ) ) ;
// Model *model;
//if(model != NULL) {
// gameParticleSystemNode->addAttribute("model",model->getFileName(), mapTagReplacements);
//}
2012-03-14 08:23:41 +01:00
if ( gameParticleSystemNode - > hasAttribute ( " model " ) = = true ) {
modelFileLoadDeferred = gameParticleSystemNode - > getAttribute ( " model " ) - > getValue ( ) ;
}
2012-03-13 22:58:31 +01:00
// float modelCycle;
//gameParticleSystemNode->addAttribute("modelCycle",floatToStr(modelCycle), mapTagReplacements);
modelCycle = gameParticleSystemNode - > getAttribute ( " modelCycle " ) - > getFloatValue ( ) ;
// Vec3f offset;
2013-10-02 22:22:10 +02:00
offset = Vec3f : : strToVec3 ( gameParticleSystemNode - > getAttribute ( " offset " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// Vec3f direction;
2013-10-02 22:22:10 +02:00
direction = Vec3f : : strToVec3 ( gameParticleSystemNode - > getAttribute ( " direction " ) - > getValue ( ) ) ;
2012-03-13 22:58:31 +01:00
// float tween;
tween = gameParticleSystemNode - > getAttribute ( " tween " ) - > getFloatValue ( ) ;
}
2013-09-23 19:16:34 +02:00
Checksum GameParticleSystem : : getCRC ( ) {
Checksum crcForParticleSystem = ParticleSystem : : getCRC ( ) ;
return crcForParticleSystem ;
}
string GameParticleSystem : : toString ( ) const {
string result = ParticleSystem : : toString ( ) ;
result + = " \n GameParticleSystem " ;
result + = " \n children = " + intToStr ( children . size ( ) ) ;
result + = " \n primitive = " + intToStr ( primitive ) ;
//string modelFileLoadDeferred;
//Model *model;
2013-10-02 22:22:10 +02:00
result + = " \n modelCycle = " + floatToStr ( modelCycle ) ;
2013-09-23 19:16:34 +02:00
result + = " \n offset = " + offset . getString ( ) ;
result + = " \n direction = " + direction . getString ( ) ;
2013-10-02 22:22:10 +02:00
result + = " \n tween = " + floatToStr ( tween ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// UnitParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
bool UnitParticleSystem : : isNight = false ;
2013-09-26 18:37:32 +02:00
Vec3f UnitParticleSystem : : lightColor = Vec3f ( 1.0f , 1.0f , 1.0f ) ;
2010-03-27 04:09:11 +01:00
2012-03-14 08:23:41 +01:00
UnitParticleSystem : : UnitParticleSystem ( int particleCount ) :
GameParticleSystem ( particleCount ) , parent ( NULL ) {
2014-11-19 06:38:46 +01:00
particleSystemType = NULL ;
2010-03-27 04:09:11 +01:00
radius = 0.5f ;
speed = 0.01f ;
2013-10-02 22:22:10 +02:00
windSpeed = Vec3f ( 0.0f ) ;
2012-09-22 22:13:57 +02:00
minRadius = 0.0 ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
setParticleSize ( 0.6f ) ;
2013-09-26 18:37:32 +02:00
setColorNoEnergy ( Vec4f ( 1.0f , 0.5f , 0.0f , 1.0f ) ) ;
2012-01-08 00:53:08 +01:00
sizeNoEnergy = 1.0f ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
primitive = pQuad ;
gravity = 0.0f ;
2011-03-14 00:16:07 +01:00
fixed = false ;
2012-01-08 00:53:08 +01:00
shape = UnitParticleSystem : : sLinear ;
angle = 0.0f ;
2011-03-14 00:16:07 +01:00
rotation = 0.0f ;
relativeDirection = true ;
relative = false ;
staticParticleCount = 0 ;
isVisibleAtNight = true ;
isVisibleAtDay = true ;
2012-01-07 21:24:54 +01:00
isDaylightAffected = false ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
cRotation = Vec3f ( 1.0f , 1.0f , 1.0f ) ;
fixedAddition = Vec3f ( 0.0f , 0.0f , 0.0f ) ;
2010-09-25 16:38:00 +02:00
//prepare system for given staticParticleCount
2011-03-14 00:16:07 +01:00
if ( staticParticleCount > 0 ) {
2013-10-02 22:22:10 +02:00
emissionState = ( float ) staticParticleCount ;
2010-09-25 16:38:00 +02:00
}
2011-03-14 00:16:07 +01:00
energyUp = false ;
2011-07-07 00:23:51 +02:00
delay = 0 ; // none
lifetime = - 1 ; // forever
2012-01-08 00:53:08 +01:00
emissionRateFade = 0.0f ;
2011-08-27 08:52:17 +02:00
startTime = 0 ;
endTime = 1 ;
2014-01-04 18:40:00 +01:00
unitModel = NULL ;
meshName = " " ;
2011-10-01 01:55:07 +02:00
radiusBasedStartenergy = false ;
2011-07-07 00:23:51 +02:00
}
UnitParticleSystem : : ~ UnitParticleSystem ( ) {
if ( parent ) {
parent - > removeChild ( this ) ;
}
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
bool UnitParticleSystem : : getVisible ( ) const {
if ( ( isNight = = true ) & & ( isVisibleAtNight = = true ) ) {
return visible ;
}
else if ( ( isNight = = false ) & & ( isVisibleAtDay = = true ) ) {
return visible ;
}
2013-09-27 18:15:36 +02:00
else
return false ;
2011-03-14 00:16:07 +01:00
}
2011-07-07 00:23:51 +02:00
void UnitParticleSystem : : render ( ParticleRenderer * pr , ModelRenderer * mr ) {
GameParticleSystem : : render ( pr , mr ) ;
}
2013-10-02 22:22:10 +02:00
void UnitParticleSystem : : setRotation ( float rotation ) {
2011-07-07 00:23:51 +02:00
this - > rotation = rotation ;
2011-09-01 03:11:23 +02:00
for ( Children : : iterator it = children . begin ( ) ; it ! = children . end ( ) ; + + it )
2011-07-07 00:23:51 +02:00
( * it ) - > setRotation ( rotation ) ;
}
void UnitParticleSystem : : fade ( ) {
if ( ! parent | | ( lifetime < = 0 & & ! ( emissionRateFade & & emissionRate > 0 ) ) ) { // particle has its own lifetime?
2014-01-04 18:40:00 +01:00
unitModel = NULL ;
2011-07-07 00:23:51 +02:00
GameParticleSystem : : fade ( ) ;
2011-03-14 00:16:07 +01:00
}
2010-03-27 04:09:11 +01:00
}
2011-07-07 00:23:51 +02:00
UnitParticleSystem : : Shape UnitParticleSystem : : strToShape ( const string & str ) {
if ( str = = " spherical " ) {
return sSpherical ;
2010-03-27 04:09:11 +01:00
}
2011-07-07 00:23:51 +02:00
else if ( str = = " conical " ) {
return sConical ;
}
else if ( str = = " linear " ) {
return sLinear ;
2010-03-27 04:09:11 +01:00
}
else {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Unknown particle shape: " + str ) ;
2010-03-27 04:09:11 +01:00
}
}
void UnitParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
ParticleSystem : : initParticle ( p , particleIndex ) ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
const float ang = random . randRange ( - 2.0f * pi , 2.0f * pi ) ;
2011-07-07 00:23:51 +02:00
# ifdef USE_STREFLOP
2013-10-02 22:22:10 +02:00
const float mod = streflop : : fabsf ( static_cast < streflop : : Simple > ( random . randRange ( - radius , radius ) ) ) ;
const float radRatio = streflop : : sqrtf ( static_cast < streflop : : Simple > ( mod / radius ) ) ;
2010-05-01 22:14:25 +02:00
# else
2013-10-02 22:22:10 +02:00
const float mod = fabsf ( random . randRange ( - radius , radius ) ) ;
const float radRatio = sqrtf ( mod / radius ) ;
2010-05-01 22:14:25 +02:00
# endif
2011-03-14 00:16:07 +01:00
p - > color = color ;
2013-09-27 18:15:36 +02:00
if ( isDaylightAffected = = true ) {
2012-04-16 00:38:41 +02:00
p - > color . x = p - > color . x * lightColor . x ;
p - > color . y = p - > color . y * lightColor . y ;
p - > color . z = p - > color . z * lightColor . z ;
}
2013-09-27 18:15:36 +02:00
if ( radiusBasedStartenergy = = true ) {
p - > energy = static_cast < int > ( maxParticleEnergy * radRatio ) +
random . randRange ( - varParticleEnergy , varParticleEnergy ) ;
2011-03-14 00:16:07 +01:00
}
2013-09-27 18:15:36 +02:00
else {
p - > energy = static_cast < int > ( maxParticleEnergy ) +
random . randRange ( - varParticleEnergy , varParticleEnergy ) ;
2011-03-14 00:16:07 +01:00
}
2010-03-27 04:09:11 +01:00
p - > lastPos = pos ;
2011-03-14 00:16:07 +01:00
oldPosition = pos ;
2010-03-27 04:09:11 +01:00
p - > size = particleSize ;
2014-07-26 13:56:29 +02:00
p - > speedUpRelative = speedUpRelative ;
2013-10-02 22:22:10 +02:00
p - > accel = Vec3f ( 0.0f , - gravity , 0.0f ) ;
p - > accel . x = truncateDecimal < float > ( p - > accel . x , 6 ) ;
2014-07-26 14:03:54 +02:00
p - > accel . y = truncateDecimal < float > ( p - > accel . y , 6 ) ;
2013-10-02 22:22:10 +02:00
p - > accel . z = truncateDecimal < float > ( p - > accel . z , 6 ) ;
2011-07-07 00:23:51 +02:00
// work out where we start for our shape (set speed and pos)
switch ( shape ) {
case sSpherical :
2013-10-02 22:22:10 +02:00
angle = ( float ) random . randRange ( 0 , 360 ) ;
2011-07-07 00:23:51 +02:00
// fall through
case sConical : {
2013-10-02 22:22:10 +02:00
Vec2f horiz = Vec2f ( 1 , 0 ) . rotate ( ang ) ;
Vec2f vert = Vec2f ( 1 , 0 ) . rotate ( degToRad ( angle ) ) ;
Vec3f start = Vec3f ( horiz . x * vert . y , vert . x , horiz . y ) . getNormalized ( ) ; // close enough
2011-07-07 00:23:51 +02:00
p - > speed = start * speed ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-07-07 00:23:51 +02:00
start = start * random . randRange ( minRadius , radius ) ;
p - > pos = pos + offset + start ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-07-07 00:23:51 +02:00
} break ;
case sLinear : {
# ifdef USE_STREFLOP
2013-10-02 22:22:10 +02:00
float x = streflop : : sinf ( static_cast < streflop : : Simple > ( ang ) ) * mod ;
float y = streflop : : cosf ( static_cast < streflop : : Simple > ( ang ) ) * mod ;
2011-07-07 00:23:51 +02:00
# else
2013-10-02 22:22:10 +02:00
float x = sinf ( ang ) * mod ;
float y = cosf ( ang ) * mod ;
2011-07-07 00:23:51 +02:00
# endif
2013-10-02 22:22:10 +02:00
const float rad = degToRad ( rotation ) ;
2011-07-07 00:23:51 +02:00
if ( ! relative ) {
2013-10-02 22:22:10 +02:00
p - > pos = Vec3f ( pos . x + x + offset . x , pos . y +
2013-09-27 18:15:36 +02:00
random . randRange ( - radius / 2 , radius / 2 ) + offset . y ,
pos . z + y + offset . z ) ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
}
2013-09-27 18:15:36 +02:00
else { // rotate it according to rotation
2014-01-04 18:40:00 +01:00
Vec3f combinedOffset = Vec3f ( offset ) ;
if ( meshName ! = " " & & unitModel ! = NULL ) {
//printf("meshName set unitModel given\n");
2014-01-05 23:57:29 +01:00
bool foundMesh = false ;
2014-01-18 05:10:18 +01:00
for ( unsigned int i = 0 ; i < unitModel - > getMeshCount ( ) ; i + + ) {
2014-01-04 18:40:00 +01:00
//printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str());
if ( unitModel - > getMesh ( i ) - > getName ( ) = = meshName ) {
const InterpolationData * data = unitModel - > getMesh ( i ) - > getInterpolationData ( ) ;
const Vec3f * verticepos = data - > getVertices ( ) ;
//printf("verticepos %f %f %f\n",verticepos->x,verticepos->y,verticepos->z);
combinedOffset . x + = verticepos - > x ;
combinedOffset . y + = verticepos - > y ;
combinedOffset . z + = verticepos - > z ;
2014-01-08 22:24:11 +01:00
foundMesh = true ;
2014-01-05 23:57:29 +01:00
break ;
2014-01-04 18:40:00 +01:00
}
}
2014-01-05 23:57:29 +01:00
if ( foundMesh = = false ) {
string meshesFound = " " ;
2014-01-18 05:10:18 +01:00
for ( unsigned i = 0 ; i < unitModel - > getMeshCount ( ) ; i + + ) {
2014-01-05 23:57:29 +01:00
meshesFound + = unitModel - > getMesh ( i ) - > getName ( ) + " , " ;
}
string errorString = " Warning: Particle system is trying to find mesh' " + meshName + " ', but just found: \n ' " + meshesFound + " ' in file: \n ' " + unitModel - > getFileName ( ) + " ' \n " ;
//throw megaglest_runtime_error(errorString);
printf ( " %s " , errorString . c_str ( ) ) ;
}
2014-01-04 18:40:00 +01:00
}
2011-07-07 00:23:51 +02:00
# ifdef USE_STREFLOP
2014-01-04 18:40:00 +01:00
p - > pos = Vec3f ( pos . x + x + combinedOffset . z * streflop : : sinf ( static_cast < streflop : : Simple > ( rad ) ) + combinedOffset . x * streflop : : cosf ( static_cast < streflop : : Simple > ( rad ) ) , pos . y + random . randRange ( - radius / 2 , radius / 2 ) + combinedOffset . y , pos . z + y + ( combinedOffset . z * streflop : : cosf ( static_cast < streflop : : Simple > ( rad ) ) - combinedOffset . x * streflop : : sinf ( static_cast < streflop : : Simple > ( rad ) ) ) ) ;
2011-07-07 00:23:51 +02:00
# else
2014-01-04 18:40:00 +01:00
p - > pos = Vec3f ( pos . x + x + combinedOffset . z * sinf ( rad ) + combinedOffset . x * cosf ( rad ) , pos . y + random . randRange ( - radius / 2 ,
radius / 2 ) + combinedOffset . y , pos . z + y + ( combinedOffset . z * cosf ( rad ) - combinedOffset . x * sinf ( rad ) ) ) ;
2011-07-07 00:23:51 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-07-07 00:23:51 +02:00
}
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( direction . x + direction . x * random . randRange ( - 0.5f , 0.5f ) , direction . y + direction . y
2011-07-07 00:23:51 +02:00
* random . randRange ( - 0.5f , 0.5f ) , direction . z + direction . z * random . randRange ( - 0.5f , 0.5f ) ) ;
p - > speed = p - > speed * speed ;
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
if ( relative & & relativeDirection ) {
2011-07-07 00:23:51 +02:00
# ifdef USE_STREFLOP
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( p - > speed . z * streflop : : sinf (
2013-09-27 18:15:36 +02:00
static_cast < streflop : : Simple > ( rad ) ) + p - > speed . x *
streflop : : cosf ( static_cast < streflop : : Simple > ( rad ) ) ,
p - > speed . y , ( p - > speed . z * streflop : : cosf (
static_cast < streflop : : Simple > ( rad ) ) - p - > speed . x *
streflop : : sinf ( static_cast < streflop : : Simple > ( rad ) ) ) ) ;
2011-07-07 00:23:51 +02:00
# else
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( p - > speed . z * sinf ( rad ) + p - > speed . x * cosf ( rad ) ,
2013-09-27 18:15:36 +02:00
p - > speed . y , ( p - > speed . z * cosf ( rad ) - p - > speed . x * sinf ( rad ) ) ) ;
2011-07-07 00:23:51 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-05-01 22:14:25 +02:00
}
2011-07-07 00:23:51 +02:00
} break ;
2012-04-14 23:21:09 +02:00
default : throw megaglest_runtime_error ( " bad shape " ) ;
2010-03-27 04:09:11 +01:00
}
2014-07-26 13:56:29 +02:00
//need to do that down here because we need p->speed for it.
p - > speedUpConstant = Vec3f ( speedUpConstant ) * p - > speed ;
2010-03-27 04:09:11 +01:00
}
void UnitParticleSystem : : update ( ) {
2011-07-07 00:23:51 +02:00
// delay and timeline are only applicable for child particles
2013-09-27 18:15:36 +02:00
if ( parent & & delay > 0 & & delay - - ) {
2011-07-07 00:23:51 +02:00
return ;
}
2013-09-27 18:15:36 +02:00
if ( parent & & lifetime > 0 & & ! - - lifetime ) {
2011-07-07 00:23:51 +02:00
fade ( ) ;
}
if ( state ! = sPause ) {
emissionRate - = emissionRateFade ;
2013-10-02 22:22:10 +02:00
emissionRate = truncateDecimal < float > ( emissionRate , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-07-07 00:23:51 +02:00
if ( parent & & emissionRate < 0.0f ) {
fade ( ) ;
}
}
2013-09-27 18:15:36 +02:00
if ( fixed ) {
2013-10-02 22:22:10 +02:00
fixedAddition = Vec3f ( pos . x - oldPosition . x , pos . y - oldPosition . y , pos . z - oldPosition . z ) ;
fixedAddition . x = truncateDecimal < float > ( fixedAddition . x , 6 ) ;
fixedAddition . y = truncateDecimal < float > ( fixedAddition . y , 6 ) ;
fixedAddition . z = truncateDecimal < float > ( fixedAddition . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-03-14 00:16:07 +01:00
oldPosition = pos ;
2010-03-27 04:09:11 +01:00
}
ParticleSystem : : update ( ) ;
}
void UnitParticleSystem : : updateParticle ( Particle * p ) {
2013-10-02 22:22:10 +02:00
float energyRatio ;
2011-03-14 00:16:07 +01:00
if ( alternations > 0 ) {
int interval = ( maxParticleEnergy / alternations ) ;
2013-10-02 22:22:10 +02:00
float moduloValue = ( float ) ( ( int ) ( static_cast < float > ( p - > energy ) ) % interval ) ;
2011-03-14 00:16:07 +01:00
if ( moduloValue < interval / 2 ) {
energyRatio = ( interval - moduloValue ) / interval ;
}
else {
energyRatio = moduloValue / interval ;
}
energyRatio = clamp ( energyRatio , 0.f , 1.f ) ;
}
else {
2013-10-02 22:22:10 +02:00
energyRatio = clamp ( static_cast < float > ( p - > energy ) / maxParticleEnergy , 0.f , 1.f ) ;
2011-03-14 00:16:07 +01:00
}
2013-10-02 22:22:10 +02:00
energyRatio = truncateDecimal < float > ( energyRatio , 6 ) ;
2013-09-27 18:15:36 +02:00
p - > lastPos + = p - > speed ;
2013-10-02 22:22:10 +02:00
p - > lastPos . x = truncateDecimal < float > ( p - > lastPos . x , 6 ) ;
p - > lastPos . y = truncateDecimal < float > ( p - > lastPos . y , 6 ) ;
p - > lastPos . z = truncateDecimal < float > ( p - > lastPos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
p - > pos + = p - > speed ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
if ( fixed ) {
p - > lastPos + = fixedAddition ;
2013-10-02 22:22:10 +02:00
p - > lastPos . x = truncateDecimal < float > ( p - > lastPos . x , 6 ) ;
p - > lastPos . y = truncateDecimal < float > ( p - > lastPos . y , 6 ) ;
p - > lastPos . z = truncateDecimal < float > ( p - > lastPos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
p - > pos + = fixedAddition ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2013-09-27 18:15:36 +02:00
p - > speed + = p - > accel ;
2014-07-26 13:56:29 +02:00
p - > speed + = p - > speedUpConstant ;
p - > speed = p - > speed * ( 1 + p - > speedUpRelative ) ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-03-14 00:16:07 +01:00
p - > color = color * energyRatio + colorNoEnergy * ( 1.0f - energyRatio ) ;
2013-09-27 18:15:36 +02:00
if ( isDaylightAffected = = true ) {
2012-01-07 21:24:54 +01:00
p - > color . x = p - > color . x * lightColor . x ;
p - > color . y = p - > color . y * lightColor . y ;
p - > color . z = p - > color . z * lightColor . z ;
}
2011-03-14 00:16:07 +01:00
p - > size = particleSize * energyRatio + sizeNoEnergy * ( 1.0f - energyRatio ) ;
2013-10-02 22:22:10 +02:00
p - > size = truncateDecimal < float > ( p - > size , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-03-14 00:16:07 +01:00
if ( state = = ParticleSystem : : sFade | | staticParticleCount < 1 ) {
2010-09-25 16:38:00 +02:00
p - > energy - - ;
}
2011-03-14 00:16:07 +01:00
else {
if ( maxParticleEnergy > 2 ) {
2010-09-25 16:38:00 +02:00
if ( energyUp ) {
p - > energy + + ;
}
2011-03-14 00:16:07 +01:00
else {
2010-09-25 16:38:00 +02:00
p - > energy - - ;
}
2011-03-14 00:16:07 +01:00
if ( p - > energy = = 1 ) {
energyUp = true ;
2010-09-25 16:38:00 +02:00
}
2011-03-14 00:16:07 +01:00
if ( p - > energy = = maxParticleEnergy ) {
energyUp = false ;
2010-09-25 16:38:00 +02:00
}
}
}
2010-03-27 04:09:11 +01:00
}
// ================= SET PARAMS ====================
2013-10-02 22:22:10 +02:00
void UnitParticleSystem : : setWind ( float windAngle , float windSpeed ) {
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
this - > windSpeed . x = streflop : : sinf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-03-27 04:09:11 +01:00
this - > windSpeed . y = 0.0f ;
2012-02-10 07:21:06 +01:00
this - > windSpeed . z = streflop : : cosf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# else
2011-03-14 00:16:07 +01:00
this - > windSpeed . x = sinf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
this - > windSpeed . y = 0.0f ;
2011-03-14 00:16:07 +01:00
this - > windSpeed . z = cosf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
this - > windSpeed . x = truncateDecimal < float > ( this - > windSpeed . x , 6 ) ;
this - > windSpeed . y = truncateDecimal < float > ( this - > windSpeed . y , 6 ) ;
this - > windSpeed . z = truncateDecimal < float > ( this - > windSpeed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2012-03-13 22:58:31 +01:00
void UnitParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitParticleSystemNode = rootNode - > addChild ( " UnitParticleSystem " ) ;
GameParticleSystem : : saveGame ( unitParticleSystemNode ) ;
// float radius;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " radius " , floatToStr ( radius , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float minRadius;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " minRadius " , floatToStr ( minRadius , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f windSpeed;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " windSpeed " , windSpeed . getString ( ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f cRotation;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " cRotation " , cRotation . getString ( ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f fixedAddition;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " fixedAddition " , fixedAddition . getString ( ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Vec3f oldPosition;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " oldPosition " , oldPosition . getString ( ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool energyUp;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " energyUp " , intToStr ( energyUp ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float startTime;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " startTime " , floatToStr ( startTime , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float endTime;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " endTime " , floatToStr ( endTime , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool relative;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " relative " , intToStr ( relative ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool relativeDirection;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " relativeDirection " , intToStr ( relativeDirection ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool fixed;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " fixed " , intToStr ( fixed ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// Shape shape;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " shape " , intToStr ( shape ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float angle;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " angle " , floatToStr ( angle , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float sizeNoEnergy;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " sizeNoEnergy " , floatToStr ( sizeNoEnergy , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float gravity;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " gravity " , floatToStr ( gravity , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float rotation;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " rotation " , floatToStr ( rotation , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool isVisibleAtNight;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " isVisibleAtNight " , intToStr ( isVisibleAtNight ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool isVisibleAtDay;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " isVisibleAtDay " , intToStr ( isVisibleAtDay ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool isDaylightAffected;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " isDaylightAffected " , intToStr ( isDaylightAffected ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// bool radiusBasedStartenergy;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " radiusBasedStartenergy " , intToStr ( radiusBasedStartenergy ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// int staticParticleCount;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " staticParticleCount " , intToStr ( staticParticleCount ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// int delay;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " delay " , intToStr ( delay ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// int lifetime;
2012-03-14 08:23:41 +01:00
unitParticleSystemNode - > addAttribute ( " lifetime " , intToStr ( lifetime ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// float emissionRateFade;
2013-10-02 22:22:10 +02:00
unitParticleSystemNode - > addAttribute ( " emissionRateFade " , floatToStr ( emissionRateFade , 6 ) , mapTagReplacements ) ;
2012-03-13 22:58:31 +01:00
// GameParticleSystem* parent;
2012-03-14 08:23:41 +01:00
//if(parent != NULL) {
// parent->saveGame(unitParticleSystemNode);
//}
2012-03-13 22:58:31 +01:00
}
2012-03-14 08:23:41 +01:00
2012-03-13 22:58:31 +01:00
void UnitParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * unitParticleSystemNode = rootNode ;
2012-03-19 22:35:54 +01:00
//printf("Load Smoke particle (UnitParticleSystem)\n");
2012-03-13 22:58:31 +01:00
GameParticleSystem : : loadGame ( unitParticleSystemNode ) ;
2012-03-14 08:23:41 +01:00
// float radius;
radius = unitParticleSystemNode - > getAttribute ( " radius " ) - > getFloatValue ( ) ;
// float minRadius;
minRadius = unitParticleSystemNode - > getAttribute ( " minRadius " ) - > getFloatValue ( ) ;
// Vec3f windSpeed;
2013-10-02 22:22:10 +02:00
windSpeed = Vec3f : : strToVec3 ( unitParticleSystemNode - > getAttribute ( " windSpeed " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f cRotation;
2013-10-02 22:22:10 +02:00
windSpeed = Vec3f : : strToVec3 ( unitParticleSystemNode - > getAttribute ( " cRotation " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f fixedAddition;
2013-10-02 22:22:10 +02:00
fixedAddition = Vec3f : : strToVec3 ( unitParticleSystemNode - > getAttribute ( " fixedAddition " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f oldPosition;
2013-10-02 22:22:10 +02:00
oldPosition = Vec3f : : strToVec3 ( unitParticleSystemNode - > getAttribute ( " oldPosition " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// bool energyUp;
2012-04-16 22:15:57 +02:00
energyUp = unitParticleSystemNode - > getAttribute ( " energyUp " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// float startTime;
startTime = unitParticleSystemNode - > getAttribute ( " startTime " ) - > getFloatValue ( ) ;
// float endTime;
endTime = unitParticleSystemNode - > getAttribute ( " endTime " ) - > getFloatValue ( ) ;
// bool relative;
2012-04-16 22:15:57 +02:00
relative = unitParticleSystemNode - > getAttribute ( " relative " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// bool relativeDirection;
2012-04-16 22:15:57 +02:00
relativeDirection = unitParticleSystemNode - > getAttribute ( " relativeDirection " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// bool fixed;
2012-04-16 22:15:57 +02:00
fixed = unitParticleSystemNode - > getAttribute ( " fixed " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// Shape shape;
shape = static_cast < Shape > ( unitParticleSystemNode - > getAttribute ( " shape " ) - > getIntValue ( ) ) ;
// float angle;
angle = unitParticleSystemNode - > getAttribute ( " angle " ) - > getFloatValue ( ) ;
// float sizeNoEnergy;
sizeNoEnergy = unitParticleSystemNode - > getAttribute ( " sizeNoEnergy " ) - > getFloatValue ( ) ;
// float gravity;
gravity = unitParticleSystemNode - > getAttribute ( " gravity " ) - > getFloatValue ( ) ;
// float rotation;
rotation = unitParticleSystemNode - > getAttribute ( " rotation " ) - > getFloatValue ( ) ;
// bool isVisibleAtNight;
2012-04-16 22:15:57 +02:00
isVisibleAtNight = unitParticleSystemNode - > getAttribute ( " isVisibleAtNight " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// bool isVisibleAtDay;
2012-04-16 22:15:57 +02:00
isVisibleAtDay = unitParticleSystemNode - > getAttribute ( " isVisibleAtDay " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// bool isDaylightAffected;
2012-04-16 22:15:57 +02:00
isDaylightAffected = unitParticleSystemNode - > getAttribute ( " isDaylightAffected " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// bool radiusBasedStartenergy;
2012-04-16 22:15:57 +02:00
radiusBasedStartenergy = unitParticleSystemNode - > getAttribute ( " radiusBasedStartenergy " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 08:23:41 +01:00
// int staticParticleCount;
staticParticleCount = unitParticleSystemNode - > getAttribute ( " staticParticleCount " ) - > getIntValue ( ) ;
// int delay;
delay = unitParticleSystemNode - > getAttribute ( " delay " ) - > getIntValue ( ) ;
// int lifetime;
lifetime = unitParticleSystemNode - > getAttribute ( " lifetime " ) - > getIntValue ( ) ;
// float emissionRateFade;
emissionRateFade = unitParticleSystemNode - > getAttribute ( " emissionRateFade " ) - > getFloatValue ( ) ;
// GameParticleSystem* parent;
2012-03-19 22:35:54 +01:00
parent = NULL ;
2012-03-14 08:23:41 +01:00
//if(parent != NULL) {
// parent->saveGame(unitParticleSystemNode);
//}
//if(unitParticleSystemNode->hasChild("GameParticleSystem") == true) {
// void GameParticleSystem::saveGame(XmlNode *rootNode)
// std::map<string,string> mapTagReplacements;
// XmlNode *gameParticleSystemNode = rootNode->addChild("GameParticleSystem");
2012-03-19 22:35:54 +01:00
//XmlNode *gameParticleSystemNode = unitParticleSystemNode->getChild("GameParticleSystem");
2012-03-14 08:23:41 +01:00
//!!!
//}
2012-03-13 22:58:31 +01:00
}
2013-09-23 19:16:34 +02:00
Checksum UnitParticleSystem : : getCRC ( ) {
2013-10-18 06:55:29 +02:00
Checksum crcForParticleSystem = GameParticleSystem : : getCRC ( ) ;
2013-09-23 19:16:34 +02:00
return crcForParticleSystem ;
}
string UnitParticleSystem : : toString ( ) const {
2013-10-18 06:55:29 +02:00
string result = GameParticleSystem : : toString ( ) ;
2013-09-23 19:16:34 +02:00
result + = " \n UnitParticleSystem " ;
2013-10-02 22:22:10 +02:00
result + = " \n radius = " + floatToStr ( radius ) ;
result + = " \n minRadius = " + floatToStr ( minRadius ) ;
2013-09-23 19:16:34 +02:00
result + = " \n windSpeed = " + windSpeed . getString ( ) ;
result + = " \n cRotation = " + cRotation . getString ( ) ;
result + = " \n fixedAddition = " + fixedAddition . getString ( ) ;
result + = " \n oldPosition = " + oldPosition . getString ( ) ;
result + = " \n energyUp = " + intToStr ( energyUp ) ;
2013-10-02 22:22:10 +02:00
result + = " \n startTime = " + floatToStr ( startTime ) ;
result + = " \n endTime = " + floatToStr ( endTime ) ;
2013-09-23 19:16:34 +02:00
result + = " \n relative = " + intToStr ( relative ) ;
result + = " \n relativeDirection = " + intToStr ( relativeDirection ) ;
result + = " \n fixed = " + intToStr ( fixed ) ;
result + = " \n shape = " + intToStr ( shape ) ;
2013-10-02 22:22:10 +02:00
result + = " \n angle = " + floatToStr ( angle ) ;
result + = " \n sizeNoEnergy = " + floatToStr ( sizeNoEnergy ) ;
result + = " \n gravity = " + floatToStr ( gravity ) ;
result + = " \n rotation = " + floatToStr ( rotation ) ;
2013-09-23 19:16:34 +02:00
result + = " \n isVisibleAtNight = " + intToStr ( isVisibleAtNight ) ;
result + = " \n isVisibleAtDay = " + intToStr ( isVisibleAtDay ) ;
result + = " \n isDaylightAffected = " + intToStr ( isDaylightAffected ) ;
result + = " \n radiusBasedStartenergy = " + intToStr ( radiusBasedStartenergy ) ;
result + = " \n staticParticleCount = " + intToStr ( staticParticleCount ) ;
result + = " \n delay = " + intToStr ( delay ) ;
result + = " \n lifetime = " + intToStr ( lifetime ) ;
2013-10-02 22:22:10 +02:00
result + = " \n emissionRateFade = " + floatToStr ( emissionRateFade ) ;
2013-09-23 19:16:34 +02:00
//GameParticleSystem* parent;
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// RainParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
RainParticleSystem : : RainParticleSystem ( int particleCount ) :
ParticleSystem ( particleCount ) {
2010-03-27 04:09:11 +01:00
setWind ( 0.0f , 0.0f ) ;
setRadius ( 20.0f ) ;
2010-09-24 18:36:59 +02:00
setEmissionRate ( 25.0f ) ;
2010-03-27 04:09:11 +01:00
setParticleSize ( 3.0f ) ;
2013-09-26 18:37:32 +02:00
setColor ( Vec4f ( 0.5f , 0.5f , 0.5f , 0.3f ) ) ;
2010-03-27 04:09:11 +01:00
setSpeed ( 0.2f ) ;
}
void RainParticleSystem : : render ( ParticleRenderer * pr , ModelRenderer * mr ) {
pr - > renderSystemLineAlpha ( this ) ;
}
void RainParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
ParticleSystem : : initParticle ( p , particleIndex ) ;
2013-10-02 22:22:10 +02:00
float x = random . randRange ( - radius , radius ) ;
float y = random . randRange ( - radius , radius ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
p - > color = color ;
p - > energy = 10000 ;
2013-10-02 22:22:10 +02:00
p - > pos = Vec3f ( pos . x + x , pos . y , pos . z + y ) ;
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
p - > lastPos = p - > pos ;
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( random . randRange ( - speed / 10 , speed / 10 ) , - speed ,
2013-09-27 18:15:36 +02:00
random . randRange ( - speed / 10 , speed / 10 ) ) + windSpeed ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
bool RainParticleSystem : : deathTest ( Particle * p ) {
2011-03-14 00:16:07 +01:00
return p - > pos . y < 0 ;
2010-03-27 04:09:11 +01:00
}
2013-10-02 22:22:10 +02:00
void RainParticleSystem : : setRadius ( float radius ) {
2010-03-27 04:09:11 +01:00
this - > radius = radius ;
2011-03-14 00:16:07 +01:00
}
2010-03-27 04:09:11 +01:00
2013-10-02 22:22:10 +02:00
void RainParticleSystem : : setWind ( float windAngle , float windSpeed ) {
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
this - > windSpeed . x = streflop : : sinf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-03-27 04:09:11 +01:00
this - > windSpeed . y = 0.0f ;
2012-02-10 07:21:06 +01:00
this - > windSpeed . z = streflop : : cosf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# else
2011-03-14 00:16:07 +01:00
this - > windSpeed . x = sinf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
this - > windSpeed . y = 0.0f ;
2011-03-14 00:16:07 +01:00
this - > windSpeed . z = cosf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
this - > windSpeed . x = truncateDecimal < float > ( this - > windSpeed . x , 6 ) ;
this - > windSpeed . y = truncateDecimal < float > ( this - > windSpeed . y , 6 ) ;
this - > windSpeed . z = truncateDecimal < float > ( this - > windSpeed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2013-09-23 19:16:34 +02:00
Checksum RainParticleSystem : : getCRC ( ) {
Checksum crcForParticleSystem = ParticleSystem : : getCRC ( ) ;
return crcForParticleSystem ;
}
string RainParticleSystem : : toString ( ) const {
string result = ParticleSystem : : toString ( ) ;
result + = " \n RainParticleSystem " ;
result + = " \n windSpeed = " + windSpeed . getString ( ) ;
2013-10-02 22:22:10 +02:00
result + = " \n radius = " + floatToStr ( radius ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// SnowParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
SnowParticleSystem : : SnowParticleSystem ( int particleCount ) :
ParticleSystem ( particleCount ) {
2010-03-27 04:09:11 +01:00
setWind ( 0.0f , 0.0f ) ;
setRadius ( 30.0f ) ;
2010-09-24 18:36:59 +02:00
setEmissionRate ( 2.0f ) ;
2010-03-27 04:09:11 +01:00
setParticleSize ( 0.2f ) ;
2013-09-26 18:37:32 +02:00
setColor ( Vec4f ( 0.8f , 0.8f , 0.8f , 0.8f ) ) ;
2010-03-27 04:09:11 +01:00
setSpeed ( 0.05f ) ;
}
void SnowParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
ParticleSystem : : initParticle ( p , particleIndex ) ;
2013-10-02 22:22:10 +02:00
float x = random . randRange ( - radius , radius ) ;
float y = random . randRange ( - radius , radius ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
p - > color = color ;
p - > energy = 10000 ;
2013-10-02 22:22:10 +02:00
p - > pos = Vec3f ( pos . x + x , pos . y , pos . z + y ) ;
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
p - > lastPos = p - > pos ;
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( 0.0f , - speed , 0.0f ) + windSpeed ;
2010-03-27 04:09:11 +01:00
p - > speed . x + = random . randRange ( - 0.005f , 0.005f ) ;
p - > speed . y + = random . randRange ( - 0.005f , 0.005f ) ;
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
bool SnowParticleSystem : : deathTest ( Particle * p ) {
return p - > pos . y < 0 ;
2010-03-27 04:09:11 +01:00
}
2013-10-02 22:22:10 +02:00
void SnowParticleSystem : : setRadius ( float radius ) {
2010-03-27 04:09:11 +01:00
this - > radius = radius ;
2011-03-14 00:16:07 +01:00
}
2010-03-27 04:09:11 +01:00
2013-10-02 22:22:10 +02:00
void SnowParticleSystem : : setWind ( float windAngle , float windSpeed ) {
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
this - > windSpeed . x = streflop : : sinf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-03-27 04:09:11 +01:00
this - > windSpeed . y = 0.0f ;
2012-02-10 07:21:06 +01:00
this - > windSpeed . z = streflop : : cosf ( static_cast < streflop : : Simple > ( degToRad ( windAngle ) ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# else
2011-03-14 00:16:07 +01:00
this - > windSpeed . x = sinf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
this - > windSpeed . y = 0.0f ;
2011-03-14 00:16:07 +01:00
this - > windSpeed . z = cosf ( degToRad ( windAngle ) ) * windSpeed ;
2010-05-01 22:14:25 +02:00
# endif
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
this - > windSpeed . x = truncateDecimal < float > ( this - > windSpeed . x , 6 ) ;
this - > windSpeed . y = truncateDecimal < float > ( this - > windSpeed . y , 6 ) ;
this - > windSpeed . z = truncateDecimal < float > ( this - > windSpeed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
}
2013-09-23 19:16:34 +02:00
Checksum SnowParticleSystem : : getCRC ( ) {
Checksum crcForParticleSystem = ParticleSystem : : getCRC ( ) ;
return crcForParticleSystem ;
}
string SnowParticleSystem : : toString ( ) const {
string result = ParticleSystem : : toString ( ) ;
result + = " \n SnowParticleSystem " ;
result + = " \n windSpeed = " + windSpeed . getString ( ) ;
2013-10-02 22:22:10 +02:00
result + = " \n radius = " + floatToStr ( radius ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// AttackParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
AttackParticleSystem : : AttackParticleSystem ( int particleCount ) :
2011-07-07 00:23:51 +02:00
GameParticleSystem ( particleCount ) {
2010-03-27 04:09:11 +01:00
primitive = pQuad ;
gravity = 0.0f ;
2012-09-22 22:13:57 +02:00
sizeNoEnergy = 0.0 ;
2010-03-27 04:09:11 +01:00
}
2012-03-14 08:23:41 +01:00
void AttackParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * attackParticleSystemNode = rootNode - > addChild ( " AttackParticleSystem " ) ;
GameParticleSystem : : saveGame ( attackParticleSystemNode ) ;
// float sizeNoEnergy;
2013-10-02 22:22:10 +02:00
attackParticleSystemNode - > addAttribute ( " sizeNoEnergy " , floatToStr ( sizeNoEnergy , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float gravity;
2013-10-02 22:22:10 +02:00
attackParticleSystemNode - > addAttribute ( " gravity " , floatToStr ( gravity , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
}
void AttackParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * attackParticleSystemNode = rootNode ;
GameParticleSystem : : loadGame ( attackParticleSystemNode ) ;
// float sizeNoEnergy;
sizeNoEnergy = attackParticleSystemNode - > getAttribute ( " sizeNoEnergy " ) - > getFloatValue ( ) ;
// float gravity;
gravity = attackParticleSystemNode - > getAttribute ( " gravity " ) - > getFloatValue ( ) ;
}
2013-09-23 19:16:34 +02:00
Checksum AttackParticleSystem : : getCRC ( ) {
2013-10-18 06:55:29 +02:00
Checksum crcForParticleSystem = GameParticleSystem : : getCRC ( ) ;
2013-09-23 19:16:34 +02:00
return crcForParticleSystem ;
}
string AttackParticleSystem : : toString ( ) const {
2013-10-18 06:55:29 +02:00
string result = GameParticleSystem : : toString ( ) ;
2013-09-23 19:16:34 +02:00
result + = " \n AttackParticleSystem " ;
2013-10-02 22:22:10 +02:00
result + = " \n sizeNoEnergy = " + floatToStr ( sizeNoEnergy ) ;
result + = " \n gravity = " + floatToStr ( gravity ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// ProjectileParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
ProjectileParticleSystem : : ProjectileParticleSystem ( int particleCount ) :
AttackParticleSystem ( particleCount ) {
2010-09-24 18:36:59 +02:00
setEmissionRate ( 20.0f ) ;
2013-09-26 18:37:32 +02:00
setColor ( Vec4f ( 1.0f , 0.3f , 0.0f , 0.5f ) ) ;
2010-03-27 04:09:11 +01:00
setMaxParticleEnergy ( 100 ) ;
setVarParticleEnergy ( 50 ) ;
setParticleSize ( 0.4f ) ;
setSpeed ( 0.14f ) ;
trajectory = tLinear ;
2012-04-05 01:43:31 +02:00
2010-03-27 04:09:11 +01:00
trajectorySpeed = 1.0f ;
trajectoryScale = 1.0f ;
2011-03-14 00:16:07 +01:00
trajectoryFrequency = 1.0f ;
2011-06-15 00:39:31 +02:00
modelCycle = 0.0f ;
2010-03-27 04:09:11 +01:00
nextParticleSystem = NULL ;
2013-09-23 19:16:34 +02:00
arriveDestinationDistance = 0.0f ;
2012-04-05 01:43:31 +02:00
//printf("#aXX trajectorySpeed = %f\n",trajectorySpeed);
2010-03-27 04:09:11 +01:00
}
ProjectileParticleSystem : : ~ ProjectileParticleSystem ( ) {
2011-03-14 00:16:07 +01:00
if ( nextParticleSystem ! = NULL ) {
2010-03-27 04:09:11 +01:00
nextParticleSystem - > prevParticleSystem = NULL ;
}
}
void ProjectileParticleSystem : : link ( SplashParticleSystem * particleSystem ) {
nextParticleSystem = particleSystem ;
2011-06-11 02:26:26 +02:00
nextParticleSystem - > setVisible ( false ) ;
2010-03-27 04:09:11 +01:00
nextParticleSystem - > setState ( sPause ) ;
nextParticleSystem - > prevParticleSystem = this ;
}
void ProjectileParticleSystem : : update ( ) {
2013-09-19 22:03:36 +02:00
//printf("Projectile particle system updating...\n");
2011-03-14 00:16:07 +01:00
if ( state = = sPlay ) {
2010-03-27 04:09:11 +01:00
2013-09-23 19:16:34 +02:00
lastPos = pos ;
2013-10-02 22:22:10 +02:00
flatPos + = zVector * truncateDecimal < float > ( trajectorySpeed , 6 ) ;
flatPos . x = truncateDecimal < float > ( flatPos . x , 6 ) ;
flatPos . y = truncateDecimal < float > ( flatPos . y , 6 ) ;
flatPos . z = truncateDecimal < float > ( flatPos . z , 6 ) ;
2013-09-23 19:16:34 +02:00
2013-10-02 22:22:10 +02:00
Vec3f targetVector = endPos - startPos ;
targetVector . x = truncateDecimal < float > ( targetVector . x , 6 ) ;
targetVector . y = truncateDecimal < float > ( targetVector . y , 6 ) ;
targetVector . z = truncateDecimal < float > ( targetVector . z , 6 ) ;
2013-09-23 19:16:34 +02:00
2013-10-02 22:22:10 +02:00
Vec3f currentVector = flatPos - startPos ;
currentVector . x = truncateDecimal < float > ( currentVector . x , 6 ) ;
currentVector . y = truncateDecimal < float > ( currentVector . y , 6 ) ;
currentVector . z = truncateDecimal < float > ( currentVector . z , 6 ) ;
2010-03-27 04:09:11 +01:00
// ratio
2013-10-02 22:22:10 +02:00
float relative = clamp ( currentVector . length ( ) / targetVector . length ( ) , 0.0f , 1.0f ) ;
relative = truncateDecimal < float > ( relative , 6 ) ;
2012-04-05 01:43:31 +02:00
2013-10-02 22:22:10 +02:00
float absolute = relative ;
2011-07-19 03:25:38 +02:00
setTween ( relative , absolute ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
// trajectory
2011-06-11 02:26:26 +02:00
switch ( trajectory ) {
2011-03-14 00:16:07 +01:00
case tLinear : {
2010-03-27 04:09:11 +01:00
pos = flatPos ;
2013-09-23 19:16:34 +02:00
}
2011-03-14 00:16:07 +01:00
break ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
case tParabolic : {
2013-10-02 22:22:10 +02:00
float scaledT = truncateDecimal < float > ( 2.0f * ( relative - 0.5f ) , 6 ) ;
float paraboleY = truncateDecimal < float > ( ( 1.0f - scaledT * scaledT ) * trajectoryScale , 6 ) ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
pos = flatPos ;
2013-09-23 19:16:34 +02:00
pos . y + = paraboleY ;
2013-10-02 22:22:10 +02:00
pos . y = truncateDecimal < float > ( pos . y , 6 ) ;
2013-09-23 19:16:34 +02:00
}
2011-03-14 00:16:07 +01:00
break ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
case tSpiral : {
2010-03-27 04:09:11 +01:00
pos = flatPos ;
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
pos + = xVector * streflop : : cos ( static_cast < streflop : : Simple > ( relative * trajectoryFrequency * targetVector . length ( ) ) ) * trajectoryScale ;
2013-10-26 09:02:32 +02:00
pos . x = truncateDecimal < float > ( pos . x , 6 ) ;
pos . y = truncateDecimal < float > ( pos . y , 6 ) ;
pos . z = truncateDecimal < float > ( pos . z , 6 ) ;
2012-02-10 07:21:06 +01:00
pos + = yVector * streflop : : sin ( static_cast < streflop : : Simple > ( relative * trajectoryFrequency * targetVector . length ( ) ) ) * trajectoryScale ;
2010-05-01 22:14:25 +02:00
# else
2011-07-19 03:25:38 +02:00
pos + = xVector * cos ( relative * trajectoryFrequency * targetVector . length ( ) ) * trajectoryScale ;
2013-10-26 09:02:32 +02:00
pos . x = truncateDecimal < float > ( pos . x , 6 ) ;
pos . y = truncateDecimal < float > ( pos . y , 6 ) ;
pos . z = truncateDecimal < float > ( pos . z , 6 ) ;
2011-07-19 03:25:38 +02:00
pos + = yVector * sin ( relative * trajectoryFrequency * targetVector . length ( ) ) * trajectoryScale ;
2010-05-01 22:14:25 +02:00
# endif
2013-10-02 22:22:10 +02:00
pos . x = truncateDecimal < float > ( pos . x , 6 ) ;
pos . y = truncateDecimal < float > ( pos . y , 6 ) ;
pos . z = truncateDecimal < float > ( pos . z , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
break ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
default :
assert ( false ) ;
2012-09-22 22:13:57 +02:00
break ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
2013-10-26 09:02:32 +02:00
direction = ( pos - lastPos ) ;
direction . x = truncateDecimal < float > ( direction . x , 6 ) ;
direction . y = truncateDecimal < float > ( direction . y , 6 ) ;
direction . z = truncateDecimal < float > ( direction . z , 6 ) ;
2010-03-27 04:09:11 +01:00
direction . normalize ( ) ;
2013-10-02 22:22:10 +02:00
direction . x = truncateDecimal < float > ( direction . x , 6 ) ;
direction . y = truncateDecimal < float > ( direction . y , 6 ) ;
direction . z = truncateDecimal < float > ( direction . z , 6 ) ;
2013-09-23 19:16:34 +02:00
2011-07-07 00:23:51 +02:00
// trigger update of child particles
positionChildren ( ) ;
rotateChildren ( ) ;
2010-03-27 04:09:11 +01:00
//arrive destination
2013-10-02 22:22:10 +02:00
arriveDestinationDistance = truncateDecimal < float > ( flatPos . dist ( endPos ) , 6 ) ;
2013-10-19 23:12:08 +02:00
if ( this - > particleOwner ! = NULL ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8095 , " LINE: %d arriveDestinationDistance = %f " , __LINE__ , arriveDestinationDistance ) ;
this - > particleOwner - > logParticleInfo ( szBuf ) ;
}
2013-09-23 19:16:34 +02:00
if ( arriveDestinationDistance < 0.5f ) {
2011-07-07 00:23:51 +02:00
fade ( ) ;
2010-03-27 04:09:11 +01:00
model = NULL ;
2011-03-14 00:16:07 +01:00
if ( particleObserver ! = NULL ) {
2010-03-27 04:09:11 +01:00
particleObserver - > update ( this ) ;
2013-02-01 18:25:49 +01:00
particleObserver = NULL ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
if ( nextParticleSystem ! = NULL ) {
2013-09-20 00:04:18 +02:00
nextParticleSystem - > setVisible ( getVisible ( ) ) ;
2010-03-27 04:09:11 +01:00
nextParticleSystem - > setState ( sPlay ) ;
nextParticleSystem - > setPos ( endPos ) ;
}
}
}
ParticleSystem : : update ( ) ;
}
2011-07-07 00:23:51 +02:00
void ProjectileParticleSystem : : rotateChildren ( ) {
//### only on horizontal plane :(
# ifdef USE_STREFLOP
2013-10-02 22:22:10 +02:00
float rotation = truncateDecimal < float > ( streflop : : atan2 ( static_cast < streflop : : Simple > ( direction . x ) , static_cast < streflop : : Simple > ( direction . z ) ) , 6 ) ;
2011-07-07 00:23:51 +02:00
# else
2013-10-02 22:22:10 +02:00
float rotation = truncateDecimal < float > ( atan2 ( direction . x , direction . z ) , 6 ) ;
2011-07-07 00:23:51 +02:00
# endif
2013-10-02 22:22:10 +02:00
rotation = truncateDecimal < float > ( radToDeg ( rotation ) , 6 ) ;
2011-09-01 03:11:23 +02:00
for ( Children : : iterator it = children . begin ( ) ; it ! = children . end ( ) ; + + it )
2011-07-07 00:23:51 +02:00
( * it ) - > setRotation ( rotation ) ;
}
2010-03-27 04:09:11 +01:00
void ProjectileParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
ParticleSystem : : initParticle ( p , particleIndex ) ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
float t = static_cast < float > ( particleIndex ) / emissionRate ;
t = truncateDecimal < float > ( t , 6 ) ;
2011-03-14 00:16:07 +01:00
p - > pos = pos + ( lastPos - pos ) * t ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
p - > lastPos = lastPos ;
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( random . randRange ( - 0.1f , 0.1f ) , random . randRange ( - 0.1f , 0.1f ) ,
2013-09-27 18:15:36 +02:00
random . randRange ( - 0.1f , 0.1f ) ) * speed ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2013-10-02 22:22:10 +02:00
p - > accel = Vec3f ( 0.0f , - gravity , 0.0f ) ;
p - > accel . x = truncateDecimal < float > ( p - > accel . x , 6 ) ;
p - > accel . y = truncateDecimal < float > ( p - > accel . y , 6 ) ;
p - > accel . z = truncateDecimal < float > ( p - > accel . z , 6 ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
updateParticle ( p ) ;
}
void ProjectileParticleSystem : : updateParticle ( Particle * p ) {
2013-10-02 22:22:10 +02:00
float energyRatio = clamp ( static_cast < float > ( p - > energy ) / maxParticleEnergy , 0.f , 1.f ) ;
energyRatio = truncateDecimal < float > ( energyRatio , 6 ) ;
2011-03-14 00:16:07 +01:00
2013-09-27 18:15:36 +02:00
p - > lastPos + = p - > speed ;
2013-10-02 22:22:10 +02:00
p - > lastPos . x = truncateDecimal < float > ( p - > lastPos . x , 6 ) ;
p - > lastPos . y = truncateDecimal < float > ( p - > lastPos . y , 6 ) ;
p - > lastPos . z = truncateDecimal < float > ( p - > lastPos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
p - > pos + = p - > speed ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
p - > speed + = p - > accel ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2011-03-14 00:16:07 +01:00
p - > color = color * energyRatio + colorNoEnergy * ( 1.0f - energyRatio ) ;
2013-09-27 18:15:36 +02:00
p - > size = particleSize * energyRatio + sizeNoEnergy * ( 1.0f - energyRatio ) ;
2013-10-02 22:22:10 +02:00
p - > size = truncateDecimal < float > ( p - > size , 6 ) ;
2010-03-27 04:09:11 +01:00
p - > energy - - ;
}
2013-10-02 22:22:10 +02:00
void ProjectileParticleSystem : : setPath ( Vec3f startPos , Vec3f endPos ) {
2013-10-26 09:02:32 +02:00
startPos . x = truncateDecimal < float > ( startPos . x , 6 ) ;
startPos . y = truncateDecimal < float > ( startPos . y , 6 ) ;
startPos . z = truncateDecimal < float > ( startPos . z , 6 ) ;
endPos . x = truncateDecimal < float > ( endPos . x , 6 ) ;
endPos . y = truncateDecimal < float > ( endPos . y , 6 ) ;
endPos . z = truncateDecimal < float > ( endPos . z , 6 ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
//compute axis
zVector = endPos - startPos ;
2013-10-02 22:22:10 +02:00
zVector . x = truncateDecimal < float > ( zVector . x , 6 ) ;
zVector . y = truncateDecimal < float > ( zVector . y , 6 ) ;
zVector . z = truncateDecimal < float > ( zVector . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2010-03-27 04:09:11 +01:00
zVector . normalize ( ) ;
2013-10-02 22:22:10 +02:00
zVector . x = truncateDecimal < float > ( zVector . x , 6 ) ;
zVector . y = truncateDecimal < float > ( zVector . y , 6 ) ;
zVector . z = truncateDecimal < float > ( zVector . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2013-10-02 22:22:10 +02:00
yVector = Vec3f ( 0.0f , 1.0f , 0.0f ) ;
2010-03-27 04:09:11 +01:00
xVector = zVector . cross ( yVector ) ;
2013-10-02 22:22:10 +02:00
xVector . x = truncateDecimal < float > ( xVector . x , 6 ) ;
xVector . y = truncateDecimal < float > ( xVector . y , 6 ) ;
xVector . z = truncateDecimal < float > ( xVector . z , 6 ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
//apply offset
2013-09-27 06:45:53 +02:00
startPos + = xVector * offset . x ;
2013-10-02 22:22:10 +02:00
startPos . x = truncateDecimal < float > ( startPos . x , 6 ) ;
startPos . y = truncateDecimal < float > ( startPos . y , 6 ) ;
startPos . z = truncateDecimal < float > ( startPos . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2010-03-27 04:09:11 +01:00
startPos + = yVector * offset . y ;
2013-10-02 22:22:10 +02:00
startPos . x = truncateDecimal < float > ( startPos . x , 6 ) ;
startPos . y = truncateDecimal < float > ( startPos . y , 6 ) ;
startPos . z = truncateDecimal < float > ( startPos . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2010-03-27 04:09:11 +01:00
startPos + = zVector * offset . z ;
2013-10-02 22:22:10 +02:00
startPos . x = truncateDecimal < float > ( startPos . x , 6 ) ;
startPos . y = truncateDecimal < float > ( startPos . y , 6 ) ;
startPos . z = truncateDecimal < float > ( startPos . z , 6 ) ;
2010-03-27 04:09:11 +01:00
pos = startPos ;
lastPos = startPos ;
flatPos = startPos ;
//recompute axis
zVector = endPos - startPos ;
2013-10-02 22:22:10 +02:00
zVector . x = truncateDecimal < float > ( zVector . x , 6 ) ;
zVector . y = truncateDecimal < float > ( zVector . y , 6 ) ;
zVector . z = truncateDecimal < float > ( zVector . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2010-03-27 04:09:11 +01:00
zVector . normalize ( ) ;
2013-10-02 22:22:10 +02:00
zVector . x = truncateDecimal < float > ( zVector . x , 6 ) ;
zVector . y = truncateDecimal < float > ( zVector . y , 6 ) ;
zVector . z = truncateDecimal < float > ( zVector . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2013-10-02 22:22:10 +02:00
yVector = Vec3f ( 0.0f , 1.0f , 0.0f ) ;
2010-03-27 04:09:11 +01:00
xVector = zVector . cross ( yVector ) ;
2013-10-02 22:22:10 +02:00
xVector . x = truncateDecimal < float > ( xVector . x , 6 ) ;
xVector . y = truncateDecimal < float > ( xVector . y , 6 ) ;
xVector . z = truncateDecimal < float > ( xVector . z , 6 ) ;
2010-03-27 04:09:11 +01:00
// set members
this - > startPos = startPos ;
this - > endPos = endPos ;
2011-07-07 00:23:51 +02:00
// direction
direction = ( endPos - lastPos ) ;
2013-10-02 22:22:10 +02:00
direction . x = truncateDecimal < float > ( direction . x , 6 ) ;
direction . y = truncateDecimal < float > ( direction . y , 6 ) ;
direction . z = truncateDecimal < float > ( direction . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2011-07-07 00:23:51 +02:00
direction . normalize ( ) ;
2013-10-02 22:22:10 +02:00
direction . x = truncateDecimal < float > ( direction . x , 6 ) ;
direction . y = truncateDecimal < float > ( direction . y , 6 ) ;
direction . z = truncateDecimal < float > ( direction . z , 6 ) ;
2013-09-27 06:45:53 +02:00
2011-07-07 00:23:51 +02:00
rotateChildren ( ) ;
2010-03-27 04:09:11 +01:00
}
ProjectileParticleSystem : : Trajectory ProjectileParticleSystem : : strToTrajectory ( const string & str ) {
2011-03-14 00:16:07 +01:00
if ( str = = " linear " ) {
2010-03-27 04:09:11 +01:00
return tLinear ;
}
2011-03-14 00:16:07 +01:00
else if ( str = = " parabolic " ) {
2010-03-27 04:09:11 +01:00
return tParabolic ;
}
2011-03-14 00:16:07 +01:00
else if ( str = = " spiral " ) {
2010-03-27 04:09:11 +01:00
return tSpiral ;
}
else {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Unknown particle system trajectory: " + str ) ;
2010-03-27 04:09:11 +01:00
}
}
2012-03-14 08:23:41 +01:00
void ProjectileParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * projectileParticleSystemNode = rootNode - > addChild ( " ProjectileParticleSystem " ) ;
AttackParticleSystem : : saveGame ( projectileParticleSystemNode ) ;
// SplashParticleSystem *nextParticleSystem;
if ( nextParticleSystem ! = NULL ) {
nextParticleSystem - > saveGame ( projectileParticleSystemNode ) ;
}
// Vec3f lastPos;
projectileParticleSystemNode - > addAttribute ( " lastPos " , lastPos . getString ( ) , mapTagReplacements ) ;
// Vec3f startPos;
projectileParticleSystemNode - > addAttribute ( " startPos " , startPos . getString ( ) , mapTagReplacements ) ;
// Vec3f endPos;
projectileParticleSystemNode - > addAttribute ( " endPos " , endPos . getString ( ) , mapTagReplacements ) ;
// Vec3f flatPos;
projectileParticleSystemNode - > addAttribute ( " flatPos " , flatPos . getString ( ) , mapTagReplacements ) ;
//
// Vec3f xVector;
projectileParticleSystemNode - > addAttribute ( " xVector " , xVector . getString ( ) , mapTagReplacements ) ;
// Vec3f yVector;
projectileParticleSystemNode - > addAttribute ( " yVector " , yVector . getString ( ) , mapTagReplacements ) ;
// Vec3f zVector;
projectileParticleSystemNode - > addAttribute ( " zVector " , zVector . getString ( ) , mapTagReplacements ) ;
// Trajectory trajectory;
projectileParticleSystemNode - > addAttribute ( " trajectory " , intToStr ( trajectory ) , mapTagReplacements ) ;
// float trajectorySpeed;
2013-10-02 22:22:10 +02:00
projectileParticleSystemNode - > addAttribute ( " trajectorySpeed " , floatToStr ( trajectorySpeed , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// //parabolic
// float trajectoryScale;
2013-10-02 22:22:10 +02:00
projectileParticleSystemNode - > addAttribute ( " trajectoryScale " , floatToStr ( trajectoryScale , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float trajectoryFrequency;
2013-10-02 22:22:10 +02:00
projectileParticleSystemNode - > addAttribute ( " trajectoryFrequency " , floatToStr ( trajectoryFrequency , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
}
void ProjectileParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * projectileParticleSystemNode = rootNode ;
AttackParticleSystem : : loadGame ( projectileParticleSystemNode ) ;
// SplashParticleSystem *nextParticleSystem;
// if(nextParticleSystem != NULL) {
// nextParticleSystem->saveGame(projectileParticleSystemNode);
// }
if ( projectileParticleSystemNode - > hasChild ( " SplashParticleSystem " ) = = true ) {
XmlNode * splashParticleSystemNode = projectileParticleSystemNode - > getChild ( " SplashParticleSystem " ) ;
nextParticleSystem = new SplashParticleSystem ( ) ;
2013-09-23 19:16:34 +02:00
nextParticleSystem - > setParticleOwner ( this - > getParticleOwner ( ) ) ;
2012-03-14 08:23:41 +01:00
nextParticleSystem - > loadGame ( splashParticleSystemNode ) ;
}
// Vec3f lastPos;
2013-10-02 22:22:10 +02:00
lastPos = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " lastPos " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f startPos;
2013-10-02 22:22:10 +02:00
startPos = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " startPos " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f endPos;
2013-10-02 22:22:10 +02:00
endPos = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " endPos " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f flatPos;
2013-10-02 22:22:10 +02:00
flatPos = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " flatPos " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
//
// Vec3f xVector;
2013-10-02 22:22:10 +02:00
xVector = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " xVector " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f yVector;
2013-10-02 22:22:10 +02:00
yVector = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " yVector " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Vec3f zVector;
2013-10-02 22:22:10 +02:00
zVector = Vec3f : : strToVec3 ( projectileParticleSystemNode - > getAttribute ( " zVector " ) - > getValue ( ) ) ;
2012-03-14 08:23:41 +01:00
// Trajectory trajectory;
trajectory = static_cast < Trajectory > ( projectileParticleSystemNode - > getAttribute ( " trajectory " ) - > getIntValue ( ) ) ;
// float trajectorySpeed;
trajectorySpeed = projectileParticleSystemNode - > getAttribute ( " trajectorySpeed " ) - > getFloatValue ( ) ;
// //parabolic
// float trajectoryScale;
trajectoryScale = projectileParticleSystemNode - > getAttribute ( " trajectoryScale " ) - > getFloatValue ( ) ;
// float trajectoryFrequency;
trajectoryFrequency = projectileParticleSystemNode - > getAttribute ( " trajectoryFrequency " ) - > getFloatValue ( ) ;
}
2013-09-23 19:16:34 +02:00
Checksum ProjectileParticleSystem : : getCRC ( ) {
2013-10-18 06:55:29 +02:00
Checksum crcForParticleSystem = AttackParticleSystem : : getCRC ( ) ;
2013-09-23 19:16:34 +02:00
return crcForParticleSystem ;
}
string ProjectileParticleSystem : : toString ( ) const {
2013-10-18 06:55:29 +02:00
string result = AttackParticleSystem : : toString ( ) ;
2013-09-23 19:16:34 +02:00
result + = " \n ProjectileParticleSystem " ;
if ( nextParticleSystem ! = NULL ) {
//result += "\nnextParticleSystem = " + nextParticleSystem->toString() + "\n";
result + = " \n nextParticleSystem = NOT NULL \n " ;
}
result + = " \n lastPos = " + lastPos . getString ( ) ;
result + = " \n startPos = " + startPos . getString ( ) ;
result + = " \n endPos = " + endPos . getString ( ) ;
result + = " \n flatPos = " + flatPos . getString ( ) ;
result + = " \n xVector = " + xVector . getString ( ) ;
result + = " \n yVector = " + yVector . getString ( ) ;
result + = " \n zVector = " + zVector . getString ( ) ;
result + = " \n trajectory = " + intToStr ( trajectory ) ;
2013-10-02 22:22:10 +02:00
result + = " \n trajectorySpeed = " + floatToStr ( trajectorySpeed ) ;
result + = " \n trajectoryScale = " + floatToStr ( trajectoryScale ) ;
result + = " \n trajectoryFrequency = " + floatToStr ( trajectoryFrequency ) ;
2013-09-23 19:16:34 +02:00
2013-10-02 22:22:10 +02:00
result + = " \n arriveDestinationDistance = " + floatToStr ( arriveDestinationDistance ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// SplashParticleSystem
// ===========================================================================
2011-03-14 00:16:07 +01:00
SplashParticleSystem : : SplashParticleSystem ( int particleCount ) :
AttackParticleSystem ( particleCount ) {
2013-09-26 18:37:32 +02:00
setColor ( Vec4f ( 1.0f , 0.3f , 0.0f , 0.8f ) ) ;
2010-03-27 04:09:11 +01:00
setMaxParticleEnergy ( 100 ) ;
setVarParticleEnergy ( 50 ) ;
setParticleSize ( 1.0f ) ;
setSpeed ( 0.003f ) ;
prevParticleSystem = NULL ;
2013-09-23 19:16:34 +02:00
emissionRateFade = 1.0f ;
2010-03-27 04:09:11 +01:00
verticalSpreadA = 1.0f ;
verticalSpreadB = 0.0f ;
horizontalSpreadA = 1.0f ;
horizontalSpreadB = 0.0f ;
2012-09-22 22:13:57 +02:00
startEmissionRate = 0.0f ;
2010-03-27 04:09:11 +01:00
}
SplashParticleSystem : : ~ SplashParticleSystem ( ) {
2011-03-14 00:16:07 +01:00
if ( prevParticleSystem ! = NULL ) {
prevParticleSystem - > nextParticleSystem = NULL ;
2010-03-27 04:09:11 +01:00
}
}
2011-06-10 21:44:34 +02:00
void SplashParticleSystem : : initParticleSystem ( ) {
startEmissionRate = emissionRate ;
}
2011-06-11 02:26:26 +02:00
void SplashParticleSystem : : update ( ) {
2010-03-27 04:09:11 +01:00
ParticleSystem : : update ( ) ;
2011-06-10 21:44:34 +02:00
if ( state ! = sPause ) {
2013-09-23 19:16:34 +02:00
emissionRate - = emissionRateFade ;
2013-10-02 22:22:10 +02:00
emissionRate = truncateDecimal < float > ( emissionRate , 6 ) ;
2013-09-23 19:16:34 +02:00
2013-10-02 22:22:10 +02:00
float t = 1.0f - ( ( emissionRate + startEmissionRate ) / ( startEmissionRate * 2.0f ) ) ;
t = truncateDecimal < float > ( t , 6 ) ;
2011-06-10 21:44:34 +02:00
2011-07-07 00:23:51 +02:00
t = clamp ( t , 0.0f , 1.0f ) ;
setTween ( t , t ) ;
2011-06-10 21:44:34 +02:00
2013-10-19 23:12:08 +02:00
if ( this - > particleOwner ! = NULL ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8095 , " LINE: %d emissionRate = %f " , __LINE__ , emissionRate ) ;
this - > particleOwner - > logParticleInfo ( szBuf ) ;
}
2011-06-10 21:44:34 +02:00
if ( emissionRate < 0.0f ) { //otherwise this system lives forever!
2010-09-25 16:38:00 +02:00
fade ( ) ;
}
2010-03-27 04:09:11 +01:00
}
}
void SplashParticleSystem : : initParticle ( Particle * p , int particleIndex ) {
p - > pos = pos ;
p - > lastPos = p - > pos ;
p - > energy = maxParticleEnergy ;
p - > size = particleSize ;
p - > color = color ;
2014-07-26 13:56:29 +02:00
p - > speedUpRelative = speedUpRelative ;
2011-03-14 00:16:07 +01:00
2013-10-02 22:22:10 +02:00
p - > speed = Vec3f ( horizontalSpreadA * random . randRange ( - 1.0f , 1.0f ) + horizontalSpreadB , verticalSpreadA
2011-03-14 00:16:07 +01:00
* random . randRange ( - 1.0f , 1.0f ) + verticalSpreadB , horizontalSpreadA * random . randRange ( - 1.0f , 1.0f )
+ horizontalSpreadB ) ;
2013-10-26 09:02:32 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
p - > speed . normalize ( ) ;
2013-10-26 09:02:32 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
p - > speed = p - > speed * speed ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2010-03-27 04:09:11 +01:00
2013-10-02 22:22:10 +02:00
p - > accel = Vec3f ( 0.0f , - gravity , 0.0f ) ;
p - > accel . x = truncateDecimal < float > ( p - > accel . x , 6 ) ;
p - > accel . y = truncateDecimal < float > ( p - > accel . y , 6 ) ;
p - > accel . z = truncateDecimal < float > ( p - > accel . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2014-07-26 13:56:29 +02:00
p - > speedUpConstant = Vec3f ( speedUpConstant ) * p - > speed ;
2010-03-27 04:09:11 +01:00
}
void SplashParticleSystem : : updateParticle ( Particle * p ) {
2013-10-02 22:22:10 +02:00
float energyRatio = clamp ( static_cast < float > ( p - > energy ) / maxParticleEnergy , 0.f , 1.f ) ;
2011-03-14 00:16:07 +01:00
2010-03-27 04:09:11 +01:00
p - > lastPos = p - > pos ;
p - > pos = p - > pos + p - > speed ;
2013-10-02 22:22:10 +02:00
p - > pos . x = truncateDecimal < float > ( p - > pos . x , 6 ) ;
p - > pos . y = truncateDecimal < float > ( p - > pos . y , 6 ) ;
p - > pos . z = truncateDecimal < float > ( p - > pos . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2014-07-26 13:56:29 +02:00
p - > speed + = p - > speedUpConstant ;
p - > speed = p - > speed * ( 1 + p - > speedUpRelative ) ;
2010-03-27 04:09:11 +01:00
p - > speed = p - > speed + p - > accel ;
2013-10-02 22:22:10 +02:00
p - > speed . x = truncateDecimal < float > ( p - > speed . x , 6 ) ;
p - > speed . y = truncateDecimal < float > ( p - > speed . y , 6 ) ;
p - > speed . z = truncateDecimal < float > ( p - > speed . z , 6 ) ;
2013-09-27 18:15:36 +02:00
2010-03-27 04:09:11 +01:00
p - > energy - - ;
2011-03-14 00:16:07 +01:00
p - > color = color * energyRatio + colorNoEnergy * ( 1.0f - energyRatio ) ;
p - > size = particleSize * energyRatio + sizeNoEnergy * ( 1.0f - energyRatio ) ;
2013-10-02 22:22:10 +02:00
p - > size = truncateDecimal < float > ( p - > size , 6 ) ;
2010-03-27 04:09:11 +01:00
}
2012-03-14 08:23:41 +01:00
void SplashParticleSystem : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * splashParticleSystemNode = rootNode - > addChild ( " SplashParticleSystem " ) ;
AttackParticleSystem : : saveGame ( splashParticleSystemNode ) ;
// ProjectileParticleSystem *prevParticleSystem;
if ( prevParticleSystem ! = NULL ) {
prevParticleSystem - > saveGame ( splashParticleSystemNode ) ;
}
// float emissionRateFade;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " emissionRateFade " , floatToStr ( emissionRateFade , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float verticalSpreadA;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " verticalSpreadA " , floatToStr ( verticalSpreadA , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float verticalSpreadB;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " verticalSpreadB " , floatToStr ( verticalSpreadB , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float horizontalSpreadA;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " horizontalSpreadA " , floatToStr ( horizontalSpreadA , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
// float horizontalSpreadB;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " horizontalSpreadB " , floatToStr ( horizontalSpreadB , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
//
// float startEmissionRate;
2013-10-02 22:22:10 +02:00
splashParticleSystemNode - > addAttribute ( " startEmissionRate " , floatToStr ( startEmissionRate , 6 ) , mapTagReplacements ) ;
2012-03-14 08:23:41 +01:00
}
void SplashParticleSystem : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * splashParticleSystemNode = rootNode ;
AttackParticleSystem : : loadGame ( splashParticleSystemNode ) ;
// ProjectileParticleSystem *prevParticleSystem;
// if(nextParticleSystem != NULL) {
// nextParticleSystem->saveGame(projectileParticleSystemNode);
// }
if ( splashParticleSystemNode - > hasChild ( " ProjectileParticleSystem " ) = = true ) {
XmlNode * projectileParticleSystemNode = splashParticleSystemNode - > getChild ( " ProjectileParticleSystem " ) ;
prevParticleSystem = new ProjectileParticleSystem ( ) ;
2013-09-23 19:16:34 +02:00
prevParticleSystem - > setParticleOwner ( this - > getParticleOwner ( ) ) ;
2012-03-14 08:23:41 +01:00
prevParticleSystem - > loadGame ( projectileParticleSystemNode ) ;
}
// float emissionRateFade;
emissionRateFade = splashParticleSystemNode - > getAttribute ( " emissionRateFade " ) - > getFloatValue ( ) ;
// float verticalSpreadA;
verticalSpreadA = splashParticleSystemNode - > getAttribute ( " verticalSpreadA " ) - > getFloatValue ( ) ;
// float verticalSpreadB;
verticalSpreadB = splashParticleSystemNode - > getAttribute ( " verticalSpreadB " ) - > getFloatValue ( ) ;
// float horizontalSpreadA;
horizontalSpreadA = splashParticleSystemNode - > getAttribute ( " horizontalSpreadA " ) - > getFloatValue ( ) ;
// float horizontalSpreadB;
horizontalSpreadB = splashParticleSystemNode - > getAttribute ( " horizontalSpreadB " ) - > getFloatValue ( ) ;
// float startEmissionRate;
startEmissionRate = splashParticleSystemNode - > getAttribute ( " startEmissionRate " ) - > getFloatValue ( ) ;
}
2013-09-23 19:16:34 +02:00
Checksum SplashParticleSystem : : getCRC ( ) {
2013-10-18 06:55:29 +02:00
Checksum crcForParticleSystem = AttackParticleSystem : : getCRC ( ) ;
2013-09-23 19:16:34 +02:00
return crcForParticleSystem ;
}
string SplashParticleSystem : : toString ( ) const {
2013-10-18 06:55:29 +02:00
string result = AttackParticleSystem : : toString ( ) ;
2013-09-23 19:16:34 +02:00
result + = " \n SplashParticleSystem " ;
if ( prevParticleSystem ! = NULL ) {
//result += "\nprevParticleSystem = " + prevParticleSystem->toString() + "\n";
result + = " \n prevParticleSystem = NOT NULL \n " ;
}
2013-10-02 22:22:10 +02:00
result + = " \n emissionRateFade = " + floatToStr ( emissionRateFade ) ;
result + = " \n verticalSpreadA = " + floatToStr ( verticalSpreadA ) ;
result + = " \n verticalSpreadB = " + floatToStr ( verticalSpreadB ) ;
result + = " \n horizontalSpreadA = " + floatToStr ( horizontalSpreadA ) ;
result + = " \n horizontalSpreadB = " + floatToStr ( horizontalSpreadB ) ;
result + = " \n startEmissionRate = " + floatToStr ( startEmissionRate ) ;
2013-09-23 19:16:34 +02:00
return result ;
}
2010-03-27 04:09:11 +01:00
// ===========================================================================
// ParticleManager
// ===========================================================================
2011-12-02 23:04:02 +01:00
ParticleManager : : ParticleManager ( ) {
}
ParticleManager : : ~ ParticleManager ( ) {
2010-03-27 04:09:11 +01:00
end ( ) ;
}
void ParticleManager : : render ( ParticleRenderer * pr , ModelRenderer * mr ) const {
2011-03-14 00:16:07 +01:00
for ( unsigned int i = 0 ; i < particleSystems . size ( ) ; i + + ) {
ParticleSystem * ps = particleSystems [ i ] ;
if ( ps ! = NULL & & ps - > getVisible ( ) ) {
2010-09-06 19:52:33 +02:00
ps - > render ( pr , mr ) ;
2010-03-27 04:09:11 +01:00
}
}
}
2011-03-14 00:16:07 +01:00
bool ParticleManager : : hasActiveParticleSystem ( ParticleSystem : : ParticleSystemType type ) const {
bool result = false ;
2011-01-29 04:53:05 +01:00
2011-09-01 03:11:23 +02:00
//size_t particleSystemCount= particleSystems.size();
//int currentParticleCount= 0;
2011-01-29 04:53:05 +01:00
2013-05-17 05:59:34 +02:00
//vector<ParticleSystem *> cleanupParticleSystemsList;
2011-03-14 00:16:07 +01:00
for ( unsigned int i = 0 ; i < particleSystems . size ( ) ; i + + ) {
ParticleSystem * ps = particleSystems [ i ] ;
if ( ps ! = NULL ) {
2011-09-01 03:11:23 +02:00
//currentParticleCount+= ps->getAliveParticleCount();
2011-03-14 00:16:07 +01:00
bool showParticle = true ;
2013-10-03 22:04:55 +02:00
if ( dynamic_cast < UnitParticleSystem * > ( ps ) ! = NULL | |
dynamic_cast < FireParticleSystem * > ( ps ) ! = NULL ) {
2011-03-14 00:16:07 +01:00
showParticle = ps - > getVisible ( ) | | ( ps - > getState ( ) = = ParticleSystem : : sFade ) ;
2011-01-29 04:53:05 +01:00
}
2011-03-14 00:16:07 +01:00
if ( showParticle = = true ) {
2011-01-29 04:53:05 +01:00
//printf("Looking for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i);
2011-03-14 00:16:07 +01:00
if ( type = = ParticleSystem : : pst_All | | type = = ps - > getParticleSystemType ( ) ) {
2011-01-29 04:53:05 +01:00
//printf("FOUND particle system type match for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i);
2011-03-14 00:16:07 +01:00
result = true ;
2011-01-29 04:53:05 +01:00
break ;
}
}
}
}
return result ;
}
2011-03-14 00:16:07 +01:00
void ParticleManager : : update ( int renderFps ) {
2010-08-24 03:21:34 +02:00
Chrono chrono ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled ) chrono . start ( ) ;
2010-03-27 04:09:11 +01:00
2011-03-14 00:16:07 +01:00
size_t particleSystemCount = particleSystems . size ( ) ;
int currentParticleCount = 0 ;
2010-09-06 19:52:33 +02:00
vector < ParticleSystem * > cleanupParticleSystemsList ;
2011-03-14 00:16:07 +01:00
for ( unsigned int i = 0 ; i < particleSystems . size ( ) ; i + + ) {
ParticleSystem * ps = particleSystems [ i ] ;
2011-11-25 23:38:25 +01:00
if ( ps ! = NULL & & validateParticleSystemStillExists ( ps ) = = true ) {
2011-03-14 00:16:07 +01:00
currentParticleCount + = ps - > getAliveParticleCount ( ) ;
bool showParticle = true ;
2013-09-23 19:16:34 +02:00
if ( dynamic_cast < UnitParticleSystem * > ( ps ) ! = NULL | |
dynamic_cast < FireParticleSystem * > ( ps ) ! = NULL ) {
showParticle = ps - > getVisible ( ) | | ( ps - > getState ( ) = = ParticleSystem : : sFade ) ;
2010-08-26 21:01:44 +02:00
}
2011-03-14 00:16:07 +01:00
if ( showParticle = = true ) {
2010-08-26 21:01:44 +02:00
ps - > update ( ) ;
2013-09-23 19:16:34 +02:00
if ( ps - > isEmpty ( ) & & ps - > getState ( ) = = ParticleSystem : : sFade ) {
2010-09-06 19:52:33 +02:00
cleanupParticleSystemsList . push_back ( ps ) ;
2010-08-26 21:01:44 +02:00
}
2010-08-24 04:49:55 +02:00
}
2010-08-24 22:19:30 +02:00
}
2010-03-27 04:09:11 +01:00
}
2010-09-06 19:52:33 +02:00
//particleSystems.remove(NULL);
cleanupParticleSystems ( cleanupParticleSystemsList ) ;
2010-08-24 03:21:34 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 )
2011-03-14 00:16:07 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, currentParticleCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) , particleSystemCount , currentParticleCount ) ;
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
bool ParticleManager : : validateParticleSystemStillExists ( ParticleSystem * particleSystem ) const {
int index = findParticleSystems ( particleSystem , this - > particleSystems ) ;
2010-09-07 19:30:13 +02:00
return ( index > = 0 ) ;
}
2013-09-24 05:44:15 +02:00
void ParticleManager : : removeParticleSystemsForParticleOwner ( ParticleOwner * particleOwner ) {
if ( particleOwner ! = NULL & & particleSystems . empty ( ) = = false ) {
vector < ParticleSystem * > cleanupParticleSystemsList ;
for ( unsigned int index = 0 ; index < particleSystems . size ( ) ; + + index ) {
ParticleSystem * ps = particleSystems [ index ] ;
if ( ps ! = NULL & & ps - > getParticleOwner ( ) = = particleOwner ) {
cleanupParticleSystemsList . push_back ( ps ) ;
}
}
if ( cleanupParticleSystemsList . empty ( ) = = false ) {
cleanupParticleSystems ( cleanupParticleSystemsList ) ;
}
}
}
2011-03-14 00:16:07 +01:00
int ParticleManager : : findParticleSystems ( ParticleSystem * psFind , const vector < ParticleSystem * > & particleSystems ) const {
int result = - 1 ;
for ( unsigned int i = 0 ; i < particleSystems . size ( ) ; i + + ) {
ParticleSystem * ps = particleSystems [ i ] ;
if ( ps ! = NULL & & psFind ! = NULL & & psFind = = ps ) {
result = i ;
2010-09-06 19:52:33 +02:00
break ;
}
}
return result ;
}
2011-07-06 07:16:25 +02:00
void ParticleManager : : cleanupParticleSystems ( ParticleSystem * ps ) {
2010-09-06 19:52:33 +02:00
2011-03-14 00:16:07 +01:00
int index = findParticleSystems ( ps , this - > particleSystems ) ;
2011-07-06 07:16:25 +02:00
if ( ps ! = NULL & & index > = 0 ) {
// printf("-- Delete cleanupParticleSystems [%p]\n",ps);
// static map<void *,int> deleteList;
// if(deleteList.find(ps) != deleteList.end()) {
// assert(deleteList.find(ps) == deleteList.end());
// }
// deleteList[ps]++;
2013-09-24 05:44:15 +02:00
// This code causes segfault on game end, no need to fade, just delete
//if(ps->getState() != ParticleSystem::sFade) {
// ps->fade();
//}
2013-09-23 19:16:34 +02:00
if ( ps ! = NULL ) {
ps - > callParticleOwnerEnd ( ps ) ;
}
2010-09-06 19:52:33 +02:00
delete ps ;
this - > particleSystems . erase ( this - > particleSystems . begin ( ) + index ) ;
}
}
2013-09-23 19:16:34 +02:00
void ParticleManager : : cleanupParticleSystems ( vector < ParticleSystem * > & cleanupParticleSystemsList ) {
if ( cleanupParticleSystemsList . empty ( ) = = false ) {
2013-11-03 02:51:20 +01:00
for ( int i = ( int ) cleanupParticleSystemsList . size ( ) - 1 ; i > = 0 ; i - - ) {
2013-09-23 19:16:34 +02:00
ParticleSystem * ps = cleanupParticleSystemsList [ i ] ;
cleanupParticleSystems ( ps ) ;
}
2010-09-06 19:52:33 +02:00
2013-09-23 19:16:34 +02:00
cleanupParticleSystemsList . clear ( ) ;
2010-09-06 19:52:33 +02:00
}
}
2013-09-23 19:16:34 +02:00
void ParticleManager : : cleanupUnitParticleSystems ( vector < UnitParticleSystem * > & cleanupParticleSystemsList ) {
if ( cleanupParticleSystemsList . empty ( ) = = false ) {
2013-11-03 02:51:20 +01:00
for ( int i = ( int ) cleanupParticleSystemsList . size ( ) - 1 ; i > = 0 ; i - - ) {
2013-09-23 19:16:34 +02:00
ParticleSystem * ps = cleanupParticleSystemsList [ i ] ;
cleanupParticleSystems ( ps ) ;
}
cleanupParticleSystemsList . clear ( ) ;
2010-09-06 19:52:33 +02:00
}
}
2011-03-14 00:16:07 +01:00
void ParticleManager : : manage ( ParticleSystem * ps ) {
2011-07-07 00:23:51 +02:00
assert ( ( std : : find ( particleSystems . begin ( ) , particleSystems . end ( ) , ps ) = = particleSystems . end ( ) ) & & " particle cannot be added twice " ) ;
2010-03-27 04:09:11 +01:00
particleSystems . push_back ( ps ) ;
2013-09-23 19:16:34 +02:00
for ( int i = ps - > getChildCount ( ) - 1 ; i > = 0 ; i - - ) {
2011-07-07 00:23:51 +02:00
manage ( ps - > getChild ( i ) ) ;
2013-09-23 19:16:34 +02:00
}
2010-03-27 04:09:11 +01:00
}
2011-03-14 00:16:07 +01:00
void ParticleManager : : end ( ) {
while ( particleSystems . empty ( ) = = false ) {
2011-07-06 07:16:25 +02:00
ParticleSystem * ps = particleSystems . back ( ) ;
// printf("-- Delete end() [%p]\n",ps);
// static map<void *,int> deleteList;
// if(deleteList.find(ps) != deleteList.end()) {
// assert(deleteList.find(ps) == deleteList.end());
// }
// deleteList[ps]++;
2013-09-23 19:16:34 +02:00
if ( ps ! = NULL ) {
ps - > callParticleOwnerEnd ( ps ) ;
}
2011-07-06 07:16:25 +02:00
delete ps ;
2010-09-06 19:52:33 +02:00
particleSystems . pop_back ( ) ;
2010-03-27 04:09:11 +01:00
}
}
2011-03-14 00:16:07 +01:00
}
} //end namespace