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

  1. /*
  2.  * Copyright (c) 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.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that the above copyright notice and this paragraph are
  13.  * duplicated in all such forms and that any documentation,
  14.  * advertising materials, and other materials related to such
  15.  * distribution and use acknowledge that the software was developed
  16.  * by Antonio Costa, at INESC-Norte. The name of the author and
  17.  * INESC-Norte may not be used to endorse or promote products derived
  18.  * from this software without specific prior written permission.
  19.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  21.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  22.  */
  23. #include "defs.h"
  24. #include "extern.h"
  25.  
  26. /**********************************************************************
  27.  *    RAY TRACING - List - Version 7.3.1                              *
  28.  *                                                                    *
  29.  *    MADE BY    : Antonio Costa, INESC-Norte, July 1992              *
  30.  *    MODIFIED BY: Antonio Costa, INESC-Norte, July 1992              *
  31.  **********************************************************************/
  32.  
  33. /***** Text *****/
  34. real
  35. list_intersect(position, vector, object)
  36.   xyz_ptr         position, vector;
  37.   object_ptr      object;
  38. {
  39.   REG real        distance, tmp_distance;
  40.   xyz_struct      new_position, new_vector;
  41.   list_ptr        list;
  42.   list_node_ptr   node;
  43.   object_ptr      tmp_object;
  44.   int             octant;
  45.   boolean         intersect;
  46.  
  47.   if (object->transf != NULL)
  48.   {
  49.     transform(object->transf, position, &new_position);
  50.     transform_vector(object->transf, position, vector, &new_position,
  51.                      &new_vector);
  52.     NORMALIZE(new_vector);
  53.   } else
  54.   {
  55.     STRUCT_ASSIGN(new_position, *position);
  56.     STRUCT_ASSIGN(new_vector, *vector);
  57.   }
  58.   REALINC(list_tests);
  59.   list = (list_ptr) object->data;
  60.   distance = INFINITY;
  61.   node = list->head;
  62.   list->object = NULL;
  63.   while (node != NULL)
  64.   {
  65.     tmp_object = node->object;
  66.     FIND_OCTANT(octant, new_vector);
  67.     intersect = octant_intersect(octant, &new_position, &new_vector,
  68.                                  tmp_object->min, tmp_object->max);
  69.     if (intersect AND CHECK_BOUNDS(tmp_object->object_type))
  70.     {
  71.       tmp_distance = bound_intersect(&new_position, &new_vector,
  72.                                      tmp_object->min, tmp_object->max);
  73.       if ((tmp_distance <= 0.0) OR(tmp_distance > distance))
  74.         intersect = FALSE;
  75.     }
  76.     if (intersect)
  77.     {
  78.       OBJECT_INTERSECT(tmp_distance, &new_position, &new_vector, tmp_object);
  79.       if ((tmp_distance > threshold_distance) AND(tmp_distance < distance))
  80.       {
  81.         distance = tmp_distance;
  82.         list->object = tmp_object;
  83.     if (list->surface_id < 0)
  84.       object->surface_id = tmp_object->surface_id;
  85.     if (list->refraction < 0.0)
  86.       object->refraction = tmp_object->refraction;
  87.       }
  88.     }
  89.     node = (list_node_ptr) node->next;
  90.   }
  91.   if (list->object == NULL)
  92.     return 0.0;
  93.   if (object->transf != NULL)
  94.   {
  95.     list->position->x = new_position.x + distance * new_vector.x;
  96.     list->position->y = new_position.y + distance * new_vector.y;
  97.     list->position->z = new_position.z + distance * new_vector.z;
  98.     return transform_distance(object->inv_transf, distance,
  99.                               &new_position, &new_vector, position);
  100.   } else
  101.     return distance;
  102. }
  103. void
  104. list_normal(position, object, normal)
  105.   xyz_ptr         position;
  106.   object_ptr      object;
  107.   xyz_ptr         normal;
  108. {
  109.   xyz_struct      old_position, new_normal;
  110.   list_ptr        list;
  111.  
  112.   list = (list_ptr) object->data;
  113.   if (object->transf != NULL)
  114.     STRUCT_ASSIGN(old_position, *(list->position));
  115.   else
  116.     STRUCT_ASSIGN(old_position, *position);
  117.   list = (list_ptr) object->data;
  118.   OBJECT_NORMAL(&old_position, list->object, normal);
  119.   if (object->transf != NULL)
  120.   {
  121.     transform_normal_vector(object->transf, list->position, normal,
  122.                             &new_normal);
  123.     STRUCT_ASSIGN(*normal, new_normal);
  124.     NORMALIZE(*normal);
  125.   }
  126. }
  127. void
  128. list_enclose(object)
  129.   object_ptr      object;
  130. {
  131.   xyz_struct      max, min, temp, vertex;
  132.   list_ptr        list;
  133.   list_node_ptr   node;
  134.   object_ptr      tmp_object;
  135.  
  136.   list = (list_ptr) object->data;
  137.   list->surface_id = object->surface_id;
  138.   list->refraction = object->refraction;
  139.   node = list->head;
  140.   tmp_object = node->object;
  141.   OBJECT_ENCLOSE(tmp_object);
  142.   validate_object(tmp_object, 0);
  143.   STRUCT_ASSIGN(*(object->min), *(tmp_object->min));
  144.   STRUCT_ASSIGN(*(object->max), *(tmp_object->max));
  145.   node = (list_node_ptr) node->next;
  146.   while (node != NULL)
  147.   {
  148.     tmp_object = node->object;
  149.     OBJECT_ENCLOSE(tmp_object);
  150.     validate_object(tmp_object, 0);
  151.     object->min->x = MIN(object->min->x, tmp_object->min->x);
  152.     object->min->y = MIN(object->min->y, tmp_object->min->y);
  153.     object->min->z = MIN(object->min->z, tmp_object->min->z);
  154.     object->max->x = MAX(object->max->x, tmp_object->max->x);
  155.     object->max->y = MAX(object->max->y, tmp_object->max->y);
  156.     object->max->z = MAX(object->max->z, tmp_object->max->z);
  157.     node = (list_node_ptr) node->next;
  158.   }
  159.   if (object->transf != NULL)
  160.   {
  161.     STRUCT_ASSIGN(max, *(object->max));
  162.     STRUCT_ASSIGN(min, *(object->min));
  163.     ALLOCATE(list->position, xyz_struct, 1);
  164.     temp.x = min.x;
  165.     temp.y = min.y;
  166.     temp.z = min.z;
  167.     transform(object->inv_transf, &temp, object->min);
  168.     STRUCT_ASSIGN(*(object->max), *(object->min));
  169.     temp.x = min.x;
  170.     temp.y = min.y;
  171.     temp.z = max.z;
  172.     transform(object->inv_transf, &temp, &vertex);
  173.     if (vertex.x < object->min->x)
  174.       object->min->x = vertex.x;
  175.     if (vertex.x > object->max->x)
  176.       object->max->x = vertex.x;
  177.     if (vertex.y < object->min->y)
  178.       object->min->y = vertex.y;
  179.     if (vertex.y > object->max->y)
  180.       object->max->y = vertex.y;
  181.     if (vertex.z < object->min->z)
  182.       object->min->z = vertex.z;
  183.     if (vertex.z > object->max->z)
  184.       object->max->z = vertex.z;
  185.     temp.x = min.x;
  186.     temp.y = max.y;
  187.     temp.z = min.z;
  188.     transform(object->inv_transf, &temp, &vertex);
  189.     if (vertex.x < object->min->x)
  190.       object->min->x = vertex.x;
  191.     if (vertex.x > object->max->x)
  192.       object->max->x = vertex.x;
  193.     if (vertex.y < object->min->y)
  194.       object->min->y = vertex.y;
  195.     if (vertex.y > object->max->y)
  196.       object->max->y = vertex.y;
  197.     if (vertex.z < object->min->z)
  198.       object->min->z = vertex.z;
  199.     if (vertex.z > object->max->z)
  200.       object->max->z = vertex.z;
  201.     temp.x = min.x;
  202.     temp.y = max.y;
  203.     temp.z = max.z;
  204.     transform(object->inv_transf, &temp, &vertex);
  205.     if (vertex.x < object->min->x)
  206.       object->min->x = vertex.x;
  207.     if (vertex.x > object->max->x)
  208.       object->max->x = vertex.x;
  209.     if (vertex.y < object->min->y)
  210.       object->min->y = vertex.y;
  211.     if (vertex.y > object->max->y)
  212.       object->max->y = vertex.y;
  213.     if (vertex.z < object->min->z)
  214.       object->min->z = vertex.z;
  215.     if (vertex.z > object->max->z)
  216.       object->max->z = vertex.z;
  217.     temp.x = max.x;
  218.     temp.y = min.y;
  219.     temp.z = min.z;
  220.     transform(object->inv_transf, &temp, &vertex);
  221.     if (vertex.x < object->min->x)
  222.       object->min->x = vertex.x;
  223.     if (vertex.x > object->max->x)
  224.       object->max->x = vertex.x;
  225.     if (vertex.y < object->min->y)
  226.       object->min->y = vertex.y;
  227.     if (vertex.y > object->max->y)
  228.       object->max->y = vertex.y;
  229.     if (vertex.z < object->min->z)
  230.       object->min->z = vertex.z;
  231.     if (vertex.z > object->max->z)
  232.       object->max->z = vertex.z;
  233.     temp.x = max.x;
  234.     temp.y = min.y;
  235.     temp.z = max.z;
  236.     transform(object->inv_transf, &temp, &vertex);
  237.     if (vertex.x < object->min->x)
  238.       object->min->x = vertex.x;
  239.     if (vertex.x > object->max->x)
  240.       object->max->x = vertex.x;
  241.     if (vertex.y < object->min->y)
  242.       object->min->y = vertex.y;
  243.     if (vertex.y > object->max->y)
  244.       object->max->y = vertex.y;
  245.     if (vertex.z < object->min->z)
  246.       object->min->z = vertex.z;
  247.     if (vertex.z > object->max->z)
  248.       object->max->z = vertex.z;
  249.     temp.x = max.x;
  250.     temp.y = max.y;
  251.     temp.z = min.z;
  252.     transform(object->inv_transf, &temp, &vertex);
  253.     if (vertex.x < object->min->x)
  254.       object->min->x = vertex.x;
  255.     if (vertex.x > object->max->x)
  256.       object->max->x = vertex.x;
  257.     if (vertex.y < object->min->y)
  258.       object->min->y = vertex.y;
  259.     if (vertex.y > object->max->y)
  260.       object->max->y = vertex.y;
  261.     if (vertex.z < object->min->z)
  262.       object->min->z = vertex.z;
  263.     if (vertex.z > object->max->z)
  264.       object->max->z = vertex.z;
  265.     temp.x = max.x;
  266.     temp.y = max.y;
  267.     temp.z = max.z;
  268.     transform(object->inv_transf, &temp, &vertex);
  269.     if (vertex.x < object->min->x)
  270.       object->min->x = vertex.x;
  271.     if (vertex.x > object->max->x)
  272.       object->max->x = vertex.x;
  273.     if (vertex.y < object->min->y)
  274.       object->min->y = vertex.y;
  275.     if (vertex.y > object->max->y)
  276.       object->max->y = vertex.y;
  277.     if (vertex.z < object->min->z)
  278.       object->min->z = vertex.z;
  279.     if (vertex.z > object->max->z)
  280.       object->max->z = vertex.z;
  281.   }
  282. }
  283.