[Gcblue-commits] gcb_wx/src/graphics tcParticleEffect.cpp,NONE,1.1 ObjectUpdater.cpp,1.7,1.8 tc3DMod
Status: Alpha
Brought to you by:
ddcforge
|
From: Dewitt C. <ddc...@us...> - 2004-06-04 21:39:31
|
Update of /cvsroot/gcblue/gcb_wx/src/graphics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4924/src/graphics Modified Files: ObjectUpdater.cpp tc3DModel.cpp Added Files: tcParticleEffect.cpp Log Message: --- NEW FILE: tcParticleEffect.cpp --- /** @file tcParticleEffect.cpp ** ** Copyright (C) 2004 Dewitt Colclough (de...@tw...) ** All rights reserved. ** ** This file is part of the Global Conflict Blue (GCB) program. ** GCB is free software; you can redistribute it and/or modify ** it under the terms of version 2 of the GNU General Public License as ** published by the Free Software Foundation. ** ** GCB 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 GCB; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "tcParticleEffect.h" #include <osg/Group> #include <osg/Geode> #include <osgParticle/Particle> #include <osgParticle/ParticleSystem> #include <osgParticle/ParticleSystemUpdater> #include <osgParticle/ModularEmitter> #include <osgParticle/ModularProgram> #include <osgParticle/RandomRateCounter> #include <osgParticle/SectorPlacer> #include <osgParticle/RadialShooter> #include <osgParticle/AccelOperator> #include <osgParticle/FluidFrictionOperator> #include "stdwx.h" // precompiled header file #ifndef WX_PRECOMP #include "wx/wx.h" #ifdef WIN32 #include "wx/msw/private.h" // for MS Windows specific definitions #endif #endif #include "tcParticlePlacer.h" ////////////////////////////////////////////////////////////////////////////// // CUSTOM OPERATOR CLASS ////////////////////////////////////////////////////////////////////////////// // This class demonstrates Operator subclassing. This way you can create // custom operators to apply your motion effects to the particles. See docs // for more details. class VortexOperator: public osgParticle::Operator { public: VortexOperator() : osgParticle::Operator(), center_(0, 0, 0), axis_(0, 0, 1), intensity_(0.1f) {} VortexOperator(const VortexOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY) : osgParticle::Operator(copy, copyop), center_(copy.center_), axis_(copy.axis_), intensity_(copy.intensity_) {} META_Object(osgParticle, VortexOperator); void setCenter(const osg::Vec3 &c) { center_ = c; } void setAxis(const osg::Vec3 &a) { axis_ = a / a.length(); } // this method is called by ModularProgram before applying // operators on the particle set via the operate() method. void beginOperate(osgParticle::Program *prg) { // we have to check whether the reference frame is relative to parents // or it's absolute; in the first case, we must transform the vectors // from local to world space. if (prg->getReferenceFrame() == osgParticle::Program::RELATIVE_TO_PARENTS) { // transform the center point (full transformation) xf_center_ = prg->transformLocalToWorld(center_); // transform the axis vector (only rotation and scale) xf_axis_ = prg->rotateLocalToWorld(axis_); } else { xf_center_ = center_; xf_axis_ = axis_; } } // apply a vortex-like acceleration. This code is not optimized, // it's here only for demonstration purposes. void operate(osgParticle::Particle *P, double dt) { float l = xf_axis_ * (P->getPosition() - xf_center_); osg::Vec3 lc = xf_center_ + xf_axis_ * l; osg::Vec3 R = P->getPosition() - lc; osg::Vec3 v = (R ^ xf_axis_) * P->getMassInv() * intensity_; // compute new position osg::Vec3 newpos = P->getPosition() + v * dt; // update the position of the particle without modifying its // velocity vector (this is unusual, normally you should call // the Particle::setVelocity() or Particle::addVelocity() // methods). P->setPosition(newpos); } protected: virtual ~VortexOperator() {} private: osg::Vec3 center_; osg::Vec3 xf_center_; osg::Vec3 axis_; osg::Vec3 xf_axis_; float intensity_; }; osgParticle::ParticleSystemUpdater* tcParticleEffect::particleSystemUpdater = NULL; void tcParticleEffect::SetParticleSystemUpdater(osgParticle::ParticleSystemUpdater* psu) { particleSystemUpdater = psu; } void tcParticleEffect::AddToSceneGraph(osg::Group* rootGroup) { if (root) { std::cerr << "Warning - tcParticleEffect already added to scene graph, " "detaching first\n"; DetachFromSceneGraph(); } root = rootGroup; // add the emitter to the scene graph wxASSERT(emitter.valid()); root->addChild(emitter.get()); // add program to the scene graph wxASSERT(program.valid()); root->addChild(program.get()); // add top-level geode to scene graph wxASSERT(geode.valid()); root->addChild(geode.get()); // add the updater node to the scene graph wxASSERT(updater.valid()); root->addChild(updater.get()); } /** * Configures particle template based on smoke mode */ void tcParticleEffect::ConfigureForMode() { osgParticle::Particle ptemplate; counter->setRateRange(30, 50); switch (smokeMode) { case MISSILE: { ptemplate.setLifeTime(3); // 3 seconds of life ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f)); ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f)); ptemplate.setColorRange(osgParticle::rangev4( osg::Vec4(0.8f, 0.8f, 0.8f, 1.5f), osg::Vec4(0, 0.7f, 1.0f, 0.0f))); ptemplate.setRadius(1.5f); // 5 cm wide particles ptemplate.setMass(0.05f); // 50 g heavy shooter->setInitialSpeedRange(0, 0); accelOp->setAcceleration(osg::Vec3(0, 0, 0)); } break; case AFTERBURNER: { ptemplate.setLifeTime(3); // 3 seconds of life ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f)); ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f)); ptemplate.setColorRange(osgParticle::rangev4( osg::Vec4(0.8f, 0.6f, 0.6f, 1.5f), osg::Vec4(0, 0.7f, 1.0f, 0.0f))); ptemplate.setRadius(0.5f); // 5 cm wide particles ptemplate.setMass(0.05f); // 50 g heavy shooter->setInitialSpeedRange(0, 0); accelOp->setAcceleration(osg::Vec3(0, 0, 0)); } break; case DAMAGE: { ptemplate.setLifeTime(8); // 3 seconds of life ptemplate.setSizeRange(osgParticle::rangef(2.5f, 5.0f)); ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f)); ptemplate.setColorRange(osgParticle::rangev4( osg::Vec4(0.0f, 0.0f, 0.0f, 1.5f), osg::Vec4(0.7, 0.6f, 0.6f, 0.0f))); ptemplate.setRadius(25.0f); ptemplate.setMass(0.05f); // for friction op I guess shooter->setInitialSpeedRange(3, 15); //shooter->setPhiRange(-0.5, 0.5); //shooter->setThetaRange(-0.5, 0.5); accelOp->setAcceleration(osg::Vec3(0, 0, -0.1)); //osgParticle::FluidFrictionOperator *op = new osgParticle::FluidFrictionOperator; //op->setFluidToAir(); //program->addOperator(op); } break; default: break; } setDefaultAttributes("smoke.rgb", false, false); setDefaultParticleTemplate(ptemplate); } void tcParticleEffect::DetachFromSceneGraph() { if (!root) { std::cerr << "Warning - tcParticleEffect already removed from scene graph," "skipping\n"; return; } // remove the updater node from the scene graph wxASSERT(updater.valid()); root->removeChild(updater.get()); // remove geode from scene graph wxASSERT(geode.valid()); root->removeChild(geode.get()); // remove program from scene graph wxASSERT(program.valid()); root->removeChild(program.get()); // remove emitter from scene graph wxASSERT(emitter.valid()); root->removeChild(emitter.get()); root = 0; } tcParticleEffect::tcParticleEffect(int smokeModeCode) : root(0), smokeMode(smokeModeCode) { emitter = new osgParticle::ModularEmitter; emitter->setParticleSystem(this); counter = new osgParticle::RandomRateCounter; emitter->setCounter(counter.get()); particlePlacer = new osgParticle::tcParticlePlacer; particlePlacer->setCenter(0, 0, 0); emitter->setPlacer(particlePlacer); emitter->setReferenceFrame(osgParticle::Emitter::RELATIVE_TO_ABSOLUTE); shooter = new osgParticle::RadialShooter; emitter->setShooter(shooter.get()); program = new osgParticle::ModularProgram; program->setParticleSystem(this); // create an operator that simulates the gravity acceleration. accelOp = new osgParticle::AccelOperator; program->addOperator(accelOp.get()); /* VortexOperator *op2 = new VortexOperator; op2->setCenter(osg::Vec3(8, 0, 0)); program->addOperator(op2); // fluid operator to simulate air friction. osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator; op3->setFluidToAir(); program->addOperator(op3); */ ConfigureForMode(); // create a Geode to contain the particle system. geode = new osg::Geode; geode->addDrawable(this); updater = new osgParticle::ParticleSystemUpdater; updater->addParticleSystem(this); } tcParticleEffect::~tcParticleEffect() { } Index: ObjectUpdater.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/ObjectUpdater.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ObjectUpdater.cpp 11 Apr 2004 21:59:16 -0000 1.7 --- ObjectUpdater.cpp 4 Jun 2004 21:39:22 -0000 1.8 *************** *** 4,7 **** --- 4,8 ---- #include "tc3DViewer.h" #include <osg/MatrixTransform> + #include "tcParticleEffect.h" using namespace osg; *************** *** 101,105 **** --- 102,126 ---- osg::Vec3 cameraDelta = osg::Vec3(x,y,z) - viewer->GetCameraPosition(); distanceFromCamera = cameraDelta.length(); + model->SetDistanceFromCamera(distanceFromCamera); + + if ((distanceFromCamera <= 20)&&(gameObject->parent == 0)) + { + int xx = 8; + } + /* + if ((abs(x) < 4000)&&(gameObject->parent == 0)) + { + int xx = 8; + osg::Vec3 camPos = viewer->GetCameraPosition(); + } + */ + + + if (model->IsSmokeEnabled()) + { + model->UpdateSmokePosition(x, y, z); + } + osg::Matrix m = osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* Index: tc3DModel.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tc3DModel.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** tc3DModel.cpp 13 Apr 2004 21:37:40 -0000 1.9 --- tc3DModel.cpp 4 Jun 2004 21:39:22 -0000 1.10 *************** *** 32,35 **** --- 32,37 ---- #include "tcPlatformObject.h" #include "ObjectUpdater.h" + #include "tcParticleEffect.h" + #include "tcParticlePlacer.h" #include "tcGenericDBObject.h" #include <osg/MatrixTransform> *************** *** 237,240 **** --- 239,245 ---- }; + + osg::ref_ptr<osg::Group> tc3DModel::world; + /** * Adds child to modelTransform of this model. *************** *** 260,263 **** --- 265,293 ---- } + /** + * Do not call this in the middle of scene graph traversal. + * This leads to a crash! + */ + void tc3DModel::DisableSmoke() + { + if (smokeTrail.valid()) + { + smokeTrail->DetachFromSceneGraph(); + smokeTrail.release(); + smokePlacer = 0; + } + } + + /** + * Do not call this in the middle of scene graph traversal. + * This leads to a crash! + */ + void tc3DModel::EnableSmoke() + { + smokeTrail = new tcParticleEffect(smokeMode); + smokeTrail->AddToSceneGraph(world.get()); + smokePlacer = smokeTrail->GetParticlePlacer(); + } + osg::ref_ptr<osg::Node> tc3DModel::GetNode() { *************** *** 350,353 **** --- 380,414 ---- /** + * Call outside of scene graph traversal + */ + void tc3DModel::UpdateEffects() + { + wxASSERT(gameObj); + + bool disableSmoke = ((smokeMode == tcParticleEffect::OFF) || + (gameObj->parent) || (distanceFromCamera > 2000)); + bool smokeDisabled = !IsSmokeEnabled(); + + if (disableSmoke != smokeDisabled) + { + if (disableSmoke) + { + DisableSmoke(); + } + else + { + EnableSmoke(); + } + } + } + + void tc3DModel::UpdateSmokePosition(float x, float y, float z) + { + wxASSERT(smokePlacer); + if (smokePlacer == 0) return; + smokePlacer->setCenter(x, y, z); + } + + /** * This constructor is used for the source/factory, notionally * stored as part of the database object. *************** *** 364,367 **** --- 425,430 ---- */ tc3DModel::tc3DModel(const tc3DModel* source) + : smokePlacer(0), + distanceFromCamera(1e10) { wxASSERT(source->modelNode.valid()); // error if modelNode not loaded yet *************** *** 398,402 **** - } --- 461,464 ---- |