polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 1571991a09c404e6bae5c4e245799d1f37046f43
parent 1e59967d82b2bb62226bbabd3b365fecde31fcfb
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  7 Jul 2019 11:16:46 -0700

mdls working definitivly!

Diffstat:
Msrc/geometry.h | 1-
Msrc/mdl.c | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mtest/test_dae.c | 30++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 23 deletions(-)

diff --git a/src/geometry.h b/src/geometry.h @@ -40,7 +40,6 @@ struct make_geometry { int num_joint_ids; float *joint_weights; - int num_weights; }; struct geometry_manager { diff --git a/src/mdl.c b/src/mdl.c @@ -15,10 +15,21 @@ static inline void write_int(int val, FILE *out) fwrite(&val, sizeof(val), 1, out); } +static inline void write_nfloats(float *floats, int num_floats, FILE *out) +{ + fwrite(floats, sizeof(*floats), num_floats, out); +} + static inline void write_floats(float *floats, int num_floats, FILE *out) { write_int(num_floats, out); - fwrite(floats, sizeof(*floats), num_floats, out); + write_nfloats(floats, num_floats, out); +} + +static inline void write_ints(u32 *ints, int num_ints, FILE *out) +{ + write_int(num_ints, out); + fwrite(ints, sizeof(*ints), num_ints, out); } void init_mdl_geometry(struct mdl_geometry *lgeom) @@ -32,34 +43,73 @@ void save_mdl(FILE *out, struct model *model, struct mdl_geometry *lgeom) { struct make_geometry *mkgeom = &lgeom->mkgeom; assert(mkgeom->vertices); - - - if (mkgeom->normals) { - } - - if (mkgeom->colors) { - } + assert(mkgeom->normals); for (int i = 0; i < N_MDL_TAGS; i++) { - write_tag(MDL_NORMAL, out); switch ((enum mdl_tag)i) { case MDL_POSITION: - write_floats(mkgeom->vertices, mkgeom->num_verts, out); + write_tag(MDL_POSITION, out); + write_floats(mkgeom->vertices, mkgeom->num_verts * 3, out); break; + case MDL_NORMAL: - write_floats(mkgeom->normals, mkgeom->num_verts, out); + write_tag(MDL_NORMAL, out); + write_floats(mkgeom->normals, mkgeom->num_verts * 3, out); break; + case MDL_COLOR: - write_floats(mkgeom->colors, mkgeom->num_verts, out); + if (mkgeom->colors) { + write_tag(MDL_COLOR, out); + write_floats(mkgeom->colors, mkgeom->num_verts * 3, out); + } break; + case MDL_INDEX: - write_ints(mkgeom->indices, mkgeom->num_indices, out); + write_tag(MDL_INDEX, out); + write_ints(mkgeom->indices, mkgeom->num_indices , out); + /* debug("writing out %d indices\n", mkgeom->num_indices); */ + break; case MDL_JOINT_IDS: + if (mkgeom->joint_ids) { + write_tag(MDL_JOINT_IDS, out); + write_ints(mkgeom->joint_ids, mkgeom->num_joint_ids, out); + } + break; + case MDL_JOINT_WEIGHTS: + if (mkgeom->joint_weights) { + write_tag(MDL_JOINT_WEIGHTS, out); + write_floats(mkgeom->joint_weights, + mkgeom->num_verts * 3, out); + } + break; + case MDL_TEX_COORD: + if (mkgeom->tex_coords) { + write_tag(MDL_TEX_COORD, out); + assert(mkgeom->num_uv_components == 2); + write_floats(mkgeom->tex_coords, + mkgeom->num_verts * mkgeom->num_uv_components, + out); + } + break; + case MDL_MAX: + write_tag(MDL_MAX, out); + write_nfloats(lgeom->max, 3, out); + /* debug("write max: %f %f %f\n", */ + /* lgeom->max[0], lgeom->max[1], lgeom->max[2]); */ + break; + case MDL_MIN: + write_tag(MDL_MIN, out); + write_nfloats(lgeom->min, 3, out); + + /* debug("write min: %f %f %f\n", */ + /* lgeom->min[0], lgeom->min[1], lgeom->min[2]); */ + break; + case N_MDL_TAGS: assert(!"this shouldn't happend"); break; } @@ -72,6 +122,7 @@ static inline enum mdl_tag read_tag(FILE *stream) { enum mdl_tag tag = 0; int read = fread(&tag, 1, 1, stream); + /* debug("read_tag %d\n", tag); */ assert(read == 1 || feof(stream)); assert(tag != 0 || feof(stream)); return tag; @@ -124,26 +175,31 @@ void load_mdl(FILE *in, struct model *model, struct mdl_geometry *lgeom) enum mdl_tag tag = read_tag(in); if (feof(in)) break; - debug("tag %d\n", tag); assert(tag < N_MDL_TAGS); switch (tag) { case MDL_POSITION: - mkgeom->num_verts = read_floats(in, &mkgeom->vertices); + mkgeom->num_verts = read_floats(in, &mkgeom->vertices) / 3; break; case MDL_NORMAL: num = read_floats(in, &mkgeom->normals); - assert(num == mkgeom->num_verts); + assert(num == mkgeom->num_verts * 3); break; case MDL_COLOR: num = read_floats(in, &mkgeom->colors); - assert(num == mkgeom->num_verts); + assert(num == mkgeom->num_verts * 3); break; case MDL_INDEX: mkgeom->num_indices = read_ints(in, &mkgeom->indices); + /* debug("reading in %d indices\n", mkgeom->num_indices); */ + break; + + case MDL_TEX_COORD: + num = read_floats(in, &mkgeom->tex_coords); + assert(num == mkgeom->num_verts * 2); break; case MDL_JOINT_IDS: @@ -151,14 +207,22 @@ void load_mdl(FILE *in, struct model *model, struct mdl_geometry *lgeom) break; case MDL_JOINT_WEIGHTS: - mkgeom->num_weights = read_floats(in, &mkgeom->joint_weights); + num = read_floats(in, &mkgeom->joint_weights); + assert(num == mkgeom->num_verts * 3); break; - case MDL_TEX_COORD: - read_floats(in, &mkgeom->tex_coords); + case MDL_MIN: + read_nfloats(in, 3, lgeom->min); + /* debug("read min: %f %f %f\n", */ + /* lgeom->min[0], lgeom->min[1], lgeom->min[2]); */ break; - case MDL_MAX: read_nfloats(in, 3, lgeom->max); break; - case MDL_MIN: read_nfloats(in, 3, lgeom->min); break; + + case MDL_MAX: + read_nfloats(in, 3, lgeom->max); + /* debug("read max: %f %f %f\n", */ + /* lgeom->max[0], lgeom->max[1], lgeom->max[2]); */ + break; + case N_MDL_TAGS: assert(!"this shouldn't happend"); break; } } diff --git a/test/test_dae.c b/test/test_dae.c @@ -48,6 +48,7 @@ static void test_save_mdl() init_model(&model2); init_mdl_geometry(&mg2); + // TODO: test more models const char *filename = "data/models/pirate_officer.ply"; parse_ply_with_mkgeom(filename, &mg); @@ -58,9 +59,38 @@ static void test_save_mdl() out = fopen("/tmp/test.mdl", "rb"); load_mdl(out, &model2, &mg2); + struct make_geometry *mk1 = &mg.mkgeom; + struct make_geometry *mk2 = &mg.mkgeom; + assert(model.nposes == model2.nposes); assert(vec3_approxeq(mg.min, mg2.min)); assert(vec3_approxeq(mg.max, mg2.max)); + assert(mk1->num_verts == mk2->num_verts); + assert(mk1->num_indices == mk2->num_indices); + assert(mk1->num_uv_components == mk2->num_uv_components); + assert(mk1->num_joint_ids == mk2->num_joint_ids); + + assert(memeq(mk1->vertices, mk2->vertices, + mk1->num_verts * 3, mk2->num_verts * 3)); + + assert(memeq(mk1->colors, mk2->colors, + mk1->num_verts * 3, mk2->num_verts * 3)); + + assert(memeq(mk1->normals, mk2->normals, + mk1->num_verts * 3, mk2->num_verts * 3)); + + assert(memeq(mk1->indices, mk2->indices, + mk1->num_indices, mk2->num_indices)); + + assert(memeq(mk1->tex_coords, mk2->tex_coords, + mk1->num_verts * mk2->num_uv_components, + mk2->num_verts * mk2->num_uv_components)); + + assert(memeq(mk1->joint_ids, mk2->joint_ids, + mk1->num_joint_ids, mk2->num_joint_ids)); + + assert(memeq(mk1->joint_weights, mk2->joint_weights, + mk1->num_verts * 3, mk2->num_verts * 3)); } int main(int argc, char *argv[])