CA2483943C - Computer-assisted animation construction system and method and user interface - Google Patents

Computer-assisted animation construction system and method and user interface Download PDF

Info

Publication number
CA2483943C
CA2483943C CA002483943A CA2483943A CA2483943C CA 2483943 C CA2483943 C CA 2483943C CA 002483943 A CA002483943 A CA 002483943A CA 2483943 A CA2483943 A CA 2483943A CA 2483943 C CA2483943 C CA 2483943C
Authority
CA
Canada
Prior art keywords
getareal
sub
false
animation
true
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
CA002483943A
Other languages
French (fr)
Other versions
CA2483943A1 (en
Inventor
Roman B. Kroitor
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Imax Corp
Original Assignee
Imax Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US08/578,293 external-priority patent/US5854634A/en
Application filed by Imax Corp filed Critical Imax Corp
Priority claimed from CA002241854A external-priority patent/CA2241854C/en
Publication of CA2483943A1 publication Critical patent/CA2483943A1/en
Application granted granted Critical
Publication of CA2483943C publication Critical patent/CA2483943C/en
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Landscapes

  • Processing Or Creating Images (AREA)

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.

Description

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
-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
-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:

-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.
-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
-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
-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
-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
-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
-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
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
-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
-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
-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.
-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
-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
-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
-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
-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 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 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 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} { ~

-,~-{ 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;

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}

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 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 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

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 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 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 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 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 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 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, 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.

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), 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 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.

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 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.

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

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

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 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 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 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 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 ( ) 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) 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

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!) = ************************************ 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) 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 NoOfColors = 1 CONST LCol = 4: CONST RCol = 9:
CONST ZDivisor = 18 SCRF.E6i 9 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

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 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 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"-, "") ZFixed = False 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

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"

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", "", "") RunName$ = "Exprimnt"

WHILE NOT NameOK
INPUT "Name For This Run (8 characters including link 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

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"

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 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 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 -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 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

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 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 PRINT "Saving Source Poses Of "; PoseSave$
OPEN "k:\Projects\Imax\TWeeny\Paul\" + PoseSave$ + ",POS" FOR

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 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 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

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 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

Operation = 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

TETRAiIEDRON!"

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!"

ZFixedTempOff = False ZFixed = True END IF
CLS

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

Operation = 13 EUID IF

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

- 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?", 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 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, 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 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, 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!"

ZFixedTempOff = True ZFixed = False END IF

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 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

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!"

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 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

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 _ 73 _ IF Cornf irm ("Any Lines or Objects Intermittent? ") THEN
SELECT CASE UserChoice("Which", "", "Line", "Object", "", "") SELECT CASE UserChoice("Method To Determine When Visible", "" , "TScript", "Frai{lG1Yo", "" "" ) , . . 'CASE 2: MrklntermtLine 'CASE 3:. ErsMnu: MrkVisInvisLine END SELECT
MrkVisinvisLine VisInvisObj END SELECT
ENn IF
operation = 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 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 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

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

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 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 _ 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") ConstructOK = False Operation = 21 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:

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

_ 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 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!

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

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) GetStartFinish BLnsO, WchLine, Start, Finish GetStartFinish CLn.s(, WchLine, Start, Finish 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 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"

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 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)) 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)) 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 AdjObjPathStartEnd PathlXPg, GetA(PathlXPg, 0) ShoyoObjPath PathlXPg, 1 AdjObjPathStartEnd Path2XPg, GetA(Path2XPg, 0) ShowObjPath Path2XPg, 1 AdjObjPathStartEnd Path3XPg, GetA(Path3XPg, 0) ShowObjPath Path3XPg, 1 END SELECT

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 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

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 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 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

_ 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:

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 Record$ = "No"
IF Confirm("You Will Not Be Able To Play Back This Run On Sandde4. Is That OK?") THEAT
RecordDecisionOK = True END SELECI' WEND

CLS
SELECT CASE Record$
CASE "RecordS4"
SnapName$ = LEFT$(RunName$, 2) PRINT "SnapName$:"; SnapName$: SLEEP 1 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 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:

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

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 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

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 RevisedPropA! =
(A11Prop.PropA -ALns(LineNo).Threshold)*Conversion!
RevisedPropB! =
A11Prop.PropB * Conversion!
RevisedPropC!
AllProp.PropC * Conversion!
RevisedPropD! _ AllProp.PropD * Conversion!

RevisedPropB! =
(AllProp.PropB -ALns(LineNo).Threshold)*Conversion!

RevisedPropA! _ AllProp.PropA * Conversion!
RevisedPropC! _ AllProp.PropC * Conversion!
RevisedPropD! =
AllProp.PropD * Conversion!

RevisedPropC! =
-(AllProp.PropC
ALns(LineNo).Threshold)*Conversion!
RevisedPropB! _ AllProp.PropB * Conversion!
RevisedPropA! =
AllProp.PropA * Conversion!
RevisedPropD! _ AllProp.PropD * Conversion!

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 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! *

(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 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 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 END IF 'if visible NEXT 'object IF OneFrameOnly = True THM GOTO Skip2:
IF Record$ = "No" THM

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

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 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 IF OneFrameOnly = True THEA7 GOTO OneFrameOnlySkip SCRESTT 9, , 0, 0 LOCATE 10, 1: PRINT RunName$; RecordFrameNo IF Record$ _"No" TMN LOCATE 11, 1: PRINT "NOT RECORDED!
SCREEN 9, . 1, 1 LOCATB 10, 1: PRINT RunName$; RecordFrameNo IF Record$ = "No" TFM LOCATE 11, 1: PRINT "NOT RECORDED!

IF Record$ = "Records6" THM
CLOSE #2 PRINT "closed S6"
END IF

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:

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) IF RequiredLengthOftnTave <= GetA(TempPtsXPg, 0) THEN
WaveRefOK = True ELSE
LOCATE 2, 30: PRINT "Wave Too Short, ReDo ": SLEEP 2 CLS

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

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

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 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

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 . . .

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 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"

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 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

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:

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 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) '******* 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 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 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.

SUB DelLast (WchPose) IF wchPose = 1 Z'FM DelLastLnPart2 AL,ns(), APtsXPg, WchPose 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) 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

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 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", "=) 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

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

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"

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"

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"

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"

LOCATE 2, 28: PRINT SPACE$(65) END IF

NNm IF

---------------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?"

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

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 WndChs Text$, A$, B$, "x", "x", "x", Ans$, 0 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 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"

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 TrnsfrATo BPtsXPg, BLns() DrawBPoseOK = True TrnsfrATo CPtsXPg, CLns ( ) DrawCPoseOK = True TrnsfrATo DPtsXPg, DLns() DrawDPoseOK = True AllPosesSameAsA = True TrnsfrATo CPtsXPg, CLnsO
DrawCPoseOK = True TrnsfrATo DPtsXPg, DLnsO
DrawDPoseOK = True 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

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) 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 GetStartFinish ALnsO, WchLine, Start, Finish FindInRng APtsXPg, Start, Finish, Range GetStartFinish BLns(}, WchLine, Start, Finish FindlnRng BPtsXPg, Start, Finish, Range GetStartFinish CLns(), WchLine, Start, Finish FindinRng CPtsXPg, Start, Finish, Range GetStartFinish DLns(), WchLine, Start, Finish FindInRng DPtsXPg, Start, Finish, Range END SELECT

LOOP UNTIL FoundIt OR (Range > 10) 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"

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) 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

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

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 LenOfWave = GetA(JAPtsXPg, 0) LenOfWave = GetA(JBPtsXPg, 0) LenOfWave = GetA(JCPtsXPg, 0) 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 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 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 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 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 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 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 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; ")"

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", "") GroupsDefnd = True 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", "", "") IF WchObj > LastObj + 1 TfM
BEEP: LOCATE 3, 1 PRINT "Can't Skip A Number; Assign Object Again (Last Assignment Was To Object"; LastObj; ")"

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", "") ObjectsDefnd = True 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

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) 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) K = (J - (SegStart - TenpSegs(I).CStartPt)) SetArrayReal JCPtsXPg, J, GetAReal!(CPtsXPg, K) SetArrayReal JCPtsYPg, J, GetAReal!(CPtsYPg, K) SetArrayReal JCPtsZPg, J, GetAReal!(CPtsZPg, K) 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 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 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 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 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

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 Text$ = "Object = + Object(WchOne).Label colorCode = 2 Text$ = "Group " + Group(WchOne).Label ColorCode = 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 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 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 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

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

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

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

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 DO WHILE Finished = False SE.IõECT CASE UserChoice('", "ChooseLine", "Finished", 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) 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 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", FindMrkdPtInAPose ThisOne, "Mark The Line"
WchLine = FindAlnForlntermit(ThisOne) INPUT "Appears At Frame"; ALns(WchLine).StartVis INPUT "Disappears At Frame"; ALns(WchLine).EndVis 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!"

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)) 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

IF OneSetChosen THM
IF 50 - MtchPtNdx < 2 TFM
BEEP: BEEP: BEEP
PRINT "Last Avl Match Pt!
END IF

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 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"

LOCATE 6, 1: PRINT SPACE$(65) LOCATE 7, 1: PRINT SPACE$(65) Foundlt = False 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 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 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"

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 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) 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) 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"

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 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") EXIT DO

WndPtScan WchObj, Obj2, WchGrp, Grp2, TempPtsXPg, 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 A$ = "Name Line"
IF FrstLn = True THEN C$ = "Finished A" ELSE C$
WrndChs Text$, A$, B$, C$, D$, E$, Ans$, 1 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 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 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

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

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 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;

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 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"

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 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 END SUB

SLTB ShowAllFnlSegs (WchPose) FOR I= 1 TO NoOfLines SELECT CASE WchPose ShowFnlSegs APtsXPg, I, -1 ShowFnlSegs BPtsXPg, I, -1 ShowFnlSegs CPtsXPg, I, -1 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

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) +

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 - 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)) 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 GetStartFinish ALns(, LnNo, Start, Finish DrawPartialArray APtsXPg, Start, Finish, ShowColor, True GetStartFinish BLnsO, LnNo, Start, Finish DrawPartialArray BPtsXPg, Start, Finish, ShowColor, True GetStartFinish CLns(), LnNo, Start, Finish DrawPartialArray CPtsXPg, Start, Finish, ShowColor, True 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 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 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 NEX'T
NFsXT
END SUB

SUB ShowScaffold (WchPose) FOR I = 1 TO NoOfScaffoldPts SELECT CASE WchPose x = AScaffoldCntr(1).x - ScaffoldDisp(I).x y = AScaffoldCntr(1).y - ScaffoldDisp(I).y Z = AScaffoldCntr(i).Z - ScaffoldDisp(I).Z

x = BScaffoldCntr(1).x - ScaffoldDisp(I).x y = BScaffoldCntr(1).y - Scaffolc3Disp(I).y Z = BScaffoldCntr(1).Z - ScaffoldDisp(I).Z

x = CScaffoldCntr(1).x - ScaffoldDisp(I).x y = CScaffoldCntr(l).y - ScaffoldDisp(I).y Z = CScaffoldCntr(1).Z - ScaffoldDisp(I).Z

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

SUB ShowSyncPtLines (StartOfPresentSyncPts) IF SyncPtIndex > 0 Tl3EN
FOR s = 1 TO StartOfPresentSyncPts + 1 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 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 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) 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"

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 _ 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 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 TrnsfrPrevLnToTenpPts APtsXPg, ALns(WchLine).Beg, ALns(WchLine).Fin, WchSource, DestinationPose cASE 2 TrnsfrPrevLnToTenpPts BPtsXPg, BLns(WchLine).Beg, BLns(WchLine).Fin, WchSource, DestinationPose TrnsfrPrevLnToTempPts CPtsXPg, CLns(WchLine).Beg, CLns(WchLine)..Fin, WchSource, DestinationPose 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 Array(I).Proportion = GetAReal(RawPtsXPg, I) NEXT
SetArrayReal RawPtsXPg, 0, NoOfVals END SUB

SUB TrnsfrWave (WaveNo) SELECT CASE WaveNo TrnsfrWhlArray FastWorkArray2XPg, JAPtsXPg TrnsfrWhlArray FastWorkArray2XPg, JBPtsXPg TrnsfrWhlArray FastWorkArray2XPg, JCPtsXPg 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

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

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"

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 CASE 9: WarpSegProfPtr! = Profile9(WhereInProf).Proportion END SFLEEG"!' END FUNCTION

SUB WarpSegWaveShapePtr (PositionNo, WchWave, WarpSegWaveDisp AS t3DPoint) SELECT CASE WchWave WarpSegWaveDisp.x = GetAReal!(JAPtsXPg, PositionNo) WarpSegWaveDisp.y = GetAReal!(JAPtsYPg, PositionNo) WarpSegWaveDisp.Z = GetAReal!(JAPtsZPg, PositionNo) WarpSegWaveDisp.x = GetAReal!(JBPtsXPg, PositionNo) WarpSegWaveDisp.y = GetAReal!(JBPtsYPg, PositionNo) WarpSegWaveDisp.Z = GetAReal!(JBPtsZPg, PositionNo) WarpSegWaveDisp.x = GetAReal!(JCPtsXPg, PositionNo) WarpSegWaveDisp.y = GetAReal!(JCPtsYPg, PositionNo) WarpSegWaveDisp.Z = GetAReal!(JCPtsZPg, PositionNo) 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

IF C$ <> "x" TFM
LOCATE 1, 35 PRINi' C$
LINE (NBXVals(5), 0)-(NBXVals(6), 13), 5, B

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 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;

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 SELECT CASE XYZ.x 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

Claims (8)

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.
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, 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.
CA002483943A 1995-12-26 1996-12-24 Computer-assisted animation construction system and method and user interface Expired - Fee Related CA2483943C (en)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US08/578,293 US5854634A (en) 1995-12-26 1995-12-26 Computer-assisted animation construction system using source poses within a pose transformation space
US08/578,293 1995-12-26
CA002241854A CA2241854C (en) 1995-12-26 1996-12-24 Computer-assisted animation construction system and method and user interface

Related Parent Applications (1)

Application Number Title Priority Date Filing Date
CA002241854A Division CA2241854C (en) 1995-12-26 1996-12-24 Computer-assisted animation construction system and method and user interface

Publications (2)

Publication Number Publication Date
CA2483943A1 CA2483943A1 (en) 1997-07-10
CA2483943C true CA2483943C (en) 2008-02-19

Family

ID=33565671

Family Applications (1)

Application Number Title Priority Date Filing Date
CA002483943A Expired - Fee Related CA2483943C (en) 1995-12-26 1996-12-24 Computer-assisted animation construction system and method and user interface

Country Status (1)

Country Link
CA (1) CA2483943C (en)

Families Citing this family (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN109035357B (en) * 2018-07-10 2023-01-03 深圳市前海手绘科技文化有限公司 Artificial intelligence automatic drawing method
CN109920029A (en) * 2019-03-18 2019-06-21 河北华发教育科技股份有限公司 A method of drawing erasable figure

Also Published As

Publication number Publication date
CA2483943A1 (en) 1997-07-10

Similar Documents

Publication Publication Date Title
US5854634A (en) Computer-assisted animation construction system using source poses within a pose transformation space
Parke Computer generated animation of faces
Agrawala et al. Artistic multiprojection rendering
Wolberg Recent advances in image morphing
Beymer et al. Example based image analysis and synthesis
EP1141893B1 (en) System and method for creating 3d models from 2d sequential image data
US5696892A (en) Method and apparatus for providing animation in a three-dimensional computer generated virtual world using a succession of textures derived from temporally related source images
Avidan et al. Novel view synthesis in tensor space
EP1854282B1 (en) Method and system for spatio-temporal video warping
US5077608A (en) Video effects system able to intersect a 3-D image with a 2-D image
US6449019B1 (en) Real-time key frame effects using tracking information
JPH11331874A (en) Image processing unit, depth image measuring device, composite reality presenting system, image processing method, depth image measuring method, composite reality presenting method and storage medium for program
WO1991018381A1 (en) Computergraphic animation system
JPH10500498A (en) Spatial effective image generation method
Pighin et al. Realistic facial animation using image-based 3D morphing
US5756354A (en) Animating three dimensional images by selectively processing intermediate animation frames
CA2483943C (en) Computer-assisted animation construction system and method and user interface
Kanade et al. Virtualized reality: Being mobile in a visual scene
KR20000051217A (en) Three-dimensional face synthesis method using facial texture image from several views
CA2241854C (en) Computer-assisted animation construction system and method and user interface
CN109658326B (en) Image display method and device and computer readable storage medium
GB2342026A (en) Graphics and image processing system
Booth et al. Computers: Computers animate films and video: Computers permit spectacular visual effects and take the drudgery out of film cartooning
KR100272132B1 (en) Method and apparatus for reconstruction of stereo scene using vrml
JPH04372079A (en) Picture display device

Legal Events

Date Code Title Description
EEER Examination request
MKLA Lapsed

Effective date: 20141224