The rubberbandBox DSO uses interaction through the wand position and buttons to control the position and size of a 3D Box. The box is always aligned with the world coordinate axes and the coordinates are always given in world coordinates.
Here is an example of the rubberbandBox DSO being used in conjunction with the clipBox DSO. All data outside of the smaller box is being clipped.
And here is an example of the rubberbandBox DSO being used in conjunction with the both the clipBox and boxVolSlice DSOs. 3D cube data outside of the smaller box is being clipped by the boxClip DSO and the texture mapped slices are being generated by the boxVolSlice DSO.
The DSO displays a wireframe axis-aligned box. A 3D cursor is displayed and hovers 0.2 units out from the wand.
The user moves the 3D cursor to the box and presses a button to interact with it. There are two types of interaction:
For both types of interactions, the box highlights in appropriate ways when the cursor is in pickable proximity of something that can be picked and dragged.
The wand button that is used can be specified using the slb DSO (see below).
This mechanism for passing information to other DSOs will probably be changed in future versions of this DSO.
The box coordinates goes out to other DSOs by a pointer provided by the function getRubberbandBoxPtr.
Here are the relevant declarations:
typedef double Box[2][3];
Box *getRubberbandBoxPtr ();
The values at array positions [0][*] are the X, Y, and Z coordinates of the "minimum" corner of the box, and the values at [1][*] are the coordinates at the opposite corner of the box.
Any DSO may call this routine to get a pointer to the box coordinates, assuming that the rubberbandBox DSO is loaded. This call should be made as late a possible, preferably in the preFrame callback of the DSO (although the call need only be made once).
The data pointed to by the pointer returned by getRubberbandBoxPtr would typically be accessed each frame (either in the pre- or postFrame callback) in order to update the display based on the coordinates of the 3D box.
Note that this scheme results in some problems associated with frame accuracy (synchronization).
See the boxClip DSO for an example of a DSO that uses the box generated by this DSO.
The wireframe model that is generated to show the position
and highlighting of the 3D box is placed under the node
that is named
noClip
if that
node is present. If there is no node in the scene graph
with that name, it is placed under the node named
world
.
Normally, the node named
noClip
is created by the noClipWorld DSO.
The data that indicates the user's button presses are provided through
dtk shared memory. This shared memory can be set up through the
slb DSO.
The name of the shared memory can be specified through the
environment variable RUBBERBAND_BOX_BUTTON_SHM
.
If this
environment variable is not set, the name
rubberbandBoxButton
is used.
The box coordinates may (optionally) be placed into shared memory.
The name of the shared memory is given by the environment variable
RUBBERBAND_BOX_COORD_SHM
.
Any program (or DSO) may pick up the coordinates from this
shared memory.
The coordinates are written as six floats. The first three floats are the XYZ of the lower left corner of the box, the following three floats are the XYZ of the upper right corner of the box.
If this environment variable is not set, then the coordinates are not written to shared memory.
Here is a fragment of a shell script for running savgfly (diversifly) using this DSO. It actually uses a collection of DSOs working together: rubberbandBox, slb, boxClip, boxCull, and noClipWorldNode.
export SLB_1="rubberbandBoxButton"
export DF_DSO=":noClipWorldNode:slb:rubberbandBox:boxClip:boxCull"
savgfly -$device box.savg P01.sge
The slb DSO will put button presses for wand button 1 into the
dtk shared memory named rubberbandBoxButton
, which
is where the DSO rubberbandBox will look for it.
The rubberbandBox DSO will display its wireframe model of the
box under the noClip
scene graph node because
the noClipWorldNode DSO has been loaded.
The boxClip and boxCull DSOs will pick up the box coordinates by calling a routine provided by the rubberbandBox DSO.
In this example the file P01.sge looks like this:
LOAD hugeModel.pfb bigNode
ON P01 world
When the shell script is run, the models in
box.savg
and hugeModel.pfb
are displayed and are clipped to the 3D box generated by rubberbandBox.
The user can interactive change the box using the wand position and button 1
on the wand.
If the model in the file hugeModel.pfb is causing performance to be too slow, the user can issue the shell command:
dtk-writeLine BoxCullCmdShm 1000 "cull bigNode"
to apply culling to that object.
This puts the string "cull bigNode
" into dtk shared
memory where it will be read and acted upon by the boxCull DSO.
Of course, this shell command could also be issued indirectly
by a mechanism like a menu selection.