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

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