Xj3D 2.3-nps VRML/X3D Code API
Xj3D Overview
Xj3D is a series of libraries that form a toolkit that can be used to load and render VRML97 and X3D files.
The aim of the codebase is to provide a series of easily separable components to enable VRML and X3D content either as a full browser, static geometry or even as a component of a bigger application. The major goal of the code is to provide a highly flexible set of libraries that you may take and use to generate renderable content. If you combine them all together you could create a complete browser that we intend to be specification-conformant. The codebase itself is not a VRML/X3D browser, although you can create one from this code (see some of the example and apps directories along with this distribution for an idea how).
The code is broken into 5 major sections:
- Low level VRML and X3D lexical parsers with a callback based API
- Definitions of VRML and X3D content, structure and generators
- Various renderer implementation of the internal structured scene graph (OpenGL, and null)
- Various utilities built over the frame work, such as compression systems and format transformation
- Implementations of the EAI and external SAI to allow access to X3D/VRML content in a browser-independent, specification-conformant manner without you needing to get caught up in the details of Xj3D's internals.
Using the Code
When you start to use the code in an application, it will not automatically allow you to do everything. For example, standard Java 3D loaders do not support the idea of scripting or of Inline content. To deal with this, you must also perform some auxiliary support work so that everything works as expected.
Note: In general, we recommend that you only use the SAI classes to interact with Xj3D. By far the majority of the applications do not need anything more complex than that interface.
Loading External Content
To make life easier for our implementation, we have made use of quite a number of 3RD party libraries to build a fully capable browser. The major reason for this is that the inbuilt Java libraries are pretty terrible for the requirements of a VRML browser. Firstly we need full URI support - Java does not handle URNs that are used by the Universal Media libraries. Next, the image loading of standard Java is very bloated, consuming way too much memory. Then, to transport them across to the texture mapping used we have to make several copies of the image each time, so we bring in a library for more efficient image handling.
The next step is to use local libraries for specific areas such as Java 3D support. These libraries make a lot of things simpler by allowing us to not have to code them again. There are many similarities between VRML and the 3D graphics scene graph APIs and these libraries act as the translator between the two systems.
Preparation Work
Internally the code does not connect a lot of the parts together. For example,
Inline nodes are not automatically loaded as there are cases where you don't want
the code to handle them. You may also want to specifically handle different
content. Therefore, the Inline nodes are only loaded once you register the
appropriate handlers with the URI system. We won't detail that here, but
refer you to the applicable packages - org.web3d.net.content
and
org.xj3d.loaders.ogl
. There are a collection of properties
and factories that need to be set if you want loading of external files
like textures, scripts and Inline nodes to work correctly.
XML Integration
Xj3D can process X3D content that exists as part of a larger multiple-namespace XML document. The existing X3D spec is currently not well defined about this, so we have taken a few liberties until a firm specification is defined.
In the case where X3D is the containing document, and is the unnamespaced portion of the XML elements, we handle this transparently. You need to do nothing special. Any elements that have a namespace prefix are ignored and disposed of during the parsing process by the Xj3D browser.
If you wish to apply a namespace to the X3D nodes, then we use a fixed URI to
detect this. If there is a xmlns:
attribute on the X3D root
element, we look at the value of that attribute to determine if you are
declaring the namespace to be the X3D namespace. If we see the exact value of
http://www.web3d.org/specifications/x3d-namespace
Then we take the predefined prefix to be the X3D namespace prefix. For example:
<X3D version='3.1' profile='Interchange' xmlns:x3dns='http://www.web3d.org/specifications/x3d-namespace' xmlns:foo='http://www.foo.com/mynamespace' > <x3dns:head> ...
and
<X3D version='3.1' profile='Interchange' xmlns:bar='http://www.web3d.org/specifications/x3d-namespace' xmlns:foo='http://www.foo.com/mynamespace' > <bar:head> ...
will both generate valid and identical X3D content for viewing.
System Properties
There are two ways of controlling the runtime configuration of Xj3D. Apart from providing your own implementation of the various toolkits, the standard Java mechanisms of properties files and system properties also apply.
Property Files
Property files are used to control large collections of properties. The following properties files are used by the system (path information is relative to the CLASSPATH as per System.getProperty()):
config/2.0/spec/vrml.properties
- Defined by the EAI to control various
items of configuration. Principally used to set the default factory class
to use for
BrowserFactory
config/3.x/spec/x3d.properties
- Defined by the SAI to control various
items of configuration. Principally used to set the default factory class
to use for
BrowserFactory
config/3.x/XMLcontainerfields.props
- Mapping of node element names to the default containerField attribute value. Used when the XML parsing is not validating and so we don't get the values directly passed to us.
Configuration files are all kept in a directory
config/spec_version
with separate sub directories. These can
be overridden by the user as needed by providing their own replica directory
structure that is locatable within the CLASSPATH.
System Properties
The codebase makes reasonable use of system properties to allow the modification of its behaviour. These properties are sprinkled liberally about the code, making them sometimes hard to find. This is a summary of all those properties. Please be aware that these will need to be set before you run any code from this library because most of them will be used during the construction phase of any class.
org.web3d.vrml.nodes.loader.threads
- The number of concurrent threads to be started to do loading. There are two areas which use this - script loading and all other files. Each loader creates this number of threads in the pool.
org.web3d.vrml.parser.field.factory
- The name of the class
that implements the
FieldParserFactory
interface, which is used for parsing individual field values. org.web3d.vrml.parser.file.factory
- The name of the class
that implements the
VRMLParserFactory
interface, which is used for parsing files. org.web3d.xj3d.script.loader.class
- The name of the class
that implements the
ScriptLoader
interface, which is used for loading scripts. org.web3d.xj3d.script.manager.class
- The name of the class
that implements the
ScriptManager
interface, which is used for managing scripts. org.web3d.xj3d.file.loader.class
- the name of the class that implements the
ContentLoadManager
interface, which is used for loading content other than scripts. org.web3d.xj3d.router.manager.class
- The name of the class
that implements the
RouteManager
interface, which is used for managing routes. org.web3d.xj3d.router.factory.class
- The name of the class that implements the
RouterFactory
interface, which is used for creating routers. org.web3d.xj3d.frame.state.class
- The name of the class that implements the
FrameStateManager
interface, which is used for managing per-frame state. org.web3d.xj3d.sensor.manager.class
- The name of the class that implements the
SensorManager
interface, which is used for managing sensors. There are renderer-specific sub-interfaces of this interface which the implementing class must also adhere to. org.web3d.xj3d.eventmodel.evaluator.class
- The name of the class that implements the
EventModelEvaluator
interface, which is used for runing the event model. org.web3d.vrml.nodes.staticgroup.dispose
- Boolean value describing whether the static group should dispose of the VRML node children. This is an efficiency measure that will allow an implementation to remove unneeded memory. However, it also means that they can no longer be traversed, so if your application is trying to traverse the scene graph, it will not be able to use the nodes later on. Useful for a runtime optimisation, no good if you are writing an editor. Defaults to false.
org.web3d.vrml.nodes.staticgroup.compact
- Boolean value describing whether the static group should compact the VRML scene graph below this node or leave it in an expanded state. This is an efficiency measure that will allow an implementation to flatten the scene graph if desired. Useful for debugging but also means the runtime scene graph will probably be different from the original loaded from file. Defaults to false.
org.web3d.vrml.nodes.fontstyle.font.size
- The font size in points. The default value is 36 point font.
org.web3d.vrml.renderer.common.nodes.shape.rescale
- The method to use for rescaling textures. Valid values are "NEAREST_NEIGHBOR, BILINEAR"
org.web3d.vrml.renderer.common.nodes.shape.useTextureCache
- Whether to cache textures for later reuse. This caches by URL which might be incorrect for some dynamic systems. It improves performance for files which don't use DEF/USE for textures.
org.web3d.vrml.renderer.common.nodes.shape.maxTextureSize
- The maximum texture size to use. By default texture sizes are unlimited. Textures with a dimension over this value will be resized. The resizing will try to preserve the aspect ratio. This must be a power of two.
org.web3d.vrml.renderer.common.nodes.shape.useMipMaps
- Set to a value of "true" in order to generate mip maps for textures.
org.web3d.vrml.renderer.common.nodes.shape.anisotropicDegree
- Sets the anisotropic filtering degree. Values above 1 cause mip mapping to be turned on as well.
org.web3d.vrml.renderer.ogl.nodes.hanim.allowHardwareHumanoid
- Set to a value of "true" in order to allow the use of hardware-accelerated rendering of the HAnim humanoid. Otherwise, always uses software rendering.
Further Reading
- This software is released under the GNU LGPL
- The Xj3D Homepage
- Node implementation status
- Extensions that are added to Xj3D
- Development Snapshots to be downloaded if you don't want to build from source.
- The VRML97 ISO Specification International Standard ISO/IEC 14772-1:1997 and VRML97 EAI Specification ISO/IEC 14772-2:2002.
- The X3D FCD ISO Specification
text. There are 3 specifications in various stages of development:
- 19775 - The main X3D abstract spec
- 19776 - The file format (encodings) spec
- 19777 - The programming language bindings to the SAI
- For details on URIs see the IETF working group: URN
External Code
Xj3D is a huge project that is a collaborative effort in more ways than one. Where possible, we like to build on top of the work of others. These are the projects and libraries that we make use of in order to build this toolkit.
- JOGL (Java OpenGL) bindings
- JOAL (Java OpenAL) bindings
- JInput Abstract Java bindings to the HID specification.
- Sun's Java 3D
- Sun's JavaCOMM for abstract serial port handling (so we can interface to older devices like gloves, wands, HMDs etc).
- j3d.org The Java 3D Community Site
- J3D.org's Code Library for Java 3D specific code features.
- J3D.org's Aviatrix3D Project for an OpenGL scene graph written in Java.
- Geotools2 project provides the coordinate transformation services for implementing the Geospatial component. Most of the code uses the abstract GeoAPI that is an implementation of the OpenGIS Consortium specifications.
- JSR 108 Unit-Handling specification code
- NPS DIS-Java library for the DIS implementation.
- ODE-java Java bindings to the Open Source Open Dynamics Engine that provides our rigid body physics capabilities.
- Rhino ECMAScript Engine for providing VRML97 Annex C and X3D ECMAscript support. Rhino is a product of the Mozilla project licensed under the NPL/GPL dual license.
- GNU Regexp library (v1.0.8)
- HTTPClient v0.3-3
- Justin Couch's URI Library home page:
- For better image format support than the defaults provided by Java 3D, try Justin Couch's ImageLoader library. The codebase does not use this directly, but it fits with the URI handling code to expand and produce much, much more efficient texture loading support (also uses native code!)