solstice-anim

Geometry animation library of the solstice app
git clone git://git.meso-star.com/solstice-anim.git
Log | Files | Refs | README | LICENSE

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:
Mcmake/CMakeLists.txt | 1+
Msrc/sanim.h | 25++++++++++++++++++++++++-
Msrc/sanim_node.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Asrc/test_sanim_node.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sanim_node_transform.c | 20--------------------
Msrc/test_sanim_utils.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sanim_utils.h | 23+++++++++++++++++++++++
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);