summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-12-10 17:14:50 -0600
committersanine <sanine.not@pm.me>2022-12-10 17:14:50 -0600
commit8bc49efb970ac44f17f6076bb16f1d0e712bd750 (patch)
treeee427b3881ddf46e351a61ddb29536baf6e7b214
parent6ca18697f9eb332c38f0b46b823089ce80347580 (diff)
implement node transform processing
-rw-r--r--src/node.c49
-rw-r--r--src/node.h2
-rw-r--r--src/node.test.c103
3 files changed, 153 insertions, 1 deletions
diff --git a/src/node.c b/src/node.c
index 1ba862d..abf0034 100644
--- a/src/node.c
+++ b/src/node.c
@@ -1,5 +1,54 @@
+#include <string.h>
+
#include <kalmia.h>
#include <ezxml.h>
+
+#include "util.h"
+#include "transform.h"
#include "node.h"
+ka_node_t * kai_parse_node(kalmia_t *k, ezxml_t tag)
+{
+ /* check for incorrect tag name */
+ if (strcmp("node", ezxml_name(tag)) != 0)
+ return NULL;
+
+ /* initialize node */
+ ka_node_t *node = kai_next_node(k);
+ kai_identity(&(node->transform));
+
+ /* get first child */
+ ezxml_t t = tag->child;
+
+ /* iterate over sub-tags */
+ while (t != NULL) {
+ const char *t_name = ezxml_name(t);
+ ka_matrix_t m;
+ if (strcmp(t_name, "matrix") == 0) {
+ /* process matrix */
+ kai_parse_matrix(&m, t);
+ kai_multiply(&(node->transform), node->transform, m);
+ }
+ else if (strcmp(t_name, "rotate") == 0) {
+ /* process rotation */
+ kai_parse_rotate(&m, t);
+ kai_multiply(&(node->transform), node->transform, m);
+ }
+ else if (strcmp(t_name, "scale") == 0) {
+ /* process scale */
+ kai_parse_scale(&m, t);
+ kai_multiply(&(node->transform), node->transform, m);
+ }
+ else if (strcmp(t_name, "translate") == 0) {
+ /* process translation */
+ kai_parse_translate(&m, t);
+ kai_multiply(&(node->transform), node->transform, m);
+ }
+
+ /* advance to next child node */
+ t = t->ordered;
+ }
+
+ return node;
+}
diff --git a/src/node.h b/src/node.h
index ea0bedf..7eb75e9 100644
--- a/src/node.h
+++ b/src/node.h
@@ -4,6 +4,6 @@
#include <kalmia.h>
#include <ezxml.h>
-
+ka_node_t * kai_parse_node(kalmia_t *k, ezxml_t tag);
#endif
diff --git a/src/node.test.c b/src/node.test.c
index 236d200..26837c9 100644
--- a/src/node.test.c
+++ b/src/node.test.c
@@ -1,8 +1,111 @@
+#include <string.h>
+
#include <kalmia.h>
#include <ezxml.h>
#include "test/test.h"
+#include "transform.h"
+#include "node.h"
+
+
+void empty();
+void transforms();
void suite_node()
{
+ lily_run_test(empty);
+ lily_run_test(transforms);
+}
+
+
+void empty()
+{
+ char str[512];
+ strncpy(
+ str,
+ "<node></node>",
+ 512
+ );
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ kalmia_t k;
+ k.node = NULL;
+ k.n_nodes = 0;
+ k.n_nodes_max = 0;
+
+ ka_node_t *node = kai_parse_node(&k, tag);
+ lily_assert_not_null(k.node);
+ lily_assert_not_null(node);
+ lily_assert_int_equal(k.n_nodes, 1);
+ lily_assert_ptr_equal(k.node, node);
+
+ ka_matrix_t identity;
+ kai_identity(&identity);
+
+ int i=0;
+ for (i=0; i<16; i++) {
+ lily_assert_float_equal(
+ node->transform[i],
+ identity[i],
+ 1e-3
+ );
+ }
+
+ ezxml_free(tag);
+ free(k.node);
+}
+
+
+void transforms()
+{
+ char str[512];
+ strncpy(
+ str,
+ "<node>\n"
+ " <translate>10.0 2.0 5.0</translate>\n"
+ " <scale>5.0 1.0 2.0</scale>\n"
+ "</node>",
+ 512
+ );
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ kalmia_t k;
+ k.node = NULL;
+ k.n_nodes = 0;
+ k.n_nodes_max = 0;
+
+ ka_node_t *node = kai_parse_node(&k, tag);
+ lily_assert_not_null(k.node);
+ lily_assert_not_null(node);
+ lily_assert_int_equal(k.n_nodes, 1);
+ lily_assert_ptr_equal(k.node, node);
+
+ ka_matrix_t translate = {
+ 1.0f, 0.0f, 0.0f, 10.0f,
+ 0.0f, 1.0f, 0.0f, 2.0f,
+ 0.0f, 0.0f, 1.0f, 5.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ };
+ ka_matrix_t scale = {
+ 5.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ };
+
+ ka_matrix_t expected;
+ kai_multiply(&expected, translate, scale);
+
+
+ int i=0;
+ for (i=0; i<16; i++) {
+ lily_assert_float_equal(
+ node->transform[i],
+ expected[i],
+ 1e-3
+ );
+ }
+
+ ezxml_free(tag);
+ free(k.node);
}