SGI Techpubs Library

IRIX 6.5  »  Books  »  Developer  »  
OpenGL Optimizer Programmer's Guide: An Open API for Large-Model Visualization
(document number: 007-2852-002 / published: 1998-06-09)    table of contents  |  additional info  |  download
find in page

Chapter 7. Interactive Highlighting and Manipulating

The tools discussed in this chapter enable you to highlight a portion of a rendered scene and then pick and manipulate only the highlighted object(s). For example, you might want to “pull” a piece off a car and examine and perhaps modify it, while the rest of the vehicle remains stationary in the background. You can successively pick and move pieces to disassemble a design.

This chapter discusses the following topics:

Overview of Highlighting and Picking

During highlighting, a selected piece of the scene graph appears in a distinct color. When you pick a highlighted object, subsequent interactions with the scene affect only the picked object. You can expand or contract the picked portion of the scene graph available for interaction by “climbing” or “descending” the scene graph from the picked node, which corresponds to the csShape under the cursor. When you are finished, you can undo interactions with a picked object and return the object to its original position. You can also tag certain types of nodes as unpickable and so force the selection to nodes higher in the scene graph.

How Picking Can Accelerate Rendering Rates

The independent manipulation of an object in a scene can help accelerate scene transformations. You can pick a small key object that renders quickly, orient it as you like, recover the net transformation developed during the interaction, and then apply the transform to the whole scene. As a result, the intermediate steps required to continuously manipulate a whole scene are no longer necessary. The traversal load on the host and the load on the graphics pipeline is decreased until you are ready to change the view of the whole scene.

Interacting With a Rendered Object: opPickDrawImpl

The opPickDrawImpl class provides keyboard and mouse controls for picking and highlighting. It is derived from opDrawImpl, which is the base class for the drawing implementations discussed in “Controlling Rendering: opKeyCallback and opDrawImpl”.

If you want to use the Motif library, opXmViewer uses opXmDrawImpl, which has methods analogous to a combination of opPickDrawImpl and opDefDrawImpl (see “opDrawImpl Subclasses Used In Sample Applications”).

Class Declaration for opPickDrawImpl

The class has the following main methods:

class opPickDrawImpl : public opDrawImpl 
{
public:
opPickDrawImpl(opViewer *viewer);
virtual ~opPickDrawImpl();

// --- redefined virtual functions
virtual void draw(unsigned frame);
virtual void pick(bool mouseDown, const csHit& hit);
virtual void seetup();
virtual void reset();

static bool keyHandler(opDrawImpl *,int);

  // --- Accessors
bool    getDeleteEnabled()    
bool    enableDelete();

csNode *getHighlightedNode()  
csNode *getPickRoot() 

// --- cant always pass this to the constructor
void    setReflMap(opReflMap *_rm) 
};

Methods in opPickDrawImpl

draw() 

Implements highlighting and picking for each frame update in opViewer::eventLoop(). Enter m to toggle this rendering function.

getPickRoot () 

Returns the root node of the modified scene graph developed by opPickDrawImpl(). Use the returned csNode to render the scene. For example, viewer->drawScene (pick_root) appears in the code for draw().

opPickDrawImpl(viewer) 


Constructs an opPickDrawImpl.

keyHandler() 

Defines the effects of the keyboard commands registered by calls to registerKey(). opDefDrawImpl has the keyboard controls described in “Key Bindings for opPickDrawImpl”.

pick() 

Sets a flag to switch interactive rendering only to picked objects. This is the effect of pressing the “m” key and any mouse button.

registerKey()  

Registers a keyboard command and specifies the function that interprets the command. The registerKey() method is inherited from opDrawImpl, discussed in “Controlling Rendering: opKeyCallback and opDrawImpl”. See the file opPickDrawImpl.cxx for details.

reset() 

Returns picked objects to their original position. opDefDrawImpl defines lowercase “r” to reset the scene.

setReflMap() 

Sets the reflection map used to control the lighting effects. can also be passed into the constructor. See Chapter 8, “Efficient High-Quality Lighting Effects: Reflection Mapping.”

Key Bindings for opPickDrawImpl

opPickDrawImpl defines key bindings that control its options in an opViewer application. These are the basic features:

  • In highlight mode, object colors change to indicate which objects you can pick.

  • The up- and down-arrow keys enlarge or shrink the set of selected objects.

  • When you click on any highlighted object with a mouse button, it will be picked.

  • Subsequent frames are rendered with all but the picked objects stationary.

The class constructor for opPickDrawImpl uses the methods registerKey() and keyHandler() to register the following keyboard commands, which you can change if you make a subclass (see “opDrawImpl Subclasses Used In Sample Applications” and the file opPickDrawImpl.cxx):

P 

Print highlighted portion of the scene graph.

u 

Unpick: Disable picking interaction, leaving the picked object at its current location. opDefDrawImpl becomes the opDrawImpl used by opViewer to control rendering.

X 

Delete picked objects.

m  

Toggles highlight and picking mode. opPickDrawImpl becomes the opDrawImpl used by opViewer to control rendering. Pressing a mouse button while in this mode picks a highlighted object.

UP ARROW 

Move highlight node up in scene-graph hierarchy, thus highlighting more objects.

DOWN ARROW 

Move highlight node down in scene-graph hierarchy towards the geometry under the cursor, thus highlighting fewer objects.

Scene Graph Modification: opPick

The class opPick provides scene-graph modification tools for picking and highlighting. It uses the csCamera picking method, which returns a csHit that interactively identifies objects in the scene graph.

opPickDrawImpl uses opPick to implement picking and highlighting. Use opPick if you are creating your own viewer or want different behavior than that defined in opPickDrawImpl. A typical application that uses an opPick would include the following lines of code (see the opPickDrawImpl source code for a more detailed example of how to use an opPick):

csCamera *camera = ....
opPick   *picker = ...
csNode   *root = picker->getRoot();
csHit hit;
csNode *pickedNode;
   
if (camera->
        pick (root, csWindow::getMouseX(), csWindow::getMouseY(), hit))
  {
    if (mouseDown)
        picker->pickup (hit, pickedNode);
    else
        picker->highlight (hit, pickedNode);
  }

Class Declaration for opPick

The class has the following main methods:

class opPick
{
public:
  // Creating and destroying
opPick (csGroup *root, opReflMap *rm=NULL);
~opPick ();
  // Accessor functions
csNode      *getHighlightedNode () 
csNode      *getPickedNode () 
csTransform *getPickTransform ()
csGroup     *getRoot () 

void    setHighlightOffset (int _hl_offset) 
int     getHighlightOffset () 

void    setHighlightColor (const csVec3f& _hl_color)
csVec3f getHighlightColor () const   

void    setInfoPosition (const csVec2f& _pos)
csVec2f getInfoPosition () const 

void    setReflMap (opReflMap *_rm) 
void    setForceDraw(opBool flag)

PickBranch *getLodPath () const 

  // Utility methods
void highlight  (const csHit& hit);
csTransform *pickupNode (const csHit& hit);
csTransform *pickupHighlightedNode ();
void drop ();
void removeHighlight ();
void reset ();
void ignoreType (csType *ignore_me);

Methods in opPick

drop() 

Leaves a picked object in its most recent position, by placing a new csTransform in the scene graph above the picked node.

getHighlightedNode() 


Returns the currently highlighted node.

getPickedNode() 


Returns the currently picked node.

getPickTransform() 


Returns the transform that should be used to manipulate the picked subgraph. You manipulate the picked subgraph by changing this matrix. See the example in “Sample Use of opPick”.

getRoot() 

Returns the root of the scene graph that you use for draw traversals when picking and highlighting. opPick reorganizes the scene graph, so use getRoot() to be sure you have the correct root node.

highlight(hit) 

Highlights the node specified by the csHit returned by the method csCamera::pick(). The highlighting is accomplished by insertion of an opHighlight node (see “Node to Override Appearances: opHighlight” for more information about how the choice is made which node to highlight).

The algorithm for choosing a node out of the csHit path uses hl_offset and the list of ignored types. The default node is the csShape node. If there is no shape node, it will choose the leaf node. If the hl_offset is nonzero, it will be used to adjust the index into the hit path, for example, if hl_offset is –2, node selected will be pickpath[index–2) where index is the index of the shape node. Modifier nodes, highlight nodes, and geometry nodes are ignored, as are any node types specified in the ignore list.

You can prevent nodes from being highlighted by calling ignoreType().

ignoreType(ignore_me) 


Specifies node types that cannot be picked.

opPick() 

Constructs the class. If you use a reflection map to light the scene, pass it to the constructor so that its effects will apply to highlighted nodes.

pickupHighlightedNode() 


Picks up a currently highlighted node.

The return value is a csTransform that pickupHighlightedNode() inserts into the scene graph above the picked node. The transform node allows you to control manipulation of the picked subgraph.

pickupNode() 

Picks a node found with csCamera::pick(). You can use highlight offset to define the picked node.

The return value is a csTransform that pickupNode() inserts into the scene graph above the picked node. The transform node allows you to control manipulation of the picked subgraph.

You can prevent nodes from being highlighted by calling ignoreType().

removeHighlight() 


Turns off highlighting.

reset()  

All currently and previously picked nodes are returned to their original position.

setForceDraw(flag) 


opPick tries to only draw the picked elements during pick node.

If flag is true then the entire graph under the true root is drawn. If flag is false the viewer draws only whatever is necessary for correct display. It is recommended to use this method with flag set to true only when it is absolutely necessary to draw the entire graph (for example, when the display window is resized or exposed). As soon as possible, call this method with flag set to false again. Calling setForceDraw() with flag set to true unnecessarily might result in a slowdown during picking and highlighting.

setHighlightOffset(_hl_offset) and getHighlightOffset() 


Set and get the offset in the scene graph from the node originally highlighted. The default value, 0, results in the leaf node of the scene graph being picked. This node is typically a csShape.

setHighlightColor(_hl_color) and getHighlightColor() 


Set and get the color of highlighted nodes. The default is yellow.

setInfoPosition(_pos) and getInfoPosition()  


Set and get information about the placement of the opInfoNode that displays the node name of the highlighted node.

setReflMap(_rm) 

Specifies the reflection map that sets the appearance properties of highlighted nodes. This is useful if the opReflMap is not available when the opPick is constructed.

Sample Use of opPick

These lines of code from the opPickDrawImpl source code sketch the use of an opPick in an opViewer application. Not all the lines required for a working application are shown.

Create the opPick

 

 

picker = new opPick
((csGroup *) viewer->getRoot());

The opPick modifies the scene graph, and defines a new root node for rendering.

 

pick_root = picker->getRoot();

 

Highlight or Pick, Given a csHit

 

 

 

Here the code assumes it has a csHit named hit and uses the key bindings of opPickDrawImpl to determine highlighting or picking.

These lines of code mimic the lines of code in

“Scene Graph Modification: opPick”.

 

if (mouseDown && (state & INPICK_PICKREADY))

{

picker->pickupNode (hit, pickedNode);

}

else

picker->highlight (hit, pickedNode);

 

Set Highlight Offset

 

 

 

For either mode, use the highlight offset to define exactly which nodes are affected.

 

hl_offset = picker->getHighlighOffset();

 

Set Mouse Control of Object Manipulation

 

 

 

If in the pick mode, to specify that opViewer mouse controls act on only the picked subgraph, set the pose csTransform node shown in Figure 2-1 to be the picked node's transform.

 

viewer->setMouseFocus
(picker->getPickTransform());

 

 

Draw

 

 

 

Draw the scene graph.

See

“Controlling Rendering: opKeyCallback and opDrawImpl”

 

viewer->update (pick_root);

 

Drop the Object, if Picked

 

 

 

When you are finished with the picked subgraph, leave the objects where they are, or restore them to their original position.

 

picker->drop ();

picker->reset ();


Node to Override Appearances: opHighlight

The OpenGL Optimizer mechanism for highlighting objects in a scene graph involves placing an opHighlight node in the scene graph as a temporary parent to the object or objects to be highlighted. opHighlight will override the appearance of its children using the csContext appearance override mechanism. opPick uses opHighlight for its effects.

You can also override the rendering appearance of a selected subgraph with the Cosmo3D methods csContext::pushOverrideAppearance() and csContext::popOverrideAppearance(), but using opHighlight is more convenient.

Class Declaration for opHighlight

The class has the following main methods:

class opHighlight : public csGroup
{
public:
// Creating and destroying
opHighlight (opReflMap *rm = NULL);
~opHighlight ();

// Accessor functions
csAppearance *getHighlightAppearance () const
void setHighlightAppearance (csAppearance *_hl_appear) 

void          setColor (const csVec3f& color);
csVec3f       getColor () const

// Utility methods
virtual csTravDirective drawVisit (csDrawAction *da);
};

If you are using an opReflMap to light the scene, you must pass it to opHighlight for appropriate lighting effects.

Sample Use of opHighlight for Highlighting

The basic highlighting and picking operation inserts an opHighlight into the scene graph between a selected node and the rest of the scene graph. The opHighlight then controls the appearance of the subgraph.

This example sketches the use of an opHighlight. It includes the insertion of a csTransform node below the opHighlight, to allow manipulation of objects in the subgraph. Not all the lines required for a working application are shown.

Create an opHighlight

 

 

hl_node = new opHighlight ();

 

Determine the subgraph to highlight

 

 

hl_subgraph = myHighlightSelectionFunc();

 

Insert and highlight node in scene graph

 

 

hl_node -> addChild(hlsubgraph);parentof_hl_subgraph->replaceChild(hl_subgraph, hl_node);

 

Remove highlighting

 

 

parent...->replaceChild(hl_node, hl_subgraph);


OpenGL Optimizer Programmer's Guide: An Open API for Large-Model Visualization
(document number: 007-2852-002 / published: 1998-06-09)    table of contents  |  additional info  |  download

    Front Matter
    About This Guide
    Part I. Getting Started
    Part II. High-Level Strategic Tools for Fast Rendering
    Part III. Specific Tools for Fast Rendering
    Part IV. Managing and Rendering Higher-Order Geometric Primitives
    Part V. Traversers, Low-Level Geometry Processing, and Multiprocessing
    Part VI. Utilities and Troubleshooting
    Part VII. Appendices
    Glossary
    Index


home/search | what's new | help