📄 gl_model.cpp
字号:
/*
=================
Mod_LoadVisibility
=================
*/
void Mod_LoadVisibility( model_t *loadmodel, lump_t *l )
{
int i;
if (!l->filelen)
{
loadmodel->vis = NULL;
return;
}
loadmodel->vis = (dvis_t *)engine.MemAlloc( l->filelen );
memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
for (i=0 ; i<loadmodel->vis->numclusters ; i++)
{
loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
}
}
/*
=================
Mod_LoadVertexes
=================
*/
void Mod_LoadVertexes( model_t *loadmodel, lump_t *l )
{
dvertex_t *in;
mvertex_t *out;
int i, count;
in = (dvertex_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mvertex_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->vertexes = out;
loadmodel->numvertexes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->position[0] = LittleFloat (in->point[0]);
out->position[1] = LittleFloat (in->point[1]);
out->position[2] = LittleFloat (in->point[2]);
}
}
/*
=================
RadiusFromBounds
=================
*/
float RadiusFromBounds (Vector& mins, Vector& maxs)
{
int i;
Vector corner;
for (i=0 ; i<3 ; i++)
{
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
}
return VectorLength (corner);
}
/*
=================
Mod_LoadSubmodels
=================
*/
void Mod_LoadSubmodels( model_t *loadmodel, lump_t *l )
{
dmodel_t *in;
mmodel_t *out;
int i, j, count;
in = (dmodel_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mmodel_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->submodels = out;
loadmodel->numsubmodels = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{ // spread the mins / maxs by a pixel
out->mins[j] = LittleFloat (in->mins[j]) - 1;
out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
out->origin[j] = LittleFloat (in->origin[j]);
}
out->radius = RadiusFromBounds (out->mins, out->maxs);
out->headnode = LittleLong (in->headnode);
out->firstface = LittleLong (in->firstface);
out->numfaces = LittleLong (in->numfaces);
}
}
/*
=================
Mod_LoadEdges
=================
*/
void Mod_LoadEdges (model_t *loadmodel, lump_t *l)
{
dedge_t *in;
medge_t *out;
int i, count;
in = (dedge_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (medge_t *)engine.MemAlloc( (count + 1) * sizeof(*out));
loadmodel->edges = out;
loadmodel->numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->v[0] = (unsigned short)LittleShort(in->v[0]);
out->v[1] = (unsigned short)LittleShort(in->v[1]);
}
}
/*
=================
Mod_LoadTexdata
=================
*/
void Mod_LoadTexdata (model_t *loadmodel, lump_t *l)
{
dtexdata_t *in;
mtexdata_t *out;
int i, count;
in = (dtexdata_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mtexdata_t *)engine.MemAlloc( count*sizeof(*out));
loadmodel->texdata = out;
loadmodel->numtexdata = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
strcpy( out->name, in->name );
}
}
/*
=================
Mod_LoadTexinfo
=================
*/
void Mod_LoadTexinfo (model_t *loadmodel, lump_t *l)
{
texinfo_t *in;
mtexinfo_t *out;
int i, j, count;
in = (texinfo_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mtexinfo_t *)engine.MemAlloc( count*sizeof(*out));
loadmodel->texinfo = out;
loadmodel->numtexinfo = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<8 ; j++)
{
out->textureVecsTexelsPerWorldUnits[0][j] = LittleFloat (in->textureVecsTexelsPerWorldUnits[0][j]);
out->lightmapVecsLuxelsPerWorldUnits[0][j] = LittleFloat (in->lightmapVecsLuxelsPerWorldUnits[0][j]);
}
out->flags = LittleLong (in->flags);
out->image = GL_LoadImage( loadmodel->texdata[ in->texdata ].name );
if ( !out->image )
{
out->image = GL_EmptyTexture();
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Mod_LoadDispInfo( model_t *pModel, lump_t *pLump )
{
// don't deal with displacement maps currently
return;
}
/*
================
CalcSurfaceExtents
Fills in s->texturemins[] and s->extents[]
================
*/
void CalcSurfaceExtents (model_t *loadmodel, msurface_t *s)
{
float lightmapMins[2], lightmapMaxs[2];
float textureMins[2], textureMaxs[2], val;
int i,j, e;
mvertex_t *v;
mtexinfo_t *tex;
int bmins[2], bmaxs[2];
lightmapMins[0] = lightmapMins[1] = 999999;
lightmapMaxs[0] = lightmapMaxs[1] = -99999;
textureMins[0] = textureMins[1] = 999999;
textureMaxs[0] = textureMaxs[1] = -99999;
tex = s->texinfo;
for (i=0 ; i<s->numedges ; i++)
{
e = loadmodel->surfedges[s->firstedge+i];
if (e >= 0)
v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
else
v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
for (j=0 ; j<2 ; j++)
{
val = v->position[0] * tex->lightmapVecsLuxelsPerWorldUnits[j][0] +
v->position[1] * tex->lightmapVecsLuxelsPerWorldUnits[j][1] +
v->position[2] * tex->lightmapVecsLuxelsPerWorldUnits[j][2] +
tex->lightmapVecsLuxelsPerWorldUnits[j][3];
if (val < lightmapMins[j])
lightmapMins[j] = val;
if (val > lightmapMaxs[j])
lightmapMaxs[j] = val;
val = v->position[0] * tex->textureVecsTexelsPerWorldUnits[j][0] +
v->position[1] * tex->textureVecsTexelsPerWorldUnits[j][1] +
v->position[2] * tex->textureVecsTexelsPerWorldUnits[j][2] +
tex->textureVecsTexelsPerWorldUnits[j][3];
if (val < textureMins[j])
textureMins[j] = val;
if (val > textureMaxs[j])
textureMaxs[j] = val;
}
}
for (i=0 ; i<2 ; i++)
{
bmins[i] = floor( lightmapMins[i] );
bmaxs[i] = ceil( lightmapMaxs[i] );
s->lightmapMins[i] = bmins[i];
s->lightmapExtents[i] = ( bmaxs[i] - bmins[i] );
bmins[i] = floor( textureMins[i] );
bmaxs[i] = ceil( textureMaxs[i] );
s->textureMins[i] = bmins[i];
s->textureExtents[i] = ( bmaxs[i] - bmins[i] );
#if 0
if ( !(tex->flags & TEX_SPECIAL) && s->lightmapExtents[i] > MAX_LIGHTMAP_DIM_INCLUDING_BORDER )
{
Sys_Error ("Bad surface extents on texture %s", tex->material->GetName() );
}
#endif
}
}
void GL_BuildPolygonFromSurface(msurface_t *fa);
void GL_CreateSurfaceLightmap (msurface_t *surf);
void GL_EndBuildingLightmaps (void);
void GL_BeginBuildingLightmaps (model_t *m);
/*
=================
Mod_LoadFaces
=================
*/
void Mod_LoadFaces( model_t *loadmodel, lump_t *l )
{
dface_t *in;
msurface_t *out;
int i, count, surfnum;
int planenum;
int ti;
in = (dface_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (msurface_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
{
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
out->flags = 0;
// out->polys = NULL;
planenum = (unsigned short)LittleShort(in->planenum);
if ( in->onNode )
out->flags |= SURFDRAW_NODE;
out->plane = loadmodel->planes + planenum;
ti = LittleShort (in->texinfo);
if (ti < 0 || ti >= loadmodel->numtexinfo)
engine.Error ("MOD_LoadBmodel: bad texinfo number");
out->texinfo = loadmodel->texinfo + ti;
CalcSurfaceExtents (loadmodel, out);
// lighting info
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
out->samples = NULL;
else
out->samples = (colorRGBExp32 *)( ((byte *)loadmodel->lightdata) + i );
// set the drawing flags flag
if ( out->texinfo->flags & SURF_NOLIGHT )
{
out->flags |= SURFDRAW_NOLIGHT;
}
// skip these faces
if ( out->texinfo->flags & SURF_NODRAW )
{
out->flags |= SURFDRAW_NODRAW;
}
#ifdef STATIC_FOG
// UNDONE: Mark these faces somehow and fix this hack
if ( out->texinfo->image->name[0] == '%' )
{
out->flags |= ( SURFDRAW_FOG );
}
#endif
if ( out->texinfo->flags & SURF_WARP )
{
out->flags |= SURFDRAW_TURB;
}
if ( out->texinfo->flags & SURF_SKY )
{
out->flags |= SURFDRAW_SKY;
// R_InitSky();
}
}
}
/*
=================
Mod_SetParent
=================
*/
void Mod_SetParent (mnode_t *node, mnode_t *parent)
{
node->parent = parent;
if (node->contents != -1)
return;
Mod_SetParent (node->children[0], node);
Mod_SetParent (node->children[1], node);
}
/*
=================
Mod_LoadNodes
=================
*/
void Mod_LoadNodes( model_t *loadmodel, lump_t *l )
{
int i, j, count, p;
dnode_t *in;
mnode_t *out;
in = (dnode_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mnode_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->nodes = out;
loadmodel->numnodes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->mins[j] = LittleShort (in->mins[j]);
out->maxs[j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
out->firstsurface = (unsigned short)LittleShort (in->firstface);
out->numsurfaces = (unsigned short)LittleShort (in->numfaces);
out->contents = -1; // differentiate from leafs
for (j=0 ; j<2 ; j++)
{
p = LittleLong (in->children[j]);
if (p >= 0)
out->children[j] = loadmodel->nodes + p;
else
out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
}
}
Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
}
/*
=================
Mod_LoadLeafs
=================
*/
void Mod_LoadLeafs( model_t *loadmodel, lump_t *l )
{
dleaf_t *in;
mleaf_t *out;
int i, j, count, p;
// glpoly_t *poly;
in = (dleaf_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mleaf_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->mins[j] = LittleShort (in->mins[j]);
out->maxs[j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->cluster = LittleShort(in->cluster);
out->area = LittleShort(in->area);
out->firstmarksurface = loadmodel->marksurfaces +
(unsigned short)LittleShort(in->firstleafface);
out->nummarksurfaces = (unsigned short)LittleShort(in->numleaffaces);
out->parent = NULL;
// gl underwater warp
#if 0
if (out->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_THINWATER) )
{
for (j=0 ; j<out->nummarksurfaces ; j++)
{
out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
for (poly = out->firstmarksurface[j]->polys ; poly ; poly=poly->next)
poly->flags |= SURF_UNDERWATER;
}
}
#endif
}
}
/*
=================
Mod_LoadMarksurfaces
=================
*/
void Mod_LoadMarksurfaces( model_t *loadmodel, lump_t *l )
{
int i, j, count;
short *in;
msurface_t **out;
in = (short *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (msurface_t **)engine.MemAlloc( count*sizeof(*out) );
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
for ( i=0 ; i<count ; i++)
{
j = (unsigned short)LittleShort(in[i]);
if (j < 0 || j >= loadmodel->numsurfaces)
engine.Error ("Mod_ParseMarksurfaces: bad surface number");
out[i] = loadmodel->surfaces + j;
}
}
/*
=================
Mod_LoadSurfedges
=================
*/
void Mod_LoadSurfedges( model_t *loadmodel, lump_t *l )
{
int i, count;
int *in, *out;
in = (int *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
if (count < 1 || count >= MAX_MAP_SURFEDGES)
engine.Error ("MOD_LoadBmodel: bad surfedges count in %s: %i",
loadmodel->name, count);
out = (int *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->surfedges = out;
loadmodel->numsurfedges = count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -