Evénements partagés simples
Note du Traducteur : Les événements partagés sont ceux qui sont vus par tous les visiteurs d'un monde multi-utilisateurs.
Normalement, un clic permet à l'ordinateur de l'usager de déclencher un événement, par exemple une ouverture de porte, mais il ne sera vu que sur l'ordinateur de l'usager. Vous ouvrez une porte chez vous, mais devant leur ordinateur les autres visiteurs ne s'aperçoivent de rien.

Pour qu'un événement soit partagé il faut que l'événement soit expédié par l'usager vers le serveur de Blaxxun qui lui-même le répercute vers tous les utilisateurs connectés. Fin de Note.

Cliquez ici pour voir une Animation sans événement partagé

Cliquez ici pour voir une Animation simple avec un événement partagé

Cliquez ici pour voir une Animation simple avec deux événements partagés

Cliquez ici pour voir tous mes exemples Téléchargez mes Exemples

Pour animer vous-mêmes ces exemples, vous devrez installer les fichiers de simpleSharedEvents.zip sur votre ordinateur sous forme de "monde" multi-utilisateurs, sinon ils ne fonctionnereont pas. Votre navigateur doit rechercher l'url du fichier contact.htm

Voyez d'abord simpleAnimationWithNoSharedEvents.wrl (Animation sans événement partagé) et examinez bien son code.

Pour que simpleAnimationWithNoSharedEvents.wrl (Animation sans événement partagé) devienne "partagé" et donc devenir simpleAnimationWithOneSharedEvent.wrl (Animation simple avec un événement partagé) vous devrez faire ces trois choses:

1/ Vous devrez recopier et ajouter les PROTOs Blaxxun de BlaxxunZone (zone Blaxxun) et SharedEvent (événement partagé) en haut de votre fichier Vrml.
Le texte entier à recopier et coller figure ci-dessous (c'est long à écrire mais c'est vite copié-collé):

Copiez depuis ici :

# Protos nécessaires pour connexion multi-utilisateurs
#
PROTO BlaxxunZone [
 eventIn         MFNode   addEvents
 eventIn         MFNode   removeEvents
 exposedField    MFNode   events []
 exposedField    MFNode   avatars []
 eventOut        MFNode   events_added
 eventOut        MFNode   events_removed

 eventIn         SFInt32  set_myAvatarGesture
 eventIn         SFInt32  myAvatarGestureFromServer
 eventOut        SFInt32  myAvatarGesture_changed
 eventOut        SFInt32  myAvatarGestureToServer
 

 exposedField    MFString sendToChat ""
 exposedField    SFFloat  beamToDistance 3
 exposedField    MFString groupChatName ""
 exposedField    MFString groupChat ""
 exposedField    SFString myAvatarName ""
 exposedField    MFNode   avatarLOD []
 exposedField    MFFloat  avatarRange []
 eventIn         MFNode   addAvatars
 eventOut  MFNode   avatars_added
 eventIn   MFNode   removeAvatars
 eventOut  MFNode   avatars_removed
]

{
 DEF S Script {
  eventOut MFNode avatars_added IS avatars_added
  eventOut MFNode avatars_removed IS avatars_removed
  eventIn SFInt32  set_myAvatarGesture IS set_myAvatarGesture
  eventIn SFInt32  myAvatarGestureFromServer IS myAvatarGestureFromServer
  eventOut SFInt32  myAvatarGesture_changed IS myAvatarGesture_changed
  eventOut SFInt32  myAvatarGestureToServer IS myAvatarGestureToServer
  eventIn MFNode addAvatars IS addAvatars
  eventIn MFNode removeAvatars IS removeAvatars

  url "vrmlscript:
  function addAvatars(value, time) { avatars_added = value; }
  function removeAvatars(value, time) { avatars_removed = value; }
  function set_myAvatarGesture(value, time) { myAvatarGestureToServer = value; }
  function myAvatarGestureFromServer(value, time) { myAvatarGesture_changed = value; }

  "
 }
}

PROTO SharedEvent [
 exposedField SFString    name "event"
 exposedField SFString    type      "SFTime"
 exposedField SFString    toNickname     ""
 exposedField SFString    toGroup   ""
 eventIn   SFBool    boolFromServer
 eventIn   SFColor   colorFromServer
 eventIn   SFFloat   floatFromServer
 eventIn   SFInt32   int32FromServer
 eventIn   SFRotation     rotationFromServer
 eventIn   SFString  stringFromServer
 eventIn   SFTime    timeFromServer
 eventIn   SFVec2f   vec2fFromServer
 eventIn   SFVec3f   vec3fFromServer
 eventOut  SFBool    boolToServer
 eventOut  SFColor   colorToServer
 eventOut  SFFloat   floatToServer
 eventOut  SFInt32   int32ToServer
 eventOut  SFRotation     rotationToServer
 eventOut  SFString  stringToServer
 eventOut  SFTime    timeToServer
 eventOut  SFVec2f   vec2fToServer
 eventOut  SFVec3f   vec3fToServer
 eventIn   SFBool    set_bool
 eventIn   SFColor   set_color
 eventIn   SFFloat   set_float
 eventIn   SFInt32   set_int32
 eventIn   SFRotation     set_rotation
 eventIn   SFString  set_string
 eventIn   SFTime    set_time
 eventIn   SFVec2f   set_vec2f
 eventIn   SFVec3f   set_vec3f
 eventOut  SFBool    bool_changed
 eventOut  SFColor   color_changed
 eventOut  SFFloat   float_changed
 eventOut  SFInt32   int32_changed
 eventOut  SFRotation     rotation_changed
 eventOut  SFString  string_changed
 eventOut  SFTime    time_changed
 eventOut  SFVec2f   vec2f_changed
 eventOut  SFVec3f   vec3f_changed
 eventOut  SFBool    initialized
]
{
 Script {
  eventIn   SFBool    boolFromServer IS   boolFromServer
  eventIn   SFColor   colorFromServer     IS   colorFromServer
  eventIn   SFFloat   floatFromServer     IS   floatFromServer
  eventIn   SFInt32   int32FromServer     IS   int32FromServer
  eventIn   SFRotation     rotationFromServer  IS   rotationFromServer
  eventIn   SFString  stringFromServer    IS   stringFromServer
  eventIn   SFTime    timeFromServer      IS   timeFromServer
  eventIn   SFVec2f   vec2fFromServer     IS   vec2fFromServer
  eventIn   SFVec3f   vec3fFromServer     IS   vec3fFromServer
  eventOut  SFBool    boolToServer   IS   boolToServer
  eventOut  SFColor   colorToServer  IS   colorToServer
  eventOut  SFFloat   floatToServer  IS   floatToServer
  eventOut  SFInt32   int32ToServer  IS   int32ToServer
  eventOut  SFRotation     rotationToServer    IS   rotationToServer
  eventOut  SFString  stringToServer      IS   stringToServer
  eventOut  SFTime    timeToServer   IS   timeToServer
  eventOut  SFVec2f   vec2fToServer  IS   vec2fToServer
  eventOut  SFVec3f   vec3fToServer  IS   vec3fToServer
  eventIn   SFBool    set_bool  IS   set_bool
  eventIn   SFColor   set_color      IS   set_color
  eventIn   SFFloat   set_float      IS   set_float
  eventIn   SFInt32   set_int32      IS   set_int32
  eventIn   SFRotation     set_rotation   IS   set_rotation
  eventIn   SFString  set_string     IS   set_string
  eventIn   SFTime    set_time  IS   set_time
  eventIn   SFVec2f   set_vec2f      IS   set_vec2f
  eventIn   SFVec3f   set_vec3f      IS   set_vec3f
  eventOut  SFBool    bool_changed   IS   bool_changed
  eventOut  SFColor   color_changed  IS   color_changed
  eventOut  SFFloat   float_changed  IS   float_changed
  eventOut  SFInt32   int32_changed  IS   int32_changed
  eventOut  SFRotation     rotation_changed    IS   rotation_changed
  eventOut  SFString  string_changed      IS   string_changed
  eventOut  SFTime    time_changed   IS   time_changed
  eventOut  SFVec2f   vec2f_changed  IS   vec2f_changed
  eventOut  SFVec3f   vec3f_changed  IS   vec3f_changed
  eventOut  SFBool    initialized    IS   initialized
  url "vrmlscript:
  function initialize( time ) { initialized = TRUE;}
  function boolFromServer (value, time) { bool_changed = value; }
  function colorFromServer (value, time) { color_changed = value; }
  function floatFromServer (value, time) { float_changed = value; }
  function int32FromServer (value, time) { int32_changed = value; }
  function rotationFromServer (value, time) {rotation_changed = value; }
  function stringFromServer (value, time) { string_changed = value; }
  function timeFromServer (value, time) { time_changed = time; }
  function vec2fFromServer (value, time) { vec2f_changed = value; }
  function vec3fFromServer (value, time) { vec3f_changed = value; }
  function set_bool (value, time) { boolToServer = value; }
  function set_color (value, time) { colorToServer = value; }
  function set_float (value, time) { floatToServer = value; }
  function set_int32 (value, time) { int32ToServer = value; }
  function set_rotation (value, time) { rotationToServer = value; }
  function set_string (value, time) { stringToServer = value; }
  function set_time (value, time) { timeToServer = value; }
  function set_vec2f (value, time) { vec2fToServer = value; }
  function set_vec3f (value, time) { vec3fToServer = value; }
  "
 }
}
 
fin de la copie.

2/ Vous devrez ensuite "instancier" (voir la note qui suit) le PROTO BlaxxunZone (zone Blaxxun) et à l'intérieur de cette instanciation, instancier aussi le PROTO ShareEvent (événement partagé) comme ceci:

DEF SharedZone BlaxxunZone {
    events [
        DEF sharedAnim1 SharedEvent{ }
    ]
}
 

Note du traducteur : instancier ... Voilà. On programme d'abord un modèle, ou un prototype, un PROTO, d'un objet. Ou bien, c'est le cas ici, on fait appel à un PROTO qui existe déjà, un PROTO Blaxxun par exemple. Ce modèle reste tranquille dans son coin, il n'est pas exécuté. Au moment voulu, il est instancié : cela veut dire qu'on fait appel à ce modèle (on lui fournit si nécessaire des valeurs de variables) et on le rend exécutable. C'est ça, une instanciation. Et que les puristes me pardonnent... Fin de note.

3/ Vous devrez ensuite enlever la ROUTE que vous avez l'intention de partager et la remplacer par deux ROUTEs, la première ROUTE expédie l'événement au serveur Blaxxun et la deuxième le reçoit de ce serveur. C'est un détour, mais ainsi tous les visiteurs reçoivent cet Event (événement).

# remplacer cette ROUTE
#ROUTE touch1.touchTime TO TS1.startTime
# c'est celle qui n'intéressait que vous,
# par les deux ROUTEs suivantes

# la première est celle qui envoie l'événement
# du touch sensor (détecteur de contact) au serveur
ROUTE touch1.touchTime TO sharedAnim1.set_time

# la seconde est celle qui reçoit du serveur ce même
# événement pour déclencher l'animation partagée sur
# les ordinateurs de tous les visiteurs (vous-même y compris)
ROUTE sharedAnim1.time_changed TO TS1.startTime

Dès qu'un ordinateur expédie un événement au serveur Blaxxun, tous les ordinateurs connectés, y compris celui qui l'a envoyé, reçoivent cet événement en retour. Si vous ouvrez une porte, tout le monde le voit.. C'est ainsi que l'événement devient partagé.

Il y a une petite difficulté, surmontable. Si nous voulons ajouter un autre événement partagé à notre monde, nous pouvons utiliser la même instance du PROTO SharedEvent, pour autant qu'il s'agisse d'un événement d'un type différent. Autrement dit, nous pouvons utiliser SFTime et SFInt (simple champ temps, simple champ entier) sans avoir à instancier à nouveau le PROTO, parce qu'ils sont de types différents.

Si en revanche nous voulons ajouter un autre événement partagé, mais cette fois du même type, nous devrons procéder à une instanciation supplémentaire.
Autrement dit, tous les événements du même type devront avoir leur propre instance. Voyons ci-dessous dans un exemple comment procéder:

simpleAnimationWithTwoSharedEvents.wrl (Animation simple avec deux événements partagés) montre comment partager plus d'un événement du même type.

On notera en particulier dans simpleAnimationWithTwoSharedEvents.wrl que les deux instances du PROTO SharedEvent (événement partagé) sont bien identifiées par leur champ "nom", constitué d'une chaîne de caractères particulière et différente pour les deux, de sorte que les événements en provenance du serveur Blaxxun ne puissent être confondus entre eux.

DEF sharedAnim1 SharedEvent{
    name "SA1"
# dans le champ "nom" la chaîne de caractères "SA1"
# identifie cette instance
}
DEF sharedAnim2 SharedEvent{
    name "SA2"
# dans le champ "nom" la chaîne de caractères "SA2"
# identifie l'autre instance
}

Bien entendu, ces noms SA1 et SA2 donnés en exemple peuvent être remplacés par des noms beaucoup plus parlants, à vous d'en décider, l'essentiel est que la machine ne puisse pas confondre les deux.


Un lien d'information vers la page Blaxxun:
http://www.blaxxun.com/developer/index.html
 



Copyright© 2000-2007 Graham Perrett thyme@seamless3d.com
traduction Matthieu