1. Introduction
The Osglight sample demonstrates how OSG uses lighting. 2. Description
First take a look at the Osglight effect diagram, as shown in the following figure:
3. Create Cube 3.1 to draw a polygon
The first is to create a cube in the scene, in which each polygon of the cube needs to be created, implemented in the function Createwall, and the Createwall function is prototyped as follows
osg::geometry* createwall (const osg::vec3& v1,const osg::vec3& v2,const osg::vec3& v3,osg::StateSet* Stateset)
1 1
The code that calls it is as follows:
Create front side.
Geode->adddrawable (Createwall (Bb.corner (0),
bb.corner (4),
Bb.corner (1),
Wall));
1 2 3 4 5 1 2 3 4 5
It can be known that it is created through a bounding box of a node, so what points are the corner of the bounding box respectively? This means that the corner (0) to Corner (7) respectively refers to which of the bounding box. Check the source code to know:
BoundingBox source
Inline Const vec_type Corner (unsigned int pos) const
{
return Vec_type (pos&1?_max.x () : _min.x (), pos&2?_max.y (): _min.y (), Pos&4?_max.z (): _min.z ());
}
1 2 3 4 5 1 2 3 4 5
That is to say Corner (0) to Corner (7) follows X, Y, z from small to large, and x precedence y precedence z order, specifically corner (0-7) as shown in the figure below:
With the above figure and Createwall being called (preceded by 0, 4, 1), we can know that the first three parameters in the function Createwall v1, V2, and V3 refer to the lower left, upper left, and lower right points of a quadrilateral respectively. (If this does not clear then the code will be a big obstacle to read) by reading Createwall code can be known, the function is mainly used to draw a polygon of the cube, the face is subdivided into 100x100 four-sided small squares to draw. 3.2 drawing a cube
Assembled into a cube by drawing 6 faces, the cube draws the following code:
osg::stateset* rootstateset = new Osg::stateset;
Root->setstateset (Rootstateset);
osg::stateset* wall = new Osg::stateset;
Wall->setmode (Gl_cull_face,osg::stateattribute::on);
osg::stateset* floor = new Osg::stateset;
Floor->setmode (Gl_cull_face,osg::stateattribute::on);
osg::stateset* roof = new Osg::stateset;
Roof->setmode (Gl_cull_face,osg::stateattribute::on);
osg::geode* Geode = new Osg::geode;
Create front side.
Geode->adddrawable (Createwall (Bb.corner (0), Bb.corner (4),
Bb.corner (1), wall));
Right side geode->adddrawable (Createwall (Bb.corner (1), Bb.corner (5),
Bb.corner (3), wall));
Left Side geode->adddrawable (Createwall (Bb.corner (2), Bb.corner (6), Bb.corner (0), wall));
Back Side geode->adddrawable (Createwall (Bb.corner (3), Bb.corner (7),
Bb.corner (2), wall));
Floor geode->adddrawable (Createwall (Bb.corner (0), Bb.corner (1),
Bb.corner (2), floor));
Roof geode->adddrawable (Createwall (Bb.corner (6), Bb.corner (7), Bb.corner (4), Roof));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 4 0 41 42 43 44 45 46 47 48
Draws six faces (sets the selection of faces, which are removed from the back), which are drawn in order for the back facing outward, and can be seen inside the cube after setting. 3.3 Drawing a light source
The light draw in the scene is done in the Createlights function, which draws two light sources, a light source fixed in the upper-left corner of the Cube (Corner (4)), and the other light is a moving light source, and the moving path is made up of 8 corner points of the cube. 3.4 Model Animations
A model is added to the osglight to calculate a bounding box, and the animation effect is added to the model, mainly through Modeltransformcallback. The implementation is as follows:
Class Modeltransformcallback:public Osg::nodecallback {public:modeltransformcallback (const Osg::BoundingS
phere& bs) {_firsttime = 0.0;
_period = 4.0f;
_range = Bs.radius () *0.5f; } virtual void operator () (osg::node* Node, osg::nodevisitor* nv) {osg::P Ositionattitudetrans
form* Pat = dynamic_cast<osg::P ositionattitudetransform*> (node);
Const osg::framestamp* Framestamp = Nv->getframestamp (); if (Pat && Framestamp) {if (_firsttime==0.0) {_f
Irsttime = Framestamp->getsimulationtime ();
} Double Phase = (Framestamp->getsimulationtime ()-_firsttime)/_period;
Phase-= floor (phase);
Phase *= (2.0 * OSG::P i);
Osg::quat rotation;
Rotation.makerotate (phase,1.0f,1.0f,1.0f); PAt->setattitude (rotation);
Pat->setposition (OSG::VEC3 (0.0f,0.0f,sin (phase)) *_range);
}//must traverse the Node ' s subgraph traverse (NODE,NV);
} double _firsttime;
Double _period;
Double _range; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
The main is to modify the position of the Attitude node OSG::P Ositionattitudetransform class, the class and Osg::matrixtransform similar, the main difference is OSG::P ositionattitudetransform more intuitive, Implemented by setting the zoom, shift amount, and rotation. Its matrix of matrices = SRT (in order to zoom, rotate, pan), and in Nodecallback, to modify the translation and rotation to achieve the effect of animation.
Osg::matrixtransform and OSG: Several differences between the:P Ositionattitudetransform:
1. Osg::matrixtransform combines various transformations in the order we give them, such as when we first define the translation, define the rotation and scale, then the MatrixTransform matrix is
M = TRS, that is, it performs the operation in exactly the order we specify. The specified order does not produce a large difference in the results.
2. OSG::P ositionattitudetransform Several interfaces simultaneously to obtain the translation, rotation, and scaling matrices, respectively:
1.setPosition Specifies the translation amount 2.setAttitude specifies the amount of
rotation
3.setScale Specifies the amount of scaling
1 2 3 1 2 3
Regardless of the order in which we set it, the result matrix m=srt (scaling and then rotating the last translation) is always in a fixed order. In addition to the OSG::P Ositionattitudetransform can also set the pivot position for rotation and scaling (generally, rotation and scaling are centered on the origin). But Positionattitudetransform provides for us to rotate and scale with other locations as axes. If we want to use matrixtranform to achieve the same effect as the positionattitudetransform, then we must set the order of three matrices multiplied by SRT. If the positionattitudetransform has a pivot position, then you need to be aware that you should pan to the pivot position, then rotate (and zoom), and then pan back when you are translating and rotating the transformation.