home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Graphics / graphics-16000.iso / msdos / raytrace / rayshade / src / vecmath.c < prev    next >
C/C++ Source or Header  |  1992-02-09  |  4KB  |  162 lines

  1. /*
  2.  * vecmath.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: vecmath.c,v 4.0.1.2 91/11/26 21:36:15 cek Exp Locker: cek $
  17.  *
  18.  * $Log:    vecmath.c,v $
  19.  * Revision 4.0.1.2  91/11/26  21:36:15  cek
  20.  * patch3: Potential roundoff problems.
  21.  * 
  22.  * Revision 4.0.1.1  91/09/29  15:38:41  cek
  23.  * patch1: Fixed floating-point compare in normalization code.
  24.  *
  25.  * Revision 4.0  91/07/17  14:33:02  kolb
  26.  * Initial version.
  27.  * 
  28.  */
  29. #include "common.h"
  30.  
  31. /*
  32.  * Normalize a vector, return original length.
  33.  */
  34. Float
  35. VecNormalize(a)
  36. register Vector *a;
  37. {
  38.     Float d;
  39.  
  40.     d = sqrt(a->x*a->x + a->y*a->y + a->z*a->z);
  41.     if (equal(d, 0.))
  42.         return 0.;
  43.     a->x /= d;
  44.     a->y /= d;
  45.     a->z /= d;
  46. #ifdef CRAY
  47.     /*
  48.      * The Cray Research Inc. math functional units don't work in the IEEE
  49.      * standard way, so when we get here, we just might have an x,y or z
  50.      * that is not in the range  -1.0 <= J <= 1.0 Yes, I know that that
  51.      * can't happen, but it does. So since we know we just normalized this
  52.      * vector, we'll just force x,y and z into the range -1.0 to 1.0 O.K?
  53.      */
  54.     if (a->x >= 1.0) a->x = 1.0;
  55.     else if (a->x <= -1.0) a->x = -1.0;
  56.     if (a->y >= 1.0) a->y = 1.0;
  57.     else if (a->y <= -1.0) a->y = -1.0;
  58.     if (a->z >= 1.0) a->z = 1.0;
  59.     else if (a->z <= -1.0) a->z = -1.0;
  60. #endif /* CRAY */
  61.  
  62.     return d;
  63. }
  64.  
  65. /*
  66.  * Compute cross-product of a and b, place normalized result in o.  Returns
  67.  * length of result before normalization.
  68.  */
  69. Float
  70. VecNormCross(a, b, r)
  71. Vector *a, *b, *r;
  72. {
  73.     VecCross(a, b, r);
  74.     return VecNormalize(r);
  75. }
  76.  
  77. /*
  78.  * Compute cross-product of a and b, place result in o.
  79.  */
  80. void
  81. VecCross(a, b, r)
  82. Vector *a, *b, *r;
  83. {
  84.     r->x = (a->y * b->z) - (a->z * b->y);
  85.     r->y = (a->z * b->x) - (a->x * b->z);
  86.     r->z = (a->x * b->y) - (a->y * b->x);
  87. }
  88.  
  89. /*
  90.  * Calculate direction of refracted ray using Heckbert's formula.  Returns TRUE
  91.  * if a total internal reflection occurs.
  92.  */
  93. int
  94. Refract(dir, from_index, to_index, I, N, cos1)
  95. Float from_index, to_index, cos1;
  96. Vector *dir, *I, *N;
  97. {
  98.     double kn, cos2, k;
  99.     Vector nrm;
  100.  
  101.     if (cos1 < 0.) {
  102.         /*
  103.          * Hit the 'backside' of a surface -- flip the normal.
  104.          */
  105.         nrm.x = -N->x;
  106.         nrm.y = -N->y;
  107.         nrm.z = -N->z;
  108.         cos1 = -cos1;
  109.     } else
  110.         nrm = *N;
  111.  
  112.     kn = from_index / to_index;
  113.     cos2 = 1. - kn*kn*(1. - cos1*cos1);
  114.     if (cos2 < 0.)
  115.         return TRUE;        /* Total internal reflection. */
  116.     k = kn * cos1 - sqrt((double)cos2);
  117.     VecComb(kn, *I, k, nrm, dir);
  118.     return FALSE;
  119. }
  120.  
  121. /*
  122.  * Given a vector, find two additional vectors such that all three
  123.  * are mutually perpendicular and uaxis X vaxis = vector.  The given
  124.  * vector need not be normalized. uaxis and vaxis are normalized.
  125.  */
  126. void
  127. VecCoordSys(vector, uaxis, vaxis)
  128. Vector *vector, *uaxis, *vaxis;
  129. {
  130.     uaxis->x = -vector->y;
  131.     uaxis->y = vector->x;
  132.     uaxis->z = 0.;
  133.     if (VecNormalize(uaxis) == 0.) {
  134.         uaxis->x = vector->z;
  135.         uaxis->y = 0.;
  136.         uaxis->z = -vector->x;
  137.         if (VecNormalize(uaxis) == 0.)
  138.             RLerror(RL_WARN,
  139.                 "VecCoordSys passed degenerate vector.\n");
  140.     }
  141.     (void)VecNormCross(vector, uaxis, vaxis);
  142. }
  143.  
  144. /*
  145.  * Modify given normal by "bumping" it.
  146.  */
  147. void
  148. MakeBump(norm, dpdu, dpdv, fu, fv)
  149. Vector *norm, *dpdu, *dpdv;    /* normal, surface derivatives */
  150. Float fu, fv;            /* bump function partial derivatives in uv */
  151. {
  152.     Vector tmp1, tmp2;
  153.  
  154.     VecCross(norm, dpdv, &tmp1);
  155.     VecScale(fu, tmp1, &tmp1);
  156.     VecCross(norm, dpdu, &tmp2);
  157.     VecScale(fv, tmp2, &tmp2);
  158.     VecSub(tmp1, tmp2, &tmp1);
  159.     VecAdd(*norm, tmp1, norm);
  160.     (void)VecNormalize(norm);
  161. }
  162.