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 = StringUtil::split(line, "\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 = StringUtil::split(line, "\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 = StringUtil::split(line, "\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 = StringUtil::split(line, "\t ", 1); 00404 00405 // Look up first param (command setting) 00406 StringUtil::toLowerCase(vecparams[0]); 00407 if (vecparams[0] == "zorder") 00408 { 00409 pOverlay->setZOrder(StringConverter::parseUnsignedInt(vecparams[1])); 00410 } 00411 else 00412 { 00413 LogManager::getSingleton().logMessage("Bad overlay attribute line: '" 00414 + line + "' for overlay " + pOverlay->getName()); 00415 } 00416 } 00417 //--------------------------------------------------------------------- 00418 void OverlayManager::parseElementAttrib( const String& line, Overlay* pOverlay, GuiElement* pElement ) 00419 { 00420 std::vector<String> vecparams; 00421 00422 // Split params on first space 00423 vecparams = StringUtil::split(line, "\t ", 1); 00424 00425 // Look up first param (command setting) 00426 StringUtil::toLowerCase(vecparams[0]); 00427 if (!pElement->setParameter(vecparams[0], vecparams[1])) 00428 { 00429 // BAD command. BAD! 00430 LogManager::getSingleton().logMessage("Bad element attribute line: '" 00431 + line + "' for element " + pElement->getName() + " in overlay " + 00432 (pOverlay ? pOverlay->getName().c_str() : "")); 00433 } 00434 } 00435 //----------------------------------------------------------------------- 00436 void OverlayManager::skipToNextCloseBrace(DataChunk& chunk) 00437 { 00438 String line = ""; 00439 while (!chunk.isEOF() && line != "}") 00440 { 00441 line = chunk.getLine(); 00442 } 00443 00444 } 00445 //----------------------------------------------------------------------- 00446 void OverlayManager::skipToNextOpenBrace(DataChunk& chunk) 00447 { 00448 String line = ""; 00449 while (!chunk.isEOF() && line != "{") 00450 { 00451 line = chunk.getLine(); 00452 } 00453 00454 } 00455 //----------------------------------------------------------------------- 00456 void OverlayManager::parseNewMesh(DataChunk& chunk, String& meshName, String& entityName, 00457 Overlay* pOverlay) 00458 { 00459 String line; 00460 StringVector params; 00461 00462 // NB at this stage any scene manager will do, it's just for allocation not rendering 00463 SceneManager* sm = SceneManagerEnumerator::getSingleton().getSceneManager(ST_GENERIC); 00464 00465 // Create entity 00466 Entity* ent = sm->createEntity(entityName, meshName); 00467 // Add a new entity via a node 00468 SceneNode* node = sm->createSceneNode(entityName + "_autoNode"); 00469 00470 node->attachObject(ent); 00471 00472 00473 // parse extra info 00474 while(!chunk.isEOF()) 00475 { 00476 line = chunk.getLine(); 00477 // Ignore comments & blanks 00478 if (!(line.length() == 0 || line.substr(0,2) == "//")) 00479 { 00480 if (line == "}") 00481 { 00482 // Finished 00483 break; 00484 } 00485 else 00486 { 00487 if (line.substr(0, 8) == "position") 00488 { 00489 params = StringUtil::split(line, " \t"); 00490 if (params.size() != 4) 00491 { 00492 LogManager::getSingleton().logMessage("Bad position attribute line: '" 00493 + line + "' for entity " + entityName + " in overlay " + 00494 pOverlay->getName()); 00495 break; 00496 } 00497 node->translate(StringConverter::parseReal(params[1]), 00498 StringConverter::parseReal(params[2]), 00499 StringConverter::parseReal(params[3])); 00500 } 00501 else if (line.substr(0, 8) == "rotation") 00502 { 00503 params = StringUtil::split(line, " \t"); 00504 if (params.size() != 5) 00505 { 00506 LogManager::getSingleton().logMessage("Bad rotation attribute line: '" 00507 + line + "' for entity " + entityName + " in overlay " + 00508 pOverlay->getName()); 00509 break; 00510 } 00511 // in file it is angle axis_x axis_y axis_z 00512 Vector3 axis(StringConverter::parseReal(params[2]), 00513 StringConverter::parseReal(params[3]), 00514 StringConverter::parseReal(params[4])); 00515 node->rotate(axis, StringConverter::parseAngle(params[1])); 00516 } 00517 } 00518 } 00519 } 00520 00521 00522 00523 // Attach node to overlay 00524 pOverlay->add3D(node); 00525 00526 } 00527 //--------------------------------------------------------------------- 00528 bool OverlayManager::hasViewportChanged(void) const 00529 { 00530 return mViewportDimensionsChanged; 00531 } 00532 //--------------------------------------------------------------------- 00533 int OverlayManager::getViewportHeight(void) const 00534 { 00535 return mLastViewportHeight; 00536 } 00537 //--------------------------------------------------------------------- 00538 int OverlayManager::getViewportWidth(void) const 00539 { 00540 return mLastViewportWidth; 00541 } 00542 //--------------------------------------------------------------------- 00543 Real OverlayManager::getViewportAspectRatio(void) const 00544 { 00545 return (Real)mLastViewportHeight / (Real)mLastViewportWidth; 00546 } 00547 //--------------------------------------------------------------------- 00548 00549 //----------------------------------------------------------------------------- 00550 00551 PositionTarget* OverlayManager::getPositionTargetAt(Real x, Real y) 00552 { 00553 PositionTarget* ret = NULL; 00554 int currZ = -1; 00555 ResourceMap::iterator i, iend; 00556 iend = mResources.end(); 00557 for (i = mResources.begin(); i != iend; ++i) 00558 { 00559 Overlay* o = (Overlay*)i->second; 00560 int z = o->getZOrder(); 00561 if (z > currZ && o->isVisible()) 00562 { 00563 PositionTarget* elementFound = static_cast<MouseTarget*>(o->findElementAt(x,y)); // GuiElements are MouseTargets and MouseMotionTargets, 00564 // you need to choose one to static cast 00565 if (elementFound) 00566 { 00567 currZ = z; 00568 ret = elementFound; 00569 } 00570 } 00571 } 00572 00573 return ret; 00574 } 00575 00576 //----------------------------------------------------------------------------- 00577 void OverlayManager::processEvent(InputEvent* e) 00578 { 00579 MouseMotionListenerList::iterator i, iEnd; 00580 00581 mEventDispatcher.dispatchEvent(e); 00582 00583 // process for cursor listeners 00584 switch (e->getID()) 00585 { 00586 case MouseEvent::ME_MOUSE_MOVED : 00587 iEnd = mMouseMotionListenerList.end(); 00588 for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i) 00589 (*i)->mouseMoved(static_cast<MouseEvent*>(e)); 00590 break; 00591 00592 case MouseEvent::ME_MOUSE_DRAGGED : 00593 iEnd = mMouseMotionListenerList.end(); 00594 for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i) 00595 (*i)->mouseDragged(static_cast<MouseEvent*>(e)); 00596 break; 00597 } 00598 } 00599 00600 //----------------------------------------------------------------------------- 00601 void OverlayManager::setDefaultCursorGui(GuiContainer* cursor, MouseMotionListener* cursorListener) 00602 { 00603 mCursorGuiRegistered = cursor; 00604 //mCursorListener = cursorListener; 00605 mCursorGuiInitialised = false; 00606 00607 //if (mCursorListener != 0) 00608 // addMouseMotionListener(mCursorListener); 00609 } 00610 00611 //----------------------------------------------------------------------------- 00612 void OverlayManager::setCursorGui(GuiContainer* cursor) 00613 { 00614 // remove old cursor and listener, if any 00615 if (mCursorGuiRegistered != 0) 00616 mCursorGuiRegistered->hide(); 00617 //if (mCursorListener != 0) 00618 // removeMouseMotionListener(mCursorListener); 00619 00620 mCursorGuiRegistered = cursor; 00621 //mCursorListener = cursorListener; 00622 mCursorGuiInitialised = true; 00623 00624 // add new cursor, if any 00625 if (mCursorGuiRegistered != 0) 00626 mCursorGuiRegistered->show(); 00627 //if (mCursorListener != 0) 00628 // addMouseMotionListener(mCursorListener); 00629 } 00630 00631 //----------------------------------------------------------------------------- 00632 GuiContainer* OverlayManager::getCursorGui() 00633 { 00634 if(!mCursorGuiInitialised) 00635 { 00636 mCursorGuiRegistered->initialise(); 00637 mCursorGuiInitialised = true; 00638 } 00639 return mCursorGuiRegistered; 00640 } 00641 00642 //----------------------------------------------------------------------------- 00643 void OverlayManager::addMouseMotionListener(MouseMotionListener* l) 00644 { 00645 mMouseMotionListenerList.push_back(l); 00646 } 00647 00648 //----------------------------------------------------------------------------- 00649 void OverlayManager::removeMouseMotionListener(MouseMotionListener* l) 00650 { 00651 MouseMotionListenerList::iterator i, iEnd; 00652 00653 iEnd = mMouseMotionListenerList.end(); 00654 for (i = mMouseMotionListenerList.begin(); i != iEnd; ++i) 00655 if (*i == l) 00656 { 00657 mMouseMotionListenerList.erase(i); 00658 break; 00659 } 00660 } 00661 00662 //----------------------------------------------------------------------------- 00663 void OverlayManager::createCursorOverlay() 00664 { 00665 mCursorLevelOverlay = static_cast<Overlay* > (create("CursorLevelOverlay")); 00666 mCursorLevelOverlay->setZOrder(600); 00667 mCursorLevelOverlay->show(); 00668 EventProcessor::getSingleton().addEventTarget(this); 00669 00670 // register the new cursor and display it 00671 if (mCursorGuiRegistered/* && mCursorListener*/) 00672 { 00673 mCursorLevelOverlay->add2D(mCursorGuiRegistered); 00674 mCursorGuiRegistered->show(); 00675 } 00676 } 00677 00678 } 00679
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:37 2004