1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
|
3 | <X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.0.xsd'> |
4 | <head> |
5 | <meta name='title' content='BooleanSequencerPrototype.x3d'/> |
6 | <meta name='description' content='BooleanSequencer is modeled after ScalarInterpolator and generates true or false values.'/> |
7 | <meta name='creator' content='Don Brutzman, Estuko Lippi, Jeff Weekley, Jane Wu'/> |
8 | <meta name='created' content='7 August 2001'/> |
9 | <meta name='modified' content='20 January 2020'/> |
10 | <meta name='reference' content='https://www.web3d.org/technicalinfo/specifications/vrml97/part1/nodesRef.html#ScalarInterpolator'/> |
11 | <meta name='subject' content='boolean sequencer'/> |
12 | <meta name='identifier' content='https://www.web3d.org/x3d/content/examples/Basic/development/BooleanSequencerPrototype.x3d'/> |
13 | <meta name='generator' content='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit'/> |
14 | <meta name='license' content='../license.html'/> |
15 | </head> |
16 | <Scene> |
17 | <WorldInfo title='BooleanSequencerPrototype.x3d'/> |
18 | <ProtoDeclare name='BooleanSequencer'> |
19 | <ProtoInterface> |
20 |
<field name='set_fraction' type='SFFloat' accessType='inputOnly'
appinfo='Regular interpolator-style input, typical range [0..1]'/> |
21 | <field name='set_key' type='MFFloat' accessType='inputOnly'/> |
22 |
<field name='key' type='MFFloat' accessType='inputOutput'
appinfo='Array sequentially increasing typically [0..1]. Must have the same number of keys as keyValues.'> |
23 | <!-- NULL initialization value --> |
24 | </field> |
25 | <field name='key_changed' type='MFFloat' accessType='outputOnly'/> |
26 | <field name='set_keyValue' type='MFBool' accessType='inputOnly'/> |
27 |
<field name='keyValue' type='MFBool' accessType='inputOutput'
appinfo='Array of true|false values. Must have the same number of keys as keyValues.'> |
28 | <!-- NULL initialization value --> |
29 | </field> |
30 |
<field name='keyValue_changed' type='MFBool' accessType='outputOnly'
appinfo='Regular interpolator-style input'/> |
31 |
<field name='value_changed' type='SFBool' accessType='outputOnly'
appinfo='Regular interpolator-style input'/> |
32 |
<field name='previous' type='SFBool' accessType='inputOnly'
appinfo='Utility method'/> |
33 |
<field name='next' type='SFBool' accessType='inputOnly'
appinfo='Utility method'/> |
34 | </ProtoInterface> |
35 | <ProtoBody> |
36 | <Group> |
37 | |
38 | <IS> |
39 | <connect nodeField='key' protoField='key'/> |
40 | </IS> |
41 | </ScalarInterpolator> |
42 |
<!-- Anchor
KeyValueHolder is a DEF node that has 1 USE node: USE_1 -->
<Anchor DEF='KeyValueHolder'> |
43 | <IS> |
44 | <connect nodeField='description' protoField='keyValue'/> |
45 | </IS> |
46 | </Anchor> |
47 | <Script DEF='SequencerScript' directOutput='true'> |
48 | <!-- Regular interpolator-style input --> |
49 |
<field name='set_fraction' type='SFFloat' accessType='inputOnly'
appinfo='typical range [0..1]'/> |
50 |
<field name='set_key' type='MFFloat' accessType='inputOnly'
appinfo='Array sequentially increasing typically [0..1]. Must have the same number of keys as keyValues.'/> |
51 | <field name='keyHolderNode' type='SFNode' accessType='initializeOnly'> |
52 | <ScalarInterpolator USE='KeyHolder'/> |
53 | </field> |
54 | <field name='key_changed' type='MFFloat' accessType='outputOnly'/> |
55 |
<field name='set_keyValue' type='MFBool' accessType='inputOnly'
appinfo='Array of true or false values. Must have the same number of keys as keyValues.'/> |
56 | <field name='keyValueHolderNode' type='SFNode' accessType='initializeOnly'> |
57 | <Anchor USE='KeyValueHolder'/> |
58 | </field> |
59 | <field name='keyValue_changed' type='MFBool' accessType='outputOnly'/> |
60 | <!-- Regular interpolator-style output --> |
61 | <field name='value_changed' type='SFBool' accessType='outputOnly'/> |
62 | <!-- Utility methods --> |
63 | <field name='previous' type='SFBool' accessType='inputOnly'/> |
64 | <field name='next' type='SFBool' accessType='inputOnly'/> |
65 | <!-- Script-specific interfaces, not needed for node definition --> |
66 | <field name='traceEnabled' type='SFBool' value='false' accessType='initializeOnly'/> |
67 | <field name='keyValueArray' type='MFInt32' accessType='initializeOnly'> |
68 | <!-- NULL initialization value --> |
69 | </field> |
70 | <field name='previousFraction' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
71 | <field name='nextIndex' type='SFInt32' value='0' accessType='initializeOnly'/> |
72 | <field name='valid' type='SFBool' value='true' accessType='outputOnly'/> |
73 | <field name='recheckValidity' type='SFBool' value='false' accessType='initializeOnly'/> |
74 |
<field name='forward' type='SFBool' value='true' accessType='initializeOnly'
appinfo='leftToRight'/> |
75 | <field name='key' type='MFFloat' accessType='inputOnly'> |
76 | <!-- NULL initialization value --> |
77 | </field> |
78 | <field name='keyValue' type='MFInt32' accessType='inputOutput'> |
79 | <!-- NULL initialization value --> |
80 | </field> |
81 | <IS> |
82 | <connect nodeField='set_fraction' protoField='set_fraction'/> |
83 | <connect nodeField='set_key' protoField='set_key'/> |
84 | <connect nodeField='key_changed' protoField='key_changed'/> |
85 | <connect nodeField='set_keyValue' protoField='set_keyValue'/> |
86 | <connect nodeField='keyValue_changed' protoField='keyValue_changed'/> |
87 | <connect nodeField='value_changed' protoField='value_changed'/> |
88 | <connect nodeField='previous' protoField='previous'/> |
89 | <connect nodeField='next' protoField='next'/> |
90 | </IS> |
<![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) { alwaysPrint ('*** 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) { alwaysPrint ('*** 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) { alwaysPrint('*** warning: fraction is less than 0. fraction reset to 0 ***'); value = 0; } else if (value > 1) { alwaysPrint('*** 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) { alwaysPrint('*** 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) { alwaysPrint('*** 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) { alwaysPrint('*** error: key[' + i + '] value is NOT in the range of [0..1]. BooleanSequencer ignored ***'); valid = false; return; } if (key[i] <= key [i-1]) { alwaysPrint('*** 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.println ('[ BooleanSequencer ]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[ BooleanSequencer ]' + outputString); }
]]>
|
|
92 | </Script> |
93 | </Group> |
94 | </ProtoBody> |
95 | </ProtoDeclare> |
96 | <!-- ===============Example============== --> |
97 | <Anchor description='BooleanSequencerExample' parameter='"target=_blank"' url=' "BooleanSequencerExample.x3d" "https://www.web3d.org/x3d/content/examples/Basic/development/BooleanSequencerExample.x3d" "BooleanSequencerExample.wrl" "https://www.web3d.org/x3d/content/examples/Basic/development/BooleanSequencerExample.wrl" '> |
98 | <Shape> |
99 | <Text string='"BooleanSequencerPrototype" "defines a prototype" "" "Click on this text to see" "BooleanSequencerExample" " scene"'> |
100 | <FontStyle justify='"MIDDLE" "MIDDLE"'/> |
101 | </Text> |
102 | <Appearance> |
103 | <Material diffuseColor='1 1 0.2'/> |
104 | </Appearance> |
105 | </Shape> |
106 | </Anchor> |
107 | </Scene> |
108 | </X3D> |
Event Graph ROUTE Table with 0 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.
SequencerScript
Script |
No ROUTE connection found for output events from this node. Contains SFNode fields with direct access to another node. |
Anchor |
description='BooleanSequencerExample' User-interaction hint for this node. |
<!--
Color 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. -->