
[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

