Chapter Overview
| >What are NewActions >How to use NewActions >Details on actors >Details on the Actions >Creating Actors |
This chapter deals with fairly advanced topics, if you simply want to use the new actions it is probably sufficient to read What are NewActions and How to use NewActions
IntersectActor *pIntersectActor = IntersectActor::create();
Please note, that instances are created like those of scene graph elements with a call to create(), but since actors are no FieldContainers normal pointers are sufficient.
Next you need an action instance and add the actor to it. Please read the documentation of the actors you intend to add, if they have any special requirements. Some of them might only work with particular actions or they must be added in a specific order. The code to create an DepthFirstAction instance and add the actor looks like this:
DepthFirstAction *pDepthFirstAction = DepthFirstAction::create();
pDepthFirstAction->addActor(pIntersectActor);
The IntersectActor needs some setup before it can be used, e.g. you need to set the ray (which is of type OSG::Line) that should be tested against your scene:
// Ray from origin along positive x-axis
pIntersectActor->setRay(Line(Pnt3f(0.0, 0.0, 0.0), Vec3f(1.0, 0.0, 0.0)));
For a detailed description of the IntersectActor, please look at its documentation generated from the source.
The final step is applying the action to your graph. Just pass the root node to the apply method:
pDepthFirstAction->apply(pRootNode);
Here it is assumed that pRootNode is a NodePtr that points to the scene root. The traversal will now run and afterwards you can get the results from the IntersectActor:
// did the ray hit an object in the scene ? if(pIntersectActor->getHit()) { std::cout << "An object was hit." << std::endl; } else { std::cout << "Nothing was hit." << std::endl; }
Note that there is more information you can retrieve from the IntersectActor, at least in the case where an object was hit.
enterNode(const NodePtr &pNode) and a leaveNode(const NodePtr &pNode) method that is called when the actions enter or leave a node. The return value from enterNode/leaveNode has the follwing meaning:
Continue Everything ok. Skip Skip all children. Break Skip all children and remaining actors for this node. Quit Stop the traversal alltogether.start(void) and after it ends the stop(void) methods are called. Usually initialization and cleanup tasks are performed there. The node that is currently traversed is passed as a parameter to enterNode and leaveNode, and is also available via the getNode(void) method.getChild(UInt32 childIndex) method and are just the children the node has in the scene graph. Children may be excluded from the traversal with the setActive(UInt32 childIndex) method and they may be assigned priorities (via setPriority(UInt32 childIndex, PrirityType prio)) that affects their traversal order (if the action honors this). The so called extra children do not have a direct relation to the scene graph, they may be added by ExtendActorBase derived actors and are treated as if they were children of the current node, without changing the graph. Arbitrary nodes may be added to the set of extra children, even the node itself or its regular children.enterNode(const NodePtr &pNode) and leaveNode(const NodePtr &pNode) will be issued if necessary, that is if there is an actor that returns true from getEnterNodeFlag() and getLeaveNodeFlag() respectively.initMethod registers a functor with the actor, that is to be called when a node with a node core of the corresponding type is encountered. To allow for best possible performance there is a choice of how flexible the actor's functor storage has to be: EmptyFunctorStore This is the trivial functor store that does not store any functors at all. It can be used to indicate that an actor does not require to act upon entering or leaving a node. Alternatively, if you have an actor with fixed functionality you can code it inside the enterNode or leaveNode method (do not do this inside the OSG[ActorName]Base.{cpp,h,inl} files, though) and safe the overhead of calling a functor. SimpleFunctorStore Only one functor is stored, that is called for all types of node cores. It's a bit more flexible than the above variant, as you can change the functor at runtime, but results in similar behaviour. SingleFunctorStore Here also only one functor is stored, but along with a node cores type. The functor will only be called for cores of this type, for all other cores a default functor may be set. Note that only an exactly matching core type is accepted, i.e. for a derived node core a functor registered for the base class will not be called. If you consider using this functor store, you might think about using the MultiFunctorStore right away, as it is better equipped for future extensions. MultiFunctorStore The most versatile functor store available. Each functor that is registered has an associated node core type and will only be called for a matching type. Note that only an exactly matching core type is accepted, i.e. for a derived node core a functor registered for the base class will not be called. However, you can register the same functor for more than one type. There is also the possibility to register a default functor, which is used whenever no specific one is registered.On the left window pane you can enter data for the actor as a whole, like its name, parent class (either another actor or one of ExtendActorBase or BasicActorBase), functor storages, library and if the actor itself or its parent are part of OpenSG. The right window pane is for the actors state elements; click "New" to create one then fill in at least the name and type fields. Please read Details on Actor state so you can decide if you need to tick the "Hierarchical State" checkbox. To save the information to an .acd file, use the "Save" or "Save As" buttons; to generate the C++ code use the "Write ActorBase Code" and "Write Actor Code" buttons. Remember that changes should only be done in the non-base files, as the base files may be regenerated automatically at any time, thus overwriting changes.
1.4.3