- 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 setMinmaxIsPercent(bool value) { minmaxIsPercent=value; }
string getType() const { return type; };
protected:
};

View File

@ -30,6 +30,24 @@ namespace Glest{ namespace Game{
// =====================================================
// 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,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
@ -217,6 +235,9 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
direction.z= 0.0f;
ups->setDirection(direction);
}
ups->setStartTime(startTime);
ups->setEndTime(endTime);
}
void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path,

View File

@ -61,14 +61,24 @@ protected:
bool radiusBasedStartenergy;
int delay;
int lifetime;
float startTime;
float endTime;
public:
UnitParticleSystemType();
void load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *newTexture, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath);
void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *newTexture,
std::map<string,vector<pair<string, string> > > &loadedFileList,string parentLoader,
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);
bool hasTexture() const { return(texture != NULL); }
};

View File

@ -382,6 +382,7 @@ Unit::~Unit() {
}
// fade(and by this remove) all unit particle systems
queuedUnitParticleSystemTypes.clear();
while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade();
unitParticleSystems.pop_back();
@ -753,10 +754,12 @@ void Unit::setCurrSkill(const SkillType *currSkill) {
throw runtime_error(szBuf);
}
if(currSkill->getClass() != this->currSkill->getClass()) {
if(currSkill->getClass() != this->currSkill->getClass() ||
currSkill->getName() != this->currSkill->getName()) {
animProgress= 0;
lastAnimProgress= 0;
queuedUnitParticleSystemTypes.clear();
while(unitParticleSystems.empty() == false) {
unitParticleSystems.back()->fade();
unitParticleSystems.pop_back();
@ -764,13 +767,24 @@ void Unit::setCurrSkill(const SkillType *currSkill) {
}
if(showUnitParticles && (currSkill->unitParticleSystemTypes.empty() == false) &&
(unitParticleSystems.empty() == true) ) {
//printf("START - particle system type\n");
for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) {
UnitParticleSystem *ups = new UnitParticleSystem(200);
(*it)->setValues(ups);
ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
unitParticleSystems.push_back(ups);
Renderer::getInstance().manageParticleSystem(ups, rsGame);
if((*it)->getStartTime() == 0.0) {
//printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime());
UnitParticleSystem *ups = new UnitParticleSystem(200);
(*it)->setValues(ups);
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;
@ -1398,6 +1412,50 @@ bool Unit::needToUpdate() {
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() {
assert(progress <= 1.f);

View File

@ -330,6 +330,8 @@ private:
Commands commands;
Observers observers;
vector<UnitParticleSystem*> unitParticleSystems;
vector<UnitParticleSystemType*> queuedUnitParticleSystemTypes;
UnitParticleSystems damageParticleSystems;
std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
@ -579,6 +581,7 @@ public:
bool getUsePathfinderExtendedMaxNodes() const { return usePathfinderExtendedMaxNodes; }
void setUsePathfinderExtendedMaxNodes(bool value) { usePathfinderExtendedMaxNodes = value; }
void updateTimedParticles();
private:
float computeHeight(const Vec2i &pos) const;
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->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
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()));
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());
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
if(unit->getCurrSkill()->getClass() == scAttack) {
const AttackSkillType *ast= static_cast<const AttackSkillType*>(unit->getCurrSkill());

View File

@ -12,6 +12,7 @@
#ifndef _SHARED_GRAPHICS_MATHUTIL_H_
#define _SHARED_GRAPHICS_MATHUTIL_H_
#include "math_wrapper.h"
#include "vec.h"
#include "leak_dumper.h"
@ -266,6 +267,21 @@ inline T radToDeg(T rad){
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
#endif

View File

@ -277,6 +277,8 @@ private:
Vec3f fixedAddition;
Vec3f oldPosition;
bool energyUp;
float startTime;
float endTime;
public:
enum Shape{
@ -315,6 +317,11 @@ public:
virtual void fade();
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
void setRadius(float radius) {this->radius= radius;}
void setMinRadius(float minRadius) {this->minRadius= minRadius;}

View File

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