- added the ability to synch unit particles with model animation using start-time and end-time attributes

This commit is contained in:
Mark Vejvoda 2011-08-27 06:52:17 +00:00
parent c8f25c95f3
commit d99a8236ae
10 changed files with 141 additions and 7 deletions

View File

@ -103,6 +103,8 @@ public:
void setMaxHp(int value) { maxHp=value;} void setMaxHp(int value) { maxHp=value;}
void setMinmaxIsPercent(bool value) { minmaxIsPercent=value; } void setMinmaxIsPercent(bool value) { minmaxIsPercent=value; }
string getType() const { return type; };
protected: protected:
}; };

View File

@ -30,6 +30,24 @@ namespace Glest{ namespace Game{
// ===================================================== // =====================================================
// class UnitParticleSystemType // class UnitParticleSystemType
// ===================================================== // =====================================================
UnitParticleSystemType::UnitParticleSystemType() : ParticleSystemType() {
shape = UnitParticleSystem::sLinear;
angle = 0;
radius = 0;
minRadius = 0;
emissionRateFade = 0;
relative = false;
relativeDirection = false;
fixed = false;
staticParticleCount = 0;
isVisibleAtNight = false;
isVisibleAtDay = false;
radiusBasedStartenergy = false;
delay = 0;
lifetime = 0;
startTime = 0;
endTime = 1;
}
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,
@ -217,6 +235,9 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
direction.z= 0.0f; direction.z= 0.0f;
ups->setDirection(direction); ups->setDirection(direction);
} }
ups->setStartTime(startTime);
ups->setEndTime(endTime);
} }
void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path, void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path,

View File

@ -61,14 +61,24 @@ protected:
bool radiusBasedStartenergy; bool radiusBasedStartenergy;
int delay; int delay;
int lifetime; int lifetime;
float startTime;
float endTime;
public: public:
UnitParticleSystemType();
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 XmlNode *particleFileNode, 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);
void setStartTime(float startTime) { this->startTime = startTime; }
float getStartTime() const { return this->startTime; }
void setEndTime(float endTime) { this->endTime = endTime; }
float getEndTime() const { return this->endTime; }
const void setValues (UnitParticleSystem *uts); const void setValues (UnitParticleSystem *uts);
bool hasTexture() const { return(texture != NULL); } bool hasTexture() const { return(texture != NULL); }
}; };

View File

@ -382,6 +382,7 @@ Unit::~Unit() {
} }
// fade(and by this remove) all unit particle systems // fade(and by this remove) all unit particle systems
queuedUnitParticleSystemTypes.clear();
while(unitParticleSystems.empty() == false) { while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade(); unitParticleSystems.back()->fade();
unitParticleSystems.pop_back(); unitParticleSystems.pop_back();
@ -753,10 +754,12 @@ void Unit::setCurrSkill(const SkillType *currSkill) {
throw runtime_error(szBuf); throw runtime_error(szBuf);
} }
if(currSkill->getClass() != this->currSkill->getClass()) { if(currSkill->getClass() != this->currSkill->getClass() ||
currSkill->getName() != this->currSkill->getName()) {
animProgress= 0; animProgress= 0;
lastAnimProgress= 0; lastAnimProgress= 0;
queuedUnitParticleSystemTypes.clear();
while(unitParticleSystems.empty() == false) { while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade(); unitParticleSystems.back()->fade();
unitParticleSystems.pop_back(); unitParticleSystems.pop_back();
@ -764,13 +767,24 @@ void Unit::setCurrSkill(const SkillType *currSkill) {
} }
if(showUnitParticles && (currSkill->unitParticleSystemTypes.empty() == false) && if(showUnitParticles && (currSkill->unitParticleSystemTypes.empty() == false) &&
(unitParticleSystems.empty() == true) ) { (unitParticleSystems.empty() == true) ) {
//printf("START - particle system type\n");
for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) { for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) {
UnitParticleSystem *ups = new UnitParticleSystem(200); if((*it)->getStartTime() == 0.0) {
(*it)->setValues(ups); //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime());
ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); UnitParticleSystem *ups = new UnitParticleSystem(200);
unitParticleSystems.push_back(ups); (*it)->setValues(ups);
Renderer::getInstance().manageParticleSystem(ups, rsGame); ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
unitParticleSystems.push_back(ups);
Renderer::getInstance().manageParticleSystem(ups, rsGame);
}
else {
//printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime());
queuedUnitParticleSystemTypes.push_back(*it);
}
} }
} }
progress2= 0; progress2= 0;
@ -1398,6 +1412,50 @@ bool Unit::needToUpdate() {
return return_value; return return_value;
} }
void Unit::updateTimedParticles() {
//!!!
// Start new particle systems based on start time
for(int i = queuedUnitParticleSystemTypes.size() - 1; i >= 0; i--) {
UnitParticleSystemType *pst = queuedUnitParticleSystemTypes[i];
if(pst != NULL) {
if(truncateDecimal<float>(pst->getStartTime()) <= truncateDecimal<float>(animProgress)) {
//printf("STARTING queued particle system type [%s] [%f] [%f] [%f] [%f]\n",pst->getType().c_str(),truncateDecimal<float>(pst->getStartTime()),truncateDecimal<float>(pst->getEndTime()),truncateDecimal<float>(animProgress),truncateDecimal<float>(lastAnimProgress));
UnitParticleSystem *ups = new UnitParticleSystem(200);
pst->setValues(ups);
ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
unitParticleSystems.push_back(ups);
Renderer::getInstance().manageParticleSystem(ups, rsGame);
queuedUnitParticleSystemTypes.erase(queuedUnitParticleSystemTypes.begin() + i);
}
}
else {
queuedUnitParticleSystemTypes.erase(queuedUnitParticleSystemTypes.begin() + i);
}
}
// End existing systems based on end time
for(int i = unitParticleSystems.size() - 1; i >= 0; i--) {
UnitParticleSystem *ps = unitParticleSystems[i];
if(ps != NULL) {
if(truncateDecimal<float>(ps->getStartTime()) != 0.0 || truncateDecimal<float>(ps->getEndTime()) != 1.0) {
//printf("Checking for end particle system #%d [%d] [%f] [%f] [%f] [%f]\n",i,ps->shape,truncateDecimal<float>(ps->getStartTime()),truncateDecimal<float>(ps->getEndTime()),truncateDecimal<float>(animProgress),truncateDecimal<float>(lastAnimProgress));
if(truncateDecimal<float>(animProgress) >= 0.99 ||
truncateDecimal<float>(animProgress) >= truncateDecimal<float>(ps->getEndTime())) {
//printf("ENDING particle system [%d]\n",ps->shape);
ps->fade();
unitParticleSystems.erase(unitParticleSystems.begin() + i);
}
}
}
}
}
bool Unit::update() { bool Unit::update() {
assert(progress <= 1.f); assert(progress <= 1.f);

View File

@ -330,6 +330,8 @@ private:
Commands commands; Commands commands;
Observers observers; Observers observers;
vector<UnitParticleSystem*> unitParticleSystems; vector<UnitParticleSystem*> unitParticleSystems;
vector<UnitParticleSystemType*> queuedUnitParticleSystemTypes;
UnitParticleSystems damageParticleSystems; UnitParticleSystems damageParticleSystems;
std::map<int, UnitParticleSystem *> damageParticleSystemsInUse; std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
@ -579,6 +581,7 @@ public:
bool getUsePathfinderExtendedMaxNodes() const { return usePathfinderExtendedMaxNodes; } bool getUsePathfinderExtendedMaxNodes() const { return usePathfinderExtendedMaxNodes; }
void setUsePathfinderExtendedMaxNodes(bool value) { usePathfinderExtendedMaxNodes = value; } void setUsePathfinderExtendedMaxNodes(bool value) { usePathfinderExtendedMaxNodes = value; }
void updateTimedParticles();
private: private:
float computeHeight(const Vec2i &pos) const; float computeHeight(const Vec2i &pos) const;
void calculateXZRotation(); void calculateXZRotation();

View File

@ -226,6 +226,16 @@ void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt,
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType(); UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(), unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath()); loadedFileList,parentLoader,tt->getPath());
if(particleNode->getAttribute("start-time",false) != NULL) {
//printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue());
unitParticleSystemType->setStartTime(particleNode->getAttribute("start-time")->getFloatValue());
}
if(particleNode->getAttribute("end-time",false) != NULL) {
//printf("*NOTE particle system type has end-time [%f]\n",particleNode->getAttribute("end-time")->getFloatValue());
unitParticleSystemType->setEndTime(particleNode->getAttribute("end-time")->getFloatValue());
}
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);
} }

View File

@ -133,6 +133,10 @@ void UnitUpdater::updateUnit(Unit *unit) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
unit->updateTimedParticles();
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//start attack particle system //start attack particle system
if(unit->getCurrSkill()->getClass() == scAttack) { if(unit->getCurrSkill()->getClass() == scAttack) {
const AttackSkillType *ast= static_cast<const AttackSkillType*>(unit->getCurrSkill()); const AttackSkillType *ast= static_cast<const AttackSkillType*>(unit->getCurrSkill());

View File

@ -12,6 +12,7 @@
#ifndef _SHARED_GRAPHICS_MATHUTIL_H_ #ifndef _SHARED_GRAPHICS_MATHUTIL_H_
#define _SHARED_GRAPHICS_MATHUTIL_H_ #define _SHARED_GRAPHICS_MATHUTIL_H_
#include "math_wrapper.h"
#include "vec.h" #include "vec.h"
#include "leak_dumper.h" #include "leak_dumper.h"
@ -266,6 +267,21 @@ inline T radToDeg(T rad){
return (rad*360)/(2*pi); return (rad*360)/(2*pi);
} }
template<typename T>
inline T truncateDecimal(const T &value, int precision=6) {
int iSigned = value >= 0 ? 1: -1;
#ifdef USE_STREFLOP
unsigned int uiTemp = (value * streflop::pow((streflop::Simple)10, (streflop::Simple)precision)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
T result = (((double)uiTemp) / streflop::pow((streflop::Simple)10,(streflop::Simple)precision) * iSigned);
#else
unsigned int uiTemp = (value * pow(10, precision)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
T result = (((double)uiTemp) / pow(10,precision) * iSigned);
#endif
return result;
}
}}//end namespace }}//end namespace
#endif #endif

View File

@ -277,6 +277,8 @@ private:
Vec3f fixedAddition; Vec3f fixedAddition;
Vec3f oldPosition; Vec3f oldPosition;
bool energyUp; bool energyUp;
float startTime;
float endTime;
public: public:
enum Shape{ enum Shape{
@ -315,6 +317,11 @@ public:
virtual void fade(); virtual void fade();
virtual void render(ParticleRenderer *pr, ModelRenderer *mr); virtual void render(ParticleRenderer *pr, ModelRenderer *mr);
virtual void setStartTime(float startTime) { this->startTime = startTime; }
virtual float getStartTime() const { return this->startTime; }
virtual void setEndTime(float endTime) { this->endTime = endTime; }
virtual float getEndTime() const { return this->endTime; }
//set params //set params
void setRadius(float radius) {this->radius= radius;} void setRadius(float radius) {this->radius= radius;}
void setMinRadius(float minRadius) {this->minRadius= minRadius;} void setMinRadius(float minRadius) {this->minRadius= minRadius;}

View File

@ -553,6 +553,9 @@ UnitParticleSystem::UnitParticleSystem(int particleCount):
delay = 0; // none delay = 0; // none
lifetime = -1; // forever lifetime = -1; // forever
startTime = 0;
endTime = 1;
} }
UnitParticleSystem::~UnitParticleSystem(){ UnitParticleSystem::~UnitParticleSystem(){