[x3d-public] Can you make X3dToJson.xslt work with this file? multiple \"\"\"

Don Brutzman brutzman at nps.edu
Sat May 20 18:30:35 PDT 2017


On 5/20/2017 4:42 PM, John Carlson wrote:
> Can you at least keep the \n handling?  I was hoping for that one I think.  That’s the nextChar code.  I can send again, if desired.

OK sounds good.

I restored the following block (more complete) from a prior version:

<!-- special characters backspace, formfeed, newline, carriage return, horizontal tab are presumably character entities already -->
<!-- page links for character entities http://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#HTML -->
<!-- http://www.w3schools.com/js/js_strings.asp -->
<xsl:when test="($nextCharAfterBackslash = '/') or
		($nextCharAfterBackslash = 'n') or
		($nextCharAfterBackslash = 'r') or
		($nextCharAfterBackslash = 't') or
		($nextCharAfterBackslash = 'b') or
		($nextCharAfterBackslash = 'f')">
	<xsl:if test="$debugTrace"><xsl:message><xsl:text>[e-b-c-r][23.5]</xsl:text><xsl:value-of select="$debugMessage"/></xsl:message></xsl:if>
	<xsl:value-of select="substring-before($inputString,'\')"/>
	<xsl:text disable-output-escaping="yes">\</xsl:text>
	<xsl:value-of select="$nextCharAfterBackslash"/>
	<xsl:call-template name="escape-backslash-characters-recurse">
	  <xsl:with-param name="inputString" select="$remainder"/>
	</xsl:call-template>
</xsl:when>

Example conversion attached, looks like it handled literal \n characters in Script source OK.

excerpts:

"                tracePrint ('      keyValueOrientation[k+1]=' + keyValueOrientation[k+1].toString() + '\n');",

"         Browser.print ('[CameraMovement] ' + outputString + '\n');",

etc.


> Sent from Mail <https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
> 
> *From: *Don Brutzman <mailto:brutzman at nps.edu>
> *Sent: *Saturday, May 20, 2017 7:31 PM
> *To: *John Carlson <mailto:yottzumm at gmail.com>
> *Cc: *X3D Graphics public mailing list <mailto:x3d-public at web3d.org>; Roy Walmsley <mailto:roy.walmsley at ntlworld.com>
> *Subject: *Re: Can you make X3dToJson.xslt work with this file? multiple \"\"\"
> 
> On 5/19/2017 1:37 PM, John Carlson wrote:
> 
>  > Thanks.  Version of X3dToJson.xslt is attached.  I am thinking \"\"\&quot might be something to match.
> 
> Thanks for the stylesheet effort.  I kept the parts that strip html tags and x3dom's specialized <X3D> attributes, we can continue on that another day.
> 
> The other parts for MFString recurision I wasn't really able to use.  The existing logic is quite complex/subtle, adding another branch would have been very hard to debug/maintain.  Instead used the debugging traces and improved the existing logic.  This is especially tricky because first you have to get through escape-backslash-characters-recurse template before continuing with escape-quote-characters-recurse template.
> 
> Took some doing but I got your special example to work, apparently without breaking anything else.  X3D for Advanced Modeling passes, others are in progress.
> 
> for your text.x3d example:
> 
>                  <Text string='"Node\"\"\""'>
> 
> becomes
> 
>                  "@string":["Node\"\"\""],
> 
> as expected.
> 
> I then tried to handle adjacent SFString values in an MFString list without intervening whitespace.
> 
> can handle typical
> 
>                  <Text DEF='TextMessage' string='"Hello" "world!"'>
> 
> or
> 
>                  <Text DEF='TextMessage' string='"Hello" "" "world!"'>
> 
> but not
> 
>                  <Text DEF='TextMessage' string='"Hello""world!"'>
> 
> or
> 
>                  <Text DEF='TextMessage' string='"Hello""""world!"'>
> 
> need to think about context-free parsing a bit more.  not yet sure how to get there from here.  that special case will require more work, perhaps another day.
> 
> X3dToJson.xslt changes checked in, will update json .zip tonight.
> 
> all the best, Don
> 
> -- 
> 
> Don Brutzman  Naval Postgraduate School, Code USW/Br       brutzman at nps.edu
> 
> Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
> 
> X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman
> 


all the best, Don
-- 
Don Brutzman  Naval Postgraduate School, Code USW/Br       brutzman at nps.edu
Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman
-------------- next part --------------
{ "X3D": {
    "encoding":"UTF-8",
    "@profile":"Immersive",
    "@version":"3.2",
    "@xsd:noNamespaceSchemaLocation":"http://www.web3d.org/specifications/x3d-3.2.xsd",
    "JSON schema":"http://www.web3d.org/specifications/x3d-3.3-JSONSchema.json",
    "head": {
        "meta": [
          {
            "@name":"title",
            "@content":"CameraPrototypes.x3d"
          },
          {
            "@name":"description",
            "@content":"Camera, CameraShot and CameraMovement prototypes that demonstrate storyboard capabilities and precise camera operation. This is a developmental effort for potential X3D Specification improvement."
          },
          {
            "@name":"creator",
            "@content":"Don Brutzman and Jeff Weekley"
          },
          {
            "@name":"created",
            "@content":"16 March 2009"
          },
          {
            "@name":"modified",
            "@content":"25 October 2016"
          },
          {
            "@name":"TODO",
            "@content":"Schematron rules, backed up by initialize() checks"
          },
          {
            "@name":"reference",
            "@content":"BeyondViewpointCameraNodesWeb3D2009.pdf"
          },
          {
            "@name":"reference",
            "@content":"http://www.web3d.org/x3d/specifications/ISO-IEC-FDIS-19775-1.2-X3D-AbstractSpecification/Part01/components/navigation.html"
          },
          {
            "@name":"subject",
            "@content":"Camera nodes for Viewpoint navigation control"
          },
          {
            "@name":"reference",
            "@content":"CameraExamples.x3d"
          },
          {
            "@name":"identifier",
            "@content":"http://www.web3d.org/x3d/content/examples/Basic/development/CameraPrototypes.x3d"
          },
          {
            "@name":"reference",
            "@content":"http://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/Basic/development/CameraPrototypes.x3d"
          },
          {
            "@name":"generator",
            "@content":"X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit"
          },
          {
            "@name":"license",
            "@content":"../license.html"
          },
          {
            "@name":"translated",
            "@content":"20 May 2017"
          },
          {
            "@name":"generator",
            "@content":"X3dToJson.xslt, http://www.web3d.org/x3d/stylesheets/X3dToJson.html"
          },
          {
            "@name":"reference",
            "@content":"X3D JSON encoding: http://www.web3d.org/wiki/index.php/X3D_JSON_Encoding"
          }
        ]
    },
    "Scene": {
        "-children":[
          {
            "#comment":"=============== Camera =============="
          },
          { "ProtoDeclare":
            {
              "@name":"Camera",
              "@appinfo":"Camera node provides direct control of scene view to enable cinematic camera animation shot by shot and move by move along with still digital-photography settings for offline rendering of camera images.",
              "ProtoInterface": {
                  "-children":[
                    {
                      "#comment":"Viewpoint-related fields, NavigationInfo-related fields and Camera-unique fields"
                    }
                  ],
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"Text description to be displayed for this Camera",
                      "@type":"SFString"
                    },
                    {
                      "@name":"position",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera position in local transformation frame, which is default prior to first CameraShot initialPosition getting activated",
                      "@type":"SFVec3f",
                      "@value":[0,0,10]
                    },
                    {
                      "@name":"orientation",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera rotation in local transformation frame, which is default prior to first CameraShot initialPosition getting activated",
                      "@type":"SFRotation",
                      "@value":[0,0,1,0]
                    },
                    {
                      "@name":"fieldOfView",
                      "@accessType":"inputOutput",
                      "@appinfo":"pi/4",
                      "@type":"SFFloat",
                      "@value":0.7854
                    },
                    {
                      "@name":"set_fraction",
                      "@accessType":"inputOnly",
                      "@appinfo":"input fraction drives interpolators",
                      "@type":"SFFloat"
                    },
                    {
                      "@name":"set_bind",
                      "@accessType":"inputOnly",
                      "@appinfo":"input event binds or unbinds this Camera",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"bindTime",
                      "@accessType":"outputOnly",
                      "@appinfo":"output event indicates when this Camera is bound",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"isBound",
                      "@accessType":"outputOnly",
                      "@appinfo":"output event indicates whether this Camera is bound or unbound",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"nearClipPlane",
                      "@accessType":"inputOutput",
                      "@appinfo":"Vector distance to near clipping plane corresponds to NavigationInfo.avatarSize[0]",
                      "@type":"SFFloat",
                      "@value":0.25
                    },
                    {
                      "@name":"farClipPlane",
                      "@accessType":"inputOutput",
                      "@appinfo":"Vector distance to far clipping plane corresponds to NavigationInfo.visibilityLimit",
                      "@type":"SFFloat",
                      "@value":0.0
                    },
                    {
                      "@name":"shots",
                      "@accessType":"inputOutput",
                      "@appinfo":"Array of CameraShot nodes which in turn contain CameraMovement nodes",
                      "@type":"MFNode",
                      "-children":[
                        {
                          "#comment":"initialization nodes (if any) go here"
                        }
                      ]
                    },
                    {
                      "@name":"headlight",
                      "@accessType":"inputOutput",
                      "@appinfo":"Whether camera headlight is on or off",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"headlightColor",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera headlight color",
                      "@type":"SFColor",
                      "@value":[1,1,1]
                    },
                    {
                      "@name":"headlightIntensity",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera headlight intensity",
                      "@type":"SFFloat",
                      "@value":1
                    },
                    {
                      "@name":"filterColor",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera filter color that modifies virtual lens capture",
                      "@type":"SFColor",
                      "@value":[1,1,1]
                    },
                    {
                      "@name":"filterTransparency",
                      "@accessType":"inputOutput",
                      "@appinfo":"Camera filter transparency that modifies virtual lens capture",
                      "@type":"SFFloat",
                      "@value":1
                    },
                    {
                      "@name":"upVector",
                      "@accessType":"inputOutput",
                      "@appinfo":"upVector changes modify camera orientation (and possibly vice versa)",
                      "@type":"SFVec3f",
                      "@value":[0,1,0]
                    },
                    {
                      "@name":"fStop",
                      "@accessType":"inputOutput",
                      "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                      "@type":"SFFloat",
                      "@value":5.6
                    },
                    {
                      "@name":"focusDistance",
                      "@accessType":"inputOutput",
                      "@appinfo":"Distance to focal plane of sharpest focus",
                      "@type":"SFFloat",
                      "@value":10
                    },
                    {
                      "@name":"isActive",
                      "@accessType":"outputOnly",
                      "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"totalDuration",
                      "@accessType":"outputOnly",
                      "@appinfo":"Total duration of contained enabled CameraShot (and thus CameraMovement) move durations",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"offlineRender",
                      "@accessType":"inputOutput",
                      "@appinfo":"OfflineRender node",
                      "@type":"SFNode",
                      "-children":[
                        {
                          "#comment":"initialization node (if any) goes here"
                        }
                      ]
                    },
                    {
                      "@name":"traceEnabled",
                      "@accessType":"initializeOnly",
                      "@appinfo":"enable console output to trace script computations and prototype progress",
                      "@type":"SFBool",
                      "@value":false
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    { "Viewpoint":
                      {
                        "@DEF":"CameraViewpoint",
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"position",
                                "@protoField":"position"
                              },
                              {
                                "@nodeField":"orientation",
                                "@protoField":"orientation"
                              },
                              {
                                "@nodeField":"fieldOfView",
                                "@protoField":"fieldOfView"
                              },
                              {
                                "@nodeField":"set_bind",
                                "@protoField":"set_bind"
                              },
                              {
                                "@nodeField":"bindTime",
                                "@protoField":"bindTime"
                              },
                              {
                                "@nodeField":"isBound",
                                "@protoField":"isBound"
                              }
                            ]
                        }
                      }
                    },
                    {
                      "#comment":"NavInfo EXAMINE used since some browsers (InstantReality) try to lock view to vertical when flying to avoid disorientation"
                    },
                    { "NavigationInfo":
                      {
                        "@DEF":"CameraNavInfo",
                        "@type":["EXAMINE","FLY","ANY"],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"set_bind",
                                "@protoField":"set_bind"
                              },
                              {
                                "@nodeField":"headlight",
                                "@protoField":"headlight"
                              },
                              {
                                "@nodeField":"visibilityLimit",
                                "@protoField":"farClipPlane"
                              }
                            ],
                            "-children":[
                              {
                                "#comment":"No need to bind outputs bindTime, isBound from NavigationInfo since Viewpoint outputs will suffice. TODO inform BitManagement that bindTime field is missing."
                              }
                            ]
                        }
                      }
                    },
                    {
                      "#comment":"this DirectionalLight replaces NavigationInfo headlight in order to add color capability"
                    },
                    { "DirectionalLight":
                      {
                        "@DEF":"CameraDirectionalLight",
                        "@global":true,
                        "-children":[
                          {
                            "#comment":"TODO confirm other default field values match NavigationInfo spec"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"on",
                                "@protoField":"headlight"
                              },
                              {
                                "@nodeField":"color",
                                "@protoField":"headlightColor"
                              },
                              {
                                "@nodeField":"intensity",
                                "@protoField":"headlightIntensity"
                              }
                            ]
                        }
                      }
                    },
                    { "PositionInterpolator":
                      {
                        "@DEF":"CameraPositionInterpolator",
                        "@key":[0,1],
                        "@keyValue":[0,0,0,0,0,0],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"set_fraction",
                                "@protoField":"set_fraction"
                              }
                            ]
                        }
                      }
                    },
                    { "OrientationInterpolator":
                      {
                        "@DEF":"CameraOrientationInterpolator",
                        "@key":[0,1],
                        "@keyValue":[0,1,0,0,0,1,0,0],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"set_fraction",
                                "@protoField":"set_fraction"
                              }
                            ]
                        }
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"value_changed",
                        "@fromNode":"CameraPositionInterpolator",
                        "@toField":"position",
                        "@toNode":"CameraViewpoint"
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"value_changed",
                        "@fromNode":"CameraOrientationInterpolator",
                        "@toField":"orientation",
                        "@toNode":"CameraViewpoint"
                      }
                    },
                    { "Script":
                      {
                        "@DEF":"CameraScript",
                        "@directOutput":true,
                        "@mustEvaluate":true,
                        "-children":[
                          {
                            "#comment":"binding is controlled externally, all camera operations proceed the same regardless of whether bound or not"
                          }
                        ],
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"inputOutput",
                            "@appinfo":"Text description to be displayed for this Camera",
                            "@type":"SFString"
                          },
                          {
                            "@name":"position",
                            "@accessType":"inputOutput",
                            "@appinfo":"Camera position in local transformation frame",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"orientation",
                            "@accessType":"inputOutput",
                            "@appinfo":"Camera rotation in local transformation frame",
                            "@type":"SFRotation"
                          },
                          {
                            "@name":"set_fraction",
                            "@accessType":"inputOnly",
                            "@appinfo":"input fraction drives interpolators",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"set_bind",
                            "@accessType":"inputOnly",
                            "@appinfo":"input event binds or unbinds this Camera",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"fieldOfView",
                            "@accessType":"inputOutput",
                            "@appinfo":"pi/4",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"nearClipPlane",
                            "@accessType":"inputOutput",
                            "@appinfo":"Vector distance to near clipping plane",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"farClipPlane",
                            "@accessType":"inputOutput",
                            "@appinfo":"Vector distance to far clipping plane",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"shots",
                            "@accessType":"inputOutput",
                            "@appinfo":"Array of CameraShot nodes which in turn contain CameraMovement nodes",
                            "@type":"MFNode",
                            "-children":[
                              {
                                "#comment":"initialization nodes (if any) go here"
                              }
                            ]
                          },
                          {
                            "@name":"filterColor",
                            "@accessType":"inputOutput",
                            "@appinfo":"Camera filter color that modifies virtual lens capture",
                            "@type":"SFColor"
                          },
                          {
                            "@name":"filterTransparency",
                            "@accessType":"inputOutput",
                            "@appinfo":"Camera filter transparency that modifies virtual lens capture",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"upVector",
                            "@accessType":"inputOutput",
                            "@appinfo":"upVector changes modify camera orientation (and possibly vice versa)",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"fStop",
                            "@accessType":"inputOutput",
                            "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"focusDistance",
                            "@accessType":"inputOutput",
                            "@appinfo":"Distance to focal plane of sharpest focus",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"isActive",
                            "@accessType":"outputOnly",
                            "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"totalDuration",
                            "@accessType":"outputOnly",
                            "@appinfo":"Total duration of contained enabled CameraShot (and thus CameraMovement) move durations",
                            "@type":"SFTime"
                          },
                          {
                            "@name":"offlineRender",
                            "@accessType":"inputOutput",
                            "@appinfo":"OfflineRender node",
                            "@type":"SFNode",
                            "-children":[
                              {
                                "#comment":"initialization node (if any) goes here"
                              }
                            ]
                          },
                          {
                            "@name":"ViewpointNode",
                            "@accessType":"initializeOnly",
                            "@appinfo":"node reference to permit getting setting fields from within Script",
                            "@type":"SFNode",
                            "-children":[
                              { "Viewpoint":
                                {
                                  "@USE":"CameraViewpoint"
                                }
                              }
                            ]
                          },
                          {
                            "@name":"NavInfoNode",
                            "@accessType":"initializeOnly",
                            "@appinfo":"node reference to permit getting setting fields from within Script",
                            "@type":"SFNode",
                            "-children":[
                              { "NavigationInfo":
                                {
                                  "@USE":"CameraNavInfo"
                                }
                              }
                            ]
                          },
                          {
                            "@name":"CameraPI",
                            "@accessType":"initializeOnly",
                            "@appinfo":"node reference to permit getting setting fields from within Script",
                            "@type":"SFNode",
                            "-children":[
                              { "PositionInterpolator":
                                {
                                  "@USE":"CameraPositionInterpolator"
                                }
                              }
                            ]
                          },
                          {
                            "@name":"CameraOI",
                            "@accessType":"initializeOnly",
                            "@appinfo":"node reference to permit getting setting fields from within Script",
                            "@type":"SFNode",
                            "-children":[
                              { "OrientationInterpolator":
                                {
                                  "@USE":"CameraOrientationInterpolator"
                                }
                              }
                            ]
                          },
                          {
                            "@name":"key",
                            "@accessType":"inputOutput",
                            "@appinfo":"key array for interpolators",
                            "@type":"MFFloat"
                          },
                          {
                            "@name":"keyValuePosition",
                            "@accessType":"inputOutput",
                            "@appinfo":"keyValue array for PositionInterpolator",
                            "@type":"MFVec3f"
                          },
                          {
                            "@name":"keyValueOrientation",
                            "@accessType":"inputOutput",
                            "@appinfo":"keyValue array for OrientationInterpolator",
                            "@type":"MFRotation"
                          },
                          {
                            "@name":"animated",
                            "@accessType":"inputOutput",
                            "@appinfo":"whether internal CameraShot and CameraMove nodes are tracking or changed via ROUTE events",
                            "@type":"SFBool",
                            "@value":false
                          },
                          {
                            "@name":"initialized",
                            "@accessType":"initializeOnly",
                            "@appinfo":"perform checkShots() function once immediately after initialization",
                            "@type":"SFBool",
                            "@value":false
                          },
                          {
                            "@name":"shotCount",
                            "@accessType":"initializeOnly",
                            "@appinfo":"how many CameraShot nodes are contained in shots array",
                            "@type":"SFInt32",
                            "@value":0
                          },
                          {
                            "@name":"movesCount",
                            "@accessType":"initializeOnly",
                            "@appinfo":"how many CameraMove nodes are contained in moves array",
                            "@type":"SFInt32",
                            "@value":0
                          },
                          {
                            "@name":"frameCount",
                            "@accessType":"initializeOnly",
                            "@appinfo":"how many frames were created in current loop",
                            "@type":"SFFloat",
                            "@value":0
                          },
                          {
                            "@name":"startTime",
                            "@accessType":"initializeOnly",
                            "@appinfo":"holding variable",
                            "@type":"SFTime",
                            "@value":0
                          },
                          {
                            "@name":"priorTraceTime",
                            "@accessType":"initializeOnly",
                            "@appinfo":"holding variable",
                            "@type":"SFTime",
                            "@value":0
                          },
                          {
                            "@name":"traceEnabled",
                            "@accessType":"initializeOnly",
                            "@appinfo":"enable console output to trace script computations and prototype progress",
                            "@type":"SFBool"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"position",
                                "@protoField":"position"
                              },
                              {
                                "@nodeField":"orientation",
                                "@protoField":"orientation"
                              },
                              {
                                "@nodeField":"set_fraction",
                                "@protoField":"set_fraction"
                              },
                              {
                                "@nodeField":"set_bind",
                                "@protoField":"set_bind"
                              },
                              {
                                "@nodeField":"fieldOfView",
                                "@protoField":"fieldOfView"
                              },
                              {
                                "@nodeField":"nearClipPlane",
                                "@protoField":"nearClipPlane"
                              },
                              {
                                "@nodeField":"farClipPlane",
                                "@protoField":"farClipPlane"
                              },
                              {
                                "@nodeField":"shots",
                                "@protoField":"shots"
                              },
                              {
                                "@nodeField":"filterColor",
                                "@protoField":"filterColor"
                              },
                              {
                                "@nodeField":"filterTransparency",
                                "@protoField":"filterTransparency"
                              },
                              {
                                "@nodeField":"upVector",
                                "@protoField":"upVector"
                              },
                              {
                                "@nodeField":"fStop",
                                "@protoField":"fStop"
                              },
                              {
                                "@nodeField":"focusDistance",
                                "@protoField":"focusDistance"
                              },
                              {
                                "@nodeField":"isActive",
                                "@protoField":"isActive"
                              },
                              {
                                "@nodeField":"totalDuration",
                                "@protoField":"totalDuration"
                              },
                              {
                                "@nodeField":"offlineRender",
                                "@protoField":"offlineRender"
                              },
                              {
                                "@nodeField":"traceEnabled",
                                "@protoField":"traceEnabled"
                              }
                            ]
                        },
                        "#sourceText":[
"",
"          ",
"ecmascript:",
"function initialize () // CameraScript",
"{",
"//  tracePrint ('initialize start...');",
"",
"    NavInfoNode.avatarSize[0]   = nearClipPlane;",
"",
"    // remaining setups deferred to invocation of checkShots() method",
"    // thanks to Yvonne Jung Fraunhofer for diagnosing better approach to function initialization",
"    alwaysPrint ('initialize complete');",
"}",
"",
"function checkShots (eventValue)",
"{",
"    tracePrint ('checkShots() method should only occur after initialize() methods in all other Scripts are complete');",
"",
"    // compute totalDuration by summing durations from contained CameraShot and CameraMovement nodes",
"    totalDuration= 0;",
"    shotCount  = shots.length;",
"    movesCount = 0;",
"    for (i = 0; i < shotCount; i++) // shots index",
"    {",
"       tracePrint ('shots[' + i + '].moves.length=' + shots[i].moves.length);",
"       movesCount   += shots[i].moves.length;",
"       totalDuration = totalDuration + shots[i].shotDuration;",
"       if (shots[i].moves.length == 0)",
"       {",
"          alwaysPrint ('warning: CameraShot[' + i + '][' + shots[i].description + '] has no contained CameraMove nodes');",
"       }",
"    }",
"    // size checks before proceeding",
"    if (shotCount == 0)",
"    {",
"       alwaysPrint ('warning: no CameraShot nodes found for the shots, nothing to do!');",
"       return;",
"    }",
"    else if (movesCount == 0)",
"    {",
"       alwaysPrint ('warning: no CameraMove nodes found for the shots, nothing to do!');",
"       return;",
"    }",
"    else if (totalDuration == 0)",
"    {",
"       alwaysPrint ('warning: totalDuration = 0 seconds, nothing to do!');",
"       return;",
"    }",
"    tracePrint ('number of contained CameraShot nodes=' + shotCount);",
"    tracePrint ('number of contained CameraMove nodes=' + movesCount);",
"    tracePrint ('totalDuration=' + totalDuration + ' seconds for all shots and moves');",
"",
"    // compute interpolators",
"    var k = 0; // index for latest key, keyValuePosition, keyValueOrientation",
"    for (i = 0; i < shotCount; i++) // shots index",
"    {",
"        if (i==0) // initial entries",
"        {",
"           key[0]                   = 0.0; // no previous move",
"           keyValuePosition[0]      = shots[i].initialPosition;",
"           keyValueOrientation[0]   = shots[i].initialOrientation;",
"        }",
"        else     // new shot repositions, reorients camera as clean break from preceding shot/move",
"        {",
"           key[k+1]                 = key[k]; // start from end from previous move",
"           keyValuePosition[k+1]    = shots[i].initialPosition;",
"           keyValueOrientation[k+1] = shots[i].initialOrientation;",
"           k++;",
"        }",
"        tracePrint (shots[i].description);",
"        tracePrint ('shots[i].moves.length=' + shots[i].moves.length);",
"",
"        for (j = 0; j < shots[i].moves.length; j++) // moves index",
"        {",
"            var durationFloat =              shots[i].moves[j].duration;  // implicit type conversion from SFTime",
"            //  durationFloat = new SFFloat (shots[i].moves[j].duration); // explicit type conversion from SFTime",
"            //  tracePrint ('durationFloat=' + durationFloat);",
"            key[k+1]               = key[k] + (durationFloat / totalDuration);",
"            keyValuePosition[k+1]  = shots[i].moves[j].goalPosition;",
"            if (!animated)",
"            {",
"                 keyValueOrientation[k+1] = shots[i].moves[j].goalOrientation;",
"            }",
"            else",
"            {",
"                // using constructor SFRotation (SFVec3f fromVector, SFVec3f toVector)",
"                // see X3D ECMAScript binding Table 7.18 — SFRotation instance creation functions",
"",
"                // test if difference vector is zero, if so maintain previous rotation",
"                var shotVector = ViewpointNode.position.subtract(shots[i].moves[j].goalAimPoint).normalize();",
"                if (shotVector.length() >= 0)",
"                {",
"                    // default view direction is along -Z axis",
"                    shots[i].moves[j].goalOrientation = new SFRotation (new SFVec3f (0, 0, 1), shotVector);",
"                    keyValueOrientation[k+1] = shots[i].moves[j].goalOrientation;",
"                }",
"                else // note (k > 0)",
"                {",
"                    keyValueOrientation[k+1] = keyValueOrientation[k];  // no change",
"                }",
"",
"                tracePrint ('shots[' + i + '].moves[' + j + '].goalAimPoint=' + shots[i].moves[j].goalAimPoint.toString());",
"                tracePrint ('        ViewpointNode.position=' + ViewpointNode.position.toString());",
"                tracePrint ('          shotVector     delta=' + ViewpointNode.position.subtract(shots[i].moves[j].goalAimPoint).toString());",
"                tracePrint ('          shotVector normalize=' + ViewpointNode.position.subtract(shots[i].moves[j].goalAimPoint).normalize().toString());",
"                tracePrint ('               goalOrientation=' + shots[i].moves[j].goalOrientation.toString());",
"                tracePrint ('      keyValueOrientation[k+1]=' + keyValueOrientation[k+1].toString() + '\n');",
"            }",
"            k++; // update index to match latest key, keyValuePosition, keyValueOrientation",
"",
"            // check animated parameter:  set true if any of moves are tracking moves",
"            if (!animated)  animated = shots[i].moves[j].tracking; // once true, remains true",
"         // tracePrint ('shots[' + i + '].moves[' + j + '].tracking=' + shots[i].moves[j].tracking + ', animated=' + animated);",
"",
"            // intermediate trace",
"            tracePrint ('                key=' + key);",
"            tracePrint ('   keyValuePosition=' + keyValuePosition);",
"            tracePrint ('keyValueOrientation=' + keyValueOrientation);",
"            tracePrint ('- ' + shots[i].moves[j].description);",
"        }",
"    }",
"    tracePrint ('                key=' + key);",
"    tracePrint ('   keyValuePosition=' + keyValuePosition);",
"    tracePrint ('keyValueOrientation=' + keyValueOrientation);",
"    if (key.length != keyValuePosition.length)",
"    {",
"      alwaysPrint ('warning: internal error during array construction, ' +",
"                  'key.length=' + key.length + ' must equal ' +",
"                  'keyValuePosition.length=' + keyValuePosition.length);",
"    }",
"    if (key.length != keyValueOrientation.length)",
"    {",
"      alwaysPrint ('warning: internal error during array construction, ' +",
"                  'key.length=' + key.length + ' must equal ' +",
"                  'keyValueOrientation.length=' + keyValueOrientation.length);",
"    }",
"    if (key.length != (shotCount + movesCount))",
"    {",
"      alwaysPrint ('warning: internal error during array construction, ' +",
"                  'key.length=' + key.length + ' must equal ' +",
"                  '(shotCount + movesCount)=' + (shotCount + movesCount));",
"    }",
"    tracePrint ('           animated=' + animated);",
"    // set node values",
"    CameraPI.key      = key;",
"    CameraOI.key      = key;",
"    CameraPI.keyValue = keyValuePosition;",
"    CameraOI.keyValue = keyValueOrientation;",
"",
"    if (!animated) // output results",
"    {",
"        tracePrint ('<PositionInterpolator    DEF=\\'CameraPositionInterpolator\\'    key=\\'' + stripBrackets(CameraPI.key) + '\\' keyValue=\\'' + stripBrackets(CameraPI.keyValue) + '\\'/>');",
"        tracePrint ('<OrientationInterpolator DEF=\\'CameraOrientationInterpolator\\' key=\\'' + stripBrackets(CameraOI.key) + '\\' keyValue=\\'' + stripBrackets(CameraOI.keyValue) + '\\'/>');",
"    }",
"    tracePrint ('checkShots() complete');",
"}",
"",
"function stripBrackets (fieldArray)",
"{",
"    // some browsers add brackets to array output strings, this function strips them",
"    outputString = '';",
"    for (i = 0; i < fieldArray.length; i++)",
"    {",
"       outputString += fieldArray[i].toString();",
"       if (i < fieldArray.length - 1) outputString += ' ';",
"    }",
"    return outputString;",
"}",
"",
"function set_fraction (eventValue, timestamp) // input event received for inputOnly field",
"{",
"   // traceEnabled = false;  // for testing purposes",
"",
"   // if Camera is being animated, immediately recompute interpolator settings",
"   if (animated) checkShots (true);",
"",
"   // trace progress on console with reduced output frequency",
"   if (frameCount == 0)",
"   {",
"      alwaysPrint ('Animation loop commencing, timestamp=' + timestamp);",
"      startTime      = timestamp;",
"      priorTraceTime = timestamp;",
"      alwaysPrint ('shotClock=' + (timestamp - startTime) + ' seconds, frameCount=' + frameCount + ', fraction=' + eventValue + ', position=' + ViewpointNode.position.toString() + ', orientation=' + ViewpointNode.orientation.toString());",
"",
"      if (animated) // output results",
"      {",
"        // TODO how to report or speed up response?  alwaysPrint ('  aimPoint=' + aimPoint.toString());",
"        tracePrint ('  <PositionInterpolator    DEF=\\'CameraPositionInterpolator\\'    key=\\'' + stripBrackets(CameraPI.key) + '\\' keyValue=\\'' + stripBrackets(CameraPI.keyValue) + '\\'/>');",
"        tracePrint ('  <OrientationInterpolator DEF=\\'CameraOrientationInterpolator\\' key=\\'' + stripBrackets(CameraOI.key) + '\\' keyValue=\\'' + stripBrackets(CameraOI.keyValue) + '\\'/>');",
"      }",
"   }",
"   else if ((timestamp - priorTraceTime) >= 1.0) // 1 second trace interval",
"   {",
"      alwaysPrint ('shotClock=' + (timestamp - startTime) + ' seconds, frameCount=' + frameCount + ', fraction=' + eventValue + ', position=' + ViewpointNode.position.toString() + ', orientation=' + ViewpointNode.orientation.toString());",
"      priorTraceTime = timestamp;",
"",
"      if (animated) // output results",
"      {",
"        // TODO how to report or speed up response?  alwaysPrint ('  aimPoint=' + aimPoint.toString());",
"        tracePrint ('  <PositionInterpolator    DEF=\\'CameraPositionInterpolator\\'    key=\\'' + stripBrackets(CameraPI.key) + '\\' keyValue=\\'' + stripBrackets(CameraPI.keyValue) + '\\'/>');",
"        alwaysPrint ('  <OrientationInterpolator DEF=\\'CameraOrientationInterpolator\\' key=\\'' + stripBrackets(CameraOI.key) + '\\' keyValue=\\'' + stripBrackets(CameraOI.keyValue) + '\\'/>');",
"      }",
"   }",
"   if (eventValue == 0)",
"   {",
"      // note that zero value is not necessarily sent first by TimeSensor, so otherwise ignored",
"      frameCount++;",
"   }",
"   else if (eventValue == 1)",
"   {",
"      alwaysPrint ('shotClock=' + (timestamp - startTime) + ', frameCount=' + frameCount + ', fraction=' + eventValue + ', position=' + ViewpointNode.position.toString() + ', orientation=' + ViewpointNode.orientation.toString());",
"      if (animated) // output results",
"      {",
"        // TODO how to report or speed up response?  alwaysPrint ('  aimPoint=' + aimPoint.toString());",
"      }",
"      alwaysPrint ('Animation loop complete.');",
"      // do not unbind the Viewpoint and NavigationInfo nodes, let that be controlled externally",
"   }",
"   else",
"   {",
"      frameCount++;",
"   }",
"}",
"",
"function set_bind (eventValue) // input event received for inputOnly field",
"{",
"   // need to ensure CameraShot nodes are properly initialized",
"   if (initialized == false)",
"   {",
"      checkShots (true);",
"      initialized = true;",
"   }",
"   if (eventValue)",
"   {",
"       tracePrint ('Camera has been bound');",
"   }",
"   else",
"   {",
"       tracePrint ('Camera has been unbound');",
"   }",
"}",
"",
"function set_description (eventValue) // input event received for inputOutput field",
"{",
"    description = eventValue;",
"}",
"",
"function set_position (eventValue) // input event received for inputOutput field",
"{",
"    position = eventValue;",
"}",
"",
"function set_orientation (eventValue) // input event received for inputOutput field",
"{",
"    orientation = eventValue;",
"}",
"",
"function set_fieldOfView (eventValue) // input event received for inputOutput field",
"{",
"    fieldOfView = eventValue;",
"}",
"",
"function set_nearClipPlane (eventValue) // input event received for inputOutput field",
"{",
"    nearClipPlane = eventValue;",
"}",
"",
"function set_farClipPlane (eventValue) // input event received for inputOutput field",
"{",
"    farClipPlane = eventValue;",
"}",
"",
"function set_shots (eventValue) // input event received for inputOutput field",
"{",
"    shots = eventValue;",
"}",
"",
"function set_filterColor (eventValue) // input event received for inputOutput field",
"{",
"    filterColor = eventValue;",
"}",
"",
"function set_filterTransparency (eventValue) // input event received for inputOutput field",
"{",
"    filterTransparency = eventValue;",
"}",
"",
"function set_upVector (eventValue) // input event received for inputOutput field",
"{",
"    upVector = eventValue;",
"}",
"",
"function set_fStop (eventValue) // input event received for inputOutput field",
"{",
"    fStop = eventValue;",
"}",
"",
"function set_focusDistance (eventValue) // input event received for inputOutput field",
"{",
"    focusDistance = eventValue;",
"}",
"",
"function set_offlineRender (eventValue) // input event received for inputOutput field",
"{",
"    offlineRender = eventValue;",
"}",
"",
"function set_key (eventValue) // input event received for inputOutput field",
"{",
"    key = eventValue;",
"}",
"",
"function set_keyValuePosition (eventValue) // input event received for inputOutput field",
"{",
"    keyValuePosition = eventValue;",
"}",
"",
"function set_keyValueOrientation (eventValue) // input event received for inputOutput field",
"{",
"    keyValueOrientation = eventValue;",
"}",
"",
"function set_animated (eventValue) // input event received for inputOutput field",
"{",
"    animated = eventValue;",
"}",
"",
"function tracePrint (outputValue)",
"{",
"\tif (traceEnabled) alwaysPrint (outputValue);",
"}",
"function alwaysPrint (outputValue)",
"{",
"    // try to ensure outputValue is converted to string despite Browser.println idiosyncracies",
"    var outputString = outputValue.toString(); // utility function according to spec",
"    if (outputString == null) outputString = outputValue; // direct cast",
"",
"    if  (description.length > 0)",
"         Browser.print ('[Camera: ' + description + '] ' + outputString + '\n');",
"    else",
"         Browser.print ('[Camera] ' + outputString + '\n');",
"}"
]
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"position",
                        "@fromNode":"CameraScript",
                        "@toField":"position",
                        "@toNode":"CameraViewpoint"
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"orientation",
                        "@fromNode":"CameraScript",
                        "@toField":"orientation",
                        "@toNode":"CameraViewpoint"
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"isActive",
                        "@fromNode":"CameraScript",
                        "@toField":"set_bind",
                        "@toNode":"CameraViewpoint"
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"isActive",
                        "@fromNode":"CameraScript",
                        "@toField":"set_bind",
                        "@toNode":"CameraNavInfo"
                      }
                    },
                    { "ROUTE":
                      {
                        "@fromField":"isActive",
                        "@fromNode":"CameraScript",
                        "@toField":"on",
                        "@toNode":"CameraDirectionalLight"
                      }
                    }
                  ]
              }
            }
          },
          {
            "#comment":"=============== CameraShot =============="
          },
          { "ProtoDeclare":
            {
              "@name":"CameraShot",
              "@appinfo":"CameraShot collects a specific set of CameraMovement animations that make up an individual shot.",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"Text description to be displayed for this CameraShot",
                      "@type":"SFString"
                    },
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@appinfo":"Whether this CameraShot can be activated",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"moves",
                      "@accessType":"inputOutput",
                      "@appinfo":"Set of CameraMovement nodes",
                      "@type":"MFNode",
                      "-children":[
                        {
                          "#comment":"initializing CameraMovement nodes are inserted here by scene author using ProtoInstance"
                        }
                      ]
                    },
                    {
                      "@name":"initialPosition",
                      "@accessType":"inputOutput",
                      "@appinfo":"Setup to reinitialize camera position for this shot",
                      "@type":"SFVec3f",
                      "@value":[0,0,10]
                    },
                    {
                      "@name":"initialOrientation",
                      "@accessType":"inputOutput",
                      "@appinfo":"Setup to reinitialize camera rotation for this shot",
                      "@type":"SFRotation",
                      "@value":[0,0,1,0]
                    },
                    {
                      "@name":"initialAimPoint",
                      "@accessType":"inputOutput",
                      "@appinfo":"Setup to reinitialize aimpoint (relative location for camera direction) for this shot",
                      "@type":"SFVec3f",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"initialFieldOfView",
                      "@accessType":"inputOutput",
                      "@appinfo":"pi/4",
                      "@type":"SFFloat",
                      "@value":0.7854
                    },
                    {
                      "@name":"initialFStop",
                      "@accessType":"inputOutput",
                      "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                      "@type":"SFFloat",
                      "@value":5.6
                    },
                    {
                      "@name":"initialFocusDistance",
                      "@accessType":"inputOutput",
                      "@appinfo":"Distance to focal plane of sharpest focus",
                      "@type":"SFFloat",
                      "@value":10
                    },
                    {
                      "@name":"shotDuration",
                      "@accessType":"outputOnly",
                      "@appinfo":"Subtotal duration of contained CameraMovement move durations",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"isActive",
                      "@accessType":"outputOnly",
                      "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"traceEnabled",
                      "@accessType":"initializeOnly",
                      "@appinfo":"enable console output to trace script computations and prototype progress",
                      "@type":"SFBool",
                      "@value":false
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    { "Script":
                      {
                        "@DEF":"CameraShotScript",
                        "@directOutput":true,
                        "@mustEvaluate":true,
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"inputOutput",
                            "@appinfo":"Text description to be displayed for this CameraShot",
                            "@type":"SFString"
                          },
                          {
                            "@name":"enabled",
                            "@accessType":"inputOutput",
                            "@appinfo":"Whether this CameraShot can be activated",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"moves",
                            "@accessType":"inputOutput",
                            "@appinfo":"Set of CameraMovement nodes",
                            "@type":"MFNode",
                            "-children":[
                              {
                                "#comment":"initialization nodes (if any) go here"
                              }
                            ]
                          },
                          {
                            "@name":"initialPosition",
                            "@accessType":"inputOutput",
                            "@appinfo":"Setup to reinitialize camera position for this shot",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"initialOrientation",
                            "@accessType":"inputOutput",
                            "@appinfo":"Setup to reinitialize camera rotation for this shot",
                            "@type":"SFRotation"
                          },
                          {
                            "@name":"initialAimPoint",
                            "@accessType":"inputOutput",
                            "@appinfo":"Setup to reinitialize aimpoint (relative location for camera direction) for this shot",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"initialFieldOfView",
                            "@accessType":"inputOutput",
                            "@appinfo":"pi/4",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"initialFStop",
                            "@accessType":"inputOutput",
                            "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"initialFocusDistance",
                            "@accessType":"inputOutput",
                            "@appinfo":"Distance to focal plane of sharpest focus",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"shotDuration",
                            "@accessType":"outputOnly",
                            "@appinfo":"Subtotal duration of contained CameraMovement move durations",
                            "@type":"SFTime"
                          },
                          {
                            "@name":"isActive",
                            "@accessType":"outputOnly",
                            "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"traceEnabled",
                            "@accessType":"initializeOnly",
                            "@appinfo":"enable console output to trace script computations and prototype progress",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"key",
                            "@accessType":"inputOutput",
                            "@appinfo":"key array for interpolators",
                            "@type":"MFFloat"
                          },
                          {
                            "@name":"keyValuePosition",
                            "@accessType":"inputOutput",
                            "@appinfo":"keyValue array for PositionInterpolator",
                            "@type":"MFVec3f"
                          },
                          {
                            "@name":"keyValueOrientation",
                            "@accessType":"inputOutput",
                            "@appinfo":"keyValue array for OrientationInterpolator",
                            "@type":"MFRotation"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              },
                              {
                                "@nodeField":"moves",
                                "@protoField":"moves"
                              },
                              {
                                "@nodeField":"initialPosition",
                                "@protoField":"initialPosition"
                              },
                              {
                                "@nodeField":"initialOrientation",
                                "@protoField":"initialOrientation"
                              },
                              {
                                "@nodeField":"initialAimPoint",
                                "@protoField":"initialAimPoint"
                              },
                              {
                                "@nodeField":"initialFieldOfView",
                                "@protoField":"initialFieldOfView"
                              },
                              {
                                "@nodeField":"initialFStop",
                                "@protoField":"initialFStop"
                              },
                              {
                                "@nodeField":"initialFocusDistance",
                                "@protoField":"initialFocusDistance"
                              },
                              {
                                "@nodeField":"shotDuration",
                                "@protoField":"shotDuration"
                              },
                              {
                                "@nodeField":"isActive",
                                "@protoField":"isActive"
                              },
                              {
                                "@nodeField":"traceEnabled",
                                "@protoField":"traceEnabled"
                              }
                            ]
                        },
                        "#sourceText":[
"",
"          ",
"ecmascript:",
"function initialize () // CameraShotScript",
"{",
"//  tracePrint ('initialize start...');",
"",
"    // compute shotDuration by summing durations from contained CameraMovement nodes",
"    shotDuration = 0;",
"    for (i = 0; i < moves.length; i++)",
"    {",
"        shotDuration = shotDuration + moves[i].duration;",
"    }",
"    alwaysPrint ('number of contained CameraMove nodes=' + moves.length + ', shotDuration=' + shotDuration + ' seconds');",
"",
"//  tracePrint ('... initialize() complete');",
"}",
"",
"function set_description (eventValue) // input event received for inputOutput field",
"{",
"    description = eventValue;",
"}",
"",
"function set_enabled (eventValue) // input event received for inputOutput field",
"{",
"    enabled = eventValue;",
"}",
"",
"function set_moves (eventValue) // input event received for inputOutput field",
"{",
"    moves = eventValue;",
"}",
"",
"function set_initialPosition (eventValue) // input event received for inputOutput field",
"{",
"    initialPosition = eventValue;",
"}",
"",
"function set_initialOrientation (eventValue) // input event received for inputOutput field",
"{",
"    initialOrientation = eventValue;",
"}",
"",
"function set_initialAimPoint (eventValue) // input event received for inputOutput field",
"{",
"    initialAimPoint = eventValue;",
"}",
"",
"function set_initialFieldOfView (eventValue) // input event received for inputOutput field",
"{",
"    initialFieldOfView = eventValue;",
"}",
"",
"function set_initialFStop (eventValue) // input event received for inputOutput field",
"{",
"    initialFStop = eventValue;",
"}",
"",
"function set_initialFocusDistance (eventValue) // input event received for inputOutput field",
"{",
"    initialFocusDistance = eventValue;",
"}",
"",
"function set_key (eventValue) // input event received for inputOutput field",
"{",
"    key = eventValue;",
"}",
"",
"function set_keyValuePosition (eventValue) // input event received for inputOutput field",
"{",
"    keyValuePosition = eventValue;",
"}",
"",
"function set_keyValueOrientation (eventValue) // input event received for inputOutput field",
"{",
"    keyValueOrientation = eventValue;",
"}",
"",
"// TODO consider method set_active for constructed Camera node BooleanSequencer to send isActive",
"",
"function tracePrint (outputValue)",
"{",
"\tif (traceEnabled) alwaysPrint (outputValue);",
"}",
"function alwaysPrint (outputValue)",
"{",
"\t// try to ensure outputValue is converted to string despite browser idiosyncracies",
"    var outputString = outputValue.toString(); // utility function according to spec",
"    if (outputString == null) outputString = outputValue; // direct cast",
"",
"    if  (description.length > 0)",
"         Browser.print ('[CameraShot: ' + description + '] ' + outputString + '\n');",
"    else",
"         Browser.print ('[CameraShot] ' + outputString + '\n');",
"}"
]
                      }
                    },
                    {
                      "#comment":"Add any ROUTEs here, going from Script to other nodes within ProtoBody"
                    }
                  ]
              }
            }
          },
          {
            "#comment":"=============== CameraMovement =============="
          },
          { "ProtoDeclare":
            {
              "@name":"CameraMovement",
              "@appinfo":"CameraMovement node defines a single camera movement animation including goalPosition, goalOrientation, goalAimPoint and goalFieldOfView.",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"Text description to be displayed for this CameraMovement",
                      "@type":"SFString"
                    },
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@appinfo":"Whether this CameraMovement can be activated",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"duration",
                      "@accessType":"inputOutput",
                      "@appinfo":"Duration in seconds for this move",
                      "@type":"SFFloat",
                      "@value":0
                    },
                    {
                      "@name":"goalPosition",
                      "@accessType":"inputOutput",
                      "@appinfo":"Goal camera position for this move",
                      "@type":"SFVec3f",
                      "@value":[0,0,10]
                    },
                    {
                      "@name":"goalOrientation",
                      "@accessType":"inputOutput",
                      "@appinfo":"Goal camera rotation for this move",
                      "@type":"SFRotation",
                      "@value":[0,0,1,0]
                    },
                    {
                      "@name":"tracking",
                      "@accessType":"inputOutput",
                      "@appinfo":"Whether or not camera direction is tracking towards the aimPoint",
                      "@type":"SFBool",
                      "@value":false
                    },
                    {
                      "@name":"goalAimPoint",
                      "@accessType":"inputOutput",
                      "@appinfo":"Goal aimPoint for this move, ignored if tracking=false",
                      "@type":"SFVec3f",
                      "@value":[0,0,0]
                    },
                    {
                      "@name":"goalFieldOfView",
                      "@accessType":"inputOutput",
                      "@appinfo":"Goal fieldOfView for this move",
                      "@type":"SFFloat",
                      "@value":0.7854
                    },
                    {
                      "@name":"goalFStop",
                      "@accessType":"inputOutput",
                      "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                      "@type":"SFFloat",
                      "@value":5.6
                    },
                    {
                      "@name":"goalFocusDistance",
                      "@accessType":"inputOutput",
                      "@appinfo":"Distance to focal plane of sharpest focus",
                      "@type":"SFFloat",
                      "@value":10
                    },
                    {
                      "@name":"isActive",
                      "@accessType":"outputOnly",
                      "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"traceEnabled",
                      "@accessType":"initializeOnly",
                      "@appinfo":"enable console output to trace script computations and prototype progress",
                      "@type":"SFBool",
                      "@value":false
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    {
                      "#comment":"First node determines node type of this prototype"
                    },
                    {
                      "#comment":"Subsequent nodes do not render, but still must be a valid X3D subgraph"
                    },
                    {
                      "#comment":"Script holds CameraMovement initialization values for query by parent CameraShot, and also permits changing values via events"
                    },
                    { "Script":
                      {
                        "@DEF":"CameraMovementScript",
                        "@directOutput":true,
                        "@mustEvaluate":true,
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"inputOutput",
                            "@appinfo":"Text description to be displayed for this CameraMovement",
                            "@type":"SFString"
                          },
                          {
                            "@name":"enabled",
                            "@accessType":"inputOutput",
                            "@appinfo":"Whether this CameraMovement can be activated",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"duration",
                            "@accessType":"inputOutput",
                            "@appinfo":"Duration in seconds for this move",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"goalPosition",
                            "@accessType":"inputOutput",
                            "@appinfo":"Goal camera position for this move",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"goalOrientation",
                            "@accessType":"inputOutput",
                            "@appinfo":"Goal camera rotation for this move",
                            "@type":"SFRotation"
                          },
                          {
                            "@name":"tracking",
                            "@accessType":"inputOutput",
                            "@appinfo":"Whether or not camera direction is tracking towards the aimPoint",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"goalAimPoint",
                            "@accessType":"inputOutput",
                            "@appinfo":"Goal aimPoint for this move, ignored if tracking=false",
                            "@type":"SFVec3f"
                          },
                          {
                            "@name":"goalFieldOfView",
                            "@accessType":"inputOutput",
                            "@appinfo":"Goal fieldOfView for this move",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"goalFStop",
                            "@accessType":"inputOutput",
                            "@appinfo":"Focal length divided effective aperture diameter indicating width of focal plane",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"goalFocusDistance",
                            "@accessType":"inputOutput",
                            "@appinfo":"Distance to focal plane of sharpest focus",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"isActive",
                            "@accessType":"outputOnly",
                            "@appinfo":"Mark start/stop with true/false output respectively useful to trigger external animations",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"traceEnabled",
                            "@accessType":"initializeOnly",
                            "@appinfo":"enable console output to trace script computations and prototype progress",
                            "@type":"SFBool"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              },
                              {
                                "@nodeField":"duration",
                                "@protoField":"duration"
                              },
                              {
                                "@nodeField":"goalPosition",
                                "@protoField":"goalPosition"
                              },
                              {
                                "@nodeField":"goalOrientation",
                                "@protoField":"goalOrientation"
                              },
                              {
                                "@nodeField":"tracking",
                                "@protoField":"tracking"
                              },
                              {
                                "@nodeField":"goalAimPoint",
                                "@protoField":"goalAimPoint"
                              },
                              {
                                "@nodeField":"goalFieldOfView",
                                "@protoField":"goalFieldOfView"
                              },
                              {
                                "@nodeField":"goalFStop",
                                "@protoField":"goalFStop"
                              },
                              {
                                "@nodeField":"goalFocusDistance",
                                "@protoField":"goalFocusDistance"
                              },
                              {
                                "@nodeField":"isActive",
                                "@protoField":"isActive"
                              },
                              {
                                "@nodeField":"traceEnabled",
                                "@protoField":"traceEnabled"
                              }
                            ]
                        },
                        "#sourceText":[
"",
"          ",
"ecmascript:",
"function initialize () // CameraMovementScript",
"{",
"//  tracePrint ('initialize start...');",
"    alwaysPrint ('initialize goalPosition=' + goalPosition.toString() + ', goalOrientation=' + goalOrientation.toString() +",
"                           ', goalAimPoint=' + goalAimPoint.toString() // + ', tracking=' + tracking.toString()",
"                           );",
"    if (duration < 0)",
"    {",
"       alwaysPrint ('error: negative duration=' + duration + ', reset to 0 and ignored');",
"       duration = 0;",
"    }",
"    else if (duration == 0)",
"    {",
"       alwaysPrint ('warning: duration=0, nothing to do!');",
"    }",
"    tracePrint ('... initialize complete');",
"}",
"",
"function set_goalAimPoint (eventValue) // input event received for inputOutput field",
"{",
"    goalAimPoint_changed = eventValue;",
"    tracePrint ('goalAimPoint=' + goalAimPoint.toString());",
"",
"    // updated goalOrientation tracking is handled by Camera recomputing the OrientationInterpolator",
"}",
"",
"function set_description (eventValue) // input event received for inputOutput field",
"{",
"    description = eventValue;",
"}",
"",
"function set_enabled (eventValue) // input event received for inputOutput field",
"{",
"    enabled = eventValue;",
"}",
"",
"function set_duration (eventValue) // input event received for inputOutput field",
"{",
"    duration = eventValue;",
"}",
"",
"function set_goalPosition (eventValue) // input event received for inputOutput field",
"{",
"    goalPosition = eventValue;",
"}",
"",
"function set_goalOrientation (eventValue) // input event received for inputOutput field",
"{",
"    goalOrientation = eventValue;",
"}",
"",
"function set_tracking (eventValue) // input event received for inputOutput field",
"{",
"    tracking = eventValue;",
"}",
"",
"function set_goalFieldOfView (eventValue) // input event received for inputOutput field",
"{",
"    goalFieldOfView = eventValue;",
"}",
"",
"function set_goalFStop (eventValue) // input event received for inputOutput field",
"{",
"    goalFStop = eventValue;",
"}",
"",
"function set_goalFocusDistance (eventValue) // input event received for inputOutput field",
"{",
"    goalFocusDistance = eventValue;",
"}",
"",
"// TODO consider method set_active for constructed Camera node BooleanSequencer to send isActive",
"",
"function tracePrint (outputValue)",
"{",
"\tif (traceEnabled) alwaysPrint (outputValue);",
"}",
"",
"function alwaysPrint (outputValue)",
"{",
"\t// try to ensure outputValue is converted to string despite browser idiosyncracies",
"    var outputString = outputValue.toString(); // utility function according to spec",
"    if (outputString == null) outputString = outputValue; // direct cast",
"",
"    if  (description.length > 0)",
"         Browser.print ('[CameraMovement: ' + description + '] ' + outputString + '\n');",
"    else",
"         Browser.print ('[CameraMovement] ' + outputString + '\n');",
"}"
]
                      }
                    },
                    {
                      "#comment":"Add any ROUTEs here, going from Script to other nodes within ProtoBody"
                    }
                  ]
              }
            }
          },
          {
            "#comment":"=============== OfflineRender =============="
          },
          { "ProtoDeclare":
            {
              "@name":"OfflineRender",
              "@appinfo":"OfflineRender defines a parameters for offline rendering of Camera animation output to a movie file (or possibly a still shot).",
              "ProtoInterface": {
                  "-children":[
                    {
                      "#comment":"TODO non-photorealistic rendering (NPR) parameters"
                    }
                  ],
                  "field": [
                    {
                      "@name":"description",
                      "@accessType":"inputOutput",
                      "@appinfo":"Text description to be displayed for this OfflineRender",
                      "@type":"SFString"
                    },
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@appinfo":"Whether this OfflineRender can be activated",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"frameRate",
                      "@accessType":"inputOutput",
                      "@appinfo":"Frames per second recorded for this rendering",
                      "@type":"SFFloat",
                      "@value":30
                    },
                    {
                      "@name":"frameSize",
                      "@accessType":"inputOutput",
                      "@appinfo":"Size of frame in number of pixels width and height",
                      "@type":"SFVec2f",
                      "@value":[640,480]
                    },
                    {
                      "@name":"pixelAspectRatio",
                      "@accessType":"inputOutput",
                      "@appinfo":"Relative dimensions of pixel height/width typically 1.33 or 1",
                      "@type":"SFFloat",
                      "@value":1.33
                    },
                    {
                      "@name":"set_startTime",
                      "@accessType":"inputOnly",
                      "@appinfo":"Begin render operation",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"progress",
                      "@accessType":"outputOnly",
                      "@appinfo":"Progress performing render operation (0..1)",
                      "@type":"SFFloat"
                    },
                    {
                      "@name":"renderCompleteTime",
                      "@accessType":"outputOnly",
                      "@appinfo":"Render operation complete",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"movieFormat",
                      "@accessType":"initializeOnly",
                      "@appinfo":"Format of rendered output movie (mpeg mp4 etc.), use first supported format",
                      "@type":"MFString",
                      "@value":["mpeg"]
                    },
                    {
                      "@name":"imageFormat",
                      "@accessType":"initializeOnly",
                      "@appinfo":"Format of rendered output images (png jpeg gif tiff etc.) use first supported format",
                      "@type":"MFString",
                      "@value":["png"]
                    },
                    {
                      "@name":"traceEnabled",
                      "@accessType":"initializeOnly",
                      "@appinfo":"enable console output to trace script computations and prototype progress",
                      "@type":"SFBool",
                      "@value":false
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    {
                      "#comment":"First node determines node type of this prototype"
                    },
                    {
                      "#comment":"Subsequent nodes do not render, but still must be a valid X3D subgraph"
                    },
                    { "Script":
                      {
                        "@DEF":"OfflineRenderScript",
                        "@mustEvaluate":true,
                        "field": [
                          {
                            "@name":"description",
                            "@accessType":"inputOutput",
                            "@appinfo":"Text description to be displayed for this OfflineRender",
                            "@type":"SFString"
                          },
                          {
                            "@name":"enabled",
                            "@accessType":"inputOutput",
                            "@appinfo":"Whether this OfflineRender can be activated",
                            "@type":"SFBool"
                          },
                          {
                            "@name":"frameRate",
                            "@accessType":"inputOutput",
                            "@appinfo":"Frames per second recorded for this rendering",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"frameSize",
                            "@accessType":"inputOutput",
                            "@appinfo":"Size of frame in number of pixels width and height",
                            "@type":"SFVec2f"
                          },
                          {
                            "@name":"pixelAspectRatio",
                            "@accessType":"inputOutput",
                            "@appinfo":"Relative dimensions of pixel height/width typically 1.33 or 1",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"set_startTime",
                            "@accessType":"inputOnly",
                            "@appinfo":"Begin render operation",
                            "@type":"SFTime"
                          },
                          {
                            "@name":"progress",
                            "@accessType":"outputOnly",
                            "@appinfo":"Progress performing render operation (0..1)",
                            "@type":"SFFloat"
                          },
                          {
                            "@name":"renderCompleteTime",
                            "@accessType":"outputOnly",
                            "@appinfo":"Render operation complete",
                            "@type":"SFTime"
                          },
                          {
                            "@name":"movieFormat",
                            "@accessType":"initializeOnly",
                            "@appinfo":"Format of rendered output movie (mpeg mp4 etc.)",
                            "@type":"MFString"
                          },
                          {
                            "@name":"imageFormat",
                            "@accessType":"initializeOnly",
                            "@appinfo":"Format of rendered output images (png jpeg gif tiff etc.)",
                            "@type":"MFString"
                          },
                          {
                            "@name":"traceEnabled",
                            "@accessType":"initializeOnly",
                            "@appinfo":"enable console output to trace script computations and prototype progress",
                            "@type":"SFBool"
                          }
                        ],
                        "IS": {
                            "connect": [
                              {
                                "@nodeField":"description",
                                "@protoField":"description"
                              },
                              {
                                "@nodeField":"enabled",
                                "@protoField":"enabled"
                              },
                              {
                                "@nodeField":"frameRate",
                                "@protoField":"frameRate"
                              },
                              {
                                "@nodeField":"frameSize",
                                "@protoField":"frameSize"
                              },
                              {
                                "@nodeField":"pixelAspectRatio",
                                "@protoField":"pixelAspectRatio"
                              },
                              {
                                "@nodeField":"set_startTime",
                                "@protoField":"set_startTime"
                              },
                              {
                                "@nodeField":"progress",
                                "@protoField":"progress"
                              },
                              {
                                "@nodeField":"renderCompleteTime",
                                "@protoField":"renderCompleteTime"
                              },
                              {
                                "@nodeField":"movieFormat",
                                "@protoField":"movieFormat"
                              },
                              {
                                "@nodeField":"imageFormat",
                                "@protoField":"imageFormat"
                              },
                              {
                                "@nodeField":"traceEnabled",
                                "@protoField":"traceEnabled"
                              }
                            ]
                        },
                        "#sourceText":[
"",
"          ",
"ecmascript:",
"function initialize () // OfflineRenderScript",
"{",
"//  tracePrint ('initialize start...');",
"",
"    tracePrint ('... initialize complete');",
"}",
"",
"function set_description (eventValue) // input event received for inputOutput field",
"{",
"    description = eventValue;",
"}",
"",
"function set_enabled (eventValue) // input event received for inputOutput field",
"{",
"    enabled = eventValue;",
"}",
"",
"function set_frameRate (eventValue) // input event received for inputOutput field",
"{",
"    frameRate = eventValue;",
"}",
"",
"function set_frameSize (eventValue) // input event received for inputOutput field",
"{",
"    frameSize = eventValue;",
"}",
"",
"function set_pixelAspectRatio (eventValue) // input event received for inputOutput field",
"{",
"    pixelAspectRatio = eventValue;",
"}",
"",
"function set_startTime (eventValue) // input event received for inputOnly field",
"{",
"   // do something with input eventValue;",
"}",
"",
"function tracePrint (outputValue)",
"{",
"\tif (traceEnabled) alwaysPrint (outputValue);",
"}",
"",
"function alwaysPrint (outputValue)",
"{",
"\t// try to ensure outputValue is converted to string despite browser idiosyncracies",
"    var outputString = outputValue.toString(); // utility function according to spec",
"    if (outputString == null) outputString = outputValue; // direct cast",
"",
"    if  (description.length > 0)",
"         Browser.print ('[OfflineRender: ' + description + '] ' + outputString + '\n');",
"    else",
"         Browser.print ('[OfflineRender] ' + outputString + '\n');",
"}"
]
                      }
                    },
                    {
                      "#comment":"Add any ROUTEs here, going from Script to other nodes within ProtoBody"
                    }
                  ]
              }
            }
          },
          {
            "#comment":"=============== Launch Prototype Example =============="
          },
          { "Background":
            {
              "@skyColor":[0.282353,0.380392,0.470588]
            }
          },
          { "Anchor":
            {
              "@description":"launch CameraExample scene",
              "@url":["CameraExamples.x3d","http://www.web3d.org/x3d/content/examples/Basic/development/CameraExamples.x3d","CameraExamples.wrl","http://www.web3d.org/x3d/content/examples/Basic/development/CameraExamples.wrl"],
              "-children":[
                { "Transform":
                  {
                    "-children":[
                      { "Shape":
                        {
                          "-geometry":
                            { "Text":
                              {
                                "@string":["CameraPrototypes.x3d","defines multiple prototype nodes","","Click on this text to see","CameraExamples.x3d scene"],
                                "-fontStyle":
                                  { "FontStyle":
                                    {
                                      "@justify":["MIDDLE","MIDDLE"]
                                    }
                                  }
                              }
                            },
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@diffuseColor":[1,1,0.2]
                                    }
                                  }
                              }
                            }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        ]
    }
  }
}


More information about the x3d-public mailing list