Exemple #1
0
extern int
raymixture(		/* mix modifiers */
	RAY  *r,
	OBJECT  fore,
	OBJECT  back,
	double  coef
)
{
	RAY  fr, br;
	int  foremat, backmat;
	int  i;
					/* bound coefficient */
	if (coef > 1.0)
		coef = 1.0;
	else if (coef < 0.0)
		coef = 0.0;
					/* compute foreground and background */
	foremat = backmat = 0;
					/* foreground */
	fr = *r;
	if (coef > FTINY) {
		fr.rweight *= coef;
		scalecolor(fr.rcoef, coef);
		foremat = rayshade(&fr, fore);
	}
					/* background */
	br = *r;
	if (coef < 1.0-FTINY) {
		br.rweight *= 1.0-coef;
		scalecolor(br.rcoef, 1.0-coef);
		backmat = rayshade(&br, back);
	}
					/* check for transparency */
	if (backmat ^ foremat) {
		if (backmat && coef > FTINY)
			raytrans(&fr);
		else if (foremat && coef < 1.0-FTINY)
			raytrans(&br);
	}
					/* mix perturbations */
	for (i = 0; i < 3; i++)
		r->pert[i] = coef*fr.pert[i] + (1.0-coef)*br.pert[i];
					/* mix pattern colors */
	scalecolor(fr.pcol, coef);
	scalecolor(br.pcol, 1.0-coef);
	copycolor(r->pcol, fr.pcol);
	addcolor(r->pcol, br.pcol);
					/* return value tells if material */
	if (!foremat & !backmat)
		return(0);
					/* mix returned ray values */
	scalecolor(fr.rcol, coef);
	scalecolor(br.rcol, 1.0-coef);
	copycolor(r->rcol, fr.rcol);
	addcolor(r->rcol, br.rcol);
	r->rt = bright(fr.rcol) > bright(br.rcol) ? fr.rt : br.rt;
	return(1);
}
Exemple #2
0
/* Estimate variance based on ambient division differences */
static float *
getambdiffs(AMBHEMI *hp)
{
	const double	normf = 1./bright(hp->acoef);
	float	*earr = (float *)calloc(hp->ns*hp->ns, sizeof(float));
	float	*ep;
	AMBSAMP	*ap;
	double	b, b1, d2;
	int	i, j;

	if (earr == NULL)		/* out of memory? */
		return(NULL);
					/* sum squared neighbor diffs */
	for (ap = hp->sa, ep = earr, i = 0; i < hp->ns; i++)
	    for (j = 0; j < hp->ns; j++, ap++, ep++) {
		b = bright(ap[0].v);
		if (i) {		/* from above */
			b1 = bright(ap[-hp->ns].v);
			d2 = b - b1;
			d2 *= d2*normf/(b + b1);
			ep[0] += d2;
			ep[-hp->ns] += d2;
		}
		if (!j) continue;
					/* from behind */
		b1 = bright(ap[-1].v);
		d2 = b - b1;
		d2 *= d2*normf/(b + b1);
		ep[0] += d2;
		ep[-1] += d2;
		if (!i) continue;
					/* diagonal */
		b1 = bright(ap[-hp->ns-1].v);
		d2 = b - b1;
		d2 *= d2*normf/(b + b1);
		ep[0] += d2;
		ep[-hp->ns-1] += d2;
	    }
					/* correct for number of neighbors */
	earr[0] *= 8./3.;
	earr[hp->ns-1] *= 8./3.;
	earr[(hp->ns-1)*hp->ns] *= 8./3.;
	earr[(hp->ns-1)*hp->ns + hp->ns-1] *= 8./3.;
	for (i = 1; i < hp->ns-1; i++) {
		earr[i*hp->ns] *= 8./5.;
		earr[i*hp->ns + hp->ns-1] *= 8./5.;
	}
	for (j = 1; j < hp->ns-1; j++) {
		earr[j] *= 8./5.;
		earr[(hp->ns-1)*hp->ns + j] *= 8./5.;
	}
	return(earr);
}
void LocationEditor::RenderModeCameraMount()
{
	RGBAColour bright(255,255,0);
	RGBAColour dim(90,90,0);

	LList <CameraAnimation*> *list = &g_app->m_location->m_levelFile->m_cameraAnimations;
	for (int i = 0; i < list->Size(); ++i)
	{
		CameraAnimation *anim = list->GetData(i);
		CamAnimNode *lastNode = anim->m_nodes.GetData(0);
		for (int j = 1; j < anim->m_nodes.Size(); ++j)
		{
			CamAnimNode *node = anim->m_nodes.GetData(j);
			if (stricmp(node->m_mountName, MAGIC_MOUNT_NAME_START_POS) == 0 ||
				stricmp(lastNode->m_mountName, MAGIC_MOUNT_NAME_START_POS) == 0)
			{
				continue;
			}

			CameraMount *mount1 = g_app->m_location->m_levelFile->GetCameraMount(lastNode->m_mountName);
			CameraMount *mount2 = g_app->m_location->m_levelFile->GetCameraMount(node->m_mountName);
			if (i == m_selectionId)
			{
				RenderArrow(mount1->m_pos, mount2->m_pos, 1.0, bright);
			}
			else
			{
				RenderArrow(mount1->m_pos, mount2->m_pos, 1.0, dim);
			}

			lastNode = node;
		}
	}
}
Exemple #4
0
void
Canvas::DrawButton(PixelRect rc, bool down)
{
  const Pen old_pen = pen;

  Color gray = COLOR_LIGHT_GRAY;
  DrawFilledRectangle(rc, gray);

  Pen bright(1, LightColor(gray));
  Pen dark(1, DarkColor(gray));

  Select(down ? dark : bright);
  DrawTwoLines(rc.left, rc.bottom - 2, rc.left, rc.top,
            rc.right - 2, rc.top);
  DrawTwoLines(rc.left + 1, rc.bottom - 3, rc.left + 1, rc.top + 1,
            rc.right - 3, rc.top + 1);

  Select(down ? bright : dark);
  DrawTwoLines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1,
            rc.right - 1, rc.top + 1);
  DrawTwoLines(rc.left + 2, rc.bottom - 2, rc.right - 2, rc.bottom - 2,
            rc.right - 2, rc.top + 2);

  pen = old_pen;
}
Exemple #5
0
static double
rgb_bright(
	COLOR  clr
)
{
	return(bright(clr));
}
Exemple #6
0
//------------------------------------------------------------------------------
void
Canvas::DrawRaisedEdge(PixelRect &rc)
  {
  Pen bright(1, Color(240, 240, 240));
  this->Select(bright);
  this->DrawTwoLinesExact(rc.left,
                          rc.bottom - 2,
                          rc.left,
                          rc.top,
                          rc.right - 2,
                          rc.top);

  Pen dark(1, Color(128, 128, 128));
  this->Select(dark);
  this->DrawTwoLinesExact(rc.left + 1,
                          rc.bottom - 1,
                          rc.right - 1,
                          rc.bottom - 1,
                          rc.right - 1,
                          rc.top + 1);

  ++rc.left;
  ++rc.top;
  --rc.right;
  --rc.bottom;
  }
Exemple #7
0
static AMBHEMI *
samp_hemi(				/* sample indirect hemisphere */
	COLOR	rcol,
	RAY	*r,
	double	wt
)
{
	AMBHEMI	*hp;
	double	d;
	int	n, i, j;
					/* insignificance check */
	if (bright(rcol) <= FTINY)
		return(NULL);
					/* set number of divisions */
	if (ambacc <= FTINY &&
			wt > (d = 0.8*intens(rcol)*r->rweight/(ambdiv*minweight)))
		wt = d;			/* avoid ray termination */
	n = sqrt(ambdiv * wt) + 0.5;
	i = 1 + 5*(ambacc > FTINY);	/* minimum number of samples */
	if (n < i)
		n = i;
					/* allocate sampling array */
	hp = (AMBHEMI *)malloc(sizeof(AMBHEMI) + sizeof(AMBSAMP)*(n*n - 1));
	if (hp == NULL)
		error(SYSTEM, "out of memory in samp_hemi");
	hp->rp = r;
	hp->ns = n;
	hp->acol[RED] = hp->acol[GRN] = hp->acol[BLU] = 0.0;
	memset(hp->sa, 0, sizeof(AMBSAMP)*n*n);
	hp->sampOK = 0;
					/* assign coefficient */
	copycolor(hp->acoef, rcol);
	d = 1.0/(n*n);
	scalecolor(hp->acoef, d);
					/* make tangent plane axes */
	if (!getperpendicular(hp->ux, r->ron, 1))
		error(CONSISTENCY, "bad ray direction in samp_hemi");
	VCROSS(hp->uy, r->ron, hp->ux);
					/* sample divisions */
	for (i = hp->ns; i--; )
	    for (j = hp->ns; j--; )
		hp->sampOK += ambsample(hp, i, j, 0);
	copycolor(rcol, hp->acol);
	if (!hp->sampOK) {		/* utter failure? */
		free(hp);
		return(NULL);
	}
	if (hp->sampOK < hp->ns*hp->ns) {
		hp->sampOK *= -1;	/* soft failure */
		return(hp);
	}
	if (hp->sampOK < 64)
		return(hp);		/* insufficient for super-sampling */
	n = ambssamp*wt + 0.5;
	if (n > 8) {			/* perform super-sampling? */
		ambsupersamp(hp, n);
		copycolor(rcol, hp->acol);
	}
	return(hp);			/* all is well */
}
    virtual void onDraw(SkCanvas* canvas) {

        SkRect r = SkRect::MakeWH(FILTER_WIDTH, FILTER_HEIGHT);
        SkPaint paint;
        paint.setColor(SK_ColorRED);
        canvas->save();
        for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.2f) {
            SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness));
            SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim));
            paint.setImageFilter(bright);
            drawClippedRect(canvas, r, paint);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        canvas->restore();
        canvas->translate(0, FILTER_HEIGHT + MARGIN);
        {
            SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f));
            SkAutoTUnref<SkImageFilter> grayscale(make_grayscale(brightness));
            paint.setImageFilter(grayscale);
            drawClippedRect(canvas, r, paint);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        {
            SkAutoTUnref<SkImageFilter> grayscale(make_grayscale());
            SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f, grayscale));
            paint.setImageFilter(brightness);
            drawClippedRect(canvas, r, paint);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        {
            SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
            SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f, blue));
            paint.setImageFilter(brightness);
            drawClippedRect(canvas, r, paint);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        {
            SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f));
            SkAutoTUnref<SkImageFilter> blue(make_mode_blue(brightness));
            paint.setImageFilter(blue);
            drawClippedRect(canvas, r, paint);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        {
            SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f));
            SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.5f, blur));
            paint.setImageFilter(brightness);
            drawClippedRect(canvas, r, paint, 3);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
        {
            SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
            paint.setImageFilter(blue.get());
            drawClippedRect(canvas, r, paint, 5);
            canvas->translate(FILTER_WIDTH + MARGIN, 0);
        }
    }
static int
cresp(		/* transform color according to matrix */
	COLOR	cout,
	COLOR	cin
)
{
	colortrans(cout, solmat, cin);
	return(clipgamut(cout, bright(cout), CGAMUT, colmin, colmax));
}
void
lightinit()			/* initialize lighting */
{
	GLfloat	ambv[4];

	if (!dolights)
		return;
	glPushAttrib(GL_LIGHTING_BIT);
	if (expval <= FTINY && bright(ambval) > FTINY)
		expval = 0.2/bright(ambval);
	ambv[0] = expval*colval(ambval,RED);
	ambv[1] = expval*colval(ambval,GRN);
	ambv[2] = expval*colval(ambval,BLU);
	ambv[3] = 1.;
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambv);
	glCallList(lightlist = newglist());
	rgl_checkerr("in lightinit");
	nlights = 0;
}
static void
picdebug(void)			/* put out debugging picture */
{
	static COLOR	blkcol = BLKCOLOR;
	COLOR	*scan;
	int	y, i;
	register int	x, rg;

	if (fseek(stdin, 0L, 0) == EOF) {
		fprintf(stderr, "%s: cannot seek on input picture\n", progname);
		exit(1);
	}
	getheader(stdin, NULL, NULL);		/* skip input header */
	fgetresolu(&xmax, &ymax, stdin);
						/* allocate scanline */
	scan = (COLOR *)malloc(xmax*sizeof(COLOR));
	if (scan == NULL) {
		perror(progname);
		exit(1);
	}
						/* finish debug header */
	fputformat(COLRFMT, debugfp);
	putc('\n', debugfp);
	fprtresolu(xmax, ymax, debugfp);
						/* write debug picture */
	for (y = ymax-1; y >= 0; y--) {
		if (freadscan(scan, xmax, stdin) < 0) {
			fprintf(stderr, "%s: error rereading input picture\n",
					progname);
			exit(1);
		}
		for (x = 0; x < xmax; x++) {
			rg = chartndx(x, y, &i);
			if (rg == RG_CENT) {
				if (!(1L<<i & gmtflags) || (x+y)&07) {
					copycolor(scan[x], mbRGB[i]);
					clipgamut(scan[x], bright(scan[x]),
						CGAMUT, colmin, colmax);
				} else
					copycolor(scan[x], blkcol);
			} else if (rg == RG_CORR)
				cvtcolor(scan[x], scan[x]);
			else if (rg != RG_ORIG)
				copycolor(scan[x], blkcol);
		}
		if (fwritescan(scan, xmax, debugfp) < 0) {
			fprintf(stderr, "%s: error writing debugging picture\n",
					progname);
			exit(1);
		}
	}
						/* clean up */
	fclose(debugfp);
	free((void *)scan);
}
Exemple #12
0
float  drawerWidget::getBright()
{
	int x, y;
	int temp = 0;
	for(x = 0; x < buffer.width(); x++)
	for(y = 0; y < buffer.height(); y++)
	{
		temp += bright(buffer.pixel(x,y));
	}
	return (float)temp/(float)(buffer.height()*buffer.width()*255);
}
Exemple #13
0
float *		/* keep consistent with COLOR typedef */
greyof(				/* convert color to greyscale */
	COLOR  col
)
{
	static COLOR  gcol;
	double  b;

	b = bright(col);
	setcolor(gcol, b, b, b);
	return(gcol);
}
    void onDraw(const int loops, SkCanvas* canvas) override {
        SkRect r = getFilterRect();
        SkPaint paint;
        paint.setColor(SK_ColorRED);

        for (int i = 0; i < loops; i++) {
            for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.4f) {
                SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness));
                SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim));
                paint.setImageFilter(bright);
                canvas->drawRect(r, paint);
            }
        }
    }
Exemple #15
0
QImage convertImage(const QImage& image, int hue, int saturation, int brightness, int gamma)
{
	float	mat[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
	int	lut[3][3][256];
	QRgb	c;
	int	r,g,b,v,r2,g2,b2;
	float	gam = 1.0/(float(gamma)/1000.0);
	QImage	img(image);

	saturate(mat,saturation*0.01);
	huerotate(mat,(float)hue);
	bright(mat,brightness*0.01);
	for (int i = 0; i < 3; i ++)
	  for (int j = 0; j < 3; j ++)
	    for (int k = 0; k < 256; k ++)
		lut[i][j][k] = (int)(mat[i][j] * k + 0.5);
	
	img.detach();
	for (int i=0;i<image.width();i++)
	   for (int j=0;j<image.height();j++)
	   {
	   	c = image.pixel(i,j);
	   	r = qRed(c);
	   	g = qGreen(c);
	   	b = qBlue(c);

	   	v = lut[0][0][r] + lut[1][0][g] + lut[2][0][b];
	   	if (gamma != 1000) v = (int)rint(pow(v,gam));
	   	if (v < 0) r2 = 0;
	   	else if (v > 255) r2 = 255;
	   	else r2 = v;

	   	v = lut[0][1][r] + lut[1][1][g] + lut[2][1][b];
	   	if (gamma != 1000) v = (int)rint(pow(v,gam));
	   	if (v < 0) g2 = 0;
	   	else if (v > 255) g2 = 255;
	   	else g2 = v;

	   	v = lut[0][2][r] + lut[1][2][g] + lut[2][2][b];
	   	if (gamma != 1000) v = (int)rint(pow(v,gam));
	   	if (v < 0) b2 = 0;
	   	else if (v > 255) b2 = 255;
	   	else b2 = v;

	   	img.setPixel(i,j,qRgb(r2,g2,b2));
	   }
	return img;
}
Exemple #16
0
static double
greypoint(			/* compute gamut mapping grey target */
	COLOR col
)
{
	COLOR	gryc;
	int	i;
				/* improves saturated color rendering */
	copycolor(gryc, col);
	for (i = 3; i--; )
		if (gryc[i] > 1)
			gryc[i] = 1;
		else if (gryc[i] < 0)
			gryc[i] = 0;
	return(bright(gryc));
}
Exemple #17
0
  void raised_edge(PixelRect &rc) {
    Pen bright(1, Color(240, 240, 240));
    select(bright);
    two_lines(rc.left, rc.bottom - 2, rc.left, rc.top,
              rc.right - 2, rc.top);

    Pen dark(1, Color(128, 128, 128));
    select(dark);
    two_lines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1,
              rc.right - 1, rc.top + 1);

    ++rc.left;
    ++rc.top;
    --rc.right;
    --rc.bottom;
  }
static int
cvtcolor(		/* convert color according to our mapping */
	COLOR	cout,
	COLOR	cin
)
{
	COLOR	ctmp;
	int	clipped;

	if (wcor != NULL) {
		clipped = warp3d(cout, cin, wcor);
		clipped |= clipgamut(cout,bright(cout),CGAMUT,colmin,colmax);
	} else if (scanning) {
		bresp(ctmp, cin);
		clipped = cresp(cout, ctmp);
	} else {
		clipped = cresp(ctmp, cin);
		bresp(cout, ctmp);
	}
	return(clipped);
}
Exemple #19
0
static AMBVAL *
avstore(				/* allocate memory and store aval */
	AMBVAL  *aval
)
{
	AMBVAL  *av;
	double	d;

	if ((av = newambval()) == NULL)
		error(SYSTEM, "out of memory in avstore");
	*av = *aval;
	av->latick = ambclock;
	av->next = NULL;
	nambvals++;
	d = bright(av->val);
	if (d > FTINY) {		/* add to log sum for averaging */
		avsum += log(d);
		navsum++;
	}
	return(av);
}
Exemple #20
0
void
Canvas::draw_button(RECT rc, bool down)
{
  Brush gray(Color(192, 192, 192));
  fill_rectangle(rc, gray);

  Pen bright(1, Color(240, 240, 240));
  Pen dark(1, Color(128, 128, 128));

  select(down ? dark : bright);
  two_lines(rc.left, rc.bottom - 2, rc.left, rc.top,
            rc.right - 2, rc.top);
  two_lines(rc.left + 1, rc.bottom - 3, rc.left + 1, rc.top + 1,
            rc.right - 3, rc.top + 1);

  select(down ? bright : dark);
  two_lines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1,
            rc.right - 1, rc.top + 1);
  two_lines(rc.left + 2, rc.bottom - 2, rc.right - 2, rc.bottom - 2,
            rc.right - 2, rc.top + 2);

  white_pen();
}
Exemple #21
0
Blob::Blob(PG_Widget* parent, PG_Rect r): PG_ThemeWidget(parent, r, true){

    starttimer = 0;
    
  	vmem1=NULL;
	vmem2= (unsigned char *)malloc(XSIZE*YSIZE);
	if(!vmem2) nomem();
	mul640= (unsigned char **)malloc(YSIZE*sizeof(char *));
	if(!mul640) nomem();
	remap= (char *)malloc(16384);
	if(!remap) nomem();
	remap2=(char *)malloc(16384);
	if(!remap2) nomem();
	blobs= (explosion *)malloc(MAXBLOBS*sizeof(struct explosion));
	if(!blobs) nomem();

  	freeblobs=activeblobs=0;
	for(int i=0;i<MAXBLOBS;i++)
	{
		blobs[i].blobnext=freeblobs;
		freeblobs=blobs+i;
	}

	normal(remap);
	bright(remap2);

    explosion_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, my_width, my_height, 8, 0,0,0,0);
    
	flash=0;
	whichmap=0;
	loadcolors(whichmap);
	//addblob();
	now=0;
	
  
}
Exemple #22
0
extern void
direct(					/* add direct component */
	RAY  *r,			/* ray that hit surface */
	srcdirf_t *f,			/* direct component coefficient function */
	void  *p			/* data for f */
)
{
	register int  sn;
	register CONTRIB  *scp;
	SRCINDEX  si;
	int  nshadcheck, ncnts;
	int  nhits;
	double  prob, ourthresh, hwt;
	RAY  sr;
			/* NOTE: srccnt and cntord global so no recursion */
	if (nsources <= 0)
		return;		/* no sources?! */
						/* potential contributions */
	initsrcindex(&si);
	for (sn = 0; srcray(&sr, r, &si); sn++) {
		if (sn >= maxcntr) {
			maxcntr = sn + MAXSPART;
			srccnt = (CONTRIB *)realloc((void *)srccnt,
					maxcntr*sizeof(CONTRIB));
			cntord = (CNTPTR *)realloc((void *)cntord,
					maxcntr*sizeof(CNTPTR));
			if ((srccnt == NULL) | (cntord == NULL))
				error(SYSTEM, "out of memory in direct");
		}
		cntord[sn].sndx = sn;
		scp = srccnt + sn;
		scp->sno = sr.rsrc;
						/* compute coefficient */
		(*f)(scp->coef, p, sr.rdir, si.dom);
		cntord[sn].brt = intens(scp->coef);
		if (cntord[sn].brt <= 0.0)
			continue;
#if SHADCACHE
						/* check shadow cache */
		if (si.np == 1 && srcblocked(&sr)) {
			cntord[sn].brt = 0.0;
			continue;
		}
#endif
		VCOPY(scp->dir, sr.rdir);
		copycolor(sr.rcoef, scp->coef);
						/* compute potential */
		sr.revf = srcvalue;
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		copycolor(scp->val, sr.rcol);
		cntord[sn].brt = bright(sr.rcol);
	}
						/* sort contributions */
	qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
	{					/* find last */
		register int  l, m;

		ncnts = l = sn;
		sn = 0;
		while ((m = (sn + ncnts) >> 1) != l) {
			if (cntord[m].brt > 0.0)
				sn = m;
			else
				ncnts = m;
			l = m;
		}
	}
	if (ncnts == 0)
		return;		/* no contributions! */
                                                /* accumulate tail */
        for (sn = ncnts-1; sn > 0; sn--)
                cntord[sn-1].brt += cntord[sn].brt;
						/* compute number to check */
	nshadcheck = pow((double)ncnts, shadcert) + .5;
						/* modify threshold */
	ourthresh = shadthresh / r->rweight;
						/* test for shadows */
	for (nhits = 0, hwt = 0.0, sn = 0; sn < ncnts;
			hwt += (double)source[scp->sno].nhits /
				(double)source[scp->sno].ntests,
			sn++) {
						/* check threshold */
		if ((sn+nshadcheck>=ncnts ? cntord[sn].brt :
				cntord[sn].brt-cntord[sn+nshadcheck].brt)
				< ourthresh*bright(r->rcol))
			break;
		scp = srccnt + cntord[sn].sndx;
						/* test for hit */
		rayorigin(&sr, SHADOW, r, NULL);
		copycolor(sr.rcoef, scp->coef);
		VCOPY(sr.rdir, scp->dir);
		sr.rsrc = scp->sno;
						/* keep statistics */
		if (source[scp->sno].ntests++ > 0xfffffff0) {
			source[scp->sno].ntests >>= 1;
			source[scp->sno].nhits >>= 1;
		}
		if (localhit(&sr, &thescene) &&
				( sr.ro != source[scp->sno].so ||
				source[scp->sno].sflags & SFOLLOW )) {
						/* follow entire path */
			raycont(&sr);
			if (trace != NULL)
				(*trace)(&sr);	/* trace execution */
			if (bright(sr.rcol) <= FTINY) {
#if SHADCACHE
				if ((scp <= srccnt || scp[-1].sno != scp->sno)
						&& (scp >= srccnt+ncnts-1 ||
						    scp[1].sno != scp->sno))
					srcblocker(&sr);
#endif
				continue;	/* missed! */
			}
			rayparticipate(&sr);
			multcolor(sr.rcol, sr.rcoef);
			copycolor(scp->val, sr.rcol);
		} else if (trace != NULL &&
			(source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW))
						== (SDISTANT|SFOLLOW) &&
				sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) {
			(*trace)(&sr);		/* trace execution */
			/* skip call to rayparticipate() & scp->val update */
		}
						/* add contribution if hit */
		addcolor(r->rcol, scp->val);
		nhits++;
		source[scp->sno].nhits++;
	}
Exemple #23
0
static int
disperse(  /* check light sources for dispersion */
	OBJREC  *m,
	RAY  *r,
	FVECT  vt,
	double  tr,
	COLOR  cet,
	COLOR  abt
)
{
	RAY  sray;
	const RAY  *entray;
	FVECT  v1, v2, n1, n2;
	FVECT  dv, v2Xdv;
	double  v2Xdvv2Xdv;
	int  success = 0;
	SRCINDEX  si;
	FVECT  vtmp1, vtmp2;
	double  dtmp1, dtmp2;
	int  l1, l2;
	COLOR  ctmp;
	int  i;
	
	/*
	 *     This routine computes dispersion to the first order using
	 *  the following assumptions:
	 *
	 *	1) The dependency of the index of refraction on wavelength
	 *		is approximated by Hartmann's equation with lambda0
	 *		equal to zero.
	 *	2) The entry and exit locations are constant with respect
	 *		to dispersion.
	 *
	 *     The second assumption permits us to model dispersion without
	 *  having to sample refracted directions.  We assume that the
	 *  geometry inside the material is constant, and concern ourselves
	 *  only with the relationship between the entering and exiting ray.
	 *  We compute the first derivatives of the entering and exiting
	 *  refraction with respect to the index of refraction.  This 
	 *  is then used in a first order Taylor series to determine the
	 *  index of refraction necessary to send the exiting ray to each
	 *  light source.
	 *     If an exiting ray hits a light source within the refraction
	 *  boundaries, we sum all the frequencies over the disc of the
	 *  light source to determine the resulting color.  A smaller light
	 *  source will therefore exhibit a sharper spectrum.
	 */

	if (!(r->crtype & REFRACTED)) {		/* ray started in material */
		VCOPY(v1, r->rdir);
		n1[0] = -r->rdir[0]; n1[1] = -r->rdir[1]; n1[2] = -r->rdir[2];
	} else {
						/* find entry point */
		for (entray = r; entray->rtype != REFRACTED;
				entray = entray->parent)
			;
		entray = entray->parent;
		if (entray->crtype & REFRACTED)		/* too difficult */
			return(0);
		VCOPY(v1, entray->rdir);
		VCOPY(n1, entray->ron);
	}
	VCOPY(v2, vt);			/* exiting ray */
	VCOPY(n2, r->ron);

					/* first order dispersion approx. */
	dtmp1 = 1./DOT(n1, v1);
	dtmp2 = 1./DOT(n2, v2);
	for (i = 0; i < 3; i++)
		dv[i] = v1[i] + v2[i] - n1[i]*dtmp1 - n2[i]*dtmp2;
		
	if (DOT(dv, dv) <= FTINY)	/* null effect */
		return(0);
					/* compute plane normal */
	fcross(v2Xdv, v2, dv);
	v2Xdvv2Xdv = DOT(v2Xdv, v2Xdv);

					/* check sources */
	initsrcindex(&si);
	while (srcray(&sray, r, &si)) {

		if (DOT(sray.rdir, v2) < MINCOS)
			continue;			/* bad source */
						/* adjust source ray */

		dtmp1 = DOT(v2Xdv, sray.rdir) / v2Xdvv2Xdv;
		sray.rdir[0] -= dtmp1 * v2Xdv[0];
		sray.rdir[1] -= dtmp1 * v2Xdv[1];
		sray.rdir[2] -= dtmp1 * v2Xdv[2];

		l1 = lambda(m, v2, dv, sray.rdir);	/* mean lambda */

		if (l1 > MAXLAMBDA || l1 < MINLAMBDA)	/* not visible */
			continue;
						/* trace source ray */
		copycolor(sray.cext, cet);
		copycolor(sray.albedo, abt);
		normalize(sray.rdir);
		rayvalue(&sray);
		if (bright(sray.rcol) <= FTINY)	/* missed it */
			continue;
		
		/*
		 *	Compute spectral sum over diameter of source.
		 *  First find directions for rays going to opposite
		 *  sides of source, then compute wavelengths for each.
		 */
		 
		fcross(vtmp1, v2Xdv, sray.rdir);
		dtmp1 = sqrt(si.dom  / v2Xdvv2Xdv / PI);

							/* compute first ray */
		VSUM(vtmp2, sray.rdir, vtmp1, dtmp1);

		l1 = lambda(m, v2, dv, vtmp2);		/* first lambda */
		if (l1 < 0)
			continue;
							/* compute second ray */
		VSUM(vtmp2, sray.rdir, vtmp1, -dtmp1);

		l2 = lambda(m, v2, dv, vtmp2);		/* second lambda */
		if (l2 < 0)
			continue;
					/* compute color from spectrum */
		if (l1 < l2)
			spec_rgb(ctmp, l1, l2);
		else
			spec_rgb(ctmp, l2, l1);
		multcolor(ctmp, sray.rcol);
		scalecolor(ctmp, tr);
		addcolor(r->rcol, ctmp);
		success++;
	}
	return(success);
}
Exemple #24
0
void Compressor::Compress(unsigned int *out) {
  /* Create the matrix with the original data */
  Eigen::MatrixXi orig(height_, width_);
  for (int y = 0; y < height_; ++y) {
    for (int x = 0; x < width_; ++x) {
      orig(y, x) = data_[y*width_ + x];
    }
  }

  /* Get the internal data format */
  util::DATA_FORMAT df = util::ImageToData(format_);
  
  /* Convert to YUV if necessary */
  Eigen::MatrixXi bits;
  if (format_ == PVRTC_4BPP || format_ == PVRTC_2BPP) {
    bits = orig;
  } else {
    bits = util::RGBtoYUV(orig);
  }
    
  /* Wavelet filter */
  Eigen::MatrixXi result = util::Downscale(bits);
    
  /* Initial dark and bright prototypes */
  Eigen::Vector3i offset(32, 32, 32);
  Eigen::MatrixXi dark(result.rows(), result.cols());
  Eigen::MatrixXi bright(result.rows(), result.cols());

#ifdef USE_OPENMP
#pragma omp parallel for
#endif
  for(int y = 0; y < result.rows(); ++y) {
    for(int x = 0; x < result.cols(); ++x) {
      Eigen::Vector3i color = util::MakeColorVector(result(y, x), util::PVR888);
      dark(y, x) = util::MakeRGB(color - offset, df);
      bright(y, x) = util::MakeRGB(color + offset, df);
    }
  }
  
  // Eigen::MatrixXi dark = result - offset;
  // Eigen::MatrixXi bright = result + offset;
    
  /* Iterative optimization */
  Optimizer opt(bits, dark, bright, Optimizer::SVD, df);
  float prev_err = std::numeric_limits<float>::max();
  float curr_err = std::numeric_limits<float>::max();
  for (int k = 0; (k < 4 || (prev_err - curr_err) > 1e-10) && (k < 20); ++k) {
    /* Least squares optimization */
    opt.Optimize(ComputeModulation(bits,
                                   util::Upscale4x4(opt.dark(), df),
                                   util::Upscale4x4(opt.bright(), df)));

    /* Get the current error */
    result = util::ModulateImage(util::Upscale4x4(opt.dark(), df),
                                 util::Upscale4x4(opt.bright(), df),
                                 opt.mod());
    prev_err = curr_err;
    curr_err = util::ComputeError(orig, result);
  }
    
  /* Write the final output */
  result = util::ModulateImage(util::Upscale4x4(opt.dark(), df),
                               util::Upscale4x4(opt.bright(), df),
                               opt.mod());

  /* Convert back to RGB if necessary */
  if (!(format_ == PVRTC_4BPP || format_ == PVRTC_2BPP)) {
    result = util::YUVtoRGB(result);
  } 
  for (int y = 0; y < result.rows(); ++y) {
    for (int x = 0; x < result.cols(); ++x) {
      out[y*width_ + x] = result(y, x);
    }
  }
    
  /* Get the error */
  std::cout << "RMS Error: " << util::ComputeError(orig, result) << std::endl;
}
Exemple #25
0
extern void
multambient(		/* compute ambient component & multiply by coef. */
	COLOR  aval,
	RAY  *r,
	FVECT  nrm
)
{
	static int  rdepth = 0;			/* ambient recursion */
	COLOR	acol;
	double	d, l;

	if (ambdiv <= 0)			/* no ambient calculation */
		goto dumbamb;
						/* check number of bounces */
	if (rdepth >= ambounce)
		goto dumbamb;
						/* check ambient list */
	if (ambincl != -1 && r->ro != NULL &&
			ambincl != inset(ambset, r->ro->omod))
		goto dumbamb;

	if (ambacc <= FTINY) {			/* no ambient storage */
		copycolor(acol, aval);
		rdepth++;
		d = doambient(acol, r, r->rweight, NULL, NULL);
		rdepth--;
		if (d <= FTINY)
			goto dumbamb;
		copycolor(aval, acol);
		return;
	}

	if (tracktime)				/* sort to minimize thrashing */
		sortambvals(0);
						/* interpolate ambient value */
	setcolor(acol, 0.0, 0.0, 0.0);
	d = sumambient(acol, r, nrm, rdepth,
			&atrunk, thescene.cuorg, thescene.cusize);
	if (d > FTINY) {
		d = 1.0/d;
		scalecolor(acol, d);
		multcolor(aval, acol);
		return;
	}
	rdepth++;				/* need to cache new value */
	d = makeambient(acol, r, nrm, rdepth-1);
	rdepth--;
	if (d > FTINY) {
		multcolor(aval, acol);		/* got new value */
		return;
	}
dumbamb:					/* return global value */
	if ((ambvwt <= 0) | (navsum == 0)) {
		multcolor(aval, ambval);
		return;
	}
	l = bright(ambval);			/* average in computations */
	if (l > FTINY) {
		d = (log(l)*(double)ambvwt + avsum) /
				(double)(ambvwt + navsum);
		d = exp(d) / l;
		scalecolor(aval, d);
		multcolor(aval, ambval);	/* apply color of ambval */
	} else {
		d = exp( avsum / (double)navsum );
		scalecolor(aval, d);		/* neutral color */
	}
}
Exemple #26
0
void
getexposure(				/* get new exposure */
	char  *s
)
{
	char  buf[128];
	char  *cp;
	int  x, y;
	PNODE  *p = &ptrunk;
	int  adapt = 0;
	double  e = 1.0;

	for (cp = s; isspace(*cp); cp++)
		;
	if (*cp == '@') {
		adapt++;
		while (isspace(*++cp))
			;
	}
	if (*cp == '\0') {		/* normalize to point */
		if (dev->getcur == NULL)
			return;
		(*dev->comout)("Pick point for exposure\n");
		if ((*dev->getcur)(&x, &y) == ABORT)
			return;
		p = findrect(x, y, &ptrunk, -1);
	} else {
		if (*cp == '=') {	/* absolute setting */
			p = NULL;
			e = 1.0/exposure;
			for (cp++; isspace(*cp); cp++)
				;
			if (*cp == '\0') {	/* interactive */
				sprintf(buf, "exposure (%f): ", exposure);
				(*dev->comout)(buf);
				(*dev->comin)(buf, NULL);
				for (cp = buf; isspace(*cp); cp++)
					;
				if (*cp == '\0')
					return;
			}
		}
		if (*cp == '+' || *cp == '-')	/* f-stops */
			e *= pow(2.0, atof(cp));
		else				/* multiplier */
			e *= atof(cp);
	}
	if (p != NULL) {		/* relative setting */
		compavg(p);
		if (bright(p->v) < 1e-15) {
			error(COMMAND, "cannot normalize to zero");
			return;
		}
		if (adapt)
			e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure;
		else
			e *= 0.5 / bright(p->v);
	}
	if (e <= FTINY || fabs(1.0 - e) <= FTINY)
		return;
	scalepict(&ptrunk, e);
	exposure *= e;
	redraw();
}
Exemple #27
0
void exportBy(const QImage& bg, const QImage& smap)
{
    if (bg.size() != smap.size()) //assert size match
        return;

    Vec3 lp = Session::get()->canvas()->lightPos3D();

    int W = bg.width(), H = bg.height();

    RGBA
            histogram[BUCKETS][SAT_BUCKETS][BUCKETS];

    for(int i_h = 0; i_h < H; i_h++)
    {
        for(int i_w = 0; i_w < W; i_w++)
        {
            //QColor col = QColor(_img.pixel( x - (ww/2) + i,  y - (hh/2) + j ));
            QColor col(bg.pixel(i_w, i_h));
            float
                    h = col.hueF(),
                    s = col.saturationF(),
                    v = col.valueF();

            if (h < 0)
                continue;

            int
                    bi_h = CLAMP((h * BUCKETS), 0 , BUCKETS-1),
                    bi_s = CLAMP((s * SAT_BUCKETS), 0 , SAT_BUCKETS-1),
                    bi_v = CLAMP((v * BUCKETS), 0 , BUCKETS-1);

            histogram[bi_h][bi_s][bi_v] = histogram[bi_h][bi_s][bi_v] + RGBA(col.redF(), col.greenF(), col.blueF(),1);
        }
    }

    int size =  W*H;

    //QImage darkI(W, H, QImage::Format_ARGB32);
    //QImage brightI(W, H, QImage::Format_ARGB32);

    uchar* darkbits   = new uchar[size*4];
    uchar* brightbits = new uchar[size*4];
    uchar* final2bits = new uchar[size*4];

    for(int i_h = 0; i_h < H; i_h++)
    {
        for(int i_w = 0; i_w < W; i_w++)
        {
            //QColor col = QColor(_img.pixel( x - (ww/2) + i,  y - (hh/2) + j ));
            QRgb nrgb = smap.pixel(i_w, i_h);
            QColor coln(nrgb);

            if (qAlpha(nrgb) == 0) continue;

            //Vec3 n(coln.redF(), coln.greenF(), coln.blueF());

            Vec3 n(coln.redF()*2.0-1.0, coln.greenF()*2.0-1.0,0);
            n.z = sqrt(n.x*n.x + n.y*n.y);

            //if (n.norm()>1.0) continue;

            double px = i_w *2.0 / (W-1) - 1.0;
            double py = (H - i_h - 1)*2.0 / (H-1) - 1.0;

            Vec3 lvn = (lp - Vec3(px, py, 0)).normalize();

            float cosa = n * lvn;
            float t = (cosa+1)/2.0;
            t = CLAMP(t, 0.0, 1.0);

            QColor col(bg.pixel(i_w, i_h));

            RGB dark(0, 0, 0);
            RGB bright(1,1,1);
            RGB final(col.redF(), col.greenF(), col.blueF());

            if (col.hueF()>=0)
            {
                int
                        bi_h = col.hueF()*BUCKETS,
                        bi_s = col.saturationF()*SAT_BUCKETS, iD, iB;
                findDandB(histogram[bi_h][bi_s], iD, iB);
                dark.set(histogram[bi_h][bi_s][iD]);
                bright.set(histogram[bi_h][bi_s][iB]);
            }

            //bright = (final-dark*(1.0-t))*(1.0/t);

            RGB final2 = bright*t + dark*(1-t);

            int off = (i_w + i_h*W)*4;

            for(int i=0; i<3; i++)
            {
                float k = final[i]/(final2[i]<0.0001?0.0001:final2[i]);
                darkbits[off+2-i] = CLAMP(dark[i]*k, 0.0, 1.0)*255;
                brightbits[off+2-i] =CLAMP(bright[i]*k, 0.0, 1.0)*255;
                final2bits[off+2-i] = final2[i]*255;
            }

            darkbits[off+3] = 255;
            brightbits[off+3] = 255;
            final2bits[off+3] = 255;
        }
    }

    QImage darkI(darkbits, W, H, QImage::Format_ARGB32);
    QImage brightI(brightbits, W, H, QImage::Format_ARGB32);
    QImage final2I(final2bits, W, H, QImage::Format_ARGB32);

    darkI.save("c:/temp/D.png");
    brightI.save("c:/temp/B.png");
    smap.save("c:/temp/smap.png");
    final2I.save("c:/temp/final2.png");
}
Exemple #28
0
static void
dirbrdf(		/* compute source contribution */
	COLOR  cval,			/* returned coefficient */
	void  *nnp,		/* material data */
	FVECT  ldir,			/* light source direction */
	double  omega			/* light source size */
)
{
	BRDFDAT *np = nnp;
	double  ldot;
	double  dtmp;
	COLOR  ctmp;
	FVECT  ldx;
	static double  vldx[5], pt[MAXDIM];
	char	**sa;
	int	i;
#define lddx (vldx+1)

	setcolor(cval, 0.0, 0.0, 0.0);
	
	ldot = DOT(np->pnorm, ldir);

	if (ldot <= FTINY && ldot >= -FTINY)
		return;		/* too close to grazing */

	if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY)
		return;		/* wrong side */

	if (ldot > 0.0) {
		/*
		 *  Compute and add diffuse reflected component to returned
		 *  color.  The diffuse reflected component will always be
		 *  modified by the color of the material.
		 */
		copycolor(ctmp, np->rdiff);
		dtmp = ldot * omega / PI;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	} else {
		/*
		 *  Diffuse transmitted component.
		 */
		copycolor(ctmp, np->tdiff);
		dtmp = -ldot * omega / PI;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	}
	if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY)
		return;		/* diffuse only */
					/* set up function */
	setbrdfunc(np);
	sa = np->mp->oargs.sarg;
	errno = 0;
					/* transform light vector */
	multv3(ldx, ldir, funcxf.xfm);
	for (i = 0; i < 3; i++)
		lddx[i] = ldx[i]/funcxf.sca;
	lddx[3] = omega;
					/* compute BRTDF */
	if (np->mp->otype == MAT_BRTDF) {
		if (sa[6][0] == '0')		/* special case */
			colval(ctmp,RED) = 0.0;
		else
			colval(ctmp,RED) = funvalue(sa[6], 4, lddx);
		if (sa[7][0] == '0')
			colval(ctmp,GRN) = 0.0;
		else if (!strcmp(sa[7],sa[6]))
			colval(ctmp,GRN) = colval(ctmp,RED);
		else
			colval(ctmp,GRN) = funvalue(sa[7], 4, lddx);
		if (!strcmp(sa[8],sa[6]))
			colval(ctmp,BLU) = colval(ctmp,RED);
		else if (!strcmp(sa[8],sa[7]))
			colval(ctmp,BLU) = colval(ctmp,GRN);
		else
			colval(ctmp,BLU) = funvalue(sa[8], 4, lddx);
		dtmp = bright(ctmp);
	} else if (np->dp == NULL) {
		dtmp = funvalue(sa[0], 4, lddx);
		setcolor(ctmp, dtmp, dtmp, dtmp);
	} else {
		for (i = 0; i < np->dp->nd; i++)
			pt[i] = funvalue(sa[3+i], 4, lddx);
		vldx[0] = datavalue(np->dp, pt);
		dtmp = funvalue(sa[0], 5, vldx);
		setcolor(ctmp, dtmp, dtmp, dtmp);
	}
	if ((errno == EDOM) | (errno == ERANGE)) {
		objerror(np->mp, WARNING, "compute error");
		return;
	}
	if (dtmp <= FTINY)
		return;
	if (ldot > 0.0) {
		/*
		 *  Compute reflected non-diffuse component.
		 */
		if ((np->mp->otype == MAT_MFUNC) | (np->mp->otype == MAT_MDATA))
			multcolor(ctmp, np->mcolor);
		dtmp = ldot * omega * np->rspec;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	} else {
		/*
		 *  Compute transmitted non-diffuse component.
		 */
		if ((np->mp->otype == MAT_TFUNC) | (np->mp->otype == MAT_TDATA))
			multcolor(ctmp, np->mcolor);
		dtmp = -ldot * omega * np->tspec;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	}
#undef lddx
}
Exemple #29
0
int
m_brdf(			/* color a ray that hit a BRDTfunc material */
	OBJREC  *m,
	RAY  *r
)
{
	int  hitfront = 1;
	BRDFDAT  nd;
	RAY  sr;
	double  mirtest=0, mirdist=0;
	double  transtest=0, transdist=0;
	int  hasrefl, hastrans;
	int  hastexture;
	COLOR  ctmp;
	FVECT  vtmp;
	double  d;
	MFUNC  *mf;
	int  i;
						/* check arguments */
	if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9))
		objerror(m, USER, "bad # arguments");
	nd.mp = m;
	nd.pr = r;
						/* dummy values */
	nd.rspec = nd.tspec = 1.0;
	nd.trans = 0.5;
						/* diffuse reflectance */
	if (r->rod > 0.0)
		setcolor(nd.rdiff, m->oargs.farg[0],
				m->oargs.farg[1],
				m->oargs.farg[2]);
	else
		setcolor(nd.rdiff, m->oargs.farg[3],
				m->oargs.farg[4],
				m->oargs.farg[5]);
						/* diffuse transmittance */
	setcolor(nd.tdiff, m->oargs.farg[6],
			m->oargs.farg[7],
			m->oargs.farg[8]);
						/* get modifiers */
	raytexture(r, m->omod);
	hastexture = DOT(r->pert,r->pert) > FTINY*FTINY;
	if (hastexture) {			/* perturb normal */
		nd.pdot = raynormal(nd.pnorm, r);
	} else {
		VCOPY(nd.pnorm, r->ron);
		nd.pdot = r->rod;
	}
	if (r->rod < 0.0) {			/* orient perturbed values */
		nd.pdot = -nd.pdot;
		for (i = 0; i < 3; i++) {
			nd.pnorm[i] = -nd.pnorm[i];
			r->pert[i] = -r->pert[i];
		}
		hitfront = 0;
	}
	copycolor(nd.mcolor, r->pcol);		/* get pattern color */
	multcolor(nd.rdiff, nd.mcolor);		/* modify diffuse values */
	multcolor(nd.tdiff, nd.mcolor);
	hasrefl = bright(nd.rdiff) > FTINY;
	hastrans = bright(nd.tdiff) > FTINY;
						/* load cal file */
	nd.dp = NULL;
	mf = getfunc(m, 9, 0x3f, 0);
						/* compute transmitted ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[3]),
			evalue(mf->ep[4]),
			evalue(mf->ep[5]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, TRANS, r, ctmp) == 0) {
		if (!(r->crtype & SHADOW) && hastexture) {
						/* perturb direction */
			VSUM(sr.rdir, r->rdir, r->pert, -.75);
			if (normalize(sr.rdir) == 0.0) {
				objerror(m, WARNING, "illegal perturbation");
				VCOPY(sr.rdir, r->rdir);
			}
		} else {
			VCOPY(sr.rdir, r->rdir);
		}
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture) {
			transtest = 2.0*bright(sr.rcol);
			transdist = r->rot + sr.rt;
		}
	}
	if (r->crtype & SHADOW)			/* the rest is shadow */
		return(1);
						/* compute reflected ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[0]),
			evalue(mf->ep[1]),
			evalue(mf->ep[2]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) {
		VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot);
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) {
			mirtest = 2.0*bright(sr.rcol);
			mirdist = r->rot + sr.rt;
		}
	}
						/* compute ambient */
	if (hasrefl) {
		if (!hitfront)
			flipsurface(r);
		copycolor(ctmp, nd.rdiff);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
		if (!hitfront)
			flipsurface(r);
	}
	if (hastrans) {				/* from other side */
		if (hitfront)
			flipsurface(r);
		vtmp[0] = -nd.pnorm[0];
		vtmp[1] = -nd.pnorm[1];
		vtmp[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.tdiff);
		multambient(ctmp, r, vtmp);
		addcolor(r->rcol, ctmp);
		if (hitfront)
			flipsurface(r);
	}
	if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0')
		direct(r, dirbrdf, &nd);	/* add direct component */

	d = bright(r->rcol);			/* set effective distance */
	if (transtest > d)
		r->rt = transdist;
	else if (mirtest > d)
		r->rt = mirdist;

	return(1);
}
Exemple #30
0
extern void			/* add sources smaller than rad to computed subimage */
drawsources(
	COLOR	*pic[],				/* subimage pixel value array */
	float	*zbf[],				/* subimage distance array (opt.) */
	int	x0,				/* origin and size of subimage */
	int	xsiz,
	int	y0,
	int	ysiz
)
{
	RREAL	spoly[MAXVERT][2], ppoly[MAXVERT][2];
	int	nsv, npv;
	int	xmin, xmax, ymin, ymax, x, y;
	RREAL	cxy[2];
	double	w;
	RAY	sr;
	register SPLIST	*sp;
	register int	i;
					/* check each source in our list */
	for (sp = sphead; sp != NULL; sp = sp->next) {
					/* clip source poly to subimage */
		nsv = box_clip_poly(sp->vl, sp->nv,
				(double)x0/hres, (double)(x0+xsiz)/hres,
				(double)y0/vres, (double)(y0+ysiz)/vres, spoly);
		if (!nsv)
			continue;
					/* find common subimage (BBox) */
		xmin = x0 + xsiz; xmax = x0;
		ymin = y0 + ysiz; ymax = y0;
		for (i = 0; i < nsv; i++) {
			if ((double)xmin/hres > spoly[i][0])
				xmin = spoly[i][0]*hres + FTINY;
			if ((double)xmax/hres < spoly[i][0])
				xmax = spoly[i][0]*hres - FTINY;
			if ((double)ymin/vres > spoly[i][1])
				ymin = spoly[i][1]*vres + FTINY;
			if ((double)ymax/vres < spoly[i][1])
				ymax = spoly[i][1]*vres - FTINY;
		}
					/* evaluate each pixel in BBox */
		for (y = ymin; y <= ymax; y++)
			for (x = xmin; x <= xmax; x++) {
							/* subarea for pixel */
				npv = box_clip_poly(spoly, nsv,
						(double)x/hres, (x+1.)/hres,
						(double)y/vres, (y+1.)/vres,
						ppoly);
				if (!npv)
					continue;	/* no overlap */
				convex_center(ppoly, npv, cxy);
				if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview,
						cxy[0],cxy[1])) < -FTINY)
					continue;	/* not in view */
				if (source[sp->sn].sflags & SSPOT &&
						spotout(&sr, source[sp->sn].sl.s))
					continue;	/* outside spot */
				rayorigin(&sr, SHADOW, NULL, NULL);
				sr.rsrc = sp->sn;
				rayvalue(&sr);		/* compute value */
				if (bright(sr.rcol) <= FTINY)
					continue;	/* missed/blocked */
							/* modify pixel */
				w = poly_area(ppoly, npv) * hres * vres;
				if (zbf[y-y0] != NULL &&
						sr.rt < 0.99*zbf[y-y0][x-x0]) {
					zbf[y-y0][x-x0] = sr.rt;
				} else if (!bigdiff(sr.rcol, pic[y-y0][x-x0],
						0.01)) { /* source sample */
					scalecolor(pic[y-y0][x-x0], w);
					continue;
				}
				scalecolor(sr.rcol, w);
				scalecolor(pic[y-y0][x-x0], 1.-w);
				addcolor(pic[y-y0][x-x0], sr.rcol);
			}
	}
}