From e37ec98748a2eef9df35cb3bbf9899eafeb9fe0a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 19 May 2007 13:43:38 +0000 Subject: [PATCH] Various additions to better support view dependent overlay node, and updated wrappers --- include/osg/Plane | 29 ++ include/osg/Polytope | 27 +- src/osgSim/OverlayNode.cpp | 363 ++++++++++++++++++++-- src/osgWrappers/osg/Plane.cpp | 7 + src/osgWrappers/osg/Polytope.cpp | 8 + src/osgWrappers/osgGA/EventQueue.cpp | 11 + src/osgWrappers/osgGA/GUIEventAdapter.cpp | 39 ++- src/osgWrappers/osgSim/ElevationSlice.cpp | 2 - 8 files changed, 446 insertions(+), 40 deletions(-) diff --git a/include/osg/Plane b/include/osg/Plane index 348b5e0d4..c6ce44ee2 100644 --- a/include/osg/Plane +++ b/include/osg/Plane @@ -216,6 +216,35 @@ class OSG_EXPORT Plane return -1; // treat points on line as outside... } + /** intersection test between plane and vertex list + return 1 if the bs is completely above plane, + return 0 if the bs intersects the plane, + return -1 if the bs is completely below the plane.*/ + inline int intersect(const std::vector& vertices) const + { + if (vertices.empty()) return -1; + + int noAbove = 0; + int noBelow = 0; + int noOn = 0; + for(std::vector::const_iterator itr=vertices.begin(); + itr != vertices.end(); + ++itr) + { + float d = distance(*itr); + if (d>0.0f) ++noAbove; + else if (d<0.0f) ++noBelow; + else ++noOn; + } + + if (noAbove>0) + { + if (noBelow>0) return 0; + else return 1; + } + return -1; // treat points on line as outside... + } + /** intersection test between plane and bounding sphere. return 1 if the bs is completely above plane, return 0 if the bs intersects the plane, diff --git a/include/osg/Polytope b/include/osg/Polytope index b41b07470..f4e5e6a59 100644 --- a/include/osg/Polytope +++ b/include/osg/Polytope @@ -59,13 +59,26 @@ class OSG_EXPORT Polytope /** Create a Polytope which is a cube, centered at 0,0,0, with sides of 2 units.*/ void setToUnitFrustum(bool withNear=true, bool withFar=true) { - _planeList.erase(_planeList.begin(),_planeList.end()); - _planeList.push_back(Plane(1.0f,0.0f,0.0f,1.0f)); // left plane. - _planeList.push_back(Plane(-1.0f,0.0f,0.0f,1.0f)); // right plane. - _planeList.push_back(Plane(0.0f,1.0f,0.0f,1.0f)); // bottom plane. - _planeList.push_back(Plane(0.0f,-1.0f,0.0f,1.0f)); // top plane. - if (withNear) _planeList.push_back(Plane(0.0f,0.0f,-1.0f,1.0f)); // near plane - if (withFar) _planeList.push_back(Plane(0.0f,0.0f,1.0f,1.0f)); // far plane + _planeList.clear(); + _planeList.push_back(Plane(1.0,0.0,0.0,1.0)); // left plane. + _planeList.push_back(Plane(-1.0,0.0,0.0,1.0)); // right plane. + _planeList.push_back(Plane(0.0,1.0,0.0,1.0)); // bottom plane. + _planeList.push_back(Plane(0.0,-1.0,0.0,1.0)); // top plane. + if (withNear) _planeList.push_back(Plane(0.0,0.0,-1.0,1.0)); // near plane + if (withFar) _planeList.push_back(Plane(0.0,0.0,1.0,1.0)); // far plane + setupMask(); + } + + /** Create a Polytope which is a equivilant to BoundingBox.*/ + void setToBoundingBox(const BoundingBox& bb) + { + _planeList.clear(); + _planeList.push_back(Plane(1.0,0.0,0.0,-bb.xMin())); // left plane. + _planeList.push_back(Plane(-1.0,0.0,0.0,bb.xMax())); // right plane. + _planeList.push_back(Plane(0.0,1.0,0.0,-bb.yMin())); // bottom plane. + _planeList.push_back(Plane(0.0,-1.0,0.0,bb.yMax())); // top plane. + _planeList.push_back(Plane(0.0,0.0,-1.0,bb.zMin())); // near plane + _planeList.push_back(Plane(0.0,0.0,1.0,bb.zMax())); // far plane setupMask(); } diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index bb785eb7f..3d3e98b1b 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -23,6 +23,322 @@ using namespace osgSim; using namespace osg; + +namespace osgSim +{ + +class CustomPolytope +{ +public: + + CustomPolytope() {} + + typedef std::vector Vertices; + + struct Face + { + osg::Plane plane; + Vertices vertices; + }; + + Face& createFace() { _faces.push_back(Face()); return _faces.back(); } + + /** Create a Polytope which is a cube, centered at 0,0,0, with sides of 2 units.*/ + void setToUnitFrustum(bool withNear=true, bool withFar=true) + { + const osg::Vec3d v000(-1.0,-1.0,-1.0); + const osg::Vec3d v010(-1.0,1.0,-1.0); + const osg::Vec3d v001(-1.0,-1.0,1.0); + const osg::Vec3d v011(-1.0,1.0,1.0); + const osg::Vec3d v100(1.0,-1.0,-1.0); + const osg::Vec3d v110(1.0,1.0,-1.0); + const osg::Vec3d v101(1.0,-1.0,1.0); + const osg::Vec3d v111(1.0,1.0,1.0); + + _faces.clear(); + + { // left plane. + Face& face = createFace(); + face.plane.set(1.0,0.0,0.0,1.0); + face.vertices.push_back(v000); + face.vertices.push_back(v001); + face.vertices.push_back(v011); + face.vertices.push_back(v010); + } + + { // right plane. + Face& face = createFace(); + face.plane.set(-1.0,0.0,0.0,1.0); + face.vertices.push_back(v100); + face.vertices.push_back(v110); + face.vertices.push_back(v111); + face.vertices.push_back(v101); + } + + { // bottom plane. + Face& face = createFace(); + face.plane.set(0.0,1.0,0.0,1.0); + face.vertices.push_back(v000); + face.vertices.push_back(v010); + face.vertices.push_back(v110); + face.vertices.push_back(v100); + } + + { // top plane. + Face& face = createFace(); + face.plane.set(0.0,-1.0,0.0,1.0); + face.vertices.push_back(v001); + face.vertices.push_back(v101); + face.vertices.push_back(v111); + face.vertices.push_back(v011); + } + + if (withNear) + { // near plane + Face& face = createFace(); + face.plane.set(0.0,0.0,-1.0,1.0); + face.vertices.push_back(v000); + face.vertices.push_back(v100); + face.vertices.push_back(v101); + face.vertices.push_back(v001); + } + + if (withFar) + { // far plane + Face& face = createFace(); + face.plane.set(0.0,0.0,1.0,1.0); + face.vertices.push_back(v010); + face.vertices.push_back(v011); + face.vertices.push_back(v111); + face.vertices.push_back(v110); + } + } + + void setToBoundingBox(const osg::BoundingBox& bb) + { + const osg::Vec3d v000(bb.xMin(),bb.yMin(), bb.zMin()); + const osg::Vec3d v010(bb.xMin(),bb.yMax(), bb.zMin()); + const osg::Vec3d v001(bb.xMin(),bb.yMin(), bb.zMax()); + const osg::Vec3d v011(bb.xMin(),bb.yMax(), bb.zMax()); + const osg::Vec3d v100(bb.xMax(),bb.yMin(), bb.zMin()); + const osg::Vec3d v110(bb.xMax(),bb.yMax(), bb.zMin()); + const osg::Vec3d v101(bb.xMax(),bb.yMin(), bb.zMax()); + const osg::Vec3d v111(bb.xMax(),bb.yMax(), bb.zMax()); + + _faces.clear(); + + { // left plane. + Face& face = createFace(); + face.plane.set(1.0,0.0,0.0,-bb.xMin()); + face.vertices.push_back(v000); + face.vertices.push_back(v001); + face.vertices.push_back(v011); + face.vertices.push_back(v010); + } + + { // right plane. + Face& face = createFace(); + face.plane.set(-1.0,0.0,0.0,bb.xMax()); + face.vertices.push_back(v100); + face.vertices.push_back(v110); + face.vertices.push_back(v111); + face.vertices.push_back(v101); + } +#if 0 + { // bottom plane. + Face& face = createFace(); + face.plane.set(0.0,1.0,0.0,-bb.yMin()); + face.vertices.push_back(v000); + face.vertices.push_back(v010); + face.vertices.push_back(v110); + face.vertices.push_back(v100); + } + + { // top plane. + Face& face = createFace(); + face.plane.set(0.0,-1.0,0.0,bb.yMax()); + face.vertices.push_back(v001); + face.vertices.push_back(v101); + face.vertices.push_back(v111); + face.vertices.push_back(v011); + } +#endif + { // near plane + Face& face = createFace(); + face.plane.set(0.0,0.0,-1.0,bb.zMin()); + face.vertices.push_back(v000); + face.vertices.push_back(v100); + face.vertices.push_back(v101); + face.vertices.push_back(v001); + } + + { // far plane + Face& face = createFace(); + face.plane.set(0.0,0.0,1.0,-bb.zMax()); + face.vertices.push_back(v010); + face.vertices.push_back(v011); + face.vertices.push_back(v111); + face.vertices.push_back(v110); + } + } + + void transform(const osg::Matrix& matrix, const osg::Matrix& inverse) + { + for(Faces::iterator itr = _faces.begin(); + itr != _faces.end(); + ++itr) + { + Face& face = *itr; + face.plane.transformProvidingInverse(inverse); + for(Vertices::iterator vitr = face.vertices.begin(); + vitr != face.vertices.end(); + ++vitr) + { + *vitr = *vitr * matrix; + } + } + } + + void cut(const osg::Polytope& polytope) + { + osg::notify(osg::NOTICE)<<"Cutting with polytope "<plane); + } + } + + void cut(const osg::Plane& plane) + { + osg::notify(osg::NOTICE)<<" Cutting plane "< Distances; + Distances distances; + distances.reserve(face.vertices.size()); + for(Vertices::iterator vitr = vertices.begin(); + vitr != vertices.end(); + ++vitr) + { + distances.push_back(plane.distance(*vitr)); + } + + for(unsigned int i=0; i=0.0) newVertices.push_back(vertices[i]); + + // does edge intersect plane + if (distance_a * distance_b<0.0) + { + // inserting vertex + osg::Vec3d intersection = (vb*distance_a - va*distance_b)/(distance_a-distance_b); + newVertices.push_back(intersection); + newFace.vertices.push_back(intersection); + } + } + + vertices.swap(newVertices); + + ++itr; + } + else if (intersect==-1) + { + osg::notify(osg::NOTICE)<<" Face outside"<<_faces.size()<plane); + } + } + + void getPoints(Vertices& vertices) + { + typedef std::set VerticesSet; + VerticesSet verticesSet; + for(Faces::iterator itr = _faces.begin(); + itr != _faces.end(); + ++itr) + { + Face& face = *itr; + for(Vertices::iterator vitr = face.vertices.begin(); + vitr != face.vertices.end(); + ++vitr) + { + verticesSet.insert(*vitr); + } + } + + for(VerticesSet::iterator sitr = verticesSet.begin(); + sitr != verticesSet.end(); + ++sitr) + { + vertices.push_back(*sitr); + } + } + +protected: + + typedef std::list Faces; + Faces _faces; + + +}; + +} + + OverlayNode::OverlayNode(OverlayTechnique technique): _overlayTechnique(technique), _texEnvMode(GL_DECAL), @@ -416,9 +732,6 @@ void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVis if (_overlaySubgraph.valid()) { - // get the bounds of the model. - osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN); - _overlaySubgraph->accept(cbbv); // see if we are within a coordinate system node. osg::CoordinateSystemNode* csn = 0; @@ -464,29 +777,29 @@ void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVis osg::Matrix MVP = *(cv->getModelViewMatrix()) * pm; osg::Matrix inverseMVP; inverseMVP.invert(MVP); + + // create polytope for the view frustum in local coords + CustomPolytope frustum; + frustum.setToUnitFrustum(); + frustum.transform(inverseMVP, MVP); - // osg::notify(osg::NOTICE)<<" MVP="< &, vertices, + Properties::NON_VIRTUAL, + __int__intersect__C5_std_vectorT1_Vec3d__R1, + "intersection test between plane and vertex list return 1 if the bs is completely above plane, return 0 if the bs intersects the plane, return -1 if the bs is completely below the plane. ", + ""); I_Method1(int, intersect, IN, const osg::BoundingSphere &, bs, Properties::NON_VIRTUAL, __int__intersect__C5_BoundingSphere_R1, @@ -203,3 +208,5 @@ BEGIN_VALUE_REFLECTOR(osg::Plane) 0); END_REFLECTOR +STD_VECTOR_REFLECTOR(std::vector< osg::Vec3d >) + diff --git a/src/osgWrappers/osg/Polytope.cpp b/src/osgWrappers/osg/Polytope.cpp index 097791ad4..3c60acf95 100644 --- a/src/osgWrappers/osg/Polytope.cpp +++ b/src/osgWrappers/osg/Polytope.cpp @@ -57,6 +57,11 @@ BEGIN_VALUE_REFLECTOR(osg::Polytope) __void__setToUnitFrustum__bool__bool, "Create a Polytope which is a cube, centered at 0,0,0, with sides of 2 units. ", ""); + I_Method1(void, setToBoundingBox, IN, const osg::BoundingBox &, bb, + Properties::NON_VIRTUAL, + __void__setToBoundingBox__C5_BoundingBox_R1, + "Create a Polytope which is a equivilant to BoundingBox. ", + ""); I_Method2(void, setAndTransformProvidingInverse, IN, const osg::Polytope &, pt, IN, const osg::Matrix &, matrix, Properties::NON_VIRTUAL, __void__setAndTransformProvidingInverse__C5_Polytope_R1__C5_osg_Matrix_R1, @@ -207,6 +212,9 @@ BEGIN_VALUE_REFLECTOR(osg::Polytope) I_SimpleProperty(osg::Polytope::ClippingMask, ResultMask, __ClippingMask__getResultMask, __void__setResultMask__ClippingMask); + I_SimpleProperty(const osg::BoundingBox &, ToBoundingBox, + 0, + __void__setToBoundingBox__C5_BoundingBox_R1); END_REFLECTOR BEGIN_VALUE_REFLECTOR(osg::fast_back_stack< osg::Polytope::ClippingMask >) diff --git a/src/osgWrappers/osgGA/EventQueue.cpp b/src/osgWrappers/osgGA/EventQueue.cpp index 5752e02a8..f0d269e8a 100644 --- a/src/osgWrappers/osgGA/EventQueue.cpp +++ b/src/osgWrappers/osgGA/EventQueue.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -241,6 +242,16 @@ BEGIN_OBJECT_REFLECTOR(osgGA::EventQueue) __C5_GUIEventAdapter_P1__getCurrentEventState, "", ""); + I_Method1(void, userEvent, IN, osg::Referenced *, userEventData, + Properties::NON_VIRTUAL, + __void__userEvent__osg_Referenced_P1, + "Method for adapting user defined events. ", + ""); + I_Method2(void, userEvent, IN, osg::Referenced *, userEventData, IN, double, time, + Properties::NON_VIRTUAL, + __void__userEvent__osg_Referenced_P1__double, + "Method for adapting user defined events with specified event time. ", + ""); I_SimpleProperty(osgGA::GUIEventAdapter *, CurrentEventState, __GUIEventAdapter_P1__getCurrentEventState, 0); diff --git a/src/osgWrappers/osgGA/GUIEventAdapter.cpp b/src/osgWrappers/osgGA/GUIEventAdapter.cpp index 30b2046de..d86b02475 100644 --- a/src/osgWrappers/osgGA/GUIEventAdapter.cpp +++ b/src/osgWrappers/osgGA/GUIEventAdapter.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include #include // Must undefine IN and OUT macros defined in Windows headers @@ -43,6 +45,7 @@ BEGIN_ENUM_REFLECTOR(osgGA::GUIEventAdapter::EventType) I_EnumLabel(osgGA::GUIEventAdapter::PEN_PROXIMITY_LEAVE); I_EnumLabel(osgGA::GUIEventAdapter::CLOSE_WINDOW); I_EnumLabel(osgGA::GUIEventAdapter::QUIT_APPLICATION); + I_EnumLabel(osgGA::GUIEventAdapter::USER); END_REFLECTOR BEGIN_ENUM_REFLECTOR(osgGA::GUIEventAdapter::KeySymbol) @@ -209,15 +212,39 @@ BEGIN_ENUM_REFLECTOR(osgGA::GUIEventAdapter::TabletPointerType) END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osgGA::GUIEventAdapter) - I_BaseType(osg::Referenced); + I_BaseType(osg::Object); I_Constructor0(____GUIEventAdapter, "", ""); - I_Constructor1(IN, const osgGA::GUIEventAdapter &, rhs, - Properties::NON_EXPLICIT, - ____GUIEventAdapter__C5_GUIEventAdapter_R1, - "", - ""); + I_ConstructorWithDefaults2(IN, const osgGA::GUIEventAdapter &, rhs, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY, + ____GUIEventAdapter__C5_GUIEventAdapter_R1__C5_osg_CopyOp_R1, + "", + ""); + I_Method0(osg::Object *, cloneType, + Properties::VIRTUAL, + __osg_Object_P1__cloneType, + "Clone the type of an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop, + Properties::VIRTUAL, + __osg_Object_P1__clone__C5_osg_CopyOp_R1, + "Clone an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj, + Properties::VIRTUAL, + __bool__isSameKindAs__C5_osg_Object_P1, + "", + ""); + I_Method0(const char *, libraryName, + Properties::VIRTUAL, + __C5_char_P1__libraryName, + "return the name of the object's library. ", + "Must be defined by derived classes. The OpenSceneGraph convention is that the namespace of a library is the same as the library name. "); + I_Method0(const char *, className, + Properties::VIRTUAL, + __C5_char_P1__className, + "return the name of the object's class type. ", + "Must be defined by derived classes. "); I_Method1(void, setHandled, IN, bool, handled, Properties::NON_VIRTUAL, __void__setHandled__bool, diff --git a/src/osgWrappers/osgSim/ElevationSlice.cpp b/src/osgWrappers/osgSim/ElevationSlice.cpp index 87e5249ef..cc4df424c 100644 --- a/src/osgWrappers/osgSim/ElevationSlice.cpp +++ b/src/osgWrappers/osgSim/ElevationSlice.cpp @@ -106,7 +106,5 @@ END_REFLECTOR STD_PAIR_REFLECTOR(std::pair< double COMMA double >) -STD_VECTOR_REFLECTOR(std::vector< osg::Vec3d >) - STD_VECTOR_REFLECTOR(std::vector< osgSim::ElevationSlice::DistanceHeight >)