📄 lightv.c
字号:
// w.numpoints = lsurfaceTest[surfaceNum]->facets[facetNum].numpoints;
// DebugNet_DrawWinding(&w, 2);
for ( i = 0 ; i < numDrawSurfaces ; i++ )
{
if (i == surfaceNum)
continue;
test = lsurfaceTest[ i ];
if (!test)
continue;
if (test->trisoup)// || test->patch)
continue;
ds = &drawSurfaces[i];
if ( ds->lightmapNum < 0 )
continue;
//if this surface is not even near the edge
VectorSubtract(p1, test->origin, dir);
if (fabs(dir[0]) > test->radius ||
fabs(dir[1]) > test->radius ||
fabs(dir[1]) > test->radius)
{
VectorSubtract(p2, test->origin, dir);
if (fabs(dir[0]) > test->radius ||
fabs(dir[1]) > test->radius ||
fabs(dir[1]) > test->radius)
{
continue;
}
}
//
for (j = 0; j < test->numFacets; j++)
{
facet = &test->facets[j];
//
//if (!Plane_Equal(&facet->plane, facetplane, qfalse))
if (DotProduct(facet->plane.normal, facetplane->normal) < 0.9)
{
if (!test->trisoup && !test->patch)
break;
continue;
}
//
for (k = 0; k < facet->numpoints; k++)
{
fp1 = facet->points[k];
if (fabs(p2[0] - fp1[0]) < 0.1 &&
fabs(p2[1] - fp1[1]) < 0.1 &&
fabs(p2[2] - fp1[2]) < 0.1)
{
fp2 = facet->points[(k+1) % facet->numpoints];
if (fabs(p1[0] - fp2[0]) < 0.1 &&
fabs(p1[1] - fp2[1]) < 0.1 &&
fabs(p1[2] - fp2[2]) < 0.1)
{
// memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
// w.numpoints = facet->numpoints;
// DebugNet_DrawWinding(&w, 1);
*sNum = i;
*fNum = j;
*point = k;
return qtrue;
}
}
/*
else if (fabs(p1[0] - fp1[0]) < 0.1 &&
fabs(p1[1] - fp1[1]) < 0.1 &&
fabs(p1[2] - fp1[2]) < 0.1)
{
fp2 = facet->points[(k+1) % facet->numpoints];
if (fabs(p2[0] - fp2[0]) < 0.1 &&
fabs(p2[1] - fp2[1]) < 0.1 &&
fabs(p2[2] - fp2[2]) < 0.1)
{
// memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
// w.numpoints = facet->numpoints;
// DebugNet_DrawWinding(&w, 1);
*sNum = i;
*fNum = j;
*point = k;
return qtrue;
}
}
//*/
}
}
}
return qfalse;
}
/*
=============
VL_SmoothenLightmapEdges
this code is used to smoothen lightmaps across surface edges
=============
*/
void VL_SmoothenLightmapEdges(void)
{
int i, j, k, coords1[2][2];
float coords2[2][2];
int x1, y1, xinc1, yinc1, k1, k2;
float x2, y2, xinc2, yinc2, length;
int surfaceNum, facetNum, point;
lsurfaceTest_t *test;
lFacet_t *facet1, *facet2;
dsurface_t *ds1, *ds2;
float *p[2], s, t, *color1, *color2;
vec3_t dir, cross;
for ( i = 0 ; i < numDrawSurfaces ; i++ )
{
test = lsurfaceTest[ i ];
if (!test)
continue;
if (test->trisoup)// || test->patch)
continue;
ds1 = &drawSurfaces[i];
if ( ds1->lightmapNum < 0 )
continue;
for (j = 0; j < test->numFacets; j++)
{
facet1 = &test->facets[j];
//
for (k = 0; k < facet1->numpoints; k++)
{
p[0] = facet1->points[k];
p[1] = facet1->points[(k+1)%facet1->numpoints];
//
coords1[0][0] = facet1->lightmapCoords[k][0] * LIGHTMAP_SIZE;
coords1[0][1] = facet1->lightmapCoords[k][1] * LIGHTMAP_SIZE;
coords1[1][0] = facet1->lightmapCoords[(k+1)%facet1->numpoints][0] * LIGHTMAP_SIZE;
coords1[1][1] = facet1->lightmapCoords[(k+1)%facet1->numpoints][1] * LIGHTMAP_SIZE;
if (coords1[0][0] >= LIGHTMAP_SIZE)
coords1[0][0] = LIGHTMAP_SIZE-1;
if (coords1[0][1] >= LIGHTMAP_SIZE)
coords1[0][1] = LIGHTMAP_SIZE-1;
if (coords1[1][0] >= LIGHTMAP_SIZE)
coords1[1][0] = LIGHTMAP_SIZE-1;
if (coords1[1][1] >= LIGHTMAP_SIZE)
coords1[1][1] = LIGHTMAP_SIZE-1;
// try one row or column further because on flat faces the lightmap can
// extend beyond the edge
VectorSubtract(p[1], p[0], dir);
VectorNormalize(dir, dir);
CrossProduct(dir, facet1->plane.normal, cross);
//
if (coords1[0][0] - coords1[1][0] == 0)
{
s = DotProduct( cross, facet1->lightmapMatrix[0] );
coords1[0][0] += s < 0 ? 1 : -1;
coords1[1][0] += s < 0 ? 1 : -1;
if (coords1[0][0] < ds1->lightmapX || coords1[0][0] >= ds1->lightmapX + ds1->lightmapWidth)
{
coords1[0][0] += s < 0 ? -1 : 1;
coords1[1][0] += s < 0 ? -1 : 1;
}
length = fabs(coords1[1][1] - coords1[0][1]);
}
else if (coords1[0][1] - coords1[1][1] == 0)
{
t = DotProduct( cross, facet1->lightmapMatrix[1] );
coords1[0][1] += t < 0 ? 1 : -1;
coords1[1][1] += t < 0 ? 1 : -1;
if (coords1[0][1] < ds1->lightmapY || coords1[0][1] >= ds1->lightmapY + ds1->lightmapHeight)
{
coords1[0][1] += t < 0 ? -1 : 1;
coords1[1][1] += t < 0 ? -1 : 1;
}
length = fabs(coords1[1][0] - coords1[0][0]);
}
else
{
//the edge is not parallell to one of the lightmap axis
continue;
}
//
x1 = coords1[0][0];
y1 = coords1[0][1];
xinc1 = coords1[1][0] - coords1[0][0];
if (xinc1 < 0) xinc1 = -1;
if (xinc1 > 0) xinc1 = 1;
yinc1 = coords1[1][1] - coords1[0][1];
if (yinc1 < 0) yinc1 = -1;
if (yinc1 > 0) yinc1 = 1;
// the edge should be parallell to one of the lightmap axis
if (xinc1 != 0 && yinc1 != 0)
continue;
//
if (!VL_FindAdjacentSurface(i, j, p[0], p[1], &surfaceNum, &facetNum, &point))
continue;
//
ds2 = &drawSurfaces[surfaceNum];
facet2 = &lsurfaceTest[surfaceNum]->facets[facetNum];
coords2[0][0] = facet2->lightmapCoords[(point+1)%facet2->numpoints][0] * LIGHTMAP_SIZE;
coords2[0][1] = facet2->lightmapCoords[(point+1)%facet2->numpoints][1] * LIGHTMAP_SIZE;
coords2[1][0] = facet2->lightmapCoords[point][0] * LIGHTMAP_SIZE;
coords2[1][1] = facet2->lightmapCoords[point][1] * LIGHTMAP_SIZE;
if (coords2[0][0] >= LIGHTMAP_SIZE)
coords2[0][0] = LIGHTMAP_SIZE-1;
if (coords2[0][1] >= LIGHTMAP_SIZE)
coords2[0][1] = LIGHTMAP_SIZE-1;
if (coords2[1][0] >= LIGHTMAP_SIZE)
coords2[1][0] = LIGHTMAP_SIZE-1;
if (coords2[1][1] >= LIGHTMAP_SIZE)
coords2[1][1] = LIGHTMAP_SIZE-1;
//
x2 = coords2[0][0];
y2 = coords2[0][1];
xinc2 = coords2[1][0] - coords2[0][0];
if (length)
xinc2 = xinc2 / length;
yinc2 = coords2[1][1] - coords2[0][1];
if (length)
yinc2 = yinc2 / length;
// the edge should be parallell to one of the lightmap axis
if ((int) xinc2 != 0 && (int) yinc2 != 0)
continue;
//
while(1)
{
k1 = ( ds1->lightmapNum * LIGHTMAP_HEIGHT + y1) * LIGHTMAP_WIDTH + x1;
k2 = ( ds2->lightmapNum * LIGHTMAP_HEIGHT + ((int) y2)) * LIGHTMAP_WIDTH + ((int) x2);
color1 = lightFloats + k1*3;
color2 = lightFloats + k2*3;
if (lightmappixelarea[k1] < 0.01)
{
color1[0] = color2[0];
color1[1] = color2[1];
color1[2] = color2[2];
}
else
{
color1[0] = (float) color2[0] * 0.7 + (float) color1[0] * 0.3;
color1[1] = (float) color2[1] * 0.7 + (float) color1[1] * 0.3;
color1[2] = (float) color2[2] * 0.7 + (float) color1[2] * 0.3;
}
//
if (x1 == coords1[1][0] &&
y1 == coords1[1][1])
break;
x1 += xinc1;
y1 += yinc1;
x2 += xinc2;
y2 += yinc2;
if (x2 < ds2->lightmapX)
x2 = ds2->lightmapX;
if (x2 >= ds2->lightmapX + ds2->lightmapWidth)
x2 = ds2->lightmapX + ds2->lightmapWidth-1;
if (y2 < ds2->lightmapY)
y2 = ds2->lightmapY;
if (y2 >= ds2->lightmapY + ds2->lightmapHeight)
y2 = ds2->lightmapY + ds2->lightmapHeight-1;
}
}
}
}
}
/*
=============
VL_FixLightmapEdges
=============
*/
void VL_FixLightmapEdges(void)
{
int i, j, x, y, k, foundvalue, height, width, index;
int pos, top, bottom;
dsurface_t *ds;
lsurfaceTest_t *test;
float color[3];
float *ptr;
byte filled[(LIGHTMAP_SIZE+1) * (LIGHTMAP_SIZE+1) / 8];
float lightmap_edge_epsilon;
lightmap_edge_epsilon = 0.1 * samplesize;
for ( i = 0 ; i < numDrawSurfaces ; i++ )
{
test = lsurfaceTest[ i ];
if (!test)
continue;
ds = &drawSurfaces[ i ];
if ( ds->lightmapNum < 0 )
continue;
if (ds->surfaceType == MST_PATCH)
{
height = ds->lightmapHeight - 1;
width = ds->lightmapWidth - 1;
}
else
{
height = ds->lightmapHeight;
width = ds->lightmapWidth;
}
memset(filled, 0, sizeof(filled));
// printf("\n");
for (x = 0; x < width; x++)
{
for (y = 0; y < height; y++)
{
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
if (lightmappixelarea[k] > lightmap_edge_epsilon)
{
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
filled[index >> 3] |= 1 << (index & 7);
// printf("*");
}
// else
// printf("_");
}
// printf("\n");
}
for (y = 0; y < height; y++)
{
pos = -2;
for (x = 0; x < width; x++)
{
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
if (pos == -2)
{
if (filled[index >> 3] & (1 << (index & 7)))
pos = -1;
}
else if (pos == -1)
{
if (!(filled[index >> 3] & (1 << (index & 7))))
pos = x - 1;
}
else
{
if (filled[index >> 3] & (1 << (index & 7)))
{
bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + pos;
top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
for (j = 0; j < (x - pos + 1) / 2; j++)
{
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
filled[index >> 3] |= 1 << (index & 7);
(lightFloats + k*3)[0] = (lightFloats + top*3)[0];
(lightFloats + k*3)[1] = (lightFloats + top*3)[1];
(lightFloats + k*3)[2] = (lightFloats + top*3)[2];
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
filled[index >> 3] |= 1 << (index & 7);
(lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
(lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
(lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
}
pos = -1;
}
}
}
}
for (x = 0; x < width; x++)
{
pos = -2;
for (y = 0; y < height; y++)
{
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
if (pos == -2)
{
if (filled[index >> 3] & (1 << (index & 7)))
pos = -1;
}
else if (pos == -1)
{
if (!(filled[index >> 3] & (1 << (index & 7))))
pos = y - 1;
}
else
{
if (filled[index >> 3] & (1 << (index & 7)))
{
bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
for (j = 0; j < (y - pos + 1) / 2; j++)
{
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos + j + 1)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
index = (ds->lightmapY + pos + j + 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
filled[index >> 3] |= 1 << (index & 7);
(lightFloats + k*3)[0] = (lightFloats + top*3)[0];
(lightFloats + k*3)[1] = (lightFloats + top*3)[1];
(lightFloats + k*3)[2] = (lightFloats + top*3)[2];
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y - j - 1)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
index = (ds->lightmapY + y - j - 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
filled[index >> 3] |= 1 << (index & 7);
(lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
(lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
(lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
}
pos = -1;
}
}
}
}
for (y = 0; y < height; y++)
{
foundvalue = qfalse;
for (x = 0; x < width; x++)
{
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
if (foundvalue)
{
if (filled[index >> 3] & (1 << (index & 7)))
{
ptr = lightFloats + k*3;
color[0] = ptr[0];
color[1] = ptr[1];
color[2] = ptr[2];
}
else
{
ptr = lightFloats + k*3;
ptr[0] = color[0];
ptr[1] = color[1];
ptr[2] = color[2];
filled[index >> 3] |= 1 << (index & 7);
}
}
else
{
if (filled[index >> 3] & (1 << (index & 7)))
{
ptr = lightFloats + k*3;
color[0] = ptr[0];
color[1] = ptr[1];
color[2] = ptr[2];
foundvalue = qtrue;
}
}
}
foundvalue = qfalse;
for (x = width-1; x >= 0; x--)
{
k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
* LIGHTMAP_WIDTH + ds->lightmapX + x;
index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
if (foundvalue)
{
if (filled[index >> 3] & (1 << (index & 7)))
{
ptr = lightFloats + k*3;
color[0] = ptr[0];
color[1] = ptr[1];
color[2] = ptr[2];
}
else
{
ptr = lightFloats + k*3;
ptr[0] = color[0];
ptr[1] = color[1];
ptr[2] = color[2];
filled[index >> 3] |= 1 << (index & 7);
}
}
else
{
if (filled[index >> 3] & (1 << (index & 7)))
{
ptr = lightFloats + k*3;
color[0] = ptr[0];
color[1] = ptr[1];
color[2] = ptr[2];
foundvalue = qtrue;
}
}
}
}
for (x = 0; x < width; x++)
{
foundvalue = qfalse
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -