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

  1. /*
  2.  * lights.c -- standard routines for lights
  3.  * 
  4.  * (c) by Han-Wen Nienhuys, 1993 <hanwen@stack.urc.tue.nl>
  5.  * 
  6.  * This program is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation;
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include "ray.h"
  23. #include "proto.h"
  24. #include "extern.h"
  25.  
  26. extern struct methods my_methods;
  27.  
  28. PRIVATE void    add_light(object *l);
  29.  
  30. PRIVATE bool
  31. all_light_intersections(dqueue * q, object *o, struct ray *r, int flags, bool *isinside)
  32. {
  33.     return FALSE;
  34. }
  35.  
  36. PUBLIC void
  37. make_light_list(object *o)
  38. {
  39.  
  40.     for (; o != NULL; o = o->next)
  41.     switch (o->type) {
  42.     case LIGHTSOURCE:
  43.         add_light(o);
  44.         break;
  45.     case COMPOSITE:
  46.         make_light_list(o->data.composite->contents);
  47.         break;
  48.     }
  49. }
  50.  
  51. PRIVATE vector
  52. light_normal(struct intersect i, vector loc)
  53. {
  54.     assert(FALSE);
  55. }
  56.  
  57. PRIVATE bool
  58. inside_light(object *o, vector i)
  59. {
  60.     assert(FALSE);
  61. }
  62.  
  63. PRIVATE void
  64. init_light(struct light_data *p)
  65. {
  66.     int             i;
  67.  
  68.     setvector(p->org, 0, 0, 0);
  69.  
  70.     setvector(p->direction, 0, 0, 0);
  71.     p->tightness = 1.0;
  72.     p->spotlight = FALSE;
  73.     p->lcolor.r = p->lcolor.g = p->lcolor.b = 1.0;
  74.     p->attenuation_exp = 0.0;
  75.     p->radius = 0.0;
  76.  
  77.  
  78.     for (i = 0; i < MAXCACHE; i++)
  79.     p->scache[i] = NULL;
  80. }
  81.  
  82. PRIVATE struct light_data *
  83. get_new_light(void)
  84. {
  85.     struct light_data *p;
  86.  
  87.     p = ALLOC(struct light_data);
  88.  
  89.     CHECK_MEM(p, my_methods.name);
  90.     init_light(p);
  91.  
  92.     return p;
  93. }
  94.  
  95. PRIVATE void
  96. scale_light(object *o, vector s)
  97. {
  98.     struct light_data *l = o->data.light;
  99.     vector          inv;
  100.  
  101.     vcproduct(l->org, l->org, s);
  102.     inv.x = 1 / s.x;
  103.     inv.y = 1 / s.y;
  104.     inv.z = 1 / s.z;
  105.     vcproduct(l->direction, l->direction, inv);
  106. }
  107.  
  108. PRIVATE void
  109. rotate_light(object *o, matrix rotmat)
  110. {
  111.     struct light_data *l = o->data.light;
  112.  
  113.     rotate_vector(&l->org, rotmat);
  114.     rotate_vector(&l->direction, rotmat);
  115. }
  116.  
  117. PRIVATE void
  118. translate_light(object *o, vector t)
  119. {
  120.     struct light_data *l = o->data.light;
  121.  
  122.     vadd(l->org, l->org, t);
  123. }
  124.  
  125. PRIVATE void
  126. copy_light(object *dst, object *src)
  127. {
  128.     assert(dst != NULL && src != NULL);
  129.  
  130.     if (dst->type != LIGHTSOURCE)
  131.     dst->data.light = get_new_light();
  132.     *dst->data.light = *src->data.light;
  133.     dst->type = src->type;
  134. }
  135.  
  136. PRIVATE void
  137. free_light(object *s)
  138. {
  139.     free((void *) s->data.light);
  140.     s->type = NOSHAPE;
  141. }
  142.  
  143. PRIVATE void
  144. print_light(object *o)
  145. {
  146. #ifdef DEBUG
  147.     struct light_data *l = o->data.light;
  148.  
  149.     if (l->spotlight)
  150.     printf("\tSPOTLIGHT\n");
  151.  
  152.     print_v("origin", l->org);
  153.     print_c("color", l->lcolor);
  154.     printf("attenuation %lf, radius  %lf\n",
  155.        l->attenuation_exp, l->radius);
  156.  
  157.     if (l->spotlight) {
  158.     printf("tightness %lf ", l->tightness);
  159.     print_v("direction", l->direction);
  160.     }
  161. #endif
  162. }
  163.  
  164. PUBLIC void
  165. print_light_list(void)
  166. {
  167.     object         *p;
  168.  
  169.     for (p = first_light; p != NULL; p = p->next)
  170.     print_light(p);
  171. }
  172.  
  173. PRIVATE void
  174. precompute_light(object *o)
  175. {
  176.     my_methods.howmuch++;
  177.     global_stats.prims++;
  178. }
  179.  
  180. PRIVATE struct methods my_methods =
  181. {
  182.     all_light_intersections,
  183.     light_normal,
  184.     copy_light,
  185.     inside_light,
  186.     rotate_light,
  187.     translate_light,
  188.     scale_light,
  189.     free_light,
  190.     print_light,
  191.     precompute_light,
  192.     "lightsource"
  193. /* hit and test are variables relating to the shadowray tests. */
  194. };
  195.  
  196. PUBLIC object  *
  197. get_new_light_object(void)
  198. {
  199.     object         *o;
  200.  
  201.     o = get_new_object();
  202.  
  203.     o->data.light = get_new_light();
  204.     o->methods = &my_methods;
  205.     o->type = LIGHTSOURCE;
  206.  
  207.     return o;
  208. }
  209.  
  210. /* uhoh! */
  211. PRIVATE void
  212. add_light(object *l)
  213. {
  214.     object         *p;
  215.  
  216.     p = first_light;
  217.     first_light = get_new_object();
  218.     first_light->type = LIGHTSOURCE;
  219.     first_light->methods = &my_methods;
  220.     first_light->next = p;
  221.     first_light->data.light = l->data.light;    /* don't copy light,
  222.                          * pointer to it is enough */
  223. }
  224.  
  225. PUBLIC color
  226. light_color(struct light_data *l, vector a)
  227. {
  228.     vector          d;
  229.     double          intensity,
  230.                     dot;
  231.  
  232.     if (l->spotlight) {
  233.     vsub(d, a, l->org);
  234.     norm(d, d);
  235.  
  236.     dot = vdot(d, l->direction);
  237.     if (dot < 0)        /* this can happen, if the lighted point
  238.                  * is not in the direction of the
  239.                  * spotlight */
  240.         dot = 0;
  241.  
  242.     intensity = pow(dot, l->tightness);
  243.     return scolorproduct(intensity, l->lcolor);
  244.     } else
  245.     return l->lcolor;
  246. }
  247.