#X3D V3.2 utf8
# X3D-to-ClassicVRML XSL translation autogenerated by X3dToVrml97.xslt
# https://www.web3d.org/x3d/content/X3dToVrml97.xslt
# Generated using XSLT processor: Saxonica
PROFILE Immersive
# [X3D] version=3.2
# [X3D] noNamespaceSchemaLocation=https://www.web3d.org/specifications/x3d-3.2.xsd
# [head]
META "title" "Slider.x3d"
META "description" "X3D Follower example"
META "creator" "Herbert Stocker"
META "translator" "Don Brutzman"
META "created" "18 April 2006"
META "translated" "2 December 2011"
META "modified" "20 October 2019"
META "reference" "originals/test_Sliders.wrl"
META "reference" "Stocker_06_Followers.pdf"
META "reference" "http://www.hersto.com/Publications/Followers"
META "requires" "X3D version 3.2 or greater"
META "subject" "X3D Follower Chaser Damper"
META "warning" "under development"
META "reference" "https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html"
META "identifier" "https://www.web3d.org/x3d/content/examples/Basic/Followers/Slider.x3d"
META "generator" "Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html"
META "generator" "X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit"
META "license" "../../license.html"
# [Scene] ========== ========== ==========
NavigationInfo { type [ "EXAMINE" "ANY" ] } ### Default X3D NavigationInfo
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)"
}
PROTO Slider [
initializeOnly SFFloat initial_position 0.5
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
initializeOnly MFString credits [
"Initial idea and copyright by Herbert Stocker http://www.hersto.com/"
]
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat radiusKnob 0.3
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat radiusStick 0.2
inputOnly SFFloat silently_set_unfiltered_position
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat min 0.0
outputOnly SFFloat position_changed
inputOutput SFNode appearance Appearance {
material Material {
}
}
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFBool smoothMovements TRUE
inputOnly SFFloat set_position
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat pageSize 0.2
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat max 1.0
outputOnly SFFloat unfiltered_position_changed
inputOnly SFFloat silently_set_position
inputOnly SFFloat set_unfiltered_position
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat height 2.0
outputOnly SFInt32 positionInt_changed
] {
### Warning: ProtoBody child (or descendant) Shape following first child will not be rendered, since the first child determines node type of this prototype. (Authors can silence this warning by placing a comment as second child.)
Billboard {
children [
DEF TrStickAbove Transform {
children [
DEF TchPgUp TouchSensor {
description "touch to activate PgUp"
}
Shape {
appearance IS appearance
geometry Cylinder {
height 1.0
}
}
]
}
DEF TrStickBelow Transform {
children [
DEF TchPgDown TouchSensor {
description "touch to activate PgDown"
}
Shape {
appearance IS appearance
geometry Cylinder {
height 1.0
}
}
]
}
Group {
children [
DEF SensKnob PlaneSensor {
autoOffset FALSE
description "touch to activate"
maxPosition 0.0 -1.0
}
### Warning: no ROUTE found for PlaneSensor output
DEF TrKnob Transform {
children [
Shape {
appearance IS appearance
geometry Cylinder {
height 1.0
}
}
]
}
]
}
]
}
PROTO EFFS [
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat height 2.0
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat max 1.0
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat radiusKnob 0.5
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat pageSize 0.2
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFBool smoothMovements TRUE
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat radiusStick 0.25
### Warning: ProtoInterface is unreferenced in ProtoBody with no corresponding IS/connect/@protoField
inputOutput SFFloat min 0.0
] {
Group {
}
}
DEF EFFS EFFS {
max 1.0
height 2.0
pageSize 0.2
radiusKnob 0.5
smoothMovements TRUE
radiusStick 0.25
min 0.0
}
DEF Timer TimeSensor {
loop TRUE
}
### Warning: no ROUTE found for TimeSensor output
DEF Worker Script {
initializeOnly SFFloat height 2.0
inputOnly SFFloat set_max
initializeOnly SFBool silent FALSE
initializeOnly SFTime lastTick 0.0
inputOnly SFFloat set_pageSize
inputOnly SFTime decPage
inputOnly SFFloat set_radiusStick
inputOnly SFFloat set_height
outputOnly SFFloat position_changed IS position_changed
initializeOnly SFNode Timer USE Timer
inputOnly SFFloat set_position IS set_position
initializeOnly SFTime snapTime 0.0
initializeOnly SFNode TrStickAbove USE TrStickAbove
inputOnly SFFloat set_radiusKnob
initializeOnly SFBool smoothMovements TRUE
initializeOnly SFFloat max 1.0
initializeOnly SFBool initialUpdate TRUE
initializeOnly SFNode EFFS USE EFFS
initializeOnly SFFloat SensKnobOrigin 0.0
initializeOnly SFFloat pageSize 0.2
outputOnly SFInt32 positionInt_changed IS positionInt_changed
initializeOnly SFFloat SmoothTau3 0.05
initializeOnly SFFloat SmoothTau2 0.05
initializeOnly SFFloat SmoothTau1 0.05
inputOnly SFFloat set_min
inputOnly SFBool SensKnob_isActive
initializeOnly SFFloat KnobSize 0.0
inputOnly SFFloat silently_set_position IS silently_set_position
initializeOnly SFBool initialUnfilteredUpdate TRUE
initializeOnly SFFloat positionSmo3 0.0
initializeOnly SFBool snapToInt FALSE
initializeOnly SFFloat positionSmo2 0.0
inputOnly SFFloat set_unfiltered_position IS set_unfiltered_position
initializeOnly SFFloat positionSmo1 0.0
inputOnly SFFloat silently_set_unfiltered_position IS silently_set_unfiltered_position
initializeOnly SFFloat radiusStick 0.25
initializeOnly SFFloat KnobCenterPos 0.0
initializeOnly SFFloat position IS initial_position
inputOnly SFVec3f SensKnob_translationChanged
initializeOnly SFFloat radiusKnob 0.5
initializeOnly SFNode TrStickBelow USE TrStickBelow
initializeOnly SFNode TchPgUp USE TchPgUp
inputOnly SFTime incPage
outputOnly SFFloat unfiltered_position_changed IS unfiltered_position_changed
inputOnly SFTime Tick
inputOnly SFBool set_smooothMovements
initializeOnly SFFloat min 0.0
initializeOnly SFNode TchPgDown USE TchPgDown
initializeOnly SFNode TrKnob USE TrKnob
directOutput TRUE
### Warning: Script initializeOnly field 'TchPgUp' is not referenced in contained ecmascript: code
### Warning: Script initializeOnly field 'TchPgDown' is not referenced in contained ecmascript: code
### Warning: Script 'var' declarations of variables are not persistent in contained ecmascript: code, values are lost after each call. Use definitions instead.
### Warning: mismatched (i.e. odd number of) 'single quote' marks in contained ecmascript: code
url [ "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;
}
" ]
}
}
# TODO anchor link