summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-11-27 00:43:18 -0600
committersanine <sanine.not@pm.me>2022-11-27 00:43:18 -0600
commitc42d9264aed8da3a057719cab7390fa55904bda6 (patch)
treebe60812077cefca105769f6e841ddfdf3d0fe25e
parent29f9921b919497be4d652ce963c8afbb2c1cd1e7 (diff)
add rotation parsing
-rw-r--r--CMakeLists.txt3
-rw-r--r--src/transform.c88
-rw-r--r--src/transform.h11
-rw-r--r--src/transform.test.c115
4 files changed, 217 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bf3ca8a..2843fd3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,9 @@ endif()
if (KALMIA_BUILD_TESTS)
add_executable(kalmia-tests)
target_link_libraries(kalmia-tests kalmia)
+ if (UNIX)
+ target_link_libraries(kalmia-tests m)
+ endif()
endif()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src)
diff --git a/src/transform.c b/src/transform.c
index 7c50a5e..6e4db56 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -1,11 +1,15 @@
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include <kalmia.h>
#include <ezxml.h>
#include "transform.h"
+#define TWO_PI 6.2831853071796f
+
+
int kai_parse_matrix(ka_matrix_t *m, ezxml_t tag)
{
if (strcmp("matrix", ezxml_name(tag)) != 0)
@@ -21,3 +25,87 @@ int kai_parse_matrix(ka_matrix_t *m, ezxml_t tag)
return 0;
}
+
+
+int kai_parse_rotate(ka_matrix_t *m, ezxml_t tag)
+{
+ if (strcmp("rotate", ezxml_name(tag)) != 0)
+ return -1;
+
+ char *str = ezxml_txt(tag);
+ char *end;
+ int i;
+ double rot[4];
+ for (i=0; i<4; i++) {
+ rot[i] = strtod(str, &end);
+ str = end;
+ }
+
+ double x, y, z, angle;
+ x = rot[0];
+ y = rot[1];
+ z = rot[2];
+ angle = rot[3];
+
+ /* normalize length */
+ double axis_len = (x*x) + (y*y) + (z*z);
+ axis_len = sqrt(axis_len);
+ x /= axis_len;
+ y /= axis_len;
+ z /= axis_len;
+
+ /* convert angle to radians */
+ angle *= TWO_PI / 360;
+
+ /* compute rotation matrix entries */
+ double co = cos(angle);
+ double unco = 1 - co;
+ double si = sin(angle);
+
+ (*m)[0] = (x*x*unco) + co;
+ (*m)[1] = (x*y*unco) - (z*si);
+ (*m)[2] = (x*z*unco) + (y*si);
+ (*m)[3] = 0.0f;
+ (*m)[4] = (y*x*unco) + (z*si);
+ (*m)[5] = (y*y*unco) + co;
+ (*m)[6] = (y*z*unco) - (x*si);
+ (*m)[7] = 0.0f;
+ (*m)[8] = (z*x*unco) - (y*si);
+ (*m)[9] = (z*y*unco) + (x*si);
+ (*m)[10] = (z*z*unco) + co;
+ (*m)[11] = 0.0f;
+ (*m)[12] = 0.0f;
+ (*m)[13] = 0.0f;
+ (*m)[14] = 0.0f;
+ (*m)[15] = 1.0f;
+
+ return 0;
+}
+
+
+int kai_parse_translate(ka_matrix_t *m, ezxml_t tag)
+{
+ if (strcmp("translate", ezxml_name(tag)) != 0)
+ return -1;
+
+ char *str = ezxml_txt(tag);
+ char *end;
+ int i;
+ double move[3];
+ for (i=0; i<3; i++) {
+ move[i] = strtod(str, &end);
+ str = end;
+ }
+
+ memset(*m, 0, sizeof(ka_matrix_t));
+
+ (*m)[0] = 1.0f;
+ (*m)[3] = move[0];
+ (*m)[5] = 1.0f;
+ (*m)[7] = move[1];
+ (*m)[10] = 1.0f;
+ (*m)[11] = move[2];
+ (*m)[15] = 1.0f;
+
+ return 0;
+}
diff --git a/src/transform.h b/src/transform.h
index ef8b3e0..bbc79d1 100644
--- a/src/transform.h
+++ b/src/transform.h
@@ -1,6 +1,17 @@
+#ifndef KALMIA_TRANSLATE_H
+#define KALMIA_TRANSLATE_H
+
#include <kalmia.h>
#include <ezxml.h>
/* parse a <matrix> tag into a ka_matrix_t */
int kai_parse_matrix(ka_matrix_t *m, ezxml_t tag);
+
+/* parse a <rotate> tag into a ka_matrix_t */
+int kai_parse_rotate(ka_matrix_t *m, ezxml_t tag);
+
+/* parse a <translate> tag into a ka_matrix_t */
+int kai_parse_translate(ka_matrix_t *m, ezxml_t tag);
+
+#endif
diff --git a/src/transform.test.c b/src/transform.test.c
index e9982f6..f0cd06f 100644
--- a/src/transform.test.c
+++ b/src/transform.test.c
@@ -7,16 +7,27 @@
void parse_matrix_fail_nonmatrix();
void parse_identity();
+void parse_rotate_fail();
+void parse_rotate();
+
+void parse_translate_fail();
+void parse_translate();
+
void suite_transform()
{
lily_run_test(parse_matrix_fail_nonmatrix);
lily_run_test(parse_identity);
+ lily_run_test(parse_rotate_fail);
+ lily_run_test(parse_rotate);
+ lily_run_test(parse_translate_fail);
+ lily_run_test(parse_translate);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* ======== matrix ======== */
void parse_matrix_fail_nonmatrix()
{
char str[128];
@@ -69,3 +80,107 @@ void parse_identity()
lily_assert_float_equal(mat[14], 0.0f, 1e-3);
lily_assert_float_equal(mat[15], 1.0f, 1e-3);
}
+
+
+/* ======== rotate ======== */
+void parse_rotate_fail()
+{
+ char str[128];
+ strncpy(str, "<non></non>", 128);
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ ka_matrix_t mat;
+ int rc = kai_parse_rotate(&mat, tag);
+ lily_assert_true(rc != 0);
+
+ ezxml_free(tag);
+}
+
+
+void parse_rotate()
+{
+ char str[512];
+ strncpy(
+ str,
+ "<rotate>\n"
+ " 0 1 0 90.0\n"
+ "</rotate>",
+ 512
+ );
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ ka_matrix_t mat;
+ mat[0] = 100;
+ int rc = kai_parse_rotate(&mat, tag);
+ lily_assert_true(rc == 0);
+ ezxml_free(tag);
+
+ lily_assert_float_equal(mat[0], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[1], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[2], 1.0f, 1e-3);
+ lily_assert_float_equal(mat[3], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[4], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[5], 1.0f, 1e-3);
+ lily_assert_float_equal(mat[6], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[7], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[8], -1.0f, 1e-3);
+ lily_assert_float_equal(mat[9], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[10], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[11], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[12], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[13], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[14], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[15], 1.0f, 1e-3);
+}
+
+
+/* ======== translate ======== */
+void parse_translate_fail()
+{
+ char str[128];
+ strncpy(str, "<non></non>", 128);
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ ka_matrix_t mat;
+ int rc = kai_parse_translate(&mat, tag);
+ lily_assert_true(rc != 0);
+
+ ezxml_free(tag);
+}
+
+
+void parse_translate()
+{
+ char str[512];
+ strncpy(
+ str,
+ "<translate>\n"
+ " 10 5 -1\n"
+ "</translate>",
+ 512
+ );
+ ezxml_t tag = ezxml_parse_str(str, strlen(str));
+
+ ka_matrix_t mat;
+ mat[0] = 100;
+ int rc = kai_parse_translate(&mat, tag);
+ lily_assert_true(rc == 0);
+ ezxml_free(tag);
+
+ lily_assert_float_equal(mat[0], 1.0f, 1e-3);
+ lily_assert_float_equal(mat[1], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[2], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[3], 10.0f, 1e-3);
+ lily_assert_float_equal(mat[4], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[5], 1.0f, 1e-3);
+ lily_assert_float_equal(mat[6], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[7], 5.0f, 1e-3);
+ lily_assert_float_equal(mat[8], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[9], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[10], 1.0f, 1e-3);
+ lily_assert_float_equal(mat[11],-1.0f, 1e-3);
+ lily_assert_float_equal(mat[12], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[13], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[14], 0.0f, 1e-3);
+ lily_assert_float_equal(mat[15], 1.0f, 1e-3);
+}