Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
RD-fii38 239 PLACING HIDDEN SURFACE REMOVAL WITHIN THE CORE GRAPHICS 1/2STANDARD: AN EXAPIPLE(1I> AIR FORCE INST OF TECHWRIGHT-PATTERSON AFB OH SCHOOL OF ENGI. . T S WAILES
UCASIFIED 07 DEC 83 AFIT GC5/MA/83D-9 F/G 912 NEhhhhhso n / omho oiEsmhohhhhhhmhhsmhhhhhhhhhhhmhhhhshhhhhhhEEhhhhmhhhhhhhEmhhhhhhhhhhhhEEhhmhohmEmmhIo
im .L L
- -- ,&. .. . . . . . -L
r-
1.2 IL6
MICROCOPY RESOLUTION TEST CHARTNATIONAL BUREAU OF STANDARS-1963-A
%:4e,........-.--...
;7' %- 4. 7-k 6.7 *. C* I 4- V
*5*4
OF
. Placing Hidden Surface RemovalWithin the CORE Graphics Standard:
i An Example
i~ ~ /T s hes is
F~AFIT7!M,'@ 83D-9 Tom S. WailesCapt USAF
JDTIC
• ! ~DLMs'UTIO'N STATEMENT A I ELECTE~r
.+ D istrib uo n U nlimted S+D+ EPARTMENT OF THE AIR FORCE 7 .r
Q- AIR UNIVERSITYC..') AIR FORCE INSTITUTE OF TECHNOLOGY
IL3 W right- Patterson Air Force Base, Ohio84 02 21 169
.',
' ; ,< , ":, _Placin. Hide Sufc Removal:.,; ,..... .;, .. .....
AFIT/GCS/MA/83D-9
Placing Hidden Surface Removal
Within the CORE Graphics Standard:An Example
. Thesis
AFIT.-.'--83D-9 Tom S. WailesCapt USAF
DTICELECTEFEB 2 1984
*OV1'1MI. oontains oolorPlatesS MI DTIO reproduot.Ln. Wil be IU black and Bwhit*'
Approved for public release; distribution unlimited
qi.
AFIT/GCS/4N"/83D-9
PLACING HIDDEN SURFACE REMOVAL WITHIN
THE CORE GRAPHICS STANDARD:
AN EXAMPLE
THESIS
Presented to the Facualty of the School of Engineering
of the Air Force Institute of Technology
Air University
in Partial Fulfillment of the
Requirements for the degree of
Master of Science
by
Tom S. Wailes, B.S.
Capt USAF
Graduate Computer Science
ADecember 1983
Approved for public release; distribution unlimited.
:4 . . S .. *I'i * .'" y."". -.-. •- . -" ".-""""
AFIT/GCS/MA/83D-9
Mi Preface
This paper is a testimony to the grace and
faithfulness of God. Little did I know, when I embarked on
this adventure in the spring of 83, that so many problems
could arise on so many pieces of equipment in so short a
period of time. God was faithful, and in my many times of
dispare, He provided insight and encouragement to get me
going again.
A special thanks is due to Dr. John Reising and the
many fine people of the crew systems development branch of
the Flight Dynamics Laboratory. It was their quest for a
microcomputer-based graphics system that spawned this
project, and it was their support that made it successful.
Thanks are also in order for the students and faculty
of the University of Pennsylvania who shared their Pascal
CORE library with the Laboratory. I am greatly in debt to
Prof Norman I. Badler who was the principal contact point
for information on the design and implementation of the
subroutine package.
Perhaps, the one person most responsible for the final
outcome of this package is prof Chuck W. Richard Jr. who
taught me the basics of computer graphics and has patiently
guided me throughout the research. His timely comments and
suggestions along with his mathematical expertise made him
*:., the ideal advisor for the project.
Finally, I wish to honor the many sacrifices made by
ii
AFIT/GCS/MA/83D-9
* my wife of six and a half years. During this long graduate
school experience, she has had to take a second seat to
tests, papers, briefings, and most profoundly, this thesis.
Her encouragement, logistical support, and love have made
this effort productive, and without her, it simply could
not have been done.
Tom S. Wailes
Acesi FoNTSGR&DTCTA
'a)l 'ndo
Distriu Seial
Avi'0l t C46e.
.9V
AFIT/GCS/MA/83D-9
Contents
page
Preface . . . . . . . . . . . . . . . . . . . . . . ii
List of Figures . ................. vi
List of Tables . . . . . . . . ........ . . vii
I. Introduction . . . . . . . . . . . . . . . . . I-iProblem . . . . . . . . . . . . . . . . . . -3
S c o p e . . . 0 0 0 0 0 0 0 0-
overview . . . . . . . . . . . . . . . . . -5
II. Detailed Analysis of the Prqblemand Requirements . . . .. . . . . . . & ..*. 11-1
Rehosting the U of P Software . . . . . . . -1Raw Transport of Source Code . . . . . . -3Language Incompatibilities . . . . . . . -4Creating New Libraries . . . . . . . . . -7Developing New Device Drivers . . . . . . -8
Selecting a Hidden Surface Algorithm . . . -9Application Program Design . . . . . . . . -11
III. Solution Decisions . . . . . . . . . . . -1
Rehosting the University ofPennsylvania Software . . . . -Selection of a Hidden SurfaceRemoval Algorithm ...... .... ... -6Testing the Graphics Package . . . . . . . -12
IV. Detailed Algorithm Description . . . . . . . . IV-1
Object Description within the CORE . . . . -2The Algorithm . . . . . . . . . .. -7
Preprocessing . . . * .. .. . . -8Resolveing the Linked List .. .. .. -16Polygon Splitting. ... ...... . -26Placement of Polygon Fragments . . . -33Resolver Pseudo Code . . . . . .. .. -35
V. Analysis of the Final System . . . . . . . . . V-I
Hardware and Support System Capabilities . -1University of Pennsylvania Output Pipeline -6
iv
AFIT/GCS/MA/83D-9
Contents
The Algorithm . . . . . . . . . . . . . . . -9Sorting . . . . . . . . . . . . **-10
Resolving . . . . . . . . . -12Computational Cost of the Algorithm -18
VI. Conclusions and Recommendations . . . . . . . VI-1
Making the Algorithm Standard . . . . . . . -1Items of Future Research . .. .... . -5Recommendations . . . . . . . . . . . . . -8
Bibliography . . . . . . . . . . . . . . . . . . . Bib-1
Appendix A: Pascal Source Code . . . . . . . . . . A-I
'- Appendix B: Maintaining the Flight DynamicsLaboratory Core Graphics System . . . B-i
Appendix C: Hidden Surface Interface toMain Core Package (Structure Charts) . C-i
V i t a . . . . . . . . .. .. V i t -I
0
'V. -€ .-.. , ,.."% ,- *-"" " ""-" "" ' " -
" '
AFIT/GCS/MA/83D-9
List of Figures
Figure Page
1 Segment and Output Primitive Data Structure . IV-4
2 The Hidden Surface Linked List Data Structure IV-10
3 Initial Ordering . . . . . . . . . . . . . . . IV-18
4 Extent Tests ................. IV-19
5 Plane Equation Tests. . . . . . ...... . IV-20
6 Scan Overlap ... ......... ..... IV-21
7 Cyclic Overlap . . . . . . . . . . . . . . . . IV-26
8 Polygon Splitting . . IV-27
9 Test Scenes ......... ........ V-13
10 Memory Layout of CORE System ......... B-9
vi
.... ... . ..0 b i ' i~A - - ..
AFIT/GCS/MA/83D-9
_w List of Tables
Table Page
I Algorithm Performance in Four Scenes . . . . . V-14
.i
.ib
vii
AFIT/GCS/MA/83D-9
Abstract
A Pascal based ACM proposed standard (CORE) graphics
system from the University of Pennsylvania was converted to
run on an 8086/8087 microcomputer. Additionally, a
non-restrictive full 3-D hidden surface removal algorithm
for surfaces modelled by opaque polygons was implemented.
This algorithm is an extension of the list priority
algorithm created by Newell, Newell, and Sancha. By saving
the priority list created by the algorithm from one batch
of updates to the next, computational savings are possible.
Although the present algorithm can only be used on raster
type display surfaces, this algorithm could be used as a
prelude to other scan line hidden surface removal
algorithms to provide support for vector type displays.
viii
AFIT/GCS/MA/83D-9
!. PLACING HIDDEN SURFACE REMOVAL WITHIN
THE CORE GRAPHICS STANDARD:
AN EXAMPLE
I Introduction
Aircrew survival in today's electronic battlefields is
becoming increasingly more difficult. The rise of more
sophisticated electronic sensing devices is forcing pilots
to fly at lower altitudes and faster airspeeds to reduce
their probability of detection. To make matters worse,
future battle plans call for aircrews to carry out their
sorties independent of weather and lighting conditions,
requiring greater concentration by our pilots to avoid
natural and manmade terrain features[14:l].
In addition to the strain imposed while penetrating
deep into enemy territory, once in the target area, pilots
must quickly select from an array of weapon system delivery
options and accurately deliver ordinance in spite of new,
*more accurate target area defenses. As can readily be seen,
our pilots are being tasked with more and more decisions
with smaller and smaller room for error and need new tools
and techniques to penetrate the sophisticated air defenses
of the future.
To combat the increasing pilot workload, the Air Forceis funding research into the development of more efficient
I-1
S MX-Wl "6- F7F_7 7-- - -- - - -
AFIT/GCS/MA/83D-9
S-human-aircraft interaction[17:l]. Because of the increasing
capabilities of digital electronics, non-traditional
approaches to the problem of weapon system operation are
being explored. Research areas include voice controlled
weapons subsystems, incorporation of human engineering
*concepts in cockpit layout, and the use of computer
graphics to generate information rich, visual displays.
Fortunately, recent developments in computer graphics
have aided the development of cockpit graphic displays
proposed by the Air Force Flight Dynamics Laboratory. A
proposed graphics standard created by the Graphics
Standards Planning Committee of the Association for
Computing Machinery(ACM) in 1979(16] has motivated vendors
and Universities alike to create graphics software that is
portable from one installation to another. This standard
(commonly called the CORE) defines a set of callable
subroutine functions that draw lines, display text, and
create different views of user defined scenes on graphics
display devices.
In a typical application, a user's program calculates
data to be displayed(e.g. the position of an aircraft) and
then calls the CORE system to draw the object. The CORE
subroutines handle all necessary matrix multiplication and
low level communication with the user's output and input
devices to draw the object. By separating the user's
:7. program and the actual hardware device by the CORE
subroutines, the average user doesn't need to know the
.1-2
. ',,, %2 . . %., % "-"• ' % "-"C . " • -" C*- -' * ' ."•"' a '" -% ' -
AFIT/GCS/MA/83D-9
S..' "guts" of the display hardware, and application programs
are device independent.
Problem
The Flight Dynamics Laboratory recently acquired a
microcomputer based graphics system to design and test
computer generated visual displays for future cockpits. In
a preliminary literature search, an existing CORE graphics
package that met nearly all of their design requirements
was found at the University of Pennsylvania. To decrease
the amount of time needed for software development, they
wanted to rehost this software, adding a hidden surface
removal function to complete the package.
There were three major facets to this problem. First,
the University of Pennsylvania (UP) software would have to
be modified to allow compilation on the microcomputer
system purchased by the Flight Dynamics Laboratory. Second,
because the Flight Dynamics Laboratory wanted to display
realistic complex scenes that required the removal of
surfaces obscured by objects closer to the eye, a hidden
surface removal algorithm consistent with the CORE standard
had to be chosen and incorporated into the UP software.
Finally, a test program needed to be defined which
exercised the total graphics system and provided the
Laboratory a baseline of system capabilities.
1-3
AFIT/GCS/MA/83D-9
di ~- ~ Scope
The software modifications caused by the incorporation
of the hidden surface removal modules used the methodology
and functional specifications of the ACM SIGGRAPH CORE
standard as a guide. Because many graphics vendors support
this standard, adherence to this set of guidelines will
allow easy future hardware and software improvements.
Current cockpit visual display specifications require few
graphics input functions, therefore the primary emphasis of
this project was the development of rich 3-D graphics
output functions for drawing complex images on the cockpit
monitors.
0 Many different methods have been found to model three
dimensional objects and perform hidden surface
removal(2,3,4,5,6,7,8,9,10,12,13,15,20,211. Although
techniques and algorithms abound, each has limitations and
costly drawbacks when used in general applications.
Nevertheless, this projects's goal was to implement a
modeling system and hidden surface removal algorithm both
general in nature and time efficient in most applications.
a. Because of limited time available, the research effort
concentrated on developing only polygon hidden surface
removal modules for raster type devices. A follow on
project is required to develop the modules needed to
, ~perform hidden line removal needed by vector type display
" devices and to perform hidden surface calculations on the
1-4
4 , %* *~~ *. . ~~*~** * .%..* * .V% ~ V " V % ~f
AFIT/GCS/MA/83D-9
.other output primitives specified by the CORE.
A simplified test program was written that created
images similar to the situation display format proposed by
the Flight Dynamics Laboratory. Included in this display
were such objects as terrain features, enemy threats, and
aircraft position. The test program did not attempt to
model aircraft performance or exactly model a portion of
the earth's surface. The purpose of the test program was to
evaluate the function of the graphics software, not create
a detailed data base management system or aeronautical
model.
Because the Flight Dynamics Laboratory had recently
acquired the hardware for this project, the effort was
constrained to use the processing power, system software,
data storage, and display capability already purchased.
overview
This thesis then is a report on a design project that
took an existing CORE graphics software package, added a
hidden surface removal capability, and then created an
application program for test purposes. The following
chapter first defines the problem in detail creating a list
4of design specifications for the final program. The next
., chapter outlines the alternative approaches possible to
47. solve the problem, including a detailed discussion on the
selection of the hidden surface algorithm used in this
1-5
AFIT/GCS/MA/8 3D-94.
:* -
project. Chapter four contains a detailed technical program
description of the hidden surface removal algorithm
developed during this research including the mathematical,-,
details of the associated comparison tests. Chapter five
records performance analysis of the algorithm and the4.
graphics system. Finally, chapter six presents the
conclusions reached during the research and and
recommendations for future work.
g
.4
,!
.4.
.%
4%
4.
q-. -K- - -. J. . .. -,fi , - - - .- - ,
AFIT/GCS/MA/83D-9
II Detailed Analysis of the Problem
and Requirements
As stated earlier, this project had three major
obstacles to be overcome: the rehosting of the University
of Pennsylvania software, the development and integration
of a hidden surface removal algorithm, and the creation and
analysis of an application program to test the graphics
software. This chapter will take each of these subjects in
turn, and reveal the many facets of the problem that are
not readily observable.
First, this chapter outlines the problems that were
0 expected when trying to rehost the software; detailing the
graphics microprocessor system resources, Pascal language
differences, and operating system incompatibilities between
the software sent and the graphics system purchased by the
Laboratory. Next, the problem of selecting an appropriate
hidden surface removal algorithm is discussed,
concentrating on the requirements of the CORE standard.
Finally, this chapter presents the requirements of a
suitable test application program to test the total
software package.
Rehostina the U of P Software
The software acquired by the Flight Dynamics
!! II-i
* ' .. '.•** * % ~ ~ - ~ ~ V. V V ~ b ~ ~ . . ~ ~ V
AFIT/GCS/MA/83D-9
Laboratory was originally developed by the University of
Pennsylvania on the Moore School's UNIVAC 1100/61[18:179J.
From the beginning, the six member programming team
designed the system in Pascal using modular programming
techniques to isolate individual functions of the software
package. Because they had a modular compilation capability,
they additionally decided to place the individual
programming modules into separate files. Later when a VAX
11/780 became available, they kept the separate file
structure and transferred the system to the VAX computer
converting it to VAX Pascal. Therefore, the software source
tape that eventually was sent to the Flight Dynamics
Laboratory contained over 300 files, all in VAX Virtual
0 Memory operating System (VMS) format.
The microcomputer system obtained by the Flight
Dynamics Laboratory for the graphics function consisted of
an Intel 8086/8087 microcomputer, 384K bytes of main
Smemory, 512K bytes of pseudo disk(a RAM type memory that
appears to the operating system to be a disk), and one
double density double sided floppy disk drive having 1.2M
bytes of storage. These resources plus a terminal and the
SCION display processor (a Z80 based raster scan graphics
coprocessor) were available for use in the final
operational configuration. All of these resources, were
Ctied together by the CPM operating system which occuppied
.% .*. approximately 15K bytes of main memory.
For software development, the laboratory purchased the
11-2
a. .* Z N.'* , ..'vvc.. .C . .. ....fC :. .* ...V..i. .,.,:.......- -
AFIT/GCS/MA/83D-9
Pascal MT+86 compiler with it's optional screen editor
package designed to aid Pascal program development.
Development of software occurred on a separate processor
from the graphics system that had 512K bytes of main
memory, 2.4M bytes of of double density floppy disk storage
, and a i0N byte hard disk drive. To allow more than one
person to develop software at the same time, these
resources were linked together by the MPM operating system
(a CPM compatible operating system that allowed multiple
users). Software created, edited, compiled, and linked on
the large system was transferred to the graphics processor
using floppy disks.
0 Raw Transport of Source Code
Considering the above discussion, the following were
the requirements to be met when intergrating the Pascal
source code into the Flight Dynamics Laboratory
Microcomputers:
1) The tape sent by the University of Pennsylvania was
in VAX 11/780 VMS format. The source programs had to be
transferred to the Flight Dynamics Laboratory
microcomputers. The final code could reside on either the
hard disk or floppy disks, however in either case the
compiler needed the programs in MPM formated disk files.
11-3.
AFIT/GCS/MA/83D-9
2) The transfer of code had to be reliable to prevent
wasting precious time debugging code transfer errors.
3) The transfer of code to the micros had to be
repeatable should hardware malfunction or operator error
inadvertently destroy the transferred files.
4) Because the source tape contained object files and
operating system files not needed by the micros, these
files had to be eliminated from the transfer process, to
save disk space on the smaller capacity microcomputer
system disk drives.
Language Incompatibilities
Because the VAX 11/780 Pascal language differed from
the MT+86 version of Pascal, a method for changing the
source received from the University of Pennsylvania to the
language definitions required by MT+86 had to be developed.
The following is a complete listing of all the changes
needed to perform this activity:
1) The VAX version Pascal defined its program modules
using the key word "module" to indicate the beginning of a
module and "end." to signal the end of a module. The MT+86
compiler also expected "module" to signal the start of a
module, however the sequence "modend." ended a module. The
11-4
", • " " " " ' 'J' ' ' .- ' - - - . *. - t-..'.- -' . - -t . . .- - . '. ",-., f-t
AFIT/GCS/MA/83D-9
-VAX Pascal compiler allowed module names and procedure
names to be the same, therefore, the originators had
purposely defined modules with the name of the procedure
contained within. The MT+86 linker required that module
names and procedure names had to be different. In addition,
the VAX needed the Pascal "(input,output)" parameter
declarations right after the module name if any input or
output was performed by the module. The MT+86 compiler did
not require this declaration. Obviously, the
"(input,output)" declarations had to be removed from module
files that had them, module names had to be replaced with
unique names, and the "end." found at the end of modules
had to be replaced by "modend."
2) The VAX language used the syntax "% include '" to
include files within the modules. The MT+86 compiler
expected "1$I I" as its include-file declarations. All
include file declarations had to therefore be changed to
the MT+86 format.
3) The VAX Pascal placed the keyword "extern" after
"* external procedure declarations for use by the compiler to
establish linkages. The MT+86 compiler required the keyword
"external" before external procedure declarations.
Therefore, all external procedure declarations had to be
, prefaced by "external" and the VAX key word "extern"
deleted. Additionally, the VAX used the key word
II-5
AFIT/GCS/MA/83D-9
.- -- "[external]" to preface external variable names where as
the MT+86 compiler simply expected "external". Obviously
the only change here was to remove the braces.
4) The University of Pennsylvania source writers
decided to use the VAX unique "varying" type declaration
for the passing of variable length character arrays. This
type declaration was equivalent to a packed array of
characters, except that string length information was kept
by the system in a user accessible area referenced by
muserarrayname.length". Unfortunately, they also had to
modify the actual program code to integrate strings,
especially when initializing strings and comparing two
strings.
Pascal MT+86 supported a "string" type much like the
"varying" type of the VAX. However, the MT+86 language
required the calling of special procedures to initialize
("fillchar") or find the length ("length") of strings
ainstead of the VAX implementation which allowed the user
direct access to the array length variable. All procedures
that used varying in a type declaration obviously had to be
modified by hand.
a5) The VAX "case" construct used "otherwise" as the
default label to be executed if no matches were found. The
MT+86 compiler used "else" as the default. Therefore, all
keyword "otherwise" occurrences in the code had to be
11-6
" /~. * '4 '* ' .i.b '. .. 5* .. . . . ..... ,m€.... .... . . .., - '-ZL
AFIT/GCS/MA/83D-9
changed to "else".
6) The VAX version of Pascal required that global
procedure entry points (e.g. the procedure header line such
as "[global] procedure mine(..." ) within modules had to be
preceded by the keyword "[global]". The MT+86 compiler did
not require this information and therefore these
occurrences of "[global]" had to be deleted.
7) The VAX allowed more characters of significance in
variable,procedure,and file names than those of Pascal
p MT+86 and the CPM operating system. This required finding'
all occurrences of variables and procedures greater than 7
0characters (the limit for external variable and procedure
names in MT+86) and determining if the new truncated name
was unique. All non unique names (e.g. SETLOCP2,SETLOCP3)
had to be changed (i.e. SETLCP2,SETLCP3). In addition,
-C filenames greater than 8 characters had to be changed to beS..
compatible with CPM.
Creating New Libraries
To reduce the size of applications programs, the user
should only have to link those functions that the program
actually needs. Therefore, the software modules created had
,: . to be placed into a library that could selectively link the
modules. This library had to meet the following
11-7
AFIT/GCS/MA/83D-9
€€ "requirements:
1) The library scanning function of the Pascal MT+86
linker was a one pass scanning function. Modules had to be
placed in the library so that modules requiring the loading
of subordinate modules occurred first.
2) There was a large number of modules expected to be
in this library. Provision had to be made to either split
the modules into separate libraries or provide some other
method of access to the assembled modules should the number
and size of modules exceed the amount allowed by the linker
program.
.!Developing New Device Drivers
Because the software package developed at the
University of Pennsylvania did not use a SCION display
processor, new device communication routines had to be
created. They had to meet the following specifications:
1) Routines created had to support all output
primitives presently supported by the University of
Pennsylvania software.
2) Routines created would not require changes to the
device independent portion of the University CORE package.
II-8
AFIT/GCS/MA/83D-9
,. .... 3) Program stubs would exist for all input primitives
not implemented on the SCION processor.
Selecting a Hidden Surface Algorithm
Many hidden surface algorithms exist which exhibit
varying degrees of efficiency. Most have restrictions which
limit their application which is in direct conflict with
CORE guidelines. Therefore, the algorithm selected for use
would have as a goal the following specifications:
1) Ideally the hidden surface removal subroutines
would strictly adhere to the specifications contained in
the ACM SIGGRAPH CORE. This implied that the algorithm
would only require object descriptions in 3 dimensional
world coordinates (user coordinates), the viewing
transformations specified by the user, and the viewport
specifications given in 3 dimensional Normalized Device
Coordinate space(NDC)[16:III-9]. As suggested by the CORE,
it would be implemented at the interface between NDC and
the physical device[16:III-1l1. Finally, it would support
the four hidden surface implementation levels defined by
the CORE[16:III-121:
a) None: no hidden surface processing.
b) Temporal: Objects drawn strictly in the order given
by the user.
c) Explicit: Objects displayed prioritized according
11-9LI.
AFIT/GCS/MA/83D-9
-. to which z plane they have been assigned to by the user.
This is commonly referred to as 2 1/2 D.
d) Full : Full hidden surface removal for all output
* primitives.
2) Because the CORE central concept is generality of
use, the algorithm selected would allow the picture
generation of almost any image. This implied that it be
. free from restrictions commonly found in hidden surface
algorithms[7:10]:
a) It would allow polygons of an arbitrary number
of points(some algorithms require that polygons only
have 3 sides).
b) It would allow penetrating polygons.
c) It would allow concave polygons to be modeled.%'
'd) The user would not have to specify whether the
polygon points are defined in a clockwise or
counterclockwise direction.
e) The user could define polygons that do not
belong to polyhedrons.
f) There would be no restriction to the number of
polygons that share the same edge (e.g. a paddlewheel
of planes is permitted).
g) Boundaries with internal faces would be
allowed.
h) Line segments would be allowed.
i) The definition of objects would not require
II-10
d. - K - * ., - --- ,'"" , •' '-", . "-". ' . . , ... -,% , . ''' .
_ a . .. . .. ... . t.',, -.. , . - .? > . .AFIT/GCS/MA/83D-9
/.. more information than a list of vertices.
3) Because the algorithm would most probably be used
by programmers that knew little about the complexity of the
hidden surface removal problem, the algorithm had to be
robust, allowing inexperienced programmers to get results
even if they made minor errors. This implied that the
algorithm accept non-coplanar points and additionally be
free from infinite loops on complex objects that had
inadvertent intersecting planes.
4) Additionally, the algorithm had to be
computationally and memory space "efficient" (e.g. able to
0 run on non virtual memory systems) in a wide range of
applications. This requirement ensured that evei users Cf
- small systems would be able to get high quality graphics
pictures created by the CORE.
- 5) Finally, the algorithm selected would allow
incorporation of shading and other visual realismtechniques "on top of" the CORE (provided by vertex color
intensity arrays), to enhance the usability of the CORE in
high cost, computationally rich systems that could afford
these capabilities.
Application Program Design
II-li
AFIT/GCS/MA/83D-9
Because this project involved the rehosting of a major
software package and the incorporation of a major addition
* to the package, a test program would be needed to exercise
* the package. Specifically, the test program would create an
image that satisfied the following specifications:
1) Display the situation display format:
a) Simulated terrain data, consisting of four
sided polygon planes with the points corresponding to
the terrain elevations at 1/4 mile increments, would
be displayed. Other possibilities include: increasing
the resolution of the display by making the terrain
- .. squares smaller, defining the terrain by shapes that
0, had the same altitude (e.g. a relief map), and using
some type of polynomial to compose polygons that
approximated the surface. The 1/4 mile four sided
polygons were chosen simply for convenience.
b) Several threat markers would also be displayed
consisting of red and yellow polyhedrons corresponding
to enemy anti-aircraft positions. These polyhedrons
would contain at least 8 polygons and would be placed
in a separate data base from the terrain data.
c) An aircraft marker made of a triangular body
and a small triangular tail surface would indicate
aircraft position.
. d) The eyepoint for the display would be set
7,000 ft behind and 1,000 ft above the aircraft
11-12* b* * .*#* * ~ . . *
.P.
AFIT/GCS/4A/8 3D-9
position.
2) The view provided by the system would be a
perspective view with hidden surfaces removed.
3) The system would generate the illusion of motion by
moving the aircraft and eyepoint through the terrain
database, drawing new views after each move.
This chapter has defined the requirements that the
graphics system must meet. The next chapter discloses the
approach taken to meet them.
111
4 C.-
AFIT/GCS/MA/83D-9.4
".' ; ,*..- III Solution Decisions
Deciding on the proper course of action to solve the
problems outlined in the previous chapter was not easy, due
to the many possible approaches at various levels. However,
this chapter attempts to justify the decisions made to
create the final system. This chapter will first describe
why a Pascal program was written to automate the many
changes needed for the conversion of the University of
Pennsylvania source code into a form compilable on the
Laboratory's microcomputers. Next, the reasoning behind
choosing a depth sorter type hidden surface removal
algorithm for this package is discussed. Finally, this
chapter comments on the development of a suitable testing
sequence to debug the final system.
Rehosting the University of Pennsylvania Software
Because this research needed a reliable, repeatable
and self documented conversion of the software package
originally received from the University of Pennsylvania,
rehosting the software was accomplished in a two step
process. First, the files contained on the VAX VMS tape
were transferred onto floppy discs and then a conversion
. :. program that took the floppy disc files and converted them
into a compilable form. In the end, this process required
i III-i
°. ~ a "'*~\ * *. ~-~.*~4,° ( ' . * ~ **~~ % . * % ~ * %
AFIT/GCS/MA/83D-9
:. . the use of two VAX 11/780's in addition to the Laboratory's
microcomputer system.
The first problem was of course to find a computer
which could place the source tape onto floppy discs in a
CPM/MPM format. The main AFIT UNIX VAX 11/780 was known for
its ability to create CPM formated floppy discs and was
initially chosen to make the conversion. Unfortunately, the
tape reading facilities of its UNIX operating system did
not understand VAX VMS format and when attempts were made
to read the original tape, the resulting files contained
many extraneous characters.
To clear this hurtle, I found another VAX 11/780
located at the Air Force Avionics Laboratory that had a VMS
0operating system and a special utility program that created*. formated tapes readable by the UNIX operating system. By
using this program, I created a tape readable by the UNIX
VAX and then used the UNIX VAX to create the needed floppy
discs.
Because the MT+86 Pascal compiler of the Laboratory
had string searching, string deletion, and string insertion,%
system subroutines available to the user, the decision was
made to automate the changes needed for the Pascal language
differences by writing a conversion program. This method of
conversion had several advantages over other methods
including:
1) It would be easily repeatable if for some reason
111-2
.5%
AFIT/GCS/MA/83D-9
the converted files were destroyed, or if the University of
Pennsylvania sent a more recent release of the system.
2) It would automatically document all the changes
needed during the conversion process.
3) It would catch all occurrences of change. Manual
editing would certainly miss some needed changes.
It is debatable whether or not this method took less
time than a simple editing session method to make the
initial changes. However, during the compilation process
when changes were found to be necessary that were not
initially known, the conversion program was simply changed
slightly and run again. This time spent modifying the
conversion program was small compared to the time that
would have been spent to search and edit the entire module
library for later required changes. In addition, this
method taught the author how to use the system subroutine
library, the Pascal MT+86 compiler, and the system
subroutine linker program which sped later software
development.
Developing libraries to separate the functions for
size consideration proved to be more difficult than
originally expected. It was found that the MT+86 system
... allowed only 64K bytes of program area for any program. An
initial compilation revealed that 32K bytes of program area
111-3
4. * ~'~ v'/ . * 4 * . - '. -. . . ~4-A'
AF IT/GCS/MA/83D-9
was needed for a basic repetoire of CORE subroutines to set
color, create and delete retained segments, cause newframe
actions, batch updates, draw polygons, lines, and text, and
allow setting a fairly complete viewing specification.
Additionally, 21K bytes of device driver software was
needed to support the above mentioned device independent
CORE routines. Finally, Pascal system routines took up an
additional 14K bytes of memory to support the package,
resulting in over 67K bytes of program area without hidden
surface routines or a user's application program. This was
clearly a major problem and some solution had to be found.
To solve this problem, all graphics input functions
were removed and the CORE graphics and device driver
subroutines were placed into three independent overlays
(program groupings that are read from a secondary memory
device only when needed). This meant analyzing each of the
more than 250 program modules and determining where in the
CORE input and output pipeline they where needed. After
making the decision as to the overlay number of each
module, the overlay number was placed into its Pascal MT+86
external procedure declaration and the file name was placed
into a special overlay library build file. Three overlay
areas were defined: Initialization/ Termination, Device
Independent, and Device Dependent/ Hidden Surface.
Overlay one was rather small and contained the
procedures used one time only for initialization and
termination. This freed the two main overlays from the
111-4
p ,* " * .. . .'. - ft.
W *".." -"..9 .. ... .. . ".." ."
. . . .
AFIT/GCS/MA/83D-9
". burden of infrequently called procedures and gave them more
room for development and debugging. Overlay two contained
most of the user callable CORE procedures that set viewing
parameters, drew lines, drew polygons etc. along with the
utility procedures needed to support them such as the
graphics "clipping" routine. Overlay three contained the
device dependent device driver routines along with the
hidden surface routines developed during this research.
Finally, there were a few routines that were needed by more
than one overlay group such as the matrix multiplication
routine. These few routines were placed into the "root" or
main program by a user hidden, never called subroutine that
was incorporated into the global variable include file to
create the compiler references for them.
N This definition of overlays needed only two disk
accesses per picture to draw scenes. A sample scenario of
operation would start by accessing the initialization
overlay, caused by a user call to initialize the CORE.
After the initialization was complete, the first call to a
device independent routine would bring in the second
overlay. This overlay would remain in memory while the user
defined more polygons, lines, text etc. Upon calling
ENDBATCH OFUPDATES, the third overlay would be read into
4Ji memory and the actual drawing of primitives on the device
would be accomplished for this batch. Thus per frame there
would only have to be one swap of overlays.
All communication between the overlays was
III-5
9zz-W -3-WN 3 -A-- -CTM - WN 7-- - . 6 S. IN 77 7. 7.--7
AFIT/GCS/MA/83D-9
accomplished using data structures "owned" by the root. By
defining these data structures in the root as local and by
every other module as external, simple coordination of
effort was possible. Finally, when the user finished a
session, a call to TERMINATECORE would again read in
overlay one, this time to perform the proper termination
actions on the display device.
Selection of a Hidden Surface Removal Algorithm
Because this research's goal was a general purpose
hidden surface algorithm that was modular in design, memory
space efficient, free from the usual hidden surface removal
0 algorithm restrictions, and computationally efficient, the
Newell, Newell, and Sancha algorithm[13] was selected for
study. This algorithm simply sorts all polygons according
to their maximum z coordinate, resolves any ambiguities
when the polygons' z extents overlap, and then scan
converts each polygon in descending order of largest z
coordinate. By "painting" the objects furthest from the eye
first and then overlaying them with polygons nearer the
eye, a technically correct image is produced taking
advantage of the overwriting characteristics of raster
devices.
A review of hidden surface removal algorithms
published in the literature revealed that because of the
computational cost of generality, most algorithms had some
I111-6
*. -' -- +' " S. - "'.~ ' '-V* * % " ." * '_. t%. -. .." %" ." ..'.-. .--.".. "'. S ". " "" ". . - - ""•"'
AF IT/GCS/MA/8 3D-9
type of restriction. In a significant article written in
1974 the authors Sutherland,Sproull, and Schumacker
compared 10 well known hidden surface algorithms including
the Newell, Newell, and Sancha algorithm[20]. In this
study, it was revealed that only the Warnock, Watkins,
Bouknight, and Newell,Newell, and Sancha algorithms
permitted the user to draw images in an unrestricted
environment[20:36-7]. The other algorithms proposed by
Appel, Galimberti, Loutrel, Roberts, Schumacker, and Romney
all had some combination of restrictions, most commonly
being the requirement for additional information (adjacent
edges, clustering of faces, etc.) and the disallowing of
5- penetrating polygons. Because of my goal for generality of
use, these last six algorithms were removed from further
consideration.
Being able to draw arbitrary images is certainly an
honorable goal, but naturally no one wants to wait for
minutes for a slow hidden surface algorithm to draw a cube.
In fact, it has been the quest for a simple computationally
efficient algorithm that has driven researchers to explore
many differing approaches to solving the hidden surface
removal problem. Sutherland, Sproull, and Schumacker
addressed this important issue of computational efficiency,
and in their paper they proposed a computational cost
ordering of the ten algorithms previously mentioned in
- three hypothetical environments (20:54].
The first imaginary environment, a characterization of
111-7
- AFIT/GCS/MA/83D-9
.-'.'- most algorithm testing scenes, consisted of a simple house
made of some 200 polygon faces. An intermediate test
environment called "a harbor scene" consisted of some 5000
polygon faces and was intended to represent what one would
expect on a ship simulator scene of New York harbor. The
final environment proposed was the same harbor scene with
small detail added such as windows in buildings, finer
curved object approximations, and was intended to contain a
staggering 120,000 polygon faces.
. Although the study was simply an order of magnitude
calculation of how each algorithm would perform, the
Newell, Newell, and Sancha algorithm was considered an
order of magnitude more computationally efficient than the
ten other algorithms in the first environment, twice as
4 fast as its nearest competitor in the second environment,
and about 5 times slower than the Romney algorithm (deemed
the winner) in the third environment[20:54]. However,
J Romney's algorithm assumed all polygons were convex,
required all polygons be expressed as triangles, did not
allow penetrating polygons, and therefore was removed
earlier from my list of possible algorithms. Of the general
algorithms still remaining under consideration, the Warnock
algorithm was fastest in the third environment with the
Newell, Newell, and Sancha algorithm taking about 1.65
times as long to compute the picture. Because its
S,-. performance would be theoretically superior in applications
up to 5000 polygons and in the extreme still remain within
111-8I , , ," .""''" . " ,' " " ," " . " '..
-, "-%% . ' ,v - *; 4 ..-. '-.% '4 . ,..-*u
AFIT/GCS/MA/83D-9
" -an order of magnitude of other general hidden surface
removal algorithms, the Newell, Newell, and Sancha
algorithm was selected out of this initial study as my
candidate for research.
Obviously the search for an efficient hidden surface
algorithm did not stop in 1974, and in fact, there have
been many new algorithms proposed since that time. However,
in my search of the literature, I've only come across one
documented report of a hidden surface removal capability
residing in a CORE standard system[1l]. This particular
package used an algorithm for hidden surface removal
proposed by Myers[121; a raster-scan class algorithm that
can vary the number of pixels used in generating a
0 picture[ll:811. Unfortunately, this algorithm required aa.
large amount of memory for even a rather modest hundred
polygons[1l:81-2] and therefore this method was removed
from my list of alternatives.
The majority of algorithms developed since 1974 tend
to be geared toward one particular application of computer
graphics or toward one particular set of problems. This can
clearly be seen in the area of animation where several
algorithms try to decrease the time spent generating
successive picture frames by investing a substantial amount
of time in preprocessing the data base to be displayed.
These methods, similar to the concept proposed by
Schumacker in 1969, depend upon a priori knowledge of the
scene and may require direct operator manipulation of the
111-9
.ik. Xa* * * *. a ~ ~ - ,*- * - *~* ~
AFIT/GCS/MA/83D-9
database to minimize scene creation time[15:1131. Another
restriction found in these types of hidden surface speed up
techniques was the limitation of the scene to only static
objects or motion only under certain conditions, with the
animation coming from movement of the eye point through the
data base[9][5]. This limitation may indeed be acceptable
for flight simulators but some CORE applications may
require movement of objects within the scene.
Special techniques exist that perform hidden surface
elimination on surfaces defined by equations[2](which the
CORE does not support[16:III-75]), on voxel based
representations of medical data[l], and on special
chemistry molecular models[10]. Other algorithms exist
Owhich claim computational efficiency but require triangularpolygon definition[31, require polygon edges to belong to
at most two polygons[8], and strictly prohibit penetrating
polygons[6:264]. All of these non-generalized techniques
were discarded in favor of the Newell, Newell, and Sancha
approach. It is interesting to note that although some of
these methods were discarded because of their restrictions,
at least two algorithms devoted to fast computation of
animated scenes used the general list priority creation,
paint from back to front, split polygons if necessary,
steps of the Newell, Newell, and Sancha algorithm[4] [5].
As with all good things, this algorithm was known to
have some drawbacks and indeed would not solve all
problems. First of all, this algorithm is not well suited
III-10
.4*.* - ln I,,,,,,-".. ... .. ....... , , ... ,....... ...... ... -.-,, " '
17- .
AFIT/GCS/MA/83D-9
for raster scan film recorders. Once the film is exposed on
these output devices, the film cannot be overwritten with
the new values for polygons that obscure those previously
drawn. Also this method is effective only for hidden
surface removal and would not produce hidden line drawings
on calligraphic displays. However, this algorithm could be
used as a prelude to the excellent scan line algorithm
developed by Watkins[21].
As suggested by [20:421, the Newell, Newell, and
Sancha algorithm could be used to compute a priority
ordering of all polygons in the scene. Instead of actually
scan converting each polygon as it was resolved, the list
of polygons could be saved in a linked list maintaining the
order of "painting" required to generate a correct image.
After all polygons had been ordered, an index number could
be placed into the data structure by sequentially numbering
the polygons from back to front. The new data structure
could then be ordered into the y bucket sort needed by
Watkins, and his algorithm could begin scan converting each
line. During each scan line span calculation, when it was
necessary to determine which polygon was in front of
another, a simple reference to the index number would
resolve the question. This simple test would replace the
more complicated tests used by the Watkins algorithm.
It is difficult to predict the performance of such a
hybrid type algorithm, however, it would allow the correct
rendering of hidden line pictures and would create the type
III-ll
AFIT/GCS/MA/83D-9
* ' of output needed by raster type film recorders.
Unfortunately, one disadvantage caused by such an algorithm
would be the loss of parallelism inherent in the Watkins
algorithm (e.g. resolving polygons while scan converting
them). If however, the user is generating a sequence of
images, it would be possible to create a hidden surface
pipeline having two processors. The first processor would
perform the Newell, Newell, and Sancha algorithm, ordering
primitives in a "resolved primitives" file. The second
processor would take this file and scan convert each
primitive using the Watkins algorithm. This division of-4
labor would allow the simultaneous resolving of the display
priority of the next batch of updates while scan converting
the present batch of updates.
Testing the Graphics Package
The testing of the graphics package was divided into
three phases. First, an initial interactive program was
developed that drew lines, polygons, and placed text on the
screen. This program was used to test and debug the device
driver routines needed by the package. This program also
served to validate the basic features of the CORE package,
insuring that the system had remained intact during the
Pascal conversion process. It was during this phase that it
was found that a totally different color selection scheme
would be required to draw color pictures.
111-12
.*-.-, • . o . . . ,. .. , o .• , - • . ...... .... . o . . • t. . ** * * ** '*.*- . .
, * . - A A A * S .R- j ., J - . -. * A - - .P . . o . . o o: °
AFIT/GCS/MA/83D-9
.*X. The University of Pennsylvania's display device
achieved color by drawing pixels with separate calls to
draw the red, green, and blue values of the primitive (e.g.
a line). The SCION, on the other hand, used a color lookup
table which had to be predefined by the user and needed
only a selection of the color wished to be drawn. This
seemingly small change caused changes in some 21 different
modules.
*-. In addition, an application program to debug the
hidden surface routines and determine the cost of*1
performing hidden surface removal had to be developed. To
initially test the hidden surface removal package, a simple
scene of intersecting cubes was chosen for display. By
coloring the sides of the cubes different colors, it was
obvious when the algorithm performed properly. Several
object creating routines were developed to perform this
test, so that simple increments in scene complexity could
easily be accomplished to test the routines under varying
*scene conditions. Additionally, this method would easily
allow testing the package with several batches of updates
to determine if image transformations and retained segment
merging of primitives occurred as expected.
Finally, after this initial testing was completed, a
program to draw the situation display format was created to
analyze the systems usefulness to the Laboratory. Because
,the Laboratory had neither the computational resources of a
% ""mainframe computer nor special purpose graphics support
111-13
.. .~~~~~~.............. .. ............... ..... ........ .. ... '. * 'ta "" . " "€ '-. .
AEIT/GCS/MA/83D-9
hardware, the decision was made to initially limit the
number of polygons displayed to around 250 (comparable to a
preliminary study done by Boeing for the laboratory). This
would still allow over 200 terrain faces and would allow
testing of the algorithm with several objects used in their
scenario.
Now that the reasons behind my major design decisions
have been discussed, its time to actually reveal the
details of my hidden surface removal algorithm.
l.4.
0- 1
111-14
. * . .-.'.-. ... ..-. ... '.. .-...- .* % % N. N.6.4. .. ~ . * .. 4 % * * '*.*~ * ~ '" **JVI~* a%
- -4 9 - * *. - . -Z IF'. r.. .. '7. 77-7n. '. <. . t .
AFIT/GCS/MA/83D-9
IV Detailed Algorithm Description
The previous chapters of this work describe the
initial steps common to any major software effort, namely
the requirements definition and preliminary design phases.
These steps must be accomplished before the final detail
work begins to prevent wasted effort chasing infeasible
solutions and creating unneeded system frills. Using the
past chapters as a foundation, this chapter describes the
actual working program.
First, a short background section describes the
concepts used by the CORE specifications to define objects
to be displayed and points out additional burdens placed on
hidden surface removal algorithms by the CORE.
Additionally, this section briefly describes the data
structure and output viewing pipeline used by the original
package to give the reader an understanding of the data
available to the hidden surface removal algorithm.
Second, the programming steps required by my algorithm
to create a correct rendering of the CORE specified scene
are outlined. As stated earlier, this algorithm is an
extension of the algorithm first proposed by Newell,
Newell, and Sancha which basically "paints" objects from
back to front, letting the natural overwriting properties
of raster devices resolve conflicts. In addition, an
IV-1
AFIT/GCS/MA/83D-9
improvement to the algorithm proposed by Sutherland,
Sproull, and Schumacker is discussed.
Object Description Within the CORE
Object descriptions within the CORE can be considered
on two different levels. To allow easy interactive work
(e.g. moving objects around on the screen) the CORE system
requires the user to specify a beginning and end to object
definition. For example, if the user wishes to draw a house
made of several lines he must first open a "segment". He
then issues commands that draw the lines comprising the
house, and then he "closes" the segment. This outer layer
£7 is useful if, for example, after the house is drawn the
user wants to remove the house without having to redraw an
entire village.
Within each segment, there is another level of
description called the "primitive" level within which the
user actually issues the commands to draw objects. Six
basic output primitives are used to actually produce images
on the display surface, namely: line,polyline,text,marker,
polymarker, and polygon (move is also a primitive, but it
does not affect the screen). Provision must be made by the
hidden surface routines to perform hidden surface removal
on all six of these primitives.
Most hidden surface removal algorithms described in
the literature only discuss the problem of correctly
IV-2
AFIT/GCS/MA/83D-9
, .. rendering correct scenes made of polygons and make no
mention of provisions for line, text and marker primitives
required by the CORE. Although not presently implemented,
the Newell, Newell, and Sancha algorithm can be extended to
handle these special cases with little change in the
algorithm flow.
Because we are writing to a raster device, all we have
to do is model the marker and polymarker primitives as
points in space. Using the depth sort process we will
simply draw these objects at their proper depth priority
and let objects closer to the eye overwrite them if needed.
Lines will simply require additional checks to determine if
intersections occur with polygons. If an intersection does
* occur, the line will be divided at the point of
intersection and the two line halves and the polygon will
be inserted in the hidden surface linked list and output
primitive data structures. Polylines will be considered as
collections of individual line segments for this
-processing. Finally, text string primitives will simply be
treated as a 3 dimensional rectangular polygon that is
defined by the extent box surrounding the string of
individual characters. Calculating the polygon vertices
will require the interrogation of the present values of the
CORE "CHARUP,CHARPATH, CHARSIZE, CHARSPACE, AND CHARJUST"
attributes [16:11-22 - 11-28].
Describing the data structure provided by the
University of Pennsylvania CORE system requires us to
IV-3i**:*I~*' .*~**.~. *****~4***'**
,. "" , # 2 '--. """' . $ . -.- p' " " -- -- ." .-. w ° . --
oII".
AFIT/GCS/MA/83D-9
remember our previous description of segments and output
primitives. In their data structure, a linked list is kept
of all the segments created. Within each segment's record,
information that affects all the primitives in the segment
is kept, including: its image transformation, its name, and
detectability. Each segment points to a linked list of
associated output primitives. These output primitive
records contain the coordinates and other related
attributes of the primitive needed to draw the line,
polygon, marker,etc. on the viewing surface. Thus we have a
linked list of output primitives that make up a segment,
and a linked list of segments that make up a picture.
Segment Primitive
n, Next
P-- _ Segment
i Segment Name Pick ID
C Visable Flag Line Index, Pen #
t Highlighted Flag Coordinate Arrays
u Detectable Flag # of Coordinates
r Image Transformation NDC Primitive Extents
e Matrix Polygon Fill Index
Transformation Limi Interior, Edge Style
DC Segment Extents Color Indicies Next
_ _ _ _ Prim
* -.-. Hidden Surface Node
Fig 1. Segment and Output Primitive Data Structure
IV-4
AFIT/GCS/MA/83D-9
To invoke hidden surface removal, the user must tell
the system which objects should be processed. This is
accomplished using the BeginBatch ofUpdates and
EndBatch ofUpdates CORE subroutines. Segments defined
after the batch begins will not be drawn until
EndBatch-ofUpdates is called. At this time, previously
defined retained segments and all new segments defined in
the batch of updates will be depth sorted and processed to
create a new scene.
When each new primitive is added to the linked list
within each segment, the user defined points are
transformed into CORE system Normalized Device
Coordinates(NDC) and left in this coordinate space for
future use by the final image transformation, hidden
4u surface, and display routines. This transformation is a
concatenation of four operations consisting of a
multiplication of the image by a user defined instance
transformation (a user rotate, scale, translate),
multiplication of the image by another 4X4 matrix to place
the image in the viewing plane, "clipping" the points to a
user defined viewing volume, and then mapping the clipped
points into a user defined "viewport" on the viewing
surface. This entire process is called the "viewing
operation" and details of this process can be found in
(3:11-48 - 11-701.
.~ To speed computations requiring the generation of a
series of scenes in which a segment moves in relation to
IV-5,V. [ € : . .; : - -, • , , . .,' . ,' '., , .. .' - -. ' ' ' . '..'
J ', , -:' ]:a . -.- . ..-. o.*.,o - .-. -. . . .. ' , .- - -' '- - -''4.
AFIT/GCS/MA/83D-9
". its original orientation, the CORE standard allows the user
to specify an image transformation after the viewing
operation and before the final mapping to screen
coordinates. During each batch of updates, the user defines
viewing specifications and issues output primitive commands
which invoke the CORE viewing operations of normalization,
clipping, and mapping to the user's viewport. The NDC
coordinate results of this operation are then saved in the
main segment and primitive data structures which retain
each segment's coordinates until they are removed by a
DELETERETAINEDSegment action. The CORE final image
transformation takes these NDC coordinates and rotates,
scales, and translates each segment's image using a 4X4
0 matrix whose values are computed from rotation, scaling,
and translation parameters passed by the user. By simply
varying the image transformations from batch to batch the
user can cause segments to move (e.g. the flaps on an
aircraft) or can simulate eyepoint motion (true motion
requires a non-linear transformation that this method
really could not provide). Because the user only has to
change the segment's image transformation and does not have
to perform the entire viewing operation, this method is
significantly faster than having to redraw all images
* during each batch.
The present implementation performs all of its hidden
surface calculations on the image transformed coordinates
of each primitive. This allows the user to take advantage
IV-6
-,,, -,,4, ,v: 4,, ,' ,' .' .... . ' - ',,r . -.( -'.' * ....... % . '.- .,%:, , %.. - -.-- . ,. ..'-*,.. . ... ... .
AFIT/GCS/MA/83D-9
of the processing speed-up due to image transformations and
still receive true renderings of each scene. Additionally,
because many batches of updates may be needed by the user
to create an animated sequence of pictures, my extension of
the Newell, Newell, and Sancha algorithm maintains the
priority list and polygon definitions from the previous
*" batch of updates in the hope that the priority list will
change very little from batch to batch and that few polygon
subdivisions will be necessary if the object orientations
don't radically change. This idea to improve the algorithm
was first introduced by Sutherland, Sproull, and Schumacker
in [20:401.
0 The Algorithm
The purpose of the algorithm developed during thisresearch is to create an ordered list of polygons that when
scan converted on a raster device, will result in a proper
image. To accomplish this task, three basic steps are
needed. In the preprocessing step, an initial ordered list
ordered by maximum z is created. This list is further
refined by the resolving step which resolves any ambiguity
in primitive ordering. Finally, as ambiguities are
resolved, output primitives are scan converted and placed
on the viewing screen.
IV-7
AFIT/GCS/MA/83D-9
Preprocessing
During each batch of updates, the user may add new
segments and associated primitives to the list of segments
that comprise a picture. As each primitive is added, a
pointer that will eventually point to a hidden surface node
is set to nil. This pointer serves two purposes; first it
allows rapid deletion of the hidden surface structure
associated with each output primitive when deletion becomes
necessary and additionally it serves as a flag to determine
if hidden surface initialization has been performed (e.g. a
nil pointer indicates that hidden surface initialization
has not been performed for this primitive). This is the
only additional data item or field needed in the primitive
data structure to support hidden surface removal and is the
only data area overhead incurred by users who are not
calling the hidden surface subroutines.
The actual interface from the CORE to the Hidden
Surface support routines occurs within the
END-BATCHOFUPDATES subroutine and the delete primitive
subroutine. When ENDBATCHOFUPDATES is called and the
full hidden surface attribute has been set, a call is made
to the SORTER subroutine. This subroutine creates a linked
list structure that will be used as input to the RESOLVER
or main driver routine of the algorithm.
... This interface can be discribed by the following
pseudo code:
IV-8
AFIT/GCS/MA/83D-9
'. .END BATCH OF UPDATES:
IF FULL HIDDEN SURFACE THEN
BEGIN
CALL SORTHIDDEN (* PRODUCE ORDERED LIST *)
CALL RESOLVER (* RESOLVE AMBIGUITIES *)
V END;
As a first preprocessing step, the SORTER procedure
examines the primitives within each segment. If the hidden
surface pointer is nil, a call is made to the hidden
surface initialization procedure which calculates and4
stores the x and y screen extents (minimum and maximum),
the z extents in NDC space, and the plane equation
coefficients for polygons in a separate hidden surface
removal data structure (Figure 2). Because the CORE
specifications allow the user to perform a final image
.04. transformation to the stored NDC coordinates before display
on the screen, all of the above calculations must be based
on the image transformed points. Additionally, because
polygon splitting may be needed later, the initialization
procedure must save the image transformed points in the
hidden surface data structure.
IV-9I.'.'
9*o.
AFIT/GCS/MA/83D-9
Host Output Primitive
Next Primitive Output Primitive Next Primitive
Further From Forward - Closer to
Observer Backward Observer
X minmax
Y min,max
Z min,max
Plane Equation
Coefficients
X,Y,Z,W Image
Transformed
Arrays
Moved Flag
Enter Flag
Fig 2. The Hidden Surface Linked List Data Structure
The plane equation coefficients which define the plane
of a polygon using the equation aX + bY + cZ + d = 0 can be
calculated using several techniques. For example, if three
points on a plane are known not to be collinear, then the
a, b, and c plane equation coefficients can be computed by
taking the crossproduct of two edges between them. Because
such a computation requires detection of special cases and
because an inexperienced user may introduce non-coplanar
"% v". polygon descriptions, the calculation of the plane equation
IV-lO
AFIT/GCS/MA/83D-9
coefficients used in this implementation is based upon a
method developed by Martin Newell[20:14-151. Using this
method, the a, b, and c plane equation coefficients for the
list of vertices V = (X ,Y ,Z ) can be found by evaluatingi i ii
j = (if i-n then 1, else i + 1)
a =E(Y - Y )(Z + zi i i jb = (Z - Z )(X + X
i i i jc =E(X - X )(Y + Y
i ii j
In the present implementation, the fourth coefficient
d is found by substituting the X, Y, and Z coordinates of
the first point in the vertex list along with the a, b, c
parameters calculated above into the standard plane
equation aX + bY + cZ + d = 0 and solving for d. An
"average" d could be computed by summing the d for all of
the points and then dividing by the number of verticies.
However, this would require 3 floating point
multipliations and subtractions per vertex and would only
help approximate the d coefficient for non-coplanar points.
Because non-coplanar points would only be input as an error
by the user, the time needed to find an average d was
considered unjustified.
However, the present method is quite good and in fact
IV-1l
**,, *.' ¢ , ;.' "...., *." . . .". .. • .. .-. • ..
AFIT/GCS/MA/83D-9
"... this method requires only one multiplication per
coefficient per edge. If the polygon is not planar, this
method will produce a plane equation related closely to the
polygon, but not the best fit plane equation."[20:151
Because of the ability to get reasonable results even when
the user inputs non-coplanar points, this method of
calculating the plane equations helps make the algorithm
more robust.
Because the CORE specifications allow the user to
define polygons in either a clockwise or counterclockwise
direction, a simple modification to the plane equation
coefficients may have to be made. It can be shown that the
plane equation coefficients created for a polygon defined
in a clockwise direction will be opposite in sign and equal
in magnitude to those coefficients created from the same
list of vertices except defined in a counterclockwise
direction. In other words, the same locus of points can be
defined by plane equation coefficients whose signs for
Na,bc, and d are reversed (e.g. aX + bY +cZ +d = 0 = -aX -
bY - cZ - d).
This causes complications because all polygon plane
tests will be performed by substituting the vertices of
some polygon A into the plane equation of some polygon B to
determine if the vertex of A is closer or farther away from
the observer than the plane of polygon B. A convention is
needed such that no matter in which direction polygon B is
defined, the test results from substituting polygon A's
% . IV-12
AFIT/GCS/MA/83D-9
points into polygon B's plane equation will correctly
decide which is further from the observer. This convention
is fortunately easy to accomplish.
By arbitrary decision, we establish the convention
that a point A which is on the same side of the plane as
the observer's eyepoint must yield a positive plane value
when substituted into the plane equation of B (e.g.
(planevalue = a X + b Y + c Z + d > 0). Since thisB A B A B A B
holds when point A is the eyepoint (i.e. the origin X = YA A
- Z = 0) this convention requires that d > 0 . Therefore,A
all we have to do is check the plane coefficient d computed
above. If d is negative then the signs of all of the plane
equation coefficients must be reversed, otherwise no
modifications of the plane equations are necessary.
For example, consider the locus of points parallel to
the xy plane located at z = -2 and imagine an observer at
the origin (0,0,0). The plane equation for these points is
simply a,b,c,d = [0,0,-l,-2] or [0,0,1,2] ( for an exercise
substitute the points (x,y,z) = (-1,3,-2) and (5,30,-2)
into aX + bY + cZ + d = planevalue using both series of
plane coefficients and see that plane_value is 0 indicating
that both points are on the plane). The point (5,30,-1.5)
should be on the same side of the plane as the origin ( the
observer). If you substitute (5,30,-1.5) into the first set
of coefficients you will obtain a planevalue of -0.5 and
if you substitute it into the second set you will obtain
'C's +0.5. Therefore, if the user had defined an object whose
IV-13
"% ,
AFIT/GCS/MA/83D-9
plane equation resulted in the first set of coefficients,
reversing the signs will produce the testing values
desired.
As shown in figure 2, three pointer values are used by
* the hidden surface linked list structure to connect the
hidden surface nodes to the main CORE segment structure and
provide display prioritization of the primitives. The
*' OUTPUTPRIMITIVE pointer points back to the host primitive
of this hidden surface node and allows the primitive data
- : structure to remain the principle repository of output
primitive information. The FORWRD and BACKWRD pointers are
used to order the primitives with FORWRD pointing to the
primitive next closer to the observer and BACKWRD pointing
to the primitive next further from the observer as compared
to this node. The initialization routine sets the
OUTPUTPRIMITIVE pointer and initially sets the FORWRD and
BACKWRD pointers to nil.
The remaining two hidden surface data structure
entries MOVED and ENTER are used to mark primitives that
have been moved within the sorted list ( and thus no longer
ordered by maximum z) and to denote how this node entered
the list. Nodes created during preprocessing by the
initialization routine are labeled NORMAL, those made
during a previous batch of updates are labeled UPDATE.
Finally, those primitives created during polygon splitting
are labeled SPLIT or NEWPRIM depending on whether they are
on the negative or positive side of the split plane at.1
'.4
IV-14
*',4' 1.* ',44441 1 % ~. %. % 1". ( % p ; . .' i _ .... . '... *4 *4 - - _- -.--.-.4 . .
AFIT/GCS/MA/83D-9
split time (new entries into the list are on the positive
- "side).
Upon return to SORTER from the initialization routine,
the newly created hidden surface node will be placed into a
temporary linked list of new hidden surface nodes called
the "mergelist". Primitives whose hidden surface pointer
was not nil (made on previous batches of updates) will be
"updated" by performing any image transformation requested
by the user and then appropriately calculating new plane
equations, extents, and storing the new points in the
hidden surface node. Thus, when all segments and primitives
Shave been processed, there will be two linked lists: the
updated previous batch of updates' hidden surface linked
list, and the new input mergelist of entries.
The SORTER then merges the new hidden surface nodes
from "mergelist" into the previous batch of updates' linked
list, sorting by the maximum value of z in NDC space. An
important point to remember here is that because primitives
marked as moved from previous batches are out of order in
z, they are ignored during this sorting phase. Of course,
this new list will undoubtably contain some ambiguities
caused by the merging entries, however, only small changes
should have to be made to the list to draw it in the proper
order.
The following briefly summerizes the sorting process:
i ..
i IV-15
a.
9.
- ~~~ ~T. W- 4.Z V.. . . . ~. . . . . . .
AFIT/GCS/MA/83D-9
SORTHIDDEN:
WHILE MORE SEGMENTS DO
IF SEGMENT VISIBLE THEN
WHILE MORE PRIMITIVES DO
IF NO HIDDEN SURFACE NODE THEN
BEGIN
1i INITIALIZE NODE;
SAVE ENTERING NODE IN MERGELIST
END
ELSE
UPDATE NODE WITH NEW IMAGE TRANSFORMATION
ELSE
WHILE MORE PRIMITIVES DO
IF HIDDEN SURFACE NODE THEN
DELETE HIDDEN SURFACE NODE FROM HIDDEN
SURFACE LINKED LIST;
WHILE NODES IN MERGELIST DO
PLACE NODE IN HIDDEN SURFACE LINKED LIST
ORDERED BY MAXIMUM Z VALUE;
Resolving the Linked List
-4
• 'After the new merged list of output primitives is
created, the individual polygons are examined to determine
. ~if polygon reordering or polygon splitting is necessary to
IV-16
U.
AFIT/GCS/MA/83D-9
paint the picture in the proper order. This examination
*' involves selecting a polygon P and comparing it against the
set of all primitives 0 that overlap it in z (Figure 3). If
P does not obscure any primitive in this set then we can
scan convert P, write it on the screen, and allow the
natural overwrite process to create the correct image.
The tests used to determine if P obscures the next
primitive in the set 0 are purposely placed in increasing
order of complexity and consist of six basic comparison
steps, namely:
1) Is the next polygon in the list a member of the set
Q (P and 0 z extent overlap)?i
2) Do the x extents of P and 0 overlap?'a i
3) Do the y extents of P and Q overlap?i
4) Is P behind the plane of 0 ?i
5) Is 0 in front of the plane of P?~i
6) Do the screen projections of P and 0 overlap?i
If it cannot be proved that P does not obscure 0 then
either P or 0 is split into two primitives and the
resulting primitives are placed into the hidden surface
linked list ordered by z. Polygon splitting is expensive in
both computation time and data storage space, and therefore
is avoided if possible.
The first test determines if all ambiguity has been
resolved between P and the set 0 that overlaps it in z
extent. This is done by examining the z maximum of the next
• % polygon on the hidden surface linked list closer to the
IV-17
9* ,,;'; ':' . '-. .- '''. ' ',': ' .- .'','',.
AFIT/GCS/MA/83D-9
observer (Figure 3,4a). If P's minimum value is greater
than the maximum value of this new test polygon then we
have reached the end of the set 0 and can scan convert P
(as shown by 0 in Figure 3).5
P
I 2
00
Xv
Fig 3. Initial Ordering
If this first test fails, a comparison is made of the
x extents of P and 0 on the screen surface. This is done4 i
by comparing the screen x extremes calculated earlier in
the initialization procedure. If P is to the left of 0 (i
P's maximum x is <- 0 's minimum x) or if P is to the righti
(Q 's maximum x is <- P's minimum x) then 0 cannoti i
possibly be obscured by P (Figure 4b). Under these
conditions the 0 pointer is advanced to the primitive next
IV-18
, -, ," , ....................................... . ........ ,-........... ........ . , .
AFIT/GCS/MA/83D-9
closer to the observer and testing begins once again. If
the x extent fails, then a similar test is made for the y
extents to determine if the two primitives overlap in y
(Figure 4c).
z vz vYV V
Fig 4. pxen tet
Qi
0 x x K
a) b) c)
aFig 4. Extent testsa..4.
all If Q has not been eliminated from consideration, thei
plane equations of the polygons are used to resolve the
ambiguity. The first test determines if the polygon P has
all of its vertices on the "back side" of Q (that is, ona. ithe opposite side of the plane of 0 from the observer).• " i
This is performed by evaluating the formula aX + bY + cZ +
d - value , for each point of polygon P where a,b,c, and d
are the coefficients of the plane equation of 0 and X,Y
and Z are the coordinates of the point being evaluated. If
~IV-19
AFIT/GCS/MA/83D-9
all vertices substituted into this equation produce a
negativ~e result, then the polygon P lies wholly on the back
side of 0 and should be scan converted before 0 (Figureii
5a). If this test fails, a similar test is performed to
determine if the vertices of 0 are all on the "front side"i
of P (Figure 5b). The only difference here is that all the
Q vertices must produce a positive result when placed intoi
the plane equation of P.
z z
v v
P P
0,
x xv v
Fig 5. Plane Equation tests
If the extent tests and the plane equation tests fail
to resolve the question of whether P obscures 0, there is a
sixth test suggested by Newell, Newell, and Sancha. This
test involves checking the projection of the polygons onto
the screen to see if the polygon images overlap. To
accomplish this task, all edges of each polygon are
* "'.): converted to screen coordinates and then the parametric
IV-20
AFIT/GCS/MA/83D-9
line equation of the resulting lines on the screen are
computed. We then find the point of intersection of each
line in P and all lines in 0 . If lines intersect along the
line segments of either polygon they indeed overlap on the
screen and P may obscure part of Q (Figure 6a).i
Additionally, if any line in P when extended to infinity
crosses an odd number of Q lines, then at least one of thei
endpoints of the line of P is inside the polygon of 0 andioverlap on the screen will occur (Figure 6b).
Y
Overlap Overlap No Overlap
a) b) c)
SX! xv
Fig 6. Scan Overlap
IV-21
Zea
AFIT/GCS/MA/83D-9
Determining the intersection of a line in P and a line
of Q is based upon elementary geometry and the use of thei
parametric equation of a line.
x = x + t(x - x )1 2 1
y - y + t(y -y )1 2 2
Values of t > 1 indicate that a point is on the
positive extension of the line segment from (x y ) toward* 2 2
infinity. Similarly, values of t < 0 indicate that a point
is on the negative extention of the directed line from
(x y ) to(x y ). This is important for our testing because11 2 2
the projection of each edge of a polygon on the screen can
be considered a directed line from some (x y ) to some11
(x y ). To calculate the intersection of two lines (one22
from P, the other from 0 ) we observe that unless the linesi
are parallel, they will intersect at some point x yint int
At this point, the x of the "P3 line will equal the x of
the "0 line and similarly the y's of both P and Q willi ibe the same. Recalling the above discussion, it is easy to
see that we can find the values of the t parameters of both
the P line and 0 line at the intersection point by setting'S i
the parametric line equations for x and y to be equal and
solve for one of the t values. For example :
IV-22
Z,.A :, ~ W-47 W- V -. -- , '- - .k -- .- q
AFIT/GCS/MA/83D-94
Let x,y be the intersection point on the line of P.
Let x',y' be the intersection point on the line of .i
Then:
S.- x,y =xy
x + t(x -x ) =x ' + t'(x -x '1 2 1 1 2 1
y + t(y - y ) = y , + t'(y ' - y ')1 2 1 1 2 1
Solving for t in both equations we find that :
t iX X + t'(x-x') = y - y + t'(y - y'4 1 1 2 1 1 1 2 1
(x - x (y -y2 1 2 1
Solving the second equality for t' gives:
(x -x ')(y -y ) + (y '-y )(x -x1 1 2 1 1 1 2 1. • te =
*2 (x '-x ')(y-y ) - (y '-y ')(x -x )2 1 2 1 2 1 2 1
.. to is the parameter of where the line of the projected
IV-23q,4'
.4 r''' " , :'.'.'.','. ,., . ... ,-:.". . .,".: ,9F.., .'.,',' ,...v _" ¢ ' 'r. .I .~ I: . . . **" -. .~' !TV, % .r~i 1 !d,\,.,V..%.V , d...-.
AFIT/GCS/MA/83D-9
edge of P (x y -- > x y ) intersects the line of the• 1' 1 2 2
projected edge of Q (x 'y -- > x 'y '). To find t, thei 1.1 2 2
parameter of where the 0 edge intersects the P edge, weisimply use the t' just calculated and substitute it into
equation 1. If the values of both t' and t are between 0
and 1, then the edges of Q and P intersect and overlapi
will occur.
Unfortunately, one polygon may "surround" another
(Figure 6b). In this case none of the edges will actually
intersect, although certainly the inner polygon is
overlapping the area of the larger outer polygon. To handle
this case, the algorithm counts the number of intersections
of the edges of 0 by a line that extends to infinity from4' i
the projected line segment of P. This just requires
counting the number of times t ( the parameter for where
along the P edge the intersection occurs) is greater than 1
and at the same time t' is between 0 and 1 ( the 0 edgei
was intersected). If, when all the edges of Q are checked
against P, this count is odd; then part of P is inside 0i
and overlap has occurred. Because 0 may be "inside" P, ai
similar count is kept for the number of times an extended
Q edge intersects the edges of P. Again, if this count isi
odd when all of the P edges have been processed, then
overlap has occurred.
At this point in the algorithm, we have not been able
to prove that P will not obscure 0 and although the'- i
q' "ordering may be correct, the calculations to prove one way
I -
~IV-24'
V **.>" ~.~**
-'- AFIT/GCS/MA/83D-9
or the other were deemed by the originators to be too
." costly. However, Newell,Newell, and Sancha found during
their evaluation of the algorithm that it was worth the
"- effort at this point to attempt to reorder the placement of
0Q . Therefore, the algorithm performs the reverse of planei
equation tests 4 and 5 to see if 0 is wholly behind P or P
wholly in front of 0 . Although these conditions could have
* been detected during the initial plane equation tests,
their calculations have been delayed until now to prevent
unnecessary calculations. For example, if the first vertex
tested in the first plane test indicates that not all of P
is behind 0 (the first vertex of P is found to be in front
of 0 ), then the rest of the verticies of P could be*.~iexamined to see if they also were in front of Q . However,
if the next plane test (all of 0 is in front of P)
successfully resolves the ambiguity, the calculations done
* to prove the reverse of the first test would have been
wasted.
If, as a result of the reverse tests, it is found that
0 is wholly behind P or P wholly in front of 0 , then 0i i i
is out of order and should be scan converted before P. If
this swap is needed, Q is placed in the linked list behindI
the present P, marked that it has moved, and testing begins
as before using 0 as the new P for comparison purposes.i
The flag signifying that the polygon is moved is
needed because conditions can arise that cause cyclic
- .; overlap of polygons. This occurs when parts of polygons
IV-25
"...................... - ... .at.-a,-.. ,- . . ._,. - - - .. ,.
AFIT/GCS/MA/83D-9
overlap in such a way that no matter what order they are
scan converted, a correct image will not be created. In
this case, swapping would be attempted by the algorithm
* indefinitely to resolve the ambiguity. Therefore, swapping
is permitted only once before polygon splitting will be
accomplished ( there is one exception to this rule which is
described a little later on).
A B P
... a,
x xv v
Fig 7. Cyclic Overlap
Polygon Splitting
If this reordering test fails, then the algorithm
splits one of the two polygons using a method developed by
Sutherland and Hodgman(191. This method involves
. . substitution of each vertex of polygon A into the plane
IV-26
.5... .*.5 .
I I &- L -k I -7 %7 .. ..
AFIT/GCS/MA/83D-9
" equation of polygon B ( same as test for whether a polygon
was in front or behind the other). Points on the positive
side of the plane will be placed in one list of new
vertices and points on the negative side will be placed in
another. Points residing on the splitting plane are placed
in both lists as well as the points created when the
polygon edge intersects the splitting plane. I
. 2' + 2 vertex list vertex list
1 - + - +" i 2
1 2' I 1
2' 2 31 2
4 3' 3' 3 4 4 3
3 4 3' 3 3'
Plane Plane
Fig 8. Polygon Splitting
The splitting algorithm proceeds as follows:
1) Calculate the value of the test vertex of the
polygon substituted into the plane equation of the
splitting plane. If this is the first vertex save this
q" value for later.
2) If the test point is on the plane, place its
coordinates into both the positive and negative side lists..I 2
• . .. .. .. IV-27
71 A --- .7 7 .. 777 7. -
AFIT/GCS/MA/83D-9
3) If the test point does not lie on the plane,
S'then there is a possibility that the line from the last
vertex to this vertex has crossed the plane and further
checking must be done.
a) If the signs of the plane value
calculated during the last iteration and for this
point are different then:
i) Find the intersection of the edge of
Sthe polygon and the splitting plane.
ii) Place this intersection point in
both the positive and negative side lists.
b) Place the test vertex into the positive
or negative vertex list based on the sign of the
plane value.
4) Save the plane value calculated for this test
point for the next iteration, update the counters for
the edge under consideration and go back to 1 until
all vertices have been checked.
5) "Close" the polygon by examining the edge that
runs from the last vertex in the list to the first.
a) If the first vertex or the last vertex is
on the splitting plane, then the lists are
,A01 complete; nothing else needs to be accomplished.
IV-28
AFIT/GCS/MA/83D-9
b) If the first or last vertices are not on
the splitting plane then there is a possibility
that the line from the last vertex to the first
vertex crosses the splitting plane and further
testing is needed.
4If the signs of the plane values of the last
vertex and the first vertex are different, then :
i) Find the intersection point of the
edge of the polygon and the splitting plane.
ii) Place this intersection point in both
Alists of vertices.
After this closing step, there are two separate lists
of polygon vertices that define the parts of the original
polygon found on the positive and negative sides of the
splitting plane.
The one major calculation involved with this splitting
process is the determination of the intersection point of
polygon edges and the splitting plane. To find this point,
geometry and and the parametric equation of a line are
again used in the solution. In addition, the parametric
equation of the splitting plane is used along with the
observation that the intersection of the edge and plane
IV-29
AFIT/GCS/MA/83D-9
must satisfy the parametric line equation for the NDC x,y,
* and z edge of the polygon and also be in the locus of
points that satisfy the splitting plane equation.
This point can be expressed in parametric form as:
x = x + t(x -x1 2 1
y = y + t(y -y1 2 1
z = z + t(z -z1 2 1
The equation of the plane can be expressed as aX + bY
+ cZ + d = 0 . By substituting the x,y,z of the
intersection point above into the plane equation we find :
0
a[x + t(x -x )] + b[y + t(y -y H] + c[z + t(z -z )1 + d = 01 2 1 1 2 1 1 2 1
Solving for t yields:
- (ax + by + cz + d)4 1 1 1
a(x -x ) + b(y -y ) + c(z -z2 1 2 1 2 1
__ This is a very fortunate result, because the numerator
(without the minus sign) was calculated during the previous
IV-30
. . . .. . . . . . . . .. *".h .. . * . .
T. . . . . . .WW VW' .7- -- W V-. V-- 7- 4- -w -V J
AFIT/GCS/MA/83D-9
iteration as the plane value. Additionally, the denominator
" is the plane value calculated this iteration minus the
previous iteration's plane value. We simply solve for t and
then use this value to find the x,y,z of intersection (
e.g. x := x + t(x -x )).intersection 1 2 1
This value of t also has other uses. The CORE allows
the user to define color values associated with each vertex
of the polygon. By varying the color intensities at the
endpoints, the user can implement shading "on top of" the
CORE. Because we are splitting a polygon, new color values
will have to be made for the new points in the vertex list
which were caused by the intersection with the splitting
plane. Otherwise, the shading information will be lost and
improper picture generation will result.
The value of t is simply the percentage of the
distance along the edge from x y z to x y z where the111 222
intersection has occurred. If we consider the red, green,
and blue that make up the color value at each endpoint, we
find that these too can be expressed in terms similar to
that of the parametric value of x, y, and z. For example
consider the red color value as red-intersection := red +
"t(red -red ). Therefore, we can linearly interpolate the
2 1color index information at the original vertices by simply
substituting t into the red, green, and blue equivalence to
the parametric line equations and storing the values
calculated into the color index array.
There are two possible ways in which a polygon can be
IV-31
,7S. C -. -C.. .. . . ., . . . , . . . . . . . . .. . . . . C,, , , . . .
. .. . .- . ... ..HI N H H l ami * H i I-•i~d.SJ /
AFIT/GCS/MA/83D-9
". split. First, a test is made to see if parts of P lie on
.-.. both sides of Q . This test is made by substituting thei
polygon vertices into the plane equation of 0 . To save" i
time, all of the plane values calculated during the plane
* equation tests were saved, so that only if needed will new
plane equation calculations be performed. If parts of P do
lie on both sides of 0, the P polygon is divided by the
plane of 0 . If this fails, we determine if points in 0i i
lie on both sides of P. If so, the 0 polygon is divided byi
the plane of P.
Recall that under normal conditions if a reordering is
attempted on Q but Q has been moved, we will split one ofi i
the polygons. However, there is one exception to this rule.
This exception occurs when a polygon has been moved on ai
previous swap and because of some other ambiguity is now on
the wrong side of P. In addition, P and 0 do not have
points on both sides of each other, so the real problem is
that they are simply reversed in the list and 0 really
should be scan converted before P. The original algorithm
would at this point divide the P polygon in the hope that
by dividing P the ambiguity would be eliminated. However,
in cases used to test the algorithm, it was found that this
type of resolving the ambiguity frequently required
dividing P down to the size of a pixel, once a polygon that
was moved got out of order. Therefore, the algorithm
developed during the research eliminated this type of
polygon splitting altogether and al-lowed polygons that had
IV-32
- -*. .J mU .. ~ ~ Y-~. -' ~ i.~*~
AFIT/GCS/MA/83D-9
been moved to be swapped under the condition that points of
both polygons were only on one side of the other ( the
wrong side).
Placement of Polygon Fragments
Placement of the splitting polygon and the two halves
of the split polygon into the linked list is performed in a
manner somewhat different than the method described in
Newell, Newell, and Sancha's original paper. We propose
that the P polygon is at a position in the list that up to
this point best approximates its relative position to
surrounding polygons. Therefore, if P is split by 0 then
* the original part of P on the back (negative) side of 0
should remain in place and in fact all of the polygons up
to and including 0 in the set of 0 that overlap P in ziextent are correctly ordered. Therefore, I place the
negative vertex list created during the polygon splitting
process into the original P data structure, place the
positive vertex list into a new hidden surface node, insert
this new node into the hidden surface linked list sorted by
z on the front side of Q (ignoring moved polygons), and
set the 0 pointer to the next polygon toward the observer.i
Thus, the part of P on the negative side of 0 remains as
the testing polygon, Q remains in position, and the newi
positive side polygon fragment is placed into a first guess
position in z so that it will be scan converted after 0
i
IV-33
AFIT/GCS/MA/83D-9
-. When the polygon 0 is split by P, a different:-i i
placement of the fragments is needed. The new part of Qi
that was on the positive side of P is inserted into the
hidden surface linked list on the positive side of P,
sorted by z. However, the negative side of 0 must bei
placed directly "behind" P in the list and then must become
.the new P for testing. This movement behind P causes the z
sorting values to be incorrect and therefore requires that
0 be marked as moved. As a last step, the 0 pointer is seti
to point to the polygon next in the list after the old P.
When these steps are complete, the negative part of 0 isi
the new test polygon (P), the old P remains in position,
and the new 0 is placed on the positive side of P, sorted
0 by z.Recall that at hidden surface initialization time we
took the NDC points, performed the image transformation and
stored the new image transformed coordinates in the hidden
surface data structure. During the resolving phase, if we
split a polygon, we split the polygon in the image
transformed coordinates and did not calculate the NDC
coordinates that coorespond to the new split polygon
coordinates. Instead we have intentionally delayed
"binding" the NDC equivalent coordinates to the split
polygon coordinates until the polygon has been completely
resolved. This late binding prevents unnecessary
calculations on polygons that may have to be split more
than once and as required by the CORE, allows the user to
IV-34
AFIT/GCS/MA/83D-9
perform future image transformations on the original
segment he defined, no matter how many times the polygons
v within the segment were split. This calculation of the NDC
space equivalent points is done by calculating the inverse
matrix of the image transformation for the primitive that
was split and then multiplying each point in the hidden
surface structure by this 4X4 matrix to arrive at the
proper NDC values. These values are then stored into the
output primitive data structures for future batches of
updates.
Resolver Pseudo Code
To aid the reader in understanding the entire
resolving process, the following pseudo code is presented:
RESOLVER:
INITIALIZE P,Oi
WHILE PRIMITIVES REMAIN TO BE RESOLVED DO
BEGIN
WHILEQ MAX Z > P MIN Z DO
IF P,Q X OR Y EXTENTS DO NOT OVERLAP THENiQ :=0Q
i i+lELSE IF P BEHIND 0 THEN
0 =i i+l
ELSE IF 0 IN FRONT OF P THEN
• " 0 :=0i i+l
IV-35
AFIT/GCS/MA/83D-9
ELSE IF NO SCREEN OVERLAP P,Q THEN
. ".5 0 ":Q
i i+lELSE IF 0 MOVED THEN
IF POINTS OF P ON BOTH SIDES OF 0 THEN
SPLIT P BY PLANE OF 0iELSE IF POINTS OF 0 ON BOTH SIDES OF P THEN
-:, iSPLIT Q BY PLANE OF Pi
ELSE
BEGIN
MOVE 0 BEHIND P;.i
END
ELSE IF P IN FRONT OF 0 OR 0 BEHIND P THEN
BEGIN
MOVE 0 BEHIND P;
P20
END
ELSE
IF POINTS OF P ON BOTH SIDES OF 0 THEN
SPLIT P BY PLANE OF 0
ELSE IF POINTS OF 0 ON BOTH SIDES OF P THENi
SPLIT 0 BY PLANE OF P
ELSE
ERROR TRAP;
DRAW RESOLVED POLYGON;
IF POLYGON WAS SPLIT THEN
IV-36
:3 7 - r'W - k-LSkj *a .. . . . . ** .** .*. .. - - . .. * . pi -.-
AFIT/GCS/MA/83D-9
CALCULATE NDC POINTS;
.:- Q :=P + 1;.4" i
END;
As a result of scan converting all the polygon faces
in order from back to front,this algorithm will eventually
create a correct image. At this point, one may conclude
that we can conceivably overwrite parts of the screen many
times, and in fact we may perform very expensive polygon
splitting computations on polygons that are eventually
overwritten. This can occur unfortunately, but the tests
are purposely ordered in increasing complexity and the
algorithm spends little time in the more complicated
polygon splitting portion. In fact, Newell, Newell, and
Sancha point out that the time taken for ordering faces "is
largely dependent on how good the initial ordering is. If
few faces intersect this time is usually short, but cases
can arise where it becomes significant."[13:4471 As it
turns out, the bottleneck to this algorithm is the scan
conversion time needed to paint each polygon face.
..Clearly this is a part of the algorithm that can be
isolated and implemented in hardware."[13:447]
This chapter has discussed in detail the hidden
surface algorithm implemented during this research. The
next chapter discusses its usefulness.
IV-37
'C''," %_ " , " " .,.- ' ' k " . ". '""'"""""""" """"" '*.~ .v ; ~ i.V .. ..V..' .| - .
-- - - - * ' .
- AFIT/GCS/MA/83D-9
V Analysis of the Final system
This chapter is devoted to describing the graphics
system created by the merger of the Flight Dynamics
Laboratory's microcomputers, the University of
Pennsylvania's CORE software package, and the Hidden
Surface Removal algorithm. The first section describes the
C: serious limitations on the system caused by the Pascal
MT+86 compiler and linker. The second section briefly
outlines the changes made to the University of Pennsylvania
S software to reduce the data space and computation time used
prior to the invocation of the hidden surface routines.
Finally, this chapter closes with some conclusions reached
about the design of the present implementation and the
overall performance of the algorithm.
Hardware and Support System Capabilities
The single most devastating and complicating
limitation experienced during this research was the 64K
,4 byte limitation on program area length. As mentioned
earlier this caused the need for program overlays and still
only gave the user 18K for application program development.
This is unacceptable for major project use.
In the future, the Flight Dynamics Laboratory wants to
S* < use this system to create complex scenes from a data base
V-1
. ..... 1&,4&i ',ml ,a, -
,Z ., ,. .j ,.s, . .*
AFIT/GCS/MA/83D-9
.* containing many points and geometric figures. The present
4. '-' CORE package is very general in nature and allows the user
to create either perspective or orthogonal 3-D views of
objects. Since the Lab wants perspective views only, the
main routines could be shortened by eliminating the checks
for orthogonal views and associated processing. This would
eliminate rather large chunks of code in the routines used
to create the viewing transformation matrix and perform the
clipping operation. Smaller gains could also be realized in
the hidden surface procedures and the routine used to map
the view volume to the viewport. Additionally, the
initialization routines could be tailored to to set the
initial viewing parameters to an initial 3-D system vs the
standard 2-D viewing system parameter defaults of the CORE.
Finally, many of the CORE error checking features of the
software could be eliminated such as the check for system
initialization in all of the user callable routines.
This approach would result in a system that would not
be CORE standard, would not be for general application, and
would not protect itself from incorrect user input. This
would also defeat one of the main goals of the CORE, namely
transportability of the application programs from one
facility to another. Although undesirable from an academic
point of view, this approach would eliminate several
routines from the device independent overlay, and if
continued into the device dependent overlay area by
eliminating the routines used to support marker,
V-2.
.3 J'. ' [ " , , ,." .. ' - . "-",'. "-'-'-..-..-..- -' ,. '.
AFIT/GCS/MA/83D-9
" * polymarker, and the escape calls of the original package,
would save significant room for application program use.
Another possibility was discovered during a telephone
conversation with software personnel of Digital Research.
They plan within the year to release a new version of their
PASCAL MT+86 compiler that would remove the 64K program
area restriction. This anticipated system would also be
compatible with their C and FORTRAN compilers so that
procedures created under PASCAL,FORTRAN, or C could be
linked together to form a system. The change from the
present overlay defined CORE package to such a system would
require minimal software change, but cannot be counted upon
because of the lack of a firm date of this compiler version*r.
O and the need for graphics now.
Of course, the laboratory could also search for a
different compiler for the 8086 that did not have the 64K464
limitation. If one were found, they would then have to
convert the software from the present MT+86 format to thedPascal of the new compiler. This conversion effort could
take quite a few manhours if the conversion from the VAX
Pascal to MT+86 is any indication.
Alternatively, the laboratory could purchase a more
advanced Graphics display device that performs much or all
of the CORE functions. By offloading the functions to the
device, the present CORE user routines could be modified to
create the interface between the 8086 and the device.
Additionally, the applications programs developed during
V-3
S *I~*. .'*.. .. %. - .%v 4% ~ Z-- . .4.
AFIT/GCS/MA/83D-9
this research could be utilized for the checkout of the
device. Depending on the amount of support given by thesoftware and hardware "on board" , the 8086/8087 user
program area could be substantially increased.
* Other problems were found in the system support
software that are also worthy of mention. First, the Pascal
NEW and DISPOSE procedures of MT+86 do not work properly.
As long as the user asks for "new" memory the system
properly allocates memory space and provides an address for
the user. However, whenever DISPOSE is called, appearently
the linked list of available memory is corrupted and a
subsequent call to NEW will cause an infinite loop. This
problem prevented returning memory area to free space taken
by primitives that were completely clipped by the CLIPPER
subroutine. More importantly, this complication prevented
the deletion of created segments by the user and would not
allow the movement of an eyepoint through a data base of
segments.
An overlay manager problem was also encountered during
the research. Pascal "REAL" functions would not return
proper values in an overlay environment. Finding this error
was difficult because of the correctness of the Pascal code
involved and the natural suspicion that incorrect overlay
external declarations were being used. However, after
displaying values computed inside and passed outside of
real functions, the error was detected and reported to the
.. :compiler manufacturer.
v-4
*4 i ,,=.,[ : .
AFIT/GCS/MA/83D-9
Inclusion of the functions into the driver procedures
was accomplished by either making the functions into
procedures with a return variable (used when more than one
procedure called the function) or by including the function
into the declaration part of the calling procedure. Because
a function would work when included within a calling
module, there is reason to believe that the overlay manager
somehow corrupts the parameter stack when calling real
functions in other modules.
.During the development of the overlay areas, it was
found that symbol table space was needed behind the last
procedure in the overlay for the overlay manager. The
overlay manager used this symbol table to lookup the.4
address of a called procedure within the overlay. Whenever
the size of code within the overlay got within
approximately 3K bytes of the allotted area for the
overlay, the symbol table could be overwritten at read-in
time causing the overlay manager to fail when trying to
find the procedure name. To counter this problem, the MT+86
system had an undocumented system utility called STRIP.With this utility, it was possible to throw away unneeded
symbols for variables and compact the symbol table
considerably. In addition, a record normally containing all
zeros was eliminated at read-in time which again saved
space. Unfortunately, this utility took around 5 minutes to
run each time I changed a procedure in an overlay because
\: ."' STRIP required the manual entry of all procedure names
V-5
.|l
AFIT/GCS/MA/83D-9
within the overlay (overlay 3 had 55 procedures).
• Finally, the Scion graphics display processor
interface did not provide real time picture generation. To
draw polygons, the University of Pennsylvania graphics
package contained a procedure called PPOLY which took a
a list of verticies and performed scan line conversion of the
polygon. In other words, it figured out a list of lines in
y on the screen that when displayed would create the filled
polygon on the screen. In one test, a rectangle that
covered the entire screen was completed in 17 seconds.
University of Pennsylvania Output Pipeline
The original software package delivered by the
University of Pennsylvania was excellent. It was very well
documented, well designed, and was clearly made with the
design concepts and functional specifications of the CORE
standard. Its modularity allowed easy incorporation of the
hidden surface routines and enabled quick determination of
faulty procedures during debugging. However, I made a few
basic changes to the output pipeline to not only save space
but reduce computations on the data, including the
development of a new data representation of polygons, the
incorporation of new perspective viewing procedures, and
the reduction of the error printout routine program size.
The clipping algorithm used in the package is not a
*.. ~ polygon clipper, but rather a 3-D line clipper. To allow
v-6
4,
I - - -. - .p *. * . .-
AFIT/GCS/MA/83D-9
polygons to be clipped to the view volume, the University
of Pennsylvania stored the list of polygon verticies passed
by the user, as a list of line segments with the beginning
and ending points of a line corresponding to an edge of a
polygon. Thus for a triangle of points A,B, and C, six
coordinates would be stored representing the 3 sides (e.g.
points arranged A,B,B,C,C,A representing the edges
A-->B,B-->C,C-->A). This double representation of points
caused both twice the space requirements and twice the
computation of a simple list of polygon verticies.
Each point stored in the primitive data structure was
originally multiplied by a 4x4 viewing transformation
matrix, clipped by setting values outside the viewing
volume to a negative number, then regardless of the
clipping, transformed to the viewport by the window to
viewport maping routine. Inside the actual drawing
routines, a check was finally made to determine if a point
was outside the view volume. If it was not, it was sent to
the polygon scan conversion routine after the final user
defined image transformation. Additionally, each point
could be multiplied by a 4x4 user instancing
4~. transformation, and if perspective views were wanted, a
perspective division was necessary before the viewport
mapping. Because polygon points were stored twice, all of
the processing including the user instancing
transformation, viewing transformation, perspectiveS-
.' . division, and window to viewport mapping were accomplished
v-7
AFIT/GCS/MA/83D-9
twice per point, which was deemed an unacceptable waste of
CPU time.
Therefore, the user callable polygon routine (POLYA3)
was modified to store the list of verticies exactly as
given by the user, one point per vertex. Thus the user and
viewing transformations were accomplished only once per
point. The clipping routine was then modified to create a
temporary area that placed the transformed points in the
original double storage format. The main clipping procedure
remained the same and then a procedure was added to the
output side of clipper to eliminate points culled during
the clipping process. Thus, only relevant points were
passed down the pipeline for the perspective division and
window to viewport mapping routines. If the whole primitive
was clipped, a call to DISPOSE to free the primitive data
area was incorporated into the code, but as mentioned
earlier because DISPOSE was not functioning properly, this
call was commented out. Overall, in addition to the
computation savings, this polygon representation change
halved the space needed to store the coordinates.
Unfortunately, the original package sent early in the
research had some problems with perspective views of
scenes. The orthogonal worked properly, but because the
laboratory needed perspective views, a dilemma was created.
Professor Badler of the University of Pennsylvania was more
than helpful and near the end of the research sent to us a
working perspective CORE package. Because the orthoganal
V-8
AFIT/GCS/MA/83D-9
was working, I was able to work out the major bugs in my
subroutines before the update arrived.
Incorporation of the new version was never fully
accomplished because it was at this critical hour that the
problems with real functions started as a result of the
overlays. Early tests with the changes indicated that the y
A coordinates being generated were improper and after some
time insuring that the new code was properly inserted,
these changes had to be abandoned. Fortunately, in earlier
course work perspective routines had been developed and
after these were incorporated, research continued.
Finally, the original University of Pennsylvania
sortware had an extensive error printout routine that had
textual descriptions of errors found during operation of
the CORE. Although fantastic for debugging, this routine
(because of the many output strings) took up too much room
for use on our system. Therefore, its function was reduced
to merely printing out an error number and procedure name.
When errors occured, the original listing of the procedure
had to be consulted to find out what error had occured.
Although more time consuming, this was the only feasible
alternative.
The Aloorithm
The Newell, Newell, and Sancha approach to rendering
Scorrect images on the screen can be characterized by three
V-9
AFIT/GCS/MA/83D-9
distinct phases of operation. The first, the initial
sorting phase, takes a list of polygons and orders them by
their maximum z . Second, a resolving step takes this
initial estimate of the correct "painting" order and
eliminates conflicts between objects. Finally, after a
polygons's conflicts have been resolved, a process is
needed to convert the description of the polygon into a
physical display on some device. This section will comment
on the results of my research on the first two functions of
the algorithm (many hardware devices perform the last
function).
Sorting
My initial attempt at creating the data structures and
procedures to operate upon them centered around simplicity
of function so that an acceptable algorithm testbed could
be developed in minimal time. One area that truely suffered
from this approach was the initial sorting step. In
retrospect, this part of the implementation needs serious
thought and further research to produce a better first
guess ordering of the polygons.
First of all, a wrong assumption was made that the
user would most probably add polygons in groups that would
be close to one another in a linked list. Therefore, the
SORTER routine created a doubly linked list structure and
maintained a pointer to the the last polygon inserted into
v-10
AFIT/GCS/MA/83D-9
the list. If the merging entry had a maximum z greater than
' the last entry, SORTER searched backwards in the list
(further from the eye) until a proper place was found for
the merging entry. In the same way, upon finding a merging
entry with a maximum z less than the last entry, SORTER
went forward until a place in the list was found. This
search was known not to be as efficient as a binary search,
but it was rationalized that because of the clustering
V effect of incoming entries, it would be acceptable..4
Long searches were found however, when objects were
defined front to back. This resulted from having to search
through groups of polygons that shared the same z, such as
"' groups of terrain polygons. One reasonable approach to
* 0 solving this problem would be to store the merging polygon
entries in a binary tree structure rather than the present.4
singlely linked list. By performing an inorder traversal of
the tree, the doubly linked list needed during the
resolving phase could quickly be made for the first frame.
Subsequent batches of inserts could also be ordered in a
tree and then a one time inorder traversal of the tree
while scanning from back to front in the hidden surface
linked list would place the incoming polygons in their
proper positions. This would make a tremendous savings of
time in the first sort, and may indeed save time in
subsequent batches of updates.
As noted by (20:411, additional information as to the
k Y sorted x,y position of polygons could be added to the
V-li
...4 x m .m ':€ . L ' T
4L %Tq.. z T . Lt K- Ct 4 W-. "C .. . S.- * S *.i
AFIT/GCS/MA/83D-9
hidden surface structure to cut down on these unneeded
comparisons. In addition, a totally different scan line
algorithm could be made using a y bucket sort for each scan
line followed by the Newell, Newell, and Sancha resolving
process for z ambiguities, terminating in a final x bubble
sort[20:41,21. This new algorithm could use large chunks of
the present algorithm but would definitely need new data
structures.
Resolving
The following table contains a profile of the number
of times the major algorithm tests were peformed on four
different scenes (Figure 9):
V-12
*" *. - a "-S , ~ * * " " S'.-',' -.. . • - ' . . - -.- .. .. z. .-.. x-. , . ~.... "..
AFIT/GCS/MA/83D-9
i.Y
A 0
.Fig 9. Test Scenes
V-13
, U,
4 m
- ~ ~ ~ ~ 17 17' io WV- 1 1-. t.. .**...
AFIT/GCS/MA/83D-9
Table I
Algorithm Performance In Four Scenes
1 2 3 4
Beginning # of polygons 34 35 236 236
ending # of polygons 34 64 237 278
# of xy extent tests 2791 6751 37131 45621
# of P behind Q tests 154 12081 312 1540
# of 0 in front P tests 26 11211 59 1341
# screen overlap tests 8 51 27 189
# reoderings attempted 6 44 12 80
# swaps performed 6 15 11 43
# polygon splits 0 29 1 42
It is obvious that the algorithm performs many more
tests for x,y extent than any other. This was expected and
in fact hoped for. However, this large number also reveals
that each polygon is being compared against polygons that
could have been eliminated by some previous x or y sorting
scheme. As noted by [20:411, additional information as to
the sorted x,y position of polygons could be added to the
hidden surface structure to cut down on these unneeded
comparisons. In addition, a totally different scan line
algorithm could be made using a y bucket sort for each scan
line followed by the Newell, Newell, and Sancha resolving
V-14
I'.
AFIT/GCS/MA/83D-9
process for z ambiguities, terminating in a final x bubble
•. "sort[20:41,21. This new algorithm could use large chunks of
the present algorithm but would definitely need new data
structures.
Additionally, it can be seen that there is a
significant increase in the number of tests required to
resolve a scene with overlaping polygons vs a scene without
Aoverlap. This is due in part to the fact that there are
more polygons that have to be resolved as well as the fact
that whenever we have to split 0 by P, we will have toi
perform the x,y extent and other tests on the half of Qi
placed behind P as well as reperform the tests for P.
The plane equation tests for P behind 0 and Q ini i
front of P drastically reduce the amount of unresolved
polygons with their effectiveness highly dependant upon the
existance of penetrating polygons. In the two simple scenes
* (1 and 3), they reduce the number of unresolved polygons by
at least a factor of 7 and in the overlapping scenes, by
afactors of around 4 and 3. This is of course explained by
the fact that penetrating polygons will have points on both
sides of the plane. Because a significant amount of
- processing is done to resolve polygons using the plane
equations (3 floating point multiplications and additions
per vertex of P and 0 if it takes both tests to resolve* i
the ambiguity) this is definitely one routine that should
be coded in assembly language. Because the indexing is
2. Y~' straight forward and the plane equation coefficients remain
V-15
AFIT/GCS/MA/83D-9
the same from iteration to iteration, an assembly level
programmer should be able to save many steps needed by the
more general Pascal compiled version.
The screen overlap test is expensive. First from a
-4 computational point of view, it takes 5 floating point
multiplications, 2 floating point divisions, 2 floating
point additions, and 1 floating point subtraction to
-- compare one P edge to one Q edge. Considering that a totali
of P edges X 0 edges X (5 multiplications, 2 divisions, 2i
additions, and a subtraction) calculations will be needed
to prove P and Q don't overlap, it is easy to see that ai
search for an easier scan overlap test is in order. Indeed,
the only thing that prevents this test from having a larger
impact is the fact that only a few ambiguities remain. Of
course at a minimum this should be placed into assembly
language.
During research, it was noted that although swapping
seemed like a very cost effective way to resolve ambiguity,
it had a higher cost than expected. First of course, by
moving a polygon in the list, complications arise because
we ignore "moved" polygons in our sorting and placement
routines. Conceivably, we could reorder many polygons over
time when the user does many batches of updates with a
different view point. Thus the first guess approximation
sort would become less and less effective. This is
definitely an item of further research.
' Second, it was noted that when swapping occ',rs, many
V-16
.A ' - .-. ."""".0" .. ". " . - "- ' .". " " - "-- .- ".-.' -.
mb-A18 239 PLACING HIDDEN SURFACE REMOVAL WITHIN THE CORE GRAPHICS 2/2STANDARD- AN EXAI9PLE(U) AIR FORCE INST OF TECHWRIGHT-PATTERSON AFB OH SCHOOL OF ENGI. . T S WAILES
NCASIFIED 8? DEC 83 AFIT/GCS/MR/8-3D-9 F/G 912 NEhhLS mo soonlossmoIEhhhhohhhhhhhIsmhhhhhmhhhhhEonhSEEhhhhhEEhhhhohhEmhhhIEND
I~~. 711.'.- 7
1118112.......1.-22
IIIII I--Ip1.25 111._4 11.6
MICROCOPY RESOLUTION TEST CHARTNATONAL BUREAU OF STANDARDS-1963-A
7.',.
AFIT/GCS/MA/83D-9
ambiguity checking steps are going to be repeated. Recall
• .that the swapped polygon is placed behind the present P in
the list and becomes the new P test polygon. If this
arrangement results in the new P being resolved, then the P
pointer is advanced forward to the old P and its testing
begins once again. All the comparisons up to the old
swapped 0 position will be repeated and if many polygonsi
overlap P in z, this can be significant.
Polygon splitting is expensive both in computation
time and data structure space. First the equivalent of the
plane test is going to be performed on the vertices of the
2 polygon being split. Presently, the algorithm does not take
advantage of this fact, and any plane value computation
time taken in the main resolver program will be repeated in
the polygon splitting procedure. Additionally, the
calculation of the intersection of the polygon edge and
splitting plane is going to take 7 floating point
multiplications, 1 floating point division, and 6 floating
point additions for each time an edge traverses from one
side of the plane to the other.
* SThese computation times appear to be less than that
caused by checking for scan overlap, however remember that
each time we split a polygon, we must perform the image
transformtion, and completely resolve it; perhaps involving
the comparison of many other polygons. Finally, each
additional polygon created requires us to make not only
another hidden surface node but another primitive "host"
V-17
: ,, . ..-.- . .- . q v. d .-j. U'. J' a' . J : P j .p '7' 97'V a' * : :
AFIT/GCS/MA/83D-9
node as well. If the user creates a large scene that has
many penetrating polygons, the additional space
requirements may exceed his available memory. Generality
does not come without cost.
Computational Cost of the Algorithm
Perhaps, the best way to model the computational cost
and performance of this algorithm is to ponder the way
polygons are culled from consideration. All polygons that
overlap the test polygon will at least be tested in the
extent tests. This isolates the test polygon's further
testing to those polygons lying in a cube formed by the x,y
Vand z extent box. The first plane test culls those polygons
9on the front side of the test polygon only and reduces the
Vpossible area of conflict to the "back" side of the extent
cube. The second plane test divides the extent cube by the
plane of 0 and if all of P resides in the negative side of
that portion of the box then the ambiguity is resolved. The
scan overlap test basically is assuming that the polygons
.* are somehow out of order, but if they can be scan coverted
without disturbing the finished image, the present ordering
is okay. The test for swapping again assumes that they are
out of order and attempts to prove the same. If they cannot
be swapped, then a polygon splitting will have to be made
to resolve the conflict (almost always caused by
penetrating polygons).
~V-18
M -3 3 -W sr-M --- .3 AU -3 Vb .37MATY-17.) . -- 3 A -7- -Z' -.X --- -. 7, 77 -7~
AFIT/GCS/MA/83D-9
Thus, it can be said that this algorithm is going to
perform relative to the geometric complexity of the
generated scene not its visual complexity. If the user
specifies a scene consisting of 1000 polygons with the last
polygon overwriting all the others, it will not take
advantage of the visual coherence of the scene (e.g. that
the last polygon is the only one that needs to be
displayed). Instead, it will systematically resolve the
scene back to front until all polygons have been displayed.
Now that the graphics system and hidden surface
algorithm have been analyzed, it is time to summarize the
proposals mentioned in this thesis.
V-19ie - l
AFIT/GCS/MA/83D-9
* VI Conclusions and Recommendations
This paper has documented the design and development
of a hidden surface algorithm and its integration into the
CORE graphics standard. Many improvements to the system
were presented throughout the work and therefore the
purpose of this chapter is to place all these
recommendations and conclusions in one area for' those
interested in pursuing research using this algorithm and
those wanting to improve its present implementaion.
First, this chapter outlines the changes needed to
make the current software package completely conform to the
CORE graphics standard (recall that in chapter one the
problem was limited to creating a polygon processing
algorithm for raster type devices). Then a section
describes the areas of further research that could
conceivably result in a more efficient algorithm
implementation. Finally, a general course of action is
recommended for the Flight Dynamics Laboratory.
Makina the Aloorithm Standard
There are four basic limitations on the present
implementation that make it non standard: it only supports
raster type displays, it does not perform hidden line
removal, it only presently resolves polygons, and it does
VI-'
V 4
AFIT/GCS/MA/83D-9
not support all hidden surface levels of the CORE standard.
This section will describe the needed changes to allow all
of these improvements.
The simplest way to incorporate both support for
calligraphic displays and hidden line removal would be to
use the sorting and resolving steps of the present
algorithm as a prelude to the Watkins or a similar type
scan line algorithm. The only changes needed in the present
routines would be the deletion of the call to the scan line
converter in the main resolving subroutine and in its place
the addition of code to save the priority number of each
polygon. The present data structure would have to be
changed to incorporate the priority number, and the Watkins
0y bucket sort linked list and active segment linked list
data structures would have to be created. Of course the
major work would be to design the actual algorithm that
would use the results of the Newell, Newell, and Sancha
algorithm to create the displays.
This approach could well be unacceptable because of
the additional data structure space needed by the new
routine and the additional computations on top of the
Newell, Newell, and Sancha algorithm. An alternative to
this approach will be discussed in the section on further
research.The changes needed for extending the algorithm to
process the line, polyline, marker, polymarker, and text
* primitives simply involves the addition of logic in the
VI-2
AFIT/GCS/MA/83D-9
main resolver routine. The marker and polymarker primitives
would simply be treated as points in space. Using the depth
sort process we would simply draw these objects at their
proper depth priority and let objects closer to the eye
overwrite them if needed ( for the calligraphic type
displays their priority order will determine if they are
displayed). Lines will simply require additional checks to
determine if intersections occur with polygons. If an
intersection does occur the line will be divided at the
point of intersection and the two line halves and the
polygon will be ordered and inserted in the hidden surface
linked list and output primitive data structures. Polylines
will be considered as collections of individual line
0segments for this processing. Finally, text primitives willsimply be treated as 3-D rectangular polygons that are
defined by the extent box surrounding the strings of
characters. Obviously, the plane equation tests and scan
overlap tests would have to include different logic to
process these other cases, but the logic required is
straight forward and most of the algorithm would remain the
same.
Perhaps, the easiest change to make is the logic to
allow all four levels of hidden surface removal (none,
temporal, explicit, and full). Level 1 simply means no
effort is taken by the package to order the user's output
primitives. To implement level 2, the present placement of
primitives within the segment primitive linked list would
VI-3
r ' ' ," ', ,-.- .- - - - -,- , , .. .. , .. -. ,- .... .. , . ,, ,
AFIT/GCS/MA/83D-9
require a slight modification.
Level 2 or temporal priority, requires that primitives
are displayed in the same order as they were created by the1 user. The University of Pennsylvania CORE routines
currently add primitives such that they end up in reverse
order from that given by the user. By simply adding a
pointer to the last primitive added to the presently open
segment and using this pointer to insert primitives, level
2 could be easily accommodated.
Although the current implementation of the algorithm
would support level 3, many of the present hidden surface
initialization calculations are not needed in level 3.
Therefore, it would be best to create an additional hidden
0surface sorting routine and, to save space, create a new
binary tree structure. All the new sorting routine would
have to do is maintain a binary tree structure that ordered
the primitives by z (priority). After all incoming
primitives were placed into the tree, an inorder traversal
of the structure would produce the correct rendering of the
scene. The tree data structure would only require the
storage of the z (priority) given by the user, the image
transformed coordinates, and three pointers (one back to
the host primitive, two for the left and right branches of
the tree structure). This would save the memory area
presently taken by the x,y, and z extents, the plane
equation coefficients, and the Boolean flags used in the
present hidden surface node data structure.
VI-4
AFIT/GCS/MA/83D-9
Items of Future Research
During the the debugging of the algorithm, I was able
to watch as the procedures resolved scene ambiguity and
noted several items that need to be investigated further.
This section discusses these items, first outlining the
changes that would make the present implementation more
efficient and then discussing the areas in which new ideas
are necessary.
As mentioned earlier one important improvement would
be the incorporation of a binary tree structure to order
incoming primitives before the main resolving process
begins. The initial ordering is a very important part of
the algorithm and on the first batch of updates can be a
significant component of the time needed to create the
image. Additionally, a reduction in the time needed to
split polygons could be realized by taking advantage of the
plane values already calculated as part of the plane
equation and reordering tests. By making these available to
the polygon splitting routine, the present duplication of
calculations could be avoided. Finally, an improvement canbe realized by placing the plane equation and scan overlap
tests in assembly language. As a start, the Pascal MT+86
compiler provides an assembly code printout of each line as
it is compiling. An assembly code programmer could easily
use this printout as a first cut, and with proper knowledge
of the data structures and the goal of each procedure, cut
VI-5
AFIT/GCS/MA/83D-9
corners that a general purpose compiler simply cannot.
Further testing is needed to determine the effect of
swapping during many batches of updates. It is conceivable
that the number of moved polygons could quickly climb if
the initial ordering of polygons is improper due to the
ignoring of moved polygons when placing primitives into the
linked list. This feeding of the problem upon itself could
result in a list that spent a large part of its time
swapping primitives. This could be detected simply by
keeping track of the present number of swapped polygons,
and one solution would be to resort the list by z after a
threshold of moved polygons existed. This may not really be
a problem, but it certainly must be examined.
The present scan overlap test takes quite a few
calculations to prove that one polygon does not overlap
another. A more computationally effective method could in
itself be the topic of research as this is not the only
hidden surface algorithm that uses this kind of surrounder
test. Additionally, during research it was noted thatswapping caused duplicate calculations because polygons up
to the polygon causing the swap are recompared in the
present implementation. If some way could be developed to
save the set of polygons already compared such that when
the swapped polygon was resolved the old P could continue
where it left off, a number of comparisons could
conceivably be saved.
" *" The most exciting area of research, of course, would
VI-6
* .'* .*
AFIT/GCS/MA/83D-9
be to use the existing routines in a totally new way to
come up with a new algorithm altogether. As mentioned
before this new algorithm would combine the ideas of scan
line algorithms and the Newell, Newell, and Sancha
resolving process to make a hybrid algorithm that took
advantage of the strong points of each. The new algorithm
would first sort the primitives using a y bucket sort
placing the primitives into buckets that corresponded to
the y scan line they first appeared ( going from top to
bottom). We would then start the normal scan line type
processing of creating spans of polygons. The present
resolver procedure would be used to order the list in z as
each primitive entered the active edge list.
to.. Because newly-entering faces are added
to a list from the previous scan line which is
already in order, depth coherence from scan line
to scan line can be preserved. Newell's sort is
thus simplified to finding an appropriate
position in the priority list for each
newly-entering face."
"The final X sorting step would make full
use of the scan-line coherence properties
familiar in the other algorithms. X intercepts
woul(' be computed incrementally, and kept in X
irr by a bubble sort. When depth computations
4.
• are required, a simple test of priority number
VI-7
q%
AFIT/GCS/MA/83D-9
would suffice. One would make use of scan-line
depth coherence by remembering which segments are
visible from scan line to scan line and by
repeating a visible segment if no edge crossing
had occurred involving one of its visible edges.
Note that penetration will have been resolved for
entire faces during the Z sort
process."[20:41,42]
Because the z resolving steps are already in place,
the development of this proposed algorithm and its
comparison in performance to the present algorithm would
make an excellent topic for further research.
Recommendation
Further graphics research and future graphics
application programs will be significantly hampered by the
present 64K byte program area restriction of Pascal MT+86.
Therefore, the most reasonable course of action would be to
save the present system source programs on floppy discs
(for future use if the size restriction is lifted) and then
modify the programs to reduce their generality. Then as
development continues, search for a multitude'of software
and hardware options to increase the application program
area size. This will provide some graphics research in the
near term (perhaps implementing some of the above mentioned
VI-8
AFIT/GCS/MA/83D-9
suggestions) and if a suitable compiler, advanced display
processor, or if a future version of Pascal MT+86 allows
more user space, a full research capability in the long
run.
° .'
S' \S %'"
, .4
vI-
is.,
'p 5 4. . % s - °
i ~ , .
, -!
.%~. . .. *. ~ '*s *-% s'i, ,xA .mA.
AFIT/GCS/MA/83D-9
Bibliography
1. Artzy, E. and G.T. Herman. "The Theory, Design,Implementation, and Evaluation of a Three-DimensionalSurface Detection Algorithm," Computer Graphics 14(3): 2-9 (July 1980).
2. Boinodiris, S. "Hidden Surface Elimination for ComplexGraphical Scenes," Computer Graphics 14: 153-167(March 1981).
3. Brown, C.M. "Fast Display of Well-TesselatedSurfaces," Computers and Graphics 4 (2): 77-85 (1979).
4. Fuch, H., Z.M. Kedem, and B.F. Naylor. "On VisibleSurface Generation by a Priori Tree Structures,"Computer Graphics 14 (3): 124-133 (July 1980).
5. Goad, Chris. "Special Purpose Automatic Programmingfor Hidden Surface Elimination," Computer Graphics 16:167-178 (July 1982).
6. Hamlin, G. and C. Gear. "Raster-Scan Hidden SurfaceAlgorithm Techniques," Interactive Computer Graphics ,an IEEE Tutorial from COMPCON 80, San Francisco,0264-271.
7. Hedgley, David R. Jr. "A General Solution to theHidden-Line Problem", Report from the Ames ResearchCenter, Dryden Flight Research Facility, EdwardsCalifornia, Nov 1981.
8. Hornung, Christoph. "An Approach to a Calculation-Minimized Hidden Line Algorithm," Eurographics '81,Proceedings of the International Conference andExhibition, 31-42.
9. Hubschman, H. and S. Zucker. "Frame-to-Frame Coherenceand the Hidden Surface Computation: Constraints for aConvex World," Computer Graphics 15 (3): 45-54 (August1981).
10. Knowlton, K. and L. Cherry. "ATOMS-- A Three-D OpaqueMolecular System for Color Pictures of Space-Fillingor Ball-and-Stick Models," Computers and Chemistry 1:161-166 (1977).
' 11. Laib, G., R. Puk, and G. Stowell. "Integrating SolidImage Capability Into a General Purpose CalligraphicGraphics Package," Computer Graphics 14 (3): 79-85
. (July 1980).
BIB-i
AFIT/GCS/MA/83D-9
12. Myers, A. "An Efficient Algorithm for Computeri Generated Pictures," Ohio State University Computer
Res. Group, 1975.
13. Newell,M.E., R.G. Newell, and T.L. Sancha "A Solutionto the Hidden Surface Problem," Proceedings of the ACMNational Conference (1972), 443-450.
14. Reising, John M. and Carol Jean Kopala. "CockpitApplications of Computer Graphics." Report for Harvard
.* Computer Graphics Week, Harvard University, GraduateSchool of Design, 1982.
15. Rubin, S. and T. Whitted. "A Three-DimensionalRepresentation for Fast Rendering of Complex Scenes,"Computer Graphics 14 (3): 110-116 (July 1980).
16. "Status Report of the Graphics Standards PlanningCommittee," Computer Graphics, 13 (3): (August 1979).
17. Stein, Kenneth J. "Technical Survey: AdvancedEngineering Simulators, Computer Models Cut USAF TestCosts," Aviation Week & Space Technology, 118 (3):77-79 (January 17, I-3).
18. Stluka, Federick P. et al. "Overview of the University
of Pennsylvania CORE System Standard Graphics PackageImplementation," Computer Graphics, 16 (2): 177-86(June 1982).
19. Sutherland, I.E., and G.W. Hodgman, "Reentrant PolygonClipping," Communications of the ACM 17 (1): 32-42(January 1974).
20. Sutherland, I.E., R.F. Sproul, and R.A. Schumacker. "ACharacterization of Ten Hidden Surface Algorithms,"Computing Surveys 6 (1): 1-55 (March 1974).
21. Watkins, G.S. "A Real Time Visible Surface Algorithm,"University of Utah Computer Science Department,UTECH-CSc-70-101 (1970).
%
~BIB-2
U9.* .".'- -.*. .".. ., ..'. . ..9L """,'.'v ... , " ',9, ,, -,.. 9. .." "."-'
-r.61 r 4- -- * -... v- JI-YV . w .
AFIT/GCS/MA/83D-9
tAppendix A
Pascal Source Code
(* Date: 4 Dec 83(* Version : 1.0(* Name: Resolver
(* Module Number: 5.2(* Function:(* This procedure is the driver routine for resolving the sorted(* list made by the sort procedure. Its algorithm is based on the *)(* Newell, Newell, and Sancha method described in " A Solution to *)(* the Hidden Surface Problem," Proceedings of the ACM National(* Conference, Boston, pgs 443-450 (August 1972). It basically will *)
o(* are a face P against all other faces 0 contained in the set *)(* of faces that overlap P in z extent. As soon as we have resolved *)(* all conflicts either by testing x,y screen extents, the positions *)(* of P and 0 relative to each other using plane equations, the(* actual screen drawings of all the lines of P and Q, or at last *)(* resort splitting P or 0; we scan convert P the furthest face from *)(* the eyepoint. By systematically scan converting from back to(* front, we will create the correct picture. This method is(* sometimes referred to as a painter's algorithm because like an(* artist we will paint and overwrite to create the final picture. *)(*Inputs: None.
* Outputs: None.-I. (* Global Variables Used: Hiddenlist (hidden surface node pointer) *)
The Hidden Surface Linked List Structure *)(* Global Variables Changed: None.(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.(* Modules Called: Polysplit.
I (* Funnel (places primitives on the screen).Newframedd (clears the screen).Matrix Multiply (performs 1X4 * 4X4 matrix mult *)Make Invert Matrix (creates inverse matrix of *)
image transformation(* Calling Modules: EndBatch ofUpdates.
*Author: Tam S. Wailes, Capt, USAF(* History: This is the original module
Module RSOLVER;
const...-7- [$I defconst.srclP (*EOC end of const section *)
type
A-1
-:o
AFIT/GCS/S4/83D-9
'$I deftype.srcl. (*EOT end of type section *)
var[$I extvar.srcl(*EOV end of var section *)
(MDOP beginning of procedures and functions *)EXTEIAL [3] PROCEDURE POLY SPLIT(VAR poly : LINKPTR; VAR spit : LINKPR;
,de : SPLITIYPE);EXTERNA [3] PROCEDURE NEF1MD;
I.ERKAL [3] PROCEDURE FU,4EL(pt : PRIM PTR);E IAL PROCEDRE MAXEINVAT (TFORM: MATRIX;VAR INVMAT: RARRAY4X4);EXE1NAL PROCEDURE MATRIX ML(A: VECTOR4; B: RARRAY4X4; C: VECTOR4);(*EOP end of procedures and functions *)
procedure RESOLVER;
coflsteps = 0.000000001; (* close enough to zero for testing *)
(* needed because of computer round off *)
position = (behind,infront);
varswap,splitp, split_q • boolean;p.face,q_face,I,psides,qsides : integer;P,Q : LINKPTR;scren x,screny : IARRAY;transmat : RARRAY4x4;vec : VECICR4;p values,qvalues : RARRAY;
.-
.3.A-
1 K7,
AFIT/GCS/MA/83D-9
function planetest(sides: INTEGER;VAR face: INTEGER;VAR value: RARRAY;
A : (INKP*R; SIGN : POSITION; B : LINKPTR): BOOLEAN *
(* Date: 4 Dec 83
(* Version : 1.0(* Name: Plane Test(* Function:(* This function tests the relative position of a primitive by substi- *)(* tuting the points of A into the plane equations of B. If all points *)
are on the side of the sign then true is returned, else a false value*)(* will be returned, with the number of sides compared in face. The user*)
* (* sets face prior to the call to prevent uneeded multiplications when *)(*performing the reversal tests in the last checks before spliting(* Inputs: sides (number of sides of the polygon)
face (number of sides already tested)A ( pointer to the polygon)sign (flag that determines if testing in front or behind *)
the plane )B (pointer to plane)
(* Outputs: face (number of sides tested)(* Value (array of plane values calculated)
Boolean value of whether the polygon was on the right side *)of the plane
(* Global Variables Used: Eps (allowance for roundoff)(* Global Variables Changed: None.(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.(* Modules Called: None.(* Calling Modules: Resolver.
-~ (* Author: Tom S. Wailes, Capt, USAF(* History: This is the original module
begincase sign ofin front:
Beginrepeat
face : face + 1;(*plane equation is Ax + By + Cz + D 0(* all points that satisfy this equation are in the plane *)(* that has the the coefficients A,B,C, and D(*if Ax + By + Cz + D <> 0 then the sign of the value *)(* tells us which side of the plane the point is located *)
'4 .. (* if a point in A when substituted into the plane of B *)(* results in a positive value, then the point is in front *)
value[face] : ( B^.planea * A'.hidden.x_coortface) +
A-3
AFIT/GCS/MA/83D-9
( B^.plane b * A.hidden y-coor[facel) +. ( 8 .plane--c *A:.hidden-z-coor[face]) +
B'.plane-d;until ((value[face] + eps < OT or (face >= sides));
PLANE TEST :- value(facel + eps >- 0; (* set return value *)end;
behind :begin
repeatface : face + 1;
(" substitute the coordinates of A into the plane of B "1(* if the plane value is always negative then A is behind *)
value[face] := ( B .plans a * A^.hidden x coortface]) +B.plane_- * A^.hidden"Y-coor[face]) +B^.planec * A'.hidden z_coor(face]) +r. plane d;
until ((valuetface] - eps > U) or ( face >= sides));
PLANE TEST : value[face] - eps <= 0; (* set return values *)end; (* hind *)
end; (* case *)end; (* of planetest *)
A-4
- W-.t. .* . **
AFIT/GCS/A/83D-9
function SCREENOVERLAP( P : linkptr; sides_p : integer;0 : linkptr; sides q : integer): boolean;
(* Date: 4 Dec 83(* Version : 1.0(* Name: ScreenOverlap.
° . (* Function:(This function tests for the actual overlap on the screen of the lines*)comprising the edges of the polygons. This is done by calculating "1
(* the parametric line equation constant T for the intersection of each *).4 (* P edge and Q edge. If the T value for both the P and 0 edges are *)
(*between 0 and I then an overlap has occured and the polygons will *)(* have to be split. Additionally if a edge of P when extended in both *)(* directions splits only an odd number of the sides of 0 then overlap *)(* will also occur.(* Inputs: P, 0 (pointers to the polygons to be checked)
sidesp,sidesq (number of sides to the polygons)(* Outputs: Boolean value of whether there is screen overlap(* Global Variables Used: View State projection type (parallel or *)
perspective) *)(* Global Variables Changed: None.(* Global Tables Used: None.(* Global Tables Changed: None.
F(* iles Read: None.O (* Files Written: None.(* Modules Called: None.(* Calling Modules: Resolver.
(* Author: Tom S. Wailes, Capt, USAF(* History: This is the original module
varoverlap : boolean;i,plp2,ql,q2,Q_count : integer;P count : IARRAY;ox_coorQj poor : RARRAY;p deltax,pdeltajy,TTprme : real;P_xlP_x2,P yl,PV2,0Qxl,Q_ 2 ,0. yl,OQy 2 : real;
beginpl:- I;p2: 2;for i := 1 to sidesq do (* initialize the number of times that *)
P count[i] :- 0; (*0 rosed the edges of P.
(Save multiple calculations of the P and 0 screen coordinates if *(* perspective projection is requested *)
if view state.pjtyp - 2 then (*perspective projection *)begiA
A-5
4(~ **% %VV.\ ~ ' V ~ *%*~,*4 * 4
AFIT/GCSAIA/83D-9-.'
*: ,,' P x2 := P .hidden_x_coorfl]/P .hidden w coor(l]; (* init first *)","V' P-_2 : P-.hiddencoor[l/P-.hidden-w-coor[l]; (* P edge val *)
for i:= 1 to sidesq do (* calculate all 0 edge values *)beginQ x coort[il G.hidden x coor[i]/J .hidden w coor[i];Qyco7r_ ]" Qp.hiddeny_coor[i ]/O.hiddenw.coor(il;
end;end
else 1" parallel case,4 begin
P x2 : P-.hiddenx coor[l]; (* init first P edge value *)P-y2 := P'.hidden y coor[l];
for i:- 1 to sides_q do (* store all 0 edge val for parallel *)begin0_x_coortiJ - Q'.hidden x coor[i];0ey-coor[i] - oQ.hidden-Y-coor[i];
end;
overlap :- false;while (( not overlap) and ( pl <- sides.y )) do (* test all faces *)begin (* in Pql := 1; (* initialize the q pointers for each P face *)q2 -=2;QOcount :- 0; * init the counter that determine how many *)
(* times a P side intersects the a Q polygon edges*)(* If ever a side intersects an odd # of times *)(* overlap has certainly occured *)
P xl :nPx2; (*set the P edge beginning point to the last*)4. Pyl "- Pj 2 ; (* point coordinate checked *)
(* calculate the ending point of the edge if needed *)
if view state.pjtyp - 2 then (*perspective projection *)begin
P x2 .= P.hidden_x_coor(p2]/P .hidden_w_coor[p2 ;Py2 : P^. hiddenyqcoor [p2]/P-. hidden, _coor [p2 1;
endelse (* parallel case
beginP x2 - P'.hidden_x_coor[p2];
e• ' 2 " P " hidden -ycoor [p2] ;
(* save duplication of ccznputation of *)(* the change in x and y for each P face *)
p delta x P x2 - P xl;pjdeltay :m Pj2 - Pjrl;
while (( not overlap) and ( ql <- sides q)) do (* for each P face *)begin
A-6
Em4
AFIT/GCS/MA/83D-9
-x :O xcoor[ql];0x2 := Q_x_coor[q2] ;Q yl " ycoor[ql];0 y2 • ycoor[q2];
Tprimn -= ((( P xl - 0 xl) * p deltaj)+ T( oyf7- Pyl)-* p deltax))/ ((C x2 - 0 xl) * pdelta y)
-( Q_2 - Qyl) * p deltax));
T .= (xl -PXl+ (irri. * T _x2 -0_xl)/ pdelta_x;
if (( Tprime < 1) and (Tprime >0)) thenif (( T < 1) and ( T > 0)) then (* overlap has occured *)
overlap :- trueelse
if T > 1 thenQOcount : count + ; (*the line of pl->p2 when sent to*)
(* infinity crossed this 0 polygon edge*)if ((Tprime > 1) and (T < 1) and (T > 0)) then (* the line of ql->q2 *)
P_count [ql] := Pcount [ql ] + 1; (* crossed this P edge *)
ql : ql + 1;q2 :-q2 + 1;if ql = sides_q then q2 :- 1; (* last time thru connect last*)
(* vertex to original *)end; (* all Q sides tested against this P *)
if (Q count MOD 2 > 0) then (*ifthealineof p1>p2has*overlap := true; crossed the 0 polygon an odd *)
(* number of times, then overlap *)(* has occured *)
pl pl + 1;p2 = p2 + 1;if pl - sidesp then p2 := 1; (* last vertex is drawn to beginning *)
end;
while ((not overlap) and (i <= qsides)) do (* determine if a face in 0 *)beginif (P count[i] MOD 2 > 0) then (*has crossed P an odd number*)overlap . true; (* of times *)
i i=i +1;end;
SCREENOVERLAP . overlap;
"*: ' end; (* overlap function *)
A-7
P~' ~ .P 'ff *.~~ . ~ ** p .... . .. *..* *..-*.*.. . . . .
AFIT/G S/ W 83D-9
. function onboth sides(sides,face : INTEGER; values : RARRAY;-." A,B : LINKPTR): BOOLEAN;
(* Date: 4 Dec 83(* Version : 1.0(* Nam: On Both Sides(* Function-(* This function determines if points in the polygon lie on both sides *)(* of the plane. It takes advantage of previous calulations saved in *)(* the value array, and only does the plane value calculations if needed*)(* Inputs: sides C the number of sides in the polygon)(* face C the number of sides already tested)
values ( array of calculated plane values )A ( pointer to the polygon)B ( pointer to the plane)
(* Outputs: Boolean value of whether the polygon has points on both *)sides *)
(* Global Variables Used: Eps (allowance for round off)(* Global Variables Changed: None.(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.(* Modules Called: None.(* Calling Modules: Resolver.
* (* Author: Tom S. Wailes, Capt, USAF(* History: This is the original module
varcount : integer;positive, negative • boolean;plane value : real;
begincount :- 0;positive : false;negative : false;
repeatcount :- count + 1;if values[count] < -eps then (* first check calculated values *)
negative := true (* to see if points lie on both sides *)else if values[count] > eps then
positive :a true;until ((negative and positive) or (count >- face));
if (negative and positive) then (* exit points on both sides *)on both sides := true
else (* check remaining points *)begin (* if any points remain to *)
A-8
pr.V ~~***4** . * * .. * * '~~:... .. ', % • ..: :..-', % .'.. .-...... '....'. "-" *. '.'..-''.'.* . .'.-,*'...-- .. ... .. . . .. . ..'-.. .-..*-....g% '..,.
AFIT/GCS/AW83D-9
if count < sides then (* be calculatedrepeatcount :- count + 1;planevalue := ( B .plane a * A.hidden x coor(count]) +
B-.planeb * A:-.hiddez-icoor[count]) +( B .plani-c * A-.hidden z coor[count]) +
8". plane-d; --if plane value < -eps then check new calculated values ")
negative :- true (* to see if points lie on both sides *)else if planevalue > eps then
positive :- true;until ((negative and positive) or (count >= sides));
on both sides :- negative and positive;end;
end;
-A-1%
.
A
~A-9
. 9 ... .. - , .*-., .. *q o-*. ,- " ". ..... -o . -* o. " ".* . ."."."*-."o" ','-'• - ":": " ** ' . a *q *-q' 9., - . ' . S-" I¢: a. ' Y - *.*.* * **.-" * --' -*
, , m; : , : =i ; .
-%-X- .. . " - -' .i- -L' '\ k .'. . --4 .. - .7 r. V.
AFIT/GCS/IA/8 3D-9
- (*main resolver procedure
a:.. begin
newfrmdd; (* clear the screen for drawing *)
P :- hiddenlist; (* point the P pointer to the furthest primitive *)0 -= P-.forwrd; initialize Q *)
while P <> nil do exhaust the list of primitives "1
beginwhile (C Q'.z_max view > P-.z min view) and ( 0 <> nil)
and (P-.output primitive. prims = pgon)) do(* examine all faces that overlap P *)(* in z extent
begin(* test for overlap of P and Q in x,y screen extents *)
if (( P^.x maxscreen <- Q.x_min screen) or (* if any of these *),.,~0-.x-max screen <= P-.x mn-screen) or (* conditions exist *)
( P-.ymaxscreen <- Q- .- min-screen) or (* the two polygons *)C Q .y max_screen <= P-.yminscreen)) (* cannot overlap *)
then0 := Q-.forwrd (* update 0 and exit the tests "1
elsebegin (* x,y screen extent failure, test plane equations *)psides :- P.output.primitive^.coorcnt; (* initialize for further *)qsides := Q .outputprimitive-.coorcnt; (* testssplitp :p false;split_q : false;
(* test first for P on the back side of 0 *)p face :- 0;iT plane test(psides,p face,p values,P,behind,Q) then
(* all of P is behind Q *)*IK Q :- 0Xforwrd move 0 and exit tests *)
*4. else"* begin (* try again; test now for 0 totally in front of P *)
qMace : 0;if planetest(q sides,q_face,q values,0,in frontP) then
(T all of 0 in front P *)move 0 and exit tests *)
S.:4. 0 0% Q.forwrdelsebegin (* normal plane tests have failed therefore now try*)
(* projecting the screen points and determining if *)
A-10
AFIT/GCS/MA/83D-9
(* the edges actually overlap on the screen surface *)
if not screenoverlap(P,psides,Q,qsides) then (* polygons do not overlap *)0 0% 0.forwrd
else
(* The last possible alternative before polygon splitting is to reorder *)(* P and 0 in the hope that by simply moving 0 in the list we can resolve *)(* the conflict. Since the extent and overlap tests have failed all we(* need to check is the reverse ordering of the plane equation tests. *
beginif Q'.moved then (* reordering is only allowed once to prevent *)
begin (* cyclic overlap of polygonsif on bothsides(p_sides,p_face,p_values,P,Q) then
beginpoly_split(P,Q,Q_splitP); (* points in P on both sides of Q *)
endelse if on bothsides(gqsides,qaface,qyalues,Q,P) thenbeginpolysplit(Q,P,Psplit_0); (* points in 0 on both sides of P *)
endelse
BEGINQ0.moved := true;Q-.backwrd-.forwrd := 0'.forwrd; (* remove 0if Q^.forwrd <> nil then
Q-. forwrd^. backwrd : = Q-. backwrd;if P-.backwrd <> nil then (* insert 0 "behind" P *)P^.backwrd^.forwrd := 0;0^.forwrd : P; (* link Q pointing to P *)O^.backwrd :ff P^. backwrd;P".backwrd : 0;P := 0;0 := P-.forwrd-.forwrd; (* skip old P, its resolved *)
END;end
elsebegin
(* We can use the results of previous calculations in this test. At this *)(* point, we know that there was at least one vertex found to be on the *)(* observer's side of 0. If all points of P when substituted into the *)(* plane equation of 0 are found to be on the observer's side, then 0 can(* and should be scan converted before P. This involves making the present *)(*0 become P and moving the present Q "behind" P in the linked list of *)
* (* primitives. Furthermore, we can easily test for the possibility of(* verticies of P on both sides of 0. If splitp is not set then the first *)(* vertex of P was on the observers side of 0. Thus we will first test *)(* splLt_p and if not set check the rest of the verticies to see if they *)
• .. ,.,also are on the observer's side. otherwise, we will use the same type(* of reasoning to see if 0 is totally on the back side of P.
A-11
m \i -v%..-. q-. ** *
AFIT/GCS/MA/8 3D-9
swap := false;.... split.p := on both sides(p_sides,p_face,p_values,P,Q);
if not splitjp thenswap :- true (* move Q behind P in list, *)
elsebegin
split q :-= on both sides(q_sides,q face,%yalues,O,P);if not splitjq then
swap . true; (* move 0 behind P in list, *)end;
if swap thenbegin (* mark 0 as moved, make it the new P *)Q.moved :- true;O0.backwrd-.forwrd :-= .forwrd; ( remove 0 *)if QT.forwrd <> nil then
Q0.forwrd-.backwrd :-= Q.backwrd;if Pl.backwrd <> nil then (* insert 0 in "back" of P *)
P-.backwrd.forwrd -- 0;Q'.forwrd := P; (* link 0 pointing to P *)SO.backwrd := P .backwrd;P-.backwrd - 0;P :f 0;Q := P^.forwrd^.forwrd; (* skip old P because we know its resolved *)
endelse (* time for splitting polygons *)beginif splitp then
poly split(P,Q,Q split P) (* points in P on both sides of 0 *)else if-plit q then
poly split(Q,P,P split 0) (* points in 0 on both sides of P *)else
writeln('** resolver: swap not made points UNRESOLVED');end;
end; (* else for Q'.mved *)end; (* else overlap *)
end; (* 0 in front of P *)end; (* P behind 0 *)end; (* screen overlaps *)end; (* while Q0.znax and <> nil *)
if (( 0 = nil) or ( not QT.moved)) thenbegin
funnl(P'.output primitive); (* scan convert P *)
(* if the values of the coordinates have changed then we must recalculate *)(* the NDC equivalent before leaving. This only applies to the "split" and *)(* "newjprim" output primitives we have made this time
with P^ do• "begin
if (( enter = split) or ( enter = newprim)) thenbegin (* create a new inverse transformation matrix *)
A-12
, %. *'. ,. .'. -. -.& . -.- . . .. .'d .-* .
APIT/GCS/83D-9
.~.%. makeinvat(output primitive- .owner seg-. image-trans,transmat);for I := 1 to output jrinitive .coorcnt do (*matrix mult *beginvec~l] hidden x coor[i];vec[2] hiddenfc-oori;vec[3] hidden z coor~il;vec14] : hiddenTwFcoor I i Imatrix ud (vec ,transat, vec);outputjprimitive .xcoorf(i J: vec [1];output primitive^.ycoor[ il vec [21;output primitive-.zcoor~i] vec[31;output.priuitive^.wcoor[iJ : vec(41;1
end;end;
end;P = P^. forwrd;if P 0> nil then
0 := P-.forwrd;end
elseo : -Q-. forwrd;
end; (* P 0> nil *end;modend.
It
A-13
AFIT/GCS/MA/83D-9
; (* Date: 4 Dec 83(* Version : 1.0(* Nane: Poly Split(* Module Number: 5.2.2(* Function:(* This module takes a polygon and splitting plane and divides *)(* the polygon into two distinct polygons separated by the splitting *)(* plane. In addition, the resulting fragments are placed back into *)(* the hidden surface linked list structure for future processing. *)(* The main procedure will actually split the polygon and the smaller*)(* placement procedure will place the fragments into the linked list.*)(* Inputs: Polygon ( a pointer to polygon to be split)(* Splitpln ( a pointer to the splitting plane )
mode (flag that specifies if P is split by Q, or if *)(* Ois split by P)(* outputs: Polygon ( a pointer to the moved polygon position) *)
Splitpln ( a pointer to the moved splitting plane) *)(* Global Variables Used: The primitive and Hidden Surface data
Structures(* Global Variables Changed: The Hidden Surface data Structure(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.( Files Written: None.(* Modules Called: Initialize Hidden Surface Node
Calling Modules: Resolver.(* Calin(* Author: Tom S. Wailes, Capt, USAF(* History: This is the original module
Module SPLITER;
constc$I defconst.src]
epa = 0.000000001; (* close enough to zero for cararisons,needed *)(* because of caputer round off *)
(*EOC end of const section *)
type[$I deftype.srclM(*OT end of type section *)
var[$I extvar.srcl(*EDV end of var section *)
(*BOP beginning of procedures and functions *)EXTEMAL [3) PROCEWURE INITHIDDEN_LINK(PT : PRIM_ PR; MDE E RY);
(*EOP end of procedures and functions *)
A-14
AFIT/GCSA4/83D-9
Procedure POLYSPLIT( VAR polygon :LINKPTR; VAR splitpln :LINKPTR;mode : SPLITrYPE);
varpl,p2,side aside b : integer;plane pl,plane p2,delta x,deltayj,delta z,delta-w,T intersection,x intersection,y interection,z intersection,w intersection :real;xCa,y a,z a,w a,x b,y b,z b,,w b7: RARRAY;Ifirst plane pl :real;
-AI1
7W -- -.U .- _. . .-. .X ".P -j3,-.s ,. J-.-. - . K. -777, '. -1-
AFIT/GCS/MA/83D-9
procedure place node(start,new hidden :LINKPTR);
(* Date: 4 Dec 83(* Version : 1.0(* Name: Place Node(* Function:(* This procedure used to properly place a hidden node created(* after a polygon split. It starts at the splitting plane and *)(* searches toward the observer until it finds its proper place *)(* in the list using its z extent for the test. It will ignore *)(* polygons that have been moved when testing. Finally it does *)(* the actual insertion into the list.(* Inputs: Start ( beginning point in hidden surface linked list *)
at which to start searching for proper z placement ) *)NewHidden (pointer to node to be inserted)
(* Outputs: None.*)(* Global Variables Used: Hidden surface linked list structure(* Global Variables Changed: Hidden surface linked list structure *)(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.(* Modules Called: None.(* Calling Modules: Placement.
(* Author: Tan S. Wailes, Capt, USAF(* History: This is the original module
varpresent : LINKPTR;
beginpresent :-= start^.forwrd; (* set temporary pointer *)if present = nil thenbegin
start-.forwrd := newhidden; (*place on right *)new hidden'.backwrd := start; (* end of hidden *)new_hidden'.forwrd : nil; (* linked list *)
endelse
begin1" The next lines of logic testing will ensure that primitives "1(* are ordered first by their z maximum values. If primitives *)(* share the same z maximum value the sort will result in the *)(* primitive with the smallest minimum value being closest to *)(* the eye. Moved primitives cannot be trusted for their z values *)(* and therefore will be ignored. I also dont want to go past *)(* the last primitive in the linked list.
while (((newhidden.z max view < present^.zmax view) or((new_hidden^.zmaxview - present-.z.max-view) and
A-16
* h . A*. . . I . .i . o. * . .. . . - - --. . ' - . -- - ' '. - J . '.° . . -.
AFIT/GCS/MA/83D-9
(new hidden-.z min view < present-.z min view)) or-. preent-.moveU) and (present-.forwr 7 <nil)) do
begin
present := present .forwrd;end;
if ((new hidden^.z_maxview < present^.zmaxview) or((new hiddenr, z max view - present-.z max view) and(new-hidden .z-. in-view < present-. zirin view)) orpresent-.moiid) then (* I hit te end of the list *)begin
present .forwrd := new hidden; (* place on right *)new hidden-.backwrd :-present; (* end of hidden *)newhidden^.forwrd := nil; (* linked list *)
endelse
begin (* normal insert *)new hidden, *forwrd : - present;
new hidden.backwrd := present ^.backwrd;if present'.backwrd <> nil then
present^. backwrd^. forwrd : = new hidden;presente.backwrd:= new hidden;
end;end; (* test for nil *)Q end; (*of placenode *)
-A-17
9",-2.°" "-,".,' ?.''"" " ." "," > ", .".. ''''' <'' ,
AFIT/GCS/MA/83D-9
procedure placement;
(* Date: 4 Dec 83(* Version : 1. 0(* Name: Placement(* Function:(* This sub procedur. needed to break the poly split procedure into *)( two distinct parts. The MT+86 compiler has a limited space(* allotted for procedure area. This encourages modularity and is *)(* really for the best. This procedure will take the two vertex(* lists made during the main splitting routine and the splitting *)(* polygon and merge them into the correct ordering into the hidden *)(* surface linked list structure.(* Inputs: None.( O* utputs: None.(* Global Variables Used: vertex lists for sides a and b, Mode(* Global Variables Changed: Hidden surface linked list structure *)
Primitive data structure(* Global Tables Used: None.(* Global Tables Changed: None.
-* (* Files Read: None.(* Files Written: None.(* Modules Called: Place nods, Initialize hidden surface node(~Calling Modules: PolygonSplit
Author: Tam S. Wailes, Capt, USAF(* History: This is the original module
varI : integer;B,orig poly : PRIM PTR;last,teWpy,Bptr : LINKPTR;
*begin
(" place negative verticies from side b into original primitive "1polygonft.output primitive^.coorcnt := side b; (* set # of points *)for i :- I to side b do (* move points to linked list area
•" beginpolygon'.hidden-x-coor[il :x _b[i];polygon'.hiddenycoor(i] -- y b[i]polygone.hidden z-coor[i] := z-[i];polygon.hidden-w-coor[i] .. w-b[i];
(* polygon.outputj rrmitive.redIndex verticies(i] := red b[i]; *)-" .;end;
(' reinitialize the extents, plane equations, etc for this modified entry *)
A-18
............ .. .
WCM * -: F.. * IT*M-. *7- * -. 1 6 'k* ~ ~ ~ . ~ , -
'A
AFIT/GCSA/8 3D-9
inithiddenlink(polygon-.output_primitive,split);
(* create new primitive data holder and initialize the hidden node for *)(* the half of the polygon on the positive side of the split plane *)
new(B,pgon);origpoly := polygonr.output primitive;
with B dobegin
prins := origpoly¥.prims;o wner seg - origpoly".owner seg;next prim : origpoly'.nextprim;origpoly .nextprim :- B; place a in listpickid - origpoly^.pickid;penval := origpoyl.penval;line_index :- origpoly^.line index;poly_interior style : - origpoly^. polyinteriorstyle;polyedgestyle :- origpoly^.polyedgestyle;fill index :- origpoly.fill index;coorcnt :- sidea;new(Bptr);hidden :* Bptr;for i 1 1 to side a do (* transfer the point values *)
with Bptre dobeginhidden x_coor[i] :=x a[i];hidden ycoor [i] yali]
hidden w coor[i] :- w-a[il;(* B'.red-iidexverticies[i] := red_ai]; *)end-,
( initialize the extents, plane equations, etc for this new entry *)inithidden.link(B,new prim);
end;
case mode of- splitp: begin
(* P was split so leave negative part in place *)(* and place new positive part in front of Q *)
placenode (splitplnBptr);Bptr.moved :- true; (* z may be out of bounds *)splitpln :- splitplne.forwrd; (* move Q to check next *)
end (* primitive in list *)(* P does not change *)
p_splitq: begin(* Q was split so place negative part behind P and *)(' place new (positive) part in front of P *)
place node(splitpln,Bptr); (* positive part in front of P*)
polygon .backwrd'.forwrd :- polygone.forwrd; (* remove Q *)if polygonC.forwrd <> nil then
polygon .forwrd.backwrd :- polygon. backwrd;
A-19
ap 9F -S -T d Tw T- . 5 --.. - . .. . - - - ...-- -.-- S. W. S -0 'J
AFIT/GCS/A/83D-9
". -p:: (* place negative polygon *)if splitpln^.backwrd <> nil then on back side of P, *)
splitpln-.badcwrd-.forwrd := polygon; (* further fram eye *)polygon-.forwrd := splitpln;polygonf.backwrd . splitpln^.backwrd;splitpln.backwrd := polygon;polygon' .moved :=- true;splitpln - polygon; (* make this negative portion the new P *)polygon := splitpln.fowr-.forwrd; (* move 0 to next prim after*)
end; (* old P *)
end; (* cam *)end; (* placement *)
.2
A-20
.4. I," 3I , .'"*o',."?Y- '/ -i'? '- "".' .° ' * '--'.'';'- -?. -. :
AFIT/GCSAMA/83D-9
(* This starts the main polygon splitting procedure needed to split(* conflicting polygons found by the resolver subroutine. It uses the *)
plane equation of the input "split" to divide a "polygon" into two *)(* polygons. The main algorithm is taken from the article found in :(* Sutherland, I.E. and G.W. Hodnain. " Reentrant Polygon Clipping,"(' Communications of the AC, 17(1) : 32-42 (January 1974). Basically *)(* we take each vertex in turn and see which side of the plane that(* it resides. If it sits on the opposite side of the plane from the *)(* last vertex we checked then we must calculate the intersection of the *)(* line between the verticies and the splitting plane. This new vertex *)(* is then included in the list of verticies for both sides. As we(* continue around the polygon, points on the positive side of the plane *)
are kept in one list, and points on the negative side are kept in(* another. At the end, we end up with two sets of verticies that(* represent the two new polygons. We then call placement to create an(* initialized node and place the resulting pieces back into the hidden*)(* surface linked list.
4%
begin
O (* determine the placement of the first point *)side a :-0;side-b :- 0; (* initialize the number of verticies in each list *)
plane-pl : 0.0; (* initialize the first value to fall through test for *)(* intersection
p1:- 0; (* set the pointers so that p2 will initially be pointing to *)p2 :1 1; (* the first vertex in the list *)
(* process main body of vertex points *)
while p2 <- polygon '.outputprmitive'.coorcnt dobegin
(* determine the plane values of points P1 and P2, the verticies "14' (* in question. Planejpl already set from previous calculation *)
(* either from initial conditions or previous time through loop.*)
plane p2 :- (splitpln^.plane a * polygon-.hidden x_coor[p2])+ (splitplnC.plane b * polygonh.hidden y coor[p2])+ (splitpln^.plane-c * polygon-.hidden z coor[p2])+ splitpln.plane-d
if p2-i then (* save initial value *)firstplane pl := planep2;
(* Does the new point reside on the splitting plane? *)-....: (* if it does put it in both vertex lists and continue *)
(* otherwise we must check to see if the plane was cut *)
A-21
CIA** . 4.*. . . .
47 7
AFIT/GCS/MA/83D-9
if (( planep2 < 0.0 + eps) and ( planep2 > 0.0 - eps)) then (* on plane *)with polygon- dobegin
side a : side a + 1; (* place the vertex in both lists *)side-b : side-b + 1;x_a [sidea] : =-hidden_x coor[p2];y_a[sidea] •= hiddenjY_coor [p2] ;z alside a] -= hiddenz_coor(p2];w-a[side-a] := hidden.w_coor[p21 ;xb [side-b] • hiddenx_coor[p2J;y- [_b[side-b] hiddenY coor[p2];z-b[side-b] := hidden z-coortp2];
/..- w-bcside-b] : hiddenw-coor[p2];plane p2 :- 0.0; (* se;t to zero to prevent intersection tests *)
(* because the CORE supports color intensities at each vertex the color *)(* values would also have to moved fran the cooresponding vertex into *)(* a temporary area similar to the x,y,z values shown above!!!!
endelse
begin
(* Does the line P1 -> P2 cross the plane? If it does then the signs *)' (* of planepl and planep2 will be different *)
if ((( plane pl < 0) and C plane p2 > 0)) or(( planel > 0) and ( plane p2 < 0))) thenbegin
with polygon- do (* calculate intersection using *)begin (* paranetric equations of lines *)delta x - hidden x coor[p2] (* solving for T; for we know *)
- hidder xcoor[pl]; (* intersection must be in the *)deltay ,= hidden ycoorlp2] (* plane and at the same time on *)
- hiddenjy_coor[pl]; the line Pl-> P2. Since these*)deltaz hidden z coor[p2] values will be used more than
- hidden z coor[pl]; once, do them here *)delta w .= hiddenw-coor[p2]
- hidden-w-coorlpl];end;
(* calculate the parametric line equation constant T for the intersection *)(* of the line P1 ->P2 and the split plane *)
with splitpln do'- . T_intersection :- (-plane_9l)/((plane a * deltax) +".. (plane b * delta y) +4. (plane.c * delta_ z));
V7 now calculate the x,y,z of the intersection point by:.,:-.' (* substituting T into the parametric line equations for x,y,z *)
,V with polygon^ do
A-22
e-- - . .. :V Am~~
rAFIT/GCS/.A/83D-9
beginx intersection "-"hidden x coor plI + (Tintersection delta-x);y intersection := hiddenjD coor[pl] + (T intersection * delta-y);z intersection := hidden-z-coor[pl] + (T -intersection * deltaz);w intersection .=hidden coor[pl] + (T-intersection * delta.);w-intersection := hidden_w_coor[pl] + (Tfintersection * delta~w);
(* A similar calculation can be performed to find the color values needed *)(* this point. Using T and knowing the values of say RED at Pl and P2 we*)(* can calculate RED at the intersection vertex by :
.4 RED[pl] := RED[pl] + (T intersection * (delta red)); *)(, This new value could then be placed into the vertex list for-the new(* point
end;(* place the intersection point in both vertex lists *)
side a -= side a + 1;sideb := side b + 1;x a[side a] :::i-x intersection; x b[side b] : x intersection;y_--a[sidea] : y-intersection; y-bsideb] :f y-intersection;z a(side a] .f z intersection; z-b(side-b] : z intersection;w a[sidea] := w- intersection; wb[sideb] : w-intersection;
end;
(* now place the p2 point in the proper list *)
with polygon" dobeginif plane p2 < 0 then (* point on negative side of plane *)
beginside b :- side b + 1;x btside.b] :=-hidden x_coor[p2];y-b[side_b] :- hidden3y coortp2];z b[side b] - hidden z coor[p2];w-)[side-b] . hidden-w--coor(p2];
(* here-you woUld move the color into side b's color vertex array *)end
else (* the point is on the positive side of the plane *)begin
side a :- side a + 1;x a[iide a] :-hidden x coor[p2];y-a[side-a] : hidden-.-coor[p2];z-a[side-a] : hidden zcoor[p2];w-aside-a] : hidden w coor[p2];
end (7 color-verticies for side a moved here *).' end;
end; (* with polygon^ *)end; (* non zero planep2 *)
pl :a pl + 1;• " • p2 :=-p2 + 1;
• ." plane_pl i plane.2; (* saving this value prevents duplicate calculations
A-23
AFIT/GCS/MA/83D-9
end; (* while for main vertex points *)
(* at this point all we need to do is close the vertex lists. If the line *)(* fraum the last vertex to the Eirst vertex crosses the plane the
*" (* intersection point must be sent to each list. Plane pl contains the *)(* substitution into the plane equation for the last point and of course *)(* first plane pl contains the value frum the initial vertex. In the(* initial algorithm a test was made to see if there was output from the *)(* split. This was because their algorithm was used to split polygons on(* screen surfaces and polygons cmpletely contained on 1 surface would not *)(* be split. Because I will have a split every time, I will instead test *)(* for degenerate polygons when I terminate *)
p2 := 1; (* set p2 to point to the first vertex *)plane p2 := first_plane pl;if ((T plane pl < 0.0 - eps) or ( plane pl > 0.0 + eps)) and
( planep2 < 0.0 - eps) or ( planep2 > 0.0 + eps))) then
(* if either the beginning point or ending point is on the plane then *)(* it is already included in the vertex lists11!*
if (((planepl < 0) and (planep2 >0)) or((plane pl > 0) and (plane p2 < 0))) then
begin(with polygon- do
begindelta x .= hidden x coor(p21
- hidden-x-oor pl];delta y •= hidden-ycoor p2l
- hiddenYcoor[pl]; (* Since these *)deltaz -- hidden z coor[p2] (* values will be used more than *)
- hiddenzcoo[pl]; (* once, do them here *)deltaw := hiddenw--coor[p2]
.5 - hidden.wcoor[pl ];4 end;
(* calculate the parametric line equation constant T for the intersection *)(* of the line P1 ->P2 and the split plane *)
with splitpln^ doT intersection := (-planejpl)/((plane a * delta x) +
(plane-b * delta-) +(plane_-c * delta_z) );
(* now calculate the x,y,z of the intersection point by *),.4 (* substituting T into the parametric line equations for x,y,z *)
'4 with polygon do
beginx intersection : hidden_x_coor[pll + (T intersection * delta x);
.~,. y-ntersection .- hiddeny coor[pl + (T-intersection • deltay);z intersection .- hidden z coor[pl] + Ti-intersection delta z);w-intersection := hidden-w-coor[pll + (T-intersection * delta-w);
I A-24
AFIT/GCS/MA/83D-9
(* A similar calculation can be performed to find the color values needed *)(* this point. Using T and knowing the values of say RED at Pl and P2 we *)(* can calculate RED at the intersection vertex by :7%, (* RED[pl] :- RED[pl] + (Tintersection * (delta red)); *)(* This new value could then be placed into the vertex list for-the new *)(* point
end; (* with polygon "1* (* place the intersection point in both vertex lists *)
side a : side a + 1;side-b : side-b + 1;x a[side a] := x__intersection; x b[side b] : x_intersection;ya[sid-a] := y_intersection; y-b[side-b] := y_intersection;z a[side a] .= z intersection; z b[side b] : z intersection;w-a[side-a] := w-intersection; w-b[side--b] : w-intersection;
end; (* test for intersection *)(* see if output verticies make sense, they must have at least 3 sides *)
if ((side a < 3) or (side b < 3)) thenwriteln( 'polysplit: degenerate polygon created ')
elseplacement; (* put the vertex lists into the hidden linked list *)
end; (* of split poly *)
.. modend.
4A-25
::
AFIT/GCS/4A/83D-9
(* Date: 4 Dec 83(* Version : 1.0(* Name: Sort Hidden(* Module Number: 5.1(* Function:(* This is the preprocessor to the Newell, Newell, and Sancha Hidden *)(* Surface Removal algorithm for the U of P CORE system. It takes the *)(* output primitives created from the current batch of updates and(* merges them into the linked list created by previous batches. The *)(* sorting is simply by z in viewing coordinates with the furthest z(* at the beginning of the list. Nodes that have been moved are not *)(* used f'or camparision.(* Inputs: None.(* Outputs: None.(* Global Variables Used: Primitive and segment data structure(. Hidden surface linked list structure(* Global Variables Changed: Hidden surface linked list structure
N (* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.(* Modules Called: Initialize hidden surface node, Delete hidden
surface node(* Calling Modules: EndBatch_of_Updates
(* Author: Tam S. Wailes, Capt, USAF: (* History: This is the original module
Module SORT;
const[$I defconst.srcl(*EOC end of const section *)
o,
type[$I deftype.srcl(*EDT end of type section *)
var[$I extvar.srcl(*EOV end of var section *)
(*BOP beginning of procedures and functions *)EXTERNAL PROCEDURE DELETE HIDDEN(L : LINKPTR; MODE : DISPOSER);EXteRNAL [31 PROCEDURE INIT HIDDEN LINK(PT : PRIM PTR; MDE : mTRY);
(*EOP end of procedures and fuictions-*).4
procedure SORTHIDDEN (start: SEGPTR);
Svarseg : SEGPTR;prim: PRIM_Pm;
A-26
* . o °-I. . . • o * . ., • o . .4.. . . . 4
I . . . . . . . . .'.- ..- .1 is- - Tab -- ;W - 6- -. p. -- . ,
AFIT/GCS_.. /83D-9
. ".->. mergelist,next,present,link : LINKPTR;
begin
mergelist :- nil; (* start new list of nodes to be added *)seg := start; (* start search with first segment *)
while seg <> nil dobeginif seg^.visible then
beginprim :- seg^.prim list;while prim <> nil do(* examine all primitives for the seg ")begin
if prim^.hidden = nil thenV ,begin
new(link); (* get new hidden node *)prim'.hidden := link;init hidden link(prim,normal); (* set it up*)linkO.forwrd := mergelist;mergelist := link; (* place it into temp list *)
endelse
int hidden link(prim,update); (* recalculate image *)prim =prim .next prim;
e end;.' end
else (* segment not visible, if hidden node remove it! *)begin (* this prevents unneeded computationslprim := seg^.primlist; (* search all primitives *)while prim o nil dobeginif primC.hidden <> nil then (* remove them all *)
deletehidden(prim^.hidden, remove);prim •= prim, nextprim;
end;end;
seg :- seg'.nextseg; (* look at the next segment in the list *)end;
if mergelist > nil then (* check for merging entries *)begin
present :- hiddenlist; (* set present to the furthest primitive "1if present - nil then (* present will be nil on first hiddenlist *)
* beginhiddenlist := mergelist; (* place initial primitive in list *)present := mergelist;mergelist :- mergelist^.forwrd;present^.forwrd :- nil; (* both back and forward pointers nil *)
a, .. end;while mergelist 0 nil do
begin
A-27i " . """''"""""""" . . .". ." ,' .,.. ' .,.,V ''' ,..,. " ',"%
VV V.' ; ' . j .. % _ L-%% %_L... .'. 7% --L K. .:, .- % .-. ., / :. .
AFIT/GCS/MA/83D-9
*~ , *.: next := mergelist-.forwrd; save pointer to next merging *)(* entry into the hidden structure *)
(* because previous batching may have reordered the list *)(* this while ensures that the initial test will be either on *)(* primitive closest to the eye or on an unmoved primitive *)
while ((present'.moved) and (present'.forwrd > nil)) dopresent : - present. forwrd;
if mergelist'.z max view > present-.zmaxview then (* go left *)begin
while ((( margelist^.zmax view > present-.z max view) or( ( mrgelist. z__max view = present .zmaxview) and( mergelist.z_min _view > present-.z min view)) or
present-.moved) and ( present-.backwr <>-nil)) do
(* search left until proper place found, ignore *)(* moved polygons, for they are out of order *)
present := present^.backwrd; (* searches left *)
if ((mergelist^.z max view > present-.z max view) or( ergelist', z-max-view = present. z--ma-view) and( mergelist.z min- view > present.z min- view)) orpresentmovedT thin (* merge at eid of list *)
,, beginpresent^.backwrd := mergelist; (* place left *)mergelist^.forwrd := present;hiddenlist :- mergelist;(* this is the prim *)
(* furthest from eye *)(* mergelist-.backwrd := nil done in init *)end
elsebegin (* normal insert*)mergelist 'forwrd := present^.forwrd;mergelist^.backwrd := present;if present-.forwrd <> nil then
present-.forwrd^.backwrd := mergelist;present^.forwrd := mergelist;
end;end
elsebegin (* search right "1while (((mergelist^.zmaxview < present.zmaxview) or
(( mergelist.z ma xview = present .z max view) and( mergelist-. mrn view < present^.z m--ranview)) or
present .movrd) Znd (present".forwd <5 nil)) dopresent := present'.forwrd;
if ((mergelist^.z max view < present^.zmax view) or(( mergelist.i ziax-view = present .2 maxview) and( mergelist-.z rin view < present.z rn View)) orpresent-. moivd) Then
A-28
r.,, ", :.; , ,% ,.';'*.. *'. *.-'U",- , ...- . -- --..".. .." .. -." '. , -.. ,U ',. ' .'-,U.--. ,
AFIT/GCS/MA/83D-9
" .". beginpresent .forwrd := mergelist; (* place on right *)mergelist-.backwrd := present;mergelist-.forwrd : nil;
endelsebegin (* normal insert *)mergelist^.forwrd :-= present;mergelist^.backwrd := present-.backwrd;if present'.backwrd <> nil then
present-.backwrd-.forwrd := mergelist;present. backwrd :f mergelist;
end;end;
mergelist-= next; (* get the next entry entering the structure *)end;
4 ' end;end;modend.
.,.
.- O
A-29
&-- -_- 73D -- -- - - - -- i- o . 11- EVJ-.-,-,-.0 -
AFIT/GCS/MA/83D-9
(* Date: 4 Dec 83(* Version : 1.0(* Name: Initialize Hidden Surface Node
o(* Mdule Number: 5.1.1(* Function:(* This is the hidden surface node initialization routine. It takes*)(* a pointer to an output primitive and prepares it for use in the *)(* Newell, Newell, and Sancha hidden surface algorithm within the *)(* U of P CORE subroutine package. Four possible cases exist for *)(* primitives to be set. On the batch of updates in which a
primitive is created, this routine completely sets all of the *)(* parameters to their initial value( this is called a normal entry)*)(* On the batches of updates that follow, the pointers have been *)(* set placing the primitive in the correct ordering for the last *)(* picture, and because the present picture should have only mall *)(* changes, we do not reset them( this is called an update entry). *)(* Both of these types of entries require us to recalculate the(* image space coordinates of the primitive-s points. If a polygon *)(. is split during the application of the hidden surface removal *)(* algorithm the resolver procedure has already placed the image *)(* transformed coordinates into the hidden surface the incaing(* hidden surface node. The original polygon is initialized with *)
an entry of split and the new hidden node is entered withi & (* a value of newprim. The difference here is that the original *)
(* polygons pointers are valid and the new node's pointers must *)(* be set to nil. The min and max in screen x and y, the min and *)
max z in viewing coordinates, and the plane equations for the *)(* primitive must be calculated for all cases.(* Inputs: P (pointer to primitive structure)
mode (flag to tell what kind of update to perform)(* Outputs: None.
"d (* Global Variables Used: Primitive and Hidden surface DataStructuresView State projection type
(* Global Variables Changed: Hidden surface structure(* Global Tables Used: None.(* Global Tables Changed: None.(* Files Read: None.(* Files Written: None.( Modules Called: Make Matrix (create 4X4 image transformation *)
..-. ( * matrix)Image transformation (does image transformation*)
(* Calling Modules: EndBatch of_Updates
(* Author: Tom S. Wailes, Capt, USAF(* History: This is the original module
Module H0INITHID;
A-30
AFIT/GCSA4A,3D-9
[$I defconst.srcl(*EOC end of const section *
type[$I deftype.srcl(*EOT end of type section *
var[$1 extvar. srcl(*EDV end of var section *
(*BOP beginning of procedures and functions *[$I D(XYrLEXT. SRC J (* concol, scr<->ndc, image xforzu *
(*EP end of procedures and functions *
C,. procedure INITKIDIU4 LINK (p: PRIM PflR; mo~de 3ENTRY);
varij,nLumber ofjpoints :integer;x,y : real;
(* main routine
beginwith p;^.hiddent^ do
beginnumber ofpoints :=p^. coorcntlcase mo~de Of
normal:begin
~*1 nextid :- nextid + 1;output primitive :=p; set parent pointer *forwrd :- nil; (*initially out of list *
'S backwrd :- nil;moved :- false; (*initially placed in order *miakeniat (p .owner _seg^ .Ligtrans); (*perform image transform *for i:=1 to nmuuber of points do
imgtrans(p^.xcoor[i1 ,p^.ycoor[i] ,p^.zcoorfi] ,p^.wcoor[i],* hidden x coor~iJ,hidden ycoor~i,hidden z-coori,
hiddendwcoor(i]);
end;update:
beginmakeniat (rp. owner seg % image trans); ( perform image transform *for i:=l to nuzter .of ints do
1trans(p.xcorTi,p;.ycoorti,.zcoorti,pr.wcoor~i],J* hidden x coortiJ ,hiddenj c oor~i],hidden z coorfil,
*~ .*.thiddenwcoortiJ);
end;
A-31
AFIT/GCS/A/83D-9
newjrin:begin
next id :a next id + 1;output_primitive := p; (* set parent pointer *)forwrd := nil; (* initially out of list *)backwrd :- nil;
,ovd := false; (* initially placed in order *)end;
( split: nothing; *)end; (* case *)
enter := mods; save type of entry *)
(* calculate the x,y screen extents of the transformed points *)
if viewstate.pjtyp = 2 then (* perspective casebegin
x min screen := hidden x coor[l]/hidden_w coor[l]; (* screen position *)y min screen := hiddenYcoor[l]/hidden_w_coor[l]; (* depends on
end- hcmogeneous coor *)else
beginx min screen := hidden x coor[l]; (* parallel case does not depend *)yminscreen : hidden-y-coor[l]; on homogeneous coor *)
. end;) z_mmin view :- hidden_z_coor(l];ximax screen := Xmin _screen;y-mxscreen :-y mscreen;z_maxview := z_min _view;
for i:= 2 to numbejrofpoints do (* test each point and update the *)begin (* min and max as appropriate
if viewstate.pjtyp = 2 then (* perspective casebegin
x :a hidden x coor(il/hidden w coor[i]; (* screen position *)y "= hiddenrycoor(i]/hiddenwcoor[i]; (* depends on
end (* hcmogeneous coor *)else
beginx := hidden x coorli]j; (* parallel case does not depend *)y :e hiddsnyoor[i]; on hcmogeneous coor *)
end;
if x min screen > x thenx-mm-screen :- x
else if x max screen < x thenXimaxscreen :- x;
ifympinsren > y theny mn _screen :- y
else if yinax_screen < y theny_max screen :- y;
if z min view > hidden z coorti] thenzm-_view :- hidde7n z_coor[i]
A-324.-••4 ", - .. .- e e " . . ". ' ' ''.''er .. " ". "r . . . .:.'-.. .'
_7 ~ ~ ~ ~ ~ --7 -IF INA. -31. -MTO -%5- >"
AFIT/GCS/4A/83D-9
else if z max view < hidden z coor[i] thenzmax view := hidden z coor[ i];
end;
(* calculate the plane equations coefficients from a method found in *)(* Sutherland, I.E., R.F. Sproull, and R.A. Schumacker, N A Characteriza- *)(* tion of Ten Hidden-Surface Algorithms," Computing Surveys, *)(6(1) ."14-15(Mar 74) *
i :I;J:-2;plane_a- 0;plane b : 0;plane_c 0;
repeatplane a :- planea + ((hidden_ ycoor[iI - hiddenycoor[j])
* (hidden z coor[i + hidden z coor[jJ));
planeb -= planeb + ((hidden z coor(i] - hidden z coor[j])* (hidden_x coor[i] + hidden__x_coor[j]));
plane c : plane c + ((hidden x coorti - hidden x coor(j])* (hiddenYcoor[i] + hidden ycoor[j]));
j -j+l;
if i - number.ofjoints thenj " 1;
until I > numberof points;
(* to find d simply place the first point into the plane equation and solve *)
plane d :- -(plane a * hidden x coor[l]) - (plane b * hidden y_coor[l])- (plane-c * hidden-zcoortl]);
if plane d < 0.0 then (* user has defined the object counter-clockwise *)beginplanea - -plane_a;plane b -planeb;planeic ,= -planec;planed :- -planed;end;
end; (* with p.hidden *)end; (* nit hidden link *)
modend.
A-33
.... ... .,',,. ',,., , ,..,.. .,. ., ...,..,.,5.: - .. - ,. .... .'- .
AFIT/GCS/A/83D-9
,S
(* Date: 4 Dec 83(* Version : 1.0(* Name: Delete Hidden Surface Node(* Module Number: 5.1.2(* Function:(* This procedure is used to delete nodes fran the hidden surface linked *)(* list produced during the operation of the Newell, Newell, and Sancha *)(* Algorithm. TWo basic modes of operation are controlled by the input *)(* mode. If the mode is retain, then the node is to be removed from *)(* the linked list but not disposed. Otherwise if the user specifies(* reaove, then the node will be deleted from the linked list and its *)(* maory space given back to the operating system by a call to dispose. *)(* Inputs: L (pointer to node to be deleted), mode (type of deletion) *)(* Outputs: None.(* Global Variables Used: Hidden surface data structure(* Global Variables Changed: Hidden surface data structure(* Global Tables Used: None.(* Global Tables Changed: None.
(~Files Read: None.(* Files Written: None.(* Modules Called: None.(* Calling Modules: DDEZPTYSEG, Sorter
(* Author: Tom S. Wailes, Capt, USAFP (* History: This is the original module
Module delhid;(* Modified for VAX by SMP 7/82 *)(* (including auto-generation of CVrP
sections, which is why same may be empty. *)
const[$I defconst.srcl(*EOC end of const section *)
type[$I deftype.srcl(*EOT end of type section *)
var[$I extvar.srcl
4:[; (*iEV end of var section *)
*/: procedure DELETE_HIDDEN(L : LINKPTR; mode : DISPOSER);
begin(. hiddenlist points to the farthest primitive from the eye *)
if hiddenlist - L then (" if L is the furthest primitive then *)
A-34
AFIT/GCS/MA/83D-9
., -'.;, if L-.backwrd 0 nil then (* see if L is the only primitive *)• :.-. begin
hiddenlist := L-.backwrd; (* if it is not then move *),L.backwrd-.forwrd := nil; (* the pointers to next to last*)
endelse
hiddenlist :- nil we are removing the last primitiv% "1* else (* not the last primitive *
beginL^. fowrd^.backwrd :- L".backwrd;if L^.backwrd <> nil then (* is this the closest primitive to eye ')
L^.backwrd^.forwrd :- L^.forwrd; (* no *)end;
now reclaim memory if possible "1
if mode - remove thenbegin
L-.output primitive-.hidden : nil;dispose(L);
end;
end; (* delete hidden *)Si.
U nxodend.
4A.3
4%
'.5
AFIT/GCS/MA/83D-9
Appendix B
Maintaining the Flight Dynamics Laboratory
CORE Graphics System
The CORE graphics system developed to support the
Flight Dynamics Laboratory can be thought of as a
collection of many individual subroutine modules grouped by
major function into four overlay libraries. These overlay
libraries are connected to the users main program by LINKMT
as the last step before execution. This appendix will give
specific guidance in the steps necessary to create a
graphics program that uses the CORE and additionally
provide documentation on how to modify the existing CORE
subroutines.
First, the basic structure of a program created under
MT+86 is explained including a discussion of the various
limits in program, data, stack, and heap space caused by
the Pascal MT+86 system. Then the LINKMT link line commands
needed to "link" a user program to the CORE system are
described. Finally, the steps needed to modify the CORE
libraries are explained including how to use the
undocumented system utility program called STRIP.
Procram Structure
Programs created by Pascal MT+86 are divided into four
B-i
.- -A -j a* .7 T .S *
AFIT/GCS/MA/83D-9
, memory areas called segments (Figure 10). The first
segment, called the program segment, contains the actual
*. instructions that are executed by the 8086. A second
segment contains the data manipulated during execution and
is therefore called the data segment. Thirdly, there is an
extra segment that is used by Pascal MT+86 for the Pascal
"heap" space. Finally, because of the trend toward modular
program development requiring the passing of information
between many different procedures on a "stack", Intel
defines a stack segment.
Addressing on the 8086 is performed by adding 16 bit
offset values to four internal 16 bit registers (one for
each of the program, data, stack, and extra segments). The
use of these registers reduces the amount of bits needed by
instructions to specify an address, but under the present
compact memory model of PASCAL MT+86, also limits the
address space of program, data, and stack segments to 64K
bytes (fortunately you can use FULLHEAP in the link line to
allow up to 1 megabyte of heap (extra segment) storage
area). Although undocumented, the compiler apparently can
not generate the necessary segment register modification
instructions needed to allow larger program, data, and
stack memory areas. Therefore, to overcome program and data
area size limitations, Pascal MT+86 allows the user to
define program and data area overlays.
and An overlay area is simply a part of the 64K program
and data areas that is set aside by the linker to be shared
B-2
% * % ... .~9.' .. . •. -. -... - .. , -. . ., . . *. - ... .. ,.. ,..,.**, , , .
AFIT/GCS/MA/83D-9
by overlay modules (groups of procedures). Although Pascal
MT+86 allows the user to define several places in memory as
overlay areas, the present CORE system uses only one 32K
overlay area. During execution, an overlay manager
subroutine will be called whenever a procedure assigned to
this overlay area is required by the main program. The
overlay manager will read the procedure's overlay module
into memory, find its address by searching a symbol table
found near the end of the overlay module, and then branch
to that address. Placement of a procedure within an overlay
is done by inserting an overlay module number within Pascal
MT+86 external procedure declarations referencing the
procedure, and by placing the compiled procedure inside an
overlay module library.
Creating an overlay library requires first making a
.BLD file that contains a list (one procedure name per
line) of all the .R86 (compiled procedure) files to be
placed within the library. After this file is created and
all of the procedures within the overlay have been
compiled, LIBMT is used to create the library. LIBMT will
concatenate all of the files listed in the .BLD file into
one large .R86 file that will be used in linking the
overlay modules (note that the present .BLD files require
that all compiled .R86 files are on drive CI). The .BLD
library files needed for the present three overlay modules
are OVLYl,OVLY2,and OVLY3 (e.g. a sample command line for
. '. the overlay 1 library is: LIBMT OVLY1).
B-3
AFIT/GCS/MA/83D-9
Overlay one is rather small and contains the
procedures used one time only for initialization and
termination. This frees the two main overlays from the
burden of infrequently called procedures and gives them
more room for development and debugging. Overlay two
contains most of the user callable CORE procedures that set
viewing parameters, draw lines, draw polygons etc. along
with the utility procedures needed to support them such as
the graphics "clipping" routine. Finally, overlay three
C contains the device dependent device driver routines along
with the hidden surface routines developed during this
research.
Program segment space is divided into four separate
areas: the user's main program, the Pascal support
procedures, a gap between the support procedures and the
overlay area, and the overlay area itself. When the main
program is linked, the main program will be loaded into the
low address portion of the program segment. The Pascal
support procedures are loaded directly after the main
program and as a rule take more room than the main program.
The size of the combined memory area of the first two
sections can be found by doing a preliminary link of the
main program. The number following the printout "TOTAL
CODE:" is this size. Because the linker will load the
wprogram segment starting at offset address 0000 (hex), this
is also the offset address of the end of the combined
.. program and support procedure area.
B-4
AFIT/GCS/MA/83D-9
An 80 byte gap must exist between the end of the main
code section and the start of the overlay area. Larger gaps
are acceptable and therefore the present parameter settings
use an address that will both allow more than 80 bytes of
area between the program and overlay area and allow room at
the upper end of memory for expansion of the overlays
(useful when adding debug statements). Specifying the
beginning of the overlay area is done using the Vl
parameter of the link line when linking the main program
and by using the P parameter when linking the overlays (be
SURE to use the same number in both places!). An upper
bound to this overlay area is set using the R parameter in
the main program link line.
The data area specifications are done in a similar
fashion when overlay procedures have their own separate
'data areas. However, in this implementation the main
program "owns" all of the global variables needed by the
overlays, and the overlays use only temporary variables
during their execution. Thus, after performing a
preliminary main program link, the number following "TOTAL
DATA:" is used as the D parameter on subsequent main
program links.
'inally, it should be stated that there are a few
routines that are needed by more than one overlay group
such as the matrix multiplication routine. These few
routines are placed into the "root" or main program by a
". subroutine that is added to the end of the global variable
B-5
AFIT/GCS/MA/83D-9
include file to create the compiler references for them.
The library that contains these routines (ROOT) is not
organized as an overlay but instead is joined to the main
program by the main program link.
The Present LINKMT Command Lines
Linking of the CORE to a user program requires first
linking the main program and then linking the three
overlays. The main program link will create a special .SYM
symbol file that will be used by the linker when linking
the overlays. Therefore, the main procedure must be linked
first. Of course, if the main program is changed, then both
it and all overlays must be relinked. However, because
linking is done by symbol, changes to the overlays do not
require the subsequent relinking of the main program, only
the relinking of overlays that are changed.
The present link line for linking the main program
extends further than the margins for this report, therefore
consider this line as one continuous string of characters
entered on the system console. To link the main program
enter:
LINKMT B:TESTPRG,B:ROOT/S,TRANCEND/S,FULLHEAP/S,87REALS/S,
PASLIB/S/D:2000/Vi:7000/R:FFEF/X:3000/Z:lOOO/L
LINKMT = Name of the MT+86 linker program.
B:TESTPRG - Substitute the name of the main program
B-6
AFIT/GCS/MA/83D-9
here.
B:ROOT = Library containing the procedures used by
more than one overlay.
IS = This library is searchable, so only procedures
that were referenced will be included when linking.
2. TRANCEND - Pascal Mathematics subroutine package.
FULLHEAP = Pascal Heap space mangement package.
87REALS - 8087 co-processor subroutines.
PASLIB = Main Pascal Library.
D:2000 = Set size of main program data area at 2000.
V1:7000 = Set overlay area 1 ( we only use 1)
beginning address to 7000. Overlay module numbers 1-16 will
be placed in this area. Since we have 3 overlays numbered
p 1-3, they will all start at this address.
R:FFEF = Set upper bound for overlays at FFEF
(according to Digital, positively the highest possible
address for overlays).
Z:1000 - Set the max size of the stack segment at 64K
(max size possible).
x:3000 - Set the maximum size of the heap space at
192K (maximum value is FFFF or 1 megabyte).
L - print out the procedure offset addresses as they
are linked (a good reference later when trying to find out
the size of the program area vs the system routines.)
The current Overlay link line is:
.' 'LINKMT B:TESTPRG.001B:TESTPRG/O:I,B:OVLYI,PASLIB/S/P:7000/L
B-7
AFIT/GCS/MA/83D-9
LINKMT = The Pascal MT+86 linker program.
B:TESTPRG.001 = The name of the file created during
the link, in this case the file created will be the first
overlay module for TESTPRG.
V B:TESTPRG/O:l - This file name signals to the linker
that the file to be created is going to be an overlay and
that the .SYM file to be used for linking is named
TESTPRG.SYM.
The 1 indicates that this overlay will be loaded into
the area specified by the Vl parameter of the main link.
For our case this number could be as high as 16 without
changing the loading, however, for consistancy I use the
overlay module number for this parameter.
B:OVLYl = This is the name of the overlay library to
use when creating the overlay. Obviously, when creating
overlay module number 2 this file name would be B:OVLY2.PASLIB/S - Satisfy any system subroutines not called
by the main program using PASLIB.
P:7000 - The beginning address of the overlay. This
always agrees with the Vl parameter of the main program
link line.
L - Print out the overlay procedure offset addresses
(useful when determining if an overlay has exceeded its
4L maximum size).
Using the above parameters will result in a system
that resides in memory as:
p..-,
B-8
- - .. *... ~ *..*. ........ .... ... **.'**~ * **N~.......*
AFIT/GCS/MA/83D-9
Main Program
Program Segment Support
(64K max) Procedures
Gap (80 min)
<- VI,P
Overlay Area
<- R
Data Segment Main Program
(64K max) Data Area
I Heap Space
Extra Segment
(1M max)
------------------LXStack Segment
(64K max) Stack Area
_ _ _ _- z
Unused
CPM/86
Figure 10. Memory Layout of CORE System
B-9
"."''I .. ''."' , ",'''"'.;'' ¢
....... .. . 7
AFIT/GCS/MA/83D-9
Modifing the Overlays
, Modification of the overlays is accomplished by simply
changing the procedures desired, compiling the new
procedures, creating new module libraries using LIBMT, and
finally relinking the new overlays to a root program
segment. This, is the only processing involved as long as
major additions to the overlay area of the program segment
are avoided. However, memory conflicts arise when the
overlay procedures become too large for their assigned
space.
Whenever an overlay exceeds the space set aside by the
linker by the values of Vl,P and R parameters, problems
develop when the overlay manager tries to place the overlay
into its assigned position. Located directly behind the
procedures within an overlay module is a symbol table that
will be used to find the address of procedures contained
within the overlay. In addition, this table is followed by
a record that contains from 1 to 4 thousand zeros used when
performing the overlay linkage. The overlay manager first
fills the area specified by the Vl,P and R parameters. If
there are more records in the overlay file, the overlay
manager will overwrite the last record successfully
transferred into the overlay area by the remaining records
in the overlay file until the end of the overlay file is
reached. Thus, one of the first things that will be
destroyed whenever an overlay becomes too large for the
B-10
.0
AFIT/GCS/MA/83D-9
overlay space will be the symbol table used to find
procedure addresses. When this occurs the overlay manager
will printout a fatal error message stating that it was not
able to find the requested procedure name within the.%
overlay it was assigned. This type of error can be
confirmed by looking at the linkage offset addresses for
the overlay module in which this error occurs. If the
address of the last procedure linked is over F200 (assuming
R with a value of FFEF) then it is likely that symbol table
overwrite is occuring.
When overwriting is suspected there are four basic
options available to solve the problem. First and easiest,
the user may be able to remove some debugging or other
unneccessary code from the overlay to reduce its size. The
Vl,P and parameters may be able to be changed (reduced in
address) to create more room, but this means less area
available for the user program. Another alternative is to
remove a procedure from the overlay, which usually involves
some loss of program function. Finally, the user can both
reduce the size of the symbol table found at the end of the
overlay module and eliminate the table of zeros completely
by using the undocumented system utility program called
STRIP.
Using STRIP
To use STRIP, the user must have two things. First he
B-11
AFIT/GCS/MA/83D-9
must know the beginning address of the overlay that he
wishes to reduce in size, and second he must have a list of
all the procedures within the overlay in the order in which
they were linked. The first information is simply the P
parameter used during the linking of the overlay. Finding
.4 the second bit of information is more involved.
To obtain this list of procedures in the proper order
the user should perform three steps, in sequence. First the
user should relink the overlay adding /M to the link line
to get a load map of the link. This map will list the names
of every module, procedure, and global variable used by the
overlay in the proper order for strip. However, we wish to
keep only the procedure names needed by the overlay
manager, so some method is needed to eliminate the extra
names.
The module names can be eliminated by striking thru
the names on the map that contain an alphnumeric prefix
consisting of a letter followed by 2 digits (e.g. AOOINIT).
These module names were originally created during the
Pascal code conversion process to make them unique.
Variable names are also easy to spot by examining the names
in the global variable include file and the variable
declaration section of the user's main program.
Unfortunately, some of the names left are due to Pascal
system support procedures which also must be eliminated.
These require the use of DDT86.
.,1 Prior to using DDT86, it is best to obtain the
B-12
AFIT/GCS/MA/83D-9
*starting address of the symbol table of the overlay. The
easiest method is to use the first part of the STRIP
-. utility. To get this address simply type STRIP at the
operators console. STRIP will prompt you for the name of
the overlay. After typing the name in (e.g. B:TESTPRG.003),
STRIP will prompt you for the starting address of the
overlay. Type in the P parameter (e.g. 7000) and STRIP will
print out the address of the symbol table. Exit STRIP by
typing control C.
The next step requires access to the general purpose
debugging tool named DDT86. Because of its potential
destructive power in the hands of an unfamiliar user, it is
protected on the Flight Dynamics system by a password.
After getting into DDT86 using the password, two commands
-will be issued. To read the overlay into memory so that we
can examine the symbol table use the DDT "R" (read) command
(e.g. R B:TESTPRG.003). This will place the overlay in
memory for our examination. Next, use the "D" (display)
command to print out the symbol table in ASCII using the
beginning address of the symbol table (obtained using STRIP
above) as the address to start the display (e.g. D8754).
Compare the remaining link map entries against the names in
the symbol table. Strike out any names that are not found
in the symbol table. Because of the power of DDT86, leave
this step in the hands of an experienced user of the
system.
At this point, the modified link map contains just the
B-13
V. '•4., . $ .I.. ... .* ..- . a
: . ~ L m * .. . .- U- T-~ - - ' .r " r- ' "r' r.'r - .' rrr w rrL 7' r 'r r-'
AFIT/GCS/MA/83D-9
names of the procedures in the overlay. As long as no
V procedures are added to or subtracted from the overlay,
this listing of names will remain valid (even if
modifications are done to the procedures within the
overlay).
Now it is time to actually perform the stripping
operation. First enter STRIP as before by typing in STRIP,
the overlay file name, and the starting address of the
overlay. STRIP will respond with the prompt "ENTER NEXT
NAME TO KEEP". Enter the first name on the modified map
listing. STRIP will respond with "DO YOU WISH TO KEEP
<name>?". Enter "y" and STRIP will again prompt with "ENTER
NEXT NAME TO KEEP". Enter the next name in the list,
followed by "YO etc. until the list of names is exhausted.
If you misspell a symbol table entry, enter a name out of
order, or if you type too many characters (accidentially
insert a blank) then strip will not find the name in the
symbol table and will terminate asking if you wish to keep
the now incorrect symbol table. If you make any of these
errors, type "C" and then start STRIP over again.
Once the user makes it completely through the list, he
enters a blank followed by a carriage return to force the
STRIP program to terminate (actually any incorrect name
will do but a blank is easier). STRIP will then printout
the newly created symbol table and prompt the user with "DO
YOU WISH TO KEEP?". To keep this new file the user must
enter exactly "YESDOIT" without the quotes (no other input
B-14
V, . - . a- ;- -- 'A ' - - . -
"* AFIT/GCS/MA/83D-9
will work!). STRIP will then replace the original overlay
- with a file that has a reduced symbol table and
additionally is free from the record of zeros.
This appendix has discussed the creation and
maintainance of the three CORE overlay areas. For answers
to additional questions, refer to the Pascal MT+86 Language
Reference Manual.
11
q
..
.'
B- 15
•.. ~ ~ W 7 ~ . ' .* .1* . • .~ ..~* 2 * o* i. . --.- -, o.*° . -. L I=
AFIT/GCS/MA/83D-9
- Appendix C:
r -A Ilildden Surface Interface to ::ain C07r Package
.IrThis appendix shows the interface between the main CORE subroutines
and the hidden surface subroutines. The first structure chart shows an
overall view of the CORE, with a Create Scene process that represents the
user s program. The other six processes are the six main groupings of
Subroutine Functions within the CORE.
.1@
3 LLL
-I-
9. c
=0, ,_
" -- -- ='- ._ _. .r" - o == ,
aI=U, I I
-9, = -
' I ' '=,
3 U, , _ _ _ '4
__ _ _ _ _ _ a '
--V --W%
APIT/GCS/MLA/83D-9
z* #.
~ CCL
-SJ
This~~~ Stutr-hr hw h nefaebtentehde ufc
rotnsad h anCOEpcae
C-,
-97
AFIT/GCS/MA/83D-9
* .V'' Vita
Tom Stotts Wailes was born June 29 1955 in Shreveport,
Louisiana. He graduated from First Baptist High School of
Shreveport in 1973, and attended the Air Force Academy from
which he received the degree of Bachelor of Science in
Computer Science in 1977. Upon graduation, he worked for 5
months as a test manager for the GBU-15, a guided glide
bomb. He then attended pilot training at Reese AFB, Lubbock
Texas and was unfortunately medically disqualified after
soloing in the T-37 trainer aircraft. He then served as a
programmer, systems analyst, and supervisor in the SAGE
Programming Agency, Luke AFB, Glendale Arizona until
entering the School of Engineering, Air Force Institute of
Technology, in May 1982.
Permanent Address: Rt 5 Box 129A
Coushatta, La
71019.9
.a.
.9V t-
UNCLASS IFIlED ____2___
SECURITY CLASSIFICATION OF THIS PAGE A1REPORT DOCUMENTATION PAGE
. la. REPORT SECURITY CLASSIFICATION lb. RESTRICTIVE MARKINGS
UN(.,ASSIFIED2&. SECURITY CLASSIF tCATION AUTHORITY 3. DISTRIUUTION/AVAILABILITY OF nEEPORT
Approved for public release;2. OECLASSIFICATIONDOWNGRAOING SCHEDULE Distribution unlimited.
4. PERFORMING ORGANIZATION REPORT NUMBER(S) 5. MONITORING ORGANIZATION REPORT NUMSER(S)
AFT'] ';,.CS/mA/83D-9G& NAME OF PERFORMING ORGANIZATION b. OFFICE SYMBOL 7a. NAME OF MONITORING ORGANIZATION
( If applicable)
School of Enj;ineering AFIT/ENCSc. ADDRESS (City, Stuv and ZIP Code) 7b. ADORESS (City, Stat and ZIP Coda)
Air Force Institute of Technologyright-Patter:-,n AFB, Ohio 45433
Um NAME OF FUNDINGSPONSORING Sb. OFFICE SYMBOL 9. PROCUREMENT INSTRUMENT IDENTIFICATION N4UMBERORGANIZATION (if .ppficable)
.. %
.FiIht Dnami,. - Laboratory ATVAL/FIGRSt. ADDRESS (City. Slte and ZIP Code) 10. SOURCE OF FUNDING NOS.
- . Air Force Wri,..ht Aeronautical Laboratory PROGRAM PROJECT TASK WORK UNIWright-Patter .n AFB, Ohio 45433 ELEMENT NO. NO. NO. NO.
1. TITLE (include Security Classification)
See Box 19-A;>. 12. PERSONAL AUTHOHIS)
Tom S. Wailes, n.S., Capt, USAF
1 13a, TYPE OF REPORT 13AL TIME COVERED 114. DATE OF REPORT (Yr.. Mo.. Dy; 15. PAGE COUNT. MS Thesis I FROM TO 1983 December 7 L63
1S. SUPPLEMENTARY NOTATION yc 1w
17. COSATI CODES 18. SUBJECT TERMS (Continue on reverse if~sl sLf d mnqifjSIW,4Ar)
FIELD I GROUP SUB. GR. . et-" An CA S"09 02 Computer Graphics, Microprocessors, Algorithms12 0-1
1S. ABSTRACT (Continur on ivuer. If necessary and idenIffy by block number)
Title: Placi,_ Hidden Surface Removal Within the COREGraphi.: Standard: An Example
Thesis Chain. n: Charles W. Richard Jr.
*L 20. OIsTRISUTION/AVAILABILITY OF ABSTRACT 21. ABSTRACT SECURITY CLASSIFICATION
( "J#CLASIFIOIUNLMITEO II SAME AS RPT. 0OoTIC usER S UNCLASSIFIED
22&. NAME OF RESPONSIBLE INDIVIDUAL 22b. TELEPHONE NUMBER 22c. OFFICE SYMBOL
Chuarles W. RI, hiard Jr. 513-255-3098 AFIT/E,;C
DD FORM 1473,83 APR EDITION OF I JAN 73 IS OBSOLETE. U1,CLASSIFIEDSECURITY CLASSIFICATION OF THIS P
i q.. • ..... ... .. .. ... .. . ., .. '. . *. ... .* . .. . ,*% * ..- *.%~. * ~ .~ A IAA.
Block 19 (continued):
Abstract:
A pascal based A pioposed standard (CORE) graphics system from the University of
Pennsylvania was converted to run on an 8086/8087 microcomputer. Additionally, a
non-restrictive full 3-D hidden surface removal algorithm for surfaces modeled by
opaque polyg.ons wag implemented. This algorithm is an extension of the list priority
algorithm created by Newell, Newell, and Sancha. By saiing the priority list created
by the algorithm from one batch of updates to the next, computational savings are
possible. Although the present algorithm can only be used on raster type display
surfaces, this algorithm could be used as a prelude to other scan line hidden surface
rmoval algorithms to provide support for vector type displays.
Y-4.
Ft I I
; A4
.. k 401,
2~~~~~~t I ' ~ ~ .4
S S
all
SA h:~*