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

📄 lightv.c

📁 quake3工具源码。包括生成bsp文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		if ( fabs(t - a->lightmap[1]) > 0.01 ) {
			_printf( "Bad lightmapMatrix" );
		}
		VectorSubtract(b->xyz, f->mins, delta);
		s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
		if ( fabs(s - b->lightmap[0]) > 0.01 ) {
			_printf( "Bad lightmapMatrix" );
		}
		t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
		if ( fabs(t - b->lightmap[1]) > 0.01 ) {
			_printf( "Bad lightmapMatrix" );
		}
		VectorSubtract(c->xyz, f->mins, delta);
		s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
		if ( fabs(s - c->lightmap[0]) > 0.01 ) {
			_printf( "Bad lightmapMatrix" );
		}
		t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
		if ( fabs(t - c->lightmap[1]) > 0.01 ) {
			_printf( "Bad lightmapMatrix" );
		}
		VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
		return;
	}
	// This is an incredibly stupid way of solving a three variable equation
	for ( i = 0 ; i < 2 ; i++ ) {

		if (i)
			al = a->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
		else
			al = a->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;

		m[0][0] = a->xyz[0] - f->mins[0];
		m[0][1] = a->xyz[1] - f->mins[1];
		m[0][2] = a->xyz[2] - f->mins[2];
		m[0][3] = al;

		if (i)
			bl = b->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
		else
			bl = b->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;

		m[1][0] = b->xyz[0] - f->mins[0];
		m[1][1] = b->xyz[1] - f->mins[1];
		m[1][2] = b->xyz[2] - f->mins[2];
		m[1][3] = bl;

		if (i)
			cl = c->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
		else
			cl = c->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;

		m[2][0] = c->xyz[0] - f->mins[0];
		m[2][1] = c->xyz[1] - f->mins[1];
		m[2][2] = c->xyz[2] - f->mins[2];
		m[2][3] = cl;

		if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) >= fabs(m[2][0]) ) {
			for ( j = 0 ; j < 4 ; j ++ ) {
				t = m[0][j];
				m[0][j] = m[1][j];
				m[1][j] = t;
			}
		} else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) >= fabs(m[1][0]) ) {
			for ( j = 0 ; j < 4 ; j ++ ) {
				t = m[0][j];
				m[0][j] = m[2][j];
				m[2][j] = t;
			}
		}

		if (m[0][0])
		{
			s = 1.0 / m[0][0];
			m[0][0] *= s;
			m[0][1] *= s;
			m[0][2] *= s;
			m[0][3] *= s;

			s = m[1][0];
			m[1][0] -= m[0][0] * s;
			m[1][1] -= m[0][1] * s;
			m[1][2] -= m[0][2] * s;
			m[1][3] -= m[0][3] * s;

			s = m[2][0];
			m[2][0] -= m[0][0] * s;
			m[2][1] -= m[0][1] * s;
			m[2][2] -= m[0][2] * s;
			m[2][3] -= m[0][3] * s;
		}

		if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
			for ( j = 0 ; j < 4 ; j ++ ) {
				t = m[1][j];
				m[1][j] = m[2][j];
				m[2][j] = t;
			}
		}

		if (m[1][1])
		{
			s = 1.0 / m[1][1];
			m[1][0] *= s;
			m[1][1] *= s;
			m[1][2] *= s;
			m[1][3] *= s;

			s = m[2][1];
			m[2][0] -= m[1][0] * s;
			m[2][1] -= m[1][1] * s;
			m[2][2] -= m[1][2] * s;
			m[2][3] -= m[1][3] * s;
		}

		if (m[2][2])
		{
			s = 1.0 / m[2][2];
			m[2][0] *= s;
			m[2][1] *= s;
			m[2][2] *= s;
			m[2][3] *= s;
		}

		f->lightmapMatrix[i][2] = m[2][3];
		f->lightmapMatrix[i][1] = m[1][3] - f->lightmapMatrix[i][2] * m[1][2];
		f->lightmapMatrix[i][0] = m[0][3] - f->lightmapMatrix[i][2] * m[0][2] - f->lightmapMatrix[i][1] * m[0][1];

		f->lightmapMatrix[i][3] = 0;

		VectorSubtract(a->xyz, f->mins, delta);
		s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - al );
		if ( s > 0.01 ) {
			if (!message)
				_printf( "Bad lightmapMatrix\n" );
			message = qtrue;
		}
		VectorSubtract(b->xyz, f->mins, delta);
		s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - bl );
		if ( s > 0.01 ) {
			if (!message)
				_printf( "Bad lightmapMatrix\n" );
			message = qtrue;
		}
		VectorSubtract(c->xyz, f->mins, delta);
		s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - cl );
		if ( s > 0.01 ) {
			if (!message)
				_printf( "Bad lightmapMatrix\n" );
			message = qtrue;
		}
		VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
	}
}

/*
=============
Plane_Equal
=============
*/
#define	NORMAL_EPSILON	0.0001
#define	DIST_EPSILON	0.02

int Plane_Equal(plane_t *a, plane_t *b, int flip)
{
	vec3_t normal;
	float dist;

	if (flip) {
		normal[0] = - b->normal[0];
		normal[1] = - b->normal[1];
		normal[2] = - b->normal[2];
		dist = - b->dist;
	}
	else {
		normal[0] = b->normal[0];
		normal[1] = b->normal[1];
		normal[2] = b->normal[2];
		dist = b->dist;
	}
	if (
	   fabs(a->normal[0] - normal[0]) < NORMAL_EPSILON
	&& fabs(a->normal[1] - normal[1]) < NORMAL_EPSILON
	&& fabs(a->normal[2] - normal[2]) < NORMAL_EPSILON
	&& fabs(a->dist - dist) < DIST_EPSILON )
		return qtrue;
	return qfalse;
}

/*
=============
VL_PlaneFromPoints
=============
*/
qboolean VL_PlaneFromPoints( plane_t *plane, const vec3_t a, const vec3_t b, const vec3_t c ) {
	vec3_t	d1, d2;

	VectorSubtract( b, a, d1 );
	VectorSubtract( c, a, d2 );
	CrossProduct( d2, d1, plane->normal );
	if ( VectorNormalize( plane->normal, plane->normal ) == 0 ) {
		return qfalse;
	}

	plane->dist = DotProduct( a, plane->normal );
	return qtrue;
}

/*
=====================
VL_GenerateBoundaryForPoints
=====================
*/
void VL_GenerateBoundaryForPoints( plane_t *boundary, plane_t *plane, vec3_t a, vec3_t b ) {
	vec3_t	d1;

	// make a perpendicular vector to the edge and the surface
	VectorSubtract( a, b, d1 );
	CrossProduct( plane->normal, d1, boundary->normal );
	VectorNormalize( boundary->normal, boundary->normal );
	boundary->dist = DotProduct( a, boundary->normal );
}

/*
=====================
VL_GenerateFacetFor3Points
=====================
*/
qboolean VL_GenerateFacetFor3Points( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
	//
	vec3_t dir;
	int i;

	// if we can't generate a valid plane for the points, ignore the facet
	if ( !VL_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
		f->numpoints = 0;
		return qfalse;
	}

	f->num = numfacets++;

	VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
	VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
	VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );

	f->lightmapCoords[0][0] = a->lightmap[0];
	f->lightmapCoords[0][1] = a->lightmap[1];
	f->lightmapCoords[1][0] = b->lightmap[0];
	f->lightmapCoords[1][1] = b->lightmap[1];
	f->lightmapCoords[2][0] = c->lightmap[0];
	f->lightmapCoords[2][1] = c->lightmap[1];

	VL_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
	VL_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
	VL_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[0] );

	for (i = 0; i < 3; i++)
	{
		VectorSubtract(f->points[(i+1)%3], f->points[i], dir);
		if (VectorLength(dir) < 0.1)
			return qfalse;
	}

	VL_TextureMatrixFromPoints( f, a, b, c );
	VL_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );

	f->numpoints = 3;

	return qtrue;
}

/*
=====================
VL_GenerateFacetFor4Points

Attempts to use four points as a planar quad
=====================
*/
#define	PLANAR_EPSILON	0.1
qboolean VL_GenerateFacetFor4Points( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c, drawVert_t *d ) {
	float	dist;
	vec3_t dir;
	int i;
	plane_t plane;

	// if we can't generate a valid plane for the points, ignore the facet
	if ( !VL_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
		f->numpoints = 0;
		return qfalse;
	}

	// if the fourth point is also on the plane, we can make a quad facet
	dist = DotProduct( d->xyz, f->plane.normal ) - f->plane.dist;
	if ( fabs( dist ) > PLANAR_EPSILON ) {
		f->numpoints = 0;
		return qfalse;
	}

	VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
	VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
	VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );
	VectorAdd( d->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[3] );

	for (i = 1; i < 4; i++)
	{
		if ( !VL_PlaneFromPoints( &plane, f->points[i], f->points[(i+1) % 4], f->points[(i+2) % 4]) ) {
			f->numpoints = 0;
			return qfalse;
		}

		if (!Plane_Equal(&f->plane, &plane, qfalse)) {
			f->numpoints = 0;
			return qfalse;
		}
	}

	f->lightmapCoords[0][0] = a->lightmap[0];
	f->lightmapCoords[0][1] = a->lightmap[1];
	f->lightmapCoords[1][0] = b->lightmap[0];
	f->lightmapCoords[1][1] = b->lightmap[1];
	f->lightmapCoords[2][0] = c->lightmap[0];
	f->lightmapCoords[2][1] = c->lightmap[1];
	f->lightmapCoords[3][0] = d->lightmap[0];
	f->lightmapCoords[3][1] = d->lightmap[1];

	VL_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
	VL_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
	VL_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[3] );
	VL_GenerateBoundaryForPoints( &f->boundaries[3], &f->plane, f->points[3], f->points[0] );

	for (i = 0; i < 4; i++)
	{
		VectorSubtract(f->points[(i+1)%4], f->points[i], dir);
		if (VectorLength(dir) < 0.1)
			return qfalse;
	}

	VL_TextureMatrixFromPoints( f, a, b, c );
	VL_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );

	f->num = numfacets++;
	f->numpoints = 4;

	return qtrue;
}

/*
===============
VL_SphereFromBounds
===============
*/
void VL_SphereFromBounds( vec3_t mins, vec3_t maxs, vec3_t origin, float *radius ) {
	vec3_t		temp;

	VectorAdd( mins, maxs, origin );
	VectorScale( origin, 0.5, origin );
	VectorSubtract( maxs, origin, temp );
	*radius = VectorLength( temp );
}

/*
====================
VL_FacetsForTriangleSurface
====================
*/
void VL_FacetsForTriangleSurface( dsurface_t *dsurf, shaderInfo_t *si, lsurfaceTest_t *test ) {
	int			i;
	drawVert_t	*v1, *v2, *v3, *v4;
	int			count;
	int			i1, i2, i3, i4, i5, i6;

	test->patch = qfalse;
	if (dsurf->surfaceType == MST_TRIANGLE_SOUP)
		test->trisoup = qtrue;
	else
		test->trisoup = qfalse;
	test->numFacets = dsurf->numIndexes / 3;
	test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
	test->shader = si;

	count = 0;
	for ( i = 0 ; i < test->numFacets ; i++ ) {
		i1 = drawIndexes[ dsurf->firstIndex + i*3 ];
		i2 = drawIndexes[ dsurf->firstIndex + i*3 + 1 ];
		i3 = drawIndexes[ dsurf->firstIndex + i*3 + 2 ];

		v1 = &drawVerts[ dsurf->firstVert + i1 ];
		v2 = &drawVerts[ dsurf->firstVert + i2 ];
		v3 = &drawVerts[ dsurf->firstVert + i3 ];

		// try and make a quad out of two triangles
		if ( i != test->numFacets - 1 ) {
			i4 = drawIndexes[ dsurf->firstIndex + i*3 + 3 ];
			i5 = drawIndexes[ dsurf->firstIndex + i*3 + 4 ];
			i6 = drawIndexes[ dsurf->firstIndex + i*3 + 5 ];
			if ( i4 == i3 && i5 == i2 ) {
				v4 = &drawVerts[ dsurf->firstVert + i6 ];
				if ( VL_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v2, v4, v3 ) ) {
					count++;
					i++;		// skip next tri
					continue;
				}
			}
		}

		if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v2, v3 )) {
			count++;
		}
	}		

	// we may have turned some pairs into quads
	test->numFacets = count;
}

/*
====================
VL_FacetsForPatch
====================
*/
void VL_FacetsForPatch( dsurface_t *dsurf, int surfaceNum, shaderInfo_t *si, lsurfaceTest_t *test ) {
	int			i, j, x, y;
	drawVert_t	*v1, *v2, *v3, *v4;
	int			count, ssize;
	mesh_t		mesh;
	mesh_t		*subdivided, *detailmesh, *newmesh;
	int widthtable[LIGHTMAP_SIZE], heighttable[LIGHTMAP_SIZE];

	mesh.width = dsurf->patchWidth;
	mesh.height = dsurf->patchHeight;
	mesh.verts = &drawVerts[ dsurf->firstVert ];

	newmesh = SubdivideMesh( mesh, 8, 999 );
	PutMeshOnCurve( *newmesh );
	MakeMeshNormals( *newmesh );

	subdivided = RemoveLinearMeshColumnsRows( newmesh );
	FreeMesh(newmesh);

	//	DebugNet_RemoveAllPolys();
	//	DebugNet_DrawMesh(subdivided);

	ssize = samplesize;
	if (si->lightmapSampleSize)
		ssize = si->lightmapSampleSize;

	if ( dsurf->lightmapNum >= 0 ) {

		detailmesh = SubdivideMeshQuads( subdivided, ssize, LIGHTMAP_SIZE, widthtable, heighttable);
		test->detailMesh = detailmesh;

		// DebugNet_RemoveAllPolys();
		// DebugNet_DrawMesh(detailmesh);

		if ( detailmesh->width != dsurf->lightmapWidth || detailmesh->height != dsurf->lightmapHeight ) {
			Error( "Mesh lightmap miscount");
		}
	}
	else {
		test->detailMesh = NULL;
		memset(widthtable, 0, sizeof(widthtable));
		memset(heighttable, 0, sizeof(heighttable));
	}

	test->patch = qtrue;
	test->trisoup = qfalse;
	test->numFacets = ( subdivided->width - 1 ) * ( subdivided->height - 1 ) * 2;
	test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
	test->shader = si;

	count = 0;
	x = 0;
	for ( i = 0 ; i < subdivided->width - 1 ; i++ ) {
		y = 0;
		for ( j = 0 ; j < subdivided->height - 1 ; j++ ) {

			v1 = subdivided->verts + j * subdivided->width + i;
			v2 = v1 + 1;
			v3 = v1 + subdivided->width + 1;
			v4 = v1 + subdivided->width;

			if ( VL_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v4, v3, v2 ) ) {
				test->facets[count].x = x;
				test->facets[count].y = y;
				test->facets[count].width = widthtable[i];
				test->facets[count].height = heighttable[j];

⌨️ 快捷键说明

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