iqmtool now supports --static. Also embeds some multi-skin info.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6056 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
aa651c5059
commit
051442c041
3 changed files with 235 additions and 38 deletions
|
@ -7753,6 +7753,27 @@ struct iqmext_fte_event
|
|||
unsigned int evcode;
|
||||
unsigned int evdata_str; //stringtable
|
||||
};
|
||||
//skin lump is made of 3 parts
|
||||
struct iqmext_fte_skin
|
||||
{
|
||||
unsigned int numskinframes;
|
||||
unsigned int nummeshskins;
|
||||
//unsigned int numskins[nummeshes];
|
||||
//iqmext_fte_skin_skinframe[numskinframes];
|
||||
//iqmext_fte_skin_meshskin mesh0[numskins[0]];
|
||||
//iqmext_fte_skin_meshskin mesh1[numskins[1]]; etc
|
||||
};
|
||||
struct iqmext_fte_skin_skinframe
|
||||
{ //as many as needed
|
||||
unsigned int material_idx;
|
||||
unsigned int shadertext_idx;
|
||||
};
|
||||
struct iqmext_fte_skin_meshskin
|
||||
{
|
||||
unsigned int firstframe; //index into skinframes
|
||||
unsigned int countframes; //skinframes
|
||||
float interval;
|
||||
};
|
||||
/*struct iqmext_fte_shader
|
||||
{
|
||||
unsigned int material;
|
||||
|
@ -8093,6 +8114,10 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
const struct iqmext_fte_event *fteevents;
|
||||
const char *strings;
|
||||
|
||||
const unsigned int *fteskincount;
|
||||
const struct iqmext_fte_skin_meshskin *fteskins;
|
||||
const struct iqmext_fte_skin_skinframe *fteskinframes;
|
||||
|
||||
unsigned int i, j, t, numtris, numverts, firstvert, firsttri;
|
||||
size_t extsize;
|
||||
|
||||
|
@ -8119,8 +8144,6 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
|
||||
galiasinfo_t *gai=NULL;
|
||||
#ifndef SERVERONLY
|
||||
galiasskin_t *skin=NULL;
|
||||
skinframe_t *skinframe=NULL;
|
||||
int skinfiles;
|
||||
#endif
|
||||
galiasanimation_t *fgroup=NULL;
|
||||
|
@ -8302,8 +8325,6 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
dalloc(orgbaf, h->num_vertexes);
|
||||
else
|
||||
orgbaf = NULL;
|
||||
dalloc(skin, h->num_meshes*skinfiles);
|
||||
dalloc(skinframe, h->num_meshes*skinfiles);
|
||||
#endif
|
||||
dalloc(fgroup, numgroups);
|
||||
dalloc(oposebase, 12*h->num_joints);
|
||||
|
@ -8483,6 +8504,17 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
if (!extsize || extsize != sizeof(*ftemesh)*h->num_meshes)
|
||||
ftemesh = NULL; //erk.
|
||||
|
||||
fteskincount = IQM_FindExtension(buffer, fsize, "FTE_SKINS", 0, &extsize);
|
||||
if (extsize >= sizeof(unsigned int)*(2+h->num_meshes) && extsize == sizeof(struct iqmext_fte_skin) + sizeof(unsigned int)*h->num_meshes + LittleLong(fteskincount[0])*sizeof(*fteskinframes) + LittleLong(fteskincount[1])*sizeof(*fteskins))
|
||||
{
|
||||
unsigned int numskinframes = LittleLong(*fteskincount++);
|
||||
/*unsigned int numskins = LittleLong(* */fteskincount++;
|
||||
|
||||
fteskinframes = (const struct iqmext_fte_skin_skinframe*)(fteskincount+h->num_meshes);
|
||||
fteskins = (const struct iqmext_fte_skin_meshskin*)(fteskinframes+numskinframes);
|
||||
}
|
||||
else fteskincount = NULL, fteskins = NULL, fteskinframes = NULL;
|
||||
|
||||
for (i = 0; i < max(1, h->num_meshes); i++)
|
||||
{
|
||||
if (h->num_meshes)
|
||||
|
@ -8519,22 +8551,55 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
/*skins*/
|
||||
if (h->num_meshes)
|
||||
{
|
||||
gai[i].numskins = skinfiles;
|
||||
gai[i].ofsskins = skin;
|
||||
galiasskin_t *skin;
|
||||
skinframe_t *skinframe;
|
||||
unsigned int iqmskins = fteskincount?LittleLong(*fteskincount++):0;
|
||||
gai[i].numskins = max(iqmskins,skinfiles);
|
||||
gai[i].ofsskins = skin = ZG_Malloc(&mod->memgroup, sizeof(*gai[i].ofsskins)*gai[i].numskins);
|
||||
|
||||
for (j = 0; j < skinfiles; j++)
|
||||
for (j = 0; j < gai[i].numskins; j++, skin++)
|
||||
{
|
||||
const struct iqmext_fte_skin_skinframe *sf;
|
||||
if (j < iqmskins)
|
||||
{
|
||||
sf = fteskinframes + LittleLong(fteskins->firstframe);
|
||||
fteskins++;
|
||||
}
|
||||
else
|
||||
sf = NULL;
|
||||
|
||||
skin->skinwidth = 1;
|
||||
skin->skinheight = 1;
|
||||
skin->skinspeed = 10; /*something to avoid div by 0*/
|
||||
skin->numframes = 1; //non-sequenced skins.
|
||||
skin->frame = skinframe;
|
||||
Q_strncpyz(skin->name, "", sizeof(skinframe->shadername));
|
||||
skin++;
|
||||
Q_snprintfz(gai[i].ofsskins[j].name, sizeof(gai[i].ofsskins[j].name), "%i", j);
|
||||
if (sf)
|
||||
{
|
||||
skin->skinspeed = 1.0/LittleFloat(fteskins[-1].interval); /*something to avoid div by 0*/
|
||||
skin->numframes = LittleLong(fteskins[-1].countframes); //non-sequenced skins.
|
||||
|
||||
Q_strncpyz(skinframe->shadername, strings+mesh[i].material, sizeof(skinframe->shadername));
|
||||
skinframe++;
|
||||
if (!skin->numframes)
|
||||
continue;
|
||||
|
||||
skin->frame = ZG_Malloc(&mod->memgroup, sizeof(*skin->frame)*skin->numframes);
|
||||
for (t = 0; t < skin->numframes; t++, sf++)
|
||||
{
|
||||
Q_strncpyz(skin->frame[t].shadername, strings+sf->material_idx, sizeof(skin->frame[t].shadername));
|
||||
if (sf->shadertext_idx && sf->shadertext_idx<h->num_text)
|
||||
{
|
||||
const char *stxt = strings+sf->shadertext_idx;
|
||||
skin->frame[t].defaultshader = strcpy(ZG_Malloc(&mod->memgroup, strlen(stxt)+1), stxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skin->skinspeed = 10; //something to avoid div by 0
|
||||
skin->numframes = 1; //non-sequenced skins.
|
||||
|
||||
skin->frame = skinframe = ZG_Malloc(&mod->memgroup, sizeof(*skin->frame)*skin->numframes);
|
||||
Q_strncpyz(skinframe->shadername, strings+mesh[i].material, sizeof(skinframe->shadername));
|
||||
}
|
||||
}
|
||||
gai[i].numskins = skin-gai[i].ofsskins;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
157
iqm/iqm.cpp
157
iqm/iqm.cpp
|
@ -17,6 +17,7 @@
|
|||
bool noext = false;
|
||||
bool verbose = false;
|
||||
bool quiet = false;
|
||||
bool stripbones = false; //strip all bone+anim info.
|
||||
|
||||
struct ejoint
|
||||
{
|
||||
|
@ -32,7 +33,7 @@ struct ejoint
|
|||
struct triangle { uint vert[3]; triangle() {} triangle(uint v0, uint v1, uint v2) { vert[0] = v0; vert[1] = v1; vert[2] = v2; } };
|
||||
vector<triangle> triangles, neighbors;
|
||||
|
||||
struct mesh { uint name, material; uint firstvert, numverts; uint firsttri, numtris; mesh() : name(0), material(0), firstvert(0), numverts(0), firsttri(0), numtris(0) {} };
|
||||
struct mesh { uint name, material, numskins; uint firstvert, numverts; uint firsttri, numtris; mesh() : name(0), material(0), firstvert(0), numverts(0), firsttri(0), numtris(0) {} };
|
||||
vector<mesh> meshes;
|
||||
|
||||
struct meshprop
|
||||
|
@ -59,6 +60,9 @@ struct event_fte
|
|||
};
|
||||
vector<event_fte> events_fte;
|
||||
|
||||
vector<iqmext_fte_skin_meshskin> meshskins;
|
||||
vector<iqmext_fte_skin_skinframe> skinframes;
|
||||
|
||||
struct anim { uint name; uint firstframe, numframes; float fps; uint flags; anim() : name(0), firstframe(0), numframes(0), fps(0), flags(0) {} };
|
||||
vector<anim> anims;
|
||||
|
||||
|
@ -1127,8 +1131,8 @@ void printlastmesh(void)
|
|||
return;
|
||||
mesh &m = meshes[meshes.length()-1];
|
||||
meshprop &fm = meshes_fte[meshes.length()-1];
|
||||
printf(" %smesh %i:\tname=\"%s\",\tmat=\"%s\",\ttri=%i, vert=%i\n", fm.contents?"c":"r", meshes.length()-1,
|
||||
&stringdata[m.name], &stringdata[m.material], m.numtris, m.numverts);
|
||||
printf(" %smesh %i:\tname=\"%s\",\tmat=\"%s\",\ttri=%i, vert=%i, skins=%i\n", fm.contents?"c":"r", meshes.length()-1,
|
||||
&stringdata[m.name], &stringdata[m.material], m.numtris, m.numverts, m.numskins);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
|
@ -1232,6 +1236,41 @@ void makemeshes(const filespec &spec)
|
|||
maketriangles(tinfo, mmap);
|
||||
m.numtris = triangles.length() - m.firsttri;
|
||||
m.numverts = numfverts+vmap.length() - m.firstvert;
|
||||
m.numskins = 0; //we have a default material, so no worries.
|
||||
|
||||
if (spec.materialsuffix && !strncmp(spec.materialsuffix, "_00_00", 6))
|
||||
{ //for qex... populate our skins info
|
||||
for (int s = 0; ; s++)
|
||||
{
|
||||
char matname[512];
|
||||
formatstring(matname, "%s%s_%02d_%02d%s", spec.materialprefix?spec.materialprefix:"", em1.material, s, 0, spec.materialsuffix+6);
|
||||
FILE *f = fopen(matname, "rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f); //don't really care.
|
||||
auto &skin = meshskins.add();
|
||||
m.numskins++;
|
||||
skin.firstframe = skinframes.length();
|
||||
skin.countframes = 1;
|
||||
skin.interval = 0.2;
|
||||
|
||||
auto &skinframe = skinframes.add();
|
||||
skinframe.material_idx = sharestring(matname);
|
||||
skinframe.shadertext_idx = 0;
|
||||
for (skin.countframes = 1; ; skin.countframes++)
|
||||
{
|
||||
formatstring(matname, "%s%s_%02d_%02d%s", spec.materialprefix?spec.materialprefix:"", em1.material, s, skin.countframes, spec.materialsuffix+6);
|
||||
f = fopen(matname, "rb");
|
||||
if (!f)
|
||||
break;
|
||||
fclose(f);
|
||||
auto &skinframe = skinframes.add();
|
||||
skinframe.material_idx = sharestring(matname);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
meshprop &mf = meshes_fte.add();
|
||||
mf = em1.explicits;
|
||||
|
@ -1272,7 +1311,7 @@ void makemeshes(const filespec &spec)
|
|||
calctangents(priortris);
|
||||
setupvertexarray<IQM_TANGENT>(etangents, IQM_TANGENT, IQM_FLOAT, 4, priorverts);
|
||||
}
|
||||
if(eblends.length())
|
||||
if(eblends.length() && !stripbones)
|
||||
{
|
||||
if (ejoints.length() > 65535)
|
||||
setupvertexarray<IQM_BLENDINDEXES>(eblends, IQM_BLENDINDEXES, IQM_UINT, 4, priorverts);
|
||||
|
@ -4718,6 +4757,17 @@ bool writeiqm(const char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
iqmextension *ext_skins_fte = NULL;
|
||||
if (meshskins.length())
|
||||
{
|
||||
ext_skins_fte = &extensions.add();
|
||||
ext_skins_fte->name = sharestring("FTE_SKINS");
|
||||
ext_skins_fte->num_data = sizeof(iqmext_fte_skin);
|
||||
ext_skins_fte->num_data += meshes.length()*sizeof(uint);
|
||||
ext_skins_fte->num_data += skinframes.length()*sizeof(iqmext_fte_skin_skinframe);
|
||||
ext_skins_fte->num_data += meshskins.length()*sizeof(iqmext_fte_skin_meshskin);
|
||||
}
|
||||
|
||||
if(stringdata.length()) hdr.ofs_text = hdr.filesize, hdr.num_text = stringdata.length(), hdr.filesize += hdr.num_text;
|
||||
hdr.num_meshes = meshes.length(); if(meshes.length()) hdr.ofs_meshes = hdr.filesize; hdr.filesize += meshes.length() * sizeof(iqmmesh);
|
||||
uint voffset = hdr.filesize + varrays.length() * sizeof(iqmvertexarray);
|
||||
|
@ -4738,6 +4788,7 @@ bool writeiqm(const char *filename)
|
|||
if (extensions.length()) hdr.ofs_extensions = hdr.filesize, hdr.num_extensions = extensions.length(), hdr.filesize += sizeof(iqmextension) * hdr.num_extensions;
|
||||
if (ext_meshes_fte) ext_meshes_fte->ofs_data = hdr.filesize, ext_meshes_fte->num_data = meshes_fte.length()*sizeof(iqmext_fte_mesh), hdr.filesize += ext_meshes_fte->num_data;
|
||||
if (ext_events_fte) ext_events_fte->ofs_data = hdr.filesize, ext_events_fte->num_data = events_fte.length()*sizeof(iqmext_fte_events), hdr.filesize += ext_events_fte->num_data;
|
||||
if (ext_skins_fte) ext_skins_fte->ofs_data = hdr.filesize, hdr.filesize += ext_skins_fte->num_data;
|
||||
|
||||
lilswap(&hdr.version, (sizeof(hdr) - sizeof(hdr.magic))/sizeof(uint));
|
||||
|
||||
|
@ -4856,6 +4907,24 @@ bool writeiqm(const char *filename)
|
|||
f->putlil(ev.evdata_idx);
|
||||
}
|
||||
|
||||
if (ext_skins_fte)
|
||||
{
|
||||
f->putlil(skinframes.length());
|
||||
f->putlil(meshskins.length());
|
||||
loopv(meshes) f->putlil(meshes[i].numskins);
|
||||
loopv(skinframes)
|
||||
{
|
||||
f->putlil(skinframes[i].material_idx);
|
||||
f->putlil(skinframes[i].shadertext_idx);
|
||||
}
|
||||
loopv(meshskins)
|
||||
{
|
||||
f->putlil(meshskins[i].firstframe);
|
||||
f->putlil(meshskins[i].countframes);
|
||||
f->putlil(meshskins[i].interval);
|
||||
}
|
||||
}
|
||||
|
||||
delete f;
|
||||
return true;
|
||||
}
|
||||
|
@ -5366,7 +5435,7 @@ static void help(bool exitstatus, bool fullhelp)
|
|||
"./iqmtool [options] output.iqm mesh.fbx anim1.fbx ... animN.fbx\n"
|
||||
"./iqmtool [options] output.iqm mesh.obj\n"
|
||||
"./iqmtool [options] output.iqm source.gltf\n"
|
||||
"./iqmtool [options] output.iqm --kex sources.md5\n"
|
||||
"./iqmtool [options] output.iqm --qex sources.md5\n"
|
||||
"\n"
|
||||
"Basic commandline options:\n"
|
||||
" --help Show full help.\n"
|
||||
|
@ -5392,7 +5461,7 @@ static void help(bool exitstatus, bool fullhelp)
|
|||
" -j\n"
|
||||
" --forcejoints Forces the exporting of joint information in animation\n"
|
||||
" files without meshes.\n"
|
||||
" --kex Applies a set of fixups to work around the quirks in\n"
|
||||
" --qex Applies a set of fixups to work around the quirks in\n"
|
||||
" the quake rerelease's md5 files.\n"
|
||||
"\n"
|
||||
"Legacy commandline options that affect the following animation file:\n"
|
||||
|
@ -5516,7 +5585,6 @@ unsigned int parsebits(bitnames *names, char **line)
|
|||
comma = strchr(value, ',');
|
||||
if (comma)
|
||||
*comma++ = 0;
|
||||
|
||||
char *end;
|
||||
strtoul(value, &end, 0);
|
||||
if (end && !*end)
|
||||
|
@ -5535,7 +5603,7 @@ unsigned int parsebits(bitnames *names, char **line)
|
|||
}
|
||||
for (i = 0; names[i].name; i++)
|
||||
{
|
||||
if (!*std || !strcasecmp(names[i].std, std))
|
||||
if (!strcasecmp(names[i].std, std))
|
||||
{
|
||||
if (!strcasecmp(names[i].name, value))
|
||||
{
|
||||
|
@ -5546,7 +5614,7 @@ unsigned int parsebits(bitnames *names, char **line)
|
|||
}
|
||||
if (!names[i].name)
|
||||
{ //stuff with no specific standard, mostly for consistency
|
||||
if (!*names[i].std)
|
||||
for (i = 0; names[i].name; i++)
|
||||
{
|
||||
if (!strcasecmp(names[i].name, value))
|
||||
{
|
||||
|
@ -5693,7 +5761,7 @@ bool parseanimfield(const char *tok, char **line, filespec &spec, bool defaults)
|
|||
return true;
|
||||
}
|
||||
|
||||
struct
|
||||
static struct
|
||||
{
|
||||
const char *extname;
|
||||
bool (*write)(const char *filename);
|
||||
|
@ -5708,6 +5776,45 @@ struct
|
|||
{".md3", writemd3, "output_md3"},
|
||||
};
|
||||
|
||||
static bitnames modelflagnames[] = {
|
||||
{"q1", "rocket", 1u<<0},
|
||||
{"q1", "grenade", 1u<<1},
|
||||
{"q1", "gib", 1u<<2},
|
||||
{"q1", "rotate", 1u<<3},
|
||||
{"q1", "tracer1", 1u<<4},
|
||||
{"q1", "zomgib", 1u<<5},
|
||||
{"q1", "tracer2", 1u<<6},
|
||||
{"q1", "tracer3", 1u<<7},
|
||||
{"q1", "holey", 1u<<14}, //common extension
|
||||
|
||||
{"h2", "spidergib", 1u<<0}, //conflicts with q1.
|
||||
{"h2", "grenade", 1u<<1},
|
||||
{"h2", "gib", 1u<<2},
|
||||
{"h2", "rotate", 1u<<3},
|
||||
{"h2", "tracer1", 1u<<4},
|
||||
{"h2", "zomgib", 1u<<5},
|
||||
{"h2", "tracer2", 1u<<6},
|
||||
{"h2", "tracer3", 1u<<7},
|
||||
{"h2", "fireball", 1u<<8},
|
||||
{"h2", "ice", 1u<<9},
|
||||
{"h2", "mipmap", 1u<<10},
|
||||
{"h2", "spit", 1u<<11},
|
||||
{"h2", "transparent", 1u<<12},
|
||||
{"h2", "spell", 1u<<13},
|
||||
{"h2", "holey", 1u<<14},
|
||||
{"h2", "specialtrans", 1u<<15},
|
||||
{"h2", "faceview", 1u<<16},
|
||||
{"h2", "vorpmissile", 1u<<17},
|
||||
{"h2", "setstaff", 1u<<18},
|
||||
{"h2", "magicmissle", 1u<<19},
|
||||
{"h2", "boneshard", 1u<<20},
|
||||
{"h2", "scarab", 1u<<21},
|
||||
{"h2", "acidball", 1u<<22},
|
||||
{"h2", "bloodshot", 1u<<23},
|
||||
|
||||
{NULL}
|
||||
};
|
||||
|
||||
void parsecommands(char *filename, const char *outfiles[countof(outputtypes)], vector<filespec> &infiles, vector<hitbox> &hitboxes)
|
||||
{
|
||||
filespec defaultspec;
|
||||
|
@ -5753,20 +5860,9 @@ void parsecommands(char *filename, const char *outfiles[countof(outputtypes)], v
|
|||
else if (!strcasecmp(tok, "exec"))
|
||||
parsecommands(mystrtok(&line), outfiles, infiles, hitboxes);
|
||||
else if (!strcasecmp(tok, "modelflags"))
|
||||
{
|
||||
bitnames modelflagnames[] = {
|
||||
{"q1", "rocket", 0x01},
|
||||
{"q1", "grenade", 0x02},
|
||||
{"q1", "gib", 0x04},
|
||||
{"q1", "rotate", 0x08},
|
||||
{"q1", "tracer1", 0x10},
|
||||
{"q1", "zomgib", 0x20},
|
||||
{"q1", "tracer2", 0x40},
|
||||
{"q1", "tracer3", 0x80},
|
||||
{NULL}
|
||||
};
|
||||
modelflags = parsebits(modelflagnames, &line);
|
||||
}
|
||||
else if (!strcasecmp(tok, "static"))
|
||||
stripbones = true;
|
||||
|
||||
else if (parseanimfield(tok, &line, defaultspec, true))
|
||||
;
|
||||
|
@ -5905,7 +6001,9 @@ int main(int argc, char **argv)
|
|||
else if(!strcasecmp(&argv[i][2], "forcejoints")) forcejoints = true;
|
||||
else if(!strcasecmp(&argv[i][2], "materialprefix")) { if(i + 1 < argc) inspec.materialprefix = argv[++i]; }
|
||||
else if(!strcasecmp(&argv[i][2], "materialsuffix")) { if(i + 1 < argc) inspec.materialsuffix = argv[++i]; }
|
||||
else if(!strcasecmp(&argv[i][2], "kex")) inspec.materialprefix = "progs/", inspec.materialsuffix = "_00_00.lmp", inspec.flags |= IQM_UNPACK;
|
||||
else if(!strcasecmp(&argv[i][2], "qex")) inspec.materialprefix = "progs/", inspec.materialsuffix = "_00_00.lmp", inspec.flags |= IQM_UNPACK;
|
||||
else if(!strcasecmp(&argv[i][2], "modelflags")) { if(i + 1 < argc) { modelflags |= parsebits(modelflagnames, &argv[++i]); }}
|
||||
else if(!strcasecmp(&argv[i][2], "static")) stripbones = true;
|
||||
else if(!strcasecmp(&argv[i][2], "meshtrans"))
|
||||
{
|
||||
if(i + 1 < argc) switch(sscanf(argv[++i], "%lf , %lf , %lf", &gmeshtrans.x, &gmeshtrans.y, &gmeshtrans.z))
|
||||
|
@ -6050,6 +6148,17 @@ int main(int argc, char **argv)
|
|||
conoutf("warning: mesh \"%s\" overriden, but not present", meshoverrides[i].name);
|
||||
|
||||
|
||||
if (stripbones)
|
||||
{
|
||||
if (!quiet)
|
||||
conoutf("static bones");
|
||||
joints.setsize(0);
|
||||
poses.setsize(0);
|
||||
frames.setsize(0);
|
||||
anims.setsize(0);
|
||||
bounds.setsize(0);
|
||||
}
|
||||
|
||||
calcanimdata();
|
||||
|
||||
if (!quiet)
|
||||
|
|
23
iqm/iqm.h
23
iqm/iqm.h
|
@ -147,5 +147,28 @@ struct iqmext_fte_events
|
|||
unsigned int evcode;
|
||||
unsigned int evdata_str;
|
||||
};
|
||||
|
||||
|
||||
//skin lump is made of 3 parts
|
||||
struct iqmext_fte_skin
|
||||
{
|
||||
unsigned int nummeshskins;
|
||||
unsigned int numskinframes;
|
||||
//unsigned int numskins[nummeshes];
|
||||
//iqmext_fte_skin_skinframe[numskinframes];
|
||||
//iqmext_fte_skin_meshskin mesh0[numskins[0]];
|
||||
//iqmext_fte_skin_meshskin mesh1[numskins[1]]; etc
|
||||
};
|
||||
struct iqmext_fte_skin_skinframe
|
||||
{ //as many as needed
|
||||
unsigned int material_idx;
|
||||
unsigned int shadertext_idx;
|
||||
};
|
||||
struct iqmext_fte_skin_meshskin
|
||||
{
|
||||
unsigned int firstframe; //index into skinframes
|
||||
unsigned int countframes; //skinframes
|
||||
float interval;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue