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

Revision 5750, 6.3 kB (checked in by robert, 8 years ago)

Improved handling of bounding polytope

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