#ifndef lint
static char *sccsid = "@(#)solidtrans.c	1.2 (Steve Hill) 3/9/90";
#endif

/* solidtrans.c
 *
 * Apply transformations to solids.
 */

#include <stdio.h>

#include "basetype.h"
#include "error.h"
#include "matrix.h"
#include "cartesian.h"
#include "point.h"
#include "vector.h"
#include "indexlist.h"
#include "ray.h"
#include "quadric.h"
#include "colour.h"
#include "surface.h"
#include "bitmap.h"
#include "pattern.h"
#include "solid.h"
#include "bbox.h"
#include "transforms.h"
#include "quadtrans.h"
#include "solidtrans.h"


/* SolidTransform
 *
 * Transform a solid using the matrix m.  Note that the matrix
 * is the inverse of the required transformation.  See the functions
 * below for enlightenment.
 */

solid_t *
SolidTransform(s, m)
solid_t		*s;
matrix_t	*m;
{
	solid_body_t	*body;

	if (s->bbox != BboxNull)
	{
		BboxFree(s->bbox);
		s->bbox = BboxNull;
	}

	body = &s->body;

	switch (s->type)
	{
	case JOIN:
		body->join.left  = SolidTransform(body->join.left,  m);
		body->join.right = SolidTransform(body->join.right, m);
		break;
	case MEET:
		body->meet.left  = SolidTransform(body->meet.left,  m);
		body->meet.right = SolidTransform(body->meet.right, m);
		break;
	case ATOM:
		body->atom.quadric = QuadricTransform(body->atom.quadric, m);
		body->atom.pattern = PatternTransform(body->atom.pattern, m);
		break;
	default:
		FatalError(__FILE__, __LINE__, "SolidTransform: Invalid solid");
	}
	return(s);
}


/* SolidT
 *
 * Translate a solid by (a, b, c).
 */

solid_t *
SolidT(s, a, b, c)
solid_t	*s;
real_t	a, b, c;
{
	matrix_t	*m;

	m = MatrixT1(a, b, c);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidS
 *
 * Scale a solid by factors (a, b, c).
 */

solid_t *
SolidS(s, a, b, c)
solid_t	*s;
real_t	a, b, c;
{
	matrix_t	*m;

	m = MatrixS1(a, b, c);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidRx
 *
 * Rotate about the x-axis by t radians.
 */

solid_t *
SolidRx(s, t)
solid_t	*s;
real_t	t;
{
	matrix_t	*m;

	m = MatrixRx1(t);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidRy
 *
 * Rotate about the y-axis by t radians.
 */

solid_t *
SolidRy(s, t)
solid_t	*s;
real_t	t;
{
	matrix_t	*m;

	m = MatrixRy1(t);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidRz
 *
 * Rotate about the z-axis by t radians.
 */

solid_t *
SolidRz(s, t)
solid_t	*s;
real_t	t;
{
	matrix_t	*m;

	m = MatrixRz1(t);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidSHx
 *
 * Shear y and z.
 */

solid_t *
SolidSHx(s, y, z)
solid_t	*s;
real_t	y, z;
{
	matrix_t	*m;

	m = MatrixSHx1(y, z);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidSHy
 *
 * Shear x and z.
 */

solid_t *
SolidSHy(s, x, z)
solid_t	*s;
real_t	x, z;
{
	matrix_t	*m;

	m = MatrixSHy1(x, z);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}


/* SolidSHz
 *
 * Shear x and y.
 */

solid_t *
SolidSHz(s, x, y)
solid_t	*s;
real_t	x, y;
{
	matrix_t	*m;

	m = MatrixSHz1(x, y);
	s = SolidTransform(s, m);
	MatrixFree(m);

	return(s);
}
