📄 lightv.c
字号:
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 + -