The make sure you get the JVerge javadoc documentation which is available from the ftp list on the Intro page or you can view it online
vlc.vrml.external.geometry
For use with applets
vlc.vrml.internal.geometry
For use with VRML scripts
vlc.vrml.generic.geometry
For use with standalone applications
vlc.vrml.VrmlTypes
defines the various type IDs that are used
by all of the classes. Each interface package also includes a file called
VrmlRoot.java
which are examples on how to build a node that
represents the root of the scenegraph. It also shows how you could derive
the classes within JVerge to provide your own custom node.
VrmlRoot
is only a demonstration class to indicate how you
should write your own. Since you need to import different classes at the
top of each file, and gain access to the scene's root node in different
ways, there are three separate implementations. These reside in the
directory above the geometry. The idea is that these are example classes
only, and hence to not belong to any package. The directories are used
to keep the examples separated, not for java purposes.
VrmlObject
.
All classes are derived from this. It outlines some of the basic fucntionality
that is required of all nodes. Here you will find variables that indicate:
createVrmlFromString()
.
System.out
Browser
reference in the internal and external packages.
This is so that you only need to set the browser reference once at the very start
and then you can create the nodes without needing to cart around Browser references
all through your application code.
There are then three main methods that are used:
The first is cleanup
. Cleanup looks after the internal cleaning up,
any reference counting and stuff like that. It should be called just before you
remove any reference to this node when you are creating a subclass of VrmlObject.
In normal day to day use of the classes there is no need for you to use this
method at all. If your derived class contains MF/SFNodes then it should
recursively call the cleanup methods of those nodes as well.
The second method is called writeReset
. This is should be called
immediately before starting to write this node to a file. Like cleanup, it is
recursive and looks after any children nodes that might exist.
The final method is the abstract method writeToStream
which takes
one argument - the level of indent. For most applications this should start at
zero and then let JVerge take care of the indenting internally.
For all the classes there is a default constructor supplied. This will create an instance of the node that is completely default as per the VRML 97 spec. It will create the equivalent of the VRML construct (say for a Group node)
Group {} For nodes where you want to supply non-defualt values for anyfield
type fields then another constructor is provided for that. In the case where you have a number of different browsers there is also variants on the above two methods that include aBrowser
reference as the first argument. The other constructors use the static reference that is contained within the class.
Writing Code
Following is a series of example pieces of code that show how to use the JVerge packages.Simplest approach
Simply add the import line at the top of the file and start creating nodes. For example, to create a Transform node within an applet:
import vlc.vrml.external.geometry.*; public class myApplet extends applet { Browser browser; public void start() { Browser = Browser.getBrowser(this); // etc } { // in a method somewhere deep in the code.... Transform tx = new Transform(Browser); // then you need to add this to some // pre-existing node that you have already // fetched from the scene. some_SFNode_eventIn.setValue(tx.node); } }Note the use of thenode
reference from the VrmlObject class when adding it into the scene.JVerge classes are fine to exist by themselves, but it is no point if you cannot actually see them being added to the scene (if you are using the internal or external versions). To do this, you must start with a node reference from somewhere else. For scripts, this comes from an SFNode reference in the script's declaration. For applets, this comes from a call to the
getNode()
method. For generic, you can create your own class like I have with VrmlRoot.An Alternative Constructor
Carting around Browser references is a real pain, especially in large applications. So JVerge allows you a way to circumvent this - use the staticset_browser
method. The previous example now becomes:
import vlc.vrml.external.geometry.*; public class myApplet extends applet { Browser browser; public void start() { browser = Browser.getBrowser(this); VrmlObject.set_browser(browser); // etc } // in a method somewhere deep in the code.... { Transform tx = new Transform(); // then you need to add this to some // pre-existing node in the scene. some_SFNode_eventIn.setValue(tx.node); } }After the first call in the start method to set the browser reference there is no need to carry it anymore.I recommend this approach is the better to use if you are going to be creating a lot of nodes. I would only use the former when I was running an applet that was talking to two or more browsers at the same time where the two Browser references will be different, depending on which one you are creating geometry for.
Combining nodes together
Once you have mastered creating a single node then combining them together is very simple. For each eventIn/eventOut/exposedField that is defined for a node in the VRML specification there is a matching method. To set theappearance
value of an Appearance node there is aset_appearance
method. The following example creates a red box with dimensions of x = 2, y = 3, z = 4.
import vlc.vrml.external.geometry.*; public class myApplet extends applet { Browser browser; public void start() { browser = Browser.getBrowser(this); VrmlObject.set_browser(browser); // etc } // in a method somewhere deep in the code.... { float[] color = {1, 0, 0}; Shape shape = new Shape(); Box box = new Box(2, 3, 4); Appearance app = new Appearance(); Material mat = new Material(); // set the material to red mat.set_diffuseColor(color) // now combine them all together shape.set_geometry(box); shape.set_appearance(app); app.set_material(mat); // then you need to add this to some pre-existing node in the scene. }Printing Out the Scenegraph
Once you have built up a little bit of a scene you might want to generate the corresponding text. Jverge provides this capability. It is exspecially handy if you are writing a VRML editor like VermelGen.JVerge is deliberately very lax about where it writes the data to. So long as a PrintStream is provided then that is all that is needed. Just open a stream connected to a socket or a file and off you go. The following code is taken from VermelGen that writes the output to a String.
import java.io.*; import vlc.vrml.generic.geometry.VrmlObject public class VrmlScene { private Browser browser; private VrmlRoot file_root; // lots of snipped code! public String getSceneDescription() { ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(os); VrmlObject.outputStream = ps; file_root.writeToStream(0); String output = os.toString(); try { ps.close(); os.close(); } catch(IOException e) { System.out.println("Error closing output streams"); } return(output); } }Nowfile_root
uses the following code:
import java.io.*; import java.util.*; import vlc.vrml.external.geometry.*; public class VrmlRoot extends GroupingNode { // lots of code snipped from here public void writeToStream(int indent) { Enumeration e = _children.elements(); // firstly we need to reset the contents of the file for(; e.hasMoreElements();) ((VrmlObject)(e.nextElement())).writeReset(); fp.println("#VRML V2.0 utf8"); fp.println("#"); fp.println("# Generated by the VermelGen http://www.vlc.com.au/VermelGen/"); fp.println("# GNU Software by The Virtual Light Company"); fp.println("# Released under the GPL ftp://ftp.sunsite.edu/pub/GNU/copyinfo.txt"); fp.println(""); e = _children.elements(); for(; e.hasMoreElements();) ((VrmlObject)(e.nextElement())).writeToStream(indent); } }From this you can see that you need firstly to open up a PrintStream of your choice (this could be the default System.out if you wanted) and then call the writeReset method so that the automatic DEF/USE system works correctly. Finally calling the writeToTream method is called for all top level nodes to make sure the output is correctly generated.
[ The Virtual Light Company ] [ Justin Couch ] [ Bug Report ]