⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lightv.c

📁 quake3工具源码。包括生成bsp文件
💻 C
📖 第 1 页 / 共 5 页
字号:
				count++;
			} else {
				if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v4, v3 )) {
					test->facets[count].x = x;
					test->facets[count].y = y;
					test->facets[count].width = widthtable[i];
					test->facets[count].height = heighttable[j];
					count++;
				}
				if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v3, v2 )) {
					test->facets[count].x = x;
					test->facets[count].y = y;
					test->facets[count].width = widthtable[i];
					test->facets[count].height = heighttable[j];
					count++;
				}
			}
			y += heighttable[j];
		}
		x += widthtable[i];
	}
	test->numFacets = count;

	FreeMesh(subdivided);
}

/*
=====================
VL_InitSurfacesForTesting
=====================
*/
void VL_InitSurfacesForTesting( void ) {

	int				i, j, k;
	dsurface_t		*dsurf;
	lsurfaceTest_t	*test;
	shaderInfo_t	*si;
	lFacet_t		*facet;

	for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
		// don't light the entity surfaces with vlight
		if ( entitySurface[i] )
			continue;
		//
		dsurf = &drawSurfaces[ i ];
		if ( !dsurf->numIndexes && !dsurf->patchWidth ) {
			continue;
		}

		si = ShaderInfoForShader( dshaders[ dsurf->shaderNum].shader );
		// if the surface is translucent and does not cast an alpha shadow
		if ( (si->contents & CONTENTS_TRANSLUCENT) && !(si->surfaceFlags & SURF_ALPHASHADOW) ) {
			// if the surface has no lightmap
			if ( dsurf->lightmapNum < 0 )
				continue;
		}

		test = malloc( sizeof( *test ) );
		memset(test, 0, sizeof( *test ));
		test->mutex = MutexAlloc();
		test->numvolumes = 0;
		if (si->forceTraceLight)
			test->always_tracelight = qtrue;
		else if (si->forceVLight)
			test->always_vlight = qtrue;
		lsurfaceTest[i] = test;

		if ( dsurf->surfaceType == MST_TRIANGLE_SOUP || dsurf->surfaceType == MST_PLANAR ) {
			VL_FacetsForTriangleSurface( dsurf, si, test );
		} else if ( dsurf->surfaceType == MST_PATCH ) {
			VL_FacetsForPatch( dsurf, i, si, test );
		}
		if (numfacets >= MAX_FACETS)
			Error("numfacets >= MAX_FACETS (%d)", MAX_FACETS);

		ClearBounds( test->mins, test->maxs );
		for (j = 0; j < test->numFacets; j++)
		{
			facet = &test->facets[j];
			for ( k = 0 ; k < facet->numpoints; k++) {
				AddPointToBounds( facet->points[k], test->mins, test->maxs );
			}
		}
		VL_SphereFromBounds( test->mins, test->maxs, test->origin, &test->radius );
	}
	_printf("%6d facets\n", numfacets);
	_printf("linking surfaces...\n");
	VL_LinkSurfaces();
}

/*
=============
VL_ChopWinding
=============
*/
int VL_ChopWinding (winding_t *in, plane_t *split, float epsilon)
{
	vec_t	dists[128];
	int		sides[128];
	int		counts[3];
	vec_t	dot;
	int		i, j;
	vec_t	*p1, *p2;
	vec3_t	mid;
	winding_t out;
	winding_t	*neww;

	counts[0] = counts[1] = counts[2] = 0;

	// determine sides for each point
	for (i=0 ; i<in->numpoints ; i++)
	{
		dot = DotProduct (in->points[i], split->normal);
		dot -= split->dist;
		dists[i] = dot;
		if (dot > epsilon)
			sides[i] = SIDE_FRONT;
		else if (dot < -epsilon)
			sides[i] = SIDE_BACK;
		else
		{
			sides[i] = SIDE_ON;
		}
		counts[sides[i]]++;
	}

	if (!counts[SIDE_BACK])
	{
		if (!counts[SIDE_FRONT])
			return SIDE_ON;
		else
			return SIDE_FRONT;
	}
	
	if (!counts[SIDE_FRONT])
	{
		return SIDE_BACK;
	}

	sides[i] = sides[0];
	dists[i] = dists[0];
	
	neww = &out;

	neww->numpoints = 0;

	for (i=0 ; i<in->numpoints ; i++)
	{
		p1 = in->points[i];

		if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
		{
			_printf("WARNING: VL_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
			return SIDE_FRONT;		// can't chop -- fall back to original
		}

		if (sides[i] == SIDE_ON)
		{
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
			continue;
		}
	
		if (sides[i] == SIDE_FRONT)
		{
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
		}
		
		if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;
			
		if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
		{
			_printf("WARNING: VL_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
			return SIDE_FRONT;		// can't chop -- fall back to original
		}

		// generate a split point
		p2 = in->points[(i+1)%in->numpoints];
		
		dot = dists[i] / (dists[i]-dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{	// avoid round off error when possible
			if (split->normal[j] == 1)
				mid[j] = split->dist;
			else if (split->normal[j] == -1)
				mid[j] = -split->dist;
			else
				mid[j] = p1[j] + dot*(p2[j]-p1[j]);
		}
			
		VectorCopy (mid, neww->points[neww->numpoints]);
		neww->numpoints++;
	}
	memcpy(in, &out, sizeof(winding_t));
	
	return SIDE_CROSS;
}

/*
=============
VL_ChopWindingWithBrush

  returns all winding fragments outside the brush
=============
*/
int VL_ChopWindingWithBrush(winding_t *w, dbrush_t *brush, winding_t *outwindings, int maxout)
{
	int i, res, numout;
	winding_t front, back;
	plane_t plane;

	numout = 0;
	memcpy(front.points, w->points, w->numpoints * sizeof(vec3_t));
	front.numpoints = w->numpoints;
	for (i = 0; i < brush->numSides; i++)
	{
		VectorCopy(dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].normal, plane.normal);
		VectorInverse(plane.normal);
		plane.dist = -dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].dist;
		res = VL_SplitWinding(&front, &back, &plane, 0.1);
		if (res == SIDE_BACK || res == SIDE_ON)
		{
			memcpy(outwindings[0].points, w->points, w->numpoints * sizeof(vec3_t));
			outwindings[0].numpoints = w->numpoints;
			return 1;	//did not intersect
		}
		if (res != SIDE_FRONT)
		{
			if (numout >= maxout)
			{
				_printf("WARNING: VL_ChopWindingWithBrush: more than %d windings\n", maxout);
				return 0;
			}
			memcpy(outwindings[numout].points, back.points, back.numpoints * sizeof(vec3_t));
			outwindings[numout].numpoints = back.numpoints;
			numout++;
		}
	}
	return numout;
}

/*
=============
VL_WindingAreaOutsideBrushes
=============
*/
float VL_WindingAreaOutsideBrushes(winding_t *w, int *brushnums, int numbrushes)
{
	int i, j, numwindings[2], n;
	winding_t windingsbuf[2][64];
	dbrush_t *brush;
	float area;

	memcpy(windingsbuf[0][0].points, w->points, w->numpoints * sizeof(vec3_t));
	windingsbuf[0][0].numpoints = w->numpoints;
	numwindings[0] = 1;
	for (i = 0; i < numbrushes; i++)
	{
		brush = &dbrushes[brushnums[i]];
		if (!(dshaders[brush->shaderNum].contentFlags & (
					CONTENTS_LAVA
					| CONTENTS_SLIME
					| CONTENTS_WATER
					| CONTENTS_FOG
					| CONTENTS_AREAPORTAL
					| CONTENTS_PLAYERCLIP
					| CONTENTS_MONSTERCLIP
					| CONTENTS_CLUSTERPORTAL
					| CONTENTS_DONOTENTER
					| CONTENTS_BODY
					| CONTENTS_CORPSE
					| CONTENTS_TRANSLUCENT
					| CONTENTS_TRIGGER
					| CONTENTS_NODROP) ) &&
			(dshaders[brush->shaderNum].contentFlags & CONTENTS_SOLID) )
		{
			numwindings[!(i & 1)] = 0;
			for (j = 0; j < numwindings[i&1]; j++)
			{
				n = VL_ChopWindingWithBrush(&windingsbuf[i&1][j], brush,
											&windingsbuf[!(i&1)][numwindings[!(i&1)]],
											64 - numwindings[!(i&1)]);
				numwindings[!(i&1)] += n;
			}
			if (!numwindings[!(i&1)])
				return 0;
		}
		else
		{
			for (j = 0; j < numwindings[i&1]; j++)
			{
				windingsbuf[!(i&1)][j] = windingsbuf[i&1][j];
			}
			numwindings[!(i&1)] = numwindings[i&1];
		}
	}
	area = 0;
	for (j = 0; j < numwindings[i&1]; j++)
	{
		area += WindingArea(&windingsbuf[i&1][j]);
	}
	return area;
}

/*
=============
VL_R_WindingAreaOutsideSolid
=============
*/
float VL_R_WindingAreaOutsideSolid(winding_t *w, vec3_t normal, int nodenum)
{
	int leafnum, res;
	float area;
	dnode_t *node;
	dleaf_t *leaf;
	dplane_t *plane;
	winding_t back;
	plane_t split;

	area = 0;
	while(nodenum >= 0)
	{
		node = &dnodes[nodenum];
		plane = &dplanes[node->planeNum];

		VectorCopy(plane->normal, split.normal);
		split.dist = plane->dist;
		res = VL_SplitWinding (w, &back, &split, 0.1);

		if (res == SIDE_FRONT)
		{
			nodenum = node->children[0];
		}
		else if (res == SIDE_BACK)
		{
			nodenum = node->children[1];
		}
		else if (res == SIDE_ON)
		{
			if (DotProduct(normal, plane->normal) > 0)
				nodenum = node->children[0];
			else
				nodenum = node->children[1];
		}
		else
		{
			area += VL_R_WindingAreaOutsideSolid(&back, normal, node->children[1]);
			nodenum = node->children[0];
		}
	}
	leafnum = -nodenum - 1;
	leaf = &dleafs[leafnum];
	if (leaf->cluster != -1)
	{
		area += VL_WindingAreaOutsideBrushes(w, &dleafbrushes[leaf->firstLeafBrush], leaf->numLeafBrushes);
	}
	return area;
}

/*
=============
VL_WindingAreaOutsideSolid
=============
*/
float VL_WindingAreaOutsideSolid(winding_t *w, vec3_t normal)
{
	return VL_R_WindingAreaOutsideSolid(w, normal, 0);
}

/*
=============
VL_ChopWindingWithFacet
=============
*/
float VL_ChopWindingWithFacet(winding_t *w, lFacet_t *facet)
{
	int i;

	for (i = 0; i < facet->numpoints; i++)
	{
		if (VL_ChopWinding(w, &facet->boundaries[i], 0) == SIDE_BACK)
			return 0;
	}
	if (nostitching)
		return WindingArea(w);
	else
		return VL_WindingAreaOutsideSolid(w, facet->plane.normal);
}

/*
=============
VL_CalcVisibleLightmapPixelArea

nice brute force ;)
=============
*/
void VL_CalcVisibleLightmapPixelArea(void)
{
	int				i, j, x, y, k;
	dsurface_t		*ds;
	lsurfaceTest_t	*test;
	mesh_t			*mesh;
	winding_t w, tmpw;
	float area;

	_printf("calculating visible lightmap pixel area...\n");
	for ( i = 0 ; i < numDrawSurfaces ; i++ )
	{
		test = lsurfaceTest[ i ];
		if (!test)
			continue;
		ds = &drawSurfaces[ i ];

		if ( ds->lightmapNum < 0 )
			continue;

		for (y = 0; y < ds->lightmapHeight; y++)
		{
			for (x = 0; x < ds->lightmapWidth; x++)
			{
				if (ds->surfaceType == MST_PATCH)
				{
					if (y == ds->lightmapHeight-1)
						continue;
					if (x == ds->lightmapWidth-1)
						continue;
					mesh = lsurfaceTest[i]->detailMesh;
					VectorCopy( mesh->verts[y*mesh->width+x].xyz, w.points[0]);
					VectorCopy( mesh->verts[(y+1)*mesh->width+x].xyz, w.points[1]);
					VectorCopy( mesh->verts[(y+1)*mesh->width+x+1].xyz, w.points[2]);
					VectorCopy( mesh->verts[y*mesh->width+x+1].xyz, w.points[3]);
					w.numpoints = 4;
					if (nostitching)
						area = WindingArea(&w);
					else
						area = VL_WindingAreaOutsideSolid(&w, mesh->verts[y*mesh->width+x].normal);
				}
				else
				{
					VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[0]);
					VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[0]);
					VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[3]);
					VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[3]);
					VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[2]);
					VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[2]);
					VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[1]);
					VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[1]);
					w.numpoints = 4;
					area = 0;
					for (j = 0; j < test->numFacets; j++)
					{
						memcpy(&tmpw, &w, sizeof(winding_t));
						area += VL_ChopWindingWithFacet(&tmpw, &test->facets[j]);
					}
				}
				k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
						* LIGHTMAP_WIDTH + ds->lightmapX + x;
				lightmappixelarea[k] = area;
			}
		}
	}
}

/*
=============
VL_FindAdjacentSurface
=============
*/
int VL_FindAdjacentSurface(int surfaceNum, int facetNum, vec3_t p1, vec3_t p2, int *sNum, int *fNum, int *point)
{
	int i, j, k;
	lsurfaceTest_t *test;
	lFacet_t *facet;
	dsurface_t *ds;
	float *fp1, *fp2;
	vec3_t dir;
	plane_t *facetplane;
	//	winding_t w;

	facetplane = &lsurfaceTest[surfaceNum]->facets[facetNum].plane;
	//	DebugNet_RemoveAllPolys();
	//	memcpy(w.points, lsurfaceTest[surfaceNum]->facets[facetNum].points,
	//			lsurfaceTest[surfaceNum]->facets[facetNum].numpoints * sizeof(vec3_t));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -