Contents

Introduction

This document describes a basic mechanism for constructing and animating 3D VRML simulations using SimJava. The idea is to have animated VRML objects instead of animated icons; this allows for better visualisations. It is intended to be used as a starting point for those developing simjava/3D simulations, there are probably better ways of doing it.

This is "work in progress" at the moment.

System Requirements

In order to run Simjava with VRML you need: To compile java with VRML you need to add the vrml.* java classes to the CLASSPATH (supplied with the browser, e.g. npcosmop.zip for CosmoPlayer).

I've found that VRML + java support on Windows is better than that on Unix systems, but the area is in a state of flux at the moment, and not everything works quite how it should.

Building VRML objects for use in simulations

The standard VRML way for building a reusable object is to use a PROTO (e.g. for a glass SPHERE with a variable number of beads inside):-
PROTO SPHERE [
	exposedField SFVec3f translation 0 0 0
	exposedField SFInt32 numbeads 1
] {
  Transform {
    translation IS translation
    children [...]
  }
}

View sphere.wrl and VRML source

The exposedFields let the simulation change the object's appearance on the fly (e.g. calling set_translation(1,2,3) from java would move the sphere to position 1,2,3).

switch {} nodes can be used to provide different representations of an object for different states. Setting the whichChoice field selects which version is displayed.

Smooth animations can be built by routing TimeSensors to PositionInterpolators to the translation field of an object to animate. In order to trigger an animation from java, you need to set the startTime field of the appropriate TimeSensor node. This means that java has to know the current VRML time (not the same as the current java time). One way for java to get hold of VRML time is to use the time eventOut of a TimeSensor in the VRML world.

An example animation (with sound) and VRML source

To paint icons onto objects, the Texture node can be used:-

Bitmap icon and VRML source

A simple queue object which shows its fullness:- A queue object and VRML source

An object which changes colour according to its state (and imports other PROTOs):-

CPU object and VRML source

A 4 way crossbar switch which glows and clicks when touched. This provides a simple "hotness" meter - frequent changes make the switch glow red.

Crossbar object and VRML source

An arrow is very useful - this one has external fields for the color, orientation and scale.

Arrow object and VRML source

Building objects into a world

Once you've created all the types of 3D object you need to instantiate them. This can be done using EXTERNPROTO to include the objects. An example is shown below.

Multistage network object and VRML source

Adding inputs from world to simulation

Dials and switches can be added to the world. The eventOuts from these can be tracked by implementing an EventOutObserver callback.

Light Switch and VRML source

Oneshot Switch and VRML source

Dial and VRML source

Adding outputs to world from simulation

In order to influence the world, the java applet needs to get a handle to the browser. The simjava examples use the EAI to do this (Browser.getBrowser()).

Once the handle to the browser has been obtained, you can call getNode("NodeName") to get a pointer to the VRML nodes in the scene named using DEF.

Once you've got a Node, you access its eventIns, its eventOuts and exposedFields using e.g. node.getEventIn("startTime").

Once you've got an EventIn, you can set its values using eventin.setValue(123);

The code to do all this is outlined in the next section.

Changes required in SimJava code

Imports:-
import vrml.external.field.*;
import vrml.external.Node;
import vrml.external.Browser;
import vrml.external.exception.*;
Basic connection to the VRML world (The pauses are a cludge and are not always necessary):-
  Browser browser=null;
  boolean error=true;

  /** Connect to browser */
  public void initBrowser() { 
    pause(1000);
    browser = Browser.getBrowser(this);
    if (browser == null) {
	error = true;
    } else  {
	error = false;
    }
  }

  /** Pause thread for t millisecs */
  void pause(int t) {
    try {Thread.currentThread().sleep(t);} 
    catch (InterruptedException e) {
      System.out.println("Rudely interrupted");
    }
  }
initBrowser() should be called from anim_layout() so that the connection is reestablished each time the simulation is initialised.

The basic function to get a DEFed node by name is:-

  public Node getNode(String name) {
    Node n = null;
    if (!error) {
      try {n = browser.getNode(name); }
      catch (InvalidNodeException ne) { 
	  System.out.println("Failed to get node:" + ne);   
	  error = true; }
    }
    return n;
  }
And to get an eventIn from a node:-
  public EventIn getEventIn(Node n, String ename) {
    EventIn e = null;
    if (!error) {
    if (n!=null) {
	try {
 	  e = n.getEventIn(ename);
 	} catch (Exception ex) { 
	  System.out.println("Couldn't get event "+ename+":"+ex);
	}
    }}
    return e;
  }
Example usage (VRML fragment):-
  EXTERNPROTO CPU [
	exposedField SFInt32 state 
	exposedField SFVec3f translation] "cpu.wrl"
  DEF Node0 CPU { state 0 translation -3 4 0 }
To get hold of Node0 and set its state to 1 from java using the above functions:-
  Node node0 = getNode("Node0");
  EventIn  EventInSFInt32 set_state = 
    (EventInSFInt32) getEventIn(node0,"set_state");
  set_state.setValue(1);

A Sample Simjava/3D Simulation

3d example 1 and all the applet code and vrml in a jar file (use jar xvf example1_3d.jar to extract the directory).

Caveats

The interface between Java and the VRML browser is temperamental and can cause crashes if anything goes wrong (based on experience with Internet Explorer 4 and CosmoPlayer). This section points out some of the problems encountered, and some solutions.

The problem is that the Java program and the VRML browser operate asynchronously and each may take an unpredictable time to load java classes, html and wrl worlds. Trying to connect to any objects (or the browser) before they are ready usually results in a crash. This problem is made worse by the cacheing of class files and everything else which can lead to intermittant problems.

The browser's `Reload' or `Refresh' buttons don't refetch the .class files - you need to hold Shift- or Ctrl- to force a refetch of class files each time you recompile the java source.

If the browser does crash on Windows NT, it can be helpful to switch java logging on and check the javalog.txt file in the Winnt\java folder to read its last words.

Notes and Further Work

Useful Links

Local:-
Web pointers:-
Fred Howell - fwh@dcs.ed.ac.uk
Department of Computer Science
University of Edinburgh

Fred Howell
Last modified: Sat May 2 13:12:23 BST 1998