next last content

7. Examples

This chapter will discuss a two examples in detail to illustrate the use of net nodes and SharedObjects.

NetworkState Nodes

The example shows a green sphere which rotates 360 degrees when clicked. This is not very interesting in a single world alone, but because we use a net node to transmit the starting event, other users sharing this world with you will see it rotate and can also start it. Here is a link to the example world.

Now we take a look at the source code.

#VRML V2.0 utf8

# the PROTO of the NetworkSFBool node for transmitting SFBool events
PROTO NetworkSFBool [
  eventIn SFBool set_value
  eventOut SFBool value_changed
  eventIn SFBool value_fromnet
  eventOut SFBool value_tonet
  exposedField SFString tag       ""
  exposedField SFBool   pilotOnly TRUE
  field SFBool   localCopy TRUE
  exposedField SFBool   echo      TRUE
  exposedField SFBool   cont      FALSE
]
{
  Script {
    eventIn SFBool InSc IS set_value
    eventOut SFBool OutSc IS value_changed
    eventIn SFBool netInSc IS value_fromnet
    eventOut SFBool netOutSc IS value_tonet
    field SFBool local IS localCopy

    directOutput TRUE
    mustEvaluate TRUE

    url "javascript:
      function InSc(value) {
        netOutSc = value;
        if( local == true )
          OutSc = value;
      }
      function netInSc(value) {
        OutSc = value;
      }
    "
  }
}

First we have the PROTO node defining the net node NetworkSFBool used for transmitting SFBool events. It is taken from the matrix_protos.wrl file defining all net nodes implemented yet.

# the central Group node holding all information for the Matrix System
DEF MATRIX_CORE Group {
  children [
    DEF MATRIX_TRACKER ProximitySensor {
      size 100000 100000 100000
    },
    Viewpoint { position 0 1 10 },
    DEF NET NetworkSFBool { tag "bool" },
    NavigationInfo {
    speed 5
      },
    Background {
      skyColor    [ 0.9 0.9 0.9 ]
      groundColor [ 0.1 0.1 0.6 ]
    },
  ]
}

Then there is the Group node MATRIX_CORE with a number of child nodes. First the ProximitySensor node used to track the users position and orientation. Then a Viewpoint, NavigationInfo and Background node setting some properties of the world. And finally an instantiation of the net node NetworkSFBool. It sends its events to any node named bool, in this case to all copies of itself.

DEF GREENBALL Transform {
  translation 0 0 0
  children [
    DEF TOUCH TouchSensor{},
                DEF TIMER TimeSensor {
            loop  FALSE
            cycleInterval 5
    },
          DEF ENGINE OrientationInterpolator {
          key [ 0, .5, 1]
        keyValue [ 0 1 0 0, 0 1 0 3.14, 0 1 0 6.28]
          },
    Shape {
      appearance Appearance {
            material Material { diffuseColor 0 1 0 }
      }
        geometry Sphere { radius 1.5 }
        }
  ]
}

DEF CONTROLLER Script {
  eventIn SFBool start
  eventOut SFTime startTime
  url ["javascript:
    function start( value, time ){
      if( value == TRUE )
        startTime = time;
    }
  "]
}

Then there is some geometry defining a green sphere and a TouchSensor. Finally we have a simple script node which takes a SFBool event and puts out the events time stamp as a SFTime event.

ROUTE TOUCH.isActive TO NET.set_value
ROUTE NET.value_changed TO CONTROLLER.start
ROUTE CONTROLLER.startTime TO TIMER.set_startTime
ROUTE TIMER.fraction_changed TO ENGINE.set_fraction
ROUTE ENGINE.value_changed TO GREENBALL.set_rotation

All these nodes are connected with these ROUTEs. If a user clicks on the green sphere an SFBool event is send from the TouchSensor to the net node. The net node sends it to the controller script which generates an SFTime node with the time stamp of the SFBool event and sends it to the startTime exposedField of the TimeSensor node. This starts the TimeSensor which generates fraction_changed events turning the sphere with the help of an orientationInterpolator node. this is basic VRML stuff.

But the net node also transmits an event to other client applets running the same world. There the copies of this node generate also SFBool events to the controller script, thus starting the animation in all copies simultaneously.

SharedObject

This example describes a little SharedObject acts like a simple whiteboard displaying three different textures. The displayed texture can be selected by clicking on one of three buttons below the board. This object can be loaded into any DeepMatrix world by a user and all users can then work with it and change the texture by clicking the buttons.

The following VRML file defines the SharedObject. You can find this file here board.wrl.

#VRML V2.0 utf8

PROTO NetworkSFInt32 [
  eventIn SFInt32 set_value
  eventOut SFInt32 value_changed
  eventIn SFInt32 value_fromnet
  eventOut SFInt32 value_tonet
  exposedField SFString tag       ""
  exposedField SFBool   pilotOnly TRUE
  field SFBool   localCopy TRUE
  exposedField SFBool   echo      TRUE
  exposedField SFBool   cont      FALSE
]
{
...
}

# SharedObject PROTO
PROTO SharedObject
[
 exposedField    SFBool        isPilot            TRUE
 exposedField    SFString      name               ""
 exposedField    MFNode        children           []
 exposedField    SFVec3f       position           0 0 0
 exposedField    SFRotation    orientation        0 0 1 0
 eventIn         SFBool        set_isVisible
 eventOut        SFBool        isVisible_changed
 exposedField    MFString      url                []
 exposedField    SFBool        isAvatar           FALSE
 exposedField    MFNode        states             []
]
{
...
}

First we define all the PROTOs that we need. In this case this is the NetworkSFInt32 NetworkState to share the value of a whichChoice field in a switch node. And the SharedObject PROTO for the object definition itself. Then we start with the object definition.

SharedObject {
	children [  # Here goes the geometry
  DEF SW Switch {
    whichChoice 0
    choice [
      Transform {
        children Shape {
    	  appearance Appearance {
            texture ImageTexture {
	      repeatS TRUE
	      repeatT TRUE
	      url     "grass0.jpg"
            }
          }
          geometry Box {
            size 2 2 0.1
          }
        }
      translation	0 2 0
    },
    Transform {
      children Shape {
        appearance Appearance {
          texture ImageTexture {
	    repeatS TRUE
	    repeatT TRUE
	    url     "leaf0.gif"
          }
        }
        geometry Box {
          size 2 2 0.1
        }
      }
      translation	0 2 0
    },
    Transform {
      children Shape {
        appearance Appearance {
          texture ImageTexture {
	    repeatS TRUE
	    repeatT TRUE
	    url    "sky0.gif"
          }
        }
        geometry Box {
          size 2 2 0.1
        }
      }
      translation	0 2 0
    }
  ]
} # switch end
Transform {
  children [	Shape {
    appearance	Appearance {
      material	Material {
	specularColor	0.9 0.9 0.9
	emissiveColor	1 0 0
      }
    }
    geometry	Box {
      size	0.5 0.5 0.1
    }
  },
  DEF Button1 TouchSensor {}
  ]
  translation -0.75 0.467181 0
}
Transform {
  children	[ Shape {
    appearance	Appearance {
      material	Material {
	specularColor	0.31 0.77 0.8
	emissiveColor	0 0.87 0
	shininess	0.03
      }
    }
    geometry	Box {
      size	0.5 0.5 0.1
    }
  },
  DEF Button2 TouchSensor {}
  ]

  translation	0 0.45306 1.3411e-007
}
Transform {
  children	[ Shape {
    appearance	Appearance {
      material	Material {
	specularColor	0.8 0.78 0.77
	emissiveColor	0.74 1 0.09
	shininess	0.05
      }
    }
    geometry	Box {
      size	0.5 0.5 0.1
    }
  },
  DEF Button3 TouchSensor {}
  ]
  translation	0.75 0.471992 -2.86847e-007
},
DEF Control Script {
  eventIn SFBool b1
  eventIn SFBool b2
  eventIn SFBool b3
  eventOut SFInt32 choice

  url "javascript:
  function b1( value ){
    if( value == true ){
    	choice = 0;
    }
  }
  function b2( value ){
    if( value == true ){
    	choice = 1;
    }
  }
  function b3( value ){
    if( value == true ){
    	choice = 2;
    }
  }"
}
# This is the NetworkState node we use
DEF Net NetworkSFInt32 {
  tag "choice" echo FALSE localCopy TRUE
}
] # end children

The definition of the SharedObject is in children. Here is all the geometry and the script we need to control the texture switching defined. Furthermore the NetworkState node is defined here. Following that we put the ROUTEs we need to make it work.

ROUTE Button1.isActive TO Control.b1
ROUTE Button2.isActive TO Control.b2
ROUTE Button3.isActive TO Control.b3
ROUTE Control.choice TO Net.set_value
ROUTE Net.value_changed TO SW.whichChoice

Finally we reuse the NetworkState node to fill the states field of the SharedObject node. This way the DeepMatrix system can access the NetworkState node and transmit its value to the other clients.

states [ USE Net ]
}

The Shout3D version is very similar, besides the changes to the geometry. The script is replaced by a custom node called Control. The source of this node can be found in the custom_nodes directory in the source tree.

next last content