home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / intmath.h < prev    next >
C/C++ Source or Header  |  1996-03-19  |  10KB  |  264 lines

  1. // REND386 32-BIT INTEGER MATH LIBRARIES
  2. // All code by Dave Stampe, last updated 23/12/93
  3.  
  4. // All routines in this library were written by Dave Stampe
  5. // This code is available to programmers through the REND386
  6. // project and may be used freely if attribution is given
  7. // (see COPYRITE.H).
  8.  
  9. /*
  10.  This code is part of the VR-386 project, created by Dave Stampe.
  11.  VR-386 is a desendent of REND386, created by Dave Stampe and
  12.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  13.  Stampre for VR-386.
  14.  
  15.  Copyright (c) 1994 by Dave Stampe:
  16.  May be freely used to write software for release into the public domain
  17.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  18.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  19.  this software or source code into their products!  Usually there is no
  20.  charge for under 50-100 items for low-cost or shareware products, and terms
  21.  are reasonable.  Any royalties are used for development, so equipment is
  22.  often acceptable payment.
  23.  
  24.  ATTRIBUTION:  If you use any part of this source code or the libraries
  25.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  26.  and any other authors in your documentation, source code, and at startup
  27.  of your program.  Let's keep the freeware ball rolling!
  28.  
  29.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  30.  REND386, improving programmer access by rewriting the code and supplying
  31.  a standard API.  If you write improvements, add new functions rather
  32.  than rewriting current functions.  This will make it possible to
  33.  include you improved code in the next API release.  YOU can help advance
  34.  VR-386.  Comments on the API are welcome.
  35.  
  36.  CONTACT: dstampe@psych.toronto.edu
  37. */
  38.  
  39.  
  40. ///   NOTES ON FORMATS:
  41. //
  42. // Several fixed-point formats are used in this library.  These
  43. // are specified by <XX.YY>, where XX is the number of bits to
  44. // the left and YY is the number of bits to the right of the
  45. // "decimal point".  It's easy to compute how to do math with
  46. // these (see "Virtual Reality Creations" for more information).
  47. // The formats are:
  48. // <32.0>:   plain old integer.  Used for translational part of matrices
  49. // <16.16>:  value<<16, used for angles (in degrees) and for scaling in general
  50. // <3.29>:   the optimal formats for matrix and trigonometry, with values
  51. //           between +1.0 and -1.0.  Used for trig, matrix entries.
  52. //
  53. // Many routines expect one or the other of the above fomats: it should
  54. // be obvious which.  Some (such as magnitude) don't really care as long
  55. // as all the arguments are in the same format.
  56.  
  57.  
  58. /********* INITIALIZE: DO FIRST!!!!! ********/
  59.  
  60. extern int init_math(); // returns 0 if OK
  61.  
  62.  
  63. /************* INTEGER TRIG ************/
  64. // from intrig.asm
  65.  
  66. // numbers in <3.29> format, angles in degrees <16.16>
  67.  
  68. extern long isine(long angle);
  69. extern long icosine(long angle);
  70. extern long arcsine(long x);
  71. extern long arccosine(long x);
  72. extern long arctan2(long y, long x);
  73.  
  74.  
  75. /************* MATRIX MATH ************/
  76. // from matrix.c, matrixm.asm
  77.  
  78.                 // HOMOGENOUS MATRIX
  79. typedef long MATRIX[4][3];    // row major 3x3 rotational matrix
  80.                 // plus row [3] is translation
  81.  
  82.         // these are the order in which axes are rotated about
  83. #define RXYZ 1        /* matrix rotation types */
  84. #define RYXZ 0          /* ONLY RYXZ has an inverse routine! */
  85. #define RXZY 2
  86. #define RZYX 5
  87. #define RZXY 4
  88. #define RYZX 6
  89.  
  90.     /* Create rotation/translation "matrix" from angle data.  */
  91. extern void multi_matrix(MATRIX m, long rx, long ry, long rz,
  92.              long tx, long ty, long tz, int type);
  93.  
  94. extern void std_matrix(MATRIX m,    // same, but type = RYXZ only
  95.         long rx, long ry, long rz,
  96.         long tx, long ty, long tz);
  97.  
  98.     /* multiplies upper left 3x3 submatrices A and B giving C */
  99.     /* i.e. ROTATION ONLY */
  100. extern void matrix_mult(MATRIX a, MATRIX b, MATRIX c);
  101.  
  102.     /* multiplies matrices: A*B->C, including translational part */
  103.     /* i.e. FULL HOMOGENOUS PRODUCT */
  104. extern void matrix_product(MATRIX a, MATRIX b, MATRIX c);
  105.  
  106.     /* rotate & translate XYZ by matrix */
  107. extern void matrix_point(MATRIX m, long *xp, long *yp, long *zp);
  108.  
  109.     /* rotate XYZ by matrix */
  110. extern void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp);
  111.  
  112.     /* generate inverse of rotate matrix (transpose) */
  113.     /* ONLY WORKS FOR ORTHOGONAL MATRICES */
  114. extern void matrix_transpose(MATRIX a, MATRIX b);
  115.  
  116.     /* generate inverse of rotate/translate matrix */
  117. extern void inverse_matrix(MATRIX a, MATRIX b);
  118.  
  119.         /* create identity matrix */
  120. extern void identity_matrix(MATRIX m);
  121.  
  122.         /* copy matrix */
  123. extern void matrix_copy(MATRIX s, MATRIX d);
  124.  
  125.     /* copies upper left 3x3 submatrix, zeros translation part (bottom row) */
  126. extern void matrix_rot_copy(MATRIX s, MATRIX d);
  127.  
  128.     /* FAST INTEGER homogenous matrix -> angles (RYXZ only) */
  129.     /* Expects an unscaled rotational matrix */
  130. extern void matrix_to_angle(MATRIX m, long *rx, long *ry, long *rz);
  131.  
  132.     /* makes matrix that will xform Z axis to given vector */
  133. extern void vector_to_matrix(MATRIX m, long x, long y, long z);
  134.  
  135.     /* fixes matrix scale, needed to fix shrinkage */
  136.     /* after many matrix products                */
  137. extern void renormalize_matrix(MATRIX m);
  138.  
  139.     /* replaces <col> of matrix with cross product of other two */
  140. extern void cross_column(MATRIX m, int col);
  141.  
  142.  
  143.  
  144. /************* MAGNITUDES AND SQUARE ROOTS *************/
  145.  
  146. // these are really fast: avg. 200 clocks for 32 bit, 400 clocks for 62 bit
  147.  
  148.     /* compute 16-bit root of a 32-bit unsigned argument */
  149. extern long squareroot32(long x);
  150.  
  151.     /* compute 31-bit root of a 62-bit unsigned argument */
  152.     /* needs top 2 bits clear for overflow               */
  153. extern long squareroot62(long xh, long xl);
  154.  
  155.     /* computes magnitude of 16-bit vector */
  156. extern long magnitude16(long a, long b, long c);
  157.  
  158.     /* computes magnitude of 32-bit vector */
  159. extern long magnitude32(long a, long b, long c);
  160.  
  161.     /* scales vector */
  162. extern void set_vector_magnitude32(long length, long *x, long *y, long *z);
  163.  
  164.  
  165.  
  166. /************* MISC FIXED-POINT MATH *************/
  167.  
  168.    /* returns (ax+by+cz)>>29) */
  169.    /* DOT PRODUCT: massively useful for splits, visibility, etc. */
  170. extern long dot_prod_29(long a, long b, long c, long x, long y, long z);
  171.  
  172.     // another massively useful function for scaling, tweening and
  173.     // so on.  Performs (a*b)/c with 64-bit intermediate result
  174.     // remainder stored in longmath_overflow
  175. extern long mulmuldiv(long a, long b, long c);
  176.  
  177.  
  178. // LONG SUPPORT: these are included since many compilers have
  179. //               rather poor (slow 16-bit) math for longs.
  180. //         Also, these support 64-bit intermediate results
  181.  
  182.     // this variable is updated with remainder on division,
  183.     // and overflow on multiplies
  184. extern long longmath_overflow;
  185.  
  186.     /* perform divide, can divide 64 bit by 32 bit */
  187.     /* remainder stored in longmath_overflow       */
  188. extern long divide_long(long ahi, long alo, long b);
  189.  
  190.     /* perform multiply on longs                 */
  191.     /* any overflow stored in longmath_overflow */
  192. extern long mult_long(long a, long b);
  193.  
  194.     // shifts 32-bit signed number left or right (>0 is left, <0 is right)
  195. extern long_shift32(long a, int shift);
  196.  
  197.     // shifts 64-bit signed number left or right (>0 is left, <0 is right)
  198.     // msdword of result is returned in longmath_overflow
  199. extern long_shift64(long ahi, long alo, int shift);
  200.  
  201.  
  202. // MISC FIXED POINT
  203.  
  204.    /* perform multiplication of anything by a <3.29> matrix element */
  205. extern long m_mult(long a, long b);
  206.  
  207.    /* perform TWO multiplications of anything by a <3.29> matrix element */
  208. extern long m2_mult(long a, long b, long c);
  209.  
  210.    /* divide a by b, result in <3.29> format  */
  211.    /* up to user to test for overflow or zero */
  212. extern long divide_29(long a, long b);
  213.  
  214.    /* these are used for scaling pointer return values */
  215.    /* s is a scaling factor in <16.16> format: returns s*(x+a) */
  216. extern long scale_16(long s, long a, long x);
  217.  
  218.    /* computes <16.16> scaling factor: 2s/(a-b) */
  219.    /* a and b are desired hi, lo range, s is half of current range */
  220. extern long calc_scale_16(long a, long b, long s);
  221.  
  222.    /* computes point on plane (usually y given x, z) */
  223.    /* returns (ax+cz+d)/-b) from plane equation      */
  224. extern long plane_y(long a, long b, long c, long d, long x, long z);
  225.  
  226.    /* computes "city-block" distance betweeen points  */
  227.    /* used because many compilers have poor long sppt */
  228. extern long big_dist(long x1, long y1, long z1,
  229.                  long x2, long y2, long z2);
  230.  
  231.  
  232. /************* NOT IN LIBRARY *************/
  233.  
  234. // these are in int3d.asm, and are specific to REND386
  235.  
  236. #ifdef OBJDEF
  237. #ifdef REPDEF     // so they are declared for REND386 only
  238.  
  239.     //;   tests 3D selection point for best object to select */
  240.     //;   returns 0x7FFFFFFF if not in obj bounds, else
  241.     //;   <conservative closeness: always greater than actual>
  242. extern long sphere_pretest(VISOBJ *obj, long x, long y, long z);
  243.  
  244.     /* compute, unitize (3.29 format) normal to plane.   */
  245.     /* returns -1 if normal is zero, else log2(length)   */
  246. extern int find_normal(long x1, long y1, long z1,
  247.          long x2, long y2, long z2,
  248.          long x3, long y3, long z3,
  249.          long *xn, long *yn, long *zn);
  250.  
  251.  
  252.     // move an object's sphere only: renderer will
  253.     // move rest when drawn
  254. extern void matmove_osphere(VISOBJ *obj, MATRIX m);
  255.  
  256.     // move the actual visible object
  257. extern void matmove_rep(REP *rep, MATRIX m);
  258.  
  259. #endif
  260. #endif
  261.  
  262.  
  263. /* End of intmath.h */
  264.