<?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 name='titlecontent='PointTrackGeneratorPrototype5.x3d'/>
<meta name='descriptioncontent='Generator of randomized colored points using script nodes. The data arrays for coordinates and colors are generated in realtime or everyting is displayed, depending on your choice. This is still experimental, it is very difficult to get good contrast even despite trying different backgrounds.'/>
<meta name='creatorcontent='Frederic Roussille'/>
<meta name='createdcontent='14 May 2001'/>
<meta name='modifiedcontent='28 November 2019'/>
<meta name=' warning content=' some debugging remains necessary. '/>
<meta name='identifiercontent=' https://savage.nps.edu/Savage/Tools/Animation/PointTrackGeneratorPrototype5.x3d '/>
<meta name='generatorcontent='X3D-Edit 3.2, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent=' ../../license.html'/>
</head>
<!-- -->
<Scene>
<WorldInfo title='PointTrackGeneratorPrototype5.x3d'/>
<ProtoDeclare name='PointTrackGeneratorappinfo='Sequentially display track points. Both points and times are initially provided as a full set of values.'>
<ProtoInterface>
<field name='pointPositionsArraytype='MFVec3fvalue='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'
 appinfo='Point coordinates in meters referenced to local coordinate system origin.'/>

<field name='pointTimesArraytype='MFTimevalue='1 3 6 8 10 12 14 15 17 18 23 28 35 37 39 43 45 47 48 53 58 60 61 65 70accessType='initializeOnly'
 appinfo='Point times in seconds for local exercise clock. (Each time is clock time in seconds not in interval durations.)'/>

<field name='totalDurationtype='SFTimeaccessType='outputOnly'
 appinfo='totalDuration is derived from the pointTimesArray and used to set cycleInterval on a controlling TimeSensor clock outside the PointTrackGenerator ProtoInstance.'/>

<field name='displaypointsModetype='SFInt32value='2accessType='inputOutput'
 appinfo='displaypointsMode settings: -1=none 0=some (active interval) 1=all 2=IndexedLineSet.'/>

<field name='durationActivePointstype='SFTimeaccessType='inputOnly'
 appinfo='durationActivePoints is in seconds default initialization value is totalDuration.'/>

<field name='timeLatestActivePointtype='SFTimeaccessType='inputOnly'
 appinfo='timeLatestActivePoint is in seconds default initialization value is final point time.'/>

<field name='getStartTimetype='SFTimeaccessType='outputOnly'/>
<field name='getStopTimetype='SFTimeaccessType='outputOnly'/>
<field name='mappedColorPointCreatortype='SFTimeaccessType='inputOnly'/>
<field name='auvNametype='MFStringvalue=' "../../Robots/UnmannedUnderwaterVehicles/AriesExample.wrl"
"https://savage.nps.edu/Savage/Robots/UnmannedUnderwaterVehicles/AriesExample.wrl" ' accessType='inputOutput'/>
</ProtoInterface>
<ProtoBody>
<Group>
<Switch DEF='PointsGeometrySwitchwhichChoice='-1'>
<IS>
<connect nodeField='whichChoiceprotoField='displaypointsMode'/>
</IS>
<Shape DEF='displaypointsMode_0'>
<PointSet DEF='ActivePointSet'>
<!-- ROUTE information for ActivePointSetCoordinateNode node:  [from point_changed to Debugger.set_debugcoordinate ] -->
<Coordinate DEF='ActivePointSetCoordinateNode'/>
<!-- ROUTE information for ActivePointSetColorNode node:  [from color_changed to Debugger.set_debugcolor ] -->
<Color DEF='ActivePointSetColorNode'/>
</PointSet>
</Shape>
<Shape DEF='displaypointsMode_1'>
<PointSet DEF='CompletePointSet'>
<!-- ROUTE information for CompletePointSetCoordinateNode node:  [from point_changed to Debugger.set_debugcoordinateC ] -->
<Coordinate DEF='CompletePointSetCoordinateNode'/>
<!-- ROUTE information for CompletePointSetColorNode node:  [from color_changed to Debugger.set_debugcolorC ] -->
<Color DEF='CompletePointSetColorNode'/>
</PointSet>
</Shape>
<Group DEF='displaypointsMode_2'>
<Shape>
<!-- ROUTE information for ActiveLineSet node:  [from DrawPointScript.coordIndex_changed to set_coordIndex ] -->
<IndexedLineSet DEF='ActiveLineSet'>
<!-- ROUTE information for ActiveLineSetCoordinateNode node:  [from point to Debugger.set_debugcoord ] -->
<Coordinate DEF='ActiveLineSetCoordinateNode'/>
<Color DEF='ActiveLineSetColorNode'/>
</IndexedLineSet>
</Shape>
<Transform DEF='auvTransformscale='4 4 4'>
<Inline DEF='AuvNameInline'>
<IS>
<connect nodeField='urlprotoField='auvName'/>
</IS>
</Inline>
</Transform>
</Group>
</Switch>
<!-- work on color mapping later... -->
<ColorInterpolator DEF='ColorMapInterpolatorkey='0 0.12 0.48 0.7 1keyValue='1 1 1 1 0 0 0 1 0 0 0 1 0 0 0'/>
<!-- ROUTE information for ColorMapInterpolatorForCompletePointsSet node:  [from value_changed to DrawPointScript.set_completePointSetColorArray ] -->
<ColorInterpolator DEF='ColorMapInterpolatorForCompletePointsSetkey='0 0.12 0.48 0.7 1keyValue='1 1 1 1 0 0 0 1 0 0 0 1 0 0 0'/>
<!-- ROUTE information for CompletePointSetTimeSensor node:  [from cycleTime to DrawPointScript.completePointSetValue_changed ] -->
<TimeSensor DEF='CompletePointSetTimeSensorcycleInterval='0.01loop='true'/>
<!-- ROUTE information for DrawPointScript node:  [from CompletePointSetTimeSensor.cycleTime to completePointSetValue_changed ] [from ColorMapInterpolatorForCompletePointsSet.value_changed to set_completePointSetColorArray ] [from coordIndex_changed to ActiveLineSet.set_coordIndex ] [from coordIndex_changed to Debugger.set_debugcoordIndex_changed ] -->
<Script DEF='DrawPointScriptdirectOutput='true'>
<!-- For proper operation, first insert newPoint and then newPointTimeStamp -->
<field name='pointPositionsArraytype='MFVec3faccessType='initializeOnly'>
<!-- no default initialization value -->
</field>
<field name='pointTimesArraytype='MFTimeaccessType='initializeOnly'>
<!-- no default initialization value -->
</field>
<field name='newPointPositionsArraytype='MFVec3faccessType='initializeOnly'>
<!-- no default initialization value -->
</field>
<field name='newPointTimesArraytype='MFTimeaccessType='initializeOnly'>
<!-- no default initialization value -->
</field>
<field name='lineIndextype='SFInt32value='1accessType='initializeOnly'/>
<field name='mappedColorPointCreatortype='SFTimeaccessType='inputOnly'/>
<field name='indextype='SFInt32value='0accessType='initializeOnly'/>
<field name='completeIndextype='SFInt32value='0accessType='initializeOnly'/>
<field name='ConditionCompletetype='SFBoolaccessType='outputOnly'/>
<field name='ActivePointSetCoordinateNodetype='SFNodeaccessType='initializeOnly'>
<Coordinate USE='ActivePointSetCoordinateNode'/>
</field>
<field name='ActivePointSetColorNodetype='SFNodeaccessType='initializeOnly'>
<Color USE='ActivePointSetColorNode'/>
</field>
<field name='CompletePointSetCoordinateNodetype='SFNodeaccessType='initializeOnly'>
<Coordinate USE='CompletePointSetCoordinateNode'/>
</field>
<field name='CompletePointSetColorNodetype='SFNodeaccessType='initializeOnly'>
<Color USE='CompletePointSetColorNode'/>
</field>
<field name='ColorMapInterpolatortype='SFNodeaccessType='initializeOnly'>
<ColorInterpolator USE='ColorMapInterpolator'/>
</field>
<field name='ColorMapInterpolatorForCompletePointsSettype='SFNodeaccessType='initializeOnly'>
<ColorInterpolator USE='ColorMapInterpolatorForCompletePointsSet'/>
</field>
<field name='ActiveLineSetCoordinateNodetype='SFNodeaccessType='initializeOnly'>
<Coordinate USE='ActiveLineSetCoordinateNode'/>
</field>
<field name='ActiveLineSetColorNodetype='SFNodeaccessType='initializeOnly'>
<Color USE='ActiveLineSetColorNode'/>
</field>
<field name='auvTransformtype='SFNodeaccessType='initializeOnly'>
<Transform USE='auvTransform'/>
</field>
<field name='totalDurationtype='SFTimeaccessType='outputOnly'/>
<field name='getStartTimetype='SFTimeaccessType='outputOnly'/>
<field name='getStopTimetype='SFTimeaccessType='outputOnly'/>
<field name='coordIndex_changedtype='MFInt32accessType='outputOnly'/>
<field name='durationActivePointstype='SFTimeaccessType='inputOnly'/>
<field name='timeLatestActivePointtype='SFTimeaccessType='inputOnly'/>
<field name='completePointSetValue_changedtype='SFTimeaccessType='inputOnly'/>
<field name='set_completePointSetColorArraytype='SFColoraccessType='inputOnly'/>
<IS>
<connect nodeField='pointPositionsArrayprotoField='pointPositionsArray'/>
<connect nodeField='pointTimesArrayprotoField='pointTimesArray'/>
<connect nodeField='totalDurationprotoField='totalDuration'/>
<connect nodeField='durationActivePointsprotoField='durationActivePoints'/>
<connect nodeField='timeLatestActivePointprotoField='timeLatestActivePoint'/>
<connect nodeField='getStartTimeprotoField='getStartTime'/>
<connect nodeField='getStopTimeprotoField='getStopTime'/>
<connect nodeField='mappedColorPointCreatorprotoField='mappedColorPointCreator'/>
</IS>
<![CDATA[
            
ecmascript:

function initialize() {
 totalDuration = pointTimesArray[pointTimesArray.length-1];
 var today = new Date();
 getStartTime = Math.round(today.getTime() / 1000);
 getStopTime = getStartTime + totalDuration;
 var m = 1;

 //default values for durationActivePoint and timeLatestActivePoint
 durationActivePoint = totalDuration;
 timeLatestActivePoint = pointTimesArray[pointTimesArray.length-1];

 if(timeLatestActivePoint == durationActivePoint) {
  newPointTimesArray = pointTimesArray;
  newPointPositionsArray = pointPositionsArray;
  Browser.print ('newPointTimesArray = ' + newPointTimesArray);
 }
 if(timeLatestActivePoint > durationActivePoint) {
  var firstTime = latestTime = k = 0;
  while((timeLatestActivePoint - durationActivePoint) != pointTimesArray[firstTime]) {
   firstTime++;
  }
  while(timeLatestActivePoint != pointTimesArray[latestTime]) {
   latestTime++;
  }
  for(var j = firstTime ; j <= latestTime ; j++) {
   newPointTimesArray[k] = pointTimesArray[j] - pointTimesArray[firstTime] + 1;
   newPointPositionsArray[k] = pointPositionsArray[j];
   k++;
  }
  Browser.print ('newPointTimesArray = ' + newPointTimesArray);
 }
 if(timeLatestActivePoint < durationActivePoint) {
  Browser.print ('Fatal error : timeLatestActivePoint < durationActivePoint !');
 }
 ConditionComplete = false;
}


function completePointSetValue_changed() {
 if(ConditionComplete == false && completeIndex <= (pointPositionsArray.length-1)) {
  ColorMapInterpolatorForCompletePointsSet.set_fraction = - pointPositionsArray[completeIndex][1] / 100;
  Browser.print ('ColorMapInterpolatorForCompletePointsSet.set_fraction['+completeIndex+ '] = ' + ColorMapInterpolatorForCompletePointsSet.set_fraction);
  //need to initialize ColorMapInterpolator.set_fraction with the first point color otherwise the value is shifted
  ConditionComplete = true;
 }
}

function set_completePointSetColorArray(Value) {
  CompletePointSetColorNode.color[completeIndex] = Value;
  CompletePointSetCoordinateNode.point[completeIndex] = pointPositionsArray[completeIndex];
  completeIndex++;
  ConditionComplete = false;
}


function mappedColorPointCreator(fractionValue) {

  ColorMapInterpolator.set_fraction = - newPointPositionsArray[index][1] / 100;
  //need to initialize ColorMapInterpolator.set_fraction with the first point color otherwise the value is shifted

  if(Math.floor(fractionValue) == (newPointTimesArray[index] + getStartTime)) {
   ActivePointSetColorNode.color[index] = ColorMapInterpolator.value_changed;
   ActivePointSetCoordinateNode.point[index] = newPointPositionsArray[index];
   auvTransform.translation = newPointPositionsArray[index];
   if(index <= 1) {
	   ActiveLineSetCoordinateNode.point[index] =  newPointPositionsArray[index];
       coordIndex_changed[index] = index;
	   ActiveLineSetColorNode.color[index][0] = 1;
	   ActiveLineSetColorNode.color[index][1] = 1;
	   ActiveLineSetColorNode.color[index][2] = 1;
	   auvTransform.translation = newPointPositionsArray[index];
	   if(index == 1) {
		   	 ActiveLineSetCoordinateNode.point[index] =  newPointPositionsArray[index];
             coordIndex_changed[index] = index;
             coordIndex_changed[index+1] = -1;
	         ActiveLineSetColorNode.color[index-1][0] = 1;
	         ActiveLineSetColorNode.color[index-1][1] = 0;
	         ActiveLineSetColorNode.color[index-1][2] = 0;
	         ActiveLineSetColorNode.color[index][0] = 1;
	         ActiveLineSetColorNode.color[index][1] = 1;
	         ActiveLineSetColorNode.color[index][2] = 1;
	   }
   }
   else {
	   ActiveLineSetCoordinateNode.point[index] =  newPointPositionsArray[index];
	   coordIndex_changed[index+lineIndex] = coordIndex_changed[index+lineIndex-2];
	   coordIndex_changed[index+lineIndex+1] = index;
	   coordIndex_changed[index+lineIndex+2] = -1;
	   ActiveLineSetColorNode.color[index-1][0] = 1;
	   ActiveLineSetColorNode.color[index-1][1] = 0;
	   ActiveLineSetColorNode.color[index-1][2] = 0;
	   ActiveLineSetColorNode.color[index][0] = 1;
	   ActiveLineSetColorNode.color[index][1] = 1;
	   ActiveLineSetColorNode.color[index][2] = 1;
	   lineIndex += 2;

   }
   //print ('ActivePointSetCoordinateNode.point[' +index + '][0]=' + ActivePointSetCoordinateNode.point[index][0]);
   //print ('ActivePointSetCoordinateNode.point[' +index + '][1]=' + ActivePointSetCoordinateNode.point[index][1]);
   //print ('ActivePointSetCoordinateNode.point[' +index + '][2]=' + ActivePointSetCoordinateNode.point[index][2]);
   index ++;
 }

}

          
]]>
</Script>
<!-- ROUTE information for Debugger node:  [from ActivePointSetCoordinateNode.point_changed to set_debugcoordinate ] [from ActivePointSetColorNode.color_changed to set_debugcolor ] [from ActiveLineSetCoordinateNode.point to set_debugcoord ] [from DrawPointScript.coordIndex_changed to set_debugcoordIndex_changed ] [from CompletePointSetCoordinateNode.point_changed to set_debugcoordinateC ] [from CompletePointSetColorNode.color_changed to set_debugcolorC ] -->
<Script DEF='Debugger'>
<field name='set_debugcoordinatetype='MFVec3faccessType='inputOnly'/>
<field name='set_debugcolortype='MFColoraccessType='inputOnly'/>
<field name='set_debugcoordinateCtype='MFVec3faccessType='inputOnly'/>
<field name='set_debugcolorCtype='MFColoraccessType='inputOnly'/>
<field name='set_debugcoordtype='MFVec3faccessType='inputOnly'/>
<field name='set_debugcoordIndex_changedtype='MFInt32accessType='inputOnly'/>
<![CDATA[
            
ecmascript:

function set_debugcoordinate(Value) {
 Browser.print ('ActivePointSet : CoordinatePointArrray = ' + Value);
}

function set_debugcolor(Valeur) {
 Browser.print ('ActivePointSet : ColorPointArray = ' + Valeur);
}

function set_debugcoordinateC(Value) {
 Browser.print ('CompletePointSet : CoordinatePointArrray = ' + Value);
 Browser.print (' ');
}

function set_debugcolorC(Valeur) {
 Browser.print ('CompletePointSet : ColorPointArray = ' + Valeur);
}

function set_debugcoord(Valeur) {
 Browser.print ('ActiveLineSet : Coordinate.point = ' + Valeur);
 Browser.print (' ');
}

function set_debugcoordIndex_changed(Valeur) {
 Browser.print ('DrawPointScript : coordIndex_changed = ' + Valeur);
}

          
]]>
</Script>
</Group>
<ROUTE fromNode='CompletePointSetTimeSensorfromField='cycleTimetoNode='DrawPointScripttoField='completePointSetValue_changed'/>
<ROUTE fromNode='ColorMapInterpolatorForCompletePointsSetfromField='value_changedtoNode='DrawPointScripttoField='set_completePointSetColorArray'/>
<ROUTE fromNode='DrawPointScriptfromField='coordIndex_changedtoNode='ActiveLineSettoField='set_coordIndex'/>
<ROUTE fromNode='ActivePointSetCoordinateNodefromField='point_changedtoNode='DebuggertoField='set_debugcoordinate'/>
<ROUTE fromNode='ActivePointSetColorNodefromField='color_changedtoNode='DebuggertoField='set_debugcolor'/>
<ROUTE fromNode='ActiveLineSetCoordinateNodefromField='pointtoNode='DebuggertoField='set_debugcoord'/>
<ROUTE fromNode='DrawPointScriptfromField='coordIndex_changedtoNode='DebuggertoField='set_debugcoordIndex_changed'/>
<ROUTE fromNode='CompletePointSetCoordinateNodefromField='point_changedtoNode='DebuggertoField='set_debugcoordinateC'/>
<ROUTE fromNode='CompletePointSetColorNodefromField='color_changedtoNode='DebuggertoField='set_debugcolorC'/>
</ProtoBody>
</ProtoDeclare>
<!-- =================== -->
<!-- Example scene goes here -->
<Viewpoint description='MainViewposition='0 -50 200'/>
<!-- ROUTE information for TrackGeneratorInstance node:  [from DisplayingTimer.fraction_changed to mappedColorPointCreator ] [from getStartTime to DisplayingTimer.set_startTime ] [from getStopTime to DisplayingTimer.set_stopTime ] [from totalDuration to DisplayingTimer.set_cycleInterval ] -->
<ProtoInstance name='PointTrackGeneratorDEF='TrackGeneratorInstance'>
<fieldValue name='displaypointsModevalue='2'/>
</ProtoInstance>
<!-- ROUTE information for DisplayingTimer node:  [from TrackGeneratorInstance.getStartTime to set_startTime ] [from TrackGeneratorInstance.getStopTime to set_stopTime ] [from TrackGeneratorInstance.totalDuration to set_cycleInterval ] [from fraction_changed to TrackGeneratorInstance.mappedColorPointCreator ] -->
<TimeSensor DEF='DisplayingTimer'/>
<ROUTE fromNode='TrackGeneratorInstancefromField='getStartTimetoNode='DisplayingTimertoField='set_startTime'/>
<ROUTE fromNode='TrackGeneratorInstancefromField='getStopTimetoNode='DisplayingTimertoField='set_stopTime'/>
<ROUTE fromNode='TrackGeneratorInstancefromField='totalDurationtoNode='DisplayingTimertoField='set_cycleInterval'/>
<ROUTE fromNode='DisplayingTimerfromField='fraction_changedtoNode='TrackGeneratorInstancetoField='mappedColorPointCreator'/>
</Scene>
</X3D>
<!--

Index for ProtoDeclare definition : PointTrackGenerator

Index for DEF nodes : ActiveLineSet, ActiveLineSetColorNode, ActiveLineSetCoordinateNode, ActivePointSet, ActivePointSetColorNode, ActivePointSetCoordinateNode, AuvNameInline, auvTransform, ColorMapInterpolator, ColorMapInterpolatorForCompletePointsSet, CompletePointSet, CompletePointSetColorNode, CompletePointSetCoordinateNode, CompletePointSetTimeSensor, Debugger, DisplayingTimer, displaypointsMode_0, displaypointsMode_1, displaypointsMode_2, DrawPointScript, PointsGeometrySwitch, TrackGeneratorInstance

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

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