From Michael Gronager, osgSim::VisibilityGroup

This commit is contained in:
Robert Osfield
2003-11-27 16:23:07 +00:00
parent e7f9a51f0f
commit 2353d55697
7 changed files with 242 additions and 1 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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 <osg/Node>
#include <osg/Group>
#include <osg/NodeVisitor>
#include <osgSim/Export>
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<osg::Node> _visibilityVolume;
osg::Node::NodeMask _volumeIntersectionMask;
float _segmentLength;
};
}
#endif

View File

@@ -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)

View File

@@ -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<VisibilityGroup&>(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<const VisibilityGroup&>(obj);
fw.indent()<<"volumeIntersectionMask 0x"<<std::hex<<vg.getVolumeIntersectionMask()<<std::dec<<std::endl;
fw.indent()<<"segmentLength "<<vg.getSegmentLength()<<std::endl;
fw.indent()<<"visibilityVolume" <<std::endl;
fw.moveIn();
fw.writeObject(*vg.getVisibilityVolume());
fw.moveOut();
return true;
}

View File

@@ -15,6 +15,8 @@ CXXFILES = \
SphereSegment.cpp\
MultiSwitch.cpp\
Version.cpp\
VisibilityGroup.cpp\
DEF += -DOSGSIM_LIBRARY

View File

@@ -0,0 +1,84 @@
/* -*-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.
*/
#include <osgSim/VisibilityGroup>
#include <osgUtil/CullVisitor>
#include <osgUtil/IntersectVisitor>
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<osg::LineSegment> 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);
}
}