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:

  1. Low level VRML and X3D lexical parsers with a callback based API
  2. Definitions of VRML and X3D content, structure and generators
  3. Various renderer implementation of the internal structured scene graph (OpenGL, and null)
  4. Various utilities built over the frame work, such as compression systems and format transformation
  5. 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

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.

Packages
Package
Description