commit b81af87432fc655a9f24ca906ac9e153f421dd77
parent 9b3f1419eba78176a1f6b738b67f17b17c891396
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 2 Nov 2016 18:50:54 +0100
Add API to copy a node and to access father and children of a node.
Add a test dedicated to API testing. Move some existing test code here.
Diffstat:
7 files changed, 293 insertions(+), 24 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -96,6 +96,7 @@ if(NOT NO_TEST)
rcmake_set_test_runtime_dirs(${_name} _runtime_dirs)
endfunction()
+ new_test(test_sanim_node)
new_test(test_sanim_node_transform)
new_test(test_sanim_node_pivot)
endif()
diff --git a/src/sanim.h b/src/sanim.h
@@ -156,7 +156,30 @@ sanim_node_set_rotations
SANIM_API res_T
sanim_node_get_transform
(struct sanim_node* node,
- double transform[12]); /* 3x4 column major matrix */
+ double transform[12]); /* 3x4 column major matrix */
+
+SANIM_API res_T
+sanim_node_get_father
+ (const struct sanim_node* node,
+ const struct sanim_node** father);
+
+SANIM_API res_T
+sanim_node_get_children_count
+ (const struct sanim_node* node,
+ size_t* count);
+
+SANIM_API res_T
+sanim_node_get_child
+ (const struct sanim_node* node,
+ const size_t idx,
+ const struct sanim_node** child);
+
+/* simple copy, no recursion */
+SANIM_API res_T
+sanim_node_copy
+ (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ const struct sanim_node* src_node,
+ struct sanim_node* node);
END_DECLS
diff --git a/src/sanim_node.c b/src/sanim_node.c
@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sanim_node_c.h"
-#include "sanim_device_c.h"
#include "sanim.h"
#include <rsys/mem_allocator.h>
@@ -873,4 +872,77 @@ sanim_node_get_transform(struct sanim_node* node, double transform[12])
return RES_BAD_ARG;
node_get_transform(node, 1, transform);
return RES_OK;
-}
-\ No newline at end of file
+}
+
+res_T
+sanim_node_get_father
+ (const struct sanim_node* node,
+ const struct sanim_node** father)
+{
+ if (!node || !father)
+ return RES_BAD_ARG;
+ *father = node->data->father;
+ return RES_OK;
+}
+
+res_T
+sanim_node_get_children_count
+ (const struct sanim_node* node,
+ size_t* count)
+{
+ if (!node || !count)
+ return RES_BAD_ARG;
+ *count = darray_children_size_get(&node->data->children);
+ return RES_OK;
+}
+
+res_T
+sanim_node_get_child
+ (const struct sanim_node* node,
+ const size_t idx,
+ const struct sanim_node** child)
+{
+ const struct sanim_node* const* children;
+ if (!node || !child)
+ return RES_BAD_ARG;
+ if (idx >= darray_children_size_get(&node->data->children))
+ return RES_BAD_ARG;
+ children = darray_children_cdata_get(&node->data->children);
+ *child = children[idx];
+ return RES_OK;
+}
+
+res_T
+sanim_node_copy
+ (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ const struct sanim_node* src_node,
+ struct sanim_node* node)
+{
+ res_T res = RES_OK;
+
+ if (!node || !src_node) return RES_BAD_ARG;
+ res = sanim_node_initialize(allocator, node);
+ if (res != RES_OK) goto error;
+
+ if (src_node->data->pivot_data) {
+ /* duplicate pivot data */
+ struct mem_allocator* alloc = allocator ? allocator : &mem_default_allocator;
+ node->data->pivot_data = MEM_CALLOC(alloc, 1, sizeof(struct pivot_data));
+ if (!node->data->pivot_data) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ node->data->pivot_data->angleX = src_node->data->pivot_data->angleX;
+ node->data->pivot_data->angleZ = src_node->data->pivot_data->angleZ;
+ node->data->pivot_data->pivot = src_node->data->pivot_data->pivot;
+ node->data->pivot_data->tracking = src_node->data->pivot_data->tracking;
+ }
+ d3_set(node->data->rotations, src_node->data->rotations);
+ d3_set(node->data->translation, src_node->data->translation);
+
+exit:
+ return res;
+error:
+ sanim_node_release(node);
+ goto exit;
+}
diff --git a/src/test_sanim_node.c b/src/test_sanim_node.c
@@ -0,0 +1,111 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sanim.h"
+#include "test_sanim_utils.h"
+
+#include <rsys/double33.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct my_type t1, t2;
+ struct my_type* ptr;
+ struct sanim_pivot pivot;
+ struct sanim_tracking tracking;
+ size_t count;
+ double transform1[12], transform2[12];
+ double transl[3], rot[3];
+ (void) argc, (void) argv;
+
+ tracking.policy = TRACKING_SUN;
+ pivot.type = PIVOT_SINGLE_AXIS;
+ d3(pivot.data.pivot1.ref_normal, 0, 0, 1);
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(my_type_init(NULL, &t1), RES_OK);
+ CHECK(my_type_release(NULL), RES_BAD_ARG);
+ CHECK(my_type_release(&t1), RES_OK);
+ CHECK(my_type_init(&allocator, &t1), RES_OK);
+ CHECK(my_type_init(&allocator, NULL), RES_BAD_ARG);
+ CHECK(my_type_init(&allocator, &t2), RES_OK);
+ CHECK(my_type_release(&t1), RES_OK);
+
+ CHECK(my_type_init_pivot(&allocator, NULL, &tracking, &t1), RES_BAD_ARG);
+ CHECK(my_type_init_pivot(&allocator, &pivot, NULL, &t1), RES_BAD_ARG);
+ CHECK(my_type_init_pivot(&allocator, &pivot, &tracking, NULL), RES_BAD_ARG);
+ CHECK(my_type_init_pivot(&allocator, &pivot, &tracking, &t1), RES_OK);
+ CHECK(my_type_release(&t1), RES_OK);
+
+ CHECK(my_type_init(&allocator, &t1), RES_OK);
+ CHECK(my_type_add_child(NULL, &t1), RES_BAD_ARG);
+ CHECK(my_type_add_child(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_add_child(&t1, &t1), RES_BAD_ARG);
+ CHECK(my_type_add_child(&t1, &t2), RES_OK);
+ CHECK(my_type_add_child(&t1, &t2), RES_BAD_ARG);
+ CHECK(my_type_add_child(&t2, &t1), RES_BAD_ARG);
+
+ CHECK(my_type_copy(&allocator, NULL, &t1), RES_BAD_ARG);
+ CHECK(my_type_copy(&allocator, &t1, NULL), RES_BAD_ARG);
+
+ CHECK(my_type_get_father(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_get_father(NULL, &ptr), RES_BAD_ARG);
+ CHECK(my_type_get_children_count(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_get_children_count(NULL, &count), RES_BAD_ARG);
+ CHECK(my_type_get_children_count(&t1, &count), RES_OK);
+ CHECK(count, 1);
+ CHECK(my_type_get_child(NULL, 0, &ptr), RES_BAD_ARG);
+ CHECK(my_type_get_child(&t1, 10, &ptr), RES_BAD_ARG);
+ CHECK(my_type_get_child(&t1, 0, NULL), RES_BAD_ARG);
+ CHECK(my_type_get_child(&t1, 0, &ptr), RES_OK);
+ CHECK(ptr, &t2);
+ CHECK(my_type_get_father(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_get_father(NULL, &ptr), RES_BAD_ARG);
+ CHECK(my_type_get_father(&t1, &ptr), RES_OK);
+ CHECK(ptr, NULL);
+ CHECK(my_type_get_father(&t2, &ptr), RES_OK);
+ CHECK(ptr, &t1);
+
+ CHECK(my_type_set_translation(NULL, transl), RES_BAD_ARG);
+ CHECK(my_type_set_translation(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_set_translation(&t1, transl), RES_OK);
+
+ CHECK(my_type_set_rotations(NULL, rot), RES_BAD_ARG);
+ CHECK(my_type_set_rotations(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_set_rotations(&t1, rot), RES_OK);
+
+ CHECK(my_type_get_transform(NULL, transform1), RES_BAD_ARG);
+ CHECK(my_type_get_transform(&t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_get_transform(&t1, transform1), RES_OK);
+
+ CHECK(my_type_release(&t2), RES_OK);
+ CHECK(my_type_copy(&allocator, NULL, &t1), RES_BAD_ARG);
+ CHECK(my_type_copy(&allocator, &t1, NULL), RES_BAD_ARG);
+ CHECK(my_type_copy(&allocator, &t1, &t2), RES_OK);
+ CHECK(my_type_release(&t2), RES_OK);
+ CHECK(my_type_copy(NULL, &t1, &t2), RES_OK);
+ CHECK(my_type_get_transform(&t2, transform2), RES_OK);
+ CHECK(d34_eq_eps(transform1, transform2, 0), 1);
+
+ /* release memory */
+ CHECK(my_type_release(&t1), RES_OK);
+ CHECK(my_type_release(&t2), RES_OK);
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
diff --git a/src/test_sanim_node_transform.c b/src/test_sanim_node_transform.c
@@ -30,37 +30,17 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
/* test a typical use in my_type */
- CHECK(my_type_init(NULL, &t1), RES_OK);
- CHECK(my_type_release(NULL), RES_BAD_ARG);
- CHECK(my_type_release(&t1), RES_OK);
- CHECK(my_type_init(&allocator, &t1), RES_OK);
- CHECK(my_type_init(&allocator, NULL), RES_BAD_ARG);
- CHECK(my_type_init(&allocator, &t2), RES_OK);
-
- CHECK(my_type_add_child(NULL, &t1), RES_BAD_ARG);
- CHECK(my_type_add_child(&t1, NULL), RES_BAD_ARG);
- CHECK(my_type_add_child(&t1, &t1), RES_BAD_ARG);
- CHECK(my_type_add_child(&t1, &t2), RES_OK);
- CHECK(my_type_add_child(&t1, &t2), RES_BAD_ARG);
- CHECK(my_type_add_child(&t2, &t1), RES_BAD_ARG);
-
d3_splat(transl, +1);
- CHECK(my_type_set_translation(NULL, transl), RES_BAD_ARG);
- CHECK(my_type_set_translation(&t1, NULL), RES_BAD_ARG);
CHECK(my_type_set_translation(&t1, transl), RES_OK);
d3_splat(transl, -1);
CHECK(my_type_set_translation(&t2, transl), RES_OK);
- CHECK(my_type_get_transform(NULL, transform), RES_BAD_ARG);
- CHECK(my_type_get_transform(&t2, NULL), RES_BAD_ARG);
CHECK(my_type_get_transform(&t2, transform), RES_OK);
CHECK(d33_is_identity(transform), 1);
CHECK(d3_is_zero(transform + 9), 1);
d3(rot, PI, 0, 0);
- CHECK(my_type_set_rotations(NULL, rot), RES_BAD_ARG);
- CHECK(my_type_set_rotations(&t1, NULL), RES_BAD_ARG);
CHECK(my_type_set_rotations(&t1, rot), RES_OK);
CHECK(my_type_set_rotations(&t2, rot), RES_OK);
d3(transl, 0, +1, 0);
diff --git a/src/test_sanim_utils.c b/src/test_sanim_utils.c
@@ -44,6 +44,56 @@ my_type_init_pivot
}
res_T
+my_type_copy
+ (struct mem_allocator *allocator,
+ const struct my_type* src,
+ struct my_type* t)
+{
+ if (!t||! src) return RES_BAD_ARG;
+ /* init my stuff */
+ t->my_data = src->my_data;
+ /* init node stuff */
+ return sanim_node_copy(allocator, &src->node, &t->node);
+}
+
+res_T
+my_type_get_father
+ (const struct my_type* t,
+ const struct my_type** father)
+{
+ struct sanim_node* tmp;
+ res_T res = RES_OK;
+ if (!t || !father) return RES_BAD_ARG;
+ res = sanim_node_get_father(&t->node, &tmp);
+ if (res != RES_OK) return res;
+ *father = CONTAINER_OF(tmp, struct my_type, node);
+ return RES_OK;
+}
+
+res_T
+my_type_get_children_count
+ (const struct my_type* t,
+ size_t* count)
+{
+ return sanim_node_get_children_count(&t->node, count);
+}
+
+res_T
+my_type_get_child
+ (const struct my_type* t,
+ const size_t idx,
+ const struct my_type** child)
+{
+ struct sanim_node* tmp;
+ res_T res = RES_OK;
+ if (!t || !child) return RES_BAD_ARG;
+ res = sanim_node_get_child(&t->node, idx, &tmp);
+ if (res != RES_OK) return res;
+ *child = CONTAINER_OF(tmp, struct my_type, node);
+ return RES_OK;
+}
+
+res_T
my_type_release(struct my_type* t) {
if (!t) return RES_BAD_ARG;
/* release my stuff */
@@ -109,6 +159,16 @@ d33_is_identity_eps(const double v[9], const double eps) {
return 1;
}
+char
+d34_eq_eps(const double a[12], const double b[12], const double eps) {
+ int i;
+ ASSERT(eps >= 0);
+ FOR_EACH(i, 0, 12) {
+ if (fabs(a[i] - b[i]) > eps) return 0;
+ }
+ return 1;
+}
+
void
log_stream(const char* msg, void* ctx) {
ASSERT(msg);
diff --git a/src/test_sanim_utils.h b/src/test_sanim_utils.h
@@ -42,6 +42,12 @@ my_type_init_pivot
struct my_type* t);
res_T
+my_type_copy
+ (struct mem_allocator *allocator,
+ const struct my_type* src,
+ struct my_type* t);
+
+res_T
my_type_release(struct my_type* t);
res_T
@@ -56,6 +62,20 @@ my_type_set_rotations(struct my_type* t, const double rotations[3]);
res_T
my_type_get_transform(struct my_type* t, double transform[12]);
+res_T
+my_type_get_father
+ (const struct my_type* t,
+ const struct my_type** father);
+
+res_T
+my_type_get_children_count(const struct my_type* t, size_t* count);
+
+res_T
+my_type_get_child
+ (const struct my_type* t,
+ const size_t idx,
+ const struct my_type** child);
+
/*******************************************************************************
* Utilities
******************************************************************************/
@@ -68,6 +88,9 @@ d3_is_zero(const double v[3]);
char
d33_is_identity_eps(const double v[9], const double eps);
+char
+d34_eq_eps(const double a[12], const double b[12], const double eps);
+
void
log_stream(const char* msg, void* ctx);