{ "X3D": {
    "encoding":"UTF-8",
    "@profile":"Immersive",
    "@version":"3.3",
    "@xsd:noNamespaceSchemaLocation":"https://www.web3d.org/specifications/x3d-3.3.xsd",
    "JSON schema":"https://www.web3d.org/specifications/x3d-4.0-JSONSchema.autogenerated.json",
    "head": {
        "meta": [
          {
            "@name":"title",
            "@content":"BindingOperations.x3d"
          },
          {
            "@name":"description",
            "@content":"Illustrate Viewpoint binding operations (in gory detail!) as described in Chapter 4 concepts. Scene design: a TimeSensor clock drives and IntegerSequencer for each t0/t1/etc. event, and a customized Script node sends bind/unbind events to the correct Viewpoint. Display the browser console to see occurrence of each event."
          },
          {
            "@name":"creator",
            "@content":"Don Brutzman"
          },
          {
            "@name":"created",
            "@content":"5 January 2008"
          },
          {
            "@name":"modified",
            "@content":"4 August 2024"
          },
          {
            "@name":"reference",
            "@content":"BindingOperations.console.txt"
          },
          {
            "@name":"reference",
            "@content":"BindingStackOperations.png"
          },
          {
            "@name":"reference",
            "@content":"X3D for Web Authors, Section 2.5.1, Figure 4.1"
          },
          {
            "@name":"reference",
            "@content":"https://X3dGraphics.com"
          },
          {
            "@name":"reference",
            "@content":"https://www.web3d.org/x3d/content/examples/X3dResources.html"
          },
          {
            "@name":"rights",
            "@content":"Copyright Don Brutzman and Leonard Daly 2007"
          },
          {
            "@name":"subject",
            "@content":"X3D book, X3D graphics, X3D-Edit, http://www.x3dGraphics.com"
          },
          {
            "@name":"identifier",
            "@content":"https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter04ViewingNavigation/BindingOperations.x3d"
          },
          {
            "@name":"generator",
            "@content":"X3D-Edit 4.0, https://www.web3d.org/x3d/tools/X3D-Edit"
          },
          {
            "@name":"license",
            "@content":"../license.html"
          },
          {
            "@name":"translated",
            "@content":"17 April 2026"
          },
          {
            "@name":"generator",
            "@content":"X3dToJson.xslt, https://www.web3d.org/x3d/stylesheets/X3dToJson.html"
          },
          {
            "@name":"reference",
            "@content":"X3D JSON encoding: https://www.web3d.org/wiki/index.php/X3D_JSON_Encoding"
          }
        ]
    },
    "Scene": {
        "-children":[
          { "WorldInfo":
            {
              "@title":"BindingOperations.x3d"
            }
          },
          { "Viewpoint":
            {
              "@DEF":"View1",
              "@centerOfRotation":[-6,0,0],
              "@description":"Viewpoint 1",
              "@position":[-6,0,5]
            }
          },
          { "Viewpoint":
            {
              "@DEF":"View2",
              "@centerOfRotation":[-2,0,0],
              "@description":"Viewpoint 2",
              "@position":[-2,0,5]
            }
          },
          { "Viewpoint":
            {
              "@DEF":"View3",
              "@centerOfRotation":[2,0,0],
              "@description":"Viewpoint 3",
              "@position":[2,0,5]
            }
          },
          { "Viewpoint":
            {
              "@DEF":"View4",
              "@centerOfRotation":[6,0,0],
              "@description":"Viewpoint 4",
              "@position":[6,0,5]
            }
          },
          {
            "#comment":"Script initialization ought to first bind view5 below."
          },
          { "Group":
            {
              "-children":[
                { "Transform":
                  {
                    "@DEF":"Text1",
                    "@translation":[-6,0,0],
                    "-children":[
                      { "Shape":
                        {
                          "-geometry":
                            { "Text":
                              {
                                "@string":["View","# 1"],
                                "-fontStyle":
                                  { "FontStyle":
                                    {
                                      "@DEF":"CenterJustify",
                                      "@justify":["MIDDLE","MIDDLE"]
                                    }
                                  }
                              }
                            },
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@diffuseColor":[1,0,0]
                                    }
                                  }
                              }
                            }
                        }
                      }
                    ]
                  }
                },
                { "Transform":
                  {
                    "@DEF":"Text2",
                    "@translation":[-2,0,0],
                    "-children":[
                      { "Shape":
                        {
                          "-geometry":
                            { "Text":
                              {
                                "@string":["View","# 2"],
                                "-fontStyle":
                                  { "FontStyle":
                                    {
                                      "@USE":"CenterJustify"
                                    }
                                  }
                              }
                            },
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@diffuseColor":[0,1,0]
                                    }
                                  }
                              }
                            }
                        }
                      }
                    ]
                  }
                },
                { "Transform":
                  {
                    "@DEF":"Text3",
                    "@translation":[2,0,0],
                    "-children":[
                      { "Shape":
                        {
                          "-geometry":
                            { "Text":
                              {
                                "@string":["View","# 3"],
                                "-fontStyle":
                                  { "FontStyle":
                                    {
                                      "@USE":"CenterJustify"
                                    }
                                  }
                              }
                            },
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                      "@diffuseColor":[0,0,1]
                                    }
                                  }
                              }
                            }
                        }
                      }
                    ]
                  }
                },
                { "Transform":
                  {
                    "@DEF":"Text4",
                    "@translation":[6,0,0],
                    "-children":[
                      { "Shape":
                        {
                          "-geometry":
                            { "Text":
                              {
                                "@string":["View","# 4"],
                                "-fontStyle":
                                  { "FontStyle":
                                    {
                                      "@USE":"CenterJustify"
                                    }
                                  }
                              }
                            },
                          "-appearance":
                            { "Appearance":
                              {
                                "-material":
                                  { "Material":
                                    {
                                    }
                                  }
                              }
                            }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          {
            "#comment":"The following advanced animation sequence uses nodes covered in Chapters 7, 8 and 9."
          },
          {
            "#comment":"It does not need to be studied in this chapter."
          },
          { "Transform":
            {
              "@translation":[0,-3,8],
              "-children":[
                {
                  "#comment":"notice this next Viewpoint has been transformed with the text, so its position is relative. it is called view5 in the Script."
                },
                { "Viewpoint":
                  {
                    "@DEF":"ClickToAnimateView",
                    "@description":"Select animation sequence",
                    "@position":[0,0,7]
                  }
                },
                { "Shape":
                  {
                    "-geometry":
                      { "Text":
                        {
                          "@string":["Click here to animate"],
                          "-fontStyle":
                            { "FontStyle":
                              {
                                "@justify":["MIDDLE","BEGIN"]
                              }
                            }
                        }
                      },
                    "-appearance":
                      { "Appearance":
                        {
                          "-material":
                            { "Material":
                              {
                                "@diffuseColor":[0.8,0.4,0]
                              }
                            }
                        }
                      }
                  }
                },
                { "Shape":
                  {
                    "-geometry":
                      { "Box":
                        {
                          "@size":[7,1,0.02]
                        }
                      },
                    "-appearance":
                      { "Appearance":
                        {
                          "-material":
                            { "Material":
                              {
                                "@transparency":1
                              }
                            }
                        }
                      }
                  }
                },
                { "TouchSensor":
                  {
                    "@DEF":"TextTouchSensor",
                    "@description":"Click to begin animating viewpoint selections"
                  }
                },
                { "TimeSensor":
                  {
                    "@DEF":"Clock",
                    "@cycleInterval":10
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"touchTime",
                    "@fromNode":"TextTouchSensor",
                    "@toField":"set_startTime",
                    "@toNode":"Clock"
                  }
                },
                { "IntegerSequencer":
                  {
                    "@DEF":"TimingSequencer",
                    "@key":[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,1.0],
                    "@keyValue":[0,1,2,3,4,5,6,7,8,10]
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"fraction_changed",
                    "@fromNode":"Clock",
                    "@toField":"set_fraction",
                    "@toNode":"TimingSequencer"
                  }
                },
                { "Script":
                  {
                    "@DEF":"BindingSequencerEngine",
                    "field": [
                      {
                        "@name":"set_timeEvent",
                        "@accessType":"inputOnly",
                        "@type":"SFInt32"
                      },
                      {
                        "@name":"bindView1",
                        "@accessType":"outputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"bindView2",
                        "@accessType":"outputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"bindView3",
                        "@accessType":"outputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"bindView4",
                        "@accessType":"outputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"bindView5",
                        "@accessType":"outputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"view1Bound",
                        "@accessType":"inputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"view2Bound",
                        "@accessType":"inputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"view3Bound",
                        "@accessType":"inputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"view4Bound",
                        "@accessType":"inputOnly",
                        "@type":"SFBool"
                      },
                      {
                        "@name":"priorInputvalue",
                        "@accessType":"initializeOnly",
                        "@type":"SFInt32",
                        "@value":-1
                      }
                    ],
                    "#sourceCode":[
"",
"",
"ecmascript:",
"",
"function initialize ()",
"{",
"    bindView5 = true;",
"    Browser.println ('Timing script initialized and ready for activation');",
"}",
"function set_timeEvent (inputValue)",
"{",
"    if (inputValue == priorInputvalue)",
"    {",
"        return; // ignore repeated inputs",
"    }",
"    // new value provided",
"    priorInputvalue = inputValue;",
"    // Browser.println ('timeEvent inputValue=' + inputValue);",
"",
"    // mimics user execution of Figure 4.1 steps t_0 through t_8",
"    if (inputValue == 0)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t0');",
"        bindView1 = true;",
"    }",
"    else if (inputValue == 1)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t1');",
"        bindView2 = true;",
"    }",
"    else if (inputValue == 2)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t2');",
"        bindView3 = true;",
"    }",
"    else if (inputValue == 3)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t3');",
"        bindView3 = false;",
"    }",
"    else if (inputValue == 4)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t4');",
"        bindView1 = true;",
"    }",
"    else if (inputValue == 5)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t5');",
"        bindView2 = false;",
"    }",
"    else if (inputValue == 6)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t6');",
"        bindView1 = false;",
"    }",
"    else if (inputValue == 7)",
"    {",
"        Browser.println ('===========');",
"        Browser.println ('time t7');",
"        bindView4 = true;",
"",
"    }",
"    else if (inputValue == 8)",
"    {",
"        Browser.println ();",
"        Browser.println ('===========');",
"        Browser.println ('time t8, no action, all done');",
"    }",
"}",
"",
"function view1Bound (inputValue)",
"{",
"    Browser.println (', view1Bound ' + (inputValue));",
"    if (priorInputvalue == -1) Browser.println ();",
"}",
"function view2Bound (inputValue)",
"{",
"    Browser.println (', view2Bound ' + (inputValue));",
"}",
"function view3Bound (inputValue)",
"{",
"    Browser.println (', view3Bound ' + (inputValue));",
"}",
"function view4Bound (inputValue)",
"{",
"    Browser.println (', view4Bound ' + (inputValue));",
"}",
"function view5Bound (inputValue)",
"{",
"    Browser.println (', view5Bound ' + (inputValue));",
"}",
"",
""
]
                  }
                },
                {
                  "#comment":"drive Script with TimeSensor clock"
                },
                { "ROUTE":
                  {
                    "@fromField":"value_changed",
                    "@fromNode":"TimingSequencer",
                    "@toField":"set_timeEvent",
                    "@toNode":"BindingSequencerEngine"
                  }
                },
                {
                  "#comment":"Script will bind and unbind Viewpoint nodes"
                },
                { "ROUTE":
                  {
                    "@fromField":"bindView1",
                    "@fromNode":"BindingSequencerEngine",
                    "@toField":"set_bind",
                    "@toNode":"View1"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"bindView2",
                    "@fromNode":"BindingSequencerEngine",
                    "@toField":"set_bind",
                    "@toNode":"View2"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"bindView3",
                    "@fromNode":"BindingSequencerEngine",
                    "@toField":"set_bind",
                    "@toNode":"View3"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"bindView4",
                    "@fromNode":"BindingSequencerEngine",
                    "@toField":"set_bind",
                    "@toNode":"View4"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"bindView5",
                    "@fromNode":"BindingSequencerEngine",
                    "@toField":"set_bind",
                    "@toNode":"ClickToAnimateView"
                  }
                },
                {
                  "#comment":"Viewpoint nodes report bind and unbind events to Script for recording results"
                },
                { "ROUTE":
                  {
                    "@fromField":"isBound",
                    "@fromNode":"View1",
                    "@toField":"view1Bound",
                    "@toNode":"BindingSequencerEngine"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"isBound",
                    "@fromNode":"View2",
                    "@toField":"view2Bound",
                    "@toNode":"BindingSequencerEngine"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"isBound",
                    "@fromNode":"View3",
                    "@toField":"view3Bound",
                    "@toNode":"BindingSequencerEngine"
                  }
                },
                { "ROUTE":
                  {
                    "@fromField":"isBound",
                    "@fromNode":"View4",
                    "@toField":"view4Bound",
                    "@toNode":"BindingSequencerEngine"
                  }
                },
                {
                  "#comment":"Note that Script inputs do not cause Script outputs, and therefore no event loops occur."
                },
                {
                  "#comment":"It is possible to silence event-loop diagnostic warnings by separating the functionality of Script inputs and outputs into two separate Script nodes."
                }
              ]
            }
          }
        ]
    }
  }
}