Reference Document
Web site: <http://www.sics.se/dive/manual/tcl-behaviour.html>
Emmanuel Frécon - <emmanuel@sics.se>
Olof Hagsand - <olof@sics.se>
Swedish Institute of Computer Science,
Stockholm, November 23, 1995
1. Introduction
This document describes the principles and the functionalities of the Dive-Tcl interface. It requires some background knowledge about C, Tcl[1] and Dive[2] [4].
With the Dive-Tcl interface, Dive entities may be associated with Tcl scripts, defining the behaviour of the entities. Dive entities are fully distributed with their Tcl scripts, so that the Tcl scripts can be evaluated on any Dive node.
External applications can access the Dive/Tcl interface by the Dive Client Interface described in [5].
The Dive-Tcl interface consists in a set of new Tcl commands listed in the reference section below. These commands allow to:
called each time events occur.
each time a timer has expired.
The easiest way to create a Tcl script is to specify it in the Dive file format (.vr format) [4]. The following example defines a Tcl script that moves an object upwards when it is selected by a user:
proc move_up {type id sub_type origin src_id x y z} {
dive_move [dive_self] 0 0.5 0 LOCAL_C
}
dive_register INTERACTION_SIGNAL DIVE_IA_SELECT [dive_self] \
"" move_up
The example shows how the "move_up" Tcl procedure is registered (by
"dive_register") to be invoked when a Dive "select" (interaction
signal of type select) occurs at the object which contains the
script. The "move_up" procedure itself only calls "dive_move" to
displace the object. Note that no Dive-Tcl commands, such as
"dive_move", should be invoked in the script itself, only in a
procedure, such as "move_up" above.
2. Distribution Issues
2.1. Principles
Apart from Tcl commands, the Dive-Tcl scripts define a set of Dive interface functions, listed in the reference section below. Tcl scripts can use the usual looping and testing statements of Tcl. However, because of the non-preemptive thread package used in Dive, infinite loops that never give away control to Dive should be avoided.
Scripts are run in Tcl interpreters which are the basic context of execution. On each peer, each entity may be associated with one and only one Tcl interpreter and this interpreter has no connexions with the other interpreters.
A Tcl script associated with an entity is evaluated once on each node when the entity is created locally. A typical Dive-Tcl script contains procedure definitions and registration statements, binding Dive events or timers to Tcl procedures. Tcl and Dive-Tcl commands should only appear in Dive-Tcl procedures which are invoked by Dive events or timers.
To ensure that all nodes have an identical initial state, the Dive-Tcl
script belonging an entity is executed once on each node. In this
way, each interpreter has the same initial environment. However, when
Dive events occur, a Dive-Tcl event notification will run on one node
only, typically where it "occured".
2.2. Variables
Scripts can use local Tcl variables, but as scripts are replicated over each node connected to Dive, usual Tcl global variables are NOT distributed to the other nodes. In other words, the value of a global Tcl variable in a given Dive process is not the same as the one of the same variable in another Dive process.
Instead, Dive properties can be created and manipulated from Tcl. As Dive properties can also be manipulated from C programs, they represent an efficient solution for mixed Tcl-C applications.
Properties can be linked to global TCL variable, so that on any peer, the content of the variable reflect the content of the property.
Properties and global variables that are linked to properties may
generate high network traffic if their values are often set or reset.
2.3. Implementation Issues
All entities running Dive-Tcl execute Dive-Tcl commands in a separate thread with their own Tcl interpreter and a queue of pending commands. The thread repeatedly fetches commands from the queue and executes them in the Dive-Tcl interpreter. The command queue ensures that Dive-Tcl commands are executed in the order they are inserted and that one command terminates before the next one is begun.
When a Dive event occurs, a Dive-Tcl invokation is inserted into the
command queue. All other Dive-Tcl invokation such as those resulting
from "dive_send", "dive_call" or "dive_broadcast" (see below) also
insert commands into the queue. Synchronisation mechanisms are
provided when the result of execution is to be awaited. Typically,
"dive_call" leaves its command on the execution queue and waits for
the result to be avalaible.
3. Tcl file format
The easiest way to create a Tcl script is to specify it in the Dive file format (.vr format) [4]. The rest of this document will describe Tcl scripts written in the Dive format. In this format, the Tcl scripts are entered in the body of an entity within the begin.tcl and end.tcl keywords. Following the example above, the following defines a red sphere with a Tcl behaviour:
object {
material "red"
view {
SPHERE 0.5 0.5 0.5
}
begin.tcl
proc move_up {type id sub_type origin src_id x y z} {
dive_move [dive_self] 0 0.5 0 LOCAL_C
}
dive_register INTERACTION_SIGNAL DIVE_IA_SELECT [dive_self] \
"" move_up
end.tcl
}
Scripts declared between begin.tcl and end.tcl are, as the rest of the .vr file, run through the preprocessor. It is then possible to use declared constants.
Scripts can also be inlined using inline.tcl. inline.tcl points to a URL that is to be inserted as the script for the current entity. The following example defines the same red sphere with an inlined Tcl behaviour:
object {
material "red"
view {
SPHERE 0.5 0.5 0.5
}
inline.tcl "http://www.sics.se/dive/up_on_click.tcl"
}
Further examples can be found in the software release of Dive 3.0, see
for example the testtcl.vr.
4. Tcl/Dive Datatypes
The only data types recognized by Tcl are strings and lists. Therefore, Dive data types exported to Tcl must be translated to string and list representations.
Object identifiers are represented by four integers separated by ":", e.g., "43:789:898:89". The "empty" object identifier is represented by "0:0:0:0". When given as an argument to a command, "NULL" is an alias for "0:0:0:0".
Points are represented by a list of three floats, e.g.: {3.0 4.0 99.0}
Rotation matrices are represented by a list of three points, e.g. {{3.0 5.0 9.0} {3.0 4.0 99.0} {3.0 4.0 99.0}}.
Materials are either represented by the name of a valid Dive material, or a string of the form:
"ambient/diffuse/specular/emission/specularpower/transparency"
where ambient, diffuse, specular and emission are each represented by
three floats separated by ':' and specularpower and transparency are
floats. For example, the default (black) material is represented by
the string: 0:0:0/0:0:0/0:0:0/0:0:0/0/0. When given as an arguement to a
command, "NULL" is an alias for the "empty" material,
"0:0:0/0:0:0/0:0:0/0:0:0/0/0".
5. Tcl/Dive Functional Reference
5.1 Registering Tcl procedures
The following functions define when Tcl procedures will be called. Tcl procedures can either be invoked when a Dive event occurs or as a result of an expiring timer.
dive_register event_type sub_type id string procedure_name (arg)
dive_timer id period cmd
dive_timeout id timeout cmd
dive_time_unregister id interval cmd
dive_time_deregister id cmd
5.2 Geometry Functions
dive_move id x y z coord_option (other_id) dive_fixedXYZ id x y z coord_option (other_id) dive_EulerXYZ id x y z coord_option (other_id) dive_angle_axis id x y z theta coord_option (other_id) dive_transform id R T option (other_id) dive_rotate id R option (other_id)
Absolute transformations:
Interpolating transformations:
dive_reset_rot id
dive_velocity id {dx dy dz} {ax ay az}
dive_dir_velocity id {dx dy dz}
dive_ang_velocity id {ax ay az}
5.3 Object Composition functions
dive_add_sub id sub_id
dive_insert_sub id sub_id
dive_remove id
5.4 Signalling functions
dive_input_signal type KeySym (pid)
dive_interaction_signal type source_id dest_id pid
dive_entity_message id name msg_type msg origin
5.5 Object attributes modification functions
dive_scale id scalex scaley scalez
dive_material id mat (index)
dive_material_index id index
dive_texture id texurl (index)
dive_texture_index id index
dive_texture_move id s t
dive_texture_abs_move id s t
dive_texture_angle_point id angle s t
dive_texture_abs_angle_pt id angle s t
dive_text id text
dive_add_text id text font size
dive_flag id flagtype onoff
dive_clipping_plane id flag
5.6. Property Manipulations
dive_property_create id prop_name prop_type prop_val
dive_property_put id prop_name new_prop_val
dive_property_get id prop_name
dive_property_remove id prop_name
5.7 Dive database oriented functions
dive_for_all_entities class_type procedure_name (arg)
dive_for_all_subs id class_type procedure_name (arg)
dive_for_all_descendants id class_type procedure_name (arg)
dive_for_all_ancestors id class_type procedure_name (arg)
dive_find_super id
dive_find_ancestor id
dive_find_root id
dive_find_first_realobj id
dive_find_entity_byname name
dive_find_sub_byname id name
dive_find_ancestor_byname id name
dive_entity_info id receiving_array
dive_find_assoc id name
dive_get_radius id
dive_get_center id
dive_isect_objs id1 id2
dive_isect_ray_object direction point where
dive_find_closest_byname id name
5.8 Examining and controlling functions
dive_self
dive_type id
dive_hastcl id
5.9 Dive-Tcl script inter-communication
The following functions support communication between several Dive-Tcl interpreters. For example, procedures defined in other objects may be called. Note that there is an added complexity due to the nature of the replicated Dive objects: each replicated Dive object has several Dive-Tcl interpreters, one at each replicated node.
dive_send id cmd
dive_call id cmd
dive_declare id cmd
dive_broadcast id cmd
5.10 Miscellaneous functions
dive_sleep how_long
dive_readURL id url
dive_readURL_withMIME url
dive_read_text url
dive_random
dive_change_world worldname personid [position]
dive_world_disconnect world_id
References
[1] Tcl and the Tk toolkit, John K. Ousterhout, Addison-Wesley Publishing Co., 1994
[2] Dive 2.2 reference manual
[3] Christer Carlsson and Olof Hagsand, "Dive - A Platform for Multi-User Virtual Environments", "Computers and Graphics", 17(6), 1993
[4] Dive 3.0 file format interface, 1995
[5] Emmanuel Frécon and Olof Hagsand, "The Dive Client Interface", Dive 3 Reference Document, 1995, available at <http://www.sics.se/dive/manual/dci.html>
[6] Dive 3.0 entity interface, 1995
[7] Dive 3.0 callback interface, 1995