summaryrefslogtreecommitdiff
path: root/src/engine/md5.h
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/md5.h
parentaffde05dc07a94643f1fd2751b2b441f57f73d7d (diff)
downloadxolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz
xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/md5.h')
-rw-r--r--src/engine/md5.h214
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);