35#ifndef VP_MB_HIDDEN_FACES_H
36#define VP_MB_HIDDEN_FACES_H
38#include <visp3/core/vpConfig.h>
39#include <visp3/core/vpDebug.h>
40#include <visp3/core/vpHomogeneousMatrix.h>
41#include <visp3/core/vpMeterPixelConversion.h>
42#include <visp3/core/vpPixelMeterConversion.h>
43#include <visp3/mbt/vpMbScanLine.h>
44#include <visp3/mbt/vpMbtPolygon.h>
47#include <visp3/ar/vpAROgre.h>
85 std::vector<PolygonType *> Lpol;
87 unsigned int nbVisiblePolygon;
88 vpMbScanLine scanlineRender;
93 unsigned int nbRayAttempts;
94 double ratioVisibleRay;
96 std::vector<Ogre::ManualObject *> lOgrePolygons;
97 bool ogreShowConfigDialog;
101 const double &angleDisappears,
bool &changed,
bool useOgre =
false,
102 bool not_used =
false,
unsigned int width = 0,
unsigned int height = 0,
115 bool &changed,
bool useOgre,
bool not_used,
unsigned int width,
unsigned int height,
123 const bool &displayResults =
false);
180 bool isAppearing(
unsigned int i) {
return Lpol[i]->isAppearing(); }
198 bool isVisible(
unsigned int i) {
return Lpol[i]->isVisible(); }
205 inline PolygonType *
operator[](
unsigned int i) {
return Lpol[i]; }
207 inline const PolygonType *
operator[](
unsigned int i)
const {
return Lpol[i]; }
249 ratioVisibleRay = ratio;
250 if (ratioVisibleRay > 1.0)
251 ratioVisibleRay = 1.0;
252 if (ratioVisibleRay < 0.0)
253 ratioVisibleRay = 0.0;
288 inline unsigned int size()
const {
return static_cast<unsigned int>(Lpol.size()); }
294template <
class PolygonType>
298 ogreInitialised =
false;
300 ratioVisibleRay = 1.0;
301 ogreShowConfigDialog =
false;
312 for (
unsigned int i = 0; i < Lpol.size(); i++) {
313 if (Lpol[i] !=
nullptr) {
321 if (ogre !=
nullptr) {
334 lOgrePolygons.resize(0);
341template <
class PolygonType>
343 : Lpol(), nbVisiblePolygon(copy.nbVisiblePolygon), scanlineRender(copy.scanlineRender)
346 ogreBackground(copy.ogreBackground), ogreInitialised(copy.ogreInitialised), nbRayAttempts(copy.nbRayAttempts),
347 ratioVisibleRay(copy.ratioVisibleRay), ogre(nullptr), lOgrePolygons(), ogreShowConfigDialog(copy.ogreShowConfigDialog)
351 for (
unsigned int i = 0; i < copy.Lpol.size(); i++) {
352 PolygonType *poly =
new PolygonType(*copy.Lpol[i]);
353 Lpol.push_back(poly);
360 swap(first.Lpol, second.Lpol);
361 swap(first.nbVisiblePolygon, second.nbVisiblePolygon);
362 swap(first.scanlineRender, second.scanlineRender);
364 swap(first.ogreInitialised, second.ogreInitialised);
365 swap(first.nbRayAttempts, second.nbRayAttempts);
366 swap(first.ratioVisibleRay, second.ratioVisibleRay);
367 swap(first.ogreShowConfigDialog, second.ogreShowConfigDialog);
368 swap(first.ogre, second.ogre);
369 swap(first.ogreBackground, second.ogreBackground);
376template <
class PolygonType>
391 PolygonType *p_new =
new PolygonType;
392 p_new->index = p->index;
393 p_new->setNbPoint(p->nbpt);
394 p_new->isvisible = p->isvisible;
395 p_new->useLod = p->useLod;
396 p_new->minLineLengthThresh = p->minLineLengthThresh;
397 p_new->minPolygonAreaThresh = p->minPolygonAreaThresh;
398 p_new->setName(p->name);
399 p_new->hasOrientation = p->hasOrientation;
401 for (
unsigned int i = 0; i < p->nbpt; i++)
402 p_new->p[i] = p->p[i];
403 Lpol.push_back(p_new);
411 nbVisiblePolygon = 0;
412 for (
unsigned int i = 0; i < Lpol.size(); i++) {
413 if (Lpol[i] !=
nullptr) {
421 if (ogre !=
nullptr) {
434 lOgrePolygons.resize(0);
436 ogreInitialised =
false;
438 ratioVisibleRay = 1.0;
451template <
class PolygonType>
454 for (
unsigned int i = 0; i < Lpol.size(); i++) {
460 Lpol[i]->changeFrame(cMo);
461 Lpol[i]->computePolygonClipped(cam);
474template <
class PolygonType>
476 const unsigned int &h)
478 std::vector<std::vector<std::pair<vpPoint, unsigned int> > > polyClipped(Lpol.size());
479 std::vector<std::vector<std::pair<vpPoint, unsigned int> > *> listPolyClipped;
480 std::vector<int> listPolyIndices;
482 for (
unsigned int i = 0; i < Lpol.size(); i++) {
488 polyClipped[i].clear();
489 Lpol[i]->getPolygonClipped(polyClipped[i]);
490 if (polyClipped[i].
size() != 0) {
491 listPolyClipped.push_back(&polyClipped[i]);
492 listPolyIndices.push_back(Lpol[i]->getIndex());
497 scanlineRender.drawScene(listPolyClipped, listPolyIndices, cam, w, h);
510template <
class PolygonType>
512 std::vector<std::pair<vpPoint, vpPoint> > &lines,
513 const bool &displayResults)
515 scanlineRender.queryLineVisibility(a, b, lines, displayResults);
533template <
class PolygonType>
534unsigned int vpMbHiddenFaces<PolygonType>::setVisiblePrivate(
const vpHomogeneousMatrix &cMo,
const double &angleAppears,
535 const double &angleDisappears,
bool &changed,
bool useOgre,
536 bool not_used,
unsigned int width,
unsigned int height,
539 nbVisiblePolygon = 0;
546 cMo.inverse().extract(cameraPos);
549 vpTRACE(
"ViSP doesn't have Ogre3D, simple visibility test used");
553 for (
unsigned int i = 0;
i < Lpol.size();
i++) {
555 if (computeVisibility(cMo, angleAppears, angleDisappears, changed, useOgre, not_used, width, height, cam, cameraPos,
559 return nbVisiblePolygon;
579template <
class PolygonType>
581 const double &angleDisappears,
bool &changed,
bool useOgre,
582 bool not_used,
unsigned int width,
unsigned int height,
587 unsigned int i = index;
588 Lpol[i]->changeFrame(cMo);
589 Lpol[i]->isappearing =
false;
600 bool testDisappear =
false;
603 if (!testDisappear) {
607 ((!Lpol[i]->isVisible(cMo, angleDisappears,
true, cam, width, height)) || !
isVisibleOgre(cameraPos, i));
611 testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears,
false, cam, width, height));
615 testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears,
false, cam, width, height));
623 Lpol[i]->isvisible =
false;
627 Lpol[i]->isvisible =
true;
634 bool testAppear =
true;
640 ((Lpol[i]->isVisible(cMo, angleAppears,
true, cam, width, height)) &&
isVisibleOgre(cameraPos, i));
642 testAppear = (Lpol[i]->isVisible(cMo, angleAppears,
false, cam, width, height));
645 testAppear = (Lpol[i]->isVisible(cMo, angleAppears,
false, cam, width, height));
650 Lpol[i]->isvisible =
true;
656 Lpol[i]->isvisible =
false;
662 return Lpol[i]->isvisible;
677template <
class PolygonType>
680 const double &angle,
bool &changed)
682 return setVisible(width, height, cam, cMo, angle, angle, changed);
698template <
class PolygonType>
701 const double &angleAppears,
const double &angleDisappears,
704 return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed,
false,
true, width, height, cam);
717template <
class PolygonType>
719 const double &angleDisappears,
bool &changed)
721 return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed,
false);
732 ogreInitialised =
true;
733 ogre->setCameraParameters(cam);
734 ogre->setShowConfigDialog(ogreShowConfigDialog);
735 ogre->init(ogreBackground,
false,
true);
737 for (
unsigned int n = 0; n < Lpol.size(); n++) {
738 Ogre::ManualObject *manual = ogre->getSceneManager()->createManualObject(Ogre::StringConverter::toString(n));
740 manual->begin(
"BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
741 for (
unsigned int i = 0; i < Lpol[n]->nbpt; i++) {
742 manual->position((Ogre::Real)Lpol[n]->p[i].get_oX(), (Ogre::Real)Lpol[n]->p[i].get_oY(),
743 (Ogre::Real)Lpol[n]->p[i].get_oZ());
744 manual->colour(1.0, 1.0, 1.0);
751 ogre->getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
753 lOgrePolygons.push_back(manual);
764 if (ogreInitialised && !ogre->isWindowHidden()) {
765 for (
unsigned int i = 0; i < Lpol.size(); i++) {
767 lOgrePolygons[i]->setVisible(
true);
770 lOgrePolygons[i]->setVisible(
false);
772 ogre->display(ogreBackground, cMo);
789template <
class PolygonType>
792 const double &angleAppears,
const double &angleDisappears,
795 return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed,
true,
true, width, height, cam);
808template <
class PolygonType>
810 const double &angleDisappears,
bool &changed)
812 return setVisiblePrivate(cMo, angleAppears, angleDisappears, changed,
true);
823template <
class PolygonType>
826 Ogre::Vector3 camera((Ogre::Real)cameraPos[0], (Ogre::Real)cameraPos[1], (Ogre::Real)cameraPos[2]);
827 if (!ogre->getCamera()->isVisible(lOgrePolygons[index]->getBoundingBox())) {
828 lOgrePolygons[index]->setVisible(
false);
829 Lpol[index]->isvisible =
false;
834 bool visible =
false;
835 unsigned int nbVisible = 0;
837 for (
unsigned int i = 0; i < nbRayAttempts; i++) {
838 Ogre::Vector3 origin(0, 0, 0);
839 Ogre::Real totalFactor = 0.0f;
841 for (
unsigned int j = 0; j < Lpol[index]->getNbPoint(); j++) {
842 Ogre::Real factor = 1.0f;
844 if (nbRayAttempts > 1) {
845 int r = rand() % 101;
848 factor = ((Ogre::Real)r) / 100.0f;
851 Ogre::Vector3 tmp((Ogre::Real)Lpol[index]->getPoint(j).get_oX(), (Ogre::Real)Lpol[index]->getPoint(j).get_oY(),
852 (Ogre::Real)Lpol[index]->getPoint(j).get_oZ());
855 totalFactor += factor;
858 origin /= totalFactor;
860 Ogre::Vector3 direction = origin - camera;
861 Ogre::Real distanceCollision = direction.length();
863 direction.normalise();
864 Ogre::RaySceneQuery *mRaySceneQuery = ogre->getSceneManager()->createRayQuery(Ogre::Ray(camera, direction));
865 mRaySceneQuery->setSortByDistance(
true);
867 Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
868 Ogre::RaySceneQueryResult::iterator it = result.begin();
877 if (it != result.end())
878 if (it->movable->getName().find(
"SimpleRenderable") != Ogre::String::npos)
885 if (Lpol[index]->getNbPoint() == 2 &&
886 (((std::fabs(Lpol[index]->getPoint(0).get_oX() - Lpol[index]->getPoint(1).get_oX()) <
887 std::numeric_limits<double>::epsilon()) +
888 (std::fabs(Lpol[index]->getPoint(0).get_oY() - Lpol[index]->getPoint(1).get_oY()) <
889 std::numeric_limits<double>::epsilon()) +
890 (std::fabs(Lpol[index]->getPoint(0).get_oZ() - Lpol[index]->getPoint(1).get_oZ()) <
891 std::numeric_limits<double>::epsilon())) >= 2)) {
892 if (it != result.end()) {
893 if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
897 distance = it->distance;
901 if (distance > distanceCollision || std::fabs(distance - distanceCollision) <
910 if (it != result.end()) {
911 distance = it->distance;
912 double distancePrev = distance;
917 if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
922 while (it != result.end()) {
923 distance = it->distance;
925 if (std::fabs(distance - distancePrev) <
928 if (it->movable->getName() == Ogre::StringConverter::toString(index)) {
933 distancePrev = distance;
942 ogre->getSceneManager()->destroyQuery(mRaySceneQuery);
945 if ((
static_cast<double>(nbVisible)) / (
static_cast<double>(nbRayAttempts)) > ratioVisibleRay ||
946 std::fabs((
static_cast<double>(nbVisible)) / (
static_cast<double>(nbRayAttempts)) - ratioVisibleRay) <
947 ratioVisibleRay * std::numeric_limits<double>::epsilon())
953 lOgrePolygons[index]->setVisible(
true);
954 Lpol[index]->isvisible =
true;
957 lOgrePolygons[index]->setVisible(
false);
958 Lpol[index]->isvisible =
false;
961 return Lpol[index]->isvisible;
Implementation of an augmented reality viewer using Ogre3D 3rd party.
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Generic class defining intrinsic camera parameters.
Implementation of an homogeneous matrix and operations on such kind of matrices.
Definition of the vpImage class member functions.
Implementation of the polygons management for the model-based trackers.
bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
void setNbRayCastingAttemptsForVisibility(const unsigned int &attempts)
PolygonType * operator[](unsigned int i)
Operator[] as modifier.
virtual ~vpMbHiddenFaces()
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
void setGoodNbRayCastingAttemptsRatio(const double &ratio)
bool isAppearing(unsigned int i)
vpMbHiddenFaces & operator=(vpMbHiddenFaces other)
unsigned int size() const
std::vector< PolygonType * > & getPolygon()
unsigned int setVisibleOgre(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
bool isVisible(unsigned int i)
void addPolygon(PolygonType *p)
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
unsigned int getNbVisiblePolygon() const
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
unsigned int setVisible(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
double getGoodNbRayCastingAttemptsRatio()
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
friend void swap(vpMbHiddenFaces &first, vpMbHiddenFaces &second)
void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h)
vpAROgre * getOgreContext()
const PolygonType * operator[](unsigned int i) const
Operator[] as reader.
unsigned int getNbRayCastingAttemptsForVisibility()
void displayOgre(const vpHomogeneousMatrix &cMo)
vpMbScanLine & getMbScanLineRenderer()
void setOgreShowConfigDialog(bool showConfigDialog)
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)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Class that consider the case of a translation vector.