stateflocksimulation.cpp

00001 #include "statemachine.h"
00002 #include "debug.h"
00003 #include "random.h"
00004 #include "fast_atof.h"
00005 #include "flock.h"
00006 #include "boid.h"
00007 #include "flockanimatordefault.h"
00008 #include "gui.h"
00009 #include "terrain.h"
00010 #include "stateflocksimulation.h"
00011 
00012 using namespace irr;
00013 using namespace core;
00014 using namespace scene;
00015 using namespace video;
00016 using namespace gui;
00017 
00018 extern StateMachine* sm;
00019 extern Debug* dbg;
00020 extern ITimer* timer;
00021 
00022 StateFlockSimulation::StateFlockSimulation(c8* n, IrrlichtDevice* d) : State(n, d)
00023 {
00024     //ctor
00025 }
00026 
00027 StateFlockSimulation::~StateFlockSimulation()
00028 {
00029     //dtor
00030 }
00031 
00032 bool StateFlockSimulation::OnEvent(SEvent event)
00033 {
00034     if (event.EventType == EET_KEY_INPUT_EVENT)
00035     {
00036         if (event.KeyInput.PressedDown)
00037         {
00038             switch(event.KeyInput.Key)
00039             {
00040                 case KEY_ESCAPE:
00041                 {
00042                     if (guiMesh->isVisible())
00043                     {
00044                         guiMesh->setVisible(false);
00045                         guiFlock->setVisible(false);
00046                     }
00047                     else
00048                     {
00049                         guiMesh->setVisible(true);
00050                         guiFlock->setVisible(true);
00051                     }
00052                     return true;
00053                 }
00054             }
00055         }
00056     }
00057 
00058     if (event.EventType == EET_GUI_EVENT)
00059     {
00060         s32 id = event.GUIEvent.Caller->getID();
00061 
00062         switch(event.GUIEvent.EventType)
00063         {
00064             case EGET_BUTTON_CLICKED:
00065             {
00066                 switch (id)
00067                 {
00068                     case 101:
00069                     {
00070                         if (! device->getGUIEnvironment()->addFileOpenDialog(L"open file"))
00071                         {
00072                             dbg->log("openFileDialog() cannot create dialog");
00073                         }
00074                         return true;
00075                     }
00076                     case 102:
00077                     {
00078                         // create new flock
00079                         addFlock();
00080 
00081                         s32 meshScale = guiMesh->getSliderValue(111);
00082                         // for each flock
00083                         for (u32 i=0; i<flocks.size(); i++)
00084                         {
00085                             // for each boid
00086                             list<Boid*>::Iterator it = flocks[i]->getBoidList().begin();
00087                             for (; it != flocks[i]->getBoidList().end(); ++it)
00088                             {
00089                                 // update boid mesh scale
00090                                 (*it)->setScale(meshScale / 100.0f);
00091                             }
00092                         }
00093                         return true;
00094                     }
00095                     case 109:
00096                     {
00097                         // delete all flocks
00098                         for (u32 i=0; i<flocks.size(); i++)
00099                         {
00100                             flocks[i]->remove();
00101                             flocks[i]->drop();
00102                         }
00103                         flocks.clear();
00104                         return true;
00105                     }
00106                     case 199:
00107                     {
00108                         sm->pushEvent("STATE_MENU");
00109                         return true;
00110                     }
00111                     default:
00112                     {
00113                         dbg->log("StateFlockSimulation::OnEvent() unhandelt event from id", id);
00114                         return false;
00115                     }
00116                 }
00117             }
00118 
00119             case EGET_FILE_SELECTED:
00120             {
00121                 // create new flock from file open dialog
00122                 IGUIFileOpenDialog* dialog = (IGUIFileOpenDialog*)event.GUIEvent.Caller;
00123                 stringw path(dialog->getFilename());
00124                 guiMesh->setTextFromID(100, path);
00125                 addFlock();
00126                 return true;
00127             }
00128 
00129             case EGET_SCROLL_BAR_CHANGED:
00130             {
00131                 switch (id)
00132                 {
00133                     case 104:
00134                     {
00135                         // set new separation for each flock
00136                         s32 separation = guiFlock->getSliderValue(104);
00137                         for (u32 i=0; i<flocks.size(); i++)
00138                         {
00139                             flocks[i]->setSeparationWeight(separation);
00140                         }
00141                         break;
00142                     }
00143                     case 106:
00144                     {
00145                         // set new alignment for each flock
00146                         s32 alignment = guiFlock->getSliderValue(106);
00147                         for (u32 i=0; i<flocks.size(); i++)
00148                         {
00149                             flocks[i]->setAlignmentWeight(alignment);
00150                         }
00151                         break;
00152                     }
00153                     case 108:
00154                     {
00155                         // set new cohesion for each flock
00156                         s32 cohesion = guiFlock->getSliderValue(108);
00157                         for (u32 i=0; i<flocks.size(); i++)
00158                         {
00159                             flocks[i]->setCohesionWeight(cohesion);
00160                         }
00161                         break;
00162                     }
00163                     case 113:
00164                     {
00165                         // set new radius of neighbor searchness for each flock
00166                         s32 radius = guiFlock->getSliderValue(113);
00167                         for (u32 i=0; i<flocks.size(); i++)
00168                         {
00169                             flocks[i]->setNeighborRadius(radius * 10);
00170                         }
00171                         break;
00172                     }
00173                     case 115:
00174                     {
00175                         // set new target seekness
00176                         s32 seekness = guiFlock->getSliderValue(115);
00177                         for (u32 i=0; i<flocks.size(); i++)
00178                         {
00179                             flocks[i]->setSeekTargetWeight(seekness);
00180                         }
00181                         break;
00182                     }
00183                     case 111:
00184                     {
00185                         // set new sclae of mesh for each boid for each flock
00186                         s32 meshScale = guiMesh->getSliderValue(111);
00187                         for (u32 i=0; i<flocks.size(); i++)
00188                         {
00189                             list<Boid*>::Iterator it = flocks[i]->getBoidList().begin();
00190                             for (; it != flocks[i]->getBoidList().end(); ++it)
00191                             {
00192                                 (*it)->setScale(meshScale / 100.0f);
00193                             }
00194                         }
00195                         break;
00196                     }
00197                     default:
00198                     {
00199                         dbg->log("StateFlockSimulation::OnEvent() unhandelt event from id", id);
00200                         return false;
00201                     }
00202                 }
00203                 return true;
00204             }
00205         }
00206     }
00207 
00208     if (event.EventType == EET_MOUSE_INPUT_EVENT)
00209     {
00210         switch(event.MouseInput.Event)
00211         {
00212             case EMIE_LMOUSE_PRESSED_DOWN:
00213             {
00214                 return false;
00215             }
00216             case EMIE_RMOUSE_PRESSED_DOWN:
00217             {
00218                 return false;
00219             }
00220             case EMIE_MOUSE_WHEEL:
00221             {
00222                 f32 speed = event.MouseInput.Wheel;
00223                 moveCamera(speed * 100.0f);
00224                 return true;
00225             }
00226         }
00227     }
00228 
00229     return false;
00230 }
00231 
00232 void StateFlockSimulation::render(u32 deltaTime)
00233 {
00234     device->getVideoDriver()->beginScene(true, true, video::SColor(0,0,150,150));
00235     device->getSceneManager()->drawAll();
00236 
00237     dbg->show("this is FlockSimulationState");
00238     dbg->show("roll WHEEL to zoom");
00239     dbg->show("polyCount", device->getVideoDriver()->getPrimitiveCountDrawn());
00240     dbg->show("fps", device->getVideoDriver()->getFPS());
00241     //dbg->show("camPos", camera->getPosition());
00242 
00243     s32 sum = 0;
00244     for (u32 i=0; i<flocks.size(); i++)
00245     {
00246         flocks[i]->update(deltaTime);
00247         sum += flocks[i]->getBoidCount();
00248     }
00249     dbg->show("boidsCount", sum);
00250 
00251     device->getGUIEnvironment()->drawAll();
00252     device->getVideoDriver()->endScene();
00253 
00254     // camera tracks last added flock
00255     if (!flocks.empty())
00256     {
00257         vector3df flockCenter = flocks.getLast()->getBoundingBox().getCenter();
00258         camera->setTarget(flockCenter);
00259     }
00260 }
00261 
00262 void StateFlockSimulation::entry()
00263 {
00264     dbg->log("State", name, "entry");
00265 
00266     // init members
00267 
00268     // create GUI
00269     guiMesh = new Gui(device, stringc("Mesh"), rect<s32>(20, 220, 200, 430));
00270     guiMesh->addText(100, "media/fly/satelite40Faces1Texture.3DS");
00271     guiMesh->addButton(101, "Open mesh file");
00272     guiMesh->addButton(102, "Create flock");
00273     guiMesh->addButton(109, "Clear scene");
00274     guiMesh->addSlider(111, "Meshscale", 16);
00275     guiMesh->addButton(199, "Exit");
00276 
00277     guiFlock = new Gui(device, stringc("Flock behavior mixer"), rect<s32>(600, 20, 780, 120));
00278     guiFlock->addSlider(104, "Separation", 36);
00279     guiFlock->addSlider(106, "Alignment", 0);
00280     guiFlock->addSlider(108, "Cohesion", 35);
00281     guiFlock->addSlider(113, "Neighbor_Radius", 10);
00282     guiFlock->addSlider(115, "Seek_Target", 8);
00283 
00284     // get that messy terrain
00285     terrain = new Terrain(device, "media/terrain/terrain97_128.bmp", "media/terrain/textur99.bmp", "");
00286 
00287     // create camera
00288     camera = device->getSceneManager()->addCameraSceneNode();
00289     camera->setPosition(terrain->getCenter() + vector3df(500, 1500, 500) );
00290     camera->setRotation(vector3df(60,20,0));
00291 
00292     // create light
00293     ILightSceneNode* light = device->getSceneManager()->addLightSceneNode(camera);
00294     light->getLightData().Radius *= 40;
00295 
00296     //device->getCursorControl()->setVisible(false);
00297     device->getSceneManager()->getActiveCamera()->setFarValue(5000);
00298 }
00299 
00300 void StateFlockSimulation::exit()
00301 {
00302     dbg->log("State", name, "exit");
00303 
00304     // deinit members
00305     for (u32 i=0; i<flocks.size(); i++)
00306     {
00307         flocks[i]->remove();
00308         flocks[i]->drop();
00309     }
00310     flocks.clear();
00311 
00312     delete guiMesh;
00313     delete guiFlock;
00314     delete terrain;
00315 
00316     device->getSceneManager()->clear();
00317 }
00318 
00319 void StateFlockSimulation::moveCamera(f32 speed)
00320 {
00321     vector3df start = camera->getPosition();
00322     vector3df target = camera->getTarget() - start;
00323     target.normalize();
00324     camera->setPosition(start + target * speed);
00325 }
00326 
00327 void StateFlockSimulation::addFlock()
00328 {
00329     stringc filePath = guiMesh->getTextFromID(100);
00330     Flock* f = new Flock(device, 50, filePath.c_str(),
00331         device->getSceneManager()->getRootSceneNode() );
00332 
00333     // animatorDefault behavior
00334     f->setSeparationWeight(guiFlock->getSliderValue(104));
00335     f->setAlignmentWeight(guiFlock->getSliderValue(106));
00336     f->setCohesionWeight(guiFlock->getSliderValue(108));
00337     f->setNeighborRadius(guiFlock->getSliderValue(113) * 10);
00338     f->setTarget(terrain->getCenter() + vector3df(0, 1000, 0) );
00339     f->setSeekTargetWeight(guiFlock->getSliderValue(115));
00340     // animatorTornado behavior
00341     f->setTornadoWeight(1);
00342 
00343     flocks.push_back(f);
00344 
00345 /*
00346     Random random(timer->getRealTime());
00347     vector3df center(random.randfloat(-40,40), random.randfloat(0,30), random.randfloat(-40,40));
00348     f32 power = random.randfloat(0.0f, 10.0f);
00349     FlockAnimatorExplode* animE = new FlockAnimatorExplode(device, center, timer->getTime(), 50000, power);
00350     f->addAnimator(animE);
00351     animE->drop();
00352 */
00353 
00354     FlockAnimatorDefault* flockAnimDefault = new FlockAnimatorDefault(device);
00355     f->addAnimator(flockAnimDefault);
00356     flockAnimDefault->drop();
00357 }

Generated on Sun Dec 2 17:09:58 2007 for Swarm by  doxygen 1.4.6-NO