
This is a little toy that I have been playing with on and off for the past
two years.  It is a 3D wireframe viewer/renderer, and a perfect example of
creeping featurism.  It is written with X Windows and Motif.  It has not
been optimized for eather speed or space efficiency.  It should build and run
on sparcstations, decstations, RS6000, and SGI 4.0.

Feel free to send questions/comments/requests/bugs/patches/cookies/candy.
I love to get mail!
Please clearly mark any cookies or candy so they get first priority and
don't go stale.

Eric Bina
508 E. Michigan, #35,
Urbana, IL 61801

ebina@ncsa.uiuc.edu


Anyways, in a moment of generosity I decided to share my toy with you.
(lucky you :-)  This software is provided as free as I can possible make it.
There are two modules that are not my work.  The gif image dumping code
in writegif.c belongs to David Rowley, and it says so in the beginning of the
file.  Also, I am forever in debt to Pat Kane for spending a week of his
life deciphering Perlin's paper on noise and solid texturing and producing
the module S3Noise.c which is all his (I don't even claim to totally
understand it).  With the exception of those two modules you can do whatever
you want with this code.  However, I should mention that I believe all code
should be free, and if you decide to try and make money off my work, I hope
you can sleep knowing there is someone out there who thinks you are more
disgusting than rotted slug-slime drippings.

Alas, I am terrible at documentation, so there is none (other than this
file).  However, the code is commented.  Hmmmm... So lets see what's to say.

(Please note, I am not going to proof read or spell check this README, so all
you English majors out there should grit your teeth.)

File Format:
	Sorry, I didn't use any standard file format, just one I made up.
It is really simple though, so it should be easy to convert back and forth
to your favorite renders.  It is an ascii format.  First line is number of
points in the object.  The second line is the number of triangles in the
object.  The following lines are points, one point per line described as
x y z (separated by spaces).  The rest of the lines are triangles, one triangle
per line, put the point indicies of the three corners on the line (separated
by spaces).  If you want to be able to see the object, keep x, y, and z values
all between -1.0 and 1.0.  Also not that point indicies start at 0, not 1.
Thats all you need for a basic input file.

Bells and Whistles:
	As time passed I wanted to describe more than just a bunch of
triangles.  I wanted to give a color to each triangle.  So optionally, on
each triangle description line, after the verticies, you can specify a pixel
to color that triangle with.  Example "0 1 2 P3" says draw the triangle made
up of points 0, 1, and 2 with pixel color 3.  What the hell is pixel color
three you ask?  Well, by default the colormap is a 256 shade grayscale from
black to white.  But, you can change that colormap.  At the end of the file,
just after describing the last triangle put the line "Colormap 256".
Follow that immediately by the line "red green blue"
Ok, now you can enter your colormap.  Put one color on a line which is red greenblue (separated by white space) varying between 0 and 255.  You don't have to 
specify all 256 colors, but the colors are automatically numbered in order,
so if you want to specify pixel 30, you better have specified pixels 0 through
29 first.
		Confused yet?
	Another "feature".  You can also specify an opacity to go with each
triangle.  Opacity ranges from 0.0 to 1.0, here is an example
"0 1 2 O0.5" specifies that this triangle is only 50% opaque.  What this
really means is that this triangle will only be drawn 50% of the time, and the
other 50% of the time it will not be drawn.  This means that if you have an
object made up totaly of O0.5 triangles, and each triangle is only 1 pixel
in size, it will appear as an object shaped cloud of dots on your screen.
Souds useless?  Yep, it is, but it sounded neat at the time, and when it
ended up being a disappointment, I didn't rip the code out.  Note: O0.0
is a special case.  A triangle of opacity 0.0 is actually a transparent
filter, that passes color based on its pixel value.  Example:

3
1
1.0 -0.5 0.0
-1.0 -0.5 0.0
0.0 1.0 0.0
2 0 1 P3 O0.0
Colormap 256
red green blue
0 0 0
1 1 1
255 255 255
128 0 30

The previous file describes a triangle that will pass 128/255 of the red
no green, and 30/255 blue of whatever is behind it (since this example has
nothing behind it, it will be black)
Finally, if you are going to give triangle both opacities and pixels, they
must be described pixel and then opacity.  Reversing the order will probably
make it core dump.  That's all I can think of about the object format, I
will provide a few sample objects with the code.


Command line Options:
	type "wframe -help".


I'm sorry, but I used the Motif widget set, and you need Motif to compile it.
Its is all basic widgets though, and should be easy to port to Athena or
Open Look widgets, or whatever.


All triangles are one sided.  If the normal vector points toward you, you
can see it, if not, it is transparent.  If the vertex description of a triangle
has vertices that proceed in a clockwise direction from first to last,
it will be visible.  A two sided triangle needs to be described with 2
triangles that use the same three points back to back.


When started you get 4 scrollbars and a menu bar.  The scrollbars control
rotation of the object about the X, Y, and Z axis, and its distance from the
viewer.  Rotation is always relative to the viewer, not the object.  Note,
order matters, if you rotate in X, then in Y, then unrotate the X, and then
unrotate the Y, it will NOT be back where you started, this is not a bug, it 
is the way rotation works.

What?  You don't see any image?

The "Commands" menu has a "Display" button.  This toggles on and off the
display window.  Note, because the object viewed in the display window can
sometimes take hours to draw, that window makes no attempts to redraw itself
when it receives expose events.  It will always redraw when popped up.

The "Dump" button dumps the contents of the view window.  It currently
defaults to dumping in GIF format.  The only other format it knows is ebc
format which is an image format I made up, so it is useless to you, but it
works well with all my other toys.

"Perspective" toggles off and on perspective projection of the view window.

"Lattice" re-initializes the random number array for solid texturing
functions.

"Quit" is self explanatory.

The "Read" and "Write" under the "File" menu should be obvious.  The
"Read Script" needs explaining.  Sometimes I want to make an animation, and
it takes a long time per frame.  I added a VERY BASIC scripting language to
let me describe a sequence of motions and and frames to draw.  After
executing a script the program always exits!  Script commands are of 2 kinds.

Example 1:

Draw 18
2
0
10
0
0.2

Example 2:

Move 1
2
90
0
0
-2.0

The first example says take 18 pictures at detail level 2.  On each picture
rotate 0 degrees X, 10 degrees Y, and 0 degrees Z, and add 0.2 to the objects
distance.  The texture in the picture is whatever was set before reading
the script file.

The second example shows the Move command.  This moves the object by rotating
it 90 degrees in the X and subtracting 2.0 from distance.

Any number of Draw and Move commands can be chained together.


The "Edit" menu.  WARNING: I thought I wanted to be able to edit as well as
view objects, but I didn't like the results.  I don't use this feature much
and it may be buggy.  To make a complex object, I usually write a program
to do it.
You must first choose "Select" to use any of the editing features.  This
automatically turns off the default removal of all back facing triangles.
In Edit(Select) you can click on any vertex and have it be selected, showing
you its x, y, and z values, and letting you move it in the x, y, or z direction
with the control panel.  The control panel moves all currently selected points
together.  Click again on a selected point to unselect it.
Edit(Delete) deletes all currently selected points ans all triangles that
use them!  Edit(Add) adds a triangle.  Each sequence of 3 mouse clicks adds
a triangle described by those three points.
Edit(Link) allows you to link any three verticies to make a new triangle.
The link takes the closest vertex to your mouse click.  It must be an unselected
vertex.  If it is selected, the first click unselects it, and you have to click
again to link it.

My shading model is VERY BASIC, each triangle is filled with a solid color.
To get good pictures each triangle needs to fill only one pixel.
The "Detail" menu gives you an easy way to do that.  Each level of detailing
subdivides each triangle into 4 smaller triangles.  Detail 9 is adequate to
make even the largest object  have far too many tiny triangles.

"Textures".  "Wire" displays the object as a wireframe, back facing triangles
removed.  "Shade" shades the object in a grayscale.  "Fire" is part of a
broken attempt on my part to add a neat special effect.  I think it currently
shades the object in a yellowscale.  "Granite", "Marble", and "Wood" will
render the object out of those materials based on a solid texturing and
solid noise function.  "BaseColor" just displays each triangle in the
color that was specified with the P<pixel number> option in the input file.
"BaseShade" colors each triangle with the basecolor shaded based on angle
from the lightsource (which is a point source at the viewer location).  It
does this by dynamically allocating from the colormap, and matching best fit
color once the colormap fills up.


That's All Folks!  Have Fun!

			Eric Bina
			ebina@ncsa.uiuc.edu

 
