diff --git a/VisualStudio/osgPlugins/osgSim/dot_osgSim.dsp b/VisualStudio/osgPlugins/osgSim/dot_osgSim.dsp index ccc83efd7..815fb7932 100644 --- a/VisualStudio/osgPlugins/osgSim/dot_osgSim.dsp +++ b/VisualStudio/osgPlugins/osgSim/dot_osgSim.dsp @@ -232,6 +232,14 @@ SOURCE=..\..\..\src\osgPlugins\osgSim\IO_MultiSwitch.cpp # End Source File +# Begin Source File + + + +SOURCE=..\..\..\src\osgPlugins\osgSim\IO_VisibilityGroup.cpp + +# End Source File + # End Group # Begin Group "Header Files" diff --git a/VisualStudio/osgSim/osgSim.dsp b/VisualStudio/osgSim/osgSim.dsp index 101eebdc4..960eebaef 100644 --- a/VisualStudio/osgSim/osgSim.dsp +++ b/VisualStudio/osgSim/osgSim.dsp @@ -139,6 +139,10 @@ SOURCE=..\..\src\osgSim\MultiSwitch.cpp SOURCE=..\..\src\osgSim\Version.cpp # End Source File +# Begin Source File + +SOURCE=..\..\src\osgSim\VisibilityGroup.cpp +# End Source File # End Group # Begin Group "Header Files" @@ -195,6 +199,10 @@ SOURCE=..\..\include\osgSim\Export SOURCE=..\..\include\osgSim\Version # End Source File +# Begin Source File + +SOURCE=..\..\include\osgSim\VisibilityGroup +# End Source File # End Group # Begin Group "Resource Files" diff --git a/include/osgSim/VisibilityGroup b/include/osgSim/VisibilityGroup new file mode 100644 index 000000000..fa57dded8 --- /dev/null +++ b/include/osgSim/VisibilityGroup @@ -0,0 +1,58 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGSIM_VISIBILITYGROUP +#define OSGSIM_VISIBILITYGROUP 1 + +#include +#include +#include + +#include + +namespace osgSim { + +class OSGSIM_EXPORT VisibilityGroup : public osg::Group +{ + public : + + VisibilityGroup(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + VisibilityGroup(const VisibilityGroup&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(osgSim, VisibilityGroup) + + virtual void traverse(osg::NodeVisitor& nv); + + void setVisibilityVolume(osg::Node* node) { _visibilityVolume = node; } + osg::Node* getVisibilityVolume() { return _visibilityVolume.get(); } + const osg::Node* getVisibilityVolume() const { return _visibilityVolume.get(); } + + void setVolumeIntersectionMask(osg::Node::NodeMask mask) { _volumeIntersectionMask = mask; } + osg::Node::NodeMask getVolumeIntersectionMask() const { return _volumeIntersectionMask; } + + void setSegmentLength(float length) { _segmentLength = length; } + float getSegmentLength() const { return _segmentLength; } + + protected : + + virtual ~VisibilityGroup() {} + + osg::ref_ptr _visibilityVolume; + osg::Node::NodeMask _volumeIntersectionMask; + float _segmentLength; +}; + +} +#endif diff --git a/src/osgPlugins/osgSim/GNUmakefile b/src/osgPlugins/osgSim/GNUmakefile index c38298467..a4829edbc 100644 --- a/src/osgPlugins/osgSim/GNUmakefile +++ b/src/osgPlugins/osgSim/GNUmakefile @@ -7,7 +7,9 @@ CXXFILES =\ IO_LightPoint.cpp\ IO_BlinkSequence.cpp\ IO_MultiSwitch.cpp\ - IO_Sector.cpp + IO_Sector.cpp\ + IO_VisibilityGroup.cpp\ + LIBS += -losgSim -losgText $(OSG_LIBS) $(OTHER_LIBS) diff --git a/src/osgPlugins/osgSim/IO_VisibilityGroup.cpp b/src/osgPlugins/osgSim/IO_VisibilityGroup.cpp new file mode 100644 index 000000000..7e37c4af8 --- /dev/null +++ b/src/osgPlugins/osgSim/IO_VisibilityGroup.cpp @@ -0,0 +1,79 @@ +#include "osgSim/VisibilityGroup" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgSim; +using namespace osgDB; + +// forward declare functions to use later. +bool VisibilityGroup_readLocalData(Object& obj, Input& fr); +bool VisibilityGroup_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_VisibilityGroupProxy +( + new VisibilityGroup, + "VisibilityGroup", + "Object Node VisibilityGroup Group", + &VisibilityGroup_readLocalData, + &VisibilityGroup_writeLocalData +); + +bool VisibilityGroup_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + VisibilityGroup& vg = static_cast(obj); + + unsigned int mask = vg.getVolumeIntersectionMask(); + if (fr[0].matchWord("volumeIntersectionMask") && fr[1].getUInt(mask)) + { + vg.setNodeMask(mask); + fr+=2; + iteratorAdvanced = true; + } + + if (fr[0].matchWord("segmentLength")) + { + if (fr[1].isFloat()) + { + float value; + fr[1].getFloat(value); + vg.setSegmentLength(value); + iteratorAdvanced = true; + fr += 2; + } + } + + if (fr.matchSequence("visibilityVolume")) + { +// int entry = fr[0].getNoNestedBrackets(); + ++fr; + Node* node = NULL; + if((node=fr.readNode())!=NULL) + { + vg.setVisibilityVolume(node); + iteratorAdvanced = true; + } + } + + return iteratorAdvanced; +} + + +bool VisibilityGroup_writeLocalData(const Object& obj, Output& fw) +{ + const VisibilityGroup& vg = static_cast(obj); + + fw.indent()<<"volumeIntersectionMask 0x"< + +#include +#include + +using namespace osgSim; + +VisibilityGroup::VisibilityGroup(): + _volumeIntersectionMask(0xFFFFFFFF), + _segmentLength(0.f) +{ +} + +VisibilityGroup::VisibilityGroup(const VisibilityGroup& sw,const osg::CopyOp& copyop): + osg::Group(sw,copyop), + _volumeIntersectionMask(0xFFFFFFFF), + _segmentLength(0.f) +{ +} + +void VisibilityGroup::traverse(osg::NodeVisitor& nv) +{ + if (nv.getTraversalMode()==osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN && nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR) + { + // cast to cullvisitor + osgUtil::CullVisitor& cv = (osgUtil::CullVisitor&) nv; + + // here we test if we are inside the visibilityvolume + + // first get the eyepoint and in local coordinates + osg::Vec3 eye = cv.getEyeLocal(); + osg::Vec3 look = cv.getLookVectorLocal(); + + // now scale the segment to the segment length - if 0 use the group bounding sphere radius + float length = _segmentLength; + if(length == 0.f) + length = getBound().radius(); + look *= length; + osg::Vec3 center = eye + look; + + osg::Vec3 seg = center - eye; + + // perform the intersection using the given mask + osgUtil::IntersectVisitor iv; + osg::ref_ptr lineseg = new osg::LineSegment; + lineseg->set(eye, center); + iv.addLineSegment(lineseg.get()); + iv.setTraversalMask(_volumeIntersectionMask); + + if(_visibilityVolume.valid()) + _visibilityVolume->accept(iv); + + // now examine the hit record + if(iv.hits()) + { + osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(lineseg.get()); + if(!hitList.empty()) // we actually hit something + { + // notify(INFO) << "Hit obstruction"<< std::endl; + osg::Vec3 normal = hitList.front().getLocalIntersectNormal(); + if((normal*seg) > 0.f ) // we are inside + Group::traverse(nv); + } + } + } + else + { + Group::traverse(nv); + } +} +