📄 model_common.c
字号:
void Mod_ProcessLeafs (dleaf_t *in, int filelen); // 2001-12-28 .VIS support by Maddes
/*
=================
Mod_LoadLeafs
=================
*/
void Mod_LoadLeafs (lump_t *l)
{
dleaf_t *in;
// 2001-12-28 .VIS support by Maddes start
/*
mleaf_t *out;
int i, j, count, p;
*/
// 2001-12-28 .VIS support by Maddes end
in = (void *)(mod_base + l->fileofs);
// 2001-12-28 .VIS support by Maddes start
/*
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
*/
Mod_ProcessLeafs (in, l->filelen);
}
void Mod_ProcessLeafs (dleaf_t *in, int filelen)
{
mleaf_t *out;
int i, j, count, p;
if (filelen % sizeof(*in))
Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name);
count = filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), "USE_LEAF");
// 2001-12-28 .VIS support by Maddes end
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->firstmarksurface = loadmodel->marksurfaces +
LittleShort(in->firstmarksurface);
out->nummarksurfaces = LittleShort(in->nummarksurfaces);
p = LittleLong(in->visofs);
if (p == -1)
out->compressed_vis = NULL;
else
out->compressed_vis = loadmodel->visdata + p;
out->efrags = NULL;
for (j=0 ; j<4 ; j++)
out->ambient_sound_level[j] = in->ambient_level[j];
#ifdef GLQUAKE
// gl underwater warp
if (out->contents != CONTENTS_EMPTY)
{
for (j=0 ; j<out->nummarksurfaces ; j++)
out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
}
#endif
}
}
/*
=================
Mod_LoadClipnodes
=================
*/
void Mod_LoadClipnodes (lump_t *l)
{
dclipnode_t *in, *out;
int i, count;
hull_t *hull;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->clipnodes = out;
loadmodel->numclipnodes = count;
hull = &loadmodel->hulls[1];
hull->clipnodes = out;
hull->firstclipnode = 0;
hull->lastclipnode = count-1;
hull->planes = loadmodel->planes;
hull->clip_mins[0] = -16;
hull->clip_mins[1] = -16;
hull->clip_mins[2] = -24;
hull->clip_maxs[0] = 16;
hull->clip_maxs[1] = 16;
hull->clip_maxs[2] = 32;
hull = &loadmodel->hulls[2];
hull->clipnodes = out;
hull->firstclipnode = 0;
hull->lastclipnode = count-1;
hull->planes = loadmodel->planes;
hull->clip_mins[0] = -32;
hull->clip_mins[1] = -32;
hull->clip_mins[2] = -24;
hull->clip_maxs[0] = 32;
hull->clip_maxs[1] = 32;
hull->clip_maxs[2] = 64;
for (i=0 ; i<count ; i++, out++, in++)
{
out->planenum = LittleLong(in->planenum);
out->children[0] = LittleShort(in->children[0]);
out->children[1] = LittleShort(in->children[1]);
}
}
/*
=================
Mod_MakeHull0
Deplicate the drawing hull structure as a clipping hull
=================
*/
void Mod_MakeHull0 (void)
{
mnode_t *in, *child;
dclipnode_t *out;
int i, j, count;
hull_t *hull;
hull = &loadmodel->hulls[0];
in = loadmodel->nodes;
count = loadmodel->numnodes;
out = Hunk_AllocName ( count*sizeof(*out), loadname);
hull->clipnodes = out;
hull->firstclipnode = 0;
hull->lastclipnode = count-1;
hull->planes = loadmodel->planes;
for (i=0 ; i<count ; i++, out++, in++)
{
out->planenum = in->plane - loadmodel->planes;
for (j=0 ; j<2 ; j++)
{
child = in->children[j];
if (child->contents < 0)
out->children[j] = child->contents;
else
out->children[j] = child - loadmodel->nodes;
}
}
}
/*
=================
Mod_LoadMarksurfaces
=================
*/
void Mod_LoadMarksurfaces (lump_t *l)
{
int i, j, count;
short *in;
msurface_t **out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
for ( i=0 ; i<count ; i++)
{
j = LittleShort(in[i]);
if (j >= loadmodel->numsurfaces)
Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
out[i] = loadmodel->surfaces + j;
}
}
/*
=================
Mod_LoadSurfedges
=================
*/
void Mod_LoadSurfedges (lump_t *l)
{
int i, count;
int *in, *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->surfedges = out;
loadmodel->numsurfedges = count;
for ( i=0 ; i<count ; i++)
out[i] = LittleLong (in[i]);
}
/*
=================
Mod_LoadPlanes
=================
*/
void Mod_LoadPlanes (lump_t *l)
{
int i, j;
mplane_t *out;
dplane_t *in;
int count;
int bits;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*2*sizeof(*out), loadname);
loadmodel->planes = out;
loadmodel->numplanes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
bits = 0;
for (j=0 ; j<3 ; j++)
{
out->normal[j] = LittleFloat (in->normal[j]);
if (out->normal[j] < 0)
bits |= 1<<j;
}
out->dist = LittleFloat (in->dist);
out->type = LittleLong (in->type);
out->signbits = bits;
}
}
/*
=================
RadiusFromBounds
=================
*/
float RadiusFromBounds (vec3_t mins, vec3_t maxs)
{
int i;
vec3_t corner;
for (i=0 ; i<3 ; i++)
{
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
}
return Length (corner);
}
// 2001-12-28 .VIS support by Maddes start
/*
=================
Mod_LoadExternalVisibility
=================
*/
void Mod_LoadExternalVisibility (int fhandle)
{
long filelen;
// get visibility data length
filelen = 0;
Sys_FileRead (fhandle, &filelen, 4);
filelen = LittleLong(filelen);
Con_Printf("...%i bytes visibility data\n", filelen);
// load visibility data
if (!filelen)
{
loadmodel->visdata = NULL;
return;
}
loadmodel->visdata = Hunk_AllocName ( filelen, "EXT_VIS");
Sys_FileRead (fhandle, loadmodel->visdata, filelen);
}
/*
=================
Mod_LoadExternalLeafs
=================
*/
void Mod_LoadExternalLeafs (int fhandle)
{
dleaf_t *in;
long filelen;
// get leaf data length
filelen = 0;
Sys_FileRead (fhandle, &filelen, 4);
filelen = LittleLong(filelen);
Con_Printf("...%i bytes leaf data\n", filelen);
// load leaf data
if (!filelen)
{
loadmodel->leafs = NULL;
loadmodel->numleafs = 0;
return;
}
in = Hunk_AllocName (filelen, "EXT_LEAF");
Sys_FileRead (fhandle, in, filelen);
Mod_ProcessLeafs (in, filelen);
}
int Mod_FindExternalVIS (loadedfile_t *brush_fileinfo)
{
char visfilename[1024];
int fhandle;
int len, i, pos;
searchpath_t *s_vis;
vispatch_t header;
char mapname[VISPATCH_MAPNAME_LENGTH+5]; // + ".vis" + EoS
fhandle = -1;
if (external_vis->value)
{
// check for a .VIS file
strcpy(visfilename, loadmodel->name);
COM_StripExtension(visfilename, visfilename);
strcat(visfilename, ".vis");
len = COM_OpenFile (visfilename, &fhandle, &s_vis);
if (fhandle == -1) // check for a .VIS file with map's directory name (e.g. ID1.VIS)
{
strcpy(visfilename, "maps/");
strcat(visfilename, COM_SkipPath(brush_fileinfo->path->filename));
strcat(visfilename, ".vis");
len = COM_OpenFile (visfilename, &fhandle, &s_vis);
}
if (fhandle >= 0)
{
// check file for size
if (len <= 0)
{
COM_CloseFile(fhandle);
fhandle = -1;
}
}
if (fhandle >= 0)
{
// search map in visfile
strncpy(mapname, loadname, VISPATCH_MAPNAME_LENGTH);
mapname[VISPATCH_MAPNAME_LENGTH] = 0;
strcat(mapname, ".bsp");
pos = 0;
while ((i = Sys_FileRead (fhandle, &header, sizeof(struct vispatch_s))) == sizeof(struct vispatch_s))
{
header.filelen = LittleLong(header.filelen);
pos += i;
if (!Q_strncasecmp (header.mapname, mapname, VISPATCH_MAPNAME_LENGTH)) // found
{
break;
}
pos += header.filelen;
Sys_FileSeek(fhandle, pos);
}
if (i != sizeof(struct vispatch_s))
{
COM_CloseFile(fhandle);
fhandle = -1;
}
}
if (fhandle >= 0)
{
Con_Printf("%s for %s loaded from %s\n", visfilename, mapname, s_vis->pack ? s_vis->pack->filename : s_vis->filename);
}
}
return fhandle;
}
// 2001-12-28 .VIS support by Maddes end
/*
=================
Mod_LoadBrushModel
=================
*/
void Mod_LoadBrushModel (model_t *mod, void *buffer, loadedfile_t *brush_fileinfo) // 2001-09-12 .ENT support by Maddes
{
int i, j;
dheader_t *header;
dmodel_t *bm;
int fhandle; // 2001-12-28 .VIS support by Maddes
loadmodel->type = mod_brush;
header = (dheader_t *)buffer;
i = LittleLong (header->version);
if (i != BSPVERSION)
// 2001-12-16 No crash on wrong BSP version by MrG start
// Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
{
Con_Printf("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
mod->numvertexes=-1; // HACK - incorrect BSP version is no longer fatal
return;
}
// 2001-12-16 No crash on wrong BSP version by MrG end
// swap all the lumps
mod_base = (byte *)header;
for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
// load into heap
Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
Mod_LoadFaces (&header->lumps[LUMP_FACES]);
Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
// 2001-12-28 .VIS support by Maddes start
loadmodel->visdata = NULL;
loadmodel->leafs = NULL;
loadmodel->numleafs = 0;
fhandle = Mod_FindExternalVIS (brush_fileinfo);
if (fhandle >= 0)
{
Mod_LoadExternalVisibility (fhandle);
Mod_LoadExternalLeafs (fhandle);
}
if ((loadmodel->visdata == NULL)
|| (loadmodel->leafs == NULL)
|| (loadmodel->numleafs == 0))
{
if (fhandle >= 0)
{
Con_Printf("External VIS data are invalid!!!\n");
}
// 2001-12-28 .VIS support by Maddes end
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
// 2001-12-28 .VIS support by Maddes start
}
if (fhandle >= 0)
{
COM_CloseFile(fhandle);
}
// 2001-12-28 .VIS support by Maddes end
Mod_LoadNodes (&header->lumps[LUMP_NODES]);
Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
Mod_LoadEntities (&header->lumps[LUMP_ENTITIES], brush_fileinfo); // 2001-09-12 .ENT support by Maddes
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
Mod_MakeHull0 ();
mod->numframes = 2; // regular and alternate animation
#ifndef GLQUAKE
mod->flags = 0;
#endif
//
// set up the submodels (FIXME: this is confusing)
//
for (i=0 ; i<mod->numsubmodels ; i++)
{
bm = &mod->submodels[i];
mod->hulls[0].firstclipnode = bm->headnode[0];
for (j=1 ; j<MAX_MAP_HULLS ; j++)
{
mod->hulls[j].firstclipnode = bm->headnode[j];
mod->hulls[j].lastclipnode = mod->numclipnodes-1;
}
mod->firstmodelsurface = bm->firstface;
mod->nummodelsurfaces = bm->numfaces;
VectorCopy (bm->maxs, mod->maxs);
VectorCopy (bm->mins, mod->mins);
mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
mod->numleafs = bm->visleafs;
if (i < mod->numsubmodels-1)
{ // duplicate the basic information
char name[10];
sprintf (name, "*%i", i+1);
loadmodel = Mod_FindName (name);
*loadmodel = *mod;
strcpy (loadmodel->name, name);
mod = loadmodel;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -