This is extended.c in view mode; [Download] [Up]
/* * extended.c * * Copyright (C) 1989, 1991, Craig E. Kolb * All rights reserved. * * This software may be freely copied, modified, and redistributed * provided that this copyright notice is preserved on all copies. * * You may not distribute this software, in whole or in part, as part of * any commercial product without the express consent of the authors. * * There is no warranty or other guarantee of fitness of this software * for any purpose. It is provided solely "as is". * * $Id$ * * $Log$ */ #include "light.h" #include "libcommon/sampling.h" #include "extended.h" static LightMethods *iExtendedMethods = NULL; Extended * ExtendedCreate(r, pos) Float r; Vector *pos; { Extended *e; e = (Extended *)share_malloc(sizeof(Extended)); e->pos = *pos; e->radius = r; return e; } LightMethods * ExtendedMethods() { if (iExtendedMethods == (LightMethods *)NULL) { iExtendedMethods = LightMethodsCreate(); iExtendedMethods->intens = ExtendedIntens; iExtendedMethods->dir = ExtendedDirection; } return iExtendedMethods; } /* * Compute intensity ('color') of extended light source 'lp' from 'pos'. */ static int ExtendedIntens(lp, lcolor, cache, ray, dist, noshadow, color) Extended *lp; Color *lcolor, *color; ShadowCache *cache; Ray *ray; Float dist; int noshadow; { int uSample, vSample, islit; Float jit, vbase, ubase, vpos, upos, lightdist; Color newcol; Ray newray; Vector Uaxis, Vaxis, ldir; if (noshadow) { *color = *lcolor; return TRUE; } newray = *ray; /* * Determinte two orthoganal vectors that lay in the plane * whose normal is defined by the vector from the center * of the light source to the point of intersection and * passes through the center of the light source. */ VecSub(lp->pos, ray->pos, &ldir); VecCoordSys(&ldir, &Uaxis, &Vaxis); jit = 2. * lp->radius * Sampling.spacing; /* * If sample # is >= 0, then take that numbered sample * of the disc. */ if (ray->sample >= 0) { /* * Sample a single point, determined by SampleNumber, * on the extended source. */ vpos = -lp->radius + (ray->sample % Sampling.sidesamples)*jit; upos = -lp->radius + (ray->sample / Sampling.sidesamples)*jit; vpos += nrand() * jit; upos += nrand() * jit; VecComb(upos, Uaxis, vpos, Vaxis, &newray.dir); VecAdd(ldir, newray.dir, &newray.dir); lightdist = VecNormalize(&newray.dir); return !Shadowed(color, lcolor, cache, &newray, lightdist, noshadow); } /* * Else have to sample the entire disc using * Sampling.totsamples samples. */ color->r = color->g = color->b = 0.; islit = FALSE; /* * Sample Samples.totsamples points arranged in a square lying on the * plane calculated above. The size of the square is equal to * the diameter of the light source. We sample the square at equal * intervals in the U and V direction, with 'jitter'. */ ubase = -lp->radius; for (uSample = 0; uSample < Sampling.sidesamples; uSample++, ubase += jit) { vbase = -lp->radius; for (vSample = 0; vSample < Sampling.sidesamples; vSample++, vbase += jit) { vpos = vbase + nrand() * jit; upos = ubase + nrand() * jit; VecComb(upos, Uaxis, vpos, Vaxis, &newray.dir); VecAdd(ldir, newray.dir, &newray.dir); lightdist = VecNormalize(&newray.dir); if (!Shadowed(&newcol, lcolor, cache, &newray, lightdist, noshadow)) { islit = TRUE; color->r += newcol.r; color->g += newcol.g; color->b += newcol.b; } } } ColorScale(Sampling.weight, *color, color); return islit; } void ExtendedDirection(lp, pos, dir, dist) Extended *lp; Vector *pos, *dir; Float *dist; { /* * Calculate dir from position to center of * light source. */ VecSub(lp->pos, *pos, dir); *dist = VecNormalize(dir); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.