home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 374b.lha / 3DLibrary_v1.5 / 3d.doc < prev    next >
Text File  |  1990-05-02  |  35KB  |  1,056 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.                                      3D Library
  17.                                 version 1.5 (release)
  18.  
  19.                                   by Steven Ludtke
  20.  
  21.                                    April 28, 1990
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.                                       NOTICE
  73.  
  74.           The 3d library and all associated software in this distribution
  75.           is Copyright 1990 by Steven J. Ludtke. You have permission to
  76.           use and/or modify this code for any purpose commercial or non-
  77.           commercial with two conditions : I must be given credit in any
  78.           distributed product's documentation, and if any part of this
  79.           package is used in any commercial product (even Shareware) one
  80.           free copy of said software must be sent to me at the following
  81.           address : Steven Ludtke, 406 Yale Cir., Glenwood Springs, CO
  82.           81601; all other royalties are waived. This Copyright notice
  83.           must accompany any distributions of any part of this package,
  84.           and in general, the package should be distributed intact, with
  85.           no modifications. This notice must not be removed from the 3d.c,
  86.           test.c, and cube.c source code in this release. Modified
  87.           versions of this package may not be distributed without my
  88.           consent. If the laws in your home state make any of the
  89.           conditions in the disclaimer invalid, permission to use and
  90.           distribute any part of this package in that state is withdrawn.
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.                                         - 2 -
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.                                     Release Notes
  139.                                     -------------
  140.  
  141.           Version 1.0 :  The initial release. It used a very primitive
  142.             sorting routine which proved to be insufficient for general
  143.             hidden surface removal. It also did perspective views
  144.             incorrectly, although it was not terribly obvious.
  145.  
  146.           Version 1.5 (beta) : It fixes the above bugs and
  147.             adds an additional method for specifying viewing angles and
  148.             positions. The simple sorting routine for hidden surface
  149.             removal is still available, since it is much faster and
  150.             will work in some cases. The new routine is used by default.
  151.             Please mail bug reports to the address found at the end of the
  152.             doc file. I've been busy, so assembly language will have to
  153.             wait for the next version.
  154.                The supplied makefile, etc ... is for Manx 5.0. It should
  155.             work with Lattice, but I haven't tried it. It should also work
  156.             with Manx 3.6 with appropriate makefile mods. I didn't use
  157.             prototypes, but I did use precompiled include files. If you're
  158.             not using Manx 5.0, you'll have to tack include.c to the top
  159.             of 3d.c to get things to work.
  160.  
  161.           Version 1.5 (release) : A number of problems with the new
  162.           surface sorting algorithm were found in beta testing. I fixed
  163.           most of these, but eventually decided to take a new approach. A
  164.           slightly improved version of the simple sorting routine is used
  165.           in the package. The complex routine has been removed. A friend
  166.           of mine wrote a 3d editor for files in the standard .3d file
  167.           format I use. I included (with his permission) executable for
  168.           this editor. It's pretty spiffy. A few new .3d files have also
  169.           been included. Oh yeah, the Z axis points in the right direction
  170.           now.
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.                                         - 3 -
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.                                     Introduction
  205.                                 ---------------------
  206.  
  207.             This library represents an attempt to provide the Amiga
  208.           community with a high speed, easy to use 3d display library for
  209.           C programmers. The library uses the transformation matrix
  210.           method, which is the fastest method I know of doing 3d
  211.           transformations while still providing relatively intuitive
  212.           rotations. Integer arithmetic is used for speed. Additionally,
  213.           the data is stored in a format that will make it easy to
  214.           optimize the code in assembly language. I wrote the code for
  215.           Aztec C (5.0), but I haven't converted anything to assembly
  216.           language yet, so the current version should work with Lattice as
  217.           well.
  218.             A number of beta-testers used Lattice with the library with
  219.           complete success. They said a few obvious changes were required,
  220.           but other than that, everything went fine. (Be SURE to use the
  221.           FFP library, not one of the double prec. libraries. There is a
  222.           factor of 2 speed difference involved.)
  223.             The library provides what I consider relatively high speed 3d
  224.           displays. It can rotate and draw roughly 500 lines/second (with
  225.           the FFP library). Once I've converted the rotation code to
  226.           optimized assembly, I expect the time required for the
  227.           calculation portion of the display to be reduced by at least a
  228.           factor of 2. Surface drawing is somewhat slower, depending on a
  229.           variety of factors. It is still reasonably fast.
  230.             Since a number of the parameters used in the library are
  231.           application specific, the 'library' is actually a C source file
  232.           that you include in your program. This is done primarily for
  233.           speed. If some of the parameters were variables rather than
  234.           #defines, the library would run significantly slower. The code
  235.           is relatively small, and it seems unlikely that more than one 3d
  236.           application would be active at one time, so C source seems to me
  237.           to be a reasonable way to go. If anyone has a better idea for
  238.           future versions, I'd love to hear it.
  239.  
  240.             Included in this package are the following :
  241.           3d.c     - The actual library code. This file is included in any
  242.                      program you use the 3d routines in. It must appear in
  243.                      the correct place in your program. Read the instr. or
  244.                      look at one of the sample programs for more info.
  245.           include.c- used to precompile all standard includes. Otherwise
  246.                      put at the beginning of 3d.c.
  247.           3d.doc   - This file.
  248.           makefile - An Aztec 5.0 makefile for the two sample programs.
  249.           cube.c   - A sample program that does double buffered animation
  250.                      of a cube moving around. There is a reason it doesn't
  251.                      move very smoothly. Look at the code before you think
  252.                      that's the best the library can do.
  253.           test.c   - A sample program that allows you to display 3d files
  254.                      that are in a standard (non-IFF) format. Several
  255.                      sample files are included. Look at the source for
  256.                      instructions.
  257.  
  258.  
  259.                                         - 4 -
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.           *.3d    - Various files of 3d data (non-IFF) for use with test.c
  271.           maze.3d - This example contains a large 'floor' that won't sort
  272.                     correctly with filled surfaces. It is an example of
  273.                     what NOT to do.
  274.           earth.3d- This example contains non-planar surfaces. You'll note
  275.                     that it won't work well with the complex sorting
  276.                     routine (it does work with the simple one,though).
  277.           edit    - A 3d editor written by a friend of mine. No source is
  278.                     included with this release. He compiled it with
  279.                     Lattice, and I think he might have used a double prec.
  280.                     math library. This could slow it down a bit more than
  281.                     is necessary.
  282.           edit.doc- Docs for the editor.
  283.  
  284.             The two sample programs were written for Aztec C ver 5.0. A
  285.           few changes are necessary to use them with Lattice, but they
  286.           will work.
  287.  
  288.             Hopefully most of the bugs have been worked out by now. If you
  289.           do find a bug (or have some questions), please let me know so I
  290.           can try to fix it.
  291.  
  292.           I can be contacted via any of the following :
  293.           stevel@tybalt.caltech.edu  (until June 90)
  294.           stevel@citiago.bitnet      (until June 90)
  295.           gluon@theta.caltech.edu
  296.           72335,1537  (compuserve)
  297.           Steve Ludtke, 1-54 Caltech, Pasadena CA 91126   (until June 90)
  298.           Steve Ludtke, 406 Yale Cir, Glen. Spgs. CO 81601 (after that)
  299.  
  300.             My current plans for the next version are as follows :
  301.           1. Convert much of the code to assembly for speed.
  302.           2. Perhaps I'll try to add some primitive shading routines
  303.           (simple lighting effects).
  304.           3. More complete x-specs support ???
  305.           4. A more intelligent surface sorting routine (faster).
  306.           5. Some object oriented routines to sit on top of the current
  307.           library.
  308.           6. Anything you suggest ...
  309.  
  310.             Please talk to me. I like to get mail. Btw, this code should
  311.           be pretty easy to convert for use on other machines. All you
  312.           really need to change is the actual graphics function calls.
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.                                         - 5 -
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.             Here's the actual programming info. Info on structures follows
  337.           the function information. I tried to make it as easy to use as
  338.           possible.
  339.  
  340.             Before your try to write your own code, you should probably
  341.           look at one of the examples. I'll summarize the basic steps in
  342.           using the library here :
  343.  
  344.             Before the #include "3d.c" statement, you need to have several
  345.           #define statements in you program. If necessary you can replace
  346.           some of the defines with global variables, but you should avoid
  347.           this as it will slow the program down. The defines you need are
  348.           as follows :
  349.  
  350.           #define D3VDIST  256   <- This is the distance from the
  351.                                      observer to the vanishing point. It
  352.                                      is only used with rotatev(), and
  353.                                      rotatevp(). Please read about it.
  354.           #define REZ 1024        <- Since the program uses integer
  355.                                      math, it must use several bits
  356.                                      for fractional calculations. 1024
  357.                                      would give 3 digits of accuracy. This
  358.                                      number needs to be a power of 2 for
  359.                                      upward compatibility. In general it
  360.                                      should be roughly as large as the
  361.                                      # of pixels in the display you use.
  362.                                      The larger it is, the smaller your
  363.                                      space for points is. REZ=1024 leaves
  364.                                      you with 20 bits for each of: x,y,z.
  365.           #define XCEN 250        <- This is the x coord (in the bitmap)
  366.                                      of the center (x=0) coordinate for 3d
  367.                                      displays.
  368.           #define YCEN 100        <- Same for y coord.
  369.           #define XHI  600        <- This is the highest x value in your
  370.                                      bitmap. Anything above this will be
  371.                                      clipped by the drawing routines.
  372.           #define YHI  180        <- Same for y.
  373.           #define XLO  0          <- Low x clipping value.
  374.           #define YLO  0          <- Low y clipping value.
  375.           #define ASPECT  23/10   <- This is the aspect ratio used to
  376.                                      insure a square coord system on the
  377.                                      screen. 23/10 is correct for 640X200
  378.                                      mode. Obviously 11/10 should be used
  379.                                      in 320X200 mode.
  380.           #include "3d.c"
  381.  
  382.  
  383.  
  384.             Now, set up a VECTOR structure. You'll need to get free memory
  385.           for all 6 arrays it points to. Set up a LINES structure with
  386.           sufficient memory, too. Once, this is done, you can load your 3d
  387.           data into the structures.
  388.             Now set up a window or screen (something with a valid
  389.           RastPort), or two for double buffering, or four for double
  390.  
  391.                                         - 6 -
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.           buffered x-specs displays. If you intend to use d3surf(), call
  403.           Init3Ras() with all your RastPorts.
  404.             Now SetDrMd() for all RastPorts. If you don't have color data
  405.           in your LINES structure, also do a SetAPen() and a SetOPen()
  406.           (for surfaces) for all RastPorts.
  407.             Now you can actually display data. setxfm() or setxfm2() can
  408.           be used to set the viewpoint for the display. rotatev(),
  409.           rotate(), rotatep(), or rotatevp() can be used to actually
  410.           perform the rotations with or without perspective. d3surf() and
  411.           d3lines() can then be used to render the data in a RastPort.
  412.             When you're all done, don't forget to call Exit3d() if you
  413.           called Init3Ras(). DON'T call it if you only used d3lines().
  414.           Simple huh ??? : )
  415.  
  416.             No real x-specs support code is provided in this release. You
  417.           still have to set up the code to drive the glasses yourself.
  418.           This library is ideal, however, for doing the actual drawing.
  419.           Just pick a point the person is looking at, then set up two
  420.           viewing positions, one for each eye. This should be quite easy
  421.           using the setxfm2() routine.
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.                                         - 7 -
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.           FUNCTION DEFINITIONS :
  470.  
  471.           setxfm - Set rotation and translation values for next xform.
  472.  
  473.           USAGE :
  474.           setxfm(a1,a1,a3,x,y,z,m,d)
  475.           double a1,a2,a3;
  476.           long x,y,z,m,d;
  477.  
  478.           FUNCTION :
  479.               This routine sets transformation matrix values based on the
  480.           parameters you pass it. The actual matrix is a global array,
  481.           however for upward compatibility's sake, you shouldn't access it
  482.           except through this routine.
  483.  
  484.           INPUTS :
  485.               The three parameters, 'a1-a3' are rotation angles in radians
  486.           (see the description of rotations following the structure
  487.           definitions). 'x','y','z' are translation parameters. Since
  488.           positional values are integral, the translation values must also
  489.           be integral.
  490.              'n' and 'd' are scaling factors. Since integer arithmetic is
  491.           used, a fraction is used for the scaling factor. 'n' is the
  492.           numerator and 'd' is the denominator of the scaling factor. The
  493.           way this is implemented, it doesn't slow the translations down,
  494.           so if you don't need it just set 'n' and 'd' to 1. It will be
  495.           just like they didn't exist.
  496.  
  497.           OUTPUTS :
  498.           None.
  499.  
  500.           ---------------------------------------
  501.           setxfm2 - Set rotation and translation values for next xform.
  502.  
  503.           USAGE :
  504.           setxfm(x,y,z,dx,dy,dz,m,d)
  505.           long x,y,z,dx,dy,dz,m,d;
  506.  
  507.           FUNCTION :
  508.               This routine sets transformation matrix values based on the
  509.           parameters you pass it. The actual matrix is a global array,
  510.           however for upward compatibility's sake, you shouldn't access it
  511.           except through this routine.
  512.               The only difference between this routine and setxfm() is how
  513.           the viewing angle is specified. rotatep() or rotatevp() is
  514.           normally used with this routine.
  515.           INPUTS :
  516.               'x','y', and 'z' are translation factors, just like those
  517.           used in setxfm(). If rotatep() or rotatevp() is used, these
  518.           variables are used to specify the location of the viewer.
  519.             'dx','dy', and 'dz' are then used to specify viewing
  520.           direction. These variables define a vector pointing in the
  521.           direction to be looked in. The length of this vector affects
  522.  
  523.                                         - 8 -
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.           nothing. Z will always be upwards on the screen, unless looking
  535.           straight up or straight down. For example, a viewer at (-10,-
  536.           10,-10) looking towards the origin would be defined by :
  537.           setxfm2(-10,-10,-10,10,10,10,n,d).
  538.              'n' and 'd' are scaling factors. Since integer arithmetic is
  539.           used, a fraction is used for the scaling factor. 'n' is the
  540.           numerator and 'd' is the denominator of the scaling factor. The
  541.           way this is implemented, it doesn't slow the translations down,
  542.           so if you don't need it just set 'n' and 'd' to 1. It will be
  543.           just like they didn't exist.
  544.  
  545.           OUTPUTS :
  546.           None.
  547.  
  548.           ---------------------------------------
  549.           rotate - Rotates an array of vectors using the current setxfm()
  550.           vals without perspective.
  551.  
  552.           USAGE :
  553.           rotate(v,n)
  554.           VECTOR *v;
  555.           int n;
  556.  
  557.           FUNCTION:
  558.           This routine actually performs the translation of a group of
  559.           points in 3-space based on the parameters set by setxfm().
  560.  
  561.           INPUTS :
  562.           'v' points to a vector structure which must be initialized with
  563.           pointers to all 6 arrays of size >='n'. The first 'n' vectors
  564.           will be rotated. Note that the 'x','y','z' VECTOR values are
  565.           unchanged. These values are transformed, and the results are
  566.           stored in 'tx','ty','tz'. If you wish to transform a subset of
  567.           the points, a separate VECTOR structure pointing to the
  568.           beginning of the subset can be used.
  569.  
  570.           OUTPUTS:
  571.           none.
  572.  
  573.           ---------------------------------------
  574.           rotatev - Rotates an array of vectors using the current setxfm
  575.           vals with perspective.
  576.  
  577.           USAGE :
  578.           rotatev(v,n)
  579.           VECTOR *v;
  580.           int n;
  581.  
  582.           FUNCTION:
  583.           This routine actually performs the translation of a group of
  584.           points in 3-space based on the parameters set by setxfm(). The
  585.           only difference between this routine and rotate() is the
  586.           addition of perspective.
  587.  
  588.  
  589.                                         - 9 -
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.           INPUTS :
  601.           'v' points to a vector structure which must be initialized with
  602.           pointers to all 6 arrays of size >='n'. The first 'n' vectors
  603.           will be rotated. Note that the 'x','y','z' VECTOR values are
  604.           unchanged. These values are transformed, and the results are
  605.           stored in 'tx','ty','tz'. If you wish to transform a subset of
  606.           the points, a separate VECTOR structure pointing to the
  607.           beginning of the subset can be used.
  608.  
  609.           OUTPUTS:
  610.           none.
  611.  
  612.           ---------------------------------------
  613.           rotatep - Rotates an array of vectors using the current setxfm
  614.           vals.
  615.  
  616.           USAGE :
  617.           rotatep(v,n)
  618.           VECTOR *v;
  619.           int n;
  620.  
  621.           FUNCTION:
  622.           This routine actually performs the translation of a group of
  623.           points in 3-space based on the parameters set by setxfm(). The
  624.           only difference between this routine and rotate() is that
  625.           translations are done before, not after rotations. This makes
  626.           this routine work correctly with setxfm2().
  627.  
  628.           INPUTS :
  629.           See rotate()
  630.  
  631.           OUTPUTS:
  632.           none.
  633.           ---------------------------------------
  634.  
  635.           rotatevp - Rotates an array of vectors using the current setxfm
  636.           vals with perspective.
  637.  
  638.           USAGE :
  639.           rotatev(v,n)
  640.           VECTOR *v;
  641.           int n;
  642.  
  643.           FUNCTION:
  644.           This routine actually performs the translation of a group of
  645.           points in 3-space based on the parameters set by setxfm(). The
  646.           only difference between this routine and rotatev() is that
  647.           translations are perfomed before, not after rotations. This
  648.           routine should be used with setxfm2().
  649.  
  650.           INPUTS :
  651.           See rotatev()
  652.  
  653.           ---------------------------------------
  654.  
  655.                                        - 10 -
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.           Init3Ras - Sets a rastport up for area fills.
  668.  
  669.           USAGE:
  670.           Init3Ras(rp,rp2,rp3,rp4)
  671.           struct RastPort *rp,*rp2,*rp3,*rp4;
  672.  
  673.           FUNCTION:
  674.           This routine should be called once for each RastPort to be used
  675.           with d3surf(). If it is called more than once with the same
  676.           RastPort it could cause serious problems. This routine only
  677.           needs to be called if d3surf() is going to be used. If only
  678.           d3lines() is going to be used, you can save some memory by not
  679.           calling this routine.
  680.  
  681.           INPUTS:
  682.           'rp'-'rp4' point to RastPorts which will be used with d3surf().
  683.           d3surf uses area fill operations, so the RastPort it uses must
  684.           be given temporary storage for use in the filling. 'rp2'-'rp4'
  685.           should be set to NULL if only one RastPort is to be used. If
  686.           both are passed, they will be assigned the same temporary
  687.           storage area, thus saving a significant amount of memory.
  688.             This routine allows multiple rastports for use in double-
  689.           buffering and x-specs. If double-buffered, x-specs animation is
  690.           performed, 4 screens will be required.
  691.  
  692.           OUTPUTS:
  693.           None.
  694.           ---------------------------------------
  695.           Exit3d - Frees up the memory allocated by Init3Ras.
  696.  
  697.           USAGE :
  698.           Exit3d(rp)
  699.           struct RastPort *rp;
  700.  
  701.           FUNCTION:
  702.           This routine frees up the memory allocated by Init3Ras().
  703.  
  704.           INPUTS:
  705.           'rp' points to a RastPort initialized with Init3Ras(). If 2 or
  706.           more RastPorts were initialized with a SINGLE call to
  707.           Init3Ras(), only ONE of them should be passed to Exit3d(), and
  708.           none should be used with area fills again.
  709.             I should explain this in more detail. If two RastPorts are
  710.           initialized with a single Init3Ras() call, both RastPorts will
  711.           point to the same scratch memory area. Exit3d() frees this
  712.           memory up. After you call it for one of the two RastPorts, the
  713.           other one will point to an unallocated area in memory. If a fill
  714.           operation is done at this time, it can cause all sorts of nasty
  715.           problems. Be warned.
  716.  
  717.           OUTPUTS:
  718.           None.
  719.  
  720.  
  721.                                        - 11 -
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.           ---------------------------------------
  733.           d3lines - Draw a group of lines connecting points in 3 space.
  734.  
  735.           USAGE:
  736.           d3lines(vector,line,n,rp)
  737.           VECTOR *vector;
  738.           LINES *line;
  739.           int n;
  740.           struct RastPort *rp;
  741.  
  742.           FUNCTION:
  743.           This routine actually draws lines connecting one or more points
  744.           in 3-space. See the information on the VECTOR and LINES
  745.           structures for more info.
  746.  
  747.           INPUTS:
  748.           'vector' points to a VECTOR structure with information on the
  749.           points to be used in the line drawing. 'line' points to an array
  750.           of LINES structures which contains a description of how the
  751.           lines are to be drawn. 'n' is the number of elements in the
  752.           array pointed to by 'line'. 'rp' points to the RastPort where
  753.           the lines should be drawn.
  754.  
  755.           OUTPUTS:
  756.           none.
  757.  
  758.           ---------------------------------------
  759.           d3surf - Draw a group of surfaces in 3 space.
  760.  
  761.           USAGE:
  762.           d3lines(vector,line,n,rp)
  763.           VECTOR *vector;
  764.           LINES *line;
  765.           int n;
  766.           struct RastPort *rp;
  767.  
  768.           FUNCTION:
  769.           This routine is just like d3lines(), except filled polygons are
  770.           drawn rather than lines. The polygons are sorted before drawing,
  771.           so hidden line removal is accomplished. PLEASE READ ABOUT HIDDEN
  772.           LINE REMOVAL BELOW.
  773.  
  774.           INPUTS:
  775.           'vector' points to a VECTOR structure with information on the
  776.           points to be used in the surface drawing. 'line' points to an
  777.           array of LINES structures which contains a description of how
  778.           the surfaces are to be drawn. 'n' is the number of elements in
  779.           the array pointed to by line. 'rp' points to the RastPort where
  780.           the surfaces should be drawn.
  781.  
  782.           OUTPUTS:  none.
  783.  
  784.  
  785.  
  786.  
  787.                                        - 12 -
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.           STRUCTURES :
  799.  
  800.           VECTOR ->
  801.           long *x,*y,*z;
  802.           long *tx,*ty,*tz;
  803.  
  804.             This structure points to the data for all the vertices that
  805.           are transformed. 'x','y','z' are arrays with the untransformed
  806.           vertex information. 'tx','ty','tz' are arrays which contain the
  807.           transformed equivalents of the vertices. 'tx','ty','tz' are
  808.           filled in by rotate() and rotatev(). They must be initialized to
  809.           point to sufficiently large areas of free memory by the user.
  810.             The 'x','y','z' values represent vertical pixels on the
  811.           screen. ie - the point (10,1,10) without perspective would
  812.           appear 10 pixels below and 23 pixels to the right of the defined
  813.           center (using a 23/10) aspect ratio.
  814.           -----------------------------------------
  815.  
  816.           LINES ->
  817.           unsigned short l;
  818.           unsigned short nl : 1,nc : 1, nco : 1;
  819.  
  820.             For those of you not familiar with the above notation, nl, nc,
  821.           and nco are 1 bit integers allocated within a single unsigned
  822.           short. An array of LINES structures contains the information for
  823.           line/polygon drawing. The fact that 'l' is allocated as a short
  824.           means that you can't have more than 2^16 vertices in any single
  825.           array. Hopefully this won't present any problems.
  826.           The array of LINES should be used as follows :
  827.           'l' contains a vertex number in a VECTOR structure or a color
  828.           (see below).
  829.  
  830.           'nl' is set if this vertex is the beginning of a new
  831.           line/polygon.
  832.  
  833.           'nc' is set if 'l' represents a new fill color for polygons.
  834.  
  835.           'nco' is set if 'l' represents a new outline color for polygons,
  836.           or a new line color for line drawing.
  837.  
  838.             If filled shapes are to be drawn, not just lines, be sure to
  839.           start a new line for each new polygon. That is, don't draw two
  840.           filled shapes with one continuous line. This would look fine
  841.           with d3lines(), but would produce strange effects with d3surf().
  842.           Make sure all filled shapes are planar. The new surface sorting
  843.           routine requires all surfaces to be planar. Incorrect sorting
  844.           may occur if non-planar shapes are drawn.
  845.             Color changes with d3lines() may occur anywhere. However,
  846.           color changes used with d3surf() must occur only immediately
  847.           after a nl=1 element. This is due to the way hidden line removal
  848.           works. Every nl=1 element is taken to be the beginning of a new
  849.           polygon. These polygons are then sorted so the farthest ones are
  850.           drawn first. Color changes occurring before a nl=1 point will be
  851.           attached to the wrong polygon when they are sorted. Color
  852.  
  853.                                        - 13 -
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.           changes in the middle of the shape may not have the desired
  865.           effect (after 1 or more lines have been added).
  866.  
  867.           Here is a sample LINES array to make this all more clear :
  868.  
  869.               l   nl   nc   nco
  870.           0   0    1    0    0          <- Starts a shape, vertex 0
  871.           1   2    0    0    1          <- Changes to outline color 2
  872.           2   1    0    1    0          <- Changes to filled color 1
  873.           3   1    0    0    0
  874.           4   2    0    0    0
  875.           5   3    0    0    0
  876.           6   0    0    0    0          <- Closes the shape, not necessary
  877.                                            for d3surf().
  878.           7   3    0    0    1          <- Changes outline color. This is
  879.                                            fine for d3lines(), but won't
  880.                                            change correctly for d3surf().
  881.           8   4    1    0    0          <- New shape
  882.           9   5    0    0    0
  883.           10  6    0    0    0          <- No color was defined after the
  884.                                            new shape started, so the color
  885.                                            from the last drawn shape will
  886.                                            be used. The shape is not
  887.                                            closed. d3surf() will close the
  888.                                            shape anyway. d3lines won't.
  889.  
  890.             In the above example, 0-6 will draw a quadrilateral in color 2
  891.           if d3lines() is used. It will draw a filled quad., filled with
  892.           color 1 and outlined in color 2, if d3surf() is used.
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.                                        - 14 -
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.           ROTATIONS, AND HOW THEY'RE DONE
  931.           -------------------------------
  932.             This program uses a very standard scheme for rotating objects
  933.           which is completely general. That is, you can observe your
  934.           'scene' from absolutely any imaginable perspective (within the
  935.           bounds of integer math).
  936.             The axes are set up as follows :
  937.  
  938.                Z|   / Y
  939.                 |  /
  940.                 | /
  941.                 |/
  942.                 -------------
  943.                             X
  944.  
  945.            That is, the X axis is the screen x axis, the Z axis is the
  946.           screen y axis, and the Y axis goes positive into the screen.
  947.  
  948.             Rotations (for setxfm) are defined in terms of three steps.
  949.           'a1' defines a rotation angle from the X axis in the X-Y plane.
  950.           'a2' then rotates the specified number of radians away from the
  951.           Z axis in the Y-Z plane. Finally 'a3' defines a rotation in
  952.           radians from the new (rotated) X axis in the new X-Y plane.
  953.             Explained another way : Say the ground is in the X-Y plane, ie
  954.           going into the screen. 'a1' would spin an object resting on the
  955.           ground as if it were a top. 'a2' would cause this rotated object
  956.           to tilt on the screen, just like the Aster*ids spaceship spins.
  957.           'a3' would take the tilted object and spin it along the tilted
  958.           plane. a3 is a bit hard to picture, play with it.
  959.             I know this is somewhat complex, but you can do any possible
  960.           rotation with it once you get the hang of it. It may also be
  961.           easier to visualize if you picture the observer moving, rather
  962.           than the object being rotated. I may try to add a few other
  963.           schemes in the next version. We'll see what I can find.
  964.             For those of you who are interested you can see how this
  965.           transformation works in "Classical Mechanics" by Goldstein on
  966.           page 146. (What can I say, I'm a physics major.)
  967.             The new setxfm2() routine uses the same translation scheme as
  968.           above. It simply converts the information you give it to
  969.           setxfm() form. a3 is always set to 0.
  970.             To display shapes from setxfm2() as explained, rotatep() or
  971.           rotatevp() must be used. These routines perform the translation
  972.           operation before the rotation operation. That is, they are
  973.           designed to be used with a viewer that is moving around in 3-
  974.           space, rather than a fixed viewer with moving objects. (objects
  975.           can always be moved by changing their 'x','y','z' coords before
  976.           a call to rotate). For the record, it would have been possible
  977.           to implement this with the old rotate routines, but the new
  978.           routines should do it a little faster.
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.                                        - 15 -
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.           Hidden Surface Removal
  997.           ----------------------
  998.             This has been the single biggest headache in the development
  999.           of this library. Ver 1.5(beta) included an 'improved' routine
  1000.           that would do hidden surface removal perfectly with any set of
  1001.           planar shapes. Unfortunately, there was quite a lot of overhead
  1002.           in this routine, and I found it unbearably slow. I also never
  1003.           got it working 100% (I did get close). Eventually I got fed up
  1004.           and decided to do things the fast, but less friendly, way.
  1005.             An improved simple sorting routine is used in the release
  1006.           version. It sorts surfaces (planar surfaces are still pretty
  1007.           necessary) by doing a quicksort on the average y position of
  1008.           each surface. It is quite speedy, but it has a number of
  1009.           limitations.
  1010.             This routine will work fine as long as you restrict yourself
  1011.           so all surfaces that are close together are roughly the same
  1012.           size. If you need to make very large surfaces near very small
  1013.           surfaces, break the large one up into several smaller ones.
  1014.           Large, strange shapes, like the floor in maze.3d will cause
  1015.           problems. (that's why I included maze.3d)
  1016.             Essentially, the way to do high speed display of a series of
  1017.           3d objects is to separate objects (groups of surfaces), sort the
  1018.           objects, then sort the surfaces within the object. As long as
  1019.           objects don't overlap in strange ways, this is the way to go.
  1020.             So, what you should do is set up several different LINES
  1021.           structures (all points can go in one VECTOR structure). Each
  1022.           LINES structure will contain data for one 'object'. Sort the
  1023.           objects yourself, then call d3surf for each.
  1024.  
  1025.             I plan to write a set of object oriented routines that will
  1026.           sit on top of the present library and make the above process
  1027.           more automatic. I hope to support routines like new_object(),
  1028.           add_surface(), move_object(), draw_object(), draw_objects(), etc
  1029.           ...   This should make the library considerably more user
  1030.           friendly (if I find time to do it in the near future).
  1031.           ---------
  1032.  
  1033.             Again, if you run into any bugs or problems please let me
  1034.           know. Also keep in mind that, while you may feel free to modify
  1035.           this code, you might have upward compatibility problems if you
  1036.           do. I tried to comment the code a little for those of you who
  1037.           feel like making changes. Have fun !!!
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.                                        - 16 -
  1052.  
  1053.  
  1054.  
  1055.  
  1056.