Language selection

Search

Patent 2483943 Summary

Third-party information liability

Some of the information on this Web page has been provided by external sources. The Government of Canada is not responsible for the accuracy, reliability or currency of the information supplied by external sources. Users wishing to rely upon this information should consult directly with the source of the information. Content provided by external sources is not subject to official languages, privacy and accessibility requirements.

Claims and Abstract availability

Any discrepancies in the text and image of the Claims and Abstract are due to differing posting times. Text of the Claims and Abstract are posted:

  • At the time the application is open to public inspection;
  • At the time of issue of the patent (grant).
(12) Patent: (11) CA 2483943
(54) English Title: COMPUTER-ASSISTED ANIMATION CONSTRUCTION SYSTEM AND METHOD AND USER INTERFACE
(54) French Title: SYSTEME DE REALISATION D'ANIMATION ASSISTEE PAR ORDINATEUR ET TECHNIQUE CORRESPONDANTE ET INTERFACE UTILISATEUR
Status: Expired and beyond the Period of Reversal
Bibliographic Data
(51) International Patent Classification (IPC):
  • G06T 13/00 (2011.01)
(72) Inventors :
  • KROITOR, ROMAN B. (Canada)
(73) Owners :
  • IMAX CORPORATION
(71) Applicants :
  • IMAX CORPORATION (Canada)
(74) Agent: SMART & BIGGAR LP
(74) Associate agent:
(45) Issued: 2008-02-19
(22) Filed Date: 1996-12-24
(41) Open to Public Inspection: 1997-07-10
Examination requested: 2004-11-16
Availability of licence: N/A
Dedicated to the Public: N/A
(25) Language of filing: English

Patent Cooperation Treaty (PCT): No

(30) Application Priority Data:
Application No. Country/Territory Date
08/578,293 (United States of America) 1995-12-26

Abstracts

English Abstract

A process for transforming line segments in animation drawings for use in an animation sequence. The process includes: (a) selecting, using a computer input device to control the movement of a cursor in a computer drawing space, a reference point having initial x, y, and z coordinates, and (b) traversing a motion path relative to the predetermined reference point using the input device. The motion path defines the displacement of the reference point from the initial coordinates for a plurality of animation drawings. In a first animation drawing, a line segment is selected for transformation, the line segment being comprised of a plurality of points with initial x, y, and z coordinates. For each point comprising the line segment, a displacement of the point from its initial coordinates is defined relative to the displacement of the reference point from the initial reference point coordinates for the plurality of animation drawings. For each point comprising the line segment, the relative displacement is added to the initial predetermined coordinates to determine new coordinates for the point in a second animation drawing.


French Abstract

La présente concerne une technique pour transformer des segments de ligne dans les dessins d'animation en vue de leur utilisation dans une séquence d'animation. La technique consiste à : (a) sélectionner, en utilisant un dispositif d'entrée d'ordinateur pour commander le déplacement d'un curseur dans un espace de dessin informatique, un point de référence ayant les coordonnées initiales x, y et z; et (b) parcourir une trajectoire de mouvement par rapport audit point de référence prédéterminé en utilisant le dispositif d'entrée. La trajectoire de mouvement définit le déplacement du point de référence par rapport aux coordonnées initiales pour un certain nombre de dessins d'animation. Dans un premier dessin animation, un segment de ligne est sélectionné pour être transformé, ledit segment de ligne étant constitué d'un certain nombre de points de coordonnées initiales x, y et z. Pour chaque point composant le segment de ligne, un déplacement du point par rapport à ses coordonnées initiales est défini par rapport au déplacement du point de référence par rapport aux coordonnées du point de référence initial pour les nombreux de dessins d'animation. Pour chaque point composant le segment de ligne, le déplacement relatif est ajouté aux coordonnées prédéterminées initiales afin de déterminer les nouvelles coordonnées des points dans un second dessin d'animation.

Claims

Note: Claims are shown in the official language in which they were submitted.


-175-
I CLAIM:
1. In a computer animation system, a process for transforming line
segments in animation drawings for use in an animation sequence, the
process comprising:
(a) selecting, using a computer input device to control the
movement of a cursor in a computer drawing space, a reference point having
initial x, y, and z coordinates,
(b) traversing a motion path relative to said predetermined
reference point using said input device, said motion path defining
displacement of said reference point from said initial coordinates for a
plurality of animation drawings,
(c) selecting, in a first animation drawing, a line segment for
transformation, said line segment comprised of a plurality of points with the
initial x, y, and z coordinates,
(d) defining, for each point comprising said line segment, a
displacement of said point from its initial coordinates relative to the
displacement of said reference point from said initial reference point
coordinates for said plurality of animation drawings,
(e) for each point comprising said line segment, adding said
relative displacement to said initial coordinates to determine new coordinates
for said point in a second animation drawing.
2. The process of claim 1 wherein said relative displacements are defined
by drawing, using said input device, a graph of relative displacement as a
function of position along said segment.
3. The process of claim 1 wherein said reference point lies on said line
segment.

-176-
4. The process of claim 1 as applied in computer system for constructing
two-dimensional animation.
5. The process of claim 1 as applied in a computer system for
constructing stereoscopic drawings for use in three-dimensional animation.
6. The process of claim 1 further comprising repeating step (e) for said
plurality of animation drawings,
determining, based on said new coordinates for said points
comprising said line segment in each of said plurality of drawings, minimum
and maximum relative displacements for each of said points comprising said
line segment,
modulating said minimum and maximum relative
displacements for said points on said line segments in each of said plurality
of
animation drawings by interpolating between said minimum and maximum
displacements according to a specification of the displacement of said line
segment in each of said plurality of drawings relative to said minimum and
maximum displacements, and
using said modulated displacements to generate a new line
segment in each of said plurality of animation drawings.
7. A computer animation system for transforming line segments in
animation drawings for use in an animation sequence, the system comprising:
means for selecting, using a computer input device to control
the movement of a cursor in a computer drawing space, a reference point
having initial x, y, and z coordinates,
means for traversing a motion path relative to said
predetermined reference point using said input device, said motion path
defining displacement of said reference point from said initial coordinates
for
a plurality of animation drawings,

-177-
means for selecting, in a first animation drawing, a line segment
for transformation, said line segment comprised of a plurality of points with
initial x, y, and z coordinates,
means for defining, for each point comprising said line segment,
a displacement of said point from its initial coordinates relative to the
displacement of said reference point from said initial reference point
coordinates for said plurality of animation drawings,
for each point comprising said line segment, adding said
relative displacement for a second animation drawing to said initial
predetermined coordinates to determine new coordinates for said point in
said second animation drawing,
storing said new coordinates for each of said points comprising
said line segments,
and using said stored coordinates to generate a new line
segment in said second animation drawing, said new line segment replacing
said line segment in said first animation drawing.
8. The system of claim 7 wherein said relative displacements are defined
by drawing, using said input device, a graph of relative displacement as a
function of position along said segment.

Description

Note: Descriptions are shown in the official language in which they were submitted.


CA 02483943 2004-11-16
-1-
i e: Computer-Assisted Animation Construction System
and Method and User Interface
Field of the Invention
This invention relates to a system and method for creating
two and three-dimensional computer-assisted animation, and a simple
and intuitive user interface for generating a series of animation images
from a relatively few source drawings.
Background of the Invention
The field of animation concerns the creation of the illusion of
motion by rapidly displaying a sequence of still images, with each image
slightly changed from the previous image. In the early years of animation,
the drawings were strictly made by hand, which is a tedious and time-
consuming process given the large number of drawings required for even
a short. animation segment. More recently, with the advent of computer
graphics technology, computers have been used in the animation process.
Animators are often reluctant, however, to depend too heavily on
computers for, generating drawings because of the noticeable difference
between hand drawn figures and objects and computer-generated figures
and objects, which appear robotic rather than life-like.
More accepted in the animation field are computer systems
permitting animators to create drawings on computer display devices
using a mouse, drawing tablet or other input device rather than pen and .
paper. In these systems, computers are often used to assist an animator in
creating an animation sequence by generating intermediate animation
frames which are placed in between frames drawn by the animator. The
frames drawn by the animator are referred to as key frames or poses. The
computer generated intermediate frames are referred to as "in-between"
frames and are used to transform an image from one key pose to another.
The process of generating these in-between poses is often referred to as
"tweening" or "in-betweening." Generation of the in-between poses is
based on computer interpolation between the animator's key frames. The

CA 02483943 2004-11-16
-2-
animator specifies the number of in-between frames based on 'the
complexity of the motion, and the computer generates the in-between
frames to create a smooth transformation in the resulting animation
sequence. The advantage of this technique is' that it eliminates the
laborious task of manually generating the individual in-between fraines.
Computer in-betweening for three-dimensional animation is discussed ir1
U.S. Patent No. 4,600,919 to Stern.
Prior art computer tweening methods are lacking 'in several
respects.. First, some prior art tweening systems use simple linear
interpolation to generate intermediate poses between key frames. One
problem with this approach is that it results in actions in objects that
. appear "robotic." The problem can be minimized by increasing the
number of key poses, but this requires more manually generated drawings
and defeats the purpose of computer-assisted tweening. Another problem.
is that linear interpolation can cause distortion of objects experiencing
'rotational motion by shortening segments of the objects at certain angles of
rotation. A third problem is that discontinuifies in the speed of motion
often result if i) the number of in-betweens in adjacent intervals is
constant, but the distance between key poses is not, or ii) the distance
between adjacent key positions is equal but the number of in-between
poses in the interval are not. These problems are discussed more fully in.
D.H.U. Kochanek, R. Bartels, and K.S. Booth, "A Computer System for
Smooth Keyframe Animation," Rep. No. CS-82-42, University of Waterloo
Computer Science Dept., 1982.
Several researchers have developed improvements to the
simple linear interpolation technique as discussed in Kochanek et al. One
such technique is referred to as the "P-curve." In this process, the
animator traces out a motion path along which an object is to move. In
addition, to account for transformations in the object as it moves, the
animator can specify a selection function to designate which picture of an
object is used for any given frame along the P-curve. For example, the
object can be a bouncing ball and the animator can specify that as the ball

CA 02483943 2004-11-16
-3-
bounces, a drawing showing a compressed ball can be used.
These prior art techniques are cumbersome for animators to use,
however, because they are complicated and do not provide a simple, easy-to-
use user interface. There is thus a need for a computer-assisted animation
construction system and method that permits an animator to create high
quality animation simply and intuitively.
Summary of the Invention
It is an object of the present invention to provide an improved
system and method for computer-assisted generation of animation.
In one aspect, the invention provides, in a computer animation
system, a process for transforming line segments in animation drawings for
use in an animation sequence, the process comprising:
(a) selecting, using a computer input device to control the
movement of a cursor in a computer drawing space, a reference point having
initial x, y, and z coordinates,
(b) traversing a motion path relative to said predetermined
reference point using said input device, said motion path defining the
displacement of said reference point from said initial coordinates for a
plurality of animation drawings,
(c) selecting, in a first animation drawing, a line segment for
transformation, said line segment comprised of a plurality of points with
initial x, y, and z coordinates,
(d) defining, for each point comprising said line segment, a
displacement of said point from its initial coordinates relative to the
displacement of said reference point from said initial reference point
coordinates for said plurality of animation drawings,
(e) for each point comprising said line segment, adding said
relative displacement to said initial predetermined coordinates to determine
new coordinates for said point in a second animation drawing.
Another aspect of the invention provides a computer animation
system for transforming line segments in animation drawings for use in an
animation sequence, the system comprising:

CA 02483943 2004-11-16
-3a-
means for selecting, using a computer input device to control
the movement of a cursor in a computer drawing space, a reference point
having initial x, y, and z coordinates,
means for traversing a motion. path relative to said
predetermined reference point using said input device, said motion path
defining the displacement of said reference point from said initial
coordinates
for a plurality of animation drawings,
means for selecting, in a first animation drawing, a line segment
for transformation, said line segment comprised of a plurality of points with
initial predetermined x, y, and z coordinates,
means for defining, for each point comprising said line segment,
a displacement of said point from its initial coordinates relative to the
displacement of said reference point from said initial reference point
coordinates for said plurality of animation drawings,
for each point comprising said line segment, adding said
relative displacement for a second animation drawing to said initial
predetermined coordinates to determine new coordinates for said point in
said second animation drawing,
storing said new coordinates for each of said points comprising
said line segments,
and using said stored coordinates to generate a new line
segment in said second animation drawing, said new line segment replacing
said line segment in said first animation drawing.
Also disclosed herein is an improvement on the known concept
of using a computer to interpolate between sequential key poses of an
animation sequence through the use of what are referred to herein as "source
poses." A source pose is an animator-created drawing of an object used iri the
present invention to create computer-generated poses of the object for
animation. Unlike the prior art concept of key poses, a source pose may, but
is not required to be, part of the animation.
The invention has application to both two and three-
dimensional computer animation.

CA 02483943 2004-11-16
-4-
Any number of source poses can in theory be specified by the
animator, but practically 1-7 source poses would be used. These source poses
do not necessarily correspond identically to the appearance of the animated
object in any of the resulting animated poses. The source poses are used to
construct composite poses used.in animation sequences, referred to herein as
"constructed poses". In each constructed pose, the object's appearance is
constructed from a weighted average of the source poses. A three
dimensional drawing space is provided using a computer-driven stereoscopic
viewing system incorporating a computer input device such as a three-axis (6
degree of freedom) position sensor or drawing "wand" which utilizes sensors
to track the movement and orientation of the wand in three-dimensional
space. The position of the wand is represented by a cursor which is displayed
within the three-dimensional drawing space.
A predetermined portion of the three-dimensional drawing
space, referred to herein as the "pose transformation .space", is displayed in
the viewing system. In one embodiment, the pose transformation space is a
tetrahedron. In this case, four source poses are represented by the
tetrahedron, one at each vertex. Each point within the tetrahedron represents
a constructed pose defined by a unique combination of the four source poses.
The drawing wand is moved to control the movement of the wand cursor
within the tetrahedron in order to define the transformation of the animated
object. The position of the wand cursor relative to each vertex of the
tetrahedron controls the constructed pose at that point in time. The
constructed poses are composed of weighted averages of the source poses.
The constructed poses are viewed in real-time as the wand cursor moves
within the pose transformation space enclosed by the tetrahedron, thus
providing instantaneous feedback to the animator of the action being created
or "scripted".
In this manner, an animated object can be made to perform
any action which, given the nature of the four source poses, can be
specified by a progression of three-dimensional graph points determined

CA 02483943 2004-11-16
-5-
by the path of the wand in the pose transformation space, referred to herein
as a "transformation graph". In addition, the velocity of the pose
transformation may be controlled by the rate of motion of the wand cursor in
the pose transformation space. Alternatively, the velocity may be
independently controlled by displaying a graphical representation of the
relative rate of transformation as a function of position along the
transformation graph -- referred to herein as a "velocity profile graph" or
velocity profile for the transformation - to specify the instantaneous rate of
transformation. This velocity profile permits an animator to modify the rate
of transformation along the transformation graph using the input device.
The actions of different characters and objects and parts thereof
may be defined using different transformation graphs, thus providing
independent control over the action of the characters in a resulting animation
sequence. If less than four source poses are to be used by the animator, a two-
dimensional transformation space may be used (e.g. a triangle for three
source poses).
The present invention may be directed to further modifying
constructed poses to provide for greater control over the form and action of
computer-generated animated images undergoing some form of motion or
transformation, which may be specified as a distortion or "warp" of one or
more line segments of a drawing. A point within the drawing is chosen as a
reference point, referred to herein as a "warp handle", which will typically
be
on a line segment of a source pose, but need not be so located. A motion path
relative to this reference point - referred to herein as a "warp path" -- is
then
drawn in the drawing space. The warp path defines a motion path in time
relative to the reference warp handle, thus generating a set of relative X. y,
and z displacements as a function of time. The line segment or segments to be
modified by the warp path are then specified by any one of a number of
methods, such as pointing and clicking with the drawing wand. In addition,
a graph is drawn which defines the degree to which the successive points on

CA 02483943 2004-11-16
-6-
the line segment or segments are displaced by the warp path. This graph is
referred to herein as a "warp profile graph". The set of relative
displacements
is then applied to the designated segments, as modulated by the warp profile
graph. This general technique, referred to herein as "segment warping", may
be modified to create various effects, such as the effect on an object of
wind, of
inertia, and to create the movement of a wave along the specified segments:
Also disclosed herein is "spine warping", in which a number of
related segment warps are created simultaneously. This is accomplished by
defining, on each source pose, a single, straight line "spine" extending
approximately through the centerline of a group of line segments to be
warped. Any of the above-described warps may be applied to the spine and
the resulting warp of the spine is appropriately transferred to each point on
each of the affected line segments in the group. This provides the animator
with a tool for very simply specifying complicated transformations to groups
of line segments simultaneously.
Automatic painting of closed loops (which may represent a
surface of an object in a stereoscopic viewing system) drawn in two or three-
dimensional space is possible by "flood-filling" the loop (each of the two-
dimensional left and right eye projections of the loop in a stereoscopic
system). Flood-filling is a technique known in the art of computer graphics.
The system and method of the present invention uses a different technique for
painting closed loops, referred to herein as "fill masking". In accordance
with
the present invention, the animator need only define the color with which the
loop is to be filled in a single source pose and the color is maintained in
each
constructed pose regardless of the distortions the loop undergoes during
motion. For each such constructed loop, a two-dimensional geometric shape,
which is typically a rectangle, is generated automatically to encompass the
loop by making it slightly larger than the loop based on the minimum and
maximum x and y coordinates of the

CA 02483943 2004-11-16
-7-
loop. The entire rectangle is generated in the fill color of the loop chosen
by the anirnator. Next, the loop outline is transferred to the rectangle in
its
chosen line color or colors. A "fill" of the area bounded by the rectangle
and the line forming the exterior of the loop is then performed, using the
traditional flood-fill technique. This filled area is defined to be-
transparent
so that when the resulting rectangle is displayed, the viewable image
consists only of the loop in the appropriate filled color. This process is
automatically repeated for each of the filled loops which comprise the
complete character or object animation.
Brief Description of theprawiM
Figs. 1(a)-(d) illustrate four source poses of a fish for use in an
animation sequence.
Figs. 2(a)-(d) illustrate the four source poses of the fish's
mouth of Fig. 1.
Fig. 3 is a three-dimensional tetrahedral pose transformation
space used to generate the transformation graphs of the present invention.
Fig. 4 is a transformation graph of the present invention for
the mouth of a fish drawn in the pose transformation space of Fig. 3.
Fig. 5 is a transformation graph of the present invention for
the eye brows of a fish drawn in a three-dimensional tetrahedral pose.
transformation space.
Fig. 6 is a transformation graph of the present invention for
the body and fins of an animated fish, using only two vertices for a three-
dimensional tetrahedral pose transformation space.
Fig. 7 is a transformation graph of the present invention for
the eyes of an animated fish, using only two vertices for a three-
dimensional tetrahedral pose transformation space.
Figs. 8(a)-(f) illustrates the animation frames resulting from
the combination of the transformation graphs of Figs. 4, 5, 6 and 7.
Figs. 9(a)-(d) illustrate the velocity profiles for the
transformation graphs of Figs. 4, 5, 6, and 7.
Figs. 10(a)-(d) illustrate the velocity profiles for the

CA 02483943 2004-11-16
-8-
transformation graphs of Figs. 4, 5, 6, and 7 adjusted by the use of sync
points.
Figs. 11(a)-(f) illustrate the advantage of using match points in
constructed poses.
Figs. 12(a)-(b) illustrate the segment warp technique of the
present invention.
Figs. 13 illustrates a warp profile graph used for the segment
warps shown in Fig. 12(a).
Fig. 14 illustrates the resulting motion created by the segment
warp defined by Figs.12-13.
Fig. 15 illustrates an angel wing as an example of the
problems with prior art in-betweening systems.
Figs. 16(a)-(c) illustrate how the problem of Fig. 15 is corrected
using the segment warp technique of the present invention.
Fig. 17(a)-(f) illustrate the wind effect that can be achieved
using a variation of the segment warp of the present invention.
Figs. 18(a)-(e) illustrate the wave effect that can be achieved
using a further variation of the segment warp of the present invention.
Figs. 19(a)-(b) illustrate the spine warp of the present
invention.
Figs. 20(a)-(c) illustrate the problems with prior art seed point
and flood-fill techniques for filling loops with color.
Figs. 21(a)-(c) illustrate the fill masking technique of the
present invention for overcoming the drawbacks of prior art seed point
and flood-fill techniques.
Detailed Description of the Invention
The invention utilizes computer systems for drawing and
viewing stereoscopic (three-dimensional) images and applies such systems
to the field of computer-assisted animation. Systems for drawing in three-
dimensional space are known in the art of computer graphics. One
example of such a system is described in Schmandt, C., "Interactive Three-
dimensional Computer Space," SPIE Vol. 367, pp. 155-59 (1982). The

CA 02483943 2004-11-16
-9-
system described therein utilizes an ordinary CRT display monitor which
is viewed by the user through a half-silvered mirror placed at a 45' angle
with the monitor. The user is provided with a three-dimensional drawing
space beneath the mirror and a "wand" for drawing in the three
dimensional space. The wand used in the described system utilizes
magnetic position sensing technology to provide its x, y, and z position as
well as its.attitude. The three dimensional (stereoscopic) effect is achieved
by the user viewing the CRT through special glasses utilizing lead
lanthanum zirconate titanate (PLZT) ceramic wafers which function as
electrically operated shutters. The left and right eye views are effectively
time-multiplexed by displaying them on alternate raster scans. The
operation of the glasses is synchronized with the video signal to allow one
eye at a time to view the proper image on the CRT providing the three-
dimensional effect. This technique is sometimes referred to as field
sequential three-dimensional imaging.
An alternate means for providing a three-dimensional view
is through the use of anaglyph (two color) left and right eye image
separation. A limitation of this implementation is that the drawn images
are monochrome, whereas the field sequential technique allows for color
images. A third means for providing left and right eye image separation is
through the use of polarizing filters where the left eye image is polarized
one way and the right eye image polarized another. The polarized images
are normally viewed by projecting them onto a screen and viewing them
through appropriately polarized glasses. Although the invention has
application to both two and three-dimensional computer-assisted
animation systems, the invention will be described herein with regard to
three-dimensional animation. It will be readily apparent to those of
ordinary skill in the art that the same concepts may be applied to standard
two-dimensional animation.
The present invention requires a three-dimensional
stereoscopic viewing system using one of the above techniques to permit
the animator to draw directly in three-dimensional space. In a preferred

CA 02483943 2004-11-16
10-
embodiment, the three-dimensional drawing and viewing systemutilizes
a computer workstation monitor and field sequential left and right image
separation using synchronized liquid crystal shutter glasses.
The animator uses an electro-mechanical device referred to as..
a drawing "wand" to draw the three-dimensional drawings. The wand is -.
actually a three-dimensional location tracker, which is available from
several suppliers, including Ascension Technologies, Inc. In one
embodiment of the present invention, a drawing wand referred to as the
"Flock of BirdsTM" by Ascension is used. The device uses electromagnetic
waves to provide its position and orientation in three-dimensional space.
Liquid crystal shutter glasses are available from, among others,
Stereographics Corp. A high resolution 17-inch monitor by Nanao has
been found to the best from the standpoint of image resolution and
stability as well as ease of use. When the user moves the wand in space a
cursor moves within the drawing space under control of the wand and
when a button on the wand is pushed, a continuous line in three-
dimensional space following the path of the cursor is drawn. The line is
composed of a series of closely-spaced points joined by very short line
vectors to form what appears to be a single, continuous smooth line. It is
important that the system provide for vector-based as opposed to bit-
mapped drawings, so that the line segments drawn by the anirnator may be
mathematically defined and processed by the computer.
The present invention relates more specifically to several
novel ways for transforming 'only a few drawings to create animation
sequences. The invention incorporates several techniques for creating
computer-assisted animation that are simple for an animator to use and
provide the animator with control over the form and motion of animated
objects that is lacking in existing computer animation systems.
In general, animation consists of the transformation of
images in time to create the appearance of motion. The invention
discloses several techniques for generating transformations in a manner
that is simple and intuitive to use for an animator, and which also

CA 02483943 2004-11-16
-11-
provides the -animator with a great degree of control over the way in
which images are transformed in order to provide realistic, life-like
motion.'
The first aspect of the invention relates to a concept referred
to as transformation graphs which permit the animator to simply and
intuitively generate different, computer-constructed poses of animated
objects based on source poses drawn by the animator. A three-"
dimensional transformation graph may be iniplemented as follows
(although two-dimensional graphs may also be used). The animator is
provided with an image through the three-dimensional viewing system of
a polvhedron, such as a tetrahedron. The tetrahedron is shown in the
three-dirnensional drawing space using well-known techniques for
generating and displaying left and right eye two-dimensional images to
create a three-dimensional effect. The tetrahedron displayed is only a
guide for the animator and does not become part of the drawings used in
the animation. Each of the four vertices of the tetrahedron is defined to
represent a source pose hand-drawn by *the animator. Each source pose
consists of a vector-drawn representation of an animated object or portion
of an object. AIternatively, source poses may be generated by prior-art
computer animation systems and utilized in the present invention.
For example, four poses of a figure can be drawn, each with
different positions of the legs. The four poses may then be represented at
each of the four vertices of the tetrahedron. These four poses themselves
are not sufficient to realistically represent motion. A sufficient number of
poses to create realistic motion are constructed from these four poses.
These constructed poses are based on composites of the four source poses.
The constructed poses are defined by the animator by moving the wand in
the three-dimensional space within the tetrahedron, referred to as the pose
transformation space. The motion of the wand is tracked in time as it is
moved within the tetrahedron and a three-dimensional graph of the
wand's position traced out within the pose transformation space is
generated. Each point on the graph represents a pose constructed from the

CA 02483943 2004-11-16
-12-
four source poses. The number of points depends on the sampling rate of
the drawing wand. The generation of constructed poses in this manner
provides for continuous transformations of images in a manner simple
for the animator to use. The animator "scripts" the action of a character or
object simply by moving the wand cursor within the transformation space.
The graphs so created are referred to as transformation graphs
because they define a continuously transforming series of poses
constructed from the source poses. Different actions of the figure can be
generated by different paths of the wand cursor in the transformation
space. For example, with one set of four source poses with different
positions of the legs, the figure referred to above can -be made to "mark
time," walk forward, walk backward, walk with big steps, little steps, etc.,
and these actions can be continuously created in. any sequence simply by
manipulating the wand. The transformation graphs are, generated as
follows. Using the example of a tetrahedral drawing space, at each point
along the transformation graph, the constructed pose associated with the
point is defined by the location of the point in space relative to the four
vertices of the tetrahedron. The closer the point is to a vertex, the more
the source pose assigned to the vertex will affect the appearance of the
constructed form. In one embodiment, a simple linear weighting scheme
is used so that the weight of each vertex or source pose is inversely
proportional to the distance from the graph point to the vertex. For
example, if a graph point is, in three-dimensional.space, a distance x away
from the first vertex (v1), 2x from the second (v2), 3x from the third (v3),
and 4x from the fourth (v4), each of the four source poses associated with
the four vertices will be weighted accordingly. In other words, the points
defining the line segments of the constructed pose will be placed in
accordance with a weighted average of the positions of the points in each
of the four source poses. It should be . noted that, utilizing the
transformation graphs of the present invention, the source poses need not
actually be part of the resulting motion sequence, which may utilize only
composites of the source poses. In other words, the transformation graph

CA 02483943 2004-11-16
-13-
need not anywhere touch a vertex. It should also be noted that, unlike the
key poses of prior transformation techniques, there is no predefined time
sequence for the poses. The transformation graph can move through any
path in the pose transformation space in any sequence desired by the
animator.
In a preferred embodiment, the tetrahedron is modified so
that each edge is not a straight line but the arc of a circle centered at an
opposite vertex and with a radius equal to the length of one side of the
tetrahedron. The reason for this is as follows. Each vertex represents, by
definition, a source pose, so that the weight of any of the other three
vertices is defined to be zero at that vertex. In other words, the
contribution of a source pose goes to zero when the distance of the vertex
to which that pose is assigned to the point on the transformation graph, is
equal to the length of an edge of the tetrahedron. If an edge of the'
tetrahedron is traversed, the resulting constructed pose will be composed
primarily from the two vertices at each end of the edge. However, the
remaining two vertices will have non-zero effects because the distance to
these vertices will diminish as the edge is traversed. Thus, it would not be
possible to script a motion sequence constructed from only the two source
poses represented by the two vertices at each end of the edge. Although in
most cases the contributions of the other two vertices might not be
noticeable in the resulting animation, any such potential problem is
solved by utilizing the circular arcs in order to maintain a constant
distance from each of the two non-contributing vertices as a path between
the two vertices at the ends of the arc is traversed. It will be apparent to
those of ordinary skill in the art that the shape of the transformation space
need not be exact as it is only intended to be a guide for the animator in
scripting action sequences. The system may readily be programmed so that
if, for example, the animator moves the wand slightly inside or outside
the tetrahedron as opposed to following precisely along the edge, it will be
recognized as motion that is comprised only of the two source poses at the
vertices.

CA 02483943 2004-11-16
-14-
The transformation graph aspect -of the invention may be
further described with reference to the figures. Figs. 1(a)=(d) illustrate
four
possible configurations for the facial expressions of an animated fish. For
clarity, the fish is drawn without illustrating the z-component and
therefore appears two-dimensional, but is meant to depict a fish in a three-
dimensional stereoscopic drawing. As can be seen in Fig. 1, there are four
different source poses for the fish's mouth as shown in Fig. 2 -- frown (Fig.
2(a)), -smile (Fig. 2(b)), small mouth (Fig. 2(c)), and big mouth (Fig. 2(d)).
In
each of Figs. 2(a)-2(d), four points, A-D are shown. Each of the four source
poses of the mouth may be assigned to one of the vertices (labelled a, b, c,
and d) of a tetrahedron shown in Fig. 3 consisting of four planes: abc, bcd,
acd, and abd. For example, at a point m midway along the line cd, the
constructed pose defined by this point (a medium-sized mouth) will be
formed primarily from the source poses at vertices c (small mouth) and d
(large mouth). Each of the points A,B,C, and D in Figs. 2(c) and 2(d) (as
well as all the points along the line segment) will be mapped to a location
(x,y coordinate) approximately midway between their locations at the
vertices c and d.
Fig. 4 illustrates a transformation graph drawn by the
animator (using the wand) which controls the transformation of the shape
of the mouth. Starting at point S (which is essentially a frown) lying
approximately in the plane defined by vertices abc, the transformation
graph progresses toward vertex c to point 1, then toward vertex b to point
2, then upward along the line bd to point 3, then downward on the plane
abd to point 4, then along the line ab to the end point E. Although the
transformation graph is shown essentially along the surfaces of the
tetrahedron for purposes of illustrating it in a two-dimensional drawing,
the graph mav be drawn through any part of the volume enclosed by the
tetrahedron. As the animator draws the path, the computer calculates,
based on the sampled position of the wand in space, the location of the
cursor from each vertex and then draws the resulting constructed pose. A
subset of the points (every nth point) making up the constructed pose is

CA 02483943 2004-11-16
-15-
selected for display so that the series of constructed poses can be seen in '
real time and the animator can view the motion he is scripting. This is
done essentially in real time so that the animator can view the motion he
is scripting as he moves the wand to control the cursor movement. Fig. 5
illustrates a three-dimensional transformation graph for another element
of the fish drawing, the eye brows, Fig. 6 for the fish's body and fins taken
together, and Fig. 7 for the eyes. In Fig. 6, there are only two source poses
used at i and j. The other two vertices, k and 1, are also assigned the pose
assigned to vertex i as a programmirig convenience. The transformation.
graph could actually be scripted along a one-dimensional line as only two
source poses are used. The same is true for Fig. 7, which illustrates the
transformation graph for the eyes along the line m-n, although
tetrahedron mnop is shown.
If a sequence using only three source poses is to be generated,
a triangle on a plane may be used as the pose transformation space.
Similarly, a sequence using only two poses can. be scripted on a pose
transformation space consisting simply of a line with one pose assigned to
each end of the line. On the other hand, if more complicated motions are
to be scripted using. a greater number of source poses, the pose
transformation space may be readily extended by utilizing the existing
capability of the drawing wand to sense orientation. Each of the three
components -- pitch, roll, and yaw -- may represent an additional source
pose thus providing three additional source poses. This allows for a six
dimensional pose transformation space in which any possible
combination of seven source poses can be defined. Other inputs, 'such as
foot-pedals, could provide for additional source poses. In such a case, the
cursor in the pose transformation space would only reflect four poses; the
degree of effect of the other inputs could only be seen in the resulting
constructed pose.
In addition to controlling how the poses of animated objects
change, the transformation graphs are also used to control the rate of
transformation, which correlates to the apparent speed of the action

CA 02483943 2004-11-16
-16-
produced in the animated object in the resulting animation. sequence.
Because the drawing system is sampling the position of the wand at a fixed
rate, the position of the wand as a function of time is known. Therefore,
the rate of movement of the wand is known and may be used to control
the rate or speed of the scripted transformation.
When a transformation graph is drawn, the points of the
graph are stored. These graph points are equally spaced in time.
Therefore, the spacing of graph points in the pose transformation space
depends on the speed with which the animator moves the drawing wand
and their spacing controls the rate of change of the animated action. If the
animator draws the graph in real time, each point may correspond to a
frame of animation. Alternatively, the animator may first define the
number of frames desired for the sequence and then draw the graph in
"slow motion." In this case, the number of frames in the animation
sequence will be less than the number of graph points generated.
Similarly, the transformation graph may be drawn faster than real time so
that the number of frames will be greater than the number of graph points.
In these latter two cases, the transformation graphs are interpolated
accordingly, to create the number of frames selected by the animator. The
stored frames may then be played back at the rate at which they will be
seen by the viewer (which is typically 24 or 30 frames per second) so that
the animator can determine if the speed of the motion is appropriate.
They can also be played back at faster and slower frame rates for analysis.
To facilitate adjustxnents to the speed of the action, the
animator is provided with a graphical representation of the rate of
transformation of the poses throughout the sequence of poses, referred to
herein as a"velocity profile" for the transformation graph. The velocity
profile shows the relative rate of change of the poses along the
transformation graph. Without changing the sequence, the animator can
adjust the velocities along the transformation graph using, e.g., a point,
click, and drag action known in the art to modify the velocity profile, or by
redrawing the velocity profile entirely. When the velocity profile is so

CA 02483943 2004-11-16
-17-
changed, the spacing of the transformation points along the
transformation graph is adjusted by interpolation in such a manner that ,..
the animation sequence still occurs over the correct numbeber of frames..
For example, if the relative speed of the action is increased in a portion of
the transformation graph, it will be appropriately decreased in the
remaining portion of the transformation graph.
Figs. 8(a)-(f) illustrate the frames of animation resulting from
the combined transformation graphs in Figs. 4, 5, 6 and 7. In Fig. 8(a)
(point S on the transformation graphs), the fish is approaching a piece of
food which he notices in Fig. 8(b) (point 1). The sequence then continues
until the fish swallows the food. Figs. 8(c) through 8(f) correspond to
points 2, 3, 4, and E in Figs. 4, 5, 6 and 7. The points relate to different
frames of animation, i.e., different points in time during a transfor;nation
sequence. For example, as shown in Figs. 8(a)-(f), times 0, 1, 2, 3, 4, and E
may correspond to frames 1, 40, 90, 150, 180 and 240, respectively.
Fig. 9(a)-(d) show the velocity profiles of the transformation
graphs for the mouth, eyebrows, body, and eyes, respectively, which are
illustrated in Figs. 4-7, as they might be after recording the respective
transformation graphs. The x-axis indicates time or number of frames and
the v-axis the instantaneous rate of transformation of the constructed
,
poses. A zero rate of transformation means that the image is static; a flat,
non-zero rate that the image is transforming at a-constant rate, a positive
slope means that the rate is increasing and a negative slope that the rate is
decreasing. For each velocity profile in Figs. 9(a)-(d), six points are shown,
i-vi, each corresponding to a frame in an anirnation sequence. For each of
these points, the legend adjacent to each of the graphs indicates the pose
associated with the frame. The velocity profiles of Figs. 9(a)-(d) may be
displayed after an animator has generated the respective transformation
graphs to indicate the rate of transformation as drawn by the animator.
Note that as shown, the points i-vi do not correspond to the same frame in
each of the four velocity profiles. The aniinator may manually modify the
profile by "nudging" (using the wand cursor to push parts of the graph

CA 02483943 2004-11-16
-18-
into a different shape) a portion of the graph or by redrawing the entire
graph to adjust the transformation rate as desired.
If all the transformations in a drawing are controlled by the
same transformation graph, the effect may be mechanical and not life-like.
By dividing a drawing into groups and drawing a separate unique
transformation graph for each, a complex life-like action can be created.
However, when a composite drawing is generated from different groups of
elements controlled with different transformation graphs, there may be a
need to coordinate the action of the different groups before they are
compiled into frames of animation. For example, as originally drawn, the
velocity profiles for the mouth, eyebrow, body, and eye transformations
are as shown in Figs. 9(a)-(d). It may be seen in Figs. 9(a)-(d) that these
velocity profiles produce constructed poses of the mouth, eyebrows, body,
and eyes that are not synchronized in time compared to the desired
relationships of the different body parts as shown in Figs. 8(a)-(d). The
differences are exaggerated for clarity. For example, at the point where the
mouth of the fish is large, the eyes and eye brows must be portrayed as
squashed toward the top of the head of the fish. As originally produced (as
shown in the unmodified velocity profiles of the transformation graphs),
the mouth is large at point iv in Fig. 9(a), approximately frame $0, while
the eyes and eyebrows are squashed at frames 60 and 140, respectively. The
present invention facilitates the synchronization of the actions of different
groups of elements as follows. While drawing the transformation graph
for, e.g., the eyes, the animator may simultaneously view the played-back
action of the mouth, which was scripted using a transformation graph and
stored. In this manner, the animator may manually synchronize the
actions of the elements. Repeated "takes" may be used until the animator
is satisfied with the synchronization. The playback may be in real time or,
if desired, in slow motion to facilitate synchronization.
Alternatively, this may be done using the concept of
synchronization points or "sync" points. Sync points are used to specify.
that at a particular point in time during a sequence (i.e., a particular frame

CA 02483943 2004-11-16
-15-
of animation within a sequence of frames), a group of elements will hav.e
a selected form, such as the open mouth of the fish. In a preferred
embodiment, a frame identifier is first assigned to the designated frame
(point in time) where the sync point will occur. Next, the constructed pose
to be assigned to the selected frame is chosen by using a pointing device
(such as the drawing wand) to scroll along a linear scroll bar representative
of the entirety of the transformation graph. As the. animator moves the
cursor along the scroll bar, the constructed pose corresponding to that
point on the transformation graph is displayed. In addition, the position
of the cursor on the actual transformation path is displayed as well. When
the desired constructed pose is displayed, a wand button is clicked to
indicate that that pose is to be synchronized with the selected frame.
In a second group of elements to be coordinated with the first
group, the corresponding constructed pose (i.e., squashed eyes) is chosen by
the animator in the same manner. This pose is assigned the same frame
identifier as the frame in the transformation graph for the mouth so that it
too is synchronized with the selected frame. In this manner, the selected
mouth pose and the corresponding eye pose will occur in the same frame
and therefore the same point in time. The sequence of poses along the
transformation path is not affected. However, in order to force a selected
pose to occur at a particular time, the velocity of the transformation must
be adjusted. This is done by reducing or expanding the number of frames
between each sync point, as required. This is done by interpolation, so that
in so far as possible the original velocity profile is maintained. However,
depending on the velocity profiles, it may be difficult to maintain the
shape of the velocity profile in the vicinity of one or more sync points
without creating a discontinuity in the motion. In this case, the resulting
animation sequence may be plaved back to determine if there is a
discontinuity noticeable to a viewer. In general, sudden changes in the
velocity of a transformation are not detectable bv the viewer. However, if
it is, the shape of the velocity profile may be adjusted or re-drawn by the
animator to eliminate the discontinuity. It is likely that there will be

CA 02483943 2004-11-16
-20-
multiple sync points used along a transformation graph. The same
procedure is followed for each such point.
Figs. 10(a)-(d) illustrate the sync point concept. The sync
points are labelled SP1-SP4. These might, for example, correspond to
frames 40, 90, 150, and 180 as shown in Figs. 8(a)-(f). Fig..10(a) is the
velocity profile for the transformation graph for the mouth of the fish and
Figs. 10(b)-(d) the eyebrows, body, and eyes, respectively. As in Figs. 9(a)-
(d), the velocity profiles in Figs. 10(a)-(d) correspond to the transformation
graphs of Figs. 4-7, respectively, but in this case have been re-generated
using sync points. In the animation sequence, the large (wide open)
mouth must occur when the eyes of the fish are squashed towards the top
of its head and the small mouth when the eyes are wide open. Therefore,
point SP1 along the transformation graph is assigned to the point in time
when the mouth is small and point SP3 when the mouth. is large. The
velocities along the transformation graph are then adjusted (by
interpolation) so that point ii in Fig. 9(a) (small mouth) has been shifted
later by 20 frames, and point iv (large mouth) has been shifted later by 70
frames, to occur at frames 40 and 150, respectively. Similarly, point SP2
(frame 90), is assigned to the point in time when the first smile occurs and
SP4 (frame 180) when the second smile occurs (points iii and v in Fig. 9(a),
respectively). All the other elements are similarly adjusted, so that proper
sy,nchronization occurs, as shown in Figs. 10(a)-(d), and the desired
relationships of the different features as shown in Figs 8(a)-(f) are
obtained.
Sync points may also be used to properly synchronize the action within a
constructed pose transformation sequence to a sound track.
Segments of the source poses may be mapped onto one
another using match points to avoid undesirable constructed poses. The
use of match points is known to those of ordinary skill in the art and is
briefly described as illustrated in Fig. 11. Match points break up lines into
segments so that the weighted averaging discussed above to calculate point
locations occurs along corresponding segments in each pose. Figs. 11(a)-(c)
represent a profile view of a character's head with a growing nose. Of

CA 02483943 2004-11-16
-21-
course, the intention is that the head maintain the same shape as the nose
grows. However, if the source poses shown in Fig. 11(a) and 11(c) are used.
to generate the constructed pose in Fig. 11(b), the image is distorted. In
order to prevent such distortion, match points A and B are assigned as
shown in Figs. 11(d)-(f) so that the proper shape of the head is maintained
in the constructed pose Fig. 11(e). The match points cause the weighted
averaging to take place along two related segments of the source poses.
Therefore, because the head portion has the same form in the two source
poses in Figs. 11(d) and 11(f), the head is also the same form in the
constructed pose. Match points C and D=shown in Figs. 11(d)-(f) cause the
nose to maintain its shape as it elongates and shrinks. Without these
points, the nose could appear somewhat pointy as in Fig. 11(e) at some
point in the transform.ation.
Table 1 is one embodiment of the pseudo-code for calculating
a constructed pose from the four source poses of a tetrahedron. Table 2 is
one embodiment of the pseudo-code for creating an animated sequence
from the source poses and a transformation graph.
Table 1
Const MaxLineLength = 1000;
{ trrrr*r*r. Definition of a Point !r*rrrrrrr } .
Z'ype PointType =
Record
X, Y, Z Single;
End;
(********* Definition of a Line *******r** )
Type LineType =
Record
NoOfPoirnts : Integer;
Point : Array (1..MaxLineLengtY:I of PointZype;
End;
. {*rrrrrrrrrrrrrr*+r**rrrrrr-rrrrrv.*rrw*rerr,tr*wvrr*r*rrr+-
rrrrrr*rrrrr*rr.rr*rr*rrr} { ~

CA 02483943 2004-11-16
-,~-
{ The following routine calculates a constructed pose from four source poses.
}
{ }
{ It has two different uses : 1) for visual realtime feedback when the
animatorj
{ is creating the transformation graph and 2) as a subroutine when playing
back)
{ the recorded animation sequence for animator review. j
{ }
{ This simple exaMle works for drawings made up of a single line; it would be
)
{ put in a laraer loop for a multi-line drawing. }
{ The four source poses must previously have been "aligned" (ie. they each
must)
( contain the same number of points and point N in pose A must correspond to )
{ point N in poses B, C and D. This is done using 'Match Points,"
( }
.JRRYYYRYYRYYRRR!*~RRYRRR'IYRYYRYYRYYRYYRYYMRRRRR*RIFRRRRRY*RRRRYRRRRIYYRRRRR**
RRM*1 Procedure CalculatePose
15. (Var PoseA, PoseB,
PoseC, PoseD LineType; { The four source poses )
Var CalcPos PointType; ( Pos. in tetrahedron to calc. for)
Vaz DestPose LineRype); { Resulting pose
{ Local functicn to get distance from the point to a vertex of the tetrahedr.)
Function DistToVertex (Var P1, P2 : PointType) : Single;
Begin
DistToVertem. Sqrt ((Pl.X - P2.X)"2 + (P1.Y - P2.Y)"2 + (Pl.Z - P2.Z)"2);
End;
Var DistA, Dist:, DistC, DistD, TotalDist Single;
Proportion.=~, ProportionB, ProportionC, ProportionD, PropScaling : Single;
Begin
{************" Get Distance to each Vertex
DistA DistToVertex (CalcPos, VertexA); (Assumes vertices defined elsewhere)
DistB. DistToVertex (CalcPos, VertexB);
DistC := Dist':overtex (CalcPos, VertexC);
DistD := DistToVertex (CalcPos, VertexD);
{************~' Use them to calc, contributing proportion of each source pose)
TotalDist DistA + DistB + DistC + DistD;
ProportionA TotalDist / DistA;
ProportionB TotalDist / DistB;
ProportionC := TotalDist / DistC;
ProportionD TotalDist / DistD;
{**********=*~= Scale the proportions to total one }
PropScaling ProportionA + ProportionB + ProportionC + ProportionD;
ProportionA ProportionA / PropScaling;

CA 02483943 2004-11-16
-23-
ProportionB ProportionB / PropScaling;
ProportionC ProportionC / PropScaling;
ProportionD ProportionD / PropScaling;
{************** Calculate the new pose
DestPose.NoOfPoints := PoseA.NoOfPoints;
For I 1 to PoseA.NoOfPoints do
Begi.n
DestPose.Point[I}.X ProportionA * PoseA.Point{I].X +
ProportionB * PoseB.Poi;nt[I].X +
ProportionC * PoseC.Point(I].X +
ProportionD * PoseD.Point[I].X;
DestPose.Point(I).Y ProportionA * PoseA.Point[I].Y +
ProportionB * PoseB.Pointjl].Y +
ProportionC * PoseC.Point[I].Y +
ProportionD * PoseD.Point(I].Y;
DestPose.Pointfl).Z ProportionA * PoseA.Point(I].Z +
ProportionB * PoseB.Point[I].Z +
ProportionC * PoseC.Point[I].Z +
ProportionD * PoseD.Point(I].Z;
End;
End;
Tabl
{ ********* Definition of a Line *********" }
Type LineType =
Record
NoOfPoints integer;
Point Array j1..MaxLineLength] of PointType;
En.d;
{ w.:.xwxxw Definition of an Animated Sequence xxwwx**..x }
Type AnimatedSeqType
=
ArraY [1..No0fFrames} of LineZype;
.. . _ {:wwxrwxxwvxwxwxxi~x~-
xwwxwxw**wwwxwxxxwvrwxxwxr*xxwx*wwxwxxw*rw=awxwwwwxwxxxxwxwxx}.
{ This routine computes the frames of ceanposed animation from four source }
( poses and a transformation graph. }
{ }
- .
.~{xw*xxxwwxx*wwwxwwxwxwwwwww.twwwwxx*wwwxwwxwwxwxww*wxwwxwxwxwxwwrrxwwwwwwwwxx
wxw}

CA 02483943 2004-11-16
-24-
Procedure CreateSequence
(Var PoseA, PoseB,
PoseC, PoseD : LineType; ( The four source poses }
Var TransGraph : LineType; ( Trans. Graph is just a line)
}
NoOfFrames : Integer; { Number of frames to create
Var Destsequence : AnimatedSeqType); { Resulting sequence }
Var FramePoints LineType;
Begin
{************** Convert T-Graph to an array of Frarm Points based on,tifiing }
FramepointsFrotnTransGraphTimi.ng (TranfoiznationGraph, NoOfFrames,
FracnePoints) ;
{************** Allow user to adjust the timing manually }
While not Checklf'UserHappy (FramePoints)
LetUserFixCurve (FramePoints);
{************** Calculate each frame }
IJr For I:= 1 to NoOfFrames do
CalculatePose (PoseA, PoseB, PoseC, PoseD, FramePoints(I}. DestSequence(i});
End;
. .. . , - - {**,~,R************yr********Yryry,****~r~r4*-****+~***R***+-
**o****~-*****************f,e*} . . . .
, { . . . ' . . } . .
Sub-routine to convert a transformation graph to an array of Frame Points. }
{ Each frame point is a point on the same 3-space line as the Transformation }
{ Graph, distributed along the line so that the action timing appears natural.
}
{ }
. (V**'/,Ye***V*v-v.*1Rlr******y.**yr***1.1..*Yr**11eir*+RM-
*4.****v**r*****+t4*Yr**/I--Iellrtktt*l***-r*} . .
Procedure TransGraphToFramePoints
(Var TransGraph LineType; { Transformation Graph }
NoOfFrames Integer; { Number of frames needed }
Var FramePoints LineType); { Frame points created }
Var Units Integer;
Fraction, PointToUse Single;
Begin
FramePoints.NoOfPoints NoOfFrames;
{**=*********** First and Last Points are fixed }
,. _
FramePoints.Point[1} .= TransGraph.Pcint[l};
FramePoints.Point[NoOfFrames} TransGraph.Point(TransG-raph.NoOfPoi3rts);
" {************** Start by using the timing from when Trans. Graph was drawn }
For 12 to NoOfFrames - i do

CA 02483943 2004-11-16
-25-
Begin
{ Find a point partway along some line segment in the Trans. Graph)
PointTaUse := (I-1)/(TransGraph.NoofPoints-1); { A real number )
Units Trunc (PointToUse);
Fraction c= PointToUse - Units;
FramePoints.Point[I].X := TransGraph_Point(Units).X +
Fraction * (TransGraph.PointlUnits+11-X - TransGraph.PointfUnits].X);
FramePoints.Point(I].Y := TransGraph.Point[Units].Y +
Fraction * (TransGraph.Point[Units+l].Y - TransGraph.Point[Units).Y);
FramePoints.Point[II.Z = TransGraph.Point[Unitsl=Z +
Fraction * ITransGraph.Point[Units+1].Z - TransGraph.Point[Units].Z);
Fsid;
End;
The system and method of the present invention also
provides for the tying together of different, separatelv transformed groups
of line segments by specifying an attach point on one group of elements to
which another group is connected. This feature, is useful in the case where
different groups of elements experience different motions, but one group
is in reality attached to the other, such as in the: case of the head and body
of a person. This feature is implemented by specifying a first group of
elements as the master and a second group as the slave. In the above
example, the master would be the body and the head the slave.
Techniques for relating. the locations of animated groups in this manner
are known to those of skill in the art in the field of computer animation.
If an animation sequence requires a very complex set of
actions to be scripted -- more than can be constructed from a convenient
number of poses -- a transformation graph through two- or more pose
transformation spaces may pass through a common vertex of the
tetrahedra to generate a continuous motion sequence. In this manner, for
example, an action is scripted inside a first tetrahedron and then through a
vertex which is common between a first tetrahedron and a second
tetrahedron (which have a common source pose at that vertex). The
animator then continues the transformation . graph in the second
tetrahedron which has three different source poses associated with its
other vertices.. Similarly, the second tetrahedron may connect with a third

CA 02483943 2004-11-16
-26-
tetrahedron and so forth. Linking of pose transformation spaces inthis
manner enables complex series of actions to be defined by one continuous
"script." In addition to linking pose transformation spaces at a common
vertex, the endpoint constructed pose of a motion sequence, which need
not be a source pose, may be used as one of the source poses in the
transformation space for a second motion sequence. The transformation
graph for the second motion sequence is started at the vertex associated
with that source pose, so that the action is continuous and searilless when
the two sequences are joined together.
The transformation graphs may be stored and are not
uniquely associated with specific source poses -- the same transformation
graph representing, e.g., a walking action, may be applied to control the
animation sequence for different sets of source poses representing different
characters. Similarly, source poses can be stored for use with different
transformation graphs.
The animation sequences generated by the transformation
graphs may themselves be represented in a tetrahedral transformation
space in order to generate a single output animation sequence. For
example, four different perspective views (e.g., 90 apart) of a walking
action may be created by generating four sets of constructed poses. The
four sets of constructed poses may be generated by drawing a
transformation graph for one of the perspective views, using four source
poses for that perspective view, and then using the same transformation
graph for each of the other three pose transformation spaces associated
with the other three perspective views. In this manner, synchronization
of the four sets of constructed poses is automatic.
Each set of constructed poses is then assigned to one vertex of
a tetrahedron, which in this case may be considered a perspective
transformation space rather than a pose transformation space. Rather
than each vertex representing a single, fixed source pose, the source pose at
each vertex varies as a function of time, i.e., it is determined by the
constructed pose for that vertex at any given point in time. A

CA 02483943 2004-11-16
-27-
transformation graph is then drawn within this tetrahedron to. specifv the
contribution each constructed pose makes at each point in time during the .
transformation, to the final single constructed pose at that point. At each
point along the transformation graph, the final constructed pose is
determined by a composite of the four source poses, except that each..source
pose actually represents a different perspective of the same pose.
Therefore, the movement of the wand only changes the perspective of the
action, not the transformation of the object itself, which has already been
defined by the sets of constructed poses. In this manner, a transformation
graph can be generated representing a continuous walking action with a
continuous change of the viewer's perspective on that action to simulate,
for example, a camera panning around an object.
The aforedescribed transformation graph technique for
scripting motions is a significant improvement over existing computer
animation systems. Simply by manipulating a wand in a three-
dimensional drawing space, an animator can create long and complex
motions using a user interface that allows such motions to be generated in
an intuitive manner as.a "performance," somewhat as a puppeteer would
control the actions of a puppet, and to view the motion in real time. The
advantage of this technique is most significant in three-dimensional
computer-assisted animation, where creating even a single pose, much
less an entire sequence, using existing techniques is complicated and time
consuming. For two-dimensional animation, the technique may be used
to produce long sequences of two-dimensional animation with little effort.
In typical computer animation systems, both the position in
space and the transformation of an object are represented simultaneously
in a pose. The system and method of the present invention provides the
flexibility to separate the transformation of an object from its path in
space.
In this case, the wand may be used to generate a path in space (referred to
as a "space path") for a character or object separately from defining a pose
transformation graph. The path in space has an associated velocity graph,
which may be modified as described above by adjusting or redrawing it, or

CA 02483943 2004-11-16
-28-
through the use of sync points.
A second aspect of the present invention is referred to as
"segment warping" and is also directed to further modifying constructed
poses to provide for greater control over the form and action of animated
images. Segment warps are described as follows. A point within the
drawing space, referred to herein as a warp displacement reference point or
"warp handle," is chosen, which will typically be on a line segment of a
source- pose, but need not be so located. The function of the warp handle is
to serve as a reference point for a motion path relative to this point,
referred to herein as a "warp path." The warp path is drawn by the
animator in real time or in slow or fast motion. The warp path defines,
for each segment or segments to be modified by the segment warp, the
relative displacement of the warp handle from its starting point. The line
segment or segments of a drawing to be modified by the warp path are
then specified by any one of a number of inethods, such as pointing and
clicking with the drawing wand. In addition, a graph, referred to herein as
a "warp profile graph," is drawn which defines the degree to which the
successive points on the line segment or segments are displaced by the
warp path.
The segment warp technique is best described with reference
to a specific example. In the fish shown in Fig. 12(a), match points are
placed on the fish body and tail at points labelled MP1, MP2, MP3, and
MP4. A warp handle, H, is then placed on the segment between MP2 and
MP3. The three segments, MP1-MP2, MP2-MP3, and MP3-MP4, are then
identified as the segments to be warped. Fig. 12(b) illustrates the, warp
path, shown as the dotted line with arrows indicating direction. In this
example, the warp path represents the back and forth motion of a fish's tail
and is represented by a series of arcs. The warp path is not part of the
drawing itself and is not shown in the final animation. The path is shown
moving toward the first extreme EX7., then toward an opposite extreme,
EX2, then back toward the first extreme EX1 again. A warp profile graph is
then drawn for the three segments as shown in Fig. 13. The warp profile

CA 02483943 2004-11-16
-29-
graph defines the relative effect of the warp path of Fig. 12(b), on each
successive point along the selected line segments. As sho-sti*n in Fig. 13,
the
effect of the warp on segment MP1-MP2 is zero at MPl and increases to
90% at MP2, stays constant at 90% for segment MP2-MP3, and varies from
90% at MP3 to 0% at MP4 for segment MP3-MP4. This, means that, for
example, at any point in time, the displacement of the points along
segment MP2-MP3 will be 90% of the relative displacement of the warp
handle from its initial position at that point in time. In other words, if at
a
particular point during the warp the relative displacement of the handle
from its initial position is 1.0 units of -length in a z direction (into the
paper), 0.4 units in an x direction (horizontal), and 0.1 units in a y
direction
(vertical), the displacement of all the points along the segment MP2-3VIP3
from their initial positions will be 0.9, 0.36, and 0.09, respectively. The
points along the segment MP1-MP2 will not be displaced at all at MP1, will
be displaced progressively more towards õMP2, until at MP2 the
displacement is 0.9. The effect along MP1-MP4 will be reversed.
Because segment warps simply represent point displacements
for the points along selected line segments, they are additive -- multiple
segment warps may be applied to the same segment or segments.
The effect of the segment warp on the three segments is
shown in Fig. 14. At point Exi, the tail is at its maximum displacement
along the arc defined by the warp path. The end of the tail, segment MP2-
MP3, is displaced to its maximum extent out of the paper (toward the
observer). Similarly, at point Ex2, segment MP2-MP3 is displaced to its
maximum extent into the paper (away from the viewer.
Rather than defining a warp profile graph as shown in Fig. 13,
the animator may specify the relative displacement of the points along the
line segment in any of a number of ways, such as by varying the thickness,
brightness, or color of the selected segment.
It will be recognized by those of skill in the art that the
segment warp technique provides a powerful and intuitive tool for
animators to create complex motions very simply. By specifying the warp

CA 02483943 2004-11-16
-30-
handle on the vertical segment of the tail MPT-MP2 as shown in Fig. 12(a),.
the animator can, in effect, "grab on" to the tail with. a drawing wand and
move it back and forth in real time, exactly as it is intended that the final
motion should appear. . Thus, subtle differences in the timing, direction,
and extent of animated motions can be quickly and simply produced: The
rate and coordination of the motion with other motions of the object (i.e.,
transformations), may be controlled using the previouslv described
velocity profiles and sync points.
A further example of the utility of the segment warping
concept may be explained with reference to another application. In prior
art computer animation systems, in-between frames are frequently
generated by the computer by linearly interpolating between line segments
in the drawings of the two source poses. However, 'interpolation can
sometimes result in unrealistic motions. One situation where this occurs
is where the motion between source poses is rotational and constructed
poses are generated using linear interpolation. Fig. 15 illustrates the
potential deficiencies of using simple interpolation to create new poses.
The motion of an "angel wing" is illustrated in Fig. 15 showing the
movement of an angel's beating wings. Point E is at the tip of the right
wing and point B at the tip of the left wing. At Eo and Ba, the wings are at
the top of their arc (at pose 1) and at B i and E 1, the bottom of their arc
(at
pose 2). The midpoints of rotation of the wings are at B, and E2
respectively. In true rotational motion, the wing tips are at minimum x
displacement at the top and bottom of the arc and at maximum x
displacement at the midpoint. If the animator specifies only the top and
bottom wing positions as shown in Fig. 15 as source poses, and the
computer generates the constructed poses through linear interpolation,
the result is that the wing will appear to shrink as it moves from top to
bottom, as shown by the positions of the tips at B-, and E2 (dotted lines). Of
course, additional source poses may be specified by the animator at
intermediate positions between the extremes of motion of the wing, but
the additional poses may be needed for creating other wing motions, for

CA 02483943 2004-11-16
-31-
example, a twisting of the wings as they beat up and down.
The segment warp technique of the present invention -solves
this problem as described with reference to Fig. 16. As shown in Fig. 16(a),
using the right wing as an example, match points are specified at points A,
B, and C. A warp handle, WH, is then specified- at point B, the=wing tip. A
warp path, WP, shown as the dotted line, is drawn to specify the relative
displacement of the warp handle.
The warp path shown is for one downward sweep of the wing from the
top of its arc to the bottom. The warp profile is drawn as in Fig. 16(b). The
segment warp specified by the warp path and profile graph is then applied
in conjunction with the pose transformations of the angel wings, which
are specified with a pose transformation graph, as described above. As the
wing moves downward, the displacements specified by the warp path are
applied to the points along the segments A-B and A-C in accordance with
the warp profile shown in Fig. 16(b).
The result is that as the wing moves downward form pose 1
to pose 2 to pose 3, the points along the two segments are displaced so as to
maintain the proper size- of the wing during the transformation from pose
to pose. The wing in effect is progressively stretched outward as it moves
down so that the wing tip follows the proper arc, designated B1; B2, B3 in
Fig. 16(c). The action of the angel with the wings moving up and down
may be scripted using the previously described transformation graph and
velocity profile. This action may then be coordinated to the segment warp
of the wing. As previously described, this may be done by drawing the
warp path while viewing the transformation of the angel's wings or using
sync points to control the velocity profiles so that, for example, the
maximum displacement of the warp from the reference point occurs when
the wing is at the midpoint of the sweep downward of the wing.
If there are many beats of the wing, as .would normally be the
case, a single warp path (basicallv an outward and inward motion) is
drawn, continuously, for each down beat and each up beat, and the warps
are synchronized to the beats as described above. A similar segment warp

CA 02483943 2004-11-16
-32-
would be applied to the left wing as well.
The segment warp concept is a very powerful technique with
many applications. For example, complex effects such as waves, wind
effects, and acceleration effects may be readily achieved using this
technique. Wind effects may be created as illustrated in Fig. 17. Fig. 17(a)
illustrates a flag which the animator wants to illustrate as blowing in the
wind: Three segments of the flag are to be transformed by the segment
warp; labelled Sl, S2, and S3 as shown. Match points MP1 and MP2 are
also shown at the lower corners of the flag. SI is comprised of points 0-
MP1, S2 of points MP1-MP2, and S3 of points MP2-3. A warp handle H is
placed at point MP2 for convenience and potential warp path P,
represented by the dotted line in Fig. 17(a), is drawn. Fig. 17(b) represents
the profile graph for the three line segments. As shown in Fig. 17(b),
segment S1 varies from zero displacement at the attach point 0 to
maximum displacement at MP1. Segment S2 is always at maximum
displacement, and. segment. S3, like segment S1, varies from zero
displacement at point 3 to maximum displacement.
Thus far, a normal segment warp has been described.
However, for wind effects, the warp path P represents only the potential
warp path of the segments. The actual position along the path is
determined by specifying a wind vector as shown in Fig. 17(c). This is
sunply drawn by the animator as if the wand were being blown back and
forth by the wind, and recorded by the computer. For purposes of
simplifying the description, the wind is shown blowing along the x-axis
only. Fig. 17(d) represents the velocity profile for the wind which could be
derived from tracking the rate of the back and forth motion of the drawing
wand when generating the wind path shown in Fig. 17(c). At maximum
positive velocity the maximum positive displacement along the potential
warp path is applied and at maximum negative velocity, the maximum
negative displacement is applied. In addition, zero displacement is
defined to occur at zero velocity. Displacements between zero and the
maximum point and zero and the minimum point are produced simply

CA 02483943 2004-11-16
-33-
by using the wind velocity at each frame interpolated so that. the
maximum wind velocity corresponds to maximum displacement.
Depending on the direction (positive or negative) and speed of the wind,
the segments will be warped as shown in Fig: 17(e) (negative) or 17(f)
(positive). The displacement of a particular point of a line segment along
the motion path at any given point in time is dictated by the velocity of the
wind at that point in time, which could be positive or negative and. thus
also defines the direction of displacement. The potential warp path must
be drawn with reference to the wind direction. Thus, if the wind direction
were not along only the x axis as shown in Fig. 17(a), but also along the z
axis, a potential warp path would have to be drawn for how segments of
the flag would be warped in the z axis. The wind velocity along the z axis
would also be determined from the wind vector.
The advantage of this technique over a normal segment warp
is that it provides for control of the displacement along a potential warp
path as opposed to an actual predetermined warp path. In addition, use of
the wind warp permits the same wind vector to be applied to numerous
elements in a drawing which will all be similarly affected by the wind.
The animator may specify that the wind warp be applied to different
objects in a drawing at different times to create the effect of a gust of wind
moving through a scene.
Inertial effects are created in a manner similar to wind effects.
In this case, however, rather than using. the wind velocity to control the
displacement along a potential warp path, the acceleration of a main object
of motion is used. For example, if a character begins to run, his
acceleration will cause his coat to lift up behind him in the opposite
direction. A potential warp path for the coat may be drawn, and the
position of the appropriate segments of the coat along the potential warp
path determined by the change in velocity (acceleration) of the person
wearing the coat. Thus, when the character begins to move from a
standing position, acceleration is greatest and the coat will fan out behind
him to the maximum extent. As the character reaches a steady velocity,

CA 02483943 2004-11-16
-34-
however, his acceleration goes to zero and the coat returns to the. zero
displacement position.
Wave effects. may also be created using the segment warp
concept. A "wave warp" is a means for creating the effect of a wave
travelling through a segment or segments. In the case of a wave effect, a
warp handle and warp path are not required. A straight reference line A-B
as shown in Fig. 18(a) is drawn. The desired wave motion, showin as
dotted line wl-w2, is drawn with reference to this.line. The wave W1-W2
need not lie in one plane but may be three-dimensional so as to define, -for
example, a corkscrew.
The displacements between each point along the wave
relative to the line A-B is calculated based on vectors drawn normal to the
straight line and intersecting the wave. For each point Pi along the wave,
the corresponding displacement Di is calculated. As shown in Fig. 18(b),
these relative displacements are then applied to a line segment S of a
drawing in order to transfer the effect of the wave to the object or objects
in
the drawing (only Pl-P7, representing the first crest of the wave, are
illustrated).
The result of the effect of the initial wave crest on the
segment S in the first resulting frame is illustrated in Fig. 18(c). The
points
along the segment D1-D7 are displaced an amount Dl-D7, respectively.
The series of displacements Dl-D7 defined by the wave of Fig. 18(a) is then
shifted along the segment S (depending on the direction of travel of the
wave) so that in the next frame of animation, the displacements are
applied to different points along the segment S. In the example of Fig. 18,
the wave is traveling to the right. As shown in Fig. 18(d), the
displacements D1-D7 are shifted two points to the right so that they now
are applied to points P3-P9 on the segment S. Thus, the segment in frame
2 appears as shown in Fig. 18(e). The amount of shift is determined by the
velocity of travel for the wave, which is specified by the animator. The
process is repeated for each successive frame of animation so as to create
the appearance of a wave travelling through an object.

CA 02483943 2004-11-16
-35-
As in the case of an ordinary segment warp, a warp profile
graph is used to modulate the effect of the wave path at each point along
the segments affected segment or segments. For example, the warp profile
graph may be drawn so that the wave effect may not be evident at all at the
beginning of a segment but have an increasing effect as it travels along the
segment. For example, the tail of a tadpole moving- through the water
would have no lateral wave movement at its root, but increasing
movement toward the tail.
In one embodiment, the animator specifies four parameters
to control the wave effect: i) the velocity of wave travel in terms of the
number of points shifted per frame; ii) the direction of wave travel; iii) the
starting point of the wave; and iv) the ending point of the wave. The
wave path drawn by the animator is then interpolated based on these
parameters. to obtain, the desired effect. For, example, if the animator
desires that the wave effect start and end on the segment so that it is
present for the entire length of the animation, and that the velocity of
wave travel is 1 point per frame, the length of the originally drawn wave
path is adjusted by interpolation to be twice the length of the segment so
that at the beginning of the animation, the entire first half of the wave is
applied to the segment. Due to the movement of the wave through the
segment during the animation, at the end of the animation, the first half
has moved completely through the segment and the second half is entirely
on the segment. Similarly, if the velocity is doubled, the wave path must
be stretched by interpolation to four times the length. The wave effect may
also be specified as starting or ending off of the segment, in which case the
length would similarly be adjusted.
. . . . d . . . . . - Wave warps are a very simple but powerful method for
creating motion which appears organic and life-like.
Where the overall orientation of a character or object changes
significantly during the course of an animation sequence (e.g., by more
than 45 on any axis), simple segment warps may not create the desired
effect. For example, in the segment warping of the tail shown in Fig. 12(b),

CA 02483943 2004-11-16
-36-
if the fish~ were to turn over onto its side during the sequence, the segment
warps as shown would move the tail up and down relative to the fish
rather.than side to side. In this situation, a "constructed segment warp"
may be used.
For a constructed segment warp, a warp handle is indicated
and a source warp path and source warp profile graph are drawn for each
source pose of the character or object, with the source warp path
appropriately related to the orientation of the object in that pose. Before
the warp effect is applied, a constructed warp path and constructed warp
profile graph are derived from the source warp paths and -source warp
profile graphs using weighted averaging in the same -manner as for the
constructed poses. Similarly, from the velocity profiles of the source warp
paths, a constructed velocity profile is derived, for the constructed warp
path and may be modified as previously explained (the separate warp
paths may need to be synchronized as described above so that they stay in
sync regardless of the constructed pose). In this manner, the orientation of
the constructed warp path is correctly related to the orientation of the
object. The constructed warp path then produces the segment warp, as
described above for siunple segment warps.
For complex drawings using warps, it could be tedious if
related warps were required for many segments. . However, the concept
may be readily extended to more complicated forms using a technique
referred to as "spine warping." Spine warping is used to transform objects
comprising multiple line segments with a single warp by applying the
warp to a "spine" of the object. The term spine is used because a straight
line is drawn roughly through the centerline of a group of line segments
which may, for example, define the body of an animal. A warp is then
applied to the spine and then transferred to the individual drawing
segments. For spine warps, a straight line reference spine is drawn in each
source pose used in a transformation and the animator selects the
segments to be affected by the spine warp. For each segment selected,
perpendicular distances from the points along the segment to the reference

CA 02483943 2004-11-16
-37-
spine are calculated in order to transfer a warp applied to, the spine to the
selected segments. Constructed poses are generated in the manner
previously described. The constructed poses include the straight line
reference spine which is treated as an additional line in a source drawing
but not displayed. The spine warp is then applied to the appropriate
segments of the constructed poses, using the displacements between the
reference spine and the warped spine and the perpendicular distances
from the points along the segments to the reference spine.
For example, Fig. 19(a) illustrates a constructed pose of a fish
with a straight line spine, S. The spine is -drawn by the animator but is not
a part of the drawing that is displayed in the resulting animation frames.
The perpendicular distances from points P1-Pn along the line segments to
the spine are calculated and stored in order to transfer warps imposed on
the spine to the segments of the drawing. A single warp path P is used in
combination with a warp profile graph to warp the spine S. The spine may
be warped by any of the above-described warps. Fig. 19(b) illustrates the
warped spine S' (intended to be shown bending into the paper). For each
line segment controlled by the spine warp, each point along-the segment is
displaced using the calculated displacement of the warped spine relative to
the reference spine. In this manner, complex forms may be readily
transformed in a simple manner using any of the above warping
teChniques.
A final aspect of the present invention also relates to creating
constructed poses that maintain the proper coloring of source poses to
enable the completely automatic painting of a series of animation
drawings. In prior art computer painting methods of painting images,
closed loops are drawn in two-dimensional space and filled in with color
using a"seed" point. This technique is well known in the art of two-
dimensional computer drawing and painting systems. The seed point acts
as a starting point for the filling of closed loops in the color chosen by the
animator. Painting proceeds outward from the point until the boundary
of the loop is detected and filling the bounded, area.

CA 02483943 2004-11-16
-38-
However, the seed fill technique has drawbacks when used
for the automatic painting of stereo and two-dimensional images. For
example, when the seed fill method is used for small loops, it znay be
difficult or impossible for the animator to place the seed point within a
stereo loop in such a position that when the fill method is applied . to the
left and right 'eye two-dimensional projections of the stereo image, the
seed point falls within each projected two-dimensional projected loop.
The result is that for one or both eye projections, it may happen that, the
exterior of the loop is filled and not the interior. In addition, where a
computer-assisted animation sequence of drawings is being generated and
it is desired to automatically paint the series of drawings, the generated
drawings may, by design, contain single loops that twist in three-
dimensional space, thus creating several apparent loops in the two-
dimensional projections of the transformed loop. In this situation, the
seed point may fall entirely out of the loops, or only fill one of the two-
dimensional loops. For example, a single loop with a seed point SP,
shown in Fig. 20(a), may be twisted into a figure 8 when it is projected onto
a plane creating two loops on the plane, shown in Fig. 20(b). The seed
point SP may then fall within only one of the loops of the figure 8 as
shown in Fig. 20(8), in which case only that portion will be filled.
Alternatively, the seed point may fall outside the Ioop entirely, as shovvn
in Fig. 20(c), in which case the area external to the loop will be colored.
The present invention solves this problem using a technique
referred to herein as "fill masking." Fill masking is a technique where a
painted loop that is part of a stereo image is filled for display purposes by
processing the loop prior to display in the following manner. First, the left
and right eye projections of the stereo image of the loop on to a two-
dimensional plane are ascertained. For each of these projections, in an off-
screen buffer, a rectangle at least one pixel larger on each side than the
projected loop is generated by determining the minimum and maximum
x and y coordinates of the loop as shown in Fig. 5(a). Fig. 21(a) illustrates
a
single eye projection of a loop and rectangle. The entire rectangular area is

CA 02483943 2004-11-16
39-
generated in the color with which the loop is to be filled. The two-
dimensional projection of the loop originally drawn by the animator is
transferred to the buffer in the proper line color for the loop as shown in
Fig. 22(b). A fill of the rectangle is then performed using the seed point
and flood fill method discussed above. The seed point is generated just
within any corner of the rectangle. For this fill, only the region bounded
by the exterior of the loop and the rectangle is filled so that the interior
of
the loop is not filled and therefore remains in the original loop color as
shown in Fig. 22(c). The fill consists of a code that makes this bounded
region transparent when displayed so that only the loop remains visible in
the proper color. After processing in this manner, which takes only a
small fraction of a secorid, the rectangle is transferred from the buffer to
the viewable display. It is known in the art of computer drawing systems
to provide a"transparent" or "no-copy" color to indicate that the region
filled with this color should not be copied to the screen from the bu#fer.
All that appears is the loop in the proper color and the boundary line for
the loop. For stereo loops, the process is repeated for each of the left and
right eye projections of the loop.
This technique has been described for three-dimensional
drawings but is equally applicable to the automatic painting of sequences of
two-dimensional drawings.
The appendix contains the BASIC code for implementing the
transformation graphs, space path, segment warps, wind warp, inertia
warp, and wave warp of the present invention. This code is one example
of the code that may be utilized and should not be construed as limiting.
Those of ordinary skill in the art of will recognize that other code may be
used. The invention has been described in greatest detail with respect to
the particular embodiments and exemplary applications described above.
However, the invention is not limited by this embodiment and examples,
but is limited only by the scope of the appended claims.

CA 02483943 2004-11-16
- 40 -
A,t~aendix
EEF'SNT A-Z
Type Def7.211tioTlS *x***xrrrxxs*xxvrxx:*xxxwx*xxx*xxxxx**~rriyrxxx*rx*xx
TYPE Wanc3ReportType
X AS INxEGER
Y AS INTESM
Z AS IIVTnGER
XX AS INl.'F7GER
YY AS II3'TF7C',ER
ZZ AS nqTBGII2
Fm TYPE
TYPE t3DPcint
X AS SINGM
Y AS SINGLE
Z AS SINGLE
F1VD TYIxE
TYPE SpaceRef Pt
Locat AS t3DPoint
Labe1 AS STRING * 5
Visib AS IN'PDGER
EID TYPE
TYPE LocType
X AS INTEGER
Y AS INTEGER
Z AS ]'NTDGER
END TYPE
TYPE SterType
lx AS llad'F7M
.zx AS II11TBM
Y AS INTEGER
ENA TYPE
TYPE TScriptWayPt
Locat AS t3DPoint
Label AS S"'t'RIIVG * 8
END TYPE
TYPE LirneType
Beg AS INT2)GER
Fin AS ZNTASER
TenpF'in AS IlfimER
FinalStart AS nnmGM
Fina].End AS ZNTEm
WcbGxp AS TNTmGER
WChObj AS I1VTf7CER
LineCol AS I2u'tBGER
Looped AS nvEmm
PaintCol AS INTDGER

CA 02483943 2004-11-16
- 41 -
Intermit AS INTEGER
KeyForm AS INTEGER
Threshold AS SINGLE
StartVis AS INTEGER
EndVis AS INTEGER
Label AS STRING * 8
NormOrMag AS SINGLE .
END TYPE
TYPE TempSegType
WchLine AS INTEGER
AStartPt AS INTEGER
AEndPt AS INTEGER
BStartPt AS INTEGER
BEndPt AS INTEGER
CStartPt AS INTEGER
CEndPt AS INTEGER
DStartPt AS INTEGER
DEndPt AS INTEGER
WchObj AS INTEGER
WchGrp AS INTEGER
WchLngst AS INTEGER
ADist AS SINGLE
BDist AS SINGLE
CDist AS SINGLE
DDist AS SINGLE
END TYPE
TYPE FinlSgType
WchLine AS INTEGER
Beg AS INTEGER
Fin AS INTEGER
WchObj AS INTEGER
WchGrp AS INTEGER
WchInfoArr AS INTEGER
WarpNo AS INTEGER
Anchor AS INTEGER
E[QD TYPE
TYPE WarpType
Label AS STRING * 11
END TYPE
TYPE RefPtType
Frame AS INTEGER
TempPtslndex AS INTEGER
Label AS STR.ING * 15
WchObj AS INTEGER
WchGrp AS INTEGER
WchWrp AS INTEGER
END TYPE
TYPE TransType.
PropA AS SINGLE
PropB AS SINGLE
PropC AS SINGLE
PropD AS SINGLE
END TYPE

CA 02483943 2004-11-16
- 42 -
TYPE WarpProfileType
Proportion AS SINGLE
END TYPE
TYPE GroupType
WchObj AS INPEGER
Label AS STRING * 6
Transshift AS INTEGER
VeiHookl AS INTEGER
VelSlavl AS INTEGER
VeiHook2 AS INTEGER
VelSlav2 AS IR7TEGER
HandleVelcroLocat AS t3DPoint
END TYPE
TYPE VelcroType
GrpWithHook AS INTEGER
HookPtIndex AS INTEGER
SlaveGrp AS INP.EGER
HookXYZVa1s AS t3DPoint
END TYPE
TYPE ZDistType
Dist AS INTEGER
ObjNo AS INTEGER
END TYPE
TYPE ObjectType
PathNo AS INTEGER
ZDist AS INTEGER
Label AS ST'RING * 6
HasAnchors AS INTEGER
StartVis AS INTEGER
EndVis AS INPEGER
FakeZShift AS INTEGER
END TYPE
TYPE ObjectFinalPositType
FinalPositObjl AS t3DPoint
FinalPositObj2 AS t3DPoirnt
FinalPositObj3 AS t3DPoint
END TYPE
TYPE SegWarpInfoType
WchSeg AS INTEGER
Hndl AS INTEGER
ProfBeg AS INTEGER
Kind AS STRING * 4
WchPath AS INTEGER
WchWave AS INTEGER
WchProf AS INTEGER
SegLen AS INTEGER
WaveSpeed AS INTEGER
Direc AS STRING * 4
OverLap AS INTEGER
END TYPE
TYPE PaintType
SeedA AS t3DPoint

CA 02483943 2004-11-16
- 43 -
SeedB AS t3DPoint
SeedC AS t3DPoint
SeedD AS t3DPoint
PaintCol AS INTEGER
WchLn AS INI'EGER
END TYPE
TYPE RegType
ax AS INTEGER
bx AS INTBGER
cx AS INTEGER
dx AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
TYPE TransferType
Cmd AS INTEGER
Parant AS INTEGER
X AS SINGLE
Y AS SINGLE
Z AS SINGLE
E'ND TYPE
TYPE AnchorRunType
WchObJ AS INTEGER
WchGrp AS INTEGER
WchLine AS INTEGER
WchSeg AS INTEGER
WchPt AS INTEGER
StartFrarne AS INTEGER
EndFrame AS INTEGER
Label AS STRING * 8
END TYPE
'following are constants for Cmd field:
'connnands that need XYZ:
CONST ePointAt = &H1000 '4096
CCTIST eLineTo = &H2000 '8192
CONST eFloodFill = &H3000 112288
'coa~nands that need nothing:
CONST eNop = 0
' coirenands that need Param:
CONST eStartCel = &HAOO 12560
CONST eSetColor = &H100 '256
CONST ePaletteSize = &HBOO '2816
C'CNST eSetMix = &H300 1768
CONST eSetLineWidth = &H400 '1024
CONST eAddBorderColor = &H500 '1280
CONST eDeleteBorderColor = &H600 '1536

CA 02483943 2004-11-16
- 44 -
CONST eClearBorderColors = &H700 '1792
CONST eStartEntitY = &HC00 '3072
bit masks for Param for eStartEntitY
CON3T eFilled = &H1
CONST eNonFilled = 0
CONST eLooped = &H2
CONST eNonLooped = 0
General Enumerations *********************,r**************************
CONST False = 0
CONST True = -1
CONST eScanTransOnTempGraph = 2
CONST eObjPathOnTempPts = 3
CONST eObjPathByFrms = 4
CONST eScanForWarpByFsms = 5
CONST eScanTransByFrms = 6
CONST eScanGspTransPlusPath = 7
CONST eScanForObjPathSyncPt = 8
CONST eScanForTransSyncPt = 9
CONST eScanForWarpSyncPt = 10
CONST eScanForReferenceObject = 11
CONST eScanForAnchorPts = 12
CONST eobjPath = 13
CONST eTScript = 14
CONST eWarpPath = 15
CONST eWaveShape = 16
CONST eWindPath = 17
External Subroutine Declarations ************************************
Initialize, Read and Close 3D Pointing Device
DECLARE SUB InitWand
DECLARE SUB ReadWand (SEG Location AS WandReportType)
DECLARE SUB CloseWand
Record Image on Screen for Local Playback,
DECLARE SUB SnapShot (BYVAL NameCode, BI'VAL FrameNo)
' EMS Memory Functions
DECLARE SUB EMBInit (B'YVAL PagesReq, SEG Result)
DECLARE SUB PagesAvail (SEG Count, SEG Result)
DECLARE SUB GetArray (BYVAL PageNo, BYVAL index, SEG Value)
DECLARE SUB SetArray (BYVAL PageNo, BYVAL Index, BYVAL Value)
DECLARE SUB GetArrayReal (BYVAL PageNo, BYVAL Index, SEG Value AS SINGLE)
DECLARE SUB SetArrayReal (BYVAL PageNo, BYVAL Index, BYVAL Value AS SINGLE)
DECLARE SUB EMSClose
EMS memory page assigIlTClentS ** r*,t******,r,r***** t******~***************
' Normal EMS page allocations - change TWEENY.C if more than 80 needed

CA 02483943 2004-11-16
- 45 -
CONST RawPtsXPg = 0
CONST RawPtsYPg = 1
CONST RawPtsZPg = 2
CONST TempPtsXPg = 3
CONST TempPtsYPg = 4 . '*
CONST TempPtsZPg = 5 *
CONST JAPtsXPg = 6
CONST JAPtsYPg = 7
CONST JAPtsZPg = 8
CONST JBPtsXPg = 9
CONST JBPtsYPg = 10
CONST JBPtsZPg = 11
CONST JCPtsXPg = 12
CONST JCPtsYPg = 13
CONST JCPtsZPg = 14
CONST JDPtsXPg = 15
CONST JDPtsYPg = 16
CONST JDPtsZPg = 17
CONST TempPts2XPg = 18
CONST TempPts2YPg = 19
CONST TempPts2ZPg = 20
CONST PathlXPg = 21
CONST PathlYPg = 22
CONST PathlZPg = 23
CONST Path2XPg = 24
CONST Path2YPg = 25
CONST Path2ZPg = 26
CONST Path3XPg = 27
CONST Path3YPg = 28
CONST Path3ZPg = 29
CONST Path4XPg = 30
CONST Path4YPg = 31
CONST Path4ZPg = 32
CONST Path5XPg = 33
CONST PathSYPg = 34
CONST Path5ZPg = 35
CONST Path6XPg = 36
CONST Path6YPg = 37
CONST Path6ZPg = 38
CONST Path7XPg = 39
CONST Path7YPg = 40
CONST Path7ZPg = 41 *
CONST Path8XPg = 42
CONST Path8YPg = 43
CONST PathBZPg = 44

CA 02483943 2004-11-16
- 46 -
CONST WaveShapelXPg = 45
CONST WaveShapelYPg = 46
CONST waveShapelZPg = 47
Interlaced buffer pages : change TWEENY.C if more than 32 needed
CONST APts%Pg = 256 + 0
CcNST AptsYPg = 256 + 1
CONST APtsZPg = 256 + 2
CONST BPtsXPg = 256 + 3
CONST BPtsYPg = 256 + 4
CONST BPtsZPg = 256 + 5.
CONST CPtsXPg = 256 + 6
CONST CPtsYPg = 256 + 7
CONST CPtsZPg = 256 + 8
CONST DPtsXPg = 256 + 9
CONST DPtsYPg = 256 + 10
CONST DPtsZPg = 256 + 11
CONST FastWorkArraylXPg = 256 + 12
CONST FastWorkArraylYPg = 256 + 13
CONST FastWorkArraylZPg = 256 + 14
COf1ST FastWorkArray2XPg = 256 + 15
CONST FastWorkArray2YPg = 256 + 16
CONST FastWorkArray2ZPg = 256 + 17
CONST TempSmoothPtsXPg = 256 + 18
CONST TempSmoothPtsYPg = 256 + 19
CONST TempSYnoothPtsZPg = 256 + 20
CONST EMSPagesRequired = 82 * 8 150 normal pages + 32 interlaced pages
Global Data Variables ****************************~******,r**~********~
DIM SHARED gBuildToggle
DECLARE SUB ReCntrGrp (WchGrpQ6, PtArray$, CenterOfGrp() AS ANY)
DECLARE SUB MrkGrpCntr (Message$, Pose%, WchGrp%)
DEChAFtE SUB ShowGrp (WchPose%, WchGrp%, ShowColor%)
DECLARE FUNCTION Dist8et2Pts! (aArrayl%, aArray2%, aPointindexl%,
aPointlndexM
DECLARE SvB ShowFinalLn (WchPoset, LnNot, ShowColor%)
DECLARE SUB SaapLineDirection ()
DECLARE SUB ShowGuideMatchPts (WchPose%)
DECLARE SUB MarkSpaceRefPts ( )
DECLARE SUB ShowSpaceRefPts ( )
DECLARE SUB AdjPathAlongXYZ (WchPath%)
DECLARE SUB PathAdj ( )

CA 02483943 2004-11-16
- 47 -
DECLARE SUB AdjObjPathStartEnd (Array%, NoOfArrayPts%)
DECLnRE SUB VisInvisObj (1
DECLP,RE SUB ChooseGrp (ChosenGrp%, GrpText$)
DECLARE SUB ChooseObj (ChosenObj%, ObjText$)
DECIARE SUB MrkVisInvisLine O
DECLARE FANCTION CalcDistBetPts! (Ptl AS ANY, Pt2 AS ANY)
DECLARE FUNCTION FindAlnForIntermit-% (WchPt%)
DECLARE SUB NrkIntermtLine 0
DECLARE FUNCTION CalcTDist! (Vertex)
DECLARE F[7NCI'ION CalcTetFrms$ ( )
DECLARE FUNCTIOnI LnEndsClose (PtArray, IndexPtA, IndexPtB, Range)
DFsChARE FUNCTION FindAln (aMatchPt, aPointNdx)
DECLARE FUNCTION CalcTProps (WchFrame)
DECLARE FUNCTICrI XYZDiff ( )
DECLARE FUNCTION WarpSegProfPtr! (WchProf, WhereinProf)
DECLARE FUNCTION FindWchFin2Sg (ArrayO AS ANY, PointNdx)
DECLARE SU8 PathShiftToMatchPrevRun (WchObj%)
DECL'ARE SUB ShowAllFnlSegs (WchPose%)
DECLARE SUB A1lPosesAreA O
DEChARE SUB ScanPoseTrans (ForWhat$, WchGrp%, WchObjPath%, FrameNo%)
DECLARE SUB Velcro ( )
DECLARE SUB TrnsfrPrevLnToTempPts (Array%, Start%, Finish%, WchSource%,
DestinationPose%)
DECLARE M7B TrnsfrPrevLineTolm (WchSource%, DestinationPose%, WchLine$)
DECLARE SUB ShowGrpTransInPathPosit (WchObj, WchGrp, Grp2, index)
DFjCLARE SUB ShowObjOnPath (WchObj, Obj2, ObjPathPosit AS t3DPoint)
DECLARE SUB MrkObjAnchorPt ( )
DECLARE SUB PlaceSyncPtsOnTempPath (Kind, WhichOne%, PathText$)
DECI,ARE SUB ShowGroupTScript (WchGrp, Group2, Scanlndex, IndexType$)
DECLARE SUB ChooseLineColor O
DECLARE SUB ShowSyncPtLines (StartOfPresentSyncPts)
DECLARE SUB SwapSortedSyncPts O
DECLARE SUB FindFrm2nChartObjGrpWarp (Kind, WchOne, WchFrame)
DECLARE SUB ShowASegStart (WchSeg)
DECLARE SUB WndPtScan (Object, Object2, Group, Group2, Array, Limit,
MarkType, ScanForWhat)
DECLARE SUB DrawAPose O
DECLFIRE SUB SetLJpGlueLoops ( )
DECLARESUB DefnGrpsObjs O
DECLARE SUB MkScaffold O
DE L?AE SUB DrawBCDPoses O
DECLARE SUB FindLngstSeg U
DECLARE SUB MtchPtsPartO O
DECLARE SUB MkFrameScreenV4 (Kind%, WchOne%)
DECLARE SUB MrkScaffoldPts O
DECLM SUB ShowScaffold (WchPose)
DECLAR'E SUB MrkScaffoldCntr (Message$, WchObj, WchPose)
DECLARE SUB VerticalText (Text$, y, x)
DECLARE SUB Nameh-arps O
DECLARE SUB SortSyncPtsForApplic (Kind, WchNo)
DECLARE SUB PlaceSyncPtsOnFrmChrt (Kind, WchOne, Text$)
DECLARE SUB ScanFormTrans (ForWhat, WchGrp, WchObjPath, FrameNo)
DECLARE SUB PaintLoop O
DECLARE SUB D3Wave (RequiredLengthOfWave)
DECLARE SUB TrnsfrWave (WaveNo)
DECLAF~E SUB MyDelay (HowLong)
DECLARE SUB WarpSegWaveShapePtr (PositionNo, WchWaveShape,
WarpSegWaveShapePtPosit AS ANY)

CA 02483943 2004-11-16
- 48 -
DECLARE SUB ShowFnlSegs (WchArray, WchLine, ShowColor)
DECLARE SUB MkPathCycle O
DECLARE SUB DefnPt (DefndPoint AS t3DPoint, Message$, PtIsFor$, WchMrkr)
DECLARE SUB PlaceFr.mChrtSyncPtsOnPath (Kind, WchNo)
DEC7.ARE SUB ColorIt 0
)
DECLARE SUB PutDxwMnuOinScrn (Text$, WchPose, Version)
DECLARE SUB SmoothJoin (PtsToBeJoined, Range)
DECLARE SUB TrnsfrATo (Array, ImageLn.s() AS ANY)
DECLARE SUB Nameobjects O
DECLARE SUB NameGroups O
DECLARE SUB SbtrcArr (Result, Whole, Part(} AS ANY, I; J, K)
DECLARE SUB ShowObjectSegs (WchObj, WchPose, aColor, aUseLines)
DECLARE SUB MtchPtsPartl O
DECLARE SUB FindInRng (PtArray, Start, Finish, Range)
DECLARE SUB GetImFxXYZ (ImToFix, PtPosit)
DECI.ARE SUB AdjMtchPt (WchPose, WchLine, MtchPtNdx)
DECLARE SUB FindDesPt (WchPose, WchLine)
DECLARE SUB NtchPtsPart2 (WchPose, MtchPtNdx)
DECLARE SUB MtchPtsPart3 (WchPose, MtchPtNdx)
DECLARE SUB JstfyTempSegsPartB (WchSeg, LngstSeg, SegStart, SegEnd)
DECLARE SUB MkTetLns (Vertex, Other'Vertex)
DECLA'RE.SUB SetupTetra O
DECLARE SUB Ca1TetFrms O
DECLARE SUB Tetra (WchGrp)
DECLARE SUB DelLast (WchPose)
DECLARE SUB DelLast.B (LnArray() AS ANY, WchPose)
DECLARE SUB GetXYZ (WchPt)
DECLARE SUB TrnsfrTmpTolmPartB (PtArray)
DECLARE SUB ShowGuideLnPart2 (LnArrayO AS ANY, PtArray, WchPose)
DECLARE SUB DelLastLnPart2 (LnArrayO AS ANY, PtArray, WchPose)
DECLARE SUB ShortCutObj ects ( )
DECIARE SUB PutInObj (WchGrp, WchObj)
DECLARE SUB PutlnGrp (WchLine, WchGrp)
DECLARE SUB ShortCutGroups O
DECLARE SUB NoMtchPts O
DECLARE SUB CalcFlatXY O
DECLARE SUB ShowFlatCrsr {)
DECLARE SUB ClearT4tchPts O
DECLARE SUB HiLiFinlSg (SegNo)
DECLARE SUB ShowGuideLn (WchPose)
DECLARE SUB CalcMrkrPts O
DECLARE SUB Ca1cLHI2XY ( )
DECLARE SUB TxnsfrWhlArray (Arrayl, Array2)
DECLARE SUB WndMnu (Text$, A$, B$, C$, D$, E$)
DECLARE SUB WndSlct (Ans$, Delay)
DECLARE SUB WndChs (Text$, A$, B$, C$, D$, E$, Ans$, When)
DECLARE SUB Wndin O
DECLARE SUB Smooth (Arrayl, Array2, SmoothRange, EvenSpacing)
DECLARE SUB ShowObjPath (Array, Visibility)
DECLARE SUB MkPathGrfs (Spacer)
DECLARE SUB Construct (BeginFrame, FinishFrame, NoOfObjectsForThisRun)
DECLARE SUB GetSum4VarpDisp (SegInfoLst(), SeglnfoLstNdx, FrameNo,
SegNo, SegPtNo, SumWarpDisp AS ANY)
DECLARE SUB WarpSegPathArrayPositPtr (FrameNo, WchPath,.
WarpSegPathPtPosit AS ANY)
DECLARE SUB PathArrayPositPtr (FrameNo, WchPath, ObjPathPos AS ANY)
DECLARE SUB TransPtr (FrameNo, WchGrp, A11Prop AS TransType)
DECLARE SUB Interpo (Array, StartOfGap, EndOfGap)
DECLARE SUB Stretch (Small, Big, StartSmall, EndSmall, StartBig, EndBig)
DECLARE SUB ShowAllSegStarts O

CA 02483943 2004-11-16
- 49 -
DECLARE SUB GetWarpProfile (WarpNo)
DECLARE SUB FindMrkdPtlnAPose (ThisOne, Text$)
DECLARE SUB MkUniPath (Text$, MkUniPathFor)
DECLARE SUB FindInApts (FOUndPt)
DECLARE SUB JstfyTempSegsPartA O
DECLARE SUB GetWndXYZ (Kind)
DECL,ARE SUS MkSegs O
DECLARE SUB DefnSegWarp (Wrp'Number, AvlPth, AvlWarpProflArray)
DECLARE SUB ShowFlatPt (x, y, C)
DECLP,RE SUB TrnsfrProp (ArrayO AS ANY, NoOfVals%)
DECLARE SUB TrnsfrWarp (ArrayO AS .ANY, NoOfVals$)
DECLARE SUB TrtzsfrPath (aSourceArray, PathNo)
DEChARE SVB ShowObj (WcHobject, WchPose)
DECL,ARE StE DefnobjCntrs U
DECLARE S[JB ShowVJhllmage (WchPose, ShowColor)
DECLARE SUB ReCntrObj (WchObj, PtArray, CenterOfObjO AS t3DPoint)
DECLARE SUB MrkObjCntr (Message$, WchPose, WchObj)
DECLARE SUB HiLiLn (LnArrayO AS ANY, PtArray, LnNo)
DECLARE SUB IdentObjects O
DECLARE SUB IdentGroups ( )
DECLARE SUB GetPts (PtArray, PtArrayNdx)
DECLARE SUB BrsMnu O
DECLARE SUB GetStartFinish (LnLstO AS LineType, LnNo, Start, Finish)
DECLARE SUB TrnsfrTmpTolmPartA (WchPose)
DECLARE SUB ShowLn (WchPose, LnNo, ShowColor)
DECLARE SUS LdLsiLnArrays (WchPose, Col)
DECLARE SUB DrawABCDIm
DECLARE SUB EnterRawPt (Ptindex)
DECLARE SU8 LdLnLst (ArrayO AS LineType, WchPose, Col)
DECLARE SUB Mrk (Kind, FlatStereo)
DECLARE SUB ShowCrsr O
DECLARE SUS Drawlmg (WchPose)
DECLARE SUB CrsrOn O
DECLARE SUB MkMrkrs O
DECLARE SUB OldSmooth (RuffPtsO AS t3DPoint, SmoothPtsO AS t3DPoint,
SmoothRange)
*****"*****'~**"***********"********* General Utility Routines
DECLARE FUNCTION Confirm% (aQuestion$)
DLCL;ARE F[A4CTION UserChoice% (Text$, A$, B$, C$, D$, E$)
DECLARE SUB WaitForClick O
DECLARE FUNCTION Limits! (x!, L!, H!)
DECLARE FUNCTION GetA% (PageNo%, Index%)
DECLARE FUNCTION GetAReal! (PageNo%, Index%)
DECLARE SUB SetA (PageNo$, index$, Value%)
************************************ Velocity Graph Routines
DECLARE SUB DoVelocityGraph (aDrawnPath, aFramePosArray, Text$)
DECLARE SUB DrawVelGraph (aDrawnPath, aFramPosArray)
DECLARE SUB GetVelGraphFromPatth (aDrawnPath)
DECLARE SUB GetVelGraphFromUser (aDrawnPath)
DECLARE SUB CalcFramePosit'ions (aDrawnPath$, aFran-ePosArray$)
DECLARE FUNCTION DistToNextPoint! (aArray%, aPointlndex%)
= ************************************ Interface with Sandde 6
DECLARE SUB WriteKF'erInfo (C%, P%, x!, y!, Z!)

CA 02483943 2004-11-16
- 50 -
= ************************************ Low-level Drawing Routines
DECLARE SUB Draw3DPoint (aPoint AS t3DPoint, aColor AS INTEGER)
DECLARE SUB Draw3DLine (aPointl AS t3DPoint, aPoint2 AS t3DPoint,
aColor AS INTEGER)
DECLARE SUB DrawArray (aArrayt-, aColor9b, aUseLines$)
DECLARE SUB DrawPartialArray (aArray%, aStartB, aFinish%, aColor%,
aUseLines$)
COMMON SHARED LastLX, LastRX, LastY, LnNo, lastlmrkx, lastrmrkx,
lastmrky
CuNII4ON SHARED FrstLn, GroupsDefnd, NoOfLirnes, NoOfGroups
CQMHION SHARED ObjectsDefnd, NoOfObjects, NoOfSortedSyncPts, ImOK
COMMON SHARED NoOfFrames, Interval!, Operation, TransOK, WchGrp;
MtchPtsOK
CONASON SHARED NoOfMtchPts, NoOfSegs, NolnSrs, TotalSegsLen, WarpNo,
AvllnfArr
ComON SHARED TransGrfValsOK, A$, B$, C$, D$, E$, Ans$, UsesPrevPath,
Delay
COMMON SHARED FoundIt, ThisOne, Wx, Wy, Wz, OneFrameOnly, PtPosit,
GrfValsOK
COMMON SHARED Al1MtchPtsOK, OneSetChosen, WchLine, ObjectsNamed
COMMON SHARED MkLineLoop$, LinesToDraw, LineColor, GroupsNamed,
AdjustTestFrame
COMMON SHARED WaveLen, WaveWarp, WaveNo, Xcenter,. Ycenter, PathError
COMMON SHARED Range, LeftBound, Topbound, RightBound, BottomBound,
NoOfVelcros
COMMON SHARED Magnified, SyncPtlndex, WarpsNamedOK, NoOfWarps
COMMON SHARED NoOfScaffoldPts, G1ueLoopsYN, SegsOK, SumSegLen, RepeatA ...
COMNON SHARED FindLngstSegOK, JustifiedOK, WarpsOK, ObjCntrsOK,
WaveSpeed
COMMON SHARED DrawAPoseOK, DrawBPoseOK, DrawCPoseOK, DrawDPoseOK,
WchPoseForHili
COMMON SHARED Av1PthOnEntryToWarp, ChoicelnSegHil'i, Wchseg, SaveThisRun
COMMON SHARF,D ZPlane, Spacer, NoOfPathRefPts, ZFixed
COMMON SHARED WchObj, FrameNo, NoOfColors, Scaffold, SaveName$,
DoneMtchPts
COMMON SHARED WaveRefStart AS t3DPoint, WaveRefStid AS t3DPoint,
AbortMatchPt
CONd+SON SHARED DeleteAllButPreviouslmage, A11PosesSameAsA, NoOfAncRuns
CCMMbN SHARED LinkingToPreviousRun, EndFrameOfPrevRun, RunName$,
ColoredOK
COrMN SHARED PathMaster, Copycat, DuplicatePath, GlueLoops, Zoom!,,
ReUsingPoseAOnly
CCIMMON SHARED WchPoseForMag, NormalInn, MagLinesToDraw, ReferenceFrame,
UsingRefObject
'$DYNAMIC
DIM SHARED SpaceRef(10) AS SpaceRefPt
DIM SHARED FoundPt AS t3DPoint
DIM SHARED InRegs AS RegType, OutRegs AS RegType
DIM SHARED XYZ AS t3DPoint
DIM SHARED LXFtXY AS SterType, LastLxiZXY AS SterType
DIN! SHARED MrkrPts AS SterType, LastMrkrPts AS SterType
DIIK SHARED LCrsr ( 9, 9)

CA 02483943 2004-11-16
- 51 -
DIM SHARED RCrsr(9, 9)
DIM SHARED CtttrkL(9, 9)
DIM SHARED CmrkR(9, 9)
DIM SHPRED SqmrkL(9, 9)
DIM SHARED SqmrkR (9, 9)
DiK SHARED TrmrkL (9, 9)
DIlm SHARED TrmrkR (9, 9)
Da4 SHARED CrossMrkL ( 9, 9)
DIM SHARED CrossMrkR(9, 9)
DIl+i SHARED TransferPt AS t3DPoint
DB+! SHARED LineLength(4, 75, 0)
DIM $IiARED ALnPlace(50, 1)
DY'M SHARSD.OtherLnPlace(50, 1)
D1M SHARED PtsToBeJoined(30)
DnI SHARED AncRun(10) AS AnchorRunType
DIM SHARED XLeverage AS SINGLE
DIM SHARED YLeverage AS.SINGLE
DIl4 SHARED ZLeverage AS SINGLE
DIlK SFMM XAdjust AS SINGLE
DIM SHARED YAdjust AS SINGLE
DIM SHARED ZAdjust AS SINGLE
DIM MagCenter AS t3DPoint
DIN! ScreenCenter AS t3DPoint
DIM MagDiff AS t3DPoint
EMSinit EMSPagesRequired, Result
IF Resul t<> 0 THM
PRINT "Unable to allocate EMS memory, Error Code :"; IiEX$(Result)
STOP
ENDIF
StartAgain:
RESTORE
REDIM SHARED TPts(8) AS t3DPoiznt
TPts(1).x = 105
TPts(2).x = 276
TPts(3).x = 455
TPts(4).x = 280
TPts(1).y = 341
TPts(2).Y = 36
TPts(3).y = 338
TPts(4).y = 188
TPts(l).Z = -51
TPts(2).Z = -51
TPts(3).Z = -51
TPts(4).Z = 253
REDIM SHARED MBXVals(10)
DATA 12, 98, 140,226, 268, 354, 396, 482, 524, 610
'this is Wnd menu data
FORI=1TO10
READ MBXVals (I) ' menuboxocval s
NE XT
LeftBound = 5: Topbound = 5: RightBound = 634: BottomBound = 344

CA 02483943 2004-11-16
- 52 -
NoOfColors = 1
CONST LCol = 4: CONST RCol = 9:
CONST ZDivisor = 18
SCRF.E6i 9
COLAR 5
NkMrkrs
InitWand
OUT 888, 128+16+8+4+2
Pravide power for various things
128 : Drawing switch
64 = used for oscilliscope debugging
32 - used for oscilliscope debugging
16 - used for IR transmitter power
8 - used for IR transmitter powter
4 - used for IR transmitter power
2 - used for IR transmitter power
1 - Unused
CrsrOn
lLeverage = 10
YLeverage = 10
ZLeverage = 5
XAdjust = 150
YAdjust = 100
ZAdjust = -500 'minus moves cursor away from viewer
KEY(1) ON
ON HE7t(1) GOSUB ReduceXYZLeverage
KEY(2) ON
ON KEY(2) GOSUB IncreaseXYZLeverage
KEY ( 3 ) ON
ON IC;Y(3) GOSUB Norma7XYZLeverage
KEY(5) ON
ON Ia;i' ( 5) GOSUB Magni fyDrawSmg
KEY(7) ON
ON KEY(7) GOSUB NormalDrawlmg
KEY(8) ON.
ON IG;Y(8) GOS[7B ZShiftNormal
KEt(11) ON
ON IU;Y (11) GOSUB Shi f tUp
KEY(12) ON
ON KEY(12) GOSUB ShiftLeft
KEY(13) ON
ON XEY(13) GOSUS ShiftRight
KESt (14 ) ON

CA 02483943 2004-11-16
- 53 -
ON KEY(14) GOSUB ShiftDown
XZY (30) ON
ON XEY(30) GOSUB ZCloser
KEY(31) ON
ON KEY(31) GOSUB ZFarther
KEY (1) ON
ON IC;Y(10) GOSUB ZShiftNormal
ReUsingPoseAOnly = False
ReUsingPoses = False
SavingPoses = False
Normallm = True
DeleteAllButPreviousImage = True
Operation = 0
DO
EnterLoop:
SELECT CASE Operation
CASE 0
SetArrayReal APtsXPg, 0, 0
SetArrayReal BPtsXPg, 0, 0
SetArrayReal CPtsXPg, 01 0
SetArrayReal DPtsXPg, 0, 0
SetArrayReal RawPtsXPg, 0, 0
SetArrayReal TempPtsXPg, 0, 0
SetArrayReal APtsYPg, 0, 0
SetArrayReal BPtsYPg, 0, 0
SetArrayReal CPtsYPg, 0, 0
SetArrayReal DPtsYPg, 0, 0
SetArrayReal RawPtsYPg, 0, 0
SetArrayReal TernpPtsYPg, 0, 0
SetArrayReal APtsZPg, 0, 0
SetArrayReal BPtsZPg, 0, 0
SetArrayReal CPtsZPg, 0, 0
SetArrayReal DPtsZPg, 0, 0
SetArrayReal RawPtsZPg, 0, 0
SetArrayReal TempPtsZPg, 0, 0
SetA APtsXPg, 0, 0
SetA BPtsXPg, 0, 0
SetA CPtsXPg, 0, 0
SetA DPtsXPg, 0, 0
REDIM SHARED ALns(75) AS LineType
REDIM SIiARED BLns(75) AS LineType
REDIM SHARED CLns(75) AS LineType
REDIM SHARED DLns(75) AS LineType
REDIM SHARED Group(5) AS GroupType
REDIM SHARED Object(3) AS ObjectType
REDIM SHARED AObjCntr(3) AS t3DPoint
REDIM SHARED AGrpCntr(5) AS t3DPoint
REDIM SHARED MtchPts(50, 7)
REDIM SHARED TempSegs(105) AS TempSegType

CA 02483943 2004-11-16
- 54 -
REDIN! SHARED ObjFinalPositions(5) AS ObjectFinalPositType
DIM SHARED Transferinfo AS TransferType
ON ERROR GOTO ErrorHandler
NoFiles = False: saveThisRun = False
LinkingToPreviousRun = False
NameOK = False
UsingRecordedPoses = False
ReUsingPreviousPoses = False
SELECT CASE UserChoice("3D Or FLAT?", "", "3D', "", "Flat"-, "")
CASE 2
ZFixed = False
CASE 4
ZFixed = True
END SELECT
CLS
IF Confiztn("Link To Previous Run?") THEN
LinkingToPreviousRun =.True
PrevLinkOK = False
WHILE NOT PrevLinkOK
CLS
FILES "k:\Projects\Imax\Rt,veeny\Pau1\*.tws"
PRINT "Listed Above Are The Records Of The LAST
(CONSTRUCTED) POSE Of Previous Runs"
IF NoFiles = True THEN
PRINT "No Files"
LinkingToPreviousRun = False
ELSE
INPUT "Name Of Run To Be ADDED To (Do NOT Include TWS
in Name)"; NameOfPreviousLink$
CLS
OPEN "k:\Projects\Imax\Tweeny\Paul\" + NameOfPreviousLink$
+ ".tws" FOR BINARY AS #1
GET #1, , NoOfPts
SetA APtsXPg, 0, NoOfPts
FOR I = 1 TO NoOfPts
GET #1, , SXVa1C: SetArrayReal APtsXPg, I, SXVal!
GET #1, , SYVa1!: SetArrayReal APtsYPg, I, SYVal!
GET #1, , SZVa1!: SetArrayReal APtsZPg, I, SZVa1!
NEXP
DrawPartialArray APtsXPg, 1, GetA(APtsXPg, 0), -1, False
PRINT "End Pose(s) Of "; NameOfPreviousLink$; ":"
PrevLinkOK = False
IF Confirm("End Pose(s) Of Correct Previous Link?") THEN
PrevLinkOK = True
WHILE NOT NameOK
PRINT "Previous Link: "; UCASE$(NameOfPreviousLink$)
INPUT "Name For This Link (Same As Previous, But With
Incremented Link No)"; RunName$
IF Confirm("Is "+ UCASE$(RunName$) + " Correct Name
For Link You Are About To Make?") THEN
NameOK = True
PoseSave$ = RunName$
END IF

CA 02483943 2004-11-16
- 55 -
WEND
ELSE
CLOSE #1
SetArrayReal APtsXPg, 0, 0
SetA APtsXPg, 0, 0
END IF
END IF
WEND
IF LinkingToPreviousRun = True TfM
CLS
PRINT "Retrieving Constructed End Pose(s) Of ";
UCASE$(NameOfPreviousLink$)
PRINT
PRINT "Nlatch Points Of Previous Link Were Not Saved"
SLEEP 2
GET #1, , NoOfLines
FOR I = 1 TO NoOfLines
GET #1, , ALns(I)
NEXT
ALns(0).Beg = NoOfLines
GET #1, , NoOfGroups
FOR I = 1 TO NoOfGroups
GET #1, , Group(I)
NEXT
GET #1, , NoOfObjects
FOR I = 1 TO NoOfObjects
GET #1, Object(I)
NEXT
FOR I = 1 TO NoOfObjects
GET #1, , AObjCntr(I)
NEXT
FORI=1T05
GET #1, , ObjFinalPositions(I)
NEXT
GET #1, , EndFrameOfPrevRun
CLOSE #1
FOR I = 1 TO NoOfLines
ALns(I).Intermit = False
ALns(I).KeyForm = 0
ALns(I).Threshold = 0
NEXT
END IF
END IF
FOR I 1 TO NoOfLines 'in case using prev poses
IF ALns(I).Looped = 1 THEN GlueLoops = True
NEXT
IF LinkingToPreviousRun = False THEN
SELECT CASE UserChoice("This Run For Experiment/Practise OR
To Keep?", "", "Expr/Prac", "To Keep", "", "")
CASE 2
RunName$ = "Exprimnt"
CASE 3
WHILE NOT NameOK
INPUT "Name For This Run (8 characters including link

CA 02483943 2004-11-16
- 56 -
no if any)"; RunName$
PrevFileTest$ = "k:\Projects\Imax\Tweeny\Paul\" +
LEFT$(RunName$, 2) + "*.TGJS"
FILES PrevFileTest$
IF NoFiles = True THEN
NameOK = True
ELSE
PRINT "Name Not Allowed; First Two Letters Duplicate
Existing File(s) Shown"
IF Confirm("Override?") THEN NameOK,= True
END IF
WETID
END SELECT
PoseSave$ = UCASE$(RunName$)
IF Confirm("Use A Previously Recorded Set Of Source Poses?") THM
.CLS
FILES "k:\Projects\7max\Tweeny\Paul\*.POS"
PRINT "Listed Above Are The Previously Recorded Sets Of Poses"
INPUT "Use Which Set (Do Not Enter .POS)"; OldPoseRetrieve$
IF OldPoseRetrieve$ _"ex" OR OldPoseRetrieve$ ="Ex" THM
O1dPoseRetrieve$ _ "Exprimnt"
UsingRecordedPoses = True
ReUsingPreviousPoses = True
ReUsingPoses = True
ELSE
ReUsingPreviousPoses = False
END IF
END IF
SaveThisRun = True
CLS
Operation = 1
CASE 1 'run length
IF LinkingToPreviousRun = False THEN CLS
IF ReUsingPoses = True THM CLS
NoOfFramesOK = False
WHILE NoOfFramesOK = False
LOCATE 2, 1: INPUT "Length Of Run In Frames (Playback is at
24 fps)"; NoOfFrames
Interval! = 570 / (NoOfFrames - 1)
IF NoOfFrames > 0 THM
LOCATE 3, 1: PRINT "Run Will Be"; NoOfFrames;
"Frames Long --Is That Correct?"
IF Confirm("") TMM NoOfFramesOK = True
ELSE
PRINT "You Must Eshter The No Of Frames Wanted": SLEEP 1
END IF
FOR I= 1 TO NoOfObjects
Object(I).StartVis = 1
Object(I).EndVis = NoOfFrames
NEXT
CLS

CA 02483943 2004-11-16
- 57 -
tn1F,ND
IF UsingRecordedPoses = True TON
NormalIm =True
IF ReUsingPreviousPoses = True THN GetPose$ = OldPoseRetrieve$
PRINT "Retrieving Source Poses Of "; UCASE$(GetPose$)
PRINT
PRINT "Reminder: Match Points (If Any) Of These Source Poses
Were Saved"
SLEEP 4
OPEN "k:\Projects\Imax\Tweeny\Paul\" + GetPose$ + ".POS"
FOR BINARY AS #3
GET #3, , NoOfAPts
GET #3, , NoOfBPts
GET #3, , NoOfCPts
GET #3, , NoOfDPts
SetA APtsXPg, 0, NoOfAPts
SetA BPtsXPg, 0, NoOfBPts
SetA CPtsXPg, 0, NoOfCPts
SetA DPtsXPg, 0, NoOfDPts
FOR I= 1 TO NOOfAPts
GET #3, , SXVal!: SetArrayReal APtsXPg, I, SXVal!
GET #3, , SYVal!: SetArrayReal APtsYPg, I, SYVal!
GET #3,., SZVal!: SetArrayReal APtsZPg, I, SZVal!
NEX2'
FOR I = 1 TO NoOfBPts
GET #3, , SXVal!: SetArrayReal,BPtsXPg, I, SXVal!
GET #3, , SYVal!: SetArrayReal BPtsYPg, I, SYt7a1!
GET #3, , SZVal!: SetArrayReal BPtsZPg, I, SZVal!
NEXT
FOR I 1 TO NoOfCPts
GET #3, , 3XVa1!: SetArrayReal CPtsXPg,'I, SXVal!
GET #3, , SYVal!: SetArrayReal CPtsYPg, I, SYVal!
GET #3, , SZVal!: SetArrayReal CPtsZPg, I, SZVal!
NEXT
FOR I= 1 TO NoOfDPts
GET #3, , SXVal!: SetArrayReal DPtsXPg,.I; SXVal!
GET #3, , SXVal!i SetArrayReal DPtsYPg, I, SYVal!
GET #3, , SZVal!: SetArrayReal DPtsZPg, I, SZVal!
NEXT
GET #3, , NoOfLines
FOR I = 1 TO NoOfLines
GET #3, , ALns(I)
GET #3, , BLns(I)
GET #3, , Chns(I)
GET #3, , DLns(I)
NEXT
ALn.s(0).Beg = NoOfLines
GET #3, , NoOfMtchPts
FOR I = 1 TO NoOfMtchPts
FORJ= 0 TO 7
GET #3, , MtchPts(z, J)
NEXT
NEXT
GET #3, , NoOfGroups
FOR I = 1 TO NoOfGroups

CA 02483943 2004-11-16
- 58 -
GET #3, , Group(I)
NEXT
GET #3, , NoOfObjects
FOR I = 1 TO NoOfObjects
GET #3, , Object(I)
NEXT
CLOSE #3
FOR I = 1 TO NoOfLines 'in case using prev poses
IF ALns(I).Looped = 1 THEN GlueLoops = True
NEXT
DefnGrpsObjsOK = False
GroupsDefnd = False: GroupsNamed = False: ObjectsDefnd = False
ColoredOK = False
ObjCntrsOK = False
SegsOK = False
Operation = 4 '(grps/objs)
ELSE
Operation = 2
EAID IF
CASE 2 'glue loops yesno
WHILE SetUpGlueLoopsOK = False
SetUpGlueLoops
SetUpGlueLoopsOK = True
DrawAPoseOK = False
WEND
Operation = 3
CASE 3 'drawAPose
WHILE DrawAPoseOK = False
IF LinkingToPreviousRun = False AND
UsingRecordedPoses = False THEN
DrawingImage = True
SetA APtsXPg, 0, 0
SetA BPtsXPg, 0, 0
SetA CPtsXPg, 0, 0
SetA DPtsXPg, 0, 0
SetA RawPtsXPg, 0, 0
SetA TenmpPtsXPg, 0, 0
DeleteAllButPreviouslmage = True
Norma].Im = True
DrawAPose
IF NOT Normallm THM GOSUB NormalDrawlmg
EISE
FOR I= 1 TO NoOfLines
DrawPartialArray APtsXPg, ALns(I).Beg, ALns(I).Fin, -1, True
NEXT
END IF
DeleteAllButPreviouslmage = True
DrawAPoseOK = True
MkScaffoldOK = False
DrawBCDPosesOK = False
DrawBPoseOK = False
DrawCPoseOK = False
DrawDPoseOK = False
DefnGrpsObjsOK = False

CA 02483943 2004-11-16
- 59 -
GroupsDefnd = False: GroupsNamed = False: ObjectsDefnd = False
ColoredOK = False
ObjCntrsOK = False
SegsOK = False
WEND
Operation = 4
CASE 4 'defri grps objs
IF ReUsingPoses = True OR LinkingToPreviousRun = True THEN
IF Confirm("Redo Groups And Objects Assignments Made In Previous Source
Poses Or Link?") THEN
DefnGrpsObjsOK = False: GroupsDefnd = False
GroupsNamed = False: ObjectsDefnd = False
ObjectsNamed = False
NoOfGroups = 0: NoOfObjects = 0
ELSE
DefnGrpsObjsOK = True: GroupsDefnd = True
GroupsNamed = True: ObjectsDefnd = True: ObjectsNamed = True
E6ID . IF
ELSE
DefnGrpsObjsOK = False
F.ND IF
WHILE DefnGrpsObjsOK = False
CLS
GroupsDefnd = False: GroupsNamed = False
ObjectsDefnd = False: ObjectsNamed = False
NoOfGroups = 0: NoOfObjects = 0
DefnGrpsObjs
IF NoOfLines > 1 THEN
FOR I = 1 TO NoOfGroups
CLS
FOR J = 1 TO NoOfLines
IF ALns (J) .WchGrp = I THM SkiowLn 1, J, -1
NEXT
Text$ = "These Lines Make Up Group "+ Group(I).Label +"?~
DefnGrpsObjsOK = Confirm(Text$)
NEXT
IF DefnGrpsObjsOK THErI
FOR I = 1 To NoOfObjects
CLS
FOR J= 1 TO NoOfLines
IF ALns(J).WchObj = I THEN ShowLn 1, J, -1
NEXT
Text$ ="These Lines Make Up Object + Object(I).Label +
DefnGrpsObjsOK = Confirm(Text$)
NEXT
END IF
ELSE
DefnGxpsobjsOK = True
EDID IF
WmQD
IF ReUsingPoses = True THEN
IF Confirm("ReDraw B C D Source Poses Even Tho Using Previous
Source Poses? ") TFMN,
ReUsingPoses = False
ReUsingPoseAOnly = True

CA 02483943 2004-11-16
- 60
-
DrawBCDPosesOK = False
DrawBPoseCK = False
DrawCPoseOK = False
DrawDPoseOK = False
ColoredOK = False
ObjCntrsOK = False
SegsOK = False
SetArrayReal BPtsXPg, 0, 0
SetArrayReal CPtsXPg, 0, 0
SetArrayReal DPtsXPg, 0, 0
SetArrayReal RawPtsXPg, 0, 0
SetArrayReal TempPtsXPg, 0, 0
SetA BPtsXPg, 0, 0
SetA CPtsXPg, 0, 0
SetA DPtsXPg, 0, 0
REDIM SHARED BLns(75) AS LineType
REDII4 SfIARED CLns ( 75 ) AS LineType
REDIM SHARED DLns(75) AS LineType
END IF
END IF
IF ReUsingPoses = True THEN
Operation = 7
SegsOK = False
FindLngstSegOK = False
JustifiedOK = False
AllMtchPtsOK = False
ELSE
Operation = 5
END IF
CASE 5 'scaffold yesno
WHILE MkScaffoldOK = False
REDIM SHARED AScaffoldCntr(l) AS t3DPoint
REDIM SHARED BScaffoldCntr(1) AS t3DPoint
REDIM SHARED CScaffoldCntr(1) AS t3DPoint
REDIM SHARED DScaffoldCntr(1) AS t3DPoint
REDIM SHARED ScaffoldDisp(50) AS t3DPoint
REDIM SHARED ImDrawingCentrDisp(4) AS t3DPoint
MkScaffold
MkScaffoldOK = True
wFM
Operation = 6
CASE 6
WHILE DrawBCDPosesOK = False
Normalim = True
DrawBCDPoses
IF NOT Normallm RHF,,N GOS[TB NornialDrawlmg
DrawBCDPosesOK = True
SegsOK = False
FindLngstSegOK = False
JustifiedOK = False
AllMtchPtsOK = False
VVEND
IF Operation = 2 T'FM

CA 02483943 2004-11-16
- 61 -
DrawAPoseOK = False
A11PosesSameAsA = False
SetUpGlueLoopsOK = False
CLS
ELSE
Drawingimage = False
Operation = 7
END IF
CASE 7 'colorit plus mtchpts
IF GlueLoops = True THM
IF ReUsingPoses = True OR LinkingToPreviousRun = True THM
IF Confirnt("Redo Painting?") THM Colorlt
ELSE
Colorlt
END IF
END IF
Operation = 77
CASE 77
WHILE AllMtchPtsOK = False
CLS
IF ReUsingPoses = True THEN
IF Confirm("ReDo Existing MatchPts (If Any)?") THEN
IF Confirm("Are You Sure You Want To Erase And ReDo
Existing MatchPts?") THM
REDIM SHARED MtchPts(50, 7)
PrevMtchPtsErased = True
CLS : MtchPtsPartl
CLS
IF Confirm("A1l MtchPts OK?") THFn1,AllMtchPtsOK = True
END IF
ELSE
Al1MtchPtsOK = True
om IF
ELSE
IF PrevMtchPtsErased = True TMN LOCATE 2, 1:
PRINT "PREVIOUS MATCH PTS ERASED!"
IF Confirm("Make MtchPts?") THEN
REDIM SHARED MtchPts(50, 7)
CLS : MtchPtsPartl
CLS
IF Confirm("All MtchPts OK?") TEM Al1MtchPtsOK = True
ELSE
NoMtchPts
AllMtchPtsOK = True
END IF
END IF
WIIJD
IF NOT Noxmallm THEN GOSUB NoxmalDrawIm:g
CLS
Operation = 777
CASE 777
PRINT "Saving Source Poses Of "; PoseSave$
OPEN "k:\Projects\Imax\TWeeny\Paul\" + PoseSave$ + ",POS" FOR

CA 02483943 2004-11-16
- 62 -
BINARY AS #3
ES"idOfAPts = GetA(APtsXPg, 0)
EndOfBPts = GetA(BPtsXPg, 0)
EndOfCPts = GetA(CPtsXPg, 0)
E7idOfDPts = GetA(DPtsXPg, 0)
PUT #3, , EndOfAPts
PUT #3, , FndOfBPts
PUT #3, EndOfCPts
PUT #3, , 8'ndOfDPts
FOR I = 1 TO EndOfAPts
XVa1! = GetAReal!(APtsXPg, I)
YVal! = GetAReal!(APtsYPg, 1)
ZVal! = GetARea1!(APtsZPg, I)
PUT #3, , XVal!
PUr #3, , YVal !
PUT #3, , ZVal!
NEXT
FOR i= 1 TO EndOfBPts
XVal! = GetAReal!(BPtsXPg, I)
YVal! = GetAReal!(BPtsYPg, I)
ZVal! = GetAReal!(BPtsZPg, I)
PUT #3, , XVal!
PUT #3, , YVal!
PUT #3, , ZVal!
NEXT
FOR I = 1 TO EndOfCPts
XVa1! = GetAReal!(CPtsXPg,I)
YVal! = GetAReal!(CPtsYPg, I)
ZVal! = GetAReal!(CPtsZPg, I)
PUT #3, , XVal!
PUT #3, , YVal!
PUT #3, , ZVal!
NECT
FOR I = 1 TO EndOfDPts
XVal! = GetAReal!(DPtsXPg, I)
YVal! = GetAReal!(DPtsYPg, I)
ZVa1! = GetAReal!(DPtsZPg, I)
PUT #3, , XVal!
PUT #3, , YVal!
PUT #3, , ZVal!
NEXT
PUT #3, , NoOfLines
FOR I = 1 TO NoOfLines
PiTP #3, , ALns (I)
PUT #3, , BLns(I)
PUT #3, , CLns(I)
PUT #3, , DLns(I)
NEXT
PUT #3, , NoOfMtchPts
FOR I = 1 TO NoOfMtchPts
FORJ= 0TO7
PUT #3, , MtchPts(I, J)
NEXP
NEXT
PUT #3, , NoOfGroups

CA 02483943 2004-11-16
- 63 -
FOR I= 1 TO NoOfGroups
PUT #3, , Group(I)
NEXT
PUT #3, , NoofObjects
FOR I = 1 TO NoOfObjects
PUT #3, , Object(I)
NEX't'
CLOSE #3
CLS
LOCATE 4, 1: PRINT "The Source Poses You Have Drawn Have Been
Saved, Under The Name "; PoseSave$
PRINT "Including Colors, Groups, Objects, and MatchPts"
PRINT
PRINT "You May Quit The Program If You Want To Do Only The Source
Poses Now"
IF Confirm("~uit Now?") THEN
IF Confirm("Are You Sure You Want To Quit Now?") THEN END
END IF
CLS
Operation = 8
CASE 8
SegsOK = False
WHILE SegsOK = False
PRINT "Making Segs..."
MkSegs
SegsOK = True
FindLngstSegOK = False
RFDIM SHARED SegLen(4)
REDIM SHARED LongestSeg(105, 1)
FindLngstseg
RED324 SHARED FinlSgs(105) AS FinlSglype
JstfyTempSegsPartA
TrnsfrWhlArray JAPtsXPg, APtsXPg
TrnsfrWhlArray JBPtsXPg, BPtsXPg
TrnsfrWhlArray JCPtsXPg, CPtsXPg
TrnsfrWhlArray JDPtsXPg, DPtsXPg
WarpsOK = False
SegsOK = True
WEND
Operation = 9
IF ReUsingPoses = True THF.N
ObjCntrsOK = False
ColoredOK = False
InstTransCheck = False
PosTransOK = False
AnchorPtsAllOK = False
WindOK = False
AvlPath = 0
WarpsNamedOK = False
NoOfWarps = 0
WarpsOK = False
END IF

CA 02483943 2004-11-16
- 64 -
CASE 9
WHILE ObjCntrsOK = False
REDIM SHARED BObjCntr(3) AS t3DPoint
REDIN SHARED CObjCntr(3) AS t3DPoint
REDIM SHARED DObjCntr(3) AS t3DPoint
REDIM SHARED BGrpCntr(5) AS t3DPoint
REDIbi SHARED CGrpCntr(5) AS t3DPoint
REDIM SHARED DGrpCntr(5) AS t3DPoint
DIM SHARED MarkedObjCntr AS t3DPoint
DIM SHARED MarkedGrpCntr AS t3DPoint
DefnObjCntrs 'includes grp cntrs
ObjCntrsOK = True
PosTransOK = False
InstTransCheck = False
4JF2'TD
Operation = 10
CASE 10
IF Confirm("Redo Some Of Source Poses? ") THEN
SELECT CASE UserChoice("ReDo Which Pose", "", "Bp, "L"'", "D", "")
CASE 2: DrawBPoseOK = False: REDIM SHARED BLns(75) AS
LineType: SetArrayReal BPtsXPg, 0, 0: SetA BPtsXPg, 0, 0
CASE 3: DrawCPoseOK = False: REDIM SHARED CLns(75) AS
LineType: SetArrayReal CPtsXPg, 0, 0: SetA CPtsXPg, 0, 0
CASE 4: DrawDPoseOK = False: REDIM SHARED DLns(75) AS
LineType: SetArrayReal DPtsXPg, 0, 0: SetA DPtsXPg, 0, 0
END SELECT
DrawBCDPosesOK = False
Operation = 6
ELSE
Operation = 11
mTD IF
CASE 11
Operation = 12
CASE 12
IF NOT AllPosesSameAsA TfEN
CLS
OneGroupExplored = False
WHILE InstTransCheck = False
REDIM SHARED TransGrftlal(0) AS TransType
REDIM SHARED TEnds(4) AS SterType
IF OneGroupFxplored = False THEN Ques$ = "Explore Actions
Available For Group(s) And Check For Line Reversals?"
ELSE Ques$ ="Explore Other Groups And Check For Line
Reversals?'
IF Confirm(Ques$) 'IHM
IF NoOfGroups > 1 THM
WchGrp = UserChoice("Which Group?", Group(1).Label,
Group(2).Label, Group(3).Label, Group(4).Label,
Group(5).Label)
ELSE
WchGrp = 1
END IF
IF ZFixed = True TFM
PRINT "PUT ON THE RED BLUE GLASSES TO USE THE

CA 02483943 2004-11-16
- 65
TETRAiIEDRON!"
SLEEP 2
ZFixedTempOff = True
ZFixed = False
FdJD IF
ScanPoseTrans 0, WchGrp, 0, 0
OneGroupExplored = True
ELSE
InstTransCheck = True
F.N!? IF
REDIM SHARED 7'Ends(0) AS Ster'Iype
IF ZFixedTempOff = True THEN
PRINT "TAKE OFF THE RED BLUE GLASSES!"
SLEEP 2
ZFixedTempOff = False
ZFixed = True
END IF
CLS
SCREIIV 9
COLOR 5
wEND
END IF
IF OneGroupEcplored = True THM
IF Confirm("Redo Source Poses? ") THEN
Operation = 2
SetUpGlueLoopsOK = False
DrawAPoseOK = False
A1lPosesSameAsA = False
ELSE
IF Confirm("Swap Direction Of A Line?") THEN
SwapLineDirection
AllMtchPtsOK = False
InstTransCheck = False
LOCATE 3, 1: PRINT "NOTE: You Will Have To Redo Any
MatchPts You Have Made": SLEEP 2
Operation = 77
F.LSE
Operation = 13
ETID IF
END IF
EL9E
Operation = 13
EUID IF
CASE 13
VelcrosOK = False
REDIM SHARED VelcroAGrp(4) AS VelcroType
WHILE VelcrosOK = False
IF NoOfGroups > 1 THEN
IF Confirm("Any Group Velcroed To Another Group?") THEN
Velcro
IF Confirm("A11 Velcros OK?") THEN VelcrosOK = True
ELSE
VelcrosOK = True
EM IF

CA 02483943 2004-11-16
- 66 , .
ELSE
VelcrosOK = True
E[QD IF
tnTEND
Operation = 14
CASE 14 'does obj paths, and transform graphs for all groups
of the object
WHILE PosTransOK = False
SyncPtlndex = 0
REDIM SHARED ObjectStatPos(3) AS t3DPoint
REDIM SHARED PathRefPt(30) AS RefPtType
REDIM SHARED syncpts(30) AS RefPtType
REDIM SHARED SortedSyncPts(30) AS RefPtType
REDIM SHARED TerminalPoint(1) AS t3DPoint
REDIM SHARED FrmToFrmVelocity!(NoOfFrames)
REDIM SHARED TEnds(4) AS SterType
REDIM SHARED TransGrfVal(NoOfFrames) AS TransType
DIlK SHARED Al1SumdPt. AS t3DPoint
DIM SHARED ObjPathPosit AS t3DPoint
DIM SHARED AllProp AS TransType
Av1Pth = 0
SyncPtIndexAfterEachObjMoveAndTrans = SyncPtIndex
FOR I = 1 TO NoOfObjects
NoOfGroupsForThisObj = 0
FOR q= 1 TO NoOfGroups
IF Group(q).WchObj = I THEN NoOfGroupsForThisObj =
NoOfGroupsForThisObj + 1
NEXT
ThisObjMoveAndGrpTransOK = False
WHILE NOT ThisObjMoveAndGrpTransOK
SyncPtIrndex = SyncPtIndexAfterEachObjMoveAndTrans
SPIAfterEachObjMove = SyncPtZndex
IF I <> Copycat THEN
DO
PathError = False
DO 'making obj path
SyncPtlndex = SPIAfterEachObjMove
CLS
IF NoOfObjects > 1 AND I > 1 THEN
Text$ ="See A Frame Of Path+Action Of A Prev Obj
As Ref For Drwng Path Of "+
Object(I).Label + " ?"
IF Confixm(Text$) TFM
UsingRefObject = True
IF NoOfObjects = 3 THEN
SELECT CASE UserChoice("Which Object?",
Object(1).Label, Object(2).Label,
CASE 1:,RefObj = 1
CASE 2: RefObj = 2
END SELECT
ELSE
RefObj = 1
END IF
IF NoOfGroups > 1 THEN
RefGrpOK = False
WHILE NOT RefGrpOK
SELECT CASE UserChoice("Which Group?",

CA 02483943 2004-11-16
- 67 -
Group(1).Label, Group(2).Label,
Group(3).Label, Group(g).Label,
Group(5).Label)
CASE 1: RefGrp = 1
CASE 2: RefGrp = 2
CASE 3: RefGrp = 3
CASE 4: RefGrp = 4
CASE 5: RefGrp = 5
END SELECT
IF Group(ItefGrp).WchObj <> RefObj THW
BEEP: LOCATE 2, 1
PRINT Group(RefGrp).Label; " Does Not
Belong To '; Object(RefObj).Label
SLEEP 2
LOCATE 2, 1: PRINT SPACE$(70)
ELSE
RefGrpOK = True
END IF
Wmm
. . . . .
ELSE
RefGrp = 1
END IF
WndPtScan RefObj, Obj2, RefGrp, Grp2, 0,
NoOfFrames, MarkType, eScanGrpTransPlusPath
END IF
END IF
WchObj = I
MarkSpaceRefPts
WchObj = I
IF LinkingToPreviousRun = True TEM
FORP=ITO5
SELECT CASE I
CASE 1: XYZ = ObjFinalPositions(P).
FinalPositdbji: Mrk 0, 1
CASE 2: XYZ = ObjFinalPositions(P).
FinalPositObj2: Mrk 0, 1
CASE 3: XYZ = ObjFinalPositions(P).
FinalPositObj3: Mrk 0, 1
ELVD SELECT
SE'LECT CASE I
CASE 1: XYZ = ObjFinalPositions(1).
FinalPositObjl: Mrk 1, 1
CASE 2: XYZ = ObjFinalPositions(1).
FinalPositObj 2: 2+trk 1, 1
CASE 3: XYZ = ObjFinalPositions(1).
FinalPositObj3: Mrk 1, 1
END SELECT
NEXT
LOCATE 2, 1: BEEP
PRINT "This Is End Of Path For"; Object(i).Label;
"in Previous Run (Square Is End)"
PRINT "Start Of Next Path Will Automatically Be
Matched To This": SLEEP 4
END IF
AvlPth = AvlPth + 1
Object(I).PathNo = AvlPth
DO
CL..S
IF UsingRefObject = True THEN
ShowGrpTranslnPathPosit RefObj, RefGrp, 0,

CA 02483943 2004-11-16
- 68 -
ReferenceFrame
ShowSpaceRefPts
MkUniPath Object(I).Label, eObjPath
DrawArray TetspPtsXPg, -1, True
WndPtScan'I, Obj2, 1, Grp2, TempPtsXPg,
GetA(TempPtsXPg, 0), 1, eObjPathOnTempPts
LOOP UNTIL Confirm("Path In Space OK?")
IF LnF.ndsClose(TempPtsXPg, 1, GetA(TempPtsXPg, 0),
15) THEN MkPathCycle
IF.LinkingToPreviousRun = True THEN
PathShiftToMatchPrevRun I
CLS
DrawPartialArray TempPtsXPg, 1, GetA(TempPtsXPg, 0),
-1, True
SELECT CASE UserChoice("Put Sync Pts On Path
In Space?", "", "On Path", "On Fr Chrt",
"No"
.
CASE 2 'on path
WchObj = I
ShowSpaceRefPts
P1aceSyncPtsOnTempPath 1, I; "Mrk Velocity
Control Reference Pts On Space Path Of
+ Object(I).Label
SortSyncPtsForApplic 1, I
SwapSortedSyncPts
CASE 3 'on frm chrt
ShowSyncPtLines SyncPtlrndexAtStartOfObjMove
PlaceSyncPtsOnFrmChrt 1, I, "Mrk Position/Timing
Sync Pts For Space Path Of" +
Object(I).Label
SortSyncPtsForApplic 1, I
SwapSortedSyncPts
DrawArray TempPtsXPg, -1, False
PlaceFrmChrtSyncPtsOnPath 1, 1
CASE 4
SortSyncPtsForApplic 1, I
SortedSyncPts(1).Frame = 1
SortedSyncPts(1).TempPtsIndex = 1
SortedSyncPts(2).Frame = NoOfFrames
'this Mks last SortedSyncPts(syncpt) end
of transform tetra graph
SortedSyncPts(2).TempPtslndex =
GetA(TempPtsXPg, 0)
END SELECT
DO
CLS
DrawArray TempPtsXPg, -1, False
Smooth TempPtsXPg, TempPts2XPg, 2, False
Text$ = "Graph Of Speed Of Movement Of "+
Object(I).Label +" Along Path In Space"
DoVelocityGraph TempPts2XPg, RawPtsXPg, Text$
IF PathError = True TFM EXIT DO
CLS
ShowSpaceRefPts
fnindPtScan I, Obj2, 0, Grp2, RawPtsXPg,

CA 02483943 2004-11-16
-69-
GetA(RawPtsXPg, 0), 1, eObjPathByFrms
LOOP UNTIL Confirm("Speed Of Movement Along Space
Path OK?")
IF PathError = True TIiM EXIT DO
IF Confirm("Space Path Itself OK?") THEN
SPlAfterEachObjMove = SyncPtlndex
EXIT DO
ELSE
AviPath = AvlPath - 1
END IF
LOOP 'mking obj path
LOOP WHILE PathError = True
TrnsfrPath RawPtsXPg, Av1Pth
ELSE 'is a copycat object
Object(I).PathNo = PathMaster
END IF
'TRANSFORM
SPlAfterEachTrans = SyncPtlndex
FOR J = 1 TO NoOfGroups
PathError = False
ThisGrpTransOK = False
Grp2 = 0
IF Group(J).WchObj = I THM
DO
ControlGraphOutOfRange = False
DO
SyncPtIndex = SPlAfterEachTrans
IF J = 1 THEN REDIM SHARED Transi(NoOfFrames) AS
TransType
IF J = 2 THETT REDIM SHARED Trans2(NoOfFrames) AS
TransType
IF J = 3 TON REDIM SHARED Trans3(NoOfFrames) AS
TransType
IF J = 4 TMW FZEDIM SHARED Trans4(NoOfFrames) AS
TransType
IF J = 5 THEA7 REDIM SHAIM TransS (NoOfFrames) AS
TransType
CLS
IF AllPosesSameAsA THEN
A1lPosesAreA
IF J = 1 THEN TrnsfrProp TranslO, NoOfFrames
IF J = 2 THEN TrnsfrProp Trans2O, NoOfFrames
IF J = 3 THEN TrnsfrProp Trans3O, NoOfFrames
IF J = 4 THE[J TrnsfrProp Trans4 O, NoOfFrames
IF J = 5 THEN TrnsfrProp.Trans5O, NoOfFrames
ELSE
CLS
WchObj = I
WchGrp = J
Grp2 = 0
IF ZFixed = True THEN
PRINT "PUT ON THE RED BLUE GLASSES TO USE THE
TE'TRAHEDRON!"
SLEEP 2
ZFixedTempOff = True
ZFixed = False
END IF

CA 02483943 2004-11-16
- 70 -
DO
CLS
MkUniPath Group(J).Label, eTScript
IF LnEndsClose(Te.mpPtsXPg, 1, GetA(TempPtsXPg,
0), 15) THErT MkPathCycle
CLS
DrawArray TempPtsXPg, -1, True
WndPtScan I, Obj2, J, Grp2; TempPtsXPg,
GetA(TenpPtsXPg, 0), 1,
eScanTransOnTempGraph
LOOP UNTIL Confirm("Action Control Graph
Looks OK?")
DO
CLS
DrawArray TempPtsXPg, -1, True
SyncPtIndex = SPlAfterEachTrans
CL8
DrawPartialArray TempPtsXPg, 1,
GetA(TempPtsXPg, 0), -1, True
SELECT CASE UserChoice("Use Sync Pts On Action
Control Graph?", "", "On Path",
"On Fr Chrt", 'No",
CASE 2 'on path
PlaceSyncPtsOnTempPath 2, J, "Mark
Timing/Transform Sync Pts For
Transform Graph Of +
Group(J).Label
SortSyncPtsForApplic 2, J
SwapSortedSyncPts
CASE 3 'on frm chrt
ShowSyncPtLines SyncPtIndexAtStartOfTrans
PlaceSYncPtsOnFrmChrt 2, J, "Mark
Timing/Transform Sync Pts For
Transform Graph Of " +
Group(J).Label
SortSyncPtsForApplic 2, J
SnrapSortedSyncPts
DrawArray TempPtsXPg, -1, False
PlaceFrmChrtSyncPtsOnPath 2, J
CASE 4
Sort3yncPtsForApplic 2, J
SortedSyncPts(1).Frame = 1
SortedSyncPts(1).TempPtsIndex = 1
Sorted.~~ncPts (2 ) . Frame = NoOfFrames
this Mks last SortedSyncPts(syncpt)
end of transform tetra graph
SortedSyncPts(2).TempPtsIndex =
GetA(TempPtsXPg, 0)
END SELECT
LOOP UNTIL Confirm("SyncPt Placement (Or Not
Using SyncPts) OK?")
IF ZFixedTempOff = True THM
PRINT "TAKE OFF THE RED BLUE GLASSES!"

CA 02483943 2004-11-16
- 71 -
SLEEP 2
ZFixedTempOff = False
ZFixed = True
END IF
DO
Grp2 = 0
Text$ _"Graph Of Speed Of Progression Of
Action Of " + Group(WchGrp).Label
DoVelocityGraph TempPtsXPg, RawPtsXPg, Text$
IF CalcTetFxms TMN
Done = True
ELSE
CLS
PRINT "Your Control Graph has some points
too far outside Tetrahedron - please redo"
BEEP
ControlGraphOutOfRange = True
SLEEP 3
END IF
IF J= 1 THEN TrnsfrProp TranslO, NoOfFrames
IF J= 2 THEN TrnsfrProp Trans2 O, NoOfFrames
IF J 3 THEN TrnsfrProp Trans3O, NoOfFrames
IF J 4 THEN TrnsfrProp Trans4 O, NoOfFrames
IF J 5 THEN TrnsfrProp Trans50, NoOfFrames
CLS
WndPtScan I, Obj2, J, Grp2, 0, NoOfFrames,
Marldl'ype, eScanTransByFrms.
LOOP UNTIL Confirm("Speed Of Action Control OK?")
END IF 'all poses are the same
IF NoOfGroupsForThisObj > 1 AND J> 1 THEN
IF Confirm("Show Action Plus Path Plus Action Of
A Reference Group?") TFM
DO
SelectionOK = False
WHILE NOT SelectionOK
SELECT CASE UserChoice("", Group(1).Label,
Group(2).Label, Group(3).Label,
Group(4).Label, "")
CASE 1: Grp2 = 1
CASE 2: Grp2 = 2
CASE 3: Grp2 = 3
CASE 4: Grp2 = 4
END SELECT
IF Grp2 < J AND Group(Grp2).WchObj = I THEN
SelectionOK = True
ELSE
LOCATE 2, 1
PRINT "Choice Unavailable":
SLEEP 2: CLS
SelectionOK= False
END IF
WF~dD
WndPtScan I, Obj2, J, Grp2, 0, NoOfFrames,
MarkType, eScanGrpTransPlusPath
LOOP WHILE Confirm("Show With Another Reference
Group?")
END IF

CA 02483943 2004-11-16
- 72 -
ELSE
Grp2 = 0
WndPtScan I, Obj2, J, Grp2, 0, NoOfFrames;
MarkType, eScanGrpTransPlusPath
END IF
Text$ ="Action Plus Path OK For " + Group(J).Label
+
LOOP UNTIL Confirm(Text$)
IF ControlGraphOutOfRange = True THEN LOCATE 2, 1:
PRINT "Action Control Graph Was Out Of Range
--You Must Redo It": SLEEP 2
LOOP WfiIhE ControlGraphOutOfRange = True
SPIAfterEachTrans = SyncPtIndex
END IF 'grp belongs to i object
NEXT 'grp
CLS
Text$ _"Path, And Group Actions, For "+ Object(I).Label
+ " All OK?"
IF Confirm(Text$) THEN
ThisObjMoveAndGrpTransOK = True
SyncPtIndexAfterEachObjMoveAndTrans = SyncPtlndex
ELSE
AvlPath = AvlPath - 1
END IF
WEND
NEXT 'object
PosTransOK = True
IF Confirm("Redo ALL Space Paths And Action Control Graphs?")
TFM
IF Confirm("Are You Sure You Want To Redo ALL Space Paths
And Action Control Graphs?") THEN
PosTransOK = False
SyncPtlndex = 0
ELSE
PosTransOK = True
FND IF
END IF
VVEND
IF Confirm("Expand All Object Paths In Z?") TFiEN
INPUP =What Expansion Factor (2 to ?) "; ZExpansionMultiplier!
FOR K= 1 TO NoOfFrames
SetArrayReal PathlZPg, K, GetAReal!(PathlZPg, K) - 650
SetArrayReal Path2ZPg, K, GetAReal!(Path2ZPg, K) - 650
SetArrayReal Path3ZPg, K, GetAReal!(Path3ZPg, K) - 650
SetArrayReal PathlZPg, K, GetAReal!(PathlZPg, K) *
ZExpansionMultiplier!
SetArrayReal Path2ZPg, K, GetAReal!(Path2ZPg, K) *
ZExpansionMtiltiplier!
SetArrayReal Path3ZPg, K, GetAReal!(Path3ZPg, K) *
ZExpansionMultiplier!
SetArrayReal PathlZPg, K, GetAReal!(PathlZPg, K) + 650
SetArrayReal Path2ZPg, K, GetAReal!(Path2ZPg, K) + 650
SetArrayReal Path3ZPg, K, GetAReal!(Path3ZPg, K) + 650
NEXT
FNDIF
Operation = 150
CASE 150

CA 02483943 2004-11-16
_ 73 _
IF Cornf irm ("Any Lines or Objects Intermittent? ") THEN
SELECT CASE UserChoice("Which", "", "Line", "Object", "", "")
CASE 2
SELECT CASE UserChoice("Method To Determine When Visible",
"" , "TScript", "Frai{lG1Yo", "" "" ) , . . 'CASE 2: MrklntermtLine
'CASE 3:. ErsMnu: MrkVisInvisLine
END SELECT
MrkVisinvisLine
CASE 3
VisInvisObj
END SELECT
ENn IF
operation = 15
CASE 15
IF Confirm("Use Anchor Pts?") THEN
WHILE AnchorPtsAllOK = False
FinishedAllAnchors = False
AncRunIndex = 0
WHILE FinishedAllAnchors = False
INPUT "Name For Anchor Point"; Name$
MrkObjAnchorPt
'note that a velcro slave can't have anchor pt!!!
FoundSeg = FindWchFinlSg(FinlSgsO, ThisOne)
WchObj = FinlSgs(FoundSeg).WchObj
Object(WchObj).HasAnchors = 1
WchLine = FinlSgs(FoundSeg).WchLine
WchGrp = ALns(WchLine).WchGrp
WchSeg = FoundSeg
WchPt = ThisOne
CLS
FinishedRunsForThisPt = False
WHILE FinishedRunsForThisPt = False
LOCATE 3, 1: PRINT "ANCHORED STRIPS SO FAR:"
LOCATE 4, 1
FOR I = 1 TO NoOfAncRuns
PRINT AncRun(I).Label; AncRun(I).StartFrame;
AncRun(I).EndFrame
NEXT
OrderCheckOK = False
AncRunlndex = AncRunlndex + 1
LOCATE 18, 1: PRINT "THIS STRIP:"
LOCATE 19, 1
PRINT AncRun(AncRunIndex).Label; "Strt";
AncRun(AncRunlndex).StartFrame; " End";
AncRun(AncRunlndex)EndFrame
NoOfAncRuns = AncRunlndex
AncRun(AncRunIndex).Label = Name$
AncRun(AncRunIndex).WchObj = WchObj
AncRun(AncRunlndex).WchGrp = WchGrp
.AncRun(AncRunlndex).WchLine = WchLine
AneRun(AncRunlndex).WchSeg = WchSeg

CA 02483943 2004-11-16
- 74 -
AncRun(AncRunIndex).WchPt = WchPt
AncRun(AncRunlndex).StartFrame = 0
LOCATE 1, 40: PRINT "Click On Anchor Start Frame"
WndPtScan WchObj,.Obj2, WchGrp, Grp2, 0, NoOfFrames, 1,
eScanForAnchorPts
AncRun(AncRunindex).StartFrame = ThisOne
LOCATE 18, 1: PRINT "THIS STRIP:"
LOCATE 19, 1
PRINT AncRun(AncRunIndex).Label; "Strt";
AncRun(AncRunlndex).StartFrame; " End";
AncRun(AncRunIndex).EndFrame
SLEEP 1
DO WHILE OrderCheckOK = False
LOCATE 1, 30: PRINT "Click On Anchor End Frame
WndPtScan WchObj, Obj2, WchGrp, Grp2, 0, NoOfFrames, 1,
eScanForAnchorPts
AncRun(AncRunIndex).EndFrame = ThisOne
IF AncRun(AncRunIndex).EndFrame >=
AncRun(AncRunlndex).StartFrame THEri
OrderCheckOK = True
LOCATE 18, 15 PRIN'!' "THIS STRIP:"
LOCATE 19, 1
PRINT AncRun(AncRunIndex).Label; "Strt";
AncRun(AncRunlndex).StartFrame; " End";
AncRun(AncRunIndex).EndFrame
ELSE
LOCATE 20, 1
PRINT "End Frame Can't Be Before Start Frame -
Do Again"
BEEP: BEEP: BEEP
SLEEP 1
LOCATE 20, 1
PRINT SPACE$(40)
OrderCheckOK = False
END IF
LOOP
LOCATE 18, 1: PRINT "THIS STRIP:"
LOCATE 19, 1
PRINT AncRun(AncRvnIndex).LabeZ; "Strt";
AncRun(AncRunIndex).StartFrame; " End";
AncRun(AncRunlndex).EndFrame
Ques$ = "More Anchored Sections For " +
AncRun(AncRunTndex).Label + ?"
ErsMnu
IF NOT Confirm(Ques$) TI-MN FinishedRunsForThisPt = True
ELSE FinishedRunsForThisPt = False
V+TENI)
IF NOT Confirm("Use Another Point As Sticky Point?") THEN
FinishedAl.lAnchors = True
WIIJD
IF Confirm("Anchor Pts All OK") TFM
AnchorPtsAllOK = True
ELSE
AnchorPtsAl1OK = False
CLS
END IF
WEND

CA 02483943 2004-11-16
- 75 -
END IF
Operation = 16
CASE 16 'Wind effect
CLS
IF Confirm("Use Wind Effect?") TFEN
WHILE WindOK = False
AvlPth = AvlPth + 1
WindPath = Av1Pth
DO
M7cUniPath "WindPath", eWindPath
LOOP UNTIL Confirm("OK?")
SortSyrncPtsForApplic 1, I
SortedSyncPts(1).Frame = 1
SortedSyncPts(1).TempPtsIndex = I
SortedSyncPts(2).Frame = NoOfFrames
'this Mks last SortedSyncPts(syncpt)
end of transform tetra graph
SortedSyncPts(2).TenpPtslndex = GetA(TempPtsXPg, 0)
DO
CLS
DrawArray TempPtsXPg, -1, False
Text$ ="Velocity Graph For Wind Path"
DoVelocityGraph TempPtsXPg, RawPtsXPg, Text$
LOOP UNTIL Confirm("Wind Velocity Graph OK?")
TrnsfrPath ttawPtsXPg, Av1Pth
IF Confirm("Wind Effect OK?") TEEN
WindOK = True
ELSE
AvlPath = AvlPath - 1
END IF
WEND
IIQDIF
Operation = 18
CASE 17
Operation = 18
CASE 18 'warps named
IF Confirm("Use Segment Warps?") THEN
LOCATE 3, 1
PRINT "No Of Warps Available:"; 7 - AvlPath: SLEEP 2
WIiILE WarpsNamedOK = False
REDIM SHARED Warp(10) AS WarpType
NameWarps
WarpsNamedOK = True
WarpsOK = False
WEND
IF Confirm("No Of Warps And Names OK?") TFM
Operation = 19
ELSE
WarpsNamedOK = False
Operation = 18
END IF
ELSE
Operation = 20
END IF
CASE 19 'warps

CA 02483943 2004-11-16
_ 76 -
IF NoOfWarps > 0 THEN
AvlPathAtStartOfWazps = AviPath
WHILE WarpsOK = False
REIDIM SHARED Seglnfo(20) AS SegWarplnfoType
REDIM SHARED WarpSrs(30, 1)
AvlPath = AvlPathAtStartOfWarps
AvlWarpProflArray = 0
CLS
FOR WarpIndex = 1 TO NoOfWarps
GrfValsOK = False
DefnSegWarp Warplndex, Av1Pth, AvlWarpProflArray
IF NOT Normallm TIiE'N GOSUB NormalDrawlmg
IF UsesPrevPath = False AND WaveWarp = False TMW
'added if wavewarp false
TrnsfrPath RawPtsXPg, AvlPth
END IF
IF WaveWazp = True THEN
TrnsfrWave WaveNo
END IF
DO
GetWarpProfile (WarpNo)
LOOP UNTIL Confirm("Warp Profile OK?")
J= AvlWarpProflArray 'next trnsfrs prop! along profile
into a Profile array
IF J= 1 THIIV REDIM SHARED Profilel(TotalSegsLen) AS
WaxpProfileType: TrnsfrWarp Profilel(), TotalSegsLen
IF J= 2 THM REDIM SHARED Profile2(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile2(), TotalSegsLen
IF J= 3 THEN REDIM SHARED Profile3(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile3(), TotalSegsLen
IF J= 4 THM RE9IM SHARED Profile4(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile4(), TotalSegsLen
IF J= 5 THEN REDIM SHARED Profile5(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile50, TotalSegsLen
IF J= 6 TFO;N REDIM SHARED Profile6(TotalSegsLen) AS
WarpprofileType: TrnsfrWarp Profile6O, TotalSegsLen
IF J= 7 TPiM REDIM SHARED Profile7(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile7O, TotalSegsLen
IF J= 8 THEN REDIM SHARED Profile8(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp ProfiZe8O, TotalSegsLen
IF J= 9 TFM REDINi SHARED Profile9(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profile9O, TotalSegsLen
IF J= 10 TFM REDIM SHARED Profilel0(TotalSegsLen) AS
WarpProfileType: TrnsfrWarp Profilel0(), TotalSegsLen
CLS
NEXT
IF Confirm("Warps OK?") TPM
WarpsOK = True
ELSE
WarpsOK = False
END IF
WIIQD
END IF
Operation = 20
CASE 20 'end menu
3ELECT CASE UserChoice("", "Make Frms", "End Prgrm")
CASE 1

CA 02483943 2004-11-16
77
ConstructOK = False
Operation = 21
CASE 5
CloseWand
END
IIQD SELECT
cASE 21 'run.
WHILE ConstructOK = False
DIM SHARED WarpSegDisp AS t3DPoint
DIM SHARED SumWarpDisp AS t3DPoint
Construct 1, NoOfFrames, NoOfObjects
ConstructOK = True
bVm
Operation = 20 'end menu
END SELECT
KEY(7) ON
XEY(8) ON
LOOP
END
ErrorHandler:
SE:LECT CASE ERR
CASE 53: PRINT "No *.TWS Files Yet"
NoFiles = True
END SELECT
REStTME NEXT
ShiftLeft:
XAdjust = XAdjust - 50
RF.'I'[1RN
ShiftRight:
XAdjust = XAdjust + 50
RETURN
ShiftUp:
YAdjust = YAdjust - 50
RETURN
ShiftDown:
YAdjust = YAdjust + 50
RETURN
ZFarther:
ZAdjust = ZAdjust - 100
LOCATE 2, 30: PRINT "Z Shift"; CINT(10000 / ZAdjust); SPACE$(5)
RETURN
ZCloser:
ZAdjust = ZAdjust + 100
LOCATE 2, 30: PRINT "Z Shift"; CINT(10000 / ZAdjust); SPACE$(5)
RETURN
ZShiftNozmal:

CA 02483943 2004-11-16
78
ZAdjust = -500
LOCATE 2, 30: PRINT "Z Shift Normal "
RETURN
ReduceXYZLeverage:
xbeverage = 30;everage * 2
YLeverage = YLeverage * 2
ZLeverage = ZLeverage * 2
LOCATE 2, 30: PRINT "XYZ Lvrage"; CINT(100 / XLeverage); SPACE$(5)
RE'1RJRN
IncreaseXYZLeverage:
XLeverage = XZ,everage / 2
YLeverage = YLeverage / 2
ZLeverage = ZLeverage / 2
LOCATE 2, 30: PRINT "XYZ Lvrage"; CINT(100 / XLeverage); SPACE$(5)
RET(JRN
NormalXYZLeverage:
X.Leverage = 10
YLeverage = 10
ZLeverage = 5
LOCATE 2, 30: PRINT "RYZ Lvrage Normal
RETURN
ReduceZLeverage:
ZLeverage = ZLeverage * 2
LOCATE 2, 30: PRINT "Z Lvrage"; CINT(100 / ZLeverage); SPACE$(5)
RETURN
IncreaseZLeverage:
ZLeverage = ZLeverage / 2
LOCATE 2, 30: PRINT "Z Lvrage"; CINT(100 / ZLeverage); SPACE$(5)
RkSURN
NormalZLeverage:
ZLeverage = 5
LOCATE 2, 30: PRINT "Z Lvrage Normal
RETURN
biagnifyDraWlltig: '*******************
IF NormalIm = True AND (Operation = 3 OR Operation = 6 OR Operation = 6
OR Operation = 19) TFM
DIM AStartRefPt AS t3DPoint
DIM MagAStartRefPt AS t3DPoint
SELECT CASE UserChoice("", "", "Expand", "Shift", "Reduce", "")
CASE 2: PFac! = 3: MText$ _"EXPANDED"
CASE 3: PFac! = 1: MText$ _"SHIFTED"
CASE 4: PFac! = .3: MText$ _ "REDUCED"
END SELSCr
Text$ = "Define Center Of Area To Be + MText$
DefnPt MagCenter, Text$, "Magnify", 1
ScreenCenter.x = 320
ScreenCenter.y = 175
ScreenCenter.Z = MagCenter_Z

CA 02483943 2004-11-16
_ 79 -
MagDiff.x = ScreenCenter.x - MagCenter.x
MagDiff.y = ScreenCenter.y - MagCenter.y
FOR I= 1 TO GetA(APtsXPg, 0).
SetArrayReal APtsXPg, I, GetAReal!(APtsXPg, I) + MagDiff.x
SetArrayReal APtsYPg, I, GetAReal!(APtsYPg, I) + MagDiff.y
x! = ScreenCenter.x - GetAReal!(APtsXPg, I)
y! = ScreenCenter.y - GetAReal!(APtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(APtsZPg, I)
magx! = x! * PFac!
magy! = y! * PFac!
magz! = Z! * PFac!
SetArrayReal APtsXPg, I, ScreenCenter.x - magx!
SetArrayReal APtsYPg, I, ScreenCenter.y - magy!
SetArrayReal APtsZPg, I, ScreenCenter.Z - magz!
NBXT
FOR I= 1 TO GetA(BPtsXPg, 0)
SetArrayReal BPtsXPg, I, GetAReal!(BPtsXPg, I) + MagDiff.x
SetArrayReal BPtsYPg, I, GetAReal!(BPtsYPg, I) + MagDiff.y
x! = ScreenCenter.x - GetAReal!(BPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(BPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(BPtsZPg, I)
magx! = x! * PFac!
magy! = y! * PFac!
magz! = Z! * PFac!
SetArrayReal BPtsXPg, I, ScreenCenter.x - znagx!
SetArrayReal BPtsYPg, I, ScreenCenter.y - magy!
SetArrayReal BPtsZPg, I, ScreenCenter.Z - tnagz!
NEXT
FOR I = 1 TO GetA(CPtsXPg, 0)
SetArrayReal CPtsXPg, I, GetAReal!(CPtsXPg, I) + MagDiff.x
SetArrayReal CPtsYPg, I, GetAReal!(CPtsYPg, I) + MagDiff.y
x! = ScreenCenter.x - GetAReal!(CPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(CPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(CPtsZPg, I)
magx! = x! * PFac!
niagy'. = y! * PFac!
magz! = Z! * PFac!
SetArrayReal CPtsXPg, I, ScreenCenter.x - mmagx!
SetArrayReal CPtsYPg, I, ScreenCenter.y - magy!
SetArrayReal CPtsZPg, I, ScreenCenter.Z - magz!
NEXT
FOR I = 1 TO GetA(DPtsXPg, 0)
SetArrayReal DPtsXPg, I, GetAReal!(DPtsXPg, I) + MagDiff.x
SetArrayReal DPtsYPg, I, GetAReal!(DPtsYPg, I) + MagDiff.y
x! = ScreenCenter.x - GetAReal!(DPtsXPg, I)
y! =ScreenCenter.y - GetAReal!(DPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(DPtsZPg, I)
magx! = x!_* PFac!
magy! = y! * PFac!
magz! = Z! * PFac!
SetArrayReal DPtsXPg1 I, ScreenCenter.x - magx!
SetArrayReal DPtsYPg, I, ScreenCenter.y - magy!
SetArrayReal DPtsZPg, I, ScreenCenter.Z - magz!
RTEKT
CLS
IF Operation = 19 THEN
FOR I = 1 TO GetA(TempPtsXPg; 0)
SetArrayReal TempPtsXPg, I, GetAReal!(TenmpPtsXPg, I)+MagDiff.x
SetArrayReal TenipPtsYPg, I, GetAReal!(TennpPtsYPg, I)+MagDiff.y

CA 02483943 2004-11-16
- 80 -
x! = ScreenCenter.x - GetAReal!(TempPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(TempPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(TempPtsZPg, I)
magx! = x! * PFac!
magy! = y! * PFac!
magz! = Z! * PFac!
SetArrayReal TempPtsXPg, I, ScreenCenter.x - magx!
SetArrayReal TempPtsYPg, I, ScreenCenter.y - magy!
SetArrayReal TempPtsZPg, I, ScreenCenter.Z - magz!
h1EX'I'
DrawArray TempPtsXPg, -1, True
ENID IF
SELECT CASE WchPoseForMag
CASE 1: ShowWhllmage 1, -1
CASE 2: ShowWhllmage 2, -1
CASE 3: ShowWhllmage 3, -1
CASE 4: ShowWhllmage 4,.-1
END SELECT
IF Drawingltnage = True TFffiLV
IF LnNo = MagLinesToDraw TFM
PutDrwMnuOnScrn Text$, WchPoseForMag, 1
ELSE
PutDrwMnuOnScrn Text$, WchPoseForMag, 0
ETJD IF
END IF
FORs1TO2
SOUND 1000, 2
SouND 2000, 2
NEXT
LOCATE 2, 30: PRIN'P "Image + MText$
Normallm = False
END IF
KEY(5) tN
RETtJRN
NozmalDrawImgs
IF NOT NornialIm THM
CLS
FOR I 1 TO GetA(APtsXPg, 0)
x! = ScreenCenter.x - GetAReal!(APtsXPg, I)
y! = ScreenCenter.y - GetAReal!(APtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(APtsZPg, I)
normx! = x! / PFac!
normy! = y! / PFac!
normz! = Z! / PFac!
SetArrayReal APtsXPg, I, ScreenCenter.x - normx!
SetArrayReal APtsYPg, I, ScreenCenter.y - normy!
SetArrayReal APtsZPg, I, ScreenCenter.Z - normz!
SetArrayReal APtsXPg, I, GetAReal!(APtsXPg, I) - MagDiff.x
SetArrayReal APtsYPg, T, GetAReal!(APtsYPg, I) - MagDiff.y
NOCT
FOR I 1 TO GetA(BPtsXPg, 0)
x! = ScreenCenter.x - GetAReal!(BPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(BPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(BPtsZPg, I)
normx! = x! / PFac!
normy! = y! / PFac!
normz! = Z! / PFac!

CA 02483943 2004-11-16
- 81 -
SetArrayReal BPtsXPg, I, ScreenCenter.x - normx!
SetArrayReal BPtsYPg, I, ScreenCenter.y - normy!
SetArrayReal BPtsZPg, I, ScreenCenter.Z - normz!
SetArrayReal BPtsXPg, I, GetAReal!(BPtsXPg, I) - MagDiff.x
SetArrayReal BPtsYPg, I, GetAReal!(BPtsYPg, I) - MagDiff.y
BiEX'I'
FOR I 1 TO GetA (CPtsXPg, 0)
x! = ScreenCente.r.x - GetAReal!(CPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(CPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(CPtsZPg, I)
normx! = x! / PFac!
normy! = Y!. / PFac!
riormz! = Z! / PFac!
SetArrayReal CPtsXPg, I, ScreenCenter.x - normx!
SetArrayReal CPtsYPg, I, ScreenCenter.y - normy!
SetArrayReal CPtsZPg, I, ScreenCenter.Z - normz!
SetArrayReal CPtsXPg, I, GetAReal!(CPtsXPg, I) - MagDiff.x
SetArrayReal CPtsYPg, 1, GetAReal!(CPtsYPg, I) - MagDiff.y
BTEXT
FOR I= 1 TO GetA(DPtSXPg, 0)
x! = ScreenCenter.x - GetAReal!(DPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(DPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(DPtsZPg, I)
nornnc! = x! / PFac!
normy! = y! / PFac!
normz! = Z! / PFac!
SetArrayReal DPtsXPg, I, ScreenCenter.x - normx!
SetArrayReal DPtsYPg, I, ScreenCenter.y - normy!
SetArrayReal DPtsZPg, I, ScreenCenter.Z - normz!
SetArrayReal DPtsXPg, I, GetAReal!(DPtsXPg, I) - MagDiff.x
SetArrayReal DPtsYPg, I, GetAReal!(DPtsYPg, I) - MagDiff.y
NEX'I'
CLS
IF Operation = 19 THIIN
FOR I= 1 TO GetA(TempPtsXPg, 0)
x! = ScreenCenter.x - GetAReal!(TempPtsXPg, I)
y! = ScreenCenter.y - GetAReal!(TempPtsYPg, I)
Z! = ScreenCenter.Z - GetAReal!(TempPtsZPg, I)
normx! = x! / PFac!
normy! = y! / PFac!
normz! = Z! / PFac!
SetArrayReal TempPtsXPg, I, ScreenCenter:x - normx!
SetArrayReal TempPtsYPg, I, ScreenCenter.y - normy!
SetArrayReal TempPtsZPg; I, ScreenCenter. Z - normz!
SetArrayReal TgnpPtsXPg, I, GetAReal!(TempPtsXPg, I) - MagDiff.x
SetArrayReal TempPtsYPg, I, GetAReal!(TempPtsYPg, I) - MagDiff.y
NE'P
DrawArray TempPtsXPg, -1, True
mTD IF
SELECT CASE WchPoseForMag
CASE 1: ShowWhllmage 1, -1
CASE 2: ShowWhlImage 2, -1
CASE 3: ShowWhl Im--ge 3, -1
CASE 4: ShowWhl7.mage 4, -1
IIQD SELECT
IF Drawinglmage = True THEN
IF LnNo = MagLinesToDraw TFBEN
PutDrwMnuOnScrn Text$, WchPoseForMag, 1
ELSE

CA 02483943 2004-11-16
- 82 -
PutDr%MnuOnScrn Text$, WchPoseForMag, 0
$ND IF
END IF
Normallm = True
FOR s= 1 T0 2
SOUND 1000. 2.
SOUND 2000, 2
NEXT
LOCATE 2, 30: PRINT "Image NORMAL"
ELVD IF
KEX (7 ) ON .
RE'!'[7RN
REM $STATIC
SUB AdjMtchPt (WchPose, WchLine, MtchPtNdx)
ErsMnu
ImToFix = WchPose
NdxToFix = MtchPtNdx
SELECT CASE WchPose
CAS.E 1
Start = 1: Finish = GetA(APtsXPg, 0)
CASE 2
GetStartFinish BLnsO, WchLine, Start, Finish
CASE 3
GetStartFinish CLn.s(, WchLine, Start, Finish
CASE 4
GetStartFinish DLnsO, WchLine, Start, Finish
END SELECT
PtMove = 6
LOCATE 8, 1: PRINT "Fast"
PtPosit = MtchPts(NdxToFix, ImToFix) 'this lets you choose done right
away if posit is ok
LOCATE 10, 1: PRINT "Original"; PtPosit
DO
A$ = "Fast": B$ = "Back": C$ = "Forward": D$ _ "Done": E$ _ "Slow"
WndChs "", A$, B$, C$, D$, E$, Ans$, 0
IF Ans$ = D$ THEN
MtchPts(NdxToFix, TmToFix) = PtPosit
ErsMnu
EXIT DO
E[,SE
GetImFxXYZ ImToFix, PtPosit
Mrk 0, 1
SELECT CASE Ans$
CASE A$
PtMove = 6
LOCATE 8, 1: PRINT "Fast"
CASE E$
PtMove = 1
LOCATE 8, 1: PRINT "Slow"
CASE C$
PtPosit = PtPosit + PtMove
IF PtPosit > Finish THEN PtPosit = PtPosit - PtMove
CASE B$
PtPosit = PtPosit - PtMove
IF PtPosit < Start THEN PtPosit = PtPosit + PtMove
FVID SELECT
Get7mFxM ImToFix, PtPosit
Mrk 0, 1

CA 02483943 2004-11-16
- 83 -
LOCATE 11, 1: PRINT "Now"; PtPosit
END IF
LOOP
C$ = "Finished": D$ ="Adj": W'ndChs "", "x", "x", C$, D$, "x", Ans$, 1
END SUB
9UB AdjObjPathStartEnd (Array, NoOfArrayPts)
REDIM TerminalPositDiff(1) AS t3DPoint
TerminalP0sitDiff(0).x = TerminalPoint(0).x - GetAReal!(Array, 1)
Ternv.nalPositDiff(0).y = TerminalPoint(0).y - GetAReal!(Array + 1, 1)
TerminalPositDiff(0).Z = TerrninalPoint(0).Z - GetAReal!(Array + 2, 1)
TerminalPositDiff(1).x = TerneinalPoint(1).x -
GetAReal!(Array, (GetA(Array, 0)))
TerminalPositAiff(1).y = TerminalPoint(1).y -
GetAReal!(Array + 1, (GetA(Array, 0)))
TerminalPositDiff(1).Z = TerminalPoint(1).Z -
GetAReal!(Array + 2, (GetA(Array, 0)))
Zoop = -1
Glob = NoOfArrayPts + 1
FOR K 1 TO NoOfArrayPts
Zoop = Zoop + 1
Glob = Glob - 1
XChange! = (TerminalPositDiff(0).x * (NoOfArrayPts - Zoop) /
GetA(TempPtsXPg, 0)) + (TerminalPositDiff(1).x *
(NoOfArrayPts - Glob) / GetA(TernpPtsXPg, 0))
YChange! = (Termi.nalPositDiff(0).y * (NoOfArrayPts - Zoop) /
GetA(TempPtsXPg, 0)) + (TerminalPositDiff(1).y *
(NoOfArrayPts - Glob) / GetA(TempPtsXPg, 0))
ZChange! _ (TenninalPositDiff(0).Z * (NoOfArrayPts - Zoop) /
GetA(TempPtsXPg, 0)) + (TerminalPasitDiff(1).Z *
(NoOfArrayPts - Glob) / GetA(TempPtsXPg, 0))
SetArrayReal Array, K, GetAReal! (Array, K) + XChange!
SetArrayReal Array + 1, K, GetAReal!(Array + 1, K) + YChange!
SetArrayReal Array + 2, K,.GetAReal!(Array + 2, K) + ZChange.!
NEXT
DrawPartialArray Array, 1, GetA(Array, 0), -1, True
Tercni.nalsHarked = False
END SUB
St7s AdjPathAlongXYZ (WchPath)
DM PathStartPt AS t3DPoint
DIM PathEndPt AS t3DPoint
m
shift = 0
B$ = "X": C$ = "Y": D$ = "Z": E$ _ "Quit"
WndChs "On Which Axis?", "x", B$, C$, D$, E$, Ans$, 0
Axi.s$ = Ans$
SELEC'I' CASE Ans$
CASE "X"
B$ = "Left": C$ = "Right"
CASE "Y"
B$ = "Up": C$ = "Down"
CASE "Z
B$ = "Farther": C$ _ "Closer"

CA 02483943 2004-11-16
- 84 -
CASE E$
EXIT DO
END SELECT
DC)
D$ = "Done " + Axis$
WndChs "Which Direction?", "x", B$, C$, D$, "x", Ans$, 0
SEI,ECT CASE Ans$
CASE B$
shift = shift - 4
CASE C$
shift = shift + 4
CASE D$
EXIT DO
EQD SELECT
I,OCATE 5, 1: PRINT "shifting path "; WchPath; Ans$; shift
LOOP
SELECT CASE WchPath
CASE 1
PathStartPt.x = GetAReal(PathlXPg, 1)
pathStartPt.y = GetAReal(PathlYPg, 1)
PathStartPt.Z = GetA'Rea1(PathlZPg, 1)
PathEndPt.x = GetAReal(PathlXPg, GetA(PathlXPg, 0))
PathEndPt.y = GetAReal(PathlYPg, GetA(PathlXPg, 0))
PathEndPt.Z = GetAReal(PathlZPg, GetA(PathlXPg, 0))
CASE 2
PathStartPt.x = GetP,Real(Path2XPg, 1)
PathStartPt.y = GetAReal(Path2YPg, 1)
pathStartPt.Z = GetAReal(Path2ZPg, 1)
PathEndPt.x = GetAReal(Patth2XPg, GetA(Path2XPg, 0))
PathEndPt.y = GetAReal(Path2YPg, GetA(Path2XPg, 0))
PathEndPt.Z = GetAReal(Path2ZPg, GetA(Path2XPg, 0))
CASE 3
PathStartPt.x = GetAReal(Path3XPg, 1)
PathStartPt.y = GetAReal(Path3YPg, 1)
PathStartPt.Z = GetAReal(Path3ZPg, 1)
PathEndPt.x = GetAReal(Path3XPg, GetA(Path3XPg, 0))
PathEhdPt.y = Get.AReal(Path3YPg, GetA(Path3XPg, 0))
PathEndPt.Z = GetAReal(Path3ZPg, GetA(Path3XPg, 0))
END SELECT
TerminalPoint(0) = PathStartPt
Tezm.inalPoint(1) = PathEndPt
SELECT CASE Axis$
. . .
4!~-~ i+TG+L~ "X"
Te~rminalPoint(0).x = PathStartPt.x + shift
TerminalPoint(1).x = PathEndPt.x + shift
CP SE "Y"
TerminalPoint(0).y = PathStartPt.y + shift
TerminalPoint(1).y = PathEndPt.y + shift
CASE "Z"
TerminalPoint(0).Z = PathStartPt.Z + shift
TerminalPoint(1).Z = PathEndPt.Z + shift
EIVD SELECT
TerminalsMrked = True
SELECT CASE WchPath
CASE 1
AdjObjPathStartEnd PathlXPg, GetA(PathlXPg, 0)
ShoyoObjPath PathlXPg, 1
CASE 2

CA 02483943 2004-11-16
- 85 -
AdjObjPathStartEnd Path2XPg, GetA(Path2XPg, 0)
ShowObjPath Path2XPg, 1
CASE 3
AdjObjPathStartEnd Path3XPg, GetA(Path3XPg, 0)
ShowObjPath Path3XPg, 1
END SELECT
SLEEP 1
LOOP
END SUB
SUB A11PosesAreA
FOR I = 1 TO NoOfFrames
TransGrfVal(I).PropA = 7
TransGrfVal(I).PropB = 0
TransGrfVal(I).PropC = 0
TransGrfVal(I).PropD = 0
NE7CI'
END SUB
FUNCTION CalcDistBetPts! (Ptl AS TScriptWayPt, Pt2 AS TScriptWayPt)
x! = (Ptl.Locat.x - Pt2.Locat.x)
y! = (Ptl.Locat.y - Pt2.Locat.y)
Z! = (Pt1.Locat.Z - Pt2.Locat.Z)
CalcDistBetPts! = SQR(x! * x! + y! * y! + Z! * Z!)
END FUNCTION
SUB Ca1cFlatXY
L?O:iXY. lx = XYZ. x - 1
L7C2XY. rx = XYZ. x
L7RXY.y = XYZ.y
IF LX2XY.lx < LeftBound TIISnT LXRXY.lx = LeftBound
IF hHI2XY.rx < LeftBound TFM LXRXY.rx = LeftBound
IF LXRXY.lx > RightBound THEN LXRXY.lx = RightBound
IF LXRXY.rx > RightBoun.d THM LxtxY.rx = RightBound
IF L7ffiXY. y< Topbound TFM L}RXY. y= Topbound
IF LHIRXY.y > BottomBound THEN LXRXY.y = BottomBound
END SUB
SUB CalcFramePositions (aDrawnPath, aFramePosArray)
SetA aFramePosArray, 0, NoOfFrames
ReqdDist! = 0
FOR Frame = 1 TO NoOfFrames
CurrDist! = 0
RegdDist! = ReqdDist! + FrmToFrmVelacity!(Frame)
PtNo = 2
NextDist! = DistToNextPoint!(aDrawnPath, PtNo)
DO WHILE CurrDist! + NextDist! < ReqdDist!
PtNo = PtNo + 1
IF PtNo > 20000 THEN
PathError = True
LOCATE 2, 1: PRINP "Path Error --Redo Path": SLEEP 2
ExIT DO
END IF
CurrDist! = CurrDist! + NextDist!
NextDist! = DistToNextPoint!(aDrawnPath, PtNo)
LOOP
IF PathError = True THM GOTO GetOut

CA 02483943 2004-11-16
- 86 -
pctNeeded! _ (ReqdDist! - CurrDist!) / NextDist!
SetArrayReal aFramePosArray + 0, Frame, GetAReal!(aDrawnPath + 0,PtNo)
*(1 - PctNeeded!) + GetAReal!(aDrawnPath + 0, PtNo + 1)
* PctNeeded!
SetArrayReal aFramePosArray + 1, Frame, GetAReal!(aDrawnPath + 1,PtNo)
*(1 - PctNeeded!) + GetP,Real!(aDrawnPath + 1, PtNo + 1)
* PctNeeded!
SetArrayReal aFramePosArray + 2, Frame, GetAReal!(aDrawnPath + 2,PtNo)
(1 - PctNeeded!) + GetA'Real!(aDrawnPath + 2, PtNo + 1)
* PctNeeded!
NFXT
PtCount = GetA(aDrawnPath, 0)
SetArrayReal aFramePosArray + 0, NoOfFrames, GetAReal!(aDrawnPath + 0,
PtCount)
SetArrayReal aFramePosArray + 1, NoOfFrames, GetAReal!(aDrawnPath + 1,
PtCount)
SetArrayReal aFramePosArray + 2, NoOfFrames, GetAReal!(aDrawnPath + 2,
PtCount)
GetOut:
EtJD SUB
SUB Ca1cLXtXY
LRRRY.1x = XYZ.x - XYZ.Z / ZDivisor
LXtXY.s'x= XYZ.x + XYZ.Z / ZDivisor
L%RXY.y = XYZ.y
IF LXRXY.lx < LeftBound THEN LXRXY.lx = LeftBound
IF LX'tXY.rx < LeftBound THIIJ LXRXY.rx = LeftBound
IF LXRXY.2x > RightBound THM LXRXY.lx = RightBound
IF L}CtXX. rx > RightBound TH~N L.XtXY. rx = RightBound
IF LXRXY. y< Topbound TAETt LXftXY. y= Topbound
IF LM:tXY.y > HottosnBound TFM LXRXY.y = BottomBound
END SUB
SUB CalcMrkrPts
MrkrPts.lx = LxiXY.lx - 4
xrkrPts.rx = LXRXY.rx - 4 '-4 is displacement to center of cursor
MrkrPts.y = L7CtXY.y - 4
FND SUB
FUNCTION CalcTDist! (Vertex)
x! = (TPts(Vertex).x - XYZ.x)
y! = (TPts(Vertex).y - XYZ.y)
Z! = (TPts(Vertex).Z - XYZ.Z)
CalcTDist! = SQR(x! * x! + y! * y! + Z! * Z!)
EVD FUNCTICN
F[JNCTION CalcTetFrms
CalcTetFrms = True
FOR I = 1 TO NoOfFrames
XYZ.x = GetAReal!(RawPtsXPg, I)
XYZ.Y = GetAReal!(RawPtsYPg, I)
XYZ.Z = Get.AReal!(RawPtsZPg, I)
IF Ca1cTProps ( I) = False TIiM
CalcTetFrms = False
EXIT FOR
END IF
NEXT

CA 02483943 2004-11-16
- 87 -
END FUNCTION
FUNCTION Ca1cTProps (WchFrame)
DIM DisToVert(4) AS SINGLE
FOR I= 1 TO 4
DisToVert(I) = Lim.i.ts!(CalcTDist!(I), 0!, 350!)
NEXT
TransGrfVal(WchFrame).PropA = 1 - DisToVert(1) / 350
TransGrfVal(WchFrame).PropB = 1 - DisToVert(2) / 350
TransGrfVal(WchFrame).PropC = 1 - DisToVert(3) / 350
TransGrtVal(WchFrame).PropD = 1 - DisToVert(4) / 350
SumProp! = TransGrfVal(WchFrame).PropA + TransGrfVal(WchFrame).PropB +
T.ransGrfVal(WchFrame).PropC + TransGrfVal(WchFrame).PropD
IF SumProp! <> 0 THQT
CalcTProps = True
Mkl! = 1 / SumProp!
TransGrfVal(WchFrame).PropA = TransGrfVal(WchFrame).PropA * Mkl!
TransGrfVal(WchFrame).PropB = TransGrfVal(WchFrame).PropB * Mkl!
TransGrfVal(WchFrame).PropC = TransGrfVal(WchFratne).PropC * Mkl!
TransGrfVal(WchFrame).PropD = TransGrfVal(WchFrame).PropD * D9cl!
ELSE
CalcTProps = False
END IF
EiM FUNCTION
SUB ChooseGrp (ChosenGrp, GrpText$)
WHILE NOT GroupOK
ChosenGrp = UserChoice(GrpText$, Group(1).Label, Group(2).Label,
Group(3).Label, Group(4).Label, Group(5).Label)
IF Confirm("Is "+ Group(ChosenGrp).Label + Correct?") THEN
GroupOK = True
WEND
END SUB
SUB ChooseLineColor
LOCATE 2, 30
INPUT "Line Color Number"; ColorNumber
LOCATE 2, 30: PRINT SPACE$(40)
IF ColorNumber > NoOfColors TtiEN NoOfColors = ColorNumber
LineColor = Color'Nunber
LOCATE 2, 50: PRINT "Line Color:"; LineColor
MyDelay 1
END SUB
SUB ChooseObj (ChosenObj, ObjText$)
WHILE NOT ObjOK
ChosenObj = UserChoice(ObjText$, Object(1).Label, Object(2).Label,
Object(3).Label, "", "")
IF Confirm("Is "+ Object(ChosenObj).Label + Correct?") 4'HM
ObjOK = True
WIIID
F.rsMnu
END SUB
SUB C1earMtchPts
FOR I= 0 TO 10
FOR J = 0 TO 7
MtchPts(I, J) = 0

CA 02483943 2004-11-16
- 88 -
NEXT
NEXT
MtchPtsOK = False
END SUB
SUB Colorlt
ColoringOK = False
WHILE Id0'!' ColoringOK
F'OR I = 1 TO NoOfLines
CLS
IF ALns(I).Looped = 1 THEN
ShowLn 1, I, -1
IF Confirm("Paint This Loop?") TFM
INPUT "Fill Color Number"; ColorNumber
IF ColorNumber > NoOfColors THEN.NoOfColors = ColorNumber
ALns(I).PaintCol = ColorNumber
ELSE
ALns(I).PaintCol = -1
EN'D IF
END IF
NEXT
IF Confirm("Coloring OK?") THEN ColoringOK = True
WEND
EIVD SUB
FUNCTION Confirm (aQuestion$)
DIM Done AS INTEGER
ErsMnu
WndMnu aQuestion$, "x", "Yes", "No", "X" , X.
Done = False
WHILE Done = False
Wndln
Ca1cFlatXY
Ca1cWkrPts
ShowFlatCrsr
IF XYZ.y > 0 AND XYZ.y < 16 fiJiEN
SELECT CASE XYZ.x
CASE NIDXVals(3) TO PBXVals(4): Done = True: Confirm = True
CASE Ng3}LVals (5) TO NBXVa1s (6) : Done = True: Confirm = False
END SELECT
END IF
WENA
MyDelay 1
ErsMnu
END FUNCTION
SUB Construct (BeginFrame, FinishFrame, NoOfObjectsForThisRun)
StartOver:
TotalNoOfFraines = FinishFrame - BeginFrame + 1
COLOR 5
REDIM SeglnfoLst(105)
DIM Disp AS t3DPoint, StaticAncVal AS t3DPoint, PtVal AS t3DPoint,
AncDisp AS t3DPoint
REDIM ObjZDist(6) AS ZDistType
SCREEDI 9, , 0, 0
apage = 0: vpage = 1
K = 0
EndOfLastTransfer = 0
FinalRecordNo =:0: LastFinalRecordNo = 0
IF OneFran-eOnly = False THEN CLS

CA 02483943 2004-11-16
_ 89 -
AncRun = False
GetObjDispVals = False
Second
ZCorrection = 40
LensFocalLength = 35
'INPUT "ZCorrec is 40, ZCorrection (larger no = smaller image)";
ZCorrection
INPUT "Lens is 35, Lens (larger no = longer focal length)
LensFocalLength
IF OneFrameOnly = True TIiE[J
Record$ = "No"
CLS
GOTO ShowOneFrame
END IF
REDOFLUFFS:
COLOR 5
RecordDecisionOK = False
WHILE NOT RecordDecisionOK
SELECT CASE UserChoice("RecordS4 Or RecordS6 Or View Mono?", =",
"RecordS4", "RecordS6", "VievMono", "")
CASE 2: Record$ ="RecordS4"i RecordDecisionOK = True
CASE 3: Record$ ="RecordS6": RecordDecisionOK = True
CASE 4
Record$ = "No"
IF Confirm("You Will Not Be Able To Play Back This Run On
Sandde4. Is That OK?") THEAT
RecordDecisionOK = True
EI1D IF
END SELECI'
WEND
CLS
SELECT CASE Record$
CASE "RecordS4"
SnapName$ = LEFT$(RunName$, 2)
PRINT "SnapName$:"; SnapName$: SLEEP 1
COLOR 5
SCREEN 9, , 1, 1
CLS
LOCATE 1, 1: PRINT SnapName$; TotalNoOfFrames
SCREEN 9, , 0, 0
CLS
LOCATE 1, 1: PRINT SnapName$; TotalNoOfFrames
SnapShot ASC(LEFT$(SnapName$, 1)) * 256 +
ASC(RIGHT$(SnapName$, 1)), NoOfFrames
SCREEN 9, , 11 1
CLS
SCREFN 9, , 0, 0
CLS
CASE "RecordS6"
FOR I = 1 TO NoOfLines
IF ALns(I).LineCol > NoOfColors THEN
NoOfColors = ALns(I).LineCol
IF ALns(I).PaintCol > NoOfColors TFBW
NoOfColors = ALns(I).PaintCol
P1EBT

CA 02483943 2004-11-16
- 90 -
S6SaveName$ _ "K:\PROJECTS\IMAX\IMPORTS\",+ RunName$ + ~,SNI"
OPE[J S6SaveName$ FOR RANDOM AS #2 LEN = LEN(Transferinfo)
Write.XFerInfo ePaletteSize, NoOfColors, 0, 0, 0
END SELECT
ShowOneFrame:
COLOR 5
FOR FrameNo = BeginFrame TO FinishFrame
Disp.x = 0: Disp.y = 0: Disp.Z = 0
EndOfLastTransfer = 0: SaveWhlImglndex = 0: SaveLineindex = 0
TotalPts = 0
IF SaveThisRun = True TMM RecordFrameNo = FrameNo + EndFrameOfPrevRun
ELSE RecordFrameNo = FrameNo
IF Record$ = "RecordS6" THEN
LOCATE 1, 10: PRINT "Recording "; RunName$; " To S6 ImportFile,
Frame'; RecordFrameNo
Write7FerInfo eStartCel, TotalNoOfFrames, 0, 0, 0
END IF
ZDistlndex = 0
IF OneFrameOnly = True THEDt LOCATE 5, 1: PRINT FrameNo
determine z dist for each obj for this frame:
FOR ObjNo = 1 TO NoOfObjectsForThisRun
ZDistlndex = ZDistlndex + 1
WchObjPath = Object(ObjNo).PathNo
PathArrayPositPtr FrameNo, WchObjPath, ObjPathPosit
objZDist(ZDistIndex).Dist = ObjPathPosit.Z +
Object(ObjNo).FakeZShift
ObjZDist(ZDistIndex).ObjNo = ObjNo
NEXT
sort object z distances:
FOR I = ZDistindex - 1 TO 1 STEP -1
FOR J = 1TOI
IF ObjZDist(J).Dist > ObjZDist(J + 1).Dist TFW
SWAP ObjZDist(J).Dist, ObjZDist(J + 1).Dist
SWAP ObjZDist(J).ObjNo, ObjZDist(J + 1).ObjNo
IIJD IF
NEXT
IJF.XT
'start actual animation construction:
FOR r 1 TO ZDistlndex 'this goes thru objects in order of their
zdist
ObjNo = ObjZDist(r).ObjNo 'from back to front
IF FrameNo >= Object(ObjNo).StartVis AND FrameNo <=
Object(ObjNo).EndVis THEN
K = 0
DO WHILE K <= NoOfAncRuns
K = K + 1
IF AncRun(K).WchObj = ObjNo THEN
IF FrameNo >= AncRun(K).StartFrame AND
FrameNo <= AncRun(K).EndFrame THEN

CA 02483943 2004-11-16
- 91 -
AncRun = True
AncObj = ObjNo
AncGrp = AncRun(K).WchGrp
AncLine = AncRun(K).WchLine
AncSeg = AncRun(K).WchSeg
AncPt = AncRun(K).WchPt
FirstAncFrm = AncRun(K).StartFrame
LastAncFrm = AncRun(K).EndFrame
Second = 2 'will do two passes --first to get
displacement. second to actually draw
whole object in displaced psition
EXIT DO
ELSE
AncRun = False
Second = 1 'will do only one unanchored pass
END IF
END IF
LOOP
FOR Pass = 1 TO Second
GetObjDispVals =.(AncRun = True AND Pass = 1)
WchObjPath =,Object(ObjNo).PathNo
PathArrayPositPtr FrameNo, WchObjPath, ObjPathPosit
IF Pass = 2 THEN
AObjCntr(ObjNo).x = AObjCntr(ObjNo).x - AncDisp.x
AObjCntr(ObjNo).y = AObjCntr(ObjNo).y - AncDisp.y
AObjCntr(ObjNo).Z = AObjCntr(ObjNo).Z - AncDisp.Z
END IF
'******* when using ancs maybe need to make obj cntr the
pathposit so link can connect properly
Disp:x = ObjPathPosit.x - AObjCntr(ObjNo).x
Disp.y = ObjPathPosit.y - AObjCntr(ObjNo).y
Disp.Z = ObjPathPosit.Z - AObjCntr(ObjNo).Z
.NegZ! = ObjPathPosit.Z / ZDivisor - ZCorrection
PFac! = LensFocalLength / NegZ!
IF GetObjDispVals = True THEN
BeginGrp = AncGrp
FinGrp = AncGrp
ELSE
BeginGrp = 1
FinGrp = NoOfGroups
E!JD IF
FOR GroupNo = BeginGrp TO FinGrp
IF Group(GroupNo).WchObj = ObjNo THIIN
TransPtr FrameNo, GroupNo, A11Prop
FOR H= 1 TO NoOfVelcros
IF VelcroAGrp(H).S1aveGrp = GroupNo THEN
ObjPathPosit = VelcroAGrp(H).HookXYZVals

CA 02483943 2004-11-16
- 92 -
Disp.x = ObjPathPosit.x - AGrpCntr(GroupNO).x
Disp.y = ObjPathPosit.y - AGrpCrntr(GroupNo).y
Disp.Z = ObjPathPosit.Z - AGrpCntr(GroupNo).Z
NegZ! = VelcroAGrp(H).HookXYZVa1s.Z /. ZDivisor -
ZCorrection
PFac! = LensFocalLength / NegZ!
END IF
NEXT
IF GetObjDispVals = True THEN
BeginLine = AncLine
FinLine = AncLine
ELSE
BeginLine = 1
FinLine = NoOfLines
END IF
FOR LineNo = BeginLine TO FinLine 'wch lines belong to
the grp
SaveLinelndex = 0
IF GetObjDispVals = False THEN TempLineBegFinIndex = 0.
TransPtr FrameNo, GrpNo, A11Prop
IF ALns(LineNo).WchGrp = GroupNo AND
ALns(LineNo).StartVis <= FrameNo AND
ALn.s(LineNo).EndVis >= FrameNo TFM
RecordingLine = LineNo
Intermi.tLine = False
IF ALns(LineNo).Intermit = True THEN
TransPtr FrameNo, GrpNo, AllProp 'this is to see if
line should be
shown
IF ALns(LineNo).KeyForm = 1 AND
ALns(LineNo).Threshold < A1lProp.PropA THN
IntermitLine = True
IF ALns(LineNo).KeyForm = 2 AND
ALns(LineNo).Threshold < AllProp.PropB THFN7
IntermitLine = True
IF ALns(LineNo).KeyForm = 3 AND
ALns(LineNo).Threshold < A,llProp.PropC ZHM
IntermitLine = True
IF ALns(LineNo).KeyForm = 4 AND
ALns(LineNo).Threshold < A1lProp.PropD TFER
IntermitLine = True
END IF
IF ALns(LineNo).Intermit = False OR
(ALns(LineNo).Intermit = True AND IntermitLine = True) THEN
'either a not intermit line or tscript meets
threshold criterion
IF GetObjDispVals = True THM
BeginSeg = AncSeg
FinSeg = AncSeg
ELSE
BeginSeg = 1
FinSeg = NoOfSegs
END IF

CA 02483943 2004-11-16
- 93 -
FOR SegNo = BeginSeg TO FinSeg
IF FinlSgs(SegNo).WchLine = LineNo TAETT
SumWarpDisp.x = 0
SumWarpDisp.y = 0
SumWarpDisp.Z = 0
SeglnfLstIndx = 0
SegDist! = AllProp.PropA * TempSegs(SegNo).ADist +
AllProp.PropB * TempSegs(SegNo).BDist +
AllProp.PropC * TempSegs(SegNo).CDist +
A11Prop.PropD * TempSegs(SegNo).DDist
StartPt = FinlSgs(SegNo).Beg
EndPt = FinlSgs(SegNo).Fin
Grp = FinlSgs(SegNo).WchGrp
'find if seg has warp info and wch seginfolst it
is (m) :
IF FinlSgs(SegNo).WchlnfoArr <> 0 THEN
FOR m= 1 TO AvllnfArr
IF Seginfo(m).WchSeg = SegNo THM
SeglnfLstlndx = SegInfLstIndx + 1
SegInfoLst(SeglnfLstIndx) = m
END IF
NEXT '(end of seg info)
END IF
SegPtNo = 0
IF GetObjDispVals = True TFiEN
BeginPt = AncPt
FinPt = AncPt
ELSE
BeginPt = StartPt
FinPt = EndPt
END IF
FOR PtNo = BeginPt TO FinPt
IF GetObjDispVals = False THEN
TempLineBegFinlndex = TempLineBegFinlndex + 1
IF IntermitLine = True THEN
Conversion! = 1 / ALns(LineNo).Threshold
SELECT CASE ALns(LineNo).KeyForm
CASE 1
RevisedPropA! =
(A11Prop.PropA -
ALns(LineNo).Threshold)*Conversion!
RevisedPropB! =
A11Prop.PropB * Conversion!
RevisedPropC!
AllProp.PropC * Conversion!
RevisedPropD! _
AllProp.PropD * Conversion!
CASE 2
RevisedPropB! =
(AllProp.PropB -
ALns(LineNo).Threshold)*Conversion!

CA 02483943 2004-11-16
- 94 -
RevisedPropA! _
AllProp.PropA * Conversion!
RevisedPropC! _
AllProp.PropC * Conversion!
RevisedPropD! =
AllProp.PropD * Conversion!
CASE 3
RevisedPropC! =
-
(AllProp.PropC
ALns(LineNo).Threshold)*Conversion!
RevisedPropB! _
AllProp.PropB * Conversion!
RevisedPropA! =
AllProp.PropA * Conversion!
RevisedPropD! _
AllProp.PropD * Conversion!
CASE 4
RevisedPropD! _
(A11Prop.PropD -
ALns(LineNo).Threshold)*Conversion!
RevisedPropB! _
AllProp.PropB * Conversion!
RevisedPropC! _
AllProp.PropC * Conversion!
RevisedPropA! _
AllProp.PropA * Conversion!
END SELECT
'adjust so props total 1
SumProp! = RevisedPropA! + RevisedPropB! +
RevisedPropC! + RevisedPropD!
N1k1! = 1 / SumProp!
AllProp.PropA = RevisedPropA! * Mk1!
A1lProp.PropB = RevisedPropB! * Mk1!
AllProp.PropC = RevisedPropC! * Mkll
AllProp.PropD = RevisedPropD! * Mkl!
END IF
A11SumdPt.x = AllProp.PropA *
GetAReal!(APtsXPg, PtNo) +
AllProp.PropB *
GetAReal!(BPtsXPg, PtNo) +
AllProp.PropC *
GetAReal!(CPtsXPg, PtNo) +
A11Prop.PropD * .
GetAReal!(DPtsXPg, PtNo) +
Disp.x
Al l StundPt . y= A11Prop. PropA *
GetAReal!(APtsYPg, PtNo) +
AllProp.PropB *
GetAReal!(BPtsYPg, PtNo) +
AllProp.PropC *
GetAReal!(CPtsYPg, PtNo) +
*
AllProp.PropD
GetAReal!(DPtsYPg, PtNo),+
Disp.y

CA 02483943 2004-11-16
- 95 -
AllSumdPt.Z = A11Prop.PropA *
GetAReal!(APtsZPg, PtNo) +
AllProp.PropB *
GetAReal!(BPtsZPg, PtNo) +
A11Prop.PropC *
GetAReal!(CPtsZPg, PtNo) +
AllProp.PropD *
GetAReal!(DPtsZPg, PtNo) +
Disp.Z
IF FinlSgs(SegNo).WchInfoArr <> 0 THEN
SegPtNo = PtNo - BeginPt + 1
GetSumWarpDisp SegInfoLstO, SeglnfLstlndx,
FrameNo, SegNo, SegPtNo, SumWarpDisp
A1lSumdPt.x = AllSumdPt.x + SumWarpDisp.x
A1lSumdPt.y = AllSimidPt.y + SumWarpDisp.y
AllSumdPt.Z = AllSumdPt.Z + SumWarpDisp.Z
END IF
IF AncRun = False OR
(AncRun = True AND Second = 2) TFTETT
SaveLineIndex = SaveLinelndex + 1
'index for complete line (each pt of
each seg of the line is added to this)
SetArrayReal FastWorkArraylXPg, SaveLineIndex,
ObjPathPosit.x - (PFac! *
(AllSumdPt.x - ObjPathPosit.x))
SetArrayReal FastWorkArraylYPg, SaveLineIndex,
ObjPathPosit.y - (PFac! *
(A1lSumdPt.y - ObjPathPosit.y))
SetArrayReal FastWorkArraylZPg, SaveLineIndex,
ObjPathPosit.Z - (PFac! *
(AllSumdPt.Z - ObjPathPosit.Z))
SetA FastWorkArraylXPg, 0,'SaveLineIndex
record pts of line without path position
and perspective, so when saved appears in
subsequent runs as first drawn:
IF SaveThisRun = True AND
FrameNo = FinishFrame THM
SaveWhl2mgIndex ='SaveWhllmglndex + 1
SetArrayReal TempPtsXPg, SaveWhllmgIndex,
A11SumdPt.x - Disp.x
SetArrayReal TempPtsYPg, SaveWhlImglndex,
A11SumdPt.y - Disp.y
SetArrayReal TempPtsZPg, SaveWhllmglndex,
Al1SumdPt.Z - Disp.Z
SetA TempPtsXPg, 0, SavewhlimgIndex
END IF
END IF
IF GetObjDispVals = True THEN
PtVal.x = ObjPathPosit.x - (PFac! *
(A11SumdPt.x - ObjPathPosit.x))
PtVal.y = ObjPathPosit.y - (PFac! *
(AllSumdPt.y - ObjPathPosit.y))
PtVal.Z = ObjPathPosit.Z - (PFac! *

CA 02483943 2004-11-16
- 96 -
(Al1SumdPt.Z - ObjPathPosit.Z))
IF FrameNo = FirstAncFrm THEN
StaticAncVal.x = PtVal.x
StaticAncVal.y = PtVal.y
StaticAncVa1.Z = PtVal.Z
END IF
AncDisp.x = StaticAncVal.x - PtVal.x
AncDisp.y = StaticAncVal.y - PtVal.y
AncDisp.Z = StaticAncVa1.Z - PtVal.Z
MD IF
FOR q = 1 TO NoOfVelcros
IF VelcroAGrp(q).HookPtIndex = PtNo AND
GetObjDispVals = False THEN
VelcroAGrp(q).HookXYZVals.x =
GetAReal!(FastWorkArraylXPg,
SaveLineIndex)
VelcroAGrp(q).HookXYZVals.y =
GetAReal!(FastWorkArraylYPg,
SaveLinelndex)
VelcroAGrp(q).HookXYZVa1s.Z =
GetAReal!(FastWorkArraylZPg,
SaveLineIndex)
END IF
NEXT
NF.XT 'point along the seg
END IF 'the seg belongs to the line
NEXT 'seg
IF GetObjDispVals = False THM
SaveLinelndex = 0 'reset semifinalpts index to 0
TnnsfrWhlArray FastWorkArraylXPg, FastWorkArray2XPg
LineCol = ALns(LineNo).LineCol
PaintCol = ALns(LineNo).PaintCol
IF Record$ = "No" THEN DrawArray
FastWorkArray2XPg, -1, True
IF Record$ = "RecordS4" THEN
SCREEN 9, , 0, 1
EyeDiff! = GetAReal!(FastworkArray2ZPg, 1) /
ZDivisor
XPt = GetAReal!(FastWorkArray2XPg, 1) - EyeDiff!
YPt = GetAReal!(FastWorkArray2YPg, 1)
PSET (XPt, YPt), 1
FOR J = 2 TO GetA(FastWorkArray2XPg, 0)
EyeDiff! = GetAReal!(FastWorkArray2ZPg, J) /
ZDivisor

CA 02483943 2004-11-16
- 97 -
XPt = GetAReal!(FastWorkArray2XPg, J) - EyeDiff!
YPt = GetARea1!(FastWor7sArray2YPg, J)
LINE -(XPt, YPt), 1
AtEXT
SCREEN 9, , 1, 0
EEyeDiff! = GetAReal!(FastWorkArray2ZPg, 1) /
ZDivisor
XPt = GetAReal!(FastWorkAxray2XPg, 1) + EyeDiff!
YPt = GetAReal!(FastWorkArray2YPg, 1)
PSET (XPt, YPt), 1
FOR J = 2 TO GetA(FastWorkP,rray2XPg, 0)
EyeDiff! = GetAReal!(FastWorkArray2ZPg, J) /
ZDivisor
XPt = GetAReal!(FastWorkArray2XBg, J) +.EyeDiff!
YPt = GetAReal!(FastWorkArray2YPg, J)
LINE - (XPt, YPt), 1
NEXT
END IF
IF ALns(LineNo).Looped = 0 TiEN 'not a loop
IF Record$ = "RecordS6" THM
WriteXFerlnfo eStartEntity + eNonLooped +
eNonFilled, 0, 0, 0, 0
Write70:'erinfo eSetLineWidth, 1, 0, 0, 0
WriteXFerInfo eSetMix, 01 0, 0, 0
WriteXFerlnfo eSetColor, ALns(LineNo).LineCol,
0. 0, 0
WriteXF'erinfo ePointAt, 0,
GetAReal!(FastWorkArray2XPg, 1) - 320,
GetAReal!(FastWorkArray2YPg, 1) - 175,
-GetAReal!(FastWorkArray2ZPg, 1) + 1200)
FOR J= 10 TO GetA(FastWorkArray2XPg, 0) STEP 10
WriteXFerlnfo eLineTo, 0,
GetAReal!(FastWorkArray2XPg, J) - 320,
GetAReal!(FastWorkArray2YPg, J) - 175,
-GetAReal!(FastWorkArray2ZPg, J) + 1200)
NEXT 'non closed line is finished
J = GetA(FastWorkArray2XPg, 0)
IF J MOD 10 <> 0 4HM
WriteXFerlnfo eLineTo, 0,
GetAReal!(FastWorkArray2XPg, J) - 320,
GetAReal!(FastWorkArray2YPg, J) - 175,
-GetAReal!(FastWorkArray2ZPg, J) + 1200)
END IF
END IF 'if not a loop
IF ALns(LineNo).Looped > 0 THM 'line is a loop
IF Record$ = "RecordS6" THEN
IF PaintCol <> -1 THEN 'paint col -1 is
flag for no fill
WriteXFerlnfo eStartEntity + eLooped +
eFilled, ALn.s(LineNo).PaintCol, 0, 0, 0
ELSE
WriteXFerlnfo eStartEntity + eLooped,
0, 0. 0. 0
END IF
WriteXFerlnfo eSetLineWidth, 1, 0, 0, 0
WriteXFerinfo eSetMix, 0, 0, 0, 0
WriteXFerlnfo eSetColor, ALns(LineNo).LineCol,
0, 0, 0

CA 02483943 2004-11-16
- 98 -
WriteXFexlnfo ePointAt, 0,
GetAReal!(FastWorkArray2XPg, 1) - 320,
GetAReal!(FastWorkArray2YPg, 1) - 175,
-Get.AReal!(FastWorkArray2ZPg, 1) + 1200)
FOR J = 10 TO GetA(FastWorkArray2XPg, 0) STEP 10
WriteXFerlnfo eLineTo, 0,
GetAReal!(FastWorkArray2XPg, J) - 320,
GetAReal!(FastWorkArray2YPg, J) - 175,
-GetAReal!(FastWorkArray2ZPg, J) + 1200)
NEXT
WriteXFerInfo eLineTo, 0,
GetAReal!(FastWorkArray2XPg, 1) - 320,
GetAReal!(FastWorkArray2YPg, 1) - 175,
-Get.AReal!(FastWorkArray2ZPg, 1) + 1200)
END IF 'if record$=S6
EM IF ' if line is a loop
END IF 'IF GetObjDispVals = False
END IF ' if Threshold ok
m1D IF 'if line belongs to object
ALns(LineNo).TempFin = TempLineBegFinlndex
NEXT 'line
END. IF 'if grp belongs to object
NEXT 'Group
NEXT 'Pass
IF FrameNo > FinishFrame - 6 THM
IF ObjNo = 1 THEN ObjFinalPositions(FinishFrame - FrameNo).
FinalPositObjl = ObjPathPosit
IF ObjNo = 2 THEN ObjFinalPositions(FinishFrame - FrameNo).
FinalPositObj2 = ObjPathPosit
IF ObjNo = 3 THEN ObjFinalPositions(FinishFrame - FrameNo).
FinalPositObj3 = ObjPathPosit
E1QD IF
END IF 'if visible
NEXT 'object
IF OneFrameOnly = True THM GOTO Skip2:
IF Record$ = "No" THM
COLOR 5
LOCATE 1, 1: PRINT RecordFrameNo
SWAP apage, vpage
SCREEN 9, , apage, vpage
CLS
END IF
IF Record$ _ "RecordS4" THM
SCREEN 9, 0, 1
LOCATE 1, 1: PRINT SnapName$; RecordFrameNo
SCREM 9, , 1, 0
LOCATE 1, 1: PRINT SnapName$; RecordFrameNo
Snap5hot ASC(LEFT$(SnapName$, 1)) * 256 +
ASC(RIGTiT$(SnapName$, 1)), RecordFrameNo
SCREEIiT 9, , 1, 0
CLS
SCREEN 9, , 0, 1
CLS
END IF
ALns(1).Beg = 1: ALns(1).Fin = ALns(1).TenpFin
FOR I = 2 TO NoOfLines
ALns(I).Beg = ALns(i - 1).Fin.+ 1
ALns(I).Fin = ALns(I).Beg + ALns(I).TenpFin - 1
NEXP

CA 02483943 2004-11-16
- 99 -
IF SaveThisRun = True AND FrameNo = FinishFrame THEN
BEEP
OPEN "k:\Projects\Irnax\Tweeny\Pau1\" + RunName$ + ",TWS" FOR
BINARY AS #1
EndOfPts = GetA(TempPtsXPg, 0)
PUT #1, , EndOfPts
FOR I= 1 TO EndOfPts
XVal! = GetARea1!(TempPtsXPg, I)
YVal! = GetAReal!(TempPtsYPg, I)
ZZVa1! = GetARea1!(TempPtsZPg, I)
PUT #1, , XVal!
PUT #1, YVa1!
PLTT #1, , ZVa1!
NEXT
SCREEN 9, 0, 0
CLS
PRINT "recorded array"
DrawPartialArray TempPtsXPg, 1, GetA(TempPtsXPg, 0), -1, False
SLEEP 1
SCREEDT 9, , apage, vpage
PUT #1, , NoOfLines
FOR I= 1 TO NoOfLines
PUT #1, , ALns(I)
NEXT
PUT #1, , NoOfGroups
FOR I = 1 TO NoOfGroups
PUT #1, , Group(I)
NEXT
PUT #1, , NoOfObjects
FOR I = 1 TO NoOfObjects
PUT #1, , Object(I)
NEXT
FOR I= 1 TO NoOfObjects
PUT #1, . AObjCntr(I)
NEXT
B'ORI=1TO5
PUT #1, , bbjFinalPositions(I)
NFCT
PUT #1, , RecordFrameNo
CLASS #1
EM zF
Skip2:
NEXT 'FrameNo
COLOR 5
IF OneFrameOnly = True THEA7 GOTO OneFrameOnlySkip
SCRESTT 9, , 0, 0
COLOR 5
LOCATE 10, 1: PRINT RunName$; RecordFrameNo
IF Record$ _"No" TMN LOCATE 11, 1: PRINT "NOT RECORDED!
SCREEN 9, . 1, 1
COLOR 5
LOCATB 10, 1: PRINT RunName$; RecordFrameNo
IF Record$ = "No" TFM LOCATE 11, 1: PRINT "NOT RECORDED!
COLOR 5
IF Record$ = "Records6" THM
CLOSE #2
PRINT "closed S6"
END IF

CA 02483943 2004-11-16
- 100 -
IF Conf irm ("See Again?") THEN
IF Confirm("Make Adjustments?") THEN
SELECT CASE UserChoice("Adjust Vhat?", "Vislnvis",
"IntermitLn",
CASE 2: MrkVisInvisLine
CASE 3: birklntermtLine
END SELECT
END IF
GOTO StartOver
END IF
OneFrameOnlySkip:
COLOR 5
END SUB
SUB CrsrOn
PUT (10, 10), LCrsr: PUT (20, 10), RCrsr
LastMrkrPts.lx = 10: LastCrsPos.rx = 10: LastCrsPos.y = 0
LastCrsPos.lx = 10: LastCrsPos.rx = 20: LastCrsPos.y = 10
END SUB
SUB D3Wave (RequiredLengthOfWave)
CLS
WaveRefOK = False
WHILE NOT WaveRefOK
DO
CLS
DefnPt WaveRefStart, "Mrk Start Of Wave Reference Line
(Must Be Longer Than Wave To Be Drawn)",
"DefnStartWaveRefLine", 3
SetArrayReal FastWorkArraylXPg, 1, XYZ.x
SetArrayReal FastWorkArraylYPg, 1, XYZ.y
SetArrayReal FastWorkArraylZPg, 1, XYZ.Z
DefnPt WaveRefEnd, "Mrk End Of Wave Reference Line",
"DefnEndWaveRefLine", 3
SetArrayReal FastWorkArraylXPg, RequiredLengthOfWave, XYZ.x
SetArrayReal FastWorkArraylYPg, RequiredLengthOfWave, XYZ.y
SetArrayReal FastWorkArraylZPg, RequiredLengthOfWave, XYZ.Z
SetA FastWorkArraylXPg, 0, RequiredLengthOfWave
Interpo FastWorkArraylXPg, 1, RequiredLengthOfWave
DrawPartialArray FastWorkArraylXPg, 1, RequiredLengthOfWave, -1,
True
LOOP UNTIL Confirm("Ref Line OK?")
DO
MkUniPath "Wave ", eWaveShape
LOOP UNTIL Confirm("OK?")
PRINT "Required Length"; RequiredLengthOfWave
PRINT "Length=", GetA(TempPtsXPg, 0)
SLEEP 3
IF RequiredLengthOftnTave <= GetA(TempPtsXPg, 0) THEN
WaveRefOK = True
ELSE
LOCATE 2, 30: PRINT "Wave Too Short, ReDo ": SLEEP 2
CLS

CA 02483943 2004-11-16
- 101 -
E.'LT1D IF
WFI+7D
PRINT "Figuring..."
istart = 1: jstart = 1 'wave is temppts(j), refline is workarrayl(i)
FOR J= 1 TO GetA(TempPtsXPg, 0) 'travels along wave
PrevDist! = 0
K = 0
FOR I = istart TO RequiredLengthOf0lave 'travels along refline
K = K + 1
ThisDist! = DistBet2Pts!(FastWorkArraylXPg, TempPtsXPg, I, J)
IF K > 1 AND PrevDist! < ThisDist! THIIJ
SetArrayReal FastWorkArray2XPg, J.
GetAReal!(FastWorkArraylXPg, I - 1) -
GetAReal!(TenpPtsXPg. J)
SetArrayReal FastWorkArray2YPg, J,
GetAReal!(FastWorkArraylYPg, I - 1) -
GetAReal!(TempPtsYPg, J)
SetArrayReal FastWorkArray2ZPg, J,
GetAReal!(FastWorkArraylZPg, I - 1) -
GetAReal!(TempPtsZPg, J)
LINE (J + 10, 136 + GetAReal!(FastWorkArray2YPg, J))-
(J + 10, 137 + GetAReal!(FastWorkArray2YPg, J))
istart = I - 2
EXIT FOR
END IF
PrevDist! = ThisDist!
NEXT
N7EXT
SLEEP 1
SetA FastWorkArray2XPg, 0, RequiredLengthOfwave
'main program puts FastWorkArray2XPg into JAPtsXPg etc.
END SUB
SUB DefnGrpsObjs
DO Wt3ILS GroupsDefnd = False
ShortCutGroups
IF GroupsDefnd = True THM EXIT DO
IdentGroups
LOOP
WHILE GroupsNamed = False
NameGroups
WEND
DO WHILE ObjectsDefnd = False
ShortCutObjects
IF ObjectsDefnd = True TFm EXIT DO
IdentObjects
LOOP
WHILE ObjectsNamed = False
Nameobjects
WFND
FOR I = 1 TO NoOfObjects
Object(I).StartVis = 1
Object(I).EndVis = NoOfFrames
NEXT
FOR I = 1 TO NoOfObjects
ShowObj I, 1
NEXT
END SOB

CA 02483943 2004-11-16
- 102 -
SUB DefnObjCntrs
FOR I = 1 TO NoOfObjects
IF LinkingToPreviousRun = True;TFB;N
FirstPoseToMark = 2
DrawPartialArray APtsXPg, 1, GetA(APtsXPg, 0), -1, False
XYZ = AObjCntr(I): Mrk 2, 1
LOCATE 2, 30
PRINT 'Note Handle Posit (Triangle) In This
Object In Previous Run. (Press Any Key)"
SLEEP
LOCATE 2, 30: PRINT SPACE$(79)
ELSE
FirstPoseToMark = 1
END IF
FOR Pose = FirstPoseToNark TO.4
IF FirstPoseToMark = 1 TMM CLS
ShowObjectSegs I, Pose, -1, True
F$ _"Click On A Point To Use As A Handle For <" +
CHR$(Pose + 64) +'> Source Pose of + Object(I).Label +
~ OBJECT"
MrkObjCntr F$, Pose, I
NMT
ReCntrObj I, BPtsXPg, BObjCntrO
ReCntrObj I, CPtsXPg, CObjCntr()
ReCntrObj I, DPtsXPg, DObjCntrO
CLS
FORJ= 1TO4
LOCATE 3, 1: PRINT "Pose'; J; "Of "; Object(I).Label; " OBJECT"
ShovuobjectSegs I, J, -1, True
SLEEP 1
CLS
NEXT
NEXT
IF NoOfGroups > 1 TMLV
FOR I = 1 TO NoOfGroups
FOR Pose = 1 TO 4
C'L.S
ShowGrp Pose, I, -1
F$ = "Click On A Point To Use As A Handle For <" +
CHR$(Pose+64) +"> Source Pose of "+ Group(I).Label +
" GROUP"
MrkGrpCntr F$, Pose, I
NE}PP
ReCntrGrp I, BPtsXPg, BGrpCntr(1
ReCntrGrp I, CPtsXPg, CGrpCntrO
ReCntrGrp I, DPtsXPg, DGrpCntr()
CLS
NEXT
END IF
END SUB
SUB DefnPt (DefndPoint AS t3DPoint, Message$, PtIsFor$, WchMrkr)
IF PtIsFor$ ="DefnScaffoldPts" OR PtlsFor$ ="MarkSpaceRefPts" THEN
C$ = "Done" ELSE C$ = "x"
WndChs "", "x", "x", C$, "X", "x"/ An5$, 1
LOCATE 2, 1: PRINT Message$
Finished = False
DO

CA 02483943 2004-11-16
- 103 -
Wndln
ShowCrsr
IF INP ( 889 )< 128 THEN
DefndPoint = XYZ
Mrk WchMrkr, 1
MyDelay 1
Finished = True
END IF
IF PtlsFor$ ="DefnScaffoldPts= OR PtIsFor$ _"MarkSpaceRefPts" THEN
IF XYZ.y < 15 THEN
wnaslGt Ans$, 0
IF Ans$ = C$ THEN MyDelay 1: EXIT DO
E[4D IF
EIVD IF
IF Finished = True THM EXIT DO
LOOP
LOCATE 2, 1: PRINT SPACE$(79)
END SUB
SUB DefnSegWarp (WarpNumber, Av1Pth, AvlWarpProflArray)
Av1PthOnEntry'!'oWarp = AvlPth
WaveLen = 0
SumPrev = 0
NoInSrs = 0
geg{Atarp = False: WaveWarp = False: UsesPrevPath = False
AllDone = False: SegOK = False
WarpNo = WarpNumber
cLs
,***************** what kind of warp
REDOLINK:
Text$ = "Link " + Warp(WarpNumber).Label + " To"
A$ = "Wind": B$ = "Iner": C$ = "Time": D$ "Wave'
WndChs Text$, A$, B$, C$, D$, Ans$, 0
Kind$ = Ans$
SELECT CASE Ans$
CASE A$, B$, C$
SegWarp = True: AvlPth = AvlPth + 1
AvlWarpProflArray = AvlWarpProflArray + 1
CASE D$
WaveWarp = True: WaveNo = WaveNo + 1
AvlWaxpProflArray = AvlWarpProflArray + 1
'used for seg wave warp profile
A$ = "1"= B$ = "2": C$ = "4": D$ = "6": E$ = "8"
WndChs "Wave Speed?", A$, B$, C$, D$, E$, Ans$, .0
WaveSpeed = VAL(Ans$)
B$ = "HeadToTail": C$ = "TailToHead"
WndChs "Wave Moves Which Direction On Seg?",
,X,, B$, C$, liX , ,Xl- Ans$, 0
SELECT CASE Ans$
CASE B$: Direc$ = "HtoT"
CASE C$: Direc$ = "TtoH"
END SELECT .
B$ = "On Seg": C$ = "OffSeg": WndChs "WaveStarts",
"X,l, B$, C$, Ans$, 0
SELECT CASE Ans$
CASE B$: 'overlap at start
B$ = "On Seg": C$ _"OffSeg": WndChs "Wave Ends ",
- "~{"/ B$, C$, "X"/ "X", Ans$I 0 . . .

CA 02483943 2004-11-16
- 104 -
SELECT CASE Ans$
CASE B$: OverLap = 0 overlap at end
CASE C$: OverLap = 1 no overlap at end
ELJA SELECT
CASE C$: 'no overlap at start
B$ ="On Seg": C$ ="OffSeg": WndChs "Wave Ends ",
"x", B$, C$, "x", "x", Ans$, 0 SELECT CASE.Ans$
CASE B$: OverLap = 2 overlap at end
CASE C$: OverLap = 3 ' no overlap at end
END SELECT
END SELECT 'WL is iinultiplied by NoFrames and Speed just
before call to D3
E61D SEL,ECT
******************* use a previous warp path or wave?
IF WarpNO > 1 TMW
IF Kind$ ="Time",OR Kind$ ="Iner" OR Kind$ ="Wind" TIIEM
Text$ = "Use Just Previous Warp Path? (Displacement
is Between Path and Warp Handle)'
IF Kind$ ="Wave" THF,N Text$ _"Use Just Previous Wave?"
IF Confirm(Text$) THEN
UsesPrevPath = True
Av1Pth = Av1Pth - 1
END IF
E[JD IF
********** show segs, place handle and choose which segs to be warped
DrawPartialArray APtsXPg, 1, FinlSgs(NoOfSegs)Fin, -1, False
ShowAllSegStarts
IF SegWarp = True THEN
IF UsesPrevPath = False THEN Text$ "Mrk Warp Path Handle On Seg
ELSE Text$ ="Mrk Warp Handle Same Place As Previous
FindNirkdPtlnAPose Hndl, Text$
END IF
D$ ="Done": WndChs "Mrk Seg(s) to'be Warped
,.. , . . . . "X , "X", "X", D$, "X", Ans$, 1
DO WHILE AilDone = False
Wndin
ShowCrsr
IF XYZ.y < 15 THEN
WndSlct Ans$, 0
IF Ans$ = D$ AND SegOK = True THEN AllDone = True: EXIT DO
END IF
IF INP(889) < 128 TFO;N
FoundIt = False
WHILE Foundlt = False
FindInApts FoundSegPt
IF Foundit = False THEN GetWndXYZ 0
4VFND
MyDelay 1
FoundSeg = FindWchFinlSg(FinlSgsO, FoundSegPt)
FOR J = 1 TO NoInSrs
IF FoundSeg = WarpSrs(J, 1) THEN
SegOK = False: LOCATE 2, 1: PRINT "Seg Mrked Already"

CA 02483943 2004-11-16
- 105 -
Nrk 0, 1: MyDelay 1: LOCATE 2, 1: PRINT SPACE$00)
F~TD IF
NEXT
ChoicelnSegHili = True
HiLiFinlSg FoundSeg
Finlsgs(FoundSeg).WarpNo = WarpNo
SegOK = True
Length = FinlSgs(FoundSeg).Fin FinlSgs(FoundSeg).Beg + 1
PreviousSumPrev = SumPrev
SumPrev = SumPrev + Length
NolnSrs = NolnSrs + 1
WarpSrs(NoInSrs, 1) = FoundSeg
WarpSrs(NoInSrs, 0) = Length
Av1InfArr = AvlInfArr + 1
FinlSgs(FoundSeg).wchlnfoArr = AvllnfArr
Seglnfo(AvlInfArr).WchSeg = FoundSeg
Seglnfo(AvlInfArr).SegLen = Length
IF SegWarp = True THEN
Seglnfo(Av1lnfArr).Hndl = Hndl
SegInfo(Av1InfArr).WchPath = AvlPth 'if prevpath is used this
is what sets same path as
prev warp for this warp
END IF
IF WaveWarp = True THEN
SegInfo(AvllrnfArr).WchWave = WaveNo
Seglnfo(AvlInfArr).WaveSpeed = WaveSpeed
SegInfo(Av1lnfArr).Direc = Direc$
SegInfo(AvlInfArr).OverLap = OverLap 'wave starts ends on off seg
WaveLen = sumPrev
E[JD IF
the following is comawn for seg and wave warps
SegInfo(Av1InfArr).WchProf = AvlWarpProflArray
Seglnfo(AvlInfArr).Kind = Kind$
IF NoInSrs = 1 THM Seg1nfo(Av11nfArr).ProfBeg = 1
IF NoInSrs > 1 THEN SegInfo(AV1InfArr).ProfBeg = PreviousSumPrev
IF NoInSrs = NoOfSegs THEN EXIT DO
D$ "Done"
WndChs "Mrk Seg(s) to be Warped ", "x", "x", "x", D$, "x", Ans$, 1
EDTD IF 'button pushed
LOOP
IF SegWarp = True TFM '(warp is not a wave warp)
syncPtIndexAtStartOfWarp = SyncPtlndex
IF UsesPrevPath = False THEN
'*****************"** draw path for handle

CA 02483943 2004-11-16
106
no
PathOk = False
PathError = False
DO WHILE PathOk = False
MkUniPath "Segment Warp ", eWarpPath
IF Confirm("OK?") THEN
PathOk = True
ELSE
DrawArray TenpPtsXPg, 0, True
ENDIF
L'OOP
IF LnEYi1dsClose(TempPtsXPg, 1, GetA(TempPtsXPg, 0), 20) THEN
IF Confirm("Mk Cycle?") THEN
DrawArray TempPtsXPg, 0, False
SmoothJoin TempPtsXPg, 30
DrawArray TempPtsXPg, -1, False
END IF
END IF
õr******************* time warp
IF Rind$ _ "Time" THEN
I = WarpNumber
CLS
DrawPartialArray TempPtsXPg, 1, GetA(Te,rapPtsXPg, 0), -1, False
SELECT CASE UserChoice("Use Warp Path Sync Pts?", "",
"On Path", "OnFzmChrt", "No",
CASE 2 'on path
P1aceSyncPtsOnTempPath 3, I, ' Warp +
Warp(WarpNiunber) .Label
SortSyncPtsForApplic 3, I
SwapSortedSyncPts
CASE 3 'on frm chrt
ShowSyncPtLines SyncPtIndexAtStartOfWarp
PlaceSyncPtsOnFrmChrt 3, I, " Warp " +
Warp(WarpNumber).Label
SortSyncPtsForApplic 3, I
SwapSortedSyncPts
DrawArray TempPtsXPg, -1, False
P1aceFxmChrtSyncPtsOnPath 3, I
CASE 4
SortSyncPtsForApplic 3, I
SortedSyncPts(1).Frame = 1
SortedSyncPts(1).TeWPts1ndex = 1
SortedSyncPts(2).Fram.e = NoOfFrames
SortedSyncPts(2).TempPtslndex = GetA(TenpPtsXPg, 0)
IIJD SELECT
RedoVelGraphForWarp:
Text$ = "Velocity Graph For Movement Of Warp Handle Along
Warp Path"
DoVelocityGraph TenpPtsXPg, RawPtsXPg, Text$
END IF
LOOP WHILE PathError = True
****************** if inertia warp then get accelerations
Redolner:

CA 02483943 2004-11-16
- 107
IF Kind$ _"Iner" THEN 'have to smooth velocities for a
smooth curve
'******* derive acceleration and find max accel
CLS
FOR I= 1 TO NoOfFrames
SetArrayReal FastWorkArraylXPg, I, FrmToFrmVelocity!(I) * 100
NEXT
SetArrayReal FastWorkArraylXPg, 0, NoOfFrames
SetArrayReal FastWorkArraylXPg, 1, GetAReal!(FastWorkArraylXPg, 2)
SetArrayReal FastWorkArraylXPg, 0, GetAReal!(FastWorkArraylXPg, 2)
FOR I = 1 TO NoOfFrames
LOCATE 2, 1: PRINT "original frm to frm vel * 100"; I
LINE (I, 150)-(I, 150 + GetAReal!(FastWorkArraylXPg, I)), 10
13EXT
ST =E:F:P
FOR I = 1 TO NoOfFrames
FrmToFrmAccel! = GetAReal!(FastWorkArraylXPg, I) -
GetAReal!(FastWorkArraylXPg, I - 1)
SetArrayReal FastWorkArray2XPg, I, FrmToF'rmAccel!
NEX'P
SetArrayReal FastWorkArray2XPg, 1, GetAReal!(FastWorkArray2XPg; 2)
FOR I = 1 TO NoOfFrames
LOCATE 2, 1:.PRINT "raw frm to frm accel"; I
LINE (I, 150)-(I, 150 + GetAReal!(FastworkArray2XPg,I)*4), 11
NEXT
SLEEP
SetArrayReal FastWorkArray2XPg, 0, NoOfFrarnes
Smooth FastWorkArray2XPg, FastWorkArraylXPg, 2, False
Smooth FastWorkArraylXPg, FastWorkArray2XPg, 2, False
Smooth FastWorkArray2XPg, FastWorkArraylXPg, 2, False
Smooth FastWorkArraylXPg, FastWorkArray2XPg, 2, False
FOR I = 1 TO NoOfFrames
LOCATE 2, 1: PRINT "smoothed frm to frm accel"; I
LINE (I, 150)-(I, 150 + GetAReal!(FastWorkArray2XPg, I) * 4),13
NEXT
SLEEP
FOR I = 1 TO NoOfFrames
IF MaxAccel! < GetAReal!(FastWorkArray2XPg, I) THEN
MaxAccel! = GetAReal!(FastWorkArray2XPg, I)
A7ET
'******* use half of inertia warp path becuz shift index
'goes pos or neg, so total excursion = len of warp path
'!! warp path shid be smoothed, becuz accel controls
position on it, not some other velocity
Smooth TempPtsXPg, FastWorkArraylXPg, 5, False
Smooth FastWorkArraylXPg, TenpPtsXPg, 5, False

CA 02483943 2004-11-16
- 108
Ha1fOfWarpPath! = GetA(TempPtsXPg, 0) / 2'
FOR q = 1 TO NoOfFrames
PercentOfNaxAccel! = GetAReal!(FastWorkArray2XPg, q) / MaxAccel!
******* set ShiftIndex for each frame as a percentage of
the length of half the Warp Path (which is in temppts)
'Shiftlndex! = PercentOfMaxAccel! * Ha1fOfWarpPath!
Friction! _ .75: Flexibility! = 15
NewAccel! = NewAccel! - POSIT! / Flexibility! +
GetAReal!(FastWorkArray2XPg, q)
IF POSIT! > 0 TIiETt FrictionEffect! = Friction!
IF POSIT! < 0 THEN FrictionEffect! = -Friction!
POSIT! = POSIT! + NewAccel! - FrictionEffect!
Shiftlndex! = POSIT!
shift = CINT(Shiftlndex!)
LOCATE 2, 1: PRINT "shift"; q
LINE (q, 150)-(q, 150 + shift), 15
'******* when accel is 0 the position on the warp path is
half way along it so it can swing pos or neg:
FinalTempPtslndex = Ha1fOfWarpPath! + ShiftIndex!
IF FinalTempPtsIndex < 1 THE[J FinalTempPtsIndex = 1
IF FinalTempPtsIndex > GetA(TempPtsXPg, 0) TFTM
FinalTempPtslndex = GetA(TempPtsXPg, 0)
SetArrayReal RawPtsXPg, q,
GetAReal!(TempPtsXPg, FinalTempPtsIndex)
SetArrayReal RawPtsYPg, q,
GetAReal!(TempPtsYPg, FinalTempPtslndex)
SetArrayReal RawPtsZPg, q,
GetAReal!(TemnPtsZPg, FinalTe.mpPtsIndex)
CIRCLE (GetAReal!(RawPtsXPg,q), GetAReal!(RawPtsYPg,q)), 3, 10
NEXT
SetA RawPtsXPg, 0, NoOfFrames
SLEEP
END IF
RedoAirF:
IF Kind$ _ "Wind" TH8r1
******** find max wind velocity
FOR P = 1 TO NoOfFrames
IF MaxWindVel! < FrmToFrmVelocity!(P) THM
MaxWindVel! = P'rmToFxmVelocity!(P)
IF MaxWindVel! = 0 TEM MaxWindVel! =.01

CA 02483943 2004-11-16
- 109 -
NEXT
'******** get wind velocity for each frame as a
percentage of max velocity
FOR q 1 TO NoOfFrames
PercentMaxFrmVel! = FrmToFrmVelocity!(q) / MaxWindVel!
******* set Shiftindex for each frame as a percentage of
'the length of the Wind Warp Path (which is in temppts)
ShiftIndex! = PercentMaxFrmVel! * GetA(TempPtsXPg, 0)
IF Shiftindex! >,GetA(TempPtsXPg, 0) THEN Shiftlndex! _
GetA(Tem,pPtsXPg, 0)
IF Shiftindex! < 1 THEN ShiftIndex! = 1
,*******
SetArrayReal RawPtsXPg, q, GetAReal!(TempPtsXPg,
CINT(ShiftIndex!))
. NEXT
SetA RawPtsXPg, 0, NoOfFrames
Smooth RawPtsXPg, TempPtsXPg, 3, False
FOR q = 1 TO NoOfFrames
CIRCLE (GetAReal!(TempPtsXPg,q), GetAReal!(TempPtsYPg,q)),3,10
IXTEXT
EPID IF
IF NOT Confirm("OK?") THEN
IF Kind$ ="Iner" THEN GOTO RedoIner
IF Kind$ ="A'irF" TFIaT GOTO RedoAirF
IF Kind$ = "Time" GOTO RedoVelGraphForWarp
ENA IF
END IF 'if uses prevpath
END IF
IF WaveWarp = True AND UsesPrevPath = False THEDT
FOR I = I TO NoInSrs
TotalSegsLen = TotalSegsLen + WaxpSrs(I, 0)
NEXT
SELECT CASE OverLap
CASE 0: WL = 2 * Length * WaveSpeed 'ol at start ol at end
CASE 1: WL = Length * WaveSpeed 'ol at start no ol at end
CASE 2: WL = Length * WaveSpeed 'no ol at start ol at end
CASE 3: WL = Length * WaveSpeed 'no ol at start no ol at end
'WL is needed length of wave
END SELECT
D3Wave WL
END IF
CLS
main program now puts RawPts into avlpath
if a wave warp main program now puts FastWorkArray2XPg
into JAPtsXPg etc.
ET7D SUB
SUB DelLast (WchPose)
IF wchPose = 1 Z'FM DelLastLnPart2 AL,ns(), APtsXPg, WchPose

CA 02483943 2004-11-16
110
IF WchPose = 2 TMW DelLastLnPart2 BLns BPtsXPg, WchPose
IF WchPose = 3 THEN DelLastLaPart2 CLnsO, CPtsXPg, WchPose
IF WchPose = 4 Tfi8T7 DelLastLnPart2 DLnsO, DPtsXPg, WchPose
FND SUB
SUB DelLastLnPart2 (LnArrayO AS LineType, PtArray, WchPose)
Start = LnArray(LnNo).Beg 'start of last line
Finish = LnArray(LnNo).Fin 'end
DrawPartialArray PtArray, Start, Finish, 0, True
LnNo = LnNo - 1
IF LnNo > 0 THEN ShowGuideLn WchPose
SetA APtsXPg + 3*(WchPose - 1), 0, LnArray(LnNo).Fin
SetA RawPtsXPg, 0, 0
IF WchPose = 1 THEN
NoOfLines = NoOfLines - 1
ALns(0).Beg = NoOfLines
END IF
IIJD SUB
FUIVC7PION DistBet2Pts! (aArrayl, aArray2, aPointIndexl, aPointIndex2)
dx! = GetAReal(aArrayl + 0, aPointIndexl) -
GetAReal(aArray2 + 0, aPointindex2)
DY! = GetAReal(aArrayl + 1, aPointindexl) -
GetAReal(aArray2 + 1, aPointIndex2)
DZ! = GetAReal(aArrayl + 2, aPointlndexl) -
GetAReal(aArray2 + 2, aPointIndex2)
DistBet2Pts! = SQR(dx! * dx! + DY! * DY! + DZ! * DZ!)
END FUNCTION
FUNCTION DistToNextPoint! (aArray, aPointlndex)
dx! = GetAReal(aArray + 0, aPointIndex) -
GetAReal(aArray + 0, aPointIndex + 1)
DY! = GetAReal(aArray + 1, aPointIndex) -
GetAReal(aArray + 1, aPointTndex + 1)
DZ! = GetAReal(aArray + 2, aPointIndex) -
GetAReal(aArray + 2, aPointindex + 1)
DistToNextPOi.nt! = SQR(dx! *.dx! + DY! * DY! + DZ! * DZ!)
END FUTiCTION
SUB DoVelocityGraph (aDrawnPath, aFramePosArray, Text$)
ErsMnu
GetvelGraphFromPath (aDrawnPath)
Done = False
DO WHILE Done = False
CalcFramePositions aDrawnPath, aFramePosArray
IF PathError = True TFIW EXIT DO
DrawVelGraph aDrawnPath, aFramePosArray
LOCATE 3, 1: PRINT "FAST"
LOCATE 3, 1: PRINT Text$
LOCATE 4, 39: PRINT "Use REVISE To Enable Sync Pts"
SELECT CASE UserChoice("", "", "OK To Try", "Revise",
CASE 2: Done = True
CASE 3: GetVelGraphFromUser (aDrawnPath)
END SELECT
LOOP
END SUB
SUB Draw3DLine (aPointl AS t3DPoint, aPoint2 AS t3DPoint,
aColor AS INTEGER)

CA 02483943 2004-11-16
- 111 -
laX1 = CINT(aPointl.x - aPointl.Z / ZDivisor)
LX2 = CINT(aPoint2.x - aPoint2.Z / ZDivisor)
RXl = CINT(aPointl.x + aPointl.Z / ZDivisor)
RXZ = CINT(aPoint2.x + aPoint2.Z / ZDivisor)
IF aColor = -1 THEN
IF LX1 = RX1 AND LX2 = RX2 TfO;[Q
LINE (LX1, aPointl.y)-(LX2, aPoint2.y), 13
ELSE
LINE (LX1, aPointl.y)-(LX2, aPoint2.y), LCol
LINE (RX1, aPointl.y)-(RX2, aPoint2.y), RCol
END IF
ELSE
LINE (LXi, aPointl.y)-(LX2, aPoint2.y), aColor
LINE (RX1, aPointi.y)-(RX2, aPoint2.y), aColor
IIJD IF
II+7D SUB
Draw a three-D point on the screen Color -1 indicates anaglyph
SUB Draw3DPoint (aPoint AS t3DPoint, aColor AS INTEGER)
lx = CINT(aPoint.x - aPoint.Z / ZDivisor)
rx = CINT(aPoint.x + aPoint.Z / ZDivisor)
IFaColor=-1TFW
IF lx = rx THM
PSET (lx, aPoint.y), 13
EiaSE
PSET (lx, aPoint.y), LCol
P58T (rx, aPoint.y), RCol
END IF
ELSE
pSET (lx, aPoint.y), aColor
PSE'T (rx, aPoint.y), aColor
END IF
END SUB
SIJB DrawAPose
CLS
LineColor = 1 'Default color to start
Drawlmg 1
END StJB
SUB DrawArray (aArray, aColor, aUseLines)
DrawPartialArray aArray, 1, GetA(aArray, 0), aColor, aUseLines
END SUB
SUB DrawBCDPoses
WHILE DrawBPoseOK = False
CLS
LINE (10, 29)-(630, 340), 5, B
IF Scaffold = True THm
MrkScaffoldCntr "Mark Scaffold Center For B Pose", 1, 2
ShowScaffold 2
XYZ = BScaffoldC'ntr(1)
Mrk 2, i
showScaffold 1 'erases scaffold for previous pose
END IF

CA 02483943 2004-11-16
- 112 -
Drawim9 2
WF,[dD
WHILE DrawCPoseOK = False
CLS
LINE (10, 29)-(630, 340), 5, B
IF Scaffold = True THSN
MrkScaffoldCntr "Mark Scaffold Center For C Pose", 1, 3
3howScaffold 3
SYiowScaffold 2
XYZ = CScaffoldCntr(l)
Mrk 2, 1
II4DIF
Drawirng 3
viIIm
WHILE DrawDPoseOK = False
CLS
L,INE (10, 29)-(630, 340), 5, B
IF Scaffold = True TfM
MrkScaffoldCntr "Mark Scaffold Center For D Pose", 1, 4
ShowScaffold 4
Showscaffold 3
XYZ = DScaffoldCntr(2)
Mrk 2, 1
END IF
Drawlmg 4
WEND
IF DrawAPoseOK = True AND DrawBPoseOK = True AND
DrawCPoseOK = True AND DrawDPoseOK = True THEN ImOR = True
sELECT CASE UserChoice("", "", =", "Poses OK", "RedoPoses", "=)
CASE 4
Operation = 2
Eb7D SELECT
END SUB
SUB DrawImg (WchPose),
WchPoseForMag = WchPose
STATIC LinesToDraw
DIlm GuideBox AS t3DPoint
DIIm O1dXYZ AS t3DPoint
LINE (10, 29)-(630, 340), 5, B
IF LinkingToPreviousRUn = True OR ReUsingPoseAOnly = True TFEN
LinesToDraw = NoOfLines
SetA RawPtsXPg, 0, 0: LnNo = 0: SetA TenpPtsXPg, 0, 0
IF DeleteAllButPreviouslmage = True THEN
SELE7CP CASE WchPose
CASE 3: DrawArray APtsXPg, 0, True
IF ShowingScaffold = True THEN Showscaffold 1
CASE 4: DrawArray APtsRPg, 0, True: DrawArray BPtsXPg, 0, True
IF ShowingScaffold = True THEN ShowScaffold 2
END SELECT
E[JD IF
PutDzwMnuOnScrn Text$, WchPose, 0
FrstLn = False: Drawing = False: ImOK = False
LineStartMarked = False
IF WchPose = 1 AND LnNo = 0 TMW
LOCATE 2, 50:
IF LinkingToPreviousRun = False THM
PRINT "Line Color:"; LineColor
ELSE

CA 02483943 2004-11-16
- 113 -
pRINT "Line Color:"; ALns(LnNo).LineCol
END IF
END IF
IF WchPose = 1 TRW LOCATE 2, 65: PRINT "Lines Avl:"; 75 - LnNo
WchPoseForHili = WchPose
ShowGuideLn WchPose
DO
Wndin
ShowCrsr
IF XYZDiff TFM
IF INP(889) < 128 AND WchPose > 1 AND LinesToDraw > 0 AND
LnNo = LinesToDraw THIN
LOCATE 2, 1
PRINT "Last Line Already Done"
MyDelay 1
LOCATE 2, 1
PRIIVT SPACE$ (30)
GOTO RFDOLINEOK
END IF
IF INP(889) < 128 THEN
IF LineStartMarked = False THEN
GuideBox = XYZ
Mrk 1, 1
LineStartMarked = True
ZStartPt! = XYZ.Z
END IF
Draw3DPoint XYZ, -1
ZEndPt! = XYZ.Z
IF GlueLoops = True THM
IF index > 1 TFM
ZDisp = ZEndPt! - ZStartPt!
AbsZDisp = CINT(ABS(ZEndPt! - ZStartPt!))
IINID IF
IF AbsZDisp > 3 TFEN SOUND 30 * AbsZDisp, 1
END IF
FrstLn = True 'firstline needed to prevent accidental
exit when no line is there
IF Drawing = False THBN
Drawing = True
Index = 0
oID IF
index = Index + 1
IF XYZ.x <> 0 AND XYZ.y <> 0 THEN EnterRawPt Index
END IF
IF INP(889) >= 128 AND Drawing = True THEN
XYZ = GuideBox
Mrk 1, 1
LineStartMarked = False
Drawing = False
Smooth RawPtsXPg, TempPtsXPg, 3, True
'--------------- check loop closure----------------------
IF WchPose = 1 AND (MkLineLoop$ = "CnfirmEach" OR
MkLineLoop$ = "Automatic") THEN

CA 02483943 2004-11-16
- 114 -
IF LnEndsClose(TempPtsXPg, 1, GetA(TempPtsXPg, 0), 10) THEN
SELECT CASE MkLineLoop$
CASE "CnfirmEach"
IF Confirm("Glue Ends?") TMTT
IF GetA(TempPtsXPg, 0) > 30 THEN
SmoothJoin TeapPtsXPg, 30
ELSE
LOCATE 6, 1
PRINT "Too Small To SmoothJoin"
SLEEP 1
LOCATE 6, 1
PRINT'SPACE$(75)
ENDIF
LOCATE 2, 30: PRINT "Glued
MyDelay 1
LOCATE 2, 30: PRINT SPACE$(20)
ALns(LnNo + 1).Looped = 1
END IF
CASE "Autonatic"
IF GetA(TempPtsXPg, 0) > 30 TMM
SmoothJoin TempPtsXPg, 30
ELSE
LOCATE 6, 1
PRINT "Too Small To SmoothJoin"
SLEEP 1
LOCATE 6. 1
PRINT SPACE$(75)
ENDIF
LOCATE 2, 30: PRINT "Glued
MyDelay 1
LOCATE 2, 30: PRINT SPACE$(25)
ALns(LnNo + 1).Looped = 1
END SELECT
ELSE
BEEP
LOCATE 2, 30: PRINT "NOT A LOOP"
SLEEP 2
LOCATE 2, 30: PRINT SPACE$(25)
END IF
DO UNTIL XYZ.y > 15
Wndin
LOOP
END IF
IF WchPose > 1 AND ALns(LnNo + 1).Looped = 1 TMM
IF LnEndsClose(TempPtsXPg, 1, GetA(TempPtsXPg, 0), 10) THEN
LOCATE 2, 30: PRINT "Glued ": MyDelay 1
IF GetA(TempPtsXPg, 0) > 30 THErT SmoothJoin TenpPtsXPg, 30
LOCATE 2, 30: PRINT SPACE$(25)
ELSE
BEEP: BEEP
LOCATE 2, 28
PRINT "NO LOOP CLOSURE, YOU MUST DELETE AND REDO"
SLEEP 2
LOCATE 2, 28: PRINT SPACE$(65)
END IF
NNm IF

CA 02483943 2004-11-16
- 115 -
---------------end check loop closure-----------------------
LINEENTRY:
LnNo = LnNo + 1
IF NozmalIm = False TBERT ALns (LnNo) .NormOrNlag = 1 ELSE
ALns(LnNo).NormOrMag = 0
ALns(LnNo).StartVis = 1: ALns(LnNo).EndVis = NoOfFrames
putDrwMnuOnScrn Text$, WchPose, 0
IF WchPose =. 1 THFN
ALns(LnNo).LineCol = LineColor
LinesToDraw = LnNo
MagLinesToDraw = LnNo
NoOfLines = LnNo
ALns(0).Beg = LnNo
END IF
SELECT CASE WcbPose
CASE 1: LineLength(1, LnNo, 0) = GetA(TempPtsXPg, 0)
CASE 2: LineLength(2, LnNo, 0) = GetA(TempPtsXPg, 0)
CASE 3: LineLength(3, LnNo, 0) = GetA(TenpPtsXPg, 0)
CASE 4: LineLength(4, LnNo, 0) = GetA(TempPtsXPg, 0)
END SELECT
iF WchPose > 1 AND LineLength(WchPose, LnNo, 0) <
LineLength(WchPose - 1, LnNo, 0) / 2 TFEN
BEEP: LOCATE 2, 30: PRINT "LINE ENDED BY TRIGGER ERROR?"
SLEEP 2
LOCATE 20, 1: PRINT SPACE$(30)
END IF
IF WchPose = 1 TIiEN
LOCATE 2, 65: PRINT "Lines Avl:"; 75 - LnNo
LOCATE 2, 50: PRINT "Line Color:"; LineColor
END IF
IF WchPose > 1 THEN
IF LriNo = LinesToDraw TFM
PutDxwMnuOnScrn Text$, WchPose, 1
showScaffoZd WchPose - 1
END IF
END IF
TrnBfrTmpToImPartA WchPose 'transfers ternppts to appropriate
PtArray (Apts, BPts,etc.)
' and sets line info
DrawArray RawPtsXPg, 0, False 'erases RawPts on screen
ShowLn WchPose, LnNo, -1 'shows line
IF WchPose > 1 AND NOT ReUsingPrevLine THEN
ShowLn WchPose - 1, LnNo, 0
ReUsingPrevLine = False
ShowGuideLn WchPose 'shows guideline on previous Pose
(except for A Pose shows B Pose)
END IF
END IF
REDpLINEOK:
IF XYZ . y< 15 TFM
WndSlct Ans$, 1
SELECT CASE Ans$
CASE A$
IF WchPose = 1 THEN

CA 02483943 2004-11-16
IACATE 4, 1: PRINT SPACE$(35)
LOCATE 4, 1: INPUT "Line Name"; Name$:
ALns(LnNo).Label = UCASE$(Name$)
LOCATE 4, 1: PRINT SPACE$(35)
ELSE
ShowScaffold WchPose
ShowScaffold WchPose - 1
F~M IF
CASE B$ '(choose line color in Pose 1; use prev line in all
other Poses)
IF WchPose = 1 THEN
ChooseLineColor
PutDrwMnuOnScrn Text$, WchPose, 0
LoCATE 2, 50: PRINT "Line Color:"; LineColor
IF WchPose = 1 TFEN
LOCATE 2, 65
PRINT "Lines Avl:"; 75 - LnNo
EtdD IF
END IF
IF WchPose > 1 AND LnNo < LinesToDraw THM
ReUsingPrevLine = True
IF WchPose = 2 THM SourcePose = 1 'can only re-use line
from Pose 1
IF WchPose > 2 TFiEN
Text$ = "From What Pose?"
A$ = "A": B$ - "B": C$ -- "C"
SELECT CASE WchPose
CASE 3
WndChs Text$, A$, B$, "x", "x", "x", Ans$, 0
CASE 4
WndChs Text$, A$, B$, C$, "x", "x", Ans$, 0
END SELECT
SELECT CASE Ans $
CASE A$: SourcePose = 1
CASE B$: SourcePose = 2
CASE C$: SourcePose = 3
END SELECT
Em IF
DestinationPose = WchPose
TrnsfrPrevLineTolm SourcePose, DestinationPose, LnNo + 1
PutDxwMnuOnScrn WchPose, 0 ~as if drawn by wand
FrstLn = True 'when goes to LINEEN'PRY
GOTO LINEENTRY:
EtQD IF
CASE C$ (finished)
IF LnNo < LinesToDraw THEN
BEEP
LOCATE 5, 1: PRINT "Not Enough Lines
PlyDelay 1
LOCATE 5, 1: PRINT SPACE$(16)
END IF
IF FrstLn = True AND LnNo = LinesToDraw TMM
FrstLn = False
IF WchPose = 1 TFM DrawAPoseOK = True
IF WchPose = 2 THEN DrawBPoseOK = True
IF WchPose = 3 THEN DrawCPoseOK = True

CA 02483943 2004-11-16
- 117 -
IF WchPose = 4 THEN DrawDPoseOK = True
EDID IF
CASE D$ '(delete last line)
IF (NormalIm = True AND ALns(LnNo).NorniOrMag = 0) OR
(NormalIm = False AND ALns(LnNo).NormOrMag = 1) THEN
IF LnNo > 0 THEN DelLast WchPose
IF LnNo = 0 THEN FrstLn = False
IF WchPose = 1 THM
ALns(LnNo + 1).Looped = 0
LinesToDraw = LinesToDraw - 1
MagLinesToDraw = LinesToDraw
END IF
LOCATE 2, 60: PRINT "Lines Avl:"; 75 - LnNo
PutDrwMnuOnScrn "", WchPose, 0
ShowGuideLn WchPose
ELSE
LOCATE 7, 1: PRINT "Can't Delete A Line Drawn In A
Different Nlagnification"
SLEEP 2
LOCATE 7, 1: PRINT SPACE$ (75)
END IF
CASE E$ '(in Pose l this is intermittent line; in all others
is repeat whole of A Pose for all remaining Poses)
IF WchPose = 1 TFENN
PRINT "will be intermittent"
Intermittent = True
ELSE
SELECT CASE WchPose
CASE 2
TrnsfrATo BPtsXPg, BLns()
DrawBPoseOK = True
TrnsfrATo CPtsXPg, CLns ( )
DrawCPoseOK = True
TrnsfrATo DPtsXPg, DLns()
DrawDPoseOK = True
AllPosesSameAsA = True
CASE 3
TrnsfrATo CPtsXPg, CLnsO
DrawCPoseOK = True
TrnsfrATo DPtsXPg, DLnsO
DrawDPoseOK = True
CASE 4
TrnsfrATo DPtsXPg, DLnsO
DrawDPoseOK = True
END SELECT
RepeatA = True
END IF
END SELECT
END IF
IF (WchPose = 1 AND DrawAPoseOK = True) OR
(WchPose = 2 AND DrawBPoseOK = True) OR
(WchPose = 3 AND DrawCPoseOK = True) OR
(WchPose = 4 AND DrawDPoseOK = True) THIIV EXIT DO
LOOP
END SUB
SUB DrawPartialArray (aArray, aStart, aFinish, aColor, aUseLines)
DIM Ptl AS t3DPoint, Pt2 AS t3DPoint
IF aFinish > aStart THM

CA 02483943 2004-11-16
- 118 -
GetArrayReal aArray + 0, aStart, Ptl.x
GetArrayReal aArray + 1, aStart, Ptl.y
GetArrayReal aArray + 2, aStart, Pt1.Z
Draw3DPoint Pt1, aColor
FOR I = aStart + 1 TO aFinish
GetArrayReal aArray + 0, I, Pt2.x
GetArrayReal aArray + 1, I, Pt2.y
GetArrayReal aArray + 2, I, Pt2.Z
IFPt2.x=0TMW
LOCATE 5, 1: PRINT "You have drawn a line in which the value
of one point or more is zero"
SLEEP 2: LOCATE 5, 1: PRINT SPACE$ (79)
END IF
IF aUseLines = True TFM
Draw3DLine Ptl, Pt2, aColor
ptl = Pt2
ELSE
Draw3DPoint Pt2, aColor
END IF
NEXT
IIJD IF
IIQD S[7B
SUB DrawVelGraph (aDrawnPath, aFramePosArray)
CLS
DrawArray aDrawnPath, -1, True
FOR I= 1 TO GetA(aFramePosArray, 0)
XYZ.x = GetAReal!(aFramePosArray + 0, I)
XYZ.y = GetAReal!(aFramePosArray + 1, I)
XYZ.Z = GetAReal!(aFramePosArray + 2, I)
Mrk 0, 1
NEXT
LINE (0, 20)-(639, 20), 15
LINE (0, 320)-(639, 320), 15
LOCATE 3, 1: PRINT "FAST"
LOCATE 23, 1: PRINT "STATIC"
TextPos = 5
TextLineColor = 1
FOR I = 1 TO NoOfSortedSyncPts
TextLineColor = TextLineColor + 1
IF TextLineColor = 4 THETT TextLineColor = 5
IF TextLineColor = 7 TMI4 TextLineColor = 15
IF TextLineColor = 9 TfO;N TextLineColor = 10
IF TextLineColor = 16 THEN TextLineColor = 1
x = 40 + (SortedSyncPts(I).Frame - 1) * Interval!
LINE (x, 20)-(x, 320), TextLineColor
LOCATE I + 3, 1
IF I > 1 AND I < NoOfSortedSyncPts TMN
COLOR TextLineColor: PRINT SortedSyncPts(I).Label: COLOR 5
END IF
NEXT
FOR Frame = 1 Ta NoOfFrames
XPos = 40 + (Frame - 1) * interval!
LINE (XPos, 320)-(XPos, 325), 7
CIRCLB (XPos, 320 - 2 * FrmToFrmVelocity!(Frame)), 3, 15
NEXT
END SUB
SiJg EnterRawPt (Ptlndex)

CA 02483943 2004-11-16
- 119 -
SetArrayReal RawPtsXPg, Ptlndex, XYZ.x
SetArrayReal RawPtsXPg + 1, Ptlndex, XYZ.y
SetArrayReal RawPtsXPg + 2, Ptlndex, XYZ.Z
SetA RawPtsXPg, 0, PtIn.dex
END SUB
SUB ErsMnu
LINE (0, 0)-(639, 28), 0, BF
IIND SU$
FUNCTION FindAln (a'MatchPt, aPointNdx) Returns an index into the
line table
I = 0
DO: I=I+1
LOOP UMIL I > NoOfLines OR (aPointNdx >= ALns(I).Beg AND
aPointNdx <= ALns(I).Fin)
IF i <= NoOfLines TfM
FindAln = I
MtchPts(aMatchPt, 5) = P.Lns(I).WchGrp
MtchPts(aMatchPt, 6) = ALns(I).WchObj
MtchPts(aMatchPt, 7) = I
ELSE
FindAln = -1
END IF
E[JD FUNCTION
FUNCTION FindAlnForlntermit (WchPt)
I = 0
D0: I=I+1
LOOP UNTIL I > NoOfLines OR (WchPt >= ALns(I).Beg.AND
WchPt <= ALns(I).Fin)
IF I <= NoOfLines TMN
FindP,].nForlnterini.t = I
ELSE
FindAlnForlntermit = -1
EIVD IF
END FUNCTION
SUB FindDesPt (WchPose, WchLine)
Range = 0
FoundIt = False
m
Range = Range + 1
SELECT CASE WchPose
CASE 1
GetStartFinish ALnsO, WchLine, Start, Finish
FindInRng APtsXPg, Start, Finish, Range
CASE 2
GetStartFinish BLns(}, WchLine, Start, Finish
FindlnRng BPtsXPg, Start, Finish, Range
CASE 3
GetStartFinish CLns(), WchLine, Start, Finish
FindinRng CPtsXPg, Start, Finish, Range
CASE 4
GetStartFinish DLns(), WchLine, Start, Finish
FindInRng DPtsXPg, Start, Finish, Range
END SELECT
LOOP UNTIL FoundIt OR (Range > 10)

CA 02483943 2004-11-16
- 120 -
IF ThisOne < Start + 10 OR ThisOne > Finish - 10 THETT
BEEP: BEEP:
Foundit = False
END IF
IF Foundit = False THEN
IOCATE 3, 1
pRINT "Not Found Or Too Close To Start Or End Of A Line"
SLEEP 1
LOCATE 3, 1: PRINT SPACE$(70)
END IF
EIJD SUB
SUB FindFrlnInChartObjGrpWarp (Kind, WchOne,'WchFrame)
DO
Wnd2n
CalcFlatXY
ShowFlatCrsr
FrameNo = CINT((XyZ.x - 40) / Interval! + 1)
IF FrameNo > 0 AND FrameNo <= NoOfFrames THEN
LOCATE 2, 30: PRIN'P "Frame"; FrameNo
DistFromPrev = FrameNo - syncpts(SyncPtIndex).Frame
LOCATE 3, 1:' PRINT "Distance From Previous SyncPt"; DistFromPrev
IF INP(889) < 128 THEN7
Foundlt = True
WchFrame = FrameNo
EXIT DO
AND IF
ELSE
LOCATE 2, 30: PRINT SPACE$ (15)
LOCATE 3, 1. PRINT SPACE$(65)
END IF
LOOP
END SLTB
St78 FindInApts (FoundPt)
Range = 0
Foundlt = False
DO
Range = Range + 1
FindlnRng APts70?g, 1, GetA(APtsXPg00), Range
T.,oOp UNTIL FoundIt OR (Range > 10)
IF Foundlt = True THM FoundPt = ThisOne
IF FoundTt = False THEN
LOCATE 3, 1: PRINT "Not Found": SLEEP 1
LOCATE 3, 1: PRINT SPACE$(10)
II1D IF
E!QD SUB
SUB FindlnRng (PtArray, Start, Finish, Range)
Foundit = False
I = Start
m
I = I + 1
IF I > Finish THEN EXIT DO
TrialX = GetAReal!(PtArray, I)
TrialY = GetAReal!(PtArray + 1, I)
TrialZ = GetAReal!(PtArray + 2, 1)
IF TrialX < XYZ.x + Range AND TrialX > XYZ.x - Range AND
TrialY < XYZ.y + Range AND TrialY > XYZ.y - Range AND

CA 02483943 2004-11-16
- 121 -
Tria1Z < XYZ.Z + Range * 4 AND TrialZ > XYZ.Z - Range * 4.THM
Foundlt = True
EXIT DO
END IF
LOOP
IF Foundlt = True THEN
ThisOne = I
gyZ.x = Tria1X: XYZ.y = TrialY: XYZ.Z = TrialZ
FoundPt = XYZ
END IF
END SUB
SUB FindLngstSeg
SumSegLen = 0
FOR i= 1 TO NoOfSegs
SegLen(1) = (TenpSegs(I).AEndPt - TempSegs(I).AStartPt) + 1
SegLen(2) = (TempSegs(I).BEndPt - TempSegs(I).BStartPt) + 1
SegLen(3) = (TentpSegs(I).CEhdPt - TempSegs(I).CStartPt) + 1
SegLen(4) = (TempSegs(I).AEhdPt - TempSegs(I).DStartPt) + 1
BestLenSoFar = 0
FORs=1TO4
IF SegLen(s) > BestLenSoFar TFOM
BestLenSoFar = SegLen(s)
Longest = s
END IF
NEXT
LongestSeg(I, 0) = Longest 'the val of the 0 posit is the Pose
in which seg(i) is the longest
LongestSeg(I, 1) = SegLen(Longest) 'the val of the.1 posit is the
length
SumSegLen = SumSegLen + BestLenSoFar 'total length of segs after
justification
NEXT
END SUB
SfJB FindMrkdPtInAPose (ThisOne, Text$)
LOCATE 2, 1: PRINT Text$
Foundit = False
WHILE Foundlt = False
GetWndXYZ 0
FindInApts ThisOne
NiIIJD
GetXYZ ThisOne
Nrkl, 1
MyDelay 1
LOCATE 1, 1: PRINT SPACE$(35)
FND S(1B
FUNCTION FindWchFinlSg (ArrayO AS FinlSgType, PointNdx)
I = 0
DO: I+1
LOOP UNTIL I > NoOfSegs OR (PointNdx >= Array(I).Beg AND
PointNdx <= Array(I).Fin)
IF I <= NoOfSegs THEN
FindwchFinlSg = I
ELSE
FindWchFinlSg = -1
END IF
END FfJNCTION

CA 02483943 2004-11-16
- 122 -
Ft7NCTION GetA (PageNo, Index)
GetArray PageNo, Index, Value
GetA = Value
END F[7NCTION
FUNCTION GetAReal! (PageNo, Index)
GetArrayReal PageNo, Index, Value!
GetAReal = Value!
END FUNCTION
SUB GetImFxXYZ (ImToFix,PtPosit)
XYZ.x = GetAReal!(APtsXPg + 3*(ImToFix - 1), PtPosit)
XyZ.y = GetAReal!(APtsYPg + 3*(ImToFix - 1), PtPosit)
XYZ.Z = GetAReal!(APtsZPg + 3 * (ImToFix - 1), PtPosit)
E'ND SUB
SL7B GetPts (PtArray, PtArrayNdx)
XYZ:x = GetAReal!(PtArray, PtArrayNdx)
XyZ.y = GetAReal!(PtArray + 1, PtArrayNdx)
XYZ.Z = GetAReal!(PtArray + 2, PtArrayNdx)
Eb7D S[JB
SUB GetStartFinish (LnLstO AS LineType, LnNo, Start, Finish)
Start = LnLst(LnNo).Beg
Finish = LnLst(LnNo).Fin
fiND SUB
SUB GetSumWarpDisp (SegInfoLstO, SeglnfLstlndx, FrameNo,
SegNo, SegPtNo, SumWarpDisp AS t3DPoint)
DIM WarpSegPathPtPosit AS t3DPoint
DIM HndlPathDiff AS t3DPoint
DIM WazpSegWaveDisp AS t3DPoint
SumWaxpDisp.x = 0: SumWarpDisp.y = 0: Su=nlarpDisp.2 = 0
FOR I = 1 TO SegInfLstIndx
m = SegInfoLst(I)
'******* where in warp path if inertia or wind warp:
IF Seginfo(m).Kind = "Iner" OR SegInfo(m).Kind ="Wind' TFW
AdjFrameNo = FrameNo - 5
IF AdjFrameNo < 1 THEN AdjFrameNo = 1 'this delays warp so it
feels like an effect of
movement
WarpSegPathArrayPositPtr AdjFrameNo, SegInfo(m).WchPath,
WarpSegPathPtPosit
END IF
IF SegInfo (m) .Kind = "T9me" THM
WarpSegPathArrayPositPtr FrameNo, Seglnfo(m).WchPath,
WarpSegPathPtPosit
END IF
******** wave position along segment:
(length of seg is in SegInfo(m).SegLen)
SELECT CASE Seginfo(m).WchWave
CASE 1
LenOfWave = GetA(JAPtsXPg, 0)
CASE 2
LenOfWave = GetA(JBPtsXPg, 0)
CASE 3
LenOfWave = GetA(JCPtsXPg, 0)

CA 02483943 2004-11-16
- 123 -
CASE 4
LernOfWave = GetA(JDPtsXPg, 0)
END SELECT
IF Seglnfo(m).Kind = "Wave' THEN
3ELECT CASE SegIrifo(m).OverLap
CASE 0 'o1 at start ol at end
L14 = SegInfo(m).SegLen
Increment = (LM / NoOfFrames * WaveSpeed) * FrameNo
SELECT CASE Seglnfo(m).Direc
CASE "HtoT"
PositionNo = SegPtNo + LenOfWave / 2 - Increment
CASE "TtoH"
PositioriNo = SegPtNo + Increment
END SELECT
CASE 1 'o1 at start no ol at end
LM = Seglnfo(m).SegLen
Increment = (LM / NoOfFrames * WaveSpeed) * FrameNo
SELECT CASE SegInfo(m).Direc
CASE "HtoT"
PositionNo = SegPtNo - Increment
CASE "TtoH"
PositionNo = SegPtNo + Increment
MVD SELECT
CASE 2 'no ol at start ol at end
LM = Seglnfo(m).SegLen
Increment = (LM / NoOfFrames * WaveSpeed) * FrameNo
SELECT CASE SegInfo(m).Direc
CASE "HtoT"
PositionNo = SegPtNo + LenOfWave - Increment
CASE "TtoH"
PositionNo = SegPtNo + Increment
EM SELECT
CASE 3 'no ol at start no ol at end
LM = 2 * SegInfo(m).SegLen
Increment = (LM / NoOfFrames * WaveSpeed) * FrameNo
SELECT CASE Seglnfo(m).Direc
CASE "HtoT"
PositionNo = SegPtNo + LenOfWave - Increment
CASE "TtoH"
PositionNo = SegPtNo + Increment
END SELECT
END SEL+ECT
EndOfWave = LenOfWave
IF PositionNo > LenOfWave THM PositionNo = LenOfWave
'end of wave array
IF PositionNo < 1 THEN PositionNo = 1
WarpSegWaveShapePtr PositionNo, SegInfo(m).WchWave, WarpSegWaveDisp
END IF
~****** where along the warp profile is this image (segment) point?:
'Prop! is how much the point will be affected by the
'displacement between the warp handle and the position on the
warp path
WhereInProf = SegPtNo + Seginfo(m).ProfBeg - 1

CA 02483943 2004-11-16
- 124 -
Prop! _ '~1arpSegProfPtr(SegInfo(m).WchProf, WhereInProf)
****** get the displacement for this warp:
IF SegInfo(m).Kind ="Time" OR Seglnfo(m).Kind ="Iner" OR
SegInfo (m) .Kind = "Wind" TFM
HndlPathDiff.x = WarpSegPathPtPosit.x -
GetAReal!(APtsXPg, SegInfo(m).Hndl)
HndlPathDiff.y = WarpSegPathPtPosit.y -
GetAReal!(APtsYPg, Seglnfo(m).Hndl)
HndlPathDiff.Z = WarpSegPathPtPosit.Z -
GetP,Real!(APtsZPg, Seglnfo(m).Hndl)
WarpSegDisp.x = (HndlPathDiff.x * Prop!)
WarpSegDisp.y = (HndlPathDiff.y * Prop!)
WarpSegDisp.Z = (HndlPatbDiff.Z * Prop!)
END IF
IF Seglnfo(m).Kind = "Wave" THEri
WarpSegDisp.x = (WarpSegWaveDisp.x * Prop!)
WarpSegDisp.y = (WarpSegWaveDisp.y * Prop!)
warpSegDisp.Z = (WarpSegWaveDisp.Z * Prop!)
END IF
******: add it to any other warp(s) if any:
SunWaxpDisp.x = SUmWarpDisp.x + WarpSegDisp.x
SumWazpDisp.y = SiunWarpDisp.y + WarpSegDisp.y
gumWarpDisp.Z = SumWarpDisp.Z + WarpSegDisp.Z
NEXT
END SUB
SUB GetVelGraphFromPath (aArray)
PtsPerFrame! = (GetA(aArray, 0) - 1) / (NoOfFrames - 1)
FOR Frame = 2 TO NoOfFrames
StartPt! _ (Frame - 2) * PtsPerFrame! + 1
EndPt! = StartPt! + PtsPerFrame!
IF INT(StartPt!) = INT(EndPt!) THEN
FrmToFzmVelocity!(Frame) = DistToNextPoint(aArray, INT(StartPt!))
* (EndPt! - StartPt!)
ELSE
SunD! = DistToNextPoint(aArray, INT(StartPt!)) *
(INT(StartPt!) + 1 - StartPt!)
FOR I = INT(StartPt!) + 1 TO INT(EndPt!) - 1
SumD! = SumD! + DistToNextPoint(aArray, I)
NEXT
IF INT (EndPt ! ) <> EndPt ! THEN
SumU! = SumD! + DistToNextPoint(aArray, INT (EndPt!))
*
(EndPt! - INT(EndPt!))
END IF
FrmToFrmVelocity!(Frame) = SumD!
ENA IF
NEXT
END SUB
SUB GetVelGraphFromUser (aDrawnPath)
LOCATE 1, 1: PRINT "Redraw Velocity Graph"
******************************* Wait for button down
WFiILE INP(889) >= 128
Wndln

CA 02483943 2004-11-16
- 125 -
IF XYZDiff THEN ShowFlatCrsr
WIIJD
FOR I 1 TO 1000: NEXT 'Short Delay for Button Bounce
****** ************************* Draw velocity curve
Index = 0
WHILE INP(889) < 128
WndIi1
IF XYZDiff TIW
ShowFlatCrsr
PSET (XYZ.x, XYZ.y), 15
Index = Index + 1
EnterRawPt Index
END IF
WEND
' ******************************* Convert curve to velocities
Frm'IbFrmVelocity!(1) = 0
J = 2
FOR Frame = 2 T0 NoOfFrames
qTHILE (GetAReal!(RawPtsXPg, J) < 40 + (Frame - 1) * Interval!) AND
(J < GetA(RawPtsXPg, 0))
J = J + 1
vEtTD
dx! = GetAReal!(RawPtsXPg, J) - GetAReal!(RawPtsXPg, J- 1)
IF dx != 0 TFM dx !=. 01
Dy! = GetARea1!(RawPtsYPg, J) - GetAReal!(RawPtsYPg, J - 1)
Vel! = 320 - (GetAReal!(RawPtsYPg, J - 1) + DY! * (40 + (Frame - 1)*
Interval! - GetAReal!(RawPtsXPg, J - 1)) / dx!)
Vel is PrevY + DY *(X - PrevX) / DX
FYmToFrmVelocity!(Frame) = Limits(Vel!, 0!, 275!)
CIRCLE (40+(Frame-1) *Interval!, 320-FrmToFrmVelo.city!(Frame)),3,14
NEXT
'********************* Adjust vels for total length and syncPoints
FOR Segment = 1 TO NoOfSortedSymcPts - 1
SegLength! = 0
TotalSegVels! = 0
FOR PtNo = SortedSyncPts(Segment).TempPtslndex TO
SortedSyncPts(Segment + 1).TempPtslndex - 1
segLength! = SegLength! + DistToNextPoint!(aDrawnPath, PtNo)
ATEXT
FOR Frame = SortedSyncPts(Segment).Frame + 1 TO
SortedSyncPts(Segment + 1).Frame
TotalSegl7els! = TotalSegVels! + FrmToFrmVelocity!(Frame)
NEXT
FOR Frame = SortedSyncPts(Segment).Frame + 1 TO
SortedSyncPts(Segment + 1).Frame
IF TotalSegVels ! = 0 THEN
FrmToFrmVelocity!(Frame) = 0
ELSE
FrmToFrmVelocity!(Frame) =
FrmToFrmVelocity!(Frame) * SegLength! / TotalSegVels!
END IF
NEXT
NE?CP
END SUB
SZ7B GetWarpProfile (WarpNo)
' ******************************* Display layout on screen

CA 02483943 2004-11-16
- 126 -
CLS
LOCATE 1, 1: PRINT "Draw Profile of Desired Warp Along
Selected Segments(s)"
LOCATE 3, 1: PRINT -Full Warp Effect"
LOCATE 23, 1: PRINT "No Warp Effect"
LINE (0, 42)-(639, 42), 6
LINE (0, 308)-(639, 308j, 6
LI1VE (30, 42)-(30, 308), 15
TotalSegsLen = 0
FOR I = 1 TO NoInSrs
TotalSegsLen = TotalSegsLen + WaspSrs(I, 0)
NEXP
Pointlnterval! = 600! / (TotalSegsLen - 1)
FOR I= 0 TO TotalSegsLen - 1
LINE (30+I*Pointlnterval!,305)-(30+I*Pointlnterval!,307), 15
NEXT
Length = 0
FOR I 1 TO NoInSrs
Length = WarpSrs(I, 0) + Length
POSIT = CINT((Length - 1) * Pointlnterval!)
LINE (30 +.POSIT, 42)-(30 + POSIT, 308), 10
NE7U
LINE (30 + POSIT, 42)-(30 + POSIT, 308), 15
****~******************** Show a-Pose of segments being warped
FOR J= 1 TO NoOfSegs
IF FinlSgs(J).WarpNo = WarpNo TFTEN
DrawPartialArray APtsXPg, FinlSgs(J).Beg, FinlSgs(J).Fin, -1, False
ShowASegStart J
END IF
NEXT
' *'***********'******* ********* Wait for button down
WHILE INP(889) >= 128
Wndln
IF XYZDiff THEN ShowFlatCrsr
Wom
FOR I = 1 TO 1000: NEXT 'Short Delay for Button Bounce
***********+******************* Draw warp profile
Index = 0
WHILE INP(889) < 128
WndIn
IF XYZDi f f TFM
ShowFlatCrsr
PSET (XYZ.x, XYZ.y), 15
index = Index + 1
EnterRawPt Index
END IF
W.IIM
' ******************************* Smooth and redraw
Smooth RawPtsXPg, TempPtsXPg, 3, True
FOR I = 1 TO GetA(RawPtsXPg, 0)
ShowFlatPt GetAReal!(RawPtsXPg, I), GetAReal!(RawptsYPg, I), 13
ShowFlatPt GetAReal!(TempPtsXPg, I), GetAReal!(TempPtsYPg, I), 15
NEXT
***r*******************w******* Convert to
proportions
J = 2

CA 02483943 2004-11-16
- 127 -
FOR PtNo = 1 TO TotalSegsLen
WHILE (GetAReal!(TempPtsXPg, J) < 30 + (PtNo - 1) * PointInterval!)
AND (J < GetA(TempPtsXPg, 0))
J = J + l
WEND
dx! = GetAReal!(TempPtsXPg, J) - GetARea1!(TeMPtsXPg, J - 1)
IF dx! = 0 TFM dx! =.01
DY! = GetAReal!(TempPtsYPg, J) - GetAReal!(TempPtsYPg, J - 1)
Prop! = (308- (GetAReal! (TempPtsYPg, J-1) +
DY! * (30+(PtNo-1)*PointInterval!-
GetAReal!(TempPtsXPg, J-1)) / dx!)) / 267!
Prop is PrevY + DY *(X - PrevX) / DX
Prop! = Limits(Prop!, 0!, 1!)
SetArrayReal RawPtsXPg, PtNo, Prop!
CIRCLE (30 + (PtNo - 1) * Pointlnterval!, 308 - Prop! * 267), 3, 14
NF.xI'
END SUB
SUB GetWndXYZ (Kind)
Foundit = False
m
Wndln
ShowCrsr
IF INP(889) < 128 THEN
Wx = XYZ.x: Wy = XYZ.y: Wz = XYZ.Z
EXIT DO
ET7fl IF
IF Kind = 1 TRW
FOR I = 1 TO NoOfFrames
J = bpacer * I + 30
IF XYZ.x = J TIgN LOCATE 2, 30: PRINT "Frame"; I
NFx'I'
FND IF
LOOP
END SUB
SUB GetXYZ (WchPt)
XYZ.x = GetAReal!(APtsXPg, WchPt)
XYZ.y = GetAReal!(APtsYPg, WchPt)
XYZ.Z = GetAReal!(APtsZPg, WchPt)
ErID SUB
SUg HiLiFinlSg (SegNo)
IF ChoiceinSegHili = True TFiM
B$ = "Confirm": C$ = "Reject"
WndChs B$, C$, "x", "x", Ans$, 1
IIQD IF
Start =.FinlSgs(SegNo).Beg
Finish = FinlSgs(SegNo).Fin
DO WHILE XYZ.y > 15
XYZ.x = GetAReal!(APtsXPg, Start)
XYZ.y = GetAReal!(APtsYPg, Start)
XYZ:Z = GetAReal!(APtsZPg, Start)
Mrk 3, 1
counter = 0
DO WHILE counter < 20000
counter = counter + 1

CA 02483943 2004-11-16
- 128 -
LOOP
Mrk 3. 1
FOR I Start TO Finish - 3 STEP 2
FOR J = I TO I + 3
Wndln
IF XYZ.y < 15 THEN EXIT DO
ShowCrsr
GetXYZ (J)
Draw3DPoint XYZ, 0
IF INP(889) < 128 TFW EXIT DO
NEXT
FORJ=ITOI+3
Wndin
ShowCrsr
GetXYZ (J)
Draw3DPoint XYZ, -1
IF INP(889) < 128 THEN EXIT DO
IdF=XT
NE)CT
LOOP
IF ChoiceInSegHili = True THEN
WndSlct Ans$, 1
ErsMnu
END IF
ChoiceInSegHili = False
END SUB
SUB HiLiLn (LnArrayO AS LineType, PtArray, LnNo)
DIIM Ptl AS t3DPoint, Pt2 AS t3DPoint
IF WchPoseForHili > 1 AND LnNo < ALns(0).Seg + 1 THEN
GetStartFinish LnArrayO, LnNo, Start, Finish
Done = False
IF Finish > Start + 5 TFM
WHILE NOT Done
GetPts PtArray, Start 'puts values into XYZ
Mrk 3, 1
counter = 0
DO WHILE counter < 30000
counter = counter + 1
LOOP
Mrk 3, 1
FOR I = Start TO Finish - 1
GetArrayReal PtArray + 0, I, Ptl.x
GetArrayReal PtArray + 1, I, Ptl.y
GetArrayReal PtArray + 2, I, Pt1.Z
GetArrayReal PtArray + 0, I+ 1, Pt2.x
GetArrayReal PtArray + 1, I+ 1, Pt2.y
GetArrayReal PtArray + 2, I+ 1, Pt2.Z
Draw3DLine Ptl, Pt2, 0
Delay = 0
Done = (INP(889) < 128)
WHILE Delay < 2 AND NOT EarlyExit
Wndln
Done = ((INP(889) < 128) OR (XYZ.y < 15))
ShowCrsr
Delay = Delay + 1
WEND
Draw3DLine Pt1, Pt2, -1

CA 02483943 2004-11-16
- 129 -
IF Done ZHM EXIT FOR
NEXT
WEND
END IF
END IF
END SUB
SUB IdentGroups
WchPoseForHili = 2
LastGrp = 0
WHILE GroupsDefnd = False
FOR I 1 TO ALns(0).Beg
A$ "1": B$ = "2": C$ "3": D$ "4": E$ 5"
WndChs "ASSIGN INDICATED LINE TO A GROUP",
A$, B$, C$, D$, E$, Ans$, 1
HiLiLn ALnsO, APtsXPg, I
WndSlct Ans$, 1
wchGrp = VAL(Ans$)
IF WchGrp > LastGrp + 1 THEN
BEEP: LOCATE 3, 1
PRINT "Can't Skip A Number; Assign Group Again
(Last Assignment Was To Group"; LastGrp; ")"
SLEEP 3
LOCATE 3, 1: PRINT SPACE$(40)
I = I - 1
CLS
ELSE
PutInGrp I, WchGrp
LastGrp = WchGrp
E[JD IF
NEXT
RedoGroupsOK:
SELECT CASE UserChoice("", "Groups OK", "Redo", "")
CA3E 3
GroupsDefnd = True
CASE 4
FOR I = 1 TO NoOfGroups
ALns(I).WchGrp = 0
BLns(I).WchGrp = 0
CLns(I).WchGrp = 0
DLns(I).WchGrp = 0
NEXT
NoOfGroups = 0
CASE ELSE
GOTO RedoGroupsOK
END SELECT
WEND
END SUB
SC7B IdentObjects
LastObj = 0
WHILE ObjectsDefnd = False
FOR I = 1 TO NoOfGroups
CLS
FOR J = 1 TO NoOfLines
IF ALns(J).WOhGrp = I THEN ShowLn 1, J, -1
NEXT
F$ ="ASSIGN ": G$ = Group(I).Label: H$ TO AN OBJECT"
J$ = F$ +G$+H$
WchObj = UserChoice(J$, "1", "2", "3", "", "")

CA 02483943 2004-11-16
- 130 -
IF WchObj > LastObj + 1 TfM
BEEP: LOCATE 3, 1
PRINT "Can't Skip A Number; Assign Object Again
(Last Assignment Was To Object"; LastObj; ")"
SLEEP 3
LOCATE 3, 1: PRINT SPACE$(40)
I = I - 1
CLS
ELSE
putinObj I, WchObj
LastObj = WchObj
EBiD IF
NEXT
SELECT CASE UserChoice("", "", =", "Objects OK", "Redo", "")
CASE 3
ObjectsDefnd = True
CASE 4
FOR K= 1 TO NoOfObj
ALns(K).WchObj = 0
BLns(K).WchObj = 0
CLns(K).WchObj = 0
Dlais(K).WchObj = 0
Group(WchGrp)'.WchObj = 0
NE~tT
NoOfObj = 0
END SELECT
WEND
PNID SUB
SUB InterpO (Array, StartOfGap, EndOfGaP)
this creates missing pts in gaps between
two susequent values of array.
NoOfGaps = EndOfGap - StartOfGap
ValDiff = GetAReal!(Array, IIzdOfGap) -
GetAReal!(Array, StartOfGap) 'for x
Incr! = ValDiff / NoOfGaps
FOR I = StartOfGap - StartOfGap + 1 TO EndOfGap - StartOfGap - 1
SetArrayReal Array, StartOfGap + I,
GetAReal!(Array, StartOfGap) + (I * Incr!)
NEXT
ValDiff = GetAReal!(Array + 1, EndOfGap) -
GetAReal!(Array + 1, StartOfGap) 'for y
incr! = ValDiff / NoOfGaps
FOR I = StartOfGap - StartOfGap + 1 TO EndOfGap - StartOfGap - 1
SetArrayReal Array + 1, StartOfGap + I,
GetAReal!(Array + 1, StartOfGap) + (I * Incr!)
NEXP
ValDiff = GetAReal!(Array + 2, EndOfGap) -
GetAReal!(Array + 2, StartOfGap) 'for z
incr! = ValDiff / NoOfGaps
FOR i= StartOfGap - StartOfGap + 1 TO EndOfGap - StartOfGap - 1
SetArrayReal Array + 2; StartOfGap + I,
GetAReal!(Array + 2, StartOfGap) + (I * Incr!)
NEXT
END SUB
SUB JstfyTeapSegsPartA
SegStart
FOR I = 1 TO.NoOfSegs
IF SegLen(1) <> 0 AND SegLen(2) <> 0 AND

CA 02483943 2004-11-16
- 131 -
SegLen(3) <> 0 AND SegLen (4) <> 0 THEN
SegEnd = SegStart + LongestSeg=(I, 1) - 1
JstfyTempSegsPartB I, LongestSeg(I, 0), SegStart, SegEnd
FinlSgs(I).Beg = SegStart
FinlSgs(I).Fin = SegEnd
SegStart = SegEnd + 1
FM IF
FinlSgs(I).WchGrp = TempSegs(I).WchGrp
FinISgs(I).WchObj = TennpSegs(I).WchObj
FiniSgs(I).WchLine = TempSegs (I). WchLine
NEXT
SetA JAPtsXPg, 0, SegEnd
SetA JBPtsXPg, 0, SegEnd
SetA JCPtsXPg, 0, SegEnd
SetA JDPtsXPg, 0, SegEnd
FOR I = 1 TO NoOfLines
FOR J = 1 TO NoOfSegs
IF FinlSgs (J) .WchLine = I THEN
ALns(I).FinalStart = FinlSgs(J).Beg
E'SIT FOR
END IF
NEXT
FOR J= 1 TO NoOfSegs
IF FinlSgs(J).WchLine = I THEN
ALns(I).FinalEnd = FinlSgs(J).Fin
END IF
NEXT
ALns(I).Beg = ALns(I).FinalStart
ALns(I).Fin = At,ns(I).FinalEnd
BLns(I).Beg = ALns(I).FinalStart
BLns(I).Fin = ALns(I).FinalEnd
CLns(I).Beg = ALns(2).FinalStart
CLns(I).Fin = ALns(I).FinalEnd
DLns(I).Beg = ALns(I).FinalStart
DLns(I).Fin = ALns(I).FinalEnd
NEXT
END SUB
SUB JstfyTempSegsPartB (WchSeg, LngstSeg, SegStart, SegEnd)
'seg start,end, refers to len of the seg to which the
"others will be stretched
I = WchSeg
FOR J= SegStart TO SegEnd
SELECT CASE LngstSeg
CASE 1 'first transfer vals of longest seg from APts toJAPts
K = (J - (SegStart - TempSegs(I).AStartPt))
SetArrayReal JAPtsXPg, J, GetAReal!(APtsXPg, K)
SetArrayReal JAPtsYPg, J, GetAReal!(APtsYPg, K)
SetArrayReal JAPtsZPg, J, GetAReal!(APtsZPg, K)
CASE 2
K = (J - (SegStart - TempSegs(I).BStartPt))
SetArrayReal JBPtsXPg, J, GetAReal!(BPtsXPg, K)
SetArrayReal JBPtsYPg, J, GetP,l2eal!(BPtsYPg, K)
SetArray'Rea1 JBPtsZPg, J, GetAReal!(BPtsZPg, K)
CASE 3
K = (J - (SegStart - TenpSegs(I).CStartPt))

CA 02483943 2004-11-16
- 132 -
SetArrayReal JCPtsXPg, J, GetAReal!(CPtsXPg, K)
SetArrayReal JCPtsYPg, J, GetAReal!(CPtsYPg, K)
SetArrayReal JCPtsZPg, J, GetAReal!(CPtsZPg, K)
CASE 4
K = (J - (SegStart - TeccpSegs (I) DStartPt) )
SetArrayReal JDPtsXPg, J, GetAReal!(DPtsXPg, K)
SetArrayReal JDPtsYPg, J, GetAReal!(DPtsYPg, K)
SetArrayReal JDPtsZPg, J, GetAReal!(DPtsZPg, K)
FTID SELECT
IqMfT
SELECT CASE LngstSeg
CASE 1
Stretch BPtsXPg, JBPtsXPg, TempSegs(I).BStartPt,
TempSegs(I).BErndPt, SegStart, SegEnd
Stretch CPtsXPg, JCPtsXPg, TempSegs(I).CStartPt,
TempSegs(I).CEndPt, SegStart, SegEnd
Stretch DPtsXPg, JDPtsXPg, TenpSegs(I).DStartPt,
TexnpSegs ( I). DEYidPt, SegStart, SegEnd
CASE 2
Stretch APtsXPg, JAPtsXPg, TempSegs(I).AStartPt,
TenpSegs(I).AFhdPt, SegStart, SegEnd
Stretch CPtsXPg, JCPtsXPg, TempSegs(I).CStartPt,
TempSegs(I).CEndPt, SegStart, SegEnd
Stretch DPtsXPg, JDPts7Pg, Temj%Segs(I).DStartPt,
TempSegs(I).DEndPt, SegStart, SegEnd
CABE 3
Stretch BPtsXPg, JBPtsXPg, TempSegs(I).BStartPt,
TempSegs(I).BEndPt, SegStart, SegEnd
Stretch APtsXPg, JAPtsXPg, TenVSegs(I).AStartPt,
TempSegs(I).AFndPt, SegStart, SegEnd
Stretch DPtsXPg, JDPtsXPg, TempSegs(I).DStartPt,
TenpSegs(I).DEndPt, SegStart, SegEnd
CASE 4
Stretch BPtsXPg, JBPtsXPg, TenmpSegs(I).BStartPt,
TempSegs(I).BEndPt, SegStart, SegEnd
Stretch APtsXPg, JAPtsXPg, TempSegs(I).AStartPt,
TempSegs(I).AEndPt, SegStart, SegEnd
Stretch CPtsXPg, JCPtsXPg, TernpSegs(I)CStartPt,
TempSegs(I).CEndPt, SegStart, SegEnd
END SELECT
END SUB
SUB LdLnLnArrays (WchPose, Col)
IF WchPose = 1 THM LdLnLst ALnsO, WchPose, Col
IF WchPose = 2 TMN LdLnLst BLns O, WchPose, Col
IF WchPose = 3 TFIEN LdLnLst CLnsO, WchPose, Col
IF WchPose = 4 TFM LdLnLst DLnsO, WchPose, Col
END SUB
SUB LdLnLst (Array() AS LineType, WchPose, Co1)
Array(LnNO).Beg = Array(LnNo - 1).Fin + 1
Array(LnNo).Fin = GetA(APtsXPg + 3*(WchPose - 1), 0)
Array(0)Beg = LnNo
END SUB
FUNCTION Limits! (x!, L!, H!)
IF x! < L! TFM

CA 02483943 2004-11-16
- 133 -
Limits! = L!
ELSE
IF X! > H! TH$N
Limits! = H!
ELSE
Limits! = x!
END IF
END IF
END FUNCTION
FtJNCTION LnEndsClose (PtArray, IndexPtA, IndexPtB, Range)
LnEndsClose = GetAReal!(PtArray, IndexPtA) <
GetAReal!(PtArray, IndexPtB) + Range AND
GetAReal!(PtArray, IndexPtA) >
GetAReal!(PtArray, IndexPtB) - Range AND
GetAReal!(PtArray + 1, IndexPtA) <
GetAReal!(PtArray + 1, IndexPtB) + Ran& AND
GetAReal!(PtArray + 1, IndexPtA) >
GetAReal!(PtArray + 1, IndexPtB) - Range AND
GetAReal!(PtArray + 2, IndexPtA) <
GetAReal!(PtArray + 2, IndexPtB) + Range * 4 AND
GetAReal!(PtArray + 2, IndexPtA) >
GetAReal!(PtArray + 2, IndexPtB) - Range * 4
END FUNCTION
SUB MarkSpaceRefPts
ShowSpaceRefPts
STATIC I
Ans$
DO UNTIL Ans$ = C$
I = I + 1
Text$ ="If Wanted, Mark Reference Points In Space For Drawing
5pace Path Of " + Object(WchObj).Label
DefnPt SpaceRef(I).Locat, Text$, "MarkSpaceRefPts", 2
SpaceRef(0).Visib = I
LOOP
END SUB
SUB MkFrameScreenV4 (Kind, WchOne)
SELECT CASE Kind
CASE 1
Text$ = "Object = + Object(WchOne).Label
colorCode = 2
CASE 2
Text$ = "Group " + Group(WchOne).Label
ColorCode = 3
CASE 3
Text$ = "Warp + Warp(WchOne).Label
ColorCode = 4
END SELECT
CLS
LOCATE 5, 1
PRINT Text$
YPos = 80
Height = 14
LINE (0, YPos)-(639, YPos), ColorCode
LINE (0, YPos + Height)-(639, YPos + Height), ColorCode
LINE (0, YPos)-(39, YPos + Height), ColorCode, BF
FOR Frame = 1 TO NoOfFrames

CA 02483943 2004-11-16
- 134 -
XPos = 40 + inteYval! * (Frame - 1)
LINE (XPos, YPos)-(XPos, YPos + Height), ColorCode
NEXT
END SUB
SUB MkMrJtrs
LINE (1, 8)-(4, 5), LCol
LINE -(7, 8), LCol
LINE (4, 8)-(4, 5), LCol
GET (0, 0)-(9, 9), LCrsr
LINE (1, 8)-(4, 5), RCol
LINE -(7, 8), RCoZ
LINE (4, 8)-(4, 5), RCol
GbT (0, 0)-(9, 9), RCrsr: CLS
CIRCLE (4, 4), 2, LCo1: GET (0, 0)-(9, 9), CmrkL
CIRCLE (4, 4), 2, RCo1: GET (0, 0)-(9, 9), CmrkR: CLS
L1NE (0, 0)-(8, 8), LCol, B: GET (0, 0)-(9, 9), SqmrkL
LINE (0, 0)-(8, 8), RCol, B: GET (0, 0)-(9, 9), ScgmrkR: CLS
LINE (0, 6)-(8, 6), LCol: LINE (0, 6)-(4, 1), LCo1: LINE -(8, 6), LCol
GET (0, 0)-(9, 9), TrmrkL
LINE (0, 6)-(8, 6), RCol: LINE (0, 6)-(4, 1), RCo1: LINE -(8, 6), RCol
GET (0, 0) - (9, 9), TrmrkR: CLS
LINE (0, 4)-(9, 4), LCol: LINE (4, 0)-(4, 9), LCol
GET (0, 0)-(9, 9), CrossMrkL
LINE (0, 4)-(9, 4), RCol: LINE (4, 0)-(4, 9), RCo1
GET (0, 0)-(9, 9), CrossMrkR
END SUB
SUB MkPathCycle
IF Confinn( "Mk Cycle?") TEM
IF GetA(TempPtsXPg, 0) > 30 THEN
DrawArray TempPtsXPg, 0, False
SmoothJoin TempPtslPg, 30
NoOfFrames = NoOfPYarnes - 1
LOCATE 3, 1: PRINT "Frames Reduced To"; NoOfFrames
F.LSE
LOCATE 3, 1: PRINT 'Too Short"
MTD IF
END IF
DrawArray TempPtsXPg, -1, False
END SUB
SUB MkScaffold
IF Confirm("Mark Scaffold On <A> Source Pose For Reference When
Drawing Other Source Poses? ") THEN
MrkScaffoldCntr "Mark Scaffold Center", 1, 1
Scaffold = True
MrkScaffoldPts
END IF
END SUB
SUB MkSegs
DIM SegStarts(NoOfLines + NoOfMtchPts + 1) AS TempSegType
FOR 1 = 1 TO NoOfLines

CA 02483943 2004-11-16
135 -
SegStarts(I).AStartPt = ALns(I).Beg
SegStarts(I).BStartPt = BLns(I).Beg
SegStarts(I)CStartPt = CLns(I).Beg
SegStarts(I).DStartPt = DLns(I).Beg
SegStarts(I).WchGrp = ALns(I).WchGrp
SegStarts(I).WchObj = ALns(I)WchObj
NRXT
J = 0
IF NoOfMtchPts > 0 THEN
FOR I = 1 TO NoOfMtchPts + 1
J = NoOfLines + I
SegStarts(J).AStartPt = MtchPts(I, 1)
SegStarts(J).BStartPt = MtchPts(I, 2)
SegStarts(J).CStartPt = MtchPts(I, 3)
SegStarts(J).DStartPt = MtchPts(I, 4)
SegStarts(J).WchGrp = MtchPts(I, 5)
SegStarts(J).WchObj = MtchPts(I, 6)
NoOfSegs = J - 1
NEXT
ELSE
NoOfSegs = NoOfLines
END IF
FOR K = 1 TO NoOfSegs - 1
FOR I = 1 TO NoOfsegs - X
IF SegStarts(I).AStartPt > SegStarts(I + 1).AStartPt THEN
SWAP Segstarts(I).AStartPt, Segstarts(I + 1).AStartPt
SWAP SegStarts(I).BStartPt, SegStarts(I + 1).BStartPt
SWAP SegStarts(I).CStartPt, SegStarts(I + 1).CStartPt
SWAP SegStarts(I).DStartPt, SegStarts(I + 1).DStartPt
SWAP SegStarts(I).WchGrp, SegStarts(I + 1).WchGzp
SWAP SegStarts(I).WchObj, SegStarts(I + 1).WchObj
END IF
NEXT I
NEXT
FOR I = 1 TO NoOfSegs 'tempsegs are unjustified segs
TeMSegs(I).AStartPt = SegStarts(I).AStartPt
TempSegs(I).BStartPt = SegStarts(I).BStartPt
TempSegs(I).CStartPt = SegStarts(I).CStartPt
TempSegs(I).DStartPt = SegStarts(I).DStartPt
TempSegs(I).WchGrp = SegStarts(I).WchGrg
TempSegs(I).WchObj = SegStarts(I).Wchobj
IF SegStarts(I + 1).AStartPt <> 0 TIiEN
TempSegs(I).AEndPt = SegStarts(I + 1).AStartPt - 1
TempSegs(I).BEndPt = SegStarts(I + 1).BStartPt - 1
TempSegs(I).CEndPt = SegStarts(I + 1).CStartPt - 1
TempSegs(I).DEndPt = SegStarts(I + 1).DStartPt - 1
ELSE
TempSegs(I).AEndPt = ALns(NoOfLines).Fin
TempSegs(I).BEndPt = BLns(NoOfLines).Fin
TempSegs(I).CEndPt = CLns(NoOfLines).Fin
TemPSegs(I).DEndPt = DLns(NoOfLines).Fin
END IF
NEXT
FOR I = I TO NoOfSegs

CA 02483943 2004-11-16
- 136 -
FOR J 1 TO NoOfLines
IF Temp3egs(I).AStartPt >= ALns(J).Beg AND
TempSegs(I).AEndPt <= ALns(J).Fin TIiEN TempSegs(I).WchLine = J
NEXT
A7EXT
REDIM SegStarts(0) AS TempBegType
END StJB
SUB MkTetLns (Vertex, OtherVertex)
LINE (TEnds(Vertex).lx, TEnds(Vertex).y)-(TEnds(OtherVertex).lx,
TEnds(OtherVertex).y), LCol
LINE (TEnds(Vertex).rx, TEnds(Vertex)y)-(TEnds(OtherVertex).rx,
TEnds(OtherVertex).y), RCol
END SUB
SUB blkUniPath (Text$, M'kUniPathFor)
' *w******'**"******************* Draw stuff in background
LOCATE 1, 1
SELECT CP,SEs MkUniPathFor
CASE eObjPath: PRINT "Draw Path In Space Or Static Position For
+ Text$
CASE eTScript
SetupTetra
LOCATE 1, 1: PRINT "Draw Action Control Graph For." + Text$
IF LinkingToPreviousRun = True TFM
LOCATE 2, 1: BEEP
PRINT "Chained --You MUST Start Action Control
Graph Exactly At <A> Source Pose,Vertex!"
EATD IF
CASE eWarpPath: PRINT "Draw Path For Warp Handle"
CASE eWaveShape: PRINT "Draw Wave"
CASE eWindPath: PRINT "Draw Wind Path"
END SELECT
SetA FastWorkArraylXPg + 3 - gBuildToggle, 0, 0
inhibit initial erase
' *******************'*********** Wait for button down
WHILE INP(889) >= 128
Wndln
IF XYZDiff = True THEN
ShowCrsr
LOCATE 2, 40: PRINT "Z="; XYZ.Z
SELECT CASE 19cUniPathFor
CASE eObjPath: ShowObjOnPath WchObj, Obj2. XYZ
CASE eTScript: ShowGroupTScript WchGrp, Group2, Scanindeic, "Temp"
END SELECT
F1QD IF
WoID
y*. ~ ** ~x*+,r*ww+.*,r t:*~eaw*** t tk Draw path
Index = 0
WFiILE INP(889) < 128
Wndln
IF XYZDiff = True THEN
ShowCrsr
LOCATE 2, 40: PRINT "Z="; XYZ_Z

CA 02483943 2004-11-16
- 137 -
SELECT CASE MkUniPathFor
CASE eObjPath: ShowObjOnPath WchObj, obj2, XYZ
CASE eTScript: ShowGroupTScript WchGrp, Group2, ScanIndex, "Temp"
END SELECT
Draw3DPoint XYZ, -1
Index = Index + 1
EnterRawPt Index
END IF
WIIQD
=************'*****'**********"* Redraw path as solid and confirm ok
SELECT CASE MkUniPathFor
CA9E eTscript: SetupTetra
CASE eWarpPath: ShowAllFnlSegs 1: ShowAllSegStarts
CASE eWaveShape: Draw3DLine WaveRefStart, WaveRefEnd, -1
END SELECT
Smooth RawPtSXPg, Tex[pPtsXPg, 3, False
DrawArray RawPtsXPg, 0, True
DrawArray TeWPtsXPg, -1, True
END SUS
SUB Mrk (Kind, FlatStereo) 'F1atStereo: O=flat 1=stereo
IF FlatStereo = 1 THEN CalchHI2RY
IF F1atStereo = 0 THEN Ca1cFlat)CY
CalcMrkrPts -
IF MrkrPts.lx > 5 AND MrkrPts.rx > 5 AND
MrkrPts.lx < 645 AND MrkrPts.rx < 645 AND
MrkrPts.y > 5 AND MrkrPts.y < 345 THEN
IF Kind = 0 TPM
PUT (MrkrPts.lx, MrkrPts.y), CmrkL
PUT (MrkrPts.rx, MrkrPts.y), CmrkR
END IF
IF Kind = 1 THM
PUT (MrkrPts.lx, MrkrPts.y), SqmrkL
PUT (MrkrPts.rx, MrkrPts.y), SqmrkR
EBID IF
IF Kind = 2 TFW
PUT (MrkrPts.lx, MrkrPts.y), TrmrkL
PUT (MrkrPts.rx, MrkrPts.y), TrmrkR
ED7D IF
IF Kind = 3 THM
PUT (MrkrPts.lx, MrkrPts.y), CrossMrkL
PUT (MrkrPts.rx, MrkrPts.y), CrossMrkR
END IF
END IF
END SUS
SUB MrkGrpCntr (Message$, Pose, WchGrp)
DefnPt MarkedGrpCntr, Message$, "", 3
IF Pose = 1 THEN : AGrpCntr(WchGrp) = MarkedGrpCntr
IF Pose = 2 TFEN : BGrpCntr(WchGrp) = MarkedGrpCntr
IF Pose = 3 THE[d.: CGrpCntr(WchGrp) = MarkedGrpCntr
IF Pose = 4 THEN : DGrpCntr(WchGrp) = MarkedGrpCntr
END StT
S[JB MrkIntermtLine
CLS
ShowA11Fn1Segs 1-
Finished = False

CA 02483943 2004-11-16
- 138 -
DO WHILE Finished = False
SE.IõECT CASE UserChoice('", "ChooseLine", "Finished",
CASE 1
FindMrkdPtlnAPose ThisOne, "Mark The Line"
WchLine = FindAlnForlntermit(ThisOne)
Ai,ns(WchLine).Intermit = True
-ALns(WchLine).ReyForm = UserChoice("Which Source Pose Shows
This Line?", "A", "B", "C., "D.,
LOCATE 4, 1
INPUT "Enter TriggerPt Range is 0 (always visible) TO 1
(vis if TScript at vertex)"; ALns(WchLine).Threshold
LOCATE 4, 1: PRINT SPACE$(79)
CASE 2
EXIT DO
END SEIIECT
LOOP
CLS
END SUB
SUB MrkObjAnchorPt
CLS
ShowAllFnlSegs 1
Text$ ="Mrk'Point That Will Stay On Anchor"
FindMrkdPtInAPose ThisOne, Text$
END SUB
SUB MrkObjCntr (Message$, WchPose, WchQbj)
DefnPt MarkedObjCntr, Message$, "", 3
IF WchPose = 1 TOM AObjCntr(WchObj) = MarkedObjCntr.
IF WchPose = 2 THaT BObjCntr(WchObj) = MarkedObjCntr
IF WchPose = 3 TIM : CObjCntr(WchObj) = MarkedObjCntr
IF WchPose = 4 TFIEN DObjCntr(WchObj) = MarkedObjCntr
END SUB
SUB MrkScaffoldCntr (Message$, WchObj, WchPose)
DIM UniObjCntr(0) AS t3DPoint
DefnPt UniObjCntr(0), Message$, "MrkScaffoldCntr", 3
IF WchPOse > 1 TRW
Mrk 3, 1'removes mrk put on by defnpt from screen
UniObjCntr(0).Z = ZPlane
XYZ = UniObjCntr(0)
Mrk 2. 1
END IF
SELECT CASE WchPose
CASE 1: AScaffoldCntr(1) = UniObjCntr(0)
ZPlane = UniObjCntr(0).Z
CASE 2: BScaffoldCntr(1) = UniObjCntr(0)
7mDrawingCentrDisp(2).x = BScaffoldCntr(1).x - AScaffoldCntr(l).x
ImDrawingCentrDisp(2).y = BScaffoldCntr(1).y - AScaffoldCntr(1).y
ImDrawingCentrDisp(2).Z = BScaffoldCntr(1).Z - AScaffoldCntr(1).Z
CASE 3: CScaffoldCntr(1) = UniObjCntr(0)
ImDrawingCentrDisp(3).x = CScaffoldCntr(1).x - AScaffoldCntr(1).x
ImDrawingCentrDisp(3).y = CScaffoldCntr(1).y - AScaffoldCntr(1).y
ImDrawingCentrDisp(3).Z = CScaffoldCntr(1).Z - AScaffoldCntr(1).Z
CASE 4: DScaffoldCntr(1) = UniObjCntr(0) ImDrawingCentrDisp(4).x =
DScaffoldCYZtr(l).x - AScaffoldcntr(1).x
ImDrawingCentrDisp(4).y = DScaffoldCntr(1).y - AScaffoldCntr(1).y

CA 02483943 2004-11-16
- 139 -
ImDrawingCentrDisp(4).Z = DScaffoldCntr(1).Z - AScaffoldCntr(1).Z
END SELECT
LOCATE 4, 1: PRINf SPACE$(45)
IIND SUB
SUB MrkScaffoldPts
DIM ADispPt(0) AS t3DPoint
Message$ = "Mark Scaffold RefPoints; <Done> If Finished, Or No Pts
Wanted"
ScaffoldPtIndex = 0
Ans$
DO UNTIL Ans$ = C$
DefnPt ADispPt(0), Message$, "DefnScaffoldPts", 2
ScaffoldPtlndex = ScaffoldPtIndex + 1
ScaffoldDisp(ScaffoldPtlndex).x = AScaffoldCntr(1).x - ADispPt(0).x
ScaffoldDisp(ScaffoldPtindex).y = AScaffoldCntr(1).y - ADispPt(0).y
ScaffoldDisp(ScaffoldPtlndex).Z = AScaffoldCntr(1).Z - ADispPt(0).Z
NoOfScaffoldPts = ScaffoldPtlndex
IAOP
IF Ans$ = C$ TMM
NoOfScaffoldPts = NoOfScaffoldPts - 1
LOCAZ'E 5, 1: PRINT SPACE$(75)
END IF
E'[TU,ID SUB
SUB MrkVisInvisLine
CLS
ShowAllFnlSegs 1
Finished = False
DO UIiiILE Finished = False
SELECT CASE UserChoice("", "ChooseLine", "Finished",
CASE 2
FindMrkdPtInAPose ThisOne, "Mark The Line"
WchLine = FindAlnForlntermit(ThisOne)
INPUT "Appears At Frame"; ALns(WchLine).StartVis
INPUT "Disappears At Frame"; ALns(WchLine).EndVis
CASE 3
MXIT DO
EDID SELECT
LOOP
CLS
END SUB
SUB MtchPtsPartl
NoOfMtchPts = 0
OneSetChosen = False
DoneMtchPts = False
LOCATE 4, 1: PRINT "Reninder: Make MatchPts At Location Of
Future Velcro Pts, If Any"
PRINT "Don't Put MatchPt Near Start Or End Of A Line!"
SLEEP 3
FOR WchLine = 1 TO NoOfLines
CLS
ShowLn 1, WchLine, -1
= 1
Wchpose
FOR q = 1 TO NoOfMtchPts - 1
IF MtchPts(q, 7) = WchLine THIIJ
XYZ.x = GetAReal!(APtsXPg + 3 * (WchPose - 1),
MtchPts(q, WchPose))

CA 02483943 2004-11-16
- 140 -
XYZ.y = GetAReal!(APtsYPg + 3 * (WchPose - 1),
MtchPts(q, WchPose).)
XYZ.Z = GetAReal!(APtsZPg + 3 * (WchPose - 1),
MtchPts(q, WchPose))
Mrk 0, 1
END IF
NEXT
LOCATE 2, 1: PRINT "Avail MatchPts ="; 50 - NoOfMtchPts: SLEEP 1
WHILE Confirm("Make (More) MatchPts On This Line?")
NoOfMtchPts = NoOfMtchPts + 1
AbortMatchPt = False
FOR WchPose = 1 TO 4
CLS 'show existing mtchpts
ShowLn WchPose, WchLine, -1
FOR q = 1 TO NoOfMtchPts - 1
IF MtchPts(q, 7) = WchLine TREni
XYZ.x = GetAReal!(APtsXPg + 3 * (WchPose - 1),
MtchPts(q, WchPose))
XYZ.y = GetAReal!(APtsYPg + 3 * (WchPose - 1),
MtchPts(q, WchPose))
XYZ.Z = GetARea1!(APtsZPg + 3 * (WchPose - 1),
MtchPts(q, WchPose))
Mrk 0, 1 .
END IF
NEXT
MtchPtsPart2 WchPose, NoOfMtchPts
IF AbortMatchPt = True T3iIIJ
NoOfMtchPts = NoOfMtchPts - 1
CLS
ShowLn 1, WchLine, -1
EXIT FOR
END IF
NEXT 'next pose
CLS
LOCATE 2, 1: PRINT "Avail MatchPts 50 - NoOfMtchPts: SLEEP 1
ShowLn 1, WchLine, -1
FOR q= 1 TO NoOfMtchPts
IF MtchPts(q, 7) = WchLine THEN
XYZ.x = GetAReal! (APtsXPg + 3 * (1 - 1), MtchPts(q, 1))
XYZ.y = GetAReal!(APtsYPg + 3 * (1 - 1), MtchPts(q, 1))
XYZ.Z = GetAReal!(APtsZPg + 3 * (1 - 1), MtchPts(q, 1))
Mrk 0, 1
END IF
NEXT
WEND 'make more on same line
NEXT 'next line
END SUB
SUB MtchPtsPart2 (WchPose, MtchPtNdx)
I = WchPose
SELECT CASE I
CASE 1
IF OneSetChosen THM
IF 50 - MtchPtNdx < 2 TFM
BEEP: BEEP: BEEP
PRINT "Last Avl Match Pt!
END IF

CA 02483943 2004-11-16
- 141 -
ELSE
7,OCATE 2, 1: PRINT "Mrk Match Pt in A Image"
END IF
CASE 2: LOCATE 2, 1: PRINT "Mrk Matching Pt in B Image
CASE 3: LOCATE 2, 1: PRINT "Mrk Matching Pt in C Image
CASE 4: LOCATE 2, 1: PRINT "Mrk Matching Pt in D Image
END SELECT
LnNo = WchLine - 1
WchPoseForHili = 2
ShowGuideMatchPts I
MtchPtsPart3 I, MtchPtNdx
END SUB
SUB MtchPtsPart3 (WchPose, MtchPtNdx)
FoundIt = False
MaybeMore:
A$ = "Erase": C$ = "AbortPt": B$ = "Good": D$ _ "Adj"
WndChs "", A$, B$, C$, D$, "x", Ans$, 1
DO
WndIn
ShowCrsr
IFXYZ.y<15THEN
WndSlct Ans$., 1
SELSCT CASE Ans$
CASE A$ 'erase
XYZ = FoundPt
Mrk 0, 1
FoundIt = False
CASE B$ 'good
IF Foundlt = True TFOTi EXIT DO
CASE E$ 'alldone
IF WchPose = 1 AND OneSetChosen = True THEN
DoneMtchPts = True
EXIT DO
END IF
CASE D$ 'adj
IF Foundlt = True TFffiN
AdjMtchPt WchPose, WchLine, MtchPtNdx
G0T0 MaybeMore
END IF
CASE C$ 'abort
BEEP: BEEP
LOCATE 6, 1: PRINT "ABORTING THIS MATCH POINT SLEEP 1
LOCATE 6, 1: PRINT SPACE$(45)
AbortMatchPt = True
EXIT DO
END SELECT
END IF
IF INP(889) < 128 AND Foundlt = False TFM
FindDesPt WchPose, WchLine
IF Foundlt = True THEN
SOUND 50, 3
Mrk 0, 1
MtchPts(MtchPtNdx, WchPose) = ThisOne
MtchPts(MtchPtNdx, 5) = ATans(WchLine).WchGrp
MtchPts(MtchPtNdx, 6) = ALns(WchLine).WchObj
MtchPts(MtchPtNdx, 7) = WchLine

CA 02483943 2004-11-16
- 142 -
FND IF
IF WchPose = 1 AND Foundlt = True TFM
AtLeastOneChosen = True
--------get order of mtchpts in ALn:
ALnPlaceNdx = 0
FC?R q = 1 TO MtchPtNdx
IF MtchPts(q, 7) = WchLine ZHM
ALnPlaceNdx = ALnPlaceNdx + 1
ALnPlace(ALnPlaceNdx, 0) = q 'which mtchpt
ALnPlace(ALnPlaceNdx, 1) = MtchPts(q, 1) 'APose pt
E~ID IF
NEXT
sort according to pt position:
FOR J= 1 TO ALnPlaceNdx - 1
FOR I = 1 TO ALnPlaceNdx - J
IF ALnPlace(I, 1) > ALnPlace(I + 1, 1) THM
SWAP ALnPlace(I, 0), ALnPlace(I + 1, 0)
SWAP ALnPlace(I, 1), ALnPlace(I + 1, 1)
END IF
NEST I
NERT
END IF
IF WchPose > 1 AND Foundlt = True THEN 'sort mtchpts for this Pose and compare
with ALn
'if not same order its no good
OtherLnPlaceNdx = 0
FOR q = 1 TO MtchPtNdx
IF MtchPts (q, 7) = WchLine TFM
OtherLnPlaceNdx = OtherLnPlaceNdx + 1
OtherLnPlace(otherLnPlaceNdx, 0) = q 'which mtchpt
OtherLnPlace(OtherLnPlaceNdx, 1) = MtchPts(q, WchPose)
! ET7D IF
NE}CT
'sort according to pt position:
FOR J = 1 TO OtherLnPlaceNdx - 1
FOR I = 1 TO OtherLnPlaceNdx - J
IF OtherLnPlace(I, 1) > OtherLnPlace(I + 1, 1) THM
SWAP OtherLnPlace(I, 0), OtherLnPlace(I + 1, 0)
SWAP OtherLnPlace(I, 1), OtherLrnPlace(I + 1, 1)
; END IF
NEXT I
NEXT
FOR I l TO OtherLnPlaceNdx
IF OtherLnPlace(I, 0) <> ALnPlace(i, 0) THEN
LOCATE 6, 1: BEEP
PRINT "Erased --Not In Correct Order. Maybe Line Direction
Is Reversed."
PRINT "If So, Quit MatchPts And Reverse Line) Else Do
MatchPt Again"
SLEEP 4
LOCATE 6, 1: PRINT SPACE$(65)
LOCATE 7, 1: PRINT SPACE$(65)
Foundlt = False

CA 02483943 2004-11-16
- 143 -
Mrk 0. 1
EXIT FOR
END IF
NEXT
END IF
AtLeastOneChosen = True
IF WchPose = 4 THEN OneSetChosen = True
END IF
LOOP
END SUB
SUB MyDelay (HowLong)
FOR q= 1 TO 200
FOR I = 1 TO HowLong * 3000: NEXT I
NEXT
END SUB
SUB NameGroups
FOR I = 1 TO NoOfGroups
CLS
FOR J= 1 TO NoOfLines
IF ALns(J).WchGrp = I 4RM ShowLn 1, J,-1
NFFXT
INPL7T "Name For This"; Name$
Group(I):Label = UCASE$(Name$)
NEXT
GroupsNamed = True
IF NoOfGroups = 1 THEN
Object(1).Lebel = UCASE$(Name$)
ObjectNamed = True
END IF
END SUB
SU8 NameObjects
FOR I = 1 TO NoOfObjects
Groups2nThisObj = 0
FOR J = 1 TO NoOfGroups
IF Group(J).WchObj = I THfiT
GroupsInThisObj = GroupsInThisObj + 1
WchGrplnThisObj = J
END IF
NEXT
IF GroupsInThisObj = 1 T.EiEr7
Object(I).Label = Group(WchGrplnThisObj).Label
ELSE
CLS
ShowObj I, 1
INPUT "Name For This Object"; Name$
Object(I).Label = UCASE$(Name$)
IIQD IF
NEXT
ObjectsNamed = True
END SUB
SUB NameWaxps
CLaS
Warplndex = 0
LOCATE 2, 1: PRINT "TO FINISH HIT <Enter>"
DO
FOR I= 1 TO Warplndex

CA 02483943 2004-11-16
- 144 -
LOCATR I + 5: PRINR' "Warp No"; I; Waz'p(I).Label
NEXT
Warplndex = WarpIndex + 1
LACATE 4, 1: INPUT "Warp Name"; Name$
LOCATE 4, 1: PRINT SPACE$(65)
IF Name$ THEN
WarpIndex = WarpIndex - 1
EXIT DO
END IF
Wazp(WarpIndex).Label = UCASE$(Name$)
FOR I = 1 TO Warplndex.
LOCATE I + 5: PRINT "Warp No"; I; Warp(I).Label
1IM'r
pRINT "Remaining Waxps Available:"; 6 Warplndex
LOOP
NoOfWarps = WarpIndex
CLS
FOR I = 1 TO WarpIndex
LOCATE I + 5: PRINT "Warp No"; I; Warp(T).Label
NEXT
END SUB
SUB NoMtChPts
FOR I= 1 TO NoOfLines
TenpSegs(I).AStartPt = ALns(I).Beg
TempSegs(I).AEndPt = ALns(I).Fin
TeznpSegs(I).BStartPt = BLns(2).Beg
TempSegs(I).BEndPt = BLns(I).Fin
TempSegs(I).CStartPt = CLns(I).Beg
TenVSegs(I).CEndPt = CLns(I).Fin
Z'e~npSegs ( I). DStartPt = DLns (1) . Beg
TempSegs(I).DLhdPt = DLns(I).Fin
TempSegs(I).WchGrp = ALns(I).WchGrp
TempSegs(I).WchObj = ALns(I).WchObj
TempSegs(I).WchLine = I
NEXT
NoOfSegs = NoOfLines
Al1MtchPtsOK = True
END SUB
SUB O1dSmooth (RuffPtsO AS.t3DPoint, SmoothPtsO AS t3DPoint,
SmoothRange)
PtLimit = RuffPts(O).x
IF PtLimit < SmoothRange + 1 THM
smoothRange = PtLim.it - 1
IF SmoothRange < 0 TFM SmoothRange = 0
END IF
TotalRange = 2 * SmoothRange + 1
FOR I = 1+ SmoothRange TO PtLimit - SmoothRange
xsum! = 0: ysum! = 0: zsum! = 0
FOR J = I - SmoothRange TO I + SmoothRange
xsum! = xsum! + RuffPts(J).x
ysum! = ysum! + RuffPts(J).y
zsum! = zsum! + RuffPts(J).Z
NEXCt J
SmoothPts(I).x = xsum! / TotalRange

CA 02483943 2004-11-16
- 145 -
SmoothPts(I).y = ystm-! / TotalRange
SmoothPts(I).Z = zsum! / TotaiRange
NEXT I
FOR I = 0 TO Smooth'Range 'puts in pts at start
SmoothPts(I) = RuffPts(I)
NEXT I
FOR I = PtLimit - SmoothRange TO PtLimit 'puts in end pts
SmoothPts(I) = RuffPts(I)
NEXT I
EM SUB
SUB PaintLoop
PRINT "will be paint Loop"
SLEEP 1
END SUB
SUB PathAdj
PathToAdj = UserChoice("Adj Path For Which Object?", Object(1).Label,
Object(2).Label, Object(3).Label,
AdjPathAlongXYZ PathToAdj
END SUB
SUB PathArrayPositPtr (FrameNo, WchPath, ObjPathPos AS t3DPoint)
ObjPathPos.x = GetAReal!(PathlXPg + 3 * (WchPath - 1), FrameNo)
ObjPathPos.y = GetAReal!(PathlYPg + 3 * (WchPath - 1), FrameNo)
ObjPathPos.Z = GetAReal!(PathlZPg + 3*(WchPath - 1), FrameNo)
EIQD SUB
SUB PathShiftToMatchPrevRun (WchObj)
DIM DiffInPosit AS t3DPoint
SELECT CASE WchObj
CASE 1
DifflnPosit.x = ObjFinalPositions(1).FinalPositObjl.x -
GetAReal!(TenVPtsXPg, 1)
DifflnPosit.y = ObjFinalPositions(l).FinalPositObjl.y -
GetAReal!(TempPtsYPg, 1)
DifflnPosit.Z = ObjFinalPositions(1).FinalPositObjl.Z -
GetAReal!(TenmpPtsZPg, 1)
CASE 2
DifflnPosit.x = ObjFinalPositions(1).FinalPositObj2.x -
GetAReal!(TempPtsXPg, 1)
DifflnPosit.y = ObjFinalPositions(1).FinalPositObj2.y -
GetAReal!(TempPtsYPg, 1)
DiffInPosit.Z = ObjFinalPositions(1).FinalPositObj2.Z -
GetAReal!(TempPtsZPg, 1)
CASE 3
DiffInPosit.x = ObjFinalPositions(1).FinalPositObj3.x -
GetAReal!(TempPtsXPg, 1)
DiffInPosit.y = ObjFinalPositions(1)=FinalPositObj3.y -
GetAReal!(TeMPtsYPg, 1)
DiffInPosit.Z = ObjFinalPositions(1).FinalPositObj3.Z -
GetAReal!(TempPtsZPg, 1)
END SELECT
FOR I = 1 TO GetA(Te.mpPtsXPg, 0)
SetArrayReal TempPtsXPg, I, GetAReal!(TempPtsXPg, I) + DifflnPosit.x
SetArrayReal TempPtsYPg, I, GetAReal!(TempPtsYPg, I) + DifflnPosit.y
SetArrayReal TempPtsZPg, I, GetAReal!(TempPtsZPg, I) + DifflnPosit.2
NEXT
LOCATE 4, 1: PRINT "Shifting Path To Match Start To End Of Previous Run"

CA 02483943 2004-11-16
- 146 -
SLEEP 1
LOCATE 4, 1: PRINT SPACE$ (75)
END SUB
SUB PlaceFrmChrtSymcPtsOnPath (Kind, WchNo)
3ortSyncPtsForApplic Kind, WchNo
SELECT CASE Kind
CASE 1: ScanSyncPtsName = eScanForObjPathSyncPt
CASE 2: ScanSyncPtsName = eScanForTransSyncPt
CASE 3: ScanSyncPtsName = eScanForWarpSyncPt
END SELECT
FOR I = 2 TO No0f3ortedSyncPts - 1 'leaves out start and end
IF Kind = 1 TFM
WchPath = Object(Group(WchGrp).WchObj)PathNo
IF WchPath = 1 Tf0M ShowObjPath PathlXPg, 1
IF WchPath = 2 TFM ShowobjPath Path2XPg, 1
IF WchPath = 3 TFM ShowObjPath Path3XPg, 1
END IF
LOcATE 3, 1
PRINT "I4ARIC LOCATION FOR SYNC PT: "; SortedSyncPts(I)Label
FoundIt = False
'DO WHILE FoundIt = False
WndPtScan WchObj; Obj2, WchGrp, Gxp2, TempPtsXPg,
GetA(TempPtsXPg, 0), 1, ScanSyncPtsName
IF FoundIt = True TIiEN
MyDelay 1
SortedSyncPts(I).TempPtsIndex = ThisOne
SOUND 4000, 3
EXIT DO
END IF
LOOP
I,OCATE 5, 1
PRINT "Marked So Far:"
IAC',ATE 4 + I
PRINT SortedSyncPts(I).Label; " At TempPt"; ThisOne; Frm";
SortedSyncPts(I).Frame
NEXT
END SUB
SUB PlaceSyncPtsOnY''xmChrt (Kind, WchOne, Text$)
CLS
Range = 3
SyncPtlndexAtStartOfFrmChrt = SyncPtIrndex
rlkFrameScreenV4 Kind, WchOne
ShowSyncPtLines SyncPtlndexAtStartOfFrmChrt
,m
Wndin
CalcFlatXY
ShowFlatCrsr
IF XYZ.y < 15 TFm WndSlct Ans$, 1
FoundIt = False
LOCATE 2, 1: PRINT "Place Desired Sync Pt
DO WHILE Foundlt = False
FindFrntInChartObjGrpWarp Kind, WchOne, WchFrame
XLocat = XYZ.x
SyncPtIndex = SyncPtIndex + 1
syncpts(SyncPtlndex).Frame = WchFrame

CA 02483943 2004-11-16
- 147 -
LOOP
UsingExistSyncPt = False
XPos = 40 + interval! * (WchFrame - 1)
YPos = 70
Height = 34
LINE (XPos, YPos)-(XPos, YPos + Height), 14
SELECT CASE Kind
CASE 1: syncpts(SyncPtIndex).WchObj = WchOne
CASE 2: syncpts(SyncPtIndex).WchGrp = WchOne
CASE 3: syncpts(SyncPtlndex).WchWrp = WchOne
END SELECT
FOR q 1 TO SyncPtIndex - 1 'becuz last syncpt has just been
put on
IF syncpts(q).Frame = WchFrame THm
syrncpts(SyncPtIndex).Label = syncpts(q).Label
syncpts(SyncPtlndex).TempPtslndex = syncpts(q).TempPtsIndex
ShowSyncPtLines SyncPtlndexAtStartOfFrmChrt
LOCATE 1, 1: PRINT "Using Existing Name ".: MyDelay 1
UsingExistSyncPt = True
END IF
I$om
IF UsingExistSyncPt = False THM
LOCATE 1, 1: INPUT =Name For This SyncPt U. Text$
syncpts(SyncPtlndex).Label = STR$(WchFrame) + -= + UCASE$(Text$)
ShowSyncPtLines SyncPtlndexAtStartOfFrmChrt
END IF
LOCATE 1, 1: PRINT SPACE$(75)
C$ = "More": D$ = "Finished"
Wnd.(:!hS "", xX", "X", C+$, D$, "X", Ans$, 0
LOCATE 1, 1: PRINT SPACE$(75)
LOCATE 2, 1: PRINT SPACE$(75)
IF Ans$ = D$ TM:N RXIT DO
ShowSyncPtLines SyncPtlndexAtStartOfFrmChrt: SLEEP 1
LOOP
CLS
EDID SUB
SUB P1aceSyncPtsOnTempPath (Kind, WhichOne, PathText$)
SyncPtlndexSoFar = SyncPtlndex
LOCATE 1, 1: PRINT PathText$
SELECT CASE Kind
CASE 1: ScanSyncPtsName = eScanForobjPathSyncpt
CASE 2: ScanSyncPtsName = eScanForTransSyncPt
CASE 3: ScanSyncPtsName = eScanForWarpSyncPt
END SELECT
SyncPtsOK = False
WHILE NOT SyncPtsOK
DO
ErsMnu
SELECT CASE UserChoice(=MARK SYNC POINT (Touch <Mark> First)
R "Mark , , "", "Finished")
CASE 5
EXIT DO
CASE 2
WndPtScan WchObj, Obj2, WchGrp, Grp2, TempPtsXPg,

CA 02483943 2004-11-16
- 148 -
GetA(TempPtsXPg, 0), 1, eScanForObjPathSyncPt
SOUM 4000, 2
END SELECT
SyncPtlndex = SyncPtlndex + 1
syncpts(SyncPtindex).TempPtsIndex = ThisOne
syncpts(SyncPtIndex)Frame =
CINT((syncpts(SyncPtIndex).TempPtsIndex /
GetA(TempPtsXPg, 0)) * NoOfFrames)
IF Kind = 1 THM
syncpts(SyncPtlndex).WchObj = WhichOne
END IF
IFKind=2T1iEN
syncpts(SyncPtindex).WchGrp = WhichOne
END IF
IFKind=3TFM
syncpts(SyncPtlndex).WchWrp = WhichOne
END IF
LOCATE 1, 1
INPUT "Name For This Sync Pt "; Name$
LOCATE 1, 1: PRINT SPACE$ (79)
syncpts(SyncPtIndex).ILabel = STR$(syncpts(SyncPtlndex).Frame) +
"_" + UCASE$(Name$)
IF SyrncPtIndex > 0 TFMq
LOCATE 5, 1
PRINT "Marked So Far:"
FOR T = SyncPtIndexSoFar + 1 TO SyncPtIndex
IF T > 0 THEN PRINT syncpts (T) .Labei; At Tenq,~Pt" ;
syncpts(T).TempPtsIndex; " Frm"; syncpts(T).Frame
NEXT
END IF
LOOP
IF Confirm("SyncPtsOK") TFM
SyncPtsOK = True
ELSE
SyncPtlndex = SyncPtlndexSoFar
CL.S
DrawPartialArray TempPtsXPg, 1,.GetA(TempPtsXPg, 0), -1, False
END IF
WEND
EIVD SUB
SUB PutbrwMnuOnScrn (Text$, WchPose, Version)
'Version 0 is when drawing, 1 when finished
ErsMnu
IF Scaffold = True THEN A$ _"TogglScaff" ELSE A$
IF WchPose = 1 THM B$ ="Line Color" ELSE B$ = "UsePrevLn"
IF LnNo > 0 Tfg3N D$ ="Del Last" ELSE D$ ="x"
IF WchPose = 1 Z'HEN E$ ="x" ELSE E$ ="Rpt A Pose"
SELECT CASE WchPose
CASE 1
A$ = "Name Line"
IF FrstLn = True THEN C$ = "Finished A" ELSE C$
WrndChs Text$, A$, B$, C$, D$, E$, Ans$, 1
CASE 2
IF Version = 0 THEN C$ ="x"
IF Version = 1 THM C$ ="Finished B": B$ ="x": E$ X.
WndChs Text$, A$, B$, C$, D$, E$, Ans$, 1

CA 02483943 2004-11-16
- 149 -
CABE 3
IF Version = 0 RHM C$ ="x"
IF Version = 1 7EM C$ ="Finished C": B$ -"x": E$ -"x"
WndChs Text$, A$, B$, C$, D$, E$, Ans$, 1
CASE 4
IF Version = 0 THEtd. C$ ="x"
IF Version = 1 TfB's!d C$ = "Finished D": B$ "x": E$ _"x"
WndChs Text$, A$, B$, C$, D$, E$, Ans$, 1
E[QD SELECT
IF Version = 0 AND WchPose = 1'PEM
LOCATE 2, 1
PRINT "DRAW <" + CHR$(64 + WchPose) +SOURCE POSE"
END IF
IF Version = 0 AND WchPose > 1 TFIIsTt
LOCATE 2, 1
PRINT "DRAW CORRESPONDING LINE " + ALns(LnNo),Label +
IN <" + CHR$(64 + WchPose) +"> SOURCE POSE"
END IF
IF Version = 1 THEN LOCATE 2, 1: PRINT SPACE$(50)
END SUB
SUB PutlnGrp (WchLine, WchGrp)
ALns(WchLine).WchGrp = WchGrp
BLns(WchLine).WchGrp = WchGrp
CLns(WchLine).WchGrp = WchGrp
DLn.s(WchLine).WchGrp = WchGrp
IF NoOfGroups < WchGrp THM NoOfGroups = WchGrp
END SUB SUB PutinObj (WchGrp, WchObj)
FOR K = 1 TO NoOfLines
IF ALns (K) .WchGrp = WchGrp THEN
ALns(K).WchObj = WchObj
BLns(K).WchObj = WchObj
CLns(K).WchObj = WchObj
DLns(K).WchObj = WchObj
Group(WchGrp).WchObj = WchObj
END IF
NEU
IF NoOfObjects < WchObj TFiE!J'NoOfObjects = WchObj
END SUB
SUB ReCntrGrp (WchGrp, PtArray, CenterOfGrp() AS t3DPoint)
DIM Disp(0) AS t3DPoint
Disp(0).x = CenterOfGrp(WchGrp).x - AGrpCntr(WchGrp).x
Disp(0).y = CenterOfGrp(WchGrp).y - AGrpCntr(WchGrp).y
Disp(0).Z = CenterOfGrp(WchGrp).Z - AGrpCntr (WchGrp) . Z
FOR J = 1 TO NoOfSegs
IF FinlSgs(J).WchGrp = WchGrp TFM
FOR I = FinlSgs(J).Beg TO FinlSgs(J).Fin
SetArrayReal PtArray, I, GetAReal! (PtArray, I) - Disp(0).x
SetArrayReal PtArray+l, I, GetAReal!(PtArray+l, I),- Disp(O).y
SetArrayReal PtArray+2, I, GetAReal! (PtArray+2, I) - Disp(0).Z
NERT
E!VD IF
NEXT
EnID SUB

CA 02483943 2004-11-16
- 150 -
3UB ReCntrObj (WchObj, PtArray, CenterOfObj() AS t3DPoint)
DIM Disp(0) AS t3DPoint
Disp(0).x = CenterOfObj(WchObj).x - AObjCntr(WchObj).x
Disp(0).y = CenterOfObj(WchObj).y - AObjCntr(WchObj).y
Disp(0).Z = CenterOfObj(WchObj) .Z - AObjCntr(WchObj).Z
FOR J= 1 TO NoOfSegs
IF FinlSgs(J).WchObj = WchObj TFM
FOR I = FinlSgs(J).Beg TO Finlsgs(J).Fin
SetArrayReal PtArray, I, GetAReal!(PtArray, I) - Disp(0).x
SetArrayReal PtArray+l, I, GetAReal!(PtArray+l, I) - Disp(0).y
SetArrayReal PtArray+2, I, GetAReal!(PtArray+2, I) - Disp(0):Z
NF,XL'
END IF
NEXT
FT7D SUB
SUB ScanPoseTrans (ForWhat, WchGrp, WchObjPath, FrameNo)
'scans tetra space by wand position and
shows resulting group transform in a path position according
to path and
'which frame has been set (or in a static position if group is static)
DIM ObjCntr AS t3DPoint
DIM Disp AS t3DPoint
DIM Pt AS t3DPoint
ErsNtnu
LOCATE 1, 1
IF ForWhat = 0 THEN PRINT 'Explore Possible Action Available
For Group(WchGrp).Label; " (click to exit)"
SetupTetra
ZCorrection = 40
LensFocalLength = 35
SetA FastWorkArraylXPg + 3 BuildToggle, 0, 0 'Inhibit initial erase
DO
Wndln
ShowCrsr
IF ForWhat <> 0 THEN
IF XYZ. y< 15 THEN
WndSlct Ans$, 1
SFsLECT CASE Ans$
CASE 8$
FrameNo = FrameNo - 1
CASE C$
FrameNo = FrameNo + 1
EZ7D SELECT
END IF
IIQD IF
IF FrameNo > NoOfFrames THEN FrameNo = NoOfFrames
IF FrameNo < 1 THEN FrameNo = 1
Ndx = 0
IF Ca1cTProps(0) TFM '0 is fake frame no;

CA 02483943 2004-11-16
- 151 -
uses XYZ from Wand Position
FOR SegNo = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchGrp = WchGrp THEN
StartPt = FinlSgs(SegNo).Beg
SndPt = FinlSgs(SegNo).Fin
Grp = FinlSgs(SegNo).WchGrp
IF ForWhat = 0 OR ForWhat = 2 THEN
ObjPathPosit.x = AObjCntr(ObjNo).x
ObjPathPosit.y = AObjCntr(ObjNo).y
ObjPathPosit.Z = AObjCntr(ObjNo).Z
END IF
IF ForWhat = 1 TFEN 'if exploring Poses there is no path yet
PathArrayPositPtr FrameNo, WchObjPath, ObjPathPosit
Disp.x = ObjPathPosit.x - AObjCntr(WchObj).x
Disp.y = ObjPathPosit.y - AObjCntr(WchObj).y
Disp.Z = ObjPathPosit.Z - AObjCntr(WchObj).Z
END IF
NegZ! = AObjCntr(ObjNo).Z / ZDivisor - ZCorrection
PFac! = LensFocalLength / NegZ!
FOR PtNo = StartPt TO EndPt STEP INT(GetA(APtsXPg, 0) / 150) + 1
Pt.x = TransGrfVal(0).PropA * GetAReal!(APtsXPg, PtNo)'+
TransGrfVal(0).PropB * GetAReal!(BPtsXPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsXPg, PtNo) +
TransGrfVal(0).PropD * GetAReal!(DPtsXPg, PtNo) +
Disp.x
Pt.y = TransGrfVal(0).PropA * GetAReal!(APtsYPg, PtNo) +
TransGrfVal(0).PropB * GetAReal!(BPtsYPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsYPg, PtNo) +
TransGrfVal(0).PropD * GetAReal!(DPtsYPg, PtNo) +
Disp.y
Pt.Z = TransGrfVal(0).PropA * Get.AReal!(APtsZPg, PtNo) +
TransGrfVal(0).PropB * GetAReal!(BPtsZPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsZPg, PtNo) +
TransGrfVal(0).PropD * GetAReal!(DPtsZPg, PtNo) +
Disp.Z
IF VkiatFor = 1 OR WhatFor = 2 TON
Pt.x = ObjPathPosit.x - (PFac! * (Pt.x - ObjPathPosit.x))
Pt.y = ObjPathPosit.y - (PFac! * (Pt.y - ObjPathPosit.y))
Pt.Z = ObjPathPosit.Z - (PFac! * (Pt.Z - ObjPathPosit.Z))
END IF
Ndx=Ndx+ 1
SetArrayReal FastWorkArraylXPg + gBuildToggle, Ndx, Pt.x
SetArrayReal FastWorkArraylYPg + gBuildToggle, Ndx, Pt.y
SetArrayReal FastWorkArraylZPg + gBuildToggle, Ndx, Pt.Z
NEXT 'point along the seg
END IF
NEXT '(seg)
FI~ID IF
SetA FastWorkArraylXPg + gBuildToggle, 0, Ndx
ShowCrsr
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, 0, False
IF INP(889) < 128 THEN EXIT DO
gBuildToggle = 3 - gBuildToggle

CA 02483943 2004-11-16
- 152 -
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, -1, False
LOOP
LOCATE 12, 1: PRINI' SPACE$(55)
END SUB
SUB SetA (PageNo, Index, Value)
SetArray PageNo, Index, Value
EHID SUB
SUB SetTJpGlueLoops
B$ = "No": C$ = "CnfirmEach": D$ "Automatic"
WndChs "Glue Loops For Later Painting?", "x", B$, C$, D$, "x", Ans$, 0
SELECT CASE Ans$
CASE B$: MkLineLoop$ = B$
CASE C$: MkLineLoop$ = C$
CASE D$: MkLineLoop$ = D$
END SELECT
GlueLoops =(MkLineLoop$ = C$ OR MkLineLoop$ = D$)
END SUB
SUB SetupTetra
FORI=1T04
XYZ = TPts(I)
Ca1cLXRXY
TEnds (I) = LXRXY
NEXT
COLOR 4: LOCATE 23, 6: PRINT "A"
COLOR 9: LOCATE 23, 5: PRINT "A"
COLOR 4: LOCATE 23, 65: PRINT "C"
COLOR 9: LOCATE 23, 64: PRINT "C"
COLOR 4: LOCATE 4, 41: PRINT "B"
COLOR 9: LOCATE 4, 40: PRINT "B"
COLOR 4: LOCATE 18, 31: PRINT "D"
COLOR 9: LOCATE 18, 35: PRINT "D"
COLOR 5
MkTetLns 1, 2
MkTetLns 1, 3
mkTetLns 1. 4
mkTetLns 2, 3
mkTetLns 2, 4
mkTetLns 3, 4
END SUB
SUB ShiftPathOneFrame (WchPath)
END SUB
SUB ShortCutGroups
NoOfLines = ALns(0).Beg
IF NoOfLines = 1 THEN
ALns(1).WchGrp = 1: BLns(1)WohGrp = 1
CLns(1).WchGrp = 1: DLns(1).WchGrp = 1
NoOfGroups = 1
GroupsDefnd = True
END IF
END SUB
SUB ShortCutObjects

CA 02483943 2004-11-16
- 153 -
IF NoOfGroups = 1 TfM
FOR I= 1 TO NoOfLines
ALns(I).WchObj = 1: BLns(I).WchObj = 1
CLns(I).WchObj = 1: DLns(I).WchObj = 1
NMXT
Group(1).WchObj = 1
NoOfQbjects = 1
ObjectsDefnd = True
ET1D IF
END SUB
SLTB ShowAllFnlSegs (WchPose)
FOR I= 1 TO NoOfLines
SELECT CASE WchPose
CASE 1
ShowFnlSegs APtsXPg, I, -1
CASE 2
ShowFnlSegs BPtsXPg, I, -1
CASE 3
ShowFnlSegs CPtsXPg, I, -1
CASE 4
ShowFnlSegs DPtsXPg, I, -1
Ez1D SELBCT
NMT
END SUB
SUB ShowAllSegStarts
FOR I = 1 TO NoOfSegs
GetXYZ FinlSgs(I).Beg
Mrk 0, 1
NEXT
END SUB
SUB ShowASegStart (WchSeg)
A = FinlSgs(Wchseg).Beg
B = FinlSgs(WchSeg).Beg + 8
GetXYZ A
Mrk 0, 1
GetXYZ B
Mrk 2, 1
E[JD SUB
SUB ShowCrsr
Ca1cL7tXY
CalcMrkrPts
PUT (LastMrkrPts.lx, LastMrkrPts.y), LCrsr
PUT (LastMrk.rPts.rx, LastMrkrPts.y), RCrsr
PUT (MrkrPts.lx, MrkrPts.y), LCrsr
PUT (MrkrPts.rx, MrkrPts.y), RCrsr
LastMrkrPts = MrkrPts
SM SUB
SUB ShowFinalLn (WchPose, LnNo, ShowColor)
DrawPartialArray APtsXPg + 3 * (WchPose - 1), ALns(LnNo).FinalStart,
ALns(LnNo).FinalEnd, ShowColor, True
F.ND SUB
SUB ShowFlatCrsr
CalcFlatXY

CA 02483943 2004-11-16
- 154 -
CalcMrkrPts
PUT (LastMrkrPts.lx, LastMrkrPts.y), LCrsr
PUT (LastMrkrPts.rx, LastMrkrPts.y), RCrsr
PUT (MrkrPts.lx, MrkrPts.y), LCrsr
PUT (MrkrPts.rx, MrkrPts.y), RCrsr
LastMrkrPts = MrkrPts
END SUB
SUB ShowFlatPt (x, y, C)
PSE'T (x, Y), C
IIVD SUB
SUB ShowFnlSegs (WchArray, WchLn, ShowColor)
FOR I = 1 TO NoOfSegs
IF FinlSgs ( I). WchLine = WcrhLn Tam
DrawPartialArray WchArray, FinlSgs(I).Beg, FinlSgs(I).Fin,
ShowColor, False
END IF
NhXT
END SUB
SUB ShowGroupTScript (WchGrp, Grp2, Scanlndex, IndexType$)
DIM Pt AS t3DPoint
'scans thru tetra space according to wand posit
'shows group where it was first drawn in A Pose
IF IndexType$ ==Terap" TFM StartVis = 0: FsndVis = 10000
,*************************** Find totalpoj.nts to be drawn TotalPoints = 0
FOR SegNo = 1 TO NopfSegs
IF FinlSgs(SegNo).WchGrp = WchGrp TIIEN
TotalPoints=TotalPoints + FinlSgs(SegNo).Fin-FinlSgs(SegNo).Beg+l
END IF
NEXT
*************************** Build up into toggled buffer area
Ndx = 0
IF CalcTProps(0) THEN 0 is frame no to put prop vals in,
using XYZ from wand position in CalcTProps
FOR SegNo = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchGrp=WchGrp OR FinlSgs(SegNo).WchGrp=Grp2 TM!V
IF IndexType$ = "Frames" THEN
StartVis = ALns(FinlSgs(SegNo).WchLine).StartVis
EndVis = ALns(Finlsgs(SegNo).WchLine).EndVis
END IF
IF StartVis <= ScanIndex AND EndVis >= ScanIndex THEN
FOR PtNo = FinlSgs(SegNo).Beg TO FinlSgs(SegNo).Fin
STEP INT(TotalPoints / 150) + 1
Ndx = Ndx + 1
Pt.x = TransGrtVa1(0)_PropA * GetAReal!(APtsXPg, PtNo) +
TransGrfVal(0).PropB * GetAReal!(BPtsXPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsXPg, PtNo) +
TransGrfVal(0).PropD * Ge.tAReal!(DPtsXPg, PtNo)
Pt.y = TransGrfVal(0).PropA * GetARea1!(APtsYPg, PtNo) +
TransGrfVal(0).PropB * GetAReal!(BPtsYPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsYPg, PtNo) +
TransGrfVal(0).PropD * GetAReal!(DPtsYPg, PtNo)
Pt.Z = TransGrfVal(0).PropA * GetAReal!(APtsZPg, PtNo) +
TransGrfVal(0).PropB * GetAReal!(BPtsZPg, PtNo) +
TransGrfVal(0).PropC * GetAReal!(CPtsZPg, PtNo) +

CA 02483943 2004-11-16
- 155 -
TransGrfVal(0).PropD * GetAReal!(DPtsZPg, PtNo)
SetArrayReal FastWorkArraylXPg + gBuildToggle + 0, Ndx, Pt.x
SetArrayReal FastWorkArraylXPg + gBuildToggle + 1, Ndx, Pt.y
SetArrayReal FastWorkArraylXPg + gBuildToggle + 2,: Ndx, Pt.Z
NEXT 'point along the seg
IIVD IF
END IF
NEXT
END IF
SetA FastWorkArraylXPg + gBuildToggle, 0, Ndx
'**************************** Uridraw previous buffer and draw new one
DrawArray FasttnTorkArraylXPg + 3 - gBuildToggle, 0, False
gBuildToggle = 3 - gBuildToggle
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, -1, False
EbID S[3B
SUB ShowGrp (WchPose, WchGrp, ShowColor)
FOR I= 1 TO NoOfSegs
IF FinlSgs(I).WchGrp = WchGrp THEN
SELECT CASE WchPose
CASE 1: WchArray = APtsXPg
CASE 2: WchArray = BPtsXPg
CASE 3: WchArray = CPtsXPg
CASE 4: WchArray = DPtsXPg
E[JD SEL,~'CT
DrawPartialArray WchArray, FinlSgs(I).Beg, FinlSgs(I).Fin,
ShowColor, False
END IF
NEXT
END S[TB
SUB Show~urpTransInPathPosit (WchObj, WchGrp, Grp2, index)
DIIm ObjC7itr AS t3DPoint, Disp AS t3DPoint, Pt AS t3DPoint
Path = Object(Group(WchGrp).WchObj).PathNo
PathArrayPositPtr index; Path, ObjPathPosit
TransPtr Index, WchGrp, AliProp
ZCorrection = 40
LensFocalLength = 35
NegZ! = ObjPathPosit.Z / ZDivisor - ZCorrection
PFac! = LensFocalLength / NegZ!
Disp.x = ObjPathPosit.x - AObjCntr(WchObj).x
Disp.y = ObjPathPosit.y - AObjCntr(WchObj).y
Disp.Z = ObjPathPosit.Z - AObjCntr(WchObj).Z
'*************************** Find total points to be drawn
TotalPoints = 0
FOR SegNo = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchGrp=WchGrp OR FinlSgs(SegNo).WchGrp=Grp2 THEN
TotalPoints = TotalPoints+FinlSgs(SegNo).Fin-FinlSgs(SegNo).Beg+1
END IF
NEXT
'*************************** Build up into toggled buffer area
Ndx = 0

CA 02483943 2004-11-16
- 156 - FOR SegNo = 1 TO NoOfSegs
IF Fi.nlSgs(SegNo).WchGrp = WchGrp TfM
IF ALns(FinlSgs(SegNo).WchLine).StartVis <= Index AND
ALns(FinlSgs(SegNo).WchLine).EndVis >= Index THEN
FOR PtNo = FinlSgs(SegNo).Beg TO FinlSgs(SegNo).Fin STEP
INT(TotalPoints / 150) + 1
Ndx = Ndx + 1
Pt.x = AllProp.PropA * GetAReal!(APtsXPg, PtNo) +
AllProp.PropB * GetAReal!(BPtsXPg, PtNo) +
AllProp.PropC * GetAReal!(CPtsXPg, PtNo) +
AllProp.PropD * GetAReal!(DPtsXPg, PtNo) + Disp.x
Pt.y = A11Prop.PropA * GetAReal!(APtsYPg, PtNo) +
AllProp.PropB * GetAReal!(BPtsYPg, PtNo) +
AllProp.PropC * GetAReal!(CPtsYPg, PtNo) +
AllProp.PropD * GetAReal!(DPtsYPg, PtNo) + Disp.y
Pt.Z = Al1Prop.PropA * GetAReal!(APtsZPg, PtNo) +
AllProp.PropB * GetAReal!(BPtsZPg, PtNo) +
A11Prop.PropC * GetAReal!(CPtsZPg, PtNo) +
AllProp.PropD * GetAReal!(DPtsZPg, PtNo) + Disp.Z
Pt.x = ObjPathPosit.x - (PFac! * (Pt.x - ObjPathPosit.x))
Pt.y = ObjPathPosit.y - (PFac! * (Pt.y - ObjPathPosit.y))
Pt.Z = ObjPathPosit.Z - (PFac! * (Pt.Z - ObjPathPosit.Z))
SetArrayReal FastWorkArraylxPg + gBuildToggle + 0, Ndx, Pt.x
SetArrayReal FastWorkArraylXPg + gBuildToggle + 1, Ndx, Pt.y
SetArrayReal FastWorkArraylXPg + gBuildToggle + 2, Ndx, Pt.Z
NSRT 'point along the seg
END IF
ELVD IF
NEXT
TransPtr Index, Grp2, AllProp
FOR SegNo = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchGrp = Grp2 THM
IF ALns(FinlSgs(SegNo).WchLine).StartVis <= index AND
ALns(FinlSgs(SegNo).WchLine).EndVis >= Index THEN
FOR PtNo = FinlSgs(SegNo).Beg TO FinlSgs(SegNo).Fin STEP
INT(TotalPoints / 150) + 1
Ndx = Ndx + 1
Pt.x = AllProp.PropA * GetAReal!(APtsXPg, PtNo) +
AllProp.PropB * GetAReal!(BPtsXPg, PtNo) +
A11Prop.PropC * GetAReal!(CPtsXPg, PtNo) +
A11Prop.PropD * GetAReal!(DPtsxPg, PtNo) + Disp.x
Pt.y = A11Prop.PropA * GetAReal!(APtsYPg, PtNo) +
A11Prop.PropB * GetAReal!(BPtsYPg, PtNo) +
AllProp.PropC * GetAReal!(CPtsYPg, PtNo) +
A11Prop.PropD * GetAReal!(DPtsYPg, PtNo) + Disp.y
Pt.Z = AllProp.PropA * GetAReal!(APtsZPg, PtNo) +
AllProp.PropB * GetAReal!(BPtsZPg, PtNo) +
A11Prop.PropC * GetAReal!(CPtsZPg, PtNo) +
A11Prop.PropD * GetAReal!(DPtsZPg, PtNo) + Disp.Z
Pt.x = ObjPathPosit.x - (PFac! * (Pt.x - ObjPathPosit.x))
Pt.y = ObjPathPosit.y - (PFac! * (Pt.y - ObjPathPosit.y))
Pt.Z = ObjPathPosit.Z - (PFac! * (Pt.Z - ObjPathPosit.Z))

CA 02483943 2004-11-16
- 157 -
SetArrayReal FastWorkArraylXPg + gBuildToggle + 0, Ndx, Pt.x
SetArrayReal FastWorkArraylRPg + gBuildToggle + 1, Ndx, Pt.y
SetArrayReal FastWorkArraylXPg + gBuildToggle + 2, Ndx, Pt.Z
NEXT 'point along the seg
END IF
END IF
NE}LT
SetA FastWorkArraylXPg + gBuildToggle, 0, Ndx
**************************** Undraw previous buffer and draw new one
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, 0, False
gBuildToggle = 3 - gBuildToggle
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, -1, False
END SUB
SUS ShowUuideLn (WchPose)
IF WchPose = 1 THM ShowGuideLnPart2 BLnsO, BPtsXPg, WchPose
IF WchPose = 2 THM $howGuideLnPart2 ALnsO, APtsXPg, WchPose
IF WchPose = 3 THEN ShowGuideLnPart2 BLnsO, BPtsXPg, WchPose
IF WchPose = 4 THM Show3uideLnPart2 CLnsO, CPtsRPg, WchPose
END SUB
SUB ShowGuideLnPart2 (LnArrayO AS LineType, PtArray, WchPose)
IF p,i,ns (0) . Beg <> 0 AND LnNo + 1< ALns (0) . Beg + 1 TxEN
HiLiLn LnArrayO; PtArray, LnNo + 1
FND IF
EM S[JB
SUB ShowGuideMatchPts (WchPose)
IF WchPose = 1 THM ShowGuideLnPart2 ALnsO, APtsXPg, WchPose
IF WchPose = 2 THEN ShowGuideLnPart2 BLnsO, BPtsXPg, WchPose
IF wchPose =3 THEN ShowGuideLnPart2 CLnsO, CPtsXPg, WchPose
IF WchPose = 4 TUDI ShowGuideLnPart2 DLnsO, DPtsXPg, WchPose
END SUB
SUB ShowLn (WchPose, LnNo, ShowColor)
SELECT CASE WchPose
CASE 1
GetStartFinish ALns(, LnNo, Start, Finish
DrawPartialArray APtsXPg, Start, Finish, ShowColor, True
CASE 2
GetStartFinish BLnsO, LnNo, Start, Finish
DrawPartialArray BPtsXPg, Start, Finish, ShowColor, True
CASE 3
GetStartFinish CLns(), LnNo, Start, Finish
DrawPartialArray CPtsXPg, Start, Finish, ShowColor, True
CASE 4
GetStartFinish DLnsO, LnNo, Start, Finish
DrawPartialArray DPtsXPg, Start, Finish, ShowColor, True
END SELECT
END SUB
SUB ShowObj (WchObject, WchPose) 'before lines turned into segs
FOR I = 1 TO NoOfLines

CA 02483943 2004-11-16
158 -
IF ALns(I).WchObj = WchObject THM
ShowLn WchPose, I, -1
END IF
NEXT
END SUB
SUB 3howObjectSegs (aObj, aPose, aColor, aUseLines)
FOR I= 1 TO NoOfSegs
IF FinlSgs(I).WchObj = aObj THEN
DrawPartialArray APtsXPg+3*(aPose-1), FinlSgs(I).Beg,
FinlSgs(I).Fin, aColor, aUseLines
END IF
NEXT
END SUB
SOB ShowObjOnPath (WchObj, Obj2, ObjPathPosit AS t3DPoint)
DIM Pt AS t3DPoint
Simplified to show only A Pose
ZCorrection = 40
LensFocalLength = 35
NegZ! = ObjPathPosit.Z / ZDivisor - ZCorrection
PFac! = LensFocalhength / NegZ!
*************************** Find total points to be drawn
TotalPoints = 0
FOR SegNo = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchObj = WchObj THEN
TotalPoints = TotalPoints+FinlSgs(SegNo).Fin-FinlSgs(SegNo).Beg+1
EAID IF
NEXT
~*************************** Build up into toggled buffer area
Ndx = 0
FOR SegNO = 1 TO NoOfSegs
IF FinlSgs(SegNo).WchObj = WchObj TM!4
FOR PtNo = FinlSgs(SegNo).Beg TO FinlSgs(SegNo).Fin
STEP INT(TotalPoints / 150) + 1
Ndx = Ndx + 1
Pt.x = GetAReal!(APtsXPg,PtNo)+ObjPathPosit.x-AObjCntr(WchObj).x
Pt.y = GetAReal!(APtsYPg,PtNo)+ObjPathPosit.y-AObjCntr(WchObj).y
Pt.Z = GetAReal!(APtsZPg,PtNo)+ObjPathPosit.Z-AObjCntr(WchObj).Z
Pt.x = ObjPathPosit.x - (PFac! * (Pt.x - ObjPathPosit.x))
Pt.y = ObjPathPosit.y - (PFac! (Pt.y - ObjPathPosit.y))
Pt.Z = ObjPathPosit.Z - (PFac! * (Pt.Z - ObjPathPosit.Z))
SetArrayReal FastWorkArraylXPg + gBuildToggle, Ndx, Pt.x
SetArrayReal FastWorkArraylYPg + gBuildToggle, Ndx, Pt.y
SetArrayReal FastWorkArraylZPg + gBuildToggle, Ndx, Pt.Z
NERT 'point along the seg
END IF
NExT
SetA FastWOrkArraylXPg + gBuildToggle, 0, Ndx
**************************** Undraw previous buffer and draw new one
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, 0, False
gBuildToggle = 3 - gBuildToggle
DrawArray FastWorkArraylXPg + 3 - gBuildToggle, -1, False

CA 02483943 2004-11-16
- 159 -
IIM SUB
SUB ShowObjPath (Array, Visibility)
IF Visibility = 0 TFOIN LeftColor = 0: RightColor = 0
IF Visibility = 1 THEN LeftColor = LCol: RightColor = RCol
FOR I = 1 TO NoOfFrames 'shows object path
EyeDisp = GetAReal!(Array + 2, I) / ZDivisor
CIRCLE (GetAReal!(Array, I) - EyeDisp,
GetAReal!(Array + 1, I)), 2, LeftColor
CIRCLE (GetAReal! (Array, I) + EyeDisp,
GetAReal!(Array + 1, I)), 2, RightColor
FOR J= 1 TO NoOfSortedSyncPts
IF SortedSyncPts (J) .Frame = I THEN
CIRCLE (GetAReal!(Array, I) - EyeDisp,
GetAReal!(Array + 1, I)), 8, LeftColor
CIRCLE (GetAReal!(Array, I) + EyeDisp,
GetAReal!(Array + 1, I)), 8, RightColor
E3J0 IF
NEX'T
NFsXT
END SUB
SUB ShowScaffold (WchPose)
FOR I = 1 TO NoOfScaffoldPts
SELECT CASE WchPose
CASE 1
x = AScaffoldCntr(1).x - ScaffoldDisp(I).x
y = AScaffoldCntr(1).y - ScaffoldDisp(I).y
Z = AScaffoldCntr(i).Z - ScaffoldDisp(I).Z
CASE 2
x = BScaffoldCntr(1).x - ScaffoldDisp(I).x
y = BScaffoldCntr(1).y - Scaffolc3Disp(I).y
Z = BScaffoldCntr(1).Z - ScaffoldDisp(I).Z
CASE 3
x = CScaffoldCntr(1).x - ScaffoldDisp(I).x
y = CScaffoldCntr(l).y - ScaffoldDisp(I).y
Z = CScaffoldCntr(1).Z - ScaffoldDisp(I).Z
CASE 4
x = DScaffoldCntr(1).x - ScaffoldDisp(I).x
y = DScaffoldCntr(1).y - ScaffoldDisp(I).y
Z = DScaffoldCntr(1).Z - ScaffoldDisp(I).Z
END SELECT
XYZ.x = x: XYZ.y = Y: XYZ.Z = Z
Mrk 2, 1
NFX'P
IIJD SUB
SUB ShowSpaceRefPts
FOR I = 1 TO SpaceRef(0).Visib
XYZ = SpaceRef(I).Locat
Mrk 2, 1
NF~P
II1D SUB
SUB ShowSyncPtLines (StartOfPresentSyncPts)
IF SyncPtIndex > 0 Tl3EN
FOR s = 1 TO StartOfPresentSyncPts + 1

CA 02483943 2004-11-16
- 160 -
XPos = 40 + interval! * (syncpts(s).Frame - 1)
LINE (XPos, 42)-(XPos, 349), 8
VerticalText syncpts(s).Label, 125, XPos
NEXP
FOR s StartOfPresentSyncPts + 1 TO SyncPtIndex
XPos = 40 + Interval! * (syncpts(s).Frame - 1)
LINE (XPos, 42)-(XPos, 349), 10
VerticalText syncpts(s).Label, 125, XPos
NEXT
LOCATE 23, 1: PRINI' "Vert Lines Show SyncPts Used Before
-Mark Again If Wanted Again For This Path"
IIQD IF
EDID SUB
SUB ShowWhllmage (WchPose, ShowColor) 'showin is only good before
justify
FOR I = 1 TO NoOfLines
ShowLn WchPose, I, ShowColor
I+EC'T
IIVD SUB
SUB Smooth (Arrayl, Array2, SmoothRange, EvenSpacing)
Dn4 Pt AS t3DPoint, Delta AS t3DPoint
IF EvenSpacing THEN
ArrayB = TempSmoothPtsXPg If spacing evenly, dest of part 1 is
tenp array
F3LSE
ArrayB = Array2 else dest of part 1 is output array
F.ND IF
PtLimit = GetA(Arrayl, 0)
IF PtLimit < SmoothRange + 1 THM
SmoothRange = PtLimit - 1
IF SmoothRange < 0 TSa1 SnoothRange = 0
F.I3DIF
SetA ArrayB, 0, GetA(Arrayl, 0)
TotalRange = 2 * SmoothRange + 1
************************************************ X Values
FOR I= 1 TO PtLimit
Sum! 0
FOR J = I SmoothRange TO I + SmoothRange
IF J < 1 TIiEN
K
ELSE
IF J > PtLimit THEN
K = PtLimit
ET GF.
K = J
END IF
E[JD IF
Sum! = Sum! +'GetAReal!(Arrayl, K)
NEXT J
SetArrayReal ArrayB, I, Sum! / TotalRange
NEXT I
. r**ir******,rw*************ve*****+r*,r~*****v w,twvt*** Y Values
FOR 1 = 1 TO PtLimit

CA 02483943 2004-11-16
- 161 -
Siua! = 0
FOR J= I - SmoothRange TO I + SmoothRange
IF J < 1 THEN
K = 1
ELSE
IF J > PtLimit THM
K = PtLimit
ELSE
K = J
EbID IF
EdJD IF
Sum! = Sum! + GetAReal!(Arrayl + 1, K)
NE}U J
SetArrayReal ArrayB + 1, I, Sum! / TotalRange
NMU I
**,**W****************************************** Z Values
FOR I= 1 TO PtLimit
Sum! = 0
FOR J I SmoothRange TO I+SnoothRange
IF J < 1 THM
K = 1
ELSE
IF J > PtLimit THM
K = PtLimit
ELSE
K = J
END IF
E,ND IF
sum! = Sum! + GetAReal!(Arrayl + 2, K)
hTMT J
SetArrayReal ArrayB + 2, I, Sum! / TotalRange
NE2?P I
*********************** Insert points for even segment lens
IF EvenSpacing THM
outIndex = 0
I ************* Find shortest line segment
MinDist! = 1E+09
FOR I = 1 TO PtLimit - 1
Dist! = DistToNextPoint(ArrayB, I)
IF Dist! < MinDist! THEN MinDist! = Dist!
NEXT
IF MinDist! < 1! THM MinDist! = 1!
************* Copy to new array, inserting new points where needed
FOR I= 1 TO PtLim.it - 1
Pt.x = GetAReal!(ArrayB + 0, I)
pt.y = GetAReal!(ArrayB + 1, I)
Pt.Z = GetAReal!(ArrayB + 2, I)
Outlndex = Outlndex + 1
SetArrayReal Array2 + 0, OutIndex, Pt.x
SetArrayReal Array2 + 1, Outlndex, Pt.y
SetArrayReal Array2 + 2, Outlndex, Pt.Z
Dist! = DistToNextPoint(ArrayB, I)
factor! = Dist! / MinDist!
IF factor! > 1.7 THEN
NumNewpoints = INT(factor! - .7)
Delta.x = (GetAReal!(ArrayB+O, I+1) - GetAReal!(ArrayB+O, I)) /
(NumNewPoints + 1)

CA 02483943 2004-11-16
- 162 -
De1ta.Y = (GetAReal!(ArrayB+1, I+1) - GetAReal!(ArrayB+l, I)) /.
(NumNewPoints + 1)
De1ta.Z = (GetARea1!(ArrayB+2, I+1) - GetAReal!(ArrayB+2, I)) /
(NuwnNewPoints + 1)
FOR J= 1 TO NumNewPoints
Outlndex = OutIndex + 1
SetArrayReal Array2 + 0, Outlndex, Pt.x + J* Delta.x
SetArrayReal Array2 + 1, Outlndex, Pt.y + J * Delta.y
SetArrayReal Array2 + 2, OutIndex, Pt.Z + J * De1ta.Z
NEXT
FM IF
NEXT
SetA Array2, 0, OutIndex
END IF
END SUB
SUB SmoothJoin (PtsToBeJoined, Range)
DIM SmthJnPts(65) AS t3DPoint
DIM SmthJnPtsAA(65) AS t3DPoint
NoOfPtsToBeJoined = GetA(PtsToBeJoined, 0)
J = 0
FOR I Range TO 1 STEP -1
J = J + 1
ScnthJnPts(J).x = GetAReal!(PtsToBeJoined, I)
SmthJnPts(J).y = GetAReal!(PtsToBeJoined + 1, I).:
SmthJnPts(J).Z = GetAReal!(PtsToBeJoined + 2, I)
NEXT
FOR I = NoOfPtsToBeJoined TO NoOfPtsToBeJoined - Range STEP -1
J = J + 1
SmthJnPts(J).x = GetAReal! (PtsToBeJoined, I)
SmthJnPts(J).Y = GetAReal!(PtsToBeJoined + 1, I)
SmthJnPts(J).Z = GetAReal!(PtsToBeJoined + 2, I),
NEXT
9mtlhJnPts(0).x = J
OldSnooth Santh7nPts ( ) , SmthJnPtsAA ( ) , 5
J = 0
FOR I = Range TO 1 STEP -1
J = J + 1
3etArrayReal PtsToBeJoined, I, SmthJnPtsAA.(J).x
SetArrayReal PtsToBeJoinetZ + 1, I, SnthJnPtsAA(J).y
SetArraYReal PtsToBeJoi.ned + 2, I, SYnthJnPtsAA(J).Z
NEXT
FOR I NoOfPtsToBeJoined TO NoOfPtsToBeJoined - Range STEP -1
J = J + 1
SetArrayReal PtsToBeJoined, I, SmthJnPtsAA(J).x
SetArrayReal PtsToBeJoined + 1, I, SmthJnPtsAA(J).y
SetArraYRea1 PtsToBeJoined + 2, I, SmthJnPtsAA(J).Z
NEXT
END SUB
SUB SortSyncPtsForApplic (Kind, WchNo) 'kind: 1=obj, 2=grp, 3=wxp
'this re-sorts sync pts for what obj or grp or wrp they are for,
every time
so index goes from one to noof syncpts for that obj or grp etc.
sortedSyncPts(1).Frame = 1 'this Mks first SortedSyncPts(syncpt)
start of path
SortedSyncPts(1).TeapPtsIndex = 1
SortedSyncPts(1).Label = "StartFrm"

CA 02483943 2004-11-16
- 163 -
SortedSyncPtslndex = 1
IF Kind = 1 TFM
SortedSyncPts(1).WchObj = WchNo
FOR G= 1 TO SyncPtIndex
IF syncpts(G).WchObj = WchNo THM
SortedSyncPtslndex = SortedSyncPtsIndex + 1
'first real SortedS)mcPts is index 2
SortedSyncPts(SortedSyncPtsIndex).WchObj = WchNo
SortedSyncPts(SortedSyncPtslndex).Frame = syncpts(G).Frame
SortedSyncPts(SortedSyncPtsIndex).Label = syncpts(G).Label
SortedSyncPts(SortedSyncPtsIndex).TempPtsIndex =
syncpts(G).TempPtslndex
END IF
NEXP
SortedSyncPts(SortedSyncPtsIndex + 1).WchObj = WchNo
END IF
IF Kind = 2 TFISBT
SortedSyncPts(1).WchGrp = WchNo
FOR G = 1 TO SyncPtlndex
IF syncpts (G) .WchGrp = WchNo THEN
SortedSyncPtsIndex = SortedSyncPtsIndex + 1
'first reai SortedSyncPts is index 2
SortedSyncPts(SortedSyncPtsIndex).WchGrp = WchNo
SortedSyncPts(SortedSyncPtsIndex).Frame = syncpts(G).Frame
SortedSyncPts(SortedSyncPtslndex).Label = syncpts(G).Label
SortedSyncPts(SortedSyncPtslndex).TenpPtsindex =
syncpts(G).TempPtsIndex
END IF
NEXT
SortedSyncPts(SortedSyncPtsIndex + 1).WchGrp = WchNo
EM IF
IF Kind = 3 TFM
SortedSyncPts(1).WchWrp = WchNo
FOR G= 1 TO SyncPtlndex
IF syrncpts(G).WchWrp = WchNo THEN
SortedSyncPtslndex = SortedSyncPtslndex + 1
'first real SortedSyncPts is index 2
SortedsyncPts(SortedSyncPtsindex).WchWrp = WchNo
SortedSyncPts(SortedSyncPtsindex).Frame =.syncpts(G).Frame
SortedSynaPts(SortedSyncPtslndex).Label = syncpts(G).Label
SortedSyncPts(SortedSyncPtslndex).TempPtslndex =
syncpts(G).TempPtsIndex
F.ND IF
NEXT
SortedSyncPts(SortedSyncPtslndex + 1).WchWrp = WchNo
END IF
SortedS}yncPts(SortedSyncPtslndex + 1)Frame = NoOfFrames
'this Mks last SortedSyncPts(syncpt) end of array
SortedSyncPts(SortedSyncPtsIndex + 1).TempPtslndex = GetA(TempPtsXPg, 0)
SortedSyncPts(SortedSyncPtslndex + 1).Label = "EndFrm"
NoOfSortedSyncPts = SortedSyncPtsIndex + 1
EM SUB
SUB Stretch (Small, Big, StartSmall, EndSmall, StartBig, EndBig)
NoOfSroall = EndSmall - StartSmall: NoOfBig = EndBig - StartBig

CA 02483943 2004-11-16
_ 164 -
IF NoOfSmall <> 0 AND NoOfBig <> 0 THEN
SetArrayReal Big, StartBig, GetAReal!(Small, StartSmall)
SetArrayReal Big + 1, StartBig, GetAReal!(Small + 1, StartSmall)
SetArrayReal Big + 2, StartBig, GetAReal!(Small + 2, StartSmall)
SetArrayReal Big, EndBig, GetAReal!(Small, EndSmall)
SetArrayReal Big + 1, EndBig, GetAReal!(Small + 1, EndSma.ll)
SetArrayReal Big + 2, E,hdBig, GetARea1!(Small + 2, EndSmall)
Ratio! = (NoOfBig / NoOfSmall)
END IF
LastBig = StartBig 'at the start only
FOR i= StartSmall - StartSmall + 1 TO EndSmall - StartSmall - 1
BigNdx = CINT(StartBig + (I * Ratio!))
SetArrayReal Big, BigNdx, GetAReal!(Small, StartSmall + I)
SetArrayReal Big + 1, BigNdx, GetAReal! (Small + 1, StartSmall + I)
SetArrayReal Big + 2, BigNdx, GetAReal!(Small + 2, StartSmall + I)
IF BigNdx > LastBig + 1 THEN Interpo Big, LastBig, BigNdx
LastBig = BigNdx
NEX'I'
IF EndBig > LastBig + 1 THEN Interpo Big, LastBig, EndBig
END SUB
SUB SwapLineDirection
wchPose = UserChoice("Swap Direction Of A Line In Which Pose?",
l. NN) _ .. . . .
. . . . -l~TN, ~BN, N/'~Nr ND-I
b.J.~1.7
LineNo = 0
DO
IF LineNo <> 0 THEN ShowFinalLn WchPose, LineNo, 0
LineNO = LineNo + 1
IF LineNo > NoOfLines THEN LineNo = 1
ShowFinalLn WchPose, LineNo, -1
LOOP WHILE NOT Confixrrn ("This Line? N)
Index = 0
J = 0
start = ALns(LineNo).FinalStart
Finish = ALns(LineNo).FinalEnd
FOR I Start TO Finish
J = J_+ 1
SetArrayReal TempPtsXPg, J, Get.AReal!(APtsXPg + 3 * (WchPose - 1), I)
SetArrayReal TempPtsYPg, J, GetAReal!(APtsYPg + 3 * (WchPose - 1), I)
SetArrayReal TettrpPtsZPg, J, Get.AReal!(APtsZPg + 3 * (WchPose - 1), I)
EndTempPts = J
NEXT
FOR I = Finish TO Start STEP -1
Index = index + 1
SetArrayReal APtsXPg + 3 * (WchPose- 1) , I, GetAReal!(TempPtsXPg, Index)
SetArrayReal APtsYPg + 3 * (WchPose- 1) , I, GetAReal! (TempPtsYPg, Index)
SetArrayReal APtsZPg + 3 * (WchPose-1) , I, GetAReal!(TenpPtsZPg, Index)
NEXT
I = LineNo
ALn.s(I).Beg = ALns(I).FinalStart
ALns(I).Fin = ALns(I).FinalEnd
BLns(I).Beg = ALns(I).FinalStart
BLns(I).Fin = ALns(I).FinalEnd
CLns(I).Beg = ALns(I).FinalStart
CLns(I).Fin = ALns(I).FinalEnd

CA 02483943 2004-11-16
- 165 -
DLns(I).Beg = ALns (I). FinalStart
DLns(I).Fin = ALns(I).FinalEnd
END SUB
SUB SwapSortedSyncPts
FOR I = 1 TO SortedSyncPtlndex - 1
FOR q = 1 TO SortedSyncPtIndex - I
IF SortedSyncPts(q).Frame > SortedSyncPts(q + 1).Frame TEiM
SWAP SortedSyncPts(q).Frame, SortedSyncPts(q + 1).Frame
SWAP SortedSyncPts(q).TempPtslndex,
SortedSyncPts(q + 1).TempPtsIndex.
SWAP SortedSyncPts(q).WchObj, SortedSyncPts(q + 1).WchObj
SWAP SortedSyncPts(q).WchGrp, SortedSynoPts(q + 1).WchGrp~
SWAP SortedSyncPts(q).WchWrp, SortedSyncPts(q + 1).WchWrp
'CAN'T SWAP STRINGS in a type, APPARENTLY, TMREFORE:
LabelA$ = SortedSyncPts(q).Label
LabelB$ = SortedSyncPts(q + 1).Label
SortedSyncPts(q).Label = LabelB$
SortedSyncPts(q + 1).Label = LabelA$
END IF
NEXT
NEXT
END SUB
SUB TransPtr (FrameNo, WchGrp, A11Prop AS TransType)
SELEC'T CASE WchGrp
CASE 1: AliProp = Trans1(FrameNo)
CABE 2: AliProp = Trans2(FrameNo)
CASE 3: AllProp = Trans3 (FrameNo)
CASE 4: AllProp = Trans4(FrameNo)
CASE 5: A11Prop = Trans5(FrameNo)
END SELECT
END SUB
SUB TrnsfrATo (Array, ImageLnsO AS LineType)
FOR I= 0 TO GetA(APtsXPg, 0)
SetArrayReal Array, I, GetAReal!(APtsXPg, I)
SetArrayReal Array + 1, I, GetAReal!(APtsXPg + 1, I)
SetArrayReal Array + 2, I, GetAlZeal!(APtsXPg + 2, I)
NEXP
FOR i= 0 TO NoOfLines
ImageLns(I).Beg = ALns(I).Beg
ImageLns(I).Fin = ALns(I).Fin
NEXT
SetA Array, 0, GetA(APtsXPg, 0)
END SUB
SUB TrnsfrPath (aSourceArray, PathNo)
TrnsfrWhlArray aSourceArray, PathlXPg + 3*(PathNo - 1)
END SUB
SUB TrnsfrPrevLineTo2ra (WchSource, DestinationPose, WchLine)
SELECT CASE WchSource
CASE 1
TrnsfrPrevLnToTenpPts APtsXPg, ALns(WchLine).Beg, ALns(WchLine).Fin,

CA 02483943 2004-11-16
- 166 -
WchSource, DestinationPose
cASE 2
TrnsfrPrevLnToTenpPts BPtsXPg, BLns(WchLine).Beg, BLns(WchLine).Fin,
WchSource, DestinationPose
CASE 3
TrnsfrPrevLnToTempPts CPtsXPg, CLns(WchLine).Beg, CLns(WchLine)..Fin,
WchSource, DestinationPose
ED7D SELECT
END SUB
SUB TrnsfrPrevLnToTempPts (Array, Start, Finish, WchSource,
DestinationPose)
DIM shift AS t3DPoint
shift.x = ImDrawingCentrDisp(DestinationPose).x -
ImDrawingCentrDisp(WchSource).x
shift.y = ImDrawingCentrDisp(DestinationPose).y -
ImDrawingCentrDisp(WchSource).y
shift.Z = ImDrawingCentrDisp(DestinationPose).Z -
ImDrawingCentrDisp(WchSource).Z
J = 0
FOR I= Start TO Finish
J = + 1
SetArrayReal TempPtsXPg, J, (GetAReal!(Array, I) + shift.x)
SetArrayReal TempPtsYPg, J, (GetAReal!(Array + 1, I) + shift.y)
SetArrayReal TempPtsZPg, J, (GetAReal!(Array + 2, I) + shift.Z)
NEXT
SetA TennpPtsRPg, 0, J
END SUB
SUB TrnsfrProp (Array() AS TransType, NoOfVals)
FOR I= 1 TO NoOfVals
Array(I).PropA = TransGrfVal(I).PropA
Array(I).PropB = TransGrfVal(I).PropB
Array(I).PropC = TransGrfVal(I).PropC
Array(I).PropD = TransGrfi7al(I).PropD
N.Ex'P
IIM SUB
SUB Trnsfr'tlnpToImPartA (WchPose)
IF WchPose = 1 TFM TrnsfrTmpToImPartB APtsXPg
IF WchPose = 2 THEN TrnsfrTmpTolmPartB BPtsXPg
IF WchPose = 3 THEtV TrnsfrTmgi'olmPartB CPtsXPg
IF WchPose = 4 TFO;N TrnsfrTmpTolmPartB DPtsXPg
LdLLrni,nArrays WchPose, Col
END SUB
SUB TrnsfzTaipToImPartB (PtArray)
FOR I= 1 TO GetA(TempPtsXPg, 0)i=1 to end of temppts
J= I + GetA(PtArray, 0) 'j=i+end of previous line in this Pose
SetArrayReal PtArray, J, GetAReal!(TempPtsXPg, I)
SetArrayReal PtArray + 1, J, GetAReal!(TempPtsXPg + 1, I)
SetArrayReal PtP,rray + 2, J, GetAReal!(TempPtsXPg + 2, I)
NEXT
SetA PtArray, 0, J'this sets end of Apts, BPts etc. to new end
END SUB
SUB TrnsfrWarp (Array() AS WarpProfileType, NoOfVals)
FpR I= 1 TO NoOfVals

CA 02483943 2004-11-16
- 167 -
Array(I).Proportion = GetAReal(RawPtsXPg, I)
NEXT
SetArrayReal RawPtsXPg, 0, NoOfVals
END SUB
SUB TrnsfrWave (WaveNo)
SELECT CASE WaveNo
CASE 1
TrnsfrWhlArray FastWorkArray2XPg, JAPtsXPg
CASE 2
TrnsfrWhlArray FastWorkArray2XPg, JBPtsXPg
CASE 3
TrnsfrWhlArray FastWorkArray2XPg, JCPtsXPg
CASE 4
TrnsfrWhlArray FastWorkArray2XPg, JDPtsXPg
END SELECT
END SUB
SUB TzasfrWhlArray (Arrayl, Array2)
Elements = GetA(Arrayl, 0)
Source = Arrayl
Dest = Array2
FOR I 1 TO Elements
SetArrayReal Dest, I, GetAReal!(Source, I)
NFsXT
SetA Dest, 0, Elements
Source = Arrayl + 1
Dest = Array2 + 1
FOR I= 1 TO Elements
SetArrayReal Dest, I, GetAReal!(Source, I)
NEXT
Source = Arrayl + 2
Dest = Array2 + 2
FOR I= 1 TO Elements
SetArrayReal Dest, I, GetAReal!(Source, I)
NEXT
EIJD SUB
FUNCTION UserChoice (Text$, A$, B$, C$, D$, E$)
ErsMnu
LOCATE 2, 1: PRINT Text$
IF A$ <> = THEN
LOCATE 1, 3
PRINT A$
LINE (M3XVals(1), 0)-(MBXVals(2), 13), 5, B
END IF
IF B$ <> "" THF1V
LOOATE 1, 19
PRINT B$
LI[+1E (MBX'Vals(3), 0) - (MBXVals (4), 13), 5, B
END IF
IF C$ <> = " TFEN .
IAC.ATE 1, 35
PRINT C$
LINE (MBXVals(5), 0)-(NIDXVals(6), 13), 5, B
END IF

CA 02483943 2004-11-16
- 168 -
IF D$ <> THEN
LOCATE 1, 51
PRINT D$
LINE (MBXVals(7), 0)-(148XVais(8), 13), 5, B
END IF
IF E$ <> "" THEN
LOCATE 1, 67
PRINT E$
LINE (14$XVals(9), 0)-(NBXVals(10), 13), 5, B
mTD IF
Done = False
WFiILE Done = False
WndIn
CalcFlatXY
CalcMrkrPts
ShowFlatCrsr
IF XYZ.y > 0 AND XYZ.y < 16 THEN
SELECT CASE XYZ.x
CASE M13XVals(1) TO bIDXVals(2): Done = True: UserChoice = 1
CASE NBXVals(3) TO XBXVals(4): Done = True: UserChoice = 2
CASE NBXVals ( 5) TO XIDXVals ( 6): Done = True : UserChoice = 3
CASE i4$XVals(7) TO MBXVals(8) : Done = True: UserChoice = 4
CASE M6XVals(9) TO HMais(10): Done = True: UserChoice = 5
END SELECT
END IF
WEND
MyDelay 1
ErsMnu
END FUNCTION
SUS Velcro
VelcroNo = 0
DO
VelcroNo = VelcroNo + 1
A$ = Group(1).Label: B$ = Group(2).Label
C$ = Group(3).Label: D$ = Group(4).Label: E$ = Group(5).Label
VelcroAGsp(VelcroNo).GrpWithHook =
UserChoice("Which Group is Master?",
Group(1).Label, Group(2).Label,
Group(3).Label, Group(4).Label, Group(5).Label)
CLS
ShowGrp 1, VelcroAGrp(VelcroNo).GrpWithHook, -1
RightGrp = False
DO
LOCATE 1, 1
Text$ ="Mrk Point On A Master Group Line To Which Handle
Of Slave Group Is To Stick"
FindMrkdPtInAPose ThisOne, Text$
WchSeg = FindWchFinlSg(FinlSgsO, ThisOne)
WchFoundGrp = FinlSgs(WchSeg).WchGrp
IF WchFoundGrp = VelcroAGrp(VelcroNo).GrpWithHook THEN
VelcroAGrp(VeicroNo).HookPtIndex = ThisOne
RightGrp = True
ELSE
Mrk 1, 1
END IF
LOOP UNTIL RightGrp = True
S1aveGrpOK = False
DO WHILE NOT SlaveGrpOK

CA 02483943 2004-11-16
- 169 -
VelcroAGrp(VelcroNo).S1aveGrp =
UserChoice("inkiich Group is Slave?",
Group(1).Label, Group(2).Label,
Group(3).Label, Group(4),Label, Group(5).Label)
IF Group(VelcroAGrp(VelcroNo).S1aveGrp).WchObj =
Group(VelcroAGrp(VelcroNo).GrpWithHook).WchObj THEN
SlaveGrpOK = True
II,SE
LOCATE 3, 1: PRINT "Doesn't Belong To Same Object. ReDo"
SLEEP 1
LOCATE 3, 1: PRINT SPACE$(60)
EM IF
LOOP
LOOP WHILE Confirm("Velcro More Groups?")
NoOfVelcros = VelcroNo
END SUB
SUB VerticalText (Text$, y, x)
VertTextLocat = CINT(y / 14)
HorTextLocat = INT(x / 8)
FOR I = 1 TO LEN (Text$)
Letter$ = NICD$(Text$, I, 1)
IF VertTextLocat > 0 AND VertTextLocat < 23 AND
HorTextLocat > 0 AND HorTextLocat < 81 THEN
LOCATE VertTextLocat + 1, HorTextLocat + 1
PRINT Letter$
END IF
VertTextLocat = VertTextLocat + 1
NEXT
E!M SUB
SUB VisInvisObj
'ChooseObj RefObject, "Which Object?"
INPUT "Object Appears At Frame"; Object(RefObject).StartVis
INPUT "Object Disappears At Frame"; Object(RefObject)..EndVis
EM SUB
SUB WaitForClick
WHILE INP(889) >= 128: WEND
WHIL,E IrtP(889) < i28: WEND
END SUB
SUB WarpSegPathArrayPositPtr (FrameNo, WchPath,
WarpSegPathPtPosit AS t3DPoint)
warpSegPathPtPosit.x = GetAReal!(PathlXPg + 3*(WchPath-1), FrameNo)
warpSegPathPtPosit.y = GetAReal! (PathlYPg + 3* (WchPath-1), FrameNo)
WarpSegPathPtPosit.Z = GetAReal! (PathlZPg + 3* (WchPath-1) , FrameNo)
END SUB
FUNCTION trOarpSegProfPtr! (WchProf, WhereInProf)
SEIECP CASE WchProf
CASE 1: WarpSegProfPtr! = Profilel(WherelnProf).Proportion
CASE 2: WarpSegProfPtr! = Profile2(WhereInProf).Proportion
CASE 3: WarpSegProfPtr! = Profile3(WhereInProf).Proportion
CASE 4: WarpSegProfPtr! = Profile4(WhereInProf).Proportion
CASE 5: WarpSegProfPtr! = Profile5(WhereInProf).Proportion
CASE 6: WarpSegProfPtr! = Profile6(WhereInProf).Proportion
CASE 7: WarpSegProfPtr! = Profile7(WhereInProf).Proportion
CASE 8: WarpSegProfPtr! = Profile8(WhereInProf).Proportion

CA 02483943 2004-11-16
- 170 -
CASE 9: WarpSegProfPtr! = Profile9(WhereInProf).Proportion
END SFLEEG"!'
END FUNCTION
SUB WarpSegWaveShapePtr (PositionNo, WchWave,
WarpSegWaveDisp AS t3DPoint)
SELECT CASE WchWave
CASE 1
WarpSegWaveDisp.x = GetAReal!(JAPtsXPg, PositionNo)
WarpSegWaveDisp.y = GetAReal!(JAPtsYPg, PositionNo)
WarpSegWaveDisp.Z = GetAReal!(JAPtsZPg, PositionNo)
CASE 2
WarpSegWaveDisp.x = GetAReal!(JBPtsXPg, PositionNo)
WarpSegWaveDisp.y = GetAReal!(JBPtsYPg, PositionNo)
WarpSegWaveDisp.Z = GetAReal!(JBPtsZPg, PositionNo)
CASE 3
WarpSegWaveDisp.x = GetAReal!(JCPtsXPg, PositionNo)
WarpSegWaveDisp.y = GetAReal!(JCPtsYPg, PositionNo)
WarpSegWaveDisp.Z = GetAReal!(JCPtsZPg, PositionNo)
CASE 4
WarpSegWaveDisp.x = GetAReal!(JDPtsXPg, PositionNo)
WarpSegWaveDisp.y = GetAReal!(JDPtsYPg, PositionNo)
WarpSegWaveDisp.Z = GetAReal!(JDPtsZPg, PositionNo)
END SELECT
IIJD SUB
SUB WndChs (Text$, A$, B$, C$, D$, E$, Ans$, When)
ErsMnu
WndMnu Text$, A$, B$, C$, D$, E$
IF When = 0 THm WndSlct Ans$, 1
EDID SUB
SUB Wndin
'minus moves cursor away from viewer
DIM Location AS WandReportType
Readwand Location 'XYZ switches are becuz of wand
transmitter mounting only
XYZ.x = 320! + (-Location.y / XLeverage) + XAdjust - 50
xyz.y = 320! - (ABS(Location.Z) / YLeverage) + YAdjust - 50
XYZ.Z = -Location.x / ZLeverage + ZAdjust + Zoom!
IF ZFixed = True TFEN XYZ.Z = 0
EBTD SUB
SUB WndMnu (Text$, A$, B$, C$, D$, E$)
LOCATE 2, 1: PRINT Text$
IF A$ <> "x" TfM
LOCATE 1, 3
PRINT A$
LINE (Pffi7cVa1s.(1), 0) - (14BXVals (2) , 13), 5, B
END IF
IF B$ <> "x" TFO;N
LOCATE 1, 19
PRINT B$
LINE (I4B%Vals(3); 0)-(bBXVa1s(4), 13), 5, B
F1QD IF
IF C$ <> "x" TFM
LOCATE 1, 35
PRINi' C$
LINE (NBXVals(5), 0)-(NBXVals(6), 13), 5, B

CA 02483943 2004-11-16
- 171 -
END IF
IF D$ <> "x" TfM
LOCATE 1, 51
PRINT D$
LINE (NBXVals(7), 0)-(NBXVals(8), 13), 5, B
END IF
IF E$ <> "x" TEM
LOCATE 1, 67
PRINT E$
LINE (XBXV'als(9), 0)-(MBXVals(10), 13), 5, B
EIm IF
IIVD SUB
SUB WndptScan (Object, Object2, Group, Group2, Array, Limit,
MrarkType, ScanForT/W11at)
NoMarker = False: Frmsnd = False
LOCATE 23, 28: PR2NT "BACK"
LOCATE 23, 38: PRINT "STATIC"
LOCATE 23, 49: PRINT "FORWARD"
LINE (0, 340)-(639, 340), 8
LINE (0, 349)-(639, 349), 8
LINE (300, 340)-(300, 349), 8
LINE (346, 340)-(346, 349), 8
LOCATE 1, 1
SELECT CASE ScanForWhat
CASE eScanTransOnTempGraph
speed = 0
PRIlVT "Scan ACTION Created By Action Control Graph (click to exit)"
LOCATE 22, 38: PRINT "TempPt": LOCATE 22, 60
PRINT "TotalPts"; Limit
CASE eObjPathOnTempPts
speed = 0
PRINT "Scan Object's MOVEMENT OVER.PATH IN SPACE (click to exit)"
NoMarker = True
IACATE 22, 38
PRINT "TenlpPt"
LOc'ATE 22, 60
PRINT "TotalPts"; Limit
CASE eObjPathByFrms
speed = 0
F'rmsnd = True
PRINT "Scan Object's MOVEI4ENr OVER PATH IN SPACE BY FRAMES
(click to exit)"
NoMarker = True
LOC,ATE 22, 38
PRINT "FRAME"
LOCATE 22, 60
PRINT "TotalFrms"; Limit
CASE eScanForWarpByFrms
speed = 0
PR]NT "Scan Warp BY FRAMES (click to exit)"
LOCATE 22, 38
PRINT "FRAME"
CASE eBcanTransByFrms
speed = 0
bYmsnd = True
PBINT "Scan ACTION ONLY By FRAMES (click to exit)"
LOCATE 22, 38
ritii ~r~T.}It "~+p~~+~
LOCATE 2i24,YJ6G0

CA 02483943 2004-11-16
- 172 -
PRIN'I' "TotalFrms"; Limit
CASE eScanGrpTransPlusPath
speed = 0
Frrmsnd = True
PRINT "Scan ACTION PLUS MOVFMENT OVER PATH IN SPACE BY FRAMES
(click to exit)"
NoMarker = True
LOCATE 22, 38
PRINT "FRAME"
LOCATE 22, 60
PRINT "TotalFrms"; Limit
CASE eScanForObjPathSyncPt
speed = 500
PRa7T "Define Object Path SYNC PT -Click To Mark"
LOCATE 22, 38
PRINT "TempPt"
LOC,ATE 22, 60
PRINT "TotalPts"; Limit
CASE eScanForTransSyncPt
speed = 500
PRINT "Define Action Control Graph SYNC PT -Click To Mark"
LOCATE 22, 38
PRINT "TeopPt"
LOCATE 22. 60
PRINT "TotalPts"; Limit
CASE eScanForWarpSyncPt
speed = 500
PRINT "Define Warp SYNC PT -Click To Mark"
LOCATE 22, 38
PRINT "TenipPt"
LOCATE 22, 60
PRINT "TotalPts"; Limit
CASE eScanForReferenceObject
speed = 200
PRINT "Scan Over Frames To Locate Reference Object\Group
-Click To Select Frame"
LOCATE 22, 38
P~ "FRAMB"
LOCATE 22, 60
PRINP "TotalFrms"; Limit
CASE eScanForAnchorPts
speed = 1000
PRINP "Define ANCHOR PT (Click To Mark)"
IqCATE 22, 38
PRINT "FRAME"
LOCATE 22, 60
PRINT "TotalFrms"; Limit
END SELECT
LastDelayedScanIndex = 1
STATIC Scanindex
'LOC'.ATE 2, 1: PRINT "Click To Mark Or Exit"
m
Wndln
XYZ.y = 342: XYZ.Z = 0
ShowFlatCrsr
Change = I1V'I'(XYZ.x / 50) - 6
Scanlndex = Scanlndex + Change
IF ScanIndex < 1 TFOrN Scanlndex = Limit
IF Scanlndex > Limit TFOrN Scanlndex = 1
LOCATE 22, 44: PRINT Scanindex;

CA 02483943 2004-11-16
- 173 -
XYZ.x = GetAReal!(Array, Scanlndex)
xyy,y = GetAReal! (Array + 1, Scanlndex)
xYZ.Z = GetAReal! (Array + 2, Scanlndex)
IF NoMarker = False THEN Mrk MarkType, 1
SELECT CASE ScanForWhat
Cp,SE eObjPathOnTPanpPts
ShowObjOnPath Object, Obj2, XYZ
CASE eObjPathByFrms
ShowObjOnPath Object, Obj2, XYZ
CASE eScanForWarpByFrms
LOCATE 4, 1
PRINT "Visual not implemented"
CASE eScanTransOnTempGraph
ShowGroupTScript Group, Group2, Scanlndex, "Temp"
CASE eScanTransByFrms
ShowGroupTScript Group, Group2, Scanlndex, "Frames"
CASE eScanForObjPathSyncPt
ShowObjOnPath Object, Obj2, XYZ
CASE eScanForTransSyncPt
showGroupTScript Group, Group2, ScanIndex, "Temp"
CASE eScanForWarpSyncPt
LOCATE 4, 1
PRINT "not implemented"
CASE eScanGrpTransPlusPath
ShowGrpTransInPathPosit Object, Group, Group2,, ScanIndex
CASE eScanForReferernceObject
ShowGrpTransInPathPosit Object, Group, Group2, Scanlndex
CASE eScanForAnchorPts
ShowGrpTransInPathPosit Object, Group, Group2, Scanlndex
END SELEC'P
counter = 0
DO WHILE counter < speed
counter = counter + 1
FORI=1Ta,500:NEXP
LOOP
IF NoMarker = False TFEN Mrk MarkType, 1
IF INP(889) < 128 TFM
IF ScanForWhat = eScanForAnchorPts TtM BEEP
FoundIt = True
ThisOne = ScanIndex
ReferenceFrame = Scanlndex
Mrk 3, 1
EXIT DO
END IF
LOOP
END SUB
SUB WndSlct (Ans$, Delay)
Ans$ = "zilch"
m
Wrndln
Ca1cFlatXY
CalcMrkrPts
ShowFlatCrsr
DO UNTIL INP(889) >= 128
LOOP
SSLECT CASE XYZ.y
CASE 1 TO 15
SELECT CASE XYZ.x

CA 02483943 2004-11-16
- 174 -
CASE MBXVals(1) TO MBXVa1s(2): Ans$ = A$: EXIT DO
CASE NIDXVals(3) TO NIDXVals(4): Ans$ = B$: EXIT DO
CASE NiMa1s(5) TO NBXVals(6): Ans$ = C$: EXIT DO
CASE NIDXVals(7) TO NBXVals(8): Ans$ = D$:.EXIT DO
CASE NIDXVals(9) TO MBXVa1s(10): Ans$ = E$: EXIT DO
CASE ELSE: EXIT DO
END SELfiCT
END SELECT
LOOP
IF Delay = 1 TFEN MyDelay 1
END SUB
3UB WriteXFerInfo (C, P, x!, y!, Z!)
TransferInfo.Cmd = C
TransferInfo.Param = P
Transferlnfo.x = x!
TransferInfo.y = y!
TransferInfo.Z = Z!
PUT #2, , Transferinfo
END SUB
FUNCTION XYZDiff
STATIC LastXYZ AS t3DPoint
XYZDiff = (XYZ.x <> LastXYZ.x) OR
(XYZ.y <> LastXYZ.y) OR
(XYZ.Z <> LastXYZ.Z)
LastXYZ = XYZ
END FUNCTION

Representative Drawing
A single figure which represents the drawing illustrating the invention.
Administrative Status

2024-08-01:As part of the Next Generation Patents (NGP) transition, the Canadian Patents Database (CPD) now contains a more detailed Event History, which replicates the Event Log of our new back-office solution.

Please note that "Inactive:" events refers to events no longer in use in our new back-office solution.

For a clearer understanding of the status of the application/patent presented on this page, the site Disclaimer , as well as the definitions for Patent , Event History , Maintenance Fee  and Payment History  should be consulted.

Event History

Description Date
Inactive: First IPC assigned 2015-05-15
Inactive: IPC assigned 2015-05-15
Time Limit for Reversal Expired 2014-12-24
Letter Sent 2013-12-24
Inactive: IPC expired 2011-01-01
Inactive: IPC expired 2011-01-01
Inactive: IPC removed 2010-12-31
Inactive: IPC removed 2010-12-31
Amendment Received - Voluntary Amendment 2008-12-16
Grant by Issuance 2008-02-19
Inactive: Cover page published 2008-02-18
Inactive: Payment - Insufficient fee 2007-11-07
Inactive: Final fee received 2007-10-23
Pre-grant 2007-10-23
Inactive: Final fee received 2007-10-02
Notice of Allowance is Issued 2007-06-06
Notice of Allowance is Issued 2007-06-06
Letter Sent 2007-06-06
Inactive: Approved for allowance (AFA) 2007-05-17
Amendment Received - Voluntary Amendment 2007-04-10
Inactive: S.30(2) Rules - Examiner requisition 2006-10-11
Amendment Received - Voluntary Amendment 2005-04-20
Inactive: Office letter 2005-01-14
Inactive: Cover page published 2005-01-05
Inactive: First IPC assigned 2004-12-20
Inactive: IPC assigned 2004-12-20
Letter sent 2004-12-07
Correct Inventor Requirements Determined Compliant 2004-12-01
Letter Sent 2004-12-01
Divisional Requirements Determined Compliant 2004-12-01
Application Received - Regular National 2004-12-01
All Requirements for Examination Determined Compliant 2004-11-16
Application Received - Divisional 2004-11-16
Request for Examination Requirements Determined Compliant 2004-11-16
Application Published (Open to Public Inspection) 1997-07-10

Abandonment History

There is no abandonment history.

Maintenance Fee

The last payment was received on 2007-12-04

Note : If the full payment has not been received on or before the date indicated, a further fee may be required which may be one of the following

  • the reinstatement fee;
  • the late payment fee; or
  • additional fee to reverse deemed expiry.

Please refer to the CIPO Patent Fees web page to see all current fee amounts.

Owners on Record

Note: Records showing the ownership history in alphabetical order.

Current Owners on Record
IMAX CORPORATION
Past Owners on Record
ROMAN B. KROITOR
Past Owners that do not appear in the "Owners on Record" listing will appear in other documentation within the application.
Documents

To view selected files, please enter reCAPTCHA code :



To view images, click a link in the Document Description column. To download the documents, select one or more checkboxes in the first column and then click the "Download Selected in PDF format (Zip Archive)" or the "Download Selected as Single PDF" button.

List of published and non-published patent-specific documents on the CPD .

If you have any difficulty accessing content, you can call the Client Service Centre at 1-866-997-1936 or send them an e-mail at CIPO Client Service Centre.


Document
Description 
Date
(yyyy-mm-dd) 
Number of pages   Size of Image (KB) 
Description 2004-11-16 175 7,933
Abstract 2004-11-16 1 36
Claims 2004-11-16 3 139
Drawings 2004-11-16 21 304
Description 2004-11-16 175 8,144
Abstract 2004-11-16 1 37
Drawings 2004-11-16 21 331
Claims 2004-11-16 3 138
Representative drawing 2004-12-30 1 8
Cover Page 2005-01-05 1 45
Claims 2007-04-10 3 108
Representative drawing 2007-05-31 1 6
Cover Page 2008-02-01 1 44
Acknowledgement of Request for Examination 2004-12-01 1 177
Commissioner's Notice - Application Found Allowable 2007-06-06 1 165
Maintenance Fee Notice 2014-02-04 1 171
Maintenance Fee Notice 2014-02-04 1 171
Correspondence 2004-12-01 1 38
Correspondence 2005-01-14 1 15
Fees 2005-12-08 1 29
Correspondence 2007-10-02 1 29
Correspondence 2007-10-16 1 19
Correspondence 2007-10-23 1 28