Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
vpMbHiddenFaces.h
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  * Generic model based tracker. This class declares the methods to implement
33  *in order to have a model based tracker.
34  *
35  * Authors:
36  * Romain Tallonneau
37  * Aurelien Yol
38  *
39  *****************************************************************************/
40 #pragma once
41 
42 #ifndef vpMbHiddenFaces_HH
43 #define vpMbHiddenFaces_HH
44 
45 #include <visp3/core/vpHomogeneousMatrix.h>
46 #include <visp3/core/vpMeterPixelConversion.h>
47 #include <visp3/core/vpPixelMeterConversion.h>
48 #include <visp3/mbt/vpMbScanLine.h>
49 #include <visp3/mbt/vpMbtPolygon.h>
50 
51 #ifdef VISP_HAVE_OGRE
52 #include <visp3/ar/vpAROgre.h>
53 #endif
54 
55 #include <limits>
56 #include <vector>
57 
58 template <class PolygonType> class vpMbHiddenFaces;
59 
60 template <class PolygonType> void swap(vpMbHiddenFaces<PolygonType> &first, vpMbHiddenFaces<PolygonType> &second);
61 
70 template <class PolygonType = vpMbtPolygon> class vpMbHiddenFaces
71 {
72 private:
74  std::vector<PolygonType *> Lpol;
76  unsigned int nbVisiblePolygon;
77  vpMbScanLine scanlineRender;
78 
79 #ifdef VISP_HAVE_OGRE
80  vpImage<unsigned char> ogreBackground;
81  bool ogreInitialised;
82  unsigned int nbRayAttempts;
83  double ratioVisibleRay;
84  vpAROgre *ogre;
85  std::vector<Ogre::ManualObject *> lOgrePolygons;
86  bool ogreShowConfigDialog;
87 #endif
88 
89  unsigned int setVisiblePrivate(const vpHomogeneousMatrix &cMo, const double &angleAppears,
90  const double &angleDisappears, bool &changed, bool useOgre = false,
91  bool not_used = false, const vpImage<unsigned char> &I = vpImage<unsigned char>(),
92  const vpCameraParameters &cam = vpCameraParameters());
93 
94 public:
96  virtual ~vpMbHiddenFaces();
97  vpMbHiddenFaces(const vpMbHiddenFaces &copy);
99  friend void swap<>(vpMbHiddenFaces &first, vpMbHiddenFaces &second);
100 
101  void addPolygon(PolygonType *p);
102 
103  bool computeVisibility(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
104  bool &changed, bool useOgre, bool not_used, const vpImage<unsigned char> &I,
105  const vpCameraParameters &cam, const vpTranslationVector &cameraPos, unsigned int index);
106 
108 
109  void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h);
110 
111  void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector<std::pair<vpPoint, vpPoint> > &lines,
112  const bool &displayResults = false);
113 
114  vpMbScanLine &getMbScanLineRenderer() { return scanlineRender; }
115 
116 #ifdef VISP_HAVE_OGRE
117  void displayOgre(const vpHomogeneousMatrix &cMo);
118 #endif
119 
125  std::vector<PolygonType *> &getPolygon() { return Lpol; }
126 
127 #ifdef VISP_HAVE_OGRE
128  void initOgre(const vpCameraParameters &cam = vpCameraParameters());
129 #endif
130 
136  unsigned int getNbVisiblePolygon() const { return nbVisiblePolygon; }
137 
138 #ifdef VISP_HAVE_OGRE
139 
148  unsigned int getNbRayCastingAttemptsForVisibility() { return nbRayAttempts; }
149 
155  vpAROgre *getOgreContext() { return ogre; }
156 
166  double getGoodNbRayCastingAttemptsRatio() { return ratioVisibleRay; }
167 #endif
168 
169  bool isAppearing(const unsigned int i) { return Lpol[i]->isAppearing(); }
170 
171 #ifdef VISP_HAVE_OGRE
172 
177  bool isOgreInitialised() { return ogreInitialised; }
178 #endif
179 
187  bool isVisible(const unsigned int i) { return Lpol[i]->isVisible(); }
188 
189 #ifdef VISP_HAVE_OGRE
190  bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index);
191 #endif
192 
194  inline PolygonType *operator[](const unsigned int i) { return Lpol[i]; }
196  inline const PolygonType *operator[](const unsigned int i) const { return Lpol[i]; }
197 
198  void reset();
199 
200 #ifdef VISP_HAVE_OGRE
201 
211  void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
212  {
213  ogreBackground = vpImage<unsigned char>(h, w, 0);
214  }
215 
225  void setNbRayCastingAttemptsForVisibility(const unsigned int &attempts) { nbRayAttempts = attempts; }
226 
236  void setGoodNbRayCastingAttemptsRatio(const double &ratio)
237  {
238  ratioVisibleRay = ratio;
239  if (ratioVisibleRay > 1.0)
240  ratioVisibleRay = 1.0;
241  if (ratioVisibleRay < 0.0)
242  ratioVisibleRay = 0.0;
243  }
254  inline void setOgreShowConfigDialog(const bool showConfigDialog) { ogreShowConfigDialog = showConfigDialog; }
255 #endif
256 
257  unsigned int setVisible(const vpImage<unsigned char> &I, const vpCameraParameters &cam,
258  const vpHomogeneousMatrix &cMo, const double &angle, bool &changed);
259  unsigned int setVisible(const vpImage<unsigned char> &I, const vpCameraParameters &cam,
260  const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
261  bool &changed);
262  unsigned int setVisible(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
263  bool &changed);
264 
265 #ifdef VISP_HAVE_OGRE
266  unsigned int setVisibleOgre(const vpImage<unsigned char> &I, const vpCameraParameters &cam,
267  const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
268  bool &changed);
269  unsigned int setVisibleOgre(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
270  bool &changed);
271 #endif
272 
277  inline unsigned int size() const { return (unsigned int)Lpol.size(); }
278 };
279 
283 template <class PolygonType>
284 vpMbHiddenFaces<PolygonType>::vpMbHiddenFaces() : Lpol(), nbVisiblePolygon(0), scanlineRender()
285 {
286 #ifdef VISP_HAVE_OGRE
287  ogreInitialised = false;
288  nbRayAttempts = 1;
289  ratioVisibleRay = 1.0;
290  ogreShowConfigDialog = false;
291  ogre = new vpAROgre();
292  ogreBackground = vpImage<unsigned char>(480, 640, 0);
293 #endif
294 }
295 
300 {
301  for (unsigned int i = 0; i < Lpol.size(); i++) {
302  if (Lpol[i] != NULL) {
303  delete Lpol[i];
304  }
305  Lpol[i] = NULL;
306  }
307  Lpol.resize(0);
308 
309 #ifdef VISP_HAVE_OGRE
310  if (ogre != NULL) {
311  delete ogre;
312  ogre = NULL;
313  }
314 
315  // This is already done by calling "delete ogre"
316  // for(unsigned int i = 0 ; i < lOgrePolygons.size() ; i++){
317  // if (lOgrePolygons[i]!=NULL){
318  // delete lOgrePolygons[i];
319  // }
320  // lOgrePolygons[i] = NULL;
321  // }
322 
323  lOgrePolygons.resize(0);
324 #endif
325 }
326 
330 template <class PolygonType>
332  : Lpol(), nbVisiblePolygon(copy.nbVisiblePolygon), scanlineRender(copy.scanlineRender)
333 #ifdef VISP_HAVE_OGRE
334  ,
335  ogreBackground(copy.ogreBackground), ogreInitialised(copy.ogreInitialised), nbRayAttempts(copy.nbRayAttempts),
336  ratioVisibleRay(copy.ratioVisibleRay), ogre(NULL), lOgrePolygons(), ogreShowConfigDialog(copy.ogreShowConfigDialog)
337 #endif
338 {
339  // Copy the list of polygons
340  for (unsigned int i = 0; i < copy.Lpol.size(); i++) {
341  PolygonType *poly = new PolygonType(*copy.Lpol[i]);
342  Lpol.push_back(poly);
343  }
344 }
345 
346 template <class PolygonType> void swap(vpMbHiddenFaces<PolygonType> &first, vpMbHiddenFaces<PolygonType> &second)
347 {
348  using std::swap;
349  swap(first.Lpol, second.Lpol);
350  swap(first.nbVisiblePolygon, second.nbVisiblePolygon);
351  swap(first.scanlineRender, second.scanlineRender);
352 #ifdef VISP_HAVE_OGRE
353  swap(first.ogreInitialised, second.ogreInitialised);
354  swap(first.nbRayAttempts, second.nbRayAttempts);
355  swap(first.ratioVisibleRay, second.ratioVisibleRay);
356  swap(first.ogreShowConfigDialog, second.ogreShowConfigDialog);
357  swap(first.ogre, second.ogre);
358  swap(first.ogreBackground, second.ogreBackground);
359 #endif
360 }
361 
365 template <class PolygonType>
367 {
368  swap(*this, other);
369 
370  return *this;
371 }
372 
378 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::addPolygon(PolygonType *p)
379 {
380  PolygonType *p_new = new PolygonType;
381  p_new->index = p->index;
382  p_new->setNbPoint(p->nbpt);
383  p_new->isvisible = p->isvisible;
384  p_new->useLod = p->useLod;
385  p_new->minLineLengthThresh = p->minLineLengthThresh;
386  p_new->minPolygonAreaThresh = p->minPolygonAreaThresh;
387  p_new->setName(p->name);
388  p_new->hasOrientation = p->hasOrientation;
389 
390  for (unsigned int i = 0; i < p->nbpt; i++)
391  p_new->p[i] = p->p[i];
392  Lpol.push_back(p_new);
393 }
394 
398 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::reset()
399 {
400  nbVisiblePolygon = 0;
401  for (unsigned int i = 0; i < Lpol.size(); i++) {
402  if (Lpol[i] != NULL) {
403  delete Lpol[i];
404  }
405  Lpol[i] = NULL;
406  }
407  Lpol.resize(0);
408 
409 #ifdef VISP_HAVE_OGRE
410  if (ogre != NULL) {
411  delete ogre;
412  ogre = NULL;
413  }
414 
415  // This is already done by calling "delete ogre"
416  // for(unsigned int i = 0 ; i < lOgrePolygons.size() ; i++){
417  // if (lOgrePolygons[i]!=NULL){
418  // delete lOgrePolygons[i];
419  // }
420  // lOgrePolygons[i] = NULL;
421  // }
422 
423  lOgrePolygons.resize(0);
424 
425  ogreInitialised = false;
426  nbRayAttempts = 1;
427  ratioVisibleRay = 1.0;
428  ogre = new vpAROgre();
429  ogreBackground = vpImage<unsigned char>(480, 640);
430 #endif
431 }
432 
440 template <class PolygonType>
442 {
443  for (unsigned int i = 0; i < Lpol.size(); i++) {
444  // For fast result we could just clip visible polygons.
445  // However clipping all of them gives us the possibility to return more
446  // information in the scanline visibility results
447  // if(Lpol[i]->isVisible())
448  {
449  Lpol[i]->changeFrame(cMo);
450  Lpol[i]->computePolygonClipped(cam);
451  }
452  }
453 }
454 
463 template <class PolygonType>
465  const unsigned int &h)
466 {
467  std::vector<std::vector<std::pair<vpPoint, unsigned int> > > polyClipped(Lpol.size());
468  std::vector<std::vector<std::pair<vpPoint, unsigned int> > *> listPolyClipped;
469  std::vector<int> listPolyIndices;
470 
471  for (unsigned int i = 0; i < Lpol.size(); i++) {
472  // For fast result we could just use visible polygons.
473  // However using all of them gives us the possibility to return more
474  // information in the scanline visibility results
475  // if(Lpol[i]->isVisible())
476  {
477  polyClipped[i].clear();
478  Lpol[i]->getPolygonClipped(polyClipped[i]);
479  if (polyClipped[i].size() != 0) {
480  listPolyClipped.push_back(&polyClipped[i]);
481  listPolyIndices.push_back(Lpol[i]->getIndex());
482  }
483  }
484  }
485 
486  scanlineRender.drawScene(listPolyClipped, listPolyIndices, cam, w, h);
487 }
488 
500 template <class PolygonType>
502  std::vector<std::pair<vpPoint, vpPoint> > &lines,
503  const bool &displayResults)
504 {
505  scanlineRender.queryLineVisibility(a, b, lines, displayResults);
506 }
507 
522 template <class PolygonType>
523 unsigned int vpMbHiddenFaces<PolygonType>::setVisiblePrivate(const vpHomogeneousMatrix &cMo, const double &angleAppears,
524  const double &angleDisappears, bool &changed, bool useOgre,
525  bool not_used, const vpImage<unsigned char> &I,
526  const vpCameraParameters &cam)
527 {
528  nbVisiblePolygon = 0;
529  changed = false;
530 
531  vpTranslationVector cameraPos;
532 
533  if (useOgre) {
534 #ifdef VISP_HAVE_OGRE
535  cMo.inverse().extract(cameraPos);
536  ogre->renderOneFrame(ogreBackground, cMo);
537 #else
538  vpTRACE("ViSP doesn't have Ogre3D, simple visibility test used");
539 #endif
540  }
541 
542  for (unsigned int i = 0; i < Lpol.size(); i++) {
543  // std::cout << "Calling poly: " << i << std::endl;
544  if (computeVisibility(cMo, angleAppears, angleDisappears, changed, useOgre, not_used, I, cam, cameraPos, i))
545  nbVisiblePolygon++;
546  }
547  return nbVisiblePolygon;
548 }
549 
568 template <class PolygonType>
569 bool vpMbHiddenFaces<PolygonType>::computeVisibility(const vpHomogeneousMatrix &cMo, const double &angleAppears,
570  const double &angleDisappears, bool &changed, bool useOgre,
571  bool not_used, const vpImage<unsigned char> &I,
572  const vpCameraParameters &cam,
573  const vpTranslationVector &cameraPos, unsigned int index)
574 {
575  (void)not_used;
576  unsigned int i = index;
577  Lpol[i]->changeFrame(cMo);
578  Lpol[i]->isappearing = false;
579 
580  // Commented because we need to compute visibility
581  // even when dealing with line in level of detail case
582  /*if(Lpol[i]->getNbPoint() <= 2)
583  {
584  Lpol[i]->isvisible = true;
585  }
586  else*/ {
587  if (Lpol[i]->isVisible()) {
588  bool testDisappear = false;
589  // unsigned int nbCornerInsidePrev = 0;
590 
591  if (!testDisappear) {
592  if (useOgre)
593 #ifdef VISP_HAVE_OGRE
594  testDisappear = ((!Lpol[i]->isVisible(cMo, angleDisappears, true, cam, I)) || !isVisibleOgre(cameraPos, i));
595 #else
596  {
597  (void)cameraPos; // Avoid warning
598  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears, false, cam, I));
599  }
600 #endif
601  else
602  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears, false, cam, I));
603  }
604 
605  // test if the face is still visible
606  if (testDisappear) {
607  // std::cout << "Face " << i << " disappears" <<
608  // std::endl;
609  changed = true;
610  Lpol[i]->isvisible = false;
611  } else {
612  // nbVisiblePolygon++;
613  Lpol[i]->isvisible = true;
614 
615  // if(nbCornerInsidePrev > Lpol[i]->getNbCornerInsidePrevImage())
616  // changed = true;
617  }
618  } else {
619  bool testAppear = true;
620 
621  if (testAppear) {
622  if (useOgre)
623 #ifdef VISP_HAVE_OGRE
624  testAppear = ((Lpol[i]->isVisible(cMo, angleAppears, true, cam, I)) && isVisibleOgre(cameraPos, i));
625 #else
626  testAppear = (Lpol[i]->isVisible(cMo, angleAppears, false, cam, I));
627 #endif
628  else
629  testAppear = (Lpol[i]->isVisible(cMo, angleAppears, false, cam, I));
630  }
631 
632  if (testAppear) {
633  // std::cout << "Face " << i << " appears" << std::endl;
634  Lpol[i]->isvisible = true;
635  changed = true;
636  // nbVisiblePolygon++;
637  } else {
638  // std::cout << "Problem" << std::endl;
639  Lpol[i]->isvisible = false;
640  }
641  }
642  }
643  // std::cout << "Nombre de polygones visibles: " << nbVisiblePolygon <<
644  // std::endl;
645  return Lpol[i]->isvisible;
646 }
647 
659 template <class PolygonType>
661  const vpHomogeneousMatrix &cMo, const double &angle,
662  bool &changed)
663 {
664  return setVisible(I, cam, cMo, angle, angle, changed);
665 }
666 
679 template <class PolygonType>
681  const vpHomogeneousMatrix &cMo, const double &angleAppears,
682  const double &angleDisappears, bool &changed)
683 {
684  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, false, true, I, cam);
685 }
686 
698 template <class PolygonType>
699 unsigned int vpMbHiddenFaces<PolygonType>::setVisible(const vpHomogeneousMatrix &cMo, const double &angleAppears,
700  const double &angleDisappears, bool &changed)
701 {
702  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, false);
703 }
704 
705 #ifdef VISP_HAVE_OGRE
706 
711 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::initOgre(const vpCameraParameters &cam)
712 {
713  ogreInitialised = true;
714  ogre->setCameraParameters(cam);
715  ogre->setShowConfigDialog(ogreShowConfigDialog);
716  ogre->init(ogreBackground, false, true);
717 
718  for (unsigned int n = 0; n < Lpol.size(); n++) {
719  Ogre::ManualObject *manual = ogre->getSceneManager()->createManualObject(Ogre::StringConverter::toString(n));
720 
721  manual->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
722  for (unsigned int i = 0; i < Lpol[n]->nbpt; i++) {
723  manual->position((Ogre::Real)Lpol[n]->p[i].get_oX(), (Ogre::Real)Lpol[n]->p[i].get_oY(),
724  (Ogre::Real)Lpol[n]->p[i].get_oZ());
725  manual->colour(1.0, 1.0, 1.0);
726  manual->index(i);
727  }
728 
729  manual->index(0);
730  manual->end();
731 
732  ogre->getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
733 
734  lOgrePolygons.push_back(manual);
735  }
736 }
737 
743 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::displayOgre(const vpHomogeneousMatrix &cMo)
744 {
745  if (ogreInitialised && !ogre->isWindowHidden()) {
746  for (unsigned int i = 0; i < Lpol.size(); i++) {
747  if (Lpol[i]->isVisible()) {
748  lOgrePolygons[i]->setVisible(true);
749  } else
750  lOgrePolygons[i]->setVisible(false);
751  }
752  ogre->display(ogreBackground, cMo);
753  }
754 }
755 
768 template <class PolygonType>
770  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo,
771  const double &angleAppears, const double &angleDisappears,
772  bool &changed)
773 {
774  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, true, true, I, cam);
775 }
776 
788 template <class PolygonType>
789 unsigned int vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpHomogeneousMatrix &cMo, const double &angleAppears,
790  const double &angleDisappears, bool &changed)
791 {
792  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, true);
793 }
794 
803 template <class PolygonType>
804 bool vpMbHiddenFaces<PolygonType>::isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
805 {
806  Ogre::Vector3 camera((Ogre::Real)cameraPos[0], (Ogre::Real)cameraPos[1], (Ogre::Real)cameraPos[2]);
807  if (!ogre->getCamera()->isVisible(lOgrePolygons[index]->getBoundingBox())) {
808  lOgrePolygons[index]->setVisible(false);
809  Lpol[index]->isvisible = false;
810  return false;
811  }
812 
813  // Get the center of gravity
814  bool visible = false;
815  unsigned int nbVisible = 0;
816 
817  for (unsigned int i = 0; i < nbRayAttempts; i++) {
818  Ogre::Vector3 origin(0, 0, 0);
819  Ogre::Real totalFactor = 0.0f;
820 
821  for (unsigned int j = 0; j < Lpol[index]->getNbPoint(); j++) {
822  Ogre::Real factor = 1.0f;
823 
824  if (nbRayAttempts > 1) {
825  int r = rand() % 101;
826 
827  if (r != 0)
828  factor = ((Ogre::Real)r) / 100.0f;
829  }
830 
831  Ogre::Vector3 tmp((Ogre::Real)Lpol[index]->getPoint(j).get_oX(), (Ogre::Real)Lpol[index]->getPoint(j).get_oY(),
832  (Ogre::Real)Lpol[index]->getPoint(j).get_oZ());
833  tmp *= factor;
834  origin += tmp;
835  totalFactor += factor;
836  }
837 
838  origin /= totalFactor;
839 
840  Ogre::Vector3 direction = origin - camera;
841  Ogre::Real distanceCollision = direction.length();
842 
843  direction.normalise();
844  Ogre::RaySceneQuery *mRaySceneQuery = ogre->getSceneManager()->createRayQuery(Ogre::Ray(camera, direction));
845  mRaySceneQuery->setSortByDistance(true);
846 
847  Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
848  Ogre::RaySceneQueryResult::iterator it = result.begin();
849 
850  // while(it != result.end()){
851  // std::cout << it->movable->getName() << "(" << it->distance<< ") :
852  // " << std::flush; it++;
853  // }
854  // std::cout << std::endl;
855  // it = result.begin();
856 
857  if (it != result.end())
858  if (it->movable->getName().find("SimpleRenderable") !=
859  Ogre::String::npos) // Test if the ogreBackground is intersect in
860  // first
861  ++it;
862 
863  double distance;
864  // In a case of a two-axis aligned segment, ray collision is not always
865  // working.
866  if (Lpol[index]->getNbPoint() == 2 &&
867  (((std::fabs(Lpol[index]->getPoint(0).get_oX() - Lpol[index]->getPoint(1).get_oX()) <
868  std::numeric_limits<double>::epsilon()) +
869  (std::fabs(Lpol[index]->getPoint(0).get_oY() - Lpol[index]->getPoint(1).get_oY()) <
870  std::numeric_limits<double>::epsilon()) +
871  (std::fabs(Lpol[index]->getPoint(0).get_oZ() - Lpol[index]->getPoint(1).get_oZ()) <
872  std::numeric_limits<double>::epsilon())) >= 2)) {
873  if (it != result.end()) {
874  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
875  nbVisible++;
876  } else {
877  distance = it->distance;
878  // Cannot use epsilon for comparison as ray lenght is slightly
879  // different from the collision distance returned by
880  // Ogre::RaySceneQueryResult.
881  if (distance > distanceCollision || std::fabs(distance - distanceCollision) <
882  1e-6 /*std::fabs(distance) * std::numeric_limits<double>::epsilon()*/)
883  nbVisible++;
884  }
885  } else
886  nbVisible++; // Collision not detected but present.
887  } else {
888  if (it != result.end()) {
889  distance = it->distance;
890  double distancePrev = distance;
891 
892  // std::cout << "For " << Ogre::StringConverter::toString(index) << ":
893  // " << it->movable->getName() << " / " << std::flush;
894 
895  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
896  nbVisible++;
897  } else {
898  ++it;
899  while (it != result.end()) {
900  distance = it->distance;
901 
902  if (std::fabs(distance - distancePrev) <
903  1e-6 /*std::fabs(distance) * std::numeric_limits<double>::epsilon()*/) {
904  // std::cout << it->movable->getName() << " / " << std::flush;
905  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
906  nbVisible++;
907  break;
908  }
909  ++it;
910  distancePrev = distance;
911  } else
912  break;
913  }
914  }
915  }
916  }
917 
918  ogre->getSceneManager()->destroyQuery(mRaySceneQuery);
919  }
920 
921  if (((double)nbVisible) / ((double)nbRayAttempts) > ratioVisibleRay ||
922  std::fabs(((double)nbVisible) / ((double)nbRayAttempts) - ratioVisibleRay) <
923  ratioVisibleRay * std::numeric_limits<double>::epsilon())
924  visible = true;
925  else
926  visible = false;
927 
928  if (visible) {
929  lOgrePolygons[index]->setVisible(true);
930  Lpol[index]->isvisible = true;
931  } else {
932  lOgrePolygons[index]->setVisible(false);
933  Lpol[index]->isvisible = false;
934  }
935 
936  return Lpol[index]->isvisible;
937 }
938 #endif // VISP_HAVE_OGRE
939 
940 #endif // vpMbHiddenFaces
vpMbHiddenFaces & operator=(vpMbHiddenFaces other)
const PolygonType * operator[](const unsigned int i) const
operator[] as reader.
bool isAppearing(const unsigned int i)
virtual ~vpMbHiddenFaces()
Implementation of the polygons management for the model-based trackers.
Ogre::Camera * getCamera()
Definition: vpAROgre.h:143
Implementation of an homogeneous matrix and operations on such kind of matrices.
unsigned int getNbVisiblePolygon() const
void setShowConfigDialog(const bool showConfigDialog)
Definition: vpAROgre.h:258
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
PolygonType * operator[](const unsigned int i)
operator[] as modifier.
void setOgreShowConfigDialog(const bool showConfigDialog)
vpMbScanLine & getMbScanLineRenderer()
Implementation of an augmented reality viewer using Ogre3D 3rd party.
Definition: vpAROgre.h:90
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:584
unsigned int setVisibleOgre(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
Ogre::SceneManager * getSceneManager()
Definition: vpAROgre.h:163
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:618
void setGoodNbRayCastingAttemptsRatio(const double &ratio)
Class that defines what is a point.
Definition: vpPoint.h:58
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
unsigned int setVisible(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
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:115
double getGoodNbRayCastingAttemptsRatio()
friend void swap(vpMbHiddenFaces &first, vpMbHiddenFaces &second)
#define vpTRACE
Definition: vpDebug.h:416
void setCameraParameters(const vpCameraParameters &cameraP)
Definition: vpAROgre.cpp:652
void setNbRayCastingAttemptsForVisibility(const unsigned int &attempts)
Generic class defining intrinsic camera parameters.
std::vector< PolygonType * > & getPolygon()
void extract(vpRotationMatrix &R) const
void addPolygon(PolygonType *p)
unsigned int size() const
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
vpHomogeneousMatrix inverse() const
bool isWindowHidden()
Definition: vpAROgre.h:173
bool isVisible(const unsigned int i)
unsigned int getNbRayCastingAttemptsForVisibility()
void displayOgre(const vpHomogeneousMatrix &cMo)
void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h)
Class that consider the case of a translation vector.
bool computeVisibility(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed, bool useOgre, bool not_used, const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpTranslationVector &cameraPos, unsigned int index)