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.