Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreOverlayManager.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 
00027 #include "OgreOverlayManager.h"
00028 #include "OgreStringVector.h"
00029 #include "OgreOverlay.h"
00030 #include "OgreGuiManager.h"
00031 #include "OgreGuiContainer.h"
00032 #include "OgreStringConverter.h"
00033 #include "OgreLogManager.h"
00034 #include "OgreSceneManagerEnumerator.h"
00035 #include "OgreSceneManager.h"
00036 #include "OgreSceneNode.h"
00037 #include "OgreEntity.h"
00038 #include "OgrePositionTarget.h"
00039 #include "OgreEventProcessor.h"
00040 #include "OgreException.h"
00041 #include "OgreViewport.h"
00042 #include "OgreSDDataChunk.h"
00043 
00044 namespace Ogre {
00045 
00046     //---------------------------------------------------------------------
00047     template<> OverlayManager *Singleton<OverlayManager>::ms_Singleton = 0;
00048     OverlayManager* OverlayManager::getSingletonPtr(void)
00049     {
00050         return ms_Singleton;
00051     }
00052     OverlayManager& OverlayManager::getSingleton(void)
00053     {  
00054         assert( ms_Singleton );  return ( *ms_Singleton );  
00055     }
00056     //---------------------------------------------------------------------
00057     OverlayManager::OverlayManager() :
00058         mEventDispatcher(this), mCursorGuiInitialised(false), 
00059         mLastViewportWidth(0), mLastViewportHeight(0), 
00060         mViewportDimensionsChanged(false)
00061     {
00062         mCursorGuiRegistered = 0;
00063         mCursorLevelOverlay = 0;
00064     }
00065     //---------------------------------------------------------------------
00066     OverlayManager::~OverlayManager()
00067     {
00068     }
00069     //---------------------------------------------------------------------
00070     void OverlayManager::parseOverlayFile(DataChunk& chunk)
00071     {
00072         String line;
00073         Overlay* pOverlay;
00074         bool skipLine;
00075 
00076         pOverlay = 0;
00077 
00078         while(!chunk.isEOF())
00079         {
00080             bool isTemplate = false;
00081             skipLine = false;
00082             line = chunk.getLine();
00083             // Ignore comments & blanks
00084             if (!(line.length() == 0 || line.substr(0,2) == "//"))
00085             {
00086                 if (line.substr(0,8) == "#include")
00087                 {
00088                     std::vector<String> params = line.split("\t\n ()<>");
00089                     loadAndParseOverlayFile(params[1]);
00090                     continue;
00091                 }
00092                 if (pOverlay == 0)
00093                 {
00094                     // No current overlay
00095 
00096                     // check to see if there is a template
00097                     if (line.substr(0,8) == "template")
00098                     {
00099                         isTemplate = true;
00100 
00101                     }
00102                     else
00103                     {
00104             
00105                         // So first valid data should be overlay name
00106                         pOverlay = (Overlay*)create(line);
00107                         // Skip to and over next {
00108                         skipToNextOpenBrace(chunk);
00109                         skipLine = true;
00110                     }
00111                 }
00112                 if ((pOverlay && !skipLine) || isTemplate)
00113                 {
00114                     // Already in overlay
00115                     std::vector<String> params = line.split("\t\n ()");
00116 
00117 
00118                     uint skipParam = 0;
00119                     if (line == "}")
00120                     {
00121                         // Finished overlay
00122                         pOverlay = 0;
00123                         isTemplate = false;
00124                     }
00125                     else if (parseChildren(chunk,line, pOverlay, isTemplate, NULL))
00126                         
00127                     {
00128 
00129                     }
00130                     else if (params[0+skipParam] == "entity")
00131                     {
00132                         // new 3D element
00133                         if (params.size() != (3+skipParam))
00134                         {
00135                             LogManager::getSingleton().logMessage( 
00136                                 "Bad entity line: '"
00137                                 + line + "' in " + pOverlay->getName() + 
00138                                 ", expecting 'entity meshName(entityName)'");
00139                                 skipToNextCloseBrace(chunk);
00140                         }
00141                         else
00142                         {
00143                             skipToNextOpenBrace(chunk);
00144                             parseNewMesh(chunk, params[1+skipParam], params[2+skipParam], pOverlay);
00145                         }
00146 
00147                     }
00148                     else
00149                     {
00150                         // Attribute
00151                         if (!isTemplate)
00152                         {
00153                             parseAttrib(line, pOverlay);
00154                         }
00155                     }
00156 
00157                 }
00158 
00159             }
00160 
00161 
00162         }
00163 
00164     }
00165     //---------------------------------------------------------------------
00166     void OverlayManager::parseAllSources(const String& extension)
00167     {
00168         StringVector overlayFiles;
00169 
00170         std::vector<ArchiveEx*>::iterator i = mVFS.begin();
00171 
00172         // Specific archives
00173         for (; i != mVFS.end(); ++i)
00174         {
00175             overlayFiles = (*i)->getAllNamesLike( "./", extension);
00176             for (StringVector::iterator si = overlayFiles.begin(); si!=overlayFiles.end(); ++si)
00177             {
00178                 parseOverlayFile(*i,si[0]);
00179             }
00180 
00181         }
00182         // search common archives
00183         for (i = mCommonVFS.begin(); i != mCommonVFS.end(); ++i)
00184         {
00185             overlayFiles = (*i)->getAllNamesLike( "./", extension);
00186             for (StringVector::iterator si = overlayFiles.begin(); si!=overlayFiles.end(); ++si)
00187             {
00188                 parseOverlayFile(*i,si[0]);
00189             }
00190         }
00191     }
00192     //---------------------------------------------------------------------
00193     void OverlayManager::loadAndParseOverlayFile(const String& filename)
00194     {
00195         bool isLoaded = false;
00196         for (StringVector::iterator i = mLoadedOverlays.begin(); i != mLoadedOverlays.end(); ++i)
00197         {
00198             if (*i == filename)
00199             {
00200                 LogManager::getSingleton().logMessage( 
00201                     "Skipping loading overlay include: '"
00202                     + filename+ " as it is already loaded.");
00203                 isLoaded = true;
00204                 break;
00205 
00206             }
00207         }
00208         if (!isLoaded)
00209         {
00210 
00211             std::vector<ArchiveEx*>::iterator i = mVFS.begin();
00212 
00213             // Specific archives
00214             for (; i != mVFS.end(); ++i)
00215             {
00216                 if ((*i)->fileTest(filename))
00217                 {
00218                     parseOverlayFile(*i,filename);
00219                 }
00220 
00221             }
00222             // search common archives
00223             for (i = mCommonVFS.begin(); i != mCommonVFS.end(); ++i)
00224             {
00225                 if ((*i)->fileTest(filename))
00226                 {
00227                     parseOverlayFile(*i,filename);
00228                 }
00229             }
00230         }
00231     }
00232     //---------------------------------------------------------------------
00233     void OverlayManager::parseOverlayFile(ArchiveEx* pArchiveEx, const String& name)
00234     {
00235         DataChunk* pChunk;
00236         SDDataChunk dat; 
00237         pChunk = &dat;
00238         pArchiveEx->fileRead(name, &pChunk );
00239         parseOverlayFile(dat);
00240         mLoadedOverlays.push_back(name);
00241     }
00242 
00243 
00244     //---------------------------------------------------------------------
00245     Resource* OverlayManager::create( const String& name)
00246     {
00247         Overlay* s = new Overlay(name);
00248         load(s,1);
00249         return s;
00250     }
00251     //---------------------------------------------------------------------
00252     void OverlayManager::_queueOverlaysForRendering(Camera* cam, 
00253         RenderQueue* pQueue, Viewport* vp)
00254     {
00255         // Flag for update pixel-based GUIElements if viewport has changed dimensions
00256         if (mLastViewportWidth != vp->getActualWidth() || 
00257             mLastViewportHeight != vp->getActualHeight())
00258         {
00259             mViewportDimensionsChanged = true;
00260             mLastViewportWidth = vp->getActualWidth();
00261             mLastViewportHeight = vp->getActualHeight();
00262 
00263         }
00264         else
00265         {
00266             mViewportDimensionsChanged = false;
00267         }
00268 
00269         ResourceMap::iterator i, iend;
00270         iend = mResources.end();
00271         for (i = mResources.begin(); i != iend; ++i)
00272         {
00273             Overlay* o = (Overlay*)i->second;
00274             o->_findVisibleObjects(cam, pQueue);
00275         }
00276     }
00277     //---------------------------------------------------------------------
00278     void OverlayManager::parseNewElement( DataChunk& chunk, String& elemType, String& elemName, 
00279             bool isContainer, Overlay* pOverlay, bool isTemplate, String templateName, GuiContainer* container)
00280     {
00281         String line;
00282 
00283         GuiElement* newElement = NULL;
00284         newElement = 
00285                 GuiManager::getSingleton().createGuiElementFromTemplate(templateName, elemType, elemName, isTemplate);
00286 
00287             // do not add a template to an overlay
00288 
00289         // add new element to parent
00290         if (container)
00291         {
00292             // Attach to container
00293             container->addChild(newElement);
00294         }
00295         // do not add a template to the overlay. For templates overlay = 0
00296         else if (pOverlay)  
00297         {
00298             pOverlay->add2D((GuiContainer*)newElement);
00299         }
00300 
00301         while(!chunk.isEOF())
00302         {
00303             line = chunk.getLine();
00304             // Ignore comments & blanks
00305             if (!(line.length() == 0 || line.substr(0,2) == "//"))
00306             {
00307                 if (line == "}")
00308                 {
00309                     // Finished element
00310                     break;
00311                 }
00312                 else
00313                 {
00314                     if (isContainer && parseChildren(chunk,line, pOverlay, isTemplate, static_cast<GuiContainer*>(newElement)))
00315                     {
00316                         // nested children... don't reparse it
00317                     }
00318                     else
00319                     {
00320                         // Attribute
00321                         parseElementAttrib(line, pOverlay, newElement);
00322                     }
00323                 }
00324             }
00325         }
00326     }
00327 
00328     //---------------------------------------------------------------------
00329     bool OverlayManager::parseChildren( DataChunk& chunk, const String& line,
00330             Overlay* pOverlay, bool isTemplate, GuiContainer* parent)
00331     {
00332         bool ret = false;
00333         std::vector<String> params;
00334         uint skipParam =0;
00335         params = line.split("\t\n ()");
00336 
00337         if (isTemplate)
00338         {
00339             if (params[0] == "template")
00340             {
00341                 skipParam++;        // the first param = 'template' on a new child element
00342             }
00343         }
00344                         
00345         // top level component cannot be an element, it must be a container unless it is a template
00346         if (params[0+skipParam] == "container" || (params[0+skipParam] == "element" && (isTemplate || parent != NULL)) )
00347         {
00348             String templateName = "";
00349             ret = true;
00350             // nested container/element
00351             if (params.size() > 3+skipParam)
00352             {
00353                 if (params.size() != 5+skipParam)
00354                 {
00355                     LogManager::getSingleton().logMessage( 
00356                         "Bad element/container line: '"
00357                         + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
00358                         ", expecting ':' templateName");
00359                     skipToNextCloseBrace(chunk);
00360                     // barf 
00361                     return ret;
00362                 }
00363                 if (params[3+skipParam] != ":")
00364                 {
00365                     LogManager::getSingleton().logMessage( 
00366                         "Bad element/container line: '"
00367                         + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
00368                         ", expecting ':' for element inheritance");
00369                     skipToNextCloseBrace(chunk);
00370                     // barf 
00371                     return ret;
00372                 }
00373 
00374                 templateName = params[4+skipParam];
00375             }
00376 
00377             else if (params.size() != 3+skipParam)
00378             {
00379                 LogManager::getSingleton().logMessage( 
00380                     "Bad element/container line: '"
00381                         + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
00382                     ", expecting 'element type(name)'");
00383                 skipToNextCloseBrace(chunk);
00384                 // barf 
00385                 return ret;
00386             }
00387        
00388             skipToNextOpenBrace(chunk);
00389             parseNewElement(chunk, params[1+skipParam], params[2+skipParam], true, pOverlay, isTemplate, templateName, (GuiContainer*)parent);
00390 
00391         }
00392 
00393 
00394         return ret;
00395     }
00396 
00397     //---------------------------------------------------------------------
00398     void OverlayManager::parseAttrib( const String& line, Overlay* pOverlay)
00399     {
00400         std::vector<String> vecparams;
00401 
00402         // Split params on first space
00403         vecparams = line.split("\t ", 1);
00404 
00405         // Look up first param (command setting)
00406         if (vecparams[0].toLowerCase() == "zorder")
00407         {
00408             pOverlay->setZOrder(StringConverter::parseUnsignedInt(vecparams[1]));
00409         }
00410         else
00411         {
00412             LogManager::getSingleton().logMessage("Bad overlay attribute line: '"
00413                 + line + "' for overlay " + pOverlay->getName());
00414         }
00415     }
00416     //---------------------------------------------------------------------
00417     void OverlayManager::parseElementAttrib( const String& line, Overlay* pOverlay, GuiElement* pElement )
00418     {
00419         std::vector<String> vecparams;
00420 
00421         // Split params on first space
00422         vecparams = line.split("\t ", 1);
00423 
00424         // Look up first param (command setting)
00425         if (!pElement->setParameter(vecparams[0].toLowerCase(), vecparams[1]))
00426         {
00427             // BAD command. BAD!
00428             LogManager::getSingleton().logMessage("Bad element attribute line: '"
00429                 + line + "' for element " + pElement->getName() + " in overlay " + 
00430                 (pOverlay ? pOverlay->getName().c_str() : ""));
00431         }
00432     }
00433     //-----------------------------------------------------------------------
00434     void OverlayManager::skipToNextCloseBrace(DataChunk& chunk)
00435     {
00436         String line = "";
00437         while (!chunk.isEOF() && line != "}")
00438         {
00439             line = chunk.getLine();
00440         }
00441 
00442     }
00443     //-----------------------------------------------------------------------
00444     void OverlayManager::skipToNextOpenBrace(DataChunk& chunk)
00445     {
00446         String line = "";
00447         while (!chunk.isEOF() && line != "{")
00448         {
00449             line = chunk.getLine();
00450         }
00451 
00452     }
00453     //-----------------------------------------------------------------------
00454     void OverlayManager::parseNewMesh(DataChunk& chunk, String& meshName, String& entityName, 
00455         Overlay* pOverlay)
00456     {
00457         String line;
00458         StringVector params;
00459 
00460         // NB at this stage any scene manager will do, it's just for allocation not rendering
00461         SceneManager* sm = SceneManagerEnumerator::getSingleton().getSceneManager(ST_GENERIC);
00462 
00463         // Create entity
00464         Entity* ent = sm->createEntity(entityName, meshName);
00465         // Add a new entity via a node
00466         SceneNode* node = sm->createSceneNode(entityName + "_autoNode");
00467 
00468         node->attachObject(ent);
00469 
00470 
00471         // parse extra info
00472         while(!chunk.isEOF())
00473         {
00474             line = chunk.getLine();
00475             // Ignore comments & blanks
00476             if (!(line.length() == 0 || line.substr(0,2) == "//"))
00477             {
00478                 if (line == "}")
00479                 {
00480                     // Finished 
00481                     break;
00482                 }
00483                 else
00484                 {
00485                     if (line.substr(0, 8) == "position")
00486                     {
00487                         params = line.split(" \t");
00488                         if (params.size() != 4)
00489                         {
00490                             LogManager::getSingleton().logMessage("Bad position attribute line: '"
00491                                 + line + "' for entity " + entityName + " in overlay " + 
00492                                 pOverlay->getName());
00493                             break;
00494                         }
00495                         node->translate(StringConverter::parseReal(params[1]),
00496                                         StringConverter::parseReal(params[2]), 
00497                                         StringConverter::parseReal(params[3]));
00498                     }
00499                     else if (line.substr(0, 8) == "rotation")
00500                     {
00501                         params = line.split(" \t");
00502                         if (params.size() != 5)
00503                         {
00504                             LogManager::getSingleton().logMessage("Bad rotation attribute line: '"
00505                                 + line + "' for entity " + entityName + " in overlay " + 
00506                                 pOverlay->getName());
00507                             break;
00508                         }
00509                         // in file it is angle axis_x axis_y axis_z
00510                         Vector3 axis(StringConverter::parseReal(params[2]),
00511                                     StringConverter::parseReal(params[3]),
00512                                     StringConverter::parseReal(params[4]));
00513                         node->rotate(axis, StringConverter::parseReal(params[1]));
00514                     }
00515                 }
00516             }
00517         }
00518 
00519 
00520 
00521         // Attach node to overlay
00522         pOverlay->add3D(node);
00523         
00524     }
00525     //---------------------------------------------------------------------
00526     bool OverlayManager::hasViewportChanged(void) const
00527     {
00528         return mViewportDimensionsChanged;
00529     }
00530     //---------------------------------------------------------------------
00531     int OverlayManager::getViewportHeight(void) const
00532     {
00533         return mLastViewportHeight;
00534     }
00535     //---------------------------------------------------------------------
00536     int OverlayManager::getViewportWidth(void) const
00537     {
00538         return mLastViewportWidth;
00539     }
00540     //---------------------------------------------------------------------
00541     Real OverlayManager::getViewportAspectRatio(void) const
00542     {
00543         return (Real)mLastViewportHeight / (Real)mLastViewportWidth;
00544     }
00545     //---------------------------------------------------------------------
00546 
00547     //-----------------------------------------------------------------------------
00548 
00549     PositionTarget* OverlayManager::getPositionTargetAt(Real x, Real y)
00550     {
00551         PositionTarget* ret = NULL;
00552         int currZ = -1;
00553         ResourceMap::iterator i, iend;
00554         iend = mResources.end();
00555         for (i = mResources.begin(); i != iend; ++i)
00556         {
00557             Overlay* o = (Overlay*)i->second;
00558             int z = o->getZOrder();
00559             if (z > currZ && o->isVisible())
00560             {
00561                 PositionTarget* elementFound = static_cast<MouseTarget*>(o->findElementAt(x,y));    // GuiElements are MouseTargets and MouseMotionTargets,
00562                                                                                                     // you need to choose one to static cast
00563                 if (elementFound)
00564                 {
00565                     currZ = z;
00566                     ret = elementFound;
00567                 }
00568             }
00569         }
00570 
00571         return ret;
00572     }
00573 
00574     //-----------------------------------------------------------------------------
00575     void OverlayManager::processEvent(InputEvent* e)
00576     {
00577         MouseMotionListenerList::iterator i, iEnd;
00578 
00579         mEventDispatcher.dispatchEvent(e);
00580 
00581             // process for cursor listeners
00582         switch (e->getID())
00583         {
00584         case MouseEvent::ME_MOUSE_MOVED :
00585             iEnd = mMouseMotionListenerList.end();
00586             for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i)
00587                 (*i)->mouseMoved(static_cast<MouseEvent*>(e));
00588             break;
00589 
00590         case MouseEvent::ME_MOUSE_DRAGGED :
00591             iEnd = mMouseMotionListenerList.end();
00592             for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i)
00593                 (*i)->mouseDragged(static_cast<MouseEvent*>(e));
00594             break;
00595         }
00596     }
00597 
00598     //-----------------------------------------------------------------------------
00599     void OverlayManager::setDefaultCursorGui(GuiContainer* cursor, MouseMotionListener* cursorListener)
00600     {
00601         mCursorGuiRegistered = cursor;
00602         //mCursorListener = cursorListener;
00603         mCursorGuiInitialised = false;
00604        
00605         //if (mCursorListener != 0)
00606         //    addMouseMotionListener(mCursorListener);
00607     }
00608 
00609     //-----------------------------------------------------------------------------
00610     void OverlayManager::setCursorGui(GuiContainer* cursor)
00611     {
00612             // remove old cursor and listener, if any
00613         if (mCursorGuiRegistered != 0)
00614             mCursorGuiRegistered->hide();
00615         //if (mCursorListener != 0)
00616         //    removeMouseMotionListener(mCursorListener);
00617 
00618         mCursorGuiRegistered  = cursor;
00619         //mCursorListener       = cursorListener;
00620         mCursorGuiInitialised = true;
00621 
00622             // add new cursor, if any
00623         if (mCursorGuiRegistered != 0)
00624             mCursorGuiRegistered->show();            
00625         //if (mCursorListener != 0)
00626         //    addMouseMotionListener(mCursorListener);
00627     }
00628 
00629     //-----------------------------------------------------------------------------
00630     GuiContainer* OverlayManager::getCursorGui()
00631     {
00632         if(!mCursorGuiInitialised)
00633         {
00634             mCursorGuiRegistered->initialise();
00635             mCursorGuiInitialised = true;
00636         }
00637         return mCursorGuiRegistered;
00638     }
00639 
00640     //-----------------------------------------------------------------------------
00641     void OverlayManager::addMouseMotionListener(MouseMotionListener* l)
00642     {
00643         mMouseMotionListenerList.push_back(l);
00644     }
00645 
00646     //-----------------------------------------------------------------------------
00647     void OverlayManager::removeMouseMotionListener(MouseMotionListener* l)
00648     {
00649         MouseMotionListenerList::iterator i, iEnd;
00650 
00651         iEnd = mMouseMotionListenerList.end();
00652         for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i)
00653             if (*i == l)
00654             {
00655                 mMouseMotionListenerList.erase(i);
00656                 break;
00657             }
00658     }
00659 
00660     //-----------------------------------------------------------------------------
00661     void OverlayManager::createCursorOverlay()
00662     {
00663         mCursorLevelOverlay = static_cast<Overlay* > (create("CursorLevelOverlay"));
00664         mCursorLevelOverlay->setZOrder(600);
00665         mCursorLevelOverlay->show();
00666         EventProcessor::getSingleton().addEventTarget(this);
00667 
00668         // register the new cursor and display it
00669         if (mCursorGuiRegistered/* && mCursorListener*/)    
00670         {
00671             mCursorLevelOverlay->add2D(mCursorGuiRegistered);
00672             mCursorGuiRegistered->show();
00673         }
00674     }
00675 
00676 }
00677 

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:30 2004