@prefix : . @prefix owl: . @prefix rdf: . @prefix rdfs: . @prefix schema: . @prefix dcterms: . @prefix xsd: . @prefix x3d: . @prefix x3do: . :X3D a owl:NamedIndividual, x3do:X3D ; x3do:hasHead :head ; x3do:hasScene :Scene ; x3do:profile 'Immersive' ; x3do:version '3.0' ; x3do:noNamespaceSchemaLocation 'https://www.web3d.org/specifications/x3d-3.0.xsd' . :head a owl:NamedIndividual, x3do:head ; x3do:hasParent :X3D ; x3do:hasMeta :meta_1_1, :meta_1_2, :meta_1_3, :meta_1_4, :meta_1_5, :meta_1_6, :meta_1_7, :meta_1_8, :meta_1_9, :meta_1_10, :meta_1_11, :meta_1_12, :meta_1_13 . :meta_1_1 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'AnimatedViewpointRecorderPrototype.x3d' ; x3do:name 'title' . :meta_1_2 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'Record camera position and orientation as user navigates, then filter values and produce output, both into the console output window and as a replayable node group. Future work: further filtering.' ; x3do:name 'description' . :meta_1_3 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'Don Brutzman, Ken Curtin, Duane Davis, Christos Kalogrias' ; x3do:name 'creator' . :meta_1_4 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content '24 October 2003' ; x3do:name 'created' . :meta_1_5 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content '12 October 2023' ; x3do:name 'modified' . :meta_1_6 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'AnimatedViewpointRecorderExample.x3d' ; x3do:name 'reference' . :meta_1_7 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'AnimatedViewpointRecorderSample.x3d' ; x3do:name 'reference' . :meta_1_8 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'http://www.realism.com/Web3D/Examples#WhereAmI' ; x3do:name 'reference' . :meta_1_9 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'http://www.realism.com/vrml/Example/WhereAmI/WhereAmI_Proto.wrl' ; x3do:name 'reference' . :meta_1_10 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'recording animated viewpoint tour' ; x3do:name 'subject' . :meta_1_11 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'https://savage.nps.edu/Savage/Tools/Authoring/AnimatedViewpointRecorderPrototype.x3d' ; x3do:name 'identifier' . :meta_1_12 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content 'X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit' ; x3do:name 'generator' . :meta_1_13 a owl:NamedIndividual, x3do:meta ; x3do:hasParent :head ; x3do:content '../../license.html' ; x3do:name 'license' . :meta dcterms:title "AnimatedViewpointRecorderPrototype.x3d" . :meta dcterms:description "Record camera position and orientation as user navigates, then filter values and produce output, both into the console output window and as a replayable node group. Future work: further filtering." . :meta dcterms:creator "Don Brutzman, Ken Curtin, Duane Davis, Christos Kalogrias" . :meta dcterms:created "24 October 2003" . :meta dcterms:modified "12 October 2023" . :meta dcterms:reference "AnimatedViewpointRecorderExample.x3d" . :meta dcterms:reference "AnimatedViewpointRecorderSample.x3d" . :meta dcterms:reference "http://www.realism.com/Web3D/Examples#WhereAmI" . :meta dcterms:reference "http://www.realism.com/vrml/Example/WhereAmI/WhereAmI_Proto.wrl" . :meta dcterms:subject "recording animated viewpoint tour" . :meta dcterms:identifier "https://savage.nps.edu/Savage/Tools/Authoring/AnimatedViewpointRecorderPrototype.x3d" . :meta dcterms:generator "X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit" . :meta dcterms:license "../../license.html" . :Scene a owl:NamedIndividual, x3do:Scene ; x3do:hasParent :X3D ; x3do:hasChildren :WorldInfo_2_1, :Background_2_3, :Viewpoint_2_4, :Anchor_2_5 ; x3do:hasProtoDeclare :ProtoDeclare_2_2 . :WorldInfo_2_1 a owl:NamedIndividual, x3do:WorldInfo ; x3do:hasParent :Scene ; x3do:title 'AnimatedViewpointRecorderPrototype.x3d' . :ProtoDeclare_2_2 a owl:NamedIndividual, x3do:ProtoDeclare ; x3do:hasParent :Scene ; x3do:hasProtoInterface :ProtoInterface_2_2_1 ; x3do:hasProtoBody :ProtoBody_2_2_2 ; x3do:appinfo 'AnimatedViewpointRecorder captures view position and orientation tour to create a guided tour animation. The recording output goes to the browser console where the .x3d (or .x3dv) output can be cut/pasted for further use.' ; x3do:name 'AnimatedViewpointRecorder' . :ProtoInterface_2_2_1 a owl:NamedIndividual, x3do:ProtoInterface ; x3do:hasParent :ProtoDeclare_2_2 ; x3do:hasField :field_2_2_1_1, :field_2_2_1_2, :field_2_2_1_3, :field_2_2_1_4, :field_2_2_1_5, :field_2_2_1_6 . :field_2_2_1_1 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'inputOnly' ; x3do:appinfo 'Set start=true to commence recording viewpoint position/orientation.' ; x3do:name 'start' ; x3do:type 'SFBool' . :field_2_2_1_2 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'inputOnly' ; x3do:appinfo 'Set stop=true to finish recording viewpoint position/orientation. Resulting VRML is added to scene resulting X3D and VRML is output to console.' ; x3do:name 'stop' ; x3do:type 'SFBool' . :field_2_2_1_3 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'default 0.1 seconds' ; x3do:name 'samplingInterval' ; x3do:type 'SFTime' ; x3do:value '0.1' . :field_2_2_1_4 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'whether to output .x3d syntax on browser console' ; x3do:name 'outputX3D' ; x3do:type 'SFBool' ; x3do:value true . :field_2_2_1_5 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'whether to output .x3d syntax on browser console' ; x3do:name 'outputClassicVRML' ; x3do:type 'SFBool' ; x3do:value false . :field_2_2_1_6 a owl:NamedIndividual, x3do:field ; x3do:hasParent :ProtoInterface_2_2_1 ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'TODO not yet implemented' ; x3do:name 'filterDeadTime' ; x3do:type 'SFBool' ; x3do:value false . :ProtoBody_2_2_2 a owl:NamedIndividual, x3do:ProtoBody ; x3do:hasParent :ProtoDeclare_2_2 ; x3do:hasChildren :Group_2_2_2_1 . :Group_2_2_2_1 a owl:NamedIndividual, x3do:Group ; x3do:hasParent :ProtoBody_2_2_2 ; x3do:hasChildren :NewViewpointGroup, :WhereSensor, :RecordingScript, :RouteHolder . :NewViewpointGroup a owl:NamedIndividual, x3do:Group ; x3do:hasParent :Group_2_2_2_1 ; x3do:DEF 'NewViewpointGroup' . :WhereSensor a owl:NamedIndividual, x3do:ProximitySensor ; x3do:hasParent :Group_2_2_2_1 ; x3do:DEF 'WhereSensor' ; x3do:size ( 1000000000 1000000000 1000000000 ) . :RecordingScript a owl:NamedIndividual, x3do:Script ; x3do:hasParent :Group_2_2_2_1 ; x3do:hasField :field_2_2_2_1_3_1, :field_2_2_2_1_3_2, :field_2_2_2_1_3_3, :field_2_2_2_1_3_4, :field_2_2_2_1_3_5, :field_2_2_2_1_3_6, :field_2_2_2_1_3_7, :field_2_2_2_1_3_8, :field_2_2_2_1_3_9, :field_2_2_2_1_3_10, :field_2_2_2_1_3_11, :field_2_2_2_1_3_12, :field_2_2_2_1_3_13, :field_2_2_2_1_3_14, :field_2_2_2_1_3_15, :field_2_2_2_1_3_16, :field_2_2_2_1_3_17, :field_2_2_2_1_3_18, :field_2_2_2_1_3_19, :field_2_2_2_1_3_20, :field_2_2_2_1_3_21, :field_2_2_2_1_3_22 ; x3do:hasIS :IS_2_2_2_1_3_23 ; x3do:DEF 'RecordingScript' ; x3do:directOutput true ; x3do:sourceCode """ ecmascript: function initialize() { positionArray = new MFVec3f (); orientationArray = new MFRotation (); positionTimeArray = new MFTime (); orientationTimeArray = new MFTime (); positionEventsReceived = false; orientationEventsReceived = false; } function roundoff (value, digits) { resolution = 1; for (i = 1; i <= digits; i++ ) { resolution *= 10; } return Math.round (value*resolution) / resolution; // round to resolution } function filterPositions() { // TODO } function filterOrientations() { // TODO } function set_position (eventValue, timestamp) { // Browser.println ('position=' + eventValue); // we are counting on an initialization eventValue being sent by ProximitySensor positionEventsReceived = true; if ( positionArray.length == 0 ) { positionArray[0] = eventValue; // initialize positionTimeArray[0] = timestamp; // initialize } precedingPositionSampleTime = positionTimeArray[ positionArray.length - 1 ]; // seconds duration since last valid sample if ( (timestamp - precedingPositionSampleTime) > samplingInterval ) { // append values to each array positionArray[positionArray.length] = eventValue; positionTimeArray[positionTimeArray.length] = timestamp; } precedingPosition = eventValue; } function set_orientation (eventValue, timestamp) { // we are counting on an initialization eventValue being sent by ProximitySensor orientationEventsReceived = true; if ( orientationArray.length == 0 ) { r = Math.sqrt (eventValue.x*eventValue.x + eventValue.y*eventValue.y + eventValue.z*eventValue.z); // Browser.println ('orientation=' + eventValue.toString() + ', r=' + r); // trace if (r != 0) { eventValue.x = eventValue.x / r; eventValue.y = eventValue.y / r; eventValue.z = eventValue.z / r; } orientationArray[0] = eventValue; // initialize orientationTimeArray[0] = timestamp; // initialize } precedingOrientationSampleTime = orientationTimeArray[ orientationTimeArray.length - 1 ]; // append sample values to each array if ( (timestamp - precedingOrientationSampleTime) > samplingInterval ) { orientationTimeArray[orientationTimeArray.length] = timestamp; // normalize SFRotation axis if needed r = Math.sqrt (eventValue.x*eventValue.x + eventValue.y*eventValue.y + eventValue.z*eventValue.z); // Browser.println ('orientation=' + eventValue.toString() + ', r=' + r); // trace if (r != 0) { eventValue.x = eventValue.x / r; eventValue.y = eventValue.y / r; eventValue.z = eventValue.z / r; // auto append to array, no need to allocate orientationArray[orientationArray.length] = eventValue; } else // illegal zero-magnitude axis returned by browser, so just use previous rotation { // auto append to array, no need to allocate orientationArray[orientationArray.length] = precedingOrientation; } } precedingOrientation = eventValue; } function start (eventValue, timestamp) { if (eventValue == false) return; // only accept start if eventValue == true if (recordingInProgress == true) return; // ignore repeated starts while already running recordingInProgress = true; // arrays need to be reinitialized from previous run initialize(); Browser.println (' '); } function stop (eventValue, timestamp) { if (eventValue == false) return; // only accept stop if eventValue == true if (recordingInProgress == false) { Browser.println (' '); return; } // ensure legal array lengths in case some events were never sent due to not moving if (positionEventsReceived == false) { Browser.println (''); return; } if (orientationEventsReceived == false) { Browser.println (''); return; } recordingInProgress = false; // preceding last values were at last sampleInterval (either set_position or set_orientation) // add one more to each array since they are not sent values by sensor when not changing positionArray[ positionArray.length] = precedingPosition; orientationArray[orientationArray.length] = precedingOrientation; positionTimeArray[ positionTimeArray.length] = timestamp; orientationTimeArray[orientationTimeArray.length] = timestamp; if (positionArray.length != positionTimeArray.length) { Browser.println (''); } if (orientationArray.length != orientationTimeArray.length) { Browser.println (''); } filterPositions(); filterOrientations(); // iff events are sent simultaneously, could use either array with start/stop times synchronized // however that might be a bad assumption... so reset start times to match if (positionTimeArray[0] > orientationTimeArray[0]) positionTimeArray[0] = orientationTimeArray[0]; if (positionTimeArray[0] < orientationTimeArray[0]) orientationTimeArray[0] = positionTimeArray[0]; startTime = positionTimeArray[0]; stopTime = positionTimeArray[positionTimeArray.length-1]; interval = stopTime - startTime; x3dString = ' ' + ' \n' + ' \n' + ' ' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n'; if (outputX3D) Browser.println (x3dString); vrmlString = '# ********** start recorded Animated Tour ' + numberOfToursCreated + ' using .x3dv syntax ********** \n' + 'Group {\n' + ' children [\n' + ' DEF AnimatedViewpointRecorderViewpoint' + numberOfToursCreated + ' Viewpoint {\n' + ' description \"Animated Tour ' + numberOfToursCreated + '\"\n' + ' orientation ' + orientationArray[0].x + ' ' + orientationArray[0].y + ' ' + orientationArray[0].z + ' ' + orientationArray[0].angle + '\n' + ' position ' + positionArray[0].x + ' ' + positionArray[0].y + ' ' + positionArray[0].z + '\n' + ' }\n' + ' DEF AnimatedViewpointRecorderTimer' + numberOfToursCreated + ' TimeSensor {\n' + ' cycleInterval ' + interval + '\n' + ' loop TRUE\n' + ' }\n' + ' DEF AnimatedViewpointRecorderPosition' + numberOfToursCreated + ' PositionInterpolator {\n' + ' key [\n'; for (counter = 0; counter < positionTimeArray.length; counter++) { vrmlString = vrmlString + roundoff(((positionTimeArray[counter] - positionTimeArray[0]) / interval),5) + ' \n'; } vrmlString = vrmlString + ' ]\n' + ' keyValue [\n'; for (counter = 0; counter < positionArray.length; counter++) { vrmlString = vrmlString + positionArray[counter].x + ' ' + positionArray[counter].y + ' ' + positionArray[counter].z + ', \n'; } vrmlString = vrmlString + ' ]\n' + ' }\n' + ' DEF AnimatedViewpointRecorderOrientation' + numberOfToursCreated + ' OrientationInterpolator {\n' + ' key [\n'; for (counter = 0; counter < orientationTimeArray.length; counter++) { vrmlString = vrmlString + roundoff(((orientationTimeArray[counter] - orientationTimeArray[0]) / interval),5) + ' \n'; } vrmlString = vrmlString + ' ]\n' + ' keyValue [\n'; for (counter = 0; counter < orientationArray.length; counter++) { vrmlString = vrmlString + orientationArray[counter].x + ' ' + orientationArray[counter].y + ' ' + orientationArray[counter].z + ' ' + orientationArray[counter].angle + ', \n'; } vrmlString = vrmlString + ' ]\n' + ' }\n' + ' Group {\n' + ' ROUTE AnimatedViewpointRecorderViewpoint' + numberOfToursCreated + '.bindTime TO AnimatedViewpointRecorderTimer' + numberOfToursCreated + '.startTime\n' + ' ROUTE AnimatedViewpointRecorderTimer' + numberOfToursCreated + '.fraction_changed TO AnimatedViewpointRecorderPosition' + numberOfToursCreated + '.set_fraction\n' + ' ROUTE AnimatedViewpointRecorderTimer' + numberOfToursCreated + '.fraction_changed TO AnimatedViewpointRecorderOrientation' + numberOfToursCreated + '.set_fraction\n' + ' ROUTE AnimatedViewpointRecorderPosition' + numberOfToursCreated + '.value_changed TO AnimatedViewpointRecorderViewpoint' + numberOfToursCreated + '.position\n' + ' ROUTE AnimatedViewpointRecorderOrientation' + numberOfToursCreated + '.value_changed TO AnimatedViewpointRecorderViewpoint' + numberOfToursCreated + '.orientation\n' + ' }\n' + ' ]\n' + '}\n'; Browser.println (); if (outputClassicVRML) Browser.println (vrmlString); numberOfToursCreated++; // TODO // newNode = new SFNode(vrmlString); // newViewpointGroup.children[numberOfToursCreated] = newNode; } """ . :field_2_2_2_1_3_1 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'inputOnly' ; x3do:name 'start' ; x3do:type 'SFBool' . :field_2_2_2_1_3_2 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'inputOnly' ; x3do:name 'stop' ; x3do:type 'SFBool' . :field_2_2_2_1_3_3 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'seconds' ; x3do:name 'samplingInterval' ; x3do:type 'SFTime' . :field_2_2_2_1_3_4 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'whether to output .x3d syntax on browser console' ; x3do:name 'outputX3D' ; x3do:type 'SFBool' . :field_2_2_2_1_3_5 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'whether to output .x3d syntax on browser console' ; x3do:name 'outputClassicVRML' ; x3do:type 'SFBool' . :field_2_2_2_1_3_6 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'outputOnly' ; x3do:appinfo 'persistent state variable' ; x3do:name 'recordingInProgress' ; x3do:type 'SFBool' . :field_2_2_2_1_3_7 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'inputOnly' ; x3do:name 'set_position' ; x3do:type 'SFVec3f' . :field_2_2_2_1_3_8 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'inputOnly' ; x3do:name 'set_orientation' ; x3do:type 'SFRotation' . :field_2_2_2_1_3_9 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:name 'positionArray' ; x3do:type 'MFVec3f' . :field_2_2_2_1_3_10 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:name 'positionTimeArray' ; x3do:type 'MFTime' . :field_2_2_2_1_3_11 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:name 'orientationArray' ; x3do:type 'MFRotation' . :field_2_2_2_1_3_12 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:name 'orientationTimeArray' ; x3do:type 'MFTime' . :field_2_2_2_1_3_13 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'not yet implemented' ; x3do:name 'filterDeadTime' ; x3do:type 'SFBool' . :field_2_2_2_1_3_14 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:hasChildren :NewViewpointGroup-USE-1 ; x3do:accessType 'initializeOnly' ; x3do:name 'newViewpointGroup' ; x3do:type 'SFNode' . :NewViewpointGroup-USE-1 a owl:NamedIndividual, x3do:Group ; x3do:hasParent :field_2_2_2_1_3_14 ; owl:sameAs :NewViewpointGroup . # DEF matching this USE :field_2_2_2_1_3_15 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'persistent holding variable' ; x3do:name 'numberOfToursCreated' ; x3do:type 'SFInt32' ; x3do:value 0 . :field_2_2_2_1_3_16 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'persistent holding variable' ; x3do:name 'precedingPosition' ; x3do:type 'SFVec3f' ; x3do:value ( 0 0 0 ) . :field_2_2_2_1_3_17 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'persistent holding variable' ; x3do:name 'precedingOrientation' ; x3do:type 'SFRotation' ; x3do:value ( 0 1 0 0 ) . :field_2_2_2_1_3_18 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'persistent holding variable' ; x3do:name 'precedingPositionSampleTime' ; x3do:type 'SFTime' ; x3do:value '0' . :field_2_2_2_1_3_19 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'persistent holding variable' ; x3do:name 'precedingOrientationSampleTime' ; x3do:type 'SFTime' ; x3do:value '0' . :field_2_2_2_1_3_20 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'normalization factor' ; x3do:name 'r' ; x3do:type 'SFFloat' ; x3do:value 1 . :field_2_2_2_1_3_21 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'track output of ProximitySensor' ; x3do:name 'positionEventsReceived' ; x3do:type 'SFBool' ; x3do:value false . :field_2_2_2_1_3_22 a owl:NamedIndividual, x3do:field ; x3do:hasParent :RecordingScript ; x3do:accessType 'initializeOnly' ; x3do:appinfo 'track output of ProximitySensor' ; x3do:name 'orientationEventsReceived' ; x3do:type 'SFBool' ; x3do:value false . :IS_2_2_2_1_3_23 a owl:NamedIndividual, x3do:IS ; x3do:hasParent :RecordingScript ; x3do:hasConnect :connect_2_2_2_1_3_23_1, :connect_2_2_2_1_3_23_2, :connect_2_2_2_1_3_23_3, :connect_2_2_2_1_3_23_4, :connect_2_2_2_1_3_23_5, :connect_2_2_2_1_3_23_6 . :connect_2_2_2_1_3_23_1 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'start' ; x3do:protoField 'start' . :connect_2_2_2_1_3_23_2 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'stop' ; x3do:protoField 'stop' . :connect_2_2_2_1_3_23_3 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'samplingInterval' ; x3do:protoField 'samplingInterval' . :connect_2_2_2_1_3_23_4 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'outputX3D' ; x3do:protoField 'outputX3D' . :connect_2_2_2_1_3_23_5 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'outputClassicVRML' ; x3do:protoField 'outputClassicVRML' . :connect_2_2_2_1_3_23_6 a owl:NamedIndividual, x3do:connect ; x3do:hasParent :IS_2_2_2_1_3_23 ; x3do:nodeField 'filterDeadTime' ; x3do:protoField 'filterDeadTime' . :RouteHolder a owl:NamedIndividual, x3do:Group ; x3do:hasParent :Group_2_2_2_1 ; x3do:hasROUTE :ROUTE_2_2_2_1_4_1, :ROUTE_2_2_2_1_4_2, :ROUTE_2_2_2_1_4_3 ; x3do:DEF 'RouteHolder' . :ROUTE_2_2_2_1_4_1 a owl:NamedIndividual, x3do:ROUTE ; x3do:hasParent :RouteHolder ; x3do:fromField 'position_changed' ; x3do:fromNode 'WhereSensor' ; x3do:toField 'set_position' ; x3do:toNode 'RecordingScript' . :ROUTE_2_2_2_1_4_2 a owl:NamedIndividual, x3do:ROUTE ; x3do:hasParent :RouteHolder ; x3do:fromField 'orientation_changed' ; x3do:fromNode 'WhereSensor' ; x3do:toField 'set_orientation' ; x3do:toNode 'RecordingScript' . :ROUTE_2_2_2_1_4_3 a owl:NamedIndividual, x3do:ROUTE ; x3do:hasParent :RouteHolder ; x3do:fromField 'recordingInProgress' ; x3do:fromNode 'RecordingScript' ; x3do:toField 'enabled' ; x3do:toNode 'WhereSensor' . :Background_2_3 a owl:NamedIndividual, x3do:Background ; x3do:hasParent :Scene ; x3do:groundColor ( 0.2 0.4 0.2 ) ; x3do:skyColor ( 0.2 0.2 0.4 ) . :Viewpoint_2_4 a owl:NamedIndividual, x3do:Viewpoint ; x3do:hasParent :Scene ; x3do:description 'Animated Viewpoint Recorder' ; x3do:position ( 0 0 14 ) . :Anchor_2_5 a owl:NamedIndividual, x3do:Anchor ; x3do:hasParent :Scene ; x3do:hasChildren :Shape_2_5_1 ; x3do:description 'AnimatedViewpointRecorder Example' ; x3do:url '"AnimatedViewpointRecorderExample.x3d" "https://savage.nps.edu/Savage/Tools/Authoring/AnimatedViewpointRecorderExample.x3d" "AnimatedViewpointRecorderExample.wrl" "https://savage.nps.edu/Savage/Tools/Authoring/AnimatedViewpointRecorderExample.wrl"' . :Shape_2_5_1 a owl:NamedIndividual, x3do:Shape ; x3do:hasParent :Anchor_2_5 ; x3do:hasGeometry :Text_2_5_1_1 ; x3do:hasAppearance :Appearance_2_5_1_2 . :Text_2_5_1_1 a owl:NamedIndividual, x3do:Text ; x3do:hasParent :Shape_2_5_1 ; x3do:hasFontStyle :FontStyle_2_5_1_1_1 ; x3do:string '"AnimatedViewpointRecorderPrototype" "is a prototype definition file" "" "Click this text to see" "AnimatedViewpointRecorderExample"' . :FontStyle_2_5_1_1_1 a owl:NamedIndividual, x3do:FontStyle ; x3do:hasParent :Text_2_5_1_1 ; x3do:justify '"MIDDLE" "MIDDLE"' ; x3do:size 1.2 . :Appearance_2_5_1_2 a owl:NamedIndividual, x3do:Appearance ; x3do:hasParent :Shape_2_5_1 ; x3do:hasMaterial :Material_2_5_1_2_1 . :Material_2_5_1_2_1 a owl:NamedIndividual, x3do:Material ; x3do:hasParent :Appearance_2_5_1_2 ; x3do:diffuseColor ( 0.6 0.8 0.4 ) .