//////////////////////////////////////////////////////////////////////
//
//                             Pixie
//
// Copyright © 1999 - 2003, Okan Arikan
//
// Contact: okan@cs.berkeley.edu
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
///////////////////////////////////////////////////////////////////////

// This is the portion of Pixie that draws a point into the stochastic

#ifdef STOCHASTIC_MOVING
#define	displacement	sampleDisplacement
#else
#define	displacement	10
#endif

// This macro draws a sample to the pixel buffer
#ifdef STOCHASTIC_EXTRA_SAMPLES

#ifdef STOCHASTIC_MOVING
#define	drawExtraSamples(__cSample)	{												\
	int				currentSample;													\
	const	float	*s0	=	v0+10;													\
																					\
	for (currentSample=0;currentSample<numExtraSamples;currentSample++,s0++) {		\
		__cSample[currentSample+8].real	=	(s0[0]*(1-jt)+s0[displacement]*jt);		\
	}																				\
}

#else
#define	drawExtraSamples(__cSample)	{												\
	int				currentSample;													\
	const	float	*s0	=	v0+10;													\
																					\
	for (currentSample=0;currentSample<numExtraSamples;currentSample++) {			\
		__cSample[currentSample+8].real	=	s0[currentSample];						\
	}																				\
}
#endif

#else
#define	drawExtraSamples(cSample)
#endif


#ifndef STOCHASTIC_MOVING
// M T
#define	drawPixel() 																\
	if (z < pixel->z) {																\
		newFragment(nSample);														\
		nSample[0].pointer				=	pixel->sample;							\
		pixel->sample					=	nSample;								\
		nSample[1].real					=	z;										\
		nSample[2].real					=	v0c[0];									\
		nSample[3].real					=	v0c[1];									\
		nSample[4].real					=	v0c[2];									\
		nSample[5].real					=	v0o[0];									\
		nSample[6].real					=	v0o[1];									\
		nSample[7].real					=	v0o[2];									\
		drawExtraSamples(nSample)													\
	}


#else
#define	drawPixel() 																\
	if (z < pixel->z) {																\
		newFragment(nSample);														\
		nSample[0].pointer				=	pixel->sample;							\
		pixel->sample					=	nSample;								\
		nSample[1].real					=	z;										\
		nSample[2].real					=	v0c[0]*(1-jt) + v0c[displacement+0]*jt;	\
		nSample[3].real					=	v0c[1]*(1-jt) + v0c[displacement+1]*jt;	\
		nSample[4].real					=	v0c[2]*(1-jt) + v0c[displacement+2]*jt;	\
		nSample[5].real					=	v0o[0]*(1-jt) + v0o[displacement+0]*jt;	\
		nSample[6].real					=	v0o[1]*(1-jt) + v0o[displacement+1]*jt;	\
		nSample[7].real					=	v0o[2]*(1-jt) + v0o[displacement+2]*jt;	\
		drawExtraSamples(nSample)													\
	}


#endif


#ifdef STOCHASTIC_UNSHADED
// We're not shaded yet, so if we pass the depth test, we need to back and shade the grid
#define drawPixelCheck()																	\
	if (z < pixel->z) {																		\
		CRasterGrid	*grid	=	(CRasterGrid *) cPrimitive->grid;							\
		shadeGrid(grid,FALSE);																\
		primitives			=	cPrimitive;													\
		goto restart;																		\
	}
#else
#define drawPixelCheck() drawPixel();
#endif



v0		=	cPrimitive->v0;
v0c		=	v0+3;
v0o		=	v0c+3;

xmin	=	cPrimitive->xbound[0] - left;
ymin	=	cPrimitive->ybound[0] - top;
xmax	=	cPrimitive->xbound[1] - left;
ymax	=	cPrimitive->ybound[1] - top;

xmin	=	max(xmin,0);
ymin	=	max(ymin,0);
xmax	=	min(xmax,xres);
ymax	=	min(ymax,yres);

for (y=ymin;y<=ymax;y++) {
	for (x=xmin;x<=xmax;x++) {
		CPixel			*pixel	=	fb[y]+x;
		const float		xcent	=	pixel->xcent;
		const float		ycent	=	pixel->ycent;

#ifdef STOCHASTIC_MOVING
		const	float	jt		=	pixel->jt;
		interpolatev(v0movTmp,v0,(v0+sampleDisplacement),jt);
		dv0						=	v0movTmp;
		const	float	size	=	cPrimitive->data[0].real*(1-jt) + cPrimitive->data[1].real*jt;
#else
		dv0						=	v0;
		const	float	size	=	cPrimitive->data[0].real;
#endif

#ifdef STOCHASTIC_FOCAL_BLUR
		v0focTmp[COMP_X]		=	dv0[COMP_X] + pixel->jdx*v0[9];
		v0focTmp[COMP_Y]		=	dv0[COMP_Y] + pixel->jdy*v0[9];
		v0focTmp[COMP_Z]		=	dv0[COMP_Z];
		dv0						=	v0focTmp;
#endif

		const	float	dx		=	xcent - dv0[0];
		const	float	dy		=	ycent - dv0[1];

		if ((dx*dx + dy*dy) < (size*size)) {
			const	float	z	=	dv0[2];
			drawPixelCheck();
		}
	}
}




#undef	drawPixelCheck
#undef	drawPixel
#undef	drawExtraSamples
#undef	displacement

