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

  1.  
  2. /*
  3.  * ring.c - This module conatins all of the code that relates to the ring
  4.  * primitive.
  5.  * 
  6.  * Copyright (C) 1990, Kory Hamzeh
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <malloc.h>
  11. #include <math.h>
  12.  
  13. #include "rt.h"
  14. #include "externs.h"
  15.  
  16.  
  17. int             Ring_intersect(), Ring_normal();
  18. extern int      line;
  19.  
  20. /*
  21.  * Build_ring()
  22.  * 
  23.  * Given some info on a ring, build the entire object structure.
  24.  */
  25.  
  26. Build_ring(r)
  27. RING           *r;
  28. {
  29.     OBJECT         *o;
  30.     VECTOR          pt1, pt2;
  31.     int             i;
  32.  
  33.     if (nobjects == MAX_PRIMS)
  34.     {
  35.         fprintf(stderr, "%s: too many objects specified\n", my_name);
  36.         exit(1);
  37.     }
  38.  
  39.     if ((o = (OBJECT *) malloc(sizeof(OBJECT))) == NULL)
  40.     {
  41.         fprintf(stderr, "%s: malloc failed\n", my_name);
  42.         exit(1);
  43.     }
  44.  
  45.  
  46.     o->type = T_RING;
  47.     o->obj = r;
  48.     o->surf = cur_surface;
  49.     o->inter = Ring_intersect;
  50.     o->normal = Ring_normal;
  51.  
  52.     objects[nobjects++] = o;
  53.  
  54.     /*
  55.      * Calculate the normals and the D coefficient by various cross
  56.      * products.
  57.      */
  58.  
  59.     VecSub(r->point1, r->center, pt1);
  60.     VecSub(r->point2, r->center, pt2);
  61.     VecCross(pt1, pt2, r->normal);
  62.     VecNormalize(&r->normal);
  63.  
  64.  
  65.     r->d = -VecDot(r->normal, r->center);
  66.  
  67.     if (fabs(VecDot(r->center, r->normal) + r->d) > MIN_T)
  68.     {
  69.         fprintf(stderr, "%s: coordinate given in wrong order on line %d\n",
  70.             my_name, line);
  71.     }
  72.  
  73.     /*
  74.      * Do some other precomp for the sake of speed.
  75.      */
  76.  
  77.     r->o_radius2 = r->o_radius * r->o_radius;
  78.     r->i_radius2 = r->i_radius * r->i_radius;
  79.  
  80.     /*
  81.      * Setup the min and the max values for the bouding box.
  82.      */
  83.  
  84.     pt1.x = pt1.y = pt1.z = r->o_radius;
  85.  
  86.     VecSub(r->center, pt1, o->b_min);
  87.     VecAdd(r->center, pt1, o->b_max);
  88. }
  89.  
  90.  
  91.  
  92. /*
  93.  * ring_intersect()
  94.  * 
  95.  * Check given ring for intersection with given ray. Return TRUE if an
  96.  * intersection takes place.
  97.  */
  98.  
  99. Ring_intersect(obj, ray, inter)
  100. OBJECT         *obj;
  101. RAY            *ray;
  102. INTERSECT      *inter;
  103. {
  104.     RING           *r;
  105.     VECTOR          ip, tp;
  106.     double          vo, vd;
  107.     double          t, t2;
  108.  
  109.     r = obj->obj;
  110.  
  111.     /*
  112.      * First check to see if this ray hit the plane which this ring
  113.      * resides on.
  114.      */
  115.  
  116.     vd = VecDot(ray->dir, r->normal);
  117.  
  118.     if (fabs(vd) < MIN_T)
  119.         return (0);
  120.  
  121.     vo = VecDot(ray->pos, r->normal) + r->d;
  122.  
  123.     t = -vo / vd;
  124.     if (t < MIN_T)
  125.         return (0);
  126.  
  127.     /*
  128.      * Calculate the point of intersection.
  129.      */
  130.  
  131.     VecAddS(t, ray->dir, ray->pos, ip);
  132.  
  133.     /*
  134.      * If the point of intersection lies between the inner and outer
  135.      * radius, the have have a hit.
  136.      */
  137.  
  138.     VecSub(r->center, ip, tp);
  139.     t2 = VecDot(tp, tp);
  140.  
  141.     if (t2 < r->i_radius2 || t2 > r->o_radius2)
  142.         return (0);
  143.  
  144.     /* we have a hit */
  145.  
  146.     inter->t = t;
  147.     inter->obj = obj;
  148.     inter->inside = 0;
  149.  
  150.     return (1);
  151. }
  152.  
  153.  
  154. /*
  155.  * Ring_normal()
  156.  * 
  157.  * Return the normal to a ring at a given point along the surface.
  158.  */
  159.  
  160. Ring_normal(ring, ray, ip, normal)
  161. RING           *ring;
  162. RAY            *ray;
  163. VECTOR         *ip;
  164. VECTOR         *normal;
  165. {
  166.     VecCopy(ring->normal, *normal);
  167.     if (VecDot(ray->dir, *normal) >= 0)
  168.         VecNegate(*normal);
  169. }
  170.