ViSP  2.7.0
vpMbHiddenFaces.h
1 /****************************************************************************
2  *
3  * $Id: vpMbTracker.h 4004 2012-11-23 17:34:44Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  * Description:
34  * Generic model based tracker. This class declares the methods to implement in
35  * order to have a model based tracker.
36  *
37  * Authors:
38  * Romain Tallonneau
39  * AurĂ©lien Yol
40  *
41  *****************************************************************************/
42 #pragma once
43 
44 #ifndef vpMbHiddenFaces_HH
45 #define vpMbHiddenFaces_HH
46 
47 #include <visp/vpHomogeneousMatrix.h>
48 #include <visp/vpMeterPixelConversion.h>
49 #include <visp/vpPixelMeterConversion.h>
50 #include <visp/vpMbtPolygon.h>
51 
52 #ifdef VISP_HAVE_OGRE
53  #include <visp/vpAROgre.h>
54 #endif
55 
56 #include <vector>
57 
66 template<class PolygonType = vpMbtPolygon>
68 {
69  private:
70  std::vector<PolygonType *> Lpol ;
72  bool depthTest;
74  unsigned int nbVisiblePolygon;
75 
76 #ifdef VISP_HAVE_OGRE
77  vpImage<vpRGBa> ogreBackground;
78  bool ogreInitialised;
79  vpAROgre *ogre;
80  std::vector< Ogre::ManualObject* > lOgrePolygons;
81 #endif
82 
83  unsigned int setVisiblePrivate(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears,
84  bool &changed,
85  bool useOgre = false, bool testRoi = false,
88  ) ;
89 
90 
91  public :
92  vpMbHiddenFaces() ;
94 
95  void addPolygon(PolygonType *p) ;
96 
97 #ifdef VISP_HAVE_OGRE
98  void displayOgre(const vpHomogeneousMatrix &_cMo);
99 #endif
100 
106  std::vector<PolygonType*>& getPolygon() {return Lpol;}
107 
108 #ifdef VISP_HAVE_OGRE
110 #endif
111 
117  bool getDepthTest(){return depthTest;}
118 
124  unsigned int getNbVisiblePolygon(){return nbVisiblePolygon;}
125 
126 #ifdef VISP_HAVE_OGRE
127 
132  vpAROgre* getOgreContext(){return ogre;}
133 #endif
134 
135  bool isAppearing(const unsigned int i){ return Lpol[i]->isAppearing(); }
136 
137 
138 #ifdef VISP_HAVE_OGRE
139 
144  bool isOgreInitialised() { return ogreInitialised; }
145 #endif
146 
154  bool isVisible(const unsigned int i){ return Lpol[i]->isVisible(); }
155 
156 #ifdef VISP_HAVE_OGRE
157  bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index);
158 #endif
159 
161  inline PolygonType* operator[](const unsigned int i) { return Lpol[i];}
163  inline const PolygonType* operator[](const unsigned int i) const { return Lpol[i];}
164 
165  void reset();
166 
172  void setDepthTest(const bool &d){depthTest = d;}
173  unsigned int setVisible(const vpHomogeneousMatrix &_cMo) ;
174  unsigned int setVisible(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angle, bool &changed) ;
175  unsigned int setVisible(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
176  unsigned int setVisible(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
177 
178 #ifdef VISP_HAVE_OGRE
179  unsigned int setVisibleOgre(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
180  unsigned int setVisibleOgre(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
181 #endif
182 
187  inline unsigned int size(){ return Lpol.size(); }
188 } ;
189 
193 template<class PolygonType>
194 vpMbHiddenFaces<PolygonType>::vpMbHiddenFaces(): depthTest(false), nbVisiblePolygon(0)
195 {
196 #ifdef VISP_HAVE_OGRE
197  ogreInitialised = false;
198  ogre = new vpAROgre();
199  ogre->setShowConfigDialog(false);
200  ogreBackground = vpImage<vpRGBa>(480, 640);
201 #endif
202 }
203 
204 
208 template<class PolygonType>
210 {
211  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
212  if (Lpol[i]!=NULL){
213  delete Lpol[i] ;
214  }
215  Lpol[i] = NULL ;
216  }
217  Lpol.resize(0);
218 
219 #ifdef VISP_HAVE_OGRE
220  delete ogre;
221 #endif
222 }
223 
229 template<class PolygonType>
230 void
232 {
233  PolygonType *p_new = new PolygonType;
234  p_new->index = p->index;
235  p_new->setNbPoint(p->nbpt);
236  p_new->isvisible = p->isvisible;
237  for(unsigned int i = 0; i < p->nbpt; i++)
238  p_new->p[i]= p->p[i];
239  Lpol.push_back(p_new);
240 }
241 
249 template<class PolygonType>
250 unsigned int
252 {
253  nbVisiblePolygon = 0 ;
254 
255  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
256  if (Lpol[i]->isVisible(_cMo, depthTest)){
257  nbVisiblePolygon++;
258  }
259  }
260  return nbVisiblePolygon ;
261 }
262 
266 template<class PolygonType>
267 void
269 {
270  nbVisiblePolygon = 0;
271  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
272  if (Lpol[i]!=NULL){
273  delete Lpol[i] ;
274  }
275  Lpol[i] = NULL ;
276  }
277  Lpol.resize(0);
278 }
279 
294 template<class PolygonType>
295 unsigned int
296 vpMbHiddenFaces<PolygonType>::setVisiblePrivate(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears,
297  bool &changed, bool useOgre, bool testRoi,
298  const vpImage<unsigned char> &_I,
299  const vpCameraParameters &_cam
300  )
301 {
302  nbVisiblePolygon = 0;
303  changed = false;
304 
305  vpTranslationVector cameraPos;
306  std::vector<vpImagePoint> roi;
307 
308  if(useOgre){
309 #ifdef VISP_HAVE_OGRE
310  _cMo.inverse().extract(cameraPos);
311  ogre->renderOneFrame(ogreBackground, _cMo);
312 #else
313  vpTRACE("ViSP doesn't have Ogre3D, simple visibility test used");
314 #endif
315  }
316 
317  for (unsigned int i = 0; i < Lpol.size(); i += 1){
318  Lpol[i]->changeFrame(_cMo);
319  Lpol[i]->isappearing = false;
320  if(testRoi)
321  roi = Lpol[i]->getRoi(_cam);
322 
323  if(Lpol[i]->isVisible())
324  {
325  bool testDisappear = false;
326 
327  if(testRoi)
328  testDisappear = (!vpMbtPolygon::roiInsideImage(_I, roi));
329 
330  if(!testDisappear){
331  if(useOgre)
332 #ifdef VISP_HAVE_OGRE
333  testDisappear = ((!Lpol[i]->isVisible(_cMo, angleDisappears)) || !isVisibleOgre(cameraPos,i));
334 #else
335  testDisappear = (!Lpol[i]->isVisible(_cMo, angleDisappears));
336 #endif
337  else
338  testDisappear = (!Lpol[i]->isVisible(_cMo, angleDisappears));
339  }
340 
341  // test if the face is still visible
342  if(testDisappear){
343 // std::cout << "Face " << i << " disappears" << std::endl;
344  changed = true;
345  Lpol[i]->isvisible = false;
346  }
347  else {
348  nbVisiblePolygon++;
349  Lpol[i]->isvisible = true;
350  }
351  }
352  else
353  {
354  bool testAppear = true;
355 
356  if(testRoi)
357  testAppear = (vpMbtPolygon::roiInsideImage(_I, roi));
358 
359  if(testAppear){
360  if(useOgre)
361 #ifdef VISP_HAVE_OGRE
362  testAppear = ((Lpol[i]->isVisible(_cMo, angleAppears)) && isVisibleOgre(cameraPos,i));
363 #else
364  testAppear = (Lpol[i]->isVisible(_cMo, angleAppears));
365 #endif
366  else
367  testAppear = (Lpol[i]->isVisible(_cMo, angleAppears));
368  }
369 
370  if(testAppear){
371 // std::cout << "Face " << i << " appears" << std::endl;
372  Lpol[i]->isvisible = true;
373  changed = true;
374  nbVisiblePolygon++;
375  }
376  else
377  Lpol[i]->isvisible = false;
378  }
379  }
380 
381  return nbVisiblePolygon;
382 }
383 
395 template<class PolygonType>
396 unsigned int
397 vpMbHiddenFaces<PolygonType>::setVisible(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angle, bool &changed)
398 {
399  return setVisible(_I, _cam, _cMo, angle, angle, changed);
400 }
401 
414 template<class PolygonType>
415 unsigned int
416 vpMbHiddenFaces<PolygonType>::setVisible(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
417 {
418  return setVisiblePrivate(_cMo,angleAppears,angleDisappears,changed,false,true,_I,_cam);
419 }
420 
431 template<class PolygonType>
432 unsigned int
433 vpMbHiddenFaces<PolygonType>::setVisible(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
434 {
435  return setVisiblePrivate(_cMo,angleAppears,angleDisappears,changed,false);
436 }
437 
438 #ifdef VISP_HAVE_OGRE
439 
444 template<class PolygonType>
445 void
447 {
448  ogreInitialised = true;
449  ogre->setCameraParameters(_cam);
450  ogre->init(ogreBackground, false, true);
451 
452  for(unsigned int n = 0 ; n < Lpol.size(); n++){
453  Ogre::ManualObject* manual = ogre->getSceneManager()->createManualObject(Ogre::StringConverter::toString(n));
454 
455  manual->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
456  for(unsigned int i = 0; i < Lpol[n]->nbpt; i++){
457  manual->position( (Ogre::Real)Lpol[n]->p[i].get_oX(), (Ogre::Real)Lpol[n]->p[i].get_oY(), (Ogre::Real)Lpol[n]->p[i].get_oZ());
458  manual->colour(1.0, 1.0, 1.0);
459  }
460 
461  manual->index(0);
462  manual->index(1);
463  manual->index(2);
464  manual->index(3);
465  manual->index(0);
466  manual->end();
467 
468  ogre->getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
469 
470  lOgrePolygons.push_back(manual);
471  }
472 }
473 
479 template<class PolygonType>
480 void
482 {
483  if(ogreInitialised && !ogre->isWindowHidden()){
484  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
485  if(Lpol[i]->isVisible()){
486  lOgrePolygons[i]->setVisible(true);
487  }
488  else
489  lOgrePolygons[i]->setVisible(false);
490  }
491  ogre->display(ogreBackground, _cMo);
492  }
493 }
494 
507 template<class PolygonType>
508 unsigned int
509 vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpImage<unsigned char>& _I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
510 {
511  return setVisiblePrivate(_cMo,angleAppears,angleDisappears,changed,true,true,_I,_cam);
512 }
513 
524 template<class PolygonType>
525 unsigned int
526 vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
527 {
528  return setVisiblePrivate(_cMo,angleAppears,angleDisappears,changed,true);
529 }
530 
539 template<class PolygonType>
540 bool
541 vpMbHiddenFaces<PolygonType>::isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
542 {
543 // std::cout << "visible" << std::endl;
544  // A line is always visible
545  if(Lpol[index]->getNbPoint() <= 2){
546  lOgrePolygons[index]->setVisible(true);
547  Lpol[index]->isvisible = true;
548  return true;
549  }
550 
551  Ogre::Vector3 camera((Ogre::Real)cameraPos[0],(Ogre::Real)cameraPos[1],(Ogre::Real)cameraPos[2]);
552  if(!ogre->getCamera()->isVisible(lOgrePolygons[index]->getBoundingBox())){
553  lOgrePolygons[index]->setVisible(false);
554  Lpol[index]->isvisible = false;
555  return false;
556  }
557 
558  //Get the center of gravity
559  Ogre::Vector3 origin(0,0,0);
560  for(unsigned int j = 0 ; j < Lpol[index]->getNbPoint() ; j++){
561  Ogre::Vector3 tmp((Ogre::Real)Lpol[index]->getPoint(j).get_oX(), (Ogre::Real)Lpol[index]->getPoint(j).get_oY(), (Ogre::Real)Lpol[index]->getPoint(j).get_oZ());
562  origin += tmp;
563  }
564  origin /= (Ogre::Real)Lpol[index]->getNbPoint();
565  Ogre::Vector3 direction = origin - camera;
566 
567  Ogre::RaySceneQuery *mRaySceneQuery = ogre->getSceneManager()->createRayQuery(Ogre::Ray(camera, direction));
568  mRaySceneQuery->setSortByDistance(true);
569 
570  Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
571  Ogre::RaySceneQueryResult::iterator it = result.begin();
572 
573  bool visible = false;
574  if(it != result.end()){
575 // std::cout << it->movable->getName() << "/";
576 
577  if(it->movable->getName().find("SimpleRenderable") != Ogre::String::npos) //Test if the ogreBackground is intersect in first
578  it++;
579 
580  if(it != result.end()){
581 // std::cout << it->movable->getName() << " / ";
582  if(it->movable->getName() == Ogre::StringConverter::toString(index)){
583  visible = true;
584  }
585  }
586 // std::cout << std::endl;
587  }
588 
589  if(visible){
590  lOgrePolygons[index]->setVisible(true);
591  Lpol[index]->isvisible = true;
592  }
593  else{
594  lOgrePolygons[index]->setVisible(false);
595  Lpol[index]->isvisible = false;
596  }
597 
598  ogre->getSceneManager()->destroyQuery(mRaySceneQuery);
599 
600  return Lpol[index]->isvisible;
601 }
602 #endif //VISP_HAVE_OGRE
603 
604 #endif
605 
const PolygonType * operator[](const unsigned int i) const
operator[] as reader.
bool isAppearing(const unsigned int i)
Implementation of the polygons management for the model-based trackers.
Ogre::Camera * getCamera()
Definition: vpAROgre.h:142
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpTRACE
Definition: vpDebug.h:401
void setDepthTest(const bool &d)
void setShowConfigDialog(const bool showConfigDialog)
Definition: vpAROgre.h:221
PolygonType * operator[](const unsigned int i)
operator[] as modifier.
void initOgre(vpCameraParameters _cam=vpCameraParameters())
Implementation of an augmented reality viewer.
Definition: vpAROgre.h:90
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:560
Ogre::SceneManager * getSceneManager()
Definition: vpAROgre.h:148
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:596
unsigned int setVisibleOgre(const vpImage< unsigned char > &_I, const vpCameraParameters &_cam, const vpHomogeneousMatrix &_cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
vpAROgre * getOgreContext()
virtual void init(vpImage< unsigned char > &I, bool bufferedKeys=false, bool hidden=false)
Definition: vpAROgre.cpp:131
void setCameraParameters(const vpCameraParameters &cameraP)
Definition: vpAROgre.cpp:636
Generic class defining intrinsic camera parameters.
void extract(vpRotationMatrix &R) const
unsigned int getNbVisiblePolygon()
void addPolygon(PolygonType *p)
unsigned int setVisible(const vpHomogeneousMatrix &_cMo)
unsigned int size()
vpHomogeneousMatrix inverse() const
bool isWindowHidden()
Definition: vpAROgre.h:158
bool isVisible(const unsigned int i)
void displayOgre(const vpHomogeneousMatrix &_cMo)
static bool roiInsideImage(const vpImage< unsigned char > &I, const std::vector< vpImagePoint > &corners)
Class that consider the case of a translation vector.
std::vector< PolygonType * > & getPolygon()