Contents:
1) General references for 3-d graphics questions.
2) How do I define an object?
3) How do I define space?
4) How do I define position?
5) How do I define orientation?
6) How do I define a velocity?
7) Drawing three-dimensional objects on a two-dimensional screen.
8) Vector Math - Dot Product and Cross-Product.
9) Matrix Math
10) Collisions.
11) Perspective.
12) Z-Buffering & the Painters Algorithm & BSP-Trees.
13) Shading.
14) 3-space clipping.
15) 3-d scanning.
16) Publically available source-code.
17) Books on the topics.
What's new?
Added a bunch of new books without net-reviews and a few more http
sites.
Added some information on velocity calculations.
1) General references for 3-d graphics questions.
Well, this FAQ is just getting off the ground. Hopefully it will
touch on most of the bases you need to get started for now, and
hopefully it will expand at least as fast as you need it too. But...
regardless, things you'll want to locate for more help are Matrix
Algebra books, Physics books talking about Eulerian motion, and some
books on the Graphics Hardware you want to program for. The code
examples included in this FAQ will most likely be in C with pseudo-code
in comments.
One of the most popular references, (and one of my favorites), is:
Computer Graphics: Principles and Practice
------------------------------------------
Foley, van Dam, Feiner, and Hughes
Addison Wesley -- Reading, Massachusetts
(c) 1990. ISBN 0-201-12110-7
But, you'll also want to definitely check out the FAQ for
comp.graphics. That FAQ touches mainly on 2-D needs, but some 3-D
aspects are reviewed there, too.
2) How do I define an object?
There are lots of ways to define objects. One of the most commonly
used is the OFF (Object File Format). The OFF toolkit and a library of
objects are available via anonymous ftp from gatekeeper.dec.com -- XXX
??? (I can't find it anymore. I found it here once about 2 years ago,
but I haven't found it since). The format provides easy methods for
extensions and a base set of things you can expect for each object. The
toolkit is a bit bulky, but the file format (in ascii) is easy enough to
parse by hand.
The OFF.aoff file contains information about the object. The most
important one there is the location of the surface specification file
(usually object name.geom). This file also contains other attributes
-
and file names relevant to this object.
The OFF surface specification begins with the number of points, the
number of polygons and the number of segments.
npts nplys nsegs
This line is followed by the floating point coordinates for the points
that make up the object.
x1 y1 z1
x2 y2 z2
x3 y3 z3
.
.
.
x(npts) y(npts) z(npts)
Then, it gets a bit more complicated. The following lines begin with a
number to indicate the number of vertices in this polygon. That number
is followed by that many numbers, one for each vertex. These are given
in an order specified in the .aoff (usually conter-clockwise). So, for
example, a triangle and a pentagon which share a side are shown below.
3 1 3 4
5 2 4 3 6 7
Here is some quick and dirty sample code to read in the .geom file:
struct polygon {
int nvert; /* Number of vertices in this polygon */
int *verts; /* Vertices in this polygon */
};
struct object {
int npts; /* The number of points */
int npolys; /* The number of polygons */
int nsegs; /* The number of segments */
double *point x,*point y,*point z;
- - -
struct polygon *polys;
};
int
read geom file( char *geom file, struct object *obj )
- - -
{
FILE *fp;
int i,j;
if (!(fp = fopen(geom file,"r"))) /* Open the .geom file */
-
return -1;
/* Get header information */
fscanf(fp,"%d %d %d",&obj.npts,&obj.npolys,&obj.nsegs);
/*
** Allocate room for the points.
*/
obj.point x = (double *)malloc(obj.npts*sizeof(double));
-
obj.point y = (double *)malloc(obj.npts*sizeof(double));
-
obj.point z = (double *)malloc(obj.npts*sizeof(double));
-
for (i=0;i triplets, it will
require a fair bit of work on reading them in to turn them into
spherical coordinates. If you're looking to this FAQ for information on
how to define the space your objects will be in, I'd strongly suggest
using rectangular coordinates and some derivative of the OFF-format.
For starters, let me just throw in that while our universe may be
infinite in all directions, that doesn't make for good programming. We
have to limit ourselves to small enough numbers that we can multiply
them together without overflowing them, we can divide them without
crashing our systems, and we can add them without accidentally flipping
a sign bit.
Now, the fun begins. The simplest form of defining the Universe is
to flat out say that the Universe stretches over these coordinates, say
in the bounding box of <-65536, -65536, -65536> to <65536, 65536,
65536>. This is often referred to as a Universal Coordinate system or
an Absolute Coordinate system. Then, each object in the Universe will
be centered about some coordinate in that range. This includes your
viewpoint. Several strategies are available for dealing with the edge
of the Universe. One can make the Universe wrap around so that an
object leaving the cube at < X, Y, 65536> will re-appear in the Universe
at < X, Y, -65536>. Or, one can make objects bounce or stop at the edge
of the Universe. And, given any approach, one can have the edge of the
Universe be transparent or opaque.
In an Absolute Coordinate system, all objects must be shown from
the position of your viewpoint. This involves lots of interesting math
that we'll get into later. But, in general, an objects position with
respect to you is it's absolute position - your absolute position (with
all kinds of hell breaking loose if you can see past the edge of the
Universe). Then, after this position is calculated, it must be rotated
based on your orientation in the Universe.
Another possibility for defining space is a Relative Coordinate
system or a View-Centered Coordinate system. In this sort of system,
the Viewpoint is always at coordinates <0,0,0> and everything else in
the Universe is based relatively to this home position. This causes
funky math to come into play when dealing with velocities of objects,
but... it does wonders for not having to deal with the 'edge of the
Universe'. This is the Schroedinger's cat method of the 'edge of the
Universe'.... in the truest sense of out of sight is out of mind. Small
provisions have to be made if objects aren't to wrap around. But... a
Relative Coordinate system can be used to give the illusion of infinite
space on a finite machine. (Yes, even your 486/66DX is finite).
I'll leave spherical coordinates to a later version if people think
they'll be of use...
|