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

/* hitdata.c
 *
 * Routines to manipulate the hitdata structure - this is used to
 * hold all relevant information on an intersection.
 */

#include <stdio.h>

#include "basetype.h"
#include "cartesian.h"
#include "matrix.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 "malloc.h"
#include "error.h"
#include "list.h"
#include "hitlist.h"
#include "hitdata.h"


/* HitData
 *
 * Allocate and initialise a hitdata structure.
 */

hit_data_t *
HitData(solid, point, normal)
solid_t		*solid;
point_t		*point;
vector_t	*normal;
{
	hit_data_t	*hit_data;

	hit_data = (hit_data_t *) malloc(sizeof(hit_data_t));
	if (hit_data == HitDataNull)
		FatalError(__FILE__, __LINE__, "Hit: Out of memory");

	hit_data->solid    = solid;
	hit_data->point    = point;
	hit_data->normal   = normal;

	return(hit_data);
}


/* HitDataLet
 *
 * Set up a hitdata structure to specified value.
 */

hit_data_t *
HitDataLet(hit_data, solid, point, normal)
hit_data_t	*hit_data;
solid_t		*solid;
point_t		*point;
vector_t	*normal;
{
	hit_data->solid    = solid;
	hit_data->point    = point;
	hit_data->normal   = normal;

	return(hit_data);
}


/* HitDataPrint
 *
 * Print hitdata structure to specified file.
 */

void
HitDataPrint(file, hit_data)
FILE		*file;
hit_data_t	*hit_data;
{
	if (hit_data = HitDataNull)
	{
		fprintf(file, "Null HitData\n");
		return;
	}
	PointPrint(file, hit_data->point);
	VectorPrint(file, hit_data->normal);
}


/* HitDataFree
 *
 * Free specified hitdata structure, and sub-components.
 */

void
HitDataFree(hit_data)
hit_data_t	*hit_data;
{
	if (hit_data == HitDataNull)
		return;

	HitDataFreeParts(hit_data);
	(void) free((char *) hit_data);
}


/* HitDataFreeParts
 *
 * Free sub-components of hitdata structure, but not the structure
 * itself.
 */

void
HitDataFreeParts(hit_data)
hit_data_t	*hit_data;
{
	PointFree(hit_data->point);
	VectorFree(hit_data->normal);
}


/* HitDataCalculate
 *
 * Calculate hit data.  The solid is simply passed on, the point
 * of intersection is copied, as is the vector.
 * The normal at the point of intersection is calculated.
 */

hit_data_t *
HitDataCalculate(hit_data, hit_info)
hit_data_t	*hit_data;
hit_info_t	*hit_info;
{
	return(HitDataLet(hit_data,
			  hit_info->solid,
			  PointCopy(hit_info->point),
		          QuadricNormal(VectorNull,
				        hit_info->point,
				        hit_info->solid->body.atom.quadric)));
}
