| 1 | <?xml version="1.0" encoding="UTF-8"?> | 
| 2 | <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd"> | 
| 3 | <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'> | 
| 4 | <head> | 
| 5 | <meta name='title' content=' FlyingTextPrototype.x3d '/> | 
| 6 | <meta name='description' content='Prototype definition for a flying text message. Waypoints, time intervals, cycleInterval and text message can be overridden.'/> | 
| 7 | <meta name='creator' content='Murat Onder and Don Brutzman'/> | 
| 8 | <meta name='created' content='2 June 2004'/> | 
| 9 | <meta name='modified' content='28 November 2019'/> | 
| 10 | <meta name='reference' content=' FlyingTextExample.x3d '/> | 
| 11 | <meta name='identifier' content=' https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/FlyingTextPrototype.x3d '/> | 
| 12 | <meta name='generator' content='X3D-Edit 3.3, https://www.web3d.org/x3d/tools/X3D-Edit'/> | 
| 13 | <meta name='license' content='../../license.html'/> | 
| 14 | </head> | 
 DEF nodes index: 
               
               AnimationScript,
Clock,
HideTextTrigger,
RevealTextTrigger,
TextAnimationGroup,
TextAnimator,
TextMessage,
TextMessageTransform,
TextVisibilityGroup,
TextVisibilitySwitch,
Toucher
               
               
                  DEF nodes index: 
               
               AnimationScript,
Clock,
HideTextTrigger,
RevealTextTrigger,
TextAnimationGroup,
TextAnimator,
TextMessage,
TextMessageTransform,
TextVisibilityGroup,
TextVisibilitySwitch,
Toucher
| 15 | <Scene> | 
| 16 | <WorldInfo title='FlyingTextPrototype.x3d'/> | 
| 17 | <ProtoDeclare name='FlyingText' appinfo='Visualize message transfer between two points as flying text'> | 
| 18 | <ProtoInterface> | 
| 19 | <field name='waypoints' type='MFVec3f' value='0 0 0 0 1 0' accessType='initializeOnly'/> | 
| 20 | <field name='set_waypoints' type='MFVec3f' accessType='inputOnly'/> | 
| 21 | <field name='timeIntervals' type='MFTime' value='1' accessType='initializeOnly'/> | 
| 22 | <field name='set_timeIntervals' type='MFTime' accessType='inputOnly'/> | 
| 23 | <field name='textMessage' type='MFString' value='"default"' accessType='initializeOnly'/> | 
| 24 | <field name='set_textMessage' type='MFString' accessType='inputOnly'/> | 
| 25 | <field name='visible' type='SFBool' value='true' accessType='initializeOnly'/> | 
| 26 | <field name='set_visible' type='SFBool' accessType='inputOnly'/> | 
| 27 | <field name='loop' type='SFBool' value='false' accessType='initializeOnly'/> | 
| 28 | <field name='axisOfRotation' type='SFVec3f' value='0 0 0' accessType='initializeOnly'/> | 
| 29 | <field name='timeSensorEnabled' type='SFBool' value='true' accessType='initializeOnly'/> | 
| 30 | <field name='startTime' type='SFTime' value='0' accessType='inputOutput'/> | 
| 31 | <field name='set_startTime' type='SFTime' accessType='inputOnly'/> | 
| 32 | <field name='stopTime' type='SFTime' value='0' accessType='inputOutput'/> | 
| 33 | <field name='set_stopTime' type='SFTime' accessType='inputOnly'/> | 
| 34 | <field name='traceEnabled' type='SFBool' value='false' accessType='initializeOnly'/> | 
| 35 | <field name='textDiffuseColor' type='SFColor' value='.2 .2 .4' accessType='inputOutput'/> | 
| 36 | <field name='fontStyle' type='SFNode' accessType='inputOutput'> | 
| 37 | <FontStyle justify='"MIDDLE" "MIDDLE"'/> | 
| 38 | </field> | 
| 39 | </ProtoInterface> | 
| 40 | <ProtoBody> | 
| 41 | <Group> | 
| 42 | <Billboard> | 
| 43 | <IS> | 
| 44 | <connect nodeField='axisOfRotation' protoField='axisOfRotation'/> | 
| 45 | </IS> | 
| 46 | 
                              <!-- ROUTE information for TextMessageTransform node: 
[from TextAnimator.value_changed to set_translation
                                                ]
 --> <Transform DEF='TextMessageTransform'> | 
| 47 | 
                                   <!-- ROUTE information for TextVisibilitySwitch node: 
[from HideTextTrigger.triggerValue to whichChoice
                                                      ]
[from RevealTextTrigger.triggerValue to whichChoice
                                                      ]
 --> <Switch DEF='TextVisibilitySwitch' whichChoice='-1'> | 
| 48 | <Shape> | 
| 49 | 
                                             <!-- Text
                                                                  TextMessage is a DEF node that has 1 USE node: USE_1 --> <Text DEF='TextMessage'> | 
| 50 | <IS> | 
| 51 | <connect nodeField='fontStyle' protoField='fontStyle'/> | 
| 52 | </IS> | 
| 53 | </Text> | 
| 54 | <Appearance> | 
| 55 | <Material> | 
| 56 | <IS> | 
| 57 | <connect nodeField='diffuseColor' protoField='textDiffuseColor'/> | 
| 58 | </IS> | 
| 59 | </Material> | 
| 60 | </Appearance> | 
| 61 | </Shape> | 
| 62 | 
                                        <!-- ROUTE information for Toucher node: 
[from touchTime to Clock.set_startTime
                                                            ]
 --> <TouchSensor DEF='Toucher' description='Touch to fly the text'/> | 
| 63 | </Switch> | 
| 64 | </Transform> | 
| 65 | <Group DEF='TextAnimationGroup'> | 
| 66 | 
                                   <!-- TimeSensor
                                                      Clock is a DEF node that has 1 USE node: USE_1
                                                       <!-- ROUTE information for Clock node: [from Toucher.touchTime to set_startTime ] [from fraction_changed to TextAnimator.set_fraction ] --> <TimeSensor DEF='Clock'> | 
| 67 | <IS> | 
| 68 | <connect nodeField='loop' protoField='loop'/> | 
| 69 | <connect nodeField='enabled' protoField='timeSensorEnabled'/> | 
| 70 | <connect nodeField='startTime' protoField='startTime'/> | 
| 71 | <connect nodeField='set_startTime' protoField='set_startTime'/> | 
| 72 | <connect nodeField='stopTime' protoField='stopTime'/> | 
| 73 | <connect nodeField='set_stopTime' protoField='set_stopTime'/> | 
| 74 | </IS> | 
| 75 | </TimeSensor> | 
| 76 | < ROUTE fromNode='Toucher' fromField='touchTime' toNode='Clock' toField='set_startTime'/> | 
| 77 | 
                                   <!-- PositionInterpolator
                                                      TextAnimator is a DEF node that has 1 USE node: USE_1
                                                       <!-- ROUTE information for TextAnimator node: [from Clock.fraction_changed to set_fraction ] [from value_changed to TextMessageTransform.set_translation ] --> <PositionInterpolator DEF='TextAnimator'/> | 
| 78 | < ROUTE fromNode='Clock' fromField='fraction_changed' toNode='TextAnimator' toField='set_fraction'/> | 
| 79 | < ROUTE fromNode='TextAnimator' fromField='value_changed' toNode='TextMessageTransform' toField='set_translation'/> | 
| 80 | </Group> | 
| 81 | </Billboard> | 
| 82 | 
                         <!-- ROUTE information for AnimationScript node: 
[from hideText to HideTextTrigger.set_boolean
                                          ]
[from revealText to RevealTextTrigger.set_boolean
                                          ]
 --> <Script DEF='AnimationScript' directOutput='true'> | 
| 83 | <field name='traceEnabled' type='SFBool' accessType='initializeOnly'/> | 
| 84 | <field name='interpolatorNode' type='SFNode' accessType='initializeOnly'> | 
| 85 | <PositionInterpolator USE='TextAnimator'/> | 
| 86 | </field> | 
| 87 | <field name='textNode' type='SFNode' accessType='initializeOnly'> | 
| 88 | <Text USE='TextMessage'/> | 
| 89 | </field> | 
| 90 | <field name='timeSensorNode' type='SFNode' accessType='initializeOnly'> | 
| 91 | <TimeSensor USE='Clock'/> | 
| 92 | </field> | 
| 93 | <field name='waypoints' type='MFVec3f' accessType='initializeOnly'/> | 
| 94 | <field name='set_waypoints' type='MFVec3f' accessType='inputOnly'/> | 
| 95 | <field name='timeIntervals' type='MFTime' accessType='initializeOnly'/> | 
| 96 | <field name='set_timeIntervals' type='MFTime' accessType='inputOnly'/> | 
| 97 | <field name='textMessage' type='MFString' accessType='initializeOnly'/> | 
| 98 | <field name='set_textMessage' type='MFString' accessType='inputOnly'/> | 
| 99 | <field name='visible' type='SFBool' accessType='initializeOnly'/> | 
| 100 | <field name='set_visible' type='SFBool' accessType='inputOnly'/> | 
| 101 | <field name='hideText' type='SFBool' accessType='outputOnly'/> | 
| 102 | <field name='revealText' type='SFBool' accessType='outputOnly'/> | 
| 103 | <field name='set_startTime' type='SFTime' accessType='inputOnly'/> | 
| 104 | <field name='totalDuration' type='SFTime' value='0' accessType='initializeOnly'/> | 
| 105 | <IS> | 
| 106 | <connect nodeField='traceEnabled' protoField='traceEnabled'/> | 
| 107 | <connect nodeField='waypoints' protoField='waypoints'/> | 
| 108 | <connect nodeField='set_waypoints' protoField='set_waypoints'/> | 
| 109 | <connect nodeField='timeIntervals' protoField='timeIntervals'/> | 
| 110 | <connect nodeField='set_timeIntervals' protoField='set_timeIntervals'/> | 
| 111 | <connect nodeField='textMessage' protoField='textMessage'/> | 
| 112 | <connect nodeField='set_textMessage' protoField='set_textMessage'/> | 
| 113 | <connect nodeField='visible' protoField='visible'/> | 
| 114 | <connect nodeField='set_visible' protoField='set_visible'/> | 
| 115 | <connect nodeField='set_startTime' protoField='set_startTime'/> | 
| 116 | </IS> | 
| 
                                                   <![CDATA[
                                                
            
ecmascript:
function initialize()
{
   if ((waypoints.length - timeIntervals.length) == 1 )
   {
     set_textMessage(textMessage);
     set_timeIntervals(timeIntervals);
     set_waypoints(waypoints);
   }
   else
   {
     alwaysPrint('timeIntervals.length=' + timeIntervals.length + ' should be one less '
                + 'than waypoints.length=' + waypoints.length);
     alwaysPrint ('timeIntervals=' + timeIntervals);
     alwaysPrint ('waypoints    =' + waypoints);
   }
   if (visible) revealText = true;
   else           hideText = true;
   tracePrint ('visible = ' + visible);
}
function set_textMessage(text)
{
   textNode.string = text;
   tracePrint ('textNode.string = ' + textNode.string);
}
function set_waypoints(waypointsArray)
{
   interpolatorNode.keyValue = waypointsArray;
   tracePrint ('interpolatorNode.keyValue = ' + interpolatorNode.keyValue);
}
function set_timeIntervals(intervals)
{
   tracePrint ('set_timeIntervals(' + timeIntervals + ')');
   totalDuration = 0;
   for(i = 0; i < timeIntervals.length; i++)
   {
      totalDuration = totalDuration + timeIntervals[i];
   }
   tracePrint ('totalDuration = ' + totalDuration);
   timeSensorNode.cycleInterval = totalDuration;
   interpolatorNode.key[0] = 0.0;
   for (j = 0; j < timeIntervals.length; j++)
   {
      interpolatorNode.key[j+1] = interpolatorNode.key[j] + timeIntervals[j]/totalDuration;
      tracePrint ('interpolatorNode.key[j] = ' + interpolatorNode.key[j]);
   }
   tracePrint ('interpolatorNode.key = ' + interpolatorNode.key);
}
function set_visible (value, timestamp)
{
	visible = value;
	if (visible) revealText = true;
	else           hideText = true;
	tracePrint ('visible = ' + visible);
}
function set_startTime (value, timestamp)
{
	tracePrint ('set_startTime = ' + value);
	set_visible (true);  // ensure visible when activated
	initialize ();       // ensure all computations up to date
}
function tracePrint(value)
{
   if (traceEnabled) alwaysPrint(value);
}
function alwaysPrint(value)
{
      if (textMessage.length > 1)
	       Browser.println ('[FlyingText ' + textMessage + '] ' + value);
      else Browser.println ('[FlyingText] ' + value);
}
          
                                                   ]]>
                                                 | |
| 118 | </Script> | 
| 119 | <Group DEF='TextVisibilityGroup'> | 
| 120 | 
                              <!-- ROUTE information for HideTextTrigger node: 
[from AnimationScript.hideText to set_boolean
                                                ]
[from triggerValue to TextVisibilitySwitch.whichChoice
                                                ]
 --> <IntegerTrigger DEF='HideTextTrigger'/> | 
| 121 | < ROUTE fromNode='AnimationScript' fromField='hideText' toNode='HideTextTrigger' toField='set_boolean'/> | 
| 122 | < ROUTE fromNode='HideTextTrigger' fromField='triggerValue' toNode='TextVisibilitySwitch' toField='whichChoice'/> | 
| 123 | 
                              <!-- ROUTE information for RevealTextTrigger node: 
[from AnimationScript.revealText to set_boolean
                                                ]
[from triggerValue to TextVisibilitySwitch.whichChoice
                                                ]
 --> <IntegerTrigger DEF='RevealTextTrigger' integerKey='0'/> | 
| 124 | < ROUTE fromNode='AnimationScript' fromField='revealText' toNode='RevealTextTrigger' toField='set_boolean'/> | 
| 125 | < ROUTE fromNode='RevealTextTrigger' fromField='triggerValue' toNode='TextVisibilitySwitch' toField='whichChoice'/> | 
| 126 | </Group> | 
| 127 | </Group> | 
| 128 | </ProtoBody> | 
| 129 | </ProtoDeclare> | 
| 130 | <!-- ============================ --> | 
| 131 | <Anchor description='FlyingText Example' parameter='"target=_blank"' url=' "../../../Savage/Tools/Animation/FlyingTextExample.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/FlyingTextExample.x3d" "../../../Savage/Tools/Animation/FlyingTextExample.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/FlyingTextExample.wrl" '> | 
| 132 | <Shape> | 
| 133 | <Text string='"FlyingTextPrototype" "defines a prototype" "" "Click text to see example scene" "" "(Text has Billboard style)"'> | 
| 134 | <FontStyle justify='"MIDDLE" "MIDDLE"' size='0.7'/> | 
| 135 | </Text> | 
| 136 | <Appearance> | 
| 137 | <Material diffuseColor='.8 .7 0.2'/> | 
| 138 | </Appearance> | 
| 139 | </Shape> | 
| 140 | </Anchor> | 
| 141 | </Scene> | 
| 142 | </X3D> | 
 DEF nodes index: 
         
         AnimationScript,
Clock,
HideTextTrigger,
RevealTextTrigger,
TextAnimationGroup,
TextAnimator,
TextMessage,
TextMessageTransform,
TextVisibilityGroup,
TextVisibilitySwitch,
Toucher
         
         
            DEF nodes index: 
         
         AnimationScript,
Clock,
HideTextTrigger,
RevealTextTrigger,
TextAnimationGroup,
TextAnimator,
TextMessage,
TextMessageTransform,
TextVisibilityGroup,
TextVisibilitySwitch,
Toucher
Event Graph ROUTE Table entries with 7 ROUTE connections total, showing X3D event-model relationships for this scene.
Each row shows an event cascade that may occur during a single timestamp interval between frame renderings, as part of the X3D execution model.
| Toucher TouchSensor touchTime SFTime | Clock TimeSensor set_startTime SFTime | then | Clock TimeSensor fraction_changed SFFloat | TextAnimator PositionInterpolator set_fraction SFFloat | then | TextAnimator PositionInterpolator value_changed SFVec3f | TextMessageTransform Transform set_translation SFVec3f | 
| AnimationScript Script hideText SFBool | HideTextTrigger IntegerTrigger set_boolean SFBool | then | HideTextTrigger IntegerTrigger triggerValue SFInt32 | TextVisibilitySwitch Switch whichChoice SFInt32 | ||
| AnimationScript Script revealText SFBool | RevealTextTrigger IntegerTrigger set_boolean SFBool | then | RevealTextTrigger IntegerTrigger triggerValue SFInt32 | TextVisibilitySwitch Switch whichChoice SFInt32 | 
| line 131 Anchor | description='FlyingText Example' User-interaction hint for this node. | 
         <!--
Color-coding legend: X3D terminology 
<X3dNode
          DEF='idName' field='value'/> 
 matches XML terminology 
<XmlElement
          DEF='idName' attribute='value'/> 
(Light-blue background: event-based behavior node or statement)
(Grey background inside box: inserted documentation)
(Magenta background: X3D Extensibility)
   
<ProtoDeclare name='ProtoName'>
	<field
         name='fieldName'/> </ProtoDeclare>
 -->
      
         
             <!--
For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints.
-->
         
         <!--
For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints.
-->