home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / macraysh.sit / Code / Source / vecmath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-23  |  3.0 KB  |  141 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 91/07/17 14:33:02 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    vecmath.c,v $
  19.  * Revision 4.0  91/07/17  14:33:02  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include "common.h"
  24.  
  25. /*
  26.  * Normalize a vector, return original length.
  27.  */
  28. Float
  29. VecNormalize(a)
  30. register Vector *a;
  31. {
  32.     Float d;
  33.  
  34.     d = sqrt(a->x*a->x + a->y*a->y + a->z*a->z);
  35.     if(equal(d, 0.))
  36.         return 0.;
  37.     a->x /= d;
  38.     a->y /= d;
  39.     a->z /= d;
  40.  
  41.     return d;
  42. }
  43.  
  44. /*
  45.  * Compute cross-product of a and b, place normalized result in o.  Returns
  46.  * length of result before normalization.
  47.  */
  48. Float
  49. VecNormCross(a, b, r)
  50. Vector *a, *b, *r;
  51. {
  52.     VecCross(a, b, r);
  53.     return VecNormalize(r);
  54. }
  55.  
  56. /*
  57.  * Compute cross-product of a and b, place result in o.
  58.  */
  59. void
  60. VecCross(a, b, r)
  61. Vector *a, *b, *r;
  62. {
  63.     r->x = (a->y * b->z) - (a->z * b->y);
  64.     r->y = (a->z * b->x) - (a->x * b->z);
  65.     r->z = (a->x * b->y) - (a->y * b->x);
  66. }
  67.  
  68. /*
  69.  * Calculate direction of refracted ray using Heckbert's formula.  Returns TRUE
  70.  * if a total internal reflection occurs.
  71.  */
  72. int
  73. Refract(dir, from_index, to_index, I, N, cos1)
  74. Float from_index, to_index, cos1;
  75. Vector *dir, *I, *N;
  76. {
  77.     Float kn, cos2, k;
  78.     Vector nrm;
  79.  
  80.     if (cos1 < 0.) {
  81.         /*
  82.          * Hit the 'backside' of a surface -- flip the normal.
  83.          */
  84.         nrm.x = -N->x;
  85.         nrm.y = -N->y;
  86.         nrm.z = -N->z;
  87.         cos1 = -cos1;
  88.     } else
  89.         nrm = *N;
  90.  
  91.     kn = from_index / to_index;
  92.     cos2 = 1. - kn*kn*(1. - cos1*cos1);
  93.     if (cos2 < 0.)
  94.         return TRUE;        /* Total internal reflection. */
  95.     k = kn * cos1 - sqrt(cos2);
  96.     VecComb(kn, *I, k, nrm, dir);
  97.     return FALSE;
  98. }
  99.  
  100. /*
  101.  * Given a vector, find two additional vectors such that all three
  102.  * are mutually perpendicular and uaxis X vaxis = vector.  The given
  103.  * vector need not be normalized. uaxis and vaxis are normalized.
  104.  */
  105. void
  106. VecCoordSys(vector, uaxis, vaxis)
  107. Vector *vector, *uaxis, *vaxis;
  108. {
  109.     uaxis->x = -vector->y;
  110.     uaxis->y = vector->x;
  111.     uaxis->z = 0.;
  112.     if (VecNormalize(uaxis) == 0.) {
  113.         uaxis->x = vector->z;
  114.         uaxis->y = 0.;
  115.         uaxis->z = -vector->x;
  116.         if (VecNormalize(uaxis) == 0.)
  117.             RLerror(RL_WARN,
  118.                 "VecCoordSys passed degenerate vector.\n",0,0,0);
  119.     }
  120.     (void)VecNormCross(vector, uaxis, vaxis);
  121. }
  122.  
  123. /*
  124.  * Modify given normal by "bumping" it.
  125.  */
  126. void
  127. MakeBump(norm, dpdu, dpdv, fu, fv)
  128. Vector *norm, *dpdu, *dpdv;    /* normal, surface derivatives */
  129. Float fu, fv;            /* bump function partial derivatives in uv */
  130. {
  131.     Vector tmp1, tmp2;
  132.  
  133.     VecCross(norm, dpdv, &tmp1);
  134.     VecScale(fu, tmp1, &tmp1);
  135.     VecCross(norm, dpdu, &tmp2);
  136.     VecScale(fv, tmp2, &tmp2);
  137.     VecSub(tmp1, tmp2, &tmp1);
  138.     VecAdd(*norm, tmp1, norm);
  139.     (void)VecNormalize(norm);
  140. }
  141.