<?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='20 October 2019'/>
<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>
<!-- -->
<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='MFFloataccessType='outputOnly'/>
<field name='displayFanSpeedtype='MFStringaccessType='outputOnly'/>
<![CDATA[
        
ecmascript:

function switchPosition(pos)
{
	if (switchPosition.pos.y == 0){
		fanCycleTime[0] = switchPosition.pos.y;
		displayFanSpeed[0] ='OFF';
	}
	else{if (switchPosition.pos.y == 3){
		fanCycleTime[0] = .01;
		displayFanSpeed[0] ='MAX';
	}
	else {
		fanCycleTime[0] = (6 - (switchPosition.pos.y*2));
		displayFanSpeed[0] = (Math.round((1/fanCycleTime[0])*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='SFInt32accessType='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 <!-- Event Graph ROUTE Table shows event connections -->
 
<!-- 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
SFInt32

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
MFFloat

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