root/OpenSceneGraph/trunk/examples/osgshadow/osgshadow.cpp @ 5747

Revision 5747, 5.5 kB (checked in by robert, 7 years ago)

Add compute of tight bounding box to enable better placement of the base plane.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/ArgumentParser>
2
3#include <osgProducer/Viewer>
4
5#include <osgShadow/OccluderGeometry>
6
7#include <osgDB/ReadFile>
8
9
10class ComputeBoundingBoxVisitor : public osg::NodeVisitor
11{
12public:
13    ComputeBoundingBoxVisitor():
14        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
15    {
16    }
17   
18    virtual void reset()
19    {
20        _matrixStack.clear();
21        _bb.init();
22    }
23   
24    osg::BoundingBox& getBoundingBox() { return _bb; }
25       
26    void apply(osg::Node& node)
27    {
28        traverse(node);
29    }
30   
31    void apply(osg::Transform& transform)
32    {
33        osg::Matrix matrix;
34        if (!_matrixStack.empty()) matrix = _matrixStack.back();
35       
36        transform.computeLocalToWorldMatrix(matrix,this);
37       
38        pushMatrix(matrix);
39       
40        traverse(transform);
41       
42        popMatrix();
43    }
44   
45    void apply(osg::Geode& geode)
46    {
47        for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
48        {
49            apply(geode.getDrawable(i));
50        }
51    }
52   
53    void pushMatrix(osg::Matrix& matrix)
54    {
55        _matrixStack.push_back(matrix);
56    }
57   
58    void popMatrix()
59    {
60        _matrixStack.pop_back();
61    }
62
63    void apply(osg::Drawable* drawable)
64    {
65        if (_matrixStack.empty()) _bb.expandBy(drawable->getBound());
66        else
67        {
68            osg::Matrix& matrix = _matrixStack.back();
69            const osg::BoundingBox& dbb = drawable->getBound();
70            if (dbb.valid())
71            {
72                _bb.expandBy(dbb.corner(0) * matrix);
73                _bb.expandBy(dbb.corner(1) * matrix);
74                _bb.expandBy(dbb.corner(2) * matrix);
75                _bb.expandBy(dbb.corner(3) * matrix);
76                _bb.expandBy(dbb.corner(4) * matrix);
77                _bb.expandBy(dbb.corner(5) * matrix);
78                _bb.expandBy(dbb.corner(6) * matrix);
79                _bb.expandBy(dbb.corner(7) * matrix);
80            }
81        }
82    }
83   
84protected:
85   
86    typedef std::vector<osg::Matrix> MatrixStack;
87
88    MatrixStack         _matrixStack;
89    osg::BoundingBox    _bb;
90};
91
92
93
94int main(int argc, char** argv)
95{
96    // use an ArgumentParser object to manage the program arguments.
97    osg::ArgumentParser arguments(&argc, argv);
98
99    // set up the usage document, in case we need to print out how to use this program.
100    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName() + " is the example which demonstrates using of GL_ARB_shadow extension implemented in osg::Texture class");
101    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
102    arguments.getApplicationUsage()->addCommandLineOption("-h or --help", "Display this information");
103    arguments.getApplicationUsage()->addCommandLineOption("--with-base-texture", "Adde base texture to shadowed model.");
104    arguments.getApplicationUsage()->addCommandLineOption("--no-base-texture", "Adde base texture to shadowed model.");
105
106    // construct the viewer.
107    osgProducer::Viewer viewer(arguments);
108
109    // set up the value with sensible default event handlers.
110    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
111
112    // get details on keyboard and mouse bindings used by the viewer.
113    viewer.getUsage(*arguments. getApplicationUsage());
114
115    // if user request help write it out to cout.
116    if (arguments.read("-h") || arguments.read("--help"))
117    {
118        arguments.getApplicationUsage()->write(std::cout);
119        return 1;
120    }
121
122    // any option left unread are converted into errors to write out later.
123    arguments.reportRemainingOptionsAsUnrecognized();
124
125    // report any errors if they have occured when parsing the program aguments.
126    if (arguments.errors())
127    {
128      arguments.writeErrorMessages(std::cout);
129      return 1;
130    }
131
132
133    osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments);
134    if (!model)
135    {
136        osg::notify(osg::NOTICE)<<"No model loaded, please specify a model to load."<<std::endl;
137        return 1;
138    }
139   
140    ComputeBoundingBoxVisitor cbbv;
141    model->accept(cbbv);
142    const osg::BoundingBox& bb = cbbv.getBoundingBox();
143    osg::Plane basePlane(0.0, 0.0, 1.0, -bb.zMin() );
144   
145    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
146
147    osg::ref_ptr<osgShadow::OccluderGeometry> occluder = new osgShadow::OccluderGeometry;
148    occluder->computeOccluderGeometry(model.get());
149    occluder->getBoundingPolytope().add(basePlane);
150    //geode->addDrawable(occluder.get());
151   
152    osg::ref_ptr<osgShadow::ShadowVolumeGeometry> shadowVolume = new osgShadow::ShadowVolumeGeometry;
153    occluder->comptueShadowVolumeGeometry(osg::Vec4(0.5f,-.5f,-1.0f,0.0f), *shadowVolume);
154    geode->addDrawable(shadowVolume.get());
155
156
157    osg::ref_ptr<osg::Group> group = new osg::Group;
158    group->addChild(model.get());
159    group->addChild(geode.get());
160
161
162    viewer.setSceneData(group.get());
163
164    // create the windows and run the threads.
165    viewer.realize();
166
167    while (!viewer.done())
168    {
169      // wait for all cull and draw threads to complete.
170      viewer.sync();
171
172      // update the scene by traversing it with the the update visitor which will
173      // call all node update callbacks and animations.
174      viewer.update();
175         
176      // fire off the cull and draw traversals of the scene.
177      viewer.frame();
178    }
179   
180    // wait for all cull and draw threads to complete.
181    viewer.sync();
182
183    // run a clean up frame to delete all OpenGL objects.
184    viewer.cleanup_frame();
185
186    // wait for all the clean up frame to complete.
187    viewer.sync();
188
189    return 0;
190}
Note: See TracBrowser for help on using the browser.