/*************************************************************************/
/*                                                                       */
/*  Copyright (c) 1994 Stanford University                               */
/*                                                                       */
/*  All rights reserved.                                                 */
/*                                                                       */
/*  Permission is given to use, copy, and modify this software for any   */
/*  non-commercial purpose as long as this copyright notice is not       */
/*  removed.  All other uses, including redistribution in whole or in    */
/*  part, are forbidden without prior written permission.                */
/*                                                                       */
/*  This software is provided with absolutely no warranty and no         */
/*  support.                                                             */
/*                                                                       */
/*************************************************************************/


/*
 * NAME
 *	sph.c
 *
 * DESCRIPTION
 *	This file contains all routines that operate on sphere objects.
 *
 */


#include <stdio.h>
#include <math.h>
#include "rt.h"



/*
 *	Define sphere data structure.
 */

typedef struct	sphere
	{
	POINT	center; 		/* Center of sphere.		     */
	REAL	rad;			/* Radius of sphere.		     */
	REAL	rad2;			/* Radius squared of sphere.	     */
	}
	SPHERE;



/*
 * NAME
 *	SphName - return the object name
 *
 * SYNOPSIS
 *	CHAR	*SphName()
 *
 * RETURNS
 *	A pointer to the name string.
 */

CHAR	*SphName()
	{
	return ("sphere");
	}



/*
 * NAME
 *	SphPrint - print the sphere object data to stdout
 *
 * SYNOPSIS
 *	VOID	SphPrint(po)
 *	OBJECT	*po;			// Ptr to sphere object.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphPrint(po)
OBJECT	*po;
	{
	INT	i;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */

	pe = po->pelem;
	fprintf(stderr,"\tSphere object\n");

	for (i = 0; i < po->numelements; i++)
		{
		ps = (SPHERE *)(pe->data);
		fprintf(stderr,"\t\tcenter  %f %f %f\n", ps->center[0], ps->center[1], ps->center[2]);
		fprintf(stderr,"\t\t        radius %f %f\n\n", ps->rad, ps->rad2);
		pe++;
		}
	}



/*
 * NAME
 *	SphElementBoundBox - compute sphere element bounding box
 *
 * SYNOPSIS
 *	VOID	SphElementBoundBox(pe, ps)
 *	ELEMENT *pe;			// Ptr to sphere element.
 *	SPHERE	*ps;			// Ptr to sphere data.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphElementBoundBox(pe, ps)
ELEMENT *pe;
SPHERE	*ps;
	{
	BBOX	*pbb;			/* Ptr to bounding box. 	     */

	pbb = &(pe->bv);

	pbb->dnear[0] = ps->center[0] - ps->rad;
	pbb->dnear[1] = ps->center[1] - ps->rad;
	pbb->dnear[2] = ps->center[2] - ps->rad;

	pbb->dfar[0]  = ps->center[0] + ps->rad;
	pbb->dfar[1]  = ps->center[1] + ps->rad;
	pbb->dfar[2]  = ps->center[2] + ps->rad;
	}



/*
 * NAME
 *	SphBoundBox - compute sphere object bounding box
 *
 * SYNOPSIS
 *	VOID	SphBoundBox(po)
 *	OBJECT	*po;			// Ptr to sphere object.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphBoundBox(po)
OBJECT	*po;
	{
	INT	i;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	BBOX	*pbb;			/* Ptr to bounding box. 	     */
	REAL	minx, maxx;
	REAL	miny, maxy;
	REAL	minz, maxz;

	pe   = po->pelem;
	pbb  = &(po->bv);

	minx = miny = minz =  HUGE_REAL;
	maxx = maxy = maxz = -HUGE_REAL;

	for (i = 0; i < po->numelements; i++)
		{
		ps = (SPHERE *)(pe->data);
		SphElementBoundBox(pe, ps);

		minx = Min(minx, pe->bv.dnear[0]);
		miny = Min(miny, pe->bv.dnear[1]);
		minz = Min(minz, pe->bv.dnear[2]);

		maxx = Max(maxx, pe->bv.dfar[0]);
		maxy = Max(maxy, pe->bv.dfar[1]);
		maxz = Max(maxz, pe->bv.dfar[2]);

		pe++;
		}

	pbb->dnear[0] = minx;
	pbb->dnear[1] = miny;
	pbb->dnear[2] = minz;

	pbb->dfar[0]  = maxx;
	pbb->dfar[1]  = maxy;
	pbb->dfar[2]  = maxz;
	}



/*
 * NAME
 *	SphNormal - compute sphere unit normal at given point on the surface
 *
 * SYNOPSIS
 *	VOID	SphNormal(hit, Pi, Ni)
 *	IRECORD *hit;			// Ptr to intersection record.
 *	POINT	Pi;			// Ipoint.
 *	POINT	Ni;			// Normal.
 *
 * NOTES
 *	The normal is the unit vector from the given point to the sphere
 *	center point.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphNormal(hit, Pi, Ni)
IRECORD *hit;
POINT	Pi;
POINT	Ni;
	{
	ELEMENT *pe;
	SPHERE	*ps;			/* Ptr to sphere data.		     */

	/*  Compute normal and make it a unit vector. */

	pe = hit->pelem;
	ps = (SPHERE *)pe->data;
	VecSub(Ni, Pi, ps->center);

	Ni[0] /= ps->rad;
	Ni[1] /= ps->rad;
	Ni[2] /= ps->rad;
	}



/*
 * NAME
 *	SphDataNormalize - normalize the sphere by the given normalization matrix
 *
 * SYNOPSIS
 *	VOID	SphDataNormalize(po, normMat)
 *	OBJECT	*po;			// Ptr to sphere object.
 *	MATRIX	normMat;		// Normalization matrix.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphDataNormalize(po, normMat)
OBJECT	*po;
MATRIX	normMat;
	{
	INT	i;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	POINT	surf_point;		/* Point on surface.		     */
	POINT	center_point;		/* Center point.		     */
	POINT	rad_vector;		/* Radius vector.		     */

	NormalizeBoundBox(&po->bv, normMat);

	pe = po->pelem;

	for (i = 0; i < po->numelements; i++)
		{
		ps = (SPHERE *)pe->data;

		NormalizeBoundBox(&pe->bv, normMat);

		surf_point[0]	= ps->center[0] + ps->rad;
		surf_point[1]	= ps->center[1];
		surf_point[2]	= ps->center[2];
		surf_point[3]	= 1.0;

		center_point[0] = ps->center[0];
		center_point[1] = ps->center[1];
		center_point[2] = ps->center[2];
		center_point[3] = 1.0;


		/* Transform center point. */

		VecMatMult(center_point, normMat, center_point);
		VecMatMult(surf_point, normMat, surf_point);


		/* Find new radius. */

		VecSub(rad_vector, surf_point, center_point);
		VecCopy(ps->center, center_point);

		ps->rad  = VecLen(rad_vector);
		ps->rad2 = ps->rad * ps->rad;

		pe++;
		}
	}



/*
 * NAME
 *	SphPeIntersect - calculate intersection of ray with sphere
 *
 * SYNOPSIS
 *	INT	SphPeIntersect(pr, pe, hit)
 *	RAY	*pr;				// Ptr to incident ray.
 *	ELEMENT *pe;				// Ptr to sphere element.
 *	IRECORD *hit;				// Intersection recorder.
 *
 * NOTES
 *	Calculate intersection of ray, X = P + tD with sphere,
 *	| X - C | = r2.  C = sphere center.  r2 = radius squared.
 *	This solves t2 - 2t(D*V) + (V*V - r2) = 0 at
 *	t = (D*V) +/- sqrt((D*V)2 - (V*V) + r2 ),
 *	where t2 = t squared, V = C - P and |D| = 1.
 *
 * RETURNS
 *	The number of intersection points.
 */

INT	SphPeIntersect(pr, pe, hit)
RAY	*pr;
ELEMENT *pe;
IRECORD *hit;
	{
	INT	nhits;				/* Number of hits.	     */
	REAL	b, disc, t1, t2, vsq;		/* Formula variables.	     */
	SPHERE	*ps;				/* Ptr to sphere data.	     */
	POINT	V;				/* C - P		     */
	IRECORD *sphhit;

	ps  = (SPHERE *)(pe->data);
	sphhit = hit;

	VecSub(V, ps->center, pr->P);		/* Ray from origin to center.*/
	vsq = VecDot(V, V);			/* Length sq of V.	     */
	b   = VecDot(V, pr->D); 		/* Perpendicular scale of V. */

	if (vsq > ps->rad2  &&	b < RAYEPS)	/* Behind ray origin.	     */
		return (0);

	disc = b*b - vsq + ps->rad2;		/* Discriminate.	     */
	if (disc < 0.0) 			/* Misses ray.		     */
		return (0);

	disc = sqrt(disc);			/* Find intersection param.  */
	t2   = b + disc;
	t1   = b - disc;

	if (t2 <= RAYEPS)			/* Behind ray origin.	     */
		return (0);

	nhits = 0;
	if (t1 > RAYEPS)			/* Entering sphere.	     */
		{
		IsectAdd(sphhit, t1, pe);
		sphhit++;
		nhits++;
		}

	IsectAdd(sphhit, t2, pe);		/* Exiting sphere	     */
	nhits++;

	return (nhits);
	}



/*
 * NAME
 *	SphIntersect - call sphere object intersection routine
 *
 * SYNOPSIS
 *	INT	SphIntersect(pr, po, hit)
 *	RAY	*pr;			// Ptr to incident ray.
 *	OBJECT	*po;			// Ptr to sphere object.
 *	IRECORD *hit;			// Intersection record.
 *
 * RETURNS
 *	The number of intersections found.
 */

INT	SphIntersect(pr, po, hit)
RAY	*pr;
OBJECT	*po;
IRECORD *hit;
	{
	INT	i;
	INT	nhits;			/* # hits in sphere.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	IRECORD newhit[2];		/* Hit list.			     */

	/* Traverse sphere list to find intersections. */

	nhits	 = 0;
	pe	 = po->pelem;
	hit[0].t = HUGE_REAL;

	for (i = 0; i < po->numelements; i++)
		{
		if (SphPeIntersect(pr, pe, newhit))
			if (newhit[0].t < hit[0].t)
				{
				nhits++;
				hit[0].t     = newhit[0].t;
				hit[0].pelem = newhit[0].pelem;
				}
		pe++;
		}

	return (nhits);
	}



/*
 * NAME
 *	SphTransform - transform sphere object by a transformation matrix
 *
 * SYNOPSIS
 *	VOID	SphTransform(po, xtrans, xinvT)
 *	OBJECT	*po;			// Ptr to sphere object.
 *	MATRIX	xtrans; 		// Transformation matrix.
 *	MATRIX	xinvT;			// Transpose of inverse matrix.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphTransform(po, xtrans, xinvT)
OBJECT	*po;
MATRIX	xtrans;
MATRIX	xinvT;
	{
	INT	i;
	INT	numelems;		/* Number of object elements.	  */
	REAL	new_rad;
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */
	POINT	surf_point;		/* Point on surface.		     */
	POINT	center_point;		/* Center_point.		     */
	POINT	rad_vector;		/* Radius vector.		     */

	pe	 = po->pelem;
	numelems = po->numelements;

	for (i = 0; i < numelems; i++)
		{
		ps = (SPHERE *)pe->data;

		/* See if radius has changed with a scale. */

		surf_point[0]	= ps->center[0] + ps->rad;
		surf_point[1]	= ps->center[1];
		surf_point[2]	= ps->center[2];
		surf_point[3]	= 1.0;

		center_point[0] = ps->center[0];
		center_point[1] = ps->center[1];
		center_point[2] = ps->center[2];
		center_point[3] = 1.0;

		/* Transform center point. */

		VecMatMult(center_point, xtrans, center_point);
		VecMatMult(surf_point, xtrans, surf_point);

		/* Find radius. */

		VecSub(rad_vector, surf_point, center_point);
		VecCopy(ps->center, center_point);

		new_rad = VecLen(rad_vector);

		if (new_rad != ps->rad)
			{
			ps->rad  = new_rad;
			ps->rad2 = ps->rad * ps->rad;
			}

		pe++;
		}
	}



/*
 * NAME
 *	SphRead - read sphere object data from file
 *
 * SYNOPSIS
 *	VOID	SphRead(po, pf)
 *	OBJECT	*po;			// Ptr to sphere object.
 *	FILE	*pf;			// Ptr to file.
 *
 * RETURNS
 *	Nothing.
 */

VOID	SphRead(po, pf)
OBJECT	*po;
FILE	*pf;
	{
	INT	i;
	INT	instat; 		/* Input counter		     */
	SPHERE	*ps;			/* Ptr to sphere data.		     */
	ELEMENT *pe;			/* Ptr to sphere element.	     */

	pe = po->pelem;
	ps = GlobalMalloc(sizeof(SPHERE)*po->numelements, "sph.c");

	for (i = 0; i < po->numelements; i++)
		{
		instat = fscanf(pf,"%lf %lf %lf %lf", &(ps->center[0]), &(ps->center[1]), &(ps->center[2]), &(ps->rad));

		if (instat != 4)
			{
			printf("Error in SphRead: sphere %ld.\n", i);
			exit(1);
			}

		ps->center[3]  = 1.0;			/* w initialization. */
		ps->rad2       = ps->rad*ps->rad;

		pe->data       = (CHAR *)ps;
		pe->parent     = po;

		SphElementBoundBox(pe, ps);

		ps++;
		pe++;
		}
	}

