[TH canvas3d n]
[Section Name]
canvas3d - Create and manipulate 3d-canvas widgets.
[Section Synopsis]
canvas3d pathName ?options?
[Section Standard Options]
None.
[Section Widget Specific Options]
[Option width {
Specifies a desired window width that the canvas widget
should request from its geometry manager.
}]
[Option height {
Specifies a desired window height that the canvas widget
should request from its geometry manager.
}]
[Option background {
Specifies the background color for the widget.
}]
[Option visibleangle {
This option is part of the low-level camera configuration
interface. See the "CAMERA POSITIONING" section below for
details.
}]
[Option cameralocation {
This option is part of the low-level camera configuration
interface. See the "CAMERA POSITIONING" section below for
details.
}]
[Option cameracenter {
This option is part of the low-level camera configuration
interface. See the "CAMERA POSITIONING" section below for
details.
}]
[Option cameraup {
This option is part of the low-level camera configuration
interface. See the "CAMERA POSITIONING" section below for
details.
}]
[Option 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.
}]
[Option 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.
}]
[Section 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:
[Bulletlist {
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.
[Section 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:
[Code 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.
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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:
[Code {
.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 [SQ .win coords P1] ;# A is now {{0 0 0} {1 1 1}}
set B [SQ .win coords P2] ;# B is now {{2 2 2}}
set C [SQ .win coords T] ;# C is now {100 100}
}]
If the [SQ 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
[SQ pathName create] command.
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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:
[Bulletlist {
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.
}]
}]
[Subcommand {
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:
[Code {
pathName itemcget search -tags
}]
}]
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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:
[Code {
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:
[Code {
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.
}]
[Subcommand {
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 [SQ array set] command for easy processing.
The following statistics are returned:
[Code {
Statistic Interpretation
--------------------------------------------------------
nVertex Total number of vertices (does not include
overlay or light items)
nFace Total number of polygon faces.
}]
}]
[Subcommand {
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).
}]
[Subcommand {
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.
}]
[Section Item Types]
All items accept the following options:
[Code {
-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:
[Bulletlist {
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 [SQ 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 [SQ 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:
[Code {
pathName create polygon \$coordsA \$coordsB \$coordsC
pathName create polygon [SQ list \$coordsA \$coordsB \$coordsC]
pathName create polygon [SQ list \$coordsA \$coordsB] \$coordsC
}]
[Subsection Polygon Items]
[Subcommand {
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 [SQ 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:
[Code {
-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
[SQ 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:
[Code {
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 [SQ 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):
[Code {
<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.
}]
[Subsection Line Items]
[Subcommand {
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.
}]
[Subsection Point Items]
[Subcommand {
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.
}]
[Subsection Light Items]
[Subcommand {
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:
[Code {
-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)
}]
}]
[Subsection 2dtext Items]
[Subcommand {
pathName create 2dtext 2dCoordList ?option value...?
[Code {
-color <color> (white)
-font <font> (Helvetica)
-text <string> ()
-anchor <anchorPos> (center)
}]
}]
[Subsection 2dline Items]
[Subcommand {
pathName create 2dline 2dCoordList ?2dCoordList...? ?option value...?
[Code {
-color <color> (white)
}]
}]
[Subsection 2dpolygon Items]
[Subcommand {
pathName create 2dpolygon 2dCoordList ?2dCoordList...? ?option value...?
[Code {
-color <color> (white)
}]
}]
[Section Colors and Lighting]
[Subsection 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:
[Bulletlist {
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:
[Code {
LightSalmon
#FFA07A
{1.0 0.627 0.478}
{1.0 0.627 0.478 1.0}
}]
[Subsection 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).
[Subsection 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.
[Code {
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:
[Code {
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
}]
[Section 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:
[Code 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".
[Subcommand {
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.
}]
[Subcommand {
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.
}]
[Subcommand {
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:
[Subcommand {
center
The current value of the -cameracenter option.
}] [Subcommand {
location
The current value of the -cameralocation option.
}] [Subcommand {
lineofsight
The vector between the vertex specified by the
-cameralocation and the -cameracenter vertex
(cameralocation - cameracenter). The vector is not
normalized.
}] [Subcommand {
up
A unit vector in the "up" direction, from the point of view
of the viewer.
}] [Subcommand {
down
A unit vector in the "down" direction, from the point of
view of the viewer.
}] [Subcommand {
left
A unit vector in the "left" direction, from the point of
view of the viewer.
}] [Subcommand {
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).
[Section 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:
[Bulletlist {
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.
[Subsection 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.
[Subsection 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
[SQ \$widget transform] command. Passing a value for the "search"
parameter of [SQ \$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:
[Code {
\$widget transform -camera lights||dashboard <transformation spec>
}]
(assuming dashboard elements are associated with the tag group
"dashboard").
[Subsection 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.
[Subcommand {
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
[SQ \$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.
}]
[Subcommand -4 {
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.
}]
[Subcommand -4 {
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.
}]
[Subcommand -2 {
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.
}]
[Subcommand {
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).
}]
[Section 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
[SQ \$widget create] command when an item is first created. They may
also be obtained via the [SQ \$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
[SQ \$widget addtag] and [SQ \$widget dtag] commands, or by setting the
-tags item option. The tags attached to an item may be queried
using [SQ \$widget gettags] or by querying the -tags item option.
[Section 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:
[Bulletlist {
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:
[Code {
<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.
[Subsection Examples]
[Subcommand {
{cubes}
All items associated with the tag "cubes".
}] [Subcommand {
{45 || cubes}
All items associated with the tag "cubes" or with unique
id "45".
}] [Subcommand {
{solid && cubes}
All items associated with both of the tags "cubes" and
"solid".
}] [Subcommand {
{viewport(45, 80) && !cubes}
All items not associated with the tag "cubes" for which
the projection includes the viewport pixel (45, 80).
}]
[Subsection 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:
[Code {
<tagname>
<tagname> && <search>
<id>
<id> && <search>
type(light)
type(light) && <search>
}]
[Section 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
[SQ pathName create polygon] command. For example, the
[SQ ::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:
[Code {
# Create a sphere.
.win create polygon [SQ ::canvas3d::sphere] -smooth true
}]
By default, [SQ ::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.
[Subcommand {
::canvas3d::sphere ?options?
This command returns a list of polygon faces that
approximate a sphere. The following options are available:
[Code {
-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.
}]
[Subcommand {
::canvas3d::cylinder ?options?
This command returns a list of polygon faces that
approximate the curved surface of a cylinder. The following
options are available:
[Code {
-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.
}]
[Subcommand {
::canvas3d::disc ?options?
This command returns vertices for a single polygon face
that approximates a flat disc. The following options are
available:
[Code {
-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.
[Section 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.
[Section Credits]
Some text in this manpage was copied directly from the Tk canvas
manpage.
[Section Keywords]
canvas3d, 3dcanvas, 3d-canvas, widget