#X3D V3.0 utf8 PROTO BoolToInt # converts false/true to -1/0, for driving Switches [ eventIn SFBool boolIn eventOut SFInt32 intOut ] { DEF RIScript Script { eventIn SFBool boolIn IS boolIn eventOut SFInt32 intOut IS intOut url "javascript: function boolIn (value,time) { if (value) intOut = 0; else intOut = -1; } " } } PROTO PolynomialInterpolator2D [ eventIn SFFloat set_fraction # fraction of minX to maxX eventIn SFFloat set_x # - or - actual X value eventOut SFFloat y_changed # output value exposedField MFFloat coefficients [1 0] # default is 1*X + 0; [2 -3 4] would be 2*X^2 - 3*X + 4 exposedField SFFloat minX 0 # use with 'fraction' exposedField SFFloat maxX 1 # use with 'fraction' ] { DEF PIScript Script { eventIn SFFloat set_fraction IS set_fraction eventIn SFFloat set_x IS set_x eventOut SFFloat y_changed IS y_changed exposedField MFFloat coefficients IS coefficients exposedField SFFloat minX IS minX exposedField SFFloat maxX IS maxX url "javascript: function set_fraction (value,time) { eval (minX + value * (maxX - minX)); } function set_x (value, time) { eval(value); } function eval (x) { var i; if (coefficients.length == 0) y_changed = 0; else if (coefficients.length == 1) y_changed = coefficients[0] * x; else { var ty; ty = coefficients[0] * x + coefficients[1]; for (i = 1; i <= coefficients.length-2; i++) { ty = ty * x + coefficients[i+1]; } //Browser.setDescription ('c:'+coefficients.length+' x:'+x+' '+ty); y_changed = ty; } } " } } PROTO Img # simple rectangle with a picture on it [ exposedField MFString url [""] exposedField SFVec3f size 1 1 1 exposedField SFVec3f position 0 0 0 exposedField SFColor color .5 .5 .5 exposedField SFFloat transparency 0 ] { DEF VisSwitch Switch { whichChoice -1 choice [ Transform { translation IS position scale IS size children [ Shape { appearance Appearance { material Material { emissiveColor IS color transparency IS transparency } texture DEF IT ImageTexture { url IS url } } geometry IndexedFaceSet { coord Coordinate { point [0 -1 0, 1 -1 0, 1 0 0, 0 0 0] } texCoord TextureCoordinate { point [0 0, 1 0, 1 1, 0 1] } coordIndex [0, 1, 2, 3, -1] texCoordIndex [0, 1, 2, 3, -1] } } ] } ] } DEF Loader LoadSensor { watchList [ USE IT ] } DEF INTTRIG IntegerTrigger { integerKey 0 } ROUTE Loader.isLoaded TO INTTRIG.set_boolean ROUTE INTTRIG.triggerValue TO VisSwitch.set_whichChoice } PROTO HammerButton # button that can send isActive events as long as it's pressed [ exposedField MFNode shapes [] exposedField SFBool repeat FALSE exposedField SFTime repeatRate 1 exposedField SFString id "" eventOut SFBool isOver eventOut SFBool isActive ] { Group { children [ DEF Touch1 TouchSensor {} Group { children IS shapes } DEF RepeatTimer TimeSensor { cycleInterval IS repeatRate loop TRUE enabled FALSE} ] } DEF HBScript Script { eventIn SFBool set_isOver eventIn SFBool set_isActive eventIn SFTime tick exposedField SFBool repeat IS repeat exposedField SFBool isOver IS isOver exposedField SFString id IS id field SFBool active FALSE eventOut SFBool isActive IS isActive eventOut SFBool startTimer url "javascript: function set_isOver(value,time) { isOver = value; } function set_isActive(value,time) { isActive = value; active = value; startTimer = (repeat && value); } function tick (value, time) { if (repeat && active) isActive = true; } " } ROUTE Touch1.isOver TO HBScript.set_isOver ROUTE Touch1.isActive TO HBScript.set_isActive ROUTE HBScript.startTimer TO RepeatTimer.enabled ROUTE RepeatTimer.cycleTime TO HBScript.tick } PROTO RolloverImg # changes appearance on mouse-over/mouse up/down [ exposedField MFString isNotOverUrl [""] exposedField MFString isOverUrl [""] exposedField MFString isNotActiveUrl [""] exposedField MFString isActiveUrl [""] exposedField SFVec3f size 1 1 1 exposedField SFVec3f position 0 0 0 exposedField SFFloat transparency 0 exposedField SFInt32 choice 0 exposedField SFBool repeat FALSE exposedField SFTime repeatRate 1 eventOut SFBool isOver eventOut SFBool isActive ] { Group { children [ DEF Touch1 TouchSensor {} DEF RISwitch Switch { whichChoice IS choice children [ DEF isNotOverImg Img { size IS size position IS position transparency IS transparency url IS isNotOverUrl } DEF isOverImg Img { size IS size position IS position transparency IS transparency url IS isOverUrl } DEF isNotActiveImg Img { size IS size position IS position transparency IS transparency url IS isNotActiveUrl } DEF isActiveImg Img { size IS size position IS position transparency IS transparency url IS isActiveUrl } ] } DEF RepeatTimer TimeSensor { cycleInterval IS repeatRate loop TRUE enabled FALSE} ] } DEF RIScript Script { eventIn SFBool set_isOver eventIn SFBool set_isActive eventIn SFTime tick exposedField SFBool repeat IS repeat exposedField SFBool isOver IS isOver field SFBool active FALSE eventOut SFBool isActive IS isActive eventOut SFInt32 choice eventOut SFBool startTimer exposedField MFString isOverUrl IS isOverUrl exposedField MFString isNotOverUrl IS isNotOverUrl exposedField MFString isActiveUrl IS isActiveUrl exposedField MFString isNotActiveUrl IS isNotActiveUrl url "javascript: function set_isOver(value,time) { if (value && (isOverUrl[0] != '')) c = 1; else c = 0; choice = c; isOver = value; } function set_isActive(value,time) { if (value) c = 3; else { if (isOver) c = 2; else c = 0; } choice = c; isActive = value; active = value; startTimer = (repeat && value); } function tick (value, time) { if (repeat && active) isActive = true; } " } ROUTE Touch1.isOver TO RIScript.set_isOver ROUTE Touch1.isActive TO RIScript.set_isActive ROUTE RIScript.choice TO RISwitch.whichChoice ROUTE RIScript.isOverUrl TO isOverImg.url ROUTE RIScript.isActiveUrl TO isActiveImg.url ROUTE RIScript.isNotActiveUrl TO isNotActiveImg.url ROUTE RIScript.startTimer TO RepeatTimer.enabled ROUTE RepeatTimer.cycleTime TO RIScript.tick } PROTO ToggleImg # toggles between two images (for checkboxes, radio buttons, etc) [ exposedField MFString isNotOverUrl [""] exposedField MFString isOverUrl [""] exposedField MFString isNotActiveUrl [""] exposedField MFString isActiveUrl [""] exposedField SFVec3f size 1 1 1 exposedField SFVec3f position 0 0 0 exposedField SFFloat transparency 0 exposedField SFBool active FALSE exposedField SFInt32 choice 0 eventOut SFBool isOver eventOut SFBool isActive ] { Group { children [ DEF Touch1 TouchSensor {} DEF RISwitch Switch { whichChoice IS choice children [ DEF isNotOverImg Img { size IS size position IS position transparency IS transparency url IS isNotOverUrl } DEF isOverImg Img { size IS size position IS position transparency IS transparency url IS isOverUrl } DEF isNotActiveImg Img { size IS size position IS position transparency IS transparency url IS isNotActiveUrl } DEF isActiveImg Img { size IS size position IS position transparency IS transparency url IS isActiveUrl } ] } ] } DEF TIScript Script { eventIn SFBool set_isOver eventIn SFBool set_isActive exposedField SFBool isOver IS isOver eventOut SFBool isActive IS isActive eventOut SFInt32 choice exposedField SFBool active IS active # eventIn SFBool set_active exposedField MFString isOverUrl IS isOverUrl exposedField MFString isNotOverUrl IS isNotOverUrl exposedField MFString isActiveUrl IS isActiveUrl exposedField MFString isNotActiveUrl IS isNotActiveUrl url "javascript: function initialize() { if (active) choice = 3; isActive = active; } function set_isOver(value,time) { if (value && (isOverUrl[0] != '')) c = 1; else { if (active) c = 3; else c = 0; } choice = c; isOver = value; } function set_active (value, time) { active = value; } function set_isActive(value,time) { if (value) c = 3; else { if (isOver) { c = 2; active = !active; } else { if (active) c = 3; else c = 0; } } choice = c; isActive = active; } " } ROUTE Touch1.isOver TO TIScript.set_isOver ROUTE Touch1.isActive TO TIScript.set_isActive ROUTE TIScript.choice TO RISwitch.whichChoice ROUTE TIScript.isOverUrl TO isOverImg.url ROUTE TIScript.isActiveUrl TO isActiveImg.url ROUTE TIScript.isNotActiveUrl TO isNotActiveImg.url } PROTO Label # simple Text wrapper [ exposedField MFString string [""] exposedField SFFloat size 12 exposedField SFVec3f position 0 0 0 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor color 1 1 1 exposedField SFBool bitmapMode TRUE ] { Transform { translation IS position children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 0 emissiveColor IS color transparency IS transparency } } geometry Text { string IS string fontStyle FontStyleExt { size IS size family IS family style IS style justify IS justify bitmapMode IS bitmapMode } } }# ] }# } PROTO HiLiteText # hilites on mouse-over [ exposedField MFString string [""] exposedField SFFloat size 12 exposedField SFVec3f position 0 0 0 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor hiColor 1 1 1 exposedField SFColor loColor .5 .5 .5 exposedField SFBool bitmapMode TRUE eventIn SFBool set_isOver eventOut SFBool isActive eventOut SFBool isOver ] { Group { children [ DEF Label1 Label { color IS loColor string IS string size IS size position IS position family IS family style IS style justify IS justify transparency IS transparency bitmapMode IS bitmapMode } DEF Touch1 TouchSensor { isOver IS isOver isActive IS isActive } ] } DEF LabelHiLite Script { exposedField SFColor hiColor IS hiColor exposedField SFColor loColor IS loColor eventIn SFBool set_isOver IS set_isOver eventIn SFBool isOver eventOut SFColor color url "javascript: function isOver(value,time) { doisOver(value,time); } function set_isOver(value,time) { doisOver(value,time); } function doisOver(value,time) { if (value) { color = hiColor; } else color = loColor; } " } ROUTE Touch1.isOver TO LabelHiLite.isOver ROUTE LabelHiLite.color TO Label1.color } PROTO HiLiteRect # hilites on mouse-over [ exposedField SFVec3f size 1 1 1 exposedField SFVec3f position 0 0 0 exposedField SFColor hiColor 1 1 1 exposedField SFColor loColor .5 .5 .5 exposedField SFFloat transparency 0 eventIn SFBool set_isOver eventOut SFBool isActive eventOut SFBool isOver ] { Group { children [ DEF Touch1 TouchSensor { isActive IS isActive isOver IS isOver } Transform { translation IS position scale IS size children [ Shape { appearance Appearance { material DEF RectMat Material { diffuseColor 0 0 0 emissiveColor IS loColor transparency IS transparency } } geometry IndexedFaceSet { coord Coordinate { point [0 -1 0, 1 -1 0, 1 0 0, 0 0 0] } texCoord TextureCoordinate { point [0 0, 1 0, 1 1, 0 1] } coordIndex [0, 1, 2, 3, -1] texCoordIndex [0, 1, 2, 3, -1] } } ] } ] } DEF RectHiLite Script { exposedField SFColor hiColor IS hiColor exposedField SFColor loColor IS loColor eventIn SFBool set_isOver IS set_isOver eventIn SFBool isOver eventOut SFColor color url "javascript: function isOver(value,time) { doisOver(value,time); } function set_isOver(value,time) { doisOver(value,time); } function doisOver(value,time) { if (value) { color = hiColor; } else color = loColor; } " } ROUTE Touch1.isOver TO RectHiLite.isOver ROUTE RectHiLite.color TO RectMat.emissiveColor } PROTO HiLiteTextRect # text & rect hilite on mouse-over [ exposedField MFString string [""] exposedField SFFloat textSize 12 exposedField SFVec3f sizeRect 200 20 1 exposedField SFVec3f position 0 0 0 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor hiTextColor 0 0 0 exposedField SFColor loTextColor .6 .6 .6 exposedField SFColor hiRectColor 1 1 1 exposedField SFColor loRectColor .3 .3 .3 exposedField SFBool bitmapMode TRUE eventOut SFBool isActive eventOut SFBool isOver exposedField SFInt32 id 0 eventOut SFInt32 command_id ] { Group { children [ DEF TheRect HiLiteRect { size IS sizeRect position IS position transparency IS transparency hiColor IS hiRectColor loColor IS loRectColor } DEF TheText HiLiteText { string IS string position IS position hiColor IS hiTextColor loColor IS loTextColor transparency IS transparency size IS textSize family IS family style IS style justify IS justify bitmapMode IS bitmapMode } ] } DEF TextRectScript Script { eventIn SFBool set_isActive exposedField SFBool isActive IS isActive field SFBool isOver FALSE eventIn SFBool set_isOver exposedField SFInt32 id IS id exposedField SFVec3f textPos IS position eventOut SFInt32 command_id IS command_id url "javascript: function set_isOver(value,time) { isOver = value; } function set_isActive(value,time) { // look for mouse-up when over this thing if (isOver && !value && isActive) { command_id = id; } isActive = value; } " } ROUTE TextRectScript.textPos TO TheText.position ROUTE TheRect.isOver TO TheText.set_isOver ROUTE TheRect.isOver TO TextRectScript.set_isOver ROUTE TheText.isOver TO TheRect.set_isOver ROUTE TheText.isActive TO TextRectScript.set_isActive ROUTE TheRect.isActive TO TextRectScript.set_isActive } PROTO HiLiteList # a list that hilites (like a menu) [ exposedField MFString list [""] exposedField MFNode children [] exposedField SFFloat textSize 12 exposedField SFVec3f position 0 0 0 exposedField SFFloat width 100 exposedField SFFloat itemHeight 25 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor hiTextColor 1 1 1 exposedField SFColor loTextColor .5 .5 .5 exposedField SFColor hiRectColor .5 .5 .5 exposedField SFColor loRectColor 1 1 1 eventIn SFInt32 set_id exposedField SFInt32 id -1 eventOut MFString chosenText ] { DEF ListGroup Group { children IS children } DEF ListHandler Script { exposedField MFString list IS list exposedField MFNode children IS children exposedField SFVec3f position IS position exposedField SFFloat itemHeight IS itemHeight eventIn SFInt32 set_id IS set_id eventOut MFNode newItems exposedField SFInt32 id IS id eventOut MFString chosenText IS chosenText exposedField SFNode self USE ListHandler exposedField SFFloat textSize IS textSize exposedField MFString family IS family exposedField SFString style IS style exposedField MFString justify IS justify url "vrmlscript: function initialize(value,time) { var s; var i; if (list.length > 0) { for (i=0; i < list.length; i++) { s = 'HiLiteTextRect { sizeRect ' + width +' ' + itemHeight + ' 0 string 100 '; s += 100 + i * itemHeight; s += ' 0 string '; s += list[i]; s += ' id '+ i; s += '}'; } } if (children.length > 0) { for (i=0; i < children.length; i++) { var newPos = new SFVec3f (position.x, position.y - (itemHeight * i), position.z); children[i].position = newPos; children[i].id = i; Browser.addRoute (children[i], 'command_id', self, 'id'); } } } function set_id(value,time) { if (value < children.length) { id = children[value].id; id_changed = children[value].id; chosenText = children[value].string; } } " } ROUTE ListHandler.newItems TO ListGroup.addChildren } PROTO PopUpMenu [ exposedField MFString list [""] exposedField MFNode children [] exposedField SFFloat textSize 12 exposedField SFVec3f position 0 0 0 exposedField SFFloat width 100 exposedField SFFloat itemHeight 25 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor hiTextColor 1 1 1 exposedField SFColor loTextColor .5 .5 .5 exposedField SFColor hiRectColor .5 .5 .5 exposedField SFColor loRectColor 1 1 1 eventIn SFInt32 set_id eventIn SFBool show exposedField SFInt32 id -1 eventOut MFString chosenText ] { DEF MenuSwitch Switch { whichChoice -1 choice [ DEF TheList HiLiteList { list IS list children IS children textSize IS textSize position IS position width IS width itemHeight IS itemHeight family IS family style IS style justify IS justify transparency IS transparency hiTextColor IS hiTextColor loTextColor IS loTextColor hiRectColor IS hiRectColor loRectColor IS loRectColor set_id IS set_id id IS id chosenText IS chosenText } ] } DEF MenuScript Script { eventIn SFBool show IS show eventIn SFInt32 set_id eventOut MFString chosenText IS chosenText eventOut SFInt32 switchVal url "vrmlscript: function show(val,time) { if (val) switchVal = 0; } function set_id(val,time) { switchVal = -1; } " } ROUTE MenuScript.switchVal TO MenuSwitch.whichChoice ROUTE TheList.id_changed TO MenuScript.set_id } PROTO Spinner # basic class for doing up/down spinners [ exposedField SFFloat value 0 exposedField SFInt32 intValue 0 exposedField SFFloat minVal 0 exposedField SFFloat maxVal 100 exposedField SFFloat delta 1 exposedField SFBool wrap FALSE eventIn SFBool valueUp eventIn SFBool valueDown exposedField SFVec3f size 20 20 1 exposedField SFVec3f upPos 0 0 0 exposedField SFVec3f downPos 0 0 0 exposedField MFString upOnUrl [""] exposedField MFString upOffUrl [""] exposedField MFString downOnUrl [""] exposedField MFString downOffUrl [""] exposedField SFBool repeat FALSE exposedField SFTime repeatRate .5 ] { DEF UpImg RolloverImg { isNotOverUrl IS upOffUrl isActiveUrl IS upOnUrl size IS size position IS upPos repeat IS repeat repeatRate IS repeatRate } DEF DownImg RolloverImg { isNotOverUrl IS downOffUrl isActiveUrl IS downOnUrl size IS size position IS downPos repeat IS repeat repeatRate IS repeatRate } DEF SpinnerScript Script { eventIn SFBool up eventIn SFBool down exposedField SFBool wrap IS wrap exposedField SFFloat value IS value exposedField SFInt32 intValue IS intValue eventOut SFFloat value_changed IS value_changed eventOut SFFloat intValue_changed IS intValue_changed exposedField SFFloat delta IS delta exposedField SFFloat minv IS minVal exposedField SFFloat maxv IS maxVal url "vrmlscript: function up(val, time) { if (val) { if (wrap) { if (value >= maxv) { value = minv; value_changed = value; } else // if (value < maxv) { value = value + delta; value_changed = value; } intValue = Math.floor(value); intValue_changed = intValue; } else // no wrap { if (value < maxv) { value = value + delta; value_changed = value; intValue = Math.floor(value); intValue_changed = intValue; } } } } function down(val, time) { if (val) { if (wrap) { if (value <= minv) { value = maxv; value_changed = value; } else // if (value > minv) { value = value - delta; value_changed = value; } intValue = Math.floor(value); intValue_changed = intValue; } else // no wrap { if (value > minv) { value = value - delta; value_changed = value; intValue = Math.floor(value); intValue_changed = intValue; } } } } " } ROUTE UpImg.isActive TO SpinnerScript.up ROUTE DownImg.isActive TO SpinnerScript.down } PROTO TextSpinner # cycle through a list of text items with up/down buttons [ exposedField SFInt32 intVal 0 exposedField SFFloat minVal 0 exposedField SFFloat maxVal 100 exposedField SFFloat delta 1 exposedField SFBool wrap FALSE eventIn SFBool valueUp eventIn SFBool valueDown exposedField SFVec3f size 20 20 1 exposedField SFVec3f upPos 0 0 0 exposedField SFVec3f downPos 0 0 0 exposedField SFVec3f textPos 0 0 0 exposedField MFString upOnUrl [""] exposedField MFString upOffUrl [""] exposedField MFString downOnUrl [""] exposedField MFString downOffUrl [""] exposedField SFBool repeat FALSE exposedField SFTime repeatRate .5 exposedField SFString currentText "" exposedField MFString strings [""] exposedField SFFloat textSize 12 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor textColor 1 1 1 ] { DEF TheText Label { size IS textSize family IS family style IS style justify IS justify transparency IS transparency color IS textColor bitmapMode TRUE position IS textPos string ["test"] } DEF TheSpinner Spinner { intValue IS intVal minVal IS minVal maxVal IS maxVal delta 1 wrap IS wrap size IS size upPos IS upPos downPos IS downPos upOnUrl IS upOnUrl upOffUrl IS upOffUrl downOnUrl IS downOnUrl downOffUrl IS downOffUrl repeat IS repeat repeatRate IS repeatRate } DEF TextSpinnerScript Script { exposedField MFString strings IS strings exposedField SFInt32 intVal IS intVal eventOut MFString text exposedField SFString currentText IS currentText exposedField SFNode spinnerNode USE TheSpinner url "vrmlscript: function initialize() { var newMax = strings.length-1; spinnerNode.maxVal = newMax; var newText = new MFString (strings[intVal]); text = newText; currentText = strings[intVal]; } function set_intVal (value, time) { var newMax = strings.length-1; spinnerNode.maxVal = newMax; var newText = new MFString (strings[value]); text = newText; intVal = value; currentText = strings[value]; } " } ROUTE TheSpinner.intValue_changed TO TextSpinnerScript.intVal ROUTE TextSpinnerScript.text TO TheText.string } PROTO NumberSpinner # a numeric value with up/down buttons [ exposedField SFFloat val 0 exposedField SFFloat minVal 0 exposedField SFFloat maxVal 100 exposedField SFFloat delta 1 exposedField SFBool wrap FALSE eventIn SFBool valueUp eventIn SFBool valueDown exposedField SFVec3f size 20 20 1 exposedField SFVec3f upPos 0 0 0 exposedField SFVec3f downPos 0 0 0 exposedField SFVec3f textPos 0 0 0 exposedField MFString upOnUrl [""] exposedField MFString upOffUrl [""] exposedField MFString downOnUrl [""] exposedField MFString downOffUrl [""] exposedField SFBool repeat FALSE exposedField SFTime repeatRate .5 exposedField SFString currentText "" exposedField SFFloat textSize 12 exposedField MFString family ["SERIF"] exposedField SFString style "PLAIN" exposedField MFString justify ["LEFT"] exposedField SFFloat transparency 0 exposedField SFColor textColor 1 1 1 exposedField SFInt32 decimals 0 exposedField SFInt32 preZeroPad 0 exposedField SFInt32 postZeroPad 0 ] { DEF TheText Label { size IS textSize family IS family style IS style justify IS justify transparency IS transparency color IS textColor bitmapMode TRUE position IS textPos string ["test"] } DEF TheSpinner Spinner { value IS val minVal IS minVal maxVal IS maxVal delta 1 wrap IS wrap size IS size upPos IS upPos downPos IS downPos upOnUrl IS upOnUrl upOffUrl IS upOffUrl downOnUrl IS downOnUrl downOffUrl IS downOffUrl repeat IS repeat repeatRate IS repeatRate } DEF NumSpinnerScript Script { exposedField SFFloat val IS val eventOut MFString text exposedField SFString currentText IS currentText eventOut SFFloat newMax exposedField SFInt32 decimals IS decimals exposedField SFInt32 preZeroPad IS preZeroPad exposedField SFInt32 postZeroPad IS postZeroPad url "vrmlscript: function initialize() { currentText = format(val); text[0] = currentText; } function set_val (value, time) { currentText = format(value); text[0] = currentText; } function format(val) { var v; var i; var l; var s; if (decimals <= 0) v = val; else { var m = pow(10, decimals); v = Math.floor(val * m) / m; } var s = v + ''; var dp = indexOf (s, '.'); if (preZeroPad > 0) { l = preZeroPad - s.length - dp - 1; for (i = 0; i < l; i++) { s = '0' + s; dp = dp + 1; } } if (dp >= 0) { if (postZeroPad > 0) { l = postZeroPad - s.length + dp + 1; for (i = 0; i < l; i++) { s = s + '0'; } } } return s; } function indexOf (s, c) { var i; var j = -1; for (i=0; i < s.length; i++) { if (s[i] == c) { j = i; break; } } return j; } function pow (m,e) { var i; var p; if (e == 0) return 1; if (e == 1) return m; p = 1; for (i = 0; i < e; i++) p = p * m; return p; } " } ROUTE TheSpinner.value_changed TO NumSpinnerScript.set_val ROUTE NumSpinnerScript.text TO TheText.string } PROTO DropDownList # not done [ exposedField SFFloat value 0 field SFInt32 digits 3 eventIn SFBool valueUp eventIn SFBool valueDown eventOut SFFloat value_changed ] { Group{} } PROTO Slider # basic slider [ exposedField SFVec3f position 0 0 0 exposedField SFFloat fraction .5 exposedField SFFloat minVal 0 exposedField SFFloat maxVal 1 eventOut SFTime touchTime exposedField SFBool enabled TRUE exposedField SFBool continuousEvents TRUE # if false, fraction_changed on mouse-up only exposedField SFFloat slideLength 1 exposedField MFNode thumb Transform { scale .08 .04 .08 children Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Sphere {} } } exposedField MFNode slide Shape { appearance Appearance { material Material { diffuseColor .75 .75 .75 shininess .9 } } geometry Cylinder { radius .01 height 1.1 } } ] { Transform { translation IS position children [ DEF Range ScalarInterpolator { key [0 1] keyValue [0 1] value_changed IS fraction_changed } DEF OUTPUT Script { eventIn SFBool is_Active eventIn SFFloat set_fraction IS set_fraction eventIn SFVec3f set_translation eventOut SFVec3f offset_changed eventOut SFFloat fraction_changed #IS fraction_changed eventOut SFTime touchTime IS touchTime eventOut SFVec3f slideSize eventOut SFVec2f railSize exposedField SFFloat slideLength IS slideLength exposedField SFBool continuousEvents IS continuousEvents exposedField SFNode Range USE Range exposedField SFFloat minVal IS minVal exposedField SFFloat maxVal IS maxVal field SFFloat fraction IS fraction field SFBool active FALSE url "javascript: function initialize(value,time) { fraction_changed = fraction; offset_changed[0] = fraction * slideLength; offset_changed[1] = 0; offset_changed[2] = 0; slideSize[0] = slideLength; slideSize[1] = 1; slideSize[2] = 1; railSize[0] = slideLength; railSize[1] = 0; Range.keyValue[0] = minVal; Range.keyValue[1] = maxVal; } function set_fraction(value,time) // set from outside, routed in { fraction = value; if (!active) // don't fight user if they're dragging { offset_changed[0] = value * slideLength; offset_changed[1] = 0; offset_changed[2] = 0; } } function set_translation(value,time) // set by knob slider sensor { //if (!active) // don't fight user if they're dragging { if (continuousEvents) fraction_changed = value[0] / slideLength; fraction = value[0] / slideLength; } } function is_Active(value, thetime) { active = value; if (value) touchTime = thetime; else if (!continuousEvents) // fraction event on mouse-up { fraction_changed = fraction; } } " } Transform { translation -.5 0 0 children [ DEF RAILSENSOR PlaneSensor { enabled IS enabled maxPosition 1 0 minPosition 0 0 offset .5 0 0 autoOffset TRUE } DEF RAIL Transform { translation .5 0 0 children IS slide } DEF BEAD Transform { translation .5 0 0 children IS thumb } ] } ] ROUTE RAILSENSOR.translation_changed TO BEAD.set_translation ROUTE OUTPUT.offset_changed TO BEAD.set_translation ROUTE OUTPUT.offset_changed TO RAILSENSOR.set_offset ROUTE OUTPUT.railSize TO RAILSENSOR.maxPosition ROUTE RAILSENSOR.translation_changed TO OUTPUT.set_translation ROUTE RAILSENSOR.isActive TO OUTPUT.is_Active ROUTE OUTPUT.slideSize TO RAIL.set_scale ROUTE OUTPUT.fraction_changed TO Range.set_fraction } } PROTO AnimTimer # a timer for the common man [ exposedField SFTime cycleInterval 1 exposedField SFBool enabled TRUE exposedField SFBool loop TRUE exposedField SFNode metadata NULL exposedField SFTime pauseTime 0 exposedField SFTime resumeTime 0 exposedField SFTime startTime 0 exposedField SFTime stopTime 0 eventOut SFTime cycleTime eventOut SFTime elapsedTime eventOut SFFloat fraction_changed eventOut SFBool isActive eventOut SFBool isPaused eventOut SFTime time exposedField SFBool reverse FALSE eventIn SFBool pause exposedField SFFloat offset 0 ] { DEF TheTimer TimeSensor { cycleInterval IS cycleInterval enabled IS enabled loop IS loop pauseTime IS pauseTime resumeTime IS resumeTime startTime IS startTime stopTime IS stopTime cycleTime IS cycleTime elapsedTime IS elapsedTime fraction_changed IS fraction_changed isActive IS isActive isPaused IS isPaused time IS time } DEF Offsetter ScalarInterpolator { key [ 0 .33 .66 1] keyValue [0 .33 .66 1] value_changed IS fraction_changed } DEF AnimScript Script { exposedField SFTime cycleInterval IS cycleInterval exposedField SFFloat offset IS offset exposedField SFBool loop IS loop eventIn SFBool pause IS pause exposedField SFBool reverse IS reverse eventIn SFFloat recordFraction field SFFloat curFraction 0 exposedField SFNode offsetter USE Offsetter exposedField SFNode timer USE TheTimer eventOut SFBool enabled url "javascript: function initialize() { if (reverse) { // create a ramp starting time zero = 1-offset, down to 0, quickly back to 1, then back up to 1-offset offsetter.keyValue[0] = 1-offset; offsetter.keyValue[1] = 0; offsetter.keyValue[2] = 1; offsetter.keyValue[3] = 1-offset; offsetter.key[1] = offset; offsetter.key[2] = offset + .00001; curFraction = offset; } else { // create a ramp starting time zero = offset, up to 1, quickly back to 0, then back up to offset offsetter.keyValue[0] = offset; offsetter.keyValue[1] = 1; offsetter.keyValue[2] = 0; offsetter.keyValue[3] = offset; offsetter.key[1] = 1 - offset; offsetter.key[2] = 1 - offset + .00001; curFraction = offset; } } function recordFraction(value,time) { curFraction = value; } function set_offset(value,time) { offset = value; initialize(); // set the offset ramp } function pause (value,time) { do_pause(value,time); } function do_pause (value,time) { if (value) // if pausing.. { timer.enabled = false; // stop the timer offset = curFraction; // start here when unpaused } else // unpausing { initialize(); // set the offset ramp from 'offset' timer.enabled = true; // start the timer } } function set_cycleInterval(value,time) { do_pause(true,time); timer.cycleInterval = value; do_pause(false,time); } function set_reverse(value,time) { reverse = value; initialize(); } " } ROUTE TheTimer.fraction_changed TO Offsetter.set_fraction ROUTE TheTimer.fraction_changed TO AnimScript.recordFraction } # Example usages DEF TestLayer1 Layer2D { type "Foreground" layout Layout { size 1200 700 align ["LEFT" "BOTTOM"] sizeUnits ["PIXEL" "PIXEL"] offset -600 -300 offsetUnits ["PIXEL" "PIXEL"] scaleMode ["PIXEL" "PIXEL"] } children [ DEF TestSlider Slider { position 500 100 -3 thumb Img { url "HUD/SliderKnob.png" position 0 0 -2 size 9 16 1 color 0 0 0 } slideLength 100 } DEF TestAnimTimer AnimTimer { cycleInterval 5 offset .3 enabled TRUE loop TRUE } RolloverImg { isNotOverUrl "off.jpg" isOverUrl "" isNotActiveUrl "" isActiveUrl "" size 64 64 1 position 100 300 0 transparency 0 repeat TRUE } RolloverImg { isNotOverUrl "off.jpg" isOverUrl "over.jpg" isNotActiveUrl "" isActiveUrl "" size 64 64 1 position 200 300 0 transparency .3 repeat TRUE repeatRate 1 } RolloverImg { isNotOverUrl "off.jpg" isOverUrl "over.jpg" isNotActiveUrl "" isActiveUrl "down.jpg" size 64 64 1 position 300 300 0 transparency 0 } RolloverImg { isNotOverUrl "off.jpg" isOverUrl "over.jpg" isNotActiveUrl "up.jpg" isActiveUrl "down.jpg" size 64 64 1 position 400 300 0 transparency 0 } DEF ToggleTest ToggleImg { isNotOverUrl "off.jpg" isOverUrl "over.jpg" isNotActiveUrl "up.jpg" isActiveUrl "down.jpg" size 32 32 1 position 700 400 0 transparency 0 active TRUE } DEF TestList HiLiteList { # list ["hey" "wtf" "wazzup"] position 150 600 0 itemHeight 25 children [ DEF HTR0 HiLiteTextRect { string "Sol (Our Sun)" } DEF HTR1 HiLiteTextRect { string "Alpha Centauri" } DEF HTR2 HiLiteTextRect { string "Betelgeuse" } DEF HTR3 HiLiteTextRect { string "Sirius" } DEF HTR4 HiLiteTextRect { string "Pliedes" } DEF HTR5 HiLiteTextRect { string "Owl Nebula" } ] } DEF PopUpButton RolloverImg { isNotOverUrl "off.jpg" isOverUrl "" isNotActiveUrl "" isActiveUrl "" size 64 64 1 position 850 600 0 transparency .5 repeat TRUE } DEF TestMenu PopUpMenu { # list ["hey" "wtf" "wazzup"] position 850 600 0 itemHeight 25 transparency .5 children [ DEF HTR0 HiLiteTextRect { string "Sol (Our Sun)" } DEF HTR1 HiLiteTextRect { string "Alpha Centauri" } DEF HTR2 HiLiteTextRect { string "Betelgeuse" } DEF HTR3 HiLiteTextRect { string "Sirius" } DEF HTR4 HiLiteTextRect { string "Pliedes" } DEF HTR5 HiLiteTextRect { string "Owl Nebula" } ] } DEF TextSpin TextSpinner { upPos 600 520 0 downPos 600 480 0 textPos 500 500 0 upOffUrl "off.jpg" upOnUrl "down.jpg" downOffUrl "off.jpg" downOnUrl "down.jpg" textColor 0 1 0 strings ["this is one" "this is two" "three" "four"] wrap TRUE repeat TRUE } DEF NumSpin NumberSpinner { minVal -5 maxVal 7 val 12.345 wrap TRUE upPos 600 420 0 downPos 600 380 0 textPos 500 400 0 upOffUrl "off.jpg" upOnUrl "down.jpg" downOffUrl "off.jpg" downOnUrl "down.jpg" textColor 1 1 0 decimals 1 preZeroPad 3 postZeroPad 2 } DEF fiver HammerButton { repeat TRUE shapes Shape { appearance DEF TranspApp Appearance { material Material { diffuseColor .6 .7 .8 transparency .5 } } geometry IndexedFaceSet { coord Coordinate { point [51 58 1,23 75 1,44 106 1,82 106 1,97 75 1] } coordIndex [0, 1, 2, 3, 4,-1] } } } DEF bigseven HammerButton { repeat TRUE shapes Shape { appearance USE TranspApp geometry IndexedFaceSet { coord Coordinate { point [216 186 1,220 162 1,300 162 1,261 288 1,247 288 1,282 178 1,231 176 1,228 188 1] } coordIndex [0, 1, 2, 3, 4, 5, 6, 7, -1] } } } DEF six HammerButton { repeat TRUE shapes Shape { appearance USE TranspApp geometry IndexedFaceSet { coord Coordinate { point [184 134 1,205 137 1,208 156 1,194 179 1,184 177 1,170 155 1] } coordIndex [0, 1, 2, 3, 4, 5, -1] } } } DEF five HammerButton { repeat TRUE shapes Shape { appearance USE TranspApp geometry IndexedFaceSet { coord Coordinate { point [88 72 1,37 113 1,78 169 1,140 169 1,158 113 1] } coordIndex [0, 1, 2, 3, 4, -1] } } } DEF four HammerButton { repeat TRUE shapes Shape { appearance USE TranspApp geometry IndexedFaceSet { coord Coordinate { point [168 27 1,165 126 1,275 126 1,275 26 1,] } coordIndex [0, 1, 2, 3, -1] } } } DEF three HammerButton { repeat TRUE shapes Shape { appearance USE TranspApp geometry IndexedFaceSet { coord Coordinate { point [128 211 1,98 290 1,181 277 1,] } coordIndex [0, 1, 2, -1] } } } ] } DEF TestLayer2 Layer2D { type "Background" children [ Layout { size 200 200 sizeUnits ["PIXEL" "PIXEL"] scaleMode ["PIXEL" "PIXEL"] children [ NavigationInfo {headlight TRUE } Transform { translation 50 0 0 scale 1 1 1 children [ TouchSensor {} Transform { translation 0 40 0 children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 0 emissiveColor 0 1 0 } } geometry IndexedFaceSet { coordIndex [0 1 2 0 2 3] coords Coordinate { point [0 0 0 200 0 0 200 72 0 0 72 0] } } } ] } ] } ] } ] } DEF TestScript Script { eventIn SFInt32 touchedId eventIn SFInt32 overId eventIn MFString text eventIn SFFloat report_float eventIn SFInt32 report_int exposedField SFBool active FALSE url "javascript: function touchedId(value,time) { Browser.print ('touched: '+value); } function overId(value,time) { Browser.print ('over id: '+value); } function text(value,time) { Browser.print ('text: '+value[0]); } function set_active(value,time) { Browser.print ('active: '+value); } function report_float(value,time) { Browser.setDescription(value); } function report_int(value,time) { Browser.setDescription(value); } " } ROUTE TestList.id TO TestScript.touchedId ROUTE TestList.chosenText TO TestScript.text ROUTE ToggleTest.active_changed TO TestScript.set_active ROUTE ToggleTest.isActive TO TestScript.active ROUTE ToggleTest.active_changed TO TestScript.active #ROUTE TestSlider.fraction TO TestScript.report_float #ROUTE TestAnimTimer.fraction TO TestScript.report_float ROUTE TestAnimTimer.fraction TO TestSlider.fraction #ROUTE TestSlider.fraction TO TestAnimTimer.cycleTime ROUTE ToggleTest.isActive TO TestAnimTimer.pause ROUTE PopUpButton.isActive TO TestMenu.show