home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / shadmod1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-24  |  16.9 KB  |  342 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *  Craig Kolb          - textures
  11.  *  David Buck          - textures
  12.  *
  13.  * Redistribution and use in source and binary forms are permitted
  14.  * provided that the above copyright notice and this paragraph are
  15.  * duplicated in all such forms and that any documentation,
  16.  * advertising materials, and other materials related to such
  17.  * distribution and use acknowledge that the software was developed
  18.  * by Antonio Costa, at INESC-Norte. The name of the author and
  19.  * INESC-Norte may not be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  */
  25. #include "defs.h"
  26. #include "extern.h"
  27.  
  28. /**********************************************************************
  29.  *    RAY TRACING - Shade Model 1 - Version 7.0                       *
  30.  *                                                                    *
  31.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1988           *
  32.  *    ADAPTED BY : Antonio Costa, INESC-Norte, June 1989              *
  33.  *    MODIFIED BY: Antonio Costa, INESC-Norte, March 1992             *
  34.  **********************************************************************/
  35.  
  36. /***** Shading Phong model *****/
  37. #define LEFT  (1 SHL shade_level)
  38. #define RIGHT (1 SHL (shade_level + 1))
  39.  
  40. #ifdef THINK_C
  41.  
  42. /* On the mac, SCREEN_SIZE_X_MAX is not a constant, so previous_repetitions
  43.     is set manually from the mac segment */
  44.         
  45. short int previous_repetitions;
  46.  
  47. #else
  48.  
  49. static short int  previous_repetitions = SCREEN_SIZE_X_MAX;
  50.  
  51. #endif
  52.  
  53. static xyz_struct previous_normal, previous_reflected;
  54. static rgb_struct previous_diffuse, previous_specular;
  55. void
  56. shade_phong(position, normal, ray, object, color)
  57.   xyz_ptr         position, normal;     /* Normal may be modified */
  58.   ray_ptr         ray;
  59.   object_ptr      object;
  60.   rgb_ptr         color;
  61. {
  62.   REG int         l;
  63.   REG real        k, diffuse, specular;
  64.   real            intensity, new_diffuse;
  65.   boolean         refractive, opposite_light;
  66.   rgb_struct      brightness, level;
  67.   rgb_struct      surface_diffuse, surface_specular, surface_transparent;
  68.   rgb_struct      new_color, distributed_color;
  69.   xyz_struct      old_normal, old_reflected, lighting;
  70.   ray_struct      reflected, refracted, distributed;
  71.   surface_struct  new_surface;
  72.   int             id, ambient_diffuse_rays, ambient_specular_rays;
  73.  
  74.   STRUCT_ASSIGN(new_surface, *(surface[object->surface_id]));
  75.   k = -2.0 * DOT_PRODUCT(ray->vector, *normal);
  76.   reflected.vector.x = k * normal->x + ray->vector.x;
  77.   reflected.vector.y = k * normal->y + ray->vector.y;
  78.   reflected.vector.z = k * normal->z + ray->vector.z;
  79.   if (normal_mode == 0)
  80.   {
  81.     if (k < 0.0)
  82.     {
  83.       normal->x = -(normal->x);
  84.       normal->y = -(normal->y);
  85.       normal->z = -(normal->z);
  86.     }
  87.   } else
  88.   if ((k < 0.0) AND ray->inside)
  89.   {
  90.     normal->x = -(normal->x);
  91.     normal->y = -(normal->y);
  92.     normal->z = -(normal->z);
  93.   }
  94.   STRUCT_ASSIGN(old_normal, *normal);
  95.   if ((texture_mode != 0) AND(object->texture != NULL))
  96.   {
  97.     if (normal_check_mode AND object->texture_modify_normal)
  98.       STRUCT_ASSIGN(old_reflected, reflected.vector);
  99.     surface_texture(position, normal, &new_surface, object->texture);
  100.     if (normal_check_mode AND object->texture_modify_normal)
  101.     {
  102.       k = -2.0 * DOT_PRODUCT(ray->vector, *normal);
  103.       reflected.vector.x = k * normal->x + ray->vector.x;
  104.       reflected.vector.y = k * normal->y + ray->vector.y;
  105.       reflected.vector.z = k * normal->z + ray->vector.z;
  106.       if (DOT_PRODUCT(reflected.vector, old_normal) < ROUNDOFF)
  107.       {
  108.         STRUCT_ASSIGN(*normal, old_normal);
  109.         STRUCT_ASSIGN(reflected.vector, old_reflected);
  110.       }
  111.     }
  112.   }
  113.   STRUCT_ASSIGN(surface_diffuse, new_surface.diffuse);
  114.   STRUCT_ASSIGN(surface_specular, new_surface.specular);
  115.   STRUCT_ASSIGN(surface_transparent, new_surface.transparent);
  116.   new_surface.diffuse.r *= new_surface.color.r;
  117.   new_surface.diffuse.g *= new_surface.color.g;
  118.   new_surface.diffuse.b *= new_surface.color.b;
  119.   new_surface.specular.r *= new_surface.color.r * (1.0 -
  120.     new_surface.metal_factor.r) + new_surface.metal_factor.r;
  121.   new_surface.specular.g *=ˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˜ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÁˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇflˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˜ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇflˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˜ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇøˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇÔˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇflˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ += light_ambient.g * new_surface.diffuse.g;
  122.     color->b += light_ambient.b * new_surface.diffuse.b;
  123.   } else
  124.   {
  125.     diffuse = (surface_diffuse.r + surface_diffuse.g +
  126.       surface_diffuse.b) / 3.0;
  127.     specular = (surface_specular.r + surface_specular.g +
  128.       surface_specular.b) / 3.0;
  129.     if (diffuse + specular > ROUNDOFF)
  130.     {
  131.       if (ABS(diffuse + specular - 1.0) > ROUNDOFF)
  132.       {
  133.         k = diffuse + specular;
  134.         diffuse /= k;
  135.         specular /= k;
  136.       }
  137.       if ((shade_level == 0) AND(distributed_cache_mode != 0)
  138.           AND(previous_repetitions <= distributed_cache_repetitions)
  139.           AND(DOT_PRODUCT(old_normal, previous_normal) > threshold_vector)
  140.           AND(DOT_PRODUCT(reflected.vector, previous_reflected) >
  141.               threshold_vector))
  142.       {
  143.         POSINC(previous_repetitions);
  144.         REALINC(distributed_cache_hits);
  145.         color->r += previous_diffuse.r * diffuse * new_surface.diffuse.r;
  146.         color->g += previous_diffuse.g * diffuse * new_surface.diffuse.g;
  147.         color->b += previous_diffuse.b * diffuse * new_surface.diffuse.b;
  148.         color->r += previous_specular.r * specular * new_surface.specular.r;
  149.         color->g += previous_specular.g * specular * new_surface.specular.g;
  150.         color->b += previous_specular.b * specular * new_surface.specular.b;
  151.       } else
  152.       {
  153.         ambient_diffuse_rays = estimate_diffuse(ambient_sample_rays, diffuse);
  154.         ambient_specular_rays = estimate_specular(ambient_sample_rays,
  155.           specular, new_surface.phong_factor);
  156.         if (shade_level < RAY_CACHE_LEVEL_MAX)
  157.           ray_node += RIGHT;
  158.         POSINC(shade_level);
  159.         if (shade_level > shade_level_max)
  160.           shade_level_max = shade_level;
  161.         if (SELF_INTERSECT(object->object_type, distributed.inside))
  162.           id = NO_OBJECTS;
  163.         else
  164.           id = object->id;
  165.         distributed.inside = ray->inside;
  166.         distributed.level.r = ray->level.r * surface_diffuse.r;
  167.         distributed.level.g = ray->level.g * surface_diffuse.g;
  168.         distributed.level.b = ray->level.b * surface_diffuse.b;
  169.         distributed_color.r = 0.0;
  170.         distributed_color.g = 0.0;
  171.         distributed_color.b = 0.0;
  172.         if (COLOR_BIG(surface_diffuse, ROUNDOFF)
  173.             AND COLOR_BIG(distributed.level, ROUNDOFF)
  174.             AND(ambient_diffuse_rays > 0))
  175.         {
  176.           /* Diffuse ambient */
  177.           for (l = 0; l < ambient_diffuse_rays; POSINC(l))
  178.           {
  179.             make_diffuse_vector(&old_normal, &(distributed.vector));
  180.             REALINC(ambient_rays);
  181.             if (intersect_all(id, position, &distributed, &new_color) > 0.0)
  182.             {
  183.               distributed_color.r += new_color.r;
  184.               distributed_color.g += new_color.g;
  185.               distributed_color.b += new_color.b;
  186.             } else
  187.             {
  188.               distributed_color.r += back_color.r;
  189.               distributed_color.g += back_color.g;
  190.               distributed_color.b += back_color.b;
  191.             }
  192.           }
  193.           k = 1.0 / (real) ambient_diffuse_rays;
  194.           distributed_color.r *= k;
  195.           distributed_color.g *= k;
  196.           distributed_color.b *= k;
  197.           color->r += distributed_color.r * diffuse * new_surface.diffuse.r;
  198.           color->g += distributed_color.g * diffuse * new_surface.diffuse.g;
  199.           color->b += distributed_color.b * diffuse * new_surface.diffuse.b;
  200.         }
  201.         if ((shade_level == 1) AND(distributed_cache_mode != 0))
  202.           STRUCT_ASSIGN(previous_diffuse, distributed_color);
  203.         distributed.level.r = ray->level.r * surface_specular.r;
  204.         distributed.level.g = ray->level.g * surface_specular.g;
  205.         distributed.level.b = ray->level.b * surface_specular.b;
  206.         distributed_color.r = 0.0;
  207.         distributed_color.g = 0.0;
  208.         distributed_color.b = 0.0;
  209.         if (COLOR_BIG(surface_specular, ROUNDOFF)
  210.             AND COLOR_BIG(distributed.level, ROUNDOFF)
  211.             AND(ambient_specular_rays > 0)
  212.             AND(new_surface.phong_factor > ROUNDOFF))
  213.         {
  214.           /* Specular ambient */
  215.           for (l = 0; l < ambient_specular_rays; POSINC(l))
  216.           {
  217.             make_specular_vector(&(reflected.vector), &old_normal,
  218.                                  new_surface.phong_factor,
  219.                                  &(distributed.vector));
  220.             REALINC(ambient_rays);
  221.             if (intersect_all(id, position, &distributed, &new_color) > 0.0)
  222.             {
  223.               distributed_color.r += new_color.r;
  224.               distributed_color.g += new_color.g;
  225.               distributed_color.b += new_color.b;
  226.             } else
  227.             {
  228.               distributed_color.r += back_color.r;
  229.               distributed_color.g += back_color.g;
  230.               distributed_color.b += back_color.b;
  231.             }
  232.           }
  233.           k = 1.0 / (real) ambient_specular_rays;
  234.           distributed_color.r *= k;
  235.           distributed_color.g *= k;
  236.           distributed_color.b *= k;
  237.           color->r += distributed_color.r * specular * new_surface.specular.r;
  238.           color->g += distributed_color.g * specular * new_surface.specular.g;
  239.           color->b += distributed_color.b * specular * new_surface.specular.b;
  240.         }
  241.         POSDEC(shade_level);
  242.         if (shade_level < RAY_CACHE_LEVEL_MAX)
  243.           ray_node -= RIGHT;
  244.         if ((shade_level == 0) AND(distributed_cache_mode != 0))
  245.         {
  246.           if (previous_repetitions > 0)
  247.           {
  248.             REALINC(distributed_cache_resets);
  249.             previous_repetitions = 0;
  250.           }
  251.           STRUCT_ASSIGN(previous_normal, old_normal);
  252.           STRUCT_ASSIGN(previous_reflected, reflected.vector);
  253.           STRUCT_ASSIGN(previous_specular, distributed_color);
  254.         }
  255.       }
  256.     }
  257.   }
  258.   new_surface.diffuse.r *= new_surface.diffuse_factor.r;
  259.   new_surface.diffuse.g *= new_surface.diffuse_factor.g;
  260.   new_surface.diffuse.b *= new_surface.diffuse_factor.b;
  261.   /* Lights */
  262.   for (l = 0; l < lights; POSINC(l))
  263.   {
  264.     vector_to_light(l, position, &lighting);
  265.     intensity = -1.0;
  266.     if ((texture_mode != 0) AND(object->texture != NULL)
  267.         AND normal_check_mode AND object->texture_modify_normal)
  268.     {
  269.       k = DOT_PRODUCT(old_normal, lighting);
  270.       diffuse = DOT_PRODUCT(*normal, lighting);
  271.       if ((k < 0.0) == (diffuse > 0.0))
  272.         diffuse = -diffuse;
  273.     } else
  274.       diffuse = DOT_PRODUCT(*normal, lighting);
  275.     if (diffuse < 0.0)
  276.     {
  277.       opposite_light = TRUE;
  278.       if (refractive AND(light_mode == 2))
  279.         diffuse = -diffuse;
  280.     } else
  281.       opposite_light = FALSE;
  282.     if ((diffuse > ROUNDOFF)
  283.         AND COLOR_BIG(surface_diffuse, ROUNDOFF))
  284.     {
  285.       intensity = light_intensity(l, &lighting);
  286.       diffuse *= intensity;
  287.     } else
  288.       diffuse = 0.0;
  289.     if (COLOR_BIG(surface_specular, ROUNDOFF))
  290.     {
  291.       if (opposite_light)
  292.         if (refractive AND(light_mode == 2))
  293.           specular = DOT_PRODUCT(refracted.vector, lighting);
  294.         else
  295.           specular = 0.0;
  296.       else
  297.         specular = DOT_PRODUCT(reflected.vector, lighting);
  298.       if (specular > ROUNDOFF)
  299.       {
  300.         if (intensity < 0.0)
  301.           intensity = light_intensity(l, &lighting);
  302.         if (intensity > ROUNDOFF)
  303.           specular = POWER(specular, new_surface.phong_factor) * intensity;
  304.         else
  305.           specular = 0.0;
  306.       }
  307.     } else
  308.       specular = 0.0;
  309.     if ((diffuse < ROUNDOFF) AND(specular < ROUNDOFF))
  310.     {
  311.       if (shade_level < LIGHT_CACHE_LEVEL_MAX)
  312.         light[l].cache_id[shade_level] = NO_OBJECTS;
  313.       continue;
  314.     }
  315.     light_brightness(object->id, l, position, &lighting, &brightness);
  316.     if (brightness.r > ROUNDOFF)
  317.     {
  318.       new_diffuse = diffuse * new_surface.diffuse_factor.r;
  319.       if (new_diffuse > ROUNDOFF)
  320.         color->r += new_diffuse * brightness.r * new_surface.diffuse.r;
  321.       if (specular > ROUNDOFF)
  322.         color->r += specular * brightness.r * new_surface.specular.r;
  323.     }
  324.     if (brightness.g > ROUNDOFF)
  325.     {
  326.       new_diffuse = diffuse * new_surface.diffuse_factor.g;
  327.       if (new_diffuse > ROUNDOFF)
  328.         color->g += new_diffuse * brightness.g * new_surface.diffuse.g;
  329.       if (specular > ROUNDOFF)
  330.         color->g += specular * brightness.g * new_surface.specular.g;
  331.     }
  332.     if (brightness.b > ROUNDOFF)
  333.     {
  334.       new_diffuse = diffuse * new_surface.diffuse_factor.b;
  335.       if (new_diffuse > ROUNDOFF)
  336.         color->b += new_diffuse * brightness.b * new_surface.diffuse.b;
  337.       if (specular > ROUNDOFF)
  338.         color->b += specular * brightness.b * new_surface.specular.b;
  339.     }
  340.   }
  341. }
  342.