diff options
| -rw-r--r-- | src/model/classes.cc | 2 | ||||
| -rw-r--r-- | src/model/classes.h | 14 | ||||
| -rw-r--r-- | src/model/map.cc | 6 | ||||
| -rw-r--r-- | src/render/particles.cc | 214 | ||||
| -rw-r--r-- | src/render/particles.h | 18 | ||||
| -rw-r--r-- | src/render/renderext.cc | 7 | 
6 files changed, 245 insertions, 16 deletions
| diff --git a/src/model/classes.cc b/src/model/classes.cc index 4042c38..06ebda3 100644 --- a/src/model/classes.cc +++ b/src/model/classes.cc @@ -43,6 +43,8 @@ Flare::~Flare()  Particles::Particles() :  	particles_location()  { +	particles_entity = false; +	particles_engine = false;  }  Particles::Particles(math::Vector3f const & location) : diff --git a/src/model/classes.h b/src/model/classes.h index 175070a..a0e9d1f 100644 --- a/src/model/classes.h +++ b/src/model/classes.h @@ -147,15 +147,21 @@ public:  		return particles_script;  	} -	inline const float radius() const +	inline bool entity() const +	{ +		return particles_entity; +	} + +	inline bool engine() const  	{ -		return particles_radius; +		return particles_engine;  	} -		  	std::string		particles_script;  	math::Vector3f		particles_location;  	math::Axis		particles_axis; -	float			particles_radius; + +	bool			particles_entity; +	bool			particles_engine;  };  /* ---- class Dock ------------------------------------------------- */ diff --git a/src/model/map.cc b/src/model/map.cc index 618fd51..f2c519f 100644 --- a/src/model/map.cc +++ b/src/model/map.cc @@ -989,7 +989,11 @@ Model * Map::load(std::string const &name)  			} else if (mapfile.got_key_float("roll", angle)) {  				particles->particles_axis.change_roll(angle); -/* + +			} else if (mapfile.got_key_int("spawnflags", u)) { +				particles->particles_entity = spawnflag_isset(u, 2); +				particles->particles_engine = spawnflag_isset(u, 4); +/*	  			} else if (mapfile.got_key_float("radius", particles->particles_radius)) {  				particles->particles_radius *= LIGHTSCALE;  */ diff --git a/src/render/particles.cc b/src/render/particles.cc index c232ca1..f9271ab 100644 --- a/src/render/particles.cc +++ b/src/render/particles.cc @@ -112,6 +112,9 @@ void ParticleScript::init()  					continue;  				} else if (inifile.got_key_float("speed", script->particles_speed)) {  					continue; +				} else if (inifile.got_key_float("offset", script->particles_offset)) { +					math::clamp(script->particles_offset, 0.0f, 1.0f); +					continue;  				} else if (inifile.got_key_float("alpha", script->particles_alpha)) {  					continue;  				} else if (inifile.got_key_float("radius", script->particles_radius)) { @@ -159,6 +162,8 @@ ParticleScript::ParticleScript()  	particles_timeout = 2.0f;  	particles_eject = 0.25f; +	particles_offset = 0.1f; +  	particles_color.assign(1.0f, 1.0f);  } @@ -168,8 +173,7 @@ ParticleScript::~ParticleScript()  /* ---- class ParticleSystem --------------------------------------- */ -ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) : -		particlesystem_location(location) +ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, model::Particles *modelclass)  {  	particlesystem_entity = entity;  	particlesystem_last_eject = 0; // timestamp of the last eject @@ -177,10 +181,24 @@ ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, con  	particlesystem_script = script;  	particlesystem_texture = 0; +	particlesystem_modelclass = modelclass; +  	if (particlesystem_script) {  		particlesystem_texture = Textures::load("textures/" + particlesystem_script->texture()); +		 +		radius = particlesystem_script->radius();  		color.assign(particlesystem_script->color());  	} + +	if (particlesystem_modelclass) { +		particlesystem_location.assign(modelclass->location()); +		if (modelclass->entity()) { +			color.assign(entity->color()); +		} +		if (modelclass->engine()) { +			color.assign(entity->model()->enginecolor()); +		} +	}  }  ParticleSystem::~ParticleSystem() @@ -249,8 +267,8 @@ void ParticleSystem::draw(float elapsed)  /* ---- class Jet -------------------------------------------------- */ -Jet::Jet(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) : -		ParticleSystem(script, entity, location) { +Jet::Jet(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : +		ParticleSystem(script, entity, modelclass) {  }  Jet::~Jet() @@ -309,8 +327,8 @@ void Jet::draw(float elapsed) {  /* ---- class Trail ------------------------------------------------ */ -Trail::Trail(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) : -		ParticleSystem(script, entity, location) { +Trail::Trail(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : +		ParticleSystem(script, entity, modelclass) {  }  Trail::~Trail() @@ -340,6 +358,7 @@ void Trail::draw(float elapsed) {  			fp = tp / (0.9f * particlesystem_script->timeout());  			fp = 1.0 - fp;  		} +		tp = (now - (*first)->time()) / particlesystem_script->timeout();  		if (tp > 0) {  			color.a = 0.0f; @@ -373,6 +392,7 @@ void Trail::draw(float elapsed) {  				f = t / (0.9f * particlesystem_script->timeout());  				f = 1.0 - f;  			} +			t = (now - (*next)->time()) / particlesystem_script->timeout();  			color.a = fp * particlesystem_script->alpha();  			gl::color(color); @@ -402,4 +422,186 @@ void Trail::draw(float elapsed) {  	}  } +/* ---- class Flame ------------------------------------------------ */ + +Flame::Flame(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : +		ParticleSystem(script, entity, modelclass) { +} + +Flame::~Flame() +{} + +void Flame::draw(float elapsed) { + +	if (!particlesystem_script) +		return; + +	ParticleSystem::draw(elapsed);	 + +	if (particlesystem_stream.size() > 1) { +		 +		Textures::bind(particlesystem_texture); +		gl::begin(gl::Quads); + +		Stream::iterator first = particlesystem_stream.begin(); + +		float tp = now - (*first)->time(); +		float fp = 0; + +		if (tp < particlesystem_script->timeout() * particlesystem_script->offset()) { +			fp = tp / (particlesystem_script->offset() * particlesystem_script->timeout()); +		} else { +			tp = tp - particlesystem_script->timeout() * particlesystem_script->offset(); +			fp = tp / ((1.0f - particlesystem_script->offset()) * particlesystem_script->timeout()); +			fp = 1.0 - fp; +		} +		tp = (now - (*first)->time()) / particlesystem_script->timeout(); + +		Stream::iterator next = first; +		if (tp > 0) { +			color.a = 0; +			gl::color(color); +			glTexCoord2f(1,0); +			gl::vertex(ejector_location); +			glTexCoord2f(0,0); +			gl::vertex(ejector_location); + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,tp); +			gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * fp); +			glTexCoord2f(1,tp); +			gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * fp); +			Stats::quads++; + +			color.a = 0; +			gl::color(color); +			glTexCoord2f(1,0); +			gl::vertex(ejector_location); +			glTexCoord2f(0,0); +			gl::vertex(ejector_location); + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,tp); +			gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * fp); +			glTexCoord2f(1,tp); +			gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * fp); +			Stats::quads++; + +			color.a = 0; +			gl::color(color); +			glTexCoord2f(1,0); +			gl::vertex(ejector_location); +			glTexCoord2f(0,0); +			gl::vertex(ejector_location); + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,tp); +			gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * fp); +			glTexCoord2f(1,tp); +			gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * fp); +			Stats::quads++; + +			color.a = 0; +			gl::color(color); +			glTexCoord2f(1,0); +			gl::vertex(ejector_location); +			glTexCoord2f(0,0); +			gl::vertex(ejector_location); + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,tp); +			gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * fp); +			glTexCoord2f(1,tp); +			gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * fp); +			Stats::quads++; +		} + +		for (next++; next != particlesystem_stream.end(); next++) { + +			float t = now - (*next)->time(); +			float f = 0; + +			if (t < particlesystem_script->timeout() * particlesystem_script->offset()) { +				f = t / (particlesystem_script->offset() * particlesystem_script->timeout()); +			} else { +				t = t - particlesystem_script->timeout() * particlesystem_script->offset(); +				f = t / ((1.0f - particlesystem_script->offset()) * particlesystem_script->timeout()); +				f = 1.0 - f; +			} +			t = (now - (*next)->time()) / particlesystem_script->timeout(); + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(1,tp); +			gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_script->radius() * fp); +			glTexCoord2f(0,tp); +			gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_script->radius() * fp); + +			color.a = f * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,t); +			gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * f); +			glTexCoord2f(1,t); +			gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * f); +			Stats::quads++; + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(1,tp); +			gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_script->radius() * fp); +			glTexCoord2f(0,tp); +			gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_script->radius() * fp); + +			color.a = f * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,t); +			gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * f); +			glTexCoord2f(1,t); +			gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * f); +			Stats::quads++; + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(1,tp); +			gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_script->radius() * fp); +			glTexCoord2f(0,tp); +			gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_script->radius() * fp); + +			color.a = f * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,t); +			gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * f); +			glTexCoord2f(1,t); +			gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * f); +			Stats::quads++; + +			color.a = fp * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(1,tp); +			gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_script->radius() * fp); +			glTexCoord2f(0,tp); +			gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_script->radius() * fp); + +			color.a = f * particlesystem_script->alpha(); +			gl::color(color); +			glTexCoord2f(0,t); +			gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * f); +			glTexCoord2f(1,t); +			gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * f); +			Stats::quads++; + +			first = next; +			fp = f; +			tp = t; +		} + + +		gl::end(); +	} +} +  } // namespace render diff --git a/src/render/particles.h b/src/render/particles.h index 0044832..9c9d44b 100644 --- a/src/render/particles.h +++ b/src/render/particles.h @@ -13,6 +13,7 @@  #include "math/color.h"  #include "math/vector3f.h"  #include "core/entity.h" +#include "model/classes.h"  namespace render { @@ -64,6 +65,8 @@ public:  	inline float alpha() const { return particles_alpha; } +	inline float offset() const { return particles_offset; } +  	static ParticleScript *find(const std::string &label);  	static void init(); @@ -84,6 +87,7 @@ private:  	float		particles_eject;  	float 		particles_speed;  	float		particles_alpha; +	float		particles_offset;  	typedef std::map<std::string, ParticleScript *> Registry; @@ -95,7 +99,7 @@ private:  /// abstract base class for a particle system attached to an entity  class ParticleSystem {  public: -	ParticleSystem(ParticleScript *script, core::Entity *entity, const math::Vector3f &location); +	ParticleSystem(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);  	virtual ~ParticleSystem();  	/// index of the texture to use @@ -136,8 +140,11 @@ protected:  	math::Vector3f  ejector_location;  	bool		ejector_active; +	float		radius;  	float		now;  	math::Color	color; +	 +	model::Particles *particlesystem_modelclass;  };  /* ---- class Flame ------------------------------------------------ */ @@ -145,6 +152,11 @@ protected:  /// flame style particles, like engine flames  class Flame : public ParticleSystem  { +public: +	Flame(ParticleScript *script, core::Entity *entity, model::Particles *modelclass); +	virtual ~Flame(); +	 +	virtual void draw(float elapsed);  };  /* ---- class Jet -------------------------------------------------- */ @@ -153,7 +165,7 @@ class Flame : public ParticleSystem  class Jet : public ParticleSystem  {  public: -	Jet(ParticleScript *script, core::Entity *entity, const math::Vector3f &location); +	Jet(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);  	virtual ~Jet();  	virtual void draw(float elapsed); @@ -165,7 +177,7 @@ public:  class Trail : public ParticleSystem  {  public: -	Trail(ParticleScript *script, core::Entity *entity, const math::Vector3f &location); +	Trail(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);  	virtual ~Trail();  	virtual void draw(float elapsed); diff --git a/src/render/renderext.cc b/src/render/renderext.cc index 0fa6796..d2d5a71 100644 --- a/src/render/renderext.cc +++ b/src/render/renderext.cc @@ -60,11 +60,14 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re  			ParticleScript *script = ParticleScript::find(particlesystem->script());  			if (script) {  				if (script->type() == render::ParticleScript::Trail) { -					Trail *trail = new Trail(script, entity, particlesystem->location()); +					Trail *trail = new Trail(script, entity, particlesystem);  					state_particles.push_back(trail);  				} else if (script->type() == render::ParticleScript::Jet) { -					Jet *jet = new Jet(script, entity, particlesystem->location()); +					Jet *jet = new Jet(script, entity, particlesystem);  					state_particles.push_back(jet); +				} else if (script->type() == render::ParticleScript::Flame) { +					Flame *flame = new Flame(script, entity, particlesystem); +					state_particles.push_back(flame);  				}  			} else {  				con_warn << "Could not find particle system '" << particlesystem->script() << "'" << std::endl; | 
