📄 lightv.c
字号:
{
VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[0]);
VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[0]);
VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[1]);
VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[1]);
VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[2]);
VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[2]);
VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[3]);
VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[3]);
w.numpoints = 4;
}
DebugNet_DrawWinding(&w, color);
}
/*
============
VL_DrawPortals
============
*/
void VL_DrawPortals(void)
{
int j;
lportal_t *p;
for (j = 0; j < numportals * 2; j++)
{
p = portals + j;
DebugNet_DrawWinding(p->winding, 1);
}
}
/*
============
VL_DrawLeaf
============
*/
void VL_DrawLeaf(int cluster)
{
int i;
lleaf_t *leaf;
lportal_t *p;
leaf = &leafs[cluster];
for (i = 0; i < leaf->numportals; i++)
{
p = leaf->portals[i];
DebugNet_DrawWinding(p->winding, 1);
}
}
#endif //DEBUGNET
/*
=============
VL_SplitWinding
=============
*/
int VL_SplitWinding (winding_t *in, winding_t *back, 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;
back->numpoints = 0;
for (i=0 ; i<in->numpoints ; i++)
{
p1 = in->points[i];
if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
{
_printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
return SIDE_FRONT; // can't chop -- fall back to original
}
if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
{
_printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
return SIDE_FRONT;
}
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, neww->points[neww->numpoints]);
neww->numpoints++;
VectorCopy (p1, back->points[back->numpoints]);
back->numpoints++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, neww->points[neww->numpoints]);
neww->numpoints++;
}
if (sides[i] == SIDE_BACK)
{
VectorCopy (p1, back->points[back->numpoints]);
back->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
{
_printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
return SIDE_FRONT; // can't chop -- fall back to original
}
if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
{
_printf("WARNING: VL_SplitWinding -> 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++;
VectorCopy (mid, back->points[back->numpoints]);
back->numpoints++;
}
memcpy(in, &out, sizeof(winding_t));
return SIDE_CROSS;
}
/*
=====================
VL_LinkSurfaceIntoCluster
=====================
*/
void VL_LinkSurfaceIntoCluster(int cluster, int surfaceNum)
{
lleaf_t *leaf;
int i;
leaf = &leafs[cluster];
for (i = 0; i < leaf->numSurfaces; i++)
{
if (clustersurfaces[leaf->firstSurface + i] == surfaceNum)
return;
}
for (i = numclustersurfaces; i > leaf->firstSurface + leaf->numSurfaces; i--)
clustersurfaces[i] = clustersurfaces[i-1];
for (i = 0; i < portalclusters; i++)
{
if (i == cluster)
continue;
if (leafs[i].firstSurface >= leaf->firstSurface + leaf->numSurfaces)
leafs[i].firstSurface++;
}
clustersurfaces[leaf->firstSurface + leaf->numSurfaces] = surfaceNum;
leaf->numSurfaces++;
numclustersurfaces++;
if (numclustersurfaces >= MAX_MAP_LEAFFACES)
Error("MAX_MAP_LEAFFACES");
}
/*
=====================
VL_R_LinkSurface
=====================
*/
void VL_R_LinkSurface(int nodenum, int surfaceNum, winding_t *w)
{
int leafnum, cluster, res;
dnode_t *node;
dplane_t *plane;
winding_t back;
plane_t split;
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)
{
memcpy(&back, w, sizeof(winding_t));
VL_R_LinkSurface(node->children[1], surfaceNum, &back);
nodenum = node->children[0];
}
else
{
VL_R_LinkSurface(node->children[1], surfaceNum, &back);
nodenum = node->children[0];
}
}
leafnum = -nodenum - 1;
cluster = dleafs[leafnum].cluster;
if (cluster != -1)
{
VL_LinkSurfaceIntoCluster(cluster, surfaceNum);
}
}
/*
=====================
VL_LinkSurfaces
maybe link each facet seperately instead of the test surfaces?
=====================
*/
void VL_LinkSurfaces(void)
{
int i, j;
lsurfaceTest_t *test;
lFacet_t *facet;
winding_t winding;
for ( i = 0 ; i < numDrawSurfaces ; i++ )
{
test = lsurfaceTest[ i ];
if (!test)
continue;
for (j = 0; j < test->numFacets; j++)
{
facet = &test->facets[j];
memcpy(winding.points, facet->points, facet->numpoints * sizeof(vec3_t));
winding.numpoints = facet->numpoints;
VL_R_LinkSurface(0, i, &winding);
}
}
}
/*
=====================
VL_TextureMatrixFromPoints
=====================
*/
void VL_TextureMatrixFromPoints( lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
int i, j;
float t;
float m[3][4];
float s;
// This is an incredibly stupid way of solving a three variable equation
for ( i = 0 ; i < 2 ; i++ ) {
m[0][0] = a->xyz[0];
m[0][1] = a->xyz[1];
m[0][2] = a->xyz[2];
m[0][3] = a->st[i];
m[1][0] = b->xyz[0];
m[1][1] = b->xyz[1];
m[1][2] = b->xyz[2];
m[1][3] = b->st[i];
m[2][0] = c->xyz[0];
m[2][1] = c->xyz[1];
m[2][2] = c->xyz[2];
m[2][3] = c->st[i];
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;
}
}
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;
}
}
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[1][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;
s = 1.0 / m[2][2];
m[2][0] *= s;
m[2][1] *= s;
m[2][2] *= s;
m[2][3] *= s;
f->textureMatrix[i][2] = m[2][3];
f->textureMatrix[i][1] = m[1][3] - f->textureMatrix[i][2] * m[1][2];
f->textureMatrix[i][0] = m[0][3] - f->textureMatrix[i][2] * m[0][2] - f->textureMatrix[i][1] * m[0][1];
f->textureMatrix[i][3] = 0;
/*
s = fabs( DotProduct( a->xyz, f->textureMatrix[i] ) - a->st[i] );
if ( s > 0.01 ) {
Error( "Bad textureMatrix" );
}
s = fabs( DotProduct( b->xyz, f->textureMatrix[i] ) - b->st[i] );
if ( s > 0.01 ) {
Error( "Bad textureMatrix" );
}
s = fabs( DotProduct( c->xyz, f->textureMatrix[i] ) - c->st[i] );
if ( s > 0.01 ) {
Error( "Bad textureMatrix" );
}
*/
}
}
/*
=====================
VL_LightmapMatrixFromPoints
=====================
*/
void VL_LightmapMatrixFromPoints( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
int i, j;
float t;
float m[3][4], al, bl, cl;
float s;
int h, w, ssize;
vec3_t mins, maxs, delta, size, planeNormal;
drawVert_t *verts;
static int message;
// vertex-lit triangle model
if ( dsurf->surfaceType == MST_TRIANGLE_SOUP ) {
return;
}
if ( dsurf->lightmapNum < 0 ) {
return; // doesn't need lighting
}
VectorClear(f->mins);
if (dsurf->surfaceType != MST_PATCH)
{
ssize = samplesize;
if (si->lightmapSampleSize)
ssize = si->lightmapSampleSize;
ClearBounds( mins, maxs );
verts = &drawVerts[dsurf->firstVert];
for ( i = 0 ; i < dsurf->numVerts ; i++ ) {
AddPointToBounds( verts[i].xyz, mins, maxs );
}
// round to the lightmap resolution
for ( i = 0 ; i < 3 ; i++ ) {
mins[i] = ssize * floor( mins[i] / ssize );
maxs[i] = ssize * ceil( maxs[i] / ssize );
f->mins[i] = mins[i];
size[i] = (maxs[i] - mins[i]) / ssize + 1;
}
// the two largest axis will be the lightmap size
VectorClear(f->lightmapMatrix[0]);
f->lightmapMatrix[0][3] = 0;
VectorClear(f->lightmapMatrix[1]);
f->lightmapMatrix[1][3] = 0;
planeNormal[0] = fabs( dsurf->lightmapVecs[2][0] );
planeNormal[1] = fabs( dsurf->lightmapVecs[2][1] );
planeNormal[2] = fabs( dsurf->lightmapVecs[2][2] );
if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
w = size[1];
h = size[2];
f->lightmapMatrix[0][1] = 1.0 / ssize;
f->lightmapMatrix[1][2] = 1.0 / ssize;
} else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
w = size[0];
h = size[2];
f->lightmapMatrix[0][0] = 1.0 / ssize;
f->lightmapMatrix[1][2] = 1.0 / ssize;
} else {
w = size[0];
h = size[1];
f->lightmapMatrix[0][0] = 1.0 / ssize;
f->lightmapMatrix[1][1] = 1.0 / ssize;
}
if ( w > LIGHTMAP_WIDTH ) {
VectorScale ( f->lightmapMatrix[0], (float)LIGHTMAP_SIZE/w, f->lightmapMatrix[0] );
}
if ( h > LIGHTMAP_HEIGHT ) {
VectorScale ( f->lightmapMatrix[1], (float)LIGHTMAP_SIZE/h, f->lightmapMatrix[1] );
}
VectorSubtract(a->xyz, f->mins, delta);
s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
if ( fabs(s - a->lightmap[0]) > 0.01 ) {
_printf( "Bad lightmapMatrix" );
}
t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -