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

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:20 2004