- merged in willvarfar's particle patch

This commit is contained in:
Mark Vejvoda
2011-07-06 22:23:51 +00:00
parent 9ef8c82441
commit 1b2d4fddea
19 changed files with 624 additions and 218 deletions

View File

@@ -1216,7 +1216,7 @@ void MainWindow::loadParticle(string path) {
std::map<string,vector<pair<string, string> > > loadedFileList; std::map<string,vector<pair<string, string> > > loadedFileList;
UnitParticleSystemType *unitParticleSystemType = new UnitParticleSystemType(); UnitParticleSystemType *unitParticleSystemType = new UnitParticleSystemType();
unitParticleSystemType->load(dir, dir + folderDelimiter + particlePath, unitParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath, //### if we knew which particle it was, we could be more accurate
renderer,loadedFileList,"g3dviewer",""); renderer,loadedFileList,"g3dviewer","");
unitParticleSystemTypes.push_back(unitParticleSystemType); unitParticleSystemTypes.push_back(unitParticleSystemType);
@@ -1313,7 +1313,7 @@ void MainWindow::loadProjectileParticle(string path) {
std::map<string,vector<pair<string, string> > > loadedFileList; std::map<string,vector<pair<string, string> > > loadedFileList;
ParticleSystemTypeProjectile *projectileParticleSystemType= new ParticleSystemTypeProjectile(); ParticleSystemTypeProjectile *projectileParticleSystemType= new ParticleSystemTypeProjectile();
projectileParticleSystemType->load(dir, projectileParticleSystemType->load(NULL, dir, //### we don't know if there are overrides in the unit XML
dir + folderDelimiter + particlePath,renderer, loadedFileList, dir + folderDelimiter + particlePath,renderer, loadedFileList,
"g3dviewer",""); "g3dviewer","");
@@ -1416,7 +1416,7 @@ void MainWindow::loadSplashParticle(string path) { // uses ParticleSystemTypeSp
std::map<string,vector<pair<string, string> > > loadedFileList; std::map<string,vector<pair<string, string> > > loadedFileList;
ParticleSystemTypeSplash *splashParticleSystemType= new ParticleSystemTypeSplash(); ParticleSystemTypeSplash *splashParticleSystemType= new ParticleSystemTypeSplash();
splashParticleSystemType->load(dir, dir + folderDelimiter + particlePath,renderer, splashParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath,renderer, //### we don't know if there are overrides in the unit XML
loadedFileList,"g3dviewer",""); // <---- only that must be splash... loadedFileList,"g3dviewer",""); // <---- only that must be splash...
// std::cout << "Values loaded, about to read..." << std::endl; // std::cout << "Values loaded, about to read..." << std::endl;

View File

@@ -10,6 +10,7 @@
// ============================================================== // ==============================================================
#include "particle_type.h" #include "particle_type.h"
#include "unit_particle_type.h"
#include "util.h" #include "util.h"
#include "core_data.h" #include "core_data.h"
@@ -57,11 +58,14 @@ ParticleSystemType::~ParticleSystemType() {
memoryObjectList[this]--; memoryObjectList[this]--;
assert(memoryObjectList[this] == 0); assert(memoryObjectList[this] == 0);
} }
for(Children::iterator it = children.begin(); it != children.end(); it++)
delete *it;
} }
void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) { string parentLoader, string techtreePath) {
//texture //texture
const XmlNode *textureNode= particleSystemNode->getChild("texture"); const XmlNode *textureNode= particleSystemNode->getChild("texture");
bool textureEnabled= textureNode->getAttribute("value")->getBoolValue(); bool textureEnabled= textureNode->getAttribute("value")->getBoolValue();
@@ -97,6 +101,12 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
model->load(path, false, &loadedFileList, &parentLoader); model->load(path, false, &loadedFileList, &parentLoader);
loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue())); loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue()));
if(modelNode->hasChild("cycles")) {
modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue();
if(modelCycle < 0.0)
throw runtime_error("negative model cycle value is bad");
}
} }
} }
else { else {
@@ -178,9 +188,35 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
else { else {
mode="normal"; mode="normal";
} }
// child particles
if(particleSystemNode->hasChild("child-particles")) {
const XmlNode *childrenNode= particleSystemNode->getChild("child-particles");
if(childrenNode->getAttribute("value")->getBoolValue()) {
for(int i = 0; i < childrenNode->getChildCount(); ++i) {
const XmlNode *particleFileNode= childrenNode->getChild("particle-file",i);
string path= particleFileNode->getAttribute("path")->getRestrictedValue();
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
string childPath= dir;
endPathWithSlash(childPath);
childPath += path;
string childDir = extractDirectoryPathFromFile(childPath);
unitParticleSystemType->load(particleFileNode,childDir,childPath,renderer,loadedFileList,parentLoader,techtreePath);
loadedFileList[childPath].push_back(make_pair(parentLoader,path));
children.push_back(unitParticleSystemType);
}
}
}
} }
void ParticleSystemType::setValues(AttackParticleSystem *ats){ void ParticleSystemType::setValues(AttackParticleSystem *ats){
// add instances of all children; some settings will cascade to all children
for(Children::iterator i=children.begin(); i!=children.end(); i++){
UnitParticleSystem *child = new UnitParticleSystem();
(*i)->setValues(child);
ats->addChild(child);
child->setState(ParticleSystem::sPlay);
}
ats->setTexture(texture); ats->setTexture(texture);
ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive)); ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive));
ats->setOffset(offset); ats->setOffset(offset);
@@ -194,6 +230,7 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){
ats->setMaxParticleEnergy(energyMax); ats->setMaxParticleEnergy(energyMax);
ats->setVarParticleEnergy(energyVar); ats->setVarParticleEnergy(energyVar);
ats->setModel(model); ats->setModel(model);
ats->setModelCycle(modelCycle);
ats->setTeamcolorNoEnergy(teamcolorNoEnergy); ats->setTeamcolorNoEnergy(teamcolorNoEnergy);
ats->setTeamcolorEnergy(teamcolorEnergy); ats->setTeamcolorEnergy(teamcolorEnergy);
ats->setAlternations(alternations); ats->setAlternations(alternations);
@@ -204,7 +241,7 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){
// class ParticleSystemTypeProjectile // class ParticleSystemTypeProjectile
// =========================================================== // ===========================================================
void ParticleSystemTypeProjectile::load(const string &dir, const string &path, void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const string &dir, const string &path,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) { string parentLoader, string techtreePath) {
@@ -217,6 +254,12 @@ void ParticleSystemTypeProjectile::load(const string &dir, const string &path,
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader)); loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
const XmlNode *particleSystemNode= xmlTree.getRootNode(); const XmlNode *particleSystemNode= xmlTree.getRootNode();
if(particleFileNode){
// immediate children in the particleFileNode will override the particleSystemNode
particleFileNode->setSuper(particleSystemNode);
particleSystemNode= particleFileNode;
}
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath); ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath);
@@ -271,7 +314,7 @@ ProjectileParticleSystem *ParticleSystemTypeProjectile::create() {
// class ParticleSystemTypeSplash // class ParticleSystemTypeSplash
// =========================================================== // ===========================================================
void ParticleSystemTypeSplash::load(const string &dir, const string &path, void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const string &dir, const string &path,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) { string parentLoader, string techtreePath) {
@@ -285,6 +328,12 @@ void ParticleSystemTypeSplash::load(const string &dir, const string &path,
const XmlNode *particleSystemNode= xmlTree.getRootNode(); const XmlNode *particleSystemNode= xmlTree.getRootNode();
if(particleFileNode){
// immediate children in the particleFileNode will override the particleSystemNode
particleFileNode->setSuper(particleSystemNode);
particleSystemNode= particleFileNode;
}
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath); ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath);
//emission rate fade //emission rate fade

View File

@@ -13,6 +13,7 @@
#define _GLEST_GAME_PARTICLETYPE_H_ #define _GLEST_GAME_PARTICLETYPE_H_
#include <string> #include <string>
#include <list>
#include "particle.h" #include "particle.h"
#include "factory.h" #include "factory.h"
@@ -28,6 +29,7 @@ using namespace Shared::Graphics;
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
using Shared::Graphics::ParticleSystem; using Shared::Graphics::ParticleSystem;
using Shared::Graphics::UnitParticleSystem;
using Shared::Graphics::AttackParticleSystem; using Shared::Graphics::AttackParticleSystem;
using Shared::Graphics::ProjectileParticleSystem; using Shared::Graphics::ProjectileParticleSystem;
using Shared::Graphics::SplashParticleSystem; using Shared::Graphics::SplashParticleSystem;
@@ -38,6 +40,8 @@ using Shared::Graphics::Model;
using Shared::Util::MultiFactory; using Shared::Util::MultiFactory;
using Shared::Xml::XmlNode; using Shared::Xml::XmlNode;
class UnitParticleSystemType;
// =========================================================== // ===========================================================
// class ParticleSystemType // class ParticleSystemType
// //
@@ -49,6 +53,7 @@ protected:
string type; string type;
Texture2D *texture; Texture2D *texture;
Model *model; Model *model;
float modelCycle;
string primitive; string primitive;
Vec3f offset; Vec3f offset;
Vec4f color; Vec4f color;
@@ -64,6 +69,8 @@ protected:
bool teamcolorNoEnergy; bool teamcolorNoEnergy;
bool teamcolorEnergy; bool teamcolorEnergy;
int alternations; int alternations;
typedef std::list<UnitParticleSystemType*> Children;
Children children;
bool minmaxEnabled; bool minmaxEnabled;
int minHp; int minHp;
@@ -72,8 +79,7 @@ protected:
public: public:
ParticleSystemType(); ParticleSystemType();
~ParticleSystemType(); virtual ~ParticleSystemType();
void load(const XmlNode *particleSystemNode, const string &dir, void load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath); string parentLoader, string techtreePath);
@@ -107,7 +113,7 @@ private:
float trajectoryFrequency; float trajectoryFrequency;
public: public:
void load(const string &dir, const string &path, void load(const XmlNode *particleFileNode, const string &dir, const string &path,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath); string parentLoader, string techtreePath);
ProjectileParticleSystem *create(); ProjectileParticleSystem *create();
@@ -120,7 +126,7 @@ public:
class ParticleSystemTypeSplash: public ParticleSystemType { class ParticleSystemTypeSplash: public ParticleSystemType {
public: public:
void load(const string &dir, const string &path, void load(const XmlNode *particleFileNode, const string &dir, const string &path,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath); string parentLoader, string techtreePath);
SplashParticleSystem *create(); SplashParticleSystem *create();

View File

@@ -16,12 +16,14 @@
#include "xml_parser.h" #include "xml_parser.h"
#include "config.h" #include "config.h"
#include "game_constants.h" #include "game_constants.h"
#include "platform_common.h"
#include "leak_dumper.h" #include "leak_dumper.h"
using namespace Shared::Xml; using namespace Shared::Xml;
using namespace Shared::Graphics; using namespace Shared::Graphics;
using namespace Shared::Util; using namespace Shared::Util;
using namespace Shared::PlatformCommon;
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
@@ -32,21 +34,63 @@ namespace Glest{ namespace Game{
void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) { string parentLoader, string techtreePath) {
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,
parentLoader,techtreePath); parentLoader,techtreePath);
//shape
angle= 0.0f;
if(particleSystemNode->hasChild("shape")){
const XmlNode *shapeNode= particleSystemNode->getChild("shape");
shape= UnitParticleSystem::strToShape(shapeNode->getAttribute("value")->getRestrictedValue());
if(shape == UnitParticleSystem::sConical){
angle= shapeNode->getChild("angle")->getAttribute("value")->getFloatValue();
}
} else {
shape = UnitParticleSystem::sLinear;
}
if(shape != UnitParticleSystem::sSpherical){
//direction
const XmlNode *directionNode= particleSystemNode->getChild("direction");
direction.x= directionNode->getAttribute("x")->getFloatValue();
direction.y= directionNode->getAttribute("y")->getFloatValue();
direction.z= directionNode->getAttribute("z")->getFloatValue();
if((shape == UnitParticleSystem::sConical) && (0.0 == direction.length()))
throw runtime_error("direction cannot be zero");
// ought to warn about 0 directions generally
}
//emission rate fade
if(particleSystemNode->hasChild("emission-rate-fade")){
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
} else {
emissionRateFade = 0;
}
//radius //radius
const XmlNode *radiusNode= particleSystemNode->getChild("radius"); const XmlNode *radiusNode= particleSystemNode->getChild("radius");
radius= radiusNode->getAttribute("value")->getFloatValue(); radius= radiusNode->getAttribute("value")->getFloatValue();
// min radius
if(particleSystemNode->hasChild("min-radius")){
const XmlNode *minRadiusNode= particleSystemNode->getChild("min-radius");
minRadius= minRadiusNode->getAttribute("value")->getFloatValue();
if(minRadius > radius)
throw runtime_error("min-radius cannot be bigger than radius");
} else {
minRadius = 0;
}
if((minRadius == 0) && (shape == UnitParticleSystem::sConical)) {
minRadius = 0.001; // fudge it so we aren't generating particles that are exactly centred
if(minRadius > radius)
radius = minRadius;
}
//relative //relative
const XmlNode *relativeNode= particleSystemNode->getChild("relative"); const XmlNode *relativeNode= particleSystemNode->getChild("relative");
relative= relativeNode->getAttribute("value")->getBoolValue(); relative= relativeNode->getAttribute("value")->getBoolValue();
//direction
const XmlNode *directionNode= particleSystemNode->getChild("direction");
direction.x= directionNode->getAttribute("x")->getFloatValue();
direction.y= directionNode->getAttribute("y")->getFloatValue();
direction.z= directionNode->getAttribute("z")->getFloatValue();
//relativeDirection //relativeDirection
if(particleSystemNode->hasChild("relativeDirection")){ if(particleSystemNode->hasChild("relativeDirection")){
@@ -93,15 +137,49 @@ void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const strin
radiusBasedStartenergy= true; radiusBasedStartenergy= true;
} }
//fixed //fixed
const XmlNode *fixedNode= particleSystemNode->getChild("fixed"); const XmlNode *fixedNode= particleSystemNode->getChild("fixed");
fixed= fixedNode->getAttribute("value")->getBoolValue(); fixed= fixedNode->getAttribute("value")->getBoolValue();
// delay
if(particleSystemNode->hasChild("delay")) {
const XmlNode* delayNode = particleSystemNode->getChild("delay");
const float delay_secs = delayNode->getAttribute("value")->getFloatValue();
if(delay_secs < 0)
throw runtime_error("particle effect delay cannot be negative");
delay = delay_secs * GameConstants::updateFps;
} else{
delay= 0;
}
// lifetime
if(particleSystemNode->hasChild("lifetime")) {
const XmlNode* lifetimeNode = particleSystemNode->getChild("lifetime");
const float lifetime_secs = lifetimeNode->getAttribute("value")->getFloatValue();
if(lifetime_secs < 0 && lifetime_secs != -1)
throw runtime_error("particle effect lifetime cannot be negative (-1 means inherited from parent particle)");
lifetime = lifetime_secs * GameConstants::updateFps;
} else{
lifetime= -1; //default
}
} }
const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
// whilst we extend ParticleSystemType we don't use ParticleSystemType::setValues()
// add instances of all children; some settings will cascade to all children
for(Children::iterator i=children.begin(); i!=children.end(); i++){
UnitParticleSystem *child = new UnitParticleSystem();
(*i)->setValues(child);
ups->addChild(child);
}
// set values
ups->setModel(model);
ups->setModelCycle(modelCycle);
ups->setTexture(texture); ups->setTexture(texture);
ups->setPrimitive(UnitParticleSystem::strToPrimitive(primitive)); ups->setPrimitive(UnitParticleSystem::strToPrimitive(primitive));
ups->setOffset(offset); ups->setOffset(offset);
ups->setShape(shape);
ups->setAngle(angle);
ups->setDirection(direction); ups->setDirection(direction);
ups->setColor(color); ups->setColor(color);
ups->setColorNoEnergy(colorNoEnergy); ups->setColorNoEnergy(colorNoEnergy);
@@ -115,6 +193,9 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
ups->setFixed(fixed); ups->setFixed(fixed);
ups->setRelative(relative); ups->setRelative(relative);
ups->setRelativeDirection(relativeDirection); ups->setRelativeDirection(relativeDirection);
ups->setDelay(delay);
ups->setLifetime(lifetime);
ups->setEmissionRateFade(emissionRateFade);
ups->setTeamcolorNoEnergy(teamcolorNoEnergy); ups->setTeamcolorNoEnergy(teamcolorNoEnergy);
ups->setTeamcolorEnergy(teamcolorEnergy); ups->setTeamcolorEnergy(teamcolorEnergy);
ups->setAlternations(alternations); ups->setAlternations(alternations);
@@ -123,6 +204,7 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
ups->setIsVisibleAtDay(isVisibleAtDay); ups->setIsVisibleAtDay(isVisibleAtDay);
ups->setStaticParticleCount(staticParticleCount); ups->setStaticParticleCount(staticParticleCount);
ups->setRadius(radius); ups->setRadius(radius);
ups->setMinRadius(minRadius);
ups->setBlendMode(ParticleSystem::strToBlendMode(mode)); ups->setBlendMode(ParticleSystem::strToBlendMode(mode));
ups->setRadiusBasedStartenergy(radiusBasedStartenergy); ups->setRadiusBasedStartenergy(radiusBasedStartenergy);
//prepare system for given staticParticleCount //prepare system for given staticParticleCount
@@ -137,7 +219,7 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
} }
} }
void UnitParticleSystemType::load(const string &dir, const string &path, void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) { string parentLoader, string techtreePath) {
@@ -150,6 +232,12 @@ void UnitParticleSystemType::load(const string &dir, const string &path,
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader)); loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
const XmlNode *particleSystemNode= xmlTree.getRootNode(); const XmlNode *particleSystemNode= xmlTree.getRootNode();
if(particleFileNode){
// immediate children in the particleFileNode will override the particleSystemNode
particleFileNode->setSuper(particleSystemNode);
particleSystemNode= particleFileNode;
}
UnitParticleSystemType::load(particleSystemNode, dir, renderer, UnitParticleSystemType::load(particleSystemNode, dir, renderer,
loadedFileList, parentLoader, techtreePath); loadedFileList, parentLoader, techtreePath);
} }

View File

@@ -13,6 +13,7 @@
#define _GLEST_GAME_UNITPARTICLETYPE_H_ #define _GLEST_GAME_UNITPARTICLETYPE_H_
#include <string> #include <string>
#include <list>
#include "particle.h" #include "particle.h"
#include "factory.h" #include "factory.h"
@@ -28,6 +29,7 @@ using namespace Shared::Graphics;
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
using Shared::Graphics::ParticleManager;
using Shared::Graphics::ParticleSystem; using Shared::Graphics::ParticleSystem;
using Shared::Graphics::UnitParticleSystem; using Shared::Graphics::UnitParticleSystem;
using Shared::Graphics::Texture2D; using Shared::Graphics::Texture2D;
@@ -44,8 +46,11 @@ using Shared::Xml::XmlNode;
class UnitParticleSystemType: public ParticleSystemType { class UnitParticleSystemType: public ParticleSystemType {
protected: protected:
UnitParticleSystem::Shape shape;
float angle;
float radius; float radius;
float minRadius;
float emissionRateFade;
Vec3f direction; Vec3f direction;
bool relative; bool relative;
bool relativeDirection; bool relativeDirection;
@@ -54,12 +59,14 @@ protected:
bool isVisibleAtNight; bool isVisibleAtNight;
bool isVisibleAtDay; bool isVisibleAtDay;
bool radiusBasedStartenergy; bool radiusBasedStartenergy;
int delay;
int lifetime;
public: public:
void load(const XmlNode *particleSystemNode, const string &dir, void load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *newTexture, std::map<string,vector<pair<string, string> > > &loadedFileList, RendererInterface *newTexture, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath); string parentLoader, string techtreePath);
void load(const string &dir, const string &path, RendererInterface *newTexture, void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *newTexture,
std::map<string,vector<pair<string, string> > > &loadedFileList,string parentLoader, std::map<string,vector<pair<string, string> > > &loadedFileList,string parentLoader,
string techtreePath); string techtreePath);
const void setValues (UnitParticleSystem *uts); const void setValues (UnitParticleSystem *uts);

View File

@@ -106,7 +106,7 @@ void ResourceType::load(const string &dir, Checksum* checksum, Checksum *techtre
string particlePath= particleFileNode->getAttribute("path")->getRestrictedValue(); string particlePath= particleFileNode->getAttribute("path")->getRestrictedValue();
ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType(); ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType();
objectParticleSystemType->load(dir, currentPath + particlePath, objectParticleSystemType->load(particleFileNode, dir, currentPath + particlePath,
&Renderer::getInstance(), loadedFileList, sourceXMLFile, techtreePath); &Renderer::getInstance(), loadedFileList, sourceXMLFile, techtreePath);
loadedFileList[currentPath + particlePath].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + particlePath].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue()));

View File

@@ -182,7 +182,7 @@ void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt,
const XmlNode *particleFileNode= particleNode->getChild("particle-file", i); const XmlNode *particleFileNode= particleNode->getChild("particle-file", i);
string path= particleFileNode->getAttribute("path")->getRestrictedValue(); string path= particleFileNode->getAttribute("path")->getRestrictedValue();
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType(); UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
unitParticleSystemType->load(dir, currentPath + path, &Renderer::getInstance(), unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath()); loadedFileList,parentLoader,tt->getPath());
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue()));
unitParticleSystemTypes.push_back(unitParticleSystemType); unitParticleSystemTypes.push_back(unitParticleSystemType);
@@ -255,16 +255,15 @@ void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt,
const XmlNode *particleFileNode= particleNode->getChild("originator-particle-file"); const XmlNode *particleFileNode= particleNode->getChild("originator-particle-file");
string path= particleFileNode->getAttribute("path")->getRestrictedValue(); string path= particleFileNode->getAttribute("path")->getRestrictedValue();
attackBoost.unitParticleSystemTypeForSourceUnit = new UnitParticleSystemType(); attackBoost.unitParticleSystemTypeForSourceUnit = new UnitParticleSystemType();
attackBoost.unitParticleSystemTypeForSourceUnit->load(dir, currentPath + path, &Renderer::getInstance(), attackBoost.unitParticleSystemTypeForSourceUnit->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath()); loadedFileList,parentLoader,tt->getPath());
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue()));
} }
if(particleNode->hasChild("affected-particle-file") == true) { if(particleNode->hasChild("affected-particle-file") == true) {
const XmlNode *particleFileNode= particleNode->getChild("affected-particle-file"); const XmlNode *particleFileNode= particleNode->getChild("affected-particle-file");
string path= particleFileNode->getAttribute("path")->getRestrictedValue(); string path= particleFileNode->getAttribute("path")->getRestrictedValue();
attackBoost.unitParticleSystemTypeForAffectedUnit = new UnitParticleSystemType(); attackBoost.unitParticleSystemTypeForAffectedUnit = new UnitParticleSystemType();
attackBoost.unitParticleSystemTypeForAffectedUnit->load(dir, currentPath + path, &Renderer::getInstance(), attackBoost.unitParticleSystemTypeForAffectedUnit->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath()); loadedFileList,parentLoader,tt->getPath());
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue()));
} }
@@ -485,7 +484,7 @@ void AttackSkillType::load(const XmlNode *sn, const string &dir, const TechTree
if(particleEnabled){ if(particleEnabled){
string path= particleNode->getAttribute("path")->getRestrictedValue(); string path= particleNode->getAttribute("path")->getRestrictedValue();
projectileParticleSystemType= new ParticleSystemTypeProjectile(); projectileParticleSystemType= new ParticleSystemTypeProjectile();
projectileParticleSystemType->load(dir, currentPath + path, projectileParticleSystemType->load(particleNode, dir, currentPath + path,
&Renderer::getInstance(), loadedFileList, parentLoader, &Renderer::getInstance(), loadedFileList, parentLoader,
tt->getPath()); tt->getPath());
} }
@@ -521,7 +520,7 @@ void AttackSkillType::load(const XmlNode *sn, const string &dir, const TechTree
if(particleEnabled){ if(particleEnabled){
string path= particleNode->getAttribute("path")->getRestrictedValue(); string path= particleNode->getAttribute("path")->getRestrictedValue();
splashParticleSystemType= new ParticleSystemTypeSplash(); splashParticleSystemType= new ParticleSystemTypeSplash();
splashParticleSystemType->load(dir, currentPath + path, splashParticleSystemType->load(particleNode, dir, currentPath + path,
&Renderer::getInstance(),loadedFileList, parentLoader, &Renderer::getInstance(),loadedFileList, parentLoader,
tt->getPath()); tt->getPath());
} }

View File

@@ -295,7 +295,7 @@ void UnitType::load(int id,const string &dir, const TechTree *techTree,
//Texture2D *newTexture = Renderer::getInstance().newTexture2D(rsGame); //Texture2D *newTexture = Renderer::getInstance().newTexture2D(rsGame);
Texture2D *newTexture = NULL; Texture2D *newTexture = NULL;
unitParticleSystemType->load(dir, currentPath + path, unitParticleSystemType->load(particleFileNode, dir, currentPath + path,
&Renderer::getInstance(),loadedFileList, sourceXMLFile, &Renderer::getInstance(),loadedFileList, sourceXMLFile,
techTree->getPath()); techTree->getPath());
loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue()));

View File

@@ -226,7 +226,7 @@ void Tileset::load(const string &dir, Checksum *checksum, Checksum *tilesetCheck
const XmlNode *particleFileNode= particleNode->getChild("particle-file", k); const XmlNode *particleFileNode= particleNode->getChild("particle-file", k);
string path= particleFileNode->getAttribute("path")->getRestrictedValue(); string path= particleFileNode->getAttribute("path")->getRestrictedValue();
ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType(); ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType();
objectParticleSystemType->load(dir, currentPath + path, objectParticleSystemType->load(particleFileNode, dir, currentPath + path,
&Renderer::getInstance(), loadedFileList, sourceXMLFile,""); &Renderer::getInstance(), loadedFileList, sourceXMLFile,"");
loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue())); loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue()));

View File

@@ -38,7 +38,7 @@ public:
virtual void renderSystem(ParticleSystem *ps); virtual void renderSystem(ParticleSystem *ps);
virtual void renderSystemLine(ParticleSystem *ps); virtual void renderSystemLine(ParticleSystem *ps);
virtual void renderSystemLineAlpha(ParticleSystem *ps); virtual void renderSystemLineAlpha(ParticleSystem *ps);
virtual void renderModel(AttackParticleSystem *ps, ModelRenderer *mr); virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr);
protected: protected:
void renderBufferQuads(int quadCount); void renderBufferQuads(int quadCount);

View File

@@ -132,14 +132,12 @@ protected:
bool teamcolorNoEnergy; bool teamcolorNoEnergy;
bool teamcolorEnergy; bool teamcolorEnergy;
int alternations; int alternations;
ParticleObserver *particleObserver; ParticleObserver *particleObserver;
public: public:
//conmstructor and destructor //conmstructor and destructor
ParticleSystem(int particleCount); ParticleSystem(int particleCount);
virtual ~ParticleSystem(); virtual ~ParticleSystem();
virtual ParticleSystemType getParticleSystemType() const = 0; virtual ParticleSystemType getParticleSystemType() const = 0;
//public //public
@@ -158,9 +156,9 @@ public:
virtual bool getVisible() const {return visible;} virtual bool getVisible() const {return visible;}
//set //set
void setState(State state); virtual void setState(State state);
void setTexture(Texture *texture); void setTexture(Texture *texture);
void setPos(Vec3f pos); virtual void setPos(Vec3f pos);
void setColor(Vec4f color); void setColor(Vec4f color);
void setColorNoEnergy(Vec4f color); void setColorNoEnergy(Vec4f color);
void setEmissionRate(float emissionRate); void setEmissionRate(float emissionRate);
@@ -168,9 +166,9 @@ public:
void setVarParticleEnergy(int varParticleEnergy); void setVarParticleEnergy(int varParticleEnergy);
void setParticleSize(float particleSize); void setParticleSize(float particleSize);
void setSpeed(float speed); void setSpeed(float speed);
void setActive(bool active); virtual void setActive(bool active);
void setObserver(ParticleObserver *particleObserver); void setObserver(ParticleObserver *particleObserver);
void setVisible(bool visible); virtual void setVisible(bool visible);
void setBlendMode(BlendMode blendMode) {this->blendMode= blendMode;} void setBlendMode(BlendMode blendMode) {this->blendMode= blendMode;}
void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {this->teamcolorNoEnergy= teamcolorNoEnergy;} void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {this->teamcolorNoEnergy= teamcolorNoEnergy;}
void setTeamcolorEnergy(bool teamcolorEnergy) {this->teamcolorEnergy= teamcolorEnergy;} void setTeamcolorEnergy(bool teamcolorEnergy) {this->teamcolorEnergy= teamcolorEnergy;}
@@ -179,8 +177,12 @@ public:
static BlendMode strToBlendMode(const string &str); static BlendMode strToBlendMode(const string &str);
//misc //misc
void fade(); virtual void fade();
int isEmpty() const; int isEmpty() const;
//children
virtual int getChildCount() { return 0; }
virtual ParticleSystem* getChild(int i);
protected: protected:
//protected //protected
@@ -217,43 +219,91 @@ public:
}; };
// ===================================================== // =====================================================
// class UnitParticleSystem // class GameParticleSystem
/// base-class for unit and attack systems
// ===================================================== // =====================================================
class UnitParticleSystem: public ParticleSystem{ class UnitParticleSystem;
public:
static bool isNight; class GameParticleSystem: public ParticleSystem{
private:
float radius;
Vec3f windSpeed;
Vec3f cRotation;
Vec3f fixedAddition;
Vec3f oldPosition;
bool energyUp;
public: public:
enum Primitive{ enum Primitive{
pQuad, pQuad,
pLine, pLine,
pLineAlpha pLineAlpha
}; };
static Primitive strToPrimitive(const string &str);
virtual ~GameParticleSystem();
int getChildCount();
ParticleSystem* getChild(int i);
void addChild(UnitParticleSystem* child);
void removeChild(UnitParticleSystem* child);
void setPos(Vec3f pos);
void setOffset(Vec3f offset);
void setModel(Model *model) {this->model= model;}
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
float getTween() { return tween; } // 0.0 -> 1.0 for animation of model
Model *getModel() const {return model;}
void setPrimitive(Primitive primitive) {this->primitive= primitive;}
Vec3f getDirection() const {return direction;}
void setModelCycle(float modelCycle) {this->modelCycle= modelCycle;}
protected:
typedef std::vector<UnitParticleSystem*> Children;
Children children;
Primitive primitive;
Model *model;
float modelCycle;
Vec3f offset;
Vec3f direction;
float tween;
GameParticleSystem(int particleCount);
void positionChildren();
void setTween(float relative,float absolute);
};
// =====================================================
// class UnitParticleSystem
// =====================================================
class UnitParticleSystem: public GameParticleSystem{
public:
static bool isNight;
private:
float radius;
float minRadius;
Vec3f windSpeed;
Vec3f cRotation;
Vec3f fixedAddition;
Vec3f oldPosition;
bool energyUp;
public:
enum Shape{
sLinear, // generated in a sphere, flying in direction
sSpherical, // generated in a sphere, flying away from center
sConical, // generated in a cone at angle from direction
};
bool relative; bool relative;
bool relativeDirection; bool relativeDirection;
bool fixed; bool fixed;
Model *model; Shape shape;
Primitive primitive; float angle;
Vec3f offset;
Vec3f direction;
float sizeNoEnergy; float sizeNoEnergy;
float gravity; float gravity;
float rotation; float rotation;
bool isVisibleAtNight; bool isVisibleAtNight;
bool isVisibleAtDay; bool isVisibleAtDay;
bool radiusBasedStartenergy; bool radiusBasedStartenergy;
int staticParticleCount; int staticParticleCount;
int delay;
int lifetime;
float emissionRateFade;
GameParticleSystem* parent;
public: public:
UnitParticleSystem(int particleCount= 2000); UnitParticleSystem(int particleCount= 2000);
~UnitParticleSystem();
virtual ParticleSystemType getParticleSystemType() const { return pst_UnitParticleSystem;} virtual ParticleSystemType getParticleSystemType() const { return pst_UnitParticleSystem;}
@@ -261,18 +311,21 @@ public:
virtual void initParticle(Particle *p, int particleIndex); virtual void initParticle(Particle *p, int particleIndex);
virtual void updateParticle(Particle *p); virtual void updateParticle(Particle *p);
virtual void update(); virtual void update();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
virtual bool getVisible() const; virtual bool getVisible() const;
virtual void fade();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
//set params //set params
void setRadius(float radius); void setRadius(float radius) {this->radius= radius;}
void setMinRadius(float minRadius) {this->minRadius= minRadius;}
void setEmissionRateFade(float emissionRateFade) {this->emissionRateFade= emissionRateFade;}
void setWind(float windAngle, float windSpeed); void setWind(float windAngle, float windSpeed);
void setOffset(Vec3f offset) {this->offset= offset;} void setDirection(Vec3f direction) {this->direction= direction;}
void setDirection(Vec3f direction) {this->direction= direction;}
void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;} void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;}
void setGravity(float gravity) {this->gravity= gravity;} void setGravity(float gravity) {this->gravity= gravity;}
void setRotation(float rotation) {this->rotation= rotation;} void setRotation(float rotation);
void setRelative(bool relative) {this->relative= relative;} void setRelative(bool relative) {this->relative= relative;}
void setRelativeDirection(bool relativeDirection) {this->relativeDirection= relativeDirection;} void setRelativeDirection(bool relativeDirection) {this->relativeDirection= relativeDirection;}
void setFixed(bool fixed) {this->fixed= fixed;} void setFixed(bool fixed) {this->fixed= fixed;}
@@ -281,9 +334,15 @@ public:
void setIsVisibleAtNight(bool value) {this->isVisibleAtNight= value;} void setIsVisibleAtNight(bool value) {this->isVisibleAtNight= value;}
void setIsVisibleAtDay(bool value) {this->isVisibleAtDay= value;} void setIsVisibleAtDay(bool value) {this->isVisibleAtDay= value;}
void setRadiusBasedStartenergy(bool value) {this->radiusBasedStartenergy= value;} void setRadiusBasedStartenergy(bool value) {this->radiusBasedStartenergy= value;}
void setShape(Shape shape) {this->shape= shape;}
static Primitive strToPrimitive(const string &str); void setAngle(float angle) {this->angle= angle;}
void setDelay(int delay) {this->delay= delay;}
void setLifetime(int lifetime) {this->lifetime= lifetime;}
void setParent(GameParticleSystem* parent) {this->parent= parent;}
GameParticleSystem* getParent() const {return parent;}
void setParentDirection(Vec3f parentDirection);
static Shape strToShape(const string& str);
}; };
// ===================================================== // =====================================================
@@ -336,43 +395,20 @@ public:
/// Base class for Projectiles and Splashes /// Base class for Projectiles and Splashes
// =========================================================================== // ===========================================================================
class AttackParticleSystem: public ParticleSystem{ class AttackParticleSystem: public GameParticleSystem{
public:
enum Primitive{
pQuad,
pLine,
pLineAlpha
};
protected: protected:
Model *model;
Primitive primitive;
Vec3f offset;
float sizeNoEnergy; float sizeNoEnergy;
float gravity; float gravity;
float tween;
Vec3f direction;
public: public:
AttackParticleSystem(int particleCount); AttackParticleSystem(int particleCount);
virtual ParticleSystemType getParticleSystemType() const { return pst_ProjectileParticleSystem;} virtual ParticleSystemType getParticleSystemType() const { return pst_ProjectileParticleSystem;}
virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
Model *getModel() const {return model;}
Vec3f getDirection() const {return direction;}
void setModel(Model *model) {this->model= model;}
void setOffset(Vec3f offset) {this->offset= offset;}
void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;} void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;}
void setGravity(float gravity) {this->gravity= gravity;} void setGravity(float gravity) {this->gravity= gravity;}
void setPrimitive(Primitive primitive) {this->primitive= primitive;}
float getTween() { return tween; } // 0.0 -> 1.0 for animation of model
virtual void initParticleSystem() {} // opportunity to do any initialization when the system has been created and all settings set virtual void initParticleSystem() {} // opportunity to do any initialization when the system has been created and all settings set
static Primitive strToPrimitive(const string &str);
}; };
// ===================================================== // =====================================================
@@ -401,14 +437,14 @@ private:
Vec3f yVector; Vec3f yVector;
Vec3f zVector; Vec3f zVector;
float modelCycle;
Trajectory trajectory; Trajectory trajectory;
float trajectorySpeed; float trajectorySpeed;
//parabolic //parabolic
float trajectoryScale; float trajectoryScale;
float trajectoryFrequency; float trajectoryFrequency;
void rotateChildren();
public: public:
ProjectileParticleSystem(int particleCount= 1000); ProjectileParticleSystem(int particleCount= 1000);
@@ -427,7 +463,6 @@ public:
void setTrajectoryScale(float trajectoryScale) {this->trajectoryScale= trajectoryScale;} void setTrajectoryScale(float trajectoryScale) {this->trajectoryScale= trajectoryScale;}
void setTrajectoryFrequency(float trajectoryFrequency) {this->trajectoryFrequency= trajectoryFrequency;} void setTrajectoryFrequency(float trajectoryFrequency) {this->trajectoryFrequency= trajectoryFrequency;}
void setModelCycle(float modelCycle) {this->modelCycle= modelCycle;}
void setPath(Vec3f startPos, Vec3f endPos); void setPath(Vec3f startPos, Vec3f endPos);
static Trajectory strToTrajectory(const string &str); static Trajectory strToTrajectory(const string &str);

View File

@@ -31,7 +31,7 @@ public:
virtual void renderSystem(ParticleSystem *ps)=0; virtual void renderSystem(ParticleSystem *ps)=0;
virtual void renderSystemLine(ParticleSystem *ps)=0; virtual void renderSystemLine(ParticleSystem *ps)=0;
virtual void renderSystemLineAlpha(ParticleSystem *ps)=0; virtual void renderSystemLineAlpha(ParticleSystem *ps)=0;
virtual void renderModel(AttackParticleSystem *ps, ModelRenderer *mr)=0; virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr)=0;
}; };
}}//end namespace }}//end namespace

View File

@@ -156,6 +156,22 @@ public:
x/= m; x/= m;
y/= m; y/= m;
} }
Vec2<T> rotate(float rad){
const float
#ifdef USE_STREFLOP
c = streflop::cosf(rad),
s = streflop::sinf(rad);
#else
c = scosf(rad),
s = ssinf(rad);
#endif
return Vec2<T>(x*c-y*s,x*s+y*c);
}
Vec2<T> rotateAround(float rad,const Vec2<T>& pt){
return pt+(*this-pt).rotate(rad);
}
std::string getString() const { std::string getString() const {
std::ostringstream streamOut; std::ostringstream streamOut;

View File

@@ -38,13 +38,22 @@ static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1;
static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2; static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2;
protected: protected:
static Mutex mutexCache;
typedef enum { typedef enum {
cacheItemGet, cacheItemGet,
cacheItemSet cacheItemSet
} CacheAccessorType; } CacheAccessorType;
template <typename T>
static Mutex & manageCachedItemMutex(string cacheKey) {
// Here is the actual type-safe instantiation
static std::map<string, Mutex> itemCacheMutexList;
if(itemCacheMutexList.find(cacheKey) == itemCacheMutexList.end()) {
itemCacheMutexList[cacheKey] = Mutex();
}
Mutex &mutex = itemCacheMutexList[cacheKey];
return mutex;
}
template <typename T> template <typename T>
static T & manageCachedItem(string cacheKey, T *value,CacheAccessorType accessor) { static T & manageCachedItem(string cacheKey, T *value,CacheAccessorType accessor) {
// Here is the actual type-safe instantiation // Here is the actual type-safe instantiation
@@ -52,6 +61,7 @@ protected:
if(accessor == cacheItemSet) { if(accessor == cacheItemSet) {
if(value == NULL) { if(value == NULL) {
try { try {
Mutex &mutexCache = manageCachedItemMutex<T>(cacheKey);
MutexSafeWrapper safeMutex(&mutexCache); MutexSafeWrapper safeMutex(&mutexCache);
if(itemCache.find(cacheKey) != itemCache.end()) { if(itemCache.find(cacheKey) != itemCache.end()) {
itemCache.erase(cacheKey); itemCache.erase(cacheKey);
@@ -64,6 +74,7 @@ protected:
} }
try { try {
Mutex &mutexCache = manageCachedItemMutex<T>(cacheKey);
MutexSafeWrapper safeMutex(&mutexCache); MutexSafeWrapper safeMutex(&mutexCache);
itemCache[cacheKey] = *value; itemCache[cacheKey] = *value;
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
@@ -94,6 +105,10 @@ public:
return manageCachedItem<T>(cacheKey,NULL,cacheItemSet); return manageCachedItem<T>(cacheKey,NULL,cacheItemSet);
} }
template <typename T>
static Mutex & getMutexForItem(string cacheKey) {
return manageCachedItemMutex<T>(cacheKey);
}
}; };
}}//end namespace }}//end namespace

View File

@@ -64,7 +64,7 @@ public:
class XmlTree{ class XmlTree{
private: private:
XmlNode *rootNode; XmlNode *rootNode;
string loadPath;
private: private:
XmlTree(XmlTree&); XmlTree(XmlTree&);
void operator =(XmlTree&); void operator =(XmlTree&);
@@ -90,6 +90,7 @@ private:
string text; string text;
vector<XmlNode*> children; vector<XmlNode*> children;
vector<XmlAttribute*> attributes; vector<XmlAttribute*> attributes;
mutable const XmlNode* superNode;
private: private:
XmlNode(XmlNode&); XmlNode(XmlNode&);
@@ -99,6 +100,8 @@ public:
XmlNode(XERCES_CPP_NAMESPACE::DOMNode *node, std::map<string,string> mapTagReplacementValues); XmlNode(XERCES_CPP_NAMESPACE::DOMNode *node, std::map<string,string> mapTagReplacementValues);
XmlNode(const string &name); XmlNode(const string &name);
~XmlNode(); ~XmlNode();
void setSuper(const XmlNode* superNode) const { this->superNode = superNode; }
const string &getName() const {return name;} const string &getName() const {return name;}
size_t getChildCount() const {return children.size();} size_t getChildCount() const {return children.size();}
@@ -122,6 +125,7 @@ public:
private: private:
string getTreeString() const; string getTreeString() const;
bool hasChildNoSuper(const string& childName) const;
}; };
// ===================================================== // =====================================================

View File

@@ -223,7 +223,7 @@ void ParticleRendererGl::renderSystemLineAlpha(ParticleSystem *ps){
assertGl(); assertGl();
} }
void ParticleRendererGl::renderModel(AttackParticleSystem *ps, ModelRenderer *mr){ void ParticleRendererGl::renderModel(GameParticleSystem *ps, ModelRenderer *mr){
//render model //render model
Model *model = ps->getModel(); Model *model = ps->getModel();
if(model != NULL) { if(model != NULL) {
@@ -262,7 +262,9 @@ void ParticleRendererGl::renderModel(AttackParticleSystem *ps, ModelRenderer *mr
//render //render
mr->begin(true, true, false); mr->begin(true, true, false);
model->updateInterpolationData(ps->getTween(), false); float t = ps->getTween();
assert(t >= 0.0f && t <= 1.0f);
model->updateInterpolationData(t, false);
mr->render(model); mr->render(model);
mr->end(); mr->end();

View File

@@ -135,7 +135,7 @@ ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
return bmOneMinusAlpha; return bmOneMinusAlpha;
} }
else{ else{
throw "Unknown particle mode: " + str; throw runtime_error("Unknown particle mode: " + str);
} }
} }
@@ -143,6 +143,8 @@ ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
void ParticleSystem::setState(State state){ void ParticleSystem::setState(State state){
this->state= state; this->state= state;
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setState(state);
} }
void ParticleSystem::setTexture(Texture *texture){ void ParticleSystem::setTexture(Texture *texture){
@@ -151,6 +153,8 @@ void ParticleSystem::setTexture(Texture *texture){
void ParticleSystem::setPos(Vec3f pos){ void ParticleSystem::setPos(Vec3f pos){
this->pos= pos; this->pos= pos;
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setPos(pos);
} }
void ParticleSystem::setColor(Vec4f color){ void ParticleSystem::setColor(Vec4f color){
@@ -183,14 +187,22 @@ void ParticleSystem::setSpeed(float speed){
void ParticleSystem::setActive(bool active){ void ParticleSystem::setActive(bool active){
this->active= active; this->active= active;
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setActive(active);
} }
void ParticleSystem::setObserver(ParticleObserver *particleObserver){ void ParticleSystem::setObserver(ParticleObserver *particleObserver){
this->particleObserver= particleObserver; this->particleObserver= particleObserver;
} }
ParticleSystem* ParticleSystem::getChild(int i){
throw std::out_of_range("ParticleSystem::getChild bad");
}
void ParticleSystem::setVisible(bool visible){ void ParticleSystem::setVisible(bool visible){
this->visible= visible; this->visible= visible;
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setVisible(visible);
} }
// =============== MISC ========================= // =============== MISC =========================
@@ -209,6 +221,8 @@ void ParticleSystem::fade(){
if(particleObserver != NULL){ if(particleObserver != NULL){
particleObserver->update(this); particleObserver->update(this);
} }
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->fade();
} }
int ParticleSystem::isEmpty() const{ int ParticleSystem::isEmpty() const{
@@ -297,6 +311,8 @@ void ParticleSystem::setFactionColor(Vec3f factionColor){
if(teamcolorNoEnergy){ if(teamcolorNoEnergy){
this->colorNoEnergy= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->colorNoEnergy.w); this->colorNoEnergy= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->colorNoEnergy.w);
} }
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setFactionColor(factionColor);
} }
// =========================================================================== // ===========================================================================
@@ -378,13 +394,132 @@ void FireParticleSystem::setWind(float windAngle, float windSpeed){
#endif #endif
} }
// ===========================================================================
// GameParticleSystem
// ===========================================================================
GameParticleSystem::GameParticleSystem(int particleCount):
ParticleSystem(particleCount),
primitive(pQuad),
model(NULL),
modelCycle(0.0f),
tween(0.0f),
offset(0.0f),
direction(0.0f, 1.0f, 0.0f)
{}
GameParticleSystem::~GameParticleSystem(){
for(Children::iterator it= children.begin(); it != children.end(); it++){
(*it)->setParent(NULL);
(*it)->fade();
}
}
GameParticleSystem::Primitive GameParticleSystem::strToPrimitive(const string &str){
if(str == "quad"){
return pQuad;
}
else if(str == "line"){
return pLine;
}
else{
throw runtime_error("Unknown particle primitive: " + str);
}
}
int GameParticleSystem::getChildCount(){
return children.size();
}
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);
}
void GameParticleSystem::setPos(Vec3f pos){
this->pos= pos;
positionChildren();
}
void GameParticleSystem::positionChildren() {
Vec3f child_pos = pos - offset;
for(int i=getChildCount()-1; i>=0; i--)
getChild(i)->setPos(child_pos);
}
void GameParticleSystem::setOffset(Vec3f offset){
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);
}
}
}
void GameParticleSystem::setTween(float relative,float absolute) {
if(model){
// animation?
if(modelCycle == 0.0f) {
tween= relative;
}
else {
#ifdef USE_STREFLOP
if(streflop::fabs(absolute) <= 0.00001f){
#else
if(fabs(absolute) <= 0.00001f){
#endif
tween = 0.0f;
}
else {
#ifdef USE_STREFLOP
tween= streflop::fmod(absolute, modelCycle);
#else
tween= fmod(absolute, modelCycle);
#endif
tween /= modelCycle;
}
}
assert(tween >= 0.0f && tween <= 1.0f);
tween= clamp(tween, 0.0f, 1.0f);
}
for(Children::iterator it= children.begin(); it != children.end(); it++)
(*it)->setTween(relative,absolute);
}
// =========================================================================== // ===========================================================================
// UnitParticleSystem // UnitParticleSystem
// =========================================================================== // ===========================================================================
bool UnitParticleSystem::isNight= false; bool UnitParticleSystem::isNight= false;
UnitParticleSystem::UnitParticleSystem(int particleCount) : UnitParticleSystem::UnitParticleSystem(int particleCount):
ParticleSystem(particleCount){ GameParticleSystem(particleCount),
parent(NULL){
radius= 0.5f; radius= 0.5f;
speed= 0.01f; speed= 0.01f;
windSpeed= Vec3f(0.0f); windSpeed= Vec3f(0.0f);
@@ -393,8 +528,6 @@ UnitParticleSystem::UnitParticleSystem(int particleCount) :
setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f)); setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f));
primitive= pQuad; primitive= pQuad;
offset= Vec3f(0.0f);
direction= Vec3f(0.0f, 1.0f, 0.0f);
gravity= 0.0f; gravity= 0.0f;
fixed= false; fixed= false;
@@ -413,6 +546,15 @@ UnitParticleSystem::UnitParticleSystem(int particleCount) :
emissionState= (float) staticParticleCount; emissionState= (float) staticParticleCount;
} }
energyUp= false; energyUp= false;
delay = 0; // none
lifetime = -1; // forever
}
UnitParticleSystem::~UnitParticleSystem(){
if(parent){
parent->removeChild(this);
}
} }
bool UnitParticleSystem::getVisible() const{ bool UnitParticleSystem::getVisible() const{
@@ -425,54 +567,48 @@ bool UnitParticleSystem::getVisible() const{
else return false; else return false;
} }
void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){ void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) {
//if(active){ GameParticleSystem::render(pr,mr);
switch(primitive){
case pQuad:
pr->renderSystem(this);
break;
case pLine:
pr->renderSystemLine(this);
break;
default:
assert(false);
}
//}
} }
UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &str){ void UnitParticleSystem::setRotation(float rotation){
if(str == "quad"){ this->rotation= rotation;
return pQuad; for(Children::iterator it= children.begin(); it != children.end(); it++)
(*it)->setRotation(rotation);
}
void UnitParticleSystem::fade(){
if(!parent || (lifetime<=0 && !(emissionRateFade && emissionRate > 0))){ // particle has its own lifetime?
GameParticleSystem::fade();
} }
else if(str == "line"){ }
return pLine;
UnitParticleSystem::Shape UnitParticleSystem::strToShape(const string& str){
if(str == "spherical"){
return sSpherical;
}
else if(str == "conical"){
return sConical;
}
else if(str == "linear"){
return sLinear;
} }
else{ else{
throw "Unknown particle primitive: " + str; throw runtime_error("Unkown particle shape: " + str);
} }
} }
void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
ParticleSystem::initParticle(p, particleIndex); ParticleSystem::initParticle(p, particleIndex);
float ang= random.randRange(-2.0f * pi, 2.0f * pi); const float ang= random.randRange(-2.0f * pi, 2.0f * pi);
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
float mod= streflop::fabsf(random.randRange(-radius, radius)); const float mod= streflop::fabsf(random.randRange(-radius, radius));
const float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius));
float x= streflop::sinf(ang)*mod;
float y= streflop::cosf(ang)*mod;
float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius));
#else #else
float mod= fabsf(random.randRange(-radius, radius)); const float mod= fabsf(random.randRange(-radius, radius));
const float radRatio= sqrtf(sqrtf(mod / radius));
float x= sinf(ang) * mod;
float y= cosf(ang) * mod;
float radRatio= sqrtf(sqrtf(mod / radius));
#endif #endif
//p->color= color*0.5f + color*0.5f*radRatio;
p->color= color; p->color= color;
if(radiusBasedStartenergy == true){ if(radiusBasedStartenergy == true){
p->energy= static_cast<int> (maxParticleEnergy * radRatio) + random.randRange(-varParticleEnergy, p->energy= static_cast<int> (maxParticleEnergy * radRatio) + random.randRange(-varParticleEnergy,
@@ -485,36 +621,72 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
p->lastPos= pos; p->lastPos= pos;
oldPosition= pos; oldPosition= pos;
p->size= particleSize; p->size= particleSize;
p->speed= Vec3f(direction.x + direction.x * random.randRange(-0.5f, 0.5f), direction.y + direction.y
* random.randRange(-0.5f, 0.5f), direction.z + direction.z * random.randRange(-0.5f, 0.5f));
p->speed= p->speed * speed;
p->accel= Vec3f(0.0f, -gravity, 0.0f); p->accel= Vec3f(0.0f, -gravity, 0.0f);
if(relative == false){ // work out where we start for our shape (set speed and pos)
p->pos= Vec3f(pos.x + x + offset.x, pos.y + random.randRange(-radius / 2, radius / 2) + offset.y, pos.z + y switch(shape){
+ offset.z); case sSpherical:
} angle = random.randRange(0,360);
else{// rotate it according to rotation // fall through
float rad= degToRad(rotation); case sConical:{
#ifdef USE_STREFLOP Vec2f horiz = Vec2f(1,0).rotate(ang);
p->pos= Vec3f(pos.x+x+offset.z*streflop::sinf(rad)+offset.x*streflop::cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*streflop::cosf(rad)-offset.x*streflop::sinf(rad))); Vec2f vert = Vec2f(1,0).rotate(degToRad(angle));
if(relativeDirection){ Vec3f start = Vec3f(horiz.x*vert.y,vert.x,horiz.y).getNormalized(); // close enough
p->speed = start * speed;
start = start * random.randRange(minRadius,radius);
p->pos = pos + offset + start;
} break;
case sLinear:{
#ifdef USE_STREFLOP
float x= streflop::sinf(ang)*mod;
float y= streflop::cosf(ang)*mod;
#else
float x= sinf(ang) * mod;
float y= cosf(ang) * mod;
#endif
const float rad= degToRad(rotation);
if(!relative){
p->pos= Vec3f(pos.x + x + offset.x, pos.y + random.randRange(-radius / 2, radius / 2) + offset.y, pos.z + y
+ offset.z);
}
else{// rotate it according to rotation
#ifdef USE_STREFLOP
p->pos= Vec3f(pos.x+x+offset.z*streflop::sinf(rad)+offset.x*streflop::cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*streflop::cosf(rad)-offset.x*streflop::sinf(rad)));
#else
p->pos= Vec3f(pos.x + x + offset.z * sinf(rad) + offset.x * cosf(rad), pos.y + random.randRange(-radius / 2,
radius / 2) + offset.y, pos.z + y + (offset.z * cosf(rad) - offset.x * sinf(rad)));
#endif
}
p->speed= Vec3f(direction.x + direction.x * random.randRange(-0.5f, 0.5f), direction.y + direction.y
* random.randRange(-0.5f, 0.5f), direction.z + direction.z * random.randRange(-0.5f, 0.5f));
p->speed= p->speed * speed;
if(relative && relativeDirection){
#ifdef USE_STREFLOP
p->speed=Vec3f(p->speed.z*streflop::sinf(rad)+p->speed.x*streflop::cosf(rad),p->speed.y,(p->speed.z*streflop::cosf(rad)-p->speed.x*streflop::sinf(rad))); p->speed=Vec3f(p->speed.z*streflop::sinf(rad)+p->speed.x*streflop::cosf(rad),p->speed.y,(p->speed.z*streflop::cosf(rad)-p->speed.x*streflop::sinf(rad)));
} #else
#else
p->pos= Vec3f(pos.x + x + offset.z * sinf(rad) + offset.x * cosf(rad), pos.y + random.randRange(-radius / 2,
radius / 2) + offset.y, pos.z + y + (offset.z * cosf(rad) - offset.x * sinf(rad)));
if(relativeDirection){
p->speed= Vec3f(p->speed.z * sinf(rad) + p->speed.x * cosf(rad), p->speed.y, (p->speed.z * cosf(rad) p->speed= Vec3f(p->speed.z * sinf(rad) + p->speed.x * cosf(rad), p->speed.y, (p->speed.z * cosf(rad)
- p->speed.x * sinf(rad))); - p->speed.x * sinf(rad)));
#endif
} }
} break;
#endif default: throw runtime_error("bad shape");
} }
} }
void UnitParticleSystem::update(){ void UnitParticleSystem::update(){
// delay and timeline are only applicable for child particles
if(parent && delay>0 && delay--){
return;
}
if(parent && lifetime>0 && !--lifetime) {
fade();
}
if(state != sPause) {
emissionRate-= emissionRateFade;
if(parent && emissionRate < 0.0f) {
fade();
}
}
if(fixed){ if(fixed){
fixedAddition= Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z); fixedAddition= Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z);
oldPosition= pos; oldPosition= pos;
@@ -573,10 +745,6 @@ void UnitParticleSystem::updateParticle(Particle *p){
// ================= SET PARAMS ==================== // ================= SET PARAMS ====================
void UnitParticleSystem::setRadius(float radius){
this->radius= radius;
}
void UnitParticleSystem::setWind(float windAngle, float windSpeed){ void UnitParticleSystem::setWind(float windAngle, float windSpeed){
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed; this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed;
@@ -700,43 +868,9 @@ void SnowParticleSystem::setWind(float windAngle, float windSpeed){
// =========================================================================== // ===========================================================================
AttackParticleSystem::AttackParticleSystem(int particleCount) : AttackParticleSystem::AttackParticleSystem(int particleCount) :
ParticleSystem(particleCount){ GameParticleSystem(particleCount){
model= NULL;
primitive= pQuad; primitive= pQuad;
offset= Vec3f(0.0f);
gravity= 0.0f; gravity= 0.0f;
tween= 0.0f;
direction= Vec3f(1.0f, 0.0f, 0.0f);
}
void AttackParticleSystem::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);
}
}
}
AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const string &str){
if(str == "quad"){
return pQuad;
}
else if(str == "line"){
return pLine;
}
else{
throw "Unknown particle primitive: " + str;
}
} }
// =========================================================================== // ===========================================================================
@@ -775,7 +909,6 @@ void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem){
} }
void ProjectileParticleSystem::update(){ void ProjectileParticleSystem::update(){
if(state == sPlay){ if(state == sPlay){
lastPos= pos; lastPos= pos;
@@ -785,19 +918,7 @@ void ProjectileParticleSystem::update(){
// ratio // ratio
float t= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f); float t= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f);
setTween(t,currentVector.length());
// animation?
if(modelCycle == 0.0f) {
tween= t;
}
else {
#ifdef USE_STREFLOP
tween= streflop::fmod(currentVector.length(), modelCycle);
#else
tween= fmod(currentVector.length(), modelCycle);
#endif
tween= clamp(tween / currentVector.length(), 0.0f, 1.0f);
}
// trajectory // trajectory
switch(trajectory) { switch(trajectory) {
@@ -833,10 +954,13 @@ void ProjectileParticleSystem::update(){
direction= pos - lastPos; direction= pos - lastPos;
direction.normalize(); direction.normalize();
// trigger update of child particles
positionChildren();
rotateChildren();
//arrive destination //arrive destination
if(flatPos.dist(endPos) < 0.5f){ if(flatPos.dist(endPos) < 0.5f){
state= sFade; fade();
model= NULL; model= NULL;
if(particleObserver != NULL){ if(particleObserver != NULL){
@@ -854,6 +978,18 @@ void ProjectileParticleSystem::update(){
ParticleSystem::update(); ParticleSystem::update();
} }
void ProjectileParticleSystem::rotateChildren() {
//### only on horizontal plane :(
#ifdef USE_STREFLOP
float rotation = streflop::atan2(direction.x, direction.z);
#else
float rotation = atan2(direction.x, direction.z);
#endif
rotation = radToDeg(rotation);
for(Children::iterator it = children.begin(); it != children.end(); it++)
(*it)->setRotation(rotation);
}
void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){ void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){
ParticleSystem::initParticle(p, particleIndex); ParticleSystem::initParticle(p, particleIndex);
@@ -906,6 +1042,11 @@ void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos){
// set members // set members
this->startPos= startPos; this->startPos= startPos;
this->endPos= endPos; this->endPos= endPos;
// direction
direction = (endPos - lastPos);
direction.normalize();
rotateChildren();
} }
ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){ ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){
@@ -919,7 +1060,7 @@ ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(c
return tSpiral; return tSpiral;
} }
else{ else{
throw "Unknown particle system trajectory: " + str; throw runtime_error("Unknown particle system trajectory: " + str);
} }
} }
@@ -959,8 +1100,9 @@ void SplashParticleSystem::update() {
if(state != sPause) { if(state != sPause) {
emissionRate-= emissionRateFade; emissionRate-= emissionRateFade;
tween= 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f)); float t= 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f));
tween= clamp(tween, 0.0f, 1.0f); t= clamp(t, 0.0f, 1.0f);
setTween(t,t);
if(emissionRate < 0.0f) {//otherwise this system lives forever! if(emissionRate < 0.0f) {//otherwise this system lives forever!
fade(); fade();
@@ -1132,7 +1274,10 @@ void ParticleManager::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &p
} }
void ParticleManager::manage(ParticleSystem *ps){ void ParticleManager::manage(ParticleSystem *ps){
assert((std::find(particleSystems.begin(),particleSystems.end(),ps) == particleSystems.end()) && "particle cannot be added twice");
particleSystems.push_back(ps); particleSystems.push_back(ps);
for(int i=ps->getChildCount()-1; i>=0; i--)
manage(ps->getChild(i));
} }
void ParticleManager::end(){ void ParticleManager::end(){

View File

@@ -13,7 +13,7 @@
namespace Shared { namespace PlatformCommon { namespace Shared { namespace PlatformCommon {
Mutex CacheManager::mutexCache; //Mutex CacheManager::mutexCache;
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1"; const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1";
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2"; const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2";
const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1"; const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1";

View File

@@ -13,6 +13,8 @@
#include <fstream> #include <fstream>
#include <stdexcept> #include <stdexcept>
#include <vector>
#include <algorithm>
#include "conversion.h" #include "conversion.h"
#include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM.hpp>
@@ -23,6 +25,7 @@
#include "properties.h" #include "properties.h"
#include "platform_common.h" #include "platform_common.h"
#include "platform_util.h" #include "platform_util.h"
#include "cache_manager.h"
#include "leak_dumper.h" #include "leak_dumper.h"
@@ -172,7 +175,26 @@ void XmlTree::init(const string &name){
this->rootNode= new XmlNode(name); this->rootNode= new XmlNode(name);
} }
typedef std::vector<XmlTree*> LoadStack;
static LoadStack loadStack;
//static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName");
void XmlTree::load(const string &path, std::map<string,string> mapTagReplacementValues) { void XmlTree::load(const string &path, std::map<string,string> mapTagReplacementValues) {
//printf("XmlTree::load p [%p]\n",this);
assert(!loadPath.size());
//LoadStack &loadStack = CacheManager::getCachedItem<LoadStack>(loadStackCacheName);
//Mutex &mutex = CacheManager::getMutexForItem<LoadStack>(loadStackCacheName);
//MutexSafeWrapper safeMutex(&mutex);
for(LoadStack::iterator it= loadStack.begin(); it!= loadStack.end(); it++){
if((*it)->loadPath == path){
throw runtime_error(path + " recursively included");
}
}
loadStack.push_back(this);
loadPath = path;
this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues); this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues);
} }
@@ -180,7 +202,17 @@ void XmlTree::save(const string &path){
XmlIo::getInstance().save(path, rootNode); XmlIo::getInstance().save(path, rootNode);
} }
XmlTree::~XmlTree(){ XmlTree::~XmlTree() {
//printf("XmlTree::~XmlTree p [%p]\n",this);
//LoadStack &loadStack = CacheManager::getCachedItem<LoadStack>(loadStackCacheName);
//Mutex &mutex = CacheManager::getMutexForItem<LoadStack>(loadStackCacheName);
//MutexSafeWrapper safeMutex(&mutex);
LoadStack::iterator it= find(loadStack.begin(),loadStack.end(),this);
if(it != loadStack.end()) {
loadStack.erase(it);
}
delete rootNode; delete rootNode;
} }
@@ -188,7 +220,7 @@ XmlTree::~XmlTree(){
// class XmlNode // class XmlNode
// ===================================================== // =====================================================
XmlNode::XmlNode(DOMNode *node, std::map<string,string> mapTagReplacementValues) { XmlNode::XmlNode(DOMNode *node, std::map<string,string> mapTagReplacementValues): superNode(NULL) {
if(node == NULL || node->getNodeName() == NULL) { if(node == NULL || node->getNodeName() == NULL) {
throw runtime_error("XML structure seems to be corrupt!"); throw runtime_error("XML structure seems to be corrupt!");
} }
@@ -235,7 +267,7 @@ XmlNode::XmlNode(DOMNode *node, std::map<string,string> mapTagReplacementValues)
} }
} }
XmlNode::XmlNode(const string &name) { XmlNode::XmlNode(const string &name): superNode(NULL) {
this->name= name; this->name= name;
} }
@@ -269,6 +301,7 @@ XmlAttribute *XmlNode::getAttribute(const string &name,bool mustExist) const {
} }
XmlNode *XmlNode::getChild(unsigned int i) const { XmlNode *XmlNode::getChild(unsigned int i) const {
assert(!superNode);
if(i >= children.size()) { if(i >= children.size()) {
throw runtime_error("\"" + getName()+"\" node doesn't have "+intToStr(i+1)+" children"); throw runtime_error("\"" + getName()+"\" node doesn't have "+intToStr(i+1)+" children");
} }
@@ -287,6 +320,8 @@ vector<XmlNode *> XmlNode::getChildList(const string &childName) const {
} }
XmlNode *XmlNode::getChild(const string &childName, unsigned int i) const{ XmlNode *XmlNode::getChild(const string &childName, unsigned int i) const{
if(superNode && !hasChildNoSuper(childName))
return superNode->getChild(childName,i);
if(i>=children.size()){ if(i>=children.size()){
throw runtime_error("\"" + name + "\" node doesn't have "+intToStr(i+1)+" children named \"" + childName + "\"\n\nTree: "+getTreeString()); throw runtime_error("\"" + name + "\" node doesn't have "+intToStr(i+1)+" children named \"" + childName + "\"\n\nTree: "+getTreeString());
} }
@@ -305,6 +340,8 @@ XmlNode *XmlNode::getChild(const string &childName, unsigned int i) const{
} }
bool XmlNode::hasChildAtIndex(const string &childName, int i) const { bool XmlNode::hasChildAtIndex(const string &childName, int i) const {
if(superNode && !hasChildNoSuper(childName))
return superNode->hasChildAtIndex(childName,i);
int count= 0; int count= 0;
for(unsigned int j = 0; j < children.size(); ++j) { for(unsigned int j = 0; j < children.size(); ++j) {
if(children[j]->getName()==childName) { if(children[j]->getName()==childName) {
@@ -318,19 +355,22 @@ bool XmlNode::hasChildAtIndex(const string &childName, int i) const {
return false; return false;
} }
bool XmlNode::hasChild(const string &childName) const { bool XmlNode::hasChild(const string &childName) const {
return hasChildNoSuper(childName) || (superNode && superNode->hasChild(childName));
}
bool XmlNode::hasChildNoSuper(const string &childName) const {
int count= 0; int count= 0;
for(unsigned int j = 0; j < children.size(); ++j) { for(unsigned int j = 0; j < children.size(); ++j) {
if(children[j]->getName() == childName) { if(children[j]->getName() == childName) {
return true; return true;
} }
} }
return false; return false;
} }
XmlNode *XmlNode::addChild(const string &name){ XmlNode *XmlNode::addChild(const string &name){
assert(!superNode);
XmlNode *node= new XmlNode(name); XmlNode *node= new XmlNode(name);
children.push_back(node); children.push_back(node);
return node; return node;