Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpAROgre.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Augmented Reality viewer using Ogre3D.
32  *
33  * Authors:
34  * Bertrand Delabarre
35  *
36  *****************************************************************************/
37 
48 #include "visp3/core/vpConfig.h"
49 
50 #ifdef VISP_HAVE_OGRE
51 
52 #include "visp3/ar/vpAROgre.h"
53 #include "visp3/core/vpIoTools.h"
54 
55 
72  unsigned int width, unsigned int height,
73  const char *resourcePath, const char *pluginsPath)
74  : name("ViSP - Augmented Reality"),mRoot(0), mCamera(0), mSceneMgr(0), mWindow(0),
75  mResourcePath(resourcePath), mPluginsPath(pluginsPath),
76 #ifdef VISP_HAVE_OIS
77  mInputManager(0), mKeyboard(0),
78 #endif
79  keepOn(true), // When created no reason to stop displaying
80  mImageRGBA(), mImage(), mPixelBuffer(NULL), mBackground(NULL), mBackgroundHeight(0),
81  mBackgroundWidth(0), mWindowHeight(height), mWindowWidth(width), windowHidden(false),
82  mNearClipping(0.001), mFarClipping(200), mcam(cam), mshowConfigDialog(true),
83  mOptionnalResourceLocation()
84 {
85 }
86 
116  bool
117 #ifdef VISP_HAVE_OIS
118  bufferedKeys
119 #endif
120  ,bool hidden
121  )
122 {
125 
126  init(
127 #ifdef VISP_HAVE_OIS
128  bufferedKeys,
129 #else
130  false,
131 #endif
132  hidden
133  );
134  // Create the background image which will come from the grabber
135  createBackground(I);
136 }
137 
167  bool
168 #ifdef VISP_HAVE_OIS
169  bufferedKeys
170 #endif
171  ,bool hidden
172  )
173 {
176 
177  init(
178 #ifdef VISP_HAVE_OIS
179  bufferedKeys,
180 #else
181  false,
182 #endif
183  hidden
184  );
185  // Create the background image which will come from the grabber
186  createBackground(I);
187 }
188 
213 void vpAROgre::init(bool
214 #ifdef VISP_HAVE_OIS
215  bufferedKeys
216 #endif
217  ,bool hidden
218  )
219 {
220  // Create the root
221  // mPluginsPath may contain more than one folder location separated by ";"
222  bool pluginsFileExists = false;
223  std::string pluginFile;
224  std::vector<std::string> plugingsPaths = vpIoTools::splitChain(std::string(mPluginsPath), std::string(";"));
225  for (size_t i=0; i<plugingsPaths.size(); i++) {
226 #if defined(NDEBUG) || !defined(_WIN32)
227  pluginFile = plugingsPaths[i]+"/plugins.cfg";
228 #else
229  pluginFile = plugingsPaths[i]+"/plugins_d.cfg";
230 #endif
231 
232  if(vpIoTools::checkFilename(pluginFile)) {
233  pluginsFileExists = true;
234  break;
235  }
236  }
237  if (! pluginsFileExists) {
238  std::string errorMsg = std::string("Error: the requested plugins file \"")
239 #if defined(NDEBUG) || !defined(_WIN32)
240  + std::string("plugins.cfg")
241 #else
242  + std::string("plugins_d.cfg")
243 #endif
244  + std::string("\" doesn't exist in ")
245  + std::string(mPluginsPath);
246  std::cout << errorMsg << std::endl;
247 
248  throw (vpException(vpException::ioError, errorMsg));
249  }
250  std::cout << "######################### Load plugin file: " << pluginFile << std::endl;
251 
252  if(Ogre::Root::getSingletonPtr() == NULL)
253  mRoot = new Ogre::Root(pluginFile, "ogre.cfg", "Ogre.log");
254  else
255  mRoot = Ogre::Root::getSingletonPtr();
256 
257  // Load resource paths from config file
258 
259  // File format is:
260  // [ResourceGroupName]
261  // ArchiveType=Path
262  // .. repeat
263  // For example:
264  // [General]
265  // FileSystem=media/
266  // Zip=packages/level1.zip
267 
268  // mResourcePath may contain more than one folder location separated by ";"
269  bool resourcesFileExists = false;
270  std::string resourceFile;
271  std::vector<std::string> resourcesPaths = vpIoTools::splitChain(std::string(mResourcePath), std::string(";"));
272  for (size_t i=0; i<resourcesPaths.size(); i++) {
273  resourceFile = resourcesPaths[i]+"/resources.cfg";
274  if(vpIoTools::checkFilename(resourceFile)) {
275  resourcesFileExists = true;
276  break;
277  }
278  }
279  if (! resourcesFileExists) {
280  std::string errorMsg = std::string("Error: the requested resource file \"resources.cfg\"")
281  + std::string("doesn't exist in ")
282  + std::string(mResourcePath);
283 
284  std::cout << errorMsg << std::endl;
285 
286  throw (vpException(vpException::ioError, errorMsg));
287  }
288  std::cout << "######################### Load resource file: " << resourceFile << std::endl;
289  Ogre::ConfigFile cf;
290  cf.load(resourceFile);
291 
292  // Go through all sections & settings in the file
293  Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
294 
295  Ogre::String secName, typeName, archName;
296  while (seci.hasMoreElements())
297  {
298  secName = seci.peekNextKey();
299  Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
300  Ogre::ConfigFile::SettingsMultiMap::iterator i;
301  for (i = settings->begin(); i != settings->end(); ++i)
302  {
303  typeName = i->first;
304  archName = i->second;
305  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
306  archName, typeName, secName);
307  }
308  }
309  std::cout << "##################### add resources" << std::endl;
310  //Add optionnal resources (given by the user).
311  for(std::list<std::string>::const_iterator iter = mOptionnalResourceLocation.begin(); iter != mOptionnalResourceLocation.end(); ++iter){
312  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(*iter, "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
313  }
314 
315  // Create the window
316  bool canInit = true;
317  if(mshowConfigDialog){
318  mRoot->restoreConfig();
319  if(!mRoot->showConfigDialog())
320  canInit = false;
321  }
322  else{
323  if(!mRoot->restoreConfig())
324  canInit = false;
325  }
326 
327  if(!mRoot->isInitialised()){
328  if(!canInit){ //We set the default renderer system
329  const Ogre::RenderSystemList& lRenderSystemList = mRoot->getAvailableRenderers();
330  if( lRenderSystemList.size() == 0 )
331  throw "ConfigDialog aborted"; // Exit the application on cancel
332 
333  Ogre::RenderSystem *lRenderSystem = lRenderSystemList.at(0);
334  std::cout << "Using " << lRenderSystem->getName() << " as renderer." << std::endl;
335  mRoot->setRenderSystem(lRenderSystem);
336  }
337 
338  mRoot->initialise(false);
339  }
340 
341  bool fullscreen = false;
342  Ogre::NameValuePairList misc;
343  Ogre::ConfigOptionMap config = mRoot->getRenderSystem()->getConfigOptions();
344  Ogre::ConfigOptionMap::const_iterator it = config.begin();
345 
346  while( it != config.end() ){
347  Ogre::String leftconf = (*it).first;
348  Ogre::String rightconf = (*it).second.currentValue;
349 
350  if(leftconf == "Video Mode"){
351  if(canInit) {
352  std::stringstream ss(rightconf.c_str());
353  std::string dummy;
354  ss >> mWindowWidth >> dummy >> mWindowHeight;
355  if (ss.fail())
356  std::cout << "Cannot read Ogre video mode" << std::endl;
357  }
358  else{
359  if(mWindowWidth == 0 && mWindowHeight == 0){
362  }
363  }
364  }
365  else if( leftconf == "Full Screen" ){
366  if(canInit){
367  if(rightconf == "Yes") fullscreen = true;
368  }
369  }
370  else
371  misc[leftconf] = rightconf;
372 
373  ++it;
374  }
375 
376  // With Ogre version >= 1.8.1 we hide the window
377  if( hidden ){
378 #if ( OGRE_VERSION >= (1 << 16 | 8 << 8 | 1) )
379  misc["hidden"] = "true";
380  windowHidden = true;
381 #endif
382  }
383  mWindow = mRoot->createRenderWindow(name, mWindowWidth, mWindowHeight, fullscreen, &misc);
384 
385  // Initialise resources
386  Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
387  //-----------------------------------------------------
388  // 4 Create the SceneManager
389  //
390  // ST_GENERIC = octree
391  // ST_EXTERIOR_CLOSE = simple terrain
392  // ST_EXTERIOR_FAR = nature terrain (depreciated)
393  // ST_EXTERIOR_REAL_FAR = paging landscape
394  // ST_INTERIOR = Quake3 BSP
395  //-----------------------------------------------------
396 
397  mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
398 
399  // Create the camera
400  createCamera();
401 
402  // Create a viewport
403  Ogre::Viewport* viewPort = mWindow->addViewport(mCamera);
404 // Ogre::Viewport* viewPort = mCamera->getViewport();
405  viewPort->setClearEveryFrame(true);
406  // Set the projection parameters to match the camera intrinsic parameters
408 
409  // Create the 3D scene
410  createScene();
411 
412  // Initialise and register event handlers
413  mRoot->addFrameListener(this);
414 
415  // Register as a Window listener
416  Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
417 
418 #ifdef VISP_HAVE_OIS
419  // Initialise OIS
420  Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
421  OIS::ParamList pl;
422 
423  size_t windowHnd = 0;
424  std::ostringstream windowHndStr;
425  // Initialise window
426  mWindow->getCustomAttribute("WINDOW", &windowHnd);
427  windowHndStr << windowHnd;
428  pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
429  // Let the user use the keyboard elsewhere
430 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
431  pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
432 #endif
433 
434  mInputManager = OIS::InputManager::createInputSystem( pl );
435 
436  //Create all devices
437  // Here we only consider the keyboard input
438  mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
439  if ( !bufferedKeys ) mKeyboard->setEventCallback ( this);
440 #endif
441 
442  // Initialise a render to texture to be able to retrieve a screenshot
443  Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
444  mWindow->getWidth(),mWindow->getHeight(), 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
445 
446 
447 
448 // Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
449 // 640,480, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
450  Ogre::RenderTexture* RTarget = Texture->getBuffer()->getRenderTarget();
451  /*Ogre::Viewport* Viewport =*/ RTarget->addViewport(mCamera);
452  RTarget->getViewport(0)->setClearEveryFrame(true);
453  RTarget->getViewport(0)->setOverlaysEnabled(false);
454 }
455 
460 {
461  // Destroy 3D scene
462  destroyScene();
463  // Close OIS
464  closeOIS();
465 
466  if ( mWindow) {
467  Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
469  }
470 
471  // Delete root
472  if(Ogre::Root::getSingletonPtr() && !Ogre::Root::getSingletonPtr()->getSceneManagerIterator().hasMoreElements()) {
473  if(mRoot) {
474  delete mRoot;
475  }
476  }
477  mRoot = 0;
478 }
479 
485 bool vpAROgre::stopTest(const Ogre::FrameEvent& evt)
486 {
487  // Always keep this part
488  if(keepOn){
489  return updateScene(evt);
490  }
491  else
492  return keepOn;
493 }
494 
504 bool vpAROgre::frameStarted(const Ogre::FrameEvent& evt)
505 {
506  // custom method telling what to do at the beginning of each frame
507  bool result = customframeStarted(evt);
508 
509  // Listen to the window
510  Ogre::WindowEventUtilities::messagePump();
511  processInputEvent(evt);
512 
513  // See if we have to stop rendering
514  if(result) return stopTest(evt);
515  else return result;
516 }
517 
518 
525 bool vpAROgre::frameEnded(const Ogre::FrameEvent& evt)
526 {
527  // custom method telling what to do at the end of each frame
528  bool result = customframeEnded(evt);
529 
530  // See if we have to stop rendering
531  if(result) return stopTest(evt);
532  else return result;
533 }
534 
543 bool vpAROgre::customframeStarted(const Ogre::FrameEvent& /*evt*/)
544 {
545  // See if window was closed
546  if(mWindow->isClosed()) return false;
547 
548 #ifdef VISP_HAVE_OIS
549  // Get keyboard input
550  mKeyboard->capture();
551  if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
552  return false;
553 #endif
554  return true;
555 }
556 
557 
563 bool vpAROgre::customframeEnded(const Ogre::FrameEvent& /*evt*/){return true;}
564 
575 void vpAROgre::windowClosed(Ogre::RenderWindow* rw)
576 {
577  //Only close for window that created OIS (the main window in these demos)
578  if( rw == mWindow ) closeOIS();
579 }
580 
587  const vpHomogeneousMatrix &cMw)
588 {
589  // Update the background to match the situation
591 
592  // Update the camera parameters to match the grabbed image
594 
595  // Display on Ogre Window
596  return mRoot->renderOneFrame();
597 }
598 
605  const vpHomogeneousMatrix &cMw)
606 {
607  // Update the background to match the situation
609 
610  // Update the camera parameters to match the grabbed image
612 
613  // Display on Ogre Window
614  return mRoot->renderOneFrame();
615 }
616 
623  const vpHomogeneousMatrix &cMw)
624 {
625  // Display on Ogre Window
626  if(renderOneFrame(I,cMw)){
627  mWindow->update();
628  keepOn = true;
629  }
630  else
631  keepOn = false;
632 }
633 
640 {
641  // Display on Ogre Window
642  if(renderOneFrame(I,cMw)){
643  mWindow->update();
644  keepOn = true;
645  }
646  else
647  keepOn = false;
648 }
649 
655 {
656  return keepOn;
657 }
658 
663 {
664  mcam = cameraP;
665 }
666 
672 void vpAROgre::load(const std::string &entityName, const std::string &model)
673 {
674  Ogre::Entity *newEntity = mSceneMgr->createEntity(entityName, model);
675  Ogre::SceneNode *newNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(entityName);
676  newNode->attachObject(newEntity);
677 }
678 
685 void vpAROgre::setPosition(const std::string &sceneName,
686  const vpTranslationVector &wTo)
687 {
688  // Reset the position
689  Ogre::SceneNode *node = mSceneMgr->getSceneNode(sceneName);
690  node->setPosition((Ogre::Real)wTo[0], (Ogre::Real)wTo[1], (Ogre::Real)wTo[2]);
691 }
692 
698 vpTranslationVector vpAROgre::getPosition(const std::string &sceneName)const
699 {
700  Ogre::Vector3 translation = mSceneMgr->getSceneNode(sceneName)->getPosition();
701  return vpTranslationVector((Ogre::Real)translation[0], (Ogre::Real)translation[1], (Ogre::Real)translation[2]);
702 }
703 
709 void vpAROgre::setRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
710 {
711  // Get the node in its original position
712  mSceneMgr->getSceneNode(sceneName)->resetOrientation();
713  // Apply the new rotation
714  Ogre::Matrix3 rotationOgre
715  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
716  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
717  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
718  Ogre::Quaternion q(rotationOgre);
719  mSceneMgr->getSceneNode(sceneName)->rotate(q);
720 }
721 
727 void vpAROgre::addRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
728 {
729  // Apply the new rotation
730  Ogre::Matrix3 rotationOgre
731  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
732  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
733  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
734  Ogre::Quaternion q(rotationOgre);
735  mSceneMgr->getSceneNode(sceneName)->rotate(q);
736 }
737 
746 void vpAROgre::setPosition(const std::string &sceneName, const vpHomogeneousMatrix &wMo)
747 {
748  // Extract the position and orientation data
749  vpRotationMatrix rotations;
750  vpTranslationVector translation;
751  wMo.extract(rotations);
752  wMo.extract(translation);
753  // Apply them to the node
754  setPosition(sceneName, translation);
755  setRotation(sceneName, rotations);
756 }
757 
763 void vpAROgre::setVisibility(const std::string &sceneName, bool isVisible)
764 {
765  mSceneMgr->getSceneNode(sceneName)->setVisible(isVisible);
766 }
767 
775 void vpAROgre::setScale(const std::string &sceneName, const float factorx, const float factory, const float factorz)
776 {
777  // Reset the scale to its original value
778  mSceneMgr->getSceneNode(sceneName)->scale(Ogre::Vector3(1,1,1)/mSceneMgr->getSceneNode(sceneName)->getScale());
779  // Apply the new scale
780  mSceneMgr->getSceneNode(sceneName)->scale(Ogre::Vector3(factorx, factory, factorz));
781 }
782 
787 {
788  mCamera = mSceneMgr->createCamera("Camera");
789 }
790 
796 void vpAROgre::createBackground(vpImage<unsigned char> & /* I */)
797 {
798  // Create a rectangle to show the incoming images from the camera
799  mBackground = new Ogre::Rectangle2D(true); // true = textured
800  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
801  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
802 
803  // Texture options
804  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
805  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
806 
807  // Dynamic texture
808  // If we are using opengl we can boost a little bit performances with a dynamic texture
809  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
810  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
811  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
812  Ogre::TEX_TYPE_2D,
813  mBackgroundWidth,//width
814  mBackgroundHeight,//height
815  0, // num of mip maps
816  Ogre::PF_BYTE_L,
817  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
818  }
819  else{
820  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
821  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
822  Ogre::TEX_TYPE_2D,
823  mBackgroundWidth,//width
824  mBackgroundHeight,//height
825  0, // num of mip maps
826  Ogre::PF_BYTE_L,
827  Ogre::TU_DEFAULT);
828  }
829 
830  // Pointer to the dynamic texture
831  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
832 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
833 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
834 //#else
835 // ;
836 //#endif
837  mPixelBuffer = dynTexPtr->getBuffer();
838 
839  // Material to apply the texture to the background
840  Ogre::MaterialPtr Backgroundmaterial
841  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
842  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
843 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
844 // .dynamicCast<Ogre::Material>();
845 //#else
846 // ;
847 //#endif
848  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
849  Backgroundtechnique->createPass();
850  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
851  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
852  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
853  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
854  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
855  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
856 
857  // Add the background to the Scene Graph so it will be rendered
858  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
859  BackgroundNode->attachObject(mBackground);
860 }
861 
867 void vpAROgre::createBackground(vpImage<vpRGBa> & /* I */)
868 {
869  // Create a rectangle to show the incoming images from the camera
870  mBackground = new Ogre::Rectangle2D(true); // true = textured
871  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
872  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
873 
874  // Texture options
875  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
876  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
877 
878  // Dynamic texture
879  // If we are using opengl we can boost a little bit performances with a dynamic texture
880  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
881  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
882  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
883  Ogre::TEX_TYPE_2D,
884  mBackgroundWidth,//width
885  mBackgroundHeight,//height
886  0, // num of mip maps
887  //Ogre::PF_BYTE_RGBA,
888  Ogre::PF_BYTE_BGRA,
889  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
890  }
891  else{ // As that texture does not seem to work properly with direct3D we use a default texture
892  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
893  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
894  Ogre::TEX_TYPE_2D,
895  mBackgroundWidth,//width
896  mBackgroundHeight,//height
897  0, // num of mip maps
898  //Ogre::PF_BYTE_RGBA,
899  Ogre::PF_BYTE_BGRA,
900  Ogre::TU_DEFAULT);
901  }
902 
903 
904  // Pointer to the dynamic texture
905  Ogre::TexturePtr dynTexPtr =
906  Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
907 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
908 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
909 //#else
910 // ;
911 //#endif
912 
913  // Get the pixel buffer
914  mPixelBuffer = dynTexPtr->getBuffer();
915 
916  // Material to apply the texture to the background
917  Ogre::MaterialPtr Backgroundmaterial
918  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
919  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
920 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
921 // .dynamicCast<Ogre::Material>();
922 //#else
923 // ;
924 //#endif
925  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
926  Backgroundtechnique->createPass();
927  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
928  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
929  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
930  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
931  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
932  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
933 
934  // Add the background to the Scene Graph so it will be rendered
935  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
936  BackgroundNode->attachObject(mBackground);
937 }
938 
947 {
948 #ifdef VISP_HAVE_OIS
949  if( mInputManager )
950  {
951  mInputManager->destroyInputObject( mKeyboard );
952 
953  OIS::InputManager::destroyInputSystem(mInputManager);
954  mInputManager = 0;
955  }
956 #endif
957 }
958 
962 // Note: equation taken from:
963 // http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
965 {
966  if(mCamera != 0){
967  Ogre::Real f,n,f_m_n,f_p_n,px,py,u0,v0;
968  f = (Ogre::Real)(mFarClipping); // Far clip distance
969  n = (Ogre::Real)(mNearClipping); // Near clip distance
970  f_m_n = (Ogre::Real)(f-n);
971  f_p_n = (Ogre::Real)(f+n);
972  px = (Ogre::Real)mcam.get_px();
973  py = (Ogre::Real)mcam.get_py();
974  u0 = (Ogre::Real)mcam.get_u0();
975  v0 = (Ogre::Real)mcam.get_v0();
976  Ogre::Matrix4 Projection
977  = Ogre::Matrix4( (Ogre::Real)(2.0*px/mBackgroundWidth), 0, (Ogre::Real)(1.0 - 2.0*(u0/mBackgroundWidth)), 0,
978  0, (Ogre::Real)(2.0*py/mBackgroundHeight), (Ogre::Real)(-1.0 + 2.0*(v0/mBackgroundHeight)),0,
979  0, 0, (Ogre::Real)(-1.0*f_p_n/f_m_n), (Ogre::Real)(-2.0*f*n/f_m_n),
980  0, 0, -1.0, 0);
981  mCamera->setCustomProjectionMatrix(true, Projection);
982  }
983 }
984 
989 {
990  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
991  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
992  // performance than HBL_NORMAL
993  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
994  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
995  // Buffer data
996  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
997  // Fill in the data in the grey level texture
998  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth);
999 
1000  // Unlock the pixel buffer
1001  mPixelBuffer->unlock();
1002 }
1003 
1008 {
1009  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
1010  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
1011  // performance than HBL_NORMAL
1012  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
1013  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
1014  // Buffer data
1015  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
1016  // Fill in the data in the grey level texture
1017 #if 1 // if texture in BGRa format
1018  for(unsigned int i=0; i<mBackgroundHeight; i++){
1019  for(unsigned int j=0; j<mBackgroundWidth; j++){
1020  // Color Image
1021 // *pDest++=I[i][mBackgroundWidth-j].B; // Blue component
1022 // *pDest++=I[i][mBackgroundWidth-j].G; // Green component
1023 // *pDest++=I[i][mBackgroundWidth-j].R; // Red component
1024 
1025  *pDest++=I[i][j].B; // Blue component
1026  *pDest++=I[i][j].G; // Green component
1027  *pDest++=I[i][j].R; // Red component
1028 
1029  *pDest++ = 255; // Alpha component
1030  }
1031  }
1032 #else // if texture in RGBa format which is the format of the input image
1033  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth*sizeof(vpRGBa));
1034 #endif
1035 
1036  // Unlock the pixel buffer
1037  mPixelBuffer->unlock();
1038 }
1039 
1044 {
1045  // The matrix is given to Ogre with some changes to fit with the world projection
1046  Ogre::Matrix4 ModelView
1047 // = Ogre::Matrix4( (Ogre::Real)-cMo[0][0], (Ogre::Real)-cMo[0][1], (Ogre::Real)-cMo[0][2], (Ogre::Real)-cMo[0][3],
1048  = Ogre::Matrix4( (Ogre::Real)cMw[0][0], (Ogre::Real)cMw[0][1], (Ogre::Real)cMw[0][2], (Ogre::Real)cMw[0][3],
1049  (Ogre::Real)-cMw[1][0], (Ogre::Real)-cMw[1][1], (Ogre::Real)-cMw[1][2], (Ogre::Real)-cMw[1][3],
1050  (Ogre::Real)-cMw[2][0], (Ogre::Real)-cMw[2][1], (Ogre::Real)-cMw[2][2], (Ogre::Real)-cMw[2][3],
1051  (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)1);
1052  mCamera->setCustomViewMatrix(true, ModelView);
1053 }
1054 
1062 {
1064  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("rtf");
1065 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
1066 // .dynamicCast<Ogre::Texture>();
1067 //#else
1068 // ;
1069 //#endif
1070  Ogre::RenderTexture* RTarget = dynTexPtr->getBuffer()->getRenderTarget();
1071  mWindow->update();
1072  RTarget->update();
1073  if(I.getHeight() != mWindow->getHeight() || I.getWidth() != mWindow->getWidth()){
1074  I.resize(mWindow->getHeight(), mWindow->getWidth());
1075  }
1076  Ogre::HardwarePixelBufferSharedPtr mPixelBuffer = dynTexPtr->getBuffer();
1077  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
1078  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
1079  dynTexPtr->getBuffer()->blitToMemory(pixelBox);
1080  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
1081 #if 1 // if texture in BGRa format
1082  for(unsigned int i=0; i<I.getHeight(); i++){
1083  for(unsigned int j=0; j<I.getWidth(); j++){
1084  // Color Image
1085  I[i][j].B = *pDest++; // Blue component
1086  I[i][j].G = *pDest++; // Green component
1087  I[i][j].R = *pDest++; // Red component
1088  I[i][j].A = *pDest++; // Alpha component
1089  }
1090  }
1091 #else // if texture in RGBa format which is the format of the input image
1092  memcpy(I.bitmap, pDest, I.getHeight()*I.getWidth()*sizeof(vpRGBa));
1093 #endif
1094 
1095  // Unlock the pixel buffer
1096  mPixelBuffer->unlock();
1097 
1098 }
1099 
1100 
1101 #elif !defined(VISP_BUILD_SHARED_LIBS)
1102 // Work arround to avoid warning: libvisp_ar.a(vpAROgre.cpp.o) has no symbols
1103 void dummy_vpAROgre() {};
1104 #endif
1105 
virtual void updateBackgroundTexture(const vpImage< unsigned char > &I)
Definition: vpAROgre.cpp:988
void setRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:709
bool keepOn
Definition: vpAROgre.h:371
void addRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:727
bool mshowConfigDialog
Definition: vpAROgre.h:387
double get_u0() const
Ogre::String name
Definition: vpAROgre.h:354
unsigned int getWidth() const
Definition: vpImage.h:226
vpTranslationVector getPosition(const std::string &sceneName) const
Definition: vpAROgre.cpp:698
unsigned int mWindowWidth
Definition: vpAROgre.h:379
Ogre::String mPluginsPath
Definition: vpAROgre.h:362
unsigned int mBackgroundWidth
Definition: vpAROgre.h:377
Implementation of an homogeneous matrix and operations on such kind of matrices.
virtual bool customframeEnded(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:563
Type * bitmap
points toward the bitmap
Definition: vpImage.h:134
virtual bool destroyScene(void)
Definition: vpAROgre.h:322
Ogre::String mResourcePath
Definition: vpAROgre.h:361
error that can be emited by ViSP classes.
Definition: vpException.h:73
virtual void createCamera(void)
Definition: vpAROgre.cpp:786
vpAROgre(const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0, const char *resourcePath=VISP_HAVE_OGRE_RESOURCES_PATH, const char *pluginsPath=VISP_HAVE_OGRE_PLUGINS_PATH)
Definition: vpAROgre.cpp:71
OIS::Keyboard * mKeyboard
Definition: vpAROgre.h:367
double get_py() const
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:586
bool continueRendering(void)
Definition: vpAROgre.cpp:654
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:622
Definition: vpRGBa.h:66
Ogre::RenderWindow * mWindow
Definition: vpAROgre.h:360
OIS::InputManager * mInputManager
Definition: vpAROgre.h:366
Implementation of a rotation matrix and operations on such kind of matrices.
virtual void updateCameraParameters(const vpHomogeneousMatrix &cMo)
Definition: vpAROgre.cpp:1043
static bool checkFilename(const char *filename)
Definition: vpIoTools.cpp:508
void setVisibility(const std::string &sceneName, bool isVisible)
Definition: vpAROgre.cpp:763
double get_v0() const
virtual void init(vpImage< unsigned char > &I, bool bufferedKeys=false, bool hidden=false)
Definition: vpAROgre.cpp:115
vpCameraParameters mcam
Definition: vpAROgre.h:385
virtual bool processInputEvent(const Ogre::FrameEvent &)
Definition: vpAROgre.h:315
void setCameraParameters(const vpCameraParameters &cameraP)
Definition: vpAROgre.cpp:662
virtual ~vpAROgre(void)
Definition: vpAROgre.cpp:459
Ogre::Camera * mCamera
Definition: vpAROgre.h:358
void setScale(const std::string &sceneName, const float factorx, const float factory, const float factorz)
Definition: vpAROgre.cpp:775
Generic class defining intrinsic camera parameters.
virtual void closeOIS(void)
Definition: vpAROgre.cpp:946
virtual bool updateScene(const Ogre::FrameEvent &)
Definition: vpAROgre.h:308
virtual void windowClosed(Ogre::RenderWindow *rw)
Definition: vpAROgre.cpp:575
unsigned int mWindowHeight
Definition: vpAROgre.h:378
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:903
bool windowHidden
Definition: vpAROgre.h:380
void extract(vpRotationMatrix &R) const
void getRenderingOutput(vpImage< vpRGBa > &I, const vpHomogeneousMatrix &cMo)
Definition: vpAROgre.cpp:1061
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1596
void load(const std::string &entityName, const std::string &model)
Definition: vpAROgre.cpp:672
virtual bool customframeStarted(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:543
unsigned int mBackgroundHeight
Definition: vpAROgre.h:376
double get_px() const
virtual void updateCameraProjection(void)
Definition: vpAROgre.cpp:964
Ogre::Root * mRoot
Definition: vpAROgre.h:357
double mFarClipping
Definition: vpAROgre.h:384
Ogre::HardwarePixelBufferSharedPtr mPixelBuffer
Definition: vpAROgre.h:374
Ogre::Rectangle2D * mBackground
Definition: vpAROgre.h:375
virtual void createScene(void)
Definition: vpAROgre.h:299
void setPosition(const std::string &sceneName, const vpTranslationVector &wTo)
Definition: vpAROgre.cpp:685
Ogre::SceneManager * mSceneMgr
Definition: vpAROgre.h:359
unsigned int getHeight() const
Definition: vpImage.h:175
double mNearClipping
Definition: vpAROgre.h:383
std::list< std::string > mOptionnalResourceLocation
Definition: vpAROgre.h:389
Class that consider the case of a translation vector.