diff --git a/Make/makedirdefs b/Make/makedirdefs index 9c0dcf0a6..4d8a70a9d 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -134,6 +134,7 @@ EXAMPLE_DIRS = \ osghangglide\ osghud\ osgfxbrowser\ + osgforest\ osgimpostor\ osgkeyboard\ osglight\ diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index bf5bb335c..fcde2e94f 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -1146,6 +1146,33 @@ Package=<4> ############################################################################### +Project: "Example osgforest"=.\examples\osgforest\osgforest.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 osgGA + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgProducer + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgUtil + End Project Dependency +}}} + +############################################################################### + Project: "Example osgstereoimage"=.\examples\osgstereoimage\osgstereoimage.dsp - Package Owner=<4> Package=<5> diff --git a/VisualStudio/examples/osgforest/osgforest.dsp b/VisualStudio/examples/osgforest/osgforest.dsp new file mode 100755 index 000000000..4fdbf6a0b --- /dev/null +++ b/VisualStudio/examples/osgforest/osgforest.dsp @@ -0,0 +1,95 @@ +# Microsoft Developer Studio Project File - Name="Example osgforest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Example osgforest - 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 "osgforest.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 "osgforest.mak" CFG="Example osgforest - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Example osgforest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Example osgforest - 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)" == "Example osgforest - 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/osgforest.exe" /libpath:"../../../lib" + +!ELSEIF "$(CFG)" == "Example osgforest - 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" /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 /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgforestd.exe" /pdbtype:sept /libpath:"../../../lib" +# SUBTRACT LINK32 /incremental:no + +!ENDIF + +# Begin Target + +# Name "Example osgforest - Win32 Release" +# Name "Example osgforest - Win32 Debug" +# Begin Source File + +SOURCE=..\..\..\examples\osgforest\osgforest.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 diff --git a/examples/osgforest/GNUmakefile b/examples/osgforest/GNUmakefile new file mode 100644 index 000000000..edc69c6bc --- /dev/null +++ b/examples/osgforest/GNUmakefile @@ -0,0 +1,17 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgforest.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgforest + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgforest/GNUmakefile.inst b/examples/osgforest/GNUmakefile.inst new file mode 100644 index 000000000..035a78152 --- /dev/null +++ b/examples/osgforest/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgforest.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgforest + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgforest/osgforest.cpp b/examples/osgforest/osgforest.cpp new file mode 100644 index 000000000..c9d2f4400 --- /dev/null +++ b/examples/osgforest/osgforest.cpp @@ -0,0 +1,462 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +// for the grid data.. +#include "../osghangglide/terrain_coords.h" + +class Tree : public osg::Referenced +{ +public: + + Tree(): + _color(255,255,255,255), + _width(1.0f), + _height(1.0f), + _type(0) {} + + Tree(const osg::Vec3& position, const osg::UByte4& color, float width, float height, unsigned int type): + _position(position), + _color(color), + _width(width), + _height(height), + _type(type) {} + + osg::Vec3 _position; + osg::UByte4 _color; + float _width; + float _height; + unsigned int _type; +}; + + +osg::Geode* createTerrain(const osg::Vec3& origin, const osg::Vec3& size) +{ + osg::Geode* geode = new osg::Geode(); + + // --------------------------------------- + // Set up a StateSet to texture the objects + // --------------------------------------- + osg::StateSet* stateset = new osg::StateSet(); + + osg::Image* image = osgDB::readImageFile("Images/lz.rgb"); + if (image) + { + osg::Texture2D* texture = new osg::Texture2D; + texture->setImage(image); + stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); + } + + geode->setStateSet( stateset ); + + unsigned int numColumns = 38; + unsigned int numRows = 39; + unsigned int r; + unsigned int c; + + // compute z range of z values of grid data so we can scale it. + float min_z = FLT_MAX; + float max_z = -FLT_MAX; + for(r=0;rallocateGrid(numColumns,numRows); + grid->setOrigin(origin); + grid->setXInterval(size.x()/(float)(numColumns-1)); + grid->setYInterval(size.y()/(float)(numRows-1)); + + for(r=0;rsetHeight(c,r,(vertex[r+c*numRows][2]-min_z)*scale_z); + } + } + + geode->addDrawable(new osg::ShapeDrawable(grid)); + } + else + { + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows)); + osg::Vec2Array& t = *(new osg::Vec2Array(numColumns*numRows)); + osg::UByte4Array& color = *(new osg::UByte4Array(1)); + + color[0].set(255,255,255,255); + + float rowCoordDelta = size.y()/(float)(numRows-1); + float columnCoordDelta = size.x()/(float)(numColumns-1); + + float rowTexDelta = 1.0f/(float)(numRows-1); + float columnTexDelta = 1.0f/(float)(numColumns-1); + + osg::Vec3 pos = origin; + osg::Vec2 tex(0.0f,0.0f); + int vi=0; + for(r=0;rsetVertexArray(&v); + geometry->setColorArray(&color); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + geometry->setTexCoordArray(0,&t); + + for(r=0;raddPrimitiveSet(&drawElements); + int ei=0; + for(c=0;caddDrawable(geometry); + + osgUtil::SmoothingVisitor sv; + sv.smooth(*geometry); + } + + return geode; +} + +typedef std::vector< osg::ref_ptr > TreeList; + +float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } +int random(int min,int max) { return min + (int)((float)(max-min)*(float)rand()/(float)RAND_MAX); } + +void createTreeList(osg::Node* terrain,const osg::Vec3& origin, const osg::Vec3& size,unsigned int numTreesToCreate,TreeList& trees) +{ + + float max_TreeHeight = sqrtf(size.length2()/(float)numTreesToCreate); + float max_TreeWidth = max_TreeHeight*0.5f; + + float min_TreeHeight = max_TreeHeight*0.3f; + float min_TreeWidth = min_TreeHeight*0.5f; + + trees.reserve(trees.size()+numTreesToCreate); + + + for(unsigned int i=0;i_position.set(random(origin.x(),origin.x()+size.x()),random(origin.y(),origin.y()+size.y()),origin.z()); + tree->_color.set(random(128,255),random(128,255),random(128,255),255); + tree->_width = random(min_TreeWidth,max_TreeWidth); + tree->_height = random(min_TreeHeight,max_TreeHeight); + tree->_type = 0; + + if (terrain) + { + osgUtil::IntersectVisitor iv; + osg::ref_ptr segDown = new osg::LineSegment; + + segDown->set(tree->_position,tree->_position+osg::Vec3(0.0f,0.0f,size.z())); + iv.addLineSegment(segDown.get()); + + terrain->accept(iv); + + if (iv.hits()) + { + osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get()); + if (!hitList.empty()) + { + osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); + osg::Vec3 np = hitList.front().getWorldIntersectNormal(); + tree->_position = ip; + } + } + } + + trees.push_back(tree); + } +} + +osg::Geometry* createSprite( float w, float h, osg::UByte4 color ) +{ + // set up the coords + osg::Vec3Array& v = *(new osg::Vec3Array(4)); + osg::Vec2Array& t = *(new osg::Vec2Array(4)); + osg::UByte4Array& c = *(new osg::UByte4Array(1)); + + v[0].set(-w*0.5f,0.0f,0.0f); + v[1].set( w*0.5f,0.0f,0.0f); + v[2].set( w*0.5f,0.0f,h); + v[3].set(-w*0.5f,0.0f,h); + + c[0] = color; + + t[0].set(0.0f,0.0f); + t[1].set(1.0f,0.0f); + t[2].set(1.0f,1.0f); + t[3].set(0.0f,1.0f); + + osg::Geometry *geom = new osg::Geometry; + + geom->setVertexArray( &v ); + + geom->setTexCoordArray( 0, &t ); + + geom->setColorArray( &c ); + geom->setColorBinding( osg::Geometry::BIND_OVERALL ); + + geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4) ); + + return geom; +} + +osg::Geometry* createOrthogonalQuads( const osg::Vec3& pos, float w, float h, osg::UByte4 color ) +{ + // set up the coords + osg::Vec3Array& v = *(new osg::Vec3Array(8)); + osg::Vec2Array& t = *(new osg::Vec2Array(8)); + osg::UByte4Array& c = *(new osg::UByte4Array(1)); + + float rotation = random(0.0f,osg::PI/2.0f); + float sw = sinf(rotation)*w*0.5f; + float cw = cosf(rotation)*w*0.5f; + + v[0].set(pos.x()-sw,pos.y()-cw,pos.z()+0.0f); + v[1].set(pos.x()+sw,pos.y()+cw,pos.z()+0.0f); + v[2].set(pos.x()+sw,pos.y()+cw,pos.z()+h); + v[3].set(pos.x()-sw,pos.y()-cw,pos.z()+h); + + v[4].set(pos.x()-cw,pos.y()+sw,pos.z()+0.0f); + v[5].set(pos.x()+cw,pos.y()-sw,pos.z()+0.0f); + v[6].set(pos.x()+cw,pos.y()-sw,pos.z()+h); + v[7].set(pos.x()-cw,pos.y()+sw,pos.z()+h); + + c[0] = color; + + t[0].set(0.0f,0.0f); + t[1].set(1.0f,0.0f); + t[2].set(1.0f,1.0f); + t[3].set(0.0f,1.0f); + + t[4].set(0.0f,0.0f); + t[5].set(1.0f,0.0f); + t[6].set(1.0f,1.0f); + t[7].set(0.0f,1.0f); + + osg::Geometry *geom = new osg::Geometry; + + geom->setVertexArray( &v ); + + geom->setTexCoordArray( 0, &t ); + + geom->setColorArray( &c ); + geom->setColorBinding( osg::Geometry::BIND_OVERALL ); + + geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,8) ); + + return geom; +} + +osg::Node* createScene() +{ + osg::Vec3 origin(0.0f,0.0f,0.0f); + osg::Vec3 size(1000.0f,1000.0f,200.0f); + unsigned int numTreesToCreates = 10000; + + osg::ref_ptr terrain = createTerrain(origin,size); + + TreeList trees; + createTreeList(terrain.get(),origin,size,numTreesToCreates,trees); + + osg::Texture2D *tex = new osg::Texture2D; + tex->setImage(osgDB::readImageFile("Images/tree0.rgba")); + + osg::StateSet *dstate = new osg::StateSet; + { + dstate->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON ); + dstate->setTextureAttribute(0, new osg::TexEnv ); + + dstate->setAttributeAndModes( new osg::BlendFunc, osg::StateAttribute::ON ); + + osg::AlphaFunc* alphaFunc = new osg::AlphaFunc; + alphaFunc->setFunction(osg::AlphaFunc::GEQUAL,0.05f); + dstate->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON ); + + dstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + + dstate->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); + } + + + osg::Switch* switchNode = new osg::Switch; + + { + osg::Billboard* billboard = new osg::Billboard; + billboard->setStateSet(dstate); + + for(TreeList::iterator itr=trees.begin(); + itr!=trees.end(); + ++itr) + { + Tree& tree = **itr; + billboard->addDrawable(createSprite(tree._width,tree._height,tree._color),tree._position); + } + + switchNode->addChild(billboard); + } + + { + osg::Geode* geode = new osg::Geode; + geode->setStateSet(dstate); + + for(TreeList::iterator itr=trees.begin(); + itr!=trees.end(); + ++itr) + { + Tree& tree = **itr; + geode->addDrawable(createOrthogonalQuads(tree._position,tree._width,tree._height,tree._color)); + } + + switchNode->addChild(geode); + } + + { + + osg::Group* transform_group = new osg::Group; + //group->setStateSet(dstate); + + osg::Geometry* geometry = createOrthogonalQuads(osg::Vec3(0.0f,0.0f,0.0f),1.0f,1.0f,osg::UByte4(255,255,255,255)); + + for(TreeList::iterator itr=trees.begin(); + itr!=trees.end(); + ++itr) + { + Tree& tree = **itr; + osg::MatrixTransform* transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrix::scale(tree._width,tree._width,tree._height)*osg::Matrix::translate(tree._position)); + + osg::Geode* geode = new osg::Geode; + geode->setStateSet(dstate); + geode->addDrawable(geometry); + transform->addChild(geode); + transform_group->addChild(transform); + } + + switchNode->addChild(transform_group); + } + + switchNode->setSingleChildOn(1); + + osg::Group* scene = new osg::Group; + + scene->addChild(terrain.get()); + scene->addChild(switchNode); + + return scene; +} + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates the osg::Shape classes."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + osg::Node* node = createScene(); + + // add model to viewer. + viewer.setSceneData( node ); + + // create the windows and run the threads. + viewer.realize(); + + while( !viewer.done() ) + { + // wait for all cull and draw threads to complete. + viewer.sync(); + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + viewer.update(); + + // fire off the cull and draw traversals of the scene. + viewer.frame(); + + } + + // wait for all cull and draw threads to complete before exit. + viewer.sync(); + + return 0; +} diff --git a/examples/osggeometry/osggeometry.cpp b/examples/osggeometry/osggeometry.cpp index d843187ef..8cbe15084 100644 --- a/examples/osggeometry/osggeometry.cpp +++ b/examples/osggeometry/osggeometry.cpp @@ -40,7 +40,7 @@ struct NormalPrint { - void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3) const + void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool) const { osg::Vec3 normal = (v2-v1)^(v3-v2); normal.normalize(); diff --git a/include/osg/BlendColor b/include/osg/BlendColor index c17e09bd8..98a020c32 100644 --- a/include/osg/BlendColor +++ b/include/osg/BlendColor @@ -56,7 +56,7 @@ class SG_EXPORT BlendColor : public StateAttribute modes.push_back(GL_BLEND); } - void setConstantColor(osg::Vec4& color) { _constantColor = color; } + void setConstantColor(const osg::Vec4& color) { _constantColor = color; } inline osg::Vec4 getConstantColor() const { return _constantColor; } virtual void apply(State& state) const; diff --git a/include/osg/CullStack b/include/osg/CullStack index 140373da1..746e3231f 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -91,7 +91,7 @@ class SG_EXPORT CullStack /** Compute the pixel of an object at position v, with specified radius.*/ float pixelSize(const Vec3& v,float radius) const { - return _modelviewCullingStack.back()->pixelSize(v,radius); + return getCurrentCullingSet().pixelSize(v,radius); } /** Compute the pixel of an bounding sphere.*/ @@ -102,56 +102,59 @@ class SG_EXPORT CullStack inline void disableAndPushOccludersCurrentMask(NodePath& nodePath) { - _modelviewCullingStack.back()->disableAndPushOccludersCurrentMask(nodePath); + getCurrentCullingSet().disableAndPushOccludersCurrentMask(nodePath); } inline void popOccludersCurrentMask(NodePath& nodePath) { - _modelviewCullingStack.back()->popOccludersCurrentMask(nodePath); + getCurrentCullingSet().popOccludersCurrentMask(nodePath); } inline bool isCulled(const std::vector& vertices) { - return _modelviewCullingStack.back()->isCulled(vertices); + return getCurrentCullingSet().isCulled(vertices); } inline bool isCulled(const BoundingBox& bb) { - return bb.valid() && _modelviewCullingStack.back()->isCulled(bb); + return bb.valid() && getCurrentCullingSet().isCulled(bb); } inline bool isCulled(const BoundingSphere& bs) { - return _modelviewCullingStack.back()->isCulled(bs); + return getCurrentCullingSet().isCulled(bs); } inline bool isCulled(const osg::Node& node) { - return node.isCullingActive() && _modelviewCullingStack.back()->isCulled(node.getBound()); + return node.isCullingActive() && getCurrentCullingSet().isCulled(node.getBound()); } inline void pushCurrentMask() { - _modelviewCullingStack.back()->pushCurrentMask(); + getCurrentCullingSet().pushCurrentMask(); } inline void popCurrentMask() { - _modelviewCullingStack.back()->popCurrentMask(); + getCurrentCullingSet().popCurrentMask(); } typedef fast_back_stack > CullingStack; - CullingStack& getClipSpaceCullingStack() { return _clipspaceCullingStack; } + inline CullingStack& getClipSpaceCullingStack() { return _clipspaceCullingStack; } - CullingStack& getProjectionCullingStack() { return _projectionCullingStack; } + inline CullingStack& getProjectionCullingStack() { return _projectionCullingStack; } - CullingStack& getModelViewCullingStack() { return _modelviewCullingStack; } + inline CullingStack& getModelViewCullingStack() { return _modelviewCullingStack; } - CullingSet& getCurrentCullingSet() { return *_modelviewCullingStack.back(); } - +// inline CullingSet& getCurrentCullingSet() { return _modelviewCullingStack.back(); } +// inline const CullingSet& getCurrentCullingSet() const { return _modelviewCullingStack.back(); } + inline CullingSet& getCurrentCullingSet() { return *_modelviewCullingStack.back(); } + inline const CullingSet& getCurrentCullingSet() const { return *_modelviewCullingStack.back(); } + inline osg::Viewport* getViewport(); inline osg::RefMatrix& getModelViewMatrix(); inline osg::RefMatrix& getProjectionMatrix(); diff --git a/include/osg/CullingSet b/include/osg/CullingSet index 171d7a8ad..2d554b64b 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -28,6 +28,17 @@ class SG_EXPORT CullingSet : public Referenced CullingSet(); + + CullingSet(const CullingSet& cs): + Referenced(), + _mask(cs._mask), + _frustum(cs._frustum), + _occluderList(cs._occluderList), + _pixelSizeVector(cs._pixelSizeVector), + _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) + { + } + CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector): _mask(cs._mask), _frustum(cs._frustum), @@ -44,6 +55,34 @@ class SG_EXPORT CullingSet : public Referenced } } + inline void set(const CullingSet& cs) + { + _mask = cs._mask; + _frustum = cs._frustum; + _occluderList = cs._occluderList; + _pixelSizeVector = cs._pixelSizeVector; + _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; + } + + inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector) + { + _mask = cs._mask; + _frustum = cs._frustum; + _occluderList = cs._occluderList; + _pixelSizeVector = pixelSizeVector; + _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; + + _frustum.transformProvidingInverse(matrix); + + for(OccluderList::iterator itr=_occluderList.begin(); + itr!=_occluderList.end(); + ++itr) + { + itr->transformProvidingInverse(matrix); + } + + } + typedef std::vector OccluderList; typedef unsigned int Mask; @@ -218,9 +257,10 @@ class SG_EXPORT CullingSet : public Referenced void popOccludersCurrentMask(NodePath& nodePath); + virtual ~CullingSet(); + protected: - virtual ~CullingSet(); Mask _mask; Polytope _frustum; diff --git a/include/osg/TriangleFunctor b/include/osg/TriangleFunctor index 526f36171..34696d4e1 100644 --- a/include/osg/TriangleFunctor +++ b/include/osg/TriangleFunctor @@ -29,9 +29,13 @@ public: _vertexArraySize=0; _vertexArrayPtr=0; _modeCache=0; + _treatVertexDataAsTemporary=false; } virtual ~TriangleFunctor() {} + + void setTreatVertexDataAsTemporary(bool treatVertexDataAsTemporary) { _treatVertexDataAsTemporary=treatVertexDataAsTemporary; } + bool getTreatVertexDataAsTemporary() const { return _treatVertexDataAsTemporary; } virtual void setVertexArray(unsigned int,const Vec2*) { @@ -60,7 +64,7 @@ public: { const Vec3* vlast = &_vertexArrayPtr[first+count]; for(const Vec3* vptr=&_vertexArrayPtr[first];vptr _vertexCache; - + bool _treatVertexDataAsTemporary; }; diff --git a/runexamples.bat b/runexamples.bat index 1c5bcf1db..175f231b3 100644 --- a/runexamples.bat +++ b/runexamples.bat @@ -22,6 +22,9 @@ osgkeyboard echo osgpick fountain.osg osgpick fountain.osg +echo osgforest +osgforest + echo osgwindows glider.osg osgwindows glider.osg diff --git a/src/osgSim/LightPointNode.cpp b/src/osgSim/LightPointNode.cpp index e52cce538..fd3776776 100644 --- a/src/osgSim/LightPointNode.cpp +++ b/src/osgSim/LightPointNode.cpp @@ -241,7 +241,7 @@ void LightPointNode::traverse(osg::NodeVisitor& nv) double time=drawable->getReferenceTime(); double timeInterval=drawable->getReferenceTimeInterval(); - const osg::Polytope clipvol(cv->getModelViewCullingStack().back()->getFrustum()); + const osg::Polytope clipvol(cv->getCurrentCullingSet().getFrustum()); const bool computeClipping = false;//(clipvol.getCurrentMask()!=0); //LightPointDrawable::ColorPosition cp; diff --git a/src/osgUtil/IntersectVisitor.cpp b/src/osgUtil/IntersectVisitor.cpp index 5d6991a1f..0bbd024bf 100644 --- a/src/osgUtil/IntersectVisitor.cpp +++ b/src/osgUtil/IntersectVisitor.cpp @@ -369,7 +369,7 @@ struct TriangleIntersect } // bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r) - inline void operator () (const Vec3& v1,const Vec3& v2,const Vec3& v3) + inline void operator () (const Vec3& v1,const Vec3& v2,const Vec3& v3, bool treatVertexDataAsTemporary) { ++_index; @@ -465,8 +465,15 @@ struct TriangleIntersect osg::notify(WARN)<<" ("<(r,TriangleHit(_index-1,normal,r1,&v1,r2,&v2,r3,&v3))); + + if (treatVertexDataAsTemporary) + { + _thl.insert(std::pair(r,TriangleHit(_index-1,normal,r1,0,r2,0,r3,0))); + } + else + { + _thl.insert(std::pair(r,TriangleHit(_index-1,normal,r1,&v1,r2,&v2,r3,&v3))); + } _hit = true; } diff --git a/src/osgUtil/SmoothingVisitor.cpp b/src/osgUtil/SmoothingVisitor.cpp index 1c82dcf04..70146ae8c 100644 --- a/src/osgUtil/SmoothingVisitor.cpp +++ b/src/osgUtil/SmoothingVisitor.cpp @@ -70,15 +70,18 @@ struct SmoothTriangleFunctor } } - inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3 ) + inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, bool treatVertexDataAsTemporary ) { - // calc orientation of triangle. - osg::Vec3 normal = (v2-v1)^(v3-v1); - // normal.normalize(); + if (!treatVertexDataAsTemporary) + { + // calc orientation of triangle. + osg::Vec3 normal = (v2-v1)^(v3-v1); + // normal.normalize(); - updateNormal(normal,&v1); - updateNormal(normal,&v2); - updateNormal(normal,&v3); + updateNormal(normal,&v1); + updateNormal(normal,&v2); + updateNormal(normal,&v3); + } } }; diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index cd8e6497a..01de50dde 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -34,15 +34,19 @@ struct TriangleAcumulatorFunctor void setCoords( const Vec3* vbase ) { _vbase = vbase; } - inline void operator() ( const Vec3 &v1, const Vec3 &v2, const Vec3 &v3 ) + inline void operator() ( const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, bool treatVertexDataAsTemporary ) { - int p1 = (int)(&v1-_vbase); - int p2 = (int)(&v2-_vbase); - int p3 = (int)(&v3-_vbase); - if (p1==p2 || p1==p3 || p2==p3) return; - in_indices.push_back(p1); - in_indices.push_back(p2); - in_indices.push_back(p3); + + if (!treatVertexDataAsTemporary) + { + int p1 = (int)(&v1-_vbase); + int p2 = (int)(&v2-_vbase); + int p3 = (int)(&v3-_vbase); + if (p1==p2 || p1==p3 || p2==p3) return; + in_indices.push_back(p1); + in_indices.push_back(p2); + in_indices.push_back(p3); + } } };