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

  1. /*
  2.  * plane.c -- infinite plane thingies.
  3.  * 
  4.  * (c) 1993, 1994 by Han-Wen Nienhuys <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 <stdlib.h>
  21. #include <math.h>
  22. #include "ray.h"
  23. #include "proto.h"
  24. #include "extern.h"
  25.  
  26.  
  27. extern struct methods my_methods;
  28.  
  29. PRIVATE int     intersect_plane(struct plane_data *p, struct ray *r, double *t);
  30.  
  31. PRIVATE bool
  32. all_plane_intersections(dqueue * q, object *o, struct ray *r,
  33.             int flags, bool *isinside)
  34. {
  35.     dqueue          q_ent;
  36.     int             no_int;
  37.     vector          sample;
  38.  
  39.     no_int = intersect_plane(o->data.plane, r, &q_ent.t);
  40.  
  41.     svproduct(sample, 2 * tolerance, r->dir);
  42.     vadd(sample, sample, r->pos);
  43.  
  44.     *isinside = (vdot(sample, o->data.plane->n) < o->data.plane->mov) ^ o->inverted;
  45.  
  46.     if (no_int > 0) {        /* found intersection? */
  47.     q_ent.obj = o;        /* store shape (so normal can be found
  48.                  * easily) */
  49.     q_ent.entering = !*isinside;
  50.     add_to_queue(q, q_ent);
  51.     return TRUE;
  52.     }
  53.     return FALSE;
  54. }
  55.  
  56. PRIVATE int
  57. intersect_plane(struct plane_data *p, struct ray *r, double *t)
  58. {
  59.     double          d;
  60.  
  61.  
  62.     my_methods.test++;
  63.  
  64.     /* solve plane/ray equation: vdot(t*dir + pos, normal) = mov */
  65.     d = vdot(p->n, r->dir);
  66.  
  67.     if (ISZERO(d))        /* plane is parallel with ray */
  68.     return 0;
  69.  
  70.     *t = (p->mov - vdot(p->n, r->pos)) / d;
  71.  
  72.     if (*t < tolerance)
  73.     return 0;
  74.  
  75.     my_methods.hit++;
  76.  
  77.     return 1;
  78. }
  79.  
  80. PRIVATE vector
  81. plane_normal(struct intersect i, vector x)
  82. {
  83.     return i.q_ent.obj->data.plane->n;
  84. }
  85.  
  86. PRIVATE void
  87. translate_plane(object *o, vector v)
  88. {
  89.     struct plane_data *d = o->data.plane;
  90.  
  91.     d->mov += vdot(v, d->n);
  92. }
  93.  
  94. PRIVATE void
  95. rotate_plane(object *o, matrix rotmat)
  96. {
  97.     struct plane_data *p = o->data.plane;
  98.  
  99.     rotate_vector(&p->n, rotmat);
  100. }
  101.  
  102. PRIVATE bool
  103. inside_plane(object *o, vector x)
  104. {
  105.     struct plane_data *p = o->data.plane;
  106.  
  107.     if (vdot(x, p->n) < p->mov) {
  108.     return !o->inverted;
  109.     } else {
  110.     return o->inverted;
  111.     }
  112. }
  113.  
  114. /*
  115.  * afgespiekt van pov source
  116.  */
  117. PRIVATE void
  118. scale_plane(object *o, vector s)
  119. {
  120.     struct plane_data *d = o->data.plane;
  121.     double          len;
  122.  
  123.     d->n.x = d->n.x / s.x;
  124.     d->n.y = d->n.y / s.y;
  125.     d->n.z = d->n.z / s.z;
  126.  
  127.     len = veclen(d->n);
  128.     d->mov /= len;
  129.  
  130.     svproduct(d->n, 1 / len, d->n);
  131. }
  132.  
  133. PRIVATE void
  134. init_plane(struct plane_data *p)
  135. {
  136.     setvector(p->n, 0, 1, 0);
  137.     p->mov = 0.0;
  138. }
  139.  
  140. PRIVATE struct plane_data *
  141. get_new_plane(void)
  142. {
  143.     struct plane_data *p;
  144.     p = ALLOC(struct plane_data);
  145.  
  146.     CHECK_MEM(p, my_methods.name);
  147.     init_plane(p);
  148.  
  149.     return p;
  150. }
  151.  
  152. PRIVATE void
  153. copy_plane(object *dst, object *src)
  154. {
  155.     assert(src != NULL && dst != NULL);
  156.  
  157.     if (dst->type != PLANE)
  158.     dst->data.plane = get_new_plane();
  159.     *dst->data.plane = *src->data.plane;
  160.     dst->type = src->type;
  161. }
  162.  
  163. PRIVATE void
  164. free_plane(object *o)
  165. {
  166.     struct plane_data *p = o->data.plane;
  167.  
  168.     free((void *) p);
  169. }
  170.  
  171. PRIVATE void
  172. print_plane(object *o)
  173. {
  174. #ifdef DEBUG
  175.     struct plane_data *p = o->data.plane;
  176.  
  177.     print_v("normal", p->n);
  178.     printf("translation %lf\n", p->mov);
  179. #endif
  180. }
  181.  
  182. PRIVATE void
  183. precompute_plane(object *o)
  184. {
  185.     my_methods.howmuch++;
  186.     global_stats.prims++;
  187. }
  188.  
  189. PRIVATE struct methods my_methods =
  190. {
  191.     all_plane_intersections,
  192.     plane_normal,
  193.     copy_plane,
  194.     inside_plane,
  195.     rotate_plane,
  196.     translate_plane,
  197.     scale_plane,
  198.     free_plane,
  199.     print_plane,
  200.  
  201.     precompute_plane,
  202.     "plane",
  203. };
  204.  
  205. PUBLIC object  *
  206. get_new_plane_object(void)
  207. {
  208.     object         *o;
  209.  
  210.     o = get_new_object();
  211.  
  212.     o->data.plane = get_new_plane();
  213.     o->methods = &my_methods;
  214.     o->type = PLANE;
  215.  
  216.     return o;
  217. }
  218.