root/OpenSceneGraph/trunk/examples/osglight/osglight.cpp @ 13292

Revision 12529, 11.0 kB (checked in by robert, 3 years ago)

Replaced .osg with .osgt file usage

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osglight.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osgViewer/Viewer>
20
21#include <osg/Group>
22#include <osg/Node>
23
24#include <osg/Light>
25#include <osg/LightSource>
26#include <osg/StateAttribute>
27#include <osg/Geometry>
28#include <osg/Point>
29
30#include <osg/MatrixTransform>
31#include <osg/PositionAttitudeTransform>
32
33#include <osgDB/Registry>
34#include <osgDB/ReadFile>
35
36#include <osgUtil/Optimizer>
37#include <osgUtil/SmoothingVisitor>
38
39#include "stdio.h"
40
41
42// callback to make the loaded model oscilate up and down.
43class ModelTransformCallback : public osg::NodeCallback
44{
45    public:
46
47        ModelTransformCallback(const osg::BoundingSphere& bs)
48        {
49            _firstTime = 0.0;
50            _period = 4.0f;
51            _range = bs.radius()*0.5f;
52        }
53   
54        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
55        {
56            osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
57            const osg::FrameStamp* frameStamp = nv->getFrameStamp();
58            if (pat && frameStamp)
59            {
60                if (_firstTime==0.0)
61                {
62                    _firstTime = frameStamp->getSimulationTime();
63                }
64               
65                double phase = (frameStamp->getSimulationTime()-_firstTime)/_period;
66                phase -= floor(phase);
67                phase *= (2.0 * osg::PI);
68           
69                osg::Quat rotation;
70                rotation.makeRotate(phase,1.0f,1.0f,1.0f);
71               
72                pat->setAttitude(rotation);
73               
74                pat->setPosition(osg::Vec3(0.0f,0.0f,sin(phase))*_range);
75            }
76       
77            // must traverse the Node's subgraph           
78            traverse(node,nv);
79        }
80       
81        double _firstTime;
82        double _period;
83        double _range;
84
85};
86
87
88osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
89{
90    osg::Group* lightGroup = new osg::Group;
91   
92    float modelSize = bb.radius();
93
94    // create a spot light.
95    osg::Light* myLight1 = new osg::Light;
96    myLight1->setLightNum(0);
97    myLight1->setPosition(osg::Vec4(bb.corner(4),1.0f));
98    myLight1->setAmbient(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
99    myLight1->setDiffuse(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
100    myLight1->setSpotCutoff(20.0f);
101    myLight1->setSpotExponent(50.0f);
102    myLight1->setDirection(osg::Vec3(1.0f,1.0f,-1.0f));
103
104    osg::LightSource* lightS1 = new osg::LightSource;   
105    lightS1->setLight(myLight1);
106    lightS1->setLocalStateSetModes(osg::StateAttribute::ON);
107
108    lightS1->setStateSetModes(*rootStateSet,osg::StateAttribute::ON);
109    lightGroup->addChild(lightS1);
110   
111
112    // create a local light.
113    osg::Light* myLight2 = new osg::Light;
114    myLight2->setLightNum(1);
115    myLight2->setPosition(osg::Vec4(0.0,0.0,0.0,1.0f));
116    myLight2->setAmbient(osg::Vec4(0.0f,1.0f,1.0f,1.0f));
117    myLight2->setDiffuse(osg::Vec4(0.0f,1.0f,1.0f,1.0f));
118    myLight2->setConstantAttenuation(1.0f);
119    myLight2->setLinearAttenuation(2.0f/modelSize);
120    myLight2->setQuadraticAttenuation(2.0f/osg::square(modelSize));
121
122    osg::LightSource* lightS2 = new osg::LightSource;   
123    lightS2->setLight(myLight2);
124    lightS2->setLocalStateSetModes(osg::StateAttribute::ON);
125
126    lightS2->setStateSetModes(*rootStateSet,osg::StateAttribute::ON);
127   
128    osg::MatrixTransform* mt = new osg::MatrixTransform();
129    {
130        // set up the animation path
131        osg::AnimationPath* animationPath = new osg::AnimationPath;
132        animationPath->insert(0.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
133        animationPath->insert(1.0,osg::AnimationPath::ControlPoint(bb.corner(1)));
134        animationPath->insert(2.0,osg::AnimationPath::ControlPoint(bb.corner(2)));
135        animationPath->insert(3.0,osg::AnimationPath::ControlPoint(bb.corner(3)));
136        animationPath->insert(4.0,osg::AnimationPath::ControlPoint(bb.corner(4)));
137        animationPath->insert(5.0,osg::AnimationPath::ControlPoint(bb.corner(5)));
138        animationPath->insert(6.0,osg::AnimationPath::ControlPoint(bb.corner(6)));
139        animationPath->insert(7.0,osg::AnimationPath::ControlPoint(bb.corner(7)));
140        animationPath->insert(8.0,osg::AnimationPath::ControlPoint(bb.corner(0)));
141        animationPath->setLoopMode(osg::AnimationPath::SWING);
142       
143        mt->setUpdateCallback(new osg::AnimationPathCallback(animationPath));
144    }
145   
146    // create marker for point light.
147    osg::Geometry* marker = new osg::Geometry;
148    osg::Vec3Array* vertices = new osg::Vec3Array;
149    vertices->push_back(osg::Vec3(0.0,0.0,0.0));
150    marker->setVertexArray(vertices);
151    marker->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,1));
152   
153    osg::StateSet* stateset = new osg::StateSet;
154    osg::Point* point = new osg::Point;
155    point->setSize(4.0f);
156    stateset->setAttribute(point);
157   
158    marker->setStateSet(stateset);
159   
160    osg::Geode* markerGeode = new osg::Geode;
161    markerGeode->addDrawable(marker);
162   
163    mt->addChild(lightS2);
164    mt->addChild(markerGeode);
165   
166    lightGroup->addChild(mt);
167
168    return lightGroup;
169}
170
171osg::Geometry* createWall(const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3,osg::StateSet* stateset)
172{
173
174   // create a drawable for occluder.
175    osg::Geometry* geom = new osg::Geometry;
176   
177    geom->setStateSet(stateset);
178
179    unsigned int noXSteps = 100;
180    unsigned int noYSteps = 100;
181   
182    osg::Vec3Array* coords = new osg::Vec3Array;
183    coords->reserve(noXSteps*noYSteps);
184   
185   
186    osg::Vec3 dx = (v2-v1)/((float)noXSteps-1.0f);
187    osg::Vec3 dy = (v3-v1)/((float)noYSteps-1.0f);
188   
189    unsigned int row;
190    osg::Vec3 vRowStart = v1;
191    for(row=0;row<noYSteps;++row)
192    {
193        osg::Vec3 v = vRowStart;
194        for(unsigned int col=0;col<noXSteps;++col)       
195        {
196            coords->push_back(v);
197            v += dx;
198        }
199        vRowStart+=dy;
200    }
201   
202    geom->setVertexArray(coords);
203   
204    osg::Vec4Array* colors = new osg::Vec4Array(1);
205    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
206    geom->setColorArray(colors);
207    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
208   
209   
210    for(row=0;row<noYSteps-1;++row)
211    {
212        osg::DrawElementsUShort* quadstrip = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
213        quadstrip->reserve(noXSteps*2);
214        for(unsigned int col=0;col<noXSteps;++col)       
215        {
216            quadstrip->push_back((row+1)*noXSteps+col);
217            quadstrip->push_back(row*noXSteps+col);
218        }   
219        geom->addPrimitiveSet(quadstrip);
220    }
221   
222    // create the normals.   
223    osgUtil::SmoothingVisitor::smooth(*geom);
224   
225    return geom;
226 
227}
228
229
230osg::Node* createRoom(osg::Node* loadedModel)
231{
232    // default scale for this model.
233    osg::BoundingSphere bs(osg::Vec3(0.0f,0.0f,0.0f),1.0f);
234
235    osg::Group* root = new osg::Group;
236
237    if (loadedModel)
238    {
239        const osg::BoundingSphere& loaded_bs = loadedModel->getBound();
240
241        osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform();
242        pat->setPivotPoint(loaded_bs.center());
243       
244        pat->setUpdateCallback(new ModelTransformCallback(loaded_bs));
245        pat->addChild(loadedModel);
246       
247        bs = pat->getBound();
248       
249        root->addChild(pat);
250
251    }
252
253    bs.radius()*=1.5f;
254
255    // create a bounding box, which we'll use to size the room.
256    osg::BoundingBox bb;
257    bb.expandBy(bs);
258
259
260    // create statesets.
261    osg::StateSet* rootStateSet = new osg::StateSet;
262    root->setStateSet(rootStateSet);
263
264    osg::StateSet* wall = new osg::StateSet;
265    wall->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
266   
267    osg::StateSet* floor = new osg::StateSet;
268    floor->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
269
270    osg::StateSet* roof = new osg::StateSet;
271    roof->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
272
273    osg::Geode* geode = new osg::Geode;
274   
275    // create front side.
276    geode->addDrawable(createWall(bb.corner(0),
277                                  bb.corner(4),
278                                  bb.corner(1),
279                                  wall));
280
281    // right side
282    geode->addDrawable(createWall(bb.corner(1),
283                                  bb.corner(5),
284                                  bb.corner(3),
285                                  wall));
286
287    // left side
288    geode->addDrawable(createWall(bb.corner(2),
289                                  bb.corner(6),
290                                  bb.corner(0),
291                                  wall));
292    // back side
293    geode->addDrawable(createWall(bb.corner(3),
294                                  bb.corner(7),
295                                  bb.corner(2),
296                                  wall));
297
298    // floor
299    geode->addDrawable(createWall(bb.corner(0),
300                                  bb.corner(1),
301                                  bb.corner(2),
302                                  floor));
303
304    // roof
305    geode->addDrawable(createWall(bb.corner(6),
306                                  bb.corner(7),
307                                  bb.corner(4),
308                                  roof));
309
310    root->addChild(geode);
311   
312    root->addChild(createLights(bb,rootStateSet));
313
314    return root;
315   
316}   
317
318int main( int argc, char **argv )
319{
320    // use an ArgumentParser object to manage the program arguments.
321    osg::ArgumentParser arguments(&argc,argv);
322
323    // construct the viewer.
324    osgViewer::Viewer viewer;
325
326    // load the nodes from the commandline arguments.
327    osg::Node* loadedModel = osgDB::readNodeFiles(arguments);
328   
329    // if not loaded assume no arguments passed in, try use default mode instead.
330    if (!loadedModel) loadedModel = osgDB::readNodeFile("glider.osgt");
331   
332    // create a room made of foor walls, a floor, a roof, and swinging light fitting.
333    osg::Node* rootnode = createRoom(loadedModel);
334
335    // run optimization over the scene graph
336    osgUtil::Optimizer optimzer;
337    optimzer.optimize(rootnode);
338     
339    // add a viewport to the viewer and attach the scene graph.
340    viewer.setSceneData( rootnode );
341   
342
343    // create the windows and run the threads.
344    viewer.realize();
345
346    viewer.getCamera()->setCullingMode( viewer.getCamera()->getCullingMode() & ~osg::CullStack::SMALL_FEATURE_CULLING);
347
348    return viewer.run();
349}
Note: See TracBrowser for help on using the browser.