X3D Model Documentation: Slider.x3d

  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='titlecontent='Slider.x3d'/>
  6            <meta name='descriptioncontent='X3D Follower example'/>
  7            <meta name='creatorcontent='Herbert Stocker'/>
  8            <meta name='translatorcontent='Don Brutzman'/>
  9            <meta name='createdcontent='18 April 2006'/>
 10            <meta name='translatedcontent='2 December 2011'/>
 11            <meta name='modifiedcontent='20 October 2019'/>
 12            <meta name='referencecontent='originals/test_Sliders.wrl'/>
 13            <meta name='referencecontent='Stocker_06_Followers.pdf'/>
 14            <meta name='referencecontent='http://www.hersto.com/Publications/Followers'/>
 15            <meta name='requirescontent='X3D version 3.2 or greater'/>
 16            <meta name='subjectcontent='X3D Follower Chaser Damper'/>
 17            <meta name=' warning content=' under development '/>
 18            <meta name='referencecontent='https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html'/>
 19            <meta name='identifiercontent='https://www.web3d.org/x3d/content/examples/Basic/Followers/Slider.x3d'/>
 20            <meta name='generatorcontent='Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html'/>
 21            <meta name='generatorcontent='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit'/>
 22            <meta name='licensecontent='../../license.html'/>
 23       </head>
<!--

<!--
Event Graph ROUTE Table shows event connections.
-->

<!-- to top Index for DEF nodes: EFFS, SensKnob, TchPgDown, TchPgUp, Timer, TrKnob, TrStickAbove, TrStickBelow, Worker

Index for ProtoDeclare definitions: EFFS, Slider
-->
 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_positiontype='SFFloatvalue='0.5accessType='initializeOnly'/>
 29                      <field name='creditstype='MFStringvalue=' "Initial idea and copyright by Herbert Stocker "http://www.hersto.com/"' accessType='initializeOnly'/>
 30                      <field name='radiusKnobtype='SFFloatvalue='0.3accessType='inputOutput'/>
 31                      <field name='radiusSticktype='SFFloatvalue='0.2accessType='inputOutput'/>
 32                      <field name='silently_set_unfiltered_positiontype='SFFloataccessType='inputOnly'/>
 33                      <field name='mintype='SFFloatvalue='0.0accessType='inputOutput'/>
 34                      <field name='position_changedtype='SFFloataccessType='outputOnly'/>
 35                      <field name='appearancetype='SFNodeaccessType='inputOutput'>
 36                           <Appearance>
 37                                <Material/>
 38                           </Appearance>
 39                      </field>
 40                      <field name='smoothMovementstype='SFBoolvalue='trueaccessType='inputOutput'/>
 41                      <field name='set_positiontype='SFFloataccessType='inputOnly'/>
 42                      <field name='pageSizetype='SFFloatvalue='0.2accessType='inputOutput'/>
 43                      <field name='maxtype='SFFloatvalue='1.0accessType='inputOutput'/>
 44                      <field name='unfiltered_position_changedtype='SFFloataccessType='outputOnly'/>
 45                      <field name='silently_set_positiontype='SFFloataccessType='inputOnly'/>
 46                      <field name='set_unfiltered_positiontype='SFFloataccessType='inputOnly'/>
 47                      <field name='heighttype='SFFloatvalue='2.0accessType='inputOutput'/>
 48                      <field name='positionInt_changedtype='SFInt32accessType='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 
                              <!-- TouchSensor TchPgUp is a DEF node that has 1 USE node: USE_1 -->
                              <TouchSensor DEF='TchPgUpdescription='touch to activate PgUp'/>
 54                                <Shape>
 55                                     <IS>
 56                                          <connect nodeField='appearanceprotoField='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 
                              <!-- TouchSensor TchPgDown is a DEF node that has 1 USE node: USE_1 -->
                              <TouchSensor DEF='TchPgDowndescription='touch to activate PgDown'/>
 63                                <Shape>
 64                                     <IS>
 65                                          <connect nodeField='appearanceprotoField='appearance'/>
 66                                     </IS>
 67                                     <Cylinder height='1.0'/>
 68                                </Shape>
 69                           </Transform>
 70                           <Group>
 71                                <PlaneSensor DEF='SensKnobautoOffset='falsedescription='touch to activatemaxPosition='0.0 -1.0'/>
 72 
                              <!-- Transform TrKnob is a DEF node that has 1 USE node: USE_1 -->
                              <Transform DEF='TrKnob'>
 73                                     <Shape>
 74                                          <IS>
 75                                               <connect nodeField='appearanceprotoField='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='heighttype='SFFloatvalue='2.0accessType='inputOutput'/>
 85                                <field name='maxtype='SFFloatvalue='1.0accessType='inputOutput'/>
 86                                <field name='radiusKnobtype='SFFloatvalue='0.5accessType='inputOutput'/>
 87                                <field name='pageSizetype='SFFloatvalue='0.2accessType='inputOutput'/>
 88                                <field name='smoothMovementstype='SFBoolvalue='trueaccessType='inputOutput'/>
 89                                <field name='radiusSticktype='SFFloatvalue='0.25accessType='inputOutput'/>
 90                                <field name='mintype='SFFloatvalue='0.0accessType='inputOutput'/>
 91                           </ProtoInterface>
 92                           <ProtoBody>
 93                                <Group/>
 94                           </ProtoBody>
 95                      </ProtoDeclare>
 96 
                    <!-- ProtoInstance EFFS is a DEF node that has 1 USE node: USE_1 -->
                    <ProtoInstance name='EFFSDEF='EFFS'>
 97                           <fieldValue name='maxvalue='1.0'/>
 98                           <fieldValue name='heightvalue='2.0'/>
 99                           <fieldValue name='pageSizevalue='0.2'/>
100                           <fieldValue name='radiusKnobvalue='0.5'/>
101                           <fieldValue name='smoothMovementsvalue='true'/>
102                           <fieldValue name='radiusStickvalue='0.25'/>
103                           <fieldValue name='minvalue='0.0'/>
104                      </ProtoInstance>
105 
                    <!-- TimeSensor Timer is a DEF node that has 1 USE node: USE_1 -->
                    <TimeSensor DEF='Timerloop='true'/>
106                      <Script DEF='WorkerdirectOutput='true'>
107                           <field name='heighttype='SFFloatvalue='2.0accessType='initializeOnly'/>
108                           <field name='set_maxtype='SFFloataccessType='inputOnly'/>
109                           <field name='silenttype='SFBoolvalue='falseaccessType='initializeOnly'/>
110                           <field name='lastTicktype='SFTimevalue='0.0accessType='initializeOnly'/>
111                           <field name='set_pageSizetype='SFFloataccessType='inputOnly'/>
112                           <field name='decPagetype='SFTimeaccessType='inputOnly'/>
113                           <field name='set_radiusSticktype='SFFloataccessType='inputOnly'/>
114                           <field name='set_heighttype='SFFloataccessType='inputOnly'/>
115                           <field name='position_changedtype='SFFloataccessType='outputOnly'/>
116                           <field name='Timertype='SFNodeaccessType='initializeOnly'>
117                                <TimeSensor USE='Timer'/>
118                           </field>
119                           <field name='set_positiontype='SFFloataccessType='inputOnly'/>
120                           <field name='snapTimetype='SFTimevalue='0.0accessType='initializeOnly'/>
121                           <field name='TrStickAbovetype='SFNodeaccessType='initializeOnly'>
122                                <Transform USE='TrStickAbove'/>
123                           </field>
124                           <field name='set_radiusKnobtype='SFFloataccessType='inputOnly'/>
125                           <field name='smoothMovementstype='SFBoolvalue='trueaccessType='initializeOnly'/>
126                           <field name='maxtype='SFFloatvalue='1.0accessType='initializeOnly'/>
127                           <field name='initialUpdatetype='SFBoolvalue='trueaccessType='initializeOnly'/>
128                           <field name='EFFStype='SFNodeaccessType='initializeOnly'>
129                                <ProtoInstance USE='EFFS'/>
130                           </field>
131                           <field name='SensKnobOrigintype='SFFloatvalue='0.0accessType='initializeOnly'/>
132                           <field name='pageSizetype='SFFloatvalue='0.2accessType='initializeOnly'/>
133                           <field name='positionInt_changedtype='SFInt32accessType='outputOnly'/>
134                           <field name='SmoothTau3type='SFFloatvalue='0.05accessType='initializeOnly'/>
135                           <field name='SmoothTau2type='SFFloatvalue='0.05accessType='initializeOnly'/>
136                           <field name='SmoothTau1type='SFFloatvalue='0.05accessType='initializeOnly'/>
137                           <field name='set_mintype='SFFloataccessType='inputOnly'/>
138                           <field name='SensKnob_isActivetype='SFBoolaccessType='inputOnly'/>
139                           <field name='KnobSizetype='SFFloatvalue='0.0accessType='initializeOnly'/>
140                           <field name='silently_set_positiontype='SFFloataccessType='inputOnly'/>
141                           <field name='initialUnfilteredUpdatetype='SFBoolvalue='trueaccessType='initializeOnly'/>
142                           <field name='positionSmo3type='SFFloatvalue='0.0accessType='initializeOnly'/>
143                           <field name='snapToInttype='SFBoolvalue='falseaccessType='initializeOnly'/>
144                           <field name='positionSmo2type='SFFloatvalue='0.0accessType='initializeOnly'/>
145                           <field name='set_unfiltered_positiontype='SFFloataccessType='inputOnly'/>
146                           <field name='positionSmo1type='SFFloatvalue='0.0accessType='initializeOnly'/>
147                           <field name='silently_set_unfiltered_positiontype='SFFloataccessType='inputOnly'/>
148                           <field name='radiusSticktype='SFFloatvalue='0.25accessType='initializeOnly'/>
149                           <field name='KnobCenterPostype='SFFloatvalue='0.0accessType='initializeOnly'/>
150                           <field name='positiontype='SFFloataccessType='initializeOnly'/>
151                           <field name='SensKnob_translationChangedtype='SFVec3faccessType='inputOnly'/>
152                           <field name='radiusKnobtype='SFFloatvalue='0.5accessType='initializeOnly'/>
153                           <field name='TrStickBelowtype='SFNodeaccessType='initializeOnly'>
154                                <Transform USE='TrStickBelow'/>
155                           </field>
156                           <field name='TchPgUptype='SFNodeaccessType='initializeOnly'>
157                                <TouchSensor USE='TchPgUp'/>
158                           </field>
159                           <field name='incPagetype='SFTimeaccessType='inputOnly'/>
160                           <field name='unfiltered_position_changedtype='SFFloataccessType='outputOnly'/>
161                           <field name='Ticktype='SFTimeaccessType='inputOnly'/>
162                           <field name='set_smooothMovementstype='SFBoolaccessType='inputOnly'/>
163                           <field name='mintype='SFFloatvalue='0.0accessType='initializeOnly'/>
164                           <field name='TchPgDowntype='SFNodeaccessType='initializeOnly'>
165                                <TouchSensor USE='TchPgDown'/>
166                           </field>
167                           <field name='TrKnobtype='SFNodeaccessType='initializeOnly'>
168                                <Transform USE='TrKnob'/>
169                           </field>
170                           <IS>
171                                <connect nodeField='position_changedprotoField='position_changed'/>
172                                <connect nodeField='set_positionprotoField='set_position'/>
173                                <connect nodeField='positionInt_changedprotoField='positionInt_changed'/>
174                                <connect nodeField='silently_set_positionprotoField='silently_set_position'/>
175                                <connect nodeField='set_unfiltered_positionprotoField='set_unfiltered_position'/>
176                                <connect nodeField='silently_set_unfiltered_positionprotoField='silently_set_unfiltered_position'/>
177                                <connect nodeField='positionprotoField='initial_position'/>
178                                <connect nodeField='unfiltered_position_changedprotoField='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 shows event connections.
-->

<!-- to top Index for DEF nodes: EFFS, SensKnob, TchPgDown, TchPgUp, Timer, TrKnob, TrStickAbove, TrStickBelow, Worker

Index for ProtoDeclare definitions: EFFS, Slider
-->
X3D Tooltips element index: Appearance, Billboard, connect, Cylinder, field, fieldValue, Group, head, IS, Material, meta, PlaneSensor, ProtoBody, ProtoDeclare, ProtoInstance, ProtoInterface, Scene, Script, Shape, TimeSensor, TouchSensor, Transform, WorldInfo, X3D, accessType and type, XML data types, field types

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. 

Additional guidance on X3D animation can be found in the 10-Step Animation Design Process and Event Tracing hint sheets. Have fun with X3D! 😀

-->
<!-- Online at
https://www.web3d.org/x3d/content/examples/Basic/Followers/SliderIndex.html -->
<!-- Version control at
https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/Basic/Followers/Slider.x3d -->

<!-- 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> -->

to top <!-- For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints. -->