📄 l_bsp_q2.c
字号:
int i, edgenum, side;
float dist, area;
q2_dplane_t plane;
vec_t *v1, *v2;
vec3_t normal, edgevec;
winding_t *w;
//
w = CopyWinding(winding);
memcpy(&plane, &q2_dplanes[face->planenum], sizeof(q2_dplane_t));
//check on which side of the plane the face is
if (face->side)
{
VectorNegate(plane.normal, plane.normal);
plane.dist = -plane.dist;
} //end if
for (i = 0; i < face->numedges && w; i++)
{
//get the first and second vertex of the edge
edgenum = q2_dsurfedges[face->firstedge + i];
side = edgenum > 0;
//if the face plane is flipped
v1 = q2_dvertexes[q2_dedges[abs(edgenum)].v[side]].point;
v2 = q2_dvertexes[q2_dedges[abs(edgenum)].v[!side]].point;
//create a plane through the edge vector, orthogonal to the face plane
//and with the normal vector pointing inward
VectorSubtract(v1, v2, edgevec);
CrossProduct(edgevec, plane.normal, normal);
VectorNormalize(normal);
dist = DotProduct(normal, v1);
//
ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
} //end for
if (w)
{
area = WindingArea(w);
FreeWinding(w);
return area;
} //end if
return 0;
} //end of the function Q2_FaceOnWinding
//===========================================================================
// creates a winding for the given brush side on the given brush
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
winding_t *Q2_BrushSideWinding(dbrush_t *brush, dbrushside_t *baseside)
{
int i;
dplane_t *baseplane, *plane;
winding_t *w;
dbrushside_t *side;
//create a winding for the brush side with the given planenumber
baseplane = &dplanes[baseside->planenum];
w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
for (i = 0; i < brush->numsides && w; i++)
{
side = &dbrushsides[brush->firstside + i];
//don't chop with the base plane
if (side->planenum == baseside->planenum) continue;
//also don't use planes that are almost equal
plane = &dplanes[side->planenum];
if (DotProduct(baseplane->normal, plane->normal) > 0.999
&& fabs(baseplane->dist - plane->dist) < 0.01) continue;
//
plane = &dplanes[side->planenum^1];
ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
} //end for
return w;
} //end of the function Q2_BrushSideWinding
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Q2_HintSkipBrush(dbrush_t *brush)
{
int j;
dbrushside_t *brushside;
for (j = 0; j < brush->numsides; j++)
{
brushside = &dbrushsides[brush->firstside + j];
if (brushside->texinfo > 0)
{
if (texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
{
return true;
} //end if
} //end if
} //end for
return false;
} //end of the function Q2_HintSkipBrush
//===========================================================================
// fix screwed brush texture references
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean WindingIsTiny(winding_t *w);
void Q2_FixTextureReferences(void)
{
int i, j, k, we;
dbrushside_t *brushside;
dbrush_t *brush;
dface_t *face;
winding_t *w;
memset(brushsidetextured, false, MAX_MAP_BRUSHSIDES);
//go over all the brushes
for (i = 0; i < numbrushes; i++)
{
brush = &dbrushes[i];
//hint brushes are not textured
if (Q2_HintSkipBrush(brush)) continue;
//go over all the sides of the brush
for (j = 0; j < brush->numsides; j++)
{
brushside = &dbrushsides[brush->firstside + j];
//
w = Q2_BrushSideWinding(brush, brushside);
if (!w)
{
brushsidetextured[brush->firstside + j] = true;
continue;
} //end if
else
{
//RemoveEqualPoints(w, 0.2);
if (WindingIsTiny(w))
{
FreeWinding(w);
brushsidetextured[brush->firstside + j] = true;
continue;
} //end if
else
{
we = WindingError(w);
if (we == WE_NOTENOUGHPOINTS
|| we == WE_SMALLAREA
|| we == WE_POINTBOGUSRANGE
// || we == WE_NONCONVEX
)
{
FreeWinding(w);
brushsidetextured[brush->firstside + j] = true;
continue;
} //end if
} //end else
} //end else
if (WindingArea(w) < 20)
{
brushsidetextured[brush->firstside + j] = true;
} //end if
//find a face for texturing this brush
for (k = 0; k < numfaces; k++)
{
face = &dfaces[k];
//if the face is in the same plane as the brush side
if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
//if the face is partly or totally on the brush side
if (Q2_FaceOnWinding(face, w))
{
brushside->texinfo = face->texinfo;
brushsidetextured[brush->firstside + j] = true;
break;
} //end if
} //end for
FreeWinding(w);
} //end for
} //end for
} //end of the function Q2_FixTextureReferences*/
//#endif //ME
/*
===============
CompressVis
===============
*/
int Q2_CompressVis (byte *vis, byte *dest)
{
int j;
int rep;
int visrow;
byte *dest_p;
dest_p = dest;
// visrow = (r_numvisleafs + 7)>>3;
visrow = (dvis->numclusters + 7)>>3;
for (j=0 ; j<visrow ; j++)
{
*dest_p++ = vis[j];
if (vis[j])
continue;
rep = 1;
for ( j++; j<visrow ; j++)
if (vis[j] || rep == 255)
break;
else
rep++;
*dest_p++ = rep;
j--;
}
return dest_p - dest;
}
/*
===================
DecompressVis
===================
*/
void Q2_DecompressVis (byte *in, byte *decompressed)
{
int c;
byte *out;
int row;
// row = (r_numvisleafs+7)>>3;
row = (dvis->numclusters+7)>>3;
out = decompressed;
do
{
if (*in)
{
*out++ = *in++;
continue;
}
c = in[1];
if (!c)
Error ("DecompressVis: 0 repeat");
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
}
//=============================================================================
/*
=============
SwapBSPFile
Byte swaps all data in a bsp file.
=============
*/
void Q2_SwapBSPFile (qboolean todisk)
{
int i, j;
dmodel_t *d;
// models
for (i=0 ; i<nummodels ; i++)
{
d = &dmodels[i];
d->firstface = LittleLong (d->firstface);
d->numfaces = LittleLong (d->numfaces);
d->headnode = LittleLong (d->headnode);
for (j=0 ; j<3 ; j++)
{
d->mins[j] = LittleFloat(d->mins[j]);
d->maxs[j] = LittleFloat(d->maxs[j]);
d->origin[j] = LittleFloat(d->origin[j]);
}
}
//
// vertexes
//
for (i=0 ; i<numvertexes ; i++)
{
for (j=0 ; j<3 ; j++)
dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
}
//
// planes
//
for (i=0 ; i<numplanes ; i++)
{
for (j=0 ; j<3 ; j++)
dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
dplanes[i].dist = LittleFloat (dplanes[i].dist);
dplanes[i].type = LittleLong (dplanes[i].type);
}
//
// texinfos
//
for (i=0 ; i<numtexinfo ; i++)
{
for (j=0 ; j<8 ; j++)
texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
texinfo[i].flags = LittleLong (texinfo[i].flags);
texinfo[i].value = LittleLong (texinfo[i].value);
texinfo[i].nexttexinfo = LittleLong (texinfo[i].nexttexinfo);
}
//
// faces
//
for (i=0 ; i<numfaces ; i++)
{
dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
dfaces[i].planenum = LittleShort (dfaces[i].planenum);
dfaces[i].side = LittleShort (dfaces[i].side);
dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
dfaces[i].numedges = LittleShort (dfaces[i].numedges);
}
//
// nodes
//
for (i=0 ; i<numnodes ; i++)
{
dnodes[i].planenum = LittleLong (dnodes[i].planenum);
for (j=0 ; j<3 ; j++)
{
dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
}
dnodes[i].children[0] = LittleLong (dnodes[i].children[0]);
dnodes[i].children[1] = LittleLong (dnodes[i].children[1]);
dnodes[i].firstface = LittleShort (dnodes[i].firstface);
dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
}
//
// leafs
//
for (i=0 ; i<numleafs ; i++)
{
dleafs[i].contents = LittleLong (dleafs[i].contents);
dleafs[i].cluster = LittleShort (dleafs[i].cluster);
dleafs[i].area = LittleShort (dleafs[i].area);
for (j=0 ; j<3 ; j++)
{
dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
}
dleafs[i].firstleafface = LittleShort (dleafs[i].firstleafface);
dleafs[i].numleaffaces = LittleShort (dleafs[i].numleaffaces);
dleafs[i].firstleafbrush = LittleShort (dleafs[i].firstleafbrush);
dleafs[i].numleafbrushes = LittleShort (dleafs[i].numleafbrushes);
}
//
// leaffaces
//
for (i=0 ; i<numleaffaces ; i++)
dleaffaces[i] = LittleShort (dleaffaces[i]);
//
// leafbrushes
//
for (i=0 ; i<numleafbrushes ; i++)
dleafbrushes[i] = LittleShort (dleafbrushes[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -