package Savage.CommunicationsAndSensors.Sonobuoys;

import org.web3d.x3d.jsail.Core.*;
import org.web3d.x3d.jsail.EnvironmentalEffects.*;
import org.web3d.x3d.jsail.EventUtilities.*;
import org.web3d.x3d.jsail.fields.*;
import org.web3d.x3d.jsail.Grouping.*;
import org.web3d.x3d.jsail.Interpolation.*;
import org.web3d.x3d.jsail.Navigation.*;
import org.web3d.x3d.jsail.Networking.*;
import org.web3d.x3d.jsail.Scripting.*;
import org.web3d.x3d.jsail.Time.*;

// Javadoc metadata annotations follow, see below for X3DJSAIL Java source code.
/**
 * <p> Representative tactical visualization of a DICASS sonobuoy field. </p>
 <p> Related links: Catalog page <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenarioIndex.html" target="_blank">SonobuoyFieldScenario</a>,  source <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario.java">SonobuoyFieldScenario.java</a>, <a href="https://www.web3d.org/x3d/content/examples/X3dResources.html" target="_blank">X3D Resources</a>, <a href="https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html" target="_blank">X3D Scene Authoring Hints</a>, and <a href="https://www.web3d.org/x3d/content/X3dTooltips.html" target="_blank">X3D Tooltips</a>. </p>
	<table style="color:black; border:0px solid; border-spacing:10px 0px;">
        <caption>Scene Meta Information</caption>
		<tr style="background-color:silver; border-color:silver;">
			<td style="text-align:center; padding:10px 0px;"><i>meta tags</i></td>
			<td style="text-align:left;   padding:10px 0px;">&nbsp; Document Metadata </td>
		</tr>

		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> title </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario.x3d">SonobuoyFieldScenario.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> description </i> </td>
			<td> Representative tactical visualization of a DICASS sonobuoy field. </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> creator </i> </td>
			<td> Don Brutzman </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> created </i> </td>
			<td> 31 January 2003 </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> modified </i> </td>
			<td> 2 January 2025 </td>
		</tr>
		<tr style="color:burntorange">
			<td style="text-align:right; vertical-align: text-top;"> <i> warning </i> </td>
			<td> problem with X3DOM, further debugging needed </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> coordinateSystem </i> </td>
			<td> x=East, z=North, y=Up </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> subject </i> </td>
			<td> sonobouy field </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/GridView.jpg">GridView.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SeaHawkRadioCommand.jpg">SeaHawkRadioCommand.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SeaHawkView.jpg">SeaHawkView.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SeaHawkViewPing.jpg">SeaHawkViewPing.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario-1.jpg">SonobuoyFieldScenario-1.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario-2.jpg">SonobuoyFieldScenario-2.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario-3.jpg">SonobuoyFieldScenario-3.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> Image </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/SonobuoyView.jpg">SonobuoyView.jpg</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> identifier </i> </td>
			<td> <a href="https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario.x3d" target="_blank">https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario.x3d</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> generator </i> </td>
			<td> X3D-Edit 3.3, <a href="https://www.web3d.org/x3d/tools/X3D-Edit" target="_blank">https://www.web3d.org/x3d/tools/X3D-Edit</a> </td>
		</tr>
		<tr>
			<td style="text-align:right; vertical-align: text-top;"> <i> license </i> </td>
			<td> <a href="../../../../CommunicationsAndSensors/Sonobuoys/../../license.html">../../license.html</a> </td>
		</tr>
		<tr style="background-color:silver; border-color:silver;">
			<td style="text-align:center;" colspan="2">  &nbsp; </td>
		</tr>
	</table>

	<p>
		This program uses the
		<a href="https://www.web3d.org/specifications/java/X3DJSAIL.html" target="_blank">X3D Java Scene Access Interface Library (X3DJSAIL)</a>.
		It has been produced using the 
		<a href="https://www.web3d.org/x3d/stylesheets/X3dToJava.xslt" target="_blank">X3dToJava.xslt</a>
		stylesheet
	       (<a href="https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets/X3dToJava.xslt" target="_blank">version control</a>)
                which is used to create Java source code from an original <code>.x3d</code> model.
	</p>

	* @author Don Brutzman
 */

public class SonobuoyFieldScenario
{
	/** Default constructor to create this object. */
	public SonobuoyFieldScenario ()
	{
	  initialize();
	}

	/** Create and initialize the X3D model for this object. */
	public final void initialize()
	{
            try { // catch-all
  x3dModel = new X3D().setProfile(X3D.PROFILE_IMMERSIVE).setVersion(X3D.VERSION_3_3)
  .setHead(new head()
    .addMeta(new meta().setName(meta.NAME_TITLE      ).setContent("SonobuoyFieldScenario.x3d"))
    .addMeta(new meta().setName(meta.NAME_DESCRIPTION).setContent("Representative tactical visualization of a DICASS sonobuoy field."))
    .addMeta(new meta().setName(meta.NAME_CREATOR    ).setContent("Don Brutzman"))
    .addMeta(new meta().setName(meta.NAME_CREATED    ).setContent("31 January 2003"))
    .addMeta(new meta().setName(meta.NAME_MODIFIED   ).setContent("2 January 2025"))
    .addMeta(new meta().setName(meta.NAME_WARNING    ).setContent("problem with X3DOM, further debugging needed"))
    .addMeta(new meta().setName("coordinateSystem").setContent("x=East, z=North, y=Up"))
    .addMeta(new meta().setName(meta.NAME_SUBJECT    ).setContent("sonobouy field"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("GridView.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SeaHawkRadioCommand.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SeaHawkView.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SeaHawkViewPing.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SonobuoyFieldScenario-1.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SonobuoyFieldScenario-2.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SonobuoyFieldScenario-3.jpg"))
    .addMeta(new meta().setName(meta.NAME_IMAGE      ).setContent("SonobuoyView.jpg"))
    .addMeta(new meta().setName(meta.NAME_IDENTIFIER ).setContent("https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario.x3d"))
    .addMeta(new meta().setName(meta.NAME_GENERATOR  ).setContent("X3D-Edit 3.3, https://www.web3d.org/x3d/tools/X3D-Edit"))
    .addMeta(new meta().setName(meta.NAME_LICENSE    ).setContent("../../license.html")))
  .setScene(new Scene()
    .addChild(new WorldInfo().setTitle("SonobuoyFieldScenario.x3d"))
    .addChild(new NavigationInfo().setSpeed(100).setVisibilityLimit(40000))
    .addChild(new Viewpoint("TopDown").setDescription("Looking down from above - TODO check visibilityLimit").setOrientation(1.0,0.0,0.0,-1.550799).setPosition(0.0,2000.0,10.0))
    .addChild(new Group("BackgroundEnvironment")
      .addComments(" topmost Background node is bound and active ")
      .addChild(new Background("OpenOcean").setGroundAngle(new double[] {0.05,1.309,1.570796}).setGroundColor(new MFColor(new double[] {0.0,0.0,0.0,0.0,0.2,0.4,0.05,0.25,0.6,0.1,0.2,0.4})).setSkyAngle(new double[] {0.05,0.1,1.309,1.571}).setSkyColor(new MFColor(new double[] {0.8,0.8,0.2,0.1,0.1,0.6,0.1,0.1,0.6,0.1,0.25,0.8,0.6,0.6,0.9})))
      .addChild(new Background("SandyShallowBottom").setGroundAngle(new double[] {0.05,1.52,1.56,1.570796}).setGroundColor(new MFColor(new double[] {0.2,0.2,0.0,0.3,0.3,0.0,0.5,0.5,0.3,0.1,0.3,0.4,0.0,0.2,0.4})).setSkyAngle(new double[] {0.05,0.1,1.309,1.571}).setSkyColor(new MFColor(new double[] {0.8,0.8,0.2,0.1,0.1,0.6,0.1,0.1,0.6,0.1,0.25,0.8,0.6,0.6,0.9})))
      .addChild(new Background().setGroundAngle(new double[] {1.309,1.570796}).setGroundColor(new MFColor(new double[] {0.1,0.1,0.0,0.4,0.25,0.2,0.6,0.6,0.6})).setSkyAngle(new double[] {1.309,1.571}).setSkyColor(new MFColor(new double[] {0.0,0.2,0.7,0.0,0.5,1.0,1.0,1.0,1.0}))))
    .addChild(new Group("ExternProtoDeclareReferences")
      .addChild(new ExternProtoDeclare("BeamCylinder").setName("BeamCylinder").setAppinfo("Produce wireframe or transparent beam cylinders. Typical uses include propeller/thruster water flow or line-of-sight sonar/radar/light beams. Negative range values invert base and apex at same relative location. Default: beam with apex at (0 0 0) and base of radius 1 in x-z plane at (1 0 0).").setUrl(new String[] {"../../CommunicationsAndSensors/Beam/BeamCylinderPrototype.x3d#BeamCylinder","https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Beam/BeamCylinderPrototype.x3d#BeamCylinder","../../CommunicationsAndSensors/Beam/BeamCylinderPrototype.wrl#BeamCylinder","https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Beam/BeamCylinderPrototype.wrl#BeamCylinder"})
        .addField(new field().setName("name").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Assigning a name to a BeamCylinder aids tracing"))
        .addField(new field().setName("contact").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("(communications) is transmitted signal in contact with receiver or (sensor) is a target return detected?"))
        .addField(new field().setName("range").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("distance in meters along x axis"))
        .addField(new field().setName("defaultRange").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("distance in meters used until eventIn range sent"))
        .addField(new field().setName("wireframe").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("whether wireframe beam is drawn"))
        .addField(new field().setName("solid").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("whether solid beam is drawn"))
        .addField(new field().setName("beamHeight").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("meters across vertical y axis"))
        .addField(new field().setName("beamWidth").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("meters across horizontal z axis"))
        .addField(new field().setName("contactColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("rendering color when contact=true"))
        .addField(new field().setName("noContactColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("rendering color when contact=false"))
        .addField(new field().setName("transparency").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("1 = fully transparent wireframe only")))
      .addChild(new ExternProtoDeclare("CrossHair").setName("CrossHair").setAppinfo("CrossHair prototype provides a heads-up display (HUD) crosshair at the view center, which is useful for assessing NavigationInfo lookAt point").setUrl(new String[] {"../../../Savage/Tools/HeadsUpDisplays/CrossHairPrototype.x3d#CrossHair","https://www.web3d.org/x3d/content/examples/Savage/Tools/HeadsUpDisplays/CrossHairPrototype.x3d#CrossHair","../../../Savage/Tools/HeadsUpDisplays/CrossHairPrototype.wrl#CrossHair","https://www.web3d.org/x3d/content/examples/Savage/Tools/HeadsUpDisplays/CrossHairPrototype.wrl#CrossHair"})
        .addField(new field().setName("enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("whether CrossHair prototype is enabled or not"))
        .addField(new field().setName("set_enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("control whether enabled/disabled"))
        .addField(new field().setName("markerColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("color of CrossHair marker"))
        .addField(new field().setName("scale").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("size of CrossHair in meters"))
        .addField(new field().setName("positionOffsetFromCamera").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("distance in front of HUD viewpoint")))
      .addChild(new ExternProtoDeclare("DICASS").setName("DICASS").setAppinfo("AN/SSQ-62B/C/D/E Directional Command Activated Sonobuoy System (DICASS) Sonobuoy").setUrl(new String[] {"DicassPrototype.x3d#DICASS","https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/DicassPrototype.x3d#DICASS","DicassPrototype.wrl#DICASS","https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/DicassPrototype.wrl#DICASS"})
        .addField(new field().setName("ID").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("identifier label for this buoy"))
        .addField(new field().setName("version").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("default value: AN/SSQ-62B"))
        .addField(new field().setName("initialPositionXZ").setType(field.TYPE_SFVEC2F).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("local surface coordinates X=North Z=East"))
        .addField(new field().setName("orderedPositionXZ").setType(field.TYPE_SFVEC2F).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("local surface coordinates X=North Z=East"))
        .addField(new field().setName("initialDepth").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("meters depth use negative numbers for subsurface"))
        .addField(new field().setName("orderedDepth").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("meters depth use negative numbers for subsurface"))
        .addField(new field().setName("bindViewpoint").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("trigger event to bind/unbind viewpoint"))
        .addField(new field().setName("location_changed").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("local coordinates X=North Y=altitude Z=East"))
        .addField(new field().setName("maxRange").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("maximum audible sonar detection range meters"))
        .addField(new field().setName("pingDuration").setType(field.TYPE_SFTIME).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("pingDuration corresponds to maxRange at 1500m/sec sound speed"))
        .addField(new field().setName("startPing").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("trigger event to start single ping"))
        .addField(new field().setName("startContinuousPings").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("trigger event to start continuous ping sequence"))
        .addField(new field().setName("linkText").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("Can add linkable text for further information"))
        .addField(new field().setName("linkUrl").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("url for linkable text"))
        .addField(new field().setName("linkTargetWindow").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("target window for linkable text"))
        .addField(new field().setName("soundSpeed").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("in-water sound speed m/s, default value 1500").setDocumentation("https://en.wikipedia.org/wiki/Speed_of_sound#Seawater")))
      .addChild(new ExternProtoDeclare("GridXZ").setName("GridXZ").setAppinfo("Line grid authoring tool to enable precise measurement of objects in 3D space - fixed position. Oriented along XZ plane size 20m by 20m.").setUrl(new String[] {"../../../Savage/Tools/Authoring/GridXZPrototype.x3d#GridXZ","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZPrototype.x3d#GridXZ","../../../Savage/Tools/Authoring/GridXZPrototype.wrl#GridXZ","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZPrototype.wrl#GridXZ"})
        .addField(new field().setName("description").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Purpose of this grid displayed for overall Viewpoint"))
        .addField(new field().setName("labelColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("color for descriptive labels at grid edges and corners"))
        .addField(new field().setName("scale").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("default unscaled size: 10m by 10m"))
        .addField(new field().setName("originLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
        .addField(new field().setName("WestLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("-X axis"))
        .addField(new field().setName("NorthWestLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
        .addField(new field().setName("NorthLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("-Z axis"))
        .addField(new field().setName("NorthEastLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
        .addField(new field().setName("EastLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("+X axis"))
        .addField(new field().setName("SouthEastLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
        .addField(new field().setName("SouthLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("+Z axis"))
        .addField(new field().setName("SouthWestLabel").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INPUTOUTPUT))
        .addField(new field().setName("labelsOffset").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("label location offset (in meters) to improve readability")))
      .addChild(new ExternProtoDeclare("ViewPositionOrientation").setName("ViewPositionOrientation").setAppinfo("ViewPositionOrientation provides provides console output of local position and orientation as user navigates").setUrl(new String[] {"../../Tools/Authoring/ViewPositionOrientationPrototype.x3d#ViewPositionOrientation","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/ViewPositionOrientationPrototype.x3d#ViewPositionOrientation","../../Tools/Authoring/ViewPositionOrientationPrototype.wrl#ViewPositionOrientation","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/ViewPositionOrientationPrototype.wrl#ViewPositionOrientation"})
        .addField(new field().setName("enabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("Whether or not ViewPositionOrientation sends output to console"))
        .addField(new field().setName("traceEnabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Output internal trace messages for debugging this node, intended for developer use only"))
        .addField(new field().setName("set_traceEnabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("Ability to turn output tracing on/off at runtime"))
        .addField(new field().setName("position_changed").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("Output local position"))
        .addField(new field().setName("orientation_changed").setType(field.TYPE_SFROTATION).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("Output local orientation"))
        .addField(new field().setName("outputViewpointString").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("MFString value of new Viewpoint")))
      .addChild(new ExternProtoDeclare("WaypointInterpolator").setName("WaypointInterpolator").setAppinfo("Reads waypoints and legSpeeds/legDurations/defaultSpeed to provide a customizable position/orientation interpolator.").setUrl(new String[] {"../../../Savage/Tools/Animation/WaypointInterpolatorPrototype.x3d#WaypointInterpolator","https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/WaypointInterpolatorPrototype.x3d#WaypointInterpolator","../../../Savage/Tools/Animation/WaypointInterpolatorPrototype.wrl#WaypointInterpolator","https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/WaypointInterpolatorPrototype.wrl#WaypointInterpolator"})
        .addComments(" Priority of use: legSpeeds (m/sec), legDurations (seconds), defaultSpeed (m/sec) ")
        .addComments(" interpolation fields ")
        .addComments(" display-related fields ")
        .addField(new field().setName("description").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Short description of what is animated by this WaypointInterpolator."))
        .addField(new field().setName("waypoints").setType(field.TYPE_MFVEC3F).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Waypoints being traversed with interpolation of intermediate positions and orientations."))
        .addField(new field().setName("add_waypoint").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("Add another single waypoint to array of waypoints recalculate interpolator values."))
        .addField(new field().setName("set_waypoints").setType(field.TYPE_MFVEC3F).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("Replace all waypoints recalculate interpolator values."))
        .addField(new field().setName("pitchUpDownForVerticalWaypoints").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Whether to pitch child geometry (such as a vehicle) up or down to match vertical slope"))
        .addField(new field().setName("legSpeeds").setType(field.TYPE_MFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Units m/sec. If used, array lengths for legSpeeds and legDurations must be one less than number of waypoints."))
        .addField(new field().setName("legDurations").setType(field.TYPE_MFTIME).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Units in seconds. If used, array lengths for legSpeeds and legDurations must be one less than number of waypoints."))
        .addField(new field().setName("defaultSpeed").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Units m/sec."))
        .addField(new field().setName("turningRate").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("turningRate (degrees/second) also determines standoff distance prior to waypoint where turn commences. If 0 turns are instantaneous."))
        .addField(new field().setName("totalDuration").setType(field.TYPE_SFTIME).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("Output calculation summing all leg durations, useful for setting TimeSensor cycleInterval. Units in seconds."))
        .addField(new field().setName("set_fraction").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTONLY).setAppinfo("exposed PositionInterpolator and OrientationInterpolator setting"))
        .addField(new field().setName("position_changed").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("exposed PositionInterpolator setting"))
        .addField(new field().setName("orientation_changed").setType(field.TYPE_SFROTATION).setAccessType(field.ACCESSTYPE_OUTPUTONLY).setAppinfo("exposed OrientationInterpolator setting"))
        .addField(new field().setName("lineColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("default color for non-active line segments"))
        .addField(new field().setName("highlightSegmentColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("active segment highlight color"))
        .addField(new field().setName("transparency").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("1.0 is completely transparent, 0.0 is completely opaque."))
        .addField(new field().setName("labelDisplayMode").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("allowed values: none; waypoints (produce labels at each waypoint); or interpolation (produce single moving label at interpolator time course speed location)"))
        .addField(new field().setName("heightLabel").setType(field.TYPE_SFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("allowed values: altitude depth (negate Y value) none"))
        .addField(new field().setName("labelOffset").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("heightLabel relative location"))
        .addField(new field().setName("labelFontSize").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("heightLabel text size"))
        .addField(new field().setName("labelColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("heightLabel text color"))
        .addField(new field().setName("traceEnabled").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("enable console output to trace script computations and prototype progress"))
        .addField(new field().setName("outputInitializationComputations").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setAppinfo("Output the number of waypoints totalDistance and totalDuration to console upon initialization"))
        .addField(new field().setName("verticalDropLineColor").setType(field.TYPE_SFCOLOR).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("default color for vertical drop-line segments"))
        .addField(new field().setName("verticalDropLineTransparency").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_INPUTOUTPUT).setAppinfo("1.0 is completely transparent, 0.0 is completely opaque."))))
    .addChild(new ProtoInstance("GridXZ").setContainerField("children")
      .addFieldValue(new fieldValue().setName("description").setValue("Sonobuoy Field Scenario"))
      .addFieldValue(new fieldValue().setName("labelColor").setValue(new SFColor(0.8,0.8,1.0)))
      .addFieldValue(new fieldValue().setName("scale").setValue(new SFVec3f(1000.0,1000.0,1000.0)))
      .addFieldValue(new fieldValue().setName("originLabel").setValue(new String[] {"origin"}))
      .addFieldValue(new fieldValue().setName("WestLabel").setValue(new String[] {"West","-Z"}))
      .addFieldValue(new fieldValue().setName("NorthWestLabel").setValue(new String[] {"10000 0 -10000"}))
      .addFieldValue(new fieldValue().setName("NorthLabel").setValue(new String[] {"North","+X"}))
      .addFieldValue(new fieldValue().setName("NorthEastLabel").setValue(new String[] {"10000 0 10000"}))
      .addFieldValue(new fieldValue().setName("EastLabel").setValue(new String[] {"East","+Z"}))
      .addFieldValue(new fieldValue().setName("SouthEastLabel").setValue(new String[] {"-10000 0 10000"}))
      .addFieldValue(new fieldValue().setName("SouthLabel").setValue(new String[] {"South","-X"}))
      .addFieldValue(new fieldValue().setName("SouthWestLabel").setValue(new String[] {"-10000 0 -10000"})))
    .addChild(new Switch("AuthoringAssist").setWhichChoice(0)
      .addChild(new Group()
        .addChild(new Transform().setScale(10.0,10.0,10.0)
          .addChild(new Inline("CoordinateAxes").setUrl(new String[] {"../../../Savage/Tools/Authoring/CoordinateAxes.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.x3d","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/CoordinateAxes.x3d","../../../Savage/Tools/Authoring/CoordinateAxes.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.wrl","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/CoordinateAxes.wrl"})))
        .addChild(new ProtoInstance("ViewPositionOrientation", "ConsoleOutputViewPositionOrientation").setContainerField("children")
          .addFieldValue(new fieldValue().setName("enabled").setValue(false)))
        .addChild(new ProtoInstance("CrossHair", "CrossHairInstance").setContainerField("children")
          .addFieldValue(new fieldValue().setName("enabled").setValue(true))
          .addFieldValue(new fieldValue().setName("markerColor").setValue(new SFColor(1.0,0.5,0.0)))
          .addFieldValue(new fieldValue().setName("scale").setValue(new SFVec3f(1.0,1.0,1.0)))
          .addFieldValue(new fieldValue().setName("positionOffsetFromCamera").setValue(new SFVec3f(0.0,0.0,-6.0)))))
      .addChild(new Transform("Grid10kmBy10km").setScale(1000.0,1000.0,1000.0)
        .addChild(new Inline().setUrl(new String[] {"../../../Savage/Tools/Authoring/GridXZ_20x20Fixed.x3d","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZ_20x20Fixed.x3d","../../../Savage/Tools/Authoring/GridXZ_20x20Fixed.wrl","https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZ_20x20Fixed.wrl"}))))
    .addChild(new Group("HelicopterGroup")
      .addChild(new Transform("SeahawkHelicopterTransform")
        .addChild(new Inline().setUrl(new String[] {"../../AircraftHelicopters/SH60-Seahawk-UnitedStates/SH60Seahawk.x3d","https://www.web3d.org/x3d/content/examples/Savage/AircraftHelicopters/SH60-Seahawk-UnitedStates/SH60Seahawk.x3d","../../AircraftHelicopters/SH60-Seahawk-UnitedStates/SH60Seahawk.wrl","https://www.web3d.org/x3d/content/examples/Savage/AircraftHelicopters/SH60-Seahawk-UnitedStates/SH60Seahawk.wrl"})))
      .addChild(new TimeSensor("HelicopterOrbitClock").setCycleInterval(211.7).setLoop(true))
      .addChild(new ProtoInstance("WaypointInterpolator", "HelicopterOrbitTrack").setContainerField("children")
        .addComments(" Priority of use: legSpeeds (m/sec), legDurations (seconds), defaultSpeed (m/sec) ")
        .addFieldValue(new fieldValue().setName("description").setValue("SH-60B Seahawk orbit"))
        .addFieldValue(new fieldValue().setName("waypoints").setValue(new MFVec3f(new MFVec3f(new double[] {0.0,100.0,0.0,-1000.0,100.0,1000.0,-1000.0,500.0,5000.0,0.0,500.0,6000.0,5000.0,500.0,6000.0,6000.0,100.0,5000.0,6000.0,100.0,0.0,5000.0,100.0,-1000.0,1000.0,100.0,-1000.0,0.0,100.0,0.0}))))
        .addFieldValue(new fieldValue().setName("pitchUpDownForVerticalWaypoints").setValue(false))
        .addFieldValue(new fieldValue().setName("defaultSpeed").setValue(50))
        .addFieldValue(new fieldValue().setName("turningRate").setValue(5))
        .addFieldValue(new fieldValue().setName("lineColor").setValue(new SFColor(0.5,0.5,0.0)))
        .addFieldValue(new fieldValue().setName("highlightSegmentColor").setValue(new SFColor(1.0,1.0,0.0)))
        .addFieldValue(new fieldValue().setName("transparency").setValue(0))
        .addFieldValue(new fieldValue().setName("labelDisplayMode").setValue("interpolation"))
        .addFieldValue(new fieldValue().setName("heightLabel").setValue("altitude"))
        .addFieldValue(new fieldValue().setName("labelOffset").setValue(new SFVec3f(0.0,3.0,0.0)))
        .addFieldValue(new fieldValue().setName("labelFontSize").setValue(0.8))
        .addFieldValue(new fieldValue().setName("labelColor").setValue(new SFColor(1.0,1.0,0.0)))
        .addFieldValue(new fieldValue().setName("traceEnabled").setValue(false)))
      .addChild(new ROUTE().setFromNode("HelicopterOrbitTrack").setFromField("totalDuration").setToNode("HelicopterOrbitClock").setToField("set_cycleInterval"))
      .addChild(new ROUTE().setFromNode("HelicopterOrbitClock").setFromField("fraction_changed").setToNode("HelicopterOrbitTrack").setToField("set_fraction"))
      .addChild(new ROUTE().setFromNode("HelicopterOrbitTrack").setFromField("position_changed").setToNode("SeahawkHelicopterTransform").setToField("set_translation"))
      .addChild(new ROUTE().setFromNode("HelicopterOrbitTrack").setFromField("orientation_changed").setToNode("SeahawkHelicopterTransform").setToField("set_rotation")))
    .addChild(new Group("SonobuoyFieldLayout")
      .addChild(new Transform("LocationBuoy1-1")
        .addChild(new ProtoInstance("DICASS", "DICASS-1-1").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 1.1"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(1000.0,1000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy1-2")
        .addChild(new ProtoInstance("DICASS", "DICASS-1-2").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 1.2"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(1000.0,2000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy1-3")
        .addChild(new ProtoInstance("DICASS", "DICASS-1-3").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 1.3"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(1000.0,3000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy1-4")
        .addChild(new ProtoInstance("DICASS", "DICASS-1-4").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 1.4"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(1000.0,4000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy2-1")
        .addChild(new ProtoInstance("DICASS", "DICASS-2-1").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 2.1"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(2000.0,1000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy2-2")
        .addChild(new ProtoInstance("DICASS", "DICASS-2-2").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 2.2"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(2000.0,2000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy2-3")
        .addChild(new ProtoInstance("DICASS", "DICASS-2-3").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 2.3"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(2000.0,3000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy2-4")
        .addChild(new ProtoInstance("DICASS", "DICASS-2-4").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 2.4"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(2000.0,4000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy3-1")
        .addChild(new ProtoInstance("DICASS", "DICASS-3-1").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 3.1"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(3000.0,1000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy3-2")
        .addChild(new ProtoInstance("DICASS", "DICASS-3-2").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 3.2"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(3000.0,2000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy3-3")
        .addChild(new ProtoInstance("DICASS", "DICASS-3-3").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 3.3"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(3000.0,3000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy3-4")
        .addChild(new ProtoInstance("DICASS", "DICASS-3-4").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 3.4"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(3000.0,4000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy4-1")
        .addChild(new ProtoInstance("DICASS", "DICASS-4-1").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 4.1"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(4000.0,1000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy4-2")
        .addChild(new ProtoInstance("DICASS", "DICASS-4-2").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 4.2"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(4000.0,2000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy4-3")
        .addChild(new ProtoInstance("DICASS", "DICASS-4-3").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 4.3"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(4000.0,3000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000))))
      .addChild(new Transform("LocationBuoy4-4")
        .addChild(new ProtoInstance("DICASS", "DICASS-4-4").setContainerField("children")
          .addFieldValue(new fieldValue().setName("ID").setValue(new String[] {"DICASS 4.4"}))
          .addFieldValue(new fieldValue().setName("initialPositionXZ").setValue(new SFVec2f(4000.0,4000.0)))
          .addFieldValue(new fieldValue().setName("initialDepth").setValue(-100))
          .addFieldValue(new fieldValue().setName("maxRange").setValue(1000)))))
    .addChild(new Group("SonobuoyCommunications")
      .addComments(" Script SonobuoyFieldScenarioScript controls animation of DICAS sonar pings and helo commands ")
      .addChild(new Script("SonobuoyFieldScenarioScript").setDirectOutput(true).setUrl(new String[] {"SonobuoyFieldScenarioScript.js","https://www.web3d.org/x3d/content/examples/Savage/CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenarioScript.js"})
        .addComments(" local Script variables ")
        .addField(new field().setName("HelicopterWaypointInterpolator").setType(field.TYPE_SFNODE).setAccessType(field.ACCESSTYPE_INITIALIZEONLY)
          .addChild(new ProtoInstance("WaypointInterpolator").setUSE("HelicopterOrbitTrack").setContainerField("children")))
        .addField(new field().setName("BuoyArray").setType(field.TYPE_MFNODE).setAccessType(field.ACCESSTYPE_INITIALIZEONLY)
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-1-1").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-1-2").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-1-3").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-1-4").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-2-1").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-2-2").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-2-3").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-2-4").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-3-1").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-3-2").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-3-3").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-3-4").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-4-1").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-4-2").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-4-3").setContainerField("children"))
          .addChild(new ProtoInstance("DICASS").setUSE("DICASS-4-4").setContainerField("children")))
        .addField(new field().setName("timeNextBouyPing").setType(field.TYPE_SFTIME).setAccessType(field.ACCESSTYPE_INPUTONLY))
        .addField(new field().setName("activeBuoyLocation").setType(field.TYPE_SFVEC3F).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
        .addField(new field().setName("buoyRange").setType(field.TYPE_SFFLOAT).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
        .addField(new field().setName("keyValueRadioCommandInterpolator").setType(field.TYPE_MFFLOAT).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
        .addField(new field().setName("beamRotation").setType(field.TYPE_SFROTATION).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
        .addField(new field().setName("sendCommand").setType(field.TYPE_SFTIME).setAccessType(field.ACCESSTYPE_OUTPUTONLY))
        .addField(new field().setName("currentBuoyNumber").setType(field.TYPE_SFINT32).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setValue(-1))
        .addField(new field().setName("ID").setType(field.TYPE_MFSTRING).setAccessType(field.ACCESSTYPE_INITIALIZEONLY))
        .addField(new field().setName("TRACE").setType(field.TYPE_SFBOOL).setAccessType(field.ACCESSTYPE_INITIALIZEONLY).setValue(true)))
      .addChild(new TimeSensor("PingBuoySequenceClock").setCycleInterval(5).setLoop(true))
      .addChild(new ROUTE().setFromNode("PingBuoySequenceClock").setFromField("cycleTime").setToNode("SonobuoyFieldScenarioScript").setToField("timeNextBouyPing"))
      .addChild(new Transform("RadioBeamOrientation")
        .addChild(new ROUTE().setFromNode("HelicopterOrbitTrack").setFromField("position_changed").setToNode("RadioBeamOrientation").setToField("set_translation"))
        .addChild(new ROUTE().setFromNode("SonobuoyFieldScenarioScript").setFromField("beamRotation").setToNode("RadioBeamOrientation").setToField("set_rotation"))
        .addChild(new ProtoInstance("BeamCylinder", "HeloToSonobuoyCommunication").setContainerField("children")
          .addFieldValue(new fieldValue().setName("name").setValue("HeloToBuoyComms"))
          .addFieldValue(new fieldValue().setName("defaultRange").setValue(0.001))
          .addFieldValue(new fieldValue().setName("beamHeight").setValue(0.25))
          .addFieldValue(new fieldValue().setName("beamWidth").setValue(0.25))
          .addFieldValue(new fieldValue().setName("transparency").setValue(0.5))
          .addFieldValue(new fieldValue().setName("wireframe").setValue(true))
          .addFieldValue(new fieldValue().setName("solid").setValue(true))
          .addFieldValue(new fieldValue().setName("contactColor").setValue(new SFColor(0.4,0.4,0.0)))
          .addFieldValue(new fieldValue().setName("noContactColor").setValue(new SFColor(1.0,0.6,0.1))))
        .addComments(" animate radio communication ")
        .addChild(new TimeSensor("RadioCommandTimer").setCycleInterval(0.5))
        .addChild(new ROUTE().setFromNode("SonobuoyFieldScenarioScript").setFromField("sendCommand").setToNode("RadioCommandTimer").setToField("startTime"))
        .addComments(" helo command to buoy (ramp and hold), blank during sonar operation ")
        .addChild(new ScalarInterpolator("RadioBeamInterpolator").setKey(new double[] {0.0,0.5,0.75,0.75,1.0}).setKeyValue(new double[] {0.0,-1000.0,-1000.0,0.0,0.0}))
        .addChild(new ROUTE().setFromNode("SonobuoyFieldScenarioScript").setFromField("keyValueRadioCommandInterpolator").setToNode("RadioBeamInterpolator").setToField("keyValue"))
        .addChild(new ROUTE().setFromNode("RadioCommandTimer").setFromField("fraction_changed").setToNode("RadioBeamInterpolator").setToField("set_fraction"))
        .addChild(new ROUTE().setFromNode("RadioBeamInterpolator").setFromField("value_changed").setToNode("HeloToSonobuoyCommunication").setToField("range"))
        .addComments(" change color to indicate command/response sequence ")
        .addChild(new BooleanSequencer("RadioContactSequencer").setKey(new double[] {0.0,0.5,1.0}).setKeyValue(new boolean[] {false,true,false}))
        .addChild(new ROUTE().setFromNode("RadioCommandTimer").setFromField("fraction_changed").setToNode("RadioContactSequencer").setToField("set_fraction"))
        .addChild(new ROUTE().setFromNode("RadioContactSequencer").setFromField("value_changed").setToNode("HeloToSonobuoyCommunication").setToField("contact")))));
            }
            catch (Exception ex)
            {       
                System.err.println ("*** Further hints on X3DJSAIL errors and exceptions at");
                System.err.println ("*** https://www.web3d.org/specifications/java/X3DJSAIL.html");
                throw (ex);
            }
	}
	// end of initialize() method

	/** The initialized model object, created within initialize() method. */
	private X3D x3dModel;

	/** 
	 * Provide a 
	 * <a href="https://dzone.com/articles/java-copy-shallow-vs-deep-in-which-you-will-swim" target="_blank">shallow copy</a>
	 * of the X3D model.
	 * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html">X3D</a>
	 * @return SonobuoyFieldScenario model
	 */
	public X3D getX3dModel()
	{	  
		return x3dModel;
	}
	   
    /** 
     * Default main() method provided for test purposes, uses CommandLine to set global ConfigurationProperties for this object.
     * @param args array of input parameters, provided as arguments
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html#handleArguments-java.lang.String:A-">X3D.handleArguments(args)</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/Core/X3D.html#validationReport--">X3D.validationReport()</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/CommandLine.html">CommandLine</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/CommandLine.html#USAGE">CommandLine.USAGE</a>
     * @see <a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/ConfigurationProperties.html">ConfigurationProperties</a>
     */
    public static void main(String args[])
    {
        System.out.println("Build this X3D model, showing validation diagnostics...");
        X3D thisExampleX3dModel = new SonobuoyFieldScenario().getX3dModel();
//      System.out.println("X3D model construction complete.");
	
        // next handle command line arguments
        boolean hasArguments = (args != null) && (args.length > 0);
        boolean validate = true; // default
        boolean argumentsLoadNewModel = false;
        String  fileName = new String();

        if (args != null)
        {
                for (String arg : args)
                {
                        if (arg.toLowerCase().startsWith("-v") || arg.toLowerCase().contains("validate"))
                        {
                                validate = true; // making sure
                        }
                        if (arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_X3D) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_CLASSICVRML) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_X3DB) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_VRML97) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_EXI) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_GZIP) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_ZIP) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_HTML) ||
                                arg.toLowerCase().endsWith(X3D.FILE_EXTENSION_XHTML))
                        {
                                argumentsLoadNewModel = true;
                                fileName = arg;
                        }
                }
        }
        if      (argumentsLoadNewModel)
                System.out.println("WARNING: \"Savage.CommunicationsAndSensors.Sonobuoys.SonobuoyFieldScenario\" model invocation is attempting to load file \"" + fileName + "\" instead of simply validating itself... file loading ignored.");
        else if (hasArguments) // if no arguments provided, this method produces usage warning
                thisExampleX3dModel.handleArguments(args);
	
        if (validate)
        {
            //  System.out.println("--- TODO fix duplicated outputs ---"); // omit when duplicated outputs problem is solved/refactored
		String validationResults = thisExampleX3dModel.validationReport();
            //  System.out.println("-----------------------------------"); // omit when duplicated outputs problem is solved/refactored
                System.out.print("Savage.CommunicationsAndSensors.Sonobuoys.SonobuoyFieldScenario self-validation test confirmation: ");
                if (!validationResults.equals("success"))
                    System.out.println();
                System.out.println(validationResults.trim());

                // experimental: test X3DJSAIL output files
                // CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario_JavaExport.* file validation is checked when building X3D Example Archives
                String filenameX3D  = "CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario_JavaExport.x3d"; 
                String filenameX3DV = "CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario_JavaExport.x3dv"; 
                String filenameJSON = "CommunicationsAndSensors/Sonobuoys/SonobuoyFieldScenario_JavaExport.json";
                thisExampleX3dModel.toFileX3D        (filenameX3D);
                thisExampleX3dModel.toFileClassicVRML(filenameX3DV);
// TODO         thisExampleX3dModel.toFileJSON       (filenameJSON);
        }
    }
}
