diff --git a/src/modules/graphic/osggraph/Car/OsgBrake.cpp b/src/modules/graphic/osggraph/Car/OsgBrake.cpp index 00a9d6739..92df420b6 100644 --- a/src/modules/graphic/osggraph/Car/OsgBrake.cpp +++ b/src/modules/graphic/osggraph/Car/OsgBrake.cpp @@ -32,7 +32,7 @@ void SDBrakes::setCar(tCarElt * car) this->car = car; } -osg::ref_ptr SDBrakes::initBrake(int wheelIndex) +osg::Node *SDBrakes::initBrake(int wheelIndex) { float alpha; osg::Vec3 vtx; @@ -43,7 +43,7 @@ osg::ref_ptr SDBrakes::initBrake(int wheelIndex) tdble curAngle = 0.0; int i; - osg::ref_ptr pBrake = new osg::Geode; + osg::Geode *pBrake = new osg::Geode; pBrake->setName("Brake Assembly"); pBrake->setCullingActive(false); @@ -88,9 +88,9 @@ osg::ref_ptr SDBrakes::initBrake(int wheelIndex) } /* hub */ - osg::ref_ptr hub_vtx = new osg::Vec3Array(); - osg::ref_ptr hub_clr = new osg::Vec4Array(); - osg::ref_ptr hub_nrm = new osg::Vec3Array(); + osg::Vec3Array *hub_vtx = new osg::Vec3Array(); + osg::Vec4Array *hub_clr = new osg::Vec4Array(); + osg::Vec3Array *hub_nrm = new osg::Vec3Array(); tdble hubRadius; @@ -129,21 +129,23 @@ osg::ref_ptr SDBrakes::initBrake(int wheelIndex) hub_nrm->push_back(nrm); - osg::ref_ptr pHub = new osg::Geometry; + osg::Geometry *pHub = new osg::Geometry; pHub->setName("Hub"); pHub->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, brakeBranch+1 )); - pHub->setVertexArray(hub_vtx.get()); - pHub->setNormalArray(hub_nrm.get()); - pHub->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - pHub->setColorArray(hub_clr.get()); - pHub->setColorBinding(osg::Geometry::BIND_PER_VERTEX); - pBrake->addDrawable(pHub.get()); + pHub->setVertexArray(hub_vtx); + pHub->setColorArray(hub_clr); + pHub->setNormalArray(hub_nrm); + + pHub->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + pHub->setNormalBinding(osg::Geometry::BIND_OFF); + + pBrake->addDrawable(pHub); /* Brake disk */ - osg::ref_ptr brk_vtx = new osg::Vec3Array(); - osg::ref_ptr brk_clr = new osg::Vec4Array(); - osg::ref_ptr brk_nrm = new osg::Vec3Array(); + osg::Vec3Array *brk_vtx = new osg::Vec3Array(); + brk_clr = new osg::Vec4Array(); + osg::Vec3Array *brk_nrm = new osg::Vec3Array(); for (i = 0; i < (brakeBranch / 2 + 2); i++) { @@ -163,24 +165,26 @@ osg::ref_ptr SDBrakes::initBrake(int wheelIndex) brk_clr->push_back(clr); brk_nrm->push_back(nrm); - osg::ref_ptr pBDisc = new osg::Geometry; + osg::Geometry *pBDisc = new osg::Geometry; pBDisc->setName("Disc Brake"); pBDisc->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, brakeBranch+4 )); - pBDisc->setVertexArray(brk_vtx.get()); - pBDisc->setNormalArray(brk_nrm.get()); - pBDisc->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + + pBDisc->setVertexArray(brk_vtx); pBDisc->setColorArray(brk_clr.get()); + pBDisc->setNormalArray(brk_nrm); + pBDisc->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + pBDisc->setNormalBinding(osg::Geometry::BIND_OFF); - pBrake->addDrawable(pBDisc.get()); + pBrake->addDrawable(pBDisc); - this->brake_disks[wheelIndex] = pBDisc.get(); + this->brake_disks[wheelIndex] = pBDisc; /* Brake caliper */ - osg::ref_ptr cal_vtx = new osg::Vec3Array(); - cal_clr = new osg::Vec4Array(); - osg::ref_ptr cal_nrm = new osg::Vec3Array(); + osg::Vec3Array *cal_vtx = new osg::Vec3Array(); + osg::Vec4Array *cal_clr = new osg::Vec4Array(); + osg::Vec3Array *cal_nrm = new osg::Vec3Array(); for (i = 0; i < (brakeBranch / 2 - 2); i++) { @@ -202,18 +206,21 @@ osg::ref_ptr SDBrakes::initBrake(int wheelIndex) cal_clr->push_back(clr); cal_nrm->push_back(nrm); - osg::ref_ptr pCaliper = new osg::Geometry; + osg::Geometry *pCaliper = new osg::Geometry; pCaliper->setName("Caliper"); pCaliper->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, brakeBranch-4 )); - pCaliper->setVertexArray(cal_vtx.get()); - pCaliper->setNormalArray(cal_nrm.get()); - pCaliper->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - pCaliper->setColorArray(cal_clr.get()); + + pCaliper->setVertexArray(cal_vtx); + pCaliper->setColorArray(cal_clr); + pCaliper->setNormalArray(cal_nrm); + pCaliper->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + pCaliper->setNormalBinding(osg::Geometry::BIND_OFF); - pBrake->addDrawable(pCaliper.get()); - return pBrake.get(); + pBrake->addDrawable(pCaliper); + + return pBrake; } void SDBrakes::updateBrakes() @@ -226,9 +233,10 @@ void SDBrakes::updateBrakes() clr[1] = 0.1 + car->_brakeTemp(i) * 0.3; clr[2] = 0.1 - car->_brakeTemp(i) * 0.3; clr[3] = 1.0; - cal_clr->push_back(clr); + (*brk_clr)[0] = clr; + brk_clr->dirty(); - this->brake_disks[i]->setColorArray(cal_clr.get(), osg::Array::BIND_PER_VERTEX); + this->brake_disks[i]->setColorArray(brk_clr.get(), osg::Array::BIND_PER_VERTEX); //GfLogInfo("brake temp %i = %f\n", i, car->_brakeTemp(i) ); } } diff --git a/src/modules/graphic/osggraph/Car/OsgBrake.h b/src/modules/graphic/osggraph/Car/OsgBrake.h index ed76cd0f0..f99483164 100644 --- a/src/modules/graphic/osggraph/Car/OsgBrake.h +++ b/src/modules/graphic/osggraph/Car/OsgBrake.h @@ -28,11 +28,11 @@ class SDBrakes private : tCarElt *car; osg::ref_ptr brake_disks[4]; - osg::ref_ptr cal_clr; + osg::ref_ptr brk_clr; public : void setCar(tCarElt * car); - osg::ref_ptr initBrake(int wheelIndex); + osg::Node *initBrake(int wheelIndex); void updateBrakes(); }; diff --git a/src/modules/graphic/ssggraph/grsmoke.cpp b/src/modules/graphic/ssggraph/grsmoke.cpp index 58d5dc2e4..ce4a58a99 100644 --- a/src/modules/graphic/ssggraph/grsmoke.cpp +++ b/src/modules/graphic/ssggraph/grsmoke.cpp @@ -23,133 +23,145 @@ #include "grsmoke.h" #include "grmain.h" -#include "grcar.h" //grCarInfo +#include "grcar.h" //grCarInfo #include "grscene.h" //SmokeAnchor -#include "grutil.h" //urandom +#include "grutil.h" //urandom #ifdef DMALLOC #include "dmalloc.h" #endif -static int grSmokeMaxNumber; -static double grSmokeDeltaT; -static double grFireDeltaT; -static double grSmokeLife; -static int grWater; +static int grSmokeMaxNumber; +static double grSmokeDeltaT; +static double grFireDeltaT; +static double grSmokeLife; +static int grWater; -static ssgSimpleState *mst = NULL; //Smoke img -static ssgSimpleState *mstf0 = NULL; //Fire img #1 -static ssgSimpleState *mstf1 = NULL; //Fire img #2 -static double *timeSmoke = NULL; //Stores the time of the wheel smoke last update -static double *timeFire = NULL; //Stores the time of the exhaust fire last update +static ssgSimpleState *mst = NULL; //Smoke img +static ssgSimpleState *mstf0 = NULL; //Fire img #1 +static ssgSimpleState *mstf1 = NULL; //Fire img #2 +static double *timeSmoke = NULL; //Stores the time of the wheel smoke last update +static double *timeFire = NULL; //Stores the time of the exhaust fire last update //! All smokes are stored here in this list. static std::list *smokeList = NULL; /** * class cSmokeDef - * + * * Utility class for passing parameters to cGrSmoke::Add easily. */ class cSmokeDef { public: - inline void Init(const double c1, const double c2, const double c3, - const tdble is, const tdble th, const tdble slc, const tdble ssc) - { - cur_clr[0] = c1; - cur_clr[1] = c2; - cur_clr[2] = c3; - init_speed = is; - threshold = th; - smoke_life_coefficient = slc; - smoke_speed_coefficient = ssc; - } + inline void Init(const double c1, const double c2, const double c3, + const tdble is, const tdble th, const tdble slc, const tdble ssc) + { + cur_clr[0] = c1; + cur_clr[1] = c2; + cur_clr[2] = c3; + init_speed = is; + threshold = th; + smoke_life_coefficient = slc; + smoke_speed_coefficient = ssc; + } - sgVec3 cur_clr; - tdble init_speed; - tdble threshold; - tdble smoke_life_coefficient; - tdble smoke_speed_coefficient; + sgVec3 cur_clr; + tdble init_speed; + tdble threshold; + tdble smoke_life_coefficient; + tdble smoke_speed_coefficient; }; /** * grInitSmoke * Initializes the smoke structure. - * + * * @param index The car index */ void grInitSmoke(const int index) { - grSmokeMaxNumber = (int)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKENB, - (char*)NULL, MAX_SMOKE_NUMBER); - grSmokeDeltaT = (double)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKEDELTAT, - (char*)NULL, DELTAT); - grSmokeLife = (double)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKEDLIFE, - (char*)NULL, 2.0); + grSmokeMaxNumber = (int)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKENB, + (char*)NULL, MAX_SMOKE_NUMBER); + grSmokeDeltaT = (double)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKEDELTAT, + (char*)NULL, DELTAT); + grSmokeLife = (double)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SMOKEDLIFE, + (char*)NULL, 2.0); - //Only proceed if there is any need for smokes to display - if(grSmokeMaxNumber) { - if (grSmokeLife > MAX_SMOKE_LIFE) - grSmokeLife = MAX_SMOKE_LIFE; - - grFireDeltaT = grSmokeDeltaT * 8; + //Only proceed if there is any need for smokes to display + if(grSmokeMaxNumber) { + if (grSmokeLife > MAX_SMOKE_LIFE) + grSmokeLife = MAX_SMOKE_LIFE; - if (!timeSmoke) { - timeSmoke = new double[index * 4]; - memset(timeSmoke, 0, sizeof(double) * index * 4); - } + grFireDeltaT = grSmokeDeltaT * 8; - if (!timeFire) { - timeFire = new double[index]; - memset(timeFire, 0 , sizeof(double) * index); - } + if (!timeSmoke) + { + timeSmoke = new double[index * 4]; + memset(timeSmoke, 0, sizeof(double) * index * 4); + } - if (!smokeList) { - smokeList = new std::list; - } + if (!timeFire) + { + timeFire = new double[index]; + memset(timeFire, 0 , sizeof(double) * index); + } - char buf[256]; - // add temp object to get a reference on the states - if (!mst) { - sprintf(buf, "data/textures;data/img;."); - mst = (ssgSimpleState*)grSsgLoadTexStateEx("smoke.png", buf, FALSE, FALSE); - if (mst) { - mst->disable(GL_LIGHTING); - mst->enable(GL_BLEND); - mst->disable(GL_CULL_FACE); - mst->setTranslucent(); - mst->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); - }//if mst - }//if !mst + if (!smokeList) + { + smokeList = new std::list; + } - if (!mstf0) { - sprintf(buf, "data/textures;data/img;."); - mstf0 = (ssgSimpleState*)grSsgLoadTexStateEx("fire0.png", buf, FALSE, FALSE); - if (mstf0) { - mstf0->disable(GL_LIGHTING); - mstf0->enable(GL_BLEND); - mstf0->disable(GL_CULL_FACE); - mstf0->setTranslucent(); - mstf0->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); - }//if mstf0 - }//if !mstf0 + char buf[256]; + // add temp object to get a reference on the states + if (!mst) + { + sprintf(buf, "data/textures;data/img;."); + mst = (ssgSimpleState*)grSsgLoadTexStateEx("smoke.png", buf, FALSE, FALSE); - if (!mstf1) { - sprintf(buf, "data/textures;data/img;."); - mstf1 = (ssgSimpleState*)grSsgLoadTexStateEx("fire1.png", buf, FALSE, FALSE); - if (mstf1) { - mstf1->disable(GL_LIGHTING); - mstf1->enable(GL_BLEND); - mstf1->disable(GL_CULL_FACE); - mstf1->setTranslucent(); - mstf1->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); - }//if mstf1 - }//if !mstf1 - }//if grSmokeMaxNumber + if (mst) + { + mst->disable(GL_LIGHTING); + mst->enable(GL_BLEND); + mst->disable(GL_CULL_FACE); + mst->setTranslucent(); + mst->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); + }//if mst + }//if !mst + + if (!mstf0) + { + sprintf(buf, "data/textures;data/img;."); + mstf0 = (ssgSimpleState*)grSsgLoadTexStateEx("fire0.png", buf, FALSE, FALSE); + + if (mstf0) + { + mstf0->disable(GL_LIGHTING); + mstf0->enable(GL_BLEND); + mstf0->disable(GL_CULL_FACE); + mstf0->setTranslucent(); + mstf0->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); + }//if mstf0 + }//if !mstf0 + + if (!mstf1) + { + sprintf(buf, "data/textures;data/img;."); + mstf1 = (ssgSimpleState*)grSsgLoadTexStateEx("fire1.png", buf, FALSE, FALSE); + + if (mstf1) + { + mstf1->disable(GL_LIGHTING); + mstf1->enable(GL_BLEND); + mstf1->disable(GL_CULL_FACE); + mstf1->setTranslucent(); + mstf1->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); + }//if mstf1 + }//if !mstf1 + }//if grSmokeMaxNumber }//grInitSmoke @@ -157,30 +169,35 @@ grInitSmoke(const int index) * grUpdateSmoke * Updates the smokes (wheel, exhaust) for a car, if necessary. * Also removes smokes that reached their end of life. - * + * * @param t Current simulation time */ void grUpdateSmoke(const double t) { - if(grSmokeMaxNumber) { - for(std::list::iterator it = smokeList->begin(); - it != smokeList->end(); - it++) { - if (!it->smoke->isAlive()) { - //Smoke too old, get rid of it. - SmokeAnchor->removeKid(it->smoke); - it = smokeList->erase(it); - - if (it == smokeList->end()) - break; + if(grSmokeMaxNumber) + { + for(std::list::iterator it = smokeList->begin(); + it != smokeList->end(); + it++) + { + if (!it->smoke->isAlive()) + { + //Smoke too old, get rid of it. + SmokeAnchor->removeKid(it->smoke); + it = smokeList->erase(it); - } else { - //Update the smoke - it->Update(t); - }//if !it->smoke->isAlive - }//for it - }//if grSmokeMaxNumber + if (it == smokeList->end()) + break; + + } + else + { + //Update the smoke + it->Update(t); + }//if !it->smoke->isAlive + }//for it + }//if grSmokeMaxNumber }//grUpdateSmoke @@ -189,98 +206,126 @@ grUpdateSmoke(const double t) * Adds smoke to a car. * If it is skidding or slipping, adds 4 smokes (one to each wheel). * If it has a sudden RPM change, adds exhaust smoke(s). - * + * * @param car Pointer to the car in need of smokes * @param t Current simulation time */ void grAddSmoke(tCarElt *car, const double t) { - if(grSmokeMaxNumber) { - //Speed ^ 2 - tdble spd2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y; + if(grSmokeMaxNumber) + { + //Speed ^ 2 + tdble spd2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y; - //!Add smoke from spinning/skidding wheels - if (spd2 > 0.001f) { //If the car is moving - for(int i = 0; i < 4; i++) { //Loop through all 4 wheels - if ((int)smokeList->size() < grSmokeMaxNumber) { //If there is space for more smoke - //If the car's smoke is not too current, let's add it. - if ((t - timeSmoke[car->index * 4 + i]) > grSmokeDeltaT) { - timeSmoke[car->index * 4 + i] = t; + //!Add smoke from spinning/skidding wheels + if (spd2 > 0.001f) + { //If the car is moving + for(int i = 0; i < 4; i++) + { //Loop through all 4 wheels + if ((int)smokeList->size() < grSmokeMaxNumber) + { //If there is space for more smoke + //If the car's smoke is not too current, let's add it. + if ((t - timeSmoke[car->index * 4 + i]) > grSmokeDeltaT) + { + timeSmoke[car->index * 4 + i] = t; - //!Different smoke for different surfaces - cSmokeDef sd;//(0.8f, 0.8f, 0.8f, 0.01f, 0.1f, 30.0f, 0.0f); - if (car->priv.wheel[i].seg) { // sanity check - const char* surface = car->priv.wheel[i].seg->surface->material; - if (strstr(surface, "sand")) { - sd.Init(0.8f, 0.7f + urandom() * 0.1f, 0.4f + urandom() * 0.2f, - 0.5f, 0.05f, 12.5f, 0.25f); - } else if (strstr(surface, "dirt")) { - sd.Init(0.7f + urandom() * 0.1f, 0.6f + urandom() * 0.1f, 0.5f + urandom() * 0.1f, 0.45f, 0.0f, 10.0f, 0.5f); - } else if (strstr(surface,"mud")) { - sd.Init(0.25f, 0.17f + urandom() * 0.02f, 0.05f + urandom() * 0.02f, 0.2f, 0.25f, 15.0f, 0.25f); - } else if (strstr(surface,"gravel")) { - sd.Init(0.6f, 0.6f, 0.6f, - 0.35f, 0.1f, 20.0f, 0.1f); - } else if (strstr(surface,"grass")) { - sd.Init(0.4f + urandom() * 0.2f, 0.5f + urandom() * 0.1f, 0.3f + urandom() * 0.1f, 0.3f, 0.1f, 25.0f, 0.0f); - } else if (strstr(surface,"snow")) { - sd.Init(0.75f, 0.75f + urandom() * 0.1f, 0.75f + urandom() * 0.1f, 0.35f, 0.0f, 8.0f, 0.4f); - } else { - sd.Init(0.8f, 0.8f, 0.8f, - 0.01f, 0.1f, 30.0f, 0.0f); - } - }//if car->priv.wheel - - //! Ground water can change the tire smoke attributes. - grWater = grTrack->local.water; + //!Different smoke for different surfaces + cSmokeDef sd;//(0.8f, 0.8f, 0.8f, 0.01f, 0.1f, 30.0f, 0.0f); + if (car->priv.wheel[i].seg) { // sanity check + const char* surface = car->priv.wheel[i].seg->surface->material; - if (grWater > 0) - { - sd.Init(0.6f, 0.6f, 0.6f, 0.45f, 0.0f, 10.5f, 0.25f); - }//if grWater + if (strstr(surface, "sand")) + { + sd.Init(0.8f, 0.7f + urandom() * 0.1f, 0.4f + urandom() * 0.2f, + 0.5f, 0.05f, 12.5f, 0.25f); + } + else if (strstr(surface, "dirt")) + { + sd.Init(0.7f + urandom() * 0.1f, 0.6f + urandom() * 0.1f, 0.5f + urandom() * 0.1f, 0.45f, 0.0f, 10.0f, 0.5f); + } + else if (strstr(surface,"mud")) + { + sd.Init(0.25f, 0.17f + urandom() * 0.02f, 0.05f + urandom() * 0.02f, 0.2f, 0.25f, 15.0f, 0.25f); + } + else if (strstr(surface,"gravel")) + { + sd.Init(0.6f, 0.6f, 0.6f, + 0.35f, 0.1f, 20.0f, 0.1f); + } + else if (strstr(surface,"grass")) + { + sd.Init(0.4f + urandom() * 0.2f, 0.5f + urandom() * 0.1f, 0.3f + urandom() * 0.1f, 0.3f, 0.1f, 25.0f, 0.0f); + } + else if (strstr(surface,"snow")) + { + sd.Init(0.75f, 0.75f + urandom() * 0.1f, 0.75f + urandom() * 0.1f, 0.35f, 0.0f, 8.0f, 0.4f); + } + else + { + sd.Init(0.8f, 0.8f, 0.8f, + 0.01f, 0.1f, 30.0f, 0.0f); + } + }//if car->priv.wheel - //!Add smoke - cGrSmoke tmp; - if(tmp.Add(car, i, t, SMOKE_TYPE_TIRE, &sd)) { - smokeList->push_back(tmp); - }//if tmp.Add - }//if t - }//if smokeList->size - }//for i - }//if spd2 - - //!Add exhaust fire smoke - if (car->_exhaustNb && (spd2 > 10.0)) { //If the car has exhaust pipes and is moving - if ((int)smokeList->size() < grSmokeMaxNumber) { //If there is space for more smoke - const int index = car->index; //current car's index - //If the car's enxhaust smoke is not too current, let's add it. - if ((t - timeFire[index]) > grFireDeltaT) { - timeFire[index] = t; - //!The need for exhaust fire is calculated from the RPM change - //Only need to display exhaust fire when the gear is changing backwards - tgrCarInstrument *curInst = &(grCarInfo[index].instrument[0]); - tdble val = ((*(curInst->monitored) - curInst->minValue) - - (curInst->rawPrev - curInst->minValue)) / curInst->maxValue; - curInst->rawPrev = *(curInst->monitored); - if (val > 0.1 && val < 0.5) {//need upper limit to prevent multiple exhaust fires at race starts - grCarInfo[index].fireCount = (int)(10.0 * val * car->_exhaustPower); - } + //! Ground water can change the tire smoke attributes. + grWater = grTrack->local.water; - if (grCarInfo[index].fireCount) { - grCarInfo[index].fireCount--; - //Add fire to each exhaust - for (int i = 0; i < car->_exhaustNb; i++) { - cGrSmoke tmp; - if(tmp.Add(car, i, t, SMOKE_TYPE_ENGINE, NULL)) { - smokeList->push_back(tmp); - }//if tmp.Add - }//for i - }//if fireCount - }//if t - }//is smokeList->size - }//if car-_exhaustNb - }//if grSmokeMaxNumber + if (grWater > 0) + { + sd.Init(0.6f, 0.6f, 0.6f, 0.45f, 0.0f, 10.5f, 0.25f); + }//if grWater + + //!Add smoke + cGrSmoke tmp; + if(tmp.Add(car, i, t, SMOKE_TYPE_TIRE, &sd)) + { + smokeList->push_back(tmp); + }//if tmp.Add + }//if t + }//if smokeList->size + }//for i + }//if spd2 + + //!Add exhaust fire smoke + if (car->_exhaustNb && (spd2 > 10.0)) + { //If the car has exhaust pipes and is moving + if ((int)smokeList->size() < grSmokeMaxNumber) + { //If there is space for more smoke + const int index = car->index; //current car's index + //If the car's enxhaust smoke is not too current, let's add it. + if ((t - timeFire[index]) > grFireDeltaT) + { + timeFire[index] = t; + //!The need for exhaust fire is calculated from the RPM change + //Only need to display exhaust fire when the gear is changing backwards + tgrCarInstrument *curInst = &(grCarInfo[index].instrument[0]); + tdble val = ((*(curInst->monitored) - curInst->minValue) + - (curInst->rawPrev - curInst->minValue)) / curInst->maxValue; + curInst->rawPrev = *(curInst->monitored); + + if (val > 0.1 && val < 0.5) + {//need upper limit to prevent multiple exhaust fires at race starts + grCarInfo[index].fireCount = (int)(10.0 * val * car->_exhaustPower); + } + + if (grCarInfo[index].fireCount) + { + grCarInfo[index].fireCount--; + //Add fire to each exhaust + for (int i = 0; i < car->_exhaustNb; i++) + { + cGrSmoke tmp; + if(tmp.Add(car, i, t, SMOKE_TYPE_ENGINE, NULL)) + { + smokeList->push_back(tmp); + }//if tmp.Add + }//for i + }//if fireCount + }//if t + }//is smokeList->size + }//if car-_exhaustNb + }//if grSmokeMaxNumber }//grAddSmoke @@ -291,51 +336,53 @@ grAddSmoke(tCarElt *car, const double t) void grShutdownSmoke() { - GfOut("-- grShutdownSmoke\n"); + GfOut("-- grShutdownSmoke\n"); - if(grSmokeMaxNumber) { - SmokeAnchor->removeAllKids(); - if (smokeList) { - //~ std::list::iterator tmp = smokeList->begin(); - //~ while(tmp != smokeList->end()) - //~ { - //~ /* SmokeAnchor->removeKid(tmp->smoke); */ - //~ tmp = smokeList->erase(tmp); - //~ } - smokeList->clear(); - delete [] timeSmoke; - delete [] timeFire; - delete smokeList; - - timeSmoke = NULL; - timeFire = NULL; - smokeList = NULL; - }//if smokeList - }//if grSmokeMaxNumber + if(grSmokeMaxNumber) + { + SmokeAnchor->removeAllKids(); + if (smokeList) + { + //~ std::list::iterator tmp = smokeList->begin(); + //~ while(tmp != smokeList->end()) + //~ { + //~ /* SmokeAnchor->removeKid(tmp->smoke); */ + //~ tmp = smokeList->erase(tmp); + //~ } + smokeList->clear(); + delete [] timeSmoke; + delete [] timeFire; + delete smokeList; + + timeSmoke = NULL; + timeFire = NULL; + smokeList = NULL; + }//if smokeList + }//if grSmokeMaxNumber }//grShutdownSmoke void ssgVtxTableSmoke::copy_from ( ssgVtxTableSmoke *src, int clone_flags ) { - ssgVtxTable::copy_from ( src, clone_flags ) ; + ssgVtxTable::copy_from ( src, clone_flags ) ; } ssgBase *ssgVtxTableSmoke::clone ( int clone_flags ) { - ssgVtxTableSmoke *b = new ssgVtxTableSmoke ; - b -> copy_from ( this, clone_flags ) ; - return b ; + ssgVtxTableSmoke *b = new ssgVtxTableSmoke ; + b -> copy_from ( this, clone_flags ) ; + return b ; } ssgVtxTableSmoke::ssgVtxTableSmoke () { - ssgVtxTable(); + ssgVtxTable(); } ssgVtxTableSmoke:: ssgVtxTableSmoke (ssgVertexArray *shd_vtx , float initsize, int typ) { sizex = sizey = sizez = initsize; - + gltype = GL_TRIANGLE_STRIP; type = ssgTypeVtxTable () ; stype = typ; @@ -348,10 +395,10 @@ ssgVtxTableSmoke:: ssgVtxTableSmoke (ssgVertexArray *shd_vtx , float initsize, i normals -> ref () ; texcoords -> ref () ; colours -> ref () ; - cur_col[0] = cur_col[1] = cur_col[2] = 0.8; - vvx = vvy = vvz = 0.0; - init_alpha = 0.9; - recalcBSphere () ; + cur_col[0] = cur_col[1] = cur_col[2] = 0.8; + vvx = vvy = vvz = 0.0; + init_alpha = 0.9; + recalcBSphere () ; } ssgVtxTableSmoke::~ssgVtxTableSmoke () @@ -360,111 +407,121 @@ ssgVtxTableSmoke::~ssgVtxTableSmoke () void ssgVtxTableSmoke::draw_geometry () { - int num_colours = getNumColours(); - int num_normals = getNumNormals(); - float alpha; - GLfloat modelView[16]; - sgVec3 A, B, C, D; - sgVec3 right, up, offset; + int num_colours = getNumColours(); + int num_normals = getNumNormals(); + float alpha; + GLfloat modelView[16]; + sgVec3 A, B, C, D; + sgVec3 right, up, offset; - sgVec3 *vx = (sgVec3 *) vertices->get(0); - sgVec3 *nm = (sgVec3 *) normals->get(0); + sgVec3 *vx = (sgVec3 *) vertices->get(0); + sgVec3 *nm = (sgVec3 *) normals->get(0); sgVec4 *cl = (sgVec4 *) colours->get(0); - alpha = 0.9f - ((float)(cur_life/max_life)); - glDepthMask(GL_FALSE); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + alpha = 0.9f - ((float)(cur_life/max_life)); + glDepthMask(GL_FALSE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - /*glPolygonOffset(-5.0f, +10.0f);*/ - /*glEnable(GL_POLYGON_OFFSET_FILL);*/ + /*glPolygonOffset(-5.0f, +10.0f);*/ + /*glEnable(GL_POLYGON_OFFSET_FILL);*/ - // the principle is to have a right and up vector - // to determine how the points of the quadri should be placed - // orthogonaly to the view, parallel to the screen. + // the principle is to have a right and up vector + // to determine how the points of the quadri should be placed + // orthogonaly to the view, parallel to the screen. - /* get the matrix */ - // TODO: replace that, glGet stalls rendering pipeline (forces flush). - glGetFloatv(GL_MODELVIEW_MATRIX, modelView); + /* get the matrix */ + // TODO: replace that, glGet stalls rendering pipeline (forces flush). + glGetFloatv(GL_MODELVIEW_MATRIX, modelView); - // get the up and right vector from the matrice view + // get the up and right vector from the matrice view - offset[0] = offset[1] = offset[2] = 0.0f; + offset[0] = offset[1] = offset[2] = 0.0f; - int i; - for (i = 0; i < 3; i++) { - int j = i; - int k; - for (k = 0; k < 4; k++, j+=4) { - if (k != 3) { - offset[i] += modelView[j] * vx[0][k]; - } else { - offset[i] += modelView[j]; - } - } - } - //printf ("%f %f %f\n", offset[0], offset[1], offset[2]); + int i; + for (i = 0; i < 3; i++) + { + int j = i; + int k; + for (k = 0; k < 4; k++, j+=4) + { + if (k != 3) + { + offset[i] += modelView[j] * vx[0][k]; + } + else + { + offset[i] += modelView[j]; + } + } + } + //printf ("%f %f %f\n", offset[0], offset[1], offset[2]); - tdble dist = sqrt(offset[0]*offset[0] - + offset[1]*offset[1] - + offset[2]*offset[2]); + tdble dist = sqrt(offset[0]*offset[0] + + offset[1]*offset[1] + + offset[2]*offset[2]); - up[0] = modelView[1]; - up[1] = modelView[5]; - up[2] = modelView[9]; + up[0] = modelView[1]; + up[1] = modelView[5]; + up[2] = modelView[9]; - right[0] = modelView[0]; - right[1] = modelView[4]; - right[2] = modelView[8]; + right[0] = modelView[0]; + right[1] = modelView[4]; + right[2] = modelView[8]; - // compute the coordinates of the four points of the quadri. + // compute the coordinates of the four points of the quadri. - // up and right points - C[0] = right[0]+up[0]; - C[1] = right[1]+up[1]; - C[2] = right[2]+up[2]; + // up and right points + C[0] = right[0]+up[0]; + C[1] = right[1]+up[1]; + C[2] = right[2]+up[2]; - // left and up - D[0] = -right[0]+up[0]; - D[1] = -right[1]+up[1]; - D[2] = -right[2]+up[2]; + // left and up + D[0] = -right[0]+up[0]; + D[1] = -right[1]+up[1]; + D[2] = -right[2]+up[2]; - // down and left - A[0] = -right[0]-up[0]; - A[1] = -right[1]-up[1]; - A[2] = -right[2]-up[2]; + // down and left + A[0] = -right[0]-up[0]; + A[1] = -right[1]-up[1]; + A[2] = -right[2]-up[2]; - // right and down - B[0] = right[0]-up[0]; - B[1] = right[1]-up[1]; - B[2] = right[2]-up[2]; + // right and down + B[0] = right[0]-up[0]; + B[1] = right[1]-up[1]; + B[2] = right[2]-up[2]; - glBegin ( gltype ) ; + glBegin ( gltype ) ; - if (dist < 50.0f) { - alpha *= (1.0f - exp(-0.1f * dist)); - } + if (dist < 50.0f) + { + alpha *= (1.0f - exp(-0.1f * dist)); + } - glColor4f(cur_col[0],cur_col[1],cur_col[2],alpha); - if (num_colours == 1) { - glColor4fv(cl[0]); - } - if (num_normals == 1) { - glNormal3fv(nm[0]); - } + glColor4f(cur_col[0],cur_col[1],cur_col[2],alpha); - // the computed coordinates are translated from the smoke position with the x, y, z speed - glTexCoord2f(0,0); - glVertex3f(vx[0][0]+sizex*A[0],vx[0][1]+sizey*A[1], vx[0][2]+sizez*A[2]); - glTexCoord2f(0,1); - glVertex3f(vx[0][0]+sizex*B[0],vx[0][1]+sizey*B[1], vx[0][2]+sizez*B[2]); - glTexCoord2f(1,0); - glVertex3f(vx[0][0]+sizex*D[0],vx[0][1]+sizey*D[1], vx[0][2]+sizez*D[2]); - glTexCoord2f(1,1); - glVertex3f(vx[0][0]+sizex*C[0],vx[0][1]+sizey*C[1], vx[0][2]+sizez*C[2]); - glEnd(); + if (num_colours == 1) + { + glColor4fv(cl[0]); + } - glDisable(GL_POLYGON_OFFSET_FILL); - glDepthMask(GL_TRUE); - glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + if (num_normals == 1) + { + glNormal3fv(nm[0]); + } + + // the computed coordinates are translated from the smoke position with the x, y, z speed + glTexCoord2f(0,0); + glVertex3f(vx[0][0]+sizex*A[0],vx[0][1]+sizey*A[1], vx[0][2]+sizez*A[2]); + glTexCoord2f(0,1); + glVertex3f(vx[0][0]+sizex*B[0],vx[0][1]+sizey*B[1], vx[0][2]+sizez*B[2]); + glTexCoord2f(1,0); + glVertex3f(vx[0][0]+sizex*D[0],vx[0][1]+sizey*D[1], vx[0][2]+sizez*D[2]); + glTexCoord2f(1,1); + glVertex3f(vx[0][0]+sizex*C[0],vx[0][1]+sizey*C[1], vx[0][2]+sizez*C[2]); + glEnd(); + + glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(GL_TRUE); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); } @@ -476,54 +533,59 @@ void ssgVtxTableSmoke::draw_geometry () void cGrSmoke::Update(const double t) { - // update the smoke - smoke->dt = t - smoke->lastTime; - // expand the Y value - smoke->sizey += smoke->dt * smoke->vexp * 2.0f; - smoke->sizez += smoke->dt * smoke->vexp * 0.25f; - smoke->sizex += smoke->dt * smoke->vexp * 2.0f; + // update the smoke + smoke->dt = t - smoke->lastTime; + // expand the Y value + smoke->sizey += smoke->dt * smoke->vexp * 2.0f; + smoke->sizez += smoke->dt * smoke->vexp * 0.25f; + smoke->sizex += smoke->dt * smoke->vexp * 2.0f; - //!Exhaust fire can change shape, hence the need for two bitmaps - if (smoke->smokeType == SMOKE_TYPE_ENGINE) { - if (smoke->smokeTypeStep == 0) { - if (smoke->cur_life >= smoke->step0_max_life) { - // changing from fire to smoke - smoke->smokeTypeStep = 1; - smoke->setState(mstf1); - } - } - else if (smoke->smokeTypeStep == 1) { - if (smoke->cur_life >= smoke->step1_max_life) { - // changing from fire to smoke - smoke->smokeTypeStep = 2; - smoke->setState(mst); - } - } - }//if smokeType SMOKE_TYPE_ENGINE + //!Exhaust fire can change shape, hence the need for two bitmaps + if (smoke->smokeType == SMOKE_TYPE_ENGINE) + { + if (smoke->smokeTypeStep == 0) + { + if (smoke->cur_life >= smoke->step0_max_life) + { + // changing from fire to smoke + smoke->smokeTypeStep = 1; + smoke->setState(mstf1); + } + } + else if (smoke->smokeTypeStep == 1) + { + if (smoke->cur_life >= smoke->step1_max_life) + { + // changing from fire to smoke + smoke->smokeTypeStep = 2; + smoke->setState(mst); + } + } + }//if smokeType SMOKE_TYPE_ENGINE - sgVec3 *vx = (sgVec3 *) smoke->getVertices()->get(0); + sgVec3 *vx = (sgVec3 *) smoke->getVertices()->get(0); - tdble dt = smoke->dt; - tdble damp = 0.2f; - smoke->vvx -= damp * smoke->vvx * fabs(smoke->vvx) * dt; - smoke->vvy -= damp * smoke->vvy * fabs(smoke->vvy) * dt; - smoke->vvz -= damp * smoke->vvz * fabs(smoke->vvz) * dt; - - if (grWater > 0) - { - smoke->vvx += 0.0039f; - smoke->vvy += 0.0039f; - smoke->vvz += 0.0039f; - } else { - smoke->vvz += 0.0001f; - } + tdble dt = smoke->dt; + tdble damp = 0.2f; + smoke->vvx -= damp * smoke->vvx * fabs(smoke->vvx) * dt; + smoke->vvy -= damp * smoke->vvy * fabs(smoke->vvy) * dt; + smoke->vvz -= damp * smoke->vvz * fabs(smoke->vvz) * dt; - vx[0][0] += smoke->vvx * dt; - vx[0][1] += smoke->vvy * dt; - vx[0][2] += smoke->vvz * dt; + if (grWater > 0) + { + smoke->vvx += 0.0039f; + smoke->vvy += 0.0039f; + smoke->vvz += 0.0039f; + } else { + smoke->vvz += 0.0001f; + } - smoke->lastTime = t; - smoke->cur_life += smoke->dt; + vx[0][0] += smoke->vvx * dt; + vx[0][1] += smoke->vvy * dt; + vx[0][2] += smoke->vvz * dt; + + smoke->lastTime = t; + smoke->cur_life += smoke->dt; }//cGrSmoke::Update @@ -539,114 +601,119 @@ cGrSmoke::Update(const double t) */ bool cGrSmoke::Add(tCarElt *car, const int i, const double t, - const int type, const cSmokeDef *sd) + const int type, const cSmokeDef *sd) { - bool ret = false; - - if(type == SMOKE_TYPE_TIRE) { - //!Add tire smoke - tdble sinCarYaw = sin(car->_yaw); - tdble cosCarYaw = cos(car->_yaw); - tdble spd2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y; - tdble smoke_life_coefficient = sd->smoke_life_coefficient * (1.0f - urandom() * urandom()); - tdble spd_fx = tanh(0.001f * car->_reaction[i]) * sd->smoke_speed_coefficient * sqrt(spd2); - double slip = MAX(0.0, ((car->_wheelSpinVel(i) * car->_wheelRadius(i)) - fabs(car->_speed_x)) - 9.0); - bool skidsmoke = (car->_skid[i] + 0.025f * urandom() * spd_fx > urandom() + sd->threshold); // instead of 0.3, to randomize - - if (skidsmoke || slip > 0.0) { // smoke from driven wheel spin - float init_speed_z = 0.1f + (float) (slip/20); - float stretch_factor = 0.2f; + bool ret = false; - ssgVertexArray *shd_vtx = new ssgVertexArray(1); - //shd_clr = new ssgColourArray(1); + if(type == SMOKE_TYPE_TIRE) + { + //!Add tire smoke + tdble sinCarYaw = sin(car->_yaw); + tdble cosCarYaw = cos(car->_yaw); + tdble spd2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y; + tdble smoke_life_coefficient = sd->smoke_life_coefficient * (1.0f - urandom() * urandom()); + tdble spd_fx = tanh(0.001f * car->_reaction[i]) * sd->smoke_speed_coefficient * sqrt(spd2); + double slip = MAX(0.0, ((car->_wheelSpinVel(i) * car->_wheelRadius(i)) - fabs(car->_speed_x)) - 9.0); + bool skidsmoke = (car->_skid[i] + 0.025f * urandom() * spd_fx > urandom() + sd->threshold); // instead of 0.3, to randomize - //Smoke originates from the given wheel - sgVec3 vtx; - vtx[0] = car->priv.wheel[i].relPos.x; - vtx[1] = car->priv.wheel[i].relPos.y; - vtx[2] = car->priv.wheel[i].relPos.z - car->_wheelRadius(i) * 1.0f + 0.5f * SMOKE_INIT_SIZE; - tdble stretchX = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_X)); - tdble stretchY = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_Y)); - vtx[0] -= 0.05f * car->_speed_x; - shd_vtx->add(vtx); + if (skidsmoke || slip > 0.0) + { // smoke from driven wheel spin + float init_speed_z = 0.1f + (float) (slip/20); + float stretch_factor = 0.2f; - tdble init_speed = sd->init_speed * urandom(); + ssgVertexArray *shd_vtx = new ssgVertexArray(1); + //shd_clr = new ssgColourArray(1); - smoke = new ssgVtxTableSmoke(shd_vtx, SMOKE_INIT_SIZE, SMOKE_TYPE_TIRE); + //Smoke originates from the given wheel + sgVec3 vtx; + vtx[0] = car->priv.wheel[i].relPos.x; + vtx[1] = car->priv.wheel[i].relPos.y; + vtx[2] = car->priv.wheel[i].relPos.z - car->_wheelRadius(i) * 1.0f + 0.5f * SMOKE_INIT_SIZE; + tdble stretchX = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_X)); + tdble stretchY = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_Y)); + vtx[0] -= 0.05f * car->_speed_x; + shd_vtx->add(vtx); - smoke->vvx = -sinCarYaw * car->_wheelSlipSide(i); - smoke->vvy = cosCarYaw * car->_wheelSlipSide(i); - smoke->vvx += cosCarYaw * car->_wheelSlipAccel(i); - smoke->vvy += sinCarYaw * car->_wheelSlipAccel(i); - smoke->vvy += cosCarYaw * slip; - smoke->vvy += sinCarYaw * slip; + tdble init_speed = sd->init_speed * urandom(); - smoke->vvz = init_speed_z; + smoke = new ssgVtxTableSmoke(shd_vtx, SMOKE_INIT_SIZE, SMOKE_TYPE_TIRE); - smoke->vvx *= init_speed; - smoke->vvy *= init_speed; - smoke->setState(mst); - smoke->setCullFace(0); + smoke->vvx = -sinCarYaw * car->_wheelSlipSide(i); + smoke->vvy = cosCarYaw * car->_wheelSlipSide(i); + smoke->vvx += cosCarYaw * car->_wheelSlipAccel(i); + smoke->vvy += sinCarYaw * car->_wheelSlipAccel(i); + smoke->vvy += cosCarYaw * slip; + smoke->vvy += sinCarYaw * slip; - //printf("%f\n", car->_reaction[i]); - smoke->max_life = 0.0; - if (skidsmoke) - smoke->max_life = grSmokeLife * - ((car->_skid[i])*sqrt(spd2)+urandom()*spd_fx)/ smoke_life_coefficient; - else - smoke->max_life = grSmokeLife * - ((slip/10)*sqrt(spd2)+urandom()*spd_fx)/ smoke_life_coefficient; + smoke->vvz = init_speed_z; - for (int c = 0; c < 3; c++) { - smoke->cur_col[c] = sd->cur_clr[c]; - } + smoke->vvx *= init_speed; + smoke->vvy *= init_speed; + smoke->setState(mst); + smoke->setCullFace(0); - smoke->cur_life = 0; - smoke->sizex = VX_INIT + stretchX; - smoke->sizey = VY_INIT + stretchY; - smoke->sizez = VZ_INIT + 0.1f * spd_fx; + //printf("%f\n", car->_reaction[i]); + smoke->max_life = 0.0; + if (skidsmoke) + smoke->max_life = grSmokeLife * + ((car->_skid[i])*sqrt(spd2)+urandom()*spd_fx)/ smoke_life_coefficient; + else + smoke->max_life = grSmokeLife * + ((slip/10)*sqrt(spd2)+urandom()*spd_fx)/ smoke_life_coefficient; - smoke->init_alpha = 1.0/(1.0+0.1*spd_fx); - if (skidsmoke) - smoke->vexp = V_EXPANSION+((car->_skid[i])+.1*spd_fx)*(((float)rand()/(float)RAND_MAX)); - else - smoke->vexp = V_EXPANSION+((slip/3)+.1*spd_fx)*(((float)rand()/(float)RAND_MAX)); - smoke->smokeType = SMOKE_TYPE_TIRE; - smoke->smokeTypeStep = 0; - smoke->lastTime = t; - smoke->transform(grCarInfo[car->index].carPos); - SmokeAnchor->addKid(smoke); - ret = true; - }//if skidsmoke || slip - } else { - //!Add engine fire - //Smoke originates from the exhaust pipe - sgVec3 vtx; - vtx[0] = car->_exhaustPos[i].x; - vtx[1] = car->_exhaustPos[i].y; - vtx[2] = car->_exhaustPos[i].z; - ssgVertexArray *shd_vtx = new ssgVertexArray(1); - shd_vtx->add(vtx); - - smoke = new ssgVtxTableSmoke(shd_vtx, SMOKE_INIT_SIZE * 4, SMOKE_TYPE_ENGINE); + for (int c = 0; c < 3; c++) + { + smoke->cur_col[c] = sd->cur_clr[c]; + } - smoke->setState(mstf0); //Starts life lloking like fire0.rgb - smoke->setCullFace(0); - smoke->max_life = grSmokeLife / 8; - smoke->step0_max_life = (grSmokeLife) / 50.0; - smoke->step1_max_life = (grSmokeLife) / 50.0 + smoke->max_life / 2.0; - smoke->cur_life = 0; - smoke->sizex = VX_INIT * 4; - smoke->sizey = VY_INIT * 4; - smoke->sizez = VZ_INIT * 4; - smoke->vexp = V_EXPANSION + 5.0 * rand() / (RAND_MAX + 1.0) * car->_exhaustPower / 2.0; - smoke->smokeType = SMOKE_TYPE_ENGINE; - smoke->smokeTypeStep = 0; - smoke->lastTime = t; - smoke->transform(grCarInfo[car->index].carPos); - SmokeAnchor->addKid(smoke); - ret = true; - }//if type - - return ret; + smoke->cur_life = 0; + smoke->sizex = VX_INIT + stretchX; + smoke->sizey = VY_INIT + stretchY; + smoke->sizez = VZ_INIT + 0.1f * spd_fx; + + smoke->init_alpha = 1.0/(1.0+0.1*spd_fx); + if (skidsmoke) + smoke->vexp = V_EXPANSION+((car->_skid[i])+.1*spd_fx)*(((float)rand()/(float)RAND_MAX)); + else + smoke->vexp = V_EXPANSION+((slip/3)+.1*spd_fx)*(((float)rand()/(float)RAND_MAX)); + smoke->smokeType = SMOKE_TYPE_TIRE; + smoke->smokeTypeStep = 0; + smoke->lastTime = t; + smoke->transform(grCarInfo[car->index].carPos); + SmokeAnchor->addKid(smoke); + ret = true; + }//if skidsmoke || slip + } + else + { + //!Add engine fire + //Smoke originates from the exhaust pipe + sgVec3 vtx; + vtx[0] = car->_exhaustPos[i].x; + vtx[1] = car->_exhaustPos[i].y; + vtx[2] = car->_exhaustPos[i].z; + ssgVertexArray *shd_vtx = new ssgVertexArray(1); + shd_vtx->add(vtx); + + smoke = new ssgVtxTableSmoke(shd_vtx, SMOKE_INIT_SIZE * 4, SMOKE_TYPE_ENGINE); + + smoke->setState(mstf0); //Starts life lloking like fire0.rgb + smoke->setCullFace(0); + smoke->max_life = grSmokeLife / 8; + smoke->step0_max_life = (grSmokeLife) / 50.0; + smoke->step1_max_life = (grSmokeLife) / 50.0 + smoke->max_life / 2.0; + smoke->cur_life = 0; + smoke->sizex = VX_INIT * 4; + smoke->sizey = VY_INIT * 4; + smoke->sizez = VZ_INIT * 4; + smoke->vexp = V_EXPANSION + 5.0 * rand() / (RAND_MAX + 1.0) * car->_exhaustPower / 2.0; + smoke->smokeType = SMOKE_TYPE_ENGINE; + smoke->smokeTypeStep = 0; + smoke->lastTime = t; + smoke->transform(grCarInfo[car->index].carPos); + SmokeAnchor->addKid(smoke); + ret = true; + }//if type + + return ret; }//cGrSmoke::Add diff --git a/src/modules/graphic/ssggraph/grsmoke.h b/src/modules/graphic/ssggraph/grsmoke.h index 173a0e138..7c65c202c 100644 --- a/src/modules/graphic/ssggraph/grsmoke.h +++ b/src/modules/graphic/ssggraph/grsmoke.h @@ -1,26 +1,26 @@ /* * grsmoke.h - * + * * Created : Fri Mar 22 23:17:54 CET 2002 * Copyright: (C) 2001 by Christophe Guionneau - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. - * + * * $Id$ - * + * */ #ifndef _GRSMOKE_H_ @@ -43,61 +43,61 @@ class ssgVtxTableSmoke : public ssgVtxTable { protected: - virtual void copy_from ( ssgVtxTableSmoke *src, int clone_flags ) ; - + virtual void copy_from ( ssgVtxTableSmoke *src, int clone_flags ) ; + public: - inline bool isAlive() const {return cur_life < max_life;} - double max_life; - double step0_max_life; - double step1_max_life; - double step2_max_life; - double cur_life; - tdble vvx, vvy,vvz; - sgVec3 cur_col; - tdble vexp; - int smokeType; - int smokeTypeStep; - double dt; - double lastTime; - float sizex; - float sizey; - float sizez; - float init_alpha; - int stype; - virtual ssgBase *clone ( int clone_flags = 0 ) ; - ssgVtxTableSmoke () ; - ssgVtxTableSmoke (ssgVertexArray *shd_vtx , float initsize, int type); + inline bool isAlive() const {return cur_life < max_life;} + double max_life; + double step0_max_life; + double step1_max_life; + double step2_max_life; + double cur_life; + tdble vvx, vvy,vvz; + sgVec3 cur_col; + tdble vexp; + int smokeType; + int smokeTypeStep; + double dt; + double lastTime; + float sizex; + float sizey; + float sizez; + float init_alpha; + int stype; + virtual ssgBase *clone ( int clone_flags = 0 ) ; + ssgVtxTableSmoke () ; + ssgVtxTableSmoke (ssgVertexArray *shd_vtx , float initsize, int type); - void draw_geometry(); - virtual void drawHighlight ( sgVec4 colour ){ssgVtxTable::drawHighlight(colour);} - virtual void drawHighlight ( sgVec4 colour, int i ){ssgVtxTable::drawHighlight(colour,i);} + void draw_geometry(); + virtual void drawHighlight ( sgVec4 colour ){ssgVtxTable::drawHighlight(colour);} + virtual void drawHighlight ( sgVec4 colour, int i ){ssgVtxTable::drawHighlight(colour,i);} - virtual void pick ( int baseName ) { ssgVtxTable::pick(baseName);} - virtual void transform ( const sgMat4 m ) { ssgVtxTable::transform(m);} + virtual void pick ( int baseName ) { ssgVtxTable::pick(baseName);} + virtual void transform ( const sgMat4 m ) { ssgVtxTable::transform(m);} - virtual void setVertices ( ssgVertexArray *vl ) { ssgVtxTable::setVertices(vl);} - virtual void setNormals ( ssgNormalArray *nl ) { ssgVtxTable::setNormals(nl);} - virtual void setTexCoords ( ssgTexCoordArray *tl ) { ssgVtxTable::setTexCoords(tl);} - virtual void setColours ( ssgColourArray *cl ) { ssgVtxTable::setColours(cl);} + virtual void setVertices ( ssgVertexArray *vl ) { ssgVtxTable::setVertices(vl);} + virtual void setNormals ( ssgNormalArray *nl ) { ssgVtxTable::setNormals(nl);} + virtual void setTexCoords ( ssgTexCoordArray *tl ) { ssgVtxTable::setTexCoords(tl);} + virtual void setColours ( ssgColourArray *cl ) { ssgVtxTable::setColours(cl);} - int getNumVertices () { return vertices -> getNum () ; } - int getNumNormals () { return normals -> getNum () ; } - int getNumColours () { return colours -> getNum () ; } - int getNumTexCoords () { return texcoords -> getNum () ; } + int getNumVertices () { return vertices -> getNum () ; } + int getNumNormals () { return normals -> getNum () ; } + int getNumColours () { return colours -> getNum () ; } + int getNumTexCoords () { return texcoords -> getNum () ; } - int getNumTriangles () { return ssgVtxTable::getNumTriangles();} - void getTriangle ( int n, short *v1, short *v2, short *v3 ) { ssgVtxTable::getTriangle(n,v1,v2,v3);} - int getNumLines () {return ssgVtxTable::getNumLines();} - void getLine ( int n, short *v1, short *v2 ) { ssgVtxTable::getLine(n,v1,v2);} + int getNumTriangles () { return ssgVtxTable::getNumTriangles();} + void getTriangle ( int n, short *v1, short *v2, short *v3 ) { ssgVtxTable::getTriangle(n,v1,v2,v3);} + int getNumLines () {return ssgVtxTable::getNumLines();} + void getLine ( int n, short *v1, short *v2 ) { ssgVtxTable::getLine(n,v1,v2);} - virtual ~ssgVtxTableSmoke (void); + virtual ~ssgVtxTableSmoke (void); - virtual const char *getTypeName(void) { return ssgVtxTable::getTypeName();} + virtual const char *getTypeName(void) { return ssgVtxTable::getTypeName();} - virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2) { ssgVtxTable::print(fd,indent,how_much);} - virtual int load ( FILE *fd ) {return ssgVtxTable::load(fd);} - virtual int save ( FILE *fd ) {return ssgVtxTable::save(fd);} + virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2) { ssgVtxTable::print(fd,indent,how_much);} + virtual int load ( FILE *fd ) {return ssgVtxTable::load(fd);} + virtual int save ( FILE *fd ) {return ssgVtxTable::save(fd);} }; @@ -106,11 +106,11 @@ class cSmokeDef; class cGrSmoke { public: - bool Add(tCarElt* car, const int i, const double t, int smokeType, - const cSmokeDef *sd); - void Update(const double t); - - ssgVtxTableSmoke *smoke; + bool Add(tCarElt* car, const int i, const double t, int smokeType, + const cSmokeDef *sd); + void Update(const double t); + + ssgVtxTableSmoke *smoke; };