Beispiel #1
0
/*
================
GL_MakeAliasModelDisplayLists
================
*/
void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *hdr)
{
	int		i, j;
	int			*cmds;
	trivertx_t	*verts;
	float	hscale, vscale; //johnfitz -- padded skins
	int		count; //johnfitz -- precompute texcoords for padded skins
	int		*loadcmds; //johnfitz

	//johnfitz -- padded skins
	hscale = (float)hdr->skinwidth/(float)TexMgr_PadConditional(hdr->skinwidth);
	vscale = (float)hdr->skinheight/(float)TexMgr_PadConditional(hdr->skinheight);
	//johnfitz

	aliasmodel = m;
	paliashdr = hdr;	// (aliashdr_t *)Mod_Extradata (m);

//johnfitz -- generate meshes
	Con_DPrintf2 ("meshing %s...\n",m->name);
	BuildTris ();

	// save the data out

	paliashdr->poseverts = numorder;

	cmds = (int *) Hunk_Alloc (numcommands * 4);
	paliashdr->commands = (byte *)cmds - (byte *)paliashdr;

	//johnfitz -- precompute texcoords for padded skins
	loadcmds = commands;
	while(1)
	{
		*cmds++ = count = *loadcmds++;

		if (!count)
			break;

		if (count < 0)
			count = -count;

		do
		{
			*(float *)cmds++ = hscale * (*(float *)loadcmds++);
			*(float *)cmds++ = vscale * (*(float *)loadcmds++);
		} while (--count);
	}
	//johnfitz

	verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t));
	paliashdr->posedata = (byte *)verts - (byte *)paliashdr;
	for (i=0 ; i<paliashdr->numposes ; i++)
		for (j=0 ; j<numorder ; j++)
			*verts++ = poseverts[i][vertexorder[j]];

	// ericw
	GL_MakeAliasModelDisplayLists_VBO ();
}
Beispiel #2
0
void GuiImage::Draw()
{
  if (!IsVisible())
  {
    return;
  }

  if (GetCombinedPos() != m_oldPos || GetSize() != m_oldSize)
  {
    BuildTris();
    m_oldPos = GetCombinedPos();
    m_oldSize = GetSize();
  }

  Assert(m_texture);
  m_texture->UseThisTexture();

//  AmjuGL::DrawTriList(m_tris);
  AmjuGL::Draw(m_triList);
}
Beispiel #3
0
void GL_MakeAliasModelDisplayLists(model_t *m, aliashdr_t *hdr) {
    aliasmodel = m;
    paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m);

    // build it from scratch
    BuildTris(); // trifans or lists

    // save the data out
    paliashdr->poseverts = numorder;

    int *cmds = (int *) Hunk_Alloc(numcommands * 4);
    paliashdr->commands = (byte *) cmds - (byte *) paliashdr;
    memcpy(cmds, commands, numcommands * 4);

    trivertx_t *verts = (trivertx_t *) Hunk_Alloc(paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx_t));
    paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
    for (int i = 0; i < paliashdr->numposes; i++)
        for (int j = 0; j < numorder; j++)
            *verts++ = poseverts[i][vertexorder[j]];
}
Beispiel #4
0
void
gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m,
								   int _s, int extra)
{
	dstring_t  *cache, *fullpath;
	unsigned char model_digest[MDFOUR_DIGEST_BYTES];
	unsigned char mesh_digest[MDFOUR_DIGEST_BYTES];
	int         i, j;
	int        *cmds;
	QFile      *f;
	qboolean    remesh = true;
	qboolean    do_cache = false;

	aliasmodel = m;
	paliashdr = hdr;

	cache = dstring_new ();
	fullpath = dstring_new ();

	if (!gl_alias_render_tri->int_val) {

		if (gl_mesh_cache->int_val
			&& gl_mesh_cache->int_val <= paliashdr->mdl.numtris) {
			do_cache = true;

			mdfour (model_digest, (unsigned char *) _m, _s);

			// look for a cached version
			dstring_copystr (cache, "glquake/");
			dstring_appendstr (cache, m->name);
			QFS_StripExtension (m->name + strlen ("progs/"),
							cache->str + strlen ("glquake/"));
			dstring_appendstr (cache, ".qfms");

			QFS_FOpenFile (cache->str, &f);
			if (f) {
				unsigned char d1[MDFOUR_DIGEST_BYTES];
				unsigned char d2[MDFOUR_DIGEST_BYTES];
				struct mdfour md;
				int			len, vers;
				int         nc = 0, no = 0;
				int        *c = 0, *vo = 0;

				memset (d1, 0, sizeof (d1));
				memset (d2, 0, sizeof (d2));

				Qread (f, &vers, sizeof (int));
				Qread (f, &len, sizeof (int));
				Qread (f, &nc, sizeof (int));
				Qread (f, &no, sizeof (int));

				if (vers == 1 && (nc + no) == len) {
					c = malloc (((nc + 1023) & ~1023) * sizeof (c[0]));
					vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0]));
					if (!c || !vo)
						Sys_Error ("gl_mesh.c: out of memory");
					Qread (f, c, nc * sizeof (c[0]));
					Qread (f, vo, no * sizeof (vo[0]));
					Qread (f, d1, MDFOUR_DIGEST_BYTES);
					Qread (f, d2, MDFOUR_DIGEST_BYTES);
					Qclose (f);

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof(int));
					mdfour_update (&md, (unsigned char *) &len, sizeof(int));
					mdfour_update (&md, (unsigned char *) &nc, sizeof(int));
					mdfour_update (&md, (unsigned char *) &no, sizeof(int));
					mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0]));
					mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0]));
					mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0
						&& memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) {
						remesh = false;
						numcommands = nc;
						numorder = no;
						if (numcommands > commands_size) {
							if (commands)
								free (commands);
							commands_size = (numcommands + 1023) & ~1023;
							commands = c;
						} else {
							memcpy (commands, c, numcommands * sizeof (c[0]));
							free(c);
						}
						if (numorder > vertexorder_size) {
							if (vertexorder)
								free (vertexorder);
							vertexorder_size = (numorder + 1023) & ~1023;
							vertexorder = vo;
						} else {
							memcpy (vertexorder, vo, numorder * sizeof (vo[0]));
							free (vo);
						}
					}
				}
			}
		}
		if (remesh) {
			// build it from scratch
			Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name);

			BuildTris ();					// trifans or lists

			if (do_cache) {
				// save out the cached version
				dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str);
				f = QFS_WOpen (fullpath->str, 9);

				if (f) {
					struct mdfour md;
					int         vers = 1;
					int         len = numcommands + numorder;

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof (int));
					mdfour_update (&md, (unsigned char *) &len, sizeof (int));
					mdfour_update (&md, (unsigned char *) &numcommands,
								   sizeof (int));
					mdfour_update (&md, (unsigned char *) &numorder, sizeof (int));
					mdfour_update (&md, (unsigned char *) commands,
								   numcommands * sizeof (commands[0]));
					mdfour_update (&md, (unsigned char *) vertexorder,
								   numorder * sizeof (vertexorder[0]));
					mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					Qwrite (f, &vers, sizeof (int));
					Qwrite (f, &len, sizeof (int));
					Qwrite (f, &numcommands, sizeof (int));
					Qwrite (f, &numorder, sizeof (int));
					Qwrite (f, commands, numcommands * sizeof (commands[0]));
					Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0]));
					Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES);
					Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES);
					Qclose (f);
				}
			}
		}

		// save the data out
		paliashdr->poseverts = numorder;

		cmds = Hunk_Alloc (numcommands * sizeof (int));
		paliashdr->commands = (byte *) cmds - (byte *) paliashdr;
		memcpy (cmds, commands, numcommands * sizeof (int));

	} else {
		tex_coord_t *tex_coord;

		numorder = 0;
		for (i=0; i < pheader->mdl.numtris; i++) {
			add_vertex(triangles[i].vertindex[0]);
			add_vertex(triangles[i].vertindex[1]);
			add_vertex(triangles[i].vertindex[2]);
		}
		paliashdr->poseverts = numorder;

		tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t));
		paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr;
		for (i=0; i < numorder; i++) {
			float s, t;
			int k;
			k = vertexorder[i];
			s = stverts[k].s;
			t = stverts[k].t;
			if (!triangles[i/3].facesfront && stverts[k].onseam)
				s += pheader->mdl.skinwidth / 2;	// on back side
			s = (s + 0.5) / pheader->mdl.skinwidth;
			t = (t + 0.5) / pheader->mdl.skinheight;
			tex_coord[i].st[0] = s;
			tex_coord[i].st[1] = t;
		}
	}

	if (extra) {
		trivertx16_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx16_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			trivertx_t *pv = poseverts[i];
			for (j = 0; j < numorder; j++) {
				trivertx16_t v;
				// convert MD16's split coordinates into something a little
				// saner. The first chunk of vertices is fully compatible with
				// IDPO alias models (even the scale). The second chunk is the
				// fractional bits of the vertex, giving 8.8. However, it's
				// easier for us to multiply everything by 256 and adjust the
				// model scale appropriately
				VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v,
							   256, pv[vertexorder[j]].v, v.v);
				v.lightnormalindex =
					poseverts[i][vertexorder[j]].lightnormalindex;
				*verts++ = v;
			}
		}
	} else {
		trivertx_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			for (j = 0; j < numorder; j++)
				*verts++ = poseverts[i][vertexorder[j]];
		}
	}
	dstring_delete (cache);
	dstring_delete (fullpath);
}
Beispiel #5
0
/*
================
GL_MakeAliasModelDisplayLists
================
*/
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
{
	int		i, j;
	maliasgroup_t	*paliasgroup;
	int			*cmds;
	trivertx_t	*verts;
	char	cache[MAX_QPATH], fullpath[MAX_OSPATH], *c;
	FILE	*f;
	int		len;
	byte	*data;

	aliasmodel = m;
	paliashdr = hdr;	// (aliashdr_t *)Mod_Extradata (m);

	//
	// look for a cached version
	//
	strcpy (cache, "glquake/");
	COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/"));
	strcat (cache, ".ms2");

	COM_FOpenFile (cache, &f, NULL);	// 2001-09-12 Returning from which searchpath a file was loaded by Maddes
	if (f)
	{
		fread (&numcommands, 4, 1, f);
		fread (&numorder, 4, 1, f);
		fread (&commands, numcommands * sizeof(commands[0]), 1, f);
		fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
		fclose (f);
	}
	else
	{
		//
		// build it from scratch
		//
		Con_Printf ("meshing %s...\n",m->name);

		BuildTris ();		// trifans or lists

		//
		// save out the cached version
		//
		sprintf (fullpath, "%s/%s", com_gamedir, cache);
		f = fopen (fullpath, "wb");
		if (f)
		{
			fwrite (&numcommands, 4, 1, f);
			fwrite (&numorder, 4, 1, f);
			fwrite (&commands, numcommands * sizeof(commands[0]), 1, f);
			fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
			fclose (f);
		}
	}


	// save the data out

	paliashdr->poseverts = numorder;

	cmds = Hunk_Alloc (numcommands * 4);
	paliashdr->commands = (byte *)cmds - (byte *)paliashdr;
	memcpy (cmds, commands, numcommands * 4);

	verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
		* sizeof(trivertx_t) );
	paliashdr->posedata = (byte *)verts - (byte *)paliashdr;
	for (i=0 ; i<paliashdr->numposes ; i++)
		for (j=0 ; j<numorder ; j++)
			*verts++ = poseverts[i][vertexorder[j]];
}
Beispiel #6
0
void WriteModel( )
{
	int i, j, k;

	mstudiobodyparts_t	*pbodypart;
	mstudiomodel_t	*pmodel;
	// vec3_t			*bbox;
	byte			*pbone;
	vec3_t			*pvert;
	vec3_t			*pnorm;
	mstudiomesh_t	*pmesh;
	s_trianglevert_t *psrctri;
	int				cur;
	int				total_tris = 0;
	int				total_strips = 0;

	pbodypart = (mstudiobodyparts_t *)pData;
	phdr->numbodyparts = numbodyparts;
	phdr->bodypartindex = (pData - pStart);
	pData += numbodyparts * sizeof( mstudiobodyparts_t );

	pmodel = (mstudiomodel_t *)pData;
	pData += nummodels * sizeof( mstudiomodel_t );

	for (i = 0, j = 0; i < numbodyparts; i++)
	{
		strcpy( pbodypart[i].name, bodypart[i].name );
		pbodypart[i].nummodels		= bodypart[i].nummodels;
		pbodypart[i].base			= bodypart[i].base;
		pbodypart[i].modelindex		= ((byte *)&pmodel[j]) - pStart;
		j += bodypart[i].nummodels;
	}
	ALIGN( pData );

	cur = (int)pData;
	for (i = 0; i < nummodels; i++) 
	{
		int normmap[MAXSTUDIOVERTS];
		int normimap[MAXSTUDIOVERTS];
		int n = 0;

		strcpy( pmodel[i].name, model[i]->name );

		// save bbox info

		// remap normals to be sorted by skin reference
		for (j = 0; j < model[i]->nummesh; j++)
		{
			for (k = 0; k < model[i]->numnorms; k++)
			{
				if (model[i]->normal[k].skinref == model[i]->pmesh[j]->skinref)
				{
					normmap[k] = n;
					normimap[n] = k;
					n++;
					model[i]->pmesh[j]->numnorms++;
				}
			}
		}
		
		// save vertice bones
		pbone = pData;
		pmodel[i].numverts	= model[i]->numverts;
		pmodel[i].vertinfoindex = (pData - pStart);
		for (j = 0; j < pmodel[i].numverts; j++)
		{
			*pbone++ = model[i]->vert[j].bone;
		}
		ALIGN( pbone );

		// save normal bones
		pmodel[i].numnorms	= model[i]->numnorms;
		pmodel[i].norminfoindex = ((byte *)pbone - pStart);
		for (j = 0; j < pmodel[i].numnorms; j++)
		{
			*pbone++ = model[i]->normal[normimap[j]].bone;
		}
		ALIGN( pbone );

		pData = pbone;

		// save group info
		pvert = (vec3_t *)pData;
		pData += model[i]->numverts * sizeof( vec3_t );
		pmodel[i].vertindex		= ((byte *)pvert - pStart); 
		ALIGN( pData );			

		pnorm = (vec3_t *)pData;
		pData += model[i]->numnorms * sizeof( vec3_t );
		pmodel[i].normindex		= ((byte *)pnorm - pStart); 
		ALIGN( pData );

		for (j = 0; j < model[i]->numverts; j++)
		{
			VectorCopy( model[i]->vert[j].org, pvert[j] );
		}

		for (j = 0; j < model[i]->numnorms; j++)
		{
			VectorCopy( model[i]->normal[normimap[j]].org, pnorm[j] );
		}
		printf("vertices  %6d bytes (%d vertices, %d normals)\n", pData - cur, model[i]->numverts, model[i]->numnorms);
		cur = (int)pData;

		// save mesh info
		pmesh = (mstudiomesh_t *)pData;
		pmodel[i].nummesh		= model[i]->nummesh;
		pmodel[i].meshindex		= (pData - pStart);
		pData += pmodel[i].nummesh * sizeof( mstudiomesh_t );
		ALIGN( pData );

		total_tris = 0;
		total_strips = 0;
		for (j = 0; j < model[i]->nummesh; j++)
		{
			int numCmdBytes;
			byte *pCmdSrc;

			pmesh[j].numtris	= model[i]->pmesh[j]->numtris;
			pmesh[j].skinref	= model[i]->pmesh[j]->skinref;
			pmesh[j].numnorms	= model[i]->pmesh[j]->numnorms;

			psrctri				= (s_trianglevert_t *)(model[i]->pmesh[j]->triangle);
			for (k = 0; k < pmesh[j].numtris * 3; k++) 
			{
				psrctri->normindex	= normmap[psrctri->normindex];
				psrctri++;
			}

			numCmdBytes = BuildTris( model[i]->pmesh[j]->triangle, model[i]->pmesh[j], &pCmdSrc );

			pmesh[j].triindex	= (pData - pStart);
			memcpy( pData, pCmdSrc, numCmdBytes );
			pData += numCmdBytes;
			ALIGN( pData );
			total_tris += pmesh[j].numtris;
			total_strips += numcommandnodes;
		}
		printf("mesh      %6d bytes (%d tris, %d strips)\n", pData - cur, total_tris, total_strips);
		cur = (int)pData;
	}	
}
Beispiel #7
0
/*
================
GL_MakeAliasModelDisplayLists
================
*/
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
{
	int		i, j;
	int			*cmds;
	trivertx_t	*verts;
#if 0
	char	cache[MAX_QPATH], fullpath[MAX_OSPATH];
	FILE	*f;
#endif

	aliasmodel = m;
	paliashdr = hdr;	// (aliashdr_t *)Mod_Extradata (m);

#if 0
	//
	// look for a cached version
	//
	strcpy (cache, "glquake/");
	COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/"));
	strcat (cache, ".ms2");

	FS_FOpenFile (cache, &f);	
	if (f)
	{
		fread (&numcommands, 4, 1, f);
		fread (&numorder, 4, 1, f);
		fread (&commands, numcommands * sizeof(commands[0]), 1, f);
		fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
		fclose (f);
	}
	else
	{
		//
		// build it from scratch
		//
		Com_Printf ("meshing %s...\n",m->name);

		BuildTris ();		// trifans or lists

		//
		// save out the cached version
		//
		sprintf (fullpath, "%s/%s", com_gamedir, cache);
		f = fopen (fullpath, "wb");
		if (!f) {
			char gldir[MAX_OSPATH];

			sprintf (gldir, "%s/glquake", com_gamedir);
			Sys_mkdir (gldir);
			f = fopen (fullpath, "wb");
		}

		if (f)
		{
			fwrite (&numcommands, 4, 1, f);
			fwrite (&numorder, 4, 1, f);
			fwrite (&commands, numcommands * sizeof(commands[0]), 1, f);
			fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
			fclose (f);
		}
	}
#else
	// Tonik: don't cache anything, because it seems just as fast
	// (if not faster) to rebuild the tris instead of loading them from disk
	BuildTris ();		// trifans or lists
#endif

	// save the data out

	paliashdr->poseverts = numorder;

	cmds = Hunk_Alloc (numcommands * 4);
	paliashdr->commands = (byte *)cmds - (byte *)paliashdr;
	memcpy (cmds, commands, numcommands * 4);

	verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts 
		* sizeof(trivertx_t) );
	paliashdr->posedata = (byte *)verts - (byte *)paliashdr;
	for (i=0 ; i<paliashdr->numposes ; i++)
		for (j=0 ; j<numorder ; j++)
			*verts++ = poseverts[i][vertexorder[j]];
}
/*
================
GL_MakeAliasModelDisplayLists
================
*/
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
{
	int		i, j;
	maliasgroup_t	*paliasgroup;
	int			*cmds;
	trivertx_t	*verts;
	char	cache[MAX_QPATH], fullpath[MAX_OSPATH], *c;
	FILE	*f;
	int		len;
	byte	*data;

	aliasmodel = m;
	paliashdr = hdr;	// (aliashdr_t *)Mod_Extradata (m);

#ifdef NO_CACHE_MESH
	BuildTris ();		// trifans or lists
#else
	//
	// look for a cached version
	//
	strcpy (cache, "glquake/");
	COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/"));
	strcat (cache, ".ms2");

	COM_FOpenFile (cache, &f);	
	if (f)
	{
		fread (&numcommands, 4, 1, f);
		fread (&numorder, 4, 1, f);
		fread (&commands, numcommands * sizeof(commands[0]), 1, f);
		fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
		fclose (f);
	}
	else
	{
		//
		// build it from scratch
		//
		Con_SafePrintf ("meshing %s...\n",m->name);

		BuildTris ();		// trifans or lists

		//
		// save out the cached version
		//
		sprintf (fullpath, "%s/%s", com_gamedir, cache);
		f = fopen (fullpath, "wb");
		if (f)
		{
			fwrite (&numcommands, 4, 1, f);
			fwrite (&numorder, 4, 1, f);
			fwrite (&commands, numcommands * sizeof(commands[0]), 1, f);
			fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
			fclose (f);
		}
	}
#endif

	// save the data out

	paliashdr->poseverts = numorder;

	cmds = Hunk_Alloc (numcommands * 4);
	paliashdr->commands = (byte *)cmds - (byte *)paliashdr;
	memcpy (cmds, commands, numcommands * 4);

	verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts 
		* sizeof(trivertx_t) );
	paliashdr->posedata = (byte *)verts - (byte *)paliashdr;
	for (i=0 ; i<paliashdr->numposes ; i++)
	{
		for (j=0 ; j<numorder ; j++)
		{
			if (vertexorder[j] < 0 || vertexorder[j] >= MAXALIASVERTS)
				Sys_Error ("GL_MakeAliasModelDisplayLists: invalid vertexorder[%d] (%d, max = %d) in %s", j, vertexorder[j], MAXALIASVERTS, m->name);

			*verts++ = poseverts[i][vertexorder[j]];
		}
	}
}
Beispiel #9
0
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
{
	int		i, j;
//	maliasgroup_t	*paliasgroup;
	int		*cmds;
	trivertx_t	*verts;
	char		cache[MAX_QPATH], fullpath[MAX_OSPATH];//, *c;
	FILE		*f;
	size_t		success = 0;
//	int		len;
//	byte		*data;

	aliasmodel = m;
	paliashdr = hdr;	// (aliashdr_t *)Mod_Extradata (m);

	//
	// look for a cached version
	//
	strcpy (cache, "glquake/");
	COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/"));
	strcat (cache, ".ms2");

	COM_FOpenFile (cache, &f);	
	if (f)
	{
		// <AWE> we always read now little endian and do more checks on fread:
		success = fread (&numcommands, 4, 1, f);
		
		if (success == 1)
		{
			success = fread (&numorder, 4, 1, f);
		}

		numcommands	= LittleLong(numcommands);		
		numorder	= LittleLong(numorder);
		
		if (numcommands >= 8192 || numorder >= 8192)
		{
			success = 0;
		}

		if (success == 1)
		{
			success = fread (&commands, numcommands * sizeof(commands[0]), 1, f);
		}
		
		if (success == 1)
		{
			success = fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
		}
		
		if (success == 1)
		{
			SwapBufferEndianess();
		}
		
		fclose (f);
	}
	
	if (success == 0)
	{
		//
		// build it from scratch
		//
		Con_Printf ("meshing %s...\n",m->name);

		BuildTris ();		// trifans or lists

		//
		// save out the cached version
		//
#if defined (__APPLE__) || defined (MACOSX)
		snprintf (fullpath, MAX_OSPATH, "%s/%s", com_gamedir, cache);
#else
		sprintf (fullpath, "%s/%s", com_gamedir, cache);
#endif /* __APPLE__ || MACOSX */
		f = fopen (fullpath, "wb");
/*
		if (!f) {
			char gldir[MAX_OSPATH];

#if defined (__APPLE__) || defined (MACOSX)
			snprintf (gldir, MAX_OSPATH, "%s/glquake", com_gamedir);
#else
			sprintf (gldir, "%s/glquake", com_gamedir);
#endif
			Sys_mkdir (gldir);
			f = fopen (fullpath, "wb");
		}                
*/              
		if (f)
		{
			// <AWE> we always write now in little endian:
			int littleNumCommands	= LittleLong(numcommands);
			int littleNumOrder		= LittleLong(numorder);
						
			fwrite (&littleNumCommands, 4, 1, f);
			fwrite (&littleNumOrder, 4, 1, f);
			
			SwapBufferEndianess();
			
			fwrite (&commands, numcommands * sizeof(commands[0]), 1, f);
			fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
			fclose (f);
			
			SwapBufferEndianess();
		}
	}


	// save the data out

	paliashdr->poseverts = numorder;

	cmds = Hunk_Alloc (numcommands * 4);
	paliashdr->commands = (int) ((byte *)cmds - (byte *)paliashdr);
	memcpy (cmds, commands, numcommands * 4);

	verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts 
		* sizeof(trivertx_t) );
	paliashdr->posedata = (int) ((byte *)verts - (byte *)paliashdr);
	for (i=0 ; i<paliashdr->numposes ; i++)
		for (j=0 ; j<numorder ; j++)
			*verts++ = poseverts[i][vertexorder[j]];
}