Background
This document describes some of the details involved in implementing the
client for the Virtual Cell game. The cheif technical difficulties involved
in constructing the client involve constructing a VRML world which conforms
to a world maintained on a centrally located server. In one respect,
the VCell client is yet another multi-user VRML client.
It is probably unimpressive to admit, but in one respect, the VCell client
is simply a MOO client which is using VRML to do the rendering.
The saving graces of this approach are
- VRML when combined with the EAI is a quite capable rendering engine
- An unobtrusive user interface can be constructed dynamically
- In the event that Java3D gets implemented on more than just
Solaris and Windows platforms, a Java3D version will be less
painful to write.
References
The following technologies are being used in implementing the client
- The Java programming language. For more information, see
http://java.sun.com/
- Virtual Reality Modeling Language. For more information, see
http://www.vrml.org/
- The External Authoring Interface (EAI). EAI allows a Java applet
to manipulate the VRML displayed by a World Wide Web brower plugin.
For more information, see
http://www.vrml.org. The original version of the EAI specifications
are available at
http://www.cosmosoftware.com/developer/eai.html.
- The CosmoPlayer VRML plugin. CosmoPlayer is a VRML plugin available
from CosmoSoftware. For more information, see
http://www.cosmosoftware.com
- Blaxxun CCPro VRML plugin. CCPro is another VRML plugin, and is
available from http://www.blaxxun.com
although the project is tested against that plug in less frequently.
Blaxxun Contact 3D hasn't been tested yet.
- VRML Repository. The VRML repository is an interesting source for
finding implementations of various editing tools and plugins.
Its located at
http://www.sdsc.edu/vrml/.
NodeStub and Thing
In order for the scene graph construction and maintenance algorithms to
work for the client, the local representation for each object is
divided into two halves
- The portion common to every object. This includes the basic
VRML structure needed for that object in the scene graph,
and the ability to respond to changes in location, position,
scale, and orientation. This portion of the functionality
is implemented by a class called NodeStub, since this half
can be created for any server object before the actual
identity and nature of the object is known.
- The portion specific to each object. One limitation of the
client software is that the role of each object (whether it is
static, functions as a finite state machine, represents a button,
etc.) on the client side has to be defined ahead of time.
To connect each of these two halves, each representation has a property
Class which is used by the NodeStub to instantiate the local implementation.
As of February 2, 1999, the following subclasses of Thing have been
implemented
- Generic. The Generic class extends Thing to handle the parameter
url, which it expects to be a string specifying the address
of a WRL file containing VRML to be used as its geometry.
- SceneRoot. This class simply serves to instruct the client that
it is a terminal end of the scene graph. It is important
mainly in the scene graph maintenance algorithms.
- Player. This class is used to represent player's to the client.
At present, the WRL file used to represent players is hard coded,
although that may change in future.
- VRMLButton. This class extends Generic to support touch sensors
and the basic "User clicks on an object and it does something"
functionality. This class supports this feature by checking for
eventOut SFBool local_activate in the local representation.
The representation is handled as for Generic. Since
VRML supports other sensors which can generate boolean events,
such as proximity sensors, additional variations are also
possible.
- GFSD. Generic Finite State Device is a slightly more complex
version of VRMLButton. GFSDs have a state property which is
expected to run over the range of integers. The GFSD assumes
that its representation will respond to an eventIn SFInt32
set_state which will cause changes in the object's state.
GFSD's can also optionally have a local_activate eventOut as
described for VRMLButton.
- GenericIO. GenericIO is a more general version of GFSD.
In addition to the parameters required by Generic, it expects
to parameters vrml_inputs and vrml_outputs. vrml_inputs specifies
additional parameters (and their expected types) which will
correspond to eventIn's of a VRML representation. vrml_outputs
specifies the names (and their expected types) for eventOuts which
will be routed back to the server. vrml_specials records the names
of the inputs which have to be set each time the node is moved
around the scene graph (e.g., the set_bind fields of VRML's bindable
nodes).
Scene Graph Maintenance
In VRML terminology, the objects in a scene are organized into a scene
hierarchy. Since the scene displayed to the user is supposed to change
in response to changes in the overal environment, updating the scene
becomes one of the primary responsibilities of the client.
The algorithm used during connection is approximatley
- At connection, receive reference to player's object. This
becomes the first unresolved object reference.
- When ever an unresolved object is encountered, the client issues
a command to the server for that object's representation.
A side effect of this request is that the client is listed
as interested in updates on that object.
- When an object representation arrives, the client attempts
to make that portion of the scene graph correct. This effort
is largely ensuring that the location/contents relationship
from the server holds for that object. A side effect of this
is that the the scene graph is reconstructed in a breadth first
manner from the user's object.
- After the scene graph is partially constructed, it is possible
that updates on location or contents may introduce new unresolved
objects into the list, or indicate that the current scene graph is
incorrect. If this occurs, then parts of the current scene graph
will be recursively discarded and the process of constructing the
scene graph continues in the same manner as if the user had
recently connected.
- Updates on all other properties of objects are handled in a
straight foreward manner by either the NodeStub or Thing object
for a locally visible object.
Animation
The glue which binds the scene graph on the client side together is
a prototype called the RotationSocket. Currently the individual components
of this prototype include a Transform node, a Group node, a TimeSensor,
a PositionInterpolator, an OrientationInterpolator, a Script node,
and routing information sufficient to provide smooth gliding and rotation
for all displayed objects.
Other forms of animation are possible as supported by VRML for the
various geometries, but care must be taken that different users viewing
the same world receive appropriate versions of the animation.
User Interface
At the moment, the user interface is fairly minimal. Other than
the interaction provided by VRML objects, only enough functionality to
connect to the server and disconnect nicely are provided.
This functionality will be extended as needed to support the learning
goals of the project.
In response to user activities, the server can instruct the client
to display windows containing informational text, windows for selecting
actions to perform on various objects, and so on. Work is currently
also underway on more task orientated (and thus less general) portions
of the user interface, such as a lab book for the students.
Communication Protocol
The LambdaMOO server uses the TCP/IP telnet protocol for communication
with client applications. Because it has very little support for
binary mode communications, information is transmitted to the client in
the form of directive strings. The basic format for these directives
is #Directive|ValueList
with the following interpretations
- Directive
- A sequence of characters not including a | character
- ValueList
- One of
- Nothing
- A sequence of the following seperated by | characters.
A terminating | character is required.
- A string surrounded by " characters.
- An integer in text format, e.g. 3.
- A floating point number including the decimal point.
E.g. 3.0 or 3e-10.
- An object reference. The text representation is
a # character followed by an integer in text form.
E.g. #303.
- A list. The format has a beginning { followed by
comma seperated elements terminated by a }.
E.g. {"url","http://www.w3.org/"}.
At present, the directive system is used for displaying windows for
dynamically generated text, and for displaying windows containing
commands. The directive system is also used for communicating the
player's identity, object representations, and value updates to the
client.
In order to simplify the coding of the server, the convention of
Give the client only the updates it has asked for is used.
Rather than attempting to guess or assume what the client is interested in,
the client is required to request state updates for any object it is
maintaining a representation of.
One benefit of the LambdaMOO server is that a text based implementation
of remote proceedure calls to the server is fairly simple. At present,
the mechanism is fairly basic, and support for synchronous proceedure
calls has not been necessary. The design details for synchronous proceedure
calls are known, however, so they will be available if the need arises.