# canvas3d (n)

Table Of Contents

## Name

canvas3d - Create and manipulate 3d-canvas widgets.

## Synopsis

canvas3d pathName ?options?

## Standard Options

None.

## Widget Specific Options

Command-Line Name: -width
Database Name: width
Database Class: Width

Specifies a desired window width that the canvas widget should request from its geometry manager.

Command-Line Name: -height
Database Name: height
Database Class: Height

Specifies a desired window height that the canvas widget should request from its geometry manager.

Command-Line Name: -background
Database Name: background
Database Class: Background

Specifies the background color for the widget.

Command-Line Name: -visibleangle
Database Name: visibleangle
Database Class: Visibleangle

This option is part of the low-level camera configuration interface. See the "CAMERA POSITIONING" section below for details.

Command-Line Name: -cameralocation
Database Name: cameralocation
Database Class: Cameralocation

This option is part of the low-level camera configuration interface. See the "CAMERA POSITIONING" section below for details.

Command-Line Name: -cameracenter
Database Name: cameracenter
Database Class: Cameracenter

This option is part of the low-level camera configuration interface. See the "CAMERA POSITIONING" section below for details.

Command-Line Name: -cameraup
Database Name: cameraup
Database Class: Cameraup

This option is part of the low-level camera configuration interface. See the "CAMERA POSITIONING" section below for details.

Command-Line Name: -enablealpha
Database Name: enablealpha
Database Class: Enablealpha

If this boolean option is true, then the alpha component of colors and light intensities is considered. This adds an overhead to the rendering process. If false (the default), then the widget operates as if the alpha component of all colors and light intensities is 1.0.

Command-Line Name: -saveunder
Database Name: saveunder
Database Class: Saveunder

The -saveunder option may be set to "none" (the default), "3d" or "all". The value determines whether or not the scene is rendered directly to a window or to an off-screen buffer that is copied to the window after it is rendered. Using off-screen buffer can be slower than rendering directly to the window, but can speed up certain window refresh operations.

If the value of the -saveunder option is "none", then no off-screen buffers are used. Each time a part of the window is exposed or an item modified the entire scene is redrawn. Unless the scene is very complicated, this is usually the best mode to use.

If the value of the -saveunder option is "all", then the entire scene, including overlay items, is rendered to an off-screen buffer. If an item is modified the entire scene must still be redrawn, but window expose events can be handled quickly.

If the value of the -saveunder option is "3d", then the 3d portion of the scene is stored in one off-screen buffer, and the entire scene (3d plus overlay) in another. This means that expose events may be handled without any redrawing and modifications to or deletions or additions of overlay items can be handled without redrawing the 3d portion of the scene.

## Introduction

The 3d-canvas widget is a Tk widget that provides a way to draw and manipulate three-dimensional scenes. It is in many ways similar to the core canvas widget that provides for two-dimensional drawing.

The 3d-canvas widget displays a three-dimensional scene. A scene consists of three major elements specified by the user:

- Zero or more geometric primitives (polygons, lines, points etc.) specified in three-dimensional space.
- Zero or more lighting sources.
- A camera position and orientation from which the scene is viewed.
- Zero or more overlay items - primitives specified in two-dimensional space drawn on top of a scene. scene in two dimensional space.

Geometric primitives, lighting sources and overlay items are collectively referred to as "items".

After a scene has been created, items or collections of items may be manipulated (e.g. moved or re-colored). The camera position and orientation may also be altered after a scene has been constructed. This may be used to produce animation effects or interactive scenes.

## Widget Command

The canvas3d command creates a new Tcl command whose name is pathName. This command may be used to invoke various operations on the widget. It has the following general form:

    pathName option ?arg arg ...?

Option and the args determine the exact behavior of the command. Some of the widget commands described below accept a "search" argument. The format of these arguments is described in the ITEM SEARCHES section below. Some widget commands accept a "transform" argument. The format of "transform" arguments is described in the TRANSFORMATIONS section of this manpage.

pathName addtag search tagToAdd ?tagToAdd ...?

For each item returned by the search parameter, add each tagToAdd to the list of tags associated with the item if it isn't already present.

Refer to the "item searches" section of this manpage for the format of the search parameter and the significance of associating a tag with an item.

pathName boundingsphere search

This command returns a description of a three-dimensional sphere that encompasses all geometric primitives returned by the search parameter. Overlay items and light sources are automatically excluded from the search.

The value returned is a usually a list of four floating point numbers. The first list element is the radius of the sphere. The following three are the X, Y and Z coordinates components of the sphere origin, respectively. If the search parameter specifies an item search that returns no items, then an empty string is returned.

Refer to the "item searches" section of this manpage for the format of the search parameter.

pathName bbox search

This command returns a description of the smallest possible two-dimensional rectangle that encompasses the projection of the geometric primitives returned by the search parameter onto the widget viewport. Light sources are automatically excluded from the search.

The value returned is usually a list of four integers. The first two values are the X and Y coordinates of the top-left corner of the returned rectangle. The following two values are the X and Y coordinates of the bottom-right corner. All values are in pixel units relative to an origin in the top-left corner of the viewport.

Refer to the "item searches" section of this manpage for the format of the search parameter.

pathName cget option

Returns the current value of the configuration option given by option. Option may have any of the values accepted by the canvas3d command.

pathName configure ?option? ?value? ?option value ...?

Query or modify the configuration options of the widget. If no option is specified, returns a list describing all of the available options for pathName (see Tk_ConfigureInfo for information on the format of this list). If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the canvas3d command.

pathName coords search ?coordList...?

This command is used to query or modify the coordinates of an existing item. The way in which item coordinates are specified is described in the ITEM TYPES section below.

If this command is invoked with no coordList arguments, then the current coordinates of the item identified by the search parameter. If the search parameter identifies more than one item, then the coordinates of the first item located are returned.

As described in the ITEM TYPES section, each item type accepts either exactly one, or one or more coordList (or 2dCoordList) parameters. For items that accept a single coordList parameter only the value of that parameter is returned. For items that accept one or more coordList parameters, the returned value is a list of all those parameters. For example, assuming ".win" is the name of a canvas3d widget:

    .win create polygon {0 0 0} {1 1 1}  -tags P1
    .win create polygon {2 2 2}          -tags P2
    .win create 2dtext {100 100}         -tags T
    set A [.win coords P1]    ;# A is now {{0 0 0} {1 1 1}}
    set B [.win coords P2]    ;# B is now {{2 2 2}}
    set C [.win coords T]     ;# C is now {100 100}

If the [pathName coords] command is invoked with one or more coordList (or 2dCoordList, depending on the type of the item returned by the search) parameters, then these arguments replace the current coordinates of the item identified by the search parameter. If the search parameter identifies more than one item, then the coordinates of the first item located are returned. The arguments are interpreted exactly as if they had been passed to the [pathName create] command.

pathName create type coordList ?option value ...?

Create a new item and add it to pathName. The exact format of the coordList and options is determined by type. The type parameter must be one of 'polygon', 'line', 'point', or 'light'. See the "item types" section of this manpage for details.

The value return is the unique id of the new item. This may be used as part of search parameter expressions.

pathName delete search

Delete all the items identified by the search parameter.

Refer to the "item searches" section of this manpage for the format of the search parameter.

pathName dtag search tagToDelete

For each item returned by the search parameter, remove tagToDelete from the list of tags associated with the item if it is present.

Refer to the "item searches" section of this manpage for the format of the search parameter and the significance of associating a tag with an item.

pathName find ?-sort? search

Return a list of the item ids for all items selected by the search parameter.

If the -sort switch is present, then the returned item ids are sorted as follows:

- Light items, in the order created,
- Overlay items, in stacking order from top to bottom,
- Three dimensional primitives, in order of increasing distance from the viewer.

pathName gettags search

Return a list whose elements are the tags associated with the item identified by the search parameter. If the search returns more than one item, then the tags are returned for the first item located. If the search returns no items, or if the item contains no tags, then an empty string is returned. This command has the same effect as:

    pathName itemcget search -tags

pathName itemcget search option

Returns the current value of the configuration option for the item given by tagOrId whose name is option. This command is similar to the cget widget command except that it applies to a particular item rather than the widget as a whole. Option may have any of the values accepted by the create widget command when the item was created. If tagOrId is a tag that refers to more than one item, the first (lowest) such item is used.

pathName itemconfigure search ?option? ?value? ?option value ...?

This command is similar to the configure widget command except that it modifies item-specific options for the items given by identified by the search parameter instead of modifying options for the overall 3d-canvas widget. If no option is specified, returns a list describing all of the available options for the first item returned by search (see Tk_ConfigureInfo for information on the format of this list). If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s) in each of the items given by tagOrId; in this case the command returns an empty string. The options and values are the same as those permissible in the create widget command when the item(s) were created; see the sections describing individual item types below for details on the legal options.

pathName projection ?x y? ?z?

When given no arguments, this command returns 16 floating point values which comprise the projection matrix for the current camera configuration. When given pixel coordinate arguments x and y, this command returns 3 floating point values which form one of many possible 3-D coordinates that projects into the given pixel. When given 3 arguments which are a point in 3-D space, this command returns the pixel coordinate the point projects into.

For the first mode of operation (with no arguments) the project matrix is a 4x4 matrix as follows:

    M =  p00  p01  p02  p03
         p10  p11  p12  p13
         p20  p21  p22  p23
         p30  p31  p32  p33

The projection matrix is returned in row order: p00, p01, p02, ..., p32, p33. A point in space is defined by a vector such as v:

    V =  x
         y
         z
         w

The w value is normally 1.0. Computing the product M*V gives a new vector where x/w and y/w components correspond to pixel locations on the screen. Both x/w and y/w range from -1.0 to +1.0 where -1.0 is the left or top of the screen and +1.0 is the right or bottom of the screen.

pathName statistics search

This command returns summary statistics for the set of items identified by the search parameter. The returned value is a list of the form {S V S V...} where S is the name of a statistic and V is the corresponding value. The list can be passed to the [array set] command for easy processing. The following statistics are returned:

    Statistic       Interpretation
    --------------------------------------------------------
    nVertex         Total number of vertices (does not include
                    overlay or light items)
    nFace           Total number of polygon faces.

pathName transform ?-camera? search transform

Apply the specified transform to all items identified by the search parameter. If the -camera option is present, then the camera is transformed as well (see section CAMERA CONFIGURATION for a description of what this means).

pathName type search

Returns the type of the item identified by search, such as polygon or line. If search identifies more than one item, then the type of the first item located is returned. If search doesn't refer to any items at all then an empty string is returned.

## Item Types

All items accept the following options:

    -tags                    <tag-list>        ()
    -hidden                  <boolean>         (false)

The -tags option is used to set or retrieve the list of tags associated with an item (see TAGS AND UNIQUE IDS below).

If the -hidden option is true for an item, then the item is not rendered. An item with the -hidden option set to true never matches a viewport() search (see ITEM SEARCHES below).

All items fall into one of three categories:

- Light sources. Currently this is "light" items only.
- Overlay items. This category consists of items specified in two dimensional space to be rendered on top of the three dimensional scene. Items that start with "2d" are overlay items: "2dtext", "2dline" and "2dpolygon".
- Three dimensional primitives. This category includes all items specified in three dimensional space. Currently this include "polygon" and "line" items. All items that are not light sources or overlay items are three dimensional primitives.

The [pathName create] command for all item types accept a parameter or parameters denoted "coordList" or "2dCoordList". "coordList" parameters are used to specify coordinates for light sources and three dimensional items. "2dCoordList" parameters specify coordinates for overlay items.

The form of a coordList parameter is a Tcl list consisting entirely of numeric values. The length of the list must be a multiple of three. The first three elements of the list specify the x, y and z components of the first vertex, respectively. The fourth, fifth and sixth elements of the list (if present) specify the x, y and z components of the second vertex, and so on.

The format of a 2dCoordList parameter is similar to a coordList parameter, except that the length of the list must be a multiple of two. The first two elements of the list specify the x and y components of the first vertex (there is no z component), and so on. Coordinates found in 2dCoordList parameters are screen coordinates. The 2dCoordList parameter value {100 200} identifies a point on the screen 100 pixels to the right of and 200 pixels below the top left corner of the widget window.

Some of the [pathName create] commands below accept multiple coordList or 2dCoordList parameters. In this case, as well as the syntax shown, passing a single list of coordList (or 2dCoordList) parameters is equivalent to passing each list element as a separate argument. To illustrate, the first two commands below are equivalent, the third is illegal:

    pathName create polygon $coordsA $coordsB $coordsC
    pathName create polygon [list {$coordsA} {$coordsB} {$coordsC}]
    pathName create polygon [list {$coordsA} {$coordsB}] $coordsC

### Polygon Items

pathName create polygon coordList ?coordList...? ?option value...?

Polygon items are displayed as one or more opaque or wireframe 2-dimensional polygons located in three-dimensional space. A single polygon item consists of one geometric polygon for each coordList parameter passed to the [pathName create polygon] command.

To create a geometric polygon, three or more vertices must be supplied (i.e. coordList must contain at least 9 numeric values). For correct display, geometric polygons must be roughly planar and not convex.

Polygon items support the following options:

    -style            solid|outline             (solid)
    -color            <color>                   (white)
    -smooth           <boolean>                 (false)

    -teximage         <image-name>              ()
    -texcoords        {<x1> <y1> <x2> <y2> ...} ()

    -ambient          <color>
    -diffuse          <color>
    -specular         <color>
    -emission         <color>
    -shininess        <float>

The value of the -style option determines whether the polygon is drawn as a solid shape (solid) or a wireframe (outline). The default value is solid.

If no light items are defined, or if the -style option is set to "outline", then each polygon is rendered in the color specified by the -color option. Otherwise, the -ambient, -diffuse, -specular, -emission and -shininess options are used in conjunction with the configuration of the various light sources to calculate the display color or colors of each polygon. See the COLORS AND LIGHTING section below for details and default values for these options.

Polygon faces may or may not have a texture applied to them. A texture is an image that is rendered so that it appears to be painted on the polygon face in three dimensional space. In order to add a texture to a polygon face, the -teximage option is set to the name of a Tk image to use as the texture.

Exactly how the texture is applied to the polygon surface is determined by the value of the -texcoords option. Each vertex of the surface is mapped to a point in image coordinates. The top-left corner of the image is designated by coordinates (0, 0), the bottom-right corner (1.0, 1.0). For the purposes of coordinate values outside the range [0.0, 1.0] the image is conceptually tiled horizontally and vertically. For example, mapping each vertice of a square polygon face to the following coordinates results in nine copies of the image being rendered in a three-by-three grid on the polygon face:

    Polygon top-left      ->  (0.0, 0.0)
    Polygon top-right     ->  (3.0, 0.0)
    Polygon bottom-right  ->  (3.0, 3.0)
    Polygon bottom-left   ->  (0.0, 3.0)

    # Example Tcl code:
    set image [image create photo -file _image-file-name_]
    .win create polygon {0 0 0   1 0 0   1 1 0   0 1 0} -tags P
    .win itemconfigure P -teximage $image
    .win itemconfigure P -texcoords {0 0   3 0   3 3   0 3}

The -texcoords option is set to a list of 2N floating point values, where N is an integer. Each pair of values is interpreted as an (x, y) pair of image coordinates. Each polygon vertex is mapped to the corresponding image coordinate. If a polygon has more vertices than image coordinates, then the image coordinates wrap around. For example, if a polygon has 10 vertices and 4 image coordinates, the first, fifth and ninth vertices are all mapped to the first pair of image coordinates. If -texcoords is set to an empty string (the default) this is handled as {0 0 1 0 1 1 0 1}.

If a polygon item has multiple faces, then the texture is applied to each face. The algorithm for determining the mapping from polygon vertex to texture coordinates ignores faces (i.e. if a polygon with six vertices divided into two triangular faces is supplied with four texture coordinates, the first vertex of the second triangle is mapped to the fourth texture coordinate, not the first).

The final color of each polygon pixel (the "pixel color") is determined by modulating the color determined by -color and lighting considerations (hereafter the "fragment color"), and the color of the image pixel mapped to the same location by the texture process (the "texture color"). Modulating two colors is accomplished by multiplying the scalar values of each pair of corresponding channels (red, green, blue and alpha):

    <pixel-red> = <fragment-red> * <texture-red>
    <pixel-green> = <fragment-green> * <texture-green>
    <pixel-blue> = <fragment-blue> * <texture-blue>
    <pixel-alpha> = <fragment-alpha> * <texture-alpha>

To ensure colors are rendered as they appear in the image, the calculated fragment color must be set to {1.0 1.0 1.0 1.0}. This is most easily done by setting the -color option to "white" and not adding any light sources to the scene.

### Line Items

pathName create line coordList ?coordList? ?option value...?

Line items are displayed as one or more line-segments in three-dimensional space. Mathematically, the line has no thickness. The width the line is drawn on the screen with is determined by the -width option (see below).

Each coordList parameter creates a series of one or more connected line-segments with a segment drawn between each adjacent vertex in the coordList (i.e a coordList containing three vertices creates two line-segments). Each coordList must contain at least two vertices.

Line items support the following options:

-color <color> (white) -width <double> 1.0

Line items are always displayed in the color specified by the -color option, regardless of the configuration of any light sources. A line is rendered approximately -width pixels wide, regardless of depth.

### Point Items

pathName create point coordList ?coordList? ?option value...?

Point items are displayed as one or more points in three-dimensional space. Mathematically, the point has no thickness. The size of the point on the screen is determined by the -width option (see below).

Each coordList parameter creates a geometric point at each vertex specified.

Point items support the following options:

-color <color> (white) -width <double> 1.0

Point items are always displayed in the color specified by the -color option, regardless of the configuration of any light sources. A point is rendered approximately -width pixels wide and high, regardless of depth.

### Light Items

pathName create light coordList ?option value...?

A light item adds a light source to a scene. A maximum of eight light sources may be present in a single scene.

Either one or two vertices may be specified when creating a light source. The first vertex represents the location of the light source in three dimensional space. The second vertex is a point in three dimensional space that the spotlight component of the light source (if any) is pointing at. If the second vertex is not specified it defaults to (x, y, z - 1.0), where (x, y, z) is the location of the light source.

Light items support the following options:

    -ambient                 <color>      (black)
    -diffuse                 <color>      (white)
    -specular                <color>      (white)
    -spotexponent            <float>      (0.0)
    -spotcutoff              <angle>      (180.0)
    -constantattenuation     <float>      (1.0)
    -linearattenuation       <float>      (0.0)
    -quadraticattenuation    <float>      (0.0)

### 2dtext Items

pathName create 2dtext 2dCoordList ?option value...?

    -color         <color>        (white)
    -font          <font>         (Helvetica)
    -text          <string>       ()
    -anchor        <anchorPos>    (center)

### 2dline Items

pathName create 2dline 2dCoordList ?2dCoordList...? ?option value...?

    -color         <color>        (white)

### 2dpolygon Items

pathName create 2dpolygon 2dCoordList ?2dCoordList...? ?option value...?

    -color         <color>        (white)

## Colors and Lighting

### Specifying Colors

The underlying OpenGL graphics system handles colors as a vector of four floating point values representing the red, green, blue and alpha channels (RGBA). The alpha value is only used if the widget -enablealpha option is set to true. This is used to create semi-transparent objects.

Ignoring the alpha channel for the time being, the color white is represented as the vector (1.0, 1.0, 1.0). Black is (0.0, 0.0, 0.0). Values outside of the 0.0-1.0 range are valid, but are clipped before display.

Colors may be passed to the widget and item options in any of the following formats:

- As a three member list specifying values for the R, G and B channels. In this case the value of the alpha channel is set to 1.0.
- As a four member list specifying values for the R, G, B and A channels.
- Any form accepted by the function Tk_GetColor(). The values of the R, G and B channels are set based on the Tk color and the alpha channel is automatically set to 1.0.

The following four color definitions are equivalent:

    LightSalmon
    #FFA07A
    {1.0 0.627 0.478}
    {1.0 0.627 0.478 1.0}

### Determining Display Colors

Overlay items and three dimensional lines and outlines are always drawn in the color specified by the items -color option. The way the displayed color of other three-dimensional geometric primitive items is determined depends on whether or not lighting is enabled. Lighting is enabled if one or more light sources (items of type "light") have been added to a scene. Setting the -hidden option on a light item stops the item from contributing any light to the scene, but has no effect on whether or not lighting is enabled.

If lighting is not enabled, then the display color of three dimensional primitives is set by the -color option, in the same way as the color of overlay items. If lighting is enabled, then the rendered color of three dimensional primitives other than lines and outlines depends on the interaction between the primitive and all defined light sources (except those for which the -hidden option is set).

### Lighting Calculations

TODO: Need a description of lighting (not just an explanation of how options are passed through to OpenGL).

Lighting calculations are performed entirely by OpenGL. The parameters of each OpenGL light source are determined by the values of options set on the corresponding 3d-canvas light item. For example the option of the -ambient option is used to set the GL_AMBIENT parameter.

Items that reflect light have the following options. The values of which are used to set the corresponding OpenGL material properties.

    Option		Type		Default value
    -------------------------------------------------
    -ambient	<color>		"0.2 0.2 0.2 1.0"
    -diffuse	<color>		"0.8 0.8 0.8 1.0"
    -specular	<color>		"0.0 0.0 0.0 1.0"
    -emission	<color>		"0.0 0.0 0.0 1.0"
    -shininess	<float>		"0.0"

The values of OpenGL light-model parameters are set as follows:

    Option				Value
    -------------------------------------------------
    GL_LIGHT_MODEL_AMBIENT		"0.0 0.0 0.0 1.0"
    GL_LIGHT_MODEL_LOCAL_VIEWER	false
    GL_LIGHT_MODEL_TWO_SIDE		true

## Transformations

A transformation is used to modify the location, orientation or size of an existing primitive or primitives. Each transformation is specified as a series of one or more "move", "rotate" and "scale" operations, which are applied to the primitive in the order specified. For example, the transformation:

    rotate 90.0 1.0 0.0 0.0 move 0.0 1.0 0.0

is interpreted as "rotate the primitive 90.0 degrees around the X-axis, then move it 1.0 units in the positive Y-direction".

rotate <angle> <x> <y> <z>

A 'rotate' transformation operation requires exactly four arguments. The first is the angle, in degrees, of the desired rotation. The subsequent three arguments define a vector around which the rotation occurs. The rotation follows the right-hand rule, so if the vector is pointed directly at the viewer, the rotation appears to occur in a counter-clockwise direction.

The center point around which the primitive is rotated is always the absolute origin (0.0, 0.0, 0.0).

The magnitude of the vector specified by <x>, <y>, <z> is not used for any purpose. Only the direction of the vector is important.

move <x> <y> <z>

A 'move' transformation operation requires three arguments. The primitive is translated <x> units in the X-direction, <y> units in the Y-direction, and <z> units in the Z-direction.

scale <x> <y> <z>

A 'scale' transformation operation requires three arguments. It is used to stretch or contract a primitive in one or more dimensions.

For any of the above transforms, one of the following strings may be substituted for the three numeric arguments "<x> <y> <z>". Before the transform matrix is calculated, the strings are replaced with numeric coordinates as follows:

center

The current value of the -cameracenter option.

location

The current value of the -cameralocation option.

lineofsight

The vector between the vertex specified by the -cameralocation and the -cameracenter vertex (cameralocation - cameracenter). The vector is not normalized.

up

A unit vector in the "up" direction, from the point of view of the viewer.

down

A unit vector in the "down" direction, from the point of view of the viewer.

left

A unit vector in the "left" direction, from the point of view of the viewer.

right

A unit vector in the "right" direction, from the point of view of the viewer.

Any of the above strings may be prefixed with a "-" character to multiply <x>, <y> and <z> by -1. i.e. "-down" is equivalent to "up". The string "los" is a synonym for "lineofsight".

Both vectors specified using shortcut strings and those specified in full as three floating point coordinates may be followed by a single floating point number, the multiplier. If present, each component of the vector is multiplied by the multiplier. This is particularly useful in concert with the "up", "down", "left" and "right" unit vectors. A vector of length 0.75 in the upward direction, from the point of view of the viewer, may be created with the syntax "up 0.75". This in turn may be used to create useful and intuitive transform syntax, such as "move up 0.75" (move the objects 0.75 units in the upward direction).

## Camera Configurations

How the three dimensional components of a scene (everything except overlay items) are projected onto the widget viewport depends on the camera configuration. The camera configuration determines the point in three dimensional space from which the viewer appears to be viewing the scene and the orientation and direction in which the viewer is looking. There are two ways to control the camera configuration:

- Directly, by manipulating the -cameralocation, -cameracenter, -cameraup and -visibleangle widget options.
- Using transformations. The camera can be transformed in a similar manner to item primitives, as described in the "TRANSFORMATIONS" section.

Configuring the camera using transformations is almost always easier. Both interfaces may be used by a single application.

### Camera Configuration By Widget Options

The -visibleangle option is used to set the vertical field of view of the viewer, in degrees. The horizontal field of view is set automatically, based on the window size and configured vertical field of view. The default value is 60.0 degrees.

The -cameralocation option specifies a point in three dimensional space at which the camera is located. It should be set to a list of three numeric values, the x, y and z coordinates of the camera. The default value is {0.0 0.0 1.0}.

The -cameracenter option specifies a point in three dimensional space that the camera is pointed at. The default value is {0.0 0.0 0.0}. Rendering results are undefined if the -cameracenter coordinates are the same as the -cameralocation coordinates.

The -cameraup option is a three dimensional vector that points roughly "upwards" from the point of view of the viewer. The default value is {0.0 1.0 0.0}. This option does not need to be set to a unit vector, it will be scaled internally. Also, this vector does not have to lie exactly on the viewport plane. However, if the vector is parallel or very close to parallel to the line of sight, then rendering results are undefined.

### Camera Configuration By Transformations

To avoid the complications of setting the above options, transformations can be used to configure the camera center, location and up direction (the -visibleangle option still needs to be set manually). The transformation specifications used are the same as those described in the "TRANSFORMATIONS" section.

To understand how a transformation will affect the three camera options, imagine a triangle in three-dimensional space (similar to a polygon item with three vertices). The values of the -cameralocation and -cameracenter options make up two of the triangles vertices. The third is found by adding the -cameraup vector to the -cameralocation vertex. When a transformation is applied to the camera, this triangle is created and transformed in three-dimensional space. After the transformation, the -cameralocation, -cameracenter and -cameraup options are set based on the transformed vertices of the triangle.

To transform the camera, pass the -camera switch to the [{$widget} transform] command. Passing a value for the "search" parameter of [{$widget} transform] allows scene elements to be transformed along with the camera. For example, if the camera is viewing a scene illuminated by care headlights from inside the automobile, then the scene light sources and three dimensional scene primitives comprising the car dashboard may all be transformed together as follows:

    $widget transform -camera lights||dashboard <transformation spec>

(assuming dashboard elements are associated with the tag group "dashboard").

### Camera Shortcut Transformations

In order to make camera transformations more intuitive, the following shortcut transforms are available. These may be used in any transformation specification along with "move", "rotate" and "scale". They are described here because they are probably only useful in the context of transforming the camera.

lookat <search>

"lookat" is unique among transform primitives as it takes a search parameter as an argument (see the ITEM SEARCHES section below).

If the search parameter returns no items, then this transformation has no effect. Otherwise, the center and radius of a sphere encompassing all returned items is calculated, using the same algorithm as the [{$widget} boundingsphere] command.

Once a sphere has been determined, the camera is rotated in place until it points at the center of the sphere. It then moves away from or toward the center until the projection sphere exactly fills the viewport in either the x or y direction (whichever is smaller).

After this transformation is applied to the camera, the -cameracenter option is set to the center of the calculated sphere. The -cameralocation value is determined by the procedure described in the above paragraph.

orbitup <angle>
orbitdown <angle>
orbitright <angle>
orbitleft <angle>

The orbit transforms are used to rotate the camera around the scene center (the -cameracenter option value), keeping the value of the -cameracenter option constant. This is similar to a satellite orbiting a planet, with the camera located on the satellite always pointed down at the center of the planet.

The <angle> parameter specifies the angle of rotation, in degrees.

The 'orbitup' transformation rotates the camera around the scene center such that the initial direction of movement is directly upwards, from the point of view of the viewer. Similarly the 'orbitdown', 'orbitright' and 'orbitleft' transformations rotate the camera such that the initial directions of movement are respectively downwards, to the right or to the left from the point of view of the view.

panup <angle>
pandown <angle>
panright <angle>
panleft <angle>

The pan transforms are used to rotate the camera center around the camera location. This is similar to (for example) moving your head to look over your shoulder.

The <angle> parameter specifies the angle of rotation, in degrees.

The 'panup' transformation rotates the camera to look upwards, from the perspective of the viewer. The 'pandown', 'panright' and 'panleft' transformations rotate the camera to look downwards, to the right or to the left, from the viewers perspective.

twistright <angle>
twistleft <angle>

The twist transforms rotate the camera around the line of sight. A twist transform leaves the -cameracenter and -cameralocation values constant and modifies the -cameraup vector.

The <angle> parameter specifies the angle of rotation, in degrees.

A 'twistright' rotation produces the same effect as tipping the top of your head to the right, the -cameraup vector is rotated clockwise from the point of view of the viewer. Naturally, a 'twistleft' rotation naturally produces the opposite effect.

movein <scale>

A movein transformation moves the camera location closer to, or further away from the scene center, keeping the -cameracenter and -cameraup vectors constant.

The distance between the scene center and camera location is multiplied by the <scale> parameter.

For example, a "movein 0.9" transform moves the camera 10% closer to the scene center. The transform "movein 1.1111" can be used to move it back (0.9 * 1.1111 = 1.0).

## Tags and Unique Ids

Each item stored by the widget has a unique integer id assigned when the item is created. Item ids are returned by the [{$widget} create] command when an item is first created. They may also be obtained via the [{$widget} find] command.

Each is associated with zero or more named tag-groups or tags. Tag- groups are identified by name. Legal tag names are any string that does not begin with a digit except for the search keyword "all". Multiple items may be associated with a single tag.

Tags may be added to or removed from items using the [{$widget} addtag] and [{$widget} dtag] commands, or by setting the -tags item option. The tags attached to an item may be queried using [{$widget} gettags] or by querying the -tags item option.

## Item Searches

Some of the widget commands described above operate on sets of items identified by a 'search' parameter. Item searches may return (or not return) items based on the following:

- The unique item id,
- Tags associated with an item,
- The type of the item,
- Whether or not the two dimensional projection of the item includes a point on the viewport.
- Logical (&&, ||, ^, !) combinations of the above.

The syntax of a search parameter is:

    <search> = all                    (matches all items)
    <search> = <id>                   (the item with unique id <id>)
    <search> = <tagname>              (items associated with tag <tagname>)
    <search> = type(<type>)           (matches items of type <type>)
    <search> = viewport(<x>, <y>)     (viewport search)
    <search> = hidden()               (matches all items with -hidden set)

    <search> = ( <search> )           (grouping operator)
    <search> = ! <search>             (logical NOT operator)
    <search> = <search> ^ <search>    (logical XOR operator)
    <search> = <search> && <search>   (logical AND operator)
    <search> = <search> || <search>   (logical OR operator)

The operators above are listed in order of precedence.

### Examples

{cubes}

All items associated with the tag "cubes".

{45 || cubes}

All items associated with the tag "cubes" or with unique id "45".

{solid && cubes}

All items associated with both of the tags "cubes" and "solid".

{viewport(45, 80) && !cubes}

All items not associated with the tag "cubes" for which the projection includes the viewport pixel (45, 80).

### Optimization

When large numbers of items are present, some item searches, for example when the search parameter consists of a single id or tag can be much faster than other searches. Such searches can use an index instead of a linear scan of all items. Currently, search expressions of the following forms can use a built in index to speed up the search:

    <tagname>
    <tagname> && <search>
    <id>
    <id> && <search>
    type(light)
    type(light) && <search>

## Shapes

This section describes the "canvas3d shapes library", a library of Tcl code that can be used to create higher level three-dimensional shapes such as spheres or cylinders for display in canvas3d widgets. The shapes library is packaged with the canvas3d code, but it's use is entirely optional; the widget as described above works fine whether or not the shapes library is present.

The shapes library provides Tcl procedures that return lists of polygon faces that can be passed to the [pathName create polygon] command. For example, the [::canvas3d::sphere] returns a list of polygon faces that approximate the surface of a sphere. Hence, the following command creates a sphere in widget .win:

    # Create a sphere.
    .win create polygon [::canvas3d::sphere] -smooth true

By default, [::canvas3d::sphere] returns a sphere centered at the origin with a radius of 1.0. The options described below under the available shapes library commands may be used to change this.

::canvas3d::sphere ?options?

This command returns a list of polygon faces that approximate a sphere. The following options are available:

    -radius           <float>                   (1.0)
    -center           <vertex>                  (0.0 0.0 0.0)
    -detail           <integer>                 (3)

The -radius option sets the radius of the sphere returned, which is centered at the vertex defined by the value of the -center option.

The value of the -detail option is used to determine the number of triangle faces used to approximate the sphere. The higher the integer value, the more triangles used. In the current implementation the exact number of triangles is (2 ^ (2N + 3)), where N is the value of -detail. Negative values for -detail are treated as 0.

::canvas3d::cylinder ?options?

This command returns a list of polygon faces that approximate the curved surface of a cylinder. The following options are available:

    -radiusone        <float>                   (1.0)
    -radiustwo        <float>                   (1.0)
    -center           <vertex>                  (0.0 0.0 0.0)
    -height           <float>                   (1.0)
    -normal           <vector>                  (0.0 0.0 1.0)
    -detail           <integer>                 (3)

The -radiusone and -radiustwo options define the radii of the circles at either end of the cylinder (A cone can be drawn by setting one option to 0.0 and the other to a non-zero value). The -center option is set to the vertex that lies at the center of the cylinder, defined as the midpoint of the line between the centers of the circles at either end of the cylinder.

The -height option is set to the distance between the centers of the two circles, and the -normal option indicates the direction of that vector.

The value of the -detail option is used to determine the number of quadralaterals used to approximate the surface. Currently the exact number of quadralaterals is (2 ^ (N + 2)), where N is the value of the -detail option.

::canvas3d::disc ?options?

This command returns vertices for a single polygon face that approximates a flat disc. The following options are available:

    -radius           <float>                   (1.0)
    -center           <vertex>                  (0.0 0.0 0.0)
    -normal           <vector>                  (0.0 0.0 1.0)
    -detail           <integer>                 (3)

The radius of the disc is determined by the value of the -radius option. The -center option defines the vertex that lies at the center of the returned shape. The -normal option is set to a vector normal to the surface of the disc.

The value of the -detail option is used to determine the number of vertices used to approximate the curved edge. Currently the exact number of vertices is (2 ^ (N + 2)), where N is the value of the -detail option.

Contributions of new shapes (or better implementations of the ones in c3dshapes.tcl) to the shapes library are very welcome. Please refer to http://3dcanvas.tcl.tk for contact details.

## Bindings

In the current implementation, new 3d-canvases are not given any default behavior: you'll have to execute explicit Tcl commands to give the 3d-canvas its behavior.

## Credits

Some text in this manpage was copied directly from the Tk canvas manpage.

## Keywords

canvas3d, 3dcanvas, 3d-canvas, widget

# canvas3d (n) - Table Of Contents

- Name
- Synopsis
- Standard Options
- Widget Specific Options
- Introduction
- Widget Command
- Item Types
  - Polygon Items
  - Line Items
  - Point Items
  - Light Items
  - 2dtext Items
  - 2dline Items
  - 2dpolygon Items
- Colors and Lighting
  - Specifying Colors
  - Determining Display Colors
  - Lighting Calculations
- Transformations
- Camera Configurations
  - Camera Configuration By Widget Options
  - Camera Configuration By Transformations
  - Camera Shortcut Transformations
- Tags and Unique Ids
- Item Searches
  - Examples
  - Optimization
- Shapes
- Bindings
- Credits
- Keywords