summaryrefslogtreecommitdiff
path: root/src/engine/iqm.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/iqm.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/iqm.h')
-rw-r--r--src/engine/iqm.h147
1 files changed, 41 insertions, 106 deletions
diff --git a/src/engine/iqm.h b/src/engine/iqm.h
index e36a628..5e7323f 100644
--- a/src/engine/iqm.h
+++ b/src/engine/iqm.h
@@ -1,7 +1,6 @@
struct iqm;
-struct iqmheader
-{
+struct iqmheader {
char magic[16];
uint version;
uint filesize;
@@ -18,16 +17,14 @@ struct iqmheader
uint num_extensions, ofs_extensions;
};
-struct iqmmesh
-{
+struct iqmmesh {
uint name;
uint material;
uint first_vertex, num_vertexes;
uint first_triangle, num_triangles;
};
-enum
-{
+enum {
IQM_POSITION = 0,
IQM_TEXCOORD = 1,
IQM_NORMAL = 2,
@@ -38,8 +35,7 @@ enum
IQM_CUSTOM = 0x10
};
-enum
-{
+enum {
IQM_BYTE = 0,
IQM_UBYTE = 1,
IQM_SHORT = 2,
@@ -51,13 +47,11 @@ enum
IQM_DOUBLE = 8,
};
-struct iqmtriangle
-{
+struct iqmtriangle {
uint vertex[3];
};
-struct iqmjoint
-{
+struct iqmjoint {
uint name;
int parent;
vec pos;
@@ -65,8 +59,7 @@ struct iqmjoint
vec size;
};
-struct iqmpose
-{
+struct iqmpose {
int parent;
uint mask;
vec offsetpos;
@@ -77,16 +70,14 @@ struct iqmpose
vec scalesize;
};
-struct iqmanim
-{
+struct iqmanim {
uint name;
uint first_frame, num_frames;
float framerate;
uint flags;
};
-struct iqmvertexarray
-{
+struct iqmvertexarray {
uint type;
uint flags;
uint format;
@@ -94,35 +85,25 @@ struct iqmvertexarray
uint offset;
};
-struct iqm : skelloader<iqm>
-{
+struct iqm : skelloader<iqm> {
iqm(const char *name) : skelloader(name) {}
-
static const char *formatname() { return "iqm"; }
int type() const { return MDL_IQM; }
-
- struct iqmmeshgroup : skelmeshgroup
- {
- iqmmeshgroup()
- {
+ struct iqmmeshgroup : skelmeshgroup {
+ iqmmeshgroup() {
}
-
- bool loadiqmmeshes(const char *filename, const iqmheader &hdr, uchar *buf)
- {
+ bool loadiqmmeshes(const char *filename, const iqmheader &hdr, uchar *buf) {
lilswap((uint *)&buf[hdr.ofs_vertexarrays], hdr.num_vertexarrays*sizeof(iqmvertexarray)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_triangles], hdr.num_triangles*sizeof(iqmtriangle)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_meshes], hdr.num_meshes*sizeof(iqmmesh)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_joints], hdr.num_joints*sizeof(iqmjoint)/sizeof(uint));
-
const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : "";
float *vpos = NULL, *vnorm = NULL, *vtan = NULL, *vtc = NULL;
uchar *vindex = NULL, *vweight = NULL;
iqmvertexarray *vas = (iqmvertexarray *)&buf[hdr.ofs_vertexarrays];
- loopi(hdr.num_vertexarrays)
- {
+ loopi(hdr.num_vertexarrays) {
iqmvertexarray &va = vas[i];
- switch(va.type)
- {
+ switch(va.type) {
case IQM_POSITION: if(va.format != IQM_FLOAT || va.size != 3) return false; vpos = (float *)&buf[va.offset]; lilswap(vpos, 3*hdr.num_vertexes); break;
case IQM_NORMAL: if(va.format != IQM_FLOAT || va.size != 3) return false; vnorm = (float *)&buf[va.offset]; lilswap(vnorm, 3*hdr.num_vertexes); break;
case IQM_TANGENT: if(va.format != IQM_FLOAT || va.size != 4) return false; vtan = (float *)&buf[va.offset]; lilswap(vtan, 4*hdr.num_vertexes); break;
@@ -132,25 +113,19 @@ struct iqm : skelloader<iqm>
}
}
if(!vpos) return false;
-
iqmtriangle *tris = (iqmtriangle *)&buf[hdr.ofs_triangles];
iqmmesh *imeshes = (iqmmesh *)&buf[hdr.ofs_meshes];
iqmjoint *joints = (iqmjoint *)&buf[hdr.ofs_joints];
-
- if(hdr.num_joints)
- {
- if(skel->numbones <= 0)
- {
+ if(hdr.num_joints) {
+ if(skel->numbones <= 0) {
skel->numbones = hdr.num_joints;
skel->bones = new boneinfo[skel->numbones];
- loopi(hdr.num_joints)
- {
+ loopi(hdr.num_joints) {
iqmjoint &j = joints[i];
boneinfo &b = skel->bones[i];
if(!b.name) b.name = newstring(&str[j.name]);
b.parent = j.parent;
- if(skel->shared <= 1)
- {
+ if(skel->shared <= 1) {
j.pos.y = -j.pos.y;
j.orient.x = -j.orient.x;
j.orient.z = -j.orient.z;
@@ -161,13 +136,10 @@ struct iqm : skelloader<iqm>
}
}
}
-
if(skel->shared <= 1)
skel->linkchildren();
}
-
- loopi(hdr.num_meshes)
- {
+ loopi(hdr.num_meshes) {
iqmmesh &im = imeshes[i];
skelmesh *m = new skelmesh;
m->group = this;
@@ -175,12 +147,10 @@ struct iqm : skelloader<iqm>
m->name = newstring(&str[im.name]);
m->numverts = im.num_vertexes;
int noblend = -1;
- if(m->numverts)
- {
+ if(m->numverts) {
m->verts = new vert[m->numverts];
if(vtan) m->bumpverts = new bumpvert[m->numverts];
- if(!vindex || !vweight)
- {
+ if(!vindex || !vweight) {
blendcombo c;
c.finalize(0);
noblend = m->addblendcombo(c);
@@ -192,30 +162,25 @@ struct iqm : skelloader<iqm>
*mtan = vtan ? vtan + 4*fv : NULL,
*mtc = vtc ? vtc + 2*fv : NULL;
uchar *mindex = vindex ? vindex + 4*fv : NULL, *mweight = vweight ? vweight + 4*fv : NULL;
- loopj(im.num_vertexes)
- {
+ loopj(im.num_vertexes) {
vert &v = m->verts[j];
v.pos = vec(mpos[0], -mpos[1], mpos[2]);
mpos += 3;
- if(mtc)
- {
+ if(mtc) {
v.tc = vec2(mtc[0], mtc[1]);
mtc += 2;
}
else v.tc = vec2(0, 0);
- if(mnorm)
- {
+ if(mnorm) {
v.norm = vec(mnorm[0], -mnorm[1], mnorm[2]);
mnorm += 3;
- if(mtan)
- {
+ if(mtan) {
m->calctangent(m->bumpverts[j], v.norm, vec(mtan[0], -mtan[1], mtan[2]), mtan[3]);
mtan += 4;
}
}
else v.norm = vec(0, 0, 0);
- if(noblend < 0)
- {
+ if(noblend < 0) {
blendcombo c;
int sorted = 0;
loopk(4) sorted = c.addweight(sorted, mweight[k], mindex[k]);
@@ -229,39 +194,31 @@ struct iqm : skelloader<iqm>
m->numtris = im.num_triangles;
if(m->numtris) m->tris = new tri[m->numtris];
iqmtriangle *mtris = tris + im.first_triangle;
- loopj(im.num_triangles)
- {
+ loopj(im.num_triangles) {
tri &t = m->tris[j];
t.vert[0] = mtris->vertex[0] - fv;
t.vert[1] = mtris->vertex[1] - fv;
t.vert[2] = mtris->vertex[2] - fv;
++mtris;
}
- if(!m->numtris || !m->numverts)
- {
+ if(!m->numtris || !m->numverts) {
conoutf(CON_WARN, "empty mesh in %s", filename);
meshes.removeobj(m);
delete m;
}
}
-
sortblendcombos();
-
return true;
}
-
- bool loadiqmanims(const char *filename, const iqmheader &hdr, uchar *buf)
- {
+ bool loadiqmanims(const char *filename, const iqmheader &hdr, uchar *buf) {
lilswap((uint *)&buf[hdr.ofs_poses], hdr.num_poses*sizeof(iqmpose)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_anims], hdr.num_anims*sizeof(iqmanim)/sizeof(uint));
lilswap((ushort *)&buf[hdr.ofs_frames], hdr.num_frames*hdr.num_framechannels);
-
const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : "";
iqmpose *poses = (iqmpose *)&buf[hdr.ofs_poses];
iqmanim *anims = (iqmanim *)&buf[hdr.ofs_anims];
ushort *frames = (ushort *)&buf[hdr.ofs_frames];
- loopi(hdr.num_anims)
- {
+ loopi(hdr.num_anims) {
iqmanim &a = anims[i];
string name;
copystring(name, filename);
@@ -273,8 +230,7 @@ struct iqm : skelloader<iqm>
sa->frame = skel->numframes;
sa->range = a.num_frames;
dualquat *animbones = new dualquat[(skel->numframes+a.num_frames)*skel->numbones];
- if(skel->bones)
- {
+ if(skel->bones) {
memcpy(animbones, skel->framebones, skel->numframes*skel->numbones*sizeof(dualquat));
delete[] skel->framebones;
}
@@ -282,11 +238,9 @@ struct iqm : skelloader<iqm>
animbones += skel->numframes*skel->numbones;
skel->numframes += a.num_frames;
ushort *animdata = &frames[a.first_frame*hdr.num_framechannels];
- loopj(a.num_frames)
- {
+ loopj(a.num_frames) {
dualquat *frame = &animbones[j*skel->numbones];
- loopk(skel->numbones)
- {
+ loopk(skel->numbones) {
iqmpose &p = poses[k];
vec pos;
quat orient;
@@ -298,8 +252,7 @@ struct iqm : skelloader<iqm>
orient.z = -p.offsetorient.z; if(p.mask&0x20) orient.z -= *animdata++ * p.scaleorient.z;
orient.w = p.offsetorient.w; if(p.mask&0x40) orient.w += *animdata++ * p.scaleorient.w;
orient.normalize();
- if(p.mask&0x380)
- {
+ if(p.mask&0x380) {
if(p.mask&0x80) animdata++;
if(p.mask&0x100) animdata++;
if(p.mask&0x200) animdata++;
@@ -313,15 +266,11 @@ struct iqm : skelloader<iqm>
}
}
}
-
return true;
}
-
- bool loadiqm(const char *filename, bool doloadmesh, bool doloadanim)
- {
+ bool loadiqm(const char *filename, bool doloadmesh, bool doloadanim) {
stream *f = openfile(filename, "rb");
if(!f) return false;
-
uchar *buf = NULL;
iqmheader hdr;
if(f->read(&hdr, sizeof(hdr)) != sizeof(hdr) || memcmp(hdr.magic, "INTERQUAKEMODEL", sizeof(hdr.magic))) goto error;
@@ -330,33 +279,24 @@ struct iqm : skelloader<iqm>
if(hdr.filesize > (16<<20)) goto error; // sanity check... don't load files bigger than 16 MB
buf = new (false) uchar[hdr.filesize];
if(!buf || f->read(buf + sizeof(hdr), hdr.filesize - sizeof(hdr)) != hdr.filesize - sizeof(hdr)) goto error;
-
if(doloadmesh && !loadiqmmeshes(filename, hdr, buf)) goto error;
if(doloadanim && !loadiqmanims(filename, hdr, buf)) goto error;
-
delete[] buf;
delete f;
return true;
-
error:
if(buf) delete[] buf;
delete f;
return false;
}
-
- bool loadmesh(const char *filename)
- {
+ bool loadmesh(const char *filename) {
name = newstring(filename);
-
return loadiqm(filename, true, false);
}
-
- skelanimspec *loadanim(const char *animname)
- {
+ skelanimspec *loadanim(const char *animname) {
const char *sep = strchr(animname, ':');
skelanimspec *sa = skel->findskelanim(animname, sep ? '\0' : ':');
- if(!sa)
- {
+ if(!sa) {
string filename;
copystring(filename, animname);
if(sep) filename[sep - animname] = '\0';
@@ -366,17 +306,13 @@ struct iqm : skelloader<iqm>
return sa;
}
};
-
- meshgroup *loadmeshes(const char *name, va_list args)
- {
+ meshgroup *loadmeshes(const char *name, va_list args) {
iqmmeshgroup *group = new iqmmeshgroup;
group->shareskeleton(va_arg(args, char *));
if(!group->loadmesh(name)) { 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);
@@ -393,4 +329,3 @@ struct iqm : skelloader<iqm>
};
skelcommands<iqm> iqmcommands;
-