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