OpenSceneGraph: Group nodes, transformation nodes, and switch nodes

3r3904. 3r3-31. 3r3887. 3r3904. 3r3885. The introduction of 3r3886. 3r3887. 3r3904. When drawing a point, line, or complex polygon in a three-dimensional world, the final result will ultimately be displayed on a flat, two-dimensional screen. Accordingly, three-dimensional objects pass a certain transformation path, turning into a set of pixels output to a two-dimensional window. 3r3887. 3r3904. 3r3887. 3r3904. The development of software tools that implement three-dimensional graphics has come, regardless of which one you choose, to approximately the same concept of both mathematical and algorithmic descriptions of the above transformations. Ideologically, both “clean” OpenGL-type graphics APIs and cool game engines like Unity and Unreal use similar mechanisms for describing the transformation of a three-dimensional scene. OpenSceneGraph is no exception. 3r3887. 3r3904. 3r3887. 3r3904. In this article we will review the mechanisms for grouping and transforming three-dimensional objects in OSG. 3r3887. 3r3904.

3r33890. 3r3887. 3r3904. 3r3885. 1. Model matrix, view matrix, and projection matrix

3r3887. 3r3904. Three basic matrices are involved in the mathematical transformation of coordinates, carrying out the transformation between different coordinate systems. Often, in terms of OpenGL, they are called 3r3-3120. matrix model

, 3r33120. matrix of the form

and 3r3-3120. 3r3121 projection matrix. . 3r3887. 3r3904. 3r3887. 3r3904. The model matrix is used to describe the location of an object in a 3D world. It converts vertices from 3r3-3120. the local coordinate system of the object

in 3r31-20. world coordinate system

. By the way, all the coordinate systems in OSG are 3r3-3120. right-handed

. 3r3887. 3r3904. 3r3887. 3r3904. The next step is the transformation of world coordinates into a view space, performed using a view matrix. Suppose we have a camera located at the origin of the world coordinate system. The inverse matrix of the camera conversion matrix is actually used as a view matrix. In the right-of-screw coordinate system, OpenGL, by default, always determines the camera located at the point (? ? 0) of the global coordinate system and is directed along the negative direction of the Z axis. 3r3887. 3r3904. 3r3887. 3r3904. I note that OpenGL does not separate the concepts of the model matrix and the view matrix. However, there is determined a model-view matrix that performs the transformation of the local coordinates of the object into the coordinates of the species space. This matrix, in fact, is the product of the matrix of the model and the matrix of the form. Thus, the transformation of a vertex V from local coordinates into a view space can be conventionally written as the product

3r3904. 3r3887. 3r3904. 3r33873. ` Ve = V * modelViewMatrix`

3r33879. 3r33880. 3r3887. 3r3904. The next important task is to determine how 3D objects will be projected onto the screen plane and calculate the so-called 3r3-3120. the clipping pyramid

- area of space containing objects to be displayed on the screen. The projection matrix is used to define the clipping pyramid defined in world space by six planes: left, right, bottom, top, near and far. OpenGL provides the gluPerapective () function, which allows you to define a clipping pyramid and a way to project a three-dimensional world onto a plane. 3r3887. 3r3904. 3r3887. 3r3904. The coordinate system obtained after the above transformations is called 3r3-3120. the normalized coordinate system of the device is

, has on each axis a range of change of coordinates from -1 to 1 and is a left-handed one. And, as a last step, the received data is projected to the port of display (viewport) of the window, defined by the rectangle of the client area of the window. After that, the 3D world appears on our 2D screen. The final value of the screen coordinates of the vertices of Vs can be expressed by the following transformation

3r3904. 3r3887. 3r3904. 3r33873. ` Vs = V * modelViewMatrix * projectionMatrix * windowMatrix`

3r33879. 3r33880. 3r3887. 3r3904. or

3r3904. 3r3887. 3r3904. 3r33873. ` Vs = V * MVPW`

3r33879. 3r33880. 3r3887. 3r3904. where MVPW is the equivalent transformation matrix, equal to the product of three matrices: model-view matrix, projection matrix and window matrix. 3r3887. 3r3904. 3r3887. 3r3904. Vs in this situation is a three-dimensional vector that determines the position of a 2D pixel with a depth value. By reversing the coordinate transformation operation, we get a line in three-dimensional space. Therefore, a 2D point can be viewed as two points — one on the near point (Zs = 0), the other on the far clipping plane (Zs = 1). The coordinates of these points in the three-dimensional space are

3r3904. 3r3887. 3r3904. 3r33873. ` V0 = (Xs, Ys, 0) * invMVPW`

V1 = (Xs, Ys, 1) * invMVPW

3r33879. 3r33880. 3r3887. 3r3904. where invMVPW is the inverse of MVPW. 3r3887. 3r3904. 3r3887. 3r3904. In all the examples considered so far, we created a single three-dimensional object in the scenes. In these examples, the local coordinates of the object always coincided with the global global coordinates. Now it's time to talk about the tools that allow placing in the scene a lot of objects and changing their position in space. 3r3887. 3r3904. 3r3887. 3r3904. 3r3885. 2. Group nodes 3r3886. 3r3887. 3r3904. The class osg :: Group is the so-called

group node 3r3121. scene graph in OSG. It can have any number of child nodes, including geometry node nodes or other group nodes. These are the most frequently used nodes with wide functionality. 3r3887. 3r3904. 3r3887. 3r3904. The osg :: Group class is derived from the osg :: Node class, and is accordingly inherited from the osg :: Referenced class. osg :: Group contains a list of child nodes, where each child node is controlled by a smart pointer. This ensures there are no memory leaks during cascading deletion of a scene tree branch. This class provides the developer with a number of public methods 3r3887. 3r3904. 3r33712. 3r3904. 3r33724. addChild () - appends a node to the end of the list of child nodes. On the other hand, there is a insertChild () method that places the child node at a specific position in the list, which is specified by an integer index or pointer to the node passed as a parameter. 3r3887. 3r3904.

3r3904. 3r33724. removeChild () and removeChildren () - remove a single node or group of nodes. 3r3887. 3r3904.

3r3904. 3r33724. getChild () - getting a pointer to a node by its index in the list

3r3904.

3r3904. 3r33724. getNumChildren () - getting the number of child nodes attached to this group. 3r3887. 3r3904.

3r3904.

3r3887. 3r3904.

` Manage parent nodes `

` Manage parent nodes `

` 3r3887. 3r3904. As we already know, the osg :: Group class manages groups of its child objects, among which there can be instances of osg :: Geode that control the geometry of scene objects. Both of these classes have an interface for managing parent nodes. 3r3887. 3r3904. 3r3887. 3r3904. OSG allows scene nodes to have several parent nodes (we'll talk about this sometime later). In the meantime, we consider the methods defined in osg :: Node, used for manipulating the parent nodes:`

3r3904. 3r33712. 3r3904. 3r33724. getParent () - returns an osg :: Group pointer containing a list of parent nodes. 3r3887. 3r3904.

3r3904. 3r33724. getNumParants () - returns the number of parent nodes. 3r3887. 3r3904.

3r3904. 3r33724. getParentalNodePath () - returns all possible paths to the root node of the scene from the current node. It returns a list of variables of the type osg :: NodePath. 3r3887. 3r3904.

3r3904.

3r3887. 3r3904. osg :: NodePath is a std :: vector of pointers to scene nodes. 3r3887. 3r3904. 3r3887. 3r3904. 3r3187. 3r3887. 3r3904. 3r3887. 3r3904. For example, for the scene shown in the picture below, the code is

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: NodePath & nodePath = child3-> getParentalNodePaths ()[0]; 3r3904. for (unsigned int i = 0; i 3r3-33199. {`

osg :: Node * node = nodePath*;*

//do something with the 3r3904 note.} 3r3904. will return the nodes Root, Child? Child2. 3r3887. 3r3904. 3r3887. 3r3904. You should not use memory management mechanisms to refer to parent nodes. When you delete the parent node, all the child nodes are automatically deleted, which may cause the application to crash. 3r3887. 3r3904. 3r3887. 3r3904. 3r3885. 3. Adding multiple models to the scene tree 3r3886. 3r3887. 3r3904. We illustrate the mechanism for using groups by the following example 3r3887. 3r3904. 3r3887. 3r3904.

3r3737. The full text of the example group [/b]

3r33737. main.h

3r3887. 3r3904. 3r33873. ` #ifndef MAIN_H`

#define MAIN_H

3r3904. #include

3r3904. #include

3r3904. #include

3r3904. 3r3904. #endif

3r33879. 3r33880. 3r3887. 3r3904. 3r33737. main.cpp

3r3887. 3r3904. 3r3887. 3r3904. 3r33873. ` #include "main.h"`

3r3904. int main (int argc, char * argv[])

{

(void) argc, (void) argv; 3r3904. 3r3904. osg :: ref_ptr

model1 = osgDB :: readNodeFile ("/data /cessna.osg"); 3r3904. osg :: ref_ptr

model2 = osgDB :: readNodeFile ("/data /cow.osg"); 3r3904. 3r3904. osg :: ref_ptr

root = new osg :: Group; 3r3904. root-> addChild (model1.get ()); 3r3904. root-> addChild (model2.get ()); 3r3904. 3r3904. osgViewer :: Viewer viewer; 3r3904. viewer.setSceneData (root.get ()); 3r3904. 3r3904. return viewer.run (); 3r3904.}

3r33879. 3r33880. 3r3887. 3r3904. 3r33900. 3r33900. 3r3887. 3r3904. Fundamentally, the example differs from all previous ones in that we load two three-dimensional models, and to add them to the scene we create a group root node and add our model files to it as child nodes 3r3887. 3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

root = new osg :: Group; 3r3904. root-> addChild (model1.get ()); 3r3904. root-> addChild (model2.get ()); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r33300. 3r3887. 3r3904. 3r3887. 3r3904. As a result, we get a scene consisting of two models - an airplane and a funny mirror cow. By the way, a mirror cow will not be a mirror if you do not copy its texture from OpenSceneGraph-Data /Images /reflect.rgb and the data /Images directory of our project. 3r3887. 3r3904. 3r3887. 3r3904. The osg :: Group class can accept any type of node as a child, including nodes of its type. In contrast, the osg :: Geode class does not contain any child nodes at all - it is a terminal node containing the geometry of the scene object. This fact is useful when figuring out whether a node is a node of the type osg :: Group or another type derived from osg :: Node. Consider a small example of

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

model = dynamic_cast

(osgDB :: readNodeFile ("/data /cessna.osg")); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. The value returned by the osgDB :: readNodeFile () function is always of type osg :: Node *, but it can be converted to its successor osg :: Group *. If the node node of the Cessna model is a group node, the conversion will succeed, otherwise the conversion will return NULL. 3r3887. 3r3904. 3r3887. 3r3904. You can also do this trick that works on most

compilers. 3r3904. 3r3887. 3r3904. 3r33873. ` //Load the model into the group node`

osg :: ref_ptr

group = ; 3r3904. //Transform it to the node

osg :: Node * node1 = dynamic_cast

(group.get ()); 3r3904. //Transform the group to a node implicitly

osg :: Node * node2 = group.get (); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. In performance critical areas of the code, it is better to use special conversion methods 3r3887. 3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

model = osgDB :: readNodeFile ("cessna.osg"); 3r3904. osg :: Group * convModel1 = model-> asGroup (); //Works fine

osg :: Geode * convModel2 = model-> asGeode (); //Returns NULL. 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r3885. 4. Transformation nodes

3r3887. 3r3904. Nodes osg :: Group can not do any transformations, except the possibility of moving to their child nodes. OSG provides the osg :: Transform class for spatial movement of geometry. This class is a successor of the osg :: Group class, but it is also abstract - in practice, its heirs are used instead, which implement various spatial transformations of geometry. When traversing a scene graph, the osg :: Transform node adds its own transformation to the current OpenGL transformation matrix. This is equivalent to the multiplication of the OpenGL transformation matrices performed by the glMultMatrix ()

command. 3r3904. 3r3887. 3r3904. 3r33333. 3r3887. 3r3904. 3r3887. 3r3904. This example of a scene graph can be translated into the following code on OpenGL

3r3904. 3r3887. 3r3904. 3r33873. ` glPushMatrix (); 3r3904. glMultMatrix (matrixOfTransform1); 3r3904. renderGeode1 (); 3r3904. 3r3904. glPushMatrix (); 3r3904. glMultMatrix (matrixOfTransform2); 3r3904. renderGeode2 (); 3r3904. glPopMatrix (); 3r3904. 3r3904. glPopMatrix (); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. We can say that the position of the Geode1 is set in the coordinate system Transform? and the position of the Geode2 is set in the coordinate system Transform? shifted relative to Transform1. At the same time, in OSG, you can enable positioning in absolute coordinates, which will lead to an object behavior equivalent to the result of the glGlobalMatrix () OpenGL command`

3r3904. 3r3887. 3r3904. 3r33873. ` transformNode-> setReferenceFrame (osg :: Transform :: ABSOLUTE_RF); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. You can switch back to positioning mode with relative coordinates`

3r3904. 3r3887. 3r3904. 3r33873. ` transformNode-> setReferenceFrame (osg :: Transform :: RELATIVE_RF); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r3885. 5. The concept of the coordinate transformation matrix 3r3r6886. 3r3887. 3r3904. The osg :: Matrix type is an OSG base type not managed by smart pointers. It provides an interface to 4x4 matrix operations describing coordinate transformations, such as moving, rotating, scaling, and calculating projections. The matrix can be specified explicitly`

3r3904. 3r3887. 3r3904. 3r33873. ` //Single matrix 4x4`

osg :: Matrix mat (1.0f, 0.0f, 0.0f, 0.0f,

0.0f, 1.0f, 0.0f, 0.0f,

0.0f, 0.0f, 1.0f, 0.0f,

0.0f , 0.0f, 0.0f, 1.0f); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. The class osg :: Matrix provides the following public methods:

3r3904. 3r3887. 3r3904. 3r33712. 3r3904. 3r33724. postMult () and operator * () is the right multiplication of the current matrix by the matrix or vector, passed as a parameter. The preMult () method performs multiplication on the left. 3r3887. 3r3904.

3r3904. 3r33724. makeTranslate (), makeRotate () and makeScale () - reset the current matrix and create a 4x4 matrix describing the movement, rotation and scaling. their static versions translate (), rotate () and scale () can be used to create a matrix object with specific parameters. 3r3887. 3r3904.

3r3904. 3r33724. invert () - calculation of the inverse current matrix. Its static version of inverse () takes as its parameter a matrix and returns a new matrix, the inverse of the given. 3r3887. 3r3904.

3r3904.

3r3887. 3r3904. OSG understands matrices as matrixes of rows, and vectors as lines, therefore, to apply the matrix transformation to the vector, do so

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: Matrix mat = ; 3r3904. osg :: Vec3 vec = ; 3r3904. osg :: Vec3 resultVec = vec * mat; 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. The order of the matrix operations is easy to understand by looking at how the matrices are multiplied to obtain an equivalent transformation`

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: Matrix mat1 = osg :: Matrix :: scale (sx, sy, sz); 3r3904. osg :: Matrix mat2 = osg :: Matrix :: translate (x, y, z); 3r3904. osg :: Matrix resultMat = mat1 * mat2; 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. The developer should read the transformation process from left to right. That is, in the described code fragment, the vector is first scaled, and then it is moved. 3r3887. 3r3904. 3r3887. 3r3904. osg :: Matrixf contains float elements. 3r3887. 3r3904. 3r3887. 3r3904. 3r3885. 6. Application class osg :: MatrixTransform`

3r3887. 3r3904. Let's apply the received theoretical knowledge in practice, having loaded two models of the plane in different points of a scene. 3r3887. 3r3904. 3r3887. 3r3904.

3r3737. The full text of the example transform [/b]

3r33737. main.h

3r3887. 3r3904. 3r33873. ` #ifndef MAIN_H`

#define MAIN_H

3r3904. #include

3r3904. #include

3r3904. #include

3r3904. 3r3904. #endif

3r33879. 3r33880. 3r3887. 3r3904. 3r33737. main.cpp

3r3887. 3r3904. 3r3887. 3r3904. 3r33873. ` #include "main.h"`

3r3904. int main (int argc, char * argv[])

{

(void) argc; (void) argv; 3r3904. 3r3904. osg :: ref_ptr

model = osgDB :: readNodeFile ("/data /cessna.osg"); 3r3904. 3r3904. osg :: ref_ptr

transform1 = new osg :: MatrixTransform; 3r3904. transform1-> setMatrix (osg :: Matrix :: translate (-25.? 0.? 0.0)); 3r3904. transform1-> addChild (model.get ()); 3r3904. 3r3904. osg :: ref_ptr

transform2 = new osg :: MatrixTransform; 3r3904. transform2-> setMatrix (osg :: Matrix :: translate (25.? 0.? 0.0)); 3r3904. transform2-> addChild (model.get ()); 3r3904. 3r3904. osg :: ref_ptr

root = new osg :: Group; 3r3904. root-> addChild (transform1.get ()); 3r3904. root-> addChild (transform2.get ()); 3r3904. 3r3904. osgViewer :: Viewer viewer; 3r3904. viewer.setSceneData (root.get ()); 3r3904. 3r3904. return viewer.run (); 3r3904.}

3r33879. 3r33880. 3r3887. 3r3904. 3r33900. 3r33900. 3r3887. 3r3904. The example is actually quite trivial. We load the model of the aircraft from the file

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

model = osgDB :: readNodeFile ("/data /cessna.osg"); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. Create a transformation node 3r3887. 3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

transform1 = new osg :: MatrixTransform; 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. Set as a transformation matrix, moving the model along the X axis 25 units to the left

3r3904. 3r3887. 3r3904. 3r33873. ` transform1-> setMatrix (osg :: Matrix :: translate (-25.? 0.? 0.0)); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. Set up the transformation node for our model as a child of`

3r3904. 3r3887. 3r3904. 3r33873. ` transform1-> addChild (model.get ()); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. We proceed in a similar way with the second transformation, but as the matrix we set the movement to the right by 25 units of`

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

transform2 = new osg :: MatrixTransform; 3r3904. transform2-> setMatrix (osg :: Matrix :: translate (25.? 0.? 0.0)); 3r3904. transform2-> addChild (model.get ()); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. Create a root node and set the transform1 and transform2

nodes as child nodes for it. 3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

root = new osg :: Group; 3r3904. root-> addChild (transform1.get ()); 3r3904. root-> addChild (transform2.get ()); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. We create a viewer and, as scene data, we pass it the root node

3r3904. 3r3887. 3r3904. 3r33873. ` osgViewer :: Viewer viewer; 3r3904. viewer.setSceneData (root.get ()); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. Running the program gives this picture`

3r3904. 3r3887. 3r3904. 3r3658. 3r3887. 3r3904. 3r3887. 3r3904. The structure of the scene graph in this example is

3r3904. 3r3887. 3r3904. 3r3667. 3r3887. 3r3904. 3r3887. 3r3904. We should not be confused by the fact that the transformation nodes (Child 1.1 and Child 1.2) refer to the same child object of the airplane model (Child 2). This is a regular OSG mechanism, when one child node of a scene graph can have several parent nodes. Thus, it is not necessary for us to keep in memory two copies of the model in order to get two identical planes in the scene. Such a mechanism makes it very efficient to allocate memory in an application. The model will not be removed from memory as long as it is referred to as a child, at least one node. 3r3887. 3r3904. 3r3887. 3r3904. By its action, the osg :: MatrixTransform class is equivalent to the OpenGL commands glMultMatrix () and glLoadMatrix (), it implements all types of spatial transformations, but is difficult to use because of the need to calculate the transformation matrix. 3r3887. 3r3904. 3r3887. 3r3904. The osg :: PositionAttitudeTransform class works like OpenGL functions glTranslate (), glScale (), glRotate (). It provides public methods for converting child nodes: 3r3887. 3r3904. 3r3887. 3r3904. 3r33712. 3r3904. 3r33724. setPosition () - move the node to a given point in space, specified by the parameter osg :: Vec3

3r3904.

3r3904. 3r33724. setScale () - scale the object along the axes. The scaling factors for the respective axes are given by the parameter of the type osg :: Vec3

3r3904.

3r3904. 3r33724. setAttitude () - set the spatial orientation of the object. As a parameter, it accepts the quaternion of the transformation of rotation osg :: Quat, the constructor of which has several overloads, allowing to set the quaternion both directly (componentwise) and, for example, through Euler angles osg :: Quat (xAngle, osg :: X_AXIS, yAngle, osg :: Y_AXIS, zAngle, osg :: Z_AXIS) (angles are given in radians!)

3r3904.

3r3904.

3r3887. 3r3904. 3r3887. 3r3904. 3r3885. 7. Switch nodes

3r3887. 3r3904. Consider another class - osg :: Switch, which allows you to display or skip the rendering of a scene node, depending on some logical condition. It is an inheritor of the osg :: Group class and attaches a logical value to each of its child nodes. It has several useful public methods: 3r3887. 3r3904. 3r33712. 3r3904. 3r33724. Overloaded addChild (), as the second parameter accepting a logical key that indicates whether or not to display this node. 3r3887. 3r3904.

3r3904. 3r33724. setValue () - setting the visibility /invisibility key. Accepts the index of the child node that interests us and the desired key value. Accordingly, getValue () allows you to get the current key value by the index of the node of interest. 3r3887. 3r3904.

3r3904. 3r33724. setNewChildDefaultValue () - sets the default value for the visibility key of all new objects added as children. 3r3887. 3r3904.

3r3904.

3r3887. 3r3904. Consider the use of this class by example. 3r3887. 3r3904. 3r3887. 3r3904.

3r3737. The full text of the example switch [/b]

3r33737. main.h

3r3887. 3r3904. 3r33873. ` #ifndef MAIN_H`

#define MAIN_H

3r3904. #include

3r3904. #include

3r3904. #include

3r3904. 3r3904. #endif

3r33879. 3r33880. 3r3887. 3r3904. 3r3887. 3r3904. 3r33737. main.cpp

3r3887. 3r3904. 3r33873. ` #include "main.h"`

3r3904. int main (int argc, char * argv[])

{

(void) argc; (void) argv; 3r3904. 3r3904. osg :: ref_ptr

model1 = osgDB :: readNodeFile ("/data /cessna.osg"); 3r3904. osg :: ref_ptr

model2 = osgDB :: readNodeFile ("/data /cessnafire.osg"); 3r3904. 3r3904. osg :: ref_ptr

root = new osg :: Switch; 3r3904. root-> addChild (model1.get (), false); 3r3904. root-> addChild (model2.get (), true); 3r3904. 3r3904. osgViewer :: Viewer viewer; 3r3904. viewer.setSceneData (root.get ()); 3r3904. 3r3904. return viewer.run (); 3r3904.}

3r33879. 3r33880. 3r3887. 3r3904. 3r33900. 3r33900. 3r3887. 3r3904. An example is trivial - we load two models: the ordinary Cessna and the Cessna with the effect of a burning engine

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

model1 = osgDB :: readNodeFile ("/data /cessna.osg"); 3r3904. osg :: ref_ptr

model2 = osgDB :: readNodeFile ("/data /cessnafire.osg"); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. However, as the root node, we create osg :: Switch, which allows us, when adding models to it as child nodes, to set the visibility key for each of them to

3r3904. 3r3887. 3r3904. 3r33873. ` osg :: ref_ptr`

root = new osg :: Switch; 3r3904. root-> addChild (model1.get (), false); 3r3904. root-> addChild (model2.get (), true); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. That is, model1 will not be rendered, and model2 will be what we will observe by running the program 3r3887. 3r3904. 3r3887. 3r3904. 3r33838. 3r3887. 3r3904. 3r3887. 3r3904. By swapping the key values we will see the opposite pattern of

3r3904. 3r3887. 3r3904. 3r33873. ` root-> addChild (model1.get (), true); 3r3904. root-> addChild (model2.get (), false); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r33847. 3r3887. 3r3904. 3r3887. 3r3904. Having cocked both keys, we will see two models simultaneously 3r3887. 3r3904. 3r3887. 3r3904. 3r33873. `` root-> addChild (model1.get (), true); 3r3904. root-> addChild (model2.get (), true); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r33838. 3r3887. 3r3904. 3r3887. 3r3904. You can turn on the visibility and invisibility of the node that is a child of osg :: Switch right on the go, using the setValue ()`

method. 3r3904. 3r3887. 3r3904. 3r33873. ` switchNode-> setValue (? false); 3r3904. switchNode-> setValue (? true); 3r3904. switchNode-> setValue (? true); 3r3904. switchNode-> setValue (? false); 3r3904. 3r33879. 3r33880. 3r3887. 3r3904. 3r3887. 3r3904. 3r3885. Conclusion 3r3886. 3r3887. 3r3904. In this lesson we covered all the main classes in between.x nodes used in OpenSceeneGraph. Thus, we have laid another basic brick in the foundation of knowledge about the structure of this undoubtedly interesting graphic engine. The examples considered in the article, as before, 3r3889. available in my repository on github`

. 3r33891. To be continued

` 3r33900. 3r3904. 3r3904. 3r3904. 3r33897. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () ();`

3r3904. 3r33900. 3r3904. 3r3904. 3r3904. 3r3904.

It may be interesting

#### weber

Author**18-11-2018, 13:34**

Publication Date
#### Programming / Game development

Category- Comments: 0
- Views: 292

We take being #1 in Commercial Odor Remover Products & Systems very seriously. Here are some of the reasons you can trust Cupridyne Clean to bring you a solution to your Commercial Odor Control problem.