From 2c0610f81afd92424748ecaee0cad01017b5fa32 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 31 May 2009 20:32:59 +0100 Subject: [PATCH] Make the smoke colours vary a little bit --- include/IBillboard.hpp | 1 + include/ISmokeTrail.hpp | 4 ++++ src/Billboard.cpp | 17 ++++++++++++++--- src/SmokeTrail.cpp | 37 +++++++++++++++++++++++++++---------- src/Train.cpp | 7 +++++++ 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/include/IBillboard.hpp b/include/IBillboard.hpp index 4b73944..1aecb93 100644 --- a/include/IBillboard.hpp +++ b/include/IBillboard.hpp @@ -31,6 +31,7 @@ struct IBillboard { virtual void setPosition(float x, float y, float z) = 0; virtual void setScale(float aScale) = 0; + virtual void setColour(float r, float g, float b, float a) = 0; }; typedef std::shared_ptr IBillboardPtr; diff --git a/include/ISmokeTrail.hpp b/include/ISmokeTrail.hpp index 5b25a8a..0ca3755 100644 --- a/include/ISmokeTrail.hpp +++ b/include/ISmokeTrail.hpp @@ -32,6 +32,10 @@ struct ISmokeTrail { // Change the position where new particles are generated virtual void setPosition(float x, float y, float z) = 0; + + // Change the rate at which particles are created + // Delay is in milliseconds + virtual void setDelay(int aDelay) = 0; }; typedef std::shared_ptr ISmokeTrailPtr; diff --git a/src/Billboard.cpp b/src/Billboard.cpp index 324f7bd..396175f 100644 --- a/src/Billboard.cpp +++ b/src/Billboard.cpp @@ -30,13 +30,15 @@ class BillboardCommon : public IBillboard { public: BillboardCommon(ITexturePtr aTexture) : myTexture(aTexture), - myX(0.0f), myY(0.0f), myZ(0.0f), myScale(1.0f) {} + myX(0.0f), myY(0.0f), myZ(0.0f), myScale(1.0f), + myR(1.0f), myG(1.0f), myB(1.0f), myA(1.0f) {} virtual ~BillboardCommon() {} // IBillboard interface void setPosition(float x, float y, float z); void setScale(float aScale); - + void setColour(float r, float g, float b, float a); + private: const ITexturePtr myTexture; @@ -46,6 +48,7 @@ protected: float myX, myY, myZ; float myScale; + float myR, myG, myB, myA; }; void BillboardCommon::setPosition(float x, float y, float z) @@ -55,6 +58,14 @@ void BillboardCommon::setPosition(float x, float y, float z) myZ = z; } +void BillboardCommon::setColour(float r, float g, float b, float a) +{ + myR = r; + myG = g; + myB = b; + myA = a; +} + void BillboardCommon::setScale(float aScale) { myScale = aScale; @@ -74,7 +85,7 @@ void BillboardCommon::drawTextureQuad() const glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glColor4f(myR, myG, myB, myA); myTexture->bind(); diff --git a/src/SmokeTrail.cpp b/src/SmokeTrail.cpp index 1ff2476..3df8e47 100644 --- a/src/SmokeTrail.cpp +++ b/src/SmokeTrail.cpp @@ -18,9 +18,9 @@ #include "ISmokeTrail.hpp" #include "IBillboard.hpp" -#include "ILogger.hpp" // REMOVE - #include +#include +#include using namespace std; @@ -34,16 +34,18 @@ public: void render() const; void setPosition(float x, float y, float z); void update(int aDelta); + void setDelay(int aDelay) { mySpawnDelay = aDelay; } // A single smoke particle struct Particle { float x, y, z; float scale; + float r, g, b, a; }; private: void newParticle(); - void moveParticle(Particle& aParticle, int aDelta); + bool moveParticle(Particle& aParticle, int aDelta); mutable list myParticles; // Need to sort particles in render() float myX, myY, myZ; @@ -55,21 +57,26 @@ private: SmokeTrail::SmokeTrail() : myX(0.0f), myY(0.0f), myZ(0.0f), - mySpawnDelay(1000), mySpawnCounter(0) + mySpawnDelay(500), mySpawnCounter(0) { ITexturePtr particle(loadTexture("data/images/smoke_particle.png")); myBillboard = makeSphericalBillboard(particle); } -void SmokeTrail::moveParticle(Particle& aParticle, int aDelta) +// Returns true if the particle is dead +bool SmokeTrail::moveParticle(Particle& aParticle, int aDelta) { - const float ySpeed = 0.1f; - const float growth = 0.1f; + const float ySpeed = 0.2f; + const float growth = 0.2f; + const float decay = 0.2f; const float time = static_cast(aDelta) / 1000.0f; aParticle.y += ySpeed * time; aParticle.scale += growth * time; + + // Kill the particle if it becomes invisible + return (aParticle.a -= decay * time) <= 0.0f; } void SmokeTrail::update(int aDelta) @@ -77,7 +84,8 @@ void SmokeTrail::update(int aDelta) // Move the existing particles for (list::iterator it = myParticles.begin(); it != myParticles.end(); ++it) - moveParticle(*it, aDelta); + if (moveParticle(*it, aDelta)) + it = myParticles.erase(it); mySpawnCounter -= aDelta; @@ -91,9 +99,17 @@ void SmokeTrail::update(int aDelta) void SmokeTrail::newParticle() { + // Random number generator for colour variance + static variate_generator > + colourRand(mt19937(time(NULL)), normal_distribution<>(0.0f, 0.05f)); + + const float col = 0.8f + colourRand(); + Particle p = { - myX, myY, myZ, // Position - 0.1f, // Scale + myX, myY, myZ, // Position + 0.2f, // Scale + col, col, col, // Colour + 0.9f, // Alpha }; myParticles.push_back(p); @@ -115,6 +131,7 @@ void SmokeTrail::render() const for (list::const_iterator it = myParticles.begin(); it != myParticles.end(); ++it) { myBillboard->setPosition((*it).x, (*it).y, (*it).z); + myBillboard->setColour((*it).r, (*it).g, (*it).b, (*it).a); myBillboard->setScale((*it).scale); myBillboard->render(); } diff --git a/src/Train.cpp b/src/Train.cpp index fb8399d..f5569f8 100644 --- a/src/Train.cpp +++ b/src/Train.cpp @@ -162,6 +162,13 @@ void Train::updateSmokePosition(int aDelta) mySmokeTrail->setPosition(matrix[12], matrix[13], matrix[14]); mySmokeTrail->update(aDelta); + + // Make the rate at which new particles are created proportional + // to the throttle of the controller + const int throttle = e.vehicle->controller()->throttle(); + const int baseDelay = 300; + + mySmokeTrail->setDelay(baseDelay - (throttle * 25)); } void Train::update(int aDelta) -- 2.39.2