/*
A word about the 3D library. Even though this library supports
three dimensions, the matrices are 4x4 for the following reason.
With normal 3 dimensional vectors, translation is an ADDITION,
and rotation is a MULTIPLICATION. A vector {x,y,z} is represented
as a 4-tuple {x,y,z,1}. It is then possible to define a 4x4
matrix such that multiplying the vector by the matrix translates
the vector. This allows combinations of translation and rotation
to be obtained in a single matrix by multiplying a translation
matrix and a rotation matrix together. Note that in the code,
vectors have three components; since the fourth component is
always 1, that value is not included in the vector variable to
save space, but the routines make use of the fourth component
(see vec_mult()). Similarly, the fourth column of EVERY matrix is
always
0
0
0
1
but currently the C version of a matrix includes this even though
it could be left out of the data structure and assumed in the
routines. Vectors are ROW vectors, and are always multiplied with
matrices FROM THE LEFT (e.g. vector*matrix). Also note the order
of indices of a matrix is matrix[row][column], and in usual C
fashion, numbering starts with 0.
TRANSLATION MATRIX = 1 0 0 0
0 1 0 0
0 0 1 0
Tx Ty Tz 1
SCALE MATRIX = Sx 0 0 0
0 Sy 0 0
0 0 Sz 0
0 0 0 1
Rotation about x axis i degrees:
ROTX(i) = 1 0 0 0
0 cosi sini 0
0 -sini cosi 0
0 0 0 1
Rotation about y axis i degrees:
ROTY(i) = cosi 0 -sini 0
0 1 0 0
sini 0 cosi 0
0 0 0 1
Rotation about z axis i degrees:
ROTZ(i) = cosi sini 0 0
-sini cosi 0 0
0 0 1 0
0 0 0 1
-- Tim Wegner April 22, 1989
*/
#include
/* see Fractint.c for a description of the "include" hierarchy */
#include "port.h"
#include "prototyp.h"
/* initialize a matrix and set to identity matrix
(all 0's, 1's on diagonal) */
void identity(MATRIX m)
{
int i,j;
for(i=0;i FLT_MAX)
return(-1);
vlength = sqrt(vlength);
if(vlength < FLT_MIN)
return(-1);
v[0] /= vlength;
v[1] /= vlength;
v[2] /= vlength;
return(0);
}
/* multiply source vector s by matrix m, result in target t */
/* used to apply transformations to a vector */
int vmult(VECTOR s, MATRIX m, VECTOR t)
{
VECTOR tmp;
int i,j;
for(j=0;j= 0.0)
{
v[0] = bad_value; /* clipping will catch these values */
v[1] = bad_value; /* so they won't plot values BEHIND viewer */
v[2] = bad_value;
return(-1);
}
v[0] = (v[0]*view[2] - view[0]*v[2])/denom;
v[1] = (v[1]*view[2] - view[1]*v[2])/denom;
/* calculation of z if needed later */
/* v[2] = v[2]/denom;*/
return(0);
}
/* long version of vmult and perspective combined for speed */
int
longvmultpersp(LVECTOR s, LMATRIX m, LVECTOR t0, LVECTOR t, LVECTOR lview,
int bitshift)
{
/* s: source vector */
/* m: transformation matrix */
/* t0: after transformation, before persp */
/* t: target vector */
/* lview: perspective viewer coordinates */
/* bitshift: fixed point conversion bitshift */
LVECTOR tmp;
int i,j, k;
overflow = 0;
k = CMAX-1; /* shorten the math if non-perspective and non-illum */
if (lview[2] == 0 && t0[0] == 0) k--;
for(j=0;j= 0) /* bail out if point is "behind" us */
{
t[0] = bad_value;
t[0] = t[0]<= 0) /* bail out if point is "behind" us */
{
lv[0] = bad_value;
lv[0] = lv[0]<