[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 \"\"\" 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