This page will tell you enough to go away and build the Body application. It describes the build and running of the clock application, and also gives an annotation of the code to explain how the application works.
You should compare and contrast this with the UCL Dive/Tcl animated body.
You will need an appropriate avatar that follows the conventions for animation. "ucl_virman_static.vr" is a simple avatar that can be animated by bodydiva. The body hierarchy is very simple, the head and animated arm objects are defined as direct descendants of "top", and the rest of the body is scaled to fit under the head.
The crucial lines in the body file are:
prop "enable_body_limbs" TYPE_INT 7 GLOBAL_PROP prop "head_height" TYPE_FLOAT HeadHeight GLOBAL_PROP prop "total_height" TYPE_FLOAT TotalHeight GLOBAL_PROP prop "arm_length" TYPE_FLOAT ArmLength GLOBAL_PROPThese define parameters that are passed to the animation routines.
The command line is thus:
vishnu -body ucl_virman_static.vrOnce the program is running, you (or other peopl) can pick up your hands and head to animate the body. If you were running with 3D tracker support on then the body would animate continuously.
callback_register_filter(ENTITY_NEW_EVENT, body_init, ACTOR_MASK, NULL, NULL, CALLBACK_SENDER, NULL);All the body animation code is contained in "bodyfunc.c". body_init is called from diva when the actor (and thus their avatar) have been created.
The phases for initialisation are:
top_entity = find_assoc(actor_obj, "top");this gets us the top virtual object in the hiearchy of the avatar.
enable_body_limbs = (int *)property_get(top_entity, enable_body_limbs_prop_id, GLOBAL_PROP);
tmp1 = find_sub_byname(actor_skeleton->top_id, "head"); ... actor_skeleton->head_id = &(tmp1->id);Note that we are storing this information in a structure of type body_skeleton_t. We define this since it makes it very easy to add animation of multiple bodies at a later date.
actor_skeleton->head_cookie = callback_register_filter(DIVEOBJ_COORD_EVENT, head_move, 0, actor_skeleton->head_id, 0, 0, (void*)actor_skeleton);Note that we store the cookie so we can deregister. We pass actor_skeleton itself as the callback parameter to aid extensibility to multiple bodies at a later date.
To read:
hand_pt = diveobj_T0(find_object(hand), time);
To write:
distr_abs_transform(upper, tmp_mx, &tmp_pt, WORLD_C, NULL, NULL);
The supporting math libraries really should be tidied up, but you can of course use your own.
Compare this with the Tcl version. The two are very similar, except for in tcl the code is associated with the objects it animates directly. Thus there is not so much searching for objects (of course the searching only happens once).
This code is not checked for the situation where you change avatar during the dive session. If the code looks very long then bear in mind that 50% of it is error checking!
Anthony Steed, A.Steed@cs.ucl.ac.uk