1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "https://www.web3d.org/specifications/x3d-3.2.dtd">
|
3 | <X3D profile='Immersive' version='3.2' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.2.xsd'> |
4 | <head> |
5 | <meta name='title' content='Slider.x3d'/> |
6 | <meta name='description' content='X3D Follower example'/> |
7 | <meta name='creator' content='Herbert Stocker'/> |
8 | <meta name='translator' content='Don Brutzman'/> |
9 | <meta name='created' content='18 April 2006'/> |
10 | <meta name='translated' content='2 December 2011'/> |
11 | <meta name='modified' content='20 October 2019'/> |
12 | <meta name='reference' content='originals/test_Sliders.wrl'/> |
13 | <meta name='reference' content='Stocker_06_Followers.pdf'/> |
14 | <meta name='reference' content='http://www.hersto.com/Publications/Followers'/> |
15 | <meta name='requires' content='X3D version 3.2 or greater'/> |
16 | <meta name='subject' content='X3D Follower Chaser Damper'/> |
17 | <meta name=' warning ' content=' under development '/> |
18 | <meta name='reference' content='https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html'/> |
19 | <meta name='identifier' content='https://www.web3d.org/x3d/content/examples/Basic/Followers/Slider.x3d'/> |
20 | <meta name='generator' content='Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html'/> |
21 | <meta name='generator' content='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit'/> |
22 | <meta name='license' content='../../license.html'/> |
23 | </head> |
24 | <Scene> |
25 | <WorldInfo info=' " The original versions of the PROTO Slider was written by me, Herbert Stocker. The original versions and some test and demonstration Worlds can be found at http://www.hersto.de/ . " " You can use and modify the PROTO in this file if you keep the credit information valid and if you do not remove the link to the originating site http://www.hersto.de/ . In brief, keep this WorldInfo node along with the Proto. " " Please send a message to hersto@hersto.de where you describe how you use or improved the nodes. Especially if you included the improved versions. " ' title='Copyright (C) 2002 by Herbert Stocker (AKA hersto)'/> |
26 | <ProtoDeclare name='Slider'> |
27 | <ProtoInterface> |
28 | <field name='initial_position' type='SFFloat' value='0.5' accessType='initializeOnly'/> |
29 | <field name='credits' type='MFString' value=' "Initial idea and copyright by Herbert Stocker "http://www.hersto.com/"' accessType='initializeOnly'/> |
30 | <field name='radiusKnob' type='SFFloat' value='0.3' accessType='inputOutput'/> |
31 | <field name='radiusStick' type='SFFloat' value='0.2' accessType='inputOutput'/> |
32 | <field name='silently_set_unfiltered_position' type='SFFloat' accessType='inputOnly'/> |
33 | <field name='min' type='SFFloat' value='0.0' accessType='inputOutput'/> |
34 | <field name='position_changed' type='SFFloat' accessType='outputOnly'/> |
35 | <field name='appearance' type='SFNode' accessType='inputOutput'> |
36 | <Appearance> |
37 | <Material/> |
38 | </Appearance> |
39 | </field> |
40 | <field name='smoothMovements' type='SFBool' value='true' accessType='inputOutput'/> |
41 | <field name='set_position' type='SFFloat' accessType='inputOnly'/> |
42 | <field name='pageSize' type='SFFloat' value='0.2' accessType='inputOutput'/> |
43 | <field name='max' type='SFFloat' value='1.0' accessType='inputOutput'/> |
44 | <field name='unfiltered_position_changed' type='SFFloat' accessType='outputOnly'/> |
45 | <field name='silently_set_position' type='SFFloat' accessType='inputOnly'/> |
46 | <field name='set_unfiltered_position' type='SFFloat' accessType='inputOnly'/> |
47 | <field name='height' type='SFFloat' value='2.0' accessType='inputOutput'/> |
48 | <field name='positionInt_changed' type='SFInt32' accessType='outputOnly'/> |
49 | </ProtoInterface> |
50 | <ProtoBody> |
51 | <Billboard> |
52 |
<!-- Transform
TrStickAbove is a DEF node that has 1 USE node: USE_1 -->
<Transform DEF='TrStickAbove'> |
53 | |
54 | <Shape> |
55 | <IS> |
56 | <connect nodeField='appearance' protoField='appearance'/> |
57 | </IS> |
58 | <Cylinder height='1.0'/> |
59 | </Shape> |
60 | </Transform> |
61 |
<!-- Transform
TrStickBelow is a DEF node that has 1 USE node: USE_1 -->
<Transform DEF='TrStickBelow'> |
62 | |
63 | <Shape> |
64 | <IS> |
65 | <connect nodeField='appearance' protoField='appearance'/> |
66 | </IS> |
67 | <Cylinder height='1.0'/> |
68 | </Shape> |
69 | </Transform> |
70 | <Group> |
71 | <PlaneSensor DEF='SensKnob' autoOffset='false' description='touch to activate' maxPosition='0.0 -1.0'/> |
72 | |
73 | <Shape> |
74 | <IS> |
75 | <connect nodeField='appearance' protoField='appearance'/> |
76 | </IS> |
77 | <Cylinder height='1.0'/> |
78 | </Shape> |
79 | </Transform> |
80 | </Group> |
81 | </Billboard> |
82 | <ProtoDeclare name='EFFS'> |
83 | <ProtoInterface> |
84 | <field name='height' type='SFFloat' value='2.0' accessType='inputOutput'/> |
85 | <field name='max' type='SFFloat' value='1.0' accessType='inputOutput'/> |
86 | <field name='radiusKnob' type='SFFloat' value='0.5' accessType='inputOutput'/> |
87 | <field name='pageSize' type='SFFloat' value='0.2' accessType='inputOutput'/> |
88 | <field name='smoothMovements' type='SFBool' value='true' accessType='inputOutput'/> |
89 | <field name='radiusStick' type='SFFloat' value='0.25' accessType='inputOutput'/> |
90 | <field name='min' type='SFFloat' value='0.0' accessType='inputOutput'/> |
91 | </ProtoInterface> |
92 | <ProtoBody> |
93 | <Group/> |
94 | </ProtoBody> |
95 | </ProtoDeclare> |
96 | |
97 | <fieldValue name='max' value='1.0'/> |
98 | <fieldValue name='height' value='2.0'/> |
99 | <fieldValue name='pageSize' value='0.2'/> |
100 | <fieldValue name='radiusKnob' value='0.5'/> |
101 | <fieldValue name='smoothMovements' value='true'/> |
102 | <fieldValue name='radiusStick' value='0.25'/> |
103 | <fieldValue name='min' value='0.0'/> |
104 | </ProtoInstance> |
105 | |
106 | <Script DEF='Worker' directOutput='true'> |
107 | <field name='height' type='SFFloat' value='2.0' accessType='initializeOnly'/> |
108 | <field name='set_max' type='SFFloat' accessType='inputOnly'/> |
109 | <field name='silent' type='SFBool' value='false' accessType='initializeOnly'/> |
110 | <field name='lastTick' type='SFTime' value='0.0' accessType='initializeOnly'/> |
111 | <field name='set_pageSize' type='SFFloat' accessType='inputOnly'/> |
112 | <field name='decPage' type='SFTime' accessType='inputOnly'/> |
113 | <field name='set_radiusStick' type='SFFloat' accessType='inputOnly'/> |
114 | <field name='set_height' type='SFFloat' accessType='inputOnly'/> |
115 | <field name='position_changed' type='SFFloat' accessType='outputOnly'/> |
116 | <field name='Timer' type='SFNode' accessType='initializeOnly'> |
117 | <TimeSensor USE='Timer'/> |
118 | </field> |
119 | <field name='set_position' type='SFFloat' accessType='inputOnly'/> |
120 | <field name='snapTime' type='SFTime' value='0.0' accessType='initializeOnly'/> |
121 | <field name='TrStickAbove' type='SFNode' accessType='initializeOnly'> |
122 | <Transform USE='TrStickAbove'/> |
123 | </field> |
124 | <field name='set_radiusKnob' type='SFFloat' accessType='inputOnly'/> |
125 | <field name='smoothMovements' type='SFBool' value='true' accessType='initializeOnly'/> |
126 | <field name='max' type='SFFloat' value='1.0' accessType='initializeOnly'/> |
127 | <field name='initialUpdate' type='SFBool' value='true' accessType='initializeOnly'/> |
128 | <field name='EFFS' type='SFNode' accessType='initializeOnly'> |
129 | <ProtoInstance USE='EFFS'/> |
130 | </field> |
131 | <field name='SensKnobOrigin' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
132 | <field name='pageSize' type='SFFloat' value='0.2' accessType='initializeOnly'/> |
133 | <field name='positionInt_changed' type='SFInt32' accessType='outputOnly'/> |
134 | <field name='SmoothTau3' type='SFFloat' value='0.05' accessType='initializeOnly'/> |
135 | <field name='SmoothTau2' type='SFFloat' value='0.05' accessType='initializeOnly'/> |
136 | <field name='SmoothTau1' type='SFFloat' value='0.05' accessType='initializeOnly'/> |
137 | <field name='set_min' type='SFFloat' accessType='inputOnly'/> |
138 | <field name='SensKnob_isActive' type='SFBool' accessType='inputOnly'/> |
139 | <field name='KnobSize' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
140 | <field name='silently_set_position' type='SFFloat' accessType='inputOnly'/> |
141 | <field name='initialUnfilteredUpdate' type='SFBool' value='true' accessType='initializeOnly'/> |
142 | <field name='positionSmo3' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
143 | <field name='snapToInt' type='SFBool' value='false' accessType='initializeOnly'/> |
144 | <field name='positionSmo2' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
145 | <field name='set_unfiltered_position' type='SFFloat' accessType='inputOnly'/> |
146 | <field name='positionSmo1' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
147 | <field name='silently_set_unfiltered_position' type='SFFloat' accessType='inputOnly'/> |
148 | <field name='radiusStick' type='SFFloat' value='0.25' accessType='initializeOnly'/> |
149 | <field name='KnobCenterPos' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
150 | <field name='position' type='SFFloat' accessType='initializeOnly'/> |
151 | <field name='SensKnob_translationChanged' type='SFVec3f' accessType='inputOnly'/> |
152 | <field name='radiusKnob' type='SFFloat' value='0.5' accessType='initializeOnly'/> |
153 | <field name='TrStickBelow' type='SFNode' accessType='initializeOnly'> |
154 | <Transform USE='TrStickBelow'/> |
155 | </field> |
156 | <field name='TchPgUp' type='SFNode' accessType='initializeOnly'> |
157 | <TouchSensor USE='TchPgUp'/> |
158 | </field> |
159 | <field name='incPage' type='SFTime' accessType='inputOnly'/> |
160 | <field name='unfiltered_position_changed' type='SFFloat' accessType='outputOnly'/> |
161 | <field name='Tick' type='SFTime' accessType='inputOnly'/> |
162 | <field name='set_smooothMovements' type='SFBool' accessType='inputOnly'/> |
163 | <field name='min' type='SFFloat' value='0.0' accessType='initializeOnly'/> |
164 | <field name='TchPgDown' type='SFNode' accessType='initializeOnly'> |
165 | <TouchSensor USE='TchPgDown'/> |
166 | </field> |
167 | <field name='TrKnob' type='SFNode' accessType='initializeOnly'> |
168 | <Transform USE='TrKnob'/> |
169 | </field> |
170 | <IS> |
171 | <connect nodeField='position_changed' protoField='position_changed'/> |
172 | <connect nodeField='set_position' protoField='set_position'/> |
173 | <connect nodeField='positionInt_changed' protoField='positionInt_changed'/> |
174 | <connect nodeField='silently_set_position' protoField='silently_set_position'/> |
175 | <connect nodeField='set_unfiltered_position' protoField='set_unfiltered_position'/> |
176 | <connect nodeField='silently_set_unfiltered_position' protoField='silently_set_unfiltered_position'/> |
177 | <connect nodeField='position' protoField='initial_position'/> |
178 | <connect nodeField='unfiltered_position_changed' protoField='unfiltered_position_changed'/> |
179 | </IS> |
<![CDATA[
ecmascript: function initialize() { positionSmo1= position; positionSmo2= position; positionSmo3= position; min= EFFS.min; max= EFFS.max; pageSize= EFFS.pageSize; height= EFFS.height; radiusKnob= EFFS.radiusKnob; radiusStick= EFFS.radiusStick; smoothMovements= EFFS.smoothMovements; // work around the initialization bug in Contact 5. if( Browser.getName() == 'blaxxunCC3D' && Browser.getVersion() <= 5.104 && !position && !min && !max && !pageSize && !height && !radiusKnob && !radiusStick ) { position= .5; min= 0; max= 1; pageSize= .2; height= 2; radiusKnob= .3; radiusStick= .2; positionSmo1= positionSmo2= positionSmo3= position; } Update(); Timer.enabled= true; // TBD: Shouldn't we start with false? } function set_min(m) { min= m; Update(); } function set_max(m) { max= m; Update(); } function set_pageSize(s) { pageSize= s; Update(); } function set_height(h) { height= h; UpdateGeometry(); } function set_radiusKnob(r) { radiusKnob= r; UpdateGeometry(); } function set_radiusStick(r) { radiusStick= r; UpdateGeometry(); } function set_position(p) { silent= false; snapTime= 0; position= snapToInt? Math.floor(p + .5) : p; Update(); } function set_smooothMovements(s) { smoothMovements= s; Update(); } function silently_set_position(p) { silent= true; snapTime= 0; position= snapToInt? Math.floor(p + .5) : p; Update(); } function silently_set_unfiltered_position(p, now) { silent= true; snapTime= 0; position= positionSmo1= positionSmo2= positionSmo3= p; snapTime= now + .1; Update(); } function set_unfiltered_position(p, now) { snapTime= 0; position= positionSmo1= positionSmo2= positionSmo3= p; snapTime= now + .1; Update(); } function incPage(t, now) { silent= false; position+= pageSize; snapTime= now + .3; Update(); } function decPage(t, now) { silent= false; position-= pageSize; snapTime= now + .3; Update(); } function SensKnob_isActive(a, now) { if(a) { SensKnobOrigin= smoothMovements? positionSmo3 : position; // TBD: Da stimmt noch was nicht. SmoothTau1= .07; SmoothTau2= .001; SmoothTau3= .001; // last_SensKnob_translationChange= SensKnob_translationChanged; }else{ SmoothTau1= .06; SmoothTau2= .06; SmoothTau3= .06; snapTime= now; } } function SensKnob_translationChanged(t, now) { silent= false; // if(t.subtract(last_SensKnob_translationChange).length() > .0001 ) // { position= SensKnobOrigin + ( height? t.y * (max - min) / (height - KnobSize) : 0 ); // snapTime= now + .3; // last_SensKnob_translationChange= t; // } Update(); } function Update() { UpdateLogic(); UpdateGeometry(); if(smoothMovements) { setUPC(position); }else{ setUPC(position); positionSmo1= position; positionSmo2= position; positionSmo3= position; setPC(position); } } function UpdateLogic() { if(max < min) max= min; if(position > max) position= max; if(positionSmo1 > max) positionSmo1= max; if(positionSmo2 > max) positionSmo2= max; if(positionSmo3 > max) positionSmo3= max; if(position < min) position= min; if(positionSmo1 < min) positionSmo1= min; if(positionSmo2 < min) positionSmo2= min; if(positionSmo3 < min) positionSmo3= min; } function UpdateGeometry() { KnobSize= max - min? pageSize / (max - min) * height : height ; KnobCenterPos= max - min? ( ( smoothMovements? positionSmo3 : position ) - (max + min)/2 ) / (max - min) * (height - KnobSize) : 0 ; TrKnob.scale= new SFVec3f(radiusKnob, KnobSize, radiusKnob); TrKnob.translation= new SFVec3f(0, KnobCenterPos, 0); TrStickAbove.scale= new SFVec3f(radiusStick, (height/2 - KnobCenterPos), radiusStick); TrStickAbove.translation= new SFVec3f(0, (height/2 + KnobCenterPos)/2, 0 ); TrStickBelow.scale= new SFVec3f(radiusStick, (KnobCenterPos - -height/2), radiusStick); TrStickBelow.translation= new SFVec3f(0, (KnobCenterPos + -height/2)/2, 0 ); } function Tick(now) { if(!lastTick) { lastTick= now; return; } var Delta= now - lastTick; if(smoothMovements) // TBD: The timer should be completely off if !Smoothmovements. { positionSmo1= position + (positionSmo1 - position ) * Math.exp(-Delta/SmoothTau1); positionSmo2= positionSmo1 + (positionSmo2 - positionSmo1) * Math.exp(-Delta/SmoothTau2); positionSmo3= positionSmo2 + (positionSmo3 - positionSmo2) * Math.exp(-Delta/SmoothTau3); UpdateGeometry(); setPC(positionSmo3); } if(snapToInt) if(snapTime && now >= snapTime) { var newPos= Math.floor(position + .5); SensKnobOrigin+= newPos - position; position= newPos; snapTime= 0; } //TBD: Set Timer.enabled lastTick= now; } function setUPC(value) { if(unfiltered_position_changed != value || initialUnfilteredUpdate) if(!silent) unfiltered_position_changed= value; initialUnfilteredUpdate= false; } function setPC(value) { if(position_changed != value || initialUpdate) if(!silent) position_changed= value; if(Math.floor(position_changed + .5) != positionInt_changed || initialUpdate) if(!silent) positionInt_changed= Math.floor(position_changed + .5); initialUpdate= false; }
]]>
|
|
181 | </Script> |
182 | </ProtoBody> |
183 | </ProtoDeclare> |
184 | <!-- TODO anchor link --> |
185 | </Scene> |
186 | </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.
TchPgDown
TouchSensor |
description='touch to activate PgDown' User-interaction hint for this node.(TouchSensor description is providing a tooltip) |
TchPgUp
TouchSensor |
description='touch to activate PgUp' User-interaction hint for this node.(TouchSensor description is providing a tooltip) |
Worker
Script |
No ROUTE connection found for output events from this node. Contains SFNode fields with direct access to another node. |
EFFS
ProtoInstance EFFS |
No ROUTE connection found for output events from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
<!--
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)
<ProtoInstance
name='ProtoName'>
<field
name='fieldName'/> </ProtoInstance>
-->
<!-- For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints. -->