X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=model_alias.c;h=e80ee4dbac4fc956389b3f6a6c3cdfa842a65e24;hb=929f9a6fe217e9c8ca40a68a5229b08400233946;hp=5c09eeb4413ab17cf9f5551756abf39f7f61fee8;hpb=ff5947f97081e10c4ce112d4d51c2d1fa14ebba8;p=xonotic%2Fdarkplaces.git diff --git a/model_alias.c b/model_alias.c index 5c09eeb4..e80ee4db 100644 --- a/model_alias.c +++ b/model_alias.c @@ -95,7 +95,7 @@ static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, Con_Printf("Mod_ConvertAliasVerts: \"%s\", %i invalid normal indices found\n", loadmodel->name, invalidnormals); } -static void Mod_MDL_LoadFrames (long datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate) +static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate) { daliasframetype_t *pframetype; daliasframe_t *pinframe; @@ -160,10 +160,10 @@ static void Mod_MDL_LoadFrames (long datapointer, int inverts, int outverts, vec } } -static rtexture_t *GL_SkinSplitShirt(byte *in, byte *out, int width, int height, int bits, char *name, int precache) +static rtexture_t *GL_SkinSplitShirt(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache) { int i, pixels, passed; - byte pixeltest[16]; + qbyte pixeltest[16]; for (i = 0;i < 16;i++) pixeltest[i] = (bits & (1 << i)) != 0; pixels = width*height; @@ -190,10 +190,10 @@ static rtexture_t *GL_SkinSplitShirt(byte *in, byte *out, int width, int height, return NULL; } -static rtexture_t *GL_SkinSplit(byte *in, byte *out, int width, int height, int bits, char *name, int precache) +static rtexture_t *GL_SkinSplit(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache) { int i, pixels, passed; - byte pixeltest[16]; + qbyte pixeltest[16]; for (i = 0;i < 16;i++) pixeltest[i] = (bits & (1 << i)) != 0; pixels = width*height; @@ -216,7 +216,7 @@ static rtexture_t *GL_SkinSplit(byte *in, byte *out, int width, int height, int return NULL; } -static void Mod_LoadSkin (char *basename, byte *skindata, byte *skintemp, int width, int height, skinframe_t *skinframe, int precache) +static void Mod_LoadSkin (char *basename, qbyte *skindata, qbyte *skintemp, int width, int height, skinframe_t *skinframe, int precache) { skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, r_mipskins.integer, precache); skinframe->fog = image_masktex; @@ -265,13 +265,13 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) daliasframetype_t *pinframetype; daliasgroup_t *pinframegroup; float scales, scalet, scale[3], translate[3], interval; - long datapointer, startframes, startskins; + qbyte *datapointer, *startframes, *startskins; char name[MAX_QPATH]; - byte *skintemp = NULL; + qbyte *skintemp = NULL; modelyawradius = 0; modelradius = 0; - datapointer = (long) buffer; + datapointer = buffer; pinmodel = (mdl_t *)datapointer; datapointer += sizeof(mdl_t); @@ -281,7 +281,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) loadmodel->name, version, ALIAS_VERSION); loadmodel->type = mod_alias; - loadmodel->aliastype = ALIASTYPE_MDL; + loadmodel->aliastype = ALIASTYPE_MDLMD2; loadmodel->numskins = LittleLong(pinmodel->numskins); BOUNDI(loadmodel->numskins,0,256); @@ -401,7 +401,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) sprintf (name, "%s_%i_%i", loadmodel->name, i, j); else sprintf (name, "%s_%i", loadmodel->name, i); - Mod_LoadSkin(name, (byte *)datapointer, skintemp, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0); + Mod_LoadSkin(name, (qbyte *)datapointer, skintemp, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0); datapointer += skinwidth * skinheight; totalskins++; } @@ -423,7 +423,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) } // load triangle data - loadmodel->mdldata_indices = Mem_Alloc(loadmodel->mempool, sizeof(int[3]) * loadmodel->numtris); + loadmodel->mdlmd2data_indices = Mem_Alloc(loadmodel->mempool, sizeof(int[3]) * loadmodel->numtris); // count the vertices used for (i = 0;i < numverts*2;i++) @@ -461,16 +461,16 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) // remap the triangle references for (i = 0;i < loadmodel->numtris;i++) { - loadmodel->mdldata_indices[i*3+0] = vertremap[temptris[i][0]]; - loadmodel->mdldata_indices[i*3+1] = vertremap[temptris[i][1]]; - loadmodel->mdldata_indices[i*3+2] = vertremap[temptris[i][2]]; + loadmodel->mdlmd2data_indices[i*3+0] = vertremap[temptris[i][0]]; + loadmodel->mdlmd2data_indices[i*3+1] = vertremap[temptris[i][1]]; + loadmodel->mdlmd2data_indices[i*3+2] = vertremap[temptris[i][2]]; } // store the texture coordinates - loadmodel->mdldata_texcoords = Mem_Alloc(loadmodel->mempool, sizeof(float[2]) * totalverts); + loadmodel->mdlmd2data_texcoords = Mem_Alloc(loadmodel->mempool, sizeof(float[2]) * totalverts); for (i = 0;i < totalverts;i++) { - loadmodel->mdldata_texcoords[i*2+0] = vertst[i][0]; - loadmodel->mdldata_texcoords[i*2+1] = vertst[i][1]; + loadmodel->mdlmd2data_texcoords[i*2+0] = vertst[i][0]; + loadmodel->mdlmd2data_texcoords[i*2+1] = vertst[i][1]; } // load the frames @@ -507,17 +507,19 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) loadmodel->DrawShadow = NULL; } -static void Mod_MD2_ConvertVerts (int numverts, vec3_t scale, vec3_t translate, trivertx_t *v, trivertx_t *out) +static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, trivertx_t *out, int *vertremap) { int i, invalidnormals = 0; float dist; + trivertx_t *in; vec3_t temp; - for (i = 0;i < numverts;i++) + for (i = 0;i < loadmodel->numverts;i++) { - VectorCopy(v[i].v, out[i].v); - temp[0] = v[i].v[0] * scale[0] + translate[0]; - temp[1] = v[i].v[1] * scale[1] + translate[1]; - temp[2] = v[i].v[2] * scale[2] + translate[2]; + in = v + vertremap[i]; + VectorCopy(in->v, out[i].v); + temp[0] = in->v[0] * scale[0] + translate[0]; + temp[1] = in->v[1] * scale[1] + translate[1]; + temp[2] = in->v[2] * scale[2] + translate[2]; // update bounding box if (temp[0] < aliasbboxmin[0]) aliasbboxmin[0] = temp[0]; if (temp[1] < aliasbboxmin[1]) aliasbboxmin[1] = temp[1]; @@ -531,7 +533,7 @@ static void Mod_MD2_ConvertVerts (int numverts, vec3_t scale, vec3_t translate, dist += temp[2]*temp[2]; if (modelradius < dist) modelradius = dist; - out[i].lightnormalindex = v[i].lightnormalindex; + out[i].lightnormalindex = in->lightnormalindex; if (out[i].lightnormalindex >= NUMVERTEXNORMALS) { invalidnormals++; @@ -542,58 +544,75 @@ static void Mod_MD2_ConvertVerts (int numverts, vec3_t scale, vec3_t translate, Con_Printf("Mod_MD2_ConvertVerts: \"%s\", %i invalid normal indices found\n", loadmodel->name, invalidnormals); } -void Mod_MD2_ReadHeader(md2_t *in, int *numglcmds) +void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) { + int *vertremap; + md2_t *pinmodel; + qbyte *base; int version, end; + int i, j, k, hashindex, num, numxyz, numst, xyz, st; + float *stverts, s, t; + struct md2verthash_s + { + struct md2verthash_s *next; + int xyz; + float st[2]; + } + *hash, **md2verthash, *md2verthashdata; + qbyte *datapointer; + md2frame_t *pinframe; + char *inskin; + md2triangle_t *intri; + unsigned short *inst; + int skinwidth, skinheight; + + pinmodel = buffer; + base = buffer; - version = LittleLong (in->version); + version = LittleLong (pinmodel->version); if (version != MD2ALIAS_VERSION) Host_Error ("%s has wrong version number (%i should be %i)", loadmodel->name, version, MD2ALIAS_VERSION); loadmodel->type = mod_alias; - loadmodel->aliastype = ALIASTYPE_MD2; + loadmodel->aliastype = ALIASTYPE_MDLMD2; loadmodel->SERAddEntity = Mod_Alias_SERAddEntity; loadmodel->Draw = R_DrawAliasModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; - if (LittleLong(in->num_tris < 1) || LittleLong(in->num_tris) > MD2MAX_TRIANGLES) - Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(in->num_tris)); - if (LittleLong(in->num_xyz < 1) || LittleLong(in->num_xyz) > MD2MAX_VERTS) - Host_Error ("%s has invalid number of vertices: %i", loadmodel->name, LittleLong(in->num_xyz)); - if (LittleLong(in->num_frames < 1) || LittleLong(in->num_frames) > MD2MAX_FRAMES) - Host_Error ("%s has invalid number of frames: %i", loadmodel->name, LittleLong(in->num_frames)); - if (LittleLong(in->num_skins < 0) || LittleLong(in->num_skins) > MAX_SKINS) - Host_Error ("%s has invalid number of skins: %i", loadmodel->name, LittleLong(in->num_skins)); - - end = LittleLong(in->ofs_end); - if (LittleLong(in->num_skins) >= 1 && (LittleLong(in->ofs_skins <= 0) || LittleLong(in->ofs_skins) >= end)) + if (LittleLong(pinmodel->num_tris < 1) || LittleLong(pinmodel->num_tris) > MD2MAX_TRIANGLES) + Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(pinmodel->num_tris)); + if (LittleLong(pinmodel->num_xyz < 1) || LittleLong(pinmodel->num_xyz) > MD2MAX_VERTS) + Host_Error ("%s has invalid number of vertices: %i", loadmodel->name, LittleLong(pinmodel->num_xyz)); + if (LittleLong(pinmodel->num_frames < 1) || LittleLong(pinmodel->num_frames) > MD2MAX_FRAMES) + Host_Error ("%s has invalid number of frames: %i", loadmodel->name, LittleLong(pinmodel->num_frames)); + if (LittleLong(pinmodel->num_skins < 0) || LittleLong(pinmodel->num_skins) > MAX_SKINS) + Host_Error ("%s has invalid number of skins: %i", loadmodel->name, LittleLong(pinmodel->num_skins)); + + end = LittleLong(pinmodel->ofs_end); + if (LittleLong(pinmodel->num_skins) >= 1 && (LittleLong(pinmodel->ofs_skins <= 0) || LittleLong(pinmodel->ofs_skins) >= end)) Host_Error ("%s is not a valid model", loadmodel->name); - if (LittleLong(in->ofs_st <= 0) || LittleLong(in->ofs_st) >= end) + if (LittleLong(pinmodel->ofs_st <= 0) || LittleLong(pinmodel->ofs_st) >= end) Host_Error ("%s is not a valid model", loadmodel->name); - if (LittleLong(in->ofs_tris <= 0) || LittleLong(in->ofs_tris) >= end) + if (LittleLong(pinmodel->ofs_tris <= 0) || LittleLong(pinmodel->ofs_tris) >= end) Host_Error ("%s is not a valid model", loadmodel->name); - if (LittleLong(in->ofs_frames <= 0) || LittleLong(in->ofs_frames) >= end) + if (LittleLong(pinmodel->ofs_frames <= 0) || LittleLong(pinmodel->ofs_frames) >= end) Host_Error ("%s is not a valid model", loadmodel->name); - if (LittleLong(in->ofs_glcmds <= 0) || LittleLong(in->ofs_glcmds) >= end) + if (LittleLong(pinmodel->ofs_glcmds <= 0) || LittleLong(pinmodel->ofs_glcmds) >= end) Host_Error ("%s is not a valid model", loadmodel->name); - loadmodel->numskins = LittleLong(in->num_skins); - loadmodel->numverts = LittleLong(in->num_xyz); -// loadmodel->md2num_st = LittleLong(in->num_st); - loadmodel->numtris = LittleLong(in->num_tris); - loadmodel->numframes = LittleLong(in->num_frames); - *numglcmds = LittleLong(in->num_glcmds); + loadmodel->numskins = LittleLong(pinmodel->num_skins); + numxyz = LittleLong(pinmodel->num_xyz); + numst = LittleLong(pinmodel->num_st); + loadmodel->numtris = LittleLong(pinmodel->num_tris); + loadmodel->numframes = LittleLong(pinmodel->num_frames); loadmodel->flags = 0; // there are no MD2 flags loadmodel->synctype = ST_RAND; -} -void Mod_MD2_LoadSkins(char *in) -{ - int i; -// load the skins + // load the skins + inskin = (void*)(base + LittleLong(pinmodel->ofs_skins)); if (loadmodel->numskins) { loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins); @@ -604,51 +623,103 @@ void Mod_MD2_LoadSkins(char *in) loadmodel->skinscenes[i].framecount = 1; loadmodel->skinscenes[i].loop = true; loadmodel->skinscenes[i].framerate = 10; - loadmodel->skinframes[i].base = loadtextureimagewithmask (loadmodel->texturepool, in, 0, 0, true, r_mipskins.integer, true); + loadmodel->skinframes[i].base = loadtextureimagewithmask (loadmodel->texturepool, inskin, 0, 0, true, r_mipskins.integer, true); loadmodel->skinframes[i].fog = image_masktex; loadmodel->skinframes[i].pants = NULL; loadmodel->skinframes[i].shirt = NULL; loadmodel->skinframes[i].glow = NULL; loadmodel->skinframes[i].merged = NULL; - in += MD2MAX_SKINNAME; + inskin += MD2MAX_SKINNAME; } } -} -/* -void Mod_MD2_LoadTriangles(md2triangle_t *in) -{ - int i, j; - loadmodel->md2data_tris = Mem_Alloc(loadmodel->mempool, loadmodel->numtris * sizeof(md2triangle_t)); + // load the triangles and stvert data + inst = (void*)(base + LittleLong(pinmodel->ofs_st)); + intri = (void*)(base + LittleLong(pinmodel->ofs_tris)); + skinwidth = LittleLong(pinmodel->skinwidth); + skinheight = LittleLong(pinmodel->skinheight); + + stverts = Mem_Alloc(tempmempool, numst * sizeof(float[2])); + s = 1.0f / skinwidth; + t = 1.0f / skinheight; + for (i = 0;i < numst;i++) + { + j = (unsigned short) LittleShort(inst[i*2+0]); + k = (unsigned short) LittleShort(inst[i*2+1]); + if (j >= skinwidth || k >= skinheight) + { + Mem_Free(stverts); + Host_Error("Mod_MD2_LoadGeometry: invalid skin coordinate (%i %i) on vert %i of model %s\n", j, k, i, loadmodel->name); + } + stverts[i*2+0] = j * s; + stverts[i*2+1] = k * t; + } + + md2verthash = Mem_Alloc(tempmempool, 256 * sizeof(hash)); + md2verthashdata = Mem_Alloc(tempmempool, loadmodel->numtris * 3 * sizeof(*hash)); // swap the triangle list + num = 0; + loadmodel->mdlmd2data_indices = Mem_Alloc(loadmodel->mempool, loadmodel->numtris * sizeof(int[3])); for (i = 0;i < loadmodel->numtris;i++) { for (j = 0;j < 3;j++) { - loadmodel->md2data_tris[i].index_xyz[j] = LittleShort (in[i].index_xyz[j]); - loadmodel->md2data_tris[i].index_st[j] = LittleShort (in[i].index_st[j]); - if (loadmodel->md2data_tris[i].index_xyz[j] >= loadmodel->md2num_xyz) - Host_Error ("%s has invalid vertex indices", loadmodel->name); - if (loadmodel->md2data_tris[i].index_st[j] >= loadmodel->md2num_st) - Host_Error ("%s has invalid vertex indices", loadmodel->name); + xyz = (unsigned short) LittleShort (intri[i].index_xyz[j]); + st = (unsigned short) LittleShort (intri[i].index_st[j]); + if (xyz >= numxyz || st >= numst) + { + Mem_Free(md2verthash); + Mem_Free(md2verthashdata); + Mem_Free(stverts); + if (xyz >= numxyz) + Host_Error("Mod_MD2_LoadGeometry: invalid xyz index (%i) on triangle %i of model %s\n", xyz, i, loadmodel->name); + if (st >= numst) + Host_Error("Mod_MD2_LoadGeometry: invalid st index (%i) on triangle %i of model %s\n", st, i, loadmodel->name); + } + s = stverts[st*2+0]; + t = stverts[st*2+1]; + hashindex = (xyz * 17 + st) & 255; + for (hash = md2verthash[hashindex];hash;hash = hash->next) + if (hash->xyz == xyz && hash->st[0] == s && hash->st[1] == t) + break; + if (hash == NULL) + { + hash = md2verthashdata + num++; + hash->xyz = xyz; + hash->st[0] = s; + hash->st[1] = t; + hash->next = md2verthash[hashindex]; + md2verthash[hashindex] = hash; + } + loadmodel->mdlmd2data_indices[i*3+j] = (hash - md2verthashdata); } } -} -*/ -void Mod_MD2_LoadFrames(void *start) -{ - int i, j; - long datapointer; - md2frame_t *pinframe; + Mem_Free(stverts); + + loadmodel->numverts = num; + vertremap = Mem_Alloc(loadmodel->mempool, num * sizeof(int)); + loadmodel->mdlmd2data_texcoords = Mem_Alloc(loadmodel->mempool, num * sizeof(float[2])); + for (i = 0;i < num;i++) + { + hash = md2verthashdata + i; + vertremap[i] = hash->xyz; + loadmodel->mdlmd2data_texcoords[i*2+0] = hash->st[0]; + loadmodel->mdlmd2data_texcoords[i*2+1] = hash->st[1]; + } + + Mem_Free(md2verthash); + Mem_Free(md2verthashdata); + + // load frames // LordHavoc: doing proper bbox for model aliasbboxmin[0] = aliasbboxmin[1] = aliasbboxmin[2] = 1000000000; aliasbboxmax[0] = aliasbboxmax[1] = aliasbboxmax[2] = -1000000000; modelyawradius = 0; modelradius = 0; - datapointer = (long) start; -// load the frames + datapointer = (base + LittleLong(pinmodel->ofs_frames)); + // load the frames loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(animscene_t)); loadmodel->mdlmd2data_frames = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(md2frame_t)); loadmodel->mdlmd2data_pose = Mem_Alloc(loadmodel->mempool, loadmodel->numverts * loadmodel->numframes * sizeof(trivertx_t)); @@ -663,8 +734,8 @@ void Mod_MD2_LoadFrames(void *start) loadmodel->mdlmd2data_frames[i].scale[j] = LittleFloat(pinframe->scale[j]); loadmodel->mdlmd2data_frames[i].translate[j] = LittleFloat(pinframe->translate[j]); } - Mod_MD2_ConvertVerts (loadmodel->numverts, loadmodel->mdlmd2data_frames[i].scale, loadmodel->mdlmd2data_frames[i].translate, (void *)datapointer, &loadmodel->mdlmd2data_pose[i * loadmodel->numverts]); - datapointer += loadmodel->numverts * sizeof(trivertx_t); + Mod_MD2_ConvertVerts (loadmodel->mdlmd2data_frames[i].scale, loadmodel->mdlmd2data_frames[i].translate, (void *)datapointer, &loadmodel->mdlmd2data_pose[i * loadmodel->numverts], vertremap); + datapointer += numxyz * sizeof(trivertx_t); strcpy(loadmodel->animscenes[i].name, loadmodel->mdlmd2data_frames[i].name); loadmodel->animscenes[i].firstframe = i; @@ -673,6 +744,8 @@ void Mod_MD2_LoadFrames(void *start) loadmodel->animscenes[i].loop = true; } + Mem_Free(vertremap); + // LordHavoc: model bbox modelyawradius = sqrt(modelyawradius); modelradius = sqrt(modelradius); @@ -689,29 +762,6 @@ void Mod_MD2_LoadFrames(void *start) loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2]; } -void Mod_MD2_LoadGLCmds(int *in, int numglcmds) -{ - int i; - // load the draw list - loadmodel->md2data_glcmds = Mem_Alloc(loadmodel->mempool, numglcmds * sizeof(int)); - for (i = 0;i < numglcmds;i++) - loadmodel->md2data_glcmds[i] = LittleLong(in[i]); -} - -void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) -{ - md2_t *pinmodel; - int numglcmds; - long base; - pinmodel = buffer; - base = (long) buffer; - Mod_MD2_ReadHeader(pinmodel, &numglcmds); - Mod_MD2_LoadSkins((void*)(base + LittleLong(pinmodel->ofs_skins))); -// Mod_MD2_LoadTriangles((void*)(base + LittleLong(pinmodel->ofs_tris))); - Mod_MD2_LoadFrames((void*)(base + LittleLong(pinmodel->ofs_frames))); - Mod_MD2_LoadGLCmds((void*)(base + LittleLong(pinmodel->ofs_glcmds)), numglcmds); -} - static void zymswapintblock(int *m, int size) { size /= 4; @@ -724,7 +774,8 @@ static void zymswapintblock(int *m, int size) void Mod_LoadZymoticModel(model_t *mod, void *buffer) { - int i, pbase, *bonecount; + int i, pbase, *bonecount, numposes; + unsigned int count, a, b, c, *renderlist, *renderlistend; rtexture_t **texture; char *shadername; zymtype1header_t *pinmodel, *pheader; @@ -738,7 +789,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) Host_Error ("Mod_LoadZymoticModel: %s is not a zymotic model\n"); if (BigLong(pinmodel->type) != 1) - Host_Error ("Mod_LoadZymoticModel: only type 1 (skeletal pose) models are currently supported\n"); + Host_Error ("Mod_LoadZymoticModel: only type 1 (skeletal pose) models are currently supported (name = %s)\n", loadmodel->name); loadmodel->type = mod_alias; loadmodel->aliastype = ALIASTYPE_ZYM; @@ -794,6 +845,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->skinframes->glow = NULL; loadmodel->skinframes->merged = NULL; loadmodel->numskins = 1; + numposes = pheader->lump_poses.length / sizeof(float[3][4]) / pheader->numbones; // go through the lumps, swapping things @@ -816,6 +868,12 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->animscenes[i].framerate = scene->framerate; loadmodel->animscenes[i].loop = (scene->flags & ZYMSCENEFLAG_NOLOOP) == 0; + if ((unsigned int) loadmodel->animscenes[i].firstframe >= numposes) + Host_Error("Mod_LoadZymoticModel: scene firstframe (%i) >= numposes (%i)\n", loadmodel->animscenes[i].firstframe, numposes); + if ((unsigned int) loadmodel->animscenes[i].firstframe + (unsigned int) loadmodel->animscenes[i].framecount > numposes) + Host_Error("Mod_LoadZymoticModel: scene firstframe (%i) + framecount (%i) >= numposes (%i)\n", loadmodel->animscenes[i].firstframe, loadmodel->animscenes[i].framecount, numposes); + if (loadmodel->animscenes[i].framerate < 0) + Host_Error("Mod_LoadZymoticModel: scene framerate (%f) < 0\n", loadmodel->animscenes[i].framerate); scene++; } @@ -829,7 +887,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) SWAPLONG(bone[i].flags); SWAPLONG(bone[i].parent); if (bone[i].parent >= i) - Host_Error("Mod_LoadZymoticModel: bone[i].parent >= i\n"); + Host_Error("Mod_LoadZymoticModel: bone[i].parent >= i in %s\n", loadmodel->name); } // zymlump_t lump_vertbonecounts; // int vertbonecounts[numvertices]; // how many bones influence each vertex (separate mainly to make this compress better) @@ -837,7 +895,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) bonecount = (void *) (pheader->lump_vertbonecounts.start + pbase); for (i = 0;i < pheader->numbones;i++) if (bonecount[i] < 1) - Host_Error("Mod_LoadZymoticModel: bone vertex count < 1\n"); + Host_Error("Mod_LoadZymoticModel: bone vertex count < 1 in %s\n", loadmodel->name); // zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct zymswapintblock((void *) (pheader->lump_verts.start + pbase), pheader->lump_verts.length); @@ -847,6 +905,32 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) // zymlump_t lump_render; // int renderlist[rendersize]; // sorted by shader with run lengths (int count), shaders are sequentially used, each run can be used with glDrawElements (each triangle is 3 int indices) zymswapintblock((void *) (pheader->lump_render.start + pbase), pheader->lump_render.length); + // validate renderlist and swap winding order of tris + renderlist = (void *) (pheader->lump_render.start + pbase); + renderlistend = (void *) ((qbyte *) renderlist + pheader->lump_render.length); + i = pheader->numshaders * sizeof(int) + pheader->numtris * sizeof(int[3]); + if (pheader->lump_render.length != i) + Host_Error("Mod_LoadZymoticModel: renderlist is wrong size in %s (is %i bytes, should be %i bytes)\n", loadmodel->name, pheader->lump_render.length, i); + for (i = 0;i < pheader->numshaders;i++) + { + if (renderlist >= renderlistend) + Host_Error("Mod_LoadZymoticModel: corrupt renderlist in %s (wrong size)\n", loadmodel->name); + count = *renderlist++; + if (renderlist + count * 3 > renderlistend) + Host_Error("Mod_LoadZymoticModel: corrupt renderlist in %s (wrong size)\n", loadmodel->name); + while (count--) + { + a = renderlist[0]; + b = renderlist[1]; + c = renderlist[2]; + if (a >= pheader->numverts || b >= pheader->numverts || c >= pheader->numverts) + Host_Error("Mod_LoadZymoticModel: corrupt renderlist in %s (out of bounds index)\n", loadmodel->name); + renderlist[0] = c; + renderlist[1] = b; + renderlist[2] = a; + renderlist += 3; + } + } // zymlump_t lump_shaders; // char shadername[numshaders][32]; // shaders used on this model shadername = (void *) (pheader->lump_shaders.start + pbase);