<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd"><X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation=' http://www.web3d.org/specifications/x3d-3.0.xsd '>
<![CDATA[
ecmascript:
var key, keyValue;
function initialize()
{
key = keyHolderNode.key;
keyValue = keyValueHolderNode.description;
tracePrint('key =' + key);
tracePrint('keyValue =' + keyValue);
keyValueToKeyValueArray ();
tracePrint('keyValueArray =' + keyValueArray);
forward = true;
tracePrint('Initializing a new BooleanSequencer. key.length=' + key.length + '; keyValueArray.length=' + keyValueArray.length);
validityCheck();
}
function keyValueToKeyValueArray ()
{
tracePrint('keyValueToKeyValueArray starting');
index = 0;
complete = false;
nextString = keyValue.toLowerCase();
tracePrint('initial nextString=' + nextString);
tokenCount=0;
while ((complete != true) && (nextString.length > 0))
{
tracePrint('nextString=' + nextString);
while ((nextString.substring(0,1) == ' ') || (nextString.substring(0,1) == ','))
nextString = nextString.slice(1);
tracePrint('deblanked nextString=' + nextString);
if (nextString.length == 0)
{
tracePrint ('nextString.length == 0');
complete = true;
}
if (nextString.length < 4)
{
forcePrint ('*** illegal keyValue input=' + nextString);
valid = false;
complete = true;
}
else if (nextString.substring(0,4) =='true')
{
keyValueArray[keyValueArray.length] = 1; // append
newString = nextString.slice(4);
nextString = newString;
tokenCount++;
tracePrint('found true, nextString=' + nextString + ', tokenCount=' + tokenCount);
}
else if (nextString.length < 5)
{
forcePrint ('*** illegal keyValue input=' + nextString);
valid = false;
complete = true;
}
else if (nextString.substring(0,5) =='false')
{
keyValueArray[keyValueArray.length] = 0; // append
newString = nextString.slice(5);
nextString = newString;
tokenCount++;
tracePrint('found false, nextString=' + nextString + ', tokenCount=' + tokenCount);
}
tracePrint(' intermediate keyValueArray=' + keyValueArray);
}
tracePrint('keyValueToKeyValueArray complete');
}
function set_fraction(value, timeStamp)
{
if (recheckValidity) validityCheck();
if (!valid) return; //BooleanSequencer ignored
tracePrint('fraction =' + value);
//Bounds checking
if (value < 0)
{
forcePrint('*** warning: fraction is less than 0. fraction reset to 0 ***');
value = 0;
}
else if (value > 1)
{
forcePrint('*** warning: fraction is greater than 1. fraction reset to 1 ***');
value = 1;
}
//Check animation direction
if (value < previousFraction && forward == true)
{
forward = false;
nextIndex = nextIndex - 1;
tracePrint('Animate backward');
}
else if (value > previousFraction && forward == false)
{
forward = true;
//nextIndex = 0;
tracePrint('Animate forward');
}
previousFraction = value;
if (forward == true)
{
for (i = nextIndex; i < key.length; i++)
{
if (value < key[i])
return;
nextIndex = i + 1;
tracePrint('nextIndex =' + nextIndex);
if (nextIndex < key.length)
{
if (value <= key[nextIndex])
{
//Fire event
if (keyValueArray[nextIndex-1] == 0)
value_changed = false;
else
value_changed = true;
tracePrint('value_changed eventOut is:' + value_changed);
}
}
else if (nextIndex == key.length)
{
//Fire event
if (keyValueArray[nextIndex-1] == 0)
value_changed = false;
else
value_changed = true;
tracePrint('value_changed eventOut is:' + value_changed);
}
else //nextIndex > key.length
{
//nextIndex = 0;
break;
}
}
}
else //backward
{
for (i = nextIndex; i > 0; i--)
{
if (value >= key[i])
return;
nextIndex = i - 1;
tracePrint('nextIndex =' + nextIndex);
if (nextIndex >= 0)
{
if (value >= key[nextIndex])
{
//Fire event
if (keyValueArray[nextIndex] == 0)
value_changed = false;
else
value_changed = true;
tracePrint('value_changed eventOut is:' + value_changed);
}
}
else //nextIndex < 0
{
//nextIndex = key.length;
break;
}
}
}
}
function set_key(value, timeStamp)
{
key = value;
keyHolderNode.key = key;
recheckValidity = true;
}
function set_keyValue(value, timeStamp)
{
keyValue = value;
keyValueHolderNode.description = keyValue;
recheckValidity = true;
keyValueToKeyValueArray ();
keyValue_changed = keyValue;
}
function validityCheck()
{
//Check if key & keyValueArray array length matches
if (key.length != keyValueArray.length)
{
forcePrint('*** error: key and keyValue arrays must be of the same length. BooleanSequencer ignored ***');
valid = false;
return;
}
//Check if key array has values in the range of [0..1] in an increasing order
if (key[0] < 0 || key[0] > 1)
{
forcePrint('*** error: key[0] value is NOT in the range of [0..1]. BooleanSequencer ignored ***');
valid = false;
return;
}
for (i = 1; i < key.length; i++)
{
if (key[i] < 0 || key[i] > 1)
{
forcePrint('*** error: key[' + i + '] value is NOT in the range of [0..1]. BooleanSequencer ignored ***');
valid = false;
return;
}
if (key[i] <= key [i-1])
{
forcePrint('*** error: values for key[] array must be listed in an increasing order. BooleanSequencer ignored ***');
valid = false;
return;
}
}
recheckValidity = false;
key_changed = key;
return;
}
function previous (SFBoolValue, timestamp)
{
nextIndex = nextIndex - 1;
if (nextIndex == 0) nextIndex = key.length - 1;
}
function next (SFBoolValue, timestamp)
{
nextIndex = nextIndex + 1;
if (nextIndex == key.length) nextIndex = 0;
}
function tracePrint(outputString)
{
if (traceEnabled) Browser.print ('[ BooleanSequencer ]' + outputString);
}
function forcePrint(outputString)
{
Browser.print ('[ BooleanSequencer ]' + outputString);
}
]]>
<!-- Tag color codes: <Node DEF='idName' attribute='value'/> <Prototype name='ProtoName'> <field name='fieldName'/> </Prototype> -->