<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://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 =' http://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 FanClock node:  [from MotorAmp.fanCycleTime to set_cycleInterval ] [from MotorButtonActionOn.fanOnButtonAction to set_cycleInterval ] [from fraction_changed to FanPath.set_fraction ] -->
<TimeSensor DEF='FanClockstartTime='10stopTime='0.1'/>
<!-- 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>
<!-- ROUTE information for MotorAmp node:  [from SwitchPlaneSensor.translation_changed to switchPosition ] [from fanCycleTime to FanClock.set_cycleInterval ] [from displayFanSpeed to SpeedDisplay.set_string ] -->
<Script DEF='MotorAmp'>
<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>
<!-- ROUTE information for MotorClockOff node:  [from SensorOffButton.touchTime to set_startTime ] [from fraction_changed to OffButtonDownPath.set_fraction ] [from fraction_changed to OnButtonUpPath.set_fraction ] [from fraction_changed to GtoRColorInerp.set_fraction ] -->
<TimeSensor DEF='MotorClockOff'/>
<!-- ROUTE information for MotorClockOn node:  [from SensorOnButton.touchTime to set_startTime ] [from fraction_changed to OnButtonDownPath.set_fraction ] [from fraction_changed to OffButtonUpPath.set_fraction ] [from fraction_changed to RtoGColorInerp.set_fraction ] -->
<TimeSensor DEF='MotorClockOn'/>
</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>
<!-- ROUTE information for MotorButtonActionOn node:  [from SensorOnButton.isActive to onButtonAction ] [from displayMotorStatus to StatusDisplay.set_string ] [from fanOnButtonAction to FanClock.set_cycleInterval ] -->
<Script DEF='MotorButtonActionOn'>
<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>
<!-- ROUTE information for MotorButtonActionOff node:  [from SensorOffButton.isActive to offButtonAction ] [from displayMotorStatus to StatusDisplay.set_string ] -->
<Script DEF='MotorButtonActionOff'>
<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='SwitchPlaneSensorfromField='translation_changedtoNode='SwitchTransformtoField='set_translation'/>
<!-- Routes for controling Fan w/ Switch -->
<ROUTE fromNode='SwitchPlaneSensorfromField='translation_changedtoNode='MotorAmptoField='switchPosition'/>
<ROUTE fromNode='MotorAmpfromField='fanCycleTimetoNode='FanClocktoField='set_cycleInterval'/>
<ROUTE fromNode='FanClockfromField='fraction_changedtoNode='FanPathtoField='set_fraction'/>
<ROUTE fromNode='FanPathfromField='value_changedtoNode='FantoField='set_rotation'/>
<!-- Button Movement Routes -->
<ROUTE fromNode='SensorOffButtonfromField='touchTimetoNode='MotorClockOfftoField='set_startTime'/>
<ROUTE fromNode='SensorOffButtonfromField='isActivetoNode='MotorButtonActionOfftoField='offButtonAction'/>
<ROUTE fromNode='SensorOnButtonfromField='touchTimetoNode='MotorClockOntoField='set_startTime'/>
<ROUTE fromNode='SensorOnButtonfromField='isActivetoNode='MotorButtonActionOntoField='onButtonAction'/>
<ROUTE fromNode='MotorClockOnfromField='fraction_changedtoNode='OnButtonDownPathtoField='set_fraction'/>
<ROUTE fromNode='MotorClockOnfromField='fraction_changedtoNode='OffButtonUpPathtoField='set_fraction'/>
<ROUTE fromNode='MotorClockOfffromField='fraction_changedtoNode='OffButtonDownPathtoField='set_fraction'/>
<ROUTE fromNode='MotorClockOfffromField='fraction_changedtoNode='OnButtonUpPathtoField='set_fraction'/>
<ROUTE fromNode='OnButtonDownPathfromField='value_changedtoNode='OnButtontoField='set_translation'/>
<ROUTE fromNode='OffButtonDownPathfromField='value_changedtoNode='OffButtontoField='set_translation'/>
<ROUTE fromNode='OnButtonUpPathfromField='value_changedtoNode='OnButtontoField='set_translation'/>
<ROUTE fromNode='OffButtonUpPathfromField='value_changedtoNode='OffButtontoField='set_translation'/>
<!-- Route for Fan display -->
<ROUTE fromNode='MotorAmpfromField='displayFanSpeedtoNode='SpeedDisplaytoField='set_string'/>
<!-- Route for Motor display -->
<ROUTE fromNode='MotorClockOnfromField='fraction_changedtoNode='RtoGColorInerptoField='set_fraction'/>
<ROUTE fromNode='MotorClockOfffromField='fraction_changedtoNode='GtoRColorInerptoField='set_fraction'/>
<ROUTE fromNode='MotorButtonActionOnfromField='displayMotorStatustoNode='StatusDisplaytoField='set_string'/>
<ROUTE fromNode='RtoGColorInerpfromField='value_changedtoNode='MotorDisplayMaterialtoField='set_diffuseColor'/>
<ROUTE fromNode='GtoRColorInerpfromField='value_changedtoNode='MotorDisplayMaterialtoField='set_diffuseColor'/>
<ROUTE fromNode='MotorButtonActionOfffromField='displayMotorStatustoNode='StatusDisplaytoField='set_string'/>
<!-- Buttons control Fan -->
<ROUTE fromNode='MotorButtonActionOnfromField='fanOnButtonActiontoNode='FanClocktoField='set_cycleInterval'/>
<!-- -->
</Scene>
</X3D>
<!--

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 images : Viewpoint_1, Viewpoint_2, Viewpoint_3, Viewpoint_4
-->

<!-- Color key: <X3dNode DEF='idName' field='value'/> matches <XmlElement DEF='idName' attribute='value'/>
(Light blue background: behavior node) (Grey background: inserted documentation) (Magenta background: X3D Extensibility)
-->

<!-- Additional help information about X3D scenes: X3D Resources, X3D Scene Authoring Hints and X3D Tooltips -->