diff options
Diffstat (limited to 'src/engine/md5.h')
| -rw-r--r-- | src/engine/md5.h | 214 |
1 files changed, 62 insertions, 152 deletions
diff --git a/src/engine/md5.h b/src/engine/md5.h index d948ccf..e508cb3 100644 --- a/src/engine/md5.h +++ b/src/engine/md5.h @@ -1,66 +1,48 @@ struct md5; -struct md5joint -{ +struct md5joint { vec pos; quat orient; }; -struct md5weight -{ +struct md5weight { int joint; float bias; vec pos; }; -struct md5vert -{ +struct md5vert { vec2 tc; ushort start, count; }; -struct md5hierarchy -{ +struct md5hierarchy { string name; int parent, flags, start; }; -struct md5 : skelloader<md5> -{ +struct md5 : skelloader<md5> { md5(const char *name) : skelloader(name) {} - static const char *formatname() { return "md5"; } int type() const { return MDL_MD5; } - - struct md5mesh : skelmesh - { + struct md5mesh : skelmesh { md5weight *weightinfo; int numweights; md5vert *vertinfo; - - md5mesh() : weightinfo(NULL), numweights(0), vertinfo(NULL) - { + md5mesh() : weightinfo(NULL), numweights(0), vertinfo(NULL) { } - - ~md5mesh() - { + ~md5mesh() { cleanup(); } - - void cleanup() - { + void cleanup() { DELETEA(weightinfo); DELETEA(vertinfo); } - - void buildverts(vector<md5joint> &joints) - { - loopi(numverts) - { + void buildverts(vector<md5joint> &joints) { + loopi(numverts) { md5vert &v = vertinfo[i]; vec pos(0, 0, 0); - loopk(v.count) - { + loopk(v.count) { md5weight &w = weightinfo[v.start+k]; md5joint &j = joints[w.joint]; vec wpos = j.orient.rotate(w.pos); @@ -71,11 +53,9 @@ struct md5 : skelloader<md5> vert &vv = verts[i]; vv.pos = pos; vv.tc = v.tc; - blendcombo c; int sorted = 0; - loopj(v.count) - { + loopj(v.count) { md5weight &w = weightinfo[v.start+j]; sorted = c.addweight(sorted, w.bias, w.joint); } @@ -83,29 +63,22 @@ struct md5 : skelloader<md5> vv.blend = addblendcombo(c); } } - - void load(stream *f, char *buf, size_t bufsize) - { + void load(stream *f, char *buf, size_t bufsize) { md5weight w; md5vert v; tri t; int index; - - while(f->getline(buf, bufsize) && buf[0]!='}') - { - if(strstr(buf, "// meshes:")) - { + while(f->getline(buf, bufsize) && buf[0]!='}') { + if(strstr(buf, "// meshes:")) { char *start = strchr(buf, ':')+1; if(*start==' ') start++; char *end = start + strlen(start)-1; while(end >= start && isspace(*end)) end--; name = newstring(start, end+1-start); } - else if(strstr(buf, "shader")) - { + else if(strstr(buf, "shader")) { char *start = strchr(buf, '"'), *end = start ? strchr(start+1, '"') : NULL; - if(start && end) - { + if(start && end) { char *texname = newstring(start+1, end-(start+1)); part *p = loading->parts.last(); p->initskins(notexture, notexture, group->meshes.length()); @@ -114,86 +87,66 @@ struct md5 : skelloader<md5> delete[] texname; } } - else if(sscanf(buf, " numverts %d", &numverts)==1) - { + else if(sscanf(buf, " numverts %d", &numverts)==1) { numverts = max(numverts, 0); - if(numverts) - { + if(numverts) { vertinfo = new md5vert[numverts]; verts = new vert[numverts]; } } - else if(sscanf(buf, " numtris %d", &numtris)==1) - { + else if(sscanf(buf, " numtris %d", &numtris)==1) { numtris = max(numtris, 0); if(numtris) tris = new tri[numtris]; } - else if(sscanf(buf, " numweights %d", &numweights)==1) - { + else if(sscanf(buf, " numweights %d", &numweights)==1) { numweights = max(numweights, 0); if(numweights) weightinfo = new md5weight[numweights]; } - else if(sscanf(buf, " vert %d ( %f %f ) %hu %hu", &index, &v.tc.x, &v.tc.y, &v.start, &v.count)==5) - { + else if(sscanf(buf, " vert %d ( %f %f ) %hu %hu", &index, &v.tc.x, &v.tc.y, &v.start, &v.count)==5) { if(index>=0 && index<numverts) vertinfo[index] = v; } - else if(sscanf(buf, " tri %d %hu %hu %hu", &index, &t.vert[0], &t.vert[1], &t.vert[2])==4) - { + else if(sscanf(buf, " tri %d %hu %hu %hu", &index, &t.vert[0], &t.vert[1], &t.vert[2])==4) { if(index>=0 && index<numtris) tris[index] = t; } - else if(sscanf(buf, " weight %d %d %f ( %f %f %f ) ", &index, &w.joint, &w.bias, &w.pos.x, &w.pos.y, &w.pos.z)==6) - { + else if(sscanf(buf, " weight %d %d %f ( %f %f %f ) ", &index, &w.joint, &w.bias, &w.pos.x, &w.pos.y, &w.pos.z)==6) { w.pos.y = -w.pos.y; if(index>=0 && index<numweights) weightinfo[index] = w; } } } }; - - struct md5meshgroup : skelmeshgroup - { - md5meshgroup() - { + struct md5meshgroup : skelmeshgroup { + md5meshgroup() { } - - bool loadmesh(const char *filename, float smooth) - { + bool loadmesh(const char *filename, float smooth) { stream *f = openfile(filename, "r"); if(!f) return false; - char buf[512]; vector<md5joint> basejoints; - while(f->getline(buf, sizeof(buf))) - { + while(f->getline(buf, sizeof(buf))) { int tmp; - if(sscanf(buf, " MD5Version %d", &tmp)==1) - { + if(sscanf(buf, " MD5Version %d", &tmp)==1) { if(tmp!=10) { delete f; return false; } } - else if(sscanf(buf, " numJoints %d", &tmp)==1) - { + else if(sscanf(buf, " numJoints %d", &tmp)==1) { if(tmp<1) { delete f; return false; } if(skel->numbones>0) continue; skel->numbones = tmp; skel->bones = new boneinfo[skel->numbones]; } - else if(sscanf(buf, " numMeshes %d", &tmp)==1) - { + else if(sscanf(buf, " numMeshes %d", &tmp)==1) { if(tmp<1) { delete f; return false; } } - else if(strstr(buf, "joints {")) - { + else if(strstr(buf, "joints {")) { string name; int parent; md5joint j; - while(f->getline(buf, sizeof(buf)) && buf[0]!='}') - { + while(f->getline(buf, sizeof(buf)) && buf[0]!='}') { char *curbuf = buf, *curname = name; bool allowspace = false; while(*curbuf && isspace(*curbuf)) curbuf++; if(*curbuf == '"') { curbuf++; allowspace = true; } - while(*curbuf && curname < &name[sizeof(name)-1]) - { + while(*curbuf && curname < &name[sizeof(name)-1]) { char c = *curbuf++; if(c == '"') break; if(isspace(c) && !allowspace) break; @@ -202,8 +155,7 @@ struct md5 : skelloader<md5> *curname = '\0'; if(sscanf(curbuf, " %d ( %f %f %f ) ( %f %f %f )", &parent, &j.pos.x, &j.pos.y, &j.pos.z, - &j.orient.x, &j.orient.y, &j.orient.z)==7) - { + &j.orient.x, &j.orient.y, &j.orient.z)==7) { j.pos.y = -j.pos.y; j.orient.x = -j.orient.x; j.orient.z = -j.orient.z; @@ -219,101 +171,77 @@ struct md5 : skelloader<md5> } if(basejoints.length()!=skel->numbones) { delete f; return false; } } - else if(strstr(buf, "mesh {")) - { + else if(strstr(buf, "mesh {")) { md5mesh *m = new md5mesh; m->group = this; meshes.add(m); m->load(f, buf, sizeof(buf)); - if(!m->numtris || !m->numverts) - { + if(!m->numtris || !m->numverts) { conoutf(CON_WARN, "empty mesh in %s", filename); meshes.removeobj(m); delete m; } } } - - if(skel->shared <= 1) - { + if(skel->shared <= 1) { skel->linkchildren(); - loopv(basejoints) - { + loopv(basejoints) { boneinfo &b = skel->bones[i]; b.base = dualquat(basejoints[i].orient, basejoints[i].pos); (b.invbase = b.base).invert(); } } - - loopv(meshes) - { + loopv(meshes) { md5mesh &m = *(md5mesh *)meshes[i]; m.buildverts(basejoints); if(smooth <= 1) m.smoothnorms(smooth); else m.buildnorms(); m.cleanup(); } - sortblendcombos(); - delete f; return true; } - - skelanimspec *loadanim(const char *filename) - { + skelanimspec *loadanim(const char *filename) { skelanimspec *sa = skel->findskelanim(filename); if(sa) return sa; - stream *f = openfile(filename, "r"); if(!f) return NULL; - vector<md5hierarchy> hierarchy; vector<md5joint> basejoints; int animdatalen = 0, animframes = 0; float *animdata = NULL; dualquat *animbones = NULL; char buf[512]; - while(f->getline(buf, sizeof(buf))) - { + while(f->getline(buf, sizeof(buf))) { int tmp; - if(sscanf(buf, " MD5Version %d", &tmp)==1) - { + if(sscanf(buf, " MD5Version %d", &tmp)==1) { if(tmp!=10) { delete f; return NULL; } } - else if(sscanf(buf, " numJoints %d", &tmp)==1) - { + else if(sscanf(buf, " numJoints %d", &tmp)==1) { if(tmp!=skel->numbones) { delete f; return NULL; } } - else if(sscanf(buf, " numFrames %d", &animframes)==1) - { + else if(sscanf(buf, " numFrames %d", &animframes)==1) { if(animframes<1) { delete f; return NULL; } } else if(sscanf(buf, " frameRate %d", &tmp)==1); - else if(sscanf(buf, " numAnimatedComponents %d", &animdatalen)==1) - { + else if(sscanf(buf, " numAnimatedComponents %d", &animdatalen)==1) { if(animdatalen>0) animdata = new float[animdatalen]; } - else if(strstr(buf, "bounds {")) - { + else if(strstr(buf, "bounds {")) { while(f->getline(buf, sizeof(buf)) && buf[0]!='}'); } - else if(strstr(buf, "hierarchy {")) - { - while(f->getline(buf, sizeof(buf)) && buf[0]!='}') - { + else if(strstr(buf, "hierarchy {")) { + while(f->getline(buf, sizeof(buf)) && buf[0]!='}') { md5hierarchy h; if(sscanf(buf, " %100s %d %d %d", h.name, &h.parent, &h.flags, &h.start)==4) hierarchy.add(h); } } - else if(strstr(buf, "baseframe {")) - { - while(f->getline(buf, sizeof(buf)) && buf[0]!='}') - { + else if(strstr(buf, "baseframe {")) { + while(f->getline(buf, sizeof(buf)) && buf[0]!='}') { md5joint j; - if(sscanf(buf, " ( %f %f %f ) ( %f %f %f )", &j.pos.x, &j.pos.y, &j.pos.z, &j.orient.x, &j.orient.y, &j.orient.z)==6) - { + if(sscanf(buf, " ( %f %f %f ) ( %f %f %f )", &j.pos.x, &j.pos.y, &j.pos.z, &j.orient.x, &j.orient.y, &j.orient.z)==6) { j.pos.y = -j.pos.y; j.orient.x = -j.orient.x; j.orient.z = -j.orient.z; @@ -323,37 +251,29 @@ struct md5 : skelloader<md5> } if(basejoints.length()!=skel->numbones) { delete f; if(animdata) delete[] animdata; return NULL; } animbones = new dualquat[(skel->numframes+animframes)*skel->numbones]; - if(skel->framebones) - { + if(skel->framebones) { memcpy(animbones, skel->framebones, skel->numframes*skel->numbones*sizeof(dualquat)); delete[] skel->framebones; } skel->framebones = animbones; animbones += skel->numframes*skel->numbones; - sa = &skel->addskelanim(filename); sa->frame = skel->numframes; sa->range = animframes; - skel->numframes += animframes; } - else if(sscanf(buf, " frame %d", &tmp)==1) - { - for(int numdata = 0; f->getline(buf, sizeof(buf)) && buf[0]!='}';) - { - for(char *src = buf, *next = src; numdata < animdatalen; numdata++, src = next) - { + else if(sscanf(buf, " frame %d", &tmp)==1) { + for(int numdata = 0; f->getline(buf, sizeof(buf)) && buf[0]!='}';) { + for(char *src = buf, *next = src; numdata < animdatalen; numdata++, src = next) { animdata[numdata] = strtod(src, &next); if(next <= src) break; } } dualquat *frame = &animbones[tmp*skel->numbones]; - loopv(basejoints) - { + loopv(basejoints) { md5hierarchy &h = hierarchy[i]; md5joint j = basejoints[i]; - if(h.start < animdatalen && h.flags) - { + if(h.start < animdatalen && h.flags) { float *jdata = &animdata[h.start]; if(h.flags&1) j.pos.x = *jdata++; if(h.flags&2) j.pos.y = -*jdata++; @@ -371,33 +291,23 @@ struct md5 : skelloader<md5> } } } - if(animdata) delete[] animdata; delete f; - return sa; } - - bool load(const char *meshfile, float smooth) - { + bool load(const char *meshfile, float smooth) { name = newstring(meshfile); - if(!loadmesh(meshfile, smooth)) return false; - return true; } }; - - meshgroup *loadmeshes(const char *name, va_list args) - { + meshgroup *loadmeshes(const char *name, va_list args) { md5meshgroup *group = new md5meshgroup; group->shareskeleton(va_arg(args, char *)); if(!group->load(name, va_arg(args, double))) { delete group; return NULL; } return group; } - - bool loaddefaultparts() - { + bool loaddefaultparts() { skelpart &mdl = addpart(); mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0; adjustments.setsize(0); |
