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.
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.
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