AJAX3D Tutorial 3:
Dynamic Scene Creation.

This tutorial illustrates how to use Ajax techniques to dynamically create a 3D scene. It builds upon the SAI<=>DOM framework that we created in the previous lesson. The scene is initially empty.
Clicking one of the images will cause strings representing X3D geometry code to be retrieved from the http server and loaded into the scene.

Launch Dynamic Scene Creation

An XMLHttpRequest object is used to fetch text data from the server. Then, the application uses advanced capabilities of the X3D SAI to dynamically create nodes based on that text and add them to an initially empty scene.

Setup: Embed X3D content in the page.
The X3D browser is initialized using the technique shown in Tutorial 1. The target scene loaded after we get the callback is "empty".

.x3d
  <X3D profile='Immersive' >
    <head>
    </head>
    <Scene>
    </Scene>
  </X3D>

You will find that it not necessary to actually load any scene, even this "empty" one. The X3D player wil be able to build the example scene whether or not there is an initial scene loaded. Doing it this way just makes me a bit more confident that I know what should be happening.

The window shows a page with images which act as clickable buttons. Click to create a new piece of X3D content from a string stored on the server then add it to the scene. Each new object gets added to the right of the previous one. The result: the world’s dumbest X3D modeling package ever -- and running in a web browser!

Step 1: Load dynamic content using XMLHttpRequest.
When one of the images is clicked, the onClick() function determines which piece of X3D to create and then fetches a piece of text from the server that will be used to create the X3D.

Function createRequest() uses typical Ajax programming techniques to create an XMLHttpRequest object in a browser-independent fashion that will work with IE, Firefox and other browsers. It turns out that if we are just interested in IE7 or Ff, the code is simple:

dom.js
  var xmlhttp = new window.XMLHttpRequest();

However the actual function also checks for older versions of IE.
The olny downside of using the method shown in this example is that IE7 code will not work locally. For that, it is ok with me because I can use Ff to test beause it runs the same code locally.

Once we have the object, we send the request and retrieve the string from the server via the following lines of code:

dom.js
  // synchronous to keep it simple for now
  xmlhttp.open("GET", url, false);
  xmlhttp.send("");
  return xmlhttp.responseText;

Function sendRequest() uses the now available XMLHttpRequest object to actually send the request and return the string. First, the request is set up by calling the open() method; then the request is actually sent by calling send(). This send() can be called either synchronously or asynchronously. We are calling it synchronously here for simplicity; if it were the asynchronous version we would supply a callback function as the argument to send(). The sendXMLHttpRequest() function then returns the string in the XMLHttpRequest object’s responseText property.

responseText
Shape { geometry Box {} appearance Appearance {
material Material { diffuseColor 0 0 1 } } }

or, maybe we might try
<Shape><Box/><Appearance>
<Material diffuseColor='0 0 1'/></Appearance></Shape>

At this point, we have a string that we can use as X3D source code that can be dynamically inserted into the scene -- once we figure out how to do that.

Note: XMLHttpRequest is the heart of Ajax. Nearly all applications use this XMLHttpRequest object to fetch data from a web server and update the document without forcing the page to reload. AjaX3D is no different. Without XMLHttpRequest, AjaX3D applications have to live with data included in the same or an entirely different document. With XMLHttpRequest the application can potentially have much more interesting data to work with.

Step 2: Dynamically create a 3D object and add it to the scene.
Now that we have the X3D data required to create a new object, we must use the SAI calls to create the object and insert it into the live scene. This tutorial application calls addX3DFromString with the string returned from our sendRequest function:

dom.js
  addX3DFromString(wrapOffset(str));

After wrapping it with a little extra X3D 'stuff’ we use wrapOffset() to adjust the X coordinate depending upon previous interactions to translate the newly created shape object to an unoccupied position in the scene.

dom.js
  // Helper to position the newly created object to
  // a new place in the world - offsets X coordinate
  function wrapOffset(str)
  {
    return "Transform
     {translation " + xoffset + " 0 0 children [ " + str + " ]}";   }

Now another helper function in our framework called addX3DFromString() actually adds the new node:

dom.js
  function addX3DFromString(str)
  {
  var scene = browser.createX3DFromString(str);
  var rootnodes = scene.getRootNodes();
  var i;
  // Do a bit of work to deal with the
  // X3D add/remove root node paradigm
    for (i = 0; i < rootnodes.length; i++)
    {
      node = rootnodes[i];
      scene.removeRootNode(node);
      context.addRootNode(node);
    }
    }
  }

Our framework version of addX3DFromString() takes some of the extra grunt work out of using the raw SAI call – specifically the need to crawl through the array of returned nodes, remove them from the scene object, and add them to the live context object. It’s boring stuff and that’s why we made a helper function for it.

That’s it; click on an HTML object and Voila! an X3D object is created. While this tutorial is a contrived and simplified example, it illustrates the basic principles required for dynamically generating content from server-side data sources — an essential element in developing dynamic AjaX3D applications.

Refresh/Reload Example page to restart.

This AjaX3D tutorial start

AJAX3D.org Tutorials

Original Author: Tony Parisi  tparisi@mediamachines.com
last updated: October 12, 2006
This version by: Joe D Williams  joedw@hypermultimedia.com
last updated: October 16, 2006