/*
 * Title:
 *	transformation.c
 *
 * Authors:
 *	Michael P. Schenck 
 *
 * Purpose:
 *	These routines are used for constructing transformation matricies.  They 
 *	all take a variety of rotation, scaling, and translation parameters.
 * 	They include scaling-rotation-translation (srt), scaling-translation-rotation
 *	(str), x-rotation, y-rotation, z-rotation, scaling, and translating.
 *
 * Copyright Info:
 *	Copyright (C) 1993, 1994 -- by Michael P. Schenck, 
 *	(mps4466@ultb.isc.rit.edu)
 *	
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published
 *	by the Free Software Foundation; either version 2 of the License,
 *	or (at your option) any later version.
 *
 *	This software is distributed in the hope that it will be useful, but
 *	WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *      For a copy of the GNU General Public License
 *	write to the Free Software Foundation, 675 Mass Ave,
 *	Cambridge, MA  02139, USA.
 *
 */

#include <stdlib.h>
#include <math.h>
#include "/include/types.h"
#include "/include/errors.h"
#include "/include/matrix.h"
#include "/include/transformation.h"

static ULONG i,j;
static MATRIX m[MAXMATREQ];
static FLOAT sintheta,costheta;

	/* Open and allocate needed matricies. */

int opentransformation()
		
{
   for(i=0;i<MAXMATREQ;i++) {
      if((m[i] = allocatematrix()) == NULL) {
	 for(j=0;j<i;j++)
	    freematrix(m[j]);
	 return(MEM_ALLOC_FAILURE);
      }
   }
   return(SUCCESS);
}

	/* Sets a scale, rotation, and translation matrix. */
      
void setsrttrans(FLOAT sx,FLOAT sy,FLOAT sz,
		 FLOAT rx,FLOAT ry,FLOAT rz,
		 FLOAT dx,FLOAT dy,FLOAT dz,
		 MATRIX rm)

{
   setscalematrix(sx,sy,sz,m[0]);
   setrotxmatrix(rx,m[1]);
   setrotymatrix(ry,m[2]);
   setrotzmatrix(rz,m[3]);
   settransmatrix(dx,dy,dz,m[4]);
   multmatrix(m[0],m[1],m[5]);
   multmatrix(m[5],m[2],m[6]);
   multmatrix(m[6],m[3],m[5]);
   multmatrix(m[5],m[4],rm);
}

	/* Sets a matrix same as above, but translation is done before rotation.
	   Very helpful for objects that need to be rotated to a position 
	   not on an axis. */

void setstrtrans(FLOAT sx,FLOAT sy,FLOAT sz,
		 FLOAT dx,FLOAT dy,FLOAT dz,
		 FLOAT rx,FLOAT ry,FLOAT rz,
		 MATRIX rm)

{
   setscalematrix(sx,sy,sz,m[0]);
   settransmatrix(dx,dy,dz,m[1]);
   setrotxmatrix(rx,m[2]);
   setrotymatrix(ry,m[3]);
   setrotzmatrix(rz,m[4]);
   multmatrix(m[0],m[1],m[5]);
   multmatrix(m[5],m[2],m[6]);
   multmatrix(m[6],m[3],m[5]);
   multmatrix(m[5],m[4],rm);
}

	/* X-axis rotation matrix. */

void setrotxmatrix(FLOAT theta,MATRIX rm)

{
   sintheta = sin(theta);
   costheta = cos(theta);
   identitymatrix(rm);
   *(rm+5) = costheta;
   *(rm+6) = sintheta;
   *(rm+9) = -sintheta;
   *(rm+10) = costheta;
}

	/* Y-axis rotation matrix. */

void setrotymatrix(FLOAT theta,MATRIX rm)

{
   sintheta = sin(theta);
   costheta = cos(theta);
   identitymatrix(rm);
   *rm = costheta;
   *(rm+2) = -sintheta;
   *(rm+8) = sintheta;
   *(rm+10) = costheta;
}

	/* Z-axis rotation matrix. */

void setrotzmatrix(FLOAT theta,MATRIX rm)

{
   sintheta = sin(theta);
   costheta = cos(theta);
   identitymatrix(rm);
   *rm = costheta;
   *(rm+1) = sintheta;
   *(rm+4) = -sintheta;
   *(rm+5) = costheta;
}

	/* Traslation matrix. */

void settransmatrix(FLOAT dx,FLOAT dy,FLOAT dz,MATRIX rm)

{
   identitymatrix(rm);
   *(rm+12) = dx;
   *(rm+13) = dy;
   *(rm+14) = dz;
}

	/* Scaling matrix. */

void setscalematrix(FLOAT sx,FLOAT sy,FLOAT sz,MATRIX rm)

{
   identitymatrix(rm);
   *rm = sx;
   *(rm+5) = sy;
   *(rm+10) = sz;
}

	/* Closeup, releasing matricies. */

void closetransformation()

{
   for(i=0;i<MAXMATREQ;i++)
      freematrix(m[i]);
}      