<?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='BathymetryGeneratorPrototype.x3d'/>
<meta name='descriptioncontent='This prototype generates bathymetry based on the input data using IndexedFaceSet.'/>
<meta name='creatorcontent='Don Brutzman, Jane Wu'/>
<meta name='createdcontent='8 February 2002'/>
<meta name='modifiedcontent='14 January 2014'/>
<meta name='subjectcontent='bathymetry'/>
<meta name='identifiercontent=' https://savage.nps.edu/Savage/Tools/Animation/BathymetryGeneratorPrototype.x3d '/>
<meta name='generatorcontent='X3D-Edit 3.2, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent=' ../../license.html'/>
</head>
<!--

Index for ProtoDeclare definition : BathymetryGenerator

Index for DEF nodes : Bathymetry, BathymetryFaceColor, BathymetryFaceCoord, BathymetryFaceSet, BathymetryScript
-->
<Scene>
<ProtoDeclare name='BathymetryGeneratorappinfo='BathymetryGenerator creates bottom topography'>
<ProtoInterface>
<field name='positionArraytype='MFVec3fvalue='0.0 0 0 10 -4 0 25 -6 0 30 -8 5 38 -15 5 45 -18 5 55 -22 5 60 -25 15 60 -27 22 55 -30 35 48 -35 35 35 -35 35 25 -45 35 20 -55 35 15 -70 35 3 -70 35 -5 -72 40 -5 -75 50 0 -80 55 15 -75 55 30 -70 55 35 -60 55 40 -50 55 50 -34 55 65 -23 70accessType='initializeOnly'/>
<field name='colorSchemeDepthRangeArraytype='MFVec2fvalue='0 -10 -10 -20 -20 -30 -30 -40 -40 -50 -50 -60 -60 -70 -70 -999999accessType='initializeOnly'/>
<field name='colorSchemeColorArraytype='MFColorvalue='1 1 0.2 0.6 1 1 0 1 1 0.2 0.6 0.2 1 0 1 0.56 0 0.32 0.2 0.3 0.7 0 0 1accessType='initializeOnly'/>
<field name='beamWidthtype='SFFloatvalue='2accessType='initializeOnly'/>
<field name='traceEnabledtype='SFBoolvalue='falseaccessType='initializeOnly'/>
</ProtoInterface>
<ProtoBody>
<Group>
<Transform DEF='Bathymetry'>
<Shape>
<!-- ROUTE information for BathymetryFaceSet node:  [from BathymetryScript.bathyCoordIndex to set_coordIndex ] [from BathymetryScript.bathyColorIndex to set_colorIndex ] -->
<IndexedFaceSet DEF='BathymetryFaceSetccw='false'>
<!-- ROUTE information for BathymetryFaceColor node:  [from BathymetryScript.bathyFaceColorArray to color ] -->
<Color DEF='BathymetryFaceColor'/>
<!-- ROUTE information for BathymetryFaceCoord node:  [from BathymetryScript.bathyFaceCoordPoints to point ] -->
<Coordinate DEF='BathymetryFaceCoord'/>
</IndexedFaceSet>
</Shape>
<!-- ROUTE information for BathymetryScript node:  [from bathyFaceCoordPoints to BathymetryFaceCoord.point ] [from bathyCoordIndex to BathymetryFaceSet.set_coordIndex ] [from bathyFaceColorArray to BathymetryFaceColor.color ] [from bathyColorIndex to BathymetryFaceSet.set_colorIndex ] -->
<Script DEF='BathymetryScript'>
<field name='positionArraytype='MFVec3faccessType='initializeOnly'/>
<field name='depthRangeArraytype='MFVec2faccessType='initializeOnly'/>
<field name='depthColorArraytype='MFColoraccessType='initializeOnly'/>
<field name='beamWidthtype='SFFloataccessType='initializeOnly'/>
<field name='bathyFaceCoordPointstype='MFVec3faccessType='outputOnly'/>
<field name='bathyCoordIndextype='MFInt32accessType='outputOnly'/>
<field name='bathyFaceColorArraytype='MFColoraccessType='outputOnly'/>
<field name='bathyColorIndextype='MFInt32accessType='outputOnly'/>
<field name='traceEnabledtype='SFBoolaccessType='initializeOnly'/>
<field name='dataValidtype='SFBoolvalue='falseaccessType='initializeOnly'
 appinfo='local variable'/>

<field name='colortype='SFColorvalue='1 1 1accessType='initializeOnly'
 appinfo='local variable'/>

<field name='leftPointtype='SFVec3fvalue='0 0 0accessType='initializeOnly'
 appinfo='local variable'/>

<field name='rightPointtype='SFVec3fvalue='0 0 0accessType='initializeOnly'
 appinfo='local variable'/>

<IS>
<connect nodeField='positionArrayprotoField='positionArray'/>
<connect nodeField='depthRangeArrayprotoField='colorSchemeDepthRangeArray'/>
<connect nodeField='depthColorArrayprotoField='colorSchemeColorArray'/>
<connect nodeField='beamWidthprotoField='beamWidth'/>
<connect nodeField='traceEnabledprotoField='traceEnabled'/>
</IS>
<![CDATA[
              
ecmascript:

function initialize()
{
	dataValid = true;
	checkDataValidity();
	if (!dataValid)
		return;

	tracePrint('positionArray.length = ' + positionArray.length);

	coordIndex = 0;
	colorIndex = 0;
	for (i = 0; i < positionArray.length; i++)
	{
		//determine the color for every position
		determineFaceColor(positionArray[i].y)
		bathyFaceColorArray[colorIndex++] = color;

		//determine the 'leftPoint' for every poistion -- For the first
		//position, use the first and second position.
		if (i == 0)
		{
			determineLeftPoint(positionArray[0], positionArray[1]);
			bathyFaceCoordPoints[coordIndex++] = leftPoint;
			determineRightPoint(positionArray[0], positionArray[1]);
			bathyFaceCoordPoints[coordIndex++] = rightPoint;
		}
		else
		{
			determineLeftPoint(positionArray[i], positionArray[i-1]);
			bathyFaceCoordPoints[coordIndex++] = leftPoint;
			determineRightPoint(positionArray[i], positionArray[i-1]);
			bathyFaceCoordPoints[coordIndex++] = rightPoint;
		}
	}

	tracePrint('bathyFaceCoordPoints = ' + bathyFaceCoordPoints);

	j = 0;
	for (i = 0; i < (positionArray.length - 1); i++)
	{
		bathyCoordIndex[j++] = i * 2;
		bathyCoordIndex[j++] = i * 2 + 1;
		bathyCoordIndex[j++] = i * 2 + 2;
		bathyCoordIndex[j++] = i * 2 + 3;
		bathyCoordIndex[j++] = -1;

		bathyCoordIndex[j++] = i * 2 + 3;
		bathyCoordIndex[j++] = i * 2 + 2;
		bathyCoordIndex[j++] = i * 2 + 1;
		bathyCoordIndex[j++] = i * 2;
		bathyCoordIndex[j++] = -1;
	}

	tracePrint('bathyCoordIndex = ' + bathyCoordIndex);
}

function checkDataValidity()
{
	if (depthRangeArray.length != depthColorArray.length)
	{
		alwaysPrint('<Error> colorSchemeDepthRangeArray must be the same length as colorSchemeColorArray');
		dataValid = false;
		return;
	}
}

function determineFaceColor(depth)
{
	for (j = 0; j < depthColorArray.length; j++)
        {
		if (depth <= depthRangeArray[j].x && depth >= depthRangeArray[j].y)
		{
			color = depthColorArray[j]
			return;
		}
        }
	color = null;
	return;
}

function determineLeftPoint(currPosition, prevPosition)
{
	deltaX = currPosition.x - prevPosition.x;
	deltaZ = currPosition.z - prevPosition.z;

	theta = Math.atan2(deltaX, deltaZ);
	tracePrint('theta = ' + theta);

	leftPoint = new SFVec3f(currPosition.x + Math.cos(theta),
	                        currPosition.y,
	                        currPosition.z - Math.sin(theta) * (beamWidth / 2));
}

function determineRightPoint(currPosition, prevPosition)
{
	deltaX = currPosition.x - prevPosition.x;
	deltaZ = currPosition.z - prevPosition.z;

	theta = Math.atan2(deltaX, deltaZ);

	rightPoint = new SFVec3f(currPosition.x - Math.cos(theta),
	                         currPosition.y,
	                         currPosition.z + Math.sin(theta) * (beamWidth / 2));
}

function alwaysPrint(string)
{
	Browser.print ('[BathymetryGeneratorPrototype] ' + string + '\n');
}

function tracePrint(string)
{
	if (traceEnabled)
		Browser.print ('[BathymetryGeneratorPrototype] ' + string + '\n');
}

            
]]>
</Script>
<ROUTE fromNode='BathymetryScriptfromField='bathyFaceCoordPointstoNode='BathymetryFaceCoordtoField='point'/>
<ROUTE fromNode='BathymetryScriptfromField='bathyCoordIndextoNode='BathymetryFaceSettoField='set_coordIndex'/>
<ROUTE fromNode='BathymetryScriptfromField='bathyFaceColorArraytoNode='BathymetryFaceColortoField='color'/>
<ROUTE fromNode='BathymetryScriptfromField='bathyColorIndextoNode='BathymetryFaceSettoField='set_colorIndex'/>
</Transform>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<!-- Example scene starts here, in case this prototype is examined. -->
<Anchor description='BathymetryGeneratorExampleparameter='"target=_blank"'
  url=' "BathymetryGeneratorExample.x3d" "https://savage.nps.edu/Savage/Tools/Animation/BathymetryGeneratorExample.x3d" "BathymetryGeneratorExample.wrl" "https://savage.nps.edu/Savage/Tools/Animation/BathymetryGeneratorExample.wrl" '>
<Shape>
<Text string='"BathymetryGeneratorPrototype" "is a prototype definition file" "" "Click this text to see" "BathymetryGeneratorExample"'>
<FontStyle justify='"MIDDLE" "MIDDLE"'/>
</Text>
<Appearance>
<Material diffuseColor='0.6 0.8 0.4'/>
</Appearance>
</Shape>
</Anchor>
</Scene>
</X3D>
<!--

Index for ProtoDeclare definition : BathymetryGenerator

Index for DEF nodes : Bathymetry, BathymetryFaceColor, BathymetryFaceCoord, BathymetryFaceSet, BathymetryScript
-->

<!-- 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)
    <Prototype name='ProtoName'> <field name='fieldName'/> </Prototype> -->

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