home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* raysphere.c */
- /* */
- /* Ray / sphere intersection routines */
- /* Modified from Optik v(1.2e) (C) 1987 John Amanatides & Andrew Woo */
- /* */
- /* Copyright (C) 1992, Bernard Kwok */
- /* All rights reserved. */
- /* Revision 1.0 */
- /* May, 1992 */
- /**********************************************************************/
- #include <stdio.h>
- #include <math.h>
- #include "geo.h"
- #include "struct.h"
- #include "io.h"
- #include "ray.h"
-
- extern RayStats_Type RayStats;
- extern OptionType Option;
-
- /**********************************************************************/
- /* Intersect a ray with a unit sphere */
- /**********************************************************************/
- RaySphere(ray, hit, optr)
- register Ray *ray;
- register HitData *hit;
- register Objectt *optr;
- {
- double a,b,c,r1,r2,t,discrim;
-
- RayStats.raySphere++;
- if (Option.debug)
- printf("\t\tRay-Sphere: (%g,%g,%g) > (%g,%g,%g)\n",
- ray->origin.x, ray->origin.y, ray->origin.z,
- ray->dir.x, ray->dir.y, ray->dir.z);
-
- /* Find a,b,c of at**2 + bt + c */
- a= dot(&ray->dir, &ray->dir);
- b= 2.0 * dot(&ray->origin, &ray->dir);
- c= dot(&ray->origin, &ray->origin) - 1.0;
-
- /* Calculate discriminant */
- discrim= b*b -4.0*a*c;
- if (discrim <= 0.)
- return;
-
- /* Find closest intersection (also watch for stability) */
- if (b < 0.0) {
- r2= (-b + sqrt(discrim)) / (2.0 * a);
- r1= c / (a * r2);
- } else {
- r1= (-b -sqrt(discrim)) / (2.0 * a);
- r2= c / (a * r1);
- }
- if (r1 <= MIN_DISTANCE) /* for round-off errors */
- if (r2 <= MIN_DISTANCE)
- return;
- else
- t= r2;
- else
- t=r1;
-
- if (hit->distance <= t)
- return;
-
- /* Store hit information */
- RayStats.intSphere++;
- if (Option.visibility == FORM_FACTOR)
- ray->visible = 0.0;
- Store_HitInter(hit, optr,
- (ray->origin.x + t * ray->dir.x),
- (ray->origin.y + t * ray->dir.y),
- (ray->origin.z + t * ray->dir.z));
- if (!ray->shadow) {
- hit->normal= hit->intersect;
- hit->texture= hit->intersect;
- }
- }
-