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

  1.  
  2. /*
  3.  * intersect.c - The module check for eye/object intersection
  4.  * 
  5.  * Copyright (C) 1990, Kory Hamzeh
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <math.h>
  10. #include "rt.h"
  11. #include "externs.h"
  12.  
  13.  
  14. /*
  15.  * Intersect()
  16.  * 
  17.  * Check to see if given ray intersect any objects. If so, fill in the given
  18.  * intersect structure and return 1. Else, return 0.
  19.  */
  20.  
  21. Intersect(ray, inter)
  22. RAY            *ray;
  23. INTERSECT      *inter;
  24. {
  25.     int             i, iflag;
  26.     INTERSECT       minter;
  27.     OBJECT         *obj;
  28.     COMPOSITE      *cd;
  29.  
  30.     iflag = 0;
  31.     /*
  32.      * If the root object is not a slab, then slimply call its inter
  33.      * intersect routine and return.
  34.      */
  35.  
  36.     if (root->type != T_COMPOSITE)
  37.         return ((*root->inter) (root, ray, inter));
  38.  
  39.     /*
  40.      * Push root node an top of stack and check to set if we hit
  41.      * anything.
  42.      */
  43.  
  44.     stack_cnt = 0;
  45.  
  46.     Check_and_push(root, ray);
  47.  
  48.     while (stack_cnt != 0)
  49.     {
  50.  
  51.         obj = Pop_object();
  52.  
  53.         /*
  54.          * If this object is a composite type, then check and push
  55.          * all of its childeren onto the stack.
  56.          */
  57.  
  58.  
  59.         if (obj->type == T_COMPOSITE)
  60.         {
  61.             cd = (COMPOSITE *) obj->obj;
  62.             for (i = 0; i < cd->num; i++)
  63.                 Check_and_push(cd->child[i], ray);
  64.         }
  65.         else
  66.         {
  67.  
  68.             if ((*obj->inter) (obj, ray, inter))
  69.             {
  70.                 if (iflag == 0)    /* first intersection */
  71.                 {
  72.                     iflag = 1;
  73.                     minter.t = inter->t;
  74.                     minter.obj = inter->obj;
  75.                 }
  76.                 else if (minter.t > inter->t)
  77.                 {
  78.                     minter.t = inter->t;
  79.                     minter.obj = obj;
  80.                 }
  81.             }
  82.         }
  83.     }
  84.  
  85.     if (iflag)
  86.     {
  87.         inter->t = minter.t;
  88.         inter->obj = minter.obj;
  89.         return (1);
  90.     }
  91.     else
  92.         return (0);
  93.  
  94. }
  95.  
  96. /*
  97.  * Check_and_push()
  98.  * 
  99.  * Check to see of this ray penatrate this bbox around the object. If so, push
  100.  * it on the stack.
  101.  */
  102.  
  103. Check_and_push(obj, ray)
  104. OBJECT         *obj;
  105. RAY            *ray;
  106. {
  107.  
  108.     VECTOR          mn, mx, r_dir, r_org;
  109.     double          t_near, t_far, t1, t2, t3;
  110.     int             i;
  111.  
  112.     r_dir = ray->dir;
  113.     r_org = ray->pos;
  114.  
  115.     mn = obj->b_min;
  116.     mx = obj->b_max;
  117.  
  118.     t_near = -HUGE;
  119.     t_far = HUGE;
  120.  
  121.     /* test the X slab */
  122.     if (fabs(r_dir.x) < MIN_T)    /* parralel to the X slab */
  123.     {
  124.         if (r_org.x < mn.x || r_org.x > mx.x)
  125.             return;    /* can't possible hit this puppy */
  126.     }
  127.     else
  128.     {
  129.         /* ray is not parallel to the X slab. calc intersection dist */
  130.  
  131.         t1 = (mn.x - r_org.x) / r_dir.x;
  132.         t2 = (mx.x - r_org.x) / r_dir.x;
  133.  
  134.         if (t1 > t2)
  135.         {
  136.             if (t2 > t_near)
  137.                 t_near = t2;
  138.             if (t1 < t_far)
  139.                 t_far = t1;
  140.         }
  141.         else
  142.         {
  143.             if (t1 > t_near)
  144.                 t_near = t1;
  145.             if (t2 < t_far)
  146.                 t_far = t2;
  147.         }
  148.  
  149.         if (t_near > t_far)
  150.             return;    /* no hitter             */
  151.  
  152.         if (t_far < MIN_T)
  153.             return;    /* no hitter             */
  154.     }
  155.  
  156.     /* test the Y slab */
  157.     if (fabs(r_dir.y) < MIN_T)    /* parralel to the Y slab */
  158.     {
  159.         if (r_org.y < mn.y || r_org.y > mx.y)
  160.             return;    /* can't possible hit this puppy */
  161.     }
  162.     else
  163.     {
  164.         /* this is not parallel to the Y slab. calc intersection dist */
  165.  
  166.         t1 = (mn.y - r_org.y) / r_dir.y;
  167.         t2 = (mx.y - r_org.y) / r_dir.y;
  168.  
  169.         if (t1 > t2)
  170.         {
  171.             if (t2 > t_near)
  172.                 t_near = t2;
  173.             if (t1 < t_far)
  174.                 t_far = t1;
  175.         }
  176.         else
  177.         {
  178.             if (t1 > t_near)
  179.                 t_near = t1;
  180.             if (t2 < t_far)
  181.                 t_far = t2;
  182.         }
  183.  
  184.         if (t_near > t_far)
  185.             return;    /* no hitter             */
  186.  
  187.         if (t_far < MIN_T)
  188.             return;    /* no hitter             */
  189.     }
  190.  
  191.     /* test the Z slab */
  192.     if (fabs(r_dir.z) < MIN_T)    /* parralel to the Z slab */
  193.     {
  194.         if (r_org.z < mn.z || r_org.z > mx.z)
  195.             return;    /* can't possible hit this puppy */
  196.     }
  197.     else
  198.     {
  199.         /* ray is not parallel to the Z slab. calc intersection dist */
  200.  
  201.         t1 = (mn.z - r_org.z) / r_dir.z;
  202.         t2 = (mx.z - r_org.z) / r_dir.z;
  203.  
  204.         if (t1 > t2)
  205.         {
  206.             if (t2 > t_near)
  207.                 t_near = t2;
  208.             if (t1 < t_far)
  209.                 t_far = t1;
  210.         }
  211.         else
  212.         {
  213.             if (t1 > t_near)
  214.                 t_near = t1;
  215.             if (t2 < t_far)
  216.                 t_far = t2;
  217.         }
  218.  
  219.         if (t_near > t_far)
  220.             return;    /* no hitter             */
  221.  
  222.         if (t_far < MIN_T)
  223.             return;    /* no hitter             */
  224.     }
  225.  
  226.     /*
  227.      * This object passed all of the test. So this ray will hit this
  228.      * puppy. Push at on the stack.
  229.      */
  230.  
  231.     Push_object(obj);
  232.  
  233. }
  234.