Exemplo n.º 1
0
///////////////////////////////////////////////////////////////////////
// Class				:	CPointHierarchy
// Method				:	average
// Description			:
/// \brief					Create an internal node by averaging the point data
// Return Value			:	-
// Comments				:
int			CPointHierarchy::average(int numItems,int *indices) {
	CMapNode	node;

	// PASS 1:	Average the position/normal
	initv(node.P,0);
	initv(node.N,0);
	for (int i=numItems;i>0;i--) {
		const CPointCloudPoint	*item	=	CMap<CPointCloudPoint>::items + (*indices++);
		addvv(node.P,item->P);
		addvv(node.N,item->N);
	}
	indices	-=	numItems;

	// Normalize the thing
	assert(numItems > 0);
	mulvf(node.P,1/(float) numItems);
	normalizev(node.N);

	// PASS 2:	Compute the maximum deviation
	initv(node.radiosity,0);
	node.dP		=	0;
	node.dN		=	1;
	for (int i=numItems;i>0;i--) {
		vector					D;
		const CPointCloudPoint	*item	=	CMap<CPointCloudPoint>::items + (*indices++);
		const float				*src	=	data.array + item->entryNumber;
		float					area;

		subvv(D,node.P,item->P);
		if (areaIndex == -1)		area	=	max(((float) C_PI*item->dP*item->dP*dotvv(node.N,item->N)),0);
		else						area	=	max((src[areaIndex]*dotvv(node.N,item->N)),0);
		
		node.dP		+=	area;

		if (radiosityIndex != -1) {
			vector	tmp;
			mulvf(tmp,src + radiosityIndex,area);
			addvv(node.radiosity,tmp);
		}

		node.dN		=	min(node.dN,dotvv(node.N,item->N));
	}
	indices		-=	numItems;

	// Normalize the radiosity and the area
	mulvf(node.radiosity,1 / node.dP);				// Normalize the radiosity
	node.dP		=	sqrtf(node.dP / (float) C_PI);	// Convert to effective radius

	// Create the node
	nodes.push(node);
	return nodes.numItems - 1;
}
Exemplo n.º 2
0
///////////////////////////////////////////////////////////////////////
// Class				:	CDelayedInstance
// Method				:	CDelayedInstance
// Description			:
/// \brief					Ctor
// Return Value			:	-
// Comments				:
CDelayedInstance::CDelayedInstance(CAttributes *a,CXform *x,CObject *in) : CObject(a,x) {
	atomicIncrement(&stats.numDelayeds);

	instance		=	in;
	processed		=	FALSE;

	initv(bmin,C_INFINITY);
	initv(bmax,-C_INFINITY);

	CObject	*cObject;
	for (cObject=instance;cObject!=NULL;cObject=cObject->sibling) {
		addBox(bmin,bmax,cObject->bmin);
		addBox(bmin,bmax,cObject->bmax);
	}

	xform->transformBound(this->bmin,this->bmax);
	makeBound(this->bmin,this->bmax);
}
Exemplo n.º 3
0
///////////////////////////////////////////////////////////////////////
// Class				:	CXform
// Method				:	transformBound
// Description			:	This function is used to transform a bounding box
// Return Value			:	-
// Comments				:
void	transformBound(float *lbmin,float *lbmax,const float *to,const float *bmin,const float *bmax) {
	vector		corners[8];
	int			i;
	vector		vtmp;

	// Compute & transfer the corners to the dest space
	initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[0],to,vtmp);

	initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[1],to,vtmp);

	initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[2],to,vtmp);

	initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[3],to,vtmp);

	initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[4],to,vtmp);

	initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[5],to,vtmp);

	initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[6],to,vtmp);

	initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[7],to,vtmp);

	movvv(lbmin,corners[0]);
	movvv(lbmax,corners[0]);

	for (i=1;i<8;i++) {
		addBox(lbmin,lbmax,corners[i]);
	}
}
Exemplo n.º 4
0
///////////////////////////////////////////////////////////////////////
// Class				:	CBSplinePatchGrid
// Method				:	CBSplinePatchGrid
// Description			:
/// \brief					Ctor
// Return Value			:	-
// Comments				:
CBSplinePatchGrid::CBSplinePatchGrid(CAttributes *a,CXform *x,CVertexData *var,CParameter *p,int nu,int nv,float uOrg,float vOrg,float uMult,float vMult,float *ve) : CSurface(a,x) {
	atomicIncrement(&stats.numGprims);

	variables			=	var;
	variables->attach();

	parameters			=	p;

	uVertices			=	nu;
	vVertices			=	nv;
	this->uOrg			=	uOrg;
	this->vOrg			=	vOrg;
	this->uMult			=	uMult;
	this->vMult			=	vMult;

	const int		numVertices		=	(nu*nv);
	int				i,j,k;
	matrix			ut;
	matrix			bsplinebasis;
	matrix			geometryU,geometryV;
	matrix			tmp;
	const int 		upatches		=	uVertices - 3;
	const int	 	vpatches		=	vVertices - 3;

	initv(bmin,C_INFINITY,C_INFINITY,C_INFINITY);
	initv(bmax,-C_INFINITY,-C_INFINITY,-C_INFINITY);
	
	// Note that u basis and v basis are swapped to take the transpose into account done during the precomputation
	// Note also that we could use the B-spline basis to bound the curve, but Bezier bound is tighter
	for (i=0;i<4;i++)
		for (j=0;j<4;j++)
			bsplinebasis[element(i,j)]	=	RiBSplineBasis[j][i];
	transposem(ut,bsplinebasis);
	mulmm(geometryV,invBezier,ut);
	mulmm(geometryU,bsplinebasis,invBezier);
	
	// alloc off upatches*vpatches*16*vertexSize worth of data
	const int	vertexSize	=	var->vertexSize;
	const int	vs			=	(variables->moving ? vertexSize*2 : vertexSize);
	vertex					=	new float[vs*16*upatches*vpatches];
	
	for (i=0;i<vpatches;i++) {
		for (j=0;j<upatches;j++) {
			int		r,c;
			float	*patchData = vertex + (i*upatches + j)*16*vertexSize;

			// Fill in the geometry matrices
			for (r=0;r<4;r++) {
				int					y	=	(r + i) % vVertices;
				for (c=0;c<4;c++) {
					int			x	=	(c + j) % uVertices;
					const float	*d	=	ve + (y*uVertices+x)*vs;

					for	(k=0;k<vertexSize;k++) {
						patchData[16*k + element(r,c)]		=	*d++;
					}
				}
			}

			// add to bounds
			makeCubicBound(bmin,bmax,patchData+0*16,patchData+1*16,patchData+2*16);
			
			// precompute B*G*B' and stash it
			for	(k=0;k<vertexSize;k++) {
				mulmm(tmp,ut,patchData);
				mulmm(patchData,tmp,bsplinebasis);
				patchData += 16;
			}

			// do the same for moving points
			if (variables->moving) {
				patchData = vertex + (upatches*vpatches + i*upatches + j)*16*vertexSize;

				for (r=0;r<4;r++) {
					int					y	=	(r + i) % vVertices;
					for (c=0;c<4;c++) {
						int			x	=	(c + j) % uVertices;
						const float	*d	=	ve + vertexSize + (y*uVertices+x)*vs;
						
						for	(k=0;k<vertexSize;k++) {
							patchData[16*k + element(r,c)]		=	*d++;
						}
					}
				}

				// add to bounds
				makeCubicBound(bmin,bmax,patchData+0*16,patchData+1*16,patchData+2*16);

				// precompute B*G*B' and stash it
				for	(k=0;k<vertexSize;k++) {
					mulmm(tmp,ut,patchData);
					mulmm(patchData,tmp,bsplinebasis);
					patchData += 16;
				}
			}
		}
	}
	
	makeBound(bmin,bmax);
}
Exemplo n.º 5
0
///////////////////////////////////////////////////////////////////////
// Class				:	CBSplinePatchGrid
// Method				:	sample
// Description			:	See object.h
// Return Value			:	-
// Comments				:
void		CBSplinePatchGrid::sample(int start,int numVertices,float **varying,float ***locals,unsigned int &up) const {
	const float		*u				=	varying[VARIABLE_U]+start;
	const float		*v				=	varying[VARIABLE_V]+start;
	const int		vertexSize		=	variables->vertexSize;
	float			*vertexData;
	int				vertexDataStep;
	int				vertexSampleStride;
	const int		upatches		=	uVertices - 3;
	const int		vpatches		=	vVertices - 3;
	

	if (variables->moving == FALSE) {
		vertexData			=	vertex;								// No need for interpolation
		vertexDataStep		=	0;
		vertexSampleStride	=	vertexSize*16;
	} else {									
		if (up & PARAMETER_BEGIN_SAMPLE) {
			vertexData			=	vertex;							// No need for interpolation
			vertexDataStep		=	0;
			vertexSampleStride	=	vertexSize*16;
		} else if (up & PARAMETER_END_SAMPLE) {
			vertexData			=	vertex + vertexSize*16*upatches*vpatches;	// No need for interpolation
			vertexDataStep		=	0;
			vertexSampleStride	=	vertexSize*16;
		} else {
														// Interpolate the vertex data in advance
														// Note: this is potentially hugely expensive
			float			*interpolate;
			const float		*time	=	varying[VARIABLE_TIME] + start;

			vertexData				=	(float *) alloca(numVertices*vertexSize*16*sizeof(float));
			vertexDataStep			=	vertexSize*16;
			vertexSampleStride		=	0;

			interpolate				=	vertexData;

			for (int i=0;i<numVertices;++i) {
				const	int		x			=	(int) floor(min(u[i]*upatches,(uVertices-4)));
				const	int		y			=	(int) floor(min(v[i]*vpatches,(vVertices-4)));
				const 	float	*vertex0	=	vertex + (y*upatches + x)*vertexSize*16;
				const 	float	*vertex1	=	vertex0 + vertexSize*16*upatches*vpatches;
				const	float	ctime		=	*time++;

				for (int j=0;j<vertexDataStep;++j) {
					*interpolate++	=	(float) (vertex0[j]*(1.0-ctime) + vertex1[j]*ctime);
				}
			}
		}
	}
	
	{	// Do the vertices
		float	*intr		=	(float *) alloca(numVertices*vertexSize*sizeof(float));
		float	*dPdu		=	varying[VARIABLE_DPDU] + start*3;
		float	*dPdv		=	varying[VARIABLE_DPDV] + start*3;
		float	*N			=	varying[VARIABLE_NG] + start*3;
		float	*intrStart	=	intr;
		const float um		=	(float) upatches;
		const float vm		=	(float) vpatches;
				
		// Interpolate the vertices
		for (int i=0;i<numVertices;++i) {
			double			tmp1[4],tmp2[4];
			const	int		x			=	(int) floor(min(u[i]*upatches,(uVertices-4)));
			const	int		y			=	(int) floor(min(v[i]*vpatches,(vVertices-4)));
			const	double	cu			=	(u[i]*upatches - x);
			const	double	cv			=	(v[i]*vpatches - y);
			const	float	*data		=	vertexData + (y*upatches + x)*vertexSampleStride;
			const	double	usquared	=	cu*cu;
			const	double	ucubed		=	cu*usquared;
			const	double	vsquared	=	cv*cv;
			const	double	vcubed		=	cv*vsquared;
			int				j;

			for (j=0;j<3;++j,data+=16) {
				for (int t=0;t<4;++t) {
					tmp2[t]	=	3*vsquared*data[element(0,t)] + 2*cv*data[element(1,t)]     + data[element(2,t)];
					tmp1[t]	=	  vcubed*  data[element(0,t)] + vsquared*data[element(1,t)] + cv*data[element(2,t)] + data[element(3,t)];
				}

				dPdv[j]			=	(float) (tmp2[0]*ucubed + tmp2[1]*usquared + tmp2[2]*cu + tmp2[3])*vm;
				dPdu[j]			=	(float) (tmp1[0]*3*usquared + tmp1[1]*2*cu + tmp1[2])*um;
				*intr++			=	(float) (tmp1[0]*ucubed + tmp1[1]*usquared + tmp1[2]*cu + tmp1[3]);
			}

			for (;j<vertexSize;++j) {
				for (int t=0;t<4;++t) {
					tmp1[t]	=	  vcubed*  data[element(0,t)] + vsquared*data[element(1,t)] + cv*data[element(2,t)] + data[element(3,t)];
				}

				*intr++			=	(float) (tmp1[0]*ucubed + tmp1[1]*usquared + tmp1[2]*cu + tmp1[3]);
				data			+=	16;
			}

			crossvv(N,dPdu,dPdv);

			vertexData		+=	vertexDataStep;
			dPdu			+=	3;
			dPdv			+=	3;
			N				+=	3;
		}

		// Note: make the common case fast: We're computing NG,DPDU and DPDV even if it's not required.
		// Most of the time though, surface normal is required

		// Dispatch the vertex data
		variables->dispatch(intrStart,start,numVertices,varying,locals);
	}
	
	// Compute dPdtime
	if (up & PARAMETER_DPDTIME) {
		float	*dest	=	varying[VARIABLE_DPDTIME] + start*3;
		
		// Do we have motion?
		if (variables->moving) {
			assert(u == varying[VARIABLE_U] + start);
			assert(v == varying[VARIABLE_V] + start);
			const int disp	=	vertexSize*16*upatches*vpatches;
			
			// Interpolate the thing
			for (int i=0;i<numVertices;++i) {
				double			tmpStart[4],tmpEnd[4];
				const	int		x			=	(int) floor(min(u[i]*upatches,(uVertices-4)));
				const	int		y			=	(int) floor(min(v[i]*vpatches,(vVertices-4)));
				const	double	cu			=	(u[i]*upatches - x);
				const	double	cv			=	(v[i]*vpatches - y);
				const	float	*data		=	vertex + (y*upatches + x)*vertexSize*16;
				const	double	usquared	=	cu*cu;
				const	double	ucubed		=	cu*usquared;
				const	double	vsquared	=	cv*cv;
				const	double	vcubed		=	cv*vsquared;

				// For x,y,z
				for (int j=0;j<3;++j,data+=16) {
				
					// The inner product
					for (int t=0;t<4;++t) {
						tmpStart[t]	=	  vcubed*  data[element(0,t)]			+ vsquared*data[element(1,t)]			+ cv*data[element(2,t)]				+ data[element(3,t)];
						tmpEnd[t]	=	  vcubed*  data[disp + element(0,t)]	+ vsquared*data[disp + element(1,t)]	+ cv*data[disp + element(2,t)]		+ data[disp + element(3,t)];
					}

					// Update the data
					*dest++			=	(float) ((tmpEnd[0]*ucubed + tmpEnd[1]*usquared + tmpEnd[2]*cu + tmpEnd[3]) - (tmpStart[0]*ucubed + tmpStart[1]*usquared + tmpStart[2]*cu + tmpStart[3]));
				}
				
				// Scale the dPdtime
				mulvf(dest-3,CRenderer::invShutterTime);
			}
		} else {
			// We have no motion, so dPdtime is {0,0,0}
			for (int i=0;i<numVertices;++i,dest+=3)	initv(dest,0,0,0);
		}
	}
	
	// Make sure we don't have any zero normals
	normalFix();
	
	// Turn off the processed parameters
	up	&=	~(PARAMETER_P | PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_NG | PARAMETER_DPDTIME | variables->parameters);
}
Exemplo n.º 6
0
///////////////////////////////////////////////////////////////////////
// Class				:	CShadingContext
// Method				:	convertColorFrom
// Description			:	Do color conversion
// Return Value			:	-
// Comments				:
void		convertColorFrom(float *out,const float *in,ECoordinateSystem s)	{
	switch(s) {
	case COLOR_RGB:
		movvv(out,in);
		break;
	case COLOR_HSL:
		{

#define	HueToRGB(r,m1,m2,h )												\
	if (h<0) h+=1;															\
	if (h>1) h-=1;															\
	if (6.0*h < 1  )		r	= (m1+(m2-m1)*h*6);							\
	else if (2.0*h < 1  )	r	= m2;										\
	else if (3.0*h < 2.0)	r	= (m1+(m2-m1)*((2.0f/3.0f)-h)*6);			\
	else					r	= m1;


			float m1,m2,h;

			if (in[1]==0) initv(out,in[2],in[2],in[2]);
			else {
				if (in[2] <=0.5)	m2 = in[2]*(1+in[1]);
				else				m2 = in[2]+in[1]-in[2]*in[1];
				m1	= 2*in[2]-m2;
				
				h	=	in[0] + (1.0f/3.0f);	HueToRGB(out[0],m1,m2,h);
				h	=	in[0];					HueToRGB(out[1],m1,m2,h);
				h	=	in[0] - (1.0f/3.0f);	HueToRGB(out[2],m1,m2,h);
			}
#undef HueToRGB

		}
		break;
	case COLOR_HSV:
		{
			if (in[1] < -1 || in[1] > 1) {
				if (in[0] == 0) {
					out[0]	=	in[2];
					out[1]	=	in[2];
					out[2]	=	in[2];
				} else {
					out[0]	=	in[0];
					out[1]	=	in[1];
					out[2]	=	in[2];
				}
			} else {
				float	f,p,q,t,h;
				int		i;

				h			=	(float) fmod(in[0],1);
				if (h < 0)	h	+=	1;

				h		*=	6;

				i		=	(int) floor(h);
				f		=	h - i;
				p		=	in[2]*(1-in[1]);
				q		=	in[2]*(1-(in[1]*f));
				t		=	in[2]*(1-(in[1]*(1-f)));

				switch(i) {
				case 0:	out[COMP_R]	=	in[2];	out[COMP_G]	=	t;		out[COMP_B]	=	p;		break;
				case 1:	out[COMP_R]	=	q;		out[COMP_G]	=	in[2];	out[COMP_B]	=	p;		break;
				case 2:	out[COMP_R]	=	p;		out[COMP_G]	=	in[2];	out[COMP_B]	=	t;		break;
				case 3:	out[COMP_R]	=	p;		out[COMP_G]	=	q;		out[COMP_B]	=	in[2];	break;
				case 4:	out[COMP_R]	=	t;		out[COMP_G]	=	p;		out[COMP_B]	=	in[2];	break;
				case 5:	out[COMP_R]	=	in[2];	out[COMP_G]	=	p;		out[COMP_B]	=	q;		break;
				}
			}
		}
		break;
	case COLOR_XYZ:
		out[COMP_R]		=	(float)  (3.24079*in[0]		-	1.537150*in[1]	-	0.498535*in[2]);
		out[COMP_G]		=	(float) (-0.969256*in[0]	+	1.875992*in[1]	+	 0.041556*in[2]);
		out[COMP_B]		=	(float)   (0.055648*in[0]	-	0.204043*in[1]	+	1.057311*in[2]);
		break;
	case COLOR_CIE:
		out[COMP_R]		=	(float)  (3.24079*in[0]		-	1.537150*in[1]	-	0.498535*in[2]);
		out[COMP_G]		=	(float) (-0.969256*in[0]	+	1.875992*in[1]	+	 0.041556*in[2]);
		out[COMP_B]		=	(float)   (0.055648*in[0]	-	0.204043*in[1]	+	1.057311*in[2]);
		break;
	case COLOR_YIQ:
		out[COMP_R]		=	(float) (in[0]	+	0.956*in[1]	+	0.620*in[2]);
		out[COMP_G]		=	(float) (in[0]	-	0.272*in[1]	-	0.647*in[2]);
		out[COMP_B]		=	(float) (in[0]	-	1.108*in[1]	+	1.705*in[2]);
		break;
	case COLOR_XYY:
		vector	tin;

		if (in[2] == 0) {
			tin[0]	=	0;
			tin[1]	=	0;
			tin[2]	=	0;
		} else {
			tin[0]	=	max(in[0]*in[2]/in[1],0);
			tin[1]	=	in[2];
			tin[2]	=	max((1-in[0]-in[1])*in[2]/in[1],0);
		}

		out[COMP_R]		=	(float)  (3.24079*tin[0]		-	1.537150*tin[1]	-	0.498535*tin[2]);
		out[COMP_G]		=	(float) (-0.969256*tin[0]	+	1.875992*tin[1]	+	 0.041556*tin[2]);
		out[COMP_B]		=	(float)   (0.055648*tin[0]	-	0.204043*tin[1]	+	1.057311*tin[2]);

		break;
	default:
		break;
	}
}
Exemplo n.º 7
0
///////////////////////////////////////////////////////////////////////
// Class				:	CShadingContext
// Method				:	convertColorTo
// Description			:	Do color conversion
// Return Value			:	-
// Comments				:
void		convertColorTo(float *out,const float *in,ECoordinateSystem s) {
	switch(s) {
	case COLOR_RGB:
		movvv(out,in);
		break;
	case COLOR_HSL:
		{
			float	mi	=	min(in[0],min(in[1],in[2]));
			float	ma	=	max(in[0],max(in[1],in[2]));

			out[2]		=	(mi + ma) / 2;
			if (ma == mi) {
				out[0]	=	100;// install value out of -1 to 1 range
				out[1]	=	0;
			} else {
				float	d	=	ma - mi;

				if (out[2] < 0.5) {
					out[1]	=	d / (ma + mi);
				} else {
					out[1]	=	d / (2 - (ma + mi));
				}

				if (in[COMP_R]	==	ma) {
					out[0]	=	(in[COMP_G] - in[COMP_B])/d;
				} else if (in[COMP_G] == ma) {
					out[0]	=	2 + (in[COMP_B] - in[COMP_R])/d;
				} else {
					out[0]	=	4 + (in[COMP_R] - in[COMP_G])/d;
				}

				out[0]	/=	(float) 6;

				if (out[0] < 0) out[0] +=	1;
			}
		}
		break;
	case COLOR_HSV:
		{
			float	ma	=	max(in[0],max(in[1],in[2]));
			float	mi	=	min(in[0],min(in[1],in[2]));

			out[2]		=	ma;
			out[1]		=	(ma - mi) / ma;
			if (ma == 0) {
				out[0]	=	100;// install value out of -1 to 1 range
			} else {
				float	d	=	ma	-	mi;

				if (in[COMP_R]	==	ma) {
					out[0]	=	(in[COMP_G] - in[COMP_B])	/	d;
				} else if (in[COMP_G] == ma) {
					out[0]	=	2 + (in[COMP_B] - in[COMP_R])	/	d;
				} else {
					out[0]	=	4 + (in[COMP_R] - in[COMP_G])	/	d;
				}

				out[0]		/=	(float) 6;
				if (out[0] < 0)		out[0]	+=	1;
			}
		}
		break;
	case COLOR_XYZ:
		out[0]	=	(float) (0.412453 * in[COMP_R]	+	0.357580 * in[COMP_G]	+	0.180423 * in[COMP_B]);
		out[1]	=	(float) (0.212671 * in[COMP_R]	+	0.715160 * in[COMP_G]	+	0.072169 * in[COMP_B]);
		out[2]	=	(float) (0.019334 * in[COMP_R]	+	0.119193 * in[COMP_G]	+	0.950227 * in[COMP_B]);
		break;
	case COLOR_CIE:
		out[0]	=	(float) (0.412453 * in[COMP_R]	+	0.357580 * in[COMP_G]	+	0.180423 * in[COMP_B]);
		out[1]	=	(float) (0.212671 * in[COMP_R]	+	0.715160 * in[COMP_G]	+	0.072169 * in[COMP_B]);
		out[2]	=	(float) (0.019334 * in[COMP_R]	+	0.119193 * in[COMP_G]	+	0.950227 * in[COMP_B]);
		break;
	case COLOR_YIQ:
		out[0]	=	(float) (0.299 * in[COMP_R]	+	0.587 * in[COMP_G]	+	0.114 * in[COMP_B]);
		out[1]	=	(float) (0.596 * in[COMP_R]	-	0.275 * in[COMP_G]	-	0.321 * in[COMP_B]);
		out[2]	=	(float) (0.212 * in[COMP_R]	-	0.523 * in[COMP_G]	+	0.311 * in[COMP_B]);
		break;
	case COLOR_XYY:
		vector	tin;
		float	sum;

		tin[0]	=	(float) (0.412453 * in[COMP_R]	+	0.357580 * in[COMP_G]	+	0.180423 * in[COMP_B]);
		tin[1]	=	(float) (0.212671 * in[COMP_R]	+	0.715160 * in[COMP_G]	+	0.072169 * in[COMP_B]);
		tin[2]	=	(float) (0.019334 * in[COMP_R]	+	0.119193 * in[COMP_G]	+	0.950227 * in[COMP_B]);

		sum		=	tin[0] + tin[1] + tin[2];
		if (sum == 0) {
			initv(out,0,0,0);
		} else {
			out[0]	=	tin[0] / sum;
			out[1]	=	tin[1] / sum;
			out[2]	=	tin[2];
		}
		break;
	default:
		break;
	}
}
Exemplo n.º 8
0
///////////////////////////////////////////////////////////////////////
// Class				:	CIrradianceCache
// Method				:	sample
// Description			:	Sample the occlusion
// Return Value			:
// Comments				:
void		CIrradianceCache::sample(float *C,const float *P,const float *dPdu,const float *dPdv,const float *N,CShadingContext *context) {
	CCacheSample			*cSample;
	int						i,j;
	float					coverage;
	vector					irradiance;
	vector					envdir;
	float					rMean;
	CRay					ray;
	vector					X,Y;
	CCacheNode				*cNode;
	int						depth;

	// Allocate memory
	const CShadingScratch	*scratch		=	&(context->currentShadingState->scratch);
	const int				nt				=	(int) (sqrtf(scratch->traceParams.samples / (float) C_PI) + 0.5);
	const int				np				=	(int) (C_PI*nt + 0.5);
	const int				numSamples		=	nt*np;
	CHemisphereSample		*hemisphere		=	(CHemisphereSample *) alloca(numSamples*sizeof(CHemisphereSample));
	
	// initialize texture lookups if needed
	if (scratch->occlusionParams.environment) {
		CTextureLookup::staticInit(&(context->currentShadingState->scratch));
	}
	
	// Create an orthanormal coordinate system
	if (dotvv(dPdu,dPdu) > 0) {
		normalizevf(X,dPdu);
		crossvv(Y,N,X);
	} else if (dotvv(dPdv,dPdv) > 0) {
		normalizevf(X,dPdv);
		crossvv(Y,N,X);
	} else {
		// At this point, we're pretty screwed, so why not use the P
		normalizevf(X,P);
		crossvv(Y,N,X);
	}

	// Sample the hemisphere
	coverage						=	0;
	initv(irradiance,0);
	initv(envdir,0);
	rMean							=	C_INFINITY;
	
	// Calculate the ray differentials (use average spread in theta and phi)
	const float da					=	tanf((float) C_PI/(2*(nt+np)));
	const float db					=	(lengthv(dPdu) + lengthv(dPdv))*0.5f;
	
	if (scratch->occlusionParams.occlusion == TRUE) {

		// We're shading for occlusion
		context->numOcclusionRays			+=	numSamples;
		context->numOcclusionSamples++;

		for (i=0;i<nt;i++) {
			for (j=0;j<np;j++,hemisphere++) {
				float rv[2];
				context->random2d.get(rv);

				float		tmp			=	sqrtf((i+context->urand()) / (float) nt);
				const float	phi			=	(float) (2*C_PI*(j+context->urand()) / (float) np);
				const float	cosPhi		=	(cosf(phi)*tmp);
				const float	sinPhi		=	(sinf(phi)*tmp);

				tmp						=	sqrtf(1 - tmp*tmp);

				ray.dir[0]				=	X[0]*cosPhi + Y[0]*sinPhi + N[0]*tmp;
				ray.dir[1]				=	X[1]*cosPhi + Y[1]*sinPhi + N[1]*tmp;
				ray.dir[2]				=	X[2]*cosPhi + Y[2]*sinPhi + N[2]*tmp;

				const float originJitterX = (rv[0] - 0.5f)*scratch->traceParams.sampleBase;
				const float originJitterY = (rv[1] - 0.5f)*scratch->traceParams.sampleBase;
				
				ray.from[COMP_X]		=	P[COMP_X] + originJitterX*dPdu[0] + originJitterY*dPdv[0];
				ray.from[COMP_Y]		=	P[COMP_Y] + originJitterX*dPdu[1] + originJitterY*dPdv[1];
				ray.from[COMP_Z]		=	P[COMP_Z] + originJitterX*dPdu[2] + originJitterY*dPdv[2];

				ray.flags				=	ATTRIBUTES_FLAGS_DIFFUSE_VISIBLE;
				ray.tmin				=	scratch->traceParams.bias;
				ray.t					=	scratch->traceParams.maxDist;
				ray.time				=	0;
				ray.da					=	da;
				ray.db					=	db;

				// Transform the ray into the right coordinate system
				mulmp(ray.from,from,ray.from);
				mulmv(ray.dir,from,ray.dir);

				context->trace(&ray);

				// Do we have an intersection ?
				if (ray.object != NULL) {
					const float	*color		=	ray.object->attributes->surfaceColor;

					// Yes
					coverage++;
					addvv(irradiance,color);

					hemisphere->coverage	=	1;
					initv(hemisphere->envdir,0);
					movvv(hemisphere->irradiance,color);
				} else {
					// No
					hemisphere->coverage	=	0;
					addvv(envdir,ray.dir);
					movvv(hemisphere->envdir,ray.dir);
					
					// GSH : Texture lookup for misses
					if(scratch->occlusionParams.environment != NULL){
						CEnvironment *tex = scratch->occlusionParams.environment;
						vector D0,D1,D2,D3;
						vector color;

						// GSHTODO: Add in the dCosPhi and dSinPhi
						movvv(D0,ray.dir);
						movvv(D1,ray.dir);
						movvv(D2,ray.dir);
						movvv(D3,ray.dir);
						
						float savedSamples = scratch->traceParams.samples;
						context->currentShadingState->scratch.traceParams.samples = 1;
						tex->lookup(color,D0,D1,D2,D3,context);
						context->currentShadingState->scratch.traceParams.samples = savedSamples;
						
						addvv(irradiance,color);
						movvv(hemisphere->irradiance,color);
					} else{
						initv(hemisphere->irradiance,0);
					}
				}

				hemisphere->depth			=	ray.t;
				hemisphere->invDepth		=	1 / ray.t;

				if (tmp > horizonCutoff)	rMean =	min(rMean,ray.t);
				
				movvv(hemisphere->dir,ray.dir);

				assert(hemisphere->invDepth > 0);
			}
		}
	} else {

		// We're shading for indirectdiffuse
		context->numIndirectDiffuseRays	+=	numSamples;
		context->numIndirectDiffuseSamples++;

		for (i=0;i<nt;i++) {
			for (j=0;j<np;j++,hemisphere++) {
				float rv[2];
				context->random2d.get(rv);
				
				float		tmp			=	sqrtf((i+context->urand()) / (float) nt);
				const float	phi			=	(float) (2*C_PI*(j+context->urand()) / (float) np);
				const float	cosPhi		=	(cosf(phi)*tmp);
				const float	sinPhi		=	(sinf(phi)*tmp);

				tmp						=	sqrtf(1 - tmp*tmp);

				ray.dir[0]				=	X[0]*cosPhi + Y[0]*sinPhi + N[0]*tmp;
				ray.dir[1]				=	X[1]*cosPhi + Y[1]*sinPhi + N[1]*tmp;
				ray.dir[2]				=	X[2]*cosPhi + Y[2]*sinPhi + N[2]*tmp;

				const float originJitterX = (rv[0] - 0.5f)*scratch->traceParams.sampleBase;
				const float originJitterY = (rv[1] - 0.5f)*scratch->traceParams.sampleBase;
				
				ray.from[COMP_X]		=	P[COMP_X] + originJitterX*dPdu[0] + originJitterY*dPdv[0];
				ray.from[COMP_Y]		=	P[COMP_Y] + originJitterX*dPdu[1] + originJitterY*dPdv[1];
				ray.from[COMP_Z]		=	P[COMP_Z] + originJitterX*dPdu[2] + originJitterY*dPdv[2];

				ray.flags				=	ATTRIBUTES_FLAGS_DIFFUSE_VISIBLE;
				ray.tmin				=	scratch->traceParams.bias;
				ray.t					=	scratch->traceParams.maxDist;
				ray.time				=	0;
				ray.da					=	da;
				ray.db					=	db;

				// Transform the ray into the right coordinate system
				mulmp(ray.from,from,ray.from);
				mulmv(ray.dir,from,ray.dir);

				context->trace(&ray);

				// Do we have an intersection ?
				if (ray.object != NULL) {
					vector		P,N,C;
					CAttributes	*attributes	=	ray.object->attributes;
					CPhotonMap	*globalMap;

					if ((globalMap = attributes->globalMap) != NULL) {
						normalizev(N,ray.N);
						mulvf(P,ray.dir,ray.t);
						addvv(P,ray.from);
						
						if(dotvv(ray.dir,N) > 0)
							mulvf(N,-1);

						globalMap->lookup(C,P,N,attributes->photonEstimator);

						// HACK: Avoid too bright spots
						tmp	=	max(max(C[0],C[1]),C[2]);
						if (tmp > scratch->occlusionParams.maxBrightness)	mulvf(C,scratch->occlusionParams.maxBrightness/tmp);
						
						mulvv(C,attributes->surfaceColor);
						addvv(irradiance,C);
						movvv(hemisphere->irradiance,C);

						context->numIndirectDiffusePhotonmapLookups++;
					} else {
						initv(hemisphere->irradiance,0);
					}

					// Yes
					coverage++;

					hemisphere->coverage	=	1;
					initv(hemisphere->envdir,0);
				} else {
					// No
					hemisphere->coverage	=	0;
					addvv(envdir,ray.dir);
					movvv(hemisphere->envdir,ray.dir);
					
					// GSH : Texture lookup for misses
					if(scratch->occlusionParams.environment != NULL){
						CEnvironment *tex = scratch->occlusionParams.environment;
						vector D0,D1,D2,D3;
						vector color;

						// GSHTODO: Add in the dCosPhi and dSinPhi
						movvv(D0,ray.dir);
						movvv(D1,ray.dir);
						movvv(D2,ray.dir);
						movvv(D3,ray.dir);
						
						float savedSamples = scratch->traceParams.samples;
						context->currentShadingState->scratch.traceParams.samples = 1;
						tex->lookup(color,D0,D1,D2,D3,context);
						context->currentShadingState->scratch.traceParams.samples = savedSamples;
						
						addvv(irradiance,color);
						movvv(hemisphere->irradiance,color);
					} else{
						movvv(hemisphere->irradiance,scratch->occlusionParams.environmentColor);
						addvv(irradiance,scratch->occlusionParams.environmentColor);
					}
				}

				hemisphere->depth			=	ray.t;
				hemisphere->invDepth		=	1 / ray.t;

				if (tmp > horizonCutoff)	rMean =	min(rMean,ray.t);

				movvv(hemisphere->dir,ray.dir);

				assert(hemisphere->invDepth > 0);
			}
		}
	}
	hemisphere				-=	np*nt;
	
	// Normalize
	const float	tmp			=	1 / (float) numSamples;
	coverage				*=	tmp;
	mulvf(irradiance,tmp);
	normalizevf(envdir);

	// Record the value
	C[0]					=	irradiance[0];
	C[1]					=	irradiance[1];
	C[2]					=	irradiance[2];
	C[3]					=	coverage;
	C[4]					=	envdir[0];
	C[5]					=	envdir[1];
	C[6]					=	envdir[2];

	// Should we save it ?
	if ((scratch->occlusionParams.maxError != 0) && (coverage < 1-C_EPSILON)) {

		// We're modifying, lock the thing
		osLock(mutex);
		
		// Create the sample
		cSample					=	(CCacheSample *) memory->alloc(sizeof(CCacheSample));

		// Compute the gradients of the illumination
		posGradient(cSample->gP,np,nt,hemisphere,X,Y);
		rotGradient(cSample->gR,np,nt,hemisphere,X,Y);
		
		// Compute the radius of validity
		rMean					*=	0.5f;

		// Clamp the radius of validity
		rMean					=	min(rMean,db*scratch->occlusionParams.maxPixelDist);
		
		// Record the data (in the target coordinate system)
		movvv(cSample->P,P);
		movvv(cSample->N,N);
		cSample->dP				=	rMean;
		cSample->coverage		=	coverage;
		movvv(cSample->envdir,envdir);
		movvv(cSample->irradiance,irradiance);
		
		// Do the neighbour clamping trick
		clamp(cSample);
		rMean	=	cSample->dP;	// copy dP back so we get the right place in the octree
		
		// The error multiplier
		const float		K		=	0.4f / scratch->occlusionParams.maxError;
		rMean					/=	K;
		
		// Insert the new sample into the cache
		cNode					=	root;
		depth					=	0;
		while(cNode->side > (2*rMean)) {
			depth++;

			for (j=0,i=0;i<3;i++) {
				if (P[i] > cNode->center[i]) {
					j			|=	1 << i;
				}
			}

			if (cNode->children[j] == NULL)	{
				CCacheNode	*nNode	=	(CCacheNode *) memory->alloc(sizeof(CCacheNode));

				for (i=0;i<3;i++) {
					if (P[i] > cNode->center[i]) {
						nNode->center[i]	=	cNode->center[i] + cNode->side*0.25f;
					} else {
						nNode->center[i]	=	cNode->center[i] - cNode->side*0.25f;
					}
				}

				cNode->children[j]	=	nNode;
				nNode->side			=	cNode->side*0.5f;
				nNode->samples		=	NULL;
				for (i=0;i<8;i++)	nNode->children[i]	=	NULL;
			}

			cNode			=	cNode->children[j];
		}

		cSample->next	=	cNode->samples;
		cNode->samples	=	cSample;
		maxDepth		=	max(depth,maxDepth);

		osUnlock(mutex);
	}
}
Exemplo n.º 9
0
///////////////////////////////////////////////////////////////////////
// Class				:	CIrradianceCache
// Method				:	lookup
// Description			:	Lookup da cache
// Return Value			:
// Comments				:
void	CIrradianceCache::lookup(float *C,const float *cP,const float *cdPdu,const float *cdPdv,const float *cN,CShadingContext *context) {
	const CShadingScratch	*scratch		=	&(context->currentShadingState->scratch);

	// Is this a point based lookup?
	if ((scratch->occlusionParams.pointbased) && (scratch->occlusionParams.pointHierarchy != NULL)) {
		int	i;

		for (i=0;i<7;i++)	C[i]	=	0;

		scratch->occlusionParams.pointHierarchy->lookup(C,cP,cdPdu,cdPdv,cN,context);
	} else {
		CCacheSample		*cSample;
		CCacheNode			*cNode;
		float				totalWeight		=	0;
		CCacheNode			**stackBase		=	(CCacheNode **)	alloca(maxDepth*sizeof(CCacheNode *)*8);
		CCacheNode			**stack;
		int					i;
		float				coverage;
		vector				irradiance,envdir;
		vector				P,N;
		
		// A small value for discard-smoothing of irradiance
		const float			smallSampleWeight = (flags & CACHE_SAMPLE) ? 0.1f : 0.0f;

		// Transform the lookup point to the correct coordinate system
		mulmp(P,to,cP);
		mulmn(N,from,cN);
		
		// Init the result
		coverage	=	0;
		initv(irradiance,0);
		initv(envdir,0);

		// The weighting algorithm is that described in [Tabellion and Lamorlette 2004]
		// We need to convert the max error as in Wald to Tabellion 
		// The default value of maxError is 0.4f
		const float			K		=	0.4f / scratch->occlusionParams.maxError;

		// Note, we do not need to lock the data for reading
		// if word-writes are atomic
		
		// Prepare for the non recursive tree traversal
		stack		=	stackBase;
		*stack++	=	root;
		while(stack > stackBase) {
			cNode	=	*(--stack);

			// Sum the values in this level
			for (cSample=cNode->samples;cSample!=NULL;cSample=cSample->next) {
				vector	D;

				// D = vector from sample to query point
				subvv(D,P,cSample->P);

				// Ignore sample in the front
				float	a	=	dotvv(D,cSample->N);
				if ((a*a / (dotvv(D,D) + C_EPSILON)) > 0.1)	continue;

				// Positional error
				float	e1 = sqrtf(dotvv(D,D)) / cSample->dP;

				// Directional error
				float	e2 =	1 - dotvv(N,cSample->N);
				if (e2 < 0)	e2	=	0;
				e2		=	sqrtf(e2*weightNormalDenominator);

				// Compute the weight
				float	w		=	1 - K*max(e1,e2);
				if (w > context->urand()*smallSampleWeight) {
					vector	ntmp;

					crossvv(ntmp,cSample->N,N);
					
					// Sum the sample
					totalWeight		+=	w;
					coverage		+=	w*(cSample->coverage		+ dotvv(cSample->gP+0*3,D) + dotvv(cSample->gR+0*3,ntmp));
					irradiance[0]	+=	w*(cSample->irradiance[0]	+ dotvv(cSample->gP+1*3,D) + dotvv(cSample->gR+1*3,ntmp));
					irradiance[1]	+=	w*(cSample->irradiance[1]	+ dotvv(cSample->gP+2*3,D) + dotvv(cSample->gR+2*3,ntmp));
					irradiance[2]	+=	w*(cSample->irradiance[2]	+ dotvv(cSample->gP+3*3,D) + dotvv(cSample->gR+3*3,ntmp));
					envdir[0]		+=	w*(cSample->envdir[0]		+ dotvv(cSample->gP+4*3,D) + dotvv(cSample->gR+4*3,ntmp));
					envdir[1]		+=	w*(cSample->envdir[1]		+ dotvv(cSample->gP+5*3,D) + dotvv(cSample->gR+5*3,ntmp));
					envdir[2]		+=	w*(cSample->envdir[2]		+ dotvv(cSample->gP+6*3,D) + dotvv(cSample->gR+6*3,ntmp));
				}
			}

			// Check the children
			for (i=0;i<8;i++) {
				CCacheNode	*tNode;

				if ((tNode = cNode->children[i]) != NULL) {
					const float	tSide	=	tNode->side;

					if (	((tNode->center[0] + tSide) > P[0])	&&
							((tNode->center[1] + tSide) > P[1])	&&
							((tNode->center[2] + tSide) > P[2])	&&
							((tNode->center[0] - tSide) < P[0])	&&
							((tNode->center[1] - tSide) < P[1])	&&
							((tNode->center[2] - tSide) < P[2])) {
						*stack++	=	tNode;
					}
				}
			}
		}

		// Do we have anything ?
		if (totalWeight > C_EPSILON) {
			double	normalizer	=	1 / totalWeight;

			normalizevf(envdir);

			C[0]			=	(float) (irradiance[0]*normalizer);
			C[1]			=	(float) (irradiance[1]*normalizer);
			C[2]			=	(float) (irradiance[2]*normalizer);
			C[3]			=	(float) (coverage*normalizer);
			mulmv(C+4,from,envdir);		// envdir is stored in the target coordinate system
		} else {
			// Are we sampling the cache ?
			if (flags & CACHE_SAMPLE) {
				vector	dPdu,dPdv;

				// Convert the tangent space
				mulmv(dPdu,to,cdPdu);
				mulmv(dPdv,to,cdPdv);

				// Create a new sample
				sample(C,P,dPdu,dPdv,N,context);
				mulmv(C+4,from,C+4);	// envdir is stored in the target coordinate system
			} else {

				// No joy
				C[0]	=	0;
				C[1]	=	0;
				C[2]	=	0;
				C[3]	=	1;
				C[4]	=	0;
				C[5]	=	0;
				C[6]	=	0;
			}
		}

		// Make sure we don't have NaNs
		assert(dotvv(C,C) >= 0);
	}
}
Exemplo n.º 10
0
///////////////////////////////////////////////////////////////////////
// Class				:	CAttributes
// Method				:	CAttributes
// Description			:	The constructor, the default values for
//							attributes are given here
// Return Value			:	-
// Comments				:
CAttributes::CAttributes() {
	next					=	NULL;

	atomicIncrement(&stats.numAttributes);

	surface					=	NULL;
	displacement			=	NULL;
	atmosphere				=	NULL;
	interior				=	NULL;
	exterior				=	NULL;
	usedParameters			=	0;

	initv(surfaceColor,1,1,1);
	initv(surfaceOpacity,1,1,1);

	s[0]					=	0.0;
	s[1]					=	1.0;
	s[2]					=	0.0;
	s[3]					=	1.0;
	t[0]					=	0.0;
	t[1]					=	0.0;
	t[2]					=	1.0;
	t[3]					=	1.0;	

	initv(bmin,C_INFINITY,C_INFINITY,C_INFINITY);
	initv(bmax,-C_INFINITY,-C_INFINITY,-C_INFINITY);
	bexpand					=	0.00001f;	// Epsilon

	{
		int	i,j;

		for (i=0;i<4;i++)
			for (j=0;j<4;j++) {
				uBasis[element(i,j)]	=	RiBezierBasis[i][j];
				vBasis[element(i,j)]	=	RiBezierBasis[i][j];
			}
	}

	uStep						=	3;
	vStep						=	3;

	flags						=	0;
	flags						|=	ATTRIBUTES_FLAGS_PRIMARY_VISIBLE;
	flags						|=	ATTRIBUTES_FLAGS_DOUBLE_SIDED;

	maxDisplacement				=	0;
	maxDisplacementSpace		=	NULL;

	lightSources				=	NULL;

	shadingRate					=	1.0f;
	motionFactor				=	0.0f;

	name						=	NULL;

	numUProbes					=	4;
	numVProbes					=	4;
	minSplits					=	0;		// This should no longer be needed with convergent dicing
	rasterExpand				=	0.5f;	// This could be significantly lowered for many primitives
	bias						=	0.01f;

	transmissionHitMode			=	'p';
	diffuseHitMode				=	'p';
	cameraHitMode				=	's';
	specularHitMode				=	's';


	emit						=	-1;
	relativeEmit				=	1;

	shadingModel				=	SM_MATTE;
	
	globalMapName				=	NULL;
	causticMapName				=	NULL;
	globalMap					=	NULL;
	causticMap					=	NULL;
	irradianceHandle			=	strdup("");
	irradianceHandleMode		=	strdup("w");
	irradianceMaxError			=	0.6f;
	irradianceMaxPixelDistance	=	20.0f;
	photonEstimator				=	100;
	photonIor[0]				=	1.5;
	photonIor[1]				=	1.5;
	maxDiffuseDepth				=	1;
	maxSpecularDepth			=	2;

	shootStep					=	1000;		// Shoot 1000 rays at a time
	
	lodRange[0]					=	-C_INFINITY;
	lodRange[1]					=	-C_INFINITY;
	lodRange[2]					=	C_INFINITY;
	lodRange[3]					=	C_INFINITY;
	lodSize						=	0;
	lodImportance				=	1;
	
	checkParameters();
}
Exemplo n.º 11
0
///////////////////////////////////////////////////////////////////////
// Class				:	CPointHierarchy
// Method				:	cluster
// Description			:
/// \brief					Cluster the items
// Return Value			:	-
// Comments				:
int			CPointHierarchy::cluster(int numItems,int *indices) {

	// Sanity check
	assert(numItems > 0);

	if (numItems == 1) {
		// Create a leaf
		return -indices[0];

	} else if (numItems == 2) {
		// Easy case
		int			nodeIndex	=	average(numItems,indices);
		CMapNode	*node		=	nodes.array + nodeIndex;
		node->child0			=	-indices[0];
		node->child1			=	-indices[1];
		return nodeIndex;

	} else {
		// Allocate temp memory
		int	*membership,*subItems;
		
		// Use alloca if the allocation size is low enough
		if (numItems >= ALLOCA_MAX_ITEMS)	membership	=	new int[numItems*2];
		else								membership	=	(int *) alloca(numItems*2*sizeof(int));

		subItems	=	membership	+	numItems;

		vector	bmin,bmax;

		initv(bmin,C_INFINITY);
		initv(bmax,-C_INFINITY);
		
		// The membership is dummy ... Also compute the bounding box of the point set
		for (int i=0;i<numItems;i++) {
			membership[i]	=	-1;
			addBox(bmin,bmax,CMap<CPointCloudPoint>::items[indices[i]].P);
		}
		
		vector	C0,C1;		// The cluster centers
		vector	N0,N1;		// The cluster normals

		// Create random cluster centers
		initv(C0,	_urand()*(bmax[0]-bmin[0]) + bmin[0],
					_urand()*(bmax[1]-bmin[1]) + bmin[1],
					_urand()*(bmax[2]-bmin[2]) + bmin[2]);
		initv(C1,	_urand()*(bmax[0]-bmin[0]) + bmin[0],
					_urand()*(bmax[1]-bmin[1]) + bmin[1],
					_urand()*(bmax[2]-bmin[2]) + bmin[2]);

		// Create random cluster normals
		initv(N0,	_urand()*2-1,	_urand()*2-1,	_urand()*2-1);
		initv(N1,	_urand()*2-1,	_urand()*2-1,	_urand()*2-1);
		normalizevf(N0);
		normalizevf(N1);

		// Perform the clustering iterations
		int		num0,num1;
		for (int iterations=0;iterations<5;iterations++) {	// Try 5 times ... Not until convergence
			int		changed	=	FALSE;
			vector	nC0,nC1;
			vector	nN0,nN1;

			// Clear the data
			initv(nC0,0);
			initv(nC1,0);
			initv(nN0,0);
			initv(nN1,0);
			num0	=	0;
			num1	=	0;
			
			// iterate over items
			for (int i=0;i<numItems;i++) {
				vector						D;
				const	CPointCloudPoint	*cItem	=	CMap<CPointCloudPoint>::items + indices[i];
				
				// Compute the distance to the first cluster
				subvv(D,cItem->P,C0);
				const float d0	=	dotvv(D,D) / max(dotvv(N0,cItem->N),C_EPSILON);
				
				// Compute the distance to the second cluster
				subvv(D,cItem->P,C1);
				const float d1	=	dotvv(D,D) / max(dotvv(N1,cItem->N),C_EPSILON);
				
				// Change the membership if necessary
				if (d0 < d1) {
					if (membership[i] != 0) {
						changed			=	TRUE;
						membership[i]	=	0;
					}

					addvv(nC0,cItem->P);
					addvv(nN0,cItem->N);
					num0++;
				} else {
					if (membership[i] != 1) {
						changed			=	TRUE;
						membership[i]	=	1;
					}

					addvv(nC1,cItem->P);
					addvv(nN1,cItem->N);
					num1++;
				}
			}
			
			// Check for degenerate cases
			if ((num0 == 0) || (num1 == 0)) {
				initv(C0,	_urand()*(bmax[0]-bmin[0]) + bmin[0],
							_urand()*(bmax[1]-bmin[1]) + bmin[1],
							_urand()*(bmax[2]-bmin[2]) + bmin[2]);
				initv(C1,	_urand()*(bmax[0]-bmin[0]) + bmin[0],
							_urand()*(bmax[1]-bmin[1]) + bmin[1],
							_urand()*(bmax[2]-bmin[2]) + bmin[2]);

				initv(N0,	_urand()*2-1,	_urand()*2-1,	_urand()*2-1);
				initv(N1,	_urand()*2-1,	_urand()*2-1,	_urand()*2-1);
				normalizevf(N0);
				normalizevf(N1);
			} else {
				if (changed == FALSE)	break;

				mulvf(C0,nC0,1 / (float) num0);
				mulvf(C1,nC1,1 / (float) num1);

				// Normalize the normal vectors
				normalizevf(N0,nN0);
				normalizevf(N1,nN1);
			}	
		}
		
		// Do we have a bad clustering?
		while (num0 == 0 || num1 == 0) {

			// Clustering failed - probably coincident points, make an arbitrary split
			num0 = num1 = 0;
			for (int i=0;i<numItems;i++) {
				const int which = i & 1;
				if (which)	num1++;
				else		num0++;
				membership[i] = which;
			}

			// FIXME: A smarter thing to do would be to sort the items in one dimension and split it in half
		}
		
		assert((num0 + num1) == numItems);

		// Average the items and create an internal node
		const int	nodeIndex	=	average(numItems,indices);
		
		// OK, split the items into two
		int	i,j;
		
		// Collect the items in the first child
		for (i=0,j=0;i<numItems;i++)	if (membership[i] == 0)	subItems[j++]	=	indices[i];
		assert(j == num0);
		const int	child0	=	cluster(num0,subItems);
		
		// Collect the items in the second child
		for (i=0,j=0;i<numItems;i++)	if (membership[i] == 1)	subItems[j++]	=	indices[i];
		assert(j == num1);
		const int	child1	=	cluster(num1,subItems);
		
		// NOTE: There's an important subtlety here...
		// We can not access cNode before the child nodes are created because the creation of children
		// may change the nodes.array field
		CMapNode *cNode	=	nodes.array + nodeIndex;
		cNode->child0	=	child0;
		cNode->child1	=	child1;

		// Reclaim the memory if applicable
		if (numItems >= ALLOCA_MAX_ITEMS)	delete [] membership;

		// Return the index of the node
		return nodeIndex;
	}
}
Exemplo n.º 12
0
///////////////////////////////////////////////////////////////////////
// Class				:	COptions
// Method				:	COptions
// Description			:
/// \brief					All the default frame specific settings are defined here
// Return Value			:	-
// Comments				:
COptions::COptions() {
	atomicIncrement(&stats.numOptions);

	xres					=	640;
	yres					=	480;

	frame					=	-1;

	pixelAR					=	1;
	frameAR					=	4.0f/3.0f;

	cropLeft				=	0;
	cropRight				=	1;
	cropTop					=	0;
	cropBottom				=	1;

	screenLeft				=	-4.0f/3.0f;
	screenRight				=	4.0f/3.0f;
	screenTop				=	1;
	screenBottom			=	-1;
	
	clipMin					=	C_EPSILON;
	clipMax					=	C_INFINITY;

	pixelVariance			=	0.05f;

	jitter					=	0.99f;

	hider					=	strdup("stochastic");
	
#ifdef __APPLE__
	// Support for finding resources in Mac OS X bundles and standard Mac OS X file system locations
	
	// Find the application bundle's plug-in and Resources directory
	char path[OS_MAX_PATH_LENGTH];
	char pathtmp[OS_MAX_PATH_LENGTH];
	CFBundleRef bundle = CFBundleGetMainBundle();
	if (bundle) {
		CFURLRef url = CFBundleCopyBuiltInPlugInsURL(bundle);
		if (url) {
			Boolean validpath = CFURLGetFileSystemRepresentation(url,true,(UInt8*)path,OS_MAX_PATH_LENGTH);
			if (validpath)
				setenv("PIXIEAPPPLUGINS", (const char*)path, 1);
			CFRelease(url);
		}
		url = CFBundleCopyResourcesDirectoryURL(bundle);
		if (url) {
			Boolean validpath = CFURLGetFileSystemRepresentation(url,true,(UInt8*)path,OS_MAX_PATH_LENGTH);
			if (validpath)
				setenv("PIXIEAPPRESOURCES", (const char*)path, 1);
			CFRelease(url);
		}
		CFRelease(bundle);
	}
	
	// Find the application support directory (~/Library/Application Support/Pixie/PlugIns), and set the
	// PIXIEUSERDIR environment variable to that directory
	FSRef appsupport;
    if (FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &appsupport) == noErr) {
		FSRefMakePath(&appsupport, (UInt8*)path, OS_MAX_PATH_LENGTH);
		sprintf(pathtmp, "%s/" PACKAGE, path);
		mkdir(pathtmp, 0755);
		setenv("PIXIEUSERDIR", (const char*)pathtmp, 1);
	}
	
	// Find the application support directory (/Library/Application Support/Pixie/PlugIns), and set the
	// PIXIELOCALDIR environment variable to that directory
    if (FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &appsupport) == noErr) {
		FSRefMakePath(&appsupport, (UInt8*)path, OS_MAX_PATH_LENGTH);
		snprintf(pathtmp, OS_MAX_PATH_LENGTH, "%s/" PACKAGE, path);
		mkdir(pathtmp, 0755);
		setenv("PIXIELOCALDIR", (const char*)pathtmp, 1);
	}
	
	// Default home, unless overridden with environment
	setenv("PIXIEHOME","/Library/Pixie",0);
	
	archivePath             =   optionsGetSearchPath(".:%RIBS%:%PIXIEHOME%/ribs" ,NULL);
	proceduralPath          =   optionsGetSearchPath(".:%PROCEDURALS%:%PIXIEUSERDIR%/procedurals:%PIXIELOCALDIR%/procedurals:%PIXIEAPPPLUGINS%:%PIXIEHOME%/procedurals",NULL);
	texturePath             =   optionsGetSearchPath(".:%TEXTURES%:%PIXIEUSERDIR%/textures:%PIXIELOCALDIR%/textures:%PIXIEAPPRESOURCES%/textures:%PIXIEHOME%/textures",NULL);
	shaderPath              =   optionsGetSearchPath(".:%SHADERS%:%PIXIEUSERDIR%/shaders:%PIXIELOCALDIR%/shaders:%PIXIEAPPRESOURCES%/shaders:%PIXIEHOME%/shaders",NULL);
	displayPath             =   optionsGetSearchPath("%DISPLAYS%:%PIXIEUSERDIR%/displays:%PIXIELOCALDIR%/displays:%PIXIEAPPPLUGINS%:%PIXIEHOME%/displays",NULL);
	modulePath              =   optionsGetSearchPath("%MODULES%:%PIXIEUSERDIR%/modules:%PIXIELOCALDIR%/modules:%PIXIEAPPPLUGINS%:%PIXIEHOME%/modules",NULL);

#else
	archivePath				=	optionsGetSearchPath(".:%RIBS%:" PIXIE_RIBS,NULL);
	proceduralPath			=	optionsGetSearchPath(".:%PROCEDURALS%:" PIXIE_PROCEDURALS,NULL);
	texturePath				=	optionsGetSearchPath(".:%TEXTURES%:" PIXIE_TEXTURES,NULL);
	shaderPath				=	optionsGetSearchPath(".:%SHADERS%:" PIXIE_SHADERS,NULL);
	displayPath				=	optionsGetSearchPath(".:%DISPLAYS%:" PIXIE_DISPLAYS,NULL);
	modulePath				=	optionsGetSearchPath(".:%MODULES%:" PIXIE_MODULES,NULL);
#endif

	pixelXsamples			=	2;
	pixelYsamples			=	2;

	gamma					=	1;
	gain					=	1;	

	pixelFilterWidth		=	2;
	pixelFilterHeight		=	2;
	pixelFilter				=	RiCatmullRomFilter;

	colorQuantizer[0]		=	0;				// Zero
	colorQuantizer[1]		=	255;			// One
	colorQuantizer[2]		=	0;				// Min
	colorQuantizer[3]		=	255;			// Max
	colorQuantizer[4]		=	0.5;
	depthQuantizer[0]		=	0;				// Zero
	depthQuantizer[1]		=	0;				// One
	depthQuantizer[2]		=	0;				// Min
	depthQuantizer[3]		=	0;				// Max
	depthQuantizer[4]		=	0;

	initv(opacityThreshold,0.996f);
	initv(zvisibilityThreshold,0.996f);
	
	// We default to sampling motion, but this can be turned off.
	// Additionally, if there's no motionblur in the scene, it will be turned off
	flags					=	OPTIONS_FLAGS_SAMPLEMOTION;

	displays				=	NULL;

	clipPlanes				=	NULL;

	relativeDetail			=	1;

	projection				=	OPTIONS_PROJECTION_ORTHOGRAPHIC;
	fov						=	90;

	nColorComps				=	3;
	fromRGB					=	NULL;
	toRGB					=	NULL;

	fstop					=	C_INFINITY;
	focallength				=	1;
	focaldistance			=	1;

	shutterOpen				=	0;
	shutterClose			=	0;
	shutterOffset			=	0;

	endofframe				=	0;
	filelog					=	NULL;

	numThreads              =   osAvailableCPUs();
	if (numThreads < 1)
		numThreads          =   DEFAULT_NUM_THREADS;

	maxTextureSize			=	DEFAULT_MAX_TEXTURESIZE;
	maxBrickSize			=	DEFAULT_MAX_BRICKSIZE;

	maxGridSize				=	DEFAULT_MAX_GRIDSIZE;

	maxRayDepth				=	5;
	maxPhotonDepth			=	10;

	bucketWidth				=	DEFAULT_TILE_WIDTH;
	bucketHeight			=	DEFAULT_TILE_HEIGHT;

	netXBuckets				=	DEFAULT_NET_XBUCKETS;
	netYBuckets				=	DEFAULT_NET_YBUCKETS;

	threadStride			=	DEFAULT_THREAD_STRIDE;
	
	geoCacheMemory			=	DEFAULT_GEO_CACHE_SIZE;

	maxEyeSplits			=	10;

	tsmThreshold			=	DEFAULT_TSM_THRESHOLD;

	causticIn				=	NULL;
	causticOut				=	NULL;

	globalIn				=	NULL;
	globalOut				=	NULL;

	numEmitPhotons			=	10000;

	shootStep				=	1000;

	depthFilter				=	DEPTH_MIN;
}
Exemplo n.º 13
0
double gmuon_(void)
{
/*compute the total g-2 from supersymmetry. Parameters are :
Mmu : muon mass
Mz  : Z-boson's mass
Mw  : W-boson's mass
s2thw : sin^2(thw)
e   : alpha
modM1 & argM1 : modulus and argument of M1		
modM2 & argM2 : modulus and argument of M2
modmu & argmu : modulus and argument of mu		
modAmu & argAmu : modulus and argument of Amu	
*/
/*declaration des variables*/
double thw, cb,cw,sw, ymu, g1,masssneutr, g2,gmuo = 0,beta,Mz,Mw,Mmu,e,tbeta;
matrix massmatrc,massmatrn,massmatrsmu;
matrix Ncomp, Nconj,N,Ucomp,Uconj,U,Vcomp,Vconj,V,X,Xconj,Xcomp;
vecteur massen,massec,massesmu;

double coeff1 ,coeff2;

matrix matrixtemp,matrixtemp2,matrixtemp3,matrixtemp4,matrixtemp5;
my_complex nc1,nc2;

int i,j;
/*Memory Allocation*/

massmatrn=initm(4);
massmatrc=initm(2);
massmatrsmu=initm(2);
Ncomp=initm(4);
Nconj=initm(4);
N=initm(4);

Ucomp=initm(2);
Vcomp=initm(2);
X=initm(2);
U=initm(2);
V=initm(2);
Uconj=initm(2);
Vconj=initm(2);
Xcomp=initm(2);
Xconj=initm(2);
massen=initv(4);
massesmu=initv(2);
massec=initv(2);

matrixtemp=initm(2);
matrixtemp2=initm(2);
matrixtemp3=initm(4);
matrixtemp4=initm(4);
matrixtemp5=initm(4);

/*Get the values for the masses and mixing matrices*/

e=sqrt(4*M_PI*0.00781653);
sw=0.48076;
Mz=91.1876;
Mmu=0.1057;

findVal("tB",&tbeta);


beta = atan(tbeta);
cb = cos(beta);
thw=asin(sw);
cw=cos(thw);
Mw=Mz*cw;
g1 = e/cw;
g2 = e/sw;
ymu = g2 * Mmu / (sqrt(2)*cb*Mw);

findVal("MNE1",&massen.e[0].r);
findVal("MNE2",&massen.e[1].r);
findVal("MNE3",&massen.e[2].r);
findVal("MNE4",&massen.e[3].r);

findVal("MC1",&massec.e[0].r);
findVal("MC2",&massec.e[1].r);

findVal("MSnm",&masssneutr);

findVal("Zn11",&Nconj.e[0][0].r); findVal("Zn12",&Nconj.e[1][0].r); findVal("Zn13",&Nconj.e[2][0].r); findVal("Zn14",&Nconj.e[3][0].r);
findVal("Zn21",&Nconj.e[0][1].r); findVal("Zn22",&Nconj.e[1][1].r); findVal("Zn23",&Nconj.e[2][1].r); findVal("Zn24",&Nconj.e[3][1].r);
findVal("Zn31",&Nconj.e[0][2].r); findVal("Zn32",&Nconj.e[1][2].r); findVal("Zn33",&Nconj.e[2][2].r); findVal("Zn34",&Nconj.e[3][2].r);
findVal("Zn41",&Nconj.e[0][3].r); findVal("Zn42",&Nconj.e[1][3].r); findVal("Zn43",&Nconj.e[2][3].r); findVal("Zn44",&Nconj.e[3][3].r);

findVal("Zu11",&Uconj.e[0][0].r); findVal("Zu12",&Uconj.e[1][0].r);
findVal("Zu21",&Uconj.e[0][1].r); findVal("Zu22",&Uconj.e[1][1].r);

findVal("Zv11",&Vcomp.e[0][0].r); findVal("Zv12",&Vcomp.e[0][1].r);
findVal("Zv21",&Vcomp.e[1][0].r); findVal("Zv22",&Vcomp.e[1][1].r);


{  double MSmuLL,MSmuRR,MSmuLR,Am,mu,MSmuth;

   MSmuLL=findValW("MSmL"); MSmuLL*=MSmuLL;
   MSmuRR=findValW("MSmR"); MSmuRR*=MSmuRR;
   Am=findValW("Am");
   mu=findValW("mu");
   MSmuLR=(Am-mu*tbeta)*Mmu;
 
   massesmu.e[0].r=sqrt((MSmuLL+MSmuRR-sqrt((MSmuLL-MSmuRR)*(MSmuLL-MSmuRR)+4*MSmuLR*MSmuLR))/2);
   massesmu.e[1].r=sqrt((MSmuLL+MSmuRR+sqrt((MSmuLL-MSmuRR)*(MSmuLL-MSmuRR)+4*MSmuLR*MSmuLR))/2);

   MSmuth=atan2(-2*MSmuLR, -MSmuLL+MSmuRR)/2;

   X.e[0][0].r=cos(MSmuth);
   X.e[0][1].r=sin(MSmuth);
   X.e[1][0].r=-X.e[0][1].r;
   X.e[1][1].r=X.e[0][0].r;
}




for(i=0;i<4;i++)
	if (massen.e[i].r<0)
		{for(j=0;j<4;j++)
		     {Nconj.e[j][i]=prod(icomp,Nconj.e[j][i]);
		     }
		 massen.e[i].r=-massen.e[i].r;
		}


for(i=0;i<2;i++)
	{if (massec.e[i].r<0)
		{for(j=0;j<2;j++)
		     { Uconj.e [j][i]=prod(icomp,Uconj.e[j][i]);
		     Vcomp.e [i][j]=prod(icomp,Vcomp.e[i][j]);
		     }
		 massec.e[i].r=-massec.e[i].r;
		}
	if (massesmu.e[i].r<0)
		{for(j=0;j<2;j++)
		     {X.e [i][j]=prod(icomp,X.e[i][j]);
		     
		     }
		massesmu.e[i].r=-massesmu.e[i].r;
		   
		}
	}

N=adj(Nconj);
U=adj(Uconj);

/*Compute the coefficients entering the formula for the neutral  and chargino
contribution to g-2_muon and calculates gmuon*/

/*neutralinos*/

for ( i=0;i<4;i=i+1)
	for ( j=0;j<2;j=j+1)
		{nc1=somme(prodscal(sqrt(2)*g1,prod(N.e[i][0],X.e[j][1])),prodscal(ymu,prod(N.e[i][2],X.e[j][0])));		
		nc2=diff(prodscal(1/sqrt(2),prod(somme(prodscal(g2,N.e[i][1]),prodscal(g1,N.e[i][0])),conjug(X.e[j][0]))),prodscal(ymu,prod(N.e[i][2],conjug(X.e[j][1]))));
		
		
		coeff1 =(somme(prod(nc1,conjug(nc1)),prod(nc2,conjug(nc2)))).r;
		coeff2 = prod(nc1,nc2).r;
			
		if (massesmu.e[j].r<1e-8) 
			{return 0;
			printf("erreur : Mass smuons nul\n");}		
		gmuo=gmuo+calcgmuon (0,Mmu, massen.e[i].r, massesmu.e[j].r,coeff1, coeff2);
	}

/*charginos*/

for (j=0;j<2;j=j+1)
	{
	nc1=prodscal(ymu,U.e[j][1]);
	nc2=prodscal(-g2,conjug(Vcomp.e[j][0]));
	coeff1 =(somme(prod(nc1,conjug(nc1)),prod(nc2,conjug(nc2)))).r;
	coeff2 = prod(nc1,nc2).r;
	if (masssneutr<1e-8) 
		{return 0;
		printf("erreur : Mass sneutrinos nul\n");}
	gmuo=gmuo+calcgmuon (1,Mmu, massec.e[j].r, masssneutr,coeff1, coeff2);	
	}

 return gmuo;

}
Exemplo n.º 14
0
int main()
{
    unsigned int i,j,a,*SV;
    unsigned char logpi;
    int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri;
    long M,la,lptr;

    qsieve=gmpinit(-36,0);

    if(initv()<0) return 0;

    hmod=2*mlf+1;
    mpz_set_si(TA, hmod);
    while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数
    hmod=qsieve_getsize(TA);
    hmod2=hmod-2;
    for(k=0;k<hmod;k++) hash[k]=(-1);

    M=50*(long)mm;
    NS=(int)(M/SSIZE);
    if(M%SSIZE!=0) NS++;
    M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行
    logm=0;
    la=M;
    while((la/=2)>0) logm++; // 以2为底
    rp[0]=logp[0]=0;
    for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi)
    {
        r=mpz_tdiv_q_ui(TA, D, epr[k]);
        rp[k]=qsieve_sqrmp(r,epr[k]);
        logp[k]=0;
        r=epr[k];
        while((r/=2)>0) logp[k]++;
    }

    r=mpz_tdiv_q_ui(TA, D, 8);
    if(r==5) logp[1]++;
    if(r==1) logp[1]+=2;

    threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm];

    jj=0;
    nlp=0;
    mpz_mul_si(DG, D, 2);
    mpz_root(DG, DG, 2);

    mpz_set_si(TA, M);
    qsieve_divide(DG,TA,DG);
    mpz_root(DG, DG, 2);
    if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1);
    if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数
    printf("  0%");

    while(1) //不断尝试新的多项式,可以并行计算
    {
        r=qsieve->NTRY;
        qsieve->NTRY=1;
        do
        {
            do {
               mpz_add_ui(DG, DG, 4);
            } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE));
            mpz_sub_ui(TA, DG, 1);
            mpz_tdiv_q_ui(TA, TA, 2);
            mpz_powm_sec(TA, D, TA, DG);
        } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余
        qsieve->NTRY=r;
        mpz_add_ui(TA, DG, 1);
        mpz_tdiv_q_ui(TA, TA, 4);
        mpz_powm_sec(B, D, TA, DG);
        mpz_neg(TA, D);
        qsieve_muladddiv(B,B,TA,DG,TA,TA);
        mpz_neg(TA, TA);

        mpz_mul_si(A, B, 2);
        qsieve_extgcd(A,DG,A,A,A);
        qsieve_muladddiv(A,TA,TA,DG,DG,A);
        mpz_mul(TA, A, DG);
        mpz_add(B, B, TA);
        mpz_mul(A, DG, DG);
        qsieve_extgcd(DG,D,IG,IG,IG);
        
        r1[0]=r2[0]=0;
        for(k=1;k<=mm;k++) //s1和s2是两个解
        {
            s=mpz_tdiv_q_ui(TA, B, epr[k]);
            r=mpz_tdiv_q_ui(TA, A, epr[k]);
            r=qsieve_getinvers(r,epr[k]);

            s1=(epr[k]-s+rp[k]);
            s2=(epr[k]-s+epr[k]-rp[k]);
            if(s1 > s2)
            {
                int t = s1;
                s1 = s2;
                s2 = t;
            }
            r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k]));
            r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k]));
        }
        
        for(ptr=(-NS);ptr<NS;ptr++)
        {
            la=(long)ptr*SSIZE;
            SV=(unsigned int *)sieve;
            for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0;
            for(k=1; k<=mm; k++)
            {
                epri=epr[k];
                logpi=logp[k];
                r=(int)(la%epri);
                s1=(r1[k]-r)%epri;
                if(s1<0) s1+=epri;
                s2=(r2[k]-r)%epri;
                if(s2<0) s2+=epri;

			/* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x 
				s1与s2是两个P(x)=0(mod p)的解 */
                for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi;
                if(s1==s2) continue;
                for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi;
            }

            for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数
            {
                if(sieve[a]<threshold) continue;
                lptr=la+a;
                mpz_set_si(TA, lptr);
                S=0;
                mpz_mul(TA, A, TA);
                mpz_add(TA, TA, B);
                qsieve_muladddiv(TA,IG,TA,D,D,P);
                if(qsieve_getsize(P)<0) mpz_add(P, P, D);
                qsieve_muladddiv(P,P,P,D,D,V);
                mpz_abs(TA, TA);
                if(qsieve_compare(TA,R)<0) S=1;
                if(S==1) mpz_sub(V, D, V);
                if(V!=TA) mpz_set(TA, V);
                e[0]=S;
                for(k=1;k<=mm;k++) e[k]=0;
                if(!factored(lptr,TA)) continue;
                if(gotcha())
                {
                    mpz_gcd(P, TA, N);
                    qsieve_getsize(P);
                    printf("\b\b\b\b100%\nFactors are\n");
                    qsieve_outnum(P,stdout);
                    qsieve_divide(N,P,N);
                    qsieve_outnum(N,stdout);
                    return 0;
                }
            }
        }
    }
    return 0;
}
Exemplo n.º 15
0
///////////////////////////////////////////////////////////////////////
// Class				:	CStochastic
// Method				:	rasterBegin
// Description			:
/// \brief					Begin drawing an image
// Return Value			:	-
// Comments				:
void		CStochastic::rasterBegin(int w,int h,int l,int t,int nullBucket) {
	int			i,j,pxi,pxj;
	float		zoldStart;
	CFragment	*cFragment;
	
	assert(numFragments == 0);

	zoldStart			=	CRenderer::clipMax;

	// Set the digits
	width				=	w;
	height				=	h;
	left				=	l;
	top					=	t;
	sampleWidth			=	width*CRenderer::pixelXsamples + 2*CRenderer::xSampleOffset;
	sampleHeight		=	height*CRenderer::pixelYsamples + 2*CRenderer::ySampleOffset;
	right				=	left + sampleWidth;
	bottom				=	top + sampleHeight;

	// Early-out if we have no data
	if (!(CRenderer::flags & OPTIONS_FLAGS_DEEP_SHADOW_RENDERING) && nullBucket) return;

	assert(sampleWidth <= totalWidth);
	assert(sampleHeight <= totalHeight);

	// Init the occlusion culler to zero
	initToZero();
	for (i=0,pxi=CRenderer::pixelYsamples-CRenderer::ySampleOffset;i<sampleHeight;i++,pxi++) {
		CPixel	*pixel	=	fb[i];
		
		if (pxi >= CRenderer::pixelYsamples)	pxi = 0;
		
		for (j=0,pxj=CRenderer::pixelXsamples-CRenderer::xSampleOffset;j<sampleWidth;j++,pxj++,pixel++) {
			float	aperture[2];

			// The stratified sample
			pixel->jx					=	(CRenderer::jitter*(urand()-0.5f) + 0.5001011f);
			pixel->jy					=	(CRenderer::jitter*(urand()-0.5f) + 0.5001017f);

			// Time of the sample for motion blur
			if (pxj >= CRenderer::pixelXsamples)	pxj = 0;
			pixel->jt					=	( pxi*CRenderer::pixelXsamples + pxj + CRenderer::jitter*(urand()-0.5f) + 0.5001011f)/(float)(CRenderer::pixelXsamples*CRenderer::pixelYsamples);
			
			// Importance blend / jitter
			pixel->jimp					=	1.0f - ( pxj*CRenderer::pixelYsamples + pxi + CRenderer::jitter*(urand()-0.5f) + 0.5001011f)/(float)(CRenderer::pixelXsamples*CRenderer::pixelYsamples);

			if (CRenderer::flags & OPTIONS_FLAGS_FOCALBLUR) {

				// Aperture sample for depth of field
				while (TRUE) {
					apertureGenerator.get(aperture);
					aperture[0] 			= 2.0f*aperture[0] - 1.0f;
					aperture[1] 			= 2.0f*aperture[1] - 1.0f;
					if ((aperture[0]*aperture[0] + aperture[1]*aperture[1]) < 1.0f) break;
				}

				pixel->jdx					=	aperture[0];
				pixel->jdy					=	aperture[1];
			} else {
				pixel->jdx					=	0;
				pixel->jdy					=	0;
			}
			
			// Center location of the sample
			pixel->xcent				=	(j+pixel->jx) + left;
			pixel->ycent				=	(i+pixel->jy) + top;

			pixel->z					=	CRenderer::clipMax;
			pixel->zold					=	zoldStart;
			pixel->numSplats			=	0;
			pixel->node					=	getNode(j,i);
			pixel->node->zmax			=	CRenderer::clipMax;


			cFragment					=	&pixel->last;
			cFragment->z				=	CRenderer::clipMax;
			initv(cFragment->color,0);
			initv(cFragment->opacity,0);
			cFragment->next				=	NULL;
			cFragment->prev				=	&pixel->first;
			// The last sample's extra samples are genuine AOV data
			if (CRenderer::numExtraSamples > 0)
				memcpy(cFragment->extraSamples,CRenderer::sampleDefaults,sizeof(float)*CRenderer::numExtraSamples);
			initv(cFragment->accumulatedOpacity,0);


			cFragment					=	&pixel->first;
			cFragment->z				=	-C_INFINITY;
			initv(cFragment->color,0);
			initv(cFragment->opacity,0);
			cFragment->next				=	&pixel->last;
			cFragment->prev				=	NULL;
			// Note: The first fragment's extra samples are not used, and the pointer is NULL
			assert(cFragment->extraSamples == NULL);
			initv(cFragment->accumulatedOpacity,0);

			pixel->update				=	&pixel->first;
		}
	}

	resetHierarchy();
}
Exemplo n.º 16
0
///////////////////////////////////////////////////////////////////////
// Class			   :   CObject
// Method			   :   estimateDicing
// Description		   :
/// \brief					Estimate the dicing size on the screen
// Return Value		   :
// Comments			   :
/// \note					P must be in pixels
void			   CObject::estimateDicing(float *P,int udiv,int vdiv,int &nudiv,int &nvdiv,float shadingRate,int nonrasterorient) {
   float	   uMin,vMin;  // The minimum edge length
   float	   uMax,vMax;  // The maximum edge length
   int		   i,j;
   const float *cP,*nP,*tP;
   float	   dx,dy;

   uMax	   =   vMax	   =   0;
   uMin	   =   vMin	   =   C_INFINITY;

   if (!nonrasterorient) {

	   // Project to pixels
	   camera2pixels((udiv+1)*(vdiv+1),P);

	   // U stats
	   cP  =   P;
	   for (j=(vdiv+1);j>0;--j) {
	
		   float	total	=	0;
		   for (i=udiv;i>0;--i,cP+=3) {
			   dx		=   cP[3 + COMP_X] - cP[COMP_X];
			   dy		=   cP[3 + COMP_Y] - cP[COMP_Y];
			   total	+=	sqrtf(dx*dx + dy*dy);
		   }
		   cP  +=  3;
		   uMax	=	max(uMax,total);
		   uMin	=	min(uMin,total);
	   }
	
	   // V stats
	   cP  =   P;
	   for (i=(udiv+1);i>0;--i,cP+=3) {
		   nP  =   cP;
		   tP  =   nP  +   (udiv+1)*3;
		   float	total	=	0;
		   for (j=vdiv;j>0;--j,nP=tP,tP+=(udiv+1)*3) {
			   dx		=   tP[COMP_X] - nP[COMP_X];
			   dy		=   tP[COMP_Y] - nP[COMP_Y];
			   total	+=	sqrtf(dx*dx + dy*dy);
		   }
	
		   vMax	=	max(vMax,total);
		   vMin	=	min(vMin,total);
	   }
	} else {	// non raster oriented
	   vector tmp;

	   float maxDim = max(CRenderer::dPixeldx,CRenderer::dPixeldy);
	   	if(CRenderer::projection == OPTIONS_PROJECTION_PERSPECTIVE) {
			for (j=0;j<(vdiv+1)*(udiv+1);++j) {
				float x,y;
				x	=	(CRenderer::imagePlane*P[j*3+COMP_X]/P[j*3+COMP_Z]);
				y	=	(CRenderer::imagePlane*P[j*3+COMP_Y]/P[j*3+COMP_Z]);
				initv(tmp,x-P[j*3+COMP_X],y-P[j*3+COMP_Y],P[j*3+COMP_Z]-1);
				P[j*3+COMP_X]	=	x*maxDim;
				P[j*3+COMP_Y]	=	y*maxDim;
				P[j*3+COMP_Z]	=	lengthv(tmp)*maxDim;
			}
		} else {
			for (j=0;j<(vdiv+1)*(udiv+1);++j) {
				P[j*3+COMP_X]	=	P[j*3+COMP_X]*CRenderer::dPixeldx;
				P[j*3+COMP_Y]	=	P[j*3+COMP_Y]*CRenderer::dPixeldy;
				P[j*3+COMP_Z]	*=	maxDim;
			}
		}

	   // U stats
	   cP  =   P;
	   for (j=(vdiv+1);j>0;--j) {
	
		   float	total	=	0;
		   for (i=udiv;i>0;--i,cP+=3) {
			   subvv(tmp,cP+3,cP);
			   total	+=	lengthv(tmp);
		   }
		   cP  +=  3;
		   uMax	=	max(uMax,total);
		   uMin	=	min(uMin,total);
	   }
	
	   // V stats
	   cP  =   P;
	   for (i=(udiv+1);i>0;--i,cP+=3) {
		   nP  =   cP;
		   tP  =   nP  +   (udiv+1)*3;
		   float	total	=	0;
		   for (j=vdiv;j>0;--j,nP=tP,tP+=(udiv+1)*3) {
			   subvv(tmp,tP,nP);
			   total	+=	lengthv(tmp);
		   }
	
		   vMax	=	max(vMax,total);
		   vMin	=	min(vMin,total);
	   }
	}
   float	udivf,vdivf;

   // Compute the new grid size based on the maximum size
   udivf   =	uMax / shadingRate;
   vdivf   =	vMax / shadingRate;
   
   // Clamp the division amount
   udivf	=   max(1,udivf);
   vdivf	=   max(1,vdivf);
   udivf	=	min(10000,udivf);
   vdivf	=	min(10000,vdivf);

   // Estimate the dicing amount
   if (attributes->flags & ATTRIBUTES_FLAGS_BINARY_DICE) {
		const double	log2		=	log(2.0);

		nudiv	=	1 << (unsigned int) (ceil(log(udivf) / log2));
		nvdiv	=	1 << (unsigned int) (ceil(log(vdivf) / log2));
	} else {
		nudiv   =   (int) ceil(udivf);
		nvdiv   =   (int) ceil(vdivf);
	}
}
Exemplo n.º 17
0
///////////////////////////////////////////////////////////////////////
// Class				:	CObject
// Method				:	cluster
// Description			:
/// \brief					Cluster the objects
// Return Value			:
// Comments				:
void		CObject::cluster(CShadingContext *context) {
	int		numChildren;
	CObject	*cObject;
	
	// Count the number of children
	for (numChildren=0,cObject=children;cObject!=NULL;cObject=cObject->sibling,numChildren++);

	// If we have too few children, continue
	if (numChildren <= 2)	return;

	// These are the two children
	CObject	*front,*frontChildren;
	CObject	*back,*backChildren;

	// Begin a memory page
	memBegin(context->threadMemory);

	// Cluster the midpoints of the objects
	float	*P			=	(float *)	ralloc(numChildren*3*sizeof(float),context->threadMemory);
	int		*indices	=	(int *)		ralloc(numChildren*sizeof(int),context->threadMemory);


	// For 5 iterations
	for (int iteration=0;iteration<15;iteration++) {

		// Compute a slightly jittered center position for the object
		for (numChildren=0,cObject=children;cObject!=NULL;cObject=cObject->sibling,numChildren++) {
			initv(P + numChildren*3	,	(cObject->bmax[0] - cObject->bmin[0])*(context->urand()*0.2f + 0.4f) +  cObject->bmin[0]
									,	(cObject->bmax[1] - cObject->bmin[1])*(context->urand()*0.2f + 0.4f) +  cObject->bmin[1]
									,	(cObject->bmax[2] - cObject->bmin[2])*(context->urand()*0.2f + 0.4f) +  cObject->bmin[2]);
			indices[numChildren]	=	-1;
		}

		// The random cluster centers
		vector	P1,P2;
		initv(P1,	(bmax[0] - bmin[0])*context->urand() + bmin[0]
				,	(bmax[1] - bmin[1])*context->urand() + bmin[1]
				,	(bmax[2] - bmin[2])*context->urand() + bmin[2]);
		initv(P2,	(bmax[0] - bmin[0])*context->urand() + bmin[0]
				,	(bmax[1] - bmin[1])*context->urand() + bmin[1]
				,	(bmax[2] - bmin[2])*context->urand() + bmin[2]);

		// The main clustering loop
		int	done;
		for (done=FALSE;done==FALSE;) {
			int		i;
			vector	nP1,nP2;
			int		num1,num2;

			done	=	TRUE;

			initv(nP1,0);
			initv(nP2,0);
			num1	=	0;
			num2	=	0;
			for (i=0;i<numChildren;i++) {
				vector	D1,D2;

				subvv(D1,P + i*3,P1);
				subvv(D2,P + i*3,P2);
				if (dotvv(D1,D1) < dotvv(D2,D2)) {
					if (indices[i] != 0) {
						done		=	FALSE;
						indices[i]	=	0;
					}

					addvv(nP1,P+i*3);
					num1++;
				} else {
					if (indices[i] != 1) {
						done		=	FALSE;
						indices[i]	=	1;
					}

					addvv(nP2,P+i*3);
					num2++;
				}
			}

			if ((num1 == 0) || (num2 == 0))	break;

			mulvf(P1,nP1,1/(float) num1);
			mulvf(P2,nP2,1/(float) num2);
		}

		if (done == TRUE)	break;
	}


	// Cluster the rest of the objects
	front	=	new CDummyObject(attributes,xform);
	back	=	new CDummyObject(attributes,xform);
	initv(front->bmin,C_INFINITY);
	initv(front->bmax,-C_INFINITY);
	initv(back->bmin,C_INFINITY);
	initv(back->bmax,-C_INFINITY);

	frontChildren	=	NULL;
	backChildren	=	NULL;

	// Create the clusters
	for (numChildren=0,cObject=children;cObject!=NULL;numChildren++) {
		CObject	*nObject	=	cObject->sibling;

		if (indices[numChildren] == 0) {
			cObject->sibling	=	frontChildren;
			frontChildren		=	cObject;
			addBox(front->bmin,front->bmax,cObject->bmin);
			addBox(front->bmin,front->bmax,cObject->bmax);
		} else {
			cObject->sibling	=	backChildren;
			backChildren		=	cObject;
			addBox(back->bmin,back->bmax,cObject->bmin);
			addBox(back->bmin,back->bmax,cObject->bmax);
		}

		cObject	=	nObject;
	}

	memEnd(context->threadMemory);

	// Recurse
	front->children	=	frontChildren;
	back->children	=	backChildren;
	
	front->attach();
	back->attach();

	front->sibling	=	back;
	back->sibling	=	NULL;
	children		=	front;
}
Exemplo n.º 18
0
///////////////////////////////////////////////////////////////////////
// Class				:	CXform
// Method				:	invTransformBound
// Description			:	Transfer the bounding box from one system to another
// Return Value			:	-
// Comments				:
void	CXform::invTransformBound(float *bmin,float *bmax) const {
	vector		corners[8];
	int			i;
	const float	*from;
	vector		vtmp;
	vector		lbmin,lbmax;


	from	=	this->to;

	// Compute & transfer the corners to the dest space
	initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[0],from,vtmp);

	initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[1],from,vtmp);

	initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[2],from,vtmp);

	initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[3],from,vtmp);

	initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[4],from,vtmp);

	initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[5],from,vtmp);

	initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
	mulmp(corners[6],from,vtmp);

	initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
	mulmp(corners[7],from,vtmp);

	movvv(lbmin,corners[0]);
	movvv(lbmax,corners[0]);

	for (i=1;i<8;i++) {
		addBox(lbmin,lbmax,corners[i]);
	}

	if (next != NULL) {
		from	=	next->from;

		// Compute & transfer the corners to the dest space
		initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
		mulmp(corners[0],from,vtmp);

		initv(vtmp,bmin[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
		mulmp(corners[1],from,vtmp);

		initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
		mulmp(corners[2],from,vtmp);

		initv(vtmp,bmin[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
		mulmp(corners[3],from,vtmp);

		initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmin[COMP_Z]);
		mulmp(corners[4],from,vtmp);

		initv(vtmp,bmax[COMP_X],bmin[COMP_Y],bmax[COMP_Z]);
		mulmp(corners[5],from,vtmp);

		initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmax[COMP_Z]);
		mulmp(corners[6],from,vtmp);

		initv(vtmp,bmax[COMP_X],bmax[COMP_Y],bmin[COMP_Z]);
		mulmp(corners[7],from,vtmp);

		for (i=0;i<8;i++) {
			addBox(lbmin,lbmax,corners[i]);
		}
	}
	movvv(bmin,lbmin);
	movvv(bmax,lbmax);
}