- added the ability to synch unit particles with model animation using start-time and end-time attributes
This commit is contained in:
parent
c8f25c95f3
commit
d99a8236ae
|
@ -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:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
|
@ -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(){
|
||||||
|
|
Loading…
Reference in New Issue