home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2213 / sphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  2.4 KB  |  142 lines

  1.  
  2. /*
  3.  * sphere.c - This module contain all of the code that relates to spheres.
  4.  * 
  5.  * Copyright (C) 1990, Kory Hamzeh
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <math.h>
  11.  
  12. #include "rt.h"
  13. #include "externs.h"
  14.  
  15.  
  16. int             Sphere_intersect(), Sphere_normal();
  17.  
  18.  
  19. /*
  20.  * Build_sphere()
  21.  * 
  22.  * Given some info on a sphere object, build a complete object stucture.
  23.  */
  24.  
  25. Build_sphere(s)
  26. SPHERE         *s;
  27. {
  28.     OBJECT         *o;
  29.  
  30.     if (nobjects == MAX_PRIMS)
  31.     {
  32.         fprintf(stderr, "%s: too many objects specified\n", my_name);
  33.         exit(1);
  34.     }
  35.  
  36.     if ((o = (OBJECT *) malloc(sizeof(OBJECT))) == NULL)
  37.     {
  38.         fprintf(stderr, "%s: malloc failed\n", my_name);
  39.         exit(1);
  40.     }
  41.  
  42.     s->radius2 = s->radius * s->radius;
  43.  
  44.     o->type = T_SPHERE;
  45.     o->obj = s;
  46.     o->surf = cur_surface;
  47.     o->inter = Sphere_intersect;
  48.     o->normal = Sphere_normal;
  49.  
  50.     objects[nobjects++] = o;
  51.  
  52.     /*
  53.      * Setup of bounding box for this puppy.
  54.      */
  55.  
  56.     o->b_min.x = s->center.x - s->radius;
  57.     o->b_min.y = s->center.y - s->radius;
  58.     o->b_min.z = s->center.z - s->radius;
  59.  
  60.     o->b_max.x = s->center.x + s->radius;
  61.     o->b_max.y = s->center.y + s->radius;
  62.     o->b_max.z = s->center.z + s->radius;
  63.  
  64. }
  65.  
  66.  
  67. /*
  68.  * Sphere_intersect()
  69.  * 
  70.  * Check given sphere for intersection with given ray. Return TRUE if an
  71.  * intersection takes place.
  72.  */
  73.  
  74. Sphere_intersect(obj, ray, inter)
  75. OBJECT         *obj;
  76. RAY            *ray;
  77. INTERSECT      *inter;
  78. {
  79.     SPHERE         *s;
  80.     VECTOR          oc;
  81.     double          l2oc, tca, t2hc, disc;
  82.     double          t;
  83.  
  84.     s = obj->obj;
  85.  
  86.     /* calculate the origin to center vector */
  87.  
  88.     VecSub(s->center, ray->pos, oc);
  89.     l2oc = VecDot(oc, oc);
  90.  
  91.     /* find out the closest approach along the ray */
  92.     tca = VecDot(oc, ray->dir);
  93.     t2hc = s->radius2 - l2oc + (tca * tca);
  94.  
  95.     /* if the discriminator < 0, then the ray will not hit */
  96.     if (t2hc < MIN_T)
  97.         return (0);
  98.  
  99.     disc = sqrt(t2hc);
  100.  
  101.     /* if ray is inside object, set the inside flag */
  102.     if (l2oc > s->radius2 + MIN_T)
  103.     {
  104.         inter->inside = 0;
  105.         t = tca - disc;
  106.     }
  107.     else
  108.     {
  109.         inter->inside = 1;
  110.         t = tca + disc;
  111.     }
  112.  
  113.     if (t < MIN_T)
  114.         return (0);
  115.  
  116.     inter->obj = obj;
  117.     inter->t = t;
  118.  
  119.     return (1);
  120.  
  121. }
  122.  
  123.  
  124. /*
  125.  * Sphere_normal()
  126.  * 
  127.  * Return the normal to a sphere at a given point along the surface.
  128.  */
  129.  
  130. Sphere_normal(sphere, ray, ip, normal)
  131. SPHERE         *sphere;
  132. RAY            *ray;
  133. VECTOR         *ip;
  134. VECTOR         *normal;
  135. {
  136.  
  137.     VecSub(*ip, sphere->center, *normal);
  138.     VecNormalize(normal);
  139.     if (VecDot(ray->dir, *normal) >= 0)
  140.         VecNegate(*normal);
  141. }
  142.