[net.sources] basic ray tracing: part 3

fritzz@net1.UCSD.EDU (Friedrich Knauss) (07/26/86)

#include <math.h>
#include "rtd.h"
#include "extern.h"

double  findo (m, s)/* find where a ray leaves a sphere */
struct mat *m;
struct sphere  *s;
{
    struct vector   foops;
    double  t;
/* foops is the rotated vector for the center of the sphere
   with respect to the beginning of the ray */
    mt_vec (&foops, m, &(s -> cent));
/* find out if the center of the sphere is within range.
   (it should be for this...)*/
    t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
    if (t > 0)
/*return distance from original entry. we can find the point 
  when we get out*/
	t = foops.x + sqrt (t);
    else
	t = 0;
    return (t);
}

double  find (m, s)/* see above. the only difference is that 
                      the value returned is foops.x - sqrt(t) */
struct mat *m;
struct sphere  *s;
{
    struct vector   foops;
    double  t;
    mt_vec (&foops, m, &(s -> cent));
    t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
    if (t > 0)
	t = foops.x - sqrt (t);
    else
	t = 0;
    return (t);
}

double  finds (m, s)/* returns value telling how much a sphere
                       is occluding the light source */
struct mat *m;
struct sphere  *s;
{
    struct vector   foops;
    double  t;
    mt_vec (&foops, m, &(s -> cent));
    t = s -> rad - sqrt (foops.y * foops.y + foops.z * foops.z);
    if (t > 0)
	t = t / foops.x;
    else
	t = 0;
    return (t);
}




float   shadow (p)/* gets amount of diffuse light hitting a point */
struct vector  *p;
{
    struct mat  trans;
    struct sphere   ss;
    struct vector   d;
    int     c,
            i;
    double  l,
            k,
            x,
            y,
            z,
            finds ();
    l = 0.0;
    c = -1;
    sv (&d, &(ls.cent), p);
    vecl (&d);
    vexzl (&d);
    mt (&(d), &trans);
/* get maximum obscurment */
    for (i = 0; i < nob; i++) {
	ss.rad = bl[i].s.rad;
	sv (&(ss.cent), &(bl[i].s.cent), p);
	if ((k = finds (&trans, &ss)) > l) {
	    c = i;
	    l = k;
	}
    }
    if (c == -1)
	k = 255.0;
    else {
	k = 1.0 - l / ((ls.rad) / (d.l));
	if (k < 0.0)
	    k = 0.0;
	k *= 255.0;
    }
    return (k);
}