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