<?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 content='BathymetryGeneratorPrototype.x3d' name='title'/>
    <meta content='This prototype generates bathymetry based on the input data using IndexedFaceSet.' name='description'/>
    <meta content='Don Brutzman, Jane Wu' name='creator'/>
    <meta content='8 February 2002' name='created'/>
    <meta content='28 November 2019' name='modified'/>
    <meta content='bathymetry' name='subject'/>
    <meta content='https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/BathymetryGeneratorPrototype.x3d' name='identifier'/>
    <meta content='X3D-Edit 3.2, https://www.web3d.org/x3d/tools/X3D-Edit' name='generator'/>
    <meta content='../../license.html' name='license'/>
  </head>
  <Scene>
    <WorldInfo title='BathymetryGeneratorPrototype.x3d'/>
    <ProtoDeclare appinfo='BathymetryGenerator creates bottom topography' name='BathymetryGenerator'>
      <ProtoInterface>
        <field accessType='initializeOnly' name='positionArray' type='MFVec3f' value='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 70'/>
        <field accessType='initializeOnly' name='colorSchemeDepthRangeArray' type='MFVec2f' value='0 -10 -10 -20 -20 -30 -30 -40 -40 -50 -50 -60 -60 -70 -70 -999999'/>
        <field accessType='initializeOnly' name='colorSchemeColorArray' type='MFColor' value='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 1'/>
        <field accessType='initializeOnly' name='beamWidth' type='SFFloat' value='2'/>
        <field accessType='initializeOnly' name='traceEnabled' type='SFBool' value='false'/>
      </ProtoInterface>
      <ProtoBody>
        <Group>
          <Transform DEF='Bathymetry'>
            <Shape>
              <IndexedFaceSet DEF='BathymetryFaceSet' ccw='false'>
                <Color DEF='BathymetryFaceColor'/>
                <Coordinate DEF='BathymetryFaceCoord'/>
              </IndexedFaceSet>
            </Shape>
            <Script DEF='BathymetryScript'>
              <field accessType='initializeOnly' name='positionArray' type='MFVec3f'/>
              <field accessType='initializeOnly' name='depthRangeArray' type='MFVec2f'/>
              <field accessType='initializeOnly' name='depthColorArray' type='MFColor'/>
              <field accessType='initializeOnly' name='beamWidth' type='SFFloat'/>
              <field accessType='outputOnly' name='bathyFaceCoordPoints' type='MFVec3f'/>
              <field accessType='outputOnly' name='bathyCoordIndex' type='MFInt32'/>
              <field accessType='outputOnly' name='bathyFaceColorArray' type='MFColor'/>
              <field accessType='outputOnly' name='bathyColorIndex' type='MFInt32'/>
              <field accessType='initializeOnly' name='traceEnabled' type='SFBool'/>
              <field accessType='initializeOnly' appinfo='local variable' name='dataValid' type='SFBool' value='false'/>
              <field accessType='initializeOnly' appinfo='local variable' name='color' type='SFColor' value='1 1 1'/>
              <field accessType='initializeOnly' appinfo='local variable' name='leftPoint' type='SFVec3f' value='0 0 0'/>
              <field accessType='initializeOnly' appinfo='local variable' name='rightPoint' type='SFVec3f' value='0 0 0'/>
              <IS>
                <connect nodeField='positionArray' protoField='positionArray'/>
                <connect nodeField='depthRangeArray' protoField='colorSchemeDepthRangeArray'/>
                <connect nodeField='depthColorArray' protoField='colorSchemeColorArray'/>
                <connect nodeField='beamWidth' protoField='beamWidth'/>
                <connect nodeField='traceEnabled' protoField='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.println ('[BathymetryGeneratorPrototype] ' + string);
}

function tracePrint(string)
{
	if (traceEnabled)
		Browser.println ('[BathymetryGeneratorPrototype] ' + string);
}
]]>
            </Script>
            <ROUTE fromField='bathyFaceCoordPoints' fromNode='BathymetryScript' toField='point' toNode='BathymetryFaceCoord'/>
            <ROUTE fromField='bathyCoordIndex' fromNode='BathymetryScript' toField='set_coordIndex' toNode='BathymetryFaceSet'/>
            <ROUTE fromField='bathyFaceColorArray' fromNode='BathymetryScript' toField='color' toNode='BathymetryFaceColor'/>
            <ROUTE fromField='bathyColorIndex' fromNode='BathymetryScript' toField='set_colorIndex' toNode='BathymetryFaceSet'/>
          </Transform>
        </Group>
      </ProtoBody>
    </ProtoDeclare>
    <!-- ==================== -->
    <!-- Example scene starts here, in case this prototype is examined. -->
    <Anchor description='BathymetryGeneratorExample' parameter='"target=_blank"' url='"BathymetryGeneratorExample.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/BathymetryGeneratorExample.x3d" "BathymetryGeneratorExample.wrl" "https://www.web3d.org/x3d/content/examples/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>