So far you have learned that you can access any node in a existing VRML scene that has a DEFed name. You can actually do more. Since you can inspect exposed field values, you can also retrieve children nodes. We are going to demo this in the next example. It will retrieve all the Viewpoints from a Group node called ``Viewpoints'' in a VRML scene. The Java applet then generates navigation nodes inserted into the applet. Note that this example is still pretty useless. Useful things have a tendency to become quite complex.
Contents: | getEventOut, children nodes |
HTML page: | eai/navigate/navigate-dyn.html |
JAVA code: | eai/navigate/NavigateDyn.java |
Directory: | (dir) |
DEF Viewpoints Group { children [ DEF Entry Viewpoint { position 0 1 15 description "Entry" } DEF AcrossTheRoom Viewpoint { ............ } ............ ] }
init()
method is fairly standard, so we will not comment
it. Now let's see how we exact these nodes:
We first declare an array variable to store the nodes:
Node[] VPList ;We extract the children in the
initScene()
method:
// Get the Group node called Viewpoints Node Viewpoints = browser.getNode("Viewpoints"); // Extract the list of children VPList = ((EventOutMFNode) (Viewpoints.getEventOut("children_changed"))).getValue();Note how we cast the result of
getEventOut
to
EventOutMFNode
, i.e. it will return a list of Nodes.
And that's it. Now in order to be able to rebind the user to
a Viewpoint, we are interested in getting handles on the
set_bind
field for each found viewpoint. The following
lines of code relate to that:
nVPs = VPList.length; set_VPList = new EventInSFBool[nVPs]; ...... for (i=0; i < nVPs ; i++) { // Get the handles for the Viewpoints set_bind Event fields set_VPList[i] = (EventInSFBool)VPList[i].getEventIn("set_bind"); }In the same loop we also generate the Java press buttons which we also store in an array (look at the source code) All we finally need to do is to implement the
action()
method that will handle user events and
bind the user to a new ViewPoint.
It's very much the same technology we discussed
in section 6.3.1 as well as others.
The only difference is that buttons are not stored in variables
but in an array called VPButtons:
/** Handle actions from AWT widgets */ public boolean action(Event event, Object what) { if (event.target instanceof Button) { Button b = (Button) event.target; for (int i=0; i < nVPs ; i++) { if (b == VPButtons[i]) { // get the corresponding VP EventInSFBool set_bindVP = set_VPList[i]; set_bindVP.setValue(true); System.out.println("action(): set_bound " + set_bindVP); } } } return true; } }
This example assumed that the only children of the ``Viewpoints'' node were Viewpoints. In other words, our code would break if there were other types of children nodes.
The next example deals with this issue. The applet below adds a ``tour'' button that will move the user throught all viewpoints with some pause in between (Jumping is not nice I know, but this will be addressed somewhere else).
Contents: | getEventOut(), getType(), children nodes |
HTML page: | eai/navigate/navigate-tour.html |
JAVA code: | eai/navigate/NavigateDyn.java |
Directory: | (dir) |
Basically we just had to add a few lines to the
initScene()
method. The Node.getType()
methode
will return a string with the VRML Node name which you
then can use to identify the kind of node you have retrieved.
for (int i=0; i < nVPCs ; i++) { String type_found = VPCandidates[i].getType(); if (!type_found.equals("Viewpoint")) { System.out.println("WARNING! initScene: Ignored node of type " + type_found); } else { // got a ViewPoint VPList[nVPs] = VPCandidates[i]; nVPs = nVPs+1; } }
We will also add here some comments about a revisited version of the Tiny3D applet that extracts node definitions]
Java 1.1.x (Netscape 4x PATCHED): | eai/tiny3D-2/tiny3D-2.html |
Java 1.0.x (Netscape 3x,4x): | eai/tiny3D-2-java1.0.2/tiny3D-2.html |