mirror of
https://github.com/yquake2/ref_vk.git
synced 2024-11-10 06:41:45 +00:00
Add fm/heretic2 model support
Save additional list of meshes between dmdl_t and list of skins. https://sourceforge.net/p/quark/code/HEAD/tree/runtime/trunk/plugins/ie_fm_import.py
This commit is contained in:
parent
175454e302
commit
e20dd0a717
4 changed files with 583 additions and 134 deletions
|
@ -184,6 +184,25 @@ typedef struct
|
||||||
int ofs_end; /* end of file */
|
int ofs_end; /* end of file */
|
||||||
} dmdl_t;
|
} dmdl_t;
|
||||||
|
|
||||||
|
/* .FM triangle model file format */
|
||||||
|
|
||||||
|
#define RAVENFMHEADER (('d'<<24)+('a'<<16)+('e'<<8)+'h')
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int skinwidth;
|
||||||
|
int skinheight;
|
||||||
|
int framesize; /* byte size of each frame */
|
||||||
|
|
||||||
|
int num_skins;
|
||||||
|
int num_xyz;
|
||||||
|
int num_st; /* greater than num_xyz for seams */
|
||||||
|
int num_tris;
|
||||||
|
int num_glcmds; /* dwords in strip/fan command list */
|
||||||
|
int num_frames;
|
||||||
|
int num_mesh_nodes;
|
||||||
|
} fmheader_t;
|
||||||
|
|
||||||
/* .SP2 sprite file format */
|
/* .SP2 sprite file format */
|
||||||
|
|
||||||
#define IDSPRITEHEADER (('2' << 24) + ('S' << 16) + ('D' << 8) + 'I') /* little-endian "IDS2" */
|
#define IDSPRITEHEADER (('2' << 24) + ('S' << 16) + ('D' << 8) + 'I') /* little-endian "IDS2" */
|
||||||
|
|
|
@ -26,6 +26,114 @@
|
||||||
|
|
||||||
#include "../common/header/ref_shared.h"
|
#include "../common/header/ref_shared.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadSTvertList
|
||||||
|
|
||||||
|
load base s and t vertices (not used in gl version)
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Mod_LoadSTvertList (dmdl_t *pheader, dstvert_t *pinst)
|
||||||
|
{
|
||||||
|
dstvert_t *poutst;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
|
||||||
|
|
||||||
|
for (i=0 ; i<pheader->num_st ; i++)
|
||||||
|
{
|
||||||
|
poutst[i].s = LittleShort (pinst[i].s);
|
||||||
|
poutst[i].t = LittleShort (pinst[i].t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadCmdList
|
||||||
|
|
||||||
|
Load the glcmds
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Mod_LoadCmdList (const char *mod_name, dmdl_t *pheader, int *pincmd)
|
||||||
|
{
|
||||||
|
int *poutcmd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
poutcmd = (int *)((char*)pheader + pheader->ofs_glcmds);
|
||||||
|
for (i = 0; i < pheader->num_glcmds; i++)
|
||||||
|
{
|
||||||
|
poutcmd[i] = LittleLong (pincmd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poutcmd[pheader->num_glcmds-1] != 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Entity %s has possible last element issues with %d verts.\n",
|
||||||
|
__func__, mod_name, poutcmd[pheader->num_glcmds-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadFrames
|
||||||
|
|
||||||
|
Load the frames
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Mod_LoadFrames (dmdl_t *pheader, byte *src)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0 ; i<pheader->num_frames ; i++)
|
||||||
|
{
|
||||||
|
daliasframe_t *pinframe, *poutframe;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
pinframe = (daliasframe_t *) (src + i * pheader->framesize);
|
||||||
|
poutframe = (daliasframe_t *) ((byte *)pheader
|
||||||
|
+ pheader->ofs_frames + i * pheader->framesize);
|
||||||
|
|
||||||
|
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
|
||||||
|
for (j=0 ; j<3 ; j++)
|
||||||
|
{
|
||||||
|
poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
|
||||||
|
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
|
||||||
|
}
|
||||||
|
// verts are all 8 bit, so no swapping needed
|
||||||
|
memcpy (poutframe->verts, pinframe->verts,
|
||||||
|
pheader->num_xyz*sizeof(dtrivertx_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadDTriangleList
|
||||||
|
|
||||||
|
Load triangle lists
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Mod_LoadDTriangleList (dmdl_t *pheader, dtriangle_t *pintri)
|
||||||
|
{
|
||||||
|
dtriangle_t *pouttri;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
|
||||||
|
|
||||||
|
for (i=0 ; i<pheader->num_tris ; i++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j=0 ; j<3 ; j++)
|
||||||
|
{
|
||||||
|
pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
|
||||||
|
pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Mod_LoadMDL
|
Mod_LoadMDL
|
||||||
|
@ -332,7 +440,7 @@ Mod_LoadMDL (const char *mod_name, const void *buffer, int modfilelen,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Mod_LoadAliasModel/Mod_LoadMD2
|
Mod_LoadMD2
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static void *
|
static void *
|
||||||
|
@ -341,13 +449,13 @@ Mod_LoadMD2 (const char *mod_name, const void *buffer, int modfilelen,
|
||||||
modtype_t *type)
|
modtype_t *type)
|
||||||
{
|
{
|
||||||
dmdl_t *pinmodel, *pheader;
|
dmdl_t *pinmodel, *pheader;
|
||||||
dtriangle_t *pintri, *pouttri;
|
dtriangle_t *pintri;
|
||||||
dstvert_t *pinst, *poutst;
|
dstvert_t *pinst;
|
||||||
int *pincmd, *poutcmd;
|
int *pincmd;
|
||||||
void *extradata;
|
void *extradata;
|
||||||
int version;
|
int version;
|
||||||
int ofs_end;
|
int ofs_end;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
pinmodel = (dmdl_t *)buffer;
|
pinmodel = (dmdl_t *)buffer;
|
||||||
|
|
||||||
|
@ -420,67 +528,24 @@ Mod_LoadMD2 (const char *mod_name, const void *buffer, int modfilelen,
|
||||||
// load base s and t vertices (not used in gl version)
|
// load base s and t vertices (not used in gl version)
|
||||||
//
|
//
|
||||||
pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
|
pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
|
||||||
poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
|
Mod_LoadSTvertList (pheader, pinst);
|
||||||
|
|
||||||
for (i=0 ; i<pheader->num_st ; i++)
|
|
||||||
{
|
|
||||||
poutst[i].s = LittleShort (pinst[i].s);
|
|
||||||
poutst[i].t = LittleShort (pinst[i].t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// load triangle lists
|
// load triangle lists
|
||||||
//
|
//
|
||||||
pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
|
pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
|
||||||
pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
|
Mod_LoadDTriangleList (pheader, pintri);
|
||||||
|
|
||||||
for (i=0 ; i<pheader->num_tris ; i++)
|
|
||||||
{
|
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
{
|
|
||||||
pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
|
|
||||||
pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// load the frames
|
// load the frames
|
||||||
//
|
//
|
||||||
for (i=0 ; i<pheader->num_frames ; i++)
|
Mod_LoadFrames (pheader, (byte *)pinmodel + pheader->ofs_frames);
|
||||||
{
|
|
||||||
daliasframe_t *pinframe, *poutframe;
|
|
||||||
|
|
||||||
pinframe = (daliasframe_t *) ((byte *)pinmodel
|
|
||||||
+ pheader->ofs_frames + i * pheader->framesize);
|
|
||||||
poutframe = (daliasframe_t *) ((byte *)pheader
|
|
||||||
+ pheader->ofs_frames + i * pheader->framesize);
|
|
||||||
|
|
||||||
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
|
|
||||||
for (j=0 ; j<3 ; j++)
|
|
||||||
{
|
|
||||||
poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
|
|
||||||
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
|
|
||||||
}
|
|
||||||
// verts are all 8 bit, so no swapping needed
|
|
||||||
memcpy (poutframe->verts, pinframe->verts,
|
|
||||||
pheader->num_xyz*sizeof(dtrivertx_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// load the glcmds
|
// load the glcmds
|
||||||
//
|
//
|
||||||
pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
|
pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
|
||||||
poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
|
Mod_LoadCmdList (mod_name, pheader, pincmd);
|
||||||
for (i=0; i < pheader->num_glcmds; i++)
|
|
||||||
{
|
|
||||||
poutcmd[i] = LittleLong (pincmd[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (poutcmd[pheader->num_glcmds-1] != 0)
|
|
||||||
{
|
|
||||||
R_Printf(PRINT_ALL, "%s: Entity %s has possible last element issues with %d verts.\n",
|
|
||||||
__func__, mod_name, poutcmd[pheader->num_glcmds-1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register all skins
|
// register all skins
|
||||||
memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
|
memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
|
||||||
|
@ -503,6 +568,292 @@ Mod_LoadMD2 (const char *mod_name, const void *buffer, int modfilelen,
|
||||||
return extradata;
|
return extradata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Mod_LoadFlexModel
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
Mod_LoadFlexModel(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
|
vec3_t mins, vec3_t maxs, struct image_s **skins, findimage_t find_image,
|
||||||
|
modtype_t *type)
|
||||||
|
{
|
||||||
|
char *src = (char *)buffer;
|
||||||
|
int version, size, i;
|
||||||
|
void *extradata;
|
||||||
|
dmdl_t *pheader = NULL;
|
||||||
|
|
||||||
|
while (modfilelen > 0)
|
||||||
|
{
|
||||||
|
char blockname[32];
|
||||||
|
|
||||||
|
memcpy(blockname, src, sizeof(blockname));
|
||||||
|
|
||||||
|
src += sizeof(blockname);
|
||||||
|
version = *(int*)src;
|
||||||
|
src += sizeof(version);
|
||||||
|
size = *(int*)src;
|
||||||
|
src += sizeof(size);
|
||||||
|
modfilelen = modfilelen - sizeof(blockname) - sizeof(version) - sizeof(size);
|
||||||
|
|
||||||
|
if (Q_strncasecmp(blockname, "header", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
dmdl_t dmdlheader;
|
||||||
|
fmheader_t *header = (fmheader_t *)src;
|
||||||
|
|
||||||
|
if (sizeof(fmheader_t) > size)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Too short header", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != 2)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy back all values */
|
||||||
|
dmdlheader.ident = IDALIASHEADER;
|
||||||
|
dmdlheader.version = ALIAS_VERSION;
|
||||||
|
dmdlheader.skinwidth = LittleLong (header->skinwidth);
|
||||||
|
dmdlheader.skinheight = LittleLong (header->skinheight);
|
||||||
|
dmdlheader.framesize = LittleLong (header->framesize);
|
||||||
|
|
||||||
|
dmdlheader.num_skins = LittleLong (header->num_skins);
|
||||||
|
dmdlheader.num_xyz = LittleLong (header->num_xyz);
|
||||||
|
dmdlheader.num_st = LittleLong (header->num_st);
|
||||||
|
dmdlheader.num_tris = LittleLong (header->num_tris);
|
||||||
|
dmdlheader.num_glcmds = LittleLong (header->num_glcmds);
|
||||||
|
dmdlheader.num_frames = LittleLong (header->num_frames);
|
||||||
|
|
||||||
|
// just skip header and meshes
|
||||||
|
dmdlheader.ofs_skins = sizeof(dmdl_t) + sizeof(short) * 2 * LittleLong (header->num_mesh_nodes);
|
||||||
|
dmdlheader.ofs_st = dmdlheader.ofs_skins + dmdlheader.num_skins * MAX_SKINNAME;
|
||||||
|
dmdlheader.ofs_tris = dmdlheader.ofs_st + dmdlheader.num_st * sizeof(dstvert_t);
|
||||||
|
dmdlheader.ofs_frames = dmdlheader.ofs_tris + dmdlheader.num_tris * sizeof(dtriangle_t);
|
||||||
|
dmdlheader.ofs_glcmds = dmdlheader.ofs_frames + dmdlheader.num_frames * dmdlheader.framesize;
|
||||||
|
dmdlheader.ofs_end = dmdlheader.ofs_glcmds + dmdlheader.num_glcmds * sizeof(int);
|
||||||
|
|
||||||
|
if (dmdlheader.skinheight > MAX_LBM_HEIGHT)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has a skin taller than %d",
|
||||||
|
__func__, mod_name, MAX_LBM_HEIGHT);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmdlheader.num_xyz <= 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has no vertices",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmdlheader.num_xyz > MAX_VERTS)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has too many vertices",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmdlheader.num_st <= 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has no st vertices",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmdlheader.num_tris <= 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has no triangles",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmdlheader.num_frames <= 0)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: model %s has no frames",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extradata = Hunk_Begin(dmdlheader.ofs_end);
|
||||||
|
pheader = Hunk_Alloc(dmdlheader.ofs_end);
|
||||||
|
|
||||||
|
memcpy(pheader, &dmdlheader, sizeof(dmdl_t));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!pheader)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: %s has broken header.",
|
||||||
|
__func__, mod_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "skin", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size != (pheader->num_skins * MAX_SKINNAME))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy((char*) pheader + pheader->ofs_skins, src, size);
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "st coord", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size != (pheader->num_st * sizeof(dstvert_t)))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod_LoadSTvertList (pheader, (dstvert_t *)src);
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "tris", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size != (pheader->num_tris * sizeof(dtriangle_t)))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod_LoadDTriangleList (pheader, (dtriangle_t *) src);
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "frames", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size != (pheader->num_frames * pheader->framesize))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod_LoadFrames (pheader, (byte *)src);
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "glcmds", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size != (pheader->num_glcmds * sizeof(int)))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod_LoadCmdList (mod_name, pheader, (int *)src);
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "mesh nodes", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
int num_mesh_nodes;
|
||||||
|
|
||||||
|
num_mesh_nodes = (pheader->ofs_skins - sizeof(dmdl_t)) / sizeof(short) / 2;
|
||||||
|
|
||||||
|
if (version != 3)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s version %d",
|
||||||
|
__func__, blockname, version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* 516 mesh node size */
|
||||||
|
if (size != (num_mesh_nodes * 516))
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: Invalid %s size",
|
||||||
|
__func__, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_mesh_nodes > 0)
|
||||||
|
{
|
||||||
|
short *mesh_nodes;
|
||||||
|
char *in_mesh = src;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mesh_nodes = (short *)((char*)pheader + sizeof(dmdl_t));
|
||||||
|
for (i = 0; i < num_mesh_nodes; i++)
|
||||||
|
{
|
||||||
|
/* 256 bytes of tri data */
|
||||||
|
/* 256 bytes of vert data */
|
||||||
|
/* 2 bytes of start */
|
||||||
|
/* 2 bytes of number commands */
|
||||||
|
in_mesh += 512;
|
||||||
|
mesh_nodes[i * 2] = LittleShort(*(short *)in_mesh);
|
||||||
|
in_mesh += 2;
|
||||||
|
mesh_nodes[i * 2 + 1] = LittleShort(*(short *)in_mesh);
|
||||||
|
in_mesh += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Q_strncasecmp(blockname, "normals", sizeof(blockname)) == 0 ||
|
||||||
|
Q_strncasecmp(blockname, "short frames", sizeof(blockname)) == 0 ||
|
||||||
|
Q_strncasecmp(blockname, "comp data", sizeof(blockname)) == 0 ||
|
||||||
|
Q_strncasecmp(blockname, "skeleton", sizeof(blockname)) == 0 ||
|
||||||
|
Q_strncasecmp(blockname, "references", sizeof(blockname)) == 0)
|
||||||
|
{
|
||||||
|
/* skipped block */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s: %s Unknown block %s\n",
|
||||||
|
__func__, mod_name, blockname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modfilelen -= size;
|
||||||
|
src += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load in our skins.
|
||||||
|
for (i=0 ; i<pheader->num_skins ; i++)
|
||||||
|
{
|
||||||
|
skins[i] = find_image((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME,
|
||||||
|
it_skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
*type = mod_alias;
|
||||||
|
|
||||||
|
mins[0] = -32;
|
||||||
|
mins[1] = -32;
|
||||||
|
mins[2] = -32;
|
||||||
|
maxs[0] = 32;
|
||||||
|
maxs[1] = 32;
|
||||||
|
maxs[2] = 32;
|
||||||
|
|
||||||
|
return extradata;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Mod_LoadAliasModel
|
Mod_LoadAliasModel
|
||||||
|
@ -515,14 +866,17 @@ Mod_LoadAliasModel (const char *mod_name, const void *buffer, int modfilelen,
|
||||||
{
|
{
|
||||||
switch (LittleLong(*(unsigned *)buffer))
|
switch (LittleLong(*(unsigned *)buffer))
|
||||||
{
|
{
|
||||||
case IDALIASHEADER:
|
case RAVENFMHEADER:
|
||||||
return Mod_LoadMD2(mod_name, buffer, modfilelen, mins, maxs, skins,
|
return Mod_LoadFlexModel(mod_name, buffer, modfilelen, mins, maxs, skins,
|
||||||
find_image, type);
|
find_image, type);
|
||||||
|
|
||||||
case IDMDLHEADER:
|
case IDALIASHEADER:
|
||||||
return Mod_LoadMDL(mod_name, buffer, modfilelen, mins, maxs, skins,
|
return Mod_LoadMD2(mod_name, buffer, modfilelen, mins, maxs, skins,
|
||||||
find_image, type);
|
find_image, type);
|
||||||
|
|
||||||
|
case IDMDLHEADER:
|
||||||
|
return Mod_LoadMDL(mod_name, buffer, modfilelen, mins, maxs, skins,
|
||||||
|
find_image, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -615,7 +969,8 @@ Mod_LoadFile(char *name, void **buffer)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(ext, "md2") ||
|
if (!strcmp(ext, "fm") ||
|
||||||
|
!strcmp(ext, "md2") ||
|
||||||
!strcmp(ext, "mdl"))
|
!strcmp(ext, "mdl"))
|
||||||
{
|
{
|
||||||
char namewe[256], newname[256];
|
char namewe[256], newname[256];
|
||||||
|
@ -631,6 +986,14 @@ Mod_LoadFile(char *name, void **buffer)
|
||||||
memset(namewe, 0, 256);
|
memset(namewe, 0, 256);
|
||||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||||
|
|
||||||
|
/* Check Heretic2 model */
|
||||||
|
snprintf(newname, sizeof(newname), "%s.fm", namewe);
|
||||||
|
filesize = ri.FS_LoadFile (newname, buffer);
|
||||||
|
if (filesize > 0)
|
||||||
|
{
|
||||||
|
return filesize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check Quake 2 model */
|
/* Check Quake 2 model */
|
||||||
snprintf(newname, sizeof(newname), "%s.md2", namewe);
|
snprintf(newname, sizeof(newname), "%s.md2", namewe);
|
||||||
filesize = ri.FS_LoadFile (newname, buffer);
|
filesize = ri.FS_LoadFile (newname, buffer);
|
||||||
|
|
215
src/vk/vk_mesh.c
215
src/vk/vk_mesh.c
|
@ -268,73 +268,11 @@ static void Vk_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
=============
|
Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_end,
|
||||||
Vk_DrawAliasFrameLerp
|
float alpha, image_t *skin, float *modelMatrix, int leftHandOffset, int translucentIdx,
|
||||||
|
dtrivertx_t *verts)
|
||||||
interpolates between two frames and origins
|
|
||||||
FIXME: batch lerp all vertexes
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
static void Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin, float *modelMatrix, int leftHandOffset, int translucentIdx, entity_t *currententity)
|
|
||||||
{
|
{
|
||||||
daliasframe_t *frame, *oldframe;
|
|
||||||
dtrivertx_t *v, *ov, *verts;
|
|
||||||
int *order;
|
|
||||||
float frontlerp;
|
|
||||||
float alpha;
|
|
||||||
vec3_t move, delta, vectors[3];
|
|
||||||
vec3_t frontv, backv;
|
|
||||||
int i;
|
|
||||||
float *lerp;
|
|
||||||
|
|
||||||
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
|
||||||
+ currententity->frame * paliashdr->framesize);
|
|
||||||
verts = v = frame->verts;
|
|
||||||
|
|
||||||
oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
|
||||||
+ currententity->oldframe * paliashdr->framesize);
|
|
||||||
ov = oldframe->verts;
|
|
||||||
|
|
||||||
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
|
|
||||||
|
|
||||||
if (currententity->flags & RF_TRANSLUCENT)
|
|
||||||
alpha = currententity->alpha;
|
|
||||||
else
|
|
||||||
alpha = 1.0;
|
|
||||||
|
|
||||||
frontlerp = 1.0 - backlerp;
|
|
||||||
|
|
||||||
// move should be the delta back to the previous frame * backlerp
|
|
||||||
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
|
|
||||||
AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
|
|
||||||
|
|
||||||
move[0] = DotProduct (delta, vectors[0]); // forward
|
|
||||||
move[1] = -DotProduct (delta, vectors[1]); // left
|
|
||||||
move[2] = DotProduct (delta, vectors[2]); // up
|
|
||||||
|
|
||||||
VectorAdd (move, oldframe->translate, move);
|
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
|
||||||
{
|
|
||||||
move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
|
||||||
{
|
|
||||||
frontv[i] = frontlerp*frame->scale[i];
|
|
||||||
backv[i] = backlerp*oldframe->scale[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Mesh_VertsRealloc(paliashdr->num_xyz))
|
|
||||||
{
|
|
||||||
ri.Sys_Error(ERR_FATAL, "%s: can't allocate memory", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
lerp = s_lerped[0];
|
|
||||||
|
|
||||||
Vk_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity );
|
|
||||||
|
|
||||||
int vertCounts[2] = { 0, 0 };
|
int vertCounts[2] = { 0, 0 };
|
||||||
int pipeCounters[2] = { 0, 0 };
|
int pipeCounters[2] = { 0, 0 };
|
||||||
VkDeviceSize maxTriangleFanIdxCnt = 0;
|
VkDeviceSize maxTriangleFanIdxCnt = 0;
|
||||||
|
@ -358,8 +296,11 @@ static void Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *s
|
||||||
|
|
||||||
// get the vertex count and primitive type
|
// get the vertex count and primitive type
|
||||||
count = *order++;
|
count = *order++;
|
||||||
if (!count)
|
if (!count || order >= order_end)
|
||||||
break; // done
|
{
|
||||||
|
break; /* done */
|
||||||
|
}
|
||||||
|
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
{
|
{
|
||||||
count = -count;
|
count = -count;
|
||||||
|
@ -489,6 +430,8 @@ static void Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *s
|
||||||
|
|
||||||
if (p == TRIANGLE_STRIP)
|
if (p == TRIANGLE_STRIP)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleStripIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleStripIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
for (i = 0; i < pipeCounters[p]; i++)
|
for (i = 0; i < pipeCounters[p]; i++)
|
||||||
|
@ -498,6 +441,8 @@ static void Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *s
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
for (i = 0; i < pipeCounters[p]; i++)
|
for (i = 0; i < pipeCounters[p]; i++)
|
||||||
|
@ -508,15 +453,109 @@ static void Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Vk_DrawAliasFrameLerp
|
||||||
|
|
||||||
|
interpolates between two frames and origins
|
||||||
|
FIXME: batch lerp all vertexes
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin,
|
||||||
|
float *modelMatrix, int leftHandOffset, int translucentIdx, entity_t *currententity)
|
||||||
|
{
|
||||||
|
daliasframe_t *frame, *oldframe;
|
||||||
|
dtrivertx_t *v, *ov, *verts;
|
||||||
|
int *order;
|
||||||
|
float frontlerp;
|
||||||
|
float alpha;
|
||||||
|
vec3_t move, delta, vectors[3];
|
||||||
|
vec3_t frontv, backv;
|
||||||
|
int i;
|
||||||
|
float *lerp;
|
||||||
|
int num_mesh_nodes;
|
||||||
|
short *mesh_nodes;
|
||||||
|
|
||||||
|
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
||||||
|
+ currententity->frame * paliashdr->framesize);
|
||||||
|
verts = v = frame->verts;
|
||||||
|
|
||||||
|
oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
||||||
|
+ currententity->oldframe * paliashdr->framesize);
|
||||||
|
ov = oldframe->verts;
|
||||||
|
|
||||||
|
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
|
||||||
|
|
||||||
|
if (currententity->flags & RF_TRANSLUCENT)
|
||||||
|
alpha = currententity->alpha;
|
||||||
|
else
|
||||||
|
alpha = 1.0;
|
||||||
|
|
||||||
|
frontlerp = 1.0 - backlerp;
|
||||||
|
|
||||||
|
// move should be the delta back to the previous frame * backlerp
|
||||||
|
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
|
||||||
|
AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
|
||||||
|
|
||||||
|
move[0] = DotProduct (delta, vectors[0]); // forward
|
||||||
|
move[1] = -DotProduct (delta, vectors[1]); // left
|
||||||
|
move[2] = DotProduct (delta, vectors[2]); // up
|
||||||
|
|
||||||
|
VectorAdd (move, oldframe->translate, move);
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
frontv[i] = frontlerp*frame->scale[i];
|
||||||
|
backv[i] = backlerp*oldframe->scale[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Mesh_VertsRealloc(paliashdr->num_xyz))
|
||||||
|
{
|
||||||
|
ri.Sys_Error(ERR_FATAL, "%s: can't allocate memory", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
lerp = s_lerped[0];
|
||||||
|
|
||||||
|
Vk_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity );
|
||||||
|
|
||||||
|
num_mesh_nodes = (paliashdr->ofs_skins - sizeof(dmdl_t)) / sizeof(short) / 2;
|
||||||
|
mesh_nodes = (short *)((char*)paliashdr + sizeof(dmdl_t));
|
||||||
|
|
||||||
|
if (num_mesh_nodes > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < num_mesh_nodes; i++)
|
||||||
|
{
|
||||||
|
Vk_DrawAliasFrameLerpCommands(currententity,
|
||||||
|
order + mesh_nodes[i * 2],
|
||||||
|
order + min(paliashdr->num_glcmds, mesh_nodes[i * 2] + mesh_nodes[i * 2 + 1]),
|
||||||
|
alpha, skin,
|
||||||
|
modelMatrix, leftHandOffset, translucentIdx, verts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vk_DrawAliasFrameLerpCommands(currententity,
|
||||||
|
order, order + paliashdr->num_glcmds, alpha, skin,
|
||||||
|
modelMatrix, leftHandOffset, translucentIdx, verts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
Vk_DrawAliasShadow
|
Vk_DrawAliasShadow
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
static void Vk_DrawAliasShadow (dmdl_t *paliashdr, int posenum, float *modelMatrix, entity_t *currententity)
|
static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
||||||
|
float *modelMatrix, entity_t *currententity)
|
||||||
{
|
{
|
||||||
int *order;
|
|
||||||
vec3_t point;
|
vec3_t point;
|
||||||
float height, lheight;
|
float height, lheight;
|
||||||
|
|
||||||
|
@ -524,8 +563,6 @@ static void Vk_DrawAliasShadow (dmdl_t *paliashdr, int posenum, float *modelMatr
|
||||||
|
|
||||||
height = 0;
|
height = 0;
|
||||||
|
|
||||||
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
|
|
||||||
|
|
||||||
height = -lheight + 1.0;
|
height = -lheight + 1.0;
|
||||||
|
|
||||||
uint32_t uboOffset;
|
uint32_t uboOffset;
|
||||||
|
@ -541,8 +578,11 @@ static void Vk_DrawAliasShadow (dmdl_t *paliashdr, int posenum, float *modelMatr
|
||||||
i = 0;
|
i = 0;
|
||||||
// get the vertex count and primitive type
|
// get the vertex count and primitive type
|
||||||
count = *order++;
|
count = *order++;
|
||||||
if (!count)
|
if (!count || order >= order_end)
|
||||||
break; // done
|
{
|
||||||
|
break; /* done */
|
||||||
|
}
|
||||||
|
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
{
|
{
|
||||||
count = -count;
|
count = -count;
|
||||||
|
@ -988,9 +1028,34 @@ void R_DrawAliasModel (entity_t *currententity, model_t *currentmodel)
|
||||||
|
|
||||||
if (vk_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL)))
|
if (vk_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL)))
|
||||||
{
|
{
|
||||||
|
int num_mesh_nodes;
|
||||||
|
short *mesh_nodes;
|
||||||
float model[16];
|
float model[16];
|
||||||
|
int *order;
|
||||||
|
|
||||||
Mat_Identity(model);
|
Mat_Identity(model);
|
||||||
R_RotateForEntity(currententity, model);
|
R_RotateForEntity(currententity, model);
|
||||||
Vk_DrawAliasShadow (paliashdr, currententity->frame, model, currententity);
|
|
||||||
|
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
|
||||||
|
|
||||||
|
num_mesh_nodes = (paliashdr->ofs_skins - sizeof(dmdl_t)) / sizeof(short) / 2;
|
||||||
|
mesh_nodes = (short *)((char*)paliashdr + sizeof(dmdl_t));
|
||||||
|
|
||||||
|
if (num_mesh_nodes > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < num_mesh_nodes; i++)
|
||||||
|
{
|
||||||
|
Vk_DrawAliasShadow (
|
||||||
|
order + mesh_nodes[i * 2],
|
||||||
|
order + min(paliashdr->num_glcmds, mesh_nodes[i * 2] + mesh_nodes[i * 2 + 1]),
|
||||||
|
currententity->frame, model, currententity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vk_DrawAliasShadow (order, order + paliashdr->num_glcmds,
|
||||||
|
currententity->frame, model, currententity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,6 +751,8 @@ Mod_ForName (const char *name, model_t *parent_model, qboolean crash)
|
||||||
|
|
||||||
switch (LittleLong(*(unsigned *)buf))
|
switch (LittleLong(*(unsigned *)buf))
|
||||||
{
|
{
|
||||||
|
case RAVENFMHEADER:
|
||||||
|
/* fall through */
|
||||||
case IDALIASHEADER:
|
case IDALIASHEADER:
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case IDMDLHEADER:
|
case IDMDLHEADER:
|
||||||
|
|
Loading…
Reference in a new issue