<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd">
<X3D profile='Immersive' version='3.3' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.3.xsd'>
  <head>
    <meta content='BindingOperations.x3d' name='title'/>
    <meta content='Illustrate Viewpoint binding operations (in gory detail!) as described in Chapter 4 concepts. Scene design: a TimeSensor clock drives and IntegerSequencer for each t0/t1/etc. event, and a customized Script node sends bind/unbind events to the correct Viewpoint. Display the browser console to see occurrence of each event.' name='description'/>
    <meta content='Don Brutzman' name='creator'/>
    <meta content='5 January 2008' name='created'/>
    <meta content='4 August 2024' name='modified'/>
    <meta content='BindingOperations.console.txt' name='reference'/>
    <meta content='BindingStackOperations.png' name='reference'/>
    <meta content='X3D for Web Authors, Section 2.5.1, Figure 4.1' name='reference'/>
    <meta content='https://X3dGraphics.com' name='reference'/>
    <meta content='https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/>
    <meta content='Copyright Don Brutzman and Leonard Daly 2007' name='rights'/>
    <meta content='X3D book, X3D graphics, X3D-Edit, http://www.x3dGraphics.com' name='subject'/>
    <meta content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter04ViewingNavigation/BindingOperations.x3d' name='identifier'/>
    <meta content='X3D-Edit 4.0, https://www.web3d.org/x3d/tools/X3D-Edit' name='generator'/>
    <meta content='../license.html' name='license'/>
  </head>
  <Scene>
    <WorldInfo title='BindingOperations.x3d'/>
    <Viewpoint DEF='View1' centerOfRotation='-6 0 0' description='Viewpoint 1' position='-6 0 5'/>
    <Viewpoint DEF='View2' centerOfRotation='-2 0 0' description='Viewpoint 2' position='-2 0 5'/>
    <Viewpoint DEF='View3' centerOfRotation='2 0 0' description='Viewpoint 3' position='2 0 5'/>
    <Viewpoint DEF='View4' centerOfRotation='6 0 0' description='Viewpoint 4' position='6 0 5'/>
    <!-- Script initialization ought to first bind view5 below. -->
    <Group>
      <Transform DEF='Text1' translation='-6 0 0'>
        <Shape>
          <Text string='"View" "# 1"'>
            <FontStyle DEF='CenterJustify' justify='"MIDDLE" "MIDDLE"'/>
          </Text>
          <Appearance>
            <Material diffuseColor='1 0 0'/>
          </Appearance>
        </Shape>
      </Transform>
      <Transform DEF='Text2' translation='-2 0 0'>
        <Shape>
          <Text string='"View" "# 2"'>
            <FontStyle USE='CenterJustify'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0 1 0'/>
          </Appearance>
        </Shape>
      </Transform>
      <Transform DEF='Text3' translation='2 0 0'>
        <Shape>
          <Text string='"View" "# 3"'>
            <FontStyle USE='CenterJustify'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0 0 1'/>
          </Appearance>
        </Shape>
      </Transform>
      <Transform DEF='Text4' translation='6 0 0'>
        <Shape>
          <Text string='"View" "# 4"'>
            <FontStyle USE='CenterJustify'/>
          </Text>
          <Appearance>
            <Material/>
          </Appearance>
        </Shape>
      </Transform>
    </Group>
    <!-- The following advanced animation sequence uses nodes covered in Chapters 7, 8 and 9. -->
    <!-- It does not need to be studied in this chapter. -->
    <Transform translation='0 -3 8'>
      <!-- notice this next Viewpoint has been transformed with the text, so its position is relative. it is called view5 in the Script. -->
      <Viewpoint DEF='ClickToAnimateView' description='Select animation sequence' position='0 0 7'/>
      <Shape>
        <Text string='"Click here to animate"'>
          <FontStyle justify='"MIDDLE" "BEGIN"'/>
        </Text>
        <Appearance>
          <Material diffuseColor='0.8 0.4 0'/>
        </Appearance>
      </Shape>
      <Shape>
        <Box size='7 1 0.02'/>
        <Appearance>
          <Material transparency='1'/>
        </Appearance>
      </Shape>
      <TouchSensor DEF='TextTouchSensor' description='Click to begin animating viewpoint selections'/>
      <TimeSensor DEF='Clock' cycleInterval='10'/>
      <ROUTE fromField='touchTime' fromNode='TextTouchSensor' toField='set_startTime' toNode='Clock'/>
      <IntegerSequencer DEF='TimingSequencer' key='0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 1.0' keyValue='0 1 2 3 4 5 6 7 8 10'/>
      <ROUTE fromField='fraction_changed' fromNode='Clock' toField='set_fraction' toNode='TimingSequencer'/>
      <Script DEF='BindingSequencerEngine'>
        <field accessType='inputOnly' name='set_timeEvent' type='SFInt32'/>
        <field accessType='outputOnly' name='bindView1' type='SFBool'/>
        <field accessType='outputOnly' name='bindView2' type='SFBool'/>
        <field accessType='outputOnly' name='bindView3' type='SFBool'/>
        <field accessType='outputOnly' name='bindView4' type='SFBool'/>
        <field accessType='outputOnly' name='bindView5' type='SFBool'/>
        <field accessType='inputOnly' name='view1Bound' type='SFBool'/>
        <field accessType='inputOnly' name='view2Bound' type='SFBool'/>
        <field accessType='inputOnly' name='view3Bound' type='SFBool'/>
        <field accessType='inputOnly' name='view4Bound' type='SFBool'/>
        <field accessType='initializeOnly' name='priorInputvalue' type='SFInt32' value='-1'/>
        <![CDATA[
ecmascript:

function initialize ()
{
    bindView5 = true;
    Browser.println ('Timing script initialized and ready for activation');
}
function set_timeEvent (inputValue)
{
    if (inputValue == priorInputvalue)
    {
        return; // ignore repeated inputs
    }
    // new value provided
    priorInputvalue = inputValue;
    // Browser.println ('timeEvent inputValue=' + inputValue);
        
    // mimics user execution of Figure 4.1 steps t_0 through t_8
    if (inputValue == 0)
    {
        Browser.println ('===========');
        Browser.println ('time t0');
        bindView1 = true;
    }
    else if (inputValue == 1)
    {
        Browser.println ('===========');
        Browser.println ('time t1');
        bindView2 = true;
    }
    else if (inputValue == 2)
    {
        Browser.println ('===========');
        Browser.println ('time t2');
        bindView3 = true;
    }
    else if (inputValue == 3)
    {
        Browser.println ('===========');
        Browser.println ('time t3');
        bindView3 = false;
    }
    else if (inputValue == 4)
    {
        Browser.println ('===========');
        Browser.println ('time t4');
        bindView1 = true;
    }
    else if (inputValue == 5)
    {
        Browser.println ('===========');
        Browser.println ('time t5');
        bindView2 = false;
    }
    else if (inputValue == 6)
    {
        Browser.println ('===========');
        Browser.println ('time t6');
        bindView1 = false;
    }
    else if (inputValue == 7)
    {
        Browser.println ('===========');
        Browser.println ('time t7');
        bindView4 = true;

    }
    else if (inputValue == 8)
    {
        Browser.println ();
        Browser.println ('===========');
        Browser.println ('time t8, no action, all done');
    }
}

function view1Bound (inputValue)
{
    Browser.println (', view1Bound ' + (inputValue));
    if (priorInputvalue == -1) Browser.println ();
}
function view2Bound (inputValue)
{
    Browser.println (', view2Bound ' + (inputValue));
}
function view3Bound (inputValue)
{
    Browser.println (', view3Bound ' + (inputValue));
}
function view4Bound (inputValue)
{
    Browser.println (', view4Bound ' + (inputValue));
}
function view5Bound (inputValue)
{
    Browser.println (', view5Bound ' + (inputValue));
}
]]>
      </Script>
      <!-- drive Script with TimeSensor clock -->
      <ROUTE fromField='value_changed' fromNode='TimingSequencer' toField='set_timeEvent' toNode='BindingSequencerEngine'/>
      <!-- Script will bind and unbind Viewpoint nodes -->
      <ROUTE fromField='bindView1' fromNode='BindingSequencerEngine' toField='set_bind' toNode='View1'/>
      <ROUTE fromField='bindView2' fromNode='BindingSequencerEngine' toField='set_bind' toNode='View2'/>
      <ROUTE fromField='bindView3' fromNode='BindingSequencerEngine' toField='set_bind' toNode='View3'/>
      <ROUTE fromField='bindView4' fromNode='BindingSequencerEngine' toField='set_bind' toNode='View4'/>
      <ROUTE fromField='bindView5' fromNode='BindingSequencerEngine' toField='set_bind' toNode='ClickToAnimateView'/>
      <!-- Viewpoint nodes report bind and unbind events to Script for recording results -->
      <ROUTE fromField='isBound' fromNode='View1' toField='view1Bound' toNode='BindingSequencerEngine'/>
      <ROUTE fromField='isBound' fromNode='View2' toField='view2Bound' toNode='BindingSequencerEngine'/>
      <ROUTE fromField='isBound' fromNode='View3' toField='view3Bound' toNode='BindingSequencerEngine'/>
      <ROUTE fromField='isBound' fromNode='View4' toField='view4Bound' toNode='BindingSequencerEngine'/>
      <!-- Note that Script inputs do not cause Script outputs, and therefore no event loops occur. -->
      <!-- It is possible to silence event-loop diagnostic warnings by separating the functionality of Script inputs and outputs into two separate Script nodes. -->
    </Transform>
  </Scene>
</X3D>