home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume18 / mtvraytrace / part01 / sphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-26  |  2.3 KB  |  127 lines

  1. /***********************************************************************
  2.  * $Author: markv $
  3.  * $Revision: 1.1 $
  4.  * $Date: 88/09/11 11:00:44 $
  5.  * $Log:    sphere.c,v $
  6.  * Revision 1.1  88/09/11  11:00:44  markv
  7.  * Initial revision
  8.  * 
  9.  ***********************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "defs.h"
  14. #include "extern.h"
  15.  
  16. typedef struct t_spheredata {
  17.     Vec         sph_center ;
  18.     Flt         sph_radius ;
  19.     Flt         sph_radius2 ;
  20. } SphereData ;
  21.  
  22. int SpherePrint ();
  23. int SphereIntersect ();
  24. int SphereNormal ();
  25.  
  26. ObjectProcs SphereProcs = {
  27.     SpherePrint,
  28.     SphereIntersect,
  29.     SphereNormal,
  30. } ;
  31.  
  32. int 
  33. SpherePrint(obj)
  34.  Object *obj ;
  35. {
  36.     SphereData * sp ;
  37.  
  38.     sp = (SphereData *) obj -> o_data ;
  39.  
  40.     printf("s %g %g %g %g\n", sp -> sph_center[0], 
  41.                    sp -> sph_center[1],
  42.                    sp -> sph_center[2],
  43.                    sp -> sph_radius) ;
  44. }
  45.  
  46. SphereIntersect(obj, ray, hit)
  47.  Object * obj ;
  48.  Ray * ray ;
  49.  Isect * hit ;
  50. {
  51.  
  52.     Flt b, disc, t;
  53.     Point V ;
  54.     SphereData * sp ;
  55.  
  56.     sp = (SphereData *) obj -> o_data ;
  57.  
  58.     VecSub((sp->sph_center), ray -> P, V);
  59.  
  60.     b = VecDot(V, ray -> D);
  61.  
  62.     disc = b * b - VecDot(V, V) + (sp -> sph_radius2) ;
  63.  
  64.     if (disc < 0.0)
  65.         return(0);
  66.  
  67.     disc = sqrt(disc);
  68.  
  69.     t = (b - disc < rayeps) ? b + disc : b - disc ;
  70.  
  71.     if (t < rayeps) {
  72.         return(0);
  73.     }
  74.  
  75.     hit -> isect_t = t ;
  76.     hit -> isect_enter = VecDot(V, V) > sp -> sph_radius2 + rayeps ? 1 : 0 ;
  77.     hit -> isect_prim = obj ;
  78.     hit -> isect_surf = obj -> o_surf ;
  79.     return (1);
  80. }
  81.  
  82. int
  83. SphereNormal(obj, hit, P, N)
  84.  Object * obj ;
  85.  Isect * hit ;
  86.  Point P, N ;
  87. {
  88.     SphereData * sp ;
  89.     sp = (SphereData *) obj -> o_data ;
  90.  
  91.     VecSub(P, sp -> sph_center, N);
  92.     (void) VecNormalize(N);
  93. }
  94.  
  95. Object *
  96. MakeSphere(pos, radius)
  97.  Vec pos ;
  98.  Flt radius ;
  99. {
  100.     Object * tmp ;
  101.     int i ;
  102.     SphereData *sp ;
  103.  
  104.     tmp = (Object *) malloc (sizeof(Object)) ;
  105.     tmp -> o_type = T_SPHERE ;
  106.     tmp -> o_procs = & SphereProcs ;
  107.     tmp -> o_surf = CurrentSurface ;
  108.     sp = (SphereData *) malloc (sizeof(SphereData)) ;
  109.     VecCopy(pos, sp -> sph_center) ;
  110.     sp -> sph_radius = radius ;
  111.     sp -> sph_radius2 = radius * radius ;
  112.     tmp -> o_data = (void *) sp ;
  113.  
  114.     /*
  115.      * figure out dmin and dmax values for 
  116.      * each of the slabs...
  117.      */
  118.     
  119.     for (i = 0 ; i < NSLABS; i ++) {
  120.         tmp -> o_dmin[i] = VecDot(sp -> sph_center, Slab[i]) 
  121.             - sp -> sph_radius ;
  122.         tmp -> o_dmax[i] = VecDot(sp -> sph_center, Slab[i]) 
  123.             + sp -> sph_radius ;
  124.     }
  125.     return tmp ;
  126. }
  127.