#VRML V2.0 utf8 PROTO BlaxxunZone [ eventIn MFNode addEvents eventIn MFNode removeEvents eventIn MFNode addAvatars eventIn MFNode removeAvatars exposedField MFNode events NULL exposedField MFNode avatars NULL exposedField SFString myAvatarURL "" exposedField SFString myAvatarName "" exposedField SFFloat number_avatars 0 eventOut MFNode avatars_added eventOut MFNode avatars_removed ]{ Transform { addChildren IS addEvents removeChildren IS removeEvents children IS events } Transform { addChildren IS addAvatars removeChildren IS removeAvatars children IS avatars } DEF avatarWatcher Script{ eventIn MFNode addAvatars IS addAvatars eventIn MFNode removeAvatars IS removeAvatars eventOut MFNode avatars_added IS avatars_added eventOut MFNode avatars_removed IS avatars_removed field SFFloat number_avatars IS number_avatars url"vrmlscript: function addAvatars(v,t){ avatars_added = v; number_avatars += 1; } function removeAvatars(v,t){ avatars_removed = v; number_avatars -= 1; } "} }# END BlaxxunZone DEF SharedZone BlaxxunZone { } Transform { translation -4 0 0 children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Sphere {} } ] } Transform { translation 4 0 0 children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Cone {} } ] } # for each avatar there are 3 avatarAdded events: The 1st when inserting the default avatar, the # 2nd is a techincalnode to add the real avatar and then the 3rd node after loading the rela avatar # the first 2 nodes are removed again # the "real avatar" consists of the following nodes: # the first node is an internal CC3D group node. It contains a switch node (for hiding the avatar) # a transform for moving it around and a touchsensor for getting mouse clicks DEF AV Script { eventIn MFNode addAvatars eventIn MFNode removeAvatars eventIn SFTime avatarTouched eventIn SFVec3f avatarPosition field SFNode av NULL field SFNode av1 USE AV field SFVec3f curPosition 0 0 0 url "vrmlscript: function addAvatars(val, ts) { Browser.print(' avatars added '); av = val[0].children[0]; if (av.getType() == 'Switch') { av = av.choice[0]; if (av.getType() == 'Transform') { Browser.print('got transform'); Browser.addRoute(av, 'translation_changed', av1, 'avatarPosition'); av = av.children[0]; if (av.getType() == 'TouchSensor') { Browser.print('touch route inserted'); Browser.addRoute(av, 'touchTime', av1, 'avatarTouched'); } } } } function removeAvatars(val, ts) { Browser.print(' avatars removed '); } function avatarPosition(val, ts) { curPosition = val; } function removeAvatars(val, ts) { Browser.print(' avatars removed '); } function avatarTouched(val, ts) { Browser.print(' avatar touched '); Browser.print(' position = '+curPosition[0]+','+curPosition[1]+','+curPosition[2]); }" } DEF AvatarMirror Transform { translation 0 0 -2 children [] } ROUTE SharedZone.avatars_added TO AvatarMirror.addChildren ROUTE SharedZone.avatars_removed TO AvatarMirror.removeChildren ROUTE SharedZone.avatars_added TO AV.addAvatars ROUTE SharedZone.avatars_removed TO AV.removeAvatars