More WebGL Exploration: Visualising Mutual Twitter Friends with X3DOMPosted by Dennis on Aug 5, 2010 in 3D, WebGL • 6 comments
After the WebGL BoF at Siggraph I spoke to some people from the Web3D consortium and the Fraunhofer institute. This was quite interesting. The Fraunhofer institute is working on an X3D WebGL implementation called X3DOM. Basically it means that you can set up a 3D scene as part of any HTML5 DOM tree.
This should make hardware accelerated 3D accessible for anyone who’s familiar with HTML and not familiar with WebGL/OpenGL. Most people don’t care about the low-level specifics, they just want to get 3D stuff up and running quickly. X3DOM should enable the users to do so. Before Siggraph I had heard about X3DOM but never took the time to take a closer look at it.
Show Mutual Twitter Friends
For this simple example I decided to grab some Twitter data. I found a web service that returns the mutual friends, followers, etc from two Twitter users. I had to do some PHP scripting to filter the results and I composed the actual XML server-side. I won’t bother you with the details but if you’re interested I can send you the PHP script I’ve been using.
If you want to view the final results before I go into the specifics, follow this link. You can click and drag and use the scroll wheel to navigate in 3D space. If you don’t have a WebGL-enabled browser you can click on the image below to see the YouTube video.
Setting up the scene with X3DOM
An important thing to consider is that the mime type for xhtml based documents should be “application/xhtml+xml”. Using the .xhtml extension should be sufficient for the browser to use this mime type.
An X3DOM document starts with the <X3D> root node. Here you specify the position, the dimensions and you can indicate whether you want so see the stats and the debug log:
<X3D showStat="false" showLog="false" x="0px" y="0px" width="800px" height="600px">
Then a <Scene> and <Viewpoint> are needed:
<Scene> <Viewpoint position='0 0 40'></Viewpoint>
All the individual cubes are enclosed in a <Transform> tag. This is used for scaling, rotating and translating. This tag is also key to animations, which will be shown later on. All objects are defined in a <Shape> tag. In this instance the onclick event handler is attached to this node. Clicking the shape will show the user’s Twitter name. The material properties and texture are enclosed in an <Appearance> tag. Here we specify the texture url, diffuse color, shininess, etc. The <Box> tag adds a box primitive to the scene:
<Transform DEF='MyTransform2' scale='1 1 1' rotation='0 0 0 0' translation='1.3891854213354 7.8784620240977 28.75'> <Shape onclick="showUserInfo('masdennis')"> <Appearance> <ImageTexture url='ResizeImage.php?size=256&url=http://a2.twimg.com/profile_images/1078865146/roasted-pepper.jpg'/> <Material diffuseColor='0.7 0.7 0.7' shininess='1' specularColor='0.95 0.3247 0.3247' /> </Appearance> <Box DEF='box'></Box> </Shape> </Transform>
I’m using a php script to convert the texture to a power of two texture.
All these textured cubes are grouped with a <Group> tag. There are two <Transform> nodes that control the group’s rotation around the x-axis and the rotation around the y-axis:
<Transform DEF="XAxisRotation"> <Transform DEF="YAxisRotation">
Here’s where animation comes into place. To control the animation time-wise we can use a <TimeSensor> node:
<TimeSensor DEF='XTimeInterval' cycleInterval='32' loop='true'/>
The object’s rotation can be transformed by using <OrientationInterpolator>. The “key” attribute specifices the time values and the “keyValue” attribute specificies the rotation in radians. The values are specified in “x y z value” format. So if we want to do a 180 degrees rotation (PI) around the x axis this value can be used: 1 0 0 3.14159265.
<OrientationInterpolator DEF='XSpinner' key='0 0.25 0.5 0.75 1.00' keyValue='1 0 0 0 1 0 0 1.57079633 1 0 0 3.14159265 1 0 0 4.71238898 1 0 0 6.28318531'/>
Next we need to connect the <OrientationInterpolator> to the <Transform>:
<ROUTE fromNode='XSpinner' fromField='value_changed' toNode='XAxisRotation' toField='rotation'/>
The final step involves connecting the <TimeSensor> to the <OrientationInterpolator>:
<ROUTE fromNode='XTimeInterval' fromField='fraction_changed' toNode='XSpinner' toField='set_fraction'/>
It’s as easy as that . My first impression of X3DOM is that it’s very easy to work with. Specifying the scene through XML nodes is actually very convenient. Next time I’ll give DOM scripting a try to see how that works.
If you want to know more about X3DOM or want to see more examples, go here.