lugre_ogrewrapper.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_ogrewrapper.h"
00003 #include "lugre_input.h"
00004 #include "lugre_robstring.h"
00005 #include <Ogre.h>
00006 /*
00007 #include <OgreInput.h>
00008 #include <OgreInputEvent.h>
00009 #include <OgreEventListeners.h>
00010 #include <OgreKeyEvent.h>
00011 #include <OgreOverlay.h>
00012 #include <OgreOverlayManager.h>
00013 #include <OgrePanelOverlayElement.h>
00014 #include <OgreTextAreaOverlayElement.h>
00015 #include <OgreWireBoundingBox.h>
00016 */
00017 
00018 #if LUGRE_PLATFORM == LUGRE_PLATFORM_APPLE
00019 #include <OIS/OIS.h>
00020 #else
00021 #include <OIS.h>
00022 #endif
00023 
00024 #include <map>
00025 #include <time.h>
00026 #include "lugre_shell.h"
00027 #include "lugre_timer.h"
00028 #include "lugre_ColourClipPaneOverlay.h"
00029 #include "lugre_ColourClipTextOverlay.h"
00030 #include "lugre_BorderColourClipPaneOverlay.h"
00031 #include "lugre_SortedOverlayContainer.h"
00032 #include "lugre_RobRenderableOverlay.h"
00033 #include "lugre_meshshape.h"
00034 #include "lugre_game.h"
00035 #include "lugre_CompassOverlay.h"
00036 
00037 
00038 
00039 using namespace OIS;
00040 using namespace Ogre;
00041 
00042 bool gOISHideMouse = false;
00043 bool gOISGrabInput = false;
00044 
00045 
00046 namespace Lugre {
00047 int gLastWinLeft = 0;
00048 int gLastWinTop = 0;
00049 void    PrintOgreExceptionAndTipps(Ogre::Exception& e);
00050 
00051         class cMyOISListener : public KeyListener, public MouseListener { public:
00052             cInput& input;
00053             int miLastZAbs;
00054 
00055             cMyOISListener() : miLastZAbs(0), input(cInput::GetSingleton()) {}
00056                 
00057             bool keyPressed( const KeyEvent &arg ) {
00058                 if (0) std::cout << "\nKeyPressed {" << arg.key
00059                     << ", " << ((Keyboard*)(arg.device))->getAsString(arg.key)
00060                     << "} || Character (" << (char)arg.text << ")" << std::endl;
00061                     
00062                 input.KeyDown(input.KeyConvertOIS(arg.key),(int)arg.text);
00063                 
00064                     
00065                 return true;
00066             }
00067             bool keyReleased( const KeyEvent &arg ) {
00068                 input.KeyUp( input.KeyConvertOIS(arg.key));
00069                 return true;
00070             }
00071             bool mouseMoved( const OIS::MouseEvent &arg ) {
00072                 const OIS::MouseState& s = arg.state;
00073                 if (0) std::cout << "\nMouseMoved: Abs("
00074                           << s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Abs2("
00075                           << (s.X.abs-gLastWinLeft) << ", " << (s.Y.abs-gLastWinTop) << ", " << s.Z.abs << ") Rel("
00076                           << s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
00077                 
00078                 //printf("mouse: %d %d %d %d %d %d\n", s.X.abs, s.Y.abs, s.Z.abs, s.X.rel, s.Y.rel, s.Z.rel);
00079                 
00080                 int zrel;
00081                 
00082                 #if LUGRE_PLATFORM == LUGRE_PLATFORM_APPLE
00083                     // only relative mouse movement
00084                     cInput::iMouse[0] += s.X.rel;
00085                     cInput::iMouse[1] += s.Y.rel;
00086                     cInput::iMouse[0] = mymax(0,mymin(cInput::iMouse[0],cOgreWrapper::GetSingleton().mViewport->getActualWidth()));
00087                     cInput::iMouse[1] = mymax(0,mymin(cInput::iMouse[1],cOgreWrapper::GetSingleton().mViewport->getActualHeight()));
00088                     
00089                     // mac sends only absolute z (wheel) coordinates
00090                     zrel = s.Z.abs - miLastZAbs;
00091                     miLastZAbs = s.Z.abs;
00092                 #else
00093                     cInput::iMouse[0] = s.X.abs; //-gLastWinLeft;
00094                     cInput::iMouse[1] = s.Y.abs; //-gLastWinTop;
00095                     
00096                     zrel = s.Z.rel;
00097                 #endif
00098                     
00099                 if (zrel < 0) { input.KeyDown(cInput::kkey_wheelup); input.KeyUp(cInput::kkey_wheelup); }
00100                 if (zrel > 0) { input.KeyDown(cInput::kkey_wheeldown); input.KeyUp(cInput::kkey_wheeldown); }
00101                 return true;
00102             }
00103             bool mousePressed( const MouseEvent &arg, MouseButtonID id ) {
00104                 if (0) std::cout << "\nMousePressed: " << id;
00105                 
00106                 switch (id) {
00107                     case MB_Left: input.KeyDown(cInput::kkey_mouse1); break;
00108                     case MB_Right: input.KeyDown(cInput::kkey_mouse2); break;
00109                     case MB_Middle: input.KeyDown(cInput::kkey_mouse3); break;
00110                 }
00111                 
00112                 return true;
00113             }
00114             bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) {
00115                 if (0) std::cout << "\nMouseReleased: " << id;
00116                     
00117                 switch (id) {
00118                     case MB_Left: input.KeyUp(cInput::kkey_mouse1); break;
00119                     case MB_Right: input.KeyUp(cInput::kkey_mouse2); break;
00120                     case MB_Middle: input.KeyUp(cInput::kkey_mouse3); break;
00121                 }
00122                 
00123                 return true;
00124             }
00125         };
00126 
00127 
00128 std::string sLugreOgreBaseDir;
00129 std::string sLugreOgrePluginDir;
00130     
00131 #define PATH_OGRE_LOG               (sLugreOgreBaseDir+"/Ogre.log").c_str()
00132 #define PATH_RESOURCES_CFG          (sLugreOgreBaseDir+"/resources.cfg").c_str()
00133 #ifdef WIN32
00134     #define PATH_PLUGIN_CFG         (sLugreOgreBaseDir+"/plugins.cfg").c_str()
00135 #else   
00136     #define PATH_PLUGIN_CFG         "" // loaded manually to autodetect the plugin path
00137 #endif
00138 #define PATH_PLUGIN_CFG_TEMPLATE    (sLugreOgreBaseDir+"/plugins_linux.cfg").c_str()
00139 
00140 Ogre::LogManager* gLogMan = 0;
00141 
00142 
00143 void    DisplayErrorMessage     (const char* szMsg); 
00144 
00145 #if OGRE_VERSION < 0x10700
00146 cOgreUserObjectWrapper::cOgreUserObjectWrapper() : mpEntity(0), miType(0) {}
00147 cOgreUserObjectWrapper::~cOgreUserObjectWrapper() {}
00148 long cOgreUserObjectWrapper::getTypeID(void) const { return 23; }
00149 const Ogre::String& cOgreUserObjectWrapper::getTypeName(void) const { static Ogre::String eris("shiva"); return eris; }
00150 #endif
00151     
00152 cOgreWrapper::cOgreWrapper() : mRoot(0) {PROFILE
00153     mCamera = 0;
00154     mViewport = 0;
00155     mSceneMgr = 0;
00156     mWindow = 0;
00157     mInputManager = 0;
00158     mMouse = 0;
00159     mKeyboard = 0;
00160     mJoy = 0;
00161     
00162     mfLastFPS = 0.0f;
00163     mfAvgFPS = 0.0f;
00164     mfBestFPS = 0.0f;
00165     mfWorstFPS = 0.0f;
00166     miBestFrameTime = 0;
00167     miWorstFrameTime = 0;
00168     miTriangleCount = 0;
00169     miBatchCount = 0;
00170 }
00171 
00172 
00173 
00174 #if LUGRE_PLATFORM == LUGRE_PLATFORM_LINUX
00175 void lugre_loadOgrePlugins_linux (Ogre::Root* pRoot, const Ogre::String& pluginsfile, const char* szPluginDir ) {
00176     Ogre::StringVector pluginList;
00177     Ogre::String pluginDir;
00178     Ogre::ConfigFile cfg;
00179 
00180     try {
00181         cfg.load( pluginsfile );
00182     }
00183     catch (Ogre::Exception)
00184     {
00185         Ogre::LogManager::getSingleton().logMessage(pluginsfile + " not found, automatic plugin loading disabled.");
00186         return;
00187     }
00188 
00189     //pluginDir = cfg.getSetting("PluginFolder"); // Ignored on Mac OS X, uses Resources/ directory
00190     pluginDir = szPluginDir; // autodetected during runtime now...
00191     pluginList = cfg.getMultiSetting("Plugin");
00192 
00193     char last_char = pluginDir[pluginDir.length()-1];
00194     if (last_char != '/' && last_char != '\\')
00195     {
00196 #if LUGRE_PLATFORM == LUGRE_PLATFORM_WIN32
00197         pluginDir += "\\";
00198 #elif LUGRE_PLATFORM == LUGRE_PLATFORM_LINUX
00199         pluginDir += "/";
00200 #endif
00201     }
00202 
00203     for( Ogre::StringVector::iterator it = pluginList.begin(); it != pluginList.end(); ++it )
00204     {
00205         try {
00206             pRoot->loadPlugin(pluginDir + (*it));
00207         } catch( Ogre::Exception& e ) {
00208             printf("warning, lugre_loadOgrePlugins : exception while loading plugin %s\n",(pluginDir + (*it)).c_str());
00209             PrintOgreExceptionAndTipps(e);
00210         }
00211     }
00212 
00213 }
00214 #else
00215 void lugre_loadOgrePlugins_linux (Ogre::Root* pRoot, const Ogre::String& pluginsfile, const char* szPluginDir ) {}
00216 #endif
00217 
00219 void    OgreForceCloseFullscreen () {
00220     // found no other way to hide the window, setVisible and mWindow->destroy() didn't work
00221     // arg, even mRoot->shutdown() didn't work
00222     delete cOgreWrapper::GetSingleton().mRoot;
00223     cOgreWrapper::GetSingleton().mCamera = 0;
00224     cOgreWrapper::GetSingleton().mViewport = 0;
00225     cOgreWrapper::GetSingleton().mSceneMgr = 0;
00226     cOgreWrapper::GetSingleton().mWindow = 0;
00227     cOgreWrapper::GetSingleton().mInputManager = 0;
00228     cOgreWrapper::GetSingleton().mMouse = 0;
00229     cOgreWrapper::GetSingleton().mKeyboard = 0;
00230     cOgreWrapper::GetSingleton().mJoy = 0;
00231     
00232     printf("ogre deinit ok, reinit...\n");
00233     cOgreWrapper::GetSingleton().mRoot = new Root(PATH_PLUGIN_CFG);
00234     lugre_loadOgrePlugins_linux(cOgreWrapper::GetSingleton().mRoot,PATH_PLUGIN_CFG_TEMPLATE,sLugreOgrePluginDir.c_str());
00235 }
00236 
00237 
00238 #if LUGRE_PLATFORM == LUGRE_PLATFORM_APPLE
00239 #include <CoreFoundation/CoreFoundation.h>
00240 
00241 // This function will locate the path to our application on OS X,
00242 // unlike windows you can not rely on the curent working directory
00243 // for locating your configuration files and resources.
00244 std::string macBundlePath()
00245 {
00246     char path[1024];
00247     CFBundleRef mainBundle = CFBundleGetMainBundle();
00248     assert(mainBundle);
00249 
00250     CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
00251     assert(mainBundleURL);
00252 
00253     CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
00254     assert(cfStringRef);
00255 
00256     CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
00257 
00258     CFRelease(mainBundleURL);
00259     CFRelease(cfStringRef);
00260 
00261     return std::string(path);
00262 }
00263 
00264 
00266     void MacSetupResources(std::string mResourcePath)
00267     {
00268         // Load resource paths from config file
00269         ConfigFile cf;
00270         cf.load(mResourcePath + "resources.cfg");
00271 
00272         // Go through all sections & settings in the file
00273         ConfigFile::SectionIterator seci = cf.getSectionIterator();
00274 
00275         String secName, typeName, archName;
00276         while (seci.hasMoreElements())
00277         {
00278             secName = seci.peekNextKey();
00279             ConfigFile::SettingsMultiMap *settings = seci.getNext();
00280             ConfigFile::SettingsMultiMap::iterator i;
00281             for (i = settings->begin(); i != settings->end(); ++i)
00282             {
00283                 typeName = i->first;
00284                 archName = i->second;
00285 #if LUGRE_PLATFORM == LUGRE_PLATFORM_APPLE
00286                 // OS X does not set the working directory relative to the app,
00287                 // In order to make things portable on OS X we need to provide
00288                 // the loading with it's own bundle path location
00289                 ResourceGroupManager::getSingleton().addResourceLocation(
00290                     String(macBundlePath() + "/" + archName), typeName, secName);
00291 #else
00292                 ResourceGroupManager::getSingleton().addResourceLocation(
00293                     archName, typeName, secName);
00294 #endif
00295             }
00296         }
00297     }
00298 
00299 const char* GetDefaultWorkingDir (){
00300     std::string path = strprintf("%s/Contents/Resources/",macBundlePath().c_str());
00301     static char static_path[1024];
00302     strncpy(static_path,path.c_str(),1024);
00303     return static_path;
00304 }
00305 
00306 #else
00307 const char* GetDefaultWorkingDir (){return ".";}
00308 #endif
00309 
00310 
00311 std::string gsCustomSceneMgrType;
00312 bool        gOgreWrapperEnableUnicode = false;
00313 
00314 // should be called before ogrewrapper::init
00315 void    OgreWrapperSetCustomSceneMgrType    (std::string sCustomSceneMgrType) { gsCustomSceneMgrType = sCustomSceneMgrType; }
00316 void    OgreWrapperSetEnableUnicode         (bool bState) { gOgreWrapperEnableUnicode = bState; }
00317 
00319 bool    cOgreWrapper::Init          (const char* szWindowTitle,const char* szOgrePluginDir,const char* szOgreBaseDir,bool bAutoCreateWindow) { PROFILE
00320     msWindowTitle = szWindowTitle;
00321     static bool bInitialised = false;
00322     if (bInitialised) return false;
00323     bInitialised = true;
00324     
00325     printf("OGRE_VERSION %x\n",(int)OGRE_VERSION);
00326 
00327     sLugreOgrePluginDir = szOgrePluginDir;
00328     sLugreOgreBaseDir = szOgreBaseDir;
00329     
00330     // create custom logmanager so ogre doesn't dump all that junk onto the console
00331     gLogMan = new LogManager();
00332     bool suppressFileOutput = false;
00333     gLogMan->createLog(PATH_OGRE_LOG, true, false,suppressFileOutput);
00334     //gLogMan->createLog(logFileName, true, true);
00335 
00336     //mRoot = new Root(PATH_PLUGIN_CFG);
00337     // you must provide the full path, the helper function macBundlePath does this for us.
00338     
00339 #if LUGRE_PLATFORM == LUGRE_PLATFORM_APPLE
00340     std::string mResourcePath = macBundlePath() + "/Contents/Resources/";
00341     String pluginsPath;
00342     
00343     // only use plugins.cfg if not static
00344     #ifndef OGRE_STATIC_LIB
00345             pluginsPath = mResourcePath + "plugins_mac.cfg";
00346     #endif
00347     
00348     mRoot = new Root(pluginsPath, 
00349         mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");
00350             
00351     MacSetupResources(mResourcePath);
00352 #else
00353     printf("OGRE_BASE_DIR %s\n",sLugreOgreBaseDir.c_str());
00354     printf("OGRE_PLUGIN_DIR %s\n",sLugreOgrePluginDir.c_str());
00355 
00356     mRoot = new Root(PATH_PLUGIN_CFG);
00357     lugre_loadOgrePlugins_linux(mRoot,PATH_PLUGIN_CFG_TEMPLATE,sLugreOgrePluginDir.c_str());
00358 
00359     //setupResources();
00360     {
00361         // Load resource paths from config file
00362         ConfigFile cf;
00363         cf.load(PATH_RESOURCES_CFG);
00364 
00365         // Go through all sections & settings in the file
00366         ConfigFile::SectionIterator seci = cf.getSectionIterator();
00367 
00368         String secName, typeName, archName;
00369         while (seci.hasMoreElements())
00370         {
00371             secName = seci.peekNextKey();
00372             ConfigFile::SettingsMultiMap *settings = seci.getNext();
00373             ConfigFile::SettingsMultiMap::iterator i;
00374             for (i = settings->begin(); i != settings->end(); ++i)
00375             {
00376                 typeName = i->first;
00377                 archName = i->second;
00378                 ResourceGroupManager::getSingleton().addResourceLocation(
00379                     archName, typeName, secName);
00380             }
00381         }
00382     }
00383 
00384 #endif
00385     
00386     if (!bAutoCreateWindow) return true;
00387     return CreateOgreWindow();
00388 }
00389 
00390 /*
00391 
00392 ConfigOption
00393     String  name
00394     String  currentValue
00395     StringVector    possibleValues
00396     bool    immutable
00397 
00398 
00399 void Ogre::Root::setRenderSystem    (   RenderSystem *       system      )   
00400 
00401 */
00402 
00403 std::vector<std::string>    cOgreWrapper::ListRenderSystems         () {
00404     std::vector<std::string> res;
00405     if (mRoot) {
00406 #if OGRE_VERSION < 0x10700
00407         Ogre::RenderSystemList* l = mRoot->getAvailableRenderers();
00408         if (l) for (int i=0;i<l->size();++i) {
00409             Ogre::RenderSystem* rs = (*l)[i];
00410             if (rs) res.push_back(rs->getName());
00411         }
00412 #else
00413         Ogre::RenderSystemList l = mRoot->getAvailableRenderers();
00414         for (int i=0;i<l.size();++i) {
00415             Ogre::RenderSystem* rs = l[i];
00416             if (rs) res.push_back(rs->getName());
00417         }
00418 #endif
00419     }
00420     return res;
00421 }
00422 
00423 void                        cOgreWrapper::SetRenderSystemByName     (std::string sRenderSysName) {
00424     if (mRoot) {
00425         Ogre::RenderSystem* rs = mRoot->getRenderSystemByName(sRenderSysName);
00426         if (rs) mRoot->setRenderSystem(rs);
00427     }
00428 }
00429 
00430 std::vector<std::string>    cOgreWrapper::ListConfigOptionNames     (std::string sRenderSysName) {
00431     std::vector<std::string> res;
00432     if (mRoot) {
00433         Ogre::RenderSystem* rs = (sRenderSysName == "") ? mRoot->getRenderSystem() : mRoot->getRenderSystemByName(sRenderSysName);
00434         if (rs) {
00435             Ogre::ConfigOptionMap& o = rs->getConfigOptions(); // std::map< String, ConfigOption >
00436             for (Ogre::ConfigOptionMap::iterator itor=o.begin();itor!=o.end();++itor) res.push_back((*itor).first);
00437         }
00438     }
00439     return res;
00440 }
00441 
00442 std::vector<std::string>    cOgreWrapper::ListPossibleValuesForConfigOption (std::string sRenderSysName,std::string sConfigOptionName) {
00443     std::vector<std::string> res;
00444     if (mRoot) {
00445         Ogre::RenderSystem* rs = (sRenderSysName == "") ? mRoot->getRenderSystem() : mRoot->getRenderSystemByName(sRenderSysName);
00446         if (rs && rs->getConfigOptions().count(sConfigOptionName) > 0) {
00447             Ogre::ConfigOption& o = rs->getConfigOptions()[sConfigOptionName]; // StringVector  possibleValues
00448             for (int i=0;i<o.possibleValues.size();++i) res.push_back(o.possibleValues[i]);
00449         }
00450     }
00451     return res;
00452 }
00453 
00454 void                        cOgreWrapper::SetConfigOption                       (std::string sName,std::string sValue) {
00455     if (mRoot) {
00456         Ogre::RenderSystem* rs = mRoot->getRenderSystem();
00457         if (rs) rs->setConfigOption(sName,sValue);
00458     }
00459 }
00460 
00461 std::string                     cOgreWrapper::GetConfigOption                       (std::string sName) {
00462     if (mRoot) {
00463         Ogre::RenderSystem* rs = mRoot->getRenderSystem();
00464         if (rs) return rs->getConfigOptions()[sName].currentValue;
00465     }
00466     return "";
00467 }
00468 
00469 
00470 
00471 bool    cOgreWrapper::CreateOgreWindow      (bool bConfigRestoreOrDialog) { 
00472     bool bWinDebug = false;
00473     //bool carryOn = configure();
00474     //if (!carryOn) return false;
00475     if (bConfigRestoreOrDialog && !mRoot->restoreConfig() && !mRoot->showConfigDialog()) return false;
00476     //mRoot->getRenderSystem()->setConfigOption("RTT Preferred Mode","Copy"); // todo : set via lua ?
00477     if (bWinDebug) printf("windebug safepoint -2\n"); 
00478     mRoot->getRenderSystem()->setWaitForVerticalBlank(false);
00479 
00480     //mRoot->setRenderSystem(mRoot->getAvailableRenderers()->front());
00481     //mRoot->getRenderSystem()->setConfigOption("RTT Preferred Mode", "PBuffer");
00482     //if (!mRoot->showConfigDialog()) return false;
00483 
00484     mWindow = mRoot->initialise(true,msWindowTitle.c_str());
00485     if (bWinDebug) printf("windebug safepoint -1\n"); 
00486     
00487     //printf("\n\n Ogre Root-Init Successful\n\n");
00488     
00489     if (1) {
00490         bool bIsFullScreen = mWindow->isFullScreen(); //  is bugged on linux
00491         RenderSystem* rs = mRoot->getRenderSystem();
00492         if (rs) {
00493             //printf("fsoption=%s\n",rs->getConfigOptions()["Full Screen"].currentValue.c_str());
00494             if (rs->getConfigOptions()["Full Screen"].currentValue == "No") bIsFullScreen = false; // fullscreen detect workaround
00495         }
00496         printf("bIsFullScreen=%d\n",bIsFullScreen?1:0);
00497         bool bufferedKeys = true;
00498         bool bufferedMouse = true;
00499         //bool bufferedJoy = true;
00500         ParamList pl;
00501         size_t windowHnd = 0;
00502         std::ostringstream windowHndStr;
00503 
00504         mWindow->getCustomAttribute("WINDOW", &windowHnd);
00505         windowHndStr << windowHnd;
00506         pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
00507         #if defined OIS_WIN32_PLATFORM
00508         //Default mode is foreground exclusive..but, we want to show mouse - so nonexclusive
00509         if (!gOISGrabInput) pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
00510         if (!gOISHideMouse) pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
00511         if (!gOISGrabInput) pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
00512         if (!gOISHideMouse) pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
00513         /*
00514         temp["DISCL_BACKGROUND"]    = DISCL_BACKGROUND;
00515         temp["DISCL_EXCLUSIVE"]     = DISCL_EXCLUSIVE;
00516         temp["DISCL_FOREGROUND"]    = DISCL_FOREGROUND;
00517         temp["DISCL_NONEXCLUSIVE"]  = DISCL_NONEXCLUSIVE;
00518         temp["DISCL_NOWINKEY"]      = DISCL_NOWINKEY;
00519         */
00520         #elif defined OIS_LINUX_PLATFORM
00521         //For this demo, show mouse and do not grab (confine to window)
00522         if (!gOISGrabInput) pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
00523         if (!gOISHideMouse) pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
00524         if (bIsFullScreen)
00525                 pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true"))); // blocks multitasking if not fullscreen
00526         else    pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); // does not work in fullscreen
00527         pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
00528         #endif
00529 
00530         mInputManager = InputManager::createInputSystem( pl );
00531 
00532         //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
00533         mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys ));
00534         // init tranlation mode (Unicode or Ascii)
00535         if (mKeyboard) {
00536             OIS::Keyboard::TextTranslationMode myTextTranslationMode = OIS::Keyboard::Ascii;
00537             if (gOgreWrapperEnableUnicode) myTextTranslationMode = OIS::Keyboard::Unicode;
00538             mKeyboard->setTextTranslation(myTextTranslationMode);
00539             if (mKeyboard->getTextTranslation() != myTextTranslationMode) {
00540                 DisplayErrorMessage(strprintf("failed initialising OIS TextTranslationMode : %s\n",(myTextTranslationMode==OIS::Keyboard::Ascii)?"asci":"unicode").c_str());
00541                 exit(12);
00542             }
00543         }
00544         mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse ));
00545         /*
00546         try {
00547             mJoy = static_cast<JoyStick*>(mInputManager->createInputObject( OISJoyStick, bufferedJoy ));
00548         }
00549         catch(...) {
00550             mJoy = 0;
00551         }
00552         */
00553         
00554         cMyOISListener* pMyOISListener = new cMyOISListener();
00555 
00556         mKeyboard->setEventCallback(pMyOISListener);
00557         mMouse->setEventCallback(pMyOISListener);
00558 
00559         class cMyWindowListener : public Ogre::WindowEventListener { public:
00560             virtual void windowMoved(RenderWindow* rw) {
00561                 if ( !cOgreWrapper::GetSingleton().mInputManager ) return;
00562                 unsigned int width, height, depth;
00563                 int left, top;
00564                 rw->getMetrics(width, height, depth, left, top);
00565                 gLastWinLeft = left;
00566                 gLastWinTop = top;
00567                 //printf("windowMoved, l,t=%d,%d\n",left,top); commented out by spamfilter...
00568             }
00569             
00570             //Adjust mouse clipping area
00571             virtual void windowResized(RenderWindow* rw)
00572             {
00573                 if ( !cOgreWrapper::GetSingleton().mInputManager ) return;
00574                 unsigned int width, height, depth;
00575                 int left, top;
00576                 rw->getMetrics(width, height, depth, left, top);
00577 
00578                 const OIS::MouseState &ms = cOgreWrapper::GetSingleton().mMouse->getMouseState();
00579                 ms.width = width;
00580                 ms.height = height;
00581                 
00582                 // notify game that window was resized
00583                 cGame::GetSingleton().NotifyMainWindowResized(width,height);
00584             }
00585             
00586             //Unattach OIS before window shutdown (very important under Linux)
00587             virtual void windowClosed(RenderWindow* rw)
00588             {
00589                 //Only close for window that created OIS (the main window in these demos)
00590                 if( rw == cOgreWrapper::GetSingleton().mWindow )
00591                 {
00592                     cShell::mbAlive = false;
00593                     if( cOgreWrapper::GetSingleton().mInputManager )
00594                     {
00595                         cOgreWrapper::GetSingleton().mInputManager->destroyInputObject( cOgreWrapper::GetSingleton().mMouse );
00596                         cOgreWrapper::GetSingleton().mInputManager->destroyInputObject( cOgreWrapper::GetSingleton().mKeyboard );
00597                         cOgreWrapper::GetSingleton().mInputManager->destroyInputObject( cOgreWrapper::GetSingleton().mJoy );
00598                         cOgreWrapper::GetSingleton().mMouse = 0;
00599                         cOgreWrapper::GetSingleton().mKeyboard = 0;
00600                         cOgreWrapper::GetSingleton().mJoy = 0;
00601 
00602                         OIS::InputManager::destroyInputSystem(cOgreWrapper::GetSingleton().mInputManager);
00603                         cOgreWrapper::GetSingleton().mInputManager = 0;
00604                     }
00605                 }
00606             }
00607         };
00608         cMyWindowListener* pMyWindowListener = new cMyWindowListener();
00609 
00610         //Set initial mouse clipping size
00611         pMyWindowListener->windowResized(mWindow);
00612         
00613         //Register as a Window listener
00614         // ogrenew/OgreMain/include/OgreWindowEventUtilities.h
00615         // static void Ogre::WindowEventUtilities::addWindowEventListener(Ogre::RenderWindow*, Ogre::WindowEventListener*)
00616         WindowEventUtilities::addWindowEventListener(mWindow, pMyWindowListener);
00617     }
00618         
00619     
00620     //printf("\n\n Ogre Event-Init Successful\n\n");
00621     
00622     //chooseSceneManager();
00623     //for ogre 1.0
00624     //mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
00625     //for ogre 1.2
00626     if (bWinDebug) printf("windebug safepoint 0\n"); 
00627     
00628     if (gsCustomSceneMgrType.size() > 0) {
00629         printf("ogre main scenemgrtype = %s\n",gsCustomSceneMgrType.c_str());
00630         mSceneMgr = mRoot->createSceneManager(gsCustomSceneMgrType.c_str(),"main");
00631     } else {
00632         mSceneMgr = mRoot->createSceneManager(ST_GENERIC,"main");
00633     }
00634     if (!mSceneMgr) { printf("COULDN'T CREATE SCENEMANAGER\n"); exit(3); }
00635     if (bWinDebug) printf("windebug safepoint 1\n"); 
00636     
00637 
00638     mpCamHolderSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamHolder");
00639     mpCamPosSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamPos");
00640     
00641     //printf("\n\n Ogre SceneManager-Init Successful\n\n");
00642     
00643     //createCamera();
00644     {
00645         // Create the camera
00646         mCamera = mSceneMgr->createCamera("PlayerCam");
00647 
00648         // Position it at 500 in Z direction
00649         mCamera->setPosition(Ogre::Vector3(0,0,40));
00650         // Look back along -Z
00651         //mCamera->lookAt(Vector3(0,0,0));
00652         mCamera->setNearClipDistance(1);
00653         //mCamera->setPolygonMode(PM_WIREFRAME);
00654     }
00655     if (bWinDebug) printf("windebug safepoint 2\n"); 
00656     
00657     //printf("\n\n Ogre Camera-Init Successful\n\n");
00658     
00659     // TODO : redesign this for lua cam handling
00660     mpCamHolderSceneNode->attachObject(mCamera);
00661     // Create one viewport, entire window
00662     mViewport = mWindow->addViewport(mCamera);
00663     mViewport->setBackgroundColour(ColourValue(0,0,0));
00664     
00665     if (bWinDebug) printf("windebug safepoint 3\n"); 
00666     // Alter the camera aspect ratio to match the viewport
00667     mCamera->setAspectRatio(Real(mViewport->getActualWidth()) / Real(mViewport->getActualHeight()));
00668     
00669     
00670     if (bWinDebug) printf("windebug safepoint 4\n"); 
00671     //printf("\n\n Ogre Viewport-Init Successful\n\n");
00672     
00673     
00674     /*
00675         // mbRttHack
00676         // render to texture hack, required for hagish's weird gfx-setup only =)
00677         RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "RttTex", 512, 512, TEX_TYPE_2D, PF_R8G8B8 );
00678         Viewport* vp = rttTex->addViewport( mCamera );
00679         vp->setOverlaysEnabled( false );
00680         vp->setClearEveryFrame( true );
00681         vp->setBackgroundColour( ColourValue::Black );
00682         
00683         //printf("\n\n Ogre RTT-HACK-Init Successful\n\n");
00684     */
00685     
00686     if (bWinDebug) printf("windebug safepoint 5\n"); 
00687     // Set default mipmap level (NB some APIs ignore this)
00688     TextureManager::getSingleton().setDefaultNumMipmaps(5);
00689     Animation::setDefaultInterpolationMode(Animation::IM_SPLINE);
00690 
00691     /*
00692     mFiltering = TFO_TRILINEAR; mAniso = 1;
00693     mFiltering = TFO_ANISOTROPIC; mAniso = 8;
00694     mFiltering = TFO_BILINEAR; mAniso = 1;
00695     MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
00696     MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
00697     */
00698     
00699     // TODO : Create any resource listeners (for loading screens)
00700     
00701     // Load resources
00702     // loadResources();
00703     // Initialise, parse scripts etc
00704     if (bWinDebug) printf("windebug safepoint 6\n"); 
00705         
00706     
00707     // THIS HAS TO BE CALLED MANUALLY NOW, see OgreInitResLocs() in lugre_scripting.ogre.cpp
00708     //~ ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); 
00709 
00710     if (bWinDebug) printf("windebug safepoint 7\n"); 
00711     
00712     cCompassOverlay::RegisterFactory();
00713     cRobRenderableOverlay::RegisterFactory();
00714     cColourClipPaneOverlay::RegisterFactory();
00715     cColourClipTextOverlay::RegisterFactory();
00716     cBorderColourClipPaneOverlay::RegisterFactory();
00717     cSortedOverlayContainer::RegisterFactory();
00718     
00719     if (bWinDebug) printf("windebug safepoint 12\n"); 
00720     
00721     return true;
00722 }
00723 
00724 void    cOgreWrapper::RenderOneFrame    () {PROFILE
00725     if (!mRoot) return;
00726         
00727     // draw one frame
00728     mRoot->renderOneFrame();
00729     
00730     // update input
00731     Ogre::WindowEventUtilities::messagePump();
00732     if (mKeyboard) mKeyboard->capture();
00733     if (mMouse) mMouse->capture();
00734     
00735     
00736     if (0) {
00737         // terminate the application after a few seconds, useful for experimenting with input
00738         static int iDeadTime = 0;
00739         if (iDeadTime == 0) iDeadTime = cShell::GetTicks() + 1000*20;
00740         if (iDeadTime < cShell::GetTicks()) cShell::mbAlive = false;
00741     }
00742     
00743     if(1) {
00744         // read out some statistics
00745         const RenderTarget::FrameStats& stats = mWindow->getStatistics();
00746         mfLastFPS = stats.lastFPS;
00747         mfAvgFPS = stats.avgFPS;
00748         mfBestFPS = stats.bestFPS;
00749         mfWorstFPS = stats.worstFPS;
00750         miBestFrameTime = stats.bestFrameTime;
00751         miWorstFrameTime = stats.worstFrameTime;
00752         miTriangleCount = stats.triangleCount;
00753         miBatchCount = stats.batchCount;
00754     }
00755 }
00756 
00757 void    cOgreWrapper::DeInit        () {PROFILE
00758     if (mRoot) delete mRoot; mRoot = 0;
00759 }
00760 
00761 void    cOgreWrapper::SetSkybox (const char* szMatName,const bool bFlip) { PROFILE
00762     // setSkyBox (bool enable, const String &materialName, Real distance=5000, bool drawFirst=true, const Quaternion &orientation=Quaternion::IDENTITY, const String &groupName=ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
00763     if (szMatName) {
00764         if (bFlip)
00765                 mSceneMgr->setSkyBox(true,szMatName,1000,true,Quaternion(Degree(90),Ogre::Vector3(1,0,0)));
00766         else    mSceneMgr->setSkyBox(true,szMatName);
00767     } else {
00768         mSceneMgr->setSkyBox(false,"");
00769     }
00770 }
00771 
00772 Ogre::SceneManager* cOgreWrapper::GetSceneManager   (const char* szSceneMgrName) {
00773     return mRoot->getSceneManager(szSceneMgrName);
00774 }
00775 
00776 void    cOgreWrapper::AttachCamera  (SceneNode* pSceneNode) {PROFILE
00777     if (pSceneNode) 
00778             pSceneNode->attachObject(mCamera);
00779     else    mSceneMgr->getRootSceneNode()->attachObject(mCamera);
00780 }
00781 
00782 void    cOgreWrapper::SetCameraPos      (const Ogre::Vector3 vPos) {PROFILE
00783     mCamera->setPosition(vPos);
00784 }
00785 
00786 void    cOgreWrapper::SetCameraRot      (const Quaternion qRot) {PROFILE
00787     mCamera->setOrientation(qRot);
00788 }
00789 
00790 void    cOgreWrapper::CameraLookAt      (const Ogre::Vector3 vPos) { PROFILE
00791     mCamera->lookAt(vPos);  
00792 }
00793 
00796 void cOgreWrapper::TakeGridScreenshot(/*Ogre::RenderWindow* mWindow, Ogre::Camera* mCamera, */const int& pGridSize, const Ogre::String& pFileName, const Ogre::String& pFileExtention, const bool& pStitchGridImages)
00797 {
00798   /* Parameters:
00799    *  mWindow:    Pointer to the render window.  This could be "mWindow" from the ExampleApplication,
00800    *              the window automatically created obtained when calling
00801    *              Ogre::Root::getSingletonPtr()->initialise(false) and retrieved by calling
00802    *              "Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()", or the manually created
00803    *              window from calling "mRoot->createRenderWindow()".
00804    *  mCamera:      Pointer to the camera "looking at" the scene of interest
00805    *  pGridSize:      The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the
00806                 screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
00807    *  pFileName:      The filename to generate, without an extention.  To generate "MyScreenshot.png" this
00808    *              parameter would contain the value "MyScreenshot".
00809    *  pFileExtention:    The extention of the screenshot file name, hence the type of graphics file to generate.
00810    *              To generate "MyScreenshot.pnh" this parameter would contain ".png".
00811    *  pStitchGridImages:  Determines whether the grid screenshots are (true) automatically stitched into a single
00812    *              image (and discarded) or whether they should (false) remain in their unstitched
00813    *              form.  In that case they are sequentially numbered from 0 to
00814    *              pGridSize * pGridSize - 1 (if pGridSize is 3 then from 0 to 8).
00815    *              
00816   */
00817     bool overlaysEnabled = mViewport->getOverlaysEnabled();
00818     mViewport->setOverlaysEnabled(false);   
00819     
00820   Ogre::String gridFilename;
00821 
00822   if(pGridSize <= 1)
00823   {
00824     // Simple case where the contents of the screen are taken directly
00825     // Also used when an invalid value is passed within pGridSize (zero or negative grid size)
00826     gridFilename = pFileName + pFileExtention;
00827 
00828     mWindow->writeContentsToFile(gridFilename);
00829   }
00830   else
00831   {
00832     // Generate a grid of screenshots
00833     mCamera->setCustomProjectionMatrix(false); // reset projection matrix
00834     Ogre::Matrix4 standard = mCamera->getProjectionMatrix();
00835     double nearDist = mCamera->getNearClipDistance();
00836     double nearWidth = (mCamera->getWorldSpaceCorners()[0] - mCamera->getWorldSpaceCorners()[1]).length();
00837     double nearHeight = (mCamera->getWorldSpaceCorners()[1] - mCamera->getWorldSpaceCorners()[2]).length();
00838     Ogre::Image sourceImage;
00839     Ogre::uchar* stitchedImageData;
00840 
00841     // Process each grid
00842     for (int nbScreenshots = 0; nbScreenshots < pGridSize * pGridSize; nbScreenshots++) 
00843     { 
00844       // Use asymmetrical perspective projection. For more explanations check out:
00845       // http://www.cs.kuleuven.ac.be/cwis/research/graphics/INFOTEC/viewing-in-3d/node8.html 
00846       int y = nbScreenshots / pGridSize; 
00847       int x = nbScreenshots - y * pGridSize; 
00848       Ogre::Matrix4 shearing( 
00849         1, 0,(x - (pGridSize - 1) * 0.5) * nearWidth / nearDist, 0, 
00850         0, 1, -(y - (pGridSize - 1) * 0.5) * nearHeight / nearDist, 0, 
00851         0, 0, 1, 0, 
00852         0, 0, 0, 1); 
00853       Ogre::Matrix4 scale( 
00854         pGridSize, 0, 0, 0, 
00855         0, pGridSize, 0, 0, 
00856         0, 0, 1, 0, 
00857         0, 0, 0, 1); 
00858       mCamera->setCustomProjectionMatrix(true, standard * shearing * scale);
00859       Ogre::Root::getSingletonPtr()->renderOneFrame();
00860       gridFilename = pFileName + Ogre::StringConverter::toString(nbScreenshots) + pFileExtention;
00861 
00862 
00863       // Screenshot of the current grid
00864       mWindow->writeContentsToFile(gridFilename);
00865 
00866       if(pStitchGridImages)
00867       {
00868         // Automatically stitch the grid screenshots
00869         sourceImage.load(gridFilename, "General"); // Assumes that the current directory is within the "General" resource group
00870         int sourceWidth = (int) sourceImage.getWidth();
00871         int sourceHeight = (int) sourceImage.getHeight();
00872         Ogre::ColourValue colourValue;
00873         int stitchedX, stitchedY, stitchedIndex;
00874 
00875         // Allocate memory for the stitched image when processing the screenshot of the first grid
00876         if(nbScreenshots == 0)
00877           stitchedImageData = new Ogre::uchar[(sourceImage.getWidth() * pGridSize) * (sourceImage.getHeight() * pGridSize) * 3]; // 3 colors per pixel
00878 
00879         // Copy each pixel within the grid screenshot to the proper position within the stitched image
00880         for(int rawY = 0; rawY < sourceHeight; rawY++)
00881         {
00882           for(int rawX = 0; rawX < sourceWidth; rawX++)
00883           {
00884             colourValue = sourceImage.getColourAt(rawX, rawY, 0);
00885             stitchedX = x * sourceWidth + rawX;
00886             stitchedY = y * sourceHeight + rawY;
00887             stitchedIndex = stitchedY * sourceWidth * pGridSize + stitchedX;
00888             Ogre::PixelUtil::packColour(colourValue,
00889                           Ogre::PF_R8G8B8,
00890                           (void*) &stitchedImageData[stitchedIndex * 3]);
00891           }
00892         }
00893         // The screenshot of the grid is no longer needed
00894         remove(gridFilename.c_str());
00895       }
00896     } 
00897     mCamera->setCustomProjectionMatrix(false); // reset projection matrix 
00898 
00899     if(pStitchGridImages)
00900     {
00901       // Save the stitched image to a file
00902       Ogre::Image targetImage;
00903       targetImage.loadDynamicImage(stitchedImageData,
00904                     sourceImage.getWidth() * pGridSize,
00905                     sourceImage.getHeight() * pGridSize,
00906                     1, // depth
00907                     Ogre::PF_R8G8B8,
00908                     false);
00909       targetImage.save(pFileName + pFileExtention);
00910       delete[] stitchedImageData;
00911     }
00912   }
00913     mViewport->setOverlaysEnabled(overlaysEnabled); 
00914 } 
00915 
00917 void    cOgreWrapper::TakeScreenshot    (const char* szPrefix) { PROFILE  
00918     char mybuf[256];
00919     time_t mytime;
00920     time(&mytime);
00921     strftime(mybuf,255,"%Y%m%d%H%M%S",localtime(&mytime));
00922     mWindow->writeContentsToFile(strprintf("%s%s_%03d.png",szPrefix,mybuf,cShell::GetTicks() % 1000));
00923 }
00924 
00925 std::string     cOgreWrapper::GetUniqueName () {PROFILE
00926     static int iLastName = 0;
00927     return strprintf("n%04d",++iLastName);
00928 }
00929 
00931 int     cOgreWrapper::GetViewportHeight () { return mViewport->getActualHeight(); }
00932 int     cOgreWrapper::GetViewportWidth  () { return mViewport->getActualWidth(); }
00933 
00934 // HitFaceNormal contains the normal of the nearest (ray pos) side (if hitted)
00935 bool    cOgreWrapper::RayAABBQuery  (const Ogre::Vector3& vRayPos,const Ogre::Vector3& vRayDir,
00936     const Ogre::AxisAlignedBox &aabb,float* pfHitDist, int* pfHitFaceNormalX, int* pfHitFaceNormalY, int* pfHitFaceNormalZ) { PROFILE
00937     
00938     static Ogre::Vector3 mlVertices[8];
00939     static Ogre::Vector3 d,p000,p111,p100,p010,p001,p011,p101,p110;
00940     p000 = aabb.getMinimum();
00941     p111 = aabb.getMaximum();
00942     d = p111-p000;
00943     p100 = p000 + Ogre::Vector3(d.x,0,0);
00944     p010 = p000 + Ogre::Vector3(0,d.y,0);
00945     p001 = p000 + Ogre::Vector3(0,0,d.z);
00946     p011 = p000 + Ogre::Vector3(0,d.y,d.z);
00947     p101 = p000 + Ogre::Vector3(d.x,0,d.z);
00948     p110 = p000 + Ogre::Vector3(d.x,d.y,0);
00949     
00950     static int mlIndices[] = {
00951         0,1,2, 3,1,2,   4,5,6, 7,5,6, // front, back
00952         0,1,4, 5,1,4,   2,3,6, 7,3,6, // top, bottom
00953         0,2,4, 6,2,4,   1,3,5, 7,3,5, // left, right
00954         };
00955     mlVertices[0] = p000;   mlVertices[1] = p100; // front
00956     mlVertices[2] = p010;   mlVertices[3] = p110;   
00957     
00958     mlVertices[4] = p001;   mlVertices[5] = p101; // back
00959     mlVertices[6] = p011;   mlVertices[7] = p111;
00960     
00961     bool bHit = false;
00962     float myHitDist;
00963     int iNearestHitFace;
00964     for (int i=0;i<6*6;i+=3) {
00965         if (IntersectRayTriangle(vRayPos,vRayDir,
00966             mlVertices[mlIndices[i+0]],
00967             mlVertices[mlIndices[i+1]],
00968             mlVertices[mlIndices[i+2]],&myHitDist)) {
00969             if (!bHit || myHitDist < *pfHitDist) {
00970                 *pfHitDist = myHitDist;
00971                 iNearestHitFace = i / 6;
00972             }
00973             bHit = true;
00974         }
00975     }
00976     
00977     //printf("BLA1 %d %d %d %d %d\n",bHit,iNearestHitFace,pfHitFaceNormalX,pfHitFaceNormalY,pfHitFaceNormalZ);
00978     
00979     if(bHit && pfHitFaceNormalX != 0 && pfHitFaceNormalY != 0 && pfHitFaceNormalZ != 0){
00980         // set hit face normal
00981         //printf("NEAREST FACE %i\n",iNearestHitFace);
00982         switch(iNearestHitFace){
00983             case 0:*pfHitFaceNormalX = 0; *pfHitFaceNormalY = 0;*pfHitFaceNormalZ = -1;break;   //front
00984             case 1:*pfHitFaceNormalX = 0; *pfHitFaceNormalY = 0;*pfHitFaceNormalZ = 1;break;    //back
00985             case 2:*pfHitFaceNormalX = 0; *pfHitFaceNormalY = -1;*pfHitFaceNormalZ = 0;break;   //top
00986             case 3:*pfHitFaceNormalX = 0; *pfHitFaceNormalY = 1;*pfHitFaceNormalZ = 0;break;    //bottom
00987             case 4:*pfHitFaceNormalX = -1; *pfHitFaceNormalY = 0;*pfHitFaceNormalZ = 0;break;   //left
00988             case 5:*pfHitFaceNormalX = 1; *pfHitFaceNormalY = 0;*pfHitFaceNormalZ = 0;break;    //right
00989         }
00990         // printf("BLA2 %d %d %d %d %d\n",bHit,iNearestHitFace,*pfHitFaceNormalX,*pfHitFaceNormalY,*pfHitFaceNormalZ);
00991     }
00992     
00993     return bHit;
00994 }
00995 
00996 int             cOgreWrapper::GetEntityIndexCount   (Ogre::Entity* pEntity) {
00997     if (!pEntity) return 0;
00998     MeshShape* myshape = MeshShape::GetMeshShape(pEntity);
00999     if (!myshape) return 0;
01000     return myshape->mlIndices.size();
01001 }
01002 Ogre::Vector3   cOgreWrapper::GetEntityVertex       (Ogre::Entity* pEntity,const int iIndexIndex) {
01003     if (!pEntity) return Ogre::Vector3::ZERO;
01004     MeshShape* myshape = MeshShape::GetMeshShape(pEntity);
01005     if (!myshape) return Ogre::Vector3::ZERO;
01006     assert(iIndexIndex >= 0 && iIndexIndex < myshape->mlIndices.size() && "GetEntityVertex : iIndexIndex out of bounds");
01007     int iIndexTarget = myshape->mlIndices[iIndexIndex];
01008     assert(iIndexTarget >= 0 && iIndexTarget < myshape->mlVertices.size() && "GetEntityVertex : iIndexTarget out of bounds");
01009     return myshape->mlVertices[iIndexTarget];
01010 }
01011 
01012 
01016 int     cOgreWrapper::RayEntityQuery    (const Ogre::Vector3& vRayPos,const Ogre::Vector3& vRayDir,Ogre::Entity* pEntity,const Ogre::Vector3& vPos,const Ogre::Quaternion& qRot,const Ogre::Vector3& vScale,float* pfHitDist) { PROFILE
01017     if (!pEntity) return -1;
01018         
01019     // get origin & dir in coordinates local to the entity
01020     MeshShape* myshape = MeshShape::GetMeshShape(pEntity);
01021     if (!myshape) return -1;
01022     Ogre::Quaternion invrot = qRot.Inverse();
01023     return myshape->RayIntersect((invrot*(vRayPos - vPos))/vScale,(invrot * vRayDir)/ vScale,pfHitDist);
01024 }
01025 
01028 int     cOgreWrapper::RayEntityQuery    (const Ogre::Vector3& vRayPos,const Ogre::Vector3& vRayDir,Ogre::Entity* pEntity,float* pfHitDist) { PROFILE
01029     SceneNode* scenenode = pEntity ? pEntity->getParentSceneNode() : 0;
01030     if (!scenenode) return -1; // TODO : tagpoint (like knife in hand) attachment currently not supported...
01031     return RayEntityQuery(vRayPos,vRayDir,pEntity,scenenode->_getDerivedPosition(),scenenode->_getDerivedOrientation(),scenenode->_getDerivedScale(),pfHitDist);
01032 }
01033 
01034 void    cOgreWrapper::RayEntityQuery    (const Ogre::Vector3& vRayPos,const Ogre::Vector3& vRayDir,Ogre::Entity* pEntity,std::vector<std::pair<float,int> > &pHitList) {
01035     SceneNode* scenenode = pEntity ? pEntity->getParentSceneNode() : 0;
01036     if (!scenenode) return; // TODO : tagpoint (like knife in hand) attachment currently not supported...
01037     RayEntityQuery(vRayPos,vRayDir,pEntity,scenenode->_getDerivedPosition(),scenenode->_getDerivedOrientation(),scenenode->_getDerivedScale(),pHitList);
01038 }
01039 
01040 void    cOgreWrapper::RayEntityQuery    (const Ogre::Vector3& vRayPos,const Ogre::Vector3& vRayDir,Ogre::Entity* pEntity,const Ogre::Vector3& vPos,const Ogre::Quaternion& qRot,const Ogre::Vector3& vScale,std::vector<std::pair<float,int> > &pHitList) {
01041     if (!pEntity) return;
01042     // get origin & dir in coordinates local to the entity
01043     MeshShape* myshape = MeshShape::GetMeshShape(pEntity);
01044     if (!myshape) return;
01045     Ogre::Quaternion invrot = qRot.Inverse();
01046     myshape->RayIntersect((invrot*(vRayPos - vPos))/vScale,(invrot * vRayDir)/ vScale,pHitList);
01047 }
01048 
01049 
01050 
01053 // cam->getProjectionMatrix() is cached inside ogre
01054 bool    cOgreWrapper::ProjectPos    (const Ogre::Vector3& pos,Ogre::Real& x,Ogre::Real& y) { PROFILE
01055     Camera* cam = mCamera;
01056     Ogre::Vector3 eyeSpacePos = cam->getViewMatrix(true) * pos;
01057     // z < 0 means in front of cam
01058     if (eyeSpacePos.z < 0) {
01059         Ogre::Vector3 screenSpacePos = cam->getProjectionMatrix() * eyeSpacePos;
01060         x = screenSpacePos.x;
01061         y = screenSpacePos.y;
01062         bool bIsOnSreen = true;
01063         if (x < -1.0) { x = -1.0; bIsOnSreen = false; } if (x > 1.0) { x = 1.0; bIsOnSreen = false; }
01064         if (y < -1.0) { y = -1.0; bIsOnSreen = false; } if (y > 1.0) { y = 1.0; bIsOnSreen = false; }
01065         return bIsOnSreen;
01066     } else {
01067         x = (-eyeSpacePos.x > 0) ? -1 : 1;
01068         y = (-eyeSpacePos.y > 0) ? -1 : 1;
01069         return false;
01070     }
01071 }
01072 
01075 // cam->getProjectionMatrix() is cached inside ogre
01076 bool    cOgreWrapper::ProjectSizeAndPos (const Ogre::Vector3& pos,Ogre::Real& x,Ogre::Real& y,const Ogre::Real rad,Ogre::Real& cx,Ogre::Real& cy) { PROFILE
01077     Camera* cam = mCamera;
01078     Ogre::Vector3 eyeSpacePos = cam->getViewMatrix(true) * pos;
01079     // z < 0 means in front of cam
01080     if (eyeSpacePos.z < 0) {
01081         Ogre::Vector3 screenSpacePos = cam->getProjectionMatrix() * eyeSpacePos;
01082         x = screenSpacePos.x;
01083         y = screenSpacePos.y;
01084         bool bIsOnSreen = true;
01085         if (x < -1.0) { x = -1.0; bIsOnSreen = false; } if (x > 1.0) { x = 1.0; bIsOnSreen = false; }
01086         if (y < -1.0) { y = -1.0; bIsOnSreen = false; } if (y > 1.0) { y = 1.0; bIsOnSreen = false; }
01087         if (bIsOnSreen) {
01088             Ogre::Vector3 spheresize(rad, rad, eyeSpacePos.z);
01089             spheresize = cam->getProjectionMatrix() * spheresize;
01090             cx = spheresize.x;
01091             cy = spheresize.y;
01092         } else {
01093             cx = 0;
01094             cy = 0;
01095         }
01096         return bIsOnSreen;
01097     } else {
01098         cx = 0;
01099         cy = 0;
01100         x = (-eyeSpacePos.x > 0) ? -1 : 1;
01101         y = (-eyeSpacePos.y > 0) ? -1 : 1;
01102         return false;
01103     }
01104 }
01105 
01108 // cam->getProjectionMatrix() is cached inside ogre
01109 Ogre::Vector3   cOgreWrapper::ProjectSizeAndPosEx   (const Ogre::Vector3& pos,const Ogre::Real rad,Ogre::Vector3& vSize) { PROFILE
01110     Ogre::Camera* cam = mCamera;
01111     Ogre::Vector3 eyeSpacePos = cam->getViewMatrix(true) * pos;
01112     Ogre::Vector3 screenSpacePos = cam->getProjectionMatrix() * eyeSpacePos;
01113     Ogre::Vector3 spheresize(rad, rad, eyeSpacePos.z);
01114     spheresize = cam->getProjectionMatrix() * spheresize;
01115     vSize.x = spheresize.x;
01116     vSize.y = spheresize.y;
01117     vSize.z = eyeSpacePos.z;
01118     return screenSpacePos;
01119 }
01120 
01121 
01123 Ogre::Bone* cOgreWrapper::SearchBoneByName  (Ogre::Skeleton& pSkeleton,const char* szBoneName) {
01124     return (pSkeleton.hasBone(szBoneName)) ? pSkeleton.getBone(szBoneName) : 0;
01125     //~ Ogre::Skeleton::BoneIterator itor = pSkeleton.getBoneIterator();
01126     //~ printf("cOgreWrapper::SearchBoneByName '%s' (len=%d)\n",szBoneName,strlen(szBoneName));
01127     //~ while (itor.hasMoreElements()) {
01128         //~ Ogre::Bone* pBone = itor.getNext();
01129         //~ printf(" '%s' (len=%d)\n",pBone->getName().c_str(),pBone->getName().size());
01130         //~ if (pBone->getName() == szBoneName) return pBone;
01131     //~ }
01132     //~ return 0;
01133     // try { if (sName.size() > 0) return mpSkeleton->getBone(sName); } catch (Ogre::Exception& e) {} return 0; 
01134 }
01135 
01136 
01139 void    cOgreWrapper::ImageBlit (Ogre::Image& pImageS,Ogre::Image& pImageD,const int tx0,const int ty0) {
01140     int tx1 = mymin(pImageD.getWidth() ,tx0 + pImageS.getWidth());
01141     int ty1 = mymin(pImageD.getHeight(),ty0 + pImageS.getHeight());
01142     if (tx1 <= 0) return;
01143     if (ty1 <= 0) return;
01144     int tx0m = mymax(0,tx0);
01145     int ty0m = mymax(0,ty0);
01146     
01147     // prepare vars
01148     Ogre::PixelFormat   formatS         = pImageS.getFormat();
01149     Ogre::PixelFormat   formatD         = pImageD.getFormat();
01150     Ogre::uchar*        dataS           = pImageS.getData(); // m_pBuffer
01151     Ogre::uchar*        dataD           = pImageD.getData(); // m_pBuffer
01152     size_t              pixelsizeS      = pImageS.getBPP() / 8; // m_ucPixelSize * 8;
01153     size_t              pixelsizeD      = pImageD.getBPP() / 8; // m_ucPixelSize * 8;
01154     size_t              wS              = pImageS.getWidth(); // m_uWidth
01155     size_t              wD              = pImageD.getWidth(); // m_uWidth
01156     
01157     // copy pixels
01158     if (formatS == formatD) {
01159         // fast, same format (pixelsizeS==pixelsizeD)
01160         int             cpylen  = pixelsizeS * (tx1-tx0m);
01161         int             rowlenS = pixelsizeS * wS;
01162         int             rowlenD = pixelsizeD * wD;
01163         Ogre::uchar*    reader  = &dataS[pixelsizeS*(wS * (ty0m-ty0) + (tx0m-tx0))];
01164         Ogre::uchar*    writer  = &dataD[pixelsizeD*(wD * (ty0m    ) + (tx0m    ))];
01165         if (cpylen > 0) for (int y=ty0m;y<ty1;++y,reader+=rowlenS,writer+=rowlenD) memcpy(writer,reader,cpylen);
01166     } else {
01167         // slow, on the fly conversion, avoid if possible
01168         ColourValue c;
01169         for (int y=ty0m;y<ty1;++y)
01170         for (int x=tx0m;x<tx1;++x) {
01171             PixelUtil::unpackColour(&c,formatS,&dataS[pixelsizeS*(wS * (y-ty0) + (x-tx0))]); // read from source
01172             PixelUtil::packColour(   c,formatD,&dataD[pixelsizeD*(wD * (y    ) + (x    ))]); // write to dest
01173         }
01174     }
01175 }
01176 
01177 void    cOgreWrapper::ImageColorKeyToAlpha  (Ogre::Image& pImage,Ogre::ColourValue colSearch) { ImageColorReplace(pImage,colSearch,Ogre::ColourValue(colSearch.r,colSearch.g,colSearch.b,0)); }
01178 void    cOgreWrapper::ImageColorReplace     (Ogre::Image& pImage,Ogre::ColourValue colSearch,Ogre::ColourValue colReplace) {
01179     int img_w = pImage.getWidth();
01180     int img_h = pImage.getHeight();
01181     
01182     // prepare vars
01183     Ogre::PixelFormat   format          = pImage.getFormat();
01184     Ogre::uchar*        data            = pImage.getData(); // m_pBuffer
01185     int                 pixelsize       = pImage.getBPP() / 8; // m_ucPixelSize * 8;
01186     int                 rowlen          = pImage.getRowSpan();
01187     
01188     // slow, on the fly conversion, avoid if possible
01189     Ogre::ColourValue c;
01190     for (int y=0;y<img_h;++y) {
01191         Ogre::uchar* p      = &data[rowlen*y];
01192         Ogre::uchar* pEnd   = &data[rowlen*y + pixelsize*img_w];
01193         for (;p<pEnd;p+=pixelsize) {
01194             PixelUtil::unpackColour(&c,format,p); // read
01195             if (c == colSearch) PixelUtil::packColour(colReplace,format,p); // write
01196         }
01197     }
01198 }
01199 
01202 void    cOgreWrapper::ImageBlitPart (Ogre::Image& pImageS,Ogre::Image& pImageD,int dst_x,int dst_y,int src_x,int src_y,int w,int h) {
01203     int src_img_w = pImageS.getWidth();
01204     int src_img_h = pImageS.getHeight();
01205     int dst_img_w = pImageD.getWidth();
01206     int dst_img_h = pImageD.getHeight();
01207     if (w <= 0 || h <= 0) return;
01208     if (src_x < 0 || src_x + w > src_img_w ||  
01209         src_y < 0 || src_y + h > src_img_h ||  
01210         dst_x < 0 || dst_x + w > dst_img_w ||  
01211         dst_y < 0 || dst_y + h > dst_img_h    ) { printf("cOgreWrapper::ImageBlit : illegal params"); return; }
01212     
01213     // prepare vars
01214     Ogre::PixelFormat   formatS         = pImageS.getFormat();
01215     Ogre::PixelFormat   formatD         = pImageD.getFormat();
01216     Ogre::uchar*        dataS           = pImageS.getData(); // m_pBuffer
01217     Ogre::uchar*        dataD           = pImageD.getData(); // m_pBuffer
01218     int                 pixelsizeS      = pImageS.getBPP() / 8; // m_ucPixelSize * 8;
01219     int                 pixelsizeD      = pImageD.getBPP() / 8; // m_ucPixelSize * 8;
01220     int                 rowlenS         = pImageS.getRowSpan();
01221     int                 rowlenD         = pImageD.getRowSpan();
01222     
01223     // copy pixels
01224     if (formatS == formatD) {
01225         // fast, same format (pixelsizeS==pixelsizeD)
01226         int             cpylen  = pixelsizeS * w;
01227         Ogre::uchar*    reader  = &dataS[rowlenS*src_y + pixelsizeS*src_x];
01228         Ogre::uchar*    writer  = &dataD[rowlenD*dst_y + pixelsizeD*dst_x];
01229         for (int y=0;y<h;++y,reader+=rowlenS,writer+=rowlenD) memcpy(writer,reader,cpylen);
01230     } else {
01231         // slow, on the fly conversion, avoid if possible
01232         ColourValue c;
01233         for (int y=0;y<h;++y)
01234         for (int x=0;x<w;++x) {
01235             PixelUtil::unpackColour(&c,formatS,&dataS[rowlenS*(y+src_y) + pixelsizeS*(x+src_x)]); // read from source
01236             PixelUtil::packColour(   c,formatD,&dataD[rowlenD*(y+dst_y) + pixelsizeD*(x+dst_x)]); // write to dest
01237         }
01238     }
01239 }
01240 
01241 };

Generated on Wed Feb 8 06:00:13 2012 for cpp by  doxygen 1.5.6