<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd">
<X3D profile='Immersive' version='3.3 xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation =' https://www.web3d.org/specifications/x3d-3.3.xsd '>
<head>
<meta name='titlecontent='TextureAngleViewer.x3d'/>
<meta name='descriptioncontent='View a given texture from different angles to judge readability, example use is a QR code.'/>
<meta name='creatorcontent='Don Brutzman'/>
<meta name='createdcontent='23 April 2013'/>
<meta name='modifiedcontent='20 April 2020'/>
<meta name=' TODO content=' color mapper in scene for varying Background contrast '/>
<meta name=' TODO content=' second X-axis angle slider '/>
<meta name='Imagecontent='TextureAngleViewer36degrees.png'/>
<meta name='Imagecontent='images/QrNpsEduCode.png'/>
<meta name='referencecontent=' http://qr.nps.edu '/>
<meta name='referencecontent=' https://zxing.appspot.com/generator '/>
<meta name='identifiercontent=' https://x3dgraphics.com/examples/X3dForAdvancedModeling/TextureMapping/TextureAngleViewer.x3d '/>
<meta name='generatorcontent='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent=' ../license.html'/>
</head>
<!-- -->
<Scene>
<!-- ================================ -->
<WorldInfo title='Texture Angle Viewer'/>
<Background skyColor='0.72549 1 0.721569'/>
<Viewpoint description='Texture angle viewerposition='0 0 11'/>
<NavigationInfo DEF='NavigationInfoFinaltype='"NONE"'/>
<!-- <NavigationInfo DEF='NavigationInfoDebug' type='"EXAMINE"
"ANY"'/> -->

<!-- ================================ -->
<Transform translation='0 3.6 0'>
<Shape>
<!-- ROUTE information for AngleOutputText node:  [from SliderScript.angleMFString_changed to string ] -->
<Text DEF='AngleOutputTextstring='"Texture angle viewer"'>
<FontStyle justify='"MIDDLE" "MIDDLE"size='0.7'/>
</Text>
<Appearance>
<Material diffuseColor='0.2 0.4 0.8'/>
</Appearance>
</Shape>
</Transform>
<!-- ================================ -->
<Anchor description=' this QR code links to http://qr.nps.edu '
  url=' "http://qr.nps.edu" '>
<!-- ROUTE information for ImageTransform node:  [from SliderScript.rotation_changed to rotation ] -->
<Transform DEF='ImageTransform'>
<Shape>
<!-- TODO add a single geometry node here -->
<IndexedFaceSet coordIndex='1 0 2 3 0 -1'>
<Coordinate point='-3 -3 0 3 -3 0 3 3 0 -3 3 0 -3 -3 0'/>
</IndexedFaceSet>
<Appearance> </Appearance>
</Shape>
</Transform>
</Anchor>
<!-- ================================ -->
<Transform DEF='SliderSituatedtranslation='0 -3.6 0'>
<!-- ROUTE information for SliderKnobTransform node:  [from SliderScript.translation_changed to translation ] -->
<Transform DEF='SliderKnobTransform'>
<!-- ROUTE information for SliderPlaneSensor node:  [from translation_changed to SliderScript.set_translation ] -->
<PlaneSensor DEF='SliderPlaneSensordescription='select and drag to change angle valuesmaxPosition='3 0minPosition='-3 0'/>
<Transform rotation='0 0 1 1.570796'>
<Shape>
<Cylinder DEF='SliderKnobheight='0.2radius='0.2'/>
<Appearance DEF='Metals13Appearance'>
<Material ambientIntensity='0.25641diffuseColor='0.222308 0.15428 0specularColor='0.882653 0.860832 0.687861'>
<!-- Universal Media Library: Metals 13 -->
</Material>
</Appearance>
</Shape>
</Transform>
</Transform>
<!-- SliderBar does not rotate or drag with SliderKnob -->
<Transform DEF='SliderBarrotation='0 0 1 1.570796'>
<Shape>
<Cylinder height='6radius='0.05'/>
<Appearance USE='Metals13Appearance'/>
</Shape>
</Transform>
</Transform>
<!-- ================================ -->
<!-- ROUTE information for SliderScript node:  [from SliderPlaneSensor.translation_changed to set_translation ] [from translation_changed to SliderKnobTransform.translation ] [from rotation_changed to ImageTransform.rotation ] [from angleMFString_changed to AngleOutputText.string ] -->
<Script DEF='SliderScript'>
<field name='set_translationtype='SFVec3faccessType='inputOnly'
 appinfo='input provided by SliderKnobTransform PlaneSensor output'/>

<field name='angletype='SFFloatvalue='0.0accessType='initializeOnly'/>
<field name='ytype='SFFloatvalue='0.0accessType='initializeOnly'/>
<field name='rotation_changedtype='SFRotationaccessType='outputOnly'
 appinfo='output provided for ImageTransform rotation'/>

<!-- Note that trackPoint_changed events represent unclamped intersection points on plane surface. Browsers can interpret drags off of the surface in various ways. Note that translation_changed events are clamped by minPosition/maxPosition and thus may be preferable. -->
<field name='translation_changedtype='SFVec3faccessType='outputOnly'
 appinfo='output provided for SliderKnobTransform translation'/>

<field name='angleMFString_changedtype='MFStringaccessType='outputOnly'
 appinfo='output provided for degrees of rotation in Text node'/>

<field name='tracePrinttype='SFBoolvalue='trueaccessType='initializeOnly'
 appinfo='console output for debugging'/>

<![CDATA[
      
ecmascript:

function set_translation (eventValue)
{
   x = eventValue.x;
   if (tracePrint)
   {
      Browser.println ("========================");
      Browser.println ('                  x=' + x);
   }
   // clamp values to prevent overrun/underrun, in case minPosition/maxPosition fail
   if (x >  3.0) x =  3.0;
   if (x < -3.0) x = -3.0;

   translation_changed = eventValue;
   angle = Math.round(x * 90.0 / 3.0);
   rotation_changed = new SFRotation (0, 1, 0, angle * Math.PI / 180.0);
   var angleString = angle.toString() + ' degrees'; // JavaScript string
   
// angleMFString_changed = new MFString (new SFString(angleString)); // only works in InstantReality
   angleMFString_changed = new MFString (angleString); // works in several players but not all
// angleMFString_changed = [ angleString ]; // Use JavaScript string array instead of MFString doesn't work
   
   if (tracePrint)
   {
      Browser.println ('          clamped x=' + x);
      Browser.println ("    set_translation=" + eventValue);
      Browser.println ("translation_changed=" + translation_changed.toString() + ", rotation_changed=" + rotation_changed.toString());
      Browser.println ("angle=" + angle + ", angleString=" + angleString + ", angleMFString_changed=" + angleMFString_changed.toString());
   }
/*
example console excerpt:
========================
                  x=-0.05248255282640457
          clamped x=-0.05248255282640457
    set_translation=-0.05248255282640457 0 0
translation_changed=-0.05248255282640457 0 0, rotation_changed=0 1 0 -0.03490658503988659
angle=-2, angleString=-2 degrees, angleMFString_changed="-2 degrees"
========================
*/
}

    
]]>
</Script>
<ROUTE fromNode='SliderPlaneSensorfromField='translation_changedtoNode='SliderScripttoField='set_translation'/>
<ROUTE fromNode='SliderScriptfromField='translation_changedtoNode='SliderKnobTransformtoField='translation'/>
<ROUTE fromNode='SliderScriptfromField='rotation_changedtoNode='ImageTransformtoField='rotation'/>
<ROUTE fromNode='SliderScriptfromField='angleMFString_changedtoNode='AngleOutputTexttoField='string'/>
</Scene>
</X3D>
<!--

Index for DEF nodes : AngleOutputText, ImageTransform, Metals13Appearance, NavigationInfoFinal, SliderBar, SliderKnob, SliderKnobTransform, SliderPlaneSensor, SliderScript, SliderSituated

Index for Viewpoint image : Viewpoint_1
-->

<!-- 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)
-->

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