2010-06-24 12:52:58 +02:00
|
|
|
// ==============================================================
|
|
|
|
// This file is part of Glest (www.glest.org)
|
|
|
|
//
|
|
|
|
// Copyright (C) 2010-2010 Titus Tscharntke
|
|
|
|
//
|
|
|
|
// You can redistribute this code and/or modify it under
|
|
|
|
// the terms of the GNU General Public License as published
|
|
|
|
// by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version
|
|
|
|
// ==============================================================
|
|
|
|
|
|
|
|
#include "particle_type.h"
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
#include "core_data.h"
|
|
|
|
#include "xml_parser.h"
|
|
|
|
#include "model.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "game_constants.h"
|
2010-10-06 22:22:06 +02:00
|
|
|
#include "util.h"
|
2010-06-24 12:52:58 +02:00
|
|
|
#include "leak_dumper.h"
|
|
|
|
|
|
|
|
using namespace Shared::Xml;
|
|
|
|
using namespace Shared::Graphics;
|
2010-10-06 22:22:06 +02:00
|
|
|
using namespace Shared::Util;
|
2010-06-24 12:52:58 +02:00
|
|
|
|
|
|
|
namespace Glest{ namespace Game{
|
|
|
|
|
|
|
|
// =====================================================
|
|
|
|
// class ParticleSystemType
|
|
|
|
// =====================================================
|
|
|
|
|
|
|
|
ParticleSystemType::ParticleSystemType() {
|
|
|
|
teamcolorNoEnergy=false;
|
|
|
|
teamcolorEnergy=false;
|
|
|
|
texture=NULL;
|
|
|
|
model=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,RendererInterface *renderer) {
|
|
|
|
//texture
|
|
|
|
const XmlNode *textureNode= particleSystemNode->getChild("texture");
|
|
|
|
bool textureEnabled= textureNode->getAttribute("value")->getBoolValue();
|
|
|
|
|
|
|
|
if(textureEnabled){
|
|
|
|
texture= renderer->newTexture2D(rsGame);
|
|
|
|
if(textureNode->getAttribute("luminance")->getBoolValue()){
|
|
|
|
texture->setFormat(Texture::fAlpha);
|
|
|
|
texture->getPixmap()->init(1);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
texture->getPixmap()->init(4);
|
|
|
|
}
|
|
|
|
texture->load(dir + "/" + textureNode->getAttribute("path")->getRestrictedValue());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
texture= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//model
|
|
|
|
const XmlNode *modelNode= particleSystemNode->getChild("model");
|
|
|
|
bool modelEnabled= modelNode->getAttribute("value")->getBoolValue();
|
|
|
|
if(modelEnabled) {
|
|
|
|
string path= modelNode->getAttribute("path")->getRestrictedValue();
|
|
|
|
model= renderer->newModel(rsGame);
|
|
|
|
|
|
|
|
model->load(dir + "/" + path);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
model= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//primitive
|
|
|
|
const XmlNode *primitiveNode= particleSystemNode->getChild("primitive");
|
|
|
|
primitive= primitiveNode->getAttribute("value")->getRestrictedValue();
|
|
|
|
|
|
|
|
//offset
|
|
|
|
const XmlNode *offsetNode= particleSystemNode->getChild("offset");
|
|
|
|
offset.x= offsetNode->getAttribute("x")->getFloatValue();
|
|
|
|
offset.y= offsetNode->getAttribute("y")->getFloatValue();
|
|
|
|
offset.z= offsetNode->getAttribute("z")->getFloatValue();
|
|
|
|
|
|
|
|
//color
|
|
|
|
const XmlNode *colorNode= particleSystemNode->getChild("color");
|
|
|
|
color.x= colorNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
|
|
|
color.y= colorNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
|
|
|
color.z= colorNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
|
|
|
color.w= colorNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
|
|
|
|
|
|
|
//color
|
|
|
|
const XmlNode *colorNoEnergyNode= particleSystemNode->getChild("color-no-energy");
|
|
|
|
colorNoEnergy.x= colorNoEnergyNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
|
|
|
colorNoEnergy.y= colorNoEnergyNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
|
|
|
colorNoEnergy.z= colorNoEnergyNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
|
|
|
colorNoEnergy.w= colorNoEnergyNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
|
|
|
|
|
|
|
//size
|
|
|
|
const XmlNode *sizeNode= particleSystemNode->getChild("size");
|
|
|
|
size= sizeNode->getAttribute("value")->getFloatValue();
|
|
|
|
|
|
|
|
//sizeNoEnergy
|
|
|
|
const XmlNode *sizeNoEnergyNode= particleSystemNode->getChild("size-no-energy");
|
|
|
|
sizeNoEnergy= sizeNoEnergyNode->getAttribute("value")->getFloatValue();
|
|
|
|
|
|
|
|
//speed
|
|
|
|
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
|
|
|
speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
|
|
|
|
//gravity
|
|
|
|
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
|
|
|
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
|
|
|
|
//emission rate
|
|
|
|
const XmlNode *emissionRateNode= particleSystemNode->getChild("emission-rate");
|
2010-09-24 18:36:59 +02:00
|
|
|
emissionRate= emissionRateNode->getAttribute("value")->getFloatValue();
|
2010-06-24 12:52:58 +02:00
|
|
|
|
|
|
|
//energy max
|
|
|
|
const XmlNode *energyMaxNode= particleSystemNode->getChild("energy-max");
|
|
|
|
energyMax= energyMaxNode->getAttribute("value")->getIntValue();
|
|
|
|
|
|
|
|
//speed
|
|
|
|
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
|
|
|
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
|
|
|
|
|
|
|
//teamcolorNoEnergy
|
|
|
|
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
|
|
|
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
|
|
|
teamcolorNoEnergy= teamcolorNoEnergyNode->getAttribute("value")->getBoolValue();
|
|
|
|
}
|
|
|
|
//teamcolorEnergy
|
|
|
|
if(particleSystemNode->hasChild("teamcolorEnergy")){
|
|
|
|
const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy");
|
|
|
|
teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//mode
|
|
|
|
if(particleSystemNode->hasChild("mode")){
|
|
|
|
const XmlNode *modeNode= particleSystemNode->getChild("mode");
|
|
|
|
mode= modeNode->getAttribute("value")->getRestrictedValue();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mode="normal";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ParticleSystemType::setValues(AttackParticleSystem *ats){
|
|
|
|
ats->setTexture(texture);
|
|
|
|
ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive));
|
|
|
|
ats->setOffset(offset);
|
|
|
|
ats->setColor(color);
|
|
|
|
ats->setColorNoEnergy(colorNoEnergy);
|
|
|
|
ats->setSpeed(speed);
|
|
|
|
ats->setGravity(gravity);
|
|
|
|
ats->setParticleSize(size);
|
|
|
|
ats->setSizeNoEnergy(sizeNoEnergy);
|
|
|
|
ats->setEmissionRate(emissionRate);
|
|
|
|
ats->setMaxParticleEnergy(energyMax);
|
|
|
|
ats->setVarParticleEnergy(energyVar);
|
|
|
|
ats->setModel(model);
|
|
|
|
ats->setTeamcolorNoEnergy(teamcolorNoEnergy);
|
|
|
|
ats->setTeamcolorEnergy(teamcolorEnergy);
|
|
|
|
ats->setBlendMode(ParticleSystem::strToBlendMode(mode));
|
|
|
|
}
|
|
|
|
|
|
|
|
// ===========================================================
|
|
|
|
// class ParticleSystemTypeProjectile
|
|
|
|
// ===========================================================
|
|
|
|
|
|
|
|
void ParticleSystemTypeProjectile::load(const string &dir, const string &path,RendererInterface *renderer) {
|
|
|
|
|
|
|
|
try{
|
|
|
|
XmlTree xmlTree;
|
|
|
|
xmlTree.load(path);
|
|
|
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
|
|
|
|
|
|
|
ParticleSystemType::load(particleSystemNode, dir, renderer);
|
|
|
|
|
|
|
|
//trajectory values
|
|
|
|
const XmlNode *tajectoryNode= particleSystemNode->getChild("trajectory");
|
|
|
|
trajectory= tajectoryNode->getAttribute("type")->getRestrictedValue();
|
|
|
|
|
|
|
|
//trajectory speed
|
|
|
|
const XmlNode *tajectorySpeedNode= tajectoryNode->getChild("speed");
|
|
|
|
trajectorySpeed= tajectorySpeedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
|
|
|
|
if(trajectory=="parabolic" || trajectory=="spiral"){
|
|
|
|
//trajectory scale
|
|
|
|
const XmlNode *tajectoryScaleNode= tajectoryNode->getChild("scale");
|
|
|
|
trajectoryScale= tajectoryScaleNode->getAttribute("value")->getFloatValue();
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
trajectoryScale= 1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(trajectory=="spiral"){
|
|
|
|
//trajectory frequency
|
|
|
|
const XmlNode *tajectoryFrequencyNode= tajectoryNode->getChild("frequency");
|
|
|
|
trajectoryFrequency= tajectoryFrequencyNode->getAttribute("value")->getFloatValue();
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
trajectoryFrequency= 1.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(const exception &e){
|
2010-10-06 22:22:06 +02:00
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
|
2010-06-24 12:52:58 +02:00
|
|
|
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ProjectileParticleSystem *ParticleSystemTypeProjectile::create() {
|
|
|
|
ProjectileParticleSystem *ps= new ProjectileParticleSystem();
|
|
|
|
|
|
|
|
ParticleSystemType::setValues(ps);
|
|
|
|
|
|
|
|
ps->setTrajectory(ProjectileParticleSystem::strToTrajectory(trajectory));
|
|
|
|
ps->setTrajectorySpeed(trajectorySpeed);
|
|
|
|
ps->setTrajectoryScale(trajectoryScale);
|
|
|
|
ps->setTrajectoryFrequency(trajectoryFrequency);
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ===========================================================
|
|
|
|
// class ParticleSystemTypeSplash
|
|
|
|
// ===========================================================
|
|
|
|
|
|
|
|
void ParticleSystemTypeSplash::load(const string &dir, const string &path,RendererInterface *renderer) {
|
|
|
|
|
|
|
|
try{
|
|
|
|
XmlTree xmlTree;
|
|
|
|
xmlTree.load(path);
|
|
|
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
|
|
|
|
|
|
|
ParticleSystemType::load(particleSystemNode, dir, renderer);
|
|
|
|
|
|
|
|
//emission rate fade
|
|
|
|
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
|
2010-09-24 18:36:59 +02:00
|
|
|
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
|
2010-06-24 12:52:58 +02:00
|
|
|
|
|
|
|
//spread values
|
|
|
|
const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread");
|
|
|
|
verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
|
|
|
verticalSpreadB= verticalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f);
|
|
|
|
|
|
|
|
const XmlNode *horizontalSpreadNode= particleSystemNode->getChild("horizontal-spread");
|
|
|
|
horizontalSpreadA= horizontalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
|
|
|
horizontalSpreadB= horizontalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
catch(const exception &e){
|
2010-10-06 22:22:06 +02:00
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
|
2010-06-24 12:52:58 +02:00
|
|
|
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SplashParticleSystem *ParticleSystemTypeSplash::create(){
|
|
|
|
SplashParticleSystem *ps= new SplashParticleSystem();
|
|
|
|
|
|
|
|
ParticleSystemType::setValues(ps);
|
|
|
|
|
|
|
|
ps->setEmissionRateFade(emissionRateFade);
|
|
|
|
ps->setVerticalSpreadA(verticalSpreadA);
|
|
|
|
ps->setVerticalSpreadB(verticalSpreadB);
|
|
|
|
ps->setHorizontalSpreadA(horizontalSpreadA);
|
|
|
|
ps->setHorizontalSpreadB(horizontalSpreadB);
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
}}//end mamespace
|