Beware, these functions are not a direct part of the svgalib library. Instead their source is part of svgalib and can be found in the threeDkit/ subdirectory of the original svgalib distribution. However, it is not installed in the system by default, s.t. it is unclear where you can find it if your svgalib was installed by some linux distribution.
In case of any such problem, simply get an svgalib distribution from the net. You even don't need to install it. Just make in the threeDkit/ subdirectory. As of this writing, svgalib-1.2.12.tar.gz is the latest version and can be retrieved by ftp from sunsite.unc.edu at /pub/Linux/libs/graphics and tsx-11.mit.edu at /pub/linux/sources/libs which will most probably be mirrored by a site close to you.
The functions are defined in the tri.o and triangl.o files (or their resp. sources) which you must link to your program.
Program flow:
It also establishes whether ROTATE_OBJECT option is on and zero's the camera position if so --- this is for displaying the object at the screen centre like in a 3D CAD package, as apposed to virtual reality where the object can be anywhere and the actual camera position can move.
In the case of ROTATE_OBJECT being on, although the camera position is zero, some distance has to be placed between the camera and the object (or else it would appear to be infinitely large on the screen). This is done using the variable s_cam which is initialized to distance which is set by the calling application. It then loops through each surface (ordering them in the way they were just sorted --- i.e. according to sortarray indexing) and calls one of five graphic routines to write the 3D surface to the hardware.
Following, each line from the 2D temp array is drawn on the screen.
To draw the surface, the corner wishbone (two lines) from each grid
square is drawn while advancing across and the down. After completing
the scan, the furthest two edges of the surface must then be filled
in, vis.:
_ _ _ _ _ _
|_|_|_|_|_|_
|_|_|_|_|_|_
|_|_|_|_|_|_
|_|_|_|_|_|_
|_|_|_|_|_|_
| | | | | |
To understand the object rotation, a knowledge of matrix multiplication is required. I once derived a camera rotation before I learned matrix computation. It amounted to the same thing, but was unnecessarily complicated to optimise.
To convert from a 3D coordinate to a 2D screen coordinate, the camera position (or more correctly, the position of the object from the camera) must first be added to each of the 3D grid coordinates. If the user has chosen to use 32 bit values for the discription of the surface, then these must be right shifted to the same size as the 16 bit case.
x, y and z now hold the 3D position of the object relative to the camera centre (or in these terms, the centre of the video screen RIGHT ON the screen). The vector [x y z] must now be multiplied by the rotation matrix. The xt value must also have the camera distance, s_cam, added to it in case the ROTATE_CAMERA is set (in which case x_cam, y_cam and z_cam (the camera position) will be zero and instead s_cam will have a value to provide the necessary object-camera distance). A test is also made as to whether this value is zero or negative. In the case, the point is too close to the camera, or behind the camera, and must not be drawn.
After the multiplication, the resulting vector [xt yt zt] has been rotated to be aligned with screen. The vector is now adjusted for perspective by dividing the yt and zt values (horizontal and vertical respectively) by the xt value (into the screen). Division is done by muldiv64 because the intermediate product is larger than 32 bits. xscale and yscale are factors that scale the image to size. posx and posy is just the centre of the screen, or more precisely:
The exact position of the pinhole camera viewing the object.
This also means that results (of multiplications with them) have to be scaled down by the same amount. This scaling is inherent in the final multiplication and division (muldiv64) done in the TD_translate function, so an extra division is not consumed.
The rotation matrix effectively rotates the vector by the Eulerian angles alpha, beta and gamma. These angles represent successive rotations about each of the 3D axes. You can test which angles do what by looking at the calling application. Their precise definitions are not all that important since you can get the keyboard to do the right thing with a little trial and error.
Intrisics of drawing non-transparent surfaces...
to be continued ?!
Paper mail:
Donations (by check or postal order) will be appreciated and will encourage further development of this software. However this is strictly on a voluntary basis where this software falls under the GNU LIBRARY GENERAL PUBLIC LICENSE.