This is jittered.c in view mode; [Download] [Up]
/* * jittered.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 "jittered.h" static LightMethods *iJitteredMethods = NULL; Jittered * JitteredCreate(pos, e1, e2) Vector *pos, *e1, *e2; { Jittered *j; j = (Jittered *)share_malloc(sizeof(Jittered)); j->pos = *pos; j->e1 = *e1; j->e2 = *e2; return j; } LightMethods * JitteredMethods() { if (iJitteredMethods == (LightMethods *)NULL) { iJitteredMethods = LightMethodsCreate(); iJitteredMethods->intens = JitteredIntens; iJitteredMethods->dir = JitteredDirection; } return iJitteredMethods; } int JitteredIntens(jit, lcolor, cache, ray, dist, noshadow, color) Jittered *jit; Color *lcolor, *color; ShadowCache *cache; Ray *ray; Float dist; int noshadow; { return !Shadowed(color, lcolor, cache, ray, dist, noshadow); } void JitteredDirection(lp, pos, dir, dist) Jittered *lp; Vector *pos, *dir; Float *dist; { /* * Choose a location with the area define by corner, e1 * and e2 at which this sample will be taken. */ VecAddScaled(lp->pos, nrand(), lp->e1, &lp->curpos); VecAddScaled(lp->curpos, nrand(), lp->e2, &lp->curpos); VecSub(lp->curpos, *pos, dir); *dist = VecNormalize(dir); } int AreaLightCreate(color, corner, u, usamp, v, vsamp) Color *color; Vector *corner, *u, *v; int usamp, vsamp; { Vector vpos, curpos; int i, j, numlight; Float ulen, vlen; Color intens; Light *ltmp; if (usamp < 1 || vsamp < 1) { RLerror(RL_ABORT, "Invalid area light specification.\n"); return FALSE; } numlight = usamp * vsamp; /* Total number of jittered sources */ /* * Sum of all intensities is equal to specified intensity. */ intens.r = color->r / (Float)numlight; intens.g = color->g / (Float)numlight; intens.b = color->b / (Float)numlight; VecSub(*u, *corner, u); VecSub(*v, *corner, v); /* * Make sure that u and v are not degenerate. */ ulen = VecNormalize(u); vlen = VecNormalize(v); if (ulen < EPSILON || vlen < EPSILON) { RLerror(RL_ABORT, "Degenerate area light source.\n"); return FALSE; } /* * Scale u and v such that they define the area covered by a * single sample. */ VecScale(ulen / (Float)usamp, *u, u); VecScale(vlen / (Float)vsamp, *v, v); /* * For each sample... */ vpos = *corner; for (i = 0; i < vsamp; i++) { curpos = vpos; for (j = 0; j < usamp; j++) { /* * current pos is the "corner" of a new light * source. A jittered position based on * the "corner" and the two edge vectors * is used as the position for the * light source in lighting calculations. */ ltmp = LightJitteredCreate(&intens, &curpos, u, v); LightAddToDefined(ltmp); VecAdd(curpos, *u, &curpos); } VecAdd(vpos, *v, &vpos); } return TRUE; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.