SoDragger Class |
Base class for nodekits that move in response to click-drag-release mouse events.
Namespace: OIV.Inventor.Draggers
The SoDragger type exposes the following members.
Name | Description | |
---|---|---|
AffectsState | Returns true if a node has an effect on the state during traversal. | |
Callback | (Inherited from SoBaseKit.) | |
ClearOtherEventCallbacks | ||
Copy | Calls Copy(false). (Inherited from SoNode.) | |
Copy(Boolean) | Creates and returns an exact copy of the node. | |
CopyFieldValues(SoFieldContainer) | Calls CopyFieldValues(fc, false). (Inherited from SoFieldContainer.) | |
CopyFieldValues(SoFieldContainer, Boolean) | Copies the contents of fc's fields into this object's fields. | |
CreatePathToPart(String, Boolean) | Calls CreatePathToPart(partName, makeIfNeeded, (OIV.Inventor.SoPath ^)nullptr). (Inherited from SoBaseKit.) | |
CreatePathToPart(String, Boolean, SoPath) | Returns a path that begins at this nodekit and ends at partName. | |
CreatePathToThis | ||
Dispose |
Releases all resources used by SoDisposable.
(Inherited from SoDisposable.) | |
Distribute | (Inherited from SoNode.) | |
DoAction | (Inherited from SoBaseKit.) | |
EnableNotify | Notification at this Field Container is enabled (if flag == true) or disabled (if flag == false). | |
EnableValueChangedEvent | You can temporarily disable a dragger's valueChangedCallbacks. | |
Equals | Determines whether the specified Object is equal to the current Object. (Inherited from Object.) | |
FieldsAreEqual | Returns true if this object's fields are exactly equal to fc's fields. | |
Get | Returns the values of the fields of this object in the Open Inventor ASCII file format in the given string. | |
GetAllFields | Returns a list of fields, including the eventIn's and eventOut's. | |
GetAlternateRep | This method is called by actions to allow the node to provide an "alternate representation" when appropriate (typically depending on the action type). | |
GetBoundingBox | (Inherited from SoBaseKit.) | |
GetClassNodekitCatalog | Returns the OIV.Inventor.Nodekits.SoNodekitCatalog for this class. | |
GetEvent | ||
GetEventIn | Returns a the eventIn with the given name. | |
GetEventOut | Returns the eventOut with the given name. | |
GetField | Returns a the field of this object whose name is fieldName. | |
GetFieldName | Returns the name of the given field in the fieldName argument. | |
GetFields | Appends references to all of this object's fields to resultList, and returns the number of fields appended. | |
GetHandleEventAction | ||
GetHashCode |
Overrides GetHashCode().
(Inherited from SoNetBase.) | |
GetInitialTrackerDirectMode | Get the initial tracker direct mode. | |
GetLocalStartingPoint | ||
GetLocalToWorldMatrix | Calls GetLocalToWorldMatrix((OIV.Inventor.Actions.SoAction ^)nullptr). | |
GetLocalToWorldMatrix(SoAction) | ||
GetMatrix | (Inherited from SoBaseKit.) | |
GetMinGesture | Gets the number of pixels of movement required to initiate a constraint gesture. | |
GetMinGestureFloat | Float version of OIV.Inventor.Draggers.SoDragger.GetMinGesture(). | |
GetMinScale | Gets the smallest scale that any dragger will write. | |
GetMotionMatrix | Get the motion matrix. | |
GetName | Returns the name of an instance. | |
GetNodekitCatalog | Returns the OIV.Inventor.Nodekits.SoNodekitCatalog for this instance of OIV.Inventor.Nodekits.SoBaseKit. | |
GetPart | Searches the nodekit catalog (and those of all nested nodekits) for the part named partName. | |
GetPartString | Given a node or a path to a node, checks if the part exists in the nodekit, in a nested nodekit, or an element of a list part. | |
GetPartToLocalMatrix | ||
GetPickPath | ||
GetPrimitiveCount | (Inherited from SoBaseKit.) | |
GetRenderEngineMode | Returns the supported Render engine mode. | |
GetRenderUnitID | (Inherited from SoNode.) | |
GetStartMotionMatrix | ||
GetStringName | (Inherited from SoBase.) | |
GetSurrogatePartPickedName | ||
GetSurrogatePartPickedOwner | ||
GetSurrogatePartPickedPath | ||
GetTrackerDirectMode | Get the current tracker direct mode for this dragger. | |
GetTransformFast(SbMatrix, SbVec3f, SbRotation, SbVec3f, SbRotation) | ||
GetTransformFast(SbMatrix, SbVec3f, SbRotation, SbVec3f, SbRotation, SbVec3f) | ||
GetType | Gets the Type of the current instance. (Inherited from Object.) | |
GetViewportIsEnabled | (Inherited from SoBaseKit.) | |
GetViewportOrigin | (Inherited from SoBaseKit.) | |
GetViewportRegion | Obsolete. | |
GetViewportSize | (Inherited from SoBaseKit.) | |
GetViewVolume | Obsolete. Dragger must not store information related to viewer settings. | |
GetWorldStartingPoint | ||
GetWorldToLocalMatrix | Calls GetWorldToLocalMatrix((OIV.Inventor.Actions.SoAction ^)nullptr). | |
GetWorldToLocalMatrix(SoAction) | ||
GLRender | (Inherited from SoBaseKit.) | |
GLRenderBelowPath | (Inherited from SoNode.) | |
GLRenderInPath | (Inherited from SoNode.) | |
GLRenderOffPath | (Inherited from SoNode.) | |
GrabEventsCleanup | (Inherited from SoNode.) | |
GrabEventsSetup | (Inherited from SoNode.) | |
HandleEvent | (Inherited from SoBaseKit.) | |
HasDefaultValues | Returns true if all of the object's fields have their default values. | |
InvokeValueChanged | ||
IsBoundingBoxIgnoring | Returns true if bounding box computation should be ignored during OIV.Inventor.Actions.SoGetBoundingBoxAction traversal. | |
IsNotifyEnabled | Notification is the process of telling interested objects that this object has changed. | |
IsOverride | Returns the state of the override flag. | |
IsPathSurrogateInMySubgraph(SoPath) | (Inherited from SoInteractionKit.) | |
IsPathSurrogateInMySubgraph(SoPath, SoPath, String, SoPath) | Calls IsPathSurrogateInMySubgraph(pathToCheck, pathToOwner, surrogateNameInOwner, surrogatePathInOwner, true). (Inherited from SoInteractionKit.) | |
IsPathSurrogateInMySubgraph(SoPath, SoPath, String, SoPath, Boolean) | (Inherited from SoInteractionKit.) | |
IsSynchronizable | Gets the ScaleViz synchronizable state of this object. | |
IsTrackerDirectMode | ||
Pick | (Inherited from SoNode.) | |
RayPick | (Inherited from SoBaseKit.) | |
RegisterChildDragger | ||
RegisterChildDraggerMovingIndependently | ||
SaveStartParameters | ||
Search | (Inherited from SoBaseKit.) | |
Set(String) | This function allows field values of parts (nodes) to be set in several different parts simultaneously. | |
Set(String, String) | This function allows field values of parts (nodes) to be set. | |
SetHandleEventAction | ||
SetInitialTrackerDirectMode | Calls SetInitialTrackerDirectMode(OIV.Inventor.Draggers.SoDragger.TrackerDirectModes( .SoDragger.DEFAULT )). | |
SetInitialTrackerDirectMode(SoDraggerTrackerDirectModes) | Set the initial tracker direct mode for draggers not yet created. | |
SetMinGesture(Int32) | Sets the number of pixels of movement required to initiate a constraint gesture. | |
SetMinGesture(Single) | Float version of OIV.Inventor.Draggers.SoDragger.SetMinGesture(System.Int32). | |
SetMinScale | Sets the smallest scale that any dragger will write. | |
SetMotionMatrix | Set the motion matrix. | |
SetName | (Inherited from SoBase.) | |
SetOverride | Turns the override flag on or off. | |
SetPart | Inserts the given node (not a copy) as the new part specified by partName. | |
SetPartAsDefault(String, SoNode) | Calls SetPartAsDefault(partName, newNode, true). (Inherited from SoInteractionKit.) | |
SetPartAsDefault(String, String) | Calls SetPartAsDefault(partName, newNodeName, true). (Inherited from SoInteractionKit.) | |
SetPartAsDefault(String, SoNode, Boolean) | (Inherited from SoInteractionKit.) | |
SetPartAsDefault(String, String, Boolean) | (Inherited from SoInteractionKit.) | |
SetPartAsPath | Sets any public part in the interaction kit as a "surrogate" path instead. | |
SetStartingPoint(SbVec3f) | ||
SetStartingPoint(SoPickedPoint) | ||
SetSynchronizable | Sets this to be a ScaleViz synchronizable object. | |
SetTempPathToThis | ||
SetToDefaults | Sets all fields in this object to their default values. | |
SetTrackerDirectMode | Calls SetTrackerDirectMode(OIV.Inventor.Draggers.SoDragger.TrackerDirectModes( .SoDragger.DEFAULT )). | |
SetTrackerDirectMode(SoDraggerTrackerDirectModes) | Sets the tracker direct mode for this dragger (see description above). | |
SetViewportRegion | Obsolete. | |
SetViewVolume | Obsolete. | |
ToString |
Converts this SoBase structure to a human readable string.
(Inherited from SoBase.) | |
Touch | Marks an instance as modified, simulating a change to it. | |
TransformMatrixLocalToWorld | ||
TransformMatrixToLocalSpace | ||
TransformMatrixWorldToLocal | ||
UnregisterChildDragger | ||
UnregisterChildDraggerMovingIndependently | ||
WorkFieldsIntoTransform | ||
Write | (Inherited from SoBaseKit.) |
Name | Description | |
---|---|---|
boundingBoxCaching | (Inherited from SoInteractionKit.) | |
boundingBoxIgnoring | Whether to ignore this node during bounding box traversal. | |
enableCallbacks | If set to false, motion, start and finish callbacks are disabled. | |
isActive | true when mouse is down and dragging, else false. | |
IsDisposable | ISafeDisposable interface implementation.
(Inherited from SoDisposable.) | |
pickCulling | Set pick caching mode. | |
renderCaching | Obsolete. Set render caching mode. | |
renderCulling | Set render culling mode. | |
UserData |
Gets or sets the user data to be contained by the field container.
(Inherited from SoFieldContainer.) |
Name | Description | |
---|---|---|
FinishDragging | ||
MouseMove | ||
StartDragging | ||
ValueChanged |
OIV.Inventor.Draggers.SoDragger is the base class for all nodekits you move by using the mouse to click-drag-and-release. More specifically, they are operated by a start (mouse button 1 pressed over dragger to pick it), followed by dragging (mouse motion events are interpreted by the dragger and result in some form of motion and/or change to a field), followed by finish (mouse up).
Each dragger has a different paradigm for interpreting mouse motion and changing its fields as a result. Draggers map 2D mouse motion into motion of a point on 3D lines, planes, spheres, or cylinders. (See the OIV.Inventor.Projectors.SbProjector reference pages.) Then they react to this motion of a point through 3-space by scaling, translating, or rotating. For example, OIV.Inventor.Draggers.SoTranslate2Dragger maps mouse motion onto a 3D plane, then translates to follow the cursor as it moves within that plane.
Beginning with version 3.0, draggers also respond to tracked input device events (see OIV.Inventor.Events.SoControllerButtonEvent and OIV.Inventor.Events.SoTrackerEvent) in order to support immersive VR devices like a wand. Interaction is started by pressing wand button 1 when the tracker "ray" intersects the dragger's geometry. Analogous to 2D, in which the interaction is driven by tracking the ray from the 2D mouse cursor, in 3D the interaction is driven by tracking the ray emanating from the tracking device.
Beginning with version 5.0, draggers can also take position and orientation changes directly from the tracker's position and orientation. Specifically the difference between the tracker's current values and the values at the start of the interaction is applied as an incremental change to the dragger. In general this is a more natural way to manipulate objects in an immersive environment. You can use the OIV.Inventor.Draggers.SoDragger.SetTrackerDirectMode(OIV.Inventor.Draggers.SoDragger.TrackerDirectModes) method to enable this behavior.
If mode is NONE, the dragger will not use tracker values directly (but it will still respond to tracker events in the version 3.0 way).
If mode is DEFAULT, the dragger's natural default direct behavior will be used (either NONE, MOVE, ROTATE, or FREE depending on the dragger class).
If mode is MOVE or ROTATE, the dragger will use the tracker's position or orientation directly.
If mode is FREE, the dragger will use the tracker's position and orientation directly.
Every dragger has fields that describe its current state. Scaling draggers have a scaleFactor field, rotational draggers have a rotation field, etc. All draggers have the OIV.Inventor.Draggers.SoDragger.isActive field, defined in this class. It is true while the dragger is being dragged, false otherwise.
Draggers that have only one part to pick and one motion field are called simple draggers. Examples are the OIV.Inventor.Draggers.SoRotateDiscDragger, OIV.Inventor.Draggers.SoScale1Dragger, and OIV.Inventor.Draggers.SoTranslate2Dragger.
Draggers that create assemblies out of other draggers and then orchestrate the motion of the whole assembly are called composite draggers. OIV.Inventor.Draggers.SoTransformBoxDragger is a composite dragger made entirely of simple draggers. OIV.Inventor.Draggers.SoDirectionalLightDragger contains both a simple dragger (OIV.Inventor.Draggers.SoRotateSphericalDragger) and a composite dragger (OIV.Inventor.Draggers.SoDragPointDragger) When using a composite dragger, the fields of the composite dragger are the ones you should work with. Draggers lower down in the assemblage usually have zeroed out values. For example, when you drag the face of a transformBox, an OIV.Inventor.Draggers.SoTranslate2Dragger, the transformBox "steals" the translation from the child dragger and transfers it up to the top of the composite dragger, where it effects all pieces of the assemblage.
Using draggers:
Draggers always keep their fields up to date, including while they are being dragged. So you can use field-to-field connections and engines to connect dragger values to other parts of your scene graph. Hence draggers can be easily utilized as input devices for mouse-driven 3D interface elements. You can also register value-changed delegates,which are called whenever any of the fields is changed. See example below.
This makes it easy to constrain draggers to keep their fields within certain limits: if the limit is exceeded, just set it back to the exceeded maximum or minimum. You can do this even as the dragger is in use, by constraining the field value within a value-changed delegatethat you add with OIV.Inventor.Draggers.SoDragger.ValueChanged(). In this case, be sure to temporarily disable the other value-changed delegatesusing OIV.Inventor.Draggers.SoDragger.EnableValueChangedEvent(System.Boolean). Doing this will prevent infinite-looping. See example below.
Also, if you set the field of a dragger through some method other than dragging, (by calling setValue(), for example), the dragger's internal OIV.Inventor.Sensors.SoFieldSensor will sense this and the dragger will move to satisfy that new value. This is useful to set the initial position (orientation, etc) of the dragger.
Draggers have a fixed orientation with respect to their local coordinate system. For example the OIV.Inventor.Draggers.SoTranslate1Dragger drags along its local X axis, the OIV.Inventor.Draggers.SoTranslate2Dragger drags in its local XY plane, etc. Some draggers, for example OIV.Inventor.Draggers.SoTrackballDragger, have a built-in rotation field that allows modifying the dragger's initial orientation. For other draggers you can put the dragger and a transform node under an OIV.Inventor.Nodes.SoSeparator and use the transform node to change the dragger's orientation. For example, rotate an OIV.Inventor.Draggers.SoTranslate1Dragger so it effectively drags along the world coordinate Y axis.
Draggers can have zero or more of the following delegates: - Start: called when manipulation starts
Motion: called after each mouse movement during manipulation
Value-changed: called when any of the dragger's fields change
Finish: called when manipulation finishes
Draggers vs Manipulators:
When you drag a dragger, the dragger only moves itself. Draggers do not change the state or affect objects that follow in the scene graph. For example a dragger does not ever behave like an OIV.Inventor.Nodes.SoTransform and change the current transformation matrix. Draggers are not transforms, even if they have field names like translation, rotation, scaleFactor. The application must connect the dragger to a transform node or use a delegate to update some other object in the scene graph (see example below).
However many draggers, such as OIV.Inventor.Draggers.SoTrackballDragger, have a corresponding OIV.Inventor.Manips.SoTransformManip, in this case OIV.Inventor.Manips.SoTrackballManip. The manipulator is a subclass of OIV.Inventor.Nodes.SoTransform, and affects other objects in the scene; it uses a trackball dragger to provide its user interface. In this way, draggers are employed extensively by manipulators. The dragger notifies its employer of start, motion, finish, and value changes. (See the various reference pages for more details on specific draggers and manipulators).
Customizing draggers:
All draggers are nodekits. However, draggers do not list their parts in the Parts section of the reference page. Instead, there is a section called Dragger Resources, more suited to describe the parts made available to the programmer. Each dragger has some parts you can pick on, and other parts that replace them when they are active or moving. These active parts are often just the same geometry in another color. Draggers also have parts for displaying feedback. Each of these parts has a default scene graph, as well as a special function within the dragger. Each part also has a resource name. All this information is contained in the DRAGGER RESOURCES section.
Since draggers are nodekits, you can change a part in a dragger that has already been built using the OIV.Inventor.Nodekits.SoBaseKit.SetPart(System.String, OIV.Inventor.Nodes.SoNode) method. For example, to change the "rotator" part of an OIV.Inventor.Draggers.SoTrackballDragger:
SoTrackballDragger dragger = new SoTrackballDragger(); dragger.SetPart( "rotator", geometry ); dragger.SetPart( "rotator", null );
SO_DRAGGER_DIR
Resources for each dragger class are loaded from SO_DRAGGER_DIR (if defined) when the first instance of that class is created. It is not necessary to set SO_DRAGGER_DIR before initializing Open Inventor.
OIV.Inventor.SoInput's default directory separator rules apply, i.e. the default directory separator is ":;" ( either colon or semicolon). Unfortunately this means that, on Microsoft Windows, the string "C:/myDir" will be interpreted as TWO separate directories "C/" and "/myDir".
When a dragger builds a part, it looks in the global dictionary (i.e. calls OIV.Inventor.Nodes.SoNode.GetByName(System.String)) for a node whose name is resourceName. For example the OIV.Inventor.Draggers.SoCenterballDragger lists a resource named "centerballRotator", therefore the scene graph for this dragger contains an OIV.Inventor.Nodes.SoSeparator named "centerballRotator". By putting a new entry in the dictionary (creating a node with this name), you can override the default geometry. However note two things: First, Open Inventor allows multiple nodes to have the same name and in this case OIV.Inventor.Nodes.SoNode.GetByName(System.String) returns the most recently named node. Second, when the first instance of a dragger class is created, the constructor automatically creates the default dragger geometry (either from the compiled-in scene graph or from the geometry file in SO_DRAGGER_DIR). Therefore to override default geometry using named nodes, the application must first create an instance of the dragger class, then create and name the replacement geometry. Subsequently created draggers will now use the replacement geometry.
Proxy geometry:
The OIV.Inventor.Nodekits.SoInteractionKit method OIV.Inventor.Nodekits.SoInteractionKit.SetPartAsPath(System.String, OIV.Inventor.SoPath) provides support for creating "stand-in" objects for parts in the interaction kit. The "stand-in", or "surrogate" part, is a path to an object that lies somewhere else in the scene graph. This could be used, for example, with an OIV.Inventor.Draggers.SoTranslate1Dragger to allow the user to click on some geometry and directly drag it (without displaying any separate dragger geometry). This technique is used, for example, in OIV.VolumeViz.Draggers.SoOrthoSliceDragger.
WYSIWYG Draggers:
Some of the default Open Inventor draggers have behaviors based on invisible geometry. For example, dragging a sphere by clicking on the surface of an invisible sphere. These behaviors may be unintuitive for some users. So Open Inventor also provides an alternative set of "WYSIWYG" draggers with semi-transparent handles in place of invisible geometry. For example, the OIV.Inventor.Draggers.SoCenterballDragger shown below.
To quickly enable these draggers set the environment variable SO_DRAGGER_DIR to "$OIVHOME/data/draggerWysiwyg" (for example using OIV.Inventor.SoPreferences). Applications that plan to use these draggers should make a local copy of this directory and set SO_DRAGGER_DIR to the local directory. This directory should be distributed with the application. For example:
Default OIV.Inventor.Draggers.SoCenterballDragger | WYSIWYG OIV.Inventor.Draggers.SoCenterballDragger |
When a dragger activates as a result of a mouse button press, it will handle the button down event (OIV.Inventor.Events.SoMouseButtonEvent) and subsequent mouse move events (OIV.Inventor.Events.SoLocation2Event). Other nodes in the scene graph will not see these events. Even nodes traversed before the dragger node will not see the mouse move events, because the dragger calls setGrabber() on the OIV.Inventor.Actions.SoHandleEventAction.
However, when the dragger de-activates as a result of releasing the mouse button, other nodes will see this event (OIV.Inventor.Events.SoMouseButtonEvent), because the dragger does not call setHandled(). This potentially includes nodes above the dragger, such as OIV.Inventor.Nodes.SoSelection, which defer event handling until after traversing their children. This is not a problem for the standard OIV.Inventor.Nodes.SoSelection node because it ignores the button up event if it did not previously see the matching button down event. However custom node classes that process events should be aware of this behavior.
Create a simple dragger and add a valueChanged delegatethat will be called when the dragger has changed one of its fields.
SoTranslate1Dragger dragger = new SoTranslate1Dragger(); dragger.ValueChanged += new SoDragger.DraggerCallback( draggerCB ); root.AddChild(dragger);
SoTranslation trans = new SoTranslation();
trans.translation.ConnectFrom( dragger.translation );
root.AddChild(trans);
Implementation of a simple valueChanged callback that limits the range of the dragger. Note: To avoid recursive calls, always disable the valueChanged callback before modifying the fields of the dragger.
const float X_MIN = -2; const float X_MAX = 2; public void draggerCB( SoDragger dragger ) { // Get dragger and current position SoTranslate1Dragger tdragger = (SoTranslate1Dragger)dragger; SbVec3f pos = tdragger.translation.Value; // Constrain dragger range if (pos[0] < X_MIN) { tdragger.EnableValueChangedEvent( false ); tdragger.translation.SetValue( X_MIN, 0, 0 ); tdragger.EnableValueChangedEvent( true ); } else if (pos[0] > X_MAX) { tdragger.EnableValueChangedEvent( false ); tdragger.translation.SetValue( X_MAX, 0, 0 ); tdragger.EnableValueChangedEvent( true ); } // Update object controlled by dragger (if appropriate) // . . . }
Dragger {
boundingBoxCaching | AUTO |
renderCulling | AUTO |
pickCulling | AUTO |
isActive | false |
callbackList | NULL |
All Parts
Part Name | Part Type | Default Type | NULL Default |
callbackList | NodeKitListPart | yes |
Extra Information for List Parts from Above Table
Part Name | Container Type | Possible Types |
callbackList | Separator | Callback, EventCallback |