Hi,
Dirk was unhappy with us not having functions to test containment of
volumes. Here is a first cut at adding those, but it only implements the
low hanging fruit (i.e. the easy tests ;) ) -- see attached patch.
Apart from the interface the point most worthwhile discussing is
probably the handling of the extreme cases like empty or infinite volumes.
From OSGVolume.cpp:
/*! \fn bool Volume::contain(const Volume &volume) const
Returns whether \volume is contained in this volume.
Special cases are handled as follows:
Infinite volumes contain everything, while empty volumes contain
nothing.
Infinite volumes are only contained in infinite volumes and empty
volumes
are contained in everything (except empty volumes).
\warning Most of these tests are not implemented!
*/
Feedback on this or any other part of the patch is very welcome,
Thanks,
Carsten
Index: Source/Base/Base/OSGDynamicVolume.cpp
===================================================================
--- Source/Base/Base/OSGDynamicVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGDynamicVolume.cpp (working copy)
@@ -226,6 +226,21 @@
return getInstance().isOnSurface(point);
}
+bool DynamicVolume::contain(const Pnt3r &point) const
+{
+ return getInstance().contain(point);
+}
+
+bool DynamicVolume::contain(const Volume &volume) const
+{
+ return OSG::contain(getInstance(), volume);
+}
+
+bool DynamicVolume::contain(const DynamicVolume &volume) const
+{
+ return OSG::contain(getInstance(), volume);
+}
+
/*! transform the volume bye the given matrix */
void DynamicVolume::transform(const Matrixr &matrix)
Index: Source/Base/Base/OSGSphereVolume.cpp
===================================================================
--- Source/Base/Base/OSGSphereVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGSphereVolume.cpp (working copy)
@@ -164,7 +164,21 @@
return false;
}
+bool SphereVolume::contain(const Pnt3r &point) const
+{
+ return intersect(point);
+}
+bool SphereVolume::contain(const Volume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
+bool SphereVolume::contain(const SphereVolume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
/*-------------------------- transformation -------------------------------*/
void SphereVolume::transform(const Matrixr &mat)
Index: Source/Base/Base/OSGFrustumVolume.cpp
===================================================================
--- Source/Base/Base/OSGFrustumVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGFrustumVolume.cpp (working copy)
@@ -341,6 +341,21 @@
return false;
}
+bool FrustumVolume::contain(const Pnt3r &point) const
+{
+ return intersect(point);
+}
+
+bool FrustumVolume::contain(const Volume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
+bool FrustumVolume::contain(const FrustumVolume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
void FrustumVolume::transform(const Matrixr &m)
{
_planeVec[0].transform(m);
Index: Source/Base/Base/OSGVolumeFunctions.h
===================================================================
--- Source/Base/Base/OSGVolumeFunctions.h (revision 1275)
+++ Source/Base/Base/OSGVolumeFunctions.h (working copy)
@@ -267,6 +267,82 @@
bool intersect(const Volume &srcVol, const FrustumVolume &vol);
// ###################################################################
+// # Volume Contain Functions ########################################
+// ###################################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const Volume &outerVol, const Volume &innerVol);
+
+// # Box #############################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const BoxVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const SphereVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const CylinderVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const FrustumVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const Volume &innerVol);
+
+// # Sphere ##########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const BoxVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const SphereVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const CylinderVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const FrustumVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const Volume &innerVol);
+
+// # Cylinder ########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const BoxVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const SphereVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const CylinderVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const FrustumVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const Volume &innerVol);
+
+// # Frustum #########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const BoxVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const SphereVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const CylinderVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const FrustumVolume &innerVol);
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const Volume &innerVol);
+
+
+// ###################################################################
// # Volume Extend Functions #########################################
// ###################################################################
Index: Source/Base/Base/OSGFrustumVolume.h
===================================================================
--- Source/Base/Base/OSGFrustumVolume.h (revision 1275)
+++ Source/Base/Base/OSGFrustumVolume.h (working copy)
@@ -148,6 +148,15 @@
/*! \} */
/*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const FrustumVolume &volume) const;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
/*! \name Transformation */
/*! \{ */
Index: Source/Base/Base/OSGPolytopeVolume.h
===================================================================
--- Source/Base/Base/OSGPolytopeVolume.h (revision 1275)
+++ Source/Base/Base/OSGPolytopeVolume.h (working copy)
@@ -118,7 +118,15 @@
bool intersect (const PolytopeVolume &bb ) const;
virtual bool isOnSurface (const Pnt3f &point ) const;
+ /*! \} */
+ /*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const PolytopeVolume &volume) const;
+
/*! \} */
/*---------------------------------------------------------------------*/
/*! \name Transformation */
Index: Source/Base/Base/OSGBoxVolume.h
===================================================================
--- Source/Base/Base/OSGBoxVolume.h (revision 1275)
+++ Source/Base/Base/OSGBoxVolume.h (working copy)
@@ -159,6 +159,15 @@
/*! \} */
/*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const BoxVolume &volume) const;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
/*! \name Transform */
/*! \{ */
Index: Source/Base/Base/OSGVolume.h
===================================================================
--- Source/Base/Base/OSGVolume.h (revision 1275)
+++ Source/Base/Base/OSGVolume.h (working copy)
@@ -121,7 +121,15 @@
virtual bool intersect (const Volume &volume) const = 0;
virtual bool isOnSurface(const Pnt3r &point ) const = 0;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+ virtual bool contain(const Pnt3r &point ) const = 0;
+ virtual bool contain(const Volume &volume) const = 0;
+
/*! \} */
/*---------------------------------------------------------------------*/
/*! \name Transformation */
Index: Source/Base/Base/OSGDynamicVolume.h
===================================================================
--- Source/Base/Base/OSGDynamicVolume.h (revision 1275)
+++ Source/Base/Base/OSGDynamicVolume.h (working copy)
@@ -121,6 +121,15 @@
/*! \} */
/*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const DynamicVolume &volume) const;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
/*! \name Transform */
/*! \{ */
Index: Source/Base/Base/OSGPolytopeVolume.cpp
===================================================================
--- Source/Base/Base/OSGPolytopeVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGPolytopeVolume.cpp (working copy)
@@ -160,7 +160,26 @@
return false;
}
+bool PolytopeVolume::contain(const Pnt3r &point) const
+{
+ return intersect(point);
+}
+bool PolytopeVolume::contain(const Volume &volume) const
+{
+ FFATAL(("PolytopeVolume::contain(Volume) not implemented.\n"));
+
+ return false;
+}
+
+bool PolytopeVolume::contain(const PolytopeVolume &volume) const
+{
+ FFATAL(("PolytopeVolume::contain(PolytopeVolume) not implemented.\n"));
+
+ return false;
+}
+
+
/// Transforms Frustum3f by matrix, enlarging Frustum3f to contain result
void PolytopeVolume::transform(const Matrix &OSG_CHECK_ARG(m))
{
Index: Source/Base/Base/OSGVolumeFunctions.cpp
===================================================================
--- Source/Base/Base/OSGVolumeFunctions.cpp (revision 1275)
+++ Source/Base/Base/OSGVolumeFunctions.cpp (working copy)
@@ -78,7 +78,7 @@
}
else
{
- FWARNING(("intersect(Volume, Volume): Argument 1 has unhandled type.\n"));
+ FFATAL(("intersect(Volume, Volume): Argument 1 has unhandled type.\n"));
}
return retCode;
@@ -306,7 +306,7 @@
}
else
{
- FWARNING(("intersect(BoxVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("intersect(BoxVolume, Volume): Argument 2 has unhandled type.\n"));
}
return retCode;
@@ -459,7 +459,7 @@
}
else
{
- FWARNING(("intersect(SphereVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("intersect(SphereVolume, Volume): Argument 2 has unhandled type.\n"));
}
return retCode;
@@ -651,7 +651,7 @@
}
else
{
- FWARNING(("intersect(CylinderVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("intersect(CylinderVolume, Volume): Argument 2 has unhandled type.\n"));
}
@@ -699,13 +699,538 @@
}
else
{
- FWARNING(("intersect(FrustumVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("intersect(FrustumVolume, Volume): Argument 2 has unhandled type.\n"));
}
return retCode;
}
+// ###################################################################
+// # Volume Contain Functions ########################################
+// ###################################################################
+OSG_BASE_DLLMAPPING
+bool contain(const Volume &outerVol, const Volume &innerVol)
+{
+ bool retCode = false;
+
+ const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&outerVol);
+ const Volume *v = dv ? &(dv->getInstance()) : &outerVol;
+ const BoxVolume *bv;
+ const SphereVolume *sv;
+ const CylinderVolume *cv;
+ const FrustumVolume *fv;
+
+ if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
+ {
+ retCode = contain(*bv, innerVol);
+ }
+ else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
+ {
+ retCode = contain(*sv, innerVol);
+ }
+ else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
+ {
+ retCode = contain(*cv, innerVol);
+ }
+ else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
+ {
+ retCode = contain(*fv, innerVol);
+ }
+ else
+ {
+ FFATAL(("contain(Volume, Volume): Argument 1 has unhandled type.\n"));
+ }
+
+ return retCode;
+}
+
+// # Box #############################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const BoxVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The outer box contains the inner box iff the inner min is
+ // (componentwise) greater or equal than the outer min and
+ // the inner max is (componentwise) less or equal than the outer max.
+
+ if((outerVol.getMin()[0] <= innerVol.getMin()[0] &&
+ outerVol.getMax()[0] >= innerVol.getMax()[0] ) &&
+ (outerVol.getMin()[1] <= innerVol.getMin()[1] &&
+ outerVol.getMax()[1] >= innerVol.getMax()[1] ) &&
+ (outerVol.getMin()[2] <= innerVol.getMin()[2] &&
+ outerVol.getMax()[2] >= innerVol.getMax()[2] ) )
+ {
+ retCode = true;
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const SphereVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The box contains the sphere iff the center is inside the box and the
+ // distance to the closest face is greater or equal to the radius.
+
+ const Pnt3r &bMin = outerVol.getMin ();
+ const Pnt3r &bMax = outerVol.getMax ();
+ const Pnt3r &sC = innerVol.getCenter();
+ Real dist = TypeTraits<Real>::getMax();
+ Real distMin;
+ Real distMax;
+
+ // for each component (axis) find distance to faces of the box
+ // if the center is outside the box for one component dist will become
+ // negative.
+
+ distMin = sC [0] - bMin[0];
+ distMax = bMax[0] - sC [0];
+ dist = osgMin(dist, osgMin(distMin, distMax));
+
+ distMin = sC [1] - bMin[1];
+ distMax = bMax[1] - sC [1];
+ dist = osgMin(dist, osgMin(distMin, distMax));
+
+ distMin = sC [2] - bMin[2];
+ distMax = bMax[2] - sC [2];
+ dist = osgMin(dist, osgMin(distMin, distMax));
+
+ if(dist >= TypeTraits<Real>::getZeroElement())
+ {
+ // if dist is non-negative the center is inside the box, hence
+ // compare dist and radius
+
+ retCode = (dist >= innerVol.getRadius());
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const CylinderVolume &innerVol)
+{
+ FFATAL(("contain(BoxVolume, CylinderVolume not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const FrustumVolume &innerVol)
+{
+ FFATAL(("contain(BoxVolume, FrustumVolume not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const BoxVolume &outerVol, const Volume &innerVol)
+{
+ bool retCode = false;
+
+ const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&innerVol);
+ const Volume *v = dv ? &(dv->getInstance()) : &innerVol;
+ const BoxVolume *bv;
+ const SphereVolume *sv;
+ const CylinderVolume *cv;
+ const FrustumVolume *fv;
+
+ if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *bv);
+ }
+ else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *sv);
+ }
+ else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *cv);
+ }
+ else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *fv);
+ }
+ else
+ {
+ FFATAL(("contain(BoxVolume, Volume): Argument 2 has unhandled type.\n"));
+ }
+
+ return retCode;
+}
+
+// # Sphere ##########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const BoxVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The sphere contains the box iff the distance from the center of
+ // the sphere to the farthest corner is less or equal to the radius.
+
+ const Pnt3r &sC = outerVol.getCenter();
+ const Pnt3r &bMin = innerVol.getMin ();
+ const Pnt3r &bMax = innerVol.getMax ();
+
+ // vector from center to farthest corner of box
+ Vec3r cfar(osgMax(osgAbs(sC[0] - bMin[0]), osgAbs(sC[0] - bMax[0])),
+ osgMax(osgAbs(sC[1] - bMin[1]), osgAbs(sC[1] - bMax[1])),
+ osgMax(osgAbs(sC[2] - bMin[2]), osgAbs(sC[2] - bMax[2])) );
+
+ if(cfar.squareLength() <= (outerVol.getRadius() * outerVol.getRadius()))
+ {
+ retCode = true;
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const SphereVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The outer sphere contains the inner sphere iff the distance of the
+ // centers plus the inner sphere's radius is less or equal to the outer
+ // sphere's radius.
+
+ // distance of the centers
+ Real cdist = (outerVol.getCenter() - innerVol.getCenter()).length();
+
+ if(cdist + innerVol.getRadius() <= outerVol.getRadius())
+ {
+ retCode = true;
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const CylinderVolume &innerVol)
+{
+ FFATAL(("contain(SphereVolume, CylinderVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const FrustumVolume &innerVol)
+{
+ FFATAL(("contain(SphereVolume, FrustumVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const SphereVolume &outerVol, const Volume &innerVol)
+{
+ bool retCode = false;
+
+ const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&innerVol);
+ const Volume *v = dv ? &(dv->getInstance()) : &innerVol;
+ const BoxVolume *bv;
+ const SphereVolume *sv;
+ const CylinderVolume *cv;
+ const FrustumVolume *fv;
+
+ if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *bv);
+ }
+ else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *sv);
+ }
+ else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *cv);
+ }
+ else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *fv);
+ }
+ else
+ {
+ FFATAL(("contain(SphereVolume, Volume): Argument 2 has unhandled type.\n"));
+ }
+
+ return retCode;
+}
+
+// # Cylinder ########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const BoxVolume &innerVol)
+{
+ FFATAL(("contain(CylinderVolume, BoxVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const SphereVolume &innerVol)
+{
+ FFATAL(("contain(CylinderVolume, SphereVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const CylinderVolume &innerVol)
+{
+ FFATAL(("contain(CylinderVolume, CylinderVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const FrustumVolume &innerVol)
+{
+ FFATAL(("contain(CylinderVolume, FrustumVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const CylinderVolume &outerVol, const Volume &innerVol)
+{
+ bool retCode = false;
+
+ const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&innerVol);
+ const Volume *v = dv ? &(dv->getInstance()) : &innerVol;
+ const BoxVolume *bv;
+ const SphereVolume *sv;
+ const CylinderVolume *cv;
+ const FrustumVolume *fv;
+
+ if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *bv);
+ }
+ else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *sv);
+ }
+ else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *cv);
+ }
+ else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *fv);
+ }
+ else
+ {
+ FFATAL(("contain(CylinderVolume, Volume): Argument 2 has unhandled type.\n"));
+ }
+
+ return retCode;
+}
+
+// # Frustum #########################################################
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const BoxVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The frustum contains the box iff all eight corners are inside it.
+ // This is the case iff the corners are in all half spaces defined by
+ // the planes of the frustum.
+
+ const Plane *planes = outerVol.getPlanes();
+ const Pnt3r &bMin = innerVol.getMin ();
+ const Pnt3r &bMax = innerVol.getMax ();
+
+ if(planes[0].isInHalfSpace(bMin, bMax) &&
+ planes[1].isInHalfSpace(bMin, bMax) &&
+ planes[2].isInHalfSpace(bMin, bMax) &&
+ planes[3].isInHalfSpace(bMin, bMax) &&
+ planes[4].isInHalfSpace(bMin, bMax) &&
+ planes[5].isInHalfSpace(bMin, bMax) )
+ {
+ retCode = true;
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const SphereVolume &innerVol)
+{
+ bool retCode = false;
+
+ if(outerVol.isEmpty() == true)
+ {
+ retCode = false;
+ }
+ else if(outerVol.isInfinite() == true || innerVol.isEmpty() == true)
+ {
+ retCode = true;
+ }
+ else if(innerVol.isInfinite())
+ {
+ // outer volume is finite here, so it can not contain innerVol
+ retCode = false;
+ }
+ else
+ {
+ // The frustum contains the sphere iff the distance of the center to
+ // each of the six planes is greater or equal to the sphere's radius.
+
+ const Plane *planes = outerVol.getPlanes();
+
+ if(planes[0].distance(innerVol.getCenter()) >= innerVol.getRadius() &&
+ planes[1].distance(innerVol.getCenter()) >= innerVol.getRadius() &&
+ planes[2].distance(innerVol.getCenter()) >= innerVol.getRadius() &&
+ planes[3].distance(innerVol.getCenter()) >= innerVol.getRadius() &&
+ planes[4].distance(innerVol.getCenter()) >= innerVol.getRadius() &&
+ planes[5].distance(innerVol.getCenter()) >= innerVol.getRadius() )
+ {
+ retCode = true;
+ }
+ }
+
+ return retCode;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const CylinderVolume &innerVol)
+{
+ FFATAL(("contain(FrustumVolume, CylinderVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const FrustumVolume &innerVol)
+{
+ FFATAL(("contain(FrustumVolume, FrustumVolume) not implemented.\n"));
+
+ return false;
+}
+
+OSG_BASE_DLLMAPPING
+bool contain(const FrustumVolume &outerVol, const Volume &innerVol)
+{
+ bool retCode = false;
+
+ const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&innerVol);
+ const Volume *v = dv ? &(dv->getInstance()) : &innerVol;
+ const BoxVolume *bv;
+ const SphereVolume *sv;
+ const CylinderVolume *cv;
+ const FrustumVolume *fv;
+
+ if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *bv);
+ }
+ else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *sv);
+ }
+ else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *cv);
+ }
+ else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
+ {
+ retCode = contain(outerVol, *fv);
+ }
+ else
+ {
+ FFATAL(("contain(FrustumVolume, Volume): Argument 2 has unhandled type.\n"));
+ }
+
+ return retCode;
+}
+
// ###################################################################
// # Volume Extend Functions #########################################
// ###################################################################
@@ -738,7 +1263,7 @@
}
else
{
- FWARNING(("extend(Volume, Volume): Argument 1 has unhandled type.\n"));
+ FFATAL(("extend(Volume, Volume): Argument 1 has unhandled type.\n"));
}
}
@@ -929,7 +1454,7 @@
}
else
{
- FWARNING(("extend(BoxVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("extend(BoxVolume, Volume): Argument 2 has unhandled type.\n"));
}
}
@@ -1158,7 +1683,7 @@
}
else
{
- FWARNING(("extend(SphereVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("extend(SphereVolume, Volume): Argument 2 has unhandled type.\n"));
}
}
@@ -1394,7 +1919,7 @@
}
else
{
- FWARNING(("extend(CylinderVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("extend(CylinderVolume, Volume): Argument 2 has unhandled type.\n"));
}
}
@@ -1466,7 +1991,7 @@
}
else
{
- FWARNING(("extend(FrustumVolume, Volume): Argument 2 has unhandled type.\n"));
+ FFATAL(("extend(FrustumVolume, Volume): Argument 2 has unhandled type.\n"));
}
}
Index: Source/Base/Base/OSGCylinderVolume.cpp
===================================================================
--- Source/Base/Base/OSGCylinderVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGCylinderVolume.cpp (working copy)
@@ -160,6 +160,21 @@
(!onplane && osgAbs(dist - _radius) < Eps);
}
+bool CylinderVolume::contain(const Pnt3r &point) const
+{
+ return intersect(point);
+}
+
+bool CylinderVolume::contain(const Volume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
+bool CylinderVolume::contain(const CylinderVolume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
/*-------------------------- transformation -------------------------------*/
/*! transform volume by the given matrix */
Index: Source/Base/Base/OSGVolume.cpp
===================================================================
--- Source/Base/Base/OSGVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGVolume.cpp (working copy)
@@ -42,6 +42,24 @@
OSG_USING_NAMESPACE
+/*! \fn bool Volume::contain(const Pnt3r &point) const
+ Returns whether \a point is contained in this volume.
+
+ \note This is the same as whether the volume and the point intersect
+ and only exists for completeness sake.
+ */
+
+/*! \fn bool Volume::contain(const Volume &volume) const
+ Returns whether \volume is contained in this volume.
+
+ Special cases are handled as follows:
+ Infinite volumes contain everything, while empty volumes contain nothing.
+ Infinite volumes are only contained in infinite volumes and empty volumes
+ are contained in everything (except empty volumes).
+
+ \warning Most of these tests are not implemented!
+ */
+
//! helper functions to dump a volume. Useful for debugger.
OSG_BEGIN_NAMESPACE
Index: Source/Base/Base/OSGCylinderVolume.h
===================================================================
--- Source/Base/Base/OSGCylinderVolume.h (revision 1275)
+++ Source/Base/Base/OSGCylinderVolume.h (working copy)
@@ -128,6 +128,15 @@
/*! \} */
/*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const CylinderVolume &volume) const;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
/*! \name Transform */
/*! \{ */
Index: Source/Base/Base/OSGBoxVolume.cpp
===================================================================
--- Source/Base/Base/OSGBoxVolume.cpp (revision 1275)
+++ Source/Base/Base/OSGBoxVolume.cpp (working copy)
@@ -237,7 +237,21 @@
}
}
+bool BoxVolume::contain(const Pnt3r &point) const
+{
+ return intersect(point);
+}
+bool BoxVolume::contain(const Volume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
+bool BoxVolume::contain(const BoxVolume &volume) const
+{
+ return OSG::contain(*this, volume);
+}
+
//! Transforms Box3f by matrix, enlarging Box3f to contain result
void BoxVolume::transform(const Matrixr &m)
Index: Source/Base/Base/OSGSphereVolume.h
===================================================================
--- Source/Base/Base/OSGSphereVolume.h (revision 1275)
+++ Source/Base/Base/OSGSphereVolume.h (working copy)
@@ -125,6 +125,15 @@
/*! \} */
/*---------------------------------------------------------------------*/
+ /*! \name Containment */
+ /*! \{ */
+
+ virtual bool contain(const Pnt3r &point ) const;
+ virtual bool contain(const Volume &volume) const;
+ bool contain(const SphereVolume &volume) const;
+
+ /*! \} */
+ /*---------------------------------------------------------------------*/
/*! \name Transformation */
/*! \{ */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core