Пример #1
0
/*
==============
TestPatchToFace

Sets vis bits for all patches in the face
==============
*/
void TestPatchToFace (unsigned patchnum, int facenum, int head, unsigned bitpos)
{
	patch_t		*patch = &patches[patchnum];
	patch_t		*patch2 = face_patches[facenum];

	// if emitter is behind that face plane, skip all patches

	if ( patch2 && DotProduct(patch->origin, patch2->normal) > PatchPlaneDist(patch2)+1.01 )
	{
		// we need to do a real test
		for ( ; patch2 ; patch2 = patch2->next)
		{
			unsigned m = patch2 - patches;

			// check vis between patch and patch2
			// if bit has not already been set
			//  && v2 is not behind light plane
			//  && v2 is visible from v1
			if ( m > patchnum
			  && DotProduct (patch2->origin, patch->normal) > PatchPlaneDist(patch)+1.01
		      && TestLine_r (head, patch->origin, patch2->origin) == CONTENTS_EMPTY )
			{
				// patchnum can see patch m
				int bitset = bitpos+m;
				vismatrix[ bitset>>3 ] |= 1 << (bitset&7);
			}
		}
	}
Пример #2
0
void MakeScales (int threadnum)
{
	int		i;
	unsigned j;
	vec3_t	delta;
	vec_t	dist, scale;
	int		count;
	float	trans;
	patch_t		*patch, *patch2;
	float		total, send;
	dplane_t	plane;
	vec3_t		origin;
	vec_t		area;
	transfer_t	transfers[MAX_PATCHES], *all_transfers;

	count = 0;

	while (1)
	{
		i = GetThreadWork ();
		if (i == -1)
			break;

		patch = patches + i;

		total = 0;
		patch->numtransfers = 0;

		VectorCopy (patch->origin, origin);
		plane = *patch->plane;
		plane.dist = PatchPlaneDist( patch );

		area = patch->area;

		// find out which patch2's will collect light
		// from patch

		all_transfers = transfers;
		for (j=0, patch2 = patches ; j<num_patches ; j++, patch2++)
		{
			if (!CheckVisBit (i, j))
				continue;

			// calculate transferemnce
			VectorSubtract (patch2->origin, origin, delta);
			dist = VectorNormalize (delta);
			
			// skys don't care about the interface angle, but everything
			// else does
			if (!patch->sky)
				scale = DotProduct (delta, patch->normal);
			else
				scale = 1;

			scale *= -DotProduct (delta, patch2->normal);

			trans = scale / (dist*dist);

			if (trans < -ON_EPSILON)
				Error ("transfer < 0");
			send = trans*patch2->area;
			if (send > 0.4f)
			{
				trans = 0.4f / patch2->area;
				send = 0.4f;
			}
			total += send;


			// scale to 16 bit
			trans = trans * area * INVERSE_TRANSFER_SCALE;
			if (trans >= 0x10000)
				trans = 0xffff;
			if (!trans)
				continue;
			all_transfers->transfer = (unsigned short)trans;
			all_transfers->patch = j;
			all_transfers++;
			patch->numtransfers++;
			count++;

		}

		// copy the transfers out
		if (patch->numtransfers)
		{
			transfer_t	*t, *t2;

			patch->transfers = calloc (patch->numtransfers, sizeof(transfer_t));

			if (!patch->transfers)
				Error ("Memory allocation failure");

			//
			// normalize all transfers so exactly 50% of the light
			// is transfered to the surroundings
			//
			total = 0.5f/total;
			t = patch->transfers;
			t2 = transfers;
			for (j=0 ; j<(unsigned)patch->numtransfers ; j++, t++, t2++)
			{
				t->transfer = (unsigned short)(t2->transfer*total);
				t->patch = t2->patch;
			}
		}
	}

	ThreadLock ();
	total_transfer += count;
	ThreadUnlock ();
}