From bf38e6073e0262ea4cf113a6fc22a8c811494f13 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 10 May 2012 14:47:46 +0900 Subject: [PATCH] Implement iqm joint loading. --- include/QF/iqm.h | 13 ++++++++++++- libs/models/iqm/model_iqm.c | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/QF/iqm.h b/include/QF/iqm.h index cca4cee0c..974741d2e 100644 --- a/include/QF/iqm.h +++ b/include/QF/iqm.h @@ -114,14 +114,25 @@ typedef struct iqmextension_s { uint32_t ofs_extensions; // pointer to next extension } iqmextension; +// QF stuff + +typedef struct { + DualQuat_t rt; + quat_t shear; + quat_t scale; +} iqmframe_t; + typedef struct { byte *vertices; uint16_t *elements; int num_arrays; iqmvertexarray *vertexarrays; int num_joints; + iqmjoint *joints; + mat4_t *baseframe; + mat4_t *inverse_baseframe; int num_frames; - DualQuat_t **frames; + iqmframe_t **frames; } iqm_t; #endif//__QF_iqm_h__ diff --git a/libs/models/iqm/model_iqm.c b/libs/models/iqm/model_iqm.c index e4f8fcbe0..33dca1d8e 100644 --- a/libs/models/iqm/model_iqm.c +++ b/libs/models/iqm/model_iqm.c @@ -118,6 +118,7 @@ get_joints (const iqmheader *hdr, byte *buffer) { iqmjoint *joint; uint32_t i, j; + float t; if (hdr->ofs_joints + hdr->num_joints * sizeof (iqmjoint) > hdr->filesize) return 0; @@ -134,6 +135,10 @@ get_joints (const iqmheader *hdr, byte *buffer) joint[i].translate[j] = LittleFloat (joint[i].translate[j]); for (j = 0; j < 4; j++) joint[i].rotate[j] = LittleFloat (joint[i].rotate[j]); + // iqm quaternions use xyzw but QF quaternions use wxyz + t = joint[i].rotate[3]; + memmove (&joint[i].rotate[1], &joint[i].rotate[0], 3 * sizeof (float)); + joint[i].rotate[0] = t; for (j = 0; j < 3; j++) joint[i].scale[j] = LittleFloat (joint[i].scale[j]); } @@ -345,6 +350,22 @@ load_iqm_meshes (model_t *mod, const iqmheader *hdr, byte *buffer) return false; if (!(joints = get_joints (hdr, buffer))) return false; + iqm->num_joints = hdr->num_joints; + iqm->joints = malloc (iqm->num_joints * sizeof (iqmjoint)); + iqm->baseframe = malloc (iqm->num_joints * sizeof (mat4_t)); + iqm->inverse_baseframe = malloc (iqm->num_joints * sizeof (mat4_t)); + memcpy (iqm->joints, joints, iqm->num_joints * sizeof (iqmjoint)); + for (i = 0; i < hdr->num_joints; i++) { + iqmjoint *j = &iqm->joints[i]; + mat4_t *bf = &iqm->baseframe[i]; + mat4_t *ibf = &iqm->inverse_baseframe[i]; + Mat4Init (j->rotate, j->scale, j->translate, *bf); + Mat4Inverse (*bf, *ibf); + if (j->parent >= 0) { + Mat4Mult (iqm->baseframe[j->parent], *bf, *bf); + Mat4Mult (*ibf, iqm->inverse_baseframe[j->parent], *ibf); + } + } return true; }