diff options
author | sanine <sanine.not@pm.me> | 2023-02-06 14:13:39 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-02-06 14:13:39 -0600 |
commit | d00d1029f9e2e9f55217ad3d21e5b826601ba210 (patch) | |
tree | ef0865b5ce5cfab0d4ddce9f13ab5c2bf6bf1e11 /src | |
parent | ea530015e97e5280b61f3a8bc2d2ddee5c0e2dff (diff) |
implement kai_read_mesh()
Diffstat (limited to 'src')
-rw-r--r-- | src/geometry/geometry.c | 77 | ||||
-rw-r--r-- | src/geometry/geometry.h | 3 | ||||
-rw-r--r-- | src/geometry/geometry.test.c | 58 |
3 files changed, 138 insertions, 0 deletions
diff --git a/src/geometry/geometry.c b/src/geometry/geometry.c index 78fbaea..72af92c 100644 --- a/src/geometry/geometry.c +++ b/src/geometry/geometry.c @@ -340,3 +340,80 @@ void kai_release_triangles(struct ka_triangles_t t) } +int kai_read_mesh(struct ka_mesh_t *dest, struct kai_tag_t *src) +{ + CHECK_TAG_TYPE("mesh"); + + dest->source_count = 0; + dest->source = NULL; + dest->triangles_count = 0; + dest->triangles = NULL; + + /* load vertices first bc if we don't kai_release_mesh will do bad things if we hit an error */ + struct kai_tag_t *child; + int result; + + child = kai_tag_get_first_child_with_type(src, "vertices"); + if (child == NULL) { return -1; } + result = kai_read_vertices(&(dest->vertices), child); + if (result != 0) { return -1; } + + /* load sources */ + unsigned int source_count = 0; + FOR_CHILD_OF_TYPE(src, child, "source") { source_count += 1; } + + dest->source = kai_alloc(source_count * sizeof(struct ka_source_t), "mesh source array"); + if (dest->source == NULL) { return -1; } + + int i = 0; + FOR_CHILD_OF_TYPE(src, child, "source") { + result = kai_read_source(dest->source + i, child); + if (result != 0) { + dest->source_count = i; + kai_release_mesh(*dest); + return -1; + } + i += 1; + } + dest->source_count = source_count; + + /* load triangles */ + unsigned int triangles_count = 0; + FOR_CHILD_OF_TYPE(src, child, "triangles") { triangles_count += 1; } + + dest->triangles = kai_alloc(triangles_count * sizeof(struct ka_triangles_t), "mesh triangles array"); + if (dest->triangles == NULL) { + kai_release_mesh(*dest); + return -1; + } + + i = 0; + FOR_CHILD_OF_TYPE(src, child, "triangles") { + result = kai_read_triangles(dest->triangles + i, child); + if (result != 0) { + dest->triangles_count = i; + kai_release_mesh(*dest); + return -1; + } + i += 1; + } + dest->triangles_count = triangles_count; + + return 0; +} + +void kai_release_mesh(struct ka_mesh_t m) +{ + int i; + for (i=0; i<m.source_count; i++) { + kai_release_source(m.source[i]); + } + free(m.source); + + kai_release_vertices(m.vertices); + + for (i=0; i<m.triangles_count; i++) { + kai_release_triangles(m.triangles[i]); + } + free(m.triangles); +} diff --git a/src/geometry/geometry.h b/src/geometry/geometry.h index 26fc16b..a46af87 100644 --- a/src/geometry/geometry.h +++ b/src/geometry/geometry.h @@ -26,4 +26,7 @@ void kai_release_vertices(struct ka_vertices_t v); int kai_read_triangles(struct ka_triangles_t *dest, struct kai_tag_t *src); void kai_release_triangles(struct ka_triangles_t t); +int kai_read_mesh(struct ka_mesh_t *dest, struct kai_tag_t *src); +void kai_release_mesh(struct ka_mesh_t m); + #endif diff --git a/src/geometry/geometry.test.c b/src/geometry/geometry.test.c index d918ffa..17be188 100644 --- a/src/geometry/geometry.test.c +++ b/src/geometry/geometry.test.c @@ -480,6 +480,64 @@ LILY_TEST("read triangles tag") #include LILY_PUSH_TEST() +LILY_TEST("fail to read non-mesh tag") +{ + struct kai_tag_t *t = kai_parse_string( + "<tag />" + ); + + struct ka_mesh_t mesh; + int result = kai_read_mesh(&mesh, t); + CHECK_EQ(result, -1, "%d"); + + kai_tag_destroy(t); +} +#include LILY_PUSH_TEST() + + +LILY_TEST("read mesh tag") +{ + struct kai_tag_t *t = kai_parse_string( + "<mesh>" + " <source id=\"source\">" + " <float_array count=\"1\">0.0</float_array>" + " <technique_common>" + " <accessor count=\"1\" source=\"xxx\">" + " <param type=\"float\" />" + " </accessor>" + " </technique_common>" + " </source>" + " <vertices id=\"box-Vtx\">" + " <input semantic=\"POSITION\" source=\"#box-Pos\"/>" + " </vertices>" + " <triangles count=\"2\" material=\"Bricks\">" + " <input semantic=\"VERTEX\" source=\"#verts\" offset=\"0\"/>" + " <input semantic=\"NORMAL\" source=\"#normal\" offset=\"1\"/>" + " <p>" + " 0 0 1 3 2 1" + " 0 0 2 1 3 2" + " </p>" + " </triangles>" + "</mesh>" + ); + + struct ka_mesh_t mesh; + int result = kai_read_mesh(&mesh, t); + kai_tag_destroy(t); + + REQUIRE_EQ(result, 0, "%d"); + + CHECK_EQ(mesh.source_count, 1, "%d"); + CHECK_EQS(mesh.source[0].id, "source"); + CHECK_EQS(mesh.vertices.id, "box-Vtx"); + CHECK_EQ(mesh.triangles_count, 1, "%d"); + CHECK_EQ(mesh.triangles[0].count, 2, "%d"); + + kai_release_mesh(mesh); +} +#include LILY_PUSH_TEST() + + #define LILY_FILE_END #include LILY_REGISTER_TESTS() |