home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / rayce27s / intersec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-02  |  4.4 KB  |  192 lines

  1. /*
  2.  * intersect.c -- main intersection routines
  3.  * 
  4.  * (c) 1993, 1994 by Han-Wen Nienhuys <hanwen@stack.urc.tue.nl>
  5.  * 
  6.  * This file is based on work by  George Kyriazis (1988).
  7.  * 
  8.  * This program is free software; you can redistribute it and/or modify it
  9.  * under the terms of the GNU General Public License as published by the
  10.  * Free Software Foundation;
  11.  * 
  12.  * This program is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU General Public License along
  18.  * with this program; if not, write to the Free Software Foundation, Inc.,
  19.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23.  * snelheids winst: bijhouden of een stilstaand object al getraced is.
  24.  */
  25.  
  26. #include    <math.h>
  27. #include    "ray.h"
  28. #include    "proto.h"
  29. #include     "extern.h"
  30.  
  31. /*
  32.  * Shadow check.  Check if the ray from the intersection point to the
  33.  * light, intersection any objects inbetween.  If it does, we have a
  34.  * shadow. One improvement that can be made is to check the transparencies
  35.  * of all the intersecting objects and make the shadow have a different
  36.  * intensity depending on the transparency of the objects
  37.  */
  38.  
  39. PUBLIC bool
  40. shadow_test(struct ray r, double ldistance, object *light_object, int recursion)
  41. {
  42.     dqueue         *q;
  43.     object         *op;
  44.     bool            hit;
  45.     struct light_data *light = light_object->data.light;
  46.  
  47.  
  48.     r.maxt = INFTY;
  49.     r.mint = ldistance;
  50.  
  51.  
  52.     /* intersect everything in scene */
  53.     q = get_new_queue();
  54.     light_object->methods->test++;
  55.  
  56.     /* do caching ? */
  57.     if (recursion < MAXCACHE && light->scache[recursion] != NULL) {
  58.     object         *last;
  59.  
  60.     global_stats.cachetest++;
  61.  
  62.     /* avoid intersecting CSG parts; stop if we find a composite */
  63.     for (op = light->scache[recursion]; op->type != COMPOSITE; op = op->daddy)
  64.         last = op;
  65.  
  66.     if (intersect_object(q, last, &r, FALSE) && q->t < ldistance) {
  67.         free_queue(q);
  68.         light_object->methods->hit++;
  69.         global_stats.cachehit++;
  70.         return TRUE;
  71.     } else {
  72.         global_stats.cachemiss++;
  73.         light->scache[recursion] = NULL;
  74.     }
  75.     }
  76.     global_stats.shadowtest++;
  77.     line_stats.raytest++;
  78.  
  79.     /* check whole scene */
  80.     if (intersect_object(q, thescene, &r, FALSE)) {
  81.  
  82.     /* found intersection */
  83.     line_stats.rayintersections++;
  84.  
  85.     if (q->t >= ldistance) {/* there is nothing blocking the object */
  86.  
  87.         if (recursion < MAXCACHE)    /* should we cache it? */
  88.         light->scache[recursion] = NULL;
  89.  
  90.         hit = FALSE;
  91.     } else {
  92.  
  93.         light_object->methods->hit++;
  94.         if (recursion < MAXCACHE)
  95.         light->scache[recursion] = q->obj;
  96.  
  97.         hit = TRUE;
  98.     }
  99.     } else {
  100.     hit = FALSE;        /* no intersections found */
  101.  
  102.     /* clear cache */
  103.     if (recursion < MAXCACHE)
  104.         light->scache[recursion] = NULL;
  105.     }
  106.     free_queue(q);
  107.  
  108.     return hit;
  109. }
  110.  
  111.  
  112. /*
  113.  * intersect(): intersect everything in the whole scene, and then fill in
  114.  * the intersection details.
  115.  */
  116. PUBLIC struct intersect
  117. intersect(struct ray r)
  118. {
  119.     struct intersect i;
  120.     struct ray      transray;
  121.     object         *op;
  122.     dqueue         *q;
  123.     vector          moved;
  124.  
  125.     line_stats.raytest++;
  126.     switch (r.type) {
  127.     case R_EYE:
  128.     line_stats.eyerays++;
  129.     break;
  130.     case R_REFLECT:
  131.     line_stats.reflected++;
  132.     break;
  133.     case R_REFRACT:
  134.     line_stats.refracted++;
  135.     break;
  136.     default:
  137.     assert(FALSE);
  138.     }
  139.  
  140.  
  141.     /* intersect everything in scene */
  142.     r.maxt = INFTY;
  143.     r.mint = 0;
  144.  
  145.     q = get_new_queue();
  146.     intersect_object(q, thescene, &r, FALSE);
  147.     i.q_ent = *q;
  148.     free_queue(q);
  149.  
  150.     op = i.q_ent.obj;
  151.  
  152.     if (op == NULL)
  153.     return i;        /* nothing was found */
  154.  
  155.     line_stats.rayintersections++;
  156.     setvector(moved, 0.0, 0.0, 0.0);
  157.  
  158.  
  159.     /* What was the translated ray? */
  160.     svproduct(moved, -Time, op->speed);
  161.     vadd(transray.pos, r.pos, moved);
  162.  
  163.  
  164.     /*
  165.      * translation doesn't affect direction, so just copy the dir vector
  166.      */
  167.     transray.dir = r.dir;
  168.  
  169.     /*
  170.      * determine the intersection point.
  171.      * 
  172.      * i.x = t*transray.dir + transray.pos + obj->speed * Time = t*r.dir +
  173.      * r.pos - speed*Time + speed*Time = t*r.dir + r.pos
  174.      */
  175.  
  176.     svproduct(i.x, i.q_ent.t, r.dir);
  177.     vadd(i.x, i.x, r.pos);
  178.     vadd(i.objectx, i.x, moved);
  179.  
  180.     /*
  181.      * determine normal at intersection point
  182.      */
  183.  
  184.  
  185.     i.n = i.objectn = i.q_ent.obj->methods->normal_method(i, i.objectx);
  186.  
  187.     if (i.q_ent.obj->inverted)
  188.     vneg(i.n, i.n);
  189.  
  190.     return i;
  191. }
  192.