In this tutorial you will learn how to use the output generated by one one object to control other objects in a more sophisticated way with X3DOm. In contrast to just using ROUTES, you are required to write program code to use this feature.
This tutorial is very similar to the first animation tutorial, so please read this first. Additionally, there is a second ball, that should snap to an invisible raster instead of just bouncing up and down smoothly. For animating an object you first need a scene and a shape. Surround the shape with a transform tag. Since we want to manipulate it using Javascript and DOM-Operations, the transform object also needs an ID to find it in the DOM tree later. If you don't know how to initialize a scene please take a look at the basic tutorials first.
<x3d width='500px' height='400px'>
<scene>
<transform DEF="ball2" id="ball2">
<shape>
<appearance>
<material diffuseColor='0 0 1'> </material>
</appearance>
<sphere></sphere>
</shape>
</transform>
</scene>
</x3d>
Again we create a timeSensor and a PositionInterpolator:
<timeSensor DEF="time" cycleInterval="2" loop="true"> </timeSensor>
<PositionInterpolator DEF="move" onoutputchange="snapBall(event)" key="0 0.5 1" keyValue="0 0 0 0 3 0 0 0 0"> </PositionInterpolator>
Notice the new attribute onoutputchange. We register a callback function snapBall to the onOutputChange-Event. Every time an output value of this node changes, the function is called and the event object event is passed.
In the head section of the file we define a piece of code to handle this:
function snapBall(eventObject)
{
//Check if type and output of the eventObject are correct
//There may be multiple eventObjects but only one of them contains the value we need
if(eventObject.type != "outputchange" || eventObject.fieldName != "value_changed")
return;
//Get the value...
var value = eventObject.value;
//...and create a copy with the manipulated coordinates
var newPos = new x3dom.fields.SFVec3f(2, Math.round(value.y), 0);
//Set the newly created array as new position for the second ball
document.getElementById("ball2").setAttribute('translation', newPos.toString());
}
This function takes the values, creates a new position array based upon the values of the PositionInterpolator and sets this as translation attribute to the transformation node around the second ball.
Caveat: Make sure you use only the correct value (check the name of the field), as the callback function gets called every time any output field of the node changes. Also only work with copies of the output field values, since they are passed as reference and changing them might influence other objects.
Your animation should now work and you can modify and extend it as you want. Of course you can also use the values for other actions, you are not restricted to manipulating x3dom nodes.