home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
vr386
/
intmath.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-10
|
10KB
|
264 lines
// REND386 32-BIT INTEGER MATH LIBRARIES
// All code by Dave Stampe, last updated 23/12/93
// All routines in this library were written by Dave Stampe
// This code is available to programmers through the REND386
// project and may be used freely if attribution is given
// (see COPYRITE.H).
/*
This code is part of the VR-386 project, created by Dave Stampe.
VR-386 is a desendent of REND386, created by Dave Stampe and
Bernie Roehl. Almost all the code has been rewritten by Dave
Stampre for VR-386.
Copyright (c) 1994 by Dave Stampe:
May be freely used to write software for release into the public domain
or for educational use; all commercial endeavours MUST contact Dave Stampe
(dstampe@psych.toronto.edu) for permission to incorporate any part of
this software or source code into their products! Usually there is no
charge for under 50-100 items for low-cost or shareware products, and terms
are reasonable. Any royalties are used for development, so equipment is
often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to VR-386 and Dave Stampe,
and any other authors in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling!
DEVELOPMENT: VR-386 is a effort to develop the process started by
REND386, improving programmer access by rewriting the code and supplying
a standard API. If you write improvements, add new functions rather
than rewriting current functions. This will make it possible to
include you improved code in the next API release. YOU can help advance
VR-386. Comments on the API are welcome.
CONTACT: dstampe@psych.toronto.edu
*/
/// NOTES ON FORMATS:
//
// Several fixed-point formats are used in this library. These
// are specified by <XX.YY>, where XX is the number of bits to
// the left and YY is the number of bits to the right of the
// "decimal point". It's easy to compute how to do math with
// these (see "Virtual Reality Creations" for more information).
// The formats are:
// <32.0>: plain old integer. Used for translational part of matrices
// <16.16>: value<<16, used for angles (in degrees) and for scaling in general
// <3.29>: the optimal formats for matrix and trigonometry, with values
// between +1.0 and -1.0. Used for trig, matrix entries.
//
// Many routines expect one or the other of the above fomats: it should
// be obvious which. Some (such as magnitude) don't really care as long
// as all the arguments are in the same format.
/********* INITIALIZE: DO FIRST!!!!! ********/
extern int init_math(); // returns 0 if OK
/************* INTEGER TRIG ************/
// from intrig.asm
// numbers in <3.29> format, angles in degrees <16.16>
extern long isine(long angle);
extern long icosine(long angle);
extern long arcsine(long x);
extern long arccosine(long x);
extern long arctan2(long y, long x);
/************* MATRIX MATH ************/
// from matrix.c, matrixm.asm
// HOMOGENOUS MATRIX
typedef long MATRIX[4][3]; // row major 3x3 rotational matrix
// plus row [3] is translation
// these are the order in which axes are rotated about
#define RXYZ 1 /* matrix rotation types */
#define RYXZ 0 /* ONLY RYXZ has an inverse routine! */
#define RXZY 2
#define RZYX 5
#define RZXY 4
#define RYZX 6
/* Create rotation/translation "matrix" from angle data. */
extern void multi_matrix(MATRIX m, long rx, long ry, long rz,
long tx, long ty, long tz, int type);
extern void std_matrix(MATRIX m, // same, but type = RYXZ only
long rx, long ry, long rz,
long tx, long ty, long tz);
/* multiplies upper left 3x3 submatrices A and B giving C */
/* i.e. ROTATION ONLY */
extern void matrix_mult(MATRIX a, MATRIX b, MATRIX c);
/* multiplies matrices: A*B->C, including translational part */
/* i.e. FULL HOMOGENOUS PRODUCT */
extern void matrix_product(MATRIX a, MATRIX b, MATRIX c);
/* rotate & translate XYZ by matrix */
extern void matrix_point(MATRIX m, long *xp, long *yp, long *zp);
/* rotate XYZ by matrix */
extern void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp);
/* generate inverse of rotate matrix (transpose) */
/* ONLY WORKS FOR ORTHOGONAL MATRICES */
extern void matrix_transpose(MATRIX a, MATRIX b);
/* generate inverse of rotate/translate matrix */
extern void inverse_matrix(MATRIX a, MATRIX b);
/* create identity matrix */
extern void identity_matrix(MATRIX m);
/* copy matrix */
extern void matrix_copy(MATRIX s, MATRIX d);
/* copies upper left 3x3 submatrix, zeros translation part (bottom row) */
extern void matrix_rot_copy(MATRIX s, MATRIX d);
/* FAST INTEGER homogenous matrix -> angles (RYXZ only) */
/* Expects an unscaled rotational matrix */
extern void matrix_to_angle(MATRIX m, long *rx, long *ry, long *rz);
/* makes matrix that will xform Z axis to given vector */
extern void vector_to_matrix(MATRIX m, long x, long y, long z);
/* fixes matrix scale, needed to fix shrinkage */
/* after many matrix products */
extern void renormalize_matrix(MATRIX m);
/* replaces <col> of matrix with cross product of other two */
extern void cross_column(MATRIX m, int col);
/************* MAGNITUDES AND SQUARE ROOTS *************/
// these are really fast: avg. 200 clocks for 32 bit, 400 clocks for 62 bit
/* compute 16-bit root of a 32-bit unsigned argument */
extern long squareroot32(long x);
/* compute 31-bit root of a 62-bit unsigned argument */
/* needs top 2 bits clear for overflow */
extern long squareroot62(long xh, long xl);
/* computes magnitude of 16-bit vector */
extern long magnitude16(long a, long b, long c);
/* computes magnitude of 32-bit vector */
extern long magnitude32(long a, long b, long c);
/* scales vector */
extern void set_vector_magnitude32(long length, long *x, long *y, long *z);
/************* MISC FIXED-POINT MATH *************/
/* returns (ax+by+cz)>>29) */
/* DOT PRODUCT: massively useful for splits, visibility, etc. */
extern long dot_prod_29(long a, long b, long c, long x, long y, long z);
// another massively useful function for scaling, tweening and
// so on. Performs (a*b)/c with 64-bit intermediate result
// remainder stored in longmath_overflow
extern long mulmuldiv(long a, long b, long c);
// LONG SUPPORT: these are included since many compilers have
// rather poor (slow 16-bit) math for longs.
// Also, these support 64-bit intermediate results
// this variable is updated with remainder on division,
// and overflow on multiplies
extern long longmath_overflow;
/* perform divide, can divide 64 bit by 32 bit */
/* remainder stored in longmath_overflow */
extern long divide_long(long ahi, long alo, long b);
/* perform multiply on longs */
/* any overflow stored in longmath_overflow */
extern long mult_long(long a, long b);
// shifts 32-bit signed number left or right (>0 is left, <0 is right)
extern long_shift32(long a, int shift);
// shifts 64-bit signed number left or right (>0 is left, <0 is right)
// msdword of result is returned in longmath_overflow
extern long_shift64(long ahi, long alo, int shift);
// MISC FIXED POINT
/* perform multiplication of anything by a <3.29> matrix element */
extern long m_mult(long a, long b);
/* perform TWO multiplications of anything by a <3.29> matrix element */
extern long m2_mult(long a, long b, long c);
/* divide a by b, result in <3.29> format */
/* up to user to test for overflow or zero */
extern long divide_29(long a, long b);
/* these are used for scaling pointer return values */
/* s is a scaling factor in <16.16> format: returns s*(x+a) */
extern long scale_16(long s, long a, long x);
/* computes <16.16> scaling factor: 2s/(a-b) */
/* a and b are desired hi, lo range, s is half of current range */
extern long calc_scale_16(long a, long b, long s);
/* computes point on plane (usually y given x, z) */
/* returns (ax+cz+d)/-b) from plane equation */
extern long plane_y(long a, long b, long c, long d, long x, long z);
/* computes "city-block" distance betweeen points */
/* used because many compilers have poor long sppt */
extern long big_dist(long x1, long y1, long z1,
long x2, long y2, long z2);
/************* NOT IN LIBRARY *************/
// these are in int3d.asm, and are specific to REND386
#ifdef OBJDEF
#ifdef REPDEF // so they are declared for REND386 only
//; tests 3D selection point for best object to select */
//; returns 0x7FFFFFFF if not in obj bounds, else
//; <conservative closeness: always greater than actual>
extern long sphere_pretest(VISOBJ *obj, long x, long y, long z);
/* compute, unitize (3.29 format) normal to plane. */
/* returns -1 if normal is zero, else log2(length) */
extern int find_normal(long x1, long y1, long z1,
long x2, long y2, long z2,
long x3, long y3, long z3,
long *xn, long *yn, long *zn);
// move an object's sphere only: renderer will
// move rest when drawn
extern void matmove_osphere(VISOBJ *obj, MATRIX m);
// move the actual visible object
extern void matmove_rep(REP *rep, MATRIX m);
#endif
#endif
/* End of intmath.h */