Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpAROgre.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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), mOptionalResourceLocation()
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 } else {
252 mRoot = Ogre::Root::getSingletonPtr();
253 }
254
255 // Load resource paths from config file
256
257 // File format is:
258 // [ResourceGroupName]
259 // ArchiveType=Path
260 // .. repeat
261 // For example:
262 // [General]
263 // FileSystem=media/
264 // Zip=packages/level1.zip
265
266 // mResourcePath may contain more than one folder location separated by ";"
267 bool resourcesFileExists = false;
268 std::string resourceFile;
269 std::vector<std::string> resourcesPaths = vpIoTools::splitChain(std::string(mResourcePath), std::string(";"));
270 for (size_t i = 0; i < resourcesPaths.size(); i++) {
271 resourceFile = resourcesPaths[i] + "/resources.cfg";
272 if (vpIoTools::checkFilename(resourceFile)) {
273 resourcesFileExists = true;
274 break;
275 }
276 }
277 if (!resourcesFileExists) {
278 std::string errorMsg = std::string("Error: the requested resource file \"resources.cfg\"") +
279 std::string("doesn't exist in ") + std::string(mResourcePath);
280
281 std::cout << errorMsg << std::endl;
282
283 throw(vpException(vpException::ioError, errorMsg));
284 }
285 std::cout << "######################### Load resource file: " << resourceFile << std::endl;
286 Ogre::ConfigFile cf;
287 cf.load(resourceFile);
288
289 // Go through all sections & settings in the file
290 Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
291
292 Ogre::String secName, typeName, archName;
293 while (seci.hasMoreElements()) {
294 secName = seci.peekNextKey();
295 Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
296 Ogre::ConfigFile::SettingsMultiMap::iterator i;
297 for (i = settings->begin(); i != settings->end(); ++i) {
298 typeName = i->first;
299 archName = i->second;
300 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
301 }
302 }
303 std::cout << "##################### add resources" << std::endl;
304 // Add Optional resources (given by the user).
305 for (std::list<std::string>::const_iterator iter = mOptionalResourceLocation.begin();
306 iter != mOptionalResourceLocation.end(); ++iter) {
307 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
308 *iter, "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
309 }
310
311 // Create the window
312 bool canInit = true;
313 if (mshowConfigDialog) {
314 mRoot->restoreConfig();
315 if (!mRoot->showConfigDialog()) {
316 canInit = false;
317 }
318 } else {
319 if (!mRoot->restoreConfig()) {
320 canInit = false;
321 }
322 }
323
324 if (!mRoot->isInitialised()) {
325 if (!canInit) { // We set the default renderer system
326 const Ogre::RenderSystemList &lRenderSystemList = mRoot->getAvailableRenderers();
327 if (lRenderSystemList.size() == 0) {
328 throw "ConfigDialog aborted"; // Exit the application on cancel
329 }
330
331 Ogre::RenderSystem *lRenderSystem = lRenderSystemList.at(0);
332 std::cout << "Using " << lRenderSystem->getName() << " as renderer." << std::endl;
333 mRoot->setRenderSystem(lRenderSystem);
334 }
335
336 mRoot->initialise(false);
337 }
338
339 bool fullscreen = false;
340 Ogre::NameValuePairList misc;
341 Ogre::ConfigOptionMap config = mRoot->getRenderSystem()->getConfigOptions();
342 Ogre::ConfigOptionMap::const_iterator it = config.begin();
343
344 while (it != config.end()) {
345 Ogre::String leftconf = (*it).first;
346 Ogre::String rightconf = (*it).second.currentValue;
347
348 if (leftconf == "Video Mode") {
349 if (canInit) {
350 std::stringstream ss(rightconf.c_str());
351 std::string dummy;
352 ss >> mWindowWidth >> dummy >> mWindowHeight;
353 if (ss.fail()) {
354 std::cout << "Cannot read Ogre video mode" << std::endl;
355 }
356 } else if (mWindowWidth == 0 && mWindowHeight == 0) {
359 }
360 } else if (leftconf == "Full Screen") {
361 if (canInit && (rightconf == "Yes")) {
362 fullscreen = true;
363 }
364 } else {
365 misc[leftconf] = rightconf;
366 }
367
368 ++it;
369 }
370
371 // With Ogre version >= 1.8.1 we hide the window
372 if (hidden) {
373#if (OGRE_VERSION >= (1 << 16 | 8 << 8 | 1))
374 misc["hidden"] = "true";
375 windowHidden = true;
376#endif
377 }
378 mWindow = mRoot->createRenderWindow(name, mWindowWidth, mWindowHeight, fullscreen, &misc);
379
380 // Initialise resources
381 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
382 //-----------------------------------------------------
383 // 4 Create the SceneManager
384 //
385 // ST_GENERIC = octree
386 // ST_EXTERIOR_CLOSE = simple terrain
387 // ST_EXTERIOR_FAR = nature terrain (depreciated)
388 // ST_EXTERIOR_REAL_FAR = paging landscape
389 // ST_INTERIOR = Quake3 BSP
390 //-----------------------------------------------------
391
392 mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
393
394 // Create the camera
395 createCamera();
396
397 // Create a viewport
398 Ogre::Viewport *viewPort = mWindow->addViewport(mCamera);
399 // Ogre::Viewport* viewPort = mCamera->getViewport();
400 viewPort->setClearEveryFrame(true);
401 // Set the projection parameters to match the camera intrinsic parameters
403
404 // Create the 3D scene
405 createScene();
406
407 // Initialise and register event handlers
408 mRoot->addFrameListener(this);
409
410 // Register as a Window listener
411 Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
412
413#ifdef VISP_HAVE_OIS
414 // Initialise OIS
415 Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
416 OIS::ParamList pl;
417
418 size_t windowHnd = 0;
419 std::ostringstream windowHndStr;
420 // Initialise window
421 mWindow->getCustomAttribute("WINDOW", &windowHnd);
422 windowHndStr << windowHnd;
423 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
424// Let the user use the keyboard elsewhere
425#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
426 pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
427#endif
428
429 mInputManager = OIS::InputManager::createInputSystem(pl);
430
431 // Create all devices
432 // Here we only consider the keyboard input
433 mKeyboard = static_cast<OIS::Keyboard *>(mInputManager->createInputObject(OIS::OISKeyboard, bufferedKeys));
434 if (!bufferedKeys) {
435 mKeyboard->setEventCallback(this);
436 }
437#endif
438
439 // Initialise a render to texture to be able to retrieve a screenshot
440 Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual(
441 "rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mWindow->getWidth(),
442 mWindow->getHeight(), 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
443
444 // Ogre::TexturePtr Texture =
445 // Ogre::TextureManager::getSingleton().createManual("rtf",
446 // Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
447 // 640,480, 0, Ogre::PF_R8G8B8A8,
448 // Ogre::TU_RENDERTARGET);
449 Ogre::RenderTexture *RTarget = Texture->getBuffer()->getRenderTarget();
450 /*Ogre::Viewport* Viewport =*/RTarget->addViewport(mCamera);
451 RTarget->getViewport(0)->setClearEveryFrame(true);
452 RTarget->getViewport(0)->setOverlaysEnabled(false);
453}
454
459{
460 // Destroy 3D scene
461 destroyScene();
462 // Close OIS
463 closeOIS();
464
465 if (mWindow) {
466 Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
468 }
469
470 // Delete root
471 if (Ogre::Root::getSingletonPtr() && !Ogre::Root::getSingletonPtr()->getSceneManagerIterator().hasMoreElements() &&
472 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 } else {
489 return keepOn;
490 }
491}
492
502bool vpAROgre::frameStarted(const Ogre::FrameEvent &evt)
503{
504 // custom method telling what to do at the beginning of each frame
505 bool result = customframeStarted(evt);
506
507 // Listen to the window
508 Ogre::WindowEventUtilities::messagePump();
510
511 // See if we have to stop rendering
512 if (result)
513 return stopTest(evt);
514 else
515 return result;
516}
517
524bool vpAROgre::frameEnded(const Ogre::FrameEvent &evt)
525{
526 // custom method telling what to do at the end of each frame
527 bool result = customframeEnded(evt);
528
529 // See if we have to stop rendering
530 if (result)
531 return stopTest(evt);
532 else
533 return result;
534}
535
544bool vpAROgre::customframeStarted(const Ogre::FrameEvent & /*evt*/)
545{
546 // See if window was closed
547 if (mWindow->isClosed())
548 return false;
549
550#ifdef VISP_HAVE_OIS
551 // Get keyboard input
552 mKeyboard->capture();
553 if (mKeyboard->isKeyDown(OIS::KC_ESCAPE))
554 return false;
555#endif
556 return true;
557}
558
564bool vpAROgre::customframeEnded(const Ogre::FrameEvent & /*evt*/) { return true; }
565
576void vpAROgre::windowClosed(Ogre::RenderWindow *rw)
577{
578 // Only close for window that created OIS (the main window in these demos)
579 if (rw == mWindow)
580 closeOIS();
581}
582
589{
590 // Update the background to match the situation
592
593 // Update the camera parameters to match the grabbed image
595
596 // Display on Ogre Window
597 return mRoot->renderOneFrame();
598}
599
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{
624 // Display on Ogre Window
625 if (renderOneFrame(I, cMw)) {
626 mWindow->update();
627 keepOn = true;
628 } else
629 keepOn = false;
630}
631
638{
639 // Display on Ogre Window
640 if (renderOneFrame(I, cMw)) {
641 mWindow->update();
642 keepOn = true;
643 } else
644 keepOn = false;
645}
646
652
656void vpAROgre::setCameraParameters(const vpCameraParameters &cameraP) { mcam = cameraP; }
657
663void vpAROgre::load(const std::string &entityName, const std::string &model)
664{
665 Ogre::Entity *newEntity = mSceneMgr->createEntity(entityName, model);
666 Ogre::SceneNode *newNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(entityName);
667 newNode->attachObject(newEntity);
668}
669
676void vpAROgre::setPosition(const std::string &sceneName, const vpTranslationVector &wTo)
677{
678 // Reset the position
679 Ogre::SceneNode *node = mSceneMgr->getSceneNode(sceneName);
680 node->setPosition((Ogre::Real)wTo[0], (Ogre::Real)wTo[1], (Ogre::Real)wTo[2]);
681}
682
688vpTranslationVector vpAROgre::getPosition(const std::string &sceneName) const
689{
690 Ogre::Vector3 translation = mSceneMgr->getSceneNode(sceneName)->getPosition();
691 return vpTranslationVector((Ogre::Real)translation[0], (Ogre::Real)translation[1], (Ogre::Real)translation[2]);
692}
693
699void vpAROgre::setRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
700{
701 // Get the node in its original position
702 mSceneMgr->getSceneNode(sceneName)->resetOrientation();
703 // Apply the new rotation
704 Ogre::Matrix3 rotationOgre = Ogre::Matrix3((Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
705 (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
706 (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
707 Ogre::Quaternion q(rotationOgre);
708 mSceneMgr->getSceneNode(sceneName)->rotate(q);
709}
710
716void vpAROgre::addRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
717{
718 // Apply the new rotation
719 Ogre::Matrix3 rotationOgre = Ogre::Matrix3((Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
720 (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
721 (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
722 Ogre::Quaternion q(rotationOgre);
723 mSceneMgr->getSceneNode(sceneName)->rotate(q);
724}
725
734void vpAROgre::setPosition(const std::string &sceneName, const vpHomogeneousMatrix &wMo)
735{
736 // Extract the position and orientation data
737 vpRotationMatrix rotations;
738 vpTranslationVector translation;
739 wMo.extract(rotations);
740 wMo.extract(translation);
741 // Apply them to the node
742 setPosition(sceneName, translation);
743 setRotation(sceneName, rotations);
744}
745
751void vpAROgre::setVisibility(const std::string &sceneName, bool isVisible)
752{
753 mSceneMgr->getSceneNode(sceneName)->setVisible(isVisible);
754}
755
763void vpAROgre::setScale(const std::string &sceneName, float factorx, float factory, float factorz)
764{
765 // Reset the scale to its original value
766 mSceneMgr->getSceneNode(sceneName)->scale(Ogre::Vector3(1, 1, 1) / mSceneMgr->getSceneNode(sceneName)->getScale());
767 // Apply the new scale
768 mSceneMgr->getSceneNode(sceneName)->scale(Ogre::Vector3(factorx, factory, factorz));
769}
770
774void vpAROgre::createCamera(void) { mCamera = mSceneMgr->createCamera("Camera"); }
775
782void vpAROgre::createBackground(vpImage<unsigned char> & /* I */)
783{
784 // Create a rectangle to show the incoming images from the camera
785 mBackground = new Ogre::Rectangle2D(true); // true = textured
786 mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
787 mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0 * Ogre::Vector3::UNIT_SCALE,
788 100000.0 * Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
789
790 // Texture options
791 Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
792 Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
793
794 // Dynamic texture
795 // If we are using opengl we can boost a little bit performances with a
796 // dynamic texture
797 if (mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
798 Ogre::TextureManager::getSingleton().createManual(
799 "BackgroundTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
800 mBackgroundWidth, // width
801 mBackgroundHeight, // height
802 0, // num of mip maps
803 Ogre::PF_BYTE_L, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
804 } else {
805 Ogre::TextureManager::getSingleton().createManual(
806 "BackgroundTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
807 mBackgroundWidth, // width
808 mBackgroundHeight, // height
809 0, // num of mip maps
810 Ogre::PF_BYTE_L, Ogre::TU_DEFAULT);
811 }
812
813 // Pointer to the dynamic texture
814 Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
815 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
816 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
817 //#else
818 // ;
819 //#endif
820 mPixelBuffer = dynTexPtr->getBuffer();
821
822 // Material to apply the texture to the background
823 Ogre::MaterialPtr Backgroundmaterial = Ogre::MaterialManager::getSingleton().create(
824 "BackgroundMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
825 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
826 // .dynamicCast<Ogre::Material>();
827 //#else
828 // ;
829 //#endif
830 Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
831 Backgroundtechnique->createPass();
832 Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
833 Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
834 Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
835 Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
836 mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
837 mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
838
839 // Add the background to the Scene Graph so it will be rendered
840 Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
841 BackgroundNode->attachObject(mBackground);
842}
843
850void vpAROgre::createBackground(vpImage<vpRGBa> & /* I */)
851{
852 // Create a rectangle to show the incoming images from the camera
853 mBackground = new Ogre::Rectangle2D(true); // true = textured
854 mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
855 mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0 * Ogre::Vector3::UNIT_SCALE,
856 100000.0 * Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
857
858 // Texture options
859 Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
860 Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
861
862 // Dynamic texture
863 // If we are using opengl we can boost a little bit performances with a
864 // dynamic texture
865 if (mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
866 Ogre::TextureManager::getSingleton().createManual(
867 "BackgroundTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
868 mBackgroundWidth, // width
869 mBackgroundHeight, // height
870 0, // num of mip maps
871 // Ogre::PF_BYTE_RGBA,
872 Ogre::PF_BYTE_BGRA, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
873 } else { // As that texture does not seem to work properly with direct3D we
874 // use a default texture
875 Ogre::TextureManager::getSingleton().createManual(
876 "BackgroundTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
877 mBackgroundWidth, // width
878 mBackgroundHeight, // height
879 0, // num of mip maps
880 // Ogre::PF_BYTE_RGBA,
881 Ogre::PF_BYTE_BGRA, Ogre::TU_DEFAULT);
882 }
883
884 // Pointer to the dynamic texture
885 Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
886 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
887 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
888 //#else
889 // ;
890 //#endif
891
892 // Get the pixel buffer
893 mPixelBuffer = dynTexPtr->getBuffer();
894
895 // Material to apply the texture to the background
896 Ogre::MaterialPtr Backgroundmaterial = Ogre::MaterialManager::getSingleton().create(
897 "BackgroundMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
898 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
899 // .dynamicCast<Ogre::Material>();
900 //#else
901 // ;
902 //#endif
903 Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
904 Backgroundtechnique->createPass();
905 Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
906 Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
907 Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
908 Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
909 mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
910 mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
911
912 // Add the background to the Scene Graph so it will be rendered
913 Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
914 BackgroundNode->attachObject(mBackground);
915}
916
925{
926#ifdef VISP_HAVE_OIS
927 if (mInputManager) {
928 mInputManager->destroyInputObject(mKeyboard);
929
930 OIS::InputManager::destroyInputSystem(mInputManager);
931 mInputManager = 0;
932 }
933#endif
934}
935
939// Note: equation taken from:
940// http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
942{
943 if (mCamera != 0) {
944 Ogre::Real f, n, f_m_n, f_p_n, px, py, u0, v0;
945 f = (Ogre::Real)(mFarClipping); // Far clip distance
946 n = (Ogre::Real)(mNearClipping); // Near clip distance
947 f_m_n = (Ogre::Real)(f - n);
948 f_p_n = (Ogre::Real)(f + n);
949 px = (Ogre::Real)mcam.get_px();
950 py = (Ogre::Real)mcam.get_py();
951 u0 = (Ogre::Real)mcam.get_u0();
952 v0 = (Ogre::Real)mcam.get_v0();
953 Ogre::Matrix4 Projection = Ogre::Matrix4(
954 (Ogre::Real)(2.0 * px / mBackgroundWidth), 0, (Ogre::Real)(1.0 - 2.0 * (u0 / mBackgroundWidth)), 0, 0,
955 (Ogre::Real)(2.0 * py / mBackgroundHeight), (Ogre::Real)(-1.0 + 2.0 * (v0 / mBackgroundHeight)), 0, 0, 0,
956 (Ogre::Real)(-1.0 * f_p_n / f_m_n), (Ogre::Real)(-2.0 * f * n / f_m_n), 0, 0, -1.0, 0);
957 mCamera->setCustomProjectionMatrix(true, Projection);
958 }
959}
960
965{
966 // Inspired from Ogre wiki :
967 // http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures Lock the pixel
968 // buffer and get a pixel box. HBL_DISCARD is to use for best performance
969 // than HBL_NORMAL
970 mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
971 const Ogre::PixelBox &pixelBox = mPixelBuffer->getCurrentLock();
972 // Buffer data
973 Ogre::uint8 *pDest = static_cast<Ogre::uint8 *>(pixelBox.data);
974 // Fill in the data in the grey level texture
975 memcpy(pDest, I.bitmap, mBackgroundHeight * mBackgroundWidth);
976
977 // Unlock the pixel buffer
978 mPixelBuffer->unlock();
979}
980
985{
986 // Inspired from Ogre wiki :
987 // http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures Lock the pixel
988 // buffer and get a pixel box. HBL_DISCARD is to use for best performance
989 // than HBL_NORMAL
990 mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
991 const Ogre::PixelBox &pixelBox = mPixelBuffer->getCurrentLock();
992 // Buffer data
993 Ogre::uint8 *pDest = static_cast<Ogre::uint8 *>(pixelBox.data);
994// Fill in the data in the grey level texture
995#if 1 // if texture in BGRa format
996 for (unsigned int i = 0; i < mBackgroundHeight; i++) {
997 for (unsigned int j = 0; j < mBackgroundWidth; j++) {
998 // Color Image
999 // *pDest++=I[i][mBackgroundWidth-j].B; // Blue component
1000 // *pDest++=I[i][mBackgroundWidth-j].G; // Green component
1001 // *pDest++=I[i][mBackgroundWidth-j].R; // Red component
1002
1003 *pDest++ = I[i][j].B; // Blue component
1004 *pDest++ = I[i][j].G; // Green component
1005 *pDest++ = I[i][j].R; // Red component
1006
1007 *pDest++ = 255; // Alpha component
1008 }
1009 }
1010#else // if texture in RGBa format which is the format of the input image
1011 memcpy(pDest, I.bitmap, mBackgroundHeight * mBackgroundWidth * sizeof(vpRGBa));
1012#endif
1013
1014 // Unlock the pixel buffer
1015 mPixelBuffer->unlock();
1016}
1017
1022{
1023 // The matrix is given to Ogre with some changes to fit with the world
1024 // projection
1025 Ogre::Matrix4 ModelView
1026 // = Ogre::Matrix4( (Ogre::Real)-cMo[0][0], (Ogre::Real)-cMo[0][1],
1027 // (Ogre::Real)-cMo[0][2], (Ogre::Real)-cMo[0][3],
1028 = Ogre::Matrix4((Ogre::Real)cMw[0][0], (Ogre::Real)cMw[0][1], (Ogre::Real)cMw[0][2], (Ogre::Real)cMw[0][3],
1029 (Ogre::Real)-cMw[1][0], (Ogre::Real)-cMw[1][1], (Ogre::Real)-cMw[1][2], (Ogre::Real)-cMw[1][3],
1030 (Ogre::Real)-cMw[2][0], (Ogre::Real)-cMw[2][1], (Ogre::Real)-cMw[2][2], (Ogre::Real)-cMw[2][3],
1031 (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)1);
1032 mCamera->setCustomViewMatrix(true, ModelView);
1033}
1034
1042{
1044 Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("rtf");
1045 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
1046 // .dynamicCast<Ogre::Texture>();
1047 //#else
1048 // ;
1049 //#endif
1050 Ogre::RenderTexture *RTarget = dynTexPtr->getBuffer()->getRenderTarget();
1051 mWindow->update();
1052 RTarget->update();
1053 if (I.getHeight() != mWindow->getHeight() || I.getWidth() != mWindow->getWidth()) {
1054 I.resize(mWindow->getHeight(), mWindow->getWidth());
1055 }
1056 mPixelBuffer = dynTexPtr->getBuffer();
1057 mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
1058 const Ogre::PixelBox &pixelBox = mPixelBuffer->getCurrentLock();
1059 dynTexPtr->getBuffer()->blitToMemory(pixelBox);
1060 Ogre::uint8 *pDest = static_cast<Ogre::uint8 *>(pixelBox.data);
1061#if 1 // if texture in BGRa format
1062 for (unsigned int i = 0; i < I.getHeight(); i++) {
1063 for (unsigned int j = 0; j < I.getWidth(); j++) {
1064 // Color Image
1065 I[i][j].B = *pDest++; // Blue component
1066 I[i][j].G = *pDest++; // Green component
1067 I[i][j].R = *pDest++; // Red component
1068 I[i][j].A = *pDest++; // Alpha component
1069 }
1070 }
1071#else // if texture in RGBa format which is the format of the input image
1072 memcpy(I.bitmap, pDest, I.getHeight() * I.getWidth() * sizeof(vpRGBa));
1073#endif
1074
1075 // Unlock the pixel buffer
1076 mPixelBuffer->unlock();
1077}
1078
1079#elif !defined(VISP_BUILD_SHARED_LIBS)
1080// Work around to avoid warning: libvisp_ar.a(vpAROgre.cpp.o) has no symbols
1081void dummy_vpAROgre(){};
1082#endif
OIS::InputManager * mInputManager
Definition vpAROgre.h:366
void setCameraParameters(const vpCameraParameters &cameraP)
Definition vpAROgre.cpp:656
bool continueRendering(void)
Definition vpAROgre.cpp:651
virtual bool updateScene(const Ogre::FrameEvent &)
Definition vpAROgre.h:308
virtual bool customframeEnded(const Ogre::FrameEvent &evt)
Definition vpAROgre.cpp:564
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:716
unsigned int mBackgroundWidth
Definition vpAROgre.h:378
vpCameraParameters mcam
Definition vpAROgre.h:386
void getRenderingOutput(vpImage< vpRGBa > &I, const vpHomogeneousMatrix &cMo)
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
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:941
Ogre::Camera * mCamera
Definition vpAROgre.h:358
void setRotation(const std::string &sceneName, const vpRotationMatrix &wRo)
Definition vpAROgre.cpp:699
virtual void closeOIS(void)
Definition vpAROgre.cpp:924
unsigned int mBackgroundHeight
Definition vpAROgre.h:377
virtual void windowClosed(Ogre::RenderWindow *rw)
Definition vpAROgre.cpp:576
virtual bool customframeStarted(const Ogre::FrameEvent &evt)
Definition vpAROgre.cpp:544
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:688
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:751
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:622
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition vpAROgre.cpp:588
void load(const std::string &entityName, const std::string &model)
Definition vpAROgre.cpp:663
virtual void createCamera(void)
Definition vpAROgre.cpp:774
virtual void updateCameraParameters(const vpHomogeneousMatrix &cMo)
std::list< std::string > mOptionalResourceLocation
Definition vpAROgre.h:391
Ogre::SceneManager * mSceneMgr
Definition vpAROgre.h:359
Ogre::HardwarePixelBufferSharedPtr mPixelBuffer
Definition vpAROgre.h:375
virtual ~vpAROgre(void)
Definition vpAROgre.cpp:458
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:676
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:964
void setScale(const std::string &sceneName, float factorx, float factory, float factorz)
Definition vpAROgre.cpp:763
Generic class defining intrinsic camera parameters.
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ ioError
I/O error.
Definition vpException.h:79
Implementation of an homogeneous matrix and operations on such kind of matrices.
void extract(vpRotationMatrix &R) const
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition vpImage.h:795
Type * bitmap
points toward the bitmap
Definition vpImage.h:139
unsigned int getHeight() const
Definition vpImage.h:184
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
static bool checkFilename(const std::string &filename)
Implementation of a rotation matrix and operations on such kind of matrices.
Class that consider the case of a translation vector.