home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include "MyMath.h"
- #include "rtd.h"
- #include "macros.h"
- #include "extern.h"
-
- int refract (r, bll)/*I've not been looking forward to commenting this
- please excuse it if it is ugly. (if it was hard
- to write...) */
- struct ray *r;
- struct ball *bll;
- {
- struct vector new,
- norm;
- struct mat trans;
- struct ray ir;
- FFP l,
- refk (),
- getcapt (),
- capt,
- inside ();
- FFP stupid;
- struct sphere ss;
-
- /*
- deal with a ray coming into the ball. figure out the normal,
- and how much of the light is transmitted (capt)
- */
-
- SV (norm, r -> org, bll -> s.cent);
- norm.l = LEN (norm);
-
- capt = getcapt (&norm, &(r -> dir), bll -> ior);
-
-
- /* get the addition factor for the normal for refraction */
- stupid = refk (&(norm), &(r -> dir), bll -> ior);
- SCMLT (stupid, norm);
-
- AV (ir.dir, r -> dir, norm);
- MV (r -> org.x, r -> org.y, r -> org.z, ir.org);
-
- /* now get it for reflection */
- SV (norm, r -> org, bll -> s.cent);
- norm.l = LEN (norm);
- SCMLT (SPDiv(norm.l, SPFlt(1)), norm);
- stupid = SPMul( SPFlt(2), DOT(norm, r -> dir) );
- SCMLT (stupid, norm);
- SV (r -> dir, r -> dir, norm);
-
- return (
- SPFix(
- SPAdd(
- SPMul(
- SPSub(
- capt,
- SPFlt(1)
- ),
- SPFlt(shade (r))
- ),
- SPMul(
- capt,
- inside (&ir, bll)
- )
- )
- )
- );
- }
-
- FFP inside (r, bll)/* as above, except inside out. ior is 1.0/ior now */
- struct ray *r;
- struct ball *bll;
- {
- struct vector new,
- norm;
- struct mat trans;
- struct ray er;
- FFP findo (),
- lght,
- l,
- refk (),
- getcapt (),
- capt,
- stupid;
- struct sphere ss;
-
-
- if (++level < RLEV) {
- r -> dir.l = LEN (r -> dir);
- r -> dir.xzl = XZL (r -> dir);
- mt (&(r -> dir), &trans);
- ss.rad = bll -> s.rad;
- SV (ss.cent, bll -> s.cent, r -> org);
-
- l = findo (&trans, &ss);
- MV (SPMul(l, trans.x.x),SPMul(l, trans.x.y),SPMul(l, trans.x.z),new);
- AV (er.org, r -> org, new);
- AV (r -> org, r -> org, new);
- SV (norm, er.org, bll -> s.cent);
-
- norm.l = LEN (norm);
- r -> dir.l = LEN (r -> dir);
- capt = getcapt (&norm, &(r -> dir),
- SPDiv(bll -> ior, SPFlt(1) )
- );
-
- stupid = refk (&norm, &(r -> dir),
- SPDiv(bll -> ior, SPFlt(1) )
- );
-
- SCMLT (stupid, norm);
- AV (er.dir, norm, r -> dir);
-
- SV (norm, r -> org, bll -> s.cent);
- norm.l = LEN (norm);
- SCMLT ( SPDiv( norm.l, SPFlt(1) ), norm);
- stupid = SPMul( SPFlt(2), DOT (norm, r -> dir) );
- SCMLT (stupid, norm);
- SV (r -> dir, r -> dir, norm);
- lght = SPAdd(
- SPMul(
- ( SPSub(capt, SPFlt(1) ) ),
- inside (r, bll)
- ),
- SPMul(
- capt,
- SPFlt( shade (&er) )
- )
- );
- /*
- lght = (1.0 - capt) * inside (r, bll) + (capt * (double) shade (&er));
- */
- } else
- lght = SPFlt(0);
-
- level--;
-
- return (lght);
- }
-
-
-
- FFP refk (nrm, in, ior)/*gets amount of normal that has to be added to
- incident ray to get the proper angle of
- refraction by ancient mystical methods */
- struct vector *nrm,
- *in;
- FFP ior;
- {
- FFP dt,
- ln,
- li,
- ret;
-
- ior = SPMul(ior, ior);
- dt = DOT ((*nrm), (*in));
- ln = LN2 ((*nrm));
- li = LN2 ((*in));
-
- if (SPTst(dt) < 0)
- ret = SPDiv(
- ln,
- SPSub(
- SPSqrt(
- SPSub(
- SPMul(
- dt,
- dt
- ),
- SPMul(
- ln,
- SPMul(
- li,
- SPSub(
- ior,
- SPFlt(1)
- )
- )
- )
- )
- ),
- SPNeg(dt)
- )
- );
- /*
- ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln;
- */
- else
- ret = SPDiv(
- ln,
- SPAdd(
- SPSqrt(
- SPSub(
- SPMul(
- dt,
- dt
- ),
- SPMul(
- ln,
- SPMul(
- li,
- SPSub(
- ior,
- SPFlt(1)
- )
- )
- )
- )
- ),
- SPNeg(dt)
- )
- );
- /*
- ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln;
- */
-
- return (ret);
- }
-
- FFP getcapt (nrm, dr, ior)/* gets amount of light transmitted
- through ball by mystical methods mentioned
- above. (see nasty physics text for details)*/
- struct vector *nrm,
- *dr;
- FFP ior;
- {
- FFP dt,
- cs1,
- cs2,
- p,
- s;
-
- dt = DOT ((*nrm), (*dr));
- dt = SPDiv(
- LN2 ((*dr)),
- SPDiv(
- LN2 ((*nrm)),
- SPMul(
- dt,
- dt
- )
- )
- );
-
- cs1 = SPSqrt (dt);
- cs2 = SPSqrt (
- SPSub(
- SPDiv(
- ior,
- SPSub(
- dt,
- SPFlt(1)
- )
- ),
- SPFlt(1)
- )
- );
-
- p = SPDiv(
- SPAdd(
- SPMul(
- ior,
- cs2
- ),
- cs1
- ),
- cs1
- );
-
- s = SPDiv(
- SPAdd(
- SPMul(
- ior,
- cs1
- ),
- cs2
- ),
- cs1
- );
-
- return (
- SPMul(
- SPFlt(2),
- SPAdd(
- SPMul(p, p),
- SPMul(s, s)
- )
- )
- );
- }
-