<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
<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'>
<head>
<meta name='titlecontent='PropellerControlPanel.x3d'/>
<meta name='descriptioncontent='Controller buttons and slider for a propeller.'/>
<meta name='creatorcontent='Dan DeVos'/>
<meta name='translatorcontent='*if manually translating VRML-to-X3D, enter name of person translating here*'/>
<meta name='createdcontent='8 August 2002'/>
<meta name='modifiedcontent='11 August 2024'/>
<meta name=' warning content=' mismatched typing in some ROUTEs still needs fixing '/>
<meta name='identifiercontent='https://www.web3d.org/x3d/content/examples/Basic/StudentProjects/PropellerControlPanel.x3d'/>
<meta name='generatorcontent='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent='../license.html'/>
</head> <!-- -->
X3D Tooltips element index: Appearance, Background, Box, ColorInterpolator, Cylinder, Extrusion, field, FontStyle, Group, head, Material, meta, OrientationInterpolator, PlaneSensor, PositionInterpolator, ROUTE, Scene, Script, Shape, Sphere, Text, TimeSensor, TouchSensor, Transform, Transform, Transform, Transform, Viewpoint, WorldInfo, X3D, accessType and type, XML data types, field types


<Scene>
<WorldInfo title='PropellerControlPanel.x3d'/>
<Viewpoint description='Fanposition='1 0 10'/>
<Viewpoint description='Control Panelposition='-1 0 5'/>
<Viewpoint description='Watch Fan Spinorientation='0 1 0 1.571position='10 0 0'/>
<Viewpoint description='Remote Controlorientation='1 0 0 -1.571position='0 3 20'/>
<Background groundColor='.3 .6 .4skyColor='.6 .6 .9'/>
<!-- Rotating Fan -->
<Group DEF='MaterialGroup'>
<Shape>
<Sphere radius='.001'/>
<Appearance DEF='DarkBlueGreyMetal'>
<Material diffuseColor='0.4 0.4 0.4specularColor='0.4 0.4 0.6'/>
</Appearance>
</Shape>
<Shape>
<Sphere radius='.001'/>
<Appearance DEF='LightGreyMetal'>
<Material diffuseColor='0.7 0.7 0.7shininess='0.1specularColor='0.9 0.9 0.9'/>
</Appearance>
</Shape>
</Group>
<Transform rotation='0 0 -1 1.571translation='2 0 0'>
<Group DEF='RotatingFanGroup'>
<!-- ROUTE information for Fan node:  [from FanPath.value_changed to set_rotation ] -->
<Transform DEF='Fan'>
<Transform DEF='FanHub'>
<Shape DEF='FanHubMiddle'>
<Appearance USE='DarkBlueGreyMetal'/>
<Cylinder height='.4radius='.25'/>
</Shape>
<Transform translation='0 .2 0'>
<Shape DEF='FanHubTop'>
<Sphere radius='.255'/>
<Appearance USE='DarkBlueGreyMetal'/>
</Shape>
</Transform>
</Transform>
<Transform DEF='RightFanBladerotation='1 0 0 -.2scale='2 .1 .5translation='1.8 0 0'>
<Shape DEF='FanBlade'>
<Sphere/>
<Appearance USE='LightGreyMetal'/>
</Shape>
</Transform>
<Transform DEF='LeftFanBladerotation='1 0 0 .2scale='2 .1 .5translation='-1.8 0 0'>
<Shape USE='FanBlade'/>
</Transform>
</Transform>

<!-- ROUTE information for FanPath node:  [from FanClock.fraction_changed to set_fraction ] [from value_changed to Fan.set_rotation ] -->
<OrientationInterpolator DEF='FanPathkey='0.0 0.50 1.0keyValue='0.0 1.0 0.0 0.0 0.0 1.0 0.0 3.14 0.0 1.0 0.0 6.28'/>
</Group>
</Transform>
<!-- This is where the motor goes. -->
<Transform>
<Group DEF='MotorHousingGroup'>
<Transform>
<Shape>
<Box size='3.65 3.65 3.65'/>
<Appearance>
<Material/>
</Appearance>
</Shape>
</Transform>
</Group>
</Transform>
<!-- -->
<Group DEF='ControlPanel'>
<!-- This switch is used to control the fan -->
<Transform scale='.2 .2 .2translation='-1 -.3 1.825'>
<Group DEF='SwitchGroup'>
<Transform rotation='0 0 1 1.571'>
<Transform rotation='1 0 0 1.571'>
<Shape>
<Appearance USE='DarkBlueGreyMetal'/>
<Extrusion crossSection='0 1.2 0 1.0 -2 1.0 -2 -1.0 2 -1.0 2 1.0 0 1.0 0 1.2 2.2 1.2 2.2 -1.2 -2.2 -1.2 -2.2 1.2 0 1.2spine='0 0 0 0 .5 0'/>
</Shape>
</Transform>
</Transform>
<Transform translation='0 -1.5 .251'>
<!-- ROUTE information for SwitchTransform node:  [from SwitchPlaneSensor.translation_changed to set_translation ] -->
<Transform DEF='SwitchTransform'>
<Shape DEF='SwitchNob'>
<Box size='2 1 .499'/>
<Appearance USE='LightGreyMetal'/>
</Shape>
<!-- ROUTE information for SwitchPlaneSensor node:  [from translation_changed to SwitchTransform.set_translation ] [from translation_changed to MotorAmp.switchPosition ] -->
<PlaneSensor DEF='SwitchPlaneSensormaxPosition='0 3'/>

<TouchSensor DEF='SwitchTouchSensor'/>
</Transform>
</Transform>
<Transform translation='0 0 .1'>
<Shape DEF='SwitchBack'>
<Box size='2 4 .2'/>
<Appearance USE='DarkBlueGreyMetal'/>
</Shape>
</Transform>
</Group>
</Transform>
<!-- Fan Status Display -->
<Transform translation='.5 -.5 1.83'>
<Group DEF='Display'>
<Transform translation='0 0 .01'>
<Shape>
<!-- ROUTE information for SpeedDisplay node:  [from MotorAmp.displayFanSpeed to set_string ] -->
<Text DEF='SpeedDisplaystring='"OFF"'>
<FontStyle justify='"MIDDLE" "MIDDLE"size='0.5'/>
</Text>
<Appearance DEF='BlackText'>
<Material diffuseColor='0 0 0'/>
</Appearance>
</Shape>
</Transform>
<Shape DEF='DisplayField'>
<Appearance>
<Material emissiveColor='0 1 1transparency='.7'/>
</Appearance>
<Box size='2 .6 .01'/>
</Shape>
<Transform translation='0 .5 .01'>
<Shape>
<Text string='"Fan Status:"'>
<FontStyle justify='"MIDDLE" "MIDDLE"size='0.5'/>
</Text>
<Appearance USE='BlackText'/>
</Shape>
</Transform>
</Group>
</Transform>
<field name='switchPositiontype='SFVec3faccessType='inputOnly'/>
<field name='fanCycleTimetype='SFTimeaccessType='outputOnly'/>
<field name='displayFanSpeedtype='MFStringaccessType='outputOnly'/>
<![CDATA[
        
ecmascript:

function switchPosition(pos)
{
	if (switchPosition.pos.y == 0){
		fanCycleTime = switchPosition.pos.y;
		displayFanSpeed[0] ='OFF';
	}
	else{if (switchPosition.pos.y == 3){
		fanCycleTime = .01;
		displayFanSpeed[0] ='MAX';
	}
	else {
		fanCycleTime = (6 - (switchPosition.pos.y*2));
		displayFanSpeed[0] = (Math.round((1/fanCycleTime)*6000)/100) + ' RPM';
	}}
}

      
]]>
</Script>
<!-- Motor On/Off Buttons -->
<Transform translation='-1 1 1.6'>
<Transform rotation='1 0 0 1.571'>
<!-- ROUTE information for OffButton node:  [from OffButtonDownPath.value_changed to set_translation ] [from OffButtonUpPath.value_changed to set_translation ] -->
<Transform DEF='OffButtontranslation='0 .1 .3'>
<Group>
<Shape>
<Cylinder height='.45radius='.2'/>
<Appearance DEF='RedStatus'>
<Material diffuseColor='1 0.3 0.3'/>
</Appearance>
</Shape>
<!-- ROUTE information for SensorOffButton node:  [from touchTime to MotorClockOff.set_startTime ] [from isActive to MotorButtonActionOff.offButtonAction ] -->
<TouchSensor DEF='SensorOffButton'/>

<!-- ROUTE information for OffButtonDownPath node:  [from MotorClockOff.fraction_changed to set_fraction ] [from value_changed to OffButton.set_translation ] -->
<PositionInterpolator DEF='OffButtonDownPathkey='0.0 0.50 1.0keyValue='0.0 0.3 0.3 0.0 0.2 0.3 0.0 0.1 0.3'/>

<!-- ROUTE information for OffButtonUpPath node:  [from MotorClockOn.fraction_changed to set_fraction ] [from value_changed to OffButton.set_translation ] -->
<PositionInterpolator DEF='OffButtonUpPathkey='0.0 0.50 1.0keyValue='0.0 0.1 0.3 0.0 0.2 0.3 0.0 0.3 0.3'/>
</Group>
</Transform>
<!-- ROUTE information for OnButton node:  [from OnButtonDownPath.value_changed to set_translation ] [from OnButtonUpPath.value_changed to set_translation ] -->
<Transform DEF='OnButtontranslation='0 .3 -.3'>
<Group>
<Shape>
<Cylinder height='.45radius='.2'/>
<Appearance DEF='GreenStatus'>
<Material diffuseColor='0.3 1 .3'/>
</Appearance>
</Shape>
<!-- ROUTE information for SensorOnButton node:  [from touchTime to MotorClockOn.set_startTime ] [from isActive to MotorButtonActionOn.onButtonAction ] -->
<TouchSensor DEF='SensorOnButton'/>

<!-- ROUTE information for OnButtonDownPath node:  [from MotorClockOn.fraction_changed to set_fraction ] [from value_changed to OnButton.set_translation ] -->
<PositionInterpolator DEF='OnButtonDownPathkey='0.0 0.50 1.0keyValue='0.0 0.3 -0.3 0.0 0.2 -0.3 0.0 0.1 -0.3'/>

<!-- ROUTE information for OnButtonUpPath node:  [from MotorClockOff.fraction_changed to set_fraction ] [from value_changed to OnButton.set_translation ] -->
<PositionInterpolator DEF='OnButtonUpPathkey='0.0 0.50 1.0keyValue='0.0 0.1 -0.3 0.0 0.2 -0.3 0.0 0.3 -0.3'/>
</Group>
</Transform>

</Transform>
</Transform>
<!-- Motor Status Display -->
<Transform translation='.5 .8 1.83'>
<Group DEF='MotorStatus'>
<Transform translation='0 .5 .01'>
<Shape>
<Text string='"Motor Status:"'>
<FontStyle justify='"MIDDLE" "MIDDLE"size='0.5'/>
</Text>
<Appearance USE='BlackText'/>
</Shape>
</Transform>
<Transform translation='0 0 .01'>
<Shape>
<!-- ROUTE information for StatusDisplay node:  [from MotorButtonActionOn.displayMotorStatus to set_string ] [from MotorButtonActionOff.displayMotorStatus to set_string ] -->
<Text DEF='StatusDisplaystring='"OFF"'>
<FontStyle justify='"MIDDLE" "MIDDLE"size='0.5'/>
</Text>
<Appearance>
<!-- ROUTE information for MotorDisplayMaterial node:  [from RtoGColorInerp.value_changed to set_diffuseColor ] [from GtoRColorInerp.value_changed to set_diffuseColor ] -->
<Material DEF='MotorDisplayMaterialdiffuseColor='1 .3 .3'/>
</Appearance>
</Shape>
</Transform>
<Shape USE='DisplayField'/>
</Group>
</Transform>
<field name='onButtonActiontype='SFBoolaccessType='inputOnly'/>
<field name='displayMotorStatustype='MFStringaccessType='outputOnly'/>
<field name='fanOnButtonActiontype='SFTimeaccessType='outputOnly'/>
<![CDATA[
        
ecmascript:

function onButtonAction(bool)
{
	if (onButtonAction.bool == true)
	{
		displayMotorStatus[0] ='ON';
		fanOnButtonAction = 1;
	}
}

      
]]>
</Script>
<field name='offButtonActiontype='SFBoolaccessType='inputOnly'/>
<field name='displayMotorStatustype='MFStringaccessType='outputOnly'/>
<![CDATA[
        
ecmascript:

function offButtonAction(bool)
{
	if (offButtonAction.bool == true)
	{
		displayMotorStatus[0] ='OFF';
	}
}

      
]]>
</Script>
<!-- ROUTE information for RtoGColorInerp node:  [from MotorClockOn.fraction_changed to set_fraction ] [from value_changed to MotorDisplayMaterial.set_diffuseColor ] -->
<ColorInterpolator DEF='RtoGColorInerpkey='0 .1 .1 1keyValue='1 .3 .3 1 .3 .3 .3 1 .3 .3 1 .3'/>

<!-- ROUTE information for GtoRColorInerp node:  [from MotorClockOff.fraction_changed to set_fraction ] [from value_changed to MotorDisplayMaterial.set_diffuseColor ] -->
<ColorInterpolator DEF='GtoRColorInerpkey='0 .1 .1 1keyValue='.3 1 .3 .3 1 .3 1 .3 .3 1 .3 .3'/>
</Group>
<Group DEF='RemoteControl'>
<Transform rotation='1 0 0 -1.571'>
<Transform scale='.2 .5 .5translation='0 -20 0'>
<Group USE='ControlPanel'/>
<Transform translation='0 0 1.325'>
<Shape>
<Box size='3 3 1'/>
<Appearance USE='DarkBlueGreyMetal'/>
</Shape>
</Transform>
</Transform>
</Transform>
</Group>
<!-- Route for controling Switch movement -->
< ROUTE  fromNode='SwitchPlaneSensor' fromField='translation_changed' toNode='SwitchTransform' toField='set_translation'/>
<!-- Routes for controling Fan w/ Switch -->
< ROUTE  fromNode='SwitchPlaneSensor' fromField='translation_changed' toNode='MotorAmp' toField='switchPosition'/>
< ROUTE  fromNode='MotorAmp' fromField='fanCycleTime' toNode='FanClock' toField='set_cycleInterval'/>
< ROUTE  fromNode='FanClock' fromField='fraction_changed' toNode='FanPath' toField='set_fraction'/>
< ROUTE  fromNode='FanPath' fromField='value_changed' toNode='Fan' toField='set_rotation'/>
<!-- Button Movement Routes -->
< ROUTE  fromNode='SensorOffButton' fromField='touchTime' toNode='MotorClockOff' toField='set_startTime'/>
< ROUTE  fromNode='SensorOffButton' fromField='isActive' toNode='MotorButtonActionOff' toField='offButtonAction'/>
< ROUTE  fromNode='SensorOnButton' fromField='touchTime' toNode='MotorClockOn' toField='set_startTime'/>
< ROUTE  fromNode='SensorOnButton' fromField='isActive' toNode='MotorButtonActionOn' toField='onButtonAction'/>
< ROUTE  fromNode='MotorClockOn' fromField='fraction_changed' toNode='OnButtonDownPath' toField='set_fraction'/>
< ROUTE  fromNode='MotorClockOn' fromField='fraction_changed' toNode='OffButtonUpPath' toField='set_fraction'/>
< ROUTE  fromNode='MotorClockOff' fromField='fraction_changed' toNode='OffButtonDownPath' toField='set_fraction'/>
< ROUTE  fromNode='MotorClockOff' fromField='fraction_changed' toNode='OnButtonUpPath' toField='set_fraction'/>
< ROUTE  fromNode='OnButtonDownPath' fromField='value_changed' toNode='OnButton' toField='set_translation'/>
< ROUTE  fromNode='OffButtonDownPath' fromField='value_changed' toNode='OffButton' toField='set_translation'/>
< ROUTE  fromNode='OnButtonUpPath' fromField='value_changed' toNode='OnButton' toField='set_translation'/>
< ROUTE  fromNode='OffButtonUpPath' fromField='value_changed' toNode='OffButton' toField='set_translation'/>
<!-- Route for Fan display -->
< ROUTE  fromNode='MotorAmp' fromField='displayFanSpeed' toNode='SpeedDisplay' toField='set_string'/>
<!-- Route for Motor display -->
< ROUTE  fromNode='MotorClockOn' fromField='fraction_changed' toNode='RtoGColorInerp' toField='set_fraction'/>
< ROUTE  fromNode='MotorClockOff' fromField='fraction_changed' toNode='GtoRColorInerp' toField='set_fraction'/>
< ROUTE  fromNode='MotorButtonActionOn' fromField='displayMotorStatus' toNode='StatusDisplay' toField='set_string'/>
< ROUTE  fromNode='RtoGColorInerp' fromField='value_changed' toNode='MotorDisplayMaterial' toField='set_diffuseColor'/>
< ROUTE  fromNode='GtoRColorInerp' fromField='value_changed' toNode='MotorDisplayMaterial' toField='set_diffuseColor'/>
< ROUTE  fromNode='MotorButtonActionOff' fromField='displayMotorStatus' toNode='StatusDisplay' toField='set_string'/>
<!-- Buttons control Fan -->
< ROUTE  fromNode='MotorButtonActionOn' fromField='fanOnButtonAction' toNode='FanClock' toField='set_cycleInterval'/>
<!-- -->
</Scene>
</X3D> <!--

to top <!-- Index for DEF nodes: BlackText, ControlPanel, DarkBlueGreyMetal, Display, DisplayField, Fan, FanBlade, FanClock, FanHub, FanHubMiddle, FanHubTop, FanPath, GreenStatus, GtoRColorInerp, LeftFanBlade, LightGreyMetal, MaterialGroup, MotorAmp, MotorButtonActionOff, MotorButtonActionOn, MotorClockOff, MotorClockOn, MotorDisplayMaterial, MotorHousingGroup, MotorStatus, OffButton, OffButtonDownPath, OffButtonUpPath, OnButton, OnButtonDownPath, OnButtonUpPath, RedStatus, RemoteControl, RightFanBlade, RotatingFanGroup, RtoGColorInerp, SensorOffButton, SensorOnButton, SpeedDisplay, StatusDisplay, SwitchBack, SwitchGroup, SwitchNob, SwitchPlaneSensor, SwitchTouchSensor, SwitchTransform

Index for Viewpoint nodes: Viewpoint_1, Viewpoint_2, Viewpoint_3, Viewpoint_4
-->

Event Graph ROUTE Table entries with 25 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.

SensorOffButton
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
MotorClockOff
TimeSensor
set_startTime
SFTime
then
 
 
 
MotorClockOff
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
OffButtonDownPath
PositionInterpolator
set_fraction
SFFloat
then
 
 
 
OffButtonDownPath
PositionInterpolator
value_changed
SFVec3f

ROUTE
event to
(3)
OffButton
Transform
set_translation
SFVec3f
  then
 
 
 
MotorClockOff
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
OnButtonUpPath
PositionInterpolator
set_fraction
SFFloat
then
 
 
 
OnButtonUpPath
PositionInterpolator
value_changed
SFVec3f

ROUTE
event to
(3)
OnButton
Transform
set_translation
SFVec3f
  then
 
 
 
MotorClockOff
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
GtoRColorInerp
ColorInterpolator
set_fraction
SFFloat
then
 
 
 
GtoRColorInerp
ColorInterpolator
value_changed
SFColor

ROUTE
event to
(3)
MotorDisplayMaterial
Material
set_diffuseColor
SFColor
SensorOffButton
TouchSensor
isActive
SFBool

ROUTE
event to
(1)
MotorButtonActionOff
Script
offButtonAction
SFBool
then
 
 
 
MotorButtonActionOff
Script
displayMotorStatus
MFString

ROUTE
event to
(2)
StatusDisplay
Text
set_string
MFString

SensorOnButton
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
MotorClockOn
TimeSensor
set_startTime
SFTime
then
 
 
 
MotorClockOn
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
OnButtonDownPath
PositionInterpolator
set_fraction
SFFloat
then
 
 
 
OnButtonDownPath
PositionInterpolator
value_changed
SFVec3f

ROUTE
event to
(3)
OnButton
Transform
set_translation
SFVec3f
  then
 
 
 
MotorClockOn
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
OffButtonUpPath
PositionInterpolator
set_fraction
SFFloat
then
 
 
 
OffButtonUpPath
PositionInterpolator
value_changed
SFVec3f

ROUTE
event to
(3)
OffButton
Transform
set_translation
SFVec3f
  then
 
 
 
MotorClockOn
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(2)
RtoGColorInerp
ColorInterpolator
set_fraction
SFFloat
then
 
 
 
RtoGColorInerp
ColorInterpolator
value_changed
SFColor

ROUTE
event to
(3)
MotorDisplayMaterial
Material
set_diffuseColor
SFColor
SensorOnButton
TouchSensor
isActive
SFBool

ROUTE
event to
(1)
MotorButtonActionOn
Script
onButtonAction
SFBool
then
 
 
 
MotorButtonActionOn
Script
displayMotorStatus
MFString

ROUTE
event to
(2)
StatusDisplay
Text
set_string
MFString
  then
 
 
 
MotorButtonActionOn
Script
fanOnButtonAction
SFTime

ROUTE
event to
(2)
FanClock
TimeSensor
set_cycleInterval
SFTime
then
 
 
 
FanClock
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(3)
FanPath
OrientationInterpolator
set_fraction
SFFloat
then
 
 
 
FanPath
OrientationInterpolator
value_changed
SFRotation

ROUTE
event to
(4)
Fan
Transform
set_rotation
SFRotation

SwitchPlaneSensor
PlaneSensor
translation_changed
SFVec3f

ROUTE
event to
(1)
SwitchTransform
Transform
set_translation
SFVec3f
SwitchPlaneSensor
PlaneSensor
translation_changed
SFVec3f

ROUTE
event to
(1)
MotorAmp
Script
switchPosition
SFVec3f
then
 
 
 
MotorAmp
Script
displayFanSpeed
MFString

ROUTE
event to
(2)
SpeedDisplay
Text
set_string
MFString
  then
 
 
 
MotorAmp
Script
fanCycleTime
SFTime

ROUTE
event to
(2)
FanClock
TimeSensor
set_cycleInterval
SFTime
then
 
 
 
FanClock
TimeSensor
fraction_changed
SFFloat

ROUTE
event to
(3)
FanPath
OrientationInterpolator
set_fraction
SFFloat
then
 
 
 
FanPath
OrientationInterpolator
value_changed
SFRotation

ROUTE
event to
(4)
Fan
Transform
set_rotation
SFRotation

-->
<!-- Online at
https://www.web3d.org/x3d/content/examples/Basic/StudentProjects/PropellerControlPanelIndex.html -->
<!-- Version control at
https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/Basic/StudentProjects/PropellerControlPanel.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)
-->

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