⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gl_model.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	for ( i=0 ; i<count ; i++)
		out[i] = LittleLong (in[i]);
}


/*
=================
Mod_LoadPlanes
=================
*/
void Mod_LoadPlanes( model_t *loadmodel, lump_t *l )
{
	int			i, j;
	cplane_t	*out;
	dplane_t 	*in;
	int			count;
	int			bits;
	
	in = (dplane_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 = (cplane_t *)engine.MemAlloc( count*2*sizeof(*out) );
	
	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;
	}
}


//-----------------------------------------------------------------------------
// Purpose: Loads the vertex index list for all portals
// Input  : *loadmodel - 
//			*l - 
//-----------------------------------------------------------------------------
void Mod_LoadPortalVerts( model_t *loadmodel, lump_t *l )
{
	int			i;
	unsigned short	*out;
	unsigned short	*in;
	int			count;
	
	in = (unsigned 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 = (unsigned short *)engine.MemAlloc( count*sizeof(*out) );
	
	loadmodel->portalverts = out;
	loadmodel->numportalverts = count;

	for ( i = 0; i < count; i++, in++, out++ )
	{
		*out = (unsigned short)LittleShort( *in );
	}
}

//-----------------------------------------------------------------------------
// Purpose: loads the portal index list for all clusters
// Input  : *loadmodel - 
//			*l - 
//-----------------------------------------------------------------------------
void Mod_LoadClusterPortals( model_t *loadmodel, lump_t *l )
{
	int			i;
	unsigned short	*out;
	unsigned short	*in;
	int			count;
	
	in = (unsigned 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 = (unsigned short *)engine.MemAlloc( count*sizeof(*out) );
	
	loadmodel->clusterportals = out;
	loadmodel->numclusterportals = count;

	for ( i = 0; i < count; i++, in++, out++ )
	{
		*out = (unsigned short)LittleShort( *in );
	}
}


//-----------------------------------------------------------------------------
// Purpose: Loads the data for each clusters (points to portal list)
// Input  : *loadmodel - 
//			*l - 
//-----------------------------------------------------------------------------
void Mod_LoadClusters( model_t *loadmodel, lump_t *l )
{
	int			i;
	mcluster_t	*out;
	dcluster_t	*in;
	int			count;
	
	in = (dcluster_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 = (mcluster_t *)engine.MemAlloc( count*sizeof(*out) );
	
	loadmodel->clusters = out;
	loadmodel->numclusters = count;

	for ( i = 0; i < count; i++, in++, out++ )
	{
		out->numportals = LittleLong( in->numportals );
		out->portalList = loadmodel->clusterportals + LittleLong( in->firstportal );
	}
}
	
void Mod_LoadPortals( model_t *loadmodel, lump_t *l )
{
	int			i;
	mportal_t	*out;
	dportal_t	*in;
	int			count;
	
	in = (dportal_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 = (mportal_t *)engine.MemAlloc( count*sizeof(*out) );
	
	loadmodel->portals = out;
	loadmodel->numportals = count;

	for ( i = 0; i < count; i++, in++, out++ )
	{
		out->cluster[0] = (unsigned short)LittleShort( in->cluster[0] );
		out->cluster[1] = (unsigned short)LittleShort( in->cluster[1] );
		out->numportalverts = LittleLong( in->numportalverts );
		out->plane = loadmodel->planes + LittleLong( in->planenum );
		out->vertList = loadmodel->portalverts + LittleLong( in->firstportalvert );
		out->visframe = 0;
	}
}


model_t *r_worldmodel = NULL;
/*
=================
Mod_LoadMap
=================
*/
void Mod_LoadMap( void *buffer )
{
	int			i;
	dheader_t	*header;
	model_t		*mod = mod_known;
		
	mod->type = mod_brush;
	if (mod != mod_known)
		engine.Error ("Loaded a brush model after the world");

	header = (dheader_t *)buffer;

	i = LittleLong (header->version);
	if (i != BSPVERSION)
		engine.Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);

// 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
	
	// we don't really load the entities, just parse out the .wads' that are used
	// This should go away when shaders are done
	Mod_LoadEntities( mod, &header->lumps[LUMP_ENTITIES] );

	Mod_LoadVertexes( mod, &header->lumps[LUMP_VERTEXES] );
	Mod_LoadEdges( mod, &header->lumps[LUMP_EDGES] );
	Mod_LoadSurfedges( mod, &header->lumps[LUMP_SURFEDGES] );
	Mod_LoadLighting( mod, &header->lumps[LUMP_LIGHTING] );
	Mod_LoadPlanes( mod, &header->lumps[LUMP_PLANES] );
	// texdata needs to load before texinfo
	Mod_LoadTexdata( mod, &header->lumps[LUMP_TEXDATA] );

	Mod_LoadTexinfo( mod, &header->lumps[LUMP_TEXINFO] );
    Mod_LoadDispInfo( mod, &header->lumps[LUMP_DISPINFO] );
	Mod_LoadFaces( mod, &header->lumps[LUMP_FACES] );
	Mod_LoadMarksurfaces( mod, &header->lumps[LUMP_LEAFFACES] );

	// UNDONE: Client shouldn't need visibility, use common model
	Mod_LoadVisibility( mod, &header->lumps[LUMP_VISIBILITY] );

	Mod_LoadLeafs( mod, &header->lumps[LUMP_LEAFS] );
	Mod_LoadNodes( mod, &header->lumps[LUMP_NODES] );
	
	// UNDONE: Does the cmodel need worldlights?
	Mod_LoadWorldlights( mod, &header->lumps[LUMP_WORLDLIGHTS] );
	
	// load the portal information
	Mod_LoadPortalVerts( mod, &header->lumps[LUMP_PORTALVERTS] );
	Mod_LoadClusterPortals( mod, &header->lumps[LUMP_CLUSTERPORTALS] );
	Mod_LoadClusters( mod, &header->lumps[LUMP_CLUSTERS] );
	Mod_LoadPortals( mod, &header->lumps[LUMP_PORTALS] );
	
//	mod->numframes = 2;		// regular and alternate animation

	Mod_LoadSubmodels( mod, &header->lumps[LUMP_MODELS] );
//
// set up the submodels
//
	for (i=0 ; i<mod->numsubmodels ; i++)
	{
		model_t	*starmod;
		mmodel_t 	*bm;

		bm = &mod->submodels[i];
		starmod = &mod_inline[i];

		*starmod = *mod;
		
		starmod->firstmodelsurface = bm->firstface;
		starmod->nummodelsurfaces = bm->numfaces;
		starmod->firstnode = bm->headnode;
		if (starmod->firstnode >= mod->numnodes)
			engine.Error ("Inline model %i has bad firstnode", i);

		VectorCopy (bm->maxs, starmod->maxs);
		VectorCopy (bm->mins, starmod->mins);
		starmod->radius = bm->radius;
	
		if (i == 0)
			*mod = *starmod;

		starmod->numleafs = bm->visleafs;
	}

	r_worldmodel = mod;
	GL_BeginBuildingLightmaps( mod );
	for ( i = 0; i < mod->numsurfaces; i++ )
	{
		GL_CreateSurfaceLightmap( mod->surfaces + i );
	}
	GL_EndBuildingLightmaps();
}

#if 0
/*
==============================================================================

SPRITE MODELS

==============================================================================
*/

/*
=================
Mod_LoadSpriteModel
=================
*/
void Mod_LoadSpriteModel (model_t *mod, void *buffer)
{
	dsprite_t	*sprin, *sprout;
	int			i;

	sprin = (dsprite_t *)buffer;
	sprout = Hunk_Alloc (modfilelen);

	sprout->ident = LittleLong (sprin->ident);
	sprout->version = LittleLong (sprin->version);
	sprout->numframes = LittleLong (sprin->numframes);

	if (sprout->version != SPRITE_VERSION)
		engine.Error ("%s has wrong version number (%i should be %i)",
				 mod->name, sprout->version, SPRITE_VERSION);

	if (sprout->numframes > MAX_MD2SKINS)
		engine.Error ("%s has too many frames (%i > %i)",
				 mod->name, sprout->numframes, MAX_MD2SKINS);

	// byte swap everything
	for (i=0 ; i<sprout->numframes ; i++)
	{
		sprout->frames[i].width = LittleLong (sprin->frames[i].width);
		sprout->frames[i].height = LittleLong (sprin->frames[i].height);
		sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
		sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
		memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
		mod->skins[i] = GL_FindImage (sprout->frames[i].name,
			it_sprite);
	}

	mod->type = mod_sprite;
}
#endif


#if 0
//=============================================================================

/*
@@@@@@@@@@@@@@@@@@@@@
R_BeginRegistration

Specifies the model that will be used as the world
@@@@@@@@@@@@@@@@@@@@@
*/
void R_BeginRegistration (char *model)
{
	char	fullname[MAX_QPATH];
	cvar_t	*flushmap;

	registration_sequence++;
	r_oldviewcluster = -1;		// force markleafs

	Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);

	// explicitly free the old map if different
	// this guarantees that mod_known[0] is the world map
	flushmap = ri.Cvar_Get ("flushmap", "0", 0);
	if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
		Mod_Free (&mod_known[0]);
	r_worldmodel = Mod_ForName(fullname, true);

	r_viewcluster = -1;
}


/*
@@@@@@@@@@@@@@@@@@@@@
R_RegisterModel

@@@@@@@@@@@@@@@@@@@@@
*/
struct model_s *R_RegisterModel (char *name)
{
	model_t	*mod;
	int		i;
	dsprite_t	*sprout;
	dmdl_t		*pheader;

	mod = Mod_ForName (name, false);
	if (mod)
	{
		mod->registration_sequence = registration_sequence;

		// register any images used by the models
		if (mod->type == mod_sprite)
		{
			sprout = (dsprite_t *)mod->extradata;
			for (i=0 ; i<sprout->numframes ; i++)
				mod->skins[i] = GL_FindImage (sprout->frames[i].name, it_sprite);
		}
		else if (mod->type == mod_alias)
		{
			pheader = (dmdl_t *)mod->extradata;
			for (i=0 ; i<pheader->num_skins ; i++)
				mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
		}
		else if (mod->type == mod_brush)
		{
			for (i=0 ; i<mod->numtexinfo ; i++)
				mod->texinfo[i].image->registration_sequence = registration_sequence;
		}
	}
	return mod;
}


/*
@@@@@@@@@@@@@@@@@@@@@
R_EndRegistration

@@@@@@@@@@@@@@@@@@@@@
*/
void R_EndRegistration (void)
{
	int		i;
	model_t	*mod;

	for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
	{
		if (!mod->name[0])
			continue;
		if (mod->registration_sequence != registration_sequence)
		{	// don't need this model
			Mod_Free (mod);
		}
	}

	GL_FreeUnusedImages ();
}


//=============================================================================


/*
================
Mod_Free
================
*/
void Mod_Free (model_t *mod)
{
	Hunk_Free (mod->extradata);
	memset (mod, 0, sizeof(*mod));
}

/*
================
Mod_FreeAll
================
*/
void Mod_FreeAll (void)
{
	int		i;

	for (i=0 ; i<mod_numknown ; i++)
	{
		if (mod_known[i].extradatasize)
			Mod_Free (&mod_known[i]);
	}
}

#endif

/*
===============
R_MarkLeaves

Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*/
int r_oldviewcluster = -2, r_viewcluster = -2, r_oldviewcluster2 = -2, r_viewcluster2 = -2, r_visframecount = 0;

void R_MarkLeaves( void );

void R_SetupVis( Vector& origin, model_t *worldmodel )
{
	mleaf_t *leaf;
	
	r_worldmodel = worldmodel;
	leaf = Mod_PointInLeaf( origin, worldmodel );
	r_viewcluster = r_viewcluster2 = leaf->cluster;
	R_MarkLeaves();
}


void R_MarkLeaves( void )
{
	byte	*vis;
	byte	fatvis[MAX_MAP_LEAFS/8];
	mnode_t	*node;
	int		i, c;
	mleaf_t	*leaf;
	int		cluster;

	if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1)
		return;

	// development aid to let you run around and see exactly where
	// the pvs ends
	if (gl_lockpvs->value)
		return;

	r_visframecount++;
	r_oldviewcluster = r_viewcluster;
	r_oldviewcluster2 = r_viewcluster2;

	if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
	{
		// mark everything
		for (i=0 ; i<r_worldmodel->numleafs ; i++)
			r_worldmodel->leafs[i].visframe = r_visframecount;
		for (i=0 ; i<r_worldmodel->numnodes ; i++)
			r_worldmodel->nodes[i].visframe = r_visframecount;
		for ( i = 0; i < r_worldmodel->numportals; i++ )
			r_worldmodel->portals[i].visframe = r_visframecount;
		return;
	}

	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
	// may have to combine two clusters because of solid water boundaries
	if (r_viewcluster2 != r_viewcluster)
	{
		memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
		vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
		c = (r_worldmodel->numleafs+31)/32;
		for (i=0 ; i<c ; i++)
			((int *)fatvis)[i] |= ((int *)vis)[i];
		vis = fatvis;
	}
	
	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
	{
		cluster = leaf->cluster;
		if (cluster == -1)
			continue;

		if (vis[cluster>>3] & (1<<(cluster&7)))
		{
			int j;
			unsigned short *start;

			if ( r_worldmodel->portals )
			{
				start = r_worldmodel->clusters[ cluster ].portalList;
				for ( j = 0; j < r_worldmodel->clusters[ cluster ].numportals; j++ )
				{
					r_worldmodel->portals[ *start ].visframe = r_visframecount;
					start++;
				}
			}

			node = (mnode_t *)leaf;
			do
			{
				if (node->visframe == r_visframecount)
					break;
				node->visframe = r_visframecount;
				node = node->parent;
			} while (node);
		}
	}
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -