Grafman's VR World

[ platform | demo & source | basics | sending events | receiving | help | credits ]


gcPoser EAI Example

Chris Marrin's draft proposal for the VRML 2.0 External Authoring Interface (EAI) provides 2-way communication between VRML worlds and external applications.

This example was originally created as a preliminary prototype for an Avatar controller, and contains most of the key features of EAI:

  • Java applet establishes a link to a separate VRML world.
  • VRML world sends model & user events to the applet.
  • Applet sends user events to the VRML world.

The gcPoser java class works within a single frame or across frames, uses threading to load EAI objects, provides a workaround for an EAI/JSObject bug and demonstrates the use of a single Observer to handle multiple EventOuts.

The demo itself is trivial: it lets you select a current avatar part either by clicking on the VRML model, or by selecting from the external Java applet's list box. You can then pose the part via the applet's navigation control.

Clicking on the VRML model sends events to the external applet, clicking on the navigation controls sends events to the VRML model.


Requirements

This demo has only been tested on Win95 and NT. In addition, you will need the following to run this demo: If you have problems running the demo on the above configuration, or if you succeed running it on other configurations, please let me know at grafman@graphcomp.com.


EAI Demo on same Frame

The demo takes a while to load...

EAI between Frames

This demos EAI working between frames...

View the Source

Crude, but hopefully helpful...

Grafman's VR World

More VRML demos...


A Note About The VRML Model

The VRML model used in this demo was created via a series of homegrown scripts I've written that generate, place and inter-connect vrml primitives.

This model demonstrates nested PROTOs, passing events up and down a tree heirarchy, using VRMLScript and storing attributes with nodes (parts remember their handedness).


EAI Basics

Before jumping into the External Authoring Interface (EAI), it's helpful to be familar with VRML 2.0, Java and JavaScript.

You can find related specs at The Internet Spec List, and Grafman Productions' VRML Tips page.

There seems to be some confusion about what EAI is, and how it differs from Sony's JSAI Java Extensions for VRML.

Essentially, JSAI addresses the use of Java as an internal scripting language in VRML 2.0 models -- it does not address interaction between a VRML model and an external application.

That's where EAI comes in. It's a two-way interface that lets VRML models and Java applets interact.

There also seems to be confusion about SGI's VRMLScript and the use of Netscape's JavaScript within VRML models.

Basically, VRMLScript is SGI's light-weight implementation of JavaScript -- why support all of JavaScript, when all you need are the VRML extensions?

For an overview of various VRML-related specifications, visit The Internet Spec List - VRML Overview.

The following describes the basics of using EAI:


Grabbing a VRML Model

The first thing a Java applet must do to communicate with a VRML model is to acquire a reference to the model and its members.

    
    public class gcPoser extends Applet implements EventOutObserver
    {
        JSObject        m_Win = JSObject.getWindow(this);
    
        /* Optional code, for use with frames */
        JSObject        m_Par = (JSObject)m_Win.getMember("parent");
        JSObject        m_Fst = (JSObject)m_Par.getMember("frames");
        JSObject        m_Frm = (JSObject)m_Fst.getSlot(0);
    
        JSObject        m_Doc = (JSObject)m_Frm.getMember("document");
        JSObject        m_Plg = (JSObject)m_Doc.getMember("embeds");
            . . .
        Browser         m_Mdl = (Browser)m_Plg.getSlot(0);
            . . .
        Node            torso = (Node)m_Mdl.getNode("torso");
            . . .
        EventInSFFloat  turnTorso = (EventInSFFloat)torso.getEventIn("turnTorso");
            . . .
        EventOutSFTime  torsoClicked = (EventOutSFTime)torso.getEventOut("torsoClicked");
            . . .
    
    

You need to implement EventOutObserver if you want to receive notification from your VRML model.

JSObject provides the methods needed to get a reference to the model. First, getWindow retrieves a reference to the current browser frame; getMember retrieves child members of the frame.

See Nestcape's Navigator Objects reference for info on available members, such as "frames" (a list of frames) or "document" (the web page). The "embeds" member of a document is a list of embedded plugins.

In the example above, "parent" retrieves the current frame's parent, "frames" gets a list of frames for the current window and getSlot gets the first frame of the frameset.

Note: if no frames are present, these three steps simply return the window that you started with. If you don't plan on supporting frames, you can skip these three steps and just use the initial window as the target frame.

Once you have your target frame, you nab a reference to the "document" member to grab items on the page.

getSlot retrieves a reference to a plugin by index; slot 0 is the first embedded plugin in the page. If no <EMBED> tag is used, and the VRML model is full-frame, the plugin will implicitly be slot 0. Future releases will probably have a method for grabbing the name/ID of a plugin embedded via the <OBJECT> tag.

Note: getSlot will return null until the plugin is actually loaded. This is also true for getNode and the other member methods. Ideally, EAI should have a callback to let you know when a model has been fully loaded.

Until this feature becomes available, you need to spin a thread to grab the plugin, as well as all the Node, EventIn, EventOut and Field members.

!Note!: There is a bug in EAI/Netscape when used with frames -- if you click Navigator's "back" button, and then "forward", Navigator will crash. This is caused by frame/JSObject caching the browser object and returning it (instead of null) before the browser has actually loaded. This demo includes a workaround which simply adds a four second delay prior to loading EAI objects -- this is not required when used within the same frame.


Sending Events to the Model

Sending events is simple. Once you have a reference to a EventIn or Field member, all you have to do is:
    
        turnTorso.setValue(myValue);
    
    

That's pretty much it.


Receiving notification

Receiving events is a bit more involved, but still fairly simple.

First, you need to implement EventOutObserver, either in your applet class, or in a separate class.

Next, you need to enable the EventOut references via advise:

    
        torsoClicked.advise((EventOutObserver)myObserver, (Object)myData);
    
    

If the EventOutObserver is implemented in your applet class, then myObserver should be this.

myData is just whatever data you want to pass to your event handler. This is handy for passing IDs or other object-specific data to your event handler.

Finally, within the EventOutObserver, you need to define a callback method, which will receive the model's EventOut notifications:

    
        public void callback(EventOut e, double ts, Object obj)
        {
            /* handle your model's EventOut notifications here */
                . . .        
        }
    
    

e is the model's event, ts is the timestamp of when it happened, and obj is the myData data that you passed into advise.

Using EAI, you can add, move, transform, remove or otherwise manipulate a VRML model.

And that's just about all you need to know about the External Authoring Interface!


Having Demo Problems?

Generally, the issue is that you have the wrong VRML class lib version installed. First, make sure you've installed Navigator 3.01 on NT (I haven't tried Win95), then install Cosmo Player beta 3a.

If you are still getting crashes, try the following:

  1. Back up your Netscape \programs\java\classes\ directory.
  2. Get ftp://ftp.graphcomp.com/pub/msw/vrml/classes.zip
  3. Unzip (with subdirectories) the above file into your Netscape \programs\java\classes\ directory -- make sure your unzip-er supports long file names.
  4. Make sure your system's CLASSPATH environment variable is pointing to this directory.
If you are still having troubles, notify me at grafman@graphcomp.com


Credits

Much thanks goes to Ross A. Finlayson for pointing me to the right files, and for his handy EAI FAQ page.


[ top | platform | demo & source | basics | sending events | receiving ]


© Copyright 1997 - Grafman Productions - ALL RIGHTS RESERVED
For more information on this EAI demo, email grafman@graphcomp.com.