From ae8076f83b0902b36892fa8a081c5928f54dcc8b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 May 2002 00:14:40 +0000 Subject: [PATCH] dded osg::ClipNode class for managing OpenGL clipping planes, and osgclip demo. --- Make/makedefs | 2 +- Make/makedirdefs | 5 +- VisualStudio/Demos/osgclip/osgclip.dsp | 96 +++++++++++++ VisualStudio/VisualStudio.dsw | 24 ++++ include/osg/ClipNode | 78 ++++++++++ include/osg/ClipPlane | 9 ++ include/osg/Matrix | 4 +- include/osg/NodeVisitor | 24 ++-- include/osgUtil/CullVisitor | 8 +- include/osgUtil/RenderStage | 6 +- include/osgUtil/RenderStageLighting | 10 +- src/Demos/osgclip/Makefile | 15 ++ src/Demos/osgclip/Makefile.inst | 11 ++ src/Demos/osgclip/osgclip.cpp | 189 +++++++++++++++++++++++++ src/osg/ClipNode.cpp | 119 ++++++++++++++++ src/osg/Makefile | 1 + src/osgUtil/CullVisitor.cpp | 27 +++- src/osgUtil/RenderStage.cpp | 7 +- src/osgUtil/RenderStageLighting.cpp | 6 +- src/osgUtil/SceneView.cpp | 4 +- 20 files changed, 610 insertions(+), 35 deletions(-) create mode 100755 VisualStudio/Demos/osgclip/osgclip.dsp create mode 100644 include/osg/ClipNode create mode 100644 src/Demos/osgclip/Makefile create mode 100644 src/Demos/osgclip/Makefile.inst create mode 100644 src/Demos/osgclip/osgclip.cpp create mode 100644 src/osg/ClipNode.cpp diff --git a/Make/makedefs b/Make/makedefs index 0702f1f04..faeee1ee8 100644 --- a/Make/makedefs +++ b/Make/makedefs @@ -130,7 +130,7 @@ ifeq ($(ARCH),64) else ARCHARGS = -n32 endif - LINKARGS = -LANG:std -OPT:Olimit=0 -L/usr/local/lib32 -rpath /usr/local/lib32 -rpath $(INST_LIBS) + LINKARGS = -L${TOPDIR}/lib -LANG:std -OPT:Olimit=0 -L/usr/local/lib32 -rpath /usr/local/lib32 -rpath $(INST_LIBS) DYNAMICLIBRARYLIB = -ldl OSG_LIBS = -losgGLUT -losgDB -losgUtil -losg FREETYPE_LIB = -lfreetype diff --git a/Make/makedirdefs b/Make/makedirdefs index 435cf9856..365909fc4 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -48,13 +48,13 @@ PLUGIN_DIRS += dx # PLUGIN_DIRS += quicktime # comment in if you have libpng installed. -PLUGIN_DIRS += png +#PLUGIN_DIRS += png # comment in if you have libjpeg installed. PLUGIN_DIRS += jpeg # comment in if you have libungif installed. -PLUGIN_DIRS += gif +#PLUGIN_DIRS += gif # comment in if you have libtiff installed. PLUGIN_DIRS += tiff @@ -65,6 +65,7 @@ PLUGIN_DIRS += tiff DEMOS_DIRS = \ hangglide\ osgbillboard\ + osgclip\ osgcluster\ osgconv\ osgcopy\ diff --git a/VisualStudio/Demos/osgclip/osgclip.dsp b/VisualStudio/Demos/osgclip/osgclip.dsp new file mode 100755 index 000000000..4a48c124e --- /dev/null +++ b/VisualStudio/Demos/osgclip/osgclip.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="Demo osgclip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Demo osgclip - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "osgclip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "osgclip.mak" CFG="Demo osgclip - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Demo osgclip - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Demo osgclip - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Demo osgclip - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgclip.exe" /libpath:"../../../lib" + +!ELSEIF "$(CFG)" == "Demo osgclip - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /D "OSG_USE_MEMORY_MANAGER" /FR /YX /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 glut32.lib glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgclipd.exe" /pdbtype:sept /libpath:"../../../lib" +# SUBTRACT LINK32 /incremental:no + +!ENDIF + +# Begin Target + +# Name "Demo osgclip - Win32 Release" +# Name "Demo osgclip - Win32 Debug" +# Begin Source File + +SOURCE=..\..\..\src\Demos\osgclip\osgclip.cpp +# End Source File +# End Target +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Project +\c diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index c78a67d3c..96f6a9761 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -201,6 +201,30 @@ Package=<4> ############################################################################### +Project: "Demo osgclip"=".\Demos\osgclip\osgclip.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Core osg + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgDB + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgGLUT + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgUtil + End Project Dependency +}}} + +############################################################################### + Project: "Demo osghud"=".\Demos\osghud\osghud.dsp" - Package Owner=<4> Package=<5> diff --git a/include/osg/ClipNode b/include/osg/ClipNode new file mode 100644 index 000000000..cd8c03897 --- /dev/null +++ b/include/osg/ClipNode @@ -0,0 +1,78 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_CLIPNODE +#define OSG_CLIPNODE 1 + +#include +#include + +namespace osg { + +/** Leaf Node for defining the position of ClipPlanes in the scene.*/ +class SG_EXPORT ClipNode : public Group +{ + + public: + + typedef std::vector > ClipPlaneList; + + + ClipNode(); + + ClipNode(const ClipNode& es, const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Node(ClipNode); + + /** Create a 6 clip planes to create a clip box.*/ + void createClipBox(const BoundingBox& bb,unsigned int clipPlaneNumberBase=0); + + + /** Add a ClipPlane to a ClipNode. Return true if plane is added, + * return false if plane already exists in ClipNode, or clipplane is false.*/ + const bool addClipPlane(ClipPlane* clipplane); + + /** Remove ClipPlane from a ClipNode. Return true if plane is removed, + * return false if plane does not exists in ClipNode.*/ + const bool removeClipPlane(ClipPlane* clipplane); + + /** Remove ClipPlane, at specified index, from a ClipNode. Return true if plane is removed, + * return false if plane does not exists in ClipNode.*/ + const bool removeClipPlane(unsigned int pos); + + /** return the number of ClipPlanes.*/ + inline const unsigned int getNumClipPlanes() const { return _planes.size(); } + + + /** Get ClipPlane at specificed index position.*/ + inline ClipPlane* getClipPlane(unsigned int pos) { return _planes[pos].get(); } + + /** Get const ClipPlane at specificed index position.*/ + inline const ClipPlane* getClipPlane(unsigned int pos) const { return _planes[pos].get(); } + + /** Get the ClipPlaneList.*/ + inline ClipPlaneList& getClipPlaneList() { return _planes; } + + /** Get the const ClipPlaneList.*/ + inline const ClipPlaneList& getClipPlaneList() const { return _planes; } + + /** Set the GLModes on StateSet associated with the ClipPlanes.*/ + void setStateSetModes(StateSet&,const StateAttribute::GLModeValue) const; + + /** Set up the local StateSet */ + void setLocalStateSetModes(const StateAttribute::GLModeValue=StateAttribute::ON); + + protected: + + virtual ~ClipNode(); + + virtual const bool computeBound() const; + + StateAttribute::GLModeValue _value; + ClipPlaneList _planes; +}; + +} + +#endif diff --git a/include/osg/ClipPlane b/include/osg/ClipPlane index 09db18045..bf83fb9b3 100644 --- a/include/osg/ClipPlane +++ b/include/osg/ClipPlane @@ -17,6 +17,9 @@ class SG_EXPORT ClipPlane : public StateAttribute public : ClipPlane(); + inline ClipPlane(unsigned int no,const Vec4& plane) { setClipPlaneNum(no); setClipPlane(plane); } + inline ClipPlane(unsigned int no,const Plane& plane) { setClipPlaneNum(no); setClipPlane(plane); } + inline ClipPlane(unsigned int no,const double a,const double b,const double c,const double d) { setClipPlaneNum(no); setClipPlane(a,b,c,d); } /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ ClipPlane(const ClipPlane& cp,const CopyOp& copyop=CopyOp::SHALLOW_COPY): @@ -63,6 +66,12 @@ class SG_EXPORT ClipPlane : public StateAttribute /** Set the clip plane, using a double[4] to define plane. */ void setClipPlane(const double* plane); + /** Set the clip plane, using a a to define plane. */ + void setClipPlane(const double a,const double b,const double c,const double d) + { + _clipPlane[0]=a;_clipPlane[1]=b;_clipPlane[2]=c;_clipPlane[3]=d; + } + /** Get the clip plane, values entered into a Vec4 passed to the getClipPlane. */ void getClipPlane(Vec4& plane) const; diff --git a/include/osg/Matrix b/include/osg/Matrix index 8f59a4659..b0fc0111b 100644 --- a/include/osg/Matrix +++ b/include/osg/Matrix @@ -60,13 +60,13 @@ class SG_EXPORT Matrix : public Object inline Matrix& operator = (const Matrix& other) { if( &other == this ) return *this; - set((float const * const)(other._mat)); + std::copy((const float*)other._mat,(const float*)other._mat+16,(float*)(_mat)); return *this; } inline void set(const Matrix& other) { - set((float const * const)(other._mat)); + std::copy((const float*)other._mat,(const float*)other._mat+16,(float*)(_mat)); } inline void set(float const * const ptr) diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 8d0be6d71..401b95b4f 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -14,6 +14,7 @@ namespace osg { class Geode; class Billboard; class LightSource; +class ClipNode; class Group; class Transform; class Projection; @@ -164,19 +165,20 @@ class SG_EXPORT NodeVisitor : public Referenced const bool getWorldToLocalMatrix(Matrix& matrix, Node* node); - virtual void apply(Node& node) { traverse(node);} + virtual void apply(Node& node) { traverse(node);} - virtual void apply(Geode& node) { apply((Node&)node); } - virtual void apply(Billboard& node) { apply((Geode&)node); } - virtual void apply(LightSource& node){ apply((Node&)node); } + virtual void apply(Geode& node) { apply((Node&)node); } + virtual void apply(Billboard& node) { apply((Geode&)node); } + virtual void apply(LightSource& node) { apply((Node&)node); } + virtual void apply(ClipNode& node) { apply((Node&)node); } - virtual void apply(Group& node) { apply((Node&)node); } - virtual void apply(Projection& node) { apply((Group&)node); } - virtual void apply(Transform& node) { apply((Group&)node); } - virtual void apply(Switch& node) { apply((Group&)node); } - virtual void apply(LOD& node) { apply((Group&)node); } - virtual void apply(Impostor& node) { apply((LOD&)node); } - virtual void apply(EarthSky& node) { apply((Group&)node); } + virtual void apply(Group& node) { apply((Node&)node); } + virtual void apply(Projection& node) { apply((Group&)node); } + virtual void apply(Transform& node) { apply((Group&)node); } + virtual void apply(Switch& node) { apply((Group&)node); } + virtual void apply(LOD& node) { apply((Group&)node); } + virtual void apply(Impostor& node) { apply((LOD&)node); } + virtual void apply(EarthSky& node) { apply((Group&)node); } protected: diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 89dddb93e..5e79f7e67 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -66,6 +66,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor virtual void apply(osg::Geode& node); virtual void apply(osg::Billboard& node); virtual void apply(osg::LightSource& node); + virtual void apply(osg::ClipNode& node); virtual void apply(osg::Group& node); virtual void apply(osg::Transform& node); @@ -288,12 +289,13 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor _currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix,depth)); } - /** Add a light to current render graph.*/ - inline void addLight(osg::Light* light,osg::Matrix* matrix) + /** Add an attribute which is positioned related to the modelview matrix.*/ + inline void addPositionedAttribute(osg::Matrix* matrix,const osg::StateAttribute* attr) { - _currentRenderBin->_stage->addLight(light,matrix); + _currentRenderBin->_stage->addPositionedAttribute(matrix,attr); } + /** create an impostor sprite by setting up a pre-rendering stage * to generate the impostor texture. */ osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node); diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 3ac5abf62..e4d095e3d 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -100,11 +100,11 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin return _renderStageLighting.get(); } - virtual void addLight(osg::Light* light,osg::Matrix* matrix) + virtual void addPositionedAttribute(osg::Matrix* matrix,const osg::StateAttribute* attr) { - getRenderStageLighting()->addLight(light,matrix); + getRenderStageLighting()->addPositionedAttribute(matrix,attr); } - + virtual void draw(osg::State& state,RenderLeaf*& previous); void addToDependencyList(RenderStage* rs); diff --git a/include/osgUtil/RenderStageLighting b/include/osgUtil/RenderStageLighting index 788f7e560..92aa44745 100644 --- a/include/osgUtil/RenderStageLighting +++ b/include/osgUtil/RenderStageLighting @@ -30,19 +30,19 @@ class OSGUTIL_EXPORT RenderStageLighting : public osg::Object virtual void reset(); - typedef std::pair< osg::Light*, osg::ref_ptr > LightMatrixPair; - typedef std::vector< LightMatrixPair > LightList; + typedef std::pair< const osg::StateAttribute*, osg::ref_ptr > AttrMatrixPair; + typedef std::vector< AttrMatrixPair > AttrMatrixList; - virtual void addLight(osg::Light* light,osg::Matrix* matrix) + virtual void addPositionedAttribute(osg::Matrix* matrix,const osg::StateAttribute* attr) { - _lightList.push_back(LightMatrixPair(light,matrix)); + _attrList.push_back(AttrMatrixPair(attr,matrix)); } virtual void draw(osg::State& state,RenderLeaf*& previous); public: - LightList _lightList; + AttrMatrixList _attrList; protected: diff --git a/src/Demos/osgclip/Makefile b/src/Demos/osgclip/Makefile new file mode 100644 index 000000000..feb0cb24e --- /dev/null +++ b/src/Demos/osgclip/Makefile @@ -0,0 +1,15 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgclip.cpp\ + +LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + Makefile.inst=Makefile + +EXEC = osgclip + +include $(TOPDIR)/Make/makerules diff --git a/src/Demos/osgclip/Makefile.inst b/src/Demos/osgclip/Makefile.inst new file mode 100644 index 000000000..28a00c323 --- /dev/null +++ b/src/Demos/osgclip/Makefile.inst @@ -0,0 +1,11 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgclip.cpp\ + +LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgclip + +include $(TOPDIR)/Make/makerules diff --git a/src/Demos/osgclip/osgclip.cpp b/src/Demos/osgclip/osgclip.cpp new file mode 100644 index 000000000..642432bf9 --- /dev/null +++ b/src/Demos/osgclip/osgclip.cpp @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +void write_usage(std::ostream& out,const std::string& name) +{ + out << std::endl; + out <<"usage:"<< std::endl; + out <<" "<setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); + stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE_ON); + + osg::Group* wireframe_subgraph = osgNew osg::Group; + wireframe_subgraph->setStateSet(stateset); + wireframe_subgraph->addChild(subgraph); + rootnode->addChild(wireframe_subgraph); + +/* + // simple approach to adding a clipnode above a subrgaph. + + // create clipped part. + osg::ClipNode* clipped_subgraph = osgNew osg::ClipNode; + + osg::BoundingSphere bs = subgraph->getBound(); + bs.radius()*= 0.4f; + + osg::BoundingBox bb; + bb.expandBy(bs); + + + clipped_subgraph->createClipBox(bb); + clipped_subgraph->addChild(subgraph); + rootnode->addChild(clipped_subgraph); +*/ + + + // more complex approach to managing ClipNode, allowing + // ClipNode node to be transformed independantly from the subgraph + // that it is clipping. + + osg::Transform* transform= osgNew osg::Transform; + + osg::NodeCallback* nc = new osgUtil::TransformCallback(subgraph->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f)); + transform->setAppCallback(nc); + + osg::ClipNode* clipnode = osgNew osg::ClipNode; + osg::BoundingSphere bs = subgraph->getBound(); + bs.radius()*= 0.4f; + + osg::BoundingBox bb; + bb.expandBy(bs); + + clipnode->createClipBox(bb); + clipnode->setCullingActive(false); + + transform->addChild(clipnode); + rootnode->addChild(transform); + + + // create clipped part. + osg::Group* clipped_subgraph = osgNew osg::Group; + + clipped_subgraph->setStateSet(clipnode->getStateSet()); + clipped_subgraph->addChild(subgraph); + rootnode->addChild(clipped_subgraph); + + return rootnode; +} + + +int main( int argc, char **argv ) +{ + + // initialize the GLUT + glutInit( &argc, argv ); + + if (argc<2) + { + write_usage(osg::notify(osg::NOTICE),argv[0]); + return 0; + } + + // create the commandline args. + std::vector commandLine; + for(int i=1;i + +using namespace osg; + +ClipNode::ClipNode() +{ + _value = StateAttribute::ON; + _dstate = osgNew StateSet; +} + +ClipNode::ClipNode(const ClipNode& cn, const CopyOp& copyop):Group(cn,copyop) +{ + for(ClipPlaneList::const_iterator itr=cn._planes.begin(); + itr!=cn._planes.end(); + ++itr) + { + ClipPlane* plane = dynamic_cast(copyop(itr->get())); + if (plane) addClipPlane(plane); + } +} + +ClipNode::~ClipNode() +{ +} + +// Create a 6 clip planes to create a clip box. +void ClipNode::createClipBox(const BoundingBox& bb,unsigned int clipPlaneNumberBase) +{ + _planes.clear(); + + _planes.push_back(new ClipPlane(clipPlaneNumberBase ,1.0,0.0,0.0,-bb.xMin())); + _planes.push_back(new ClipPlane(clipPlaneNumberBase+1,-1.0,0.0,0.0,bb.xMax())); + + _planes.push_back(new ClipPlane(clipPlaneNumberBase+2,0.0,1.0,0.0,-bb.yMin())); + _planes.push_back(new ClipPlane(clipPlaneNumberBase+3,0.0,-1.0,0.0,bb.yMax())); + + _planes.push_back(new ClipPlane(clipPlaneNumberBase+4,0.0,0.0,1.0,-bb.zMin())); + _planes.push_back(new ClipPlane(clipPlaneNumberBase+5,0.0,0.0,-1.0,bb.zMax())); + + setLocalStateSetModes(_value); +} + +// Add a ClipPlane to a ClipNode. Return true if plane is added, +// return false if plane already exists in ClipNode, or clipplane is false. +const bool ClipNode::addClipPlane(ClipPlane* clipplane) +{ + if (!clipplane) return false; + + if (std::find(_planes.begin(),_planes.end(),clipplane)==_planes.end()) + { + // cliplane doesn't exist in list so add it. + _planes.push_back(clipplane); + setLocalStateSetModes(_value); + return true; + } + else + { + return false; + } +} + +// Remove ClipPlane from a ClipNode. Return true if plane is removed, +// return false if plane does not exists in ClipNode. +const bool ClipNode::removeClipPlane(ClipPlane* clipplane) +{ + if (!clipplane) return false; + + ClipPlaneList::iterator itr = std::find(_planes.begin(),_planes.end(),clipplane); + if (itr!=_planes.end()) + { + // cliplane exist in list so erase it. + _planes.erase(itr); + setLocalStateSetModes(_value); + return true; + } + else + { + return false; + } +} + +// Remove ClipPlane, at specified index, from a ClipNode. Return true if plane is removed, +// return false if plane does not exists in ClipNode. +const bool ClipNode::removeClipPlane(unsigned int pos) +{ + if (pos<_planes.size()) + { + _planes.erase(_planes.begin()+pos); + setLocalStateSetModes(_value); + return true; + } + else + { + return NULL; + } +} + +// Set the GLModes on StateSet associated with the ClipPlanes. +void ClipNode::setStateSetModes(StateSet& stateset,const StateAttribute::GLModeValue value) const +{ + for(ClipPlaneList::const_iterator itr=_planes.begin(); + itr!=_planes.end(); + ++itr) + { + (*itr)->setStateSetModes(stateset,value); + } +} + +void ClipNode::setLocalStateSetModes(const StateAttribute::GLModeValue value) +{ + if (!_dstate) _dstate = osgNew StateSet; + _dstate->setAllToInherit(); + setStateSetModes(*_dstate,value); +} + +const bool ClipNode::computeBound() const +{ + return Group::computeBound(); +} diff --git a/src/osg/Makefile b/src/osg/Makefile index 086ad9d5b..707ea2249 100644 --- a/src/osg/Makefile +++ b/src/osg/Makefile @@ -8,6 +8,7 @@ CXXFILES =\ BoundingBox.cpp\ BoundingSphere.cpp\ Camera.cpp\ + ClipNode.cpp\ ClipPlane.cpp\ ColorMask.cpp\ ColorMatrix.cpp\ diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index f5e67e004..a29bc6f27 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ class PrintVisitor : public NodeVisitor virtual void apply(Geode& node) { apply((Node&)node); } virtual void apply(Billboard& node) { apply((Geode&)node); } virtual void apply(LightSource& node) { apply((Node&)node); } + virtual void apply(ClipNode& node) { apply((Node&)node); } virtual void apply(Group& node) { apply((Node&)node); } virtual void apply(Transform& node) { apply((Group&)node); } @@ -524,13 +526,34 @@ void CullVisitor::apply(LightSource& node) Light* light = node.getLight(); if (light) { - addLight(light,&matrix); + addPositionedAttribute(&matrix,light); } // pop the node's state off the geostate stack. if (node_state) popStateSet(); } +void CullVisitor::apply(ClipNode& node) +{ + // push the node's state. + StateSet* node_state = node.getStateSet(); + if (node_state) pushStateSet(node_state); + + Matrix& matrix = getModelViewMatrix(); + + const ClipNode::ClipPlaneList& planes = node.getClipPlaneList(); + for(ClipNode::ClipPlaneList::const_iterator itr=planes.begin(); + itr!=planes.end(); + ++itr) + { + addPositionedAttribute(&matrix,itr->get()); + } + + handle_cull_callbacks_and_traverse(node); + + // pop the node's state off the geostate stack. + if (node_state) popStateSet(); +} void CullVisitor::apply(Group& node) { @@ -824,7 +847,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) if (!bs.isValid()) { - std::cout << "bb invalid"<<&node<addLight(_renderStageLighting->_lightList.size()); + if (_renderStageLighting.valid()) + { + // need to re-implement by checking for lights in the scene + // by downcasting the positioned attribute list. RO. May 2002. + //primStats->addLight(_renderStageLighting->_lightList.size()); + } return RenderBin::getStats(primStats); } diff --git a/src/osgUtil/RenderStageLighting.cpp b/src/osgUtil/RenderStageLighting.cpp index 274cb2c00..cd534852a 100644 --- a/src/osgUtil/RenderStageLighting.cpp +++ b/src/osgUtil/RenderStageLighting.cpp @@ -16,7 +16,7 @@ RenderStageLighting::~RenderStageLighting() void RenderStageLighting::reset() { - _lightList.clear(); + _attrList.clear(); } void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous) @@ -30,8 +30,8 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous) } // apply the light list. - for(LightList::iterator litr=_lightList.begin(); - litr!=_lightList.end(); + for(AttrMatrixList::iterator litr=_attrList.begin(); + litr!=_attrList.end(); ++litr) { state.applyModelViewMatrix((*litr).second.get()); diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 09738f1d5..7823e06eb 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -325,10 +325,10 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil switch(_lightingMode) { case(HEADLIGHT): - renderStage->addLight(_light.get(),NULL); + renderStage->addPositionedAttribute(NULL,_light.get()); break; case(SKY_LIGHT): - renderStage->addLight(_light.get(),modelview); + renderStage->addPositionedAttribute(modelview,_light.get()); break; case(NO_SCENEVIEW_LIGHT): break;