summaryrefslogtreecommitdiff
path: root/src/geometry
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-02-06 14:13:39 -0600
committersanine <sanine.not@pm.me>2023-02-06 14:13:39 -0600
commitd00d1029f9e2e9f55217ad3d21e5b826601ba210 (patch)
treeef0865b5ce5cfab0d4ddce9f13ab5c2bf6bf1e11 /src/geometry
parentea530015e97e5280b61f3a8bc2d2ddee5c0e2dff (diff)
implement kai_read_mesh()
Diffstat (limited to 'src/geometry')
-rw-r--r--src/geometry/geometry.c77
-rw-r--r--src/geometry/geometry.h3
-rw-r--r--src/geometry/geometry.test.c58
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()