<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D profile='Immersive' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
  <head>
    <meta content='ShuttlesAndPendulums.x3d' name='title'/>
    <meta content='X3D encodings example: animation of shuttle and pendulum prototype nodes.' name='description'/>
    <meta content='Don Brutzman and Joe Williams' name='creator'/>
    <meta content='1 June 2002' name='created'/>
    <meta content='28 September 2025' name='modified'/>
    <meta content='X3D encodings, ISO/IEC 19776-1.3, Part 1: XML encoding, Annex C.14 Shuttles and pendulums' name='specificationSection'/>
    <meta content='https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19776-1v4.0-CD/Part01/examples.html#ShuttlesAndPendulums' name='specificationUrl'/>
    <meta content='https://www.web3d.org/x3d/content/examples/Basic/X3dSpecifications/ShuttlesAndPendulums.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='ShuttlesAndPendulums.x3d'/>
    <ProtoDeclare name='Shuttle'>
      <ProtoInterface>
        <field accessType='initializeOnly' name='rate' type='SFTime' value='1'/>
        <field accessType='initializeOnly' name='distance' type='SFFloat' value='1'/>
        <field accessType='initializeOnly' name='children' type='MFNode'>
          <!-- initial value is empty node array -->
        </field>
        <field accessType='inputOutput' name='startTime' type='SFTime' value='0'/>
        <field accessType='inputOutput' name='stopTime' type='SFTime' value='0'/>
        <field accessType='initializeOnly' name='loop' type='SFBool' value='true'/>
      </ProtoInterface>
      <ProtoBody>
        <Transform DEF='F'>
          <IS>
            <connect nodeField='children' protoField='children'/>
          </IS>
        </Transform>
        <!-- after first node in ProtoDeclare, remainder of nodes do not render -->
        <TimeSensor DEF='T'>
          <IS>
            <connect nodeField='cycleInterval' protoField='rate'/>
            <connect nodeField='startTime' protoField='startTime'/>
            <connect nodeField='stopTime' protoField='stopTime'/>
            <connect nodeField='loop' protoField='loop'/>
          </IS>
        </TimeSensor>
        <Script DEF='S'>
          <field accessType='initializeOnly' name='distance' type='SFFloat'/>
          <field accessType='outputOnly' name='position' type='MFVec3f'/>
          <IS>
            <connect nodeField='distance' protoField='distance'/>
          </IS>
          <![CDATA[
ecmascript:
            function initialize () {     // constructor:setup interpolator
              pos1 = new SFVec3f(-distance, 0, 0);
              pos2 = new SFVec3f(distance, 0, 0);
              position = new MFVec3f(pos1, pos2, pos1);
            }
]]>
        </Script>
        <PositionInterpolator DEF='I' key='0 0.5 1' keyValue='-1 0 0 1 0 0 -1 0 0'/>
        <ROUTE fromField='fraction_changed' fromNode='T' toField='set_fraction' toNode='I'/>
        <ROUTE fromField='value_changed' fromNode='I' toField='translation' toNode='F'/>
        <ROUTE fromField='position' fromNode='S' toField='keyValue' toNode='I'/>
      </ProtoBody>
    </ProtoDeclare>
    <ProtoDeclare name='Pendulum'>
      <ProtoInterface>
        <field accessType='initializeOnly' name='rate' type='SFTime' value='1'/>
        <field accessType='initializeOnly' name='maxAngle' type='SFFloat' value='3.14159'/>
        <field accessType='initializeOnly' name='children' type='MFNode'>
          <!-- initial value is empty node array -->
        </field>
        <field accessType='inputOutput' name='startTime' type='SFTime' value='0'/>
        <field accessType='inputOutput' name='stopTime' type='SFTime' value='0'/>
        <field accessType='initializeOnly' name='loop' type='SFBool' value='true'/>
      </ProtoInterface>
      <ProtoBody>
        <Transform DEF='FF'>
          <IS>
            <connect nodeField='children' protoField='children'/>
          </IS>
        </Transform>
        <!-- after first node in ProtoDeclare, remainder of nodes do not render -->
        <TimeSensor DEF='TT'>
          <IS>
            <connect nodeField='cycleInterval' protoField='rate'/>
            <connect nodeField='startTime' protoField='startTime'/>
            <connect nodeField='stopTime' protoField='stopTime'/>
            <connect nodeField='loop' protoField='loop'/>
          </IS>
        </TimeSensor>
        <Script DEF='SS'>
          <field accessType='initializeOnly' name='maxAngle' type='SFFloat'/>
          <field accessType='outputOnly' name='rotation' type='MFRotation'/>
          <IS>
            <connect nodeField='maxAngle' protoField='maxAngle'/>
          </IS>
          <![CDATA[
ecmascript:
            function initialize() {     // constructor: setup interpolator
              rot1 = new SFRotation(0, 0, 1, 0);
              rot2 = new SFRotation(0, 0, 1, maxAngle/2);
              rot3 = new SFRotation(0, 0, 1, maxAngle);
              rotation = new MFRotation(rot1, rot2, rot3, rot2, rot1);
            }
]]>
        </Script>
        <OrientationInterpolator DEF='II' key='0 0.25 0.5 0.75 1' keyValue='0 0 1 0 0 0 1 1.57 0 0 1 3.14 0 0 1 1.57 0 0 1 0'/>
        <ROUTE fromField='fraction_changed' fromNode='TT' toField='set_fraction' toNode='II'/>
        <ROUTE fromField='value_changed' fromNode='II' toField='rotation' toNode='FF'/>
        <ROUTE fromField='rotation' fromNode='SS' toField='keyValue' toNode='II'/>
      </ProtoBody>
    </ProtoDeclare>
    <Transform translation='-3 0 0'>
      <ProtoInstance name='Pendulum'>
        <fieldValue name='rate' value='3'/>
        <fieldValue name='maxAngle' value='6.28'/>
        <fieldValue name='children'>
          <Shape>
            <Cylinder height='5'/>
            <Appearance>
              <Material diffuseColor='0.8 0.1 0'/>
            </Appearance>
          </Shape>
        </fieldValue>
      </ProtoInstance>
    </Transform>
    <Transform>
      <ProtoInstance name='Shuttle'>
        <fieldValue name='rate' value='2'/>
        <fieldValue name='children'>
          <Shape>
            <Sphere/>
            <Appearance>
              <Material diffuseColor='0.1 0.8 0'/>
            </Appearance>
          </Shape>
        </fieldValue>
      </ProtoInstance>
    </Transform>
  </Scene>
</X3D>