mirror of
https://github.com/glest/glest-source.git
synced 2025-08-29 10:49:48 +02:00
- merged in willvarfar's particle patch
This commit is contained in:
@@ -223,7 +223,7 @@ void ParticleRendererGl::renderSystemLineAlpha(ParticleSystem *ps){
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ParticleRendererGl::renderModel(AttackParticleSystem *ps, ModelRenderer *mr){
|
||||
void ParticleRendererGl::renderModel(GameParticleSystem *ps, ModelRenderer *mr){
|
||||
//render model
|
||||
Model *model = ps->getModel();
|
||||
if(model != NULL) {
|
||||
@@ -262,7 +262,9 @@ void ParticleRendererGl::renderModel(AttackParticleSystem *ps, ModelRenderer *mr
|
||||
|
||||
//render
|
||||
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->end();
|
||||
|
||||
|
@@ -135,7 +135,7 @@ ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){
|
||||
return bmOneMinusAlpha;
|
||||
}
|
||||
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){
|
||||
this->state= state;
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
getChild(i)->setState(state);
|
||||
}
|
||||
|
||||
void ParticleSystem::setTexture(Texture *texture){
|
||||
@@ -151,6 +153,8 @@ void ParticleSystem::setTexture(Texture *texture){
|
||||
|
||||
void ParticleSystem::setPos(Vec3f pos){
|
||||
this->pos= pos;
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
getChild(i)->setPos(pos);
|
||||
}
|
||||
|
||||
void ParticleSystem::setColor(Vec4f color){
|
||||
@@ -183,14 +187,22 @@ void ParticleSystem::setSpeed(float speed){
|
||||
|
||||
void ParticleSystem::setActive(bool active){
|
||||
this->active= active;
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
getChild(i)->setActive(active);
|
||||
}
|
||||
|
||||
void ParticleSystem::setObserver(ParticleObserver *particleObserver){
|
||||
this->particleObserver= particleObserver;
|
||||
}
|
||||
|
||||
ParticleSystem* ParticleSystem::getChild(int i){
|
||||
throw std::out_of_range("ParticleSystem::getChild bad");
|
||||
}
|
||||
|
||||
void ParticleSystem::setVisible(bool visible){
|
||||
this->visible= visible;
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
getChild(i)->setVisible(visible);
|
||||
}
|
||||
|
||||
// =============== MISC =========================
|
||||
@@ -209,6 +221,8 @@ void ParticleSystem::fade(){
|
||||
if(particleObserver != NULL){
|
||||
particleObserver->update(this);
|
||||
}
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
getChild(i)->fade();
|
||||
}
|
||||
|
||||
int ParticleSystem::isEmpty() const{
|
||||
@@ -297,6 +311,8 @@ void ParticleSystem::setFactionColor(Vec3f factionColor){
|
||||
if(teamcolorNoEnergy){
|
||||
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
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// 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
|
||||
// ===========================================================================
|
||||
bool UnitParticleSystem::isNight= false;
|
||||
|
||||
UnitParticleSystem::UnitParticleSystem(int particleCount) :
|
||||
ParticleSystem(particleCount){
|
||||
UnitParticleSystem::UnitParticleSystem(int particleCount):
|
||||
GameParticleSystem(particleCount),
|
||||
parent(NULL){
|
||||
radius= 0.5f;
|
||||
speed= 0.01f;
|
||||
windSpeed= Vec3f(0.0f);
|
||||
@@ -393,8 +528,6 @@ UnitParticleSystem::UnitParticleSystem(int particleCount) :
|
||||
setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f));
|
||||
|
||||
primitive= pQuad;
|
||||
offset= Vec3f(0.0f);
|
||||
direction= Vec3f(0.0f, 1.0f, 0.0f);
|
||||
gravity= 0.0f;
|
||||
|
||||
fixed= false;
|
||||
@@ -413,6 +546,15 @@ UnitParticleSystem::UnitParticleSystem(int particleCount) :
|
||||
emissionState= (float) staticParticleCount;
|
||||
}
|
||||
energyUp= false;
|
||||
|
||||
delay = 0; // none
|
||||
lifetime = -1; // forever
|
||||
}
|
||||
|
||||
UnitParticleSystem::~UnitParticleSystem(){
|
||||
if(parent){
|
||||
parent->removeChild(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool UnitParticleSystem::getVisible() const{
|
||||
@@ -425,54 +567,48 @@ bool UnitParticleSystem::getVisible() const{
|
||||
else return false;
|
||||
}
|
||||
|
||||
void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
|
||||
//if(active){
|
||||
switch(primitive){
|
||||
case pQuad:
|
||||
pr->renderSystem(this);
|
||||
break;
|
||||
case pLine:
|
||||
pr->renderSystemLine(this);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
//}
|
||||
void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) {
|
||||
GameParticleSystem::render(pr,mr);
|
||||
}
|
||||
|
||||
UnitParticleSystem::Primitive UnitParticleSystem::strToPrimitive(const string &str){
|
||||
if(str == "quad"){
|
||||
return pQuad;
|
||||
void UnitParticleSystem::setRotation(float rotation){
|
||||
this->rotation= rotation;
|
||||
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{
|
||||
throw "Unknown particle primitive: " + str;
|
||||
throw runtime_error("Unkown particle shape: " + str);
|
||||
}
|
||||
}
|
||||
|
||||
void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||
ParticleSystem::initParticle(p, particleIndex);
|
||||
|
||||
float ang= random.randRange(-2.0f * pi, 2.0f * pi);
|
||||
#ifdef USE_STREFLOP
|
||||
float mod= streflop::fabsf(random.randRange(-radius, radius));
|
||||
|
||||
float x= streflop::sinf(ang)*mod;
|
||||
float y= streflop::cosf(ang)*mod;
|
||||
|
||||
float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius));
|
||||
const float ang= random.randRange(-2.0f * pi, 2.0f * pi);
|
||||
#ifdef USE_STREFLOP
|
||||
const float mod= streflop::fabsf(random.randRange(-radius, radius));
|
||||
const float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius));
|
||||
#else
|
||||
float mod= fabsf(random.randRange(-radius, radius));
|
||||
|
||||
float x= sinf(ang) * mod;
|
||||
float y= cosf(ang) * mod;
|
||||
|
||||
float radRatio= sqrtf(sqrtf(mod / radius));
|
||||
const float mod= fabsf(random.randRange(-radius, radius));
|
||||
const float radRatio= sqrtf(sqrtf(mod / radius));
|
||||
#endif
|
||||
|
||||
//p->color= color*0.5f + color*0.5f*radRatio;
|
||||
p->color= color;
|
||||
if(radiusBasedStartenergy == true){
|
||||
p->energy= static_cast<int> (maxParticleEnergy * radRatio) + random.randRange(-varParticleEnergy,
|
||||
@@ -485,36 +621,72 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||
p->lastPos= pos;
|
||||
oldPosition= pos;
|
||||
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);
|
||||
|
||||
if(relative == false){
|
||||
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
|
||||
float rad= degToRad(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)));
|
||||
if(relativeDirection){
|
||||
|
||||
// work out where we start for our shape (set speed and pos)
|
||||
switch(shape){
|
||||
case sSpherical:
|
||||
angle = random.randRange(0,360);
|
||||
// fall through
|
||||
case sConical:{
|
||||
Vec2f horiz = Vec2f(1,0).rotate(ang);
|
||||
Vec2f vert = Vec2f(1,0).rotate(degToRad(angle));
|
||||
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)));
|
||||
}
|
||||
#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){
|
||||
#else
|
||||
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
|
||||
}
|
||||
|
||||
#endif
|
||||
} break;
|
||||
default: throw runtime_error("bad shape");
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
fixedAddition= Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z);
|
||||
oldPosition= pos;
|
||||
@@ -573,10 +745,6 @@ void UnitParticleSystem::updateParticle(Particle *p){
|
||||
|
||||
// ================= SET PARAMS ====================
|
||||
|
||||
void UnitParticleSystem::setRadius(float radius){
|
||||
this->radius= radius;
|
||||
}
|
||||
|
||||
void UnitParticleSystem::setWind(float windAngle, float windSpeed){
|
||||
#ifdef USE_STREFLOP
|
||||
this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed;
|
||||
@@ -700,43 +868,9 @@ void SnowParticleSystem::setWind(float windAngle, float windSpeed){
|
||||
// ===========================================================================
|
||||
|
||||
AttackParticleSystem::AttackParticleSystem(int particleCount) :
|
||||
ParticleSystem(particleCount){
|
||||
model= NULL;
|
||||
GameParticleSystem(particleCount){
|
||||
primitive= pQuad;
|
||||
offset= Vec3f(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(){
|
||||
|
||||
if(state == sPlay){
|
||||
|
||||
lastPos= pos;
|
||||
@@ -785,19 +918,7 @@ void ProjectileParticleSystem::update(){
|
||||
|
||||
// ratio
|
||||
float t= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f);
|
||||
|
||||
// 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);
|
||||
}
|
||||
setTween(t,currentVector.length());
|
||||
|
||||
// trajectory
|
||||
switch(trajectory) {
|
||||
@@ -833,10 +954,13 @@ void ProjectileParticleSystem::update(){
|
||||
|
||||
direction= pos - lastPos;
|
||||
direction.normalize();
|
||||
// trigger update of child particles
|
||||
positionChildren();
|
||||
rotateChildren();
|
||||
|
||||
//arrive destination
|
||||
if(flatPos.dist(endPos) < 0.5f){
|
||||
state= sFade;
|
||||
fade();
|
||||
model= NULL;
|
||||
|
||||
if(particleObserver != NULL){
|
||||
@@ -854,6 +978,18 @@ void ProjectileParticleSystem::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){
|
||||
|
||||
ParticleSystem::initParticle(p, particleIndex);
|
||||
@@ -906,6 +1042,11 @@ void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos){
|
||||
// set members
|
||||
this->startPos= startPos;
|
||||
this->endPos= endPos;
|
||||
|
||||
// direction
|
||||
direction = (endPos - lastPos);
|
||||
direction.normalize();
|
||||
rotateChildren();
|
||||
}
|
||||
|
||||
ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){
|
||||
@@ -919,7 +1060,7 @@ ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(c
|
||||
return tSpiral;
|
||||
}
|
||||
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) {
|
||||
emissionRate-= emissionRateFade;
|
||||
|
||||
tween= 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f));
|
||||
tween= clamp(tween, 0.0f, 1.0f);
|
||||
float t= 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f));
|
||||
t= clamp(t, 0.0f, 1.0f);
|
||||
setTween(t,t);
|
||||
|
||||
if(emissionRate < 0.0f) {//otherwise this system lives forever!
|
||||
fade();
|
||||
@@ -1132,7 +1274,10 @@ void ParticleManager::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &p
|
||||
}
|
||||
|
||||
void ParticleManager::manage(ParticleSystem *ps){
|
||||
assert((std::find(particleSystems.begin(),particleSystems.end(),ps) == particleSystems.end()) && "particle cannot be added twice");
|
||||
particleSystems.push_back(ps);
|
||||
for(int i=ps->getChildCount()-1; i>=0; i--)
|
||||
manage(ps->getChild(i));
|
||||
}
|
||||
|
||||
void ParticleManager::end(){
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace Shared { namespace PlatformCommon {
|
||||
|
||||
Mutex CacheManager::mutexCache;
|
||||
//Mutex CacheManager::mutexCache;
|
||||
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1";
|
||||
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2";
|
||||
const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1";
|
||||
|
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "conversion.h"
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
@@ -23,6 +25,7 @@
|
||||
#include "properties.h"
|
||||
#include "platform_common.h"
|
||||
#include "platform_util.h"
|
||||
#include "cache_manager.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
|
||||
@@ -172,7 +175,26 @@ void XmlTree::init(const string &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) {
|
||||
//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);
|
||||
}
|
||||
|
||||
@@ -180,7 +202,17 @@ void XmlTree::save(const string &path){
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -188,7 +220,7 @@ XmlTree::~XmlTree(){
|
||||
// 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -269,6 +301,7 @@ XmlAttribute *XmlNode::getAttribute(const string &name,bool mustExist) const {
|
||||
}
|
||||
|
||||
XmlNode *XmlNode::getChild(unsigned int i) const {
|
||||
assert(!superNode);
|
||||
if(i >= children.size()) {
|
||||
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{
|
||||
if(superNode && !hasChildNoSuper(childName))
|
||||
return superNode->getChild(childName,i);
|
||||
if(i>=children.size()){
|
||||
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 {
|
||||
if(superNode && !hasChildNoSuper(childName))
|
||||
return superNode->hasChildAtIndex(childName,i);
|
||||
int count= 0;
|
||||
for(unsigned int j = 0; j < children.size(); ++j) {
|
||||
if(children[j]->getName()==childName) {
|
||||
@@ -318,19 +355,22 @@ bool XmlNode::hasChildAtIndex(const string &childName, int i) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool XmlNode::hasChild(const string &childName) const {
|
||||
return hasChildNoSuper(childName) || (superNode && superNode->hasChild(childName));
|
||||
}
|
||||
|
||||
bool XmlNode::hasChildNoSuper(const string &childName) const {
|
||||
int count= 0;
|
||||
for(unsigned int j = 0; j < children.size(); ++j) {
|
||||
if(children[j]->getName() == childName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlNode *XmlNode::addChild(const string &name){
|
||||
assert(!superNode);
|
||||
XmlNode *node= new XmlNode(name);
|
||||
children.push_back(node);
|
||||
return node;
|
||||
|
Reference in New Issue
Block a user