topical media & game development

talk show tell print

lib-game-delta3d-sdk-examples-testMotionModels-testmotionmodels.cpp / cpp



  /* -*-c++-*-
   * testMotionModels - testmotionmodels(.h & .cpp) - Using 'The MIT License'
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   */
  
  include <dtUtil/log.h>
  include <dtCore/collisionmotionmodel.h>
  include <dtCore/deltawin.h>
  include <dtCore/flymotionmodel.h>
  include <dtCore/fpsmotionmodel.h>
  include <dtCore/globals.h>
  include <dtCore/motionmodel.h>
  include <dtCore/object.h>
  include <dtCore/orbitmotionmodel.h>
  include <dtCore/refptr.h>
  include <dtCore/rtsmotionmodel.h>
  include <dtCore/scene.h>
  include <dtCore/ufomotionmodel.h>
  include <dtCore/walkmotionmodel.h>
  include <dtCore/system.h>
  
  include <dtABC/application.h>
  
  include <CEGUI/elements/CEGUIRadioButton.h>
  include <CEGUI/CEGUIExceptions.h>
  include <CEGUI/CEGUISystem.h>
  include <CEGUI/CEGUISchemeManager.h>
  include <CEGUI/CEGUIWindowManager.h>
  include <CEGUI/CEGUIEventArgs.h>
  include <dtGUI/ceuidrawable.h>
  
  include <iostream>
  
  using namespace dtCore;
  using namespace dtABC;
  using namespace dtUtil;
  
  namespace dtExample
  {
  
a quick way to manage the types of motion models we want to show off enum MotionModelType { WALK = 0L, FLY, UFO, ORBIT, FPS, COLLISION, RTS };

  
a small helper class that will set up and modify the GUI class QuickMenuManager : public osg::Referenced { public: typedef dtUtil::Functor<void,TYPELIST_1(MotionModelType)> ForwardingFunctor;

        QuickMenuManager(const ForwardingFunctor& ff)
           :mPausedUI(NULL)
           , mUseSimTimeUI(NULL)
           , mWalk(NULL)
           , mFly(NULL)
           , mUFO(NULL)
           , mOrbit(NULL)
           , mFPS(NULL)
           , mCollision(NULL)
           , mRTS(NULL)
           , mForwardingFunctor(ff)
        {
        }
  
        void SetSelected(const MotionModelType mt)
        {
           switch (mt)
           {
              case WALK:
              {
                 mWalk->setSelected(true);
              }
              break;
  
              case FLY:
              {
                 mFly->setSelected(true);
              }
              break;
  
              case UFO:
              {
                 mUFO->setSelected(true);
              }
              break;
  
              case ORBIT:
              {
                 mOrbit->setSelected(true);
              }
              break;
  
              case FPS:
              {
                 mFPS->setSelected(true);
              }
              break;
  
              case COLLISION:
              {
                 mCollision->setSelected(true);
              }
              break;
  
              case RTS:
              {
                 mRTS->setSelected(true);
              }
              break;
           }
        }
  
        bool ChangeMotionModelCB(const CEGUI::EventArgs& ea)
        {
           const CEGUI::WindowEventArgs& wea = static_cast<const CEGUI::WindowEventArgs&>( ea );
  
           if (mWalk == wea.window)           { mForwardingFunctor( WALK ); }
           else if (mFly == wea.window)       { mForwardingFunctor( FLY ); }
           else if (mUFO == wea.window)       { mForwardingFunctor( UFO ); }
           else if (mOrbit == wea.window)     { mForwardingFunctor( ORBIT ); }
           else if (mFPS == wea.window)       { mForwardingFunctor( FPS ); }
           else if (mCollision == wea.window) { mForwardingFunctor( COLLISION ); }
           else if (mRTS == wea.window)       { mForwardingFunctor( RTS ); }
  
           return true;
        }
  
        void BuildMenu()
        {
           try
           {
              std::string schemefile(dtCore::FindFileInPathList("gui/schemes/WindowsLook.scheme"));
              CEGUI::SchemeManager* sm = CEGUI::SchemeManager::getSingletonPtr();
              sm->loadScheme(schemefile);  
< populate the window factories
} catch(CEGUI::Exception&) { LOG_ERROR("A problem occurred loading the scheme.") } try { CEGUI::Window* rootWindow = CreateWidget("DefaultGUISheet", "root"); rootWindow->setArea(CEGUI::UVector2(cegui_reldim(0),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(1.0),cegui_reldim(1.0))); CEGUI::Window* frame = CreateWidget("WindowsLook/StaticText","frame"); frame->setArea(CEGUI::UVector2(cegui_reldim(0.f),cegui_reldim(0.08f /*0.f*/)), CEGUI::UVector2(cegui_reldim(1.f),cegui_reldim(0.12f /*0.2f*/))); //frame->setProperty("FrameEnabled", "false"); frame->setProperty("BackgroundEnabled","True"); frame->setProperty("BackgroundColours","tl:FFDFDFDF tr:FFDFDFDF bl:FFDFDFDF br:FFDFDFDF"); //frame->setProperty("BackgroundEnabled", "false"); frame->setText(""); rootWindow->addChildWindow(frame); CEGUI::Window* menu = CreateWidget("DefaultWindow","SelectionBar"); menu->setArea(CEGUI::UVector2(cegui_reldim(0),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(1.0),cegui_reldim(1.0))); frame->addChildWindow( menu ); CEGUI::Window* walk = CreateWidget("WindowsLook/RadioButton","WALK"); walk->setArea(CEGUI::UVector2(cegui_reldim(0.05),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); walk->setText("WALK (1)"); walk->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( walk ); CEGUI::Window* fly = CreateWidget("WindowsLook/RadioButton","FLY"); fly->setArea(CEGUI::UVector2(cegui_reldim(0.25),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); fly->setText("FLY (2)"); fly->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( fly ); CEGUI::Window* ufo = CreateWidget("WindowsLook/RadioButton","UFO"); ufo->setArea(CEGUI::UVector2(cegui_reldim(0.45),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); ufo->setText("UFO (3)"); ufo->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( ufo ); CEGUI::Window* orb = CreateWidget("WindowsLook/RadioButton","ORBIT"); orb->setArea(CEGUI::UVector2(cegui_reldim(0.65),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); orb->setText("ORBIT (4)"); orb->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( orb ); CEGUI::Window* fps = CreateWidget("WindowsLook/RadioButton","FPS"); fps->setArea(CEGUI::UVector2(cegui_reldim(0.85),cegui_reldim(0)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); fps->setText("FPS (5)"); fps->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( fps ); CEGUI::Window* col = CreateWidget("WindowsLook/RadioButton","COLLISION"); col->setArea(CEGUI::UVector2(cegui_reldim(0.05),cegui_reldim(0.25)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); col->setText("COLLISION (6)"); col->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( col ); CEGUI::Window* rts = CreateWidget("WindowsLook/RadioButton","RTS"); rts->setArea(CEGUI::UVector2(cegui_reldim(0.25),cegui_reldim(0.25)), CEGUI::UVector2(cegui_reldim(0.2),cegui_reldim(1.0))); rts->setText("RTS (7)"); rts->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&QuickMenuManager::ChangeMotionModelCB,this)); menu->addChildWindow( rts ); mPausedUI = CreateWidget("WindowsLook/StaticText", "PausedUI"); mPausedUI->setText("(F2) Not Paused"); mPausedUI->setPosition(CEGUI::UVector2(cegui_absdim(10), cegui_absdim(400))); mPausedUI->setSize(CEGUI::UVector2(cegui_absdim(155), cegui_absdim(20))); rootWindow->addChildWindow(mPausedUI); mUseSimTimeUI = CreateWidget("WindowsLook/StaticText", "UseSimTimeUI"); mUseSimTimeUI->setText("(F3) REAL Time (if applies)"); mUseSimTimeUI->setPosition(CEGUI::UVector2(cegui_absdim(10), cegui_absdim(421))); mUseSimTimeUI->setSize(CEGUI::UVector2(cegui_absdim(155), cegui_absdim(20))); rootWindow->addChildWindow(mUseSimTimeUI); CEGUI::System::getSingleton().setGUISheet(rootWindow/*menu*/); InitializeWidgets(static_cast<CEGUI::RadioButton*>(walk), static_cast<CEGUI::RadioButton*>(fly), static_cast<CEGUI::RadioButton*>(ufo), static_cast<CEGUI::RadioButton*>(orb), static_cast<CEGUI::RadioButton*>(fps), static_cast<CEGUI::RadioButton*>(col), static_cast<CEGUI::RadioButton*>(rts) ); } catch(CEGUI::Exception&) { LOG_ERROR("A problem occurred creating the layout.") } } protected: ~QuickMenuManager() { } void InitializeWidgets(CEGUI::RadioButton* walk, CEGUI::RadioButton* fly, CEGUI::RadioButton* ufo, CEGUI::RadioButton* orb, CEGUI::RadioButton* fps, CEGUI::RadioButton* col, CEGUI::RadioButton* rts) { mWalk = walk; mFly = fly; mUFO = ufo; mOrbit = orb; mFPS = fps; mCollision = col; mRTS = rts; } CEGUI::Window* CreateWidget(const std::string& wtype, const std::string& wname) { CEGUI::WindowManager* wmgr = CEGUI::WindowManager::getSingletonPtr(); CEGUI::Window* w = NULL; try { w = wmgr->createWindow(wtype, wname); } catch (CEGUI::Exception& e) { std::string err; err += std::string("Can't create CEGUI Window of type "); err += wtype; err += std::string("."); err += std::string(e.getMessage().c_str()); LOG_ERROR(err); } return w; } public: CEGUI::Window* mPausedUI; CEGUI::Window* mUseSimTimeUI; private: CEGUI::RadioButton* mWalk; CEGUI::RadioButton* mFly; CEGUI::RadioButton* mUFO; CEGUI::RadioButton* mOrbit; CEGUI::RadioButton* mFPS; CEGUI::RadioButton* mCollision; CEGUI::RadioButton* mRTS; ForwardingFunctor mForwardingFunctor; }; }
The motion model test application.
class TestMotionModelsApp : public Application { DECLARE_MANAGEMENT_LAYER(TestMotionModelsApp) public:
Constructor. TestMotionModelsApp(const std::string& configFile = "config.xml") : Application(configFile) , mTown(NULL) , mGUIDrawable(NULL) , mMenuManager(NULL) , mUseSimTime(false) , mCurrentMotionModelIndex(0) { dtExample::QuickMenuManager::ForwardingFunctor ff(this, &TestMotionModelsApp::SetMotionModel); mMenuManager = new dtExample::QuickMenuManager(ff); }

     void Config()
     {
        //make sure to call the Base Config() as well.
        Application::Config();
  
        mTown = new Object("Town");
  
        if (!mOptionalFilename.empty())
        {
           mTown->LoadFile(mOptionalFilename);
        }
        else
        {
           mTown->LoadFile("/demoMap/StaticMeshes/TestTownLt.ive");
        }
  
       
        mTown->SetCollisionMesh();
        AddDrawable(mTown.get());
        GetScene()->GetSceneNode()->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);
  
        RefPtr<WalkMotionModel> wmm = new WalkMotionModel(GetKeyboard(), GetMouse());
        wmm->SetScene(GetScene());
        mMotionModels.push_back(wmm.get());
  
        mMotionModels.push_back(new FlyMotionModel(GetKeyboard(), GetMouse()));
        mMotionModels.push_back(new UFOMotionModel(GetKeyboard(), GetMouse()));
        mMotionModels.push_back(new OrbitMotionModel(GetKeyboard(), GetMouse()));
  
        RefPtr<FPSMotionModel> fmm = new FPSMotionModel(GetKeyboard(), GetMouse());
        fmm->SetScene(GetScene());
        mMotionModels.push_back(fmm.get());
  
        osg::Vec3 gravity;
        GetScene()->GetGravity(gravity);
        mMotionModels.push_back(new CollisionMotionModel(1.5f, 0.4f, 0.25f, 0.1f, GetScene(), GetKeyboard(), GetMouse()));
  
        mMotionModels.push_back(new RTSMotionModel(GetKeyboard(), GetMouse()));
  
        for (unsigned int i = 0; i < mMotionModels.size(); i++)
        {
           mMotionModels[i]->SetTarget(GetCamera());
        }
  
        // show a HUD
        mGUIDrawable = new dtGUI::CEUIDrawable(GetWindow(), GetKeyboard(), GetMouse());
        AddDrawable(mGUIDrawable.get());
        mMenuManager->BuildMenu();
        mMenuManager->SetSelected(dtExample::WALK);
     }
  
     
Key press callback.
parameter: keyboard the keyboard object generating the event
parameter: key the key pressed
parameter: character the corresponding character

  
     virtual bool KeyPressed(const dtCore::Keyboard* kb, int key)
     {
        bool verdict = Application::KeyPressed(kb, key);
        if (verdict)
        {
           return verdict;
        }
  
        switch (key)
        {
        case '1':
           mMenuManager->SetSelected(dtExample::WALK);
           verdict = true;
           break;
        case '2':
           mMenuManager->SetSelected(dtExample::FLY);
           verdict = true;
           break;
        case '3':
           mMenuManager->SetSelected(dtExample::UFO);
           verdict = true;
           break;
        case '4':
           mMenuManager->SetSelected(dtExample::ORBIT);
           verdict = true;
           break;
        case '5':
           mMenuManager->SetSelected(dtExample::FPS);
           verdict = true;
           break;
        case '6':
           mMenuManager->SetSelected(dtExample::COLLISION);
           verdict = true;
           break;
        case '7':
           mMenuManager->SetSelected(dtExample::RTS);
           verdict = true;
           break;
  
        case osgGA::GUIEventAdapter::KEY_F2:
           {
              bool bPausedState = !dtCore::System::GetInstance().GetPause();
              dtCore::System::GetInstance().SetPause(bPausedState);
              if (bPausedState)
                 mMenuManager->mPausedUI->setText("(F2) PAUSED!");
              else
                 mMenuManager->mPausedUI->setText("(F3) Not Paused");
           }
           break;
  
        case osgGA::GUIEventAdapter::KEY_F3:
           {
              mUseSimTime = !mUseSimTime;
              if (mUseSimTime)
                 mMenuManager->mUseSimTimeUI->setText("(F3) SIM Time (if applies)");
              else
                 mMenuManager->mUseSimTimeUI->setText("(F3) REAL Time (if applies)");
              std::cout << "Note - only a few motion models support Sim time vs Real Time including::  FlyMotionModel." << std::endl;
  
              // resetting the MM will update the sim time flag.
              SetMotionModel(mCurrentMotionModelIndex);
           }
           break;
  
        default:
           break;
        }
  
        return verdict;
     }
  
     
  
     public:
        // Allow command settings to override the default filename. Allows this app to be used to test external models.
        std::string mOptionalFilename;
  
     protected:
        ~TestMotionModelsApp()
        {
           mGUIDrawable->ShutdownGUI();
        }
  
  private:
  
     
Enables one of the four motion models and disables the rest.
parameter: index the index of the motion model to enable

  
     void SetMotionModel(unsigned int index)
     {
        mCurrentMotionModelIndex = index;
  
        for (unsigned int i = 0; i < mMotionModels.size(); i++)
        {
           mMotionModels[i]->SetEnabled(i == index);
  
           if (i == index)
           {
              // figure out which MM we have so we can set the option flags appropriately.  
              // Currently, only Fly supports this 
              FlyMotionModel *flyMM = dynamic_cast<FlyMotionModel*> (mMotionModels[i].get());
              if (flyMM != NULL)
                 flyMM->SetUseSimTimeForSpeed(mUseSimTime);
           }
        }
  
        //turn off cursor for FPS motion model
        bool show_cursor = (index != dtExample::FPS) &&
                           (index != dtExample::COLLISION);
        GetWindow()->ShowCursor(show_cursor);
     }
  
  
The Town. RefPtr<Object> mTown;

  
The five motion models. std::vector< RefPtr<MotionModel> > mMotionModels;

  
Tool for rendering GUI. dtCore::RefPtr<dtGUI::CEUIDrawable> mGUIDrawable;

     dtCore::RefPtr<dtExample::QuickMenuManager> mMenuManager;
  
     bool mUseSimTime; // ie sim time versus real time. Only supported by some motion models.
     unsigned int mCurrentMotionModelIndex;
  
  };
  
  IMPLEMENT_MANAGEMENT_LAYER(TestMotionModelsApp)
  
  int main(int argc, char** argv)
  {
     std::string dataPath = dtCore::GetDeltaDataPathList();
     dtCore::SetDataFilePathList(dataPath + ";" +
                                 dtCore::GetDeltaRootPath() + "/examples/data/;" +
                                 dtCore::GetDeltaRootPath() + "/examples/data/gui/imagesets;" +
                                 dtCore::GetDeltaRootPath() + "/examples/data/gui/schemes;" +
                                 dtCore::GetDeltaRootPath() + "/examples/data/gui/fonts;" +
                                 dtCore::GetDeltaRootPath() + "/examples/data/gui/looknfeel;" +
                                 dtCore::GetDeltaRootPath() + "/examples/testMotionModels/;");
  
     RefPtr<TestMotionModelsApp> app = new TestMotionModelsApp( "config.xml" );
  
     // Pull the optional file name off of the command line.
     if (argc > 1)
     {
        std::string temp = argv[1];
        if (!temp.empty())
           app->mOptionalFilename = temp;
        std::cout << "Attempting to load file [" << temp << "] instead of the default model." << std::endl;
     }
  
     app->Config();
     app->Run();
  
     return 0;
  }
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.