home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / Light / raycone.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-21  |  3.7 KB  |  116 lines

  1. /**********************************************************************/
  2. /* raycone.c                                                          */
  3. /*                                                                    */
  4. /* Cone / ray intersection routine.                                   *
  5. /* Modified from Optik v(1.2e) (C) 1987 John Amanatides & Andrew Woo  */
  6. /*                                                                    */
  7. /* Copyright (C) 1992, Bernard Kwok                                   */
  8. /* All rights reserved.                                               */
  9. /* Revision 1.0                                                       */
  10. /* May, 1992                                                          */
  11. /**********************************************************************/
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "geo.h"
  15. #include "struct.h"
  16. #include "ray.h"
  17. #include "misc.h"
  18. #include "io.h"
  19.  
  20. extern RayStats_Type RayStats;
  21. extern OptionType Option;
  22.  
  23. /**********************************************************************/
  24. /* Ray trace cone intersection                                        */
  25. /*    ray : ray to check                                              */
  26. /*    hit : intersection (if any)                                     */
  27. /*    node : node to intersect with                                   */
  28. /**********************************************************************/
  29. void RayCone(ray, hit, node)
  30.      register Ray *ray;
  31.      register HitData *hit;
  32.      register Objectt *node;
  33. {
  34.   double a,b,c,r1,r2,t,discrim,x,y,z;
  35.   Vector v1, v2;
  36.  
  37.   RayStats.rayCone++;
  38.   if(Option.debug)
  39.     printf("\t\tRay-Cone: (%g,%g,%g) -> (%g,%g,%g)\n",
  40.        ray->origin.x, ray->origin.y, ray->origin.z, 
  41.        ray->dir.x, ray->dir.y, ray->dir.z);
  42.  
  43.   /* Find a,b,c of at**2 +bt +c. a = x^2 + y^2, 
  44.    * b = 2(x0x + y0y), and c = (x0^2 + y0^2 -1 
  45.    */
  46.   a = ray->dir.x*ray->dir.x + ray->dir.y*ray->dir.y -ray->dir.z*ray->dir.z;
  47.   b = 2.0*(ray->origin.x*ray->dir.x + ray->origin.y*ray->dir.y +
  48.      ray->dir.z - ray->origin.z*ray->dir.z);
  49.   c = ray->origin.x*ray->origin.x + ray->origin.y*ray->origin.y -1.0 +
  50.     2.0*ray->origin.z - ray->origin.z*ray->origin.z;
  51.   
  52.   /* Calculate discriminant */
  53.   discrim= b*b -4.*a*c;
  54.   if(discrim > 0.) {
  55.     /* find closest intersection (also watch for stability) */
  56.     if(b < 0.0) {
  57.       r2= (-b + sqrt(discrim)) / (2.0 * a);
  58.       r1= c/(a*r2);
  59.     } else {
  60.       r1= (-b - sqrt(discrim)) / (2.0 * a);
  61.       r2= c/(a*r1);
  62.     }
  63.     if(r1 <= MIN_DISTANCE)    /* for round-off errors */
  64.       t= r2;
  65.     else t= r1;
  66.  
  67.     if( t > MIN_DISTANCE && t < hit->distance) {
  68.       z= ray->origin.z + t*ray->dir.z;
  69.       if (z > 0.0 && z < 1.0) {
  70.  
  71.     /* Store hit information */
  72.     RayStats.intCone++;
  73.     if (Option.visibility == FORM_FACTOR)
  74.       ray->visible = 0.0;
  75.     Store_HitInter(hit, node, (ray->origin.x + t*ray->dir.x),
  76.                (ray->origin.y + t*ray->dir.y), z);
  77.     if(!ray->shadow) {
  78.       v1.x = -hit->intersect.y; 
  79.       v1.y = hit->intersect.x; 
  80.       v1.z= 0.0;
  81.       v2.x = -hit->intersect.x; 
  82.       v2.y = -hit->intersect.y; 
  83.       v2.z= 1.0 - z;
  84.       hit->normal = cross(v1, v2);
  85.       hit->texture = hit->intersect;
  86.     }
  87.       }
  88.     }
  89.   }
  90.  
  91.   
  92.   /* Check the disk part of the cone */
  93.   if (Option.visibility == FORM_FACTOR)
  94.     if (ray->visible == 0.0)
  95.       return;
  96.   if(ray->dir.z < -DAMN_SMALL || ray->dir.z > DAMN_SMALL) {
  97.     t= -ray->origin.z / ray->dir.z;
  98.     if(t > MIN_DISTANCE && t < hit->distance) {
  99.       x= ray->origin.x + t*ray->dir.x;
  100.       y= ray->origin.y + t*ray->dir.y;
  101.  
  102.       /* Store hit information */
  103.       if(x*x + y*y < 1.0) {
  104.     RayStats.intCone++;
  105.     if (Option.visibility == FORM_FACTOR)
  106.       ray->visible = 0.0;
  107.     Store_HitInter(hit, node, t, x, y, 0.0);
  108.     if(!ray->shadow) {
  109.       Store_HitNorm(hit, 0.0, 0.0, -1.0);
  110.       hit->texture= hit->intersect;
  111.     }
  112.       }
  113.     }
  114.   }
  115. }
  116.