Fixed up halflife model support - we now support models with textures stored in an external model.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3126 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2009-02-22 13:45:35 +00:00
parent d18566f4e8
commit aac9d42554
2 changed files with 71 additions and 15 deletions

View file

@ -83,6 +83,7 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
hlmodelcache_t *model; hlmodelcache_t *model;
hlmdl_header_t *header; hlmdl_header_t *header;
hlmdl_header_t *texheader;
hlmdl_tex_t *tex; hlmdl_tex_t *tex;
hlmdl_bone_t *bones; hlmdl_bone_t *bones;
hlmdl_bonecontroller_t *bonectls; hlmdl_bonecontroller_t *bonectls;
@ -126,6 +127,13 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
header = Hunk_Alloc(com_filesize); header = Hunk_Alloc(com_filesize);
memcpy(header, buffer, com_filesize); memcpy(header, buffer, com_filesize);
#if defined(HLSERVER) && (defined(__powerpc__) || defined(__ppc__))
//this is to let bigfoot know when he comes to port it all... And I'm lazy.
#warning "-----------------------------------------"
#warning "FIXME: No byteswapping on halflife models"
#warning "-----------------------------------------"
#endif
if (header->version != 10) if (header->version != 10)
{ {
Con_Printf(CON_ERROR "Cannot load model %s - unknown version %i\n", mod->name, header->version); Con_Printf(CON_ERROR "Cannot load model %s - unknown version %i\n", mod->name, header->version);
@ -146,7 +154,26 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
return false; return false;
} }
tex = (hlmdl_tex_t *) ((qbyte *) header + header->textures); texheader = NULL;
if (!header->numtextures)
{
char texmodelname[MAX_QPATH];
COM_StripExtension(mod->name, texmodelname, sizeof(texmodelname));
//no textures? eesh. They must be stored externally.
texheader = (hlmdl_header_t*)COM_LoadHunkFile(va("%st.mdl", texmodelname));
if (texheader)
{
if (texheader->version != 10)
texheader = NULL;
}
}
if (!texheader)
texheader = header;
else
header->numtextures = texheader->numtextures;
tex = (hlmdl_tex_t *) ((qbyte *) texheader + texheader->textures);
bones = (hlmdl_bone_t *) ((qbyte *) header + header->boneindex); bones = (hlmdl_bone_t *) ((qbyte *) header + header->boneindex);
bonectls = (hlmdl_bonecontroller_t *) ((qbyte *) header + header->controllerindex); bonectls = (hlmdl_bonecontroller_t *) ((qbyte *) header + header->controllerindex);
@ -167,13 +194,14 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
*/ */
model->header = (char *)header - (char *)model; model->header = (char *)header - (char *)model;
model->texheader = (char *)texheader - (char *)model;
model->textures = (char *)tex - (char *)model; model->textures = (char *)tex - (char *)model;
model->bones = (char *)bones - (char *)model; model->bones = (char *)bones - (char *)model;
model->bonectls = (char *)bonectls - (char *)model; model->bonectls = (char *)bonectls - (char *)model;
for(i = 0; i < header->numtextures; i++) for(i = 0; i < texheader->numtextures; i++)
{ {
tex[i].i = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) header + tex[i].i, (qbyte *) header + tex[i].w * tex[i].h + tex[i].i, true, false); tex[i].i = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) texheader + tex[i].i, (qbyte *) texheader + tex[i].w * tex[i].h + tex[i].i, true, false);
} }
@ -185,7 +213,7 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
mod->type = mod_halflife; mod->type = mod_halflife;
Cache_Alloc (&mod->cache, total, loadname); Cache_Alloc (&mod->cache, total, mod->name);
if (!mod->cache.data) if (!mod->cache.data)
return false; return false;
memcpy (mod->cache.data, model, total); memcpy (mod->cache.data, model, total);
@ -194,6 +222,18 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
return true; return true;
} }
#ifdef HLSERVER
void *Mod_GetHalfLifeModelData(model_t *mod)
{
hlmodelcache_t *mc;
if (!mod || mod->type != mod_halflife)
return NULL; //halflife models only, please
mc = Mod_Extradata(mod);
return (void*)((char*)mc + mc->header);
}
#endif
/* /*
======================================================================================================================= =======================================================================================================================
HL_CalculateBones - calculate bone positions - quaternion+vector in one function HL_CalculateBones - calculate bone positions - quaternion+vector in one function
@ -333,7 +373,7 @@ void HL_CalcBoneAdj(hlmodel_t *model)
======================================================================================================================= =======================================================================================================================
*/ */
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt ); void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, float subblendfrac) void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, float subblendfrac, float frametime)
{ {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int i; int i;
@ -341,7 +381,6 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
static vec3_t positions[2]; static vec3_t positions[2];
static vec4_t quaternions[2], blended; static vec4_t quaternions[2], blended;
float frametime;
int frame; int frame;
hlmdl_sequencelist_t *sequence = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) + hlmdl_sequencelist_t *sequence = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) +
@ -353,7 +392,7 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
((qbyte *) model->header + sequencedata->data + sequence->index); ((qbyte *) model->header + sequencedata->data + sequence->index);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
frametime = (cl.time - cl.lerpents[currententity->keynum].framechange)*sequence->timing; frametime *= sequence->timing;
frame = (int)frametime; frame = (int)frametime;
frametime -= frame; frametime -= frame;
@ -485,11 +524,18 @@ void R_DrawHLModel(entity_t *curent)
//general model //general model
model.header = (hlmdl_header_t *) ((char *)modelc + modelc->header); model.header = (hlmdl_header_t *) ((char *)modelc + modelc->header);
model.texheader = (hlmdl_header_t *) ((char *)modelc + modelc->texheader);
model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures); model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures);
model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones); model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones);
model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls); model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls);
skins = (short *) ((qbyte *) model.header + model.header->skins); skins = (short *) ((qbyte *) model.texheader + model.texheader->skins);
if (!model.texheader->numtextures)
{
Con_DPrintf("model with no textures: %s\n", curent->model->name);
return;
}
for (b = 0; b < MAX_BONE_CONTROLLERS; b++) for (b = 0; b < MAX_BONE_CONTROLLERS; b++)
model.controller[b] = curent->framestate.bonecontrols[b]; model.controller[b] = curent->framestate.bonecontrols[b];
@ -522,11 +568,11 @@ void R_DrawHLModel(entity_t *curent)
for (bgroup = 0; bgroup < FS_COUNT; bgroup++) for (bgroup = 0; bgroup < FS_COUNT; bgroup++)
{ {
lastbone = curent->framestate.g[bgroup].endbone; lastbone = curent->framestate.g[bgroup].endbone;
if (bgroup == FS_COUNT) if (bgroup == FS_COUNT-1)
lastbone = model.header->numbones; lastbone = model.header->numbones;
if (cbone >= lastbone) if (cbone >= lastbone)
continue; continue;
HL_SetupBones(&model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, (curent->framestate.g[bgroup].subblendfrac+1)*0.5); /* Setup the bones */ HL_SetupBones(&model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, (curent->framestate.g[bgroup].subblendfrac+1)*0.5, curent->framestate.g[bgroup].frametime[0]); /* Setup the bones */
} }
/* Manipulate each mesh directly */ /* Manipulate each mesh directly */
@ -579,11 +625,16 @@ void R_DrawHLModel(entity_t *curent)
{ {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmdl_mesh_t *mesh = (hlmdl_mesh_t *) ((qbyte *) model.header + amodel->meshindex) + m; hlmdl_mesh_t *mesh = (hlmdl_mesh_t *) ((qbyte *) model.header + amodel->meshindex) + m;
float tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w; float tex_w;
float tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h; float tex_h;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
{
tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
GL_Bind(model.textures[skins[mesh->skinindex]].i); GL_Bind(model.textures[skins[mesh->skinindex]].i);
}
GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h); GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h);
} }
} }

View file

@ -203,11 +203,12 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
float controller[4]; /* Position of bone controllers */ float controller[5]; /* Position of bone controllers */
float adjust[4]; float adjust[5];
/* Static pointers */ /* Static pointers */
hlmdl_header_t *header; hlmdl_header_t *header;
hlmdl_header_t *texheader;
hlmdl_tex_t *textures; hlmdl_tex_t *textures;
hlmdl_bone_t *bones; hlmdl_bone_t *bones;
hlmdl_bonecontroller_t *bonectls; hlmdl_bonecontroller_t *bonectls;
@ -216,6 +217,7 @@ typedef struct
typedef struct //this is stored as the cache. an hlmodel_t is generated when drawing typedef struct //this is stored as the cache. an hlmodel_t is generated when drawing
{ {
int header; int header;
int texheader;
int textures; int textures;
int bones; int bones;
int bonectls; int bonectls;
@ -229,3 +231,6 @@ void QuaternionGLMatrix(float x, float y, float z, float w, vec4_t *GLM);
/* HL drawing */ /* HL drawing */
qboolean Mod_LoadHLModel (model_t *mod, void *buffer); qboolean Mod_LoadHLModel (model_t *mod, void *buffer);
void R_Draw_HL_AliasModel(hlmodel_t *model); void R_Draw_HL_AliasModel(hlmodel_t *model);
/* physics stuff */
void *Mod_GetHalfLifeModelData(model_t *mod);