Dive 3 Reference Manual
Web site: <http://www.sics.se/dive/manual/entity.html>
Emmanuel Frécon - <emmanuel@sics.se>
Olof Hagsand - <olof@sics.se>
Olov Ståhl - <olovs@sics.se>
The Swedish Institute of Computer Science
Stockholm, June 1997
1. Introduction
This document describes Dive entities, how they are created and
manipulated locally by the functional interface. It requires some
background knowledge about C and Dive[1].
2. Entity class and hierarchies
__ DIVE_OBJ
/
| _ WORLD
| /
______ DIVENODE-- LOD
/ | \_
| | BILLBOARD
| |
| \__ SWITCH
|
| ____ ACTOR
| / ____ DLIGHT
| | /
ENTITY--- LIGHT----- PLIGHT
| \____
| SLIGHT
|
| _______ LINE
| /
| | ______ BOX
| | /
| || _____ POINTSET
| || /
| ||| _____ N_POLY
\_______ |||/
VIEW------ N_M_POLY
||||\_____
|||| QUAD_GRID
||| \_____
||| ELLIPSE
|| \______
|| CYLINDER
| \_______
| TEXT_OBJ
\________
SPHERE
Figure 1: Entity class hierarchy
Dive entities form the basic units of distribution that can be addressed, requested and distributed. Figure 1 shows a class hierarchy (note that the class hierarchy is only used for modeling, Dive is implemented in plain C) where the entity class is the top-level abstraction. An entity has a globally unique identifier used for addressing, a name, a behaviour description, and a set of properties that can be used for application specific data. The entity, divenode and view classes are abstract classes, i.e., no instantiations are allowed.
Entities are structured hierarchically: a world is a top object, while
dive_objects are non-terminals (nodes), views are terminals (leaves)
with three-dimensional graphical representations, and lights are
terminals with a light model definition.
2.1. Creating, publishing and distributing entities
After an entity or an entity hierarchy has been created and initialized locally with the functions described in this document, it is published, that is, distributed and made available to the distributed environment, so that it may replicated at other peers. After an entity has been published it is said to be distributed, and the object should only be modified by operations defined in the distribution module[2].
In this way, entities go through the following states:
If local operations are performed on entities during the distributed
phase, the entity will only be updated at the local site, not at other
sites having the replica.
2.2 Entity flags and access macros
Entities have flags describing properties of the entities. Each such flag is accessed by one access macro to get the value, and one to set the value, the flag can not be accessed directly. For example, a flag entity_group, has access macro entity_group(entity*), and a macro entity_group_set(entity*, bool) to set the value.
The reason for this is that they may not be up to date and or that the internal representation of the object may differ from what has been described in the psedo-C code.
Below, each flag is described along with the other fields of the
entities.
3 Entity definitions
In this section, each entity class as depicted in Figure 1 is described. First, the class is given in pseudo-code with a description of each field, and the the flags are described. Many of the fields and flags can be set by the file interface [1].
The full C interface to access and modify the fields is given
in the Dive C-reference manuals.
3.1 Entity
The entity is the most general entity definition. All other entities inherit the fields and flags of entity.
The pseudo-C definition of an entity is as follows:
struct entity {
DIVE_object_type obj_type;
objid_t id;
seq_t seq;
struct prop_link *global_props;
struct prop_link *local_props;
char *obj_name;
struct method *method;
objid_t super_id;
void *group;
void *addr;
}
Each field of the entity have the following meaning:
The flags of entity are as follows:
Macros for reading the status of entity flags:
divebool entity_group(entity *)
divebool entity_proc_bound(entity *)
Macros for setting the status of entity flags:
divebool entity_group_set(entity *, divebool)
divebool entity_proc_bound(entity *, divebool)
The divenode class extends entity with the following field:
struct hash_entry *sub_obj;
where "sub_obj" is a pointer to a linked array of sub objects. Thus,
the divenode class extends the entity class with sub-objects. A
divenode can act as a node, not only as a leaf, in an hierarchy. Only
wrlds and dive_objects have this property.
3.3 Dive_obj
The dive_obj class extends divenode with the following fields:
mat_t *material;
int no_materials;
char **texture;
int no_textures;
point_t R[3];
point_t T;
point_t *dirV;
point_t *angV;
float obj_radius;
float *lod_vector;
int lod_len;
The extra fields that dive_obj adds have the following meanings:
The flags of dive_obj usually effects all descendants of the object. For example, flags with graphical meaning (gouraud, invisible, etc) effect all views in the sub-structure of this dive_object. The flags of dive_obj are the following:
Macros for reading the status of dive_obj flags:
divebool diveobj_invisible(dive_obj *)
divebool diveobj_nograsp(dive_obj *)
divebool diveobj_wireframe(dive_obj *)
divebool diveobj_nobackface(dive_obj *)
divebool diveobj_realobj(dive_obj *)
divebool diveobj_gouraud(dive_obj *)
divebool diveobj_collision(dive_obj *)
divebool diveobj_propagate(dive_obj *)
divebool diveobj_clipping_plane(dive_obj *)
divebool diveobj_concave(dive_obj *)
Macros for setting the status of dive_obj flags:
divebool diveobj_invisible_set(dive_obj *, divebool)
divebool diveobj_nograsp_set(dive_obj *, divebool)
divebool diveobj_wireframe_set(dive_obj *, divebool)
divebool diveobj_nobackface_set(dive_obj *, divebool)
divebool diveobj_realobj_set(dive_obj *, divebool)
divebool diveobj_gouraud_set(dive_obj *, divebool)
divebool diveobj_collision_set(dive_obj *, divebool)
divebool diveobj_propagate_set(dive_obj *, divebool)
divebool diveobj_clipping_plane_set(dive_obj *, divebool)
divebool diveobj_concave_set(dive_obj *, divebool)
The world class extends divenode with the following fields:
char *terrain;
point_t start;
rgbtriplet background_rgb;
float attenuation_constant;
float attenuation_rate;
float far_clip;
float near_clip;
float fog;
char *info;
char *url;
int ttl;
The fields have the following meanings:
The flags of world are the following:
Macros for reading the status of world flags:
divebool world_resident(world *)
Macros for setting the status of world flags:
divebool world_resident_set(world *, divebool)
The formula for attenuation (degrading of local lights with distance) is:
1/(Kc + Kr*D)
where Kc is a constant factor, the attenuation_constant (=1 by
default), D is the distance and Kr is the attenuation rate.
3.5 Level of Detail (LOD)
Level of details are used to describe a same logical object with different geometries. One of the geometries will be used when rendering, depending on the distance or the angle between the viewer and the object.
The level of detail class extends divenode with the following fields:
float obj_radius;
point_t center;
int lod_len;
float *lod_vector;
The fields have the following meanings:
The flags of lod are the following:
Macros for reading the status of lod flags:
divebool lod_angles(lod_t *)
Macros for setting the status of lod flags:
divebool lod_angles_set(lod_t *, divebool)
Billboards are special objects which rotate around an axis or a point in order to always look at the viewer.
The billboard class extends divenode with the following fields:
float obj_radius;
point_t axis;
The fields have the following meanings:
There are no flags in billboards.
3.7 Switch
Switch are special object which choose, one, none or all of their children for rendering, intersection, collision, etc.
The switch class extends divenode with the following fields:
float obj_radius;
int choice;
The fields have the following meanings:
There are no flags in switches.
3.8 Actors
An actor is an entity which is bound to an application and process. Typical actors are bound to a user using a browser application. The actor has associated objects that have special, application-specific, meaning (eg. bodies).
The actor class extends entity with the following fields:
struct association *assoc_list;
int assoc_len;
char *user;
char *host;
The fields have the following meaning:
Lights can be added as sub-objects and are subject to geometrical
transformations (like views) so that they are defined in space. The
differences between directional light (dlight), positional light
(plight) and spot light (slight) are the following. Directional light
interprets its position as a direction vector where the light is
placed at infinity. A positional light interprets its position in
space as the origin of a light. A spot light extends positional
lights by also having a direction in space, where its rotation (the
R-factor of its super dive_obj) defines the direction of the spot
light.
3.9.1 dlight and plight
The light class extends entity with the following fields:
rgbtriplet color;
rgbtriplet ambient;
The fields have the following meanings:
The dlight and plight classes are identical to light.
3.9.2 slight
The spot light (slight) class extends light with the following fields:
float exponent;
float spread;
The fields have the following meanings:
View is an abstract class (like entity and divenode) that extends entity with the following fields:
float obj_radius;
int material_index;
int texture_index;
point_t tex_R[3];
point_t tex_T;
The fields have the following meaning:
The flags of views are the following:
Macros for reading the status of view flags:
divebool view_invisible(view *)
divebool view_wireframe(view *)
divebool view_gouraud(view *)
divebool view_nobackface(view *)
divebool view_concave(view *)
Macros for setting the status of view flags:
divebool view_invisible_set(view *, divebool)
divebool view_wireframe_set(view *, divebool)
divebool view_gouraud_set(view *, divebool)
divebool view_nobackface_set(view *, divebool)
divebool view_concave_set(view *, divebool)
The line class extends view with the following fields:
point_t *vertex;
unsigned int v_len;
The fields have the following meaning:
A box has eight corners and six rectangular polygons aligned
with the coordinate axes.
The box class extends view with the following fields:
point_t vertex[8];
The eight vertexes define the box, or parallellepiped. Vertex[0] is
the "smallest" while vertex[5] is the "largest" vertex, that is, each
component (x, y, z) is larger in vertex 5 than vertex 0.
Related commands
http://www.sics.se/dive/manual/cref.i.html#init_box_pt
3.13 Pointsets
A pointset is a set of vertices which can be assembled together to build multi-polygons, polylines or independant vertices. Pointsets are mostly used to build polygons in a separate plane.
A pointset building polygons typically consists of a set of vertices, normals and a set of polygon descriptions specifying how polygons are drawn from the vertex set. The polygons can also have textures, colours and materials depending on the values of a number of flags. Materials, colours and normals either are either defined per polygon (per_prim) or per vertex (per_vertex).
The pointset class extends view with the following fields:
prim_type_t prim_type;
point_t *vertex;
unsigned int v_len;
point_t *normals;
unsigned int n_len;
pt2d_t *texcoords;
unsigned int t_len;
int *npoly;
unsigned int p_len;
point_t *colours;
unsigned int c_len;
int *material;
unsigned int m_len;
point_t *vertexnormals;
unsigned int vn_len;
int *norm_idx;
unsigned int nidx_len;
int *tex_idx;
unsigned int tidx_len;
The fields have the following meaning:
The flags of pointsets are the same as the flags of n_m_poly, i.e.:
Note that some flags override others. This means that not all flag combinations are valid.
Macros for reading the values of the n_m_poly flags:
divebool nmpoly_draw_c_per_prim(struct pointset *)
divebool nmpoly_draw_c_per_vertex(struct pointset *)
divebool nmpoly_draw_t_per_vertex(struct pointset *)
divebool nmpoly_draw_n_per_prim(struct pointset *)
divebool nmpoly_draw_n_per_vertex(struct pointset *)
divebool nmpoly_draw_m_per_vertex(struct pointset *)
divebool nmpoly_draw_m_per_prim(struct pointset *)
Macros for setting the values of the pointset flags:
void nmpoly_draw_c_per_prim_set(struct pointset *, divebool)
void nmpoly_draw_c_per_vertex_set(struct pointset *, divebool)
void nmpoly_draw_t_per_vertex_set(struct pointset *, divebool)
void nmpoly_draw_n_per_prim_set(struct pointset *, divebool)
void nmpoly_draw_n_per_vertex_set(struct pointset *, divebool)
void nmpoly_draw_m_per_vertex_set(struct pointset *, divebool)
void nmpoly_draw_m_per_prim_set(struct pointset *, divebool)
A polygon, n_poly, is an n-sided polygon defined in the plane. The n_poly class extends view with the following fields:
point_t *vertex;
unsigned int v_len;
point_t normal;
pt2d_t *t_arr;
unsigned int t_len;
The fields have the following meaning:
Vertexes should be given in clockwise order.
3.15 Multi polygons
A multi-polygon consists of a set of primitive polygons, each defined in a separate plane. In essence, a n_m_poly consists of a set of vertices, normals and a set of polygon descriptions specifying how polygons are drawn from the vertex set. The polygons can also have textures, colours and materials depending on the values of a number of flags. Materials, colours and normals either are either defined per polygon (per_prim) or per vertex (per_vertex).
WARNING: The n_m_poly class is deprecating and will progressively be replaced by the more flexible pointset.
The n_m_poly class extends view with the following fields:
point_t *vertex;
unsigned int v_len;
point_t *normals;
unsigned int n_len;
pt2d_t *t_arr;
unsigned int t_len;
int *npoly;
unsigned int p_len;
point_t *colours;
unsigned int c_len;
int *material;
unsigned int m_len;
prim_type_t prim_type;
The fields have the following meaning:
The flags of n_m_poly are the following:
Note that some flags override others. This means that not all flag combinations are valid.
Macros for reading the values of the n_m_poly flags:
divebool nmpoly_draw_c_per_prim(struct n_m_poly *)
divebool nmpoly_draw_c_per_vertex(struct n_m_poly *)
divebool nmpoly_draw_t_per_vertex(struct n_m_poly *)
divebool nmpoly_draw_n_per_prim(struct n_m_poly *)
divebool nmpoly_draw_n_per_vertex(struct n_m_poly *)
divebool nmpoly_draw_m_per_vertex(struct n_m_poly *)
divebool nmpoly_draw_m_per_prim(struct n_m_poly *)
Macros for setting the values of the n_m_poly flags:
void nmpoly_draw_c_per_prim_set(struct n_m_poly *, divebool)
void nmpoly_draw_c_per_vertex_set(struct n_m_poly *, divebool)
void nmpoly_draw_t_per_vertex_set(struct n_m_poly *, divebool)
void nmpoly_draw_n_per_prim_set(struct n_m_poly *, divebool)
void nmpoly_draw_n_per_vertex_set(struct n_m_poly *, divebool)
void nmpoly_draw_m_per_vertex_set(struct n_m_poly *, divebool)
void nmpoly_draw_m_per_prim_set(struct n_m_poly *, divebool)
An ellipse view defines a flat ellipse approximation in the (z=0)-plane. The ellipse class extends view with the following fields:
float major_radius;
float radius;
The fields have the following meaning:
A sphere view defines a sphere by an approximation with planar triangles. The sphere view can be distorted by scaling in the three coordinate axes. The sphere class extends view with the following fields:
float xradius;
float yradius;
float zradius;
The fields have the following meaning:
The cylinder class defines an approximation of a cylinder, like an ellipse extended in the z-axis. The cylinder may be distorted by a ratio that describes the ratio between the top-ellipse and the bottom ellipse. In this way, cones may be implemented by the cylinder class. be. The cylinder class extends view with the following fields:
float major_radius;
float radius;
float ratio;
float height;
The fields have the following meaning:
The flags of cylinder are the following:
Macros for reading the status of cylinder flags:
divebool cylinder_draw_part_side(struct cylinder *)
divebool cylinder_draw_part_top(struct cylinder *)
divebool cylinder_draw_part_bottom(struct cylinder *)
Macros for setting the status of cylinder flags:
void cylinder_draw_part_side_set(struct cylinder *, divebool)
void cylinder_draw_part_top_set(struct cylinder *, divebool)
void cylinder_draw_part_bottom_set(struct cylinder *, divebool)
A text view defines a piece of text drawn in the three dimensional environment. The text class extends view with the following fields:
char *text;
unsigned int len;
font_t font;
float size;
text_align_t alignment;
The fields have the following meaning:
The "cc" font is drawn with capitals only. The special font "2d" is a
two-dimensional font. If specified, the text is always drawn in fixed
size in the x and y plane of the viewer (cf. "billboard").
4. Creating and Initializing Entities
Each non-abstract entity has a function to create a new instance. The creation functions allocates memory for the entity, inserts it in the entity database and returns a pointer to the newly created entity. All function has an "id and a "super" argument, while some have an extended argument list.
The first argument, "id", is a pointer to a dive identifier. If defined, it is used for the entity, otherwise, a new identifier is generated. The second argument, "super", is the super object under which the new entity should be placed in the hierarchy. If "super" is NULL, the entity is created outside any hierarchy.
Some entities have initialization functions that may be useful, such
as computing the normals automatically given a set of vertexes.
4.1 Dive_obj, worlds and actors
Worlds, dive_objects and actors are created with the following functions, respectively:
http://www.sics.se/dive/manual/cref.n.html#new_world,
http://www.sics.se/dive/manual/cref.n.html#new_dive_obj,
http://www.sics.se/dive/manual/cref.n.html#new_actor.
4.2 Lights
Directional, positional and spot lights are created with the following functions, respectively:
http://www.sics.se/dive/manual/cref.n.html#new_dlight,
http://www.sics.se/dive/manual/cref.n.html#new_plight
http://www.sics.se/dive/manual/cref.n.html#new_slight
4.3 Lines
Lines are created with the following function:
http://www.sics.se/dive/manual/cref.n.html#new_line_view
4.4 Boxes
Boxes are created with the following function:
http://www.sics.se/dive/manual/cref.n.html#new_box_view
4.5 Polygons
Polygons are created with the following function:
http://www.sics.se/dive/manual/cref.n.html#new_n_poly_view
http://www.sics.se/dive/manual/cref.i.html#init_n_poly
4.6 Multi polygons
Multiple polygons (n_m_polys) are created with the following function:
http://www.sics.se/dive/manual/cref.n.html#new_n_m_poly_view
http://www.sics.se/dive/manual/cref.i.html#init_n_m_poly
4.7 Ellipses
Ellipses are created by the following function:
http://www.sics.se/dive/manual/cref.n.html#new_ellipse_view
4.8 Spheres
Spheres are created by the following function:
http://www.sics.se/dive/manual/cref.n.html#new_sphere_view
4.9 Cylinders
Cylinders are created by the following function:
http://www.sics.se/dive/manual/cref.n.html#new_cylinder_view
4.10 Text
Text views are created with the following function:
http://www.sics.se/dive/manual/cref.n.html#new_text_obj_view
5. Local manipulation, finding and iterating
This section presents some useful functions for accessing and
manipulating entities locally. Note that for published entities,
local changes will not be propagated automatically to remote replicas.
Modifications of replicated entities must be made with the
distribution module interface [2]. However, prior to publishing
(eg. with distr_new) local copies can be modified freely.
5.1 Finding entities
There are functions for finding entities by its identifer and name, finding supers and subs in a hierarchy. An "ancestor" is an entity being several levels up in a hierarchy. In the same way, "descendants" are sub-entities being several levels down in a hierarchy. A "root" is an entity without a super object. Worlds are typically roots.
http://www.sics.se/dive/manual/cref.f.html#find_entity
http://www.sics.se/dive/manual/cref.f.html#find_subobj_byname
http://www.sics.se/dive/manual/cref.f.html#find_entity_byname_mask
http://www.sics.se/dive/manual/cref.f.html#find_entity_byname_type
http://www.sics.se/dive/manual/cref.f.html#find_super
http://www.sics.se/dive/manual/cref.f.html#find_ancestor
http://www.sics.se/dive/manual/cref.f.html#find_root
http://www.sics.se/dive/manual/cref.f.html#find_group_root
http://www.sics.se/dive/manual/cref.f.html#find_ancestor_byname
5.2 Quering entities
http://www.sics.se/dive/manual/cref.i.html#is_super
http://www.sics.se/dive/manual/cref.i.html#is_ancestor
http://www.sics.se/dive/manual/cref.i.html#is_topobj
5.2 Iterating over entities
http://www.sics.se/dive/manual/cref.f.html#for_all_ancestors
http://www.sics.se/dive/manual/cref.f.html#for_all_subs
http://www.sics.se/dive/manual/cref.f.html#for_all_descendants
http://www.sics.se/dive/manual/cref.f.html#for_all_descendants_type
http://www.sics.se/dive/manual/cref.f.html#for_all_entities_mask
http://www.sics.se/dive/manual/cref.f.html#for_all_entities_type
http://www.sics.se/dive/manual/cref.i.html#iterate_subs
http://www.sics.se/dive/manual/cref.i.html#iterate_subs_fast
http://www.sics.se/dive/manual/cref.i.html#iterate_entity_type
http://www.sics.se/dive/manual/cref.i.html#iterate_ancestors
http://www.sics.se/dive/manual/cref.i.html#iterate_assoc_top
5.3 Changing the hierarchy
Only one function exists for changing the hierarchy:
http://www.sics.se/dive/manual/cref.a.html#add_sub_obj
5.4 Removing entities
Note that the local dispose functions in this section should not be used after they have been published, eg. by distr_new, since they only remove entities from the local database. If a distributed entity should be removed, distr_remove should be called which invokes local dispose functions in each peer that the entity is replicated at.
http://www.sics.se/dive/manual/cref.d.html#dispose_entity
http://www.sics.se/dive/manual/cref.d.html#dispose_entity_top
http://www.sics.se/dive/manual/cref.d.html#dispose_entity_id
6. Dive object specific commands
Dive objects are the logical objects of the database but have no
graphical representations. However, transformations, materials, etc
define the location and appearance of entities (including views) below
it in the hierarchy.
6.1 Material functions
A dive object has a vector of materials. Views typically access material elements by material indexes that identifies one material in the array.
http://www.sics.se/dive/manual/cref.d.html#diveobj_add_material_byname http://www.sics.se/dive/manual/cref.d.html#diveobj_add_material http://www.sics.se/dive/manual/cref.d.html#find_obj_with_material
6.2 Texture functions
++++++++++++++++++++++++
A dive object has a vector of texture. Views typically access texture elements by texture indexes that identifies one texture in the array.
http://www.sics.se/dive/manual/cref.d.html#diveobj_add_texture
6.3 Accessing attributes
Some dive object attributes may not be access directly, e.g., by following a pointer to the object. Instead an access function must be used to acquire correct values. The reason for this is that they may not be up to date and or that the internal representation of the object may differ from what has been described above.
http://www.sics.se/dive/manual/cref.d.html#diveobj_R
http://www.sics.se/dive/manual/cref.d.html#diveobj_T
http://www.sics.se/dive/manual/cref.d.html#diveobj_R0
http://www.sics.se/dive/manual/cref.d.html#diveobj_T0
6.4 Geometric functions
The following geometric functions are only safe to use before objects have been published. Modifications of distributed entities should be made with the distribution interface [2].
http://www.sics.se/dive/manual/cref.d.html#diveobj_transform
http://www.sics.se/dive/manual/cref.d.html#diveobj_move
http://www.sics.se/dive/manual/cref.d.html#diveobj_rotate
http://www.sics.se/dive/manual/cref.d.html#diveobj_fixedXYZ
http://www.sics.se/dive/manual/cref.d.html#diveobj_EulerXYZ
http://www.sics.se/dive/manual/cref.d.html#diveobj_angle_axis
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_transform
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_move
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_rotate
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_fixedXYZ
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_EulerXYZ
http://www.sics.se/dive/manual/cref.d.html#diveobj_abs_angle_axis
http://www.sics.se/dive/manual/cref.d.html#diveobj_lc2wc_pt
http://www.sics.se/dive/manual/cref.d.html#diveobj_wc2lc_pt
http://www.sics.se/dive/manual/cref.d.html#diveobj_wc2lc_frame
http://www.sics.se/dive/manual/cref.d.html#diveobj_lc2wc_frame
7. Intersection
A fundamental functionality in three dimensions is detecting when objects intersect. Note that the default behaviour of most intersection functions is to return as soon as an intersection occurs, except entity_isect_ray and the iteration/callback functions.
http://www.sics.se/dive/manual/cref.e.html#entity_isect_ray
http://www.sics.se/dive/manual/cref.e.html#entity_isect_sphere
http://www.sics.se/dive/manual/cref.e.html#entity_isect
http://www.sics.se/dive/manual/cref.e.html#entity_isect_ray_inv
http://www.sics.se/dive/manual/cref.e.html#entity_isect_ray_inv_cb
http://www.sics.se/dive/manual/cref.e.html#entity_isect_ray_cb
http://www.sics.se/dive/manual/cref.e.html#entity_isect_sphere_cb
http://www.sics.se/dive/manual/cref.e.html#entity_isect_inv
http://www.sics.se/dive/manual/cref.e.html#entity_isect_cb
8. Examples
8.1 Creating and publishing a box
In this simple example, a dive object and a blue box is created. The dive object is inserted under a default world:
{
dive_obj *obj;
struct box *box;
objid_t id;
/* Create a dummy dive_object */
obj = new_dive_obj(&id, (struct divenode *)world);
/* Add a material to it */
diveobj_add_material_byname(obj, "blue");
/* Create the box */
box = (struct box *)new_box_view(NULL, (divenode*)obj);
/* Set box vertices, alt: assign box vertices and
normals manually. */
box->dimension.x = 0.2;
box->dimension.y = 1.6;
box->dimension.z = 0.2;
add_sub_obj(&obj->id, &box->id);
/* Distribute (publish) the new structure to other peers */
distr_new_top(&obj->id, NULL);
}
[1] Dive 3.0 file format interface
[2] Dive 3.1 Reference manual, the Distribution module.