5 /*! \defgroup GrpSystemNodeCores NodeCores
8 See \ref PageSystemNodesNCores for details.
12 /*! \page PageSystemNodesNCores Nodes & NodeCores
14 \latexonly Starter:NewChapter \endlatexonly
16 Of course the most important structures in a scene-graph are the actual nodes
17 that make up the graph.
19 OpenSG uses a somewhat different approach than many other systems. A
20 node is split into two parts: the Node and a NodeCore, both of which
21 are FieldContainers, so all that has been said before applies to them.
23 A Node keeps the general information: a children list, a parent pointer, a
24 bounding volume and a core pointer. Note that the node itself contains no
25 information about its type (e.g. transform, group, etc.). A Node cannot be
26 shared, every node can only be at one place in the graph, thus a single parent
27 pointer is enough. All nodes together define the topology of the graph,
28 without defining any content. Actions that depend on a position in the graph,
29 like accessing the accumulated matrix to the world coordinate system or the
30 world bounding volume, have to be done on the node, as it uniquely defines and
31 identifies the position in the graph.
33 Additionally, Nodes contain a traversal mask. When traversing a graph (see
34 \ref PageActions) some parts of the graph can be left out. To do that the
35 logical and of the Node's traversal mask and the Action's traversal mask is
36 checked if it's 0. If it is, the Node and all its descendents are not
37 traversed, otherwise they are. This allows splitting the graph into logical
38 partitions, that are only use for some actions (e.g. have a separate set of
39 moedls for ray intersection). To use this for rendering the osg::Viewport also
40 has a traversal mask that is used for rendering it.
42 A NodeCore carries the differentiating information for a node. There are
43 NodeCores for all the different functions needed in the tree: groups,
44 transformations, geometry and many more. NodeCores can be shared between
45 different nodes, thus they keep an array or actually a MultiField of Node
48 \image html node_core_share.png "Node & Node Core Sharing"
49 \image latex node_core_share.eps "Node & Node Core Sharing" width=8cm
51 The types of NodeCores using in OpenSG are divided into two large groups:
52 Groups (\ref PageSystemNCGroups) and Drawables (\ref PageSystemNCDrawables).
54 Thus to create a node to be put into a scene graph you need both a osg::Node
55 as well as a osg::NodeCore. To simplify creating these there are two
56 convenience functions.
58 osg::makeCoredNode is a templated function to creates a NodeCore of the
59 given type as well as a Node that goes with it and returns the NodePtr.
61 \example To create a Group node you need to do this:
64 NodePtr gr = makeCoredNode<Group>();
70 also possible to get access to the created NodeCore:
74 NodePtr gr = makeCoredNode<Transform>(&tr);
79 makeCoredNode allows the creation from scratch, in addition to that
80 there is makeNodeFor(), which allows creating a new Node for an existing
81 NodeCore, that might come from somewhere else:
84 TransformPtr tr = Transform::create();
85 NodePtr gr = makeNodeFor(tr);
88 Even with these convenience functions it is still necessary to carry
89 around two objects and two variable to manipulate the Node and the
90 NodeCore. As this can becomne rather tedious in larger applications,
91 there is a wrapper class that combines the two, the CoredNodePtr.
93 As the name implies, the CoredNodePtr is an extended NodeCorePtr that
94 internally handles the NodePtr. Due to cast operators it can be used
95 everywhere a normal NodeCorePtr can.
97 In addition to that, the CoredNodePtr features automatic refernce
98 counting in the way of s smart pointer. Thus the user doesn't have to
99 and shouldn't explicitly change the reference counts of the objects
100 assigned to a CoredNodePtr, a simple NullFC assignment will be enough to
103 It can not totally hide the distinction between Nodes and Cores, thus in
104 places where the NodePtr is needed (e.g. to add children to it), it has
105 to be accessed explicitly using the node() member function. Also the
106 begin/endEdit calls on the CoredNodePtr are not as efficient as the
107 calls on the NodePtr or NodeCorePtr, as they have to begin/end both the
108 Node and the Core using the given mask, which might result in
109 unnecessary changes being recorded.
111 \example The following code creates a torus geometry with a
112 transformation on top and deletes it afterwards:
115 typedef CoredNodePtr<Transform> TransformNodePtr;
116 typedef CoredNodePtr<Geometry> GeometryNodePtr;
118 GeometryNodePtr torus = makeTorusGeo( .5, 2, 8, 12 );
119 TransformNodePtr t = TransformNodePtr::create();
121 beginEditCP(t, Transform::MatrixFieldMask | Node::ChildrenFieldMask);
123 t->setMatrix(Matrix::identity());
124 t.node()->addChild(torus.node());
126 endEditCP(t, Transform::MatrixFieldMask | Node::ChildrenFieldMask);
128 // This keeps the torus in the graph still alive, due to refcounts
131 // This kills the whole graph, includiong the torus