Web site: <http://www.sics.se/dive/manual/tclef.html>
Main author: Emmanuel Frécon
/ emmanuel@sics.se
Co-authors: Olof Hagsand
/ olof@sics.se ,
Mårten Stenius
/ mst@sics.se ,
Olov Ståhl
/ olovs@sics.se ,
Anders Wallberg
/ andersw@sics.se,
Pär Hansson
/ par@sics.se
Dive entities form the basic units of distribution that can be addressed, requested and distributed. Each entity has a globally unique identifier, which is, in general, the first argument to all Tcl commands. Entities are oganized in a class hierarchy and some Tcl commands implement walkthroughs in parts on the database depending on a class type (see their description below). The recognized types are summarized in the class graph below. In this graph, the leaves are the primary classes and the nodes the abstract classes. For example, looking in the database for the class type LIGHT will match all PLIGHT, DLIGHT and SLIGHT.
___ DIVE_OBJ
/
| __ HOLDER --- WORLD
| /
______ DIVENODE--- LOD
/ | \__
| | BILLBOARD
| |
| \___ SWITCH
|
| __ COLLECTION -- ACTOR
| /
| | _____ DLIGHT
| | /
ENTITY--- LIGHT------ PLIGHT
| \_____
| SLIGHT
|
| ________ LINE
| /
| | _______ BOX
| | /
| || ______ POINTSET
| || /
| ||| ______ N_POLY
\_______ |||/
VIEW------- N_M_POLY
||||\______
|||| QUAD_GRID
||| \______
||| ELLIPSE
|| \_______
|| CYLINDER
| \________
| TEXT_OBJ
\_________
SPHERE
Rotate a Dive object, no linear interpolated collision detection.
Dive
dive_EulerXYZ id x y z coord_option (other_id)
dive_abs_EulerXYZ id x y z coord_option (other_id)
Rotate the Dive object identified by "id" with the Euler angles "x", "y" and "z". If "coord_option" is LOCAL_C the rotation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested rotation.
"dive_EulerXYZ" performs a relative coordinate transformation. "dive_abs_EulerXYZ" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been oriented.
The following example would rotate the object it is written in +45 degrees around its local X axis.
dive_EulerXYZ [dive_self] 0.78539816 0 0 LOCAL_C
dive_self, dive_fixedXYZ, dive_angle_axis, dive_rotate, dive_transport
Make an entity a sub entity of another.
Dive
dive_add_sub id sub_id
Make the entity identified by "sub_id" a sub entity of the entity identified by "id". When applying to objects, none of the objects is moved by this operation. Making an object sub object of a world removes any previous object composition.
The following example would make the object it is written in a top object.
dive_add_sub [dive_self] [dive_find_root [dive_self]]
dive_self, dive_find_root, dive_insert_sub
Add a new object to the personal visor.
PersonActor
dive_add_to_visor visorid objid x y
Add an object identified by "objid" to the personal visor of an actor. A visor is an invisible object, scaled to fit the viewpoint, which may have sub-elements. The position (x, y) is described in visor coordinates. The following is a picture explaining the layout of visor coordinates and the origin of the visor object.
<-0.5,0.5/(x/y-ratio)> +------------------------+ <0.5,0.5/(x/y-ratio)>
| |
| |
| + visor |
| origo |
| |
<-0.5,-0.5/(x/y-ratio)> +------------------------+ <0.5,-0.5/(x/y-ratio)>
The following example would add the object it is written in to the center of the visor.
dive_add_to_visor $visorid [dive_self] 0 0
dive_remove_from_visor dive_self
Set the angular velocity of a Dive object
Dive
dive_ang_velocity id {ax ay az}
Change the angular velocity of an object identified by "id". The angular velocity vector (ax, ay, az) represents three Euler angles, where each value should be given in radians/second.
The following example would make the object it is written in rotating around its X axis at a speed of 45 degrees/second (i.e. 0.39269908 rad/s).
dive_ang_velocity [dive_self] {0.39269908 0 0}
dive_velocity dive_dir_velocity dive_self
Rotate a Dive object, no linear interpolated collision detection.
Dive
dive_angle_axis id x y z theta coord_option (other_id)
dive_abs_angle_axis id x y z theta coord_option (other_id)
Rotate the Dive object identified by "id" around the axis composed by "x", "y" and "z" by an angle of "theta". If "coord_option" is LOCAL_C the rotation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested rotation.
"dive_angle_axis" performs a relative coordinate transformation. "dive_abs_angle_axis" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been oriented.
The following example would rotate the object it is written in +45 degrees around its local X axis.
dive_angle_axis [dive_self] 1 0 0 0.78539816 LOCAL_C
dive_self, dive_fixedXYZ, dive_EulerXYZ, dive_rotate, dive_transport
dive_assoc_put $aid "body" $body_id
dive_association_put $aid "body" $body_id 1.0 0
dive_association_remove_byname $aid "body"
dive_association_remove_byid $aid $body_id
dive_audio_group_join [dive_get_audio_group_addr $some_entity]
dive_audio_group_leave [dive_get_audio_group_addr $some_entity]
Take another object as a new body representation.
PersonActor
dive_body_change id
The current person actor will use the object identified by "id" as its new body representation.
The following example makes the current person actor using the object identified by "id" for its body icon.
dive_body_change $id
dive_body_load, dive_body_undo
Load a new body for the current person actor.
PersonActor
dive_body_load url
Replace the current body of person actor with the representation contained at "url".
The following example makes the current person actor using the 3D description contained in http://www.sics.se/dive/manual/examples/clock.vr for its body icon.
dive_body_load http://www.sics.se/dive/manual/examples/clock.vr
dive_body_change, dive_body_undo
Undo a body representation change.
PersonActor
dive_body_undo
none
Undo a body icon representation changement issued using dive_body_load or dive_body_change.
The following example undoes a previous changement.
dive_body_undo
dive_body_load, dive_body_change
Add a bookmark for the current person actor.
PersonActor
dive_bookmark_add name [index]
Associate a new bookmark named "name" to the current person actor. The bookmark will contain the current position and orientation of the body icon ("top" object) of the person actor and the URL of the current world. The bookmark will be added after the bookmark of "index" in the list of bookmarks already registered. The bookmarks can be viewed/used with the tools-bookmarks menu option.
The following example adds a bookmark named "here" for the current position and world.
dive_bookmark_add "here"
dive_bookmark_del, dive_bookmark_goto, dive_bookmark_list
Remove a bookmark for the current person actor.
PersonActor
dive_bookmark_del index
Remove the bookmark of index "index" in the list of bookmarks associated to the current person actor. The command returns "1" on success, "0" otherwise.
The following example removes the first bookmark of the current person actor.
dive_bookmark_del 0
dive_bookmark_add, dive_bookmark_goto, dive_bookmark_list
Transport the current person actor to a given bookmark.
PersonActor
dive_bookmark_goto index
Transport the body icon of the current person actor (i.e. its "top" object) to the bookmark which index is "index". The person actor will change world if it is necessary. The command returns "1" on success, "0" otherwise.
The following example transport the current person actor to the first bookmark.
dive_bookmark_goto 0
dive_bookmark_add, dive_bookmark_del, dive_bookmark_list
Give a list of all bookmarks associated to a person actor.
PersonActor
dive_bookmark_list
none
Return a Tcl list of all bookmarks associated to the current person actor. Each element of the list is itself a Tcl list composed of the following elements:
The following example sets the variable "bmk" to the list of bookmarks of the current person actor.
set bmk [dive_bookmark_list]
dive_bookmark_add, dive_bookmark_del, dive_bookmark_goto
dive_box $vid "0 0 0" 1 2 3
dive_change_interaction object
Execute a Dive/Tcl on all peers having a copy of an entity.
Dive
dive_broadcast id cmd
Execute the Dive-Tcl command "cmd" in the Tcl interpreter of the entity identified by "id" on each connected peer. This command can be used to, for example, open a MIME document on all connected peers.
The following example opens-up a window showing the picture located at http://www.sics.se/dive/data/textures/wood.rgb at all peers connected to the simulation.
dive_broadcast [dive_self] \ "dive_readURL_withMIME http://www.sics.se/dive/data/textures/wood.rgb"
Call a Dive/Tcl command in another entity and wait for result.
Dive
dive_call id cmd
Execute in the entity identified by "id" the Dive-Tcl command "cmd". The call is synchronous: the call blocks until the command has been executed and a functional value is returned. If the entity is an actor, the command is executed in the process to which the actor is bound and the result of the command is eventually sent over the network.
The following example sets the variable called "speed" to the result of the execution of the command "dive_vehicle_speed" in the object which identifier is contained in the variable named "id".
set speed [dive_call $id "dive_vehicle_speed"]
Teleport an actor in another world.
Dive
dive_change_world worldname personid [position]
Let "personid" change world from current world to one with name "worldname" and possibly change position to "position".
The following example teleport the current actor to the world named http://www.sics.se/dive/data/dive_town.vr.
dive_change_world http://www.sics.se/dive/data/dive_town.vr [dive_self]
Define which class an entity is a member of
Dive
dive_classdef id classname
Declare that the entity identified by "id" implements the class which name is "classname". The name should contain only alphanumeric characters. There are no restrictions in the number of classes an entity can be a member of and names are up to the applications. Dive reserves the following for its own use: "Dive", "Tcl", "Tk", "Diva", "PersonActor", "DCI".
The following example declares that the current object implements the class named "Screen".
dive_classdef [dive_self] "Screen"
dive_collection_create superid name hierarchical irregular mode
dive_collection_create $sid "house1" yes yes MEMBERSHIP_TOPMOST
dive_collection_membership collection_id id
dive_collection_membership $room_id $chair_id
dive_compute_bbox $oid minpt maxpt 1
Return current system local date and/or time
Dive
dive_date format
Return the current system date and/or time. The formatting string contains 0 or more directives and ordinary characters. A directive consists of a % character, an optional field width and precision specification, and a terminating character that determines the directive's behaviour. The following directives, shown without the optional field width and precision specification, are replaced by the indicated characters:
This Dive/Tcl command is a direct interface to the strftime() ANSI C function, details on the direectives and the optional field width and precision specification can be obtained in the manual pages.
The following example would set the variable current_time to "16:20:45", any day at that time.
set current_time [dive_date "%H:%M:%S"]
Declare on-the-fly a new command in an entity.
Dive
dive_declare id cmd
Declare the Dive-Tcl command "cmd" in the entity identified by "id". Declaration is typically a procedure declaration or a callback registration. This command is used to extend the Dive-Tcl script in an entity. The extension is evaluated in all interpreters of the entity and is saved as a part of the entity's state.
The following example declares the procedure "move_up" in the entity which identifier is contained in the variable named "id".
dive_declare $id {
proc move_up {step} {
dive_move [dive_self] 0 $step 0 LOCAL_C
}
}
Set the directional velocity of a Dive object
Dive
dive_dir_velocity id {dx dy dz} option
Change the directional velocity of an object identified by "id". The velocity will be set to the vector (dx, dy, dz), where each value should be given in meters/second. Boolean option decides if velocity is given in local or world coordinates.
The following example would make the object it is written in moving forward (i.e. along its Z axis) at a speed of 0.25 m/s.
dive_dir_velocity [dive_self] {0 0 0.25} yes
dive_velocity dive_ang_velocity dive_self
Copy an entity hierarchy.
Dive
dive_entity_copy id [flags]
Copy and return a new entity from the original id. If id is a divenode with subs, the sub-entities are copied recursively. Depending on the value of flags, all or only part of the fields are copied. The new object has the same super as the original. The identifier of the new entity is returned on success.
flags can be the sum of the following integers:
The following example makes a new copy of self.
set new [dive_entity_copy [dive_self]]
Check if an entity with a certain id exist in the database.
Dive
dive_entity_exist id
Check if the entity identified by id exists in the database. If entity exists, function returns 1, otherwise 0.
The following example gathers information about an entity if it exists in the database
if {[dive_entity_exist $id]} {
dive_entity_info $id info
}
Center the entity.
Dive
dive_center_entity id
Center the entity identified by id. This can improve rendering performance.
The following example centers the hierarchy of object with id bigwrl_id.
dive_center_entity $bigwrl_id
Gather information on an entity.
Dive
dive_entity_info id receiving_array
Gather information about the entity identified by "id". The entity values are returned in the "receiving_array" Tcl array. Information partly depends on the type of the entity. On return, the following elements will be set, indpendantly of the type of the entity:
Additionally, the actors will be described with:
The Dive objects will be described with:
The world entities will be described with:
The following example would fill in the array named "myself" with most of the information which can be known about the current object.
dive_entity_info [dive_self] myself
Send an entity message as if it was originated from a given actor.
Dive
dive_entity_message id name msg_type msg origin
Send the entity message of name "name" and sub type "msg_type" to the entity identified by "id", as if it was sent from the actor identified by "origin", possibly NULL. Applications are free to choose whichever name for messages, except those reserved for internal puposes within Dive standard modules and applications, i.e.: "TCL" and "Message". 0 is a forbidden sub type as it is a special of event filtering.
The content of the message is described in "msg", which is a Tcl list. Each item of the list describes one property and is a list itself: Its first element is a name, its second element a type and its last element the string representation of the value. The only formats recognized are the ones described in dive_property_create.
The following example would send an entity message to the current entity. This message is named "Doc" has a sub type of 2 and contains a unique string property named "new_page" which is containing "http://www.sics.se/dive/". The message will be understood as coming from an unknown origin (i.e. NULL).
dive_entity_message [dive_self] "Doc" 2 \
{{"new_page" string "http://www.sics.se/dive/"}} NULL
Request an entity update
Dive
dive_entity_request id sub_level
Request an update for the entity identified by "id" from the relevant group. The request is made either from the local group of the entity, or if no such group exists from the first local group found when searching the ancestors of the entity, starting with the parent. This means that the world group will be asked if no light-weight group is found among the ancestors.
"sub_level" specifies how much of the entity hierarchy is requested. One of the following values are possible:
Save an entity to a file.
PersonActor
dive_entity_save id filename
Save a description of the entity identified by "id" to the file which full path is contained in "filename". The file will contain a description in the Dive file format.
The following example would save the object identified by "id" to the temporary file "/usr/tmp/test.vr"
dive_entity_save $id /usr/tmp/test.vr
Execute an external program
Dive
dive_exec pipeline
Execute a pipeline of commands on the machine the script is currently executed. For security reasons, the normal Tcl command "exec" was removed and replaced by this command. The syntax within the pipeline is the same as "exec" and its an on-line documentation can be found here. The Dive/Tcl version starts by isolating each command within the pipeline and tests if it is not forbidden to use. All commands are by default forbidden, except the ones which are listed in the .dive_authority file.This file is first looked-up in your HOME directory, then in the directories pointed by the DIVEPATH environment variable.
The following example sends a mail to emmanuel@sics.se, provided that "mail" is an application listed in the .dive_authority file.
dive_exec "mail \"emmanuel@sics.se\" << \{This is a test mail.\}"
Save an entity to a file in a non-Dive format.
PersonActor
dive_export id filename format
Save a description of the entity identified by "id" to the file which full path is contained in "filename". The file will contain a description in the ac3d file format if "format" is the string "ac3d", in the VRML 1.0 file format if "format" is the string "vrml1_0".
The following example would save in VRML 1.0 format the object identified by "id" to the temporary file "/usr/tmp/test.wrl"
dive_export $id /usr/tmp/test.wrl vrml1_0
Find the top most ancestor of an entity.
Dive
dive_find_ancestor id
Return the identifier of the top most ancestor of the entity identified by "id". If none, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "top_id" to the identifier of the top most ancestor of the current object.
set top_id [dive_find_ancestor [dive_self]]
Find an ancestor by its class name.
Dive
dive_find_ancestor_byclass id classname
Return the identifier of the first ancestor of the entity identified by "id" whose is a member of the class "classname", i.e. for which dive_isa returns 1. If nothing was found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "bid" to the identifier of the first ancestor of the current object which is declared has being of the class "Button".
set bid [dive_find_ancestor_byclass [dive_self] "Button"]
Find an ancestor by its name.
Dive
dive_find_ancestor_byname id name
Return the identifier of the first ancestor of the entity identified by "id" whose name matches "name". A wildcard ('*') may be used at the end of the matching string, in which case the first matching entity is returned. If nothing was found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "bid" to the identifier of the first ancestor of the current object which has the name "button".
set bid [dive_find_ancestor_byname [dive_self] "button"]
Get entity associated with an actor.
Dive
dive_find_assoc id name
Return the object associated with actor "id" with logical name "name". If nothing is found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "top_id" to the identifier of the object associated to the actor identified by "aid" with the name "top".
set top_id [dive_find_assoc $aid "top"]
dive_entity_info, dive_find_assoc_actor, dive_find_closest_byclass
Get entity actor associated with an entity.
Dive
dive_find_assoc_actor id
Return the identifier of the actor which contains a logical association to the entity identified by "id". If nothing is found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "aid" to the identifier of the actor which contains an association to the current object.
set aid [dive_find_assoc_actor [dive_self]]
dive_entity_info, dive_find_assoc
Find nearest object by its class name.
Dive
dive_find_closest_byclass id classname
Return the identifier of the object which is a member of the class "classname" (i.e. for which dive_isa returns 1) and is closest to the object identified by "id". If nothing is found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "id" to the nearest of the objects of class "Screen" around the current object.
set id [dive_find_closest_byclass [dive_self] "Screen"]
Find nearest object.
Dive
dive_find_closest_byname id name
Return the identifier of the object which name matches "name" and is closest to the object identified by "id". If nothing is found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "id" to the nearest of the objects named "screen" around the current object.
set id [dive_find_closest_byname [dive_self] "screen"]
Find an entity by its name in all the DB.
Dive
dive_find_entity_byname name
Return the identifier of the first entity whose name matches "name". A wildcard ('*') may be used at the end of the match string, in which case the first matching object is returned. If nothing was found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would search all the databases the peer is currently connected to for the first entity which name is starting with "dive". The resulting identifier is set in the variable named "first_dive".
set first_dive [dive_find_entity_byname "dive*"]
Find first real object ancestor of an entity.
Dive
dive_find_first_realobj id
Return the identifier of the first real object found in the ancestors of the object identified by "id". If none, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "rid" to the identifier of the first ancestor of the current object which has the "realobj" flag on.
set rid [dive_find_first_realobj [dive_self]]
Find the root of an entity.
Dive
dive_find_root id
Return the identifier of the root of the entity identified by "id", this root is typically the world an entity is in.
The following example would set the variable named "wid" to the identifier of the world which contains the current object.
set wid [dive_find_root [dive_self]]
Find a descendant by its class name.
Dive
dive_find_sub_byclass id classname
Return the identifier of the first sub entity of the entity identified by "id" whose is a member of the class "classname", i.e. for which dive_isa returns 1. If nothing was found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "bid" to the identifier of the first descendant of the current object which is declared has being of the class "Button".
set bid [dive_find_sub_byclass [dive_self] "Button"]
Find a descendant by its name.
Dive
dive_find_sub_byname id name
Return the identifier of the first sub entity of the entity identified by "id" whose name matches "name". A wildcard ('*') may be used at the end of the matching string, in which case the first matching object is returned. If nothing was found, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "bid" to the identifier of the first descendant of the current object which has the name "button".
set bid [dive_find_sub_byname [dive_self] "button"]
Find the father of an entity.
Dive
dive_find_super id
Return the identifier of the super of the entity identified by "id". If the entity has no ancestor, the zero entity identifier is returned, i.e. "0:0:0:0".
The following example would set the variable named "super_id" to the identifier of direct ancestor of the current object.
set super_id [dive_find_super [dive_self]]
Rotate a Dive object, no linear interpolated collision detection.
Dive
dive_fixedXYZ id x y z coord_option (other_id)
dive_abs_fixedXYZ id x y z coord_option (other_id)
Rotate the Dive object identified by "id" with the rotation angles "x", "y" and "z" around the respective x, y and z axis. If "coord_option" is LOCAL_C the rotation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested rotation.
"dive_fixedXYZ" performs a relative coordinate transformation. "dive_abs_fixedXYZ" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been oriented.
The following example would rotate the object it is written in +45 degrees around its local X axis.
dive_fixedXYZ [dive_self] 0.78539816 0 0 LOCAL_C
dive_self, dive_EulerXYZ, dive_angle_axis, dive_rotate, dive_transport
Set the origo of the entity.
Dive
dive_entity_rotation_pt id x y z
Set new origo for object. This will affect rotation around own origo.
The following example will set the origo, for the object in which the command is executed, to <0,0,0>. When using mouse to rotate object, it will rotate around world origo.
dive_entity_rotation_pt [dive_self] 0.0 0.0 0.0
dive_self, dive_EulerXYZ, dive_angle_axis, dive_rotate, dive_transport
Change the local and/or distributed flags of an entity.
Dive
dive_flag id flag onoff
Set a local and/or distributed flag in the entity identified by "id" to the boolean value of "onoff". The name of the flag to change is contained in "flag" and is depending of the type of the entity.
The following distributed flags can be changed in objects:
The following distributed flags can be changed in views:
The following local flags can be changed in worlds:
The following example would make the object it is written in invisible.
dive_flag [dive_self] invisible ON
Call a procedure for some ancestors of an entity.
Dive
dive_for_all_ancestors id class_type procedure_name (arg)
For all ancestors matching the class type "class_type" (see graph of Dive Entities) in the hierarchy above the entity identified by "id", call the procedure of name "procedure_name" with the identifier of the sub entity as first argument, possibly followed by "arg". The procedure it not called with the identifier "id". This command follows the hierarchy up to the top level entity, but not the root entity (world). The procedure is called within the entity which called the command, not in the iterated entities.
The following example would move all the ancestors of the current object one meter forward.
proc do_move {id} {
dive_move $id 0 0 1.0 LOCAL_C
}
dive_for_all_ancestors [dive_self] DIVE_OBJ do_move
Call a procedure for some descendants of an entity.
Dive
dive_for_all_descendants id class_type procedure_name (arg)
For all sub entity matching the class type "class_type" (see graph in Dive entities) in the hierarchy of the entity identified by "id", call the procedure of name "procedure_name" with the identifier of the sub entity as first argument, possibly followed by "arg". The procedure is not called with the identifier "id". The procedure is called within the entity which called the command, not in the iterated entities.
The following example would move all the descendants of the current object one meter forward.
proc do_move {id} {
dive_move $id 0 0 1.0 LOCAL_C
}
dive_for_all_descendants [dive_self] DIVE_OBJ do_move
Call a procedure for some of all the entities.
Dive
dive_for_all_entities class_type procedure_name (arg)
For each entity in the current database matching the class type "class_type" (see graph of Dive entities), call the procedure of name "procedure_name" with the identifier of the entity as first argument, possibly followed by "arg". The procedure is called within the entity which called the command, not in the iterated entities.
The following example would move all objects in all databases to which the current peer is connected one meter forward.
proc do_move {id} {
dive_move $id 0 0 1.0 LOCAL_C
}
dive_for_all_entities DIVE_OBJ do_move
Call a procedure for some direct children of an entity.
Dive
dive_for_all_subs id class_type procedure_name (arg)
For all direct children matching the class type "class_type" (see graph of Dive entities) in the hierarchy of the entity identified by "id", call the procedure of name "procedure_name" with the identifier of the sub entity as first argument, possibly followed by "arg". The procedure is not called with the identifier "id". The procedure is called within the entity which called the command, not in the iterated entities.
The following example would move all direct children of the current object one meter forward.
proc do_move {id} {
dive_move $id 0 0 1.0 LOCAL_C
}
dive_for_all_subs [dive_self] DIVE_OBJ do_move
Returns the audio dive group (i.e., the group used for audio communication) associated with an entity.
Dive
dive_get_audio_group_addr id
Get the (light-weight) audio group address of an object identified by "id". Returns "NULL" if no group address is defined for the object. This call will not search the parent objects for group addresses.
The following example would set the variable named "grp" to the audio group address associated to the current object.
set grp [dive_get_audio_group_addr [dive_self]]
dive_group_join, dive_group_leave, dive_get_group_addr, dive_new_group_addr, dive_audio_group_join, dive_audio_group_leave, dive_set_audio_group_addr, dive_set_audio_src_type
Get center of an entity.
Dive
dive_get_center id
Return a point (in world coordinates), center of the entity identified by "id". If "id" identifies a view, the center of its super is returned.
The following example would set the variable named "c" to the center of current object.
set c [dive_get_center [dive_self]]
Returns the dive group associated with an entity.
Dive
dive_get_group_addr id
Get the (light-weight) group address of an object identified by "id". Returns "NULL" if no group address is defined for the object. This call will not search the parent objects for group addresses.
The following example would set the variable named "grp" to the group address associated to the current object.
set grp [dive_get_group_addr [dive_self]]
dive_group_join, dive_group_leave, dive_new_group_addr, dive_get_audio_group_addr, dive_audio_group_join, dive_audio_group_leave
Get the radius of the bounding sphere of an entity.
Dive
dive_get_radius id
Return the radius of the sphere surrounding the entity identified by "id". If "id" identifies a view, the radius of its super is returned.
The following example would set the variable named "r" to the radius of the sphere bounding the current object.
set r [dive_get_radius [dive_self]]
dive_entity_info, dive_get_center
Join current proces to a dive group.
Dive
dive_group_join gaddr (gname)
Joins the current process to a DIVE group (typically a light-weight group), with the address in "gaddr". The group address might be obtained for instance by dive_get_group_addr. If the group name is missing a default name is choosen.
The following example would join the group address which is associated to the current object.
dive_group_join [dive_get_group_addr [dive_self]]
dive_group_leave, dive_get_group_addr, dive_new_group_addr, dive_audio_group_join, dive_audio_group_leave, dive_change_world, dive_world_disconnect, dive_group_member
Disconnects the current process from a DIVE group.
Dive
dive_group_leave gaddr
Disconnects the current process from a DIVE group (typically a light-weight group). The process must previously have joined the group, by for instance dive_group_join.
The following example would leave the group address which is associated to the current object.
dive_group_leave [dive_get_group_addr [dive_self]]
dive_group_join, dive_get_group_addr, dive_change_world, dive_world_disconnect, dive_group_member
Test if the current process is member of a group.
Dive
dive_group_member gaddr
Tests if the current process is member of a DIVE group (typically a light-weight group). Returns "1" on success, "0" otherwise.
The following example would test if the current process is member of the group associated to the current object.
if { [dive_group_member [dive_get_group_addr [dive_self]]] } {
}
dive_group_join, dive_group_leave
Determine if an entity is associated with a Dive/Tcl interpreter.
Dive
dive_hastcl id
Return 1 if the entity identified by "id" has been associated with a (currently running) Dive-Tcl script, 0 otherwise.
The following example tests if the object which identifier is contained in the variable named "id" has a Dive/Tcl interpreter.
if { [dive_hastcl $id] } {
}
Simulate an input signal.
Dive
dive_input_signal type KeySym (pid)
Send the input signal of type "type" from the person identified by "pid". The content of the input signal is a valid X11 keyboard symbol and is contained in "KeySym". The type of the input signal may be KEYBOARD_KEY_DOWN or KEYBOARD_KEY_UP.
The following example would simulate that the user which identifier is contained in the variable "pid" presses down on the key "A".
dive_input_signal KEYBOARD_KEY_DOWN A $pid
Make an entity a sub entity of another.
Dive
dive_insert_sub id sub_id
Make the entity identified by "sub_id" a sub entity of the entity identified by "id". When applying to objects, The transform matrix of the sub object is not affected by this operation, which may lead to the sub object "jumping" to another location. Making an object sub object of a world removes any previous object composition.
The following example would make the object it is written in a top object and possibly move to another place.
dive_insert_sub [dive_self] [dive_find_root [dive_self]]
dive_self, dive_find_root, dive_add_sub
Simulate an interaction signal.
Dive
dive_interaction_signal type source_id dest_id pid
Send the interaction signal of type "type" to the entity (an object or a view) identified by "dest_id", as if it was sent by the object identified by "source_id" and owned by the actor "pid", both possibly NULL.
The type of the interaction signal may be one of the following: DIVE_IA_SELECT, DIVE_IA_DESELECT, DIVE_IA_DESELECT_FAIL, DIVE_IA_GRASP, DIVE_IA_GRASP_FAIL, DIVE_IA_RELEASE, DIVE_IA_RELEASE_FAIL.
The following example would simulate that an unknown user sends a select signal to the object this example is written in. The source of the interaction (i.e. typically the hand) is contained in the variable "hand_id".
dive_interaction_signal DIVE_IA_SELECT $hand_id [dive_self] NULL
Test if an entity is one of the parents of another
Dive
dive_is_ancestor id sub
Return "1" if the entity identified by "sub" is one among the descendants of the entity identified by "id", "0" otherwise.
The following example would test if the object identified by "id" is an ancestor of the current object.
if { [dive_is_ancestor $id [dive_self] } {
}
Test if an entity is member of a class
Dive
dive_isa id classname
Return 1 if the entity identified by "id" has been declared a member of the class which name is "classname", 0 otherwise.
The following example tests if the object which identifier is contained in the variable named "id" implements the class "Screen".
if { [dive_isa [dive_self] "Screen"] } {
}
Determine if two objects intersect.
Dive
dive_isect_objs id1 id2
Return 1 if the two objects identified by "id1" and "id2" intersect, 0 otherwise.
The following example would test if the object identified by "id" is intersecting the current object.
if { [dive_isect_objs $id [dive_self] } {
}
Find the first object hit by a ray.
Dive
dive_isect_ray_object direction point where (normal)
Return the object identifier (if any) of the first object hit by the ray starting from "point" (in world coordinates) pointing in "direction" (a vector). "where" is set to the point of intersection.
The following example would set the variable named "id" to the first object hit by the Z axis and starting from the center of the world. The current object is then moved to the intersection point.
set id [dive_isect_ray_object {0 0 1} {0 0 0} isect_pt]
dive_abs_move [dive_self] \
[lindex $isect_pt 0] [lindex $isect_pt 1] [lindex $isect_pt 2] WORLD_C
Change up and down in the object hierarchy the mark of the current person actor.
PersonActor
dive_mark_change direction
Given the current object marked by a person actor, change this mark to be its direct child (when direction is "down") or its direct super (when mark is "up").
The following example would mark the direct super object of the current marked object.
dive_mark_change up
Get object currently marked by an actor.
Dive
dive_mark_get id
Return the object currently mark by the actor with identifier "id". If nothing is marked by the actor, an empty string is returned.
The following example would set the variable "id" to the object marked by the actor with identifier "aid".
set id [dive_mark_get $aid]
dive_mark_put, dive_mark_change
Put new object as marked by current person actor.
PersonActor
dive_mark_put id
Set object identified by "id" as marked by the current person actor.
The following example would set the object identified by "id" as marked by the current actor.
dive_mark_put $id
dive_mark_get, dive_mark_change
Modify the material vector of an object.
Dive
dive_material id mat (index)
Modify the material vector contained in the object identified by "id". If "index" is omitted, the material "mat" is inserted at the beginning of the vector, otherwise it is inserted at the index "index". The string representation of the material may be a valid Dive material name or a valid Dive/Tcl material representation.
The following example would make the object it is written in red. More precisely, all the views of the current object which points at the first material of the object will be made red.
dive_material [dive_self] "RED_NEON_M"
dive_self, dive_texture, dive_material_index
Set the material index of a view object.
Dive
dive_material_index id index
Set the material index of view object identified by "id". The index is relative to the material table of the view's super object.
The following example would make the view which identifier is contained in "vid" use the material of index 2 in the first of its ancestors which has a material vector.
dive_material_index $vid 2
dive_texture_index, dive_material
Translate a Dive object, no linear interpolated collision detection.
Dive
dive_move id x y z coord_option (other_id)
dive_abs_move id x y z coord_option (other_id)
Move the Dive object identified by "id" by the vector composed by "x", "y" and "z". If "coord_option" is LOCAL_C the movement is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested movement.
"dive_move" performs a relative coordinate transformation. "dive_abs_move" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been translated to its new position.
The following example would move the object it is written in one meter forward in its local coordinate system.
dive_move [dive_self] 0 0 1.0 LOCAL_C
Abort a running movement.
PersonActor
dive_movement_abort mov_id
Abort a movement created using dive_movement_to_pos or dive_movement_to_obj.
The following ommand would abort the movement identified by mov_id
dive_movement_abort $mov_id
dive_movement_to_pos, dive_movement_to_obj
Move an object to the position of a given object.
PersonActor
dive_movement_to_obj id dest_id how_close speed flags [end_cb]
Move the object identified by "id" towards the position of the (possibly moving) object identified by "dest_id" at a speed of "speed" meters per second. The movement will be stopped as soon as the distance between the object and the goal is less than "how_close" fraction of the original distance. Once the movement operation is finished, the command "end_cb" will be called.
This command returns an integer identifier which can be used to abort the movement, using dive_movement_abort.
"flags" specify the movement and can be a sum of the following values:
The following ommand would move the object identified by "id" towards an object identified by "other_id", and align it with the world coordinate system.
dive_movement_to_obj $id $dest_id 100 1.0 [expr 1+4]
dive_movement_abort, dive_movement_to_pos
Move an object to a given position.
PersonActor
dive_movement_to_pos id position how_close speed flags [end_cb]
Move the object identified by "id" towards the position "position" (a list of three floats, in world coordinates) at a speed of "speed" meters per second. The movement will be stopped as soon as the distance between the object and the goal is less than "how_close" times the original distance. Once the movement operation is finished, the command "end_cb" will be called.
This command returns an integer identifier which can be used to abort the movement, using dive_movement_abort.
"flags" specify the movement and can be a sum of the following values:
The following ommand would move the object identified by "id" to the origin of the world, and align it with the world coordinate system.
dive_movement_to_pos $id {0.0 0.0 0.0} 100 1.0 [expr 1+4]
dive_movement_abort, dive_movement_to_obj
Generate and return a new group address.
Dive
dive_new_group_addr
Generate and return a new group address, i.e., an address that has not been used before. The address can for instance be used to set the audio group address of an arbitrary entity.
Set the audio group address of an entity to a new group address.
dive_set_audio_group_addr $entity [dive_new_group_addr]
dive_group_join, dive_group_leave, dive_get_group_addr, dive_audio_group_join, dive_audio_group_leave, dive_get_audio_group_addr, dive_set_audio_group_addr
Change the name of an entity.
Dive
dive_name id new_name
Change the name of an entity to "new_name"
Set the name of the entity to "apple1"
dive_name $entity apple1
dive_flag, dive_find_ancestor_byname, dive_find_closest_byname, dive_find_entity_byname, dive_find_sub_byname
Switch back and forth wireframe flag of an object locally.
PersonActor
dive_object_blink id
Switch back and forth the wireframe flag of the object identified by "id" during 5 seconds. This command can be used to highlight objects of interest.
The following example would blink the object identified by "id".
dive_object_blink $id
Load the content of an URL in front of the current person actor.
PersonActor
dive_object_load url
Load the content of the URL "url" in front of the current person actor. All top objects contained in the URL are inserted as top world objects, 5 meters in front of the body icon.
The following example would inserts the clock defined at http://www.sics.se/dive/manual/examples/clock.vr in front of the current person actor.
dive_object_load http://www.sics.se/dive/manual/examples/clock.vr
Return a string description of an entity in the Dive file format.
PersonActor
dive_object_source id
Return a description of the entity identified by "id" in the Dive file format.
The following example would set the variable "descr" to a file format-like description of the entity identified by "id".
set descr [dive_object_source $id]
Parse a string containing a 3D description and add the result under an entity.
Dive
dive_parse_string id mime_type str
Add under the entity identified by "id" the result of parsing the content of the string "str" as if it was coming from a file. The Mime type of the string description is contained in "mime_type" and can currently be either "x-world/x-dive" or "x-world/x-vrml". The identifier of the last entity resulting of the parsing is returned. This command is currently the only way of adding new objects programmatically from Dive/Tcl, i.e. without reading from an URL. Note that, when parsing Dive file format in this way, the string is not processed through "cpp", thus constants will not be translated to their values.
The following example would add a red cube under the current object.
dive_parse_string [dive_self] "x-world/x-dive" {
object {
translation v 0 -2 0
material "RED_NEON_M"
view {
RBOX
v -1 -1 -1
v 1 1 1
}
}
}
Check whether a specific DIVE plugin is loaded in the evaluating process or not.
Dive
dive_plugin_is_loaded name
Returns 1 if a plugin with the given "name" has been loaded into the evaluating process, 0 otherwise. The name is the "logical" name, that is, without filename extension or path.
The following command would return 1, if the evaluating process previously has loaded a plugin from "/foo/bar.a".
dive_plugin_is_loaded "bar"
dive_pointset_vertex $vid "0 3" "{0 1 3} {1 0 0}"
Create a new global property in an entity.
Dive
dive_property_create id prop_name prop_type prop_val
Create a new global property in the entity identified by "id". Only the types int, short, long, double, string, char, bool, float, objid_t mat_t, point_t are currently recognized. Properties should only be created using this command within procedures triggered by events, not during the initalization phase of the scripts.
The following example would create a floating point property named "speed" with the initial value of 0.0 in the object it is written in.
dive_property_create [dive_self] "speed" float 0.0
dive_property_get, dive_property_put, dive_property_remove, dive_property_link
Remove a property attached to an object.
Dive
dive_property_remove id prop_name
Remove the property of name "prop_name" from the properties of the entity identified by "id". The property may be global or local, but global properties have precedence when searching is done.
The following example would delete the property named "speed" from the current object.
dive_property_remove [dive_self] "speed"
dive_property_create, dive_property_get, dive_property_put, dive_property_link
Return a string representing the content of a property.
Dive
dive_property_get id prop_name
Return the value of the property of name "prop_name" in the entity identified by "id". The property type must be one of the recognized ones (see "dive_property_create") for the new value to be returned. The property may be global or local, but global properties have precedence when searching is done. If the property is not recognized or does not exists, an empty string is returned.
The following example would set the variable speed with the content of the property of name "speed" in the current object.
set speed [dive_property_get [dive_self] "speed"]
dive_property_create, dive_property_put, dive_property_remove, dive_property_link
Link a Tcl global variable to a property.
Dive
dive_property_remove id prop_name varname
Link the property of name "prop_name" in entity identified by "id" with the global Tcl variable of name "varname". The content of the global variable is assured to be the same as the one of the property. Linked properties can be used to implement global variables that are global to all peers. If the property did not exist it is automatically created, otherwise it has to be a string property. This mechanism will not work with global arrays. "dive_property_link", like "dive_register" must be placed in the initialization phase of a script.
The following example would link the property named "speed" in the current object to the global variable named "current_speed".
dive_property_link [dive_self] "speed" current_speed
dive_property_create, dive_property_get, dive_property_put, dive_property_remove, dive_register
Change the value of a property attached to an entity
Dive
dive_property_put id prop_name new_prop_val
Change the value of the property of name "prop_name" in the entity identified by "id" to "new_prop_val". The property type must be one of the recognized ones (see "dive_property_create") for the new value to be understood and set. The property may be global or local, but global properties have precedence when searching is done.
The following example would set to 1.0 the property called "speed" in the current object.
dive_property_put [dive_self] "speed" 1.0
dive_property_create, dive_property_get, dive_property_remove, dive_property_link
Generate a random float.
Dive
dive_random
Return a floating random number between 0 and 1.
The following example sets the variable named "rnd" to an integer random number between -5 and 5.
set rnd [expr int (([dive_random] * 10) - 5)]
Open a viewer for a MIME document residing in memory.
Dive
dive_readbuf_withMIME id buf len mime_type
Read the MIME document conatined in "buf", and handle the document according to the Dive internal MIME specification, for example by invoking the audio module. No external MIME viewers are spawned. The "mime_type" argument can be retreived by dive_readbuf_withMIME.
The following example plays the audio .au sound saved in audiobuf:
dive_readbuf_withMIME $audiobuf $len audio/basic
Insert the result of a VR or VRML parsing.
Dive
dive_readURL id url
Read the Dive file or URL of name "url" and return the identifier of the last object read. The resulting object tree is inserted under the entity identified by "id", typically a world or another object.
The following example inserts the clock which is defined at http://www.sics.se/dive/manual/examples/clock.vr as a sub object of the current object.
dive_readURL [dive_self] \ http://www.sics.se/dive/manual/examples/clock.vr
Open a viewer for a MIME document.
Dive
dive_readURL_withMIME url
Read the MIME document referenced by "url", and handle the document according to mailcap specification, for example by spawning external viewer. Dive understands the entity in which this command is executed as the origin of the event.
The following example opens-up a window showing the picture located at http://www.sics.se/dive/data/textures/wood.rgb.
dive_readURL_withMIME \ http://www.sics.se/dive/data/textures/wood.rgb
dive_readURL,dive_readbuf_withMIME
Read the content of any URL and return it as an (indirect) reference.
Dive
dive_readURL_as_addr url len_var mime_type_var
Read the file or URL of name "url". The function returns an indirect pointer to a memory refernce that can be accessed by succesive calls to dive_readbuf_withMIME .
The following example sets the variable named "s" to an address containg a sound url. s can later be used in a call to dive_readbuf_with_mime. content of the URL located at http://www.sics.se/~emmanuel/short_biography.txt.
set s [dive_readURL_as_addr \ "http://www.foo/sound.au" len type]
dive_readURL, dive_readbuf_withMIME
Read the content of any URL as text.
Dive
dive_readURL_as_text url
Read the file or URL of name "url" and open a window displaying the content of the "url" as text.
The following example sets the variable named "txt" to the content of the URL located at http://www.sics.se/~emmanuel/short_biography.txt.
set txt [dive_readURL_as_text \ http://www.sics.se/~emmanuel/short_biography.txt]
dive_readURL, dive_readbuf_withMIME
Bind a Tcl procedure to a Dive Event.
Dive
dive_register event_type sub_type id string proc_name (arg)
Register the Tcl procedure of name "proc_name" to be called each time a Dive event matching "event_type", "sub_type" and "string" occurs on the entity of identifier "id". More information on the different event types and how matching is performed can be found in [7]. The number and order of the arguments to the Tcl procedure depends on the event type.The following list shows a description of these arguments for the event types implemented. The last argument "arg" is a user-defined argument which is added at the end of the procedure call each time the event occur.
prop_type
---
DUMMY_PROP
PROP_CREATE
PROP_CHANGE
PROP_REMOVE
collision_type
---
DIVE_COLLISION
DIVE_NO_COLLISION
DIVE_COLLISION_ISECT
input_type
---
KEYBOARD_KEY_DOWN
KEYBOARD_KEY_UP
interaction_type
---
DIVE_IA_SELECT
DIVE_IA_DESELECT
DIVE_IA_DESELECT_FAIL
DIVE_IA_GRASP
DIVE_IA_GRASP_FAIL
DIVE_IA_RELEASE
DIVE_IA_RELEASE_FAIL
Note that the name of the arguments of the registered procedures are of no importance, i.e. in the table above, only the order and the number of arguments is meaningfull.
Note also that the event type is ALSO given to the procedure as an argument, it is always the first of the arguments. This may be useful when registering the same procedure for several events.
The trailing argument is added at the end of the procedure call each time the event occur.
If the entity is an actor, the procedure call will be executed in the process which is bound to the actor. Otherwise, it will be executed in the process which generated the event, thus allowing the registered procedures to migrate from site to site.
The following example register the procedure "on_down" to be called each time an interaction signal is intercepted in the hierarchy of the object in which this registration is done.
proc on_down {event vid type origin src_id x y z} {
}
dive_register INTERACTION_SIGNAL DIVE_IA_SELECT \
[dive_self] "" on_down
dive_self, dive_timer, dive_timeout
Register a Dive/Tcl command to be called each time the position of an object is requested.
This command is experimental.
Dive
dive_register id procname
Register a procedure to be called each time the position of an object is going to be requested. The procedure will return a position in local coordinates which will be used as the object's local position. Each time it is called, the procedure takes the following arguments as input:
The registration must be done in the main body of a Dive/Tcl script.
The following example contrains the movement of the current object in the XZ plane.
proc contrain {p t p0 t0} {
return [list [lindex $p 0] 0 [lindex $p 2]]
}
dive_register_velocity [dive_self] contrain
Remove and entity and its descendants.
Dive
dive_remove id
Remove the entity identified by "id" and all its descendants. Removing an object from a script written in that object (i.e. dive_remove [dive_self]) can lead to undesirable behaviours.
The following example would make the object which identifier is contained in the variable "id".
dive_remove $id
Remove an object from the personal visor.
PersonActor
dive_remove_from_visor visorid objid
Remove an object identified by "objid" from the personal visor of an actor.
The following example would remove the object which identifier is contained in the variable "objid" from the visor.
dive_remove_from_visor $visorid $objid
Align an object with the world's Y axis, no linear interpolated collision detection.
Dive
dive_reset_rot id
Align object identified by "id" to world's y-axis on a best-effort basis. That is, make object "stand up".
The following example would align the Y axis of the object it is written in with the world's Y axis.
dive_reset_rot [dive_self]
dive_self, dive_transform, dive_transport
Remove a temporary file produced by dive_saveURL.
PersonActor
dive_rmtmp filename
Remove a temporary file created when a dive_saveURL command was issued. Only these temporary files can be removed using dive_rmtmp.
The following example would remove the temporary file which name is contained in "tmpfile", assuming this name was obtained by issuing a dive_saveURL.
dive_rmtmp $tmpfile
Rotate a Dive object, no linear interpolated collision detection.
Dive
dive_rotate id R coord_option (other_id)
dive_abs_rotate id R coord_option (other_id)
Perform an arbitrary rotation on the object identified by "id". The rotation "R" is a Tcl list of three lists, each a list of three floats. If "coord_option" is LOCAL_C the transformation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested transformation.
"dive_rotate" performs a relative coordinate transformation. "dive_abs_rotate" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been rotated.
The following example would ... not rotate the object it is written in.
dive_rotate [dive_self] {{1 0 0} {0 1 0} {0 0 1}} LOCAL_C
dive_self, dive_fixedXYZ, dive_EulerXYZ, dive_angle_axis, dive_transport
Save the raw content of any URL to a local temporary file.
PersonActor
dive_saveURL url
Save the raw content of a (distant) URL to a temporary local file. The name of the temporary file is returned once the operation has been performed. The file can be remove later on using dive_rmtmp.
The following example would save the content of http://www.sics.se/dive/icons/dive_logo.gif in a temporary file and save its name in the variable "tmpfile".
set tmpfile [dive_saveURL http://www.sics.se/dive/icons/dive_logo.gif]
Scale a Dive object
Dive
dive_scale id scalex scaley scalez
Scale the object identified by "id" by a non-uniform scale of "scalex", "scaley" and "scalez" along the x, y and z axis.
The following example would scale down by a factor of two along all axis the object it is written in.
dive_scale [dive_self] 0.5 0.5 0.5
Find entity identifier in which a script is executed.
Dive
dive_self
Return the identifier of the object in which the script is executed.
The following example would set the variable named "me" to the identifier of the object it is run in.
set me [dive_self]
Submit for execution a Dive/Tcl command to another entity.
Dive
dive_send id cmd
Execute in the entity identified by "id" the Dive-Tcl command "cmd". The call is asynchronous: no functional value is returned and the call does not block until the command has been executed. If the entity is an actor, the command is executed in the process to which the actor is bound.
The following example executes the command named "move_up 1.0" in the object which identifier is contained in the variable named "id".
dive_send $id "move_up 1.0"
Set the audio dive group of an entity, i.e., the group used for distributing audio originating from the entity.
Dive
dive_set_audio_group_addr id addr
Set the (light-weight) audio group address of the entity identified by "id". All audio originating from the entity will be distributed on the given group address. If the given address is zero, the audio group address for the entity will be cleared, which means that the audio originating from the entity will be sent on the first audio group that is found when doing an search upwards in the hierarchy.
The following example would set the audio group address of entity1 to the same adress as the one entity2 uses. If entity2 has an audio group address different than zero, the effect will be that audio originating from both entities will be distributed on the same address. If the address of entity2 is zero, audio originating from the two entities may be sent on different adresses, found when doing one upward audio group search in the hierarchy for each of the two entities.
dive_set_audio_group_addr $entity1 [dive_get_audio_group_addr $entity2]
dive_group_join, dive_group_leave, dive_get_group_addr, dive_new_group_addr, dive_audio_group_join, dive_audio_group_leave, dive_get_audio_group_addr, dive_set_audio_src_type
Set the audio source type of an entity. Will determine how the audio originating from the entity will be spatialised before being played out in the speaker.
Dive
dive_set_audio_src_type id type
Set the audio source type of the entity identified by "id". The audio source type determines how the audio originating from the entity will be spatialised before being played out in the speaker. The current possible values of the type parameter are:
The following example will set the audio source type of the entity to ambient.
dive_set_audio_src_type $entity AUDIO_SOURCE_AMBIENT
dive_group_join, dive_group_leave, dive_get_group_addr, dive_audio_group_join, dive_audio_group_leave, dive_get_audio_group_addr , dive_set_audio_group_addr
Suspend execution for a while.
Dive
dive_sleep how_long
Sleep for "how_long" milliseconds, giving back control to other Dive threads.
The following example causes the current script to sleep one second (i.e. 1000 milliseconds).
dive_sleep 1000
Recursively change normals to improve Gouraud shading.
PersonActor
dive_smooth_entity id crease_angle
Recursively change the normals associated to each point in polygons to improve Gouraud shading. Improvement is achieved by calculating the mean value of the normals to all polygons that share a same point and use this calculated normal as the normal for the point. "crease_angle" (which defaults to 0.5 radians) is the maximum angle between a calculated normal and the original value, when an angle is greated than the crease angle, the calculated normal is dropped and the original normal is used instead.
This algorithm only works with N_M_POLY (so far) and adds normals as necessary. The operation may take a long time.
The following example smooth the entity identified by "id".
dive_smooth_entity $id
Inline a Dive/Tcl script.
Dive
dive_source url
Inline the content of a Dive/Tcl script. The script is located at "url" and the usual rules for finding URLs are valid, i.e. using http, ftp or the DIVEPATH variable.
The original Tcl command called "source" has not been suppressed, but is not ensured to work in all cases.
The following example adds a few compatibility commands to the current script, allowing it to use old-style Dive/Tcl commands.
dive_source "dive_compatibility.tcl"
Change the current state of a switch node.
Dive
dive_source id choice
Change the current state to the switch identified by id so that it will use its children number choice.
The following example change the current switch to use its first children.
dive_switch_choice [dive_self] 0
Modify the content of a text view.
Dive
dive_text id text
Change the text view identified by "id" to contain the new string value contained in "text".
The following example would change the content of the text view which identifier is contained in the variable "vid" to the string "Dive is fantastic".
dive_text $vid "Dive is fantastic"
dive_get_view, dive_box, dive_pointset_vertex
Set or reset the texture associated to an object.
Dive
dive_texture id texurl (index)
Modify the texture vector contained in the object identified by "id". If "index" is omitted, the texture "texurl" is inserted at the beginning of the vector, otherwise it is inserted at the index "index". The texture URL "texurl" can be an empty string when untextured effects are wanted. Once the texture URL changed, it is the responsability of each Dive peer to read or not the content of the texture from the URL.
The following example would make the object it is written in textured with the content of the texture file contained at http://www.sics.se/dive/data/textures/wood.rgb. More precisely, all the views of the current object which points at the first texture of the object will be textured with the content of this URL.
dive_texture [dive_self] \ http://www.sics.se/dive/data/textures/wood.rgb
dive_self, dive_material, dive_texture_index
Set the texture index associated to a view object.
Dive
dive_texture_index id index
Set the texture index of the view object indentified by "id". The index is relative to the texture table of the view's super object.
The following example would make the view which identifier is contained in "vid" use the texture of index 2 in its super object's texture vector.
dive_texture_index $vid 2
dive_material_index, dive_texture
Relative translation of texture.
Dive
dive_texture_move id dx dy
Performs a relative translation of the texture associated with the view indentified by "id", i.e., the texture will appear to move on the texturing surface. The x and y coordinates are relative to the texture's "coordinate system", i.e, (0.0) is the left bottom corner and (1, 1) is the right top corner of the texture.
The following example will make the texture move 0.5 in the textures x direction.
dive_texture_move $vid 0.5 0
dive_texture, dive_texture_move, dive_texture_abs_move, dive_texture_angle_point
Absolute translation of texture.
Dive
dive_texture_abs_move id x y
Performs an absolute translation of the texture associated with the view indentified by "id", i.e., the texture will appear to move on the texturing surface. The x and y coordinates are relative to the texture's "coordinate system", i.e, (0.0) is the left bottom corner and (1, 1) is the right top corner of the texture.
The following example will set the texture translation to (0, 0.7).
dive_texture_abs_move $vid 0 0.7
dive_texture, dive_texture_move, dive_texture_abs_move, dive_texture_angle_point
Relative rotation of texture arbitrary point.
Dive
dive_texture_angle_point id a x y
Performs a relative rotation around a given point of the texture associated with the view indentified by "id", i.e., the texture will appear to rotate around the given point on the texturing surface. The point's x and y coordinates are relative to the texture's "coordinate system", i.e, (0.0) is the left bottom corner and (1, 1) is the right top corner of the texture.
The following example will rotate the texture approx. 90 degrees around the point (0.5, 0.5), i.e, the middle of the texture.
dive_texture_angle_point $vid 1.57 0.5 0.5
dive_texture, dive_texture_move, dive_texture_abs_move, dive_texture_angle_point
Absolute rotation of texture around arbitrary point.
Dive
dive_texture_angle_point id a x y
Performs an absolute rotation around a given point of the texture associated with the view indentified by "id", i.e., the texture will appear to rotate around the given point on the texturing surface. The point's x and y coordinates are relative to the texture's "coordinate system", i.e, (0.0) is the left bottom corner and (1, 1) is the right top corner of the texture.
The following example will set the tetxure rotation to approx. 90 degrees relative the point (0.5, 0.5).
dive_texture_abs_angle_point $vid 1.57 0.5 0.5
dive_texture, dive_texture_move, dive_texture_abs_move, dive_texture_abs_angle_point
Unregister a timer or a timeout
Dive
dive_time_deregister id cmd
Unregister a previously registered timer or timeout. Only the command (i.e. the fourth argument given to "dive_timeout" or "dive_timer") act as an identifier for the timer. The first timer or timeout which registered command starts with "cmd" will be removed. Only this one will be removed.
Assuming the procedure move_up was registered as a timer in the current object, the following calls will both unregister the timer:
dive_time_deregister [dive_self] mov
dive_time_unregister [dive_self] "move_up"
However, if another procedure starting with mov was registered as a timer in the current object, the behaviour of the first command would be undefined.
dive_self, dive_timer, dive_timeout, dive_unregister
Add two divetimes.
Dive
dive_time_add t0 t1
Return the result time by adding time "t1" to time "t0".
The following example will set the variable "time" to the sum of time "t0" and time "t1".
set time [dive_time_add $t0 $t1]
dive_time_diff, dive_time_incr, dive_time_get, dive_time_sub
Return the difference between two absolute times expressed in seconds.
Dive
dive_time_diff t0 t1
Return the difference between two absolute times expressed in seconds.
The following example will set the variable "until_start" to the difference between time "start_time" and time "now".
set now [dive_time_get]
set until_start [dive_time_diff $start_time $now]
dive_time_add, dive_time_incr, dive_time_get, dive_time_sub
Retrieve an absolute time
Dive
dive_time_get
Retrieve an absolute time, divetime.
The following example will set the variable "now" to the current time.
set now [dive_get_time]
dive_time_diff, dive_time_incr, dive_time_add, dive_time_sub
Increment an absolute time with a relative time in seconds.
Dive
dive_time_incr t0 sec
Return an absolute time "t0" incremented by "sec" seconds.
The following example will increment the time "now" with 1000 seconds.
set now [dive_time_get]
set t [dive_time_incr $now 1000]
dive_time_add, dive_time_diff, dive_time_get, dive_time_sub
Subtract two divetimes.
Dive
dive_time_sub t0 t1
Return the result time by subtracting "t0" with "t1".
The following example will subtract time "t0" with time "t1".
set time [dive_time_sub $t0 $t1]
dive_time_add, dive_time_diff, dive_time_get, dive_time_incr
Unregister a timer or a timeout
Dive
dive_time_unregister id interval cmd
Unregister a previously registered timer or timeout. Both the interval and the command (i.e. the third and fourth arguments given to "dive_timeout" or "dive_timer") act as an identifier for the timer. The first timer or timeout which registered command starts with "cmd" will be removed. Only this one will be removed.
Assuming the procedure move_up was registered as a timer in the current object with a period of 500 milliseconds, the following calls will both unregister the timer:
dive_time_unregister [dive_self] 500 mov
dive_time_unregister [dive_self] 500 "move_up"
However, if another procedure starting with mov was registered as a timer in the current object and with the same period, the behaviour of the first command would be undefined.
dive_self, dive_timer, dive_timeout, dive_deregister
Register a Dive/Tcl command to be executed once in the future
Dive
dive_timeout id timeout cmd
Arrange so that the Dive/Tcl command "cmd" will be called in the Tcl interpreter of the entity identified by "id" when AT LEAST "timeout" milliseconds have expired. Timeouts are therefore not precise.
If the entity is an actor, the command will be executed in the process which is bound to the actor. Otherwise, the command will be executed in the process which is the time server at the moment the command is to be issued, thus allowing timeouts to migrate from one process to another.
The following example calls the procedure on_timeout once 5 seconds (i.e. 5000 milliseconds) have expired.
proc on_timeout {} {
}
dive_timeout [dive_self] 5000 on_timeout
dive_self, dive_timer, dive_time_unregister, dive_time_deregister, dive_sleep
Register a Dive/Tcl command to be periodically executed
Dive
dive_timer id period cmd
Register the Dive/Tcl command "cmd" to be called in the Tcl interpreter of the entity identified by "id" each time "period" milliseconds has expired. The timer is based on the internal Dive alarm, so that the procedure will be called when AT LEAST "period" milliseconds have expired. Timers are therefore not precise.
If the entity is an actor, the periodic command will be executed in the process which is bound to the actor. Otherwise, the periodic command will be executed in the process which is currently the time server, thus allowing timers to migrate from one process to another.
The following example register the procedure "on_timer" to be called each 200 milliseconds.
proc on_timer {} {
}
dive_timer [dive_self] 200 on_timer
dive_self, dive_timeout, dive_time_unregister, dive_time_deregister, dive_sleep
Translate and rotate a Dive object; no linear interpolated collision detection.
Dive
dive_transform id R T coord_option (other_id)
dive_abs_transform id R T coord_option (other_id)
Perform a whole transformation on the object identified by "id". The translation "T" is a Tcl list composed of three floats, one for each coordinate. The rotation "R" is a Tcl list of three lists, each a list of three floats. If "coord_option" is LOCAL_C the transformation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested transformation.
"dive_transform" performs a relative coordinate transformation. "dive_abs_transform" performs an absolute coordinate transformation.
Collision detection is only performed once the object has been transformed.
The following example would ... not rotate the object it is written in, but move it 3 meters forward (i.e. along the Z axis) in its local system.
dive_transform [dive_self] \
{{1 0 0} {0 1 0} {0 0 1}} {0 0 3} LOCAL_C
Translate and rotate a Dive object, with linear interpolated collision detection.
Dive
dive_transport id R T coord_option (other_id)
dive_abs_transport id R T coord_option (other_id)
Perform a whole transformation on the object identified by "id". The translation "T" is a Tcl list composed of three floats, one for each coordinate. The rotation "R" is a Tcl list of three lists, each a list of three floats. If "coord_option" is LOCAL_C the transformation is in local coordinates, in world coordinates if "coord_option" is WORLD_C and in relative coordinates if "coord_option" is RELATIVE_C. In the latter case, "other_id" specifies which object is the reference for the requested transformation.
These transformation functions are based on the assumption that the transformed entities move along an interpolated line between the old and new position. Intersections may occur on this line, resulting in collisions, gateway detection, etc.
"dive_transport" performs a relative coordinate transformation. "dive_abs_transport" performs an absolute coordinate transformation.
The following example would ... not rotate the object it is written in, but transport it 3 meters forward (i.e. along the Z axis) in its local system.
dive_transport [dive_self] \
{{1 0 0} {0 1 0} {0 0 1}} {0 0 3} LOCAL_C
Find the type of an entity.
Dive
dive_type id
Return the entity type of the entity identified by "id". Entity types are the leaves of the graph of Dive entities
The following example tests if the current object is really (!!) an object.
if { [dive_type [dive_self]] == "DIVE_OBJ" } {
}
Determine stereo capability.
Dive
dive_can_render_stereo
Query about stereo capability. Returns a boolen which indicates whether stereo is possible or not (only SGI machines).
The following example tests if stereo is possible.
dive_can_render_stereo
Start or stop fastrak vehicle for a person actor.
PersonActor
dive_vehicle_fast activity
Start or stop a fastrak vehicle, depending on the value of "activity", in the person actor the command is executed.
The following example starts a fastrak vehicle in the current person actor.
dive_vehicle_fast on
dive_send, dive_vehicle_mouse, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_fly, dive_vehicle_walk, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change
Start a fly vehicle for a person actor.
PersonActor
dive_vehicle_fly activity
Start or stop a fly vehicle, depending on the value of "activity", in the person actor the command is executed.
The following example starts a fly vehicle in the current person actor.
dive_vehicle_fly on
dive_send, dive_vehicle_mouse, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_walk, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start a HMD vehicle for a person actor.
PersonActor
dive_vehicle_hmd activity
Start or stop a HMD vehicle, depending on the value of "activity", in the person actor the command is executed. The HMD vehicle requires that a machine to which a flock of bird from Ascension Technology is connected runs a process called birdserver.
The following example starts a HMD vehicle in the current person actor.
dive_vehicle_hmd on
dive_send, dive_vehicle_mouse, dive_vehicle_kbd, dive_vehicle_fly, dive_vehicle_walk, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start a keyboard vehicle for a person actor.
PersonActor
dive_vehicle_kbd activity
Start or stop a keyboard vehicle, depending on the value of "activity", in the person actor the command is executed. The keyboard vehicle is "on" by default when all kind of "diva" are started.
The following example starts a keyboard vehicle in the current person actor.
dive_vehicle_kbd on
dive_send, dive_vehicle_fly, dive_vehicle_mouse, dive_vehicle_hmd, dive_vehicle_walk , dive_vehicle_speed,dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start a mouse vehicle for a person actor.
PersonActor
dive_vehicle_mouse activity
Start or stop a mouse vehicle, depending on the value of "activity", in the person actor the command is executed.
The following example starts a mouse vehicle in the current person actor.
dive_vehicle_mouse on
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_walk, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start or stop a vehicle for an object.
PersonActor
dive_vehicle_object_mouse activity
Start or stop an object mouse vehicle, depending on the value of "activity", in the person actor the command is executed. The user moves around the marked object.
The following example starts an object mouse vehicle for the marked object with identifier "id" in the person actor.
dive_mark_put $id
dive_vehicle_object_mouse on
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_mouse, dive_vehicle_walk, dive_vehicle_speed, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Get and/or set the speed of vehicle in a person actor.
PersonActor
dive_vehicle_speed [coefSpeed]
If no argument is given to the command, it returns the current speed associated to all 3D vehicles (i.e. non-Tk vehicles) for the current person actor. The speed is a floating point value.
"coefSpeed" is expressed in percent and describes how much the current speed should be decreased or increased. The new resulting speed is returned by the command. 0 is a fobidden coefficient, it is ignored.
The following doubles the speed of vehicles in the current person actor and returns the new speed in the variable "speed".
set speed [dive_vehicle_speed 200]
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_mouse, dive_vehicle_walk, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start a simple vehicle for a person actor.
PersonActor
dive_vehicle_walk activity
Start or stop a simple vehicle, depending on the value of "activity", in the person actor the command is executed. Before the Tk vehicle called "walk vehicle", the simple vehicle was called "walk vehicle".
The following example starts a simple vehicle in the current person actor.
dive_vehicle_walk on
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_mouse, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_wand_change, dive_vehicle_fast
Start or stop a wand vehicle for a person actor.
PersonActor
dive_vehicle_wand activity
Start or stop a wand vehicle, depending on the value of "activity", in the person actor the command is executed.
The following example starts a wand vehicle in the current person actor.
dive_vehicle_wand on
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_walk, dive_vehicle_mouse, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand_change, dive_vehicle_fast
Turn off or on wand features.
PersonActor
dive_vehicle_wand_change feature activity
Turn on or off wand feature, depending on the value of "activity", in the person actor the command is executed.
The following example changes wand feature "3" to on in the current person actor.
dive_vehicle_wand_change 3 on
dive_send, dive_vehicle_fly, dive_vehicle_kbd, dive_vehicle_hmd, dive_vehicle_walk, dive_vehicle_mouse, dive_vehicle_speed, dive_vehicle_object_mouse, dive_vehicle_wand, dive_vehicle_fast
Set the directional and angular velocity of a Dive object
Dive
dive_velocity id {dx dy dz} {ax ay az}
Change the directional or angular velocity of an object identified by "id". The directional velocity will be set to the vector (dx, dy, dz) and the angular velocity to (ax, ay, az), which represents three Euler angles. The directional values should be given in meters/second and the angular values in radians/second.
The following example would make the object it is written in moving forward (i.e. along the Z axis) at a speed of 0.25 m/s.
dive_velocity [dive_self] 0 0 0.25 0 0 0
dive_dir_velocity dive_ang_velocity dive_self
Configure video.
Dive
dive_video_configure
Configure video.
The following example
dive_video_configure
dive_video_out_stop dive_video_out_start dive_video_in_stop dive_video_in_start dive_video_image_quality
Set quality of video images.
Dive
dive_video_image_quality
Set quality of video images.
The following example
dive_video_image_quality
dive_video_configure dive_video_out_stop dive_video_out_start dive_video_in_stop dive_video_in_start
Start video in.
Dive
dive_video_in_start
Start video in.
The following example
dive_video_in_start
dive_video_out_stop dive_video_out_start dive_video_in_stop dive_video_configure dive_video_image_quality
Stop video in.
Dive
dive_video_in_stop
Stop video in.
The following example
dive_video_in_stop
dive_video_out_stop dive_video_out_start dive_video_in_start dive_video_configure dive_video_image_quality
Start video out.
Dive
dive_video_out_start
Start video out.
The following example
dive_video_out_start
dive_video_out_stop dive_video_in_start dive_video_in_stop dive_video_configure dive_video_image_quality
Stop video out.
Dive
dive_video_out_stop
Stop video out.
The following example
dive_video_out_stop
dive_video_out_start dive_video_in_start dive_video_in_stop dive_video_configure dive_video_image_quality
Disconnect current process from a world.
Dive
dive_world_disconnect world_id
Disconnect current process from world identified by "world_id".
The following example disconnect the current process from the world which identifier is contained in the variable named "wid".
dive_world_disconnect $wid