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