Visual Servoing Platform  version 3.5.1 under development (2022-05-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, unsigned int width = 0, unsigned int height = 0,
92  const vpCameraParameters &cam = vpCameraParameters());
93 
94 public:
96  virtual ~vpMbHiddenFaces();
97  vpMbHiddenFaces(const vpMbHiddenFaces &copy);
99  friend void swap<PolygonType>(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, unsigned int width, unsigned int height,
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(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(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[](unsigned int i) { return Lpol[i]; }
196  inline const PolygonType *operator[](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(bool showConfigDialog) { ogreShowConfigDialog = showConfigDialog; }
255 #endif
256 
257  unsigned int setVisible(unsigned int width, unsigned int height, const vpCameraParameters &cam,
258  const vpHomogeneousMatrix &cMo, const double &angle, bool &changed);
259  unsigned int setVisible(unsigned int width, unsigned int height, 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(unsigned int width, unsigned int height, 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, unsigned int width, unsigned int height,
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, width, height, cam, cameraPos,
545  i))
546  nbVisiblePolygon++;
547  }
548  return nbVisiblePolygon;
549 }
550 
569 template <class PolygonType>
570 bool vpMbHiddenFaces<PolygonType>::computeVisibility(const vpHomogeneousMatrix &cMo, const double &angleAppears,
571  const double &angleDisappears, bool &changed, bool useOgre,
572  bool not_used, unsigned int width, unsigned int height,
573  const vpCameraParameters &cam,
574  const vpTranslationVector &cameraPos, unsigned int index)
575 {
576  (void)not_used;
577  unsigned int i = index;
578  Lpol[i]->changeFrame(cMo);
579  Lpol[i]->isappearing = false;
580 
581  // Commented because we need to compute visibility
582  // even when dealing with line in level of detail case
583  /*if(Lpol[i]->getNbPoint() <= 2)
584  {
585  Lpol[i]->isvisible = true;
586  }
587  else*/
588  {
589  if (Lpol[i]->isVisible()) {
590  bool testDisappear = false;
591  // unsigned int nbCornerInsidePrev = 0;
592 
593  if (!testDisappear) {
594  if (useOgre)
595 #ifdef VISP_HAVE_OGRE
596  testDisappear =
597  ((!Lpol[i]->isVisible(cMo, angleDisappears, true, cam, width, height)) || !isVisibleOgre(cameraPos, i));
598 #else
599  {
600  (void)cameraPos; // Avoid warning
601  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears, false, cam, width, height));
602  }
603 #endif
604  else
605  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears, false, cam, width, height));
606  }
607 
608  // test if the face is still visible
609  if (testDisappear) {
610  // std::cout << "Face " << i << " disappears" <<
611  // std::endl;
612  changed = true;
613  Lpol[i]->isvisible = false;
614  } else {
615  // nbVisiblePolygon++;
616  Lpol[i]->isvisible = true;
617 
618  // if(nbCornerInsidePrev > Lpol[i]->getNbCornerInsidePrevImage())
619  // changed = true;
620  }
621  } else {
622  bool testAppear = true;
623 
624  if (testAppear) {
625  if (useOgre)
626 #ifdef VISP_HAVE_OGRE
627  testAppear =
628  ((Lpol[i]->isVisible(cMo, angleAppears, true, cam, width, height)) && isVisibleOgre(cameraPos, i));
629 #else
630  testAppear = (Lpol[i]->isVisible(cMo, angleAppears, false, cam, width, height));
631 #endif
632  else
633  testAppear = (Lpol[i]->isVisible(cMo, angleAppears, false, cam, width, height));
634  }
635 
636  if (testAppear) {
637  // std::cout << "Face " << i << " appears" << std::endl;
638  Lpol[i]->isvisible = true;
639  changed = true;
640  // nbVisiblePolygon++;
641  } else {
642  // std::cout << "Problem" << std::endl;
643  Lpol[i]->isvisible = false;
644  }
645  }
646  }
647  // std::cout << "Nombre de polygones visibles: " << nbVisiblePolygon <<
648  // std::endl;
649  return Lpol[i]->isvisible;
650 }
651 
665 template <class PolygonType>
666 unsigned int vpMbHiddenFaces<PolygonType>::setVisible(unsigned int width, unsigned int height,
667  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo,
668  const double &angle, bool &changed)
669 {
670  return setVisible(width, height, cam, cMo, angle, angle, changed);
671 }
672 
687 template <class PolygonType>
688 unsigned int vpMbHiddenFaces<PolygonType>::setVisible(unsigned int width, unsigned int height,
689  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo,
690  const double &angleAppears, const double &angleDisappears,
691  bool &changed)
692 {
693  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, false, true, width, height, cam);
694 }
695 
707 template <class PolygonType>
708 unsigned int vpMbHiddenFaces<PolygonType>::setVisible(const vpHomogeneousMatrix &cMo, const double &angleAppears,
709  const double &angleDisappears, bool &changed)
710 {
711  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, false);
712 }
713 
714 #ifdef VISP_HAVE_OGRE
715 
720 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::initOgre(const vpCameraParameters &cam)
721 {
722  ogreInitialised = true;
723  ogre->setCameraParameters(cam);
724  ogre->setShowConfigDialog(ogreShowConfigDialog);
725  ogre->init(ogreBackground, false, true);
726 
727  for (unsigned int n = 0; n < Lpol.size(); n++) {
728  Ogre::ManualObject *manual = ogre->getSceneManager()->createManualObject(Ogre::StringConverter::toString(n));
729 
730  manual->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
731  for (unsigned int i = 0; i < Lpol[n]->nbpt; i++) {
732  manual->position((Ogre::Real)Lpol[n]->p[i].get_oX(), (Ogre::Real)Lpol[n]->p[i].get_oY(),
733  (Ogre::Real)Lpol[n]->p[i].get_oZ());
734  manual->colour(1.0, 1.0, 1.0);
735  manual->index(i);
736  }
737 
738  manual->index(0);
739  manual->end();
740 
741  ogre->getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
742 
743  lOgrePolygons.push_back(manual);
744  }
745 }
746 
752 template <class PolygonType> void vpMbHiddenFaces<PolygonType>::displayOgre(const vpHomogeneousMatrix &cMo)
753 {
754  if (ogreInitialised && !ogre->isWindowHidden()) {
755  for (unsigned int i = 0; i < Lpol.size(); i++) {
756  if (Lpol[i]->isVisible()) {
757  lOgrePolygons[i]->setVisible(true);
758  } else
759  lOgrePolygons[i]->setVisible(false);
760  }
761  ogre->display(ogreBackground, cMo);
762  }
763 }
764 
779 template <class PolygonType>
780 unsigned int vpMbHiddenFaces<PolygonType>::setVisibleOgre(unsigned int width, unsigned int height,
781  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo,
782  const double &angleAppears, const double &angleDisappears,
783  bool &changed)
784 {
785  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, true, true, width, height, cam);
786 }
787 
799 template <class PolygonType>
800 unsigned int vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpHomogeneousMatrix &cMo, const double &angleAppears,
801  const double &angleDisappears, bool &changed)
802 {
803  return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed, true);
804 }
805 
814 template <class PolygonType>
815 bool vpMbHiddenFaces<PolygonType>::isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
816 {
817  Ogre::Vector3 camera((Ogre::Real)cameraPos[0], (Ogre::Real)cameraPos[1], (Ogre::Real)cameraPos[2]);
818  if (!ogre->getCamera()->isVisible(lOgrePolygons[index]->getBoundingBox())) {
819  lOgrePolygons[index]->setVisible(false);
820  Lpol[index]->isvisible = false;
821  return false;
822  }
823 
824  // Get the center of gravity
825  bool visible = false;
826  unsigned int nbVisible = 0;
827 
828  for (unsigned int i = 0; i < nbRayAttempts; i++) {
829  Ogre::Vector3 origin(0, 0, 0);
830  Ogre::Real totalFactor = 0.0f;
831 
832  for (unsigned int j = 0; j < Lpol[index]->getNbPoint(); j++) {
833  Ogre::Real factor = 1.0f;
834 
835  if (nbRayAttempts > 1) {
836  int r = rand() % 101;
837 
838  if (r != 0)
839  factor = ((Ogre::Real)r) / 100.0f;
840  }
841 
842  Ogre::Vector3 tmp((Ogre::Real)Lpol[index]->getPoint(j).get_oX(), (Ogre::Real)Lpol[index]->getPoint(j).get_oY(),
843  (Ogre::Real)Lpol[index]->getPoint(j).get_oZ());
844  tmp *= factor;
845  origin += tmp;
846  totalFactor += factor;
847  }
848 
849  origin /= totalFactor;
850 
851  Ogre::Vector3 direction = origin - camera;
852  Ogre::Real distanceCollision = direction.length();
853 
854  direction.normalise();
855  Ogre::RaySceneQuery *mRaySceneQuery = ogre->getSceneManager()->createRayQuery(Ogre::Ray(camera, direction));
856  mRaySceneQuery->setSortByDistance(true);
857 
858  Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
859  Ogre::RaySceneQueryResult::iterator it = result.begin();
860 
861  // while(it != result.end()){
862  // std::cout << it->movable->getName() << "(" << it->distance<< ") :
863  // " << std::flush; it++;
864  // }
865  // std::cout << std::endl;
866  // it = result.begin();
867 
868  if (it != result.end())
869  if (it->movable->getName().find("SimpleRenderable") != Ogre::String::npos) // Test if the ogreBackground is
870  // intersect in first
871  ++it;
872 
873  double distance;
874  // In a case of a two-axis aligned segment, ray collision is not always
875  // working.
876  if (Lpol[index]->getNbPoint() == 2 &&
877  (((std::fabs(Lpol[index]->getPoint(0).get_oX() - Lpol[index]->getPoint(1).get_oX()) <
878  std::numeric_limits<double>::epsilon()) +
879  (std::fabs(Lpol[index]->getPoint(0).get_oY() - Lpol[index]->getPoint(1).get_oY()) <
880  std::numeric_limits<double>::epsilon()) +
881  (std::fabs(Lpol[index]->getPoint(0).get_oZ() - Lpol[index]->getPoint(1).get_oZ()) <
882  std::numeric_limits<double>::epsilon())) >= 2)) {
883  if (it != result.end()) {
884  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
885  nbVisible++;
886  } else {
887  distance = it->distance;
888  // Cannot use epsilon for comparison as ray lenght is slightly
889  // different from the collision distance returned by
890  // Ogre::RaySceneQueryResult.
891  if (distance > distanceCollision || std::fabs(distance - distanceCollision) <
892  1e-6 /*std::fabs(distance) * std::numeric_limits<double>::epsilon()*/)
893  nbVisible++;
894  }
895  } else
896  nbVisible++; // Collision not detected but present.
897  } else {
898  if (it != result.end()) {
899  distance = it->distance;
900  double distancePrev = distance;
901 
902  // std::cout << "For " << Ogre::StringConverter::toString(index) << ":
903  // " << it->movable->getName() << " / " << std::flush;
904 
905  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
906  nbVisible++;
907  } else {
908  ++it;
909  while (it != result.end()) {
910  distance = it->distance;
911 
912  if (std::fabs(distance - distancePrev) <
913  1e-6 /*std::fabs(distance) * std::numeric_limits<double>::epsilon()*/) {
914  // std::cout << it->movable->getName() << " / " << std::flush;
915  if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
916  nbVisible++;
917  break;
918  }
919  ++it;
920  distancePrev = distance;
921  } else
922  break;
923  }
924  }
925  }
926  }
927 
928  ogre->getSceneManager()->destroyQuery(mRaySceneQuery);
929  }
930 
931  if (((double)nbVisible) / ((double)nbRayAttempts) > ratioVisibleRay ||
932  std::fabs(((double)nbVisible) / ((double)nbRayAttempts) - ratioVisibleRay) <
933  ratioVisibleRay * std::numeric_limits<double>::epsilon())
934  visible = true;
935  else
936  visible = false;
937 
938  if (visible) {
939  lOgrePolygons[index]->setVisible(true);
940  Lpol[index]->isvisible = true;
941  } else {
942  lOgrePolygons[index]->setVisible(false);
943  Lpol[index]->isvisible = false;
944  }
945 
946  return Lpol[index]->isvisible;
947 }
948 #endif // VISP_HAVE_OGRE
949 
950 #endif // vpMbHiddenFaces
vpMbHiddenFaces & operator=(vpMbHiddenFaces other)
bool isVisible(unsigned int i)
unsigned int size() const
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.
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
vpMbScanLine & getMbScanLineRenderer()
vpHomogeneousMatrix inverse() const
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:588
void extract(vpRotationMatrix &R) const
Ogre::SceneManager * getSceneManager()
Definition: vpAROgre.h:163
unsigned int setVisibleOgre(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:622
void setGoodNbRayCastingAttemptsRatio(const double &ratio)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:81
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
bool computeVisibility(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed, bool useOgre, bool not_used, unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpTranslationVector &cameraPos, unsigned int index)
bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
vpAROgre * getOgreContext()
PolygonType * operator[](unsigned int i)
operator[] as modifier.
unsigned int getNbVisiblePolygon() const
bool isAppearing(unsigned int i)
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:656
void setNbRayCastingAttemptsForVisibility(const unsigned int &attempts)
Generic class defining intrinsic camera parameters.
void setOgreShowConfigDialog(bool showConfigDialog)
std::vector< PolygonType * > & getPolygon()
void setShowConfigDialog(bool showConfigDialog)
Definition: vpAROgre.h:258
void addPolygon(PolygonType *p)
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
const PolygonType * operator[](unsigned int i) const
operator[] as reader.
bool isWindowHidden()
Definition: vpAROgre.h:173
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.
unsigned int setVisible(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)