solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit 685263c5681692d22d713f887c928fb3c37d678c
parent 8f389703d0e41e642692fbc6dd1828cf20493589
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 16 Dec 2016 12:03:05 +0100

Start implementing solstice_entity parser to solver.

Includes Solstice core major changes.

Diffstat:
Mcmake/core/CMakeLists.txt | 16+++++++---------
Msrc/core/solstice_core.h | 92++++++++++++++-----------------------------------------------------------------
Msrc/core/solstice_core_device.c | 9+++++++++
Msrc/core/solstice_core_device.h | 6++++++
Msrc/core/solstice_core_node.c | 244++++++++++---------------------------------------------------------------------
Msrc/core/solstice_core_node.h | 36+++++++-----------------------------
Dsrc/core/solstice_core_scene.c | 450-------------------------------------------------------------------------------
Dsrc/core/solstice_core_scene.h | 40----------------------------------------
Msrc/core/solstice_core_solver.c | 8++++----
Msrc/solstice.h | 15+++++++++++++++
Msrc/solstice_entity.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 277 insertions(+), 823 deletions(-)

diff --git a/cmake/core/CMakeLists.txt b/cmake/core/CMakeLists.txt @@ -34,14 +34,12 @@ include_directories( set(CORE_FILES_SRC solstice_core_device.c solstice_core_node.c - solstice_core_scene.c solstice_core_solver.c) set(CORE_FILES_INC solstice_core.h solstice_core_device.h - solstice_core_node.h - solstice_core_scene.h) + solstice_core_node.h) # Prepend each file in the `SOLSTICE_FILES_<SRC|INC>' list by `SOLSTICE_SOURCE_DIR' rcmake_prepend_path(CORE_FILES_SRC ${CORE_SOURCE_DIR}) @@ -70,11 +68,11 @@ if(NOT NO_TEST) ${CORE_SOURCE_DIR}/test_core_utils.h ${CORE_SOURCE_DIR}/test_core_utils.c) - - new_test(test_core_device) - new_test(test_core_node) - new_test(test_core_scene) - new_test(test_core_solve1) +# TODO: tests need to be fixed +# new_test(test_core_device) +# new_test(test_core_node) +# new_test(test_core_scene) +# new_test(test_core_solve1) - rcmake_copy_runtime_libraries(test_core_solve1) +# rcmake_copy_runtime_libraries(test_core_solve1) endif() diff --git a/src/core/solstice_core.h b/src/core/solstice_core.h @@ -35,7 +35,6 @@ struct ssp_rng; struct score_device; struct score_node; -struct score_scene; /******************************************************************************* * Device API - Main entry point of Solstice core. Applications @@ -65,22 +64,17 @@ score_device_get_solver_device * Node API ******************************************************************************/ extern LOCAL_SYM res_T -score_node_template_create +score_node_geometry_create (struct score_device* dev, - struct score_node** node); - -extern LOCAL_SYM res_T -score_node_instantiate - (struct score_node* template, - struct score_node** instance); + struct score_node** geom); extern LOCAL_SYM res_T -score_node_create_object +score_node_pivot_create (struct score_device* dev, struct score_node** node); extern LOCAL_SYM res_T -score_node_pivot_create +score_node_empty_create (struct score_device* dev, struct score_node** node); @@ -98,9 +92,9 @@ score_node_ref_put (struct score_node* node); extern LOCAL_SYM res_T -score_node_object_setup +score_node_geometry_setup (struct score_node* node, - struct ssol_object* object); + struct ssol_instance* geom); extern LOCAL_SYM res_T score_node_pivot_setup @@ -150,80 +144,26 @@ score_node_sample (struct score_node* node, const int sample); -/* Temporary API for testing purpose - * Instance introspection. - * If the template tree from which instance was created contains node, - * find the corresponding node in instance */ -extern LOCAL_SYM void -score_node_get_instance_of - (const struct score_node* instance, - const struct score_node* node, - struct ssol_instance** solver); - /******************************************************************************* - * Scene API - ******************************************************************************/ -extern LOCAL_SYM res_T -score_scene_create - (struct score_device* dev, - struct score_scene** scene); - -extern LOCAL_SYM void -score_scene_ref_get - (struct score_scene* scene); - -extern LOCAL_SYM void -score_scene_ref_put - (struct score_scene* scene); - -extern LOCAL_SYM res_T -score_scene_attach_instance - (struct score_scene* scene, - struct score_node* instance); - -extern LOCAL_SYM void -score_scene_detach_instance - (struct score_scene* scene, - struct score_node* instance); - -extern LOCAL_SYM void -score_scene_attach_sun - (struct score_scene* scene, - struct ssol_sun* sun); - -extern LOCAL_SYM void -score_scene_detach_sun - (struct score_scene* scene, - struct ssol_sun* sun); - -extern LOCAL_SYM void -score_scene_attach_atmosphere - (struct score_scene* scene, - struct ssol_atmosphere* atm); - -extern LOCAL_SYM void -score_scene_detach_atmosphere - (struct score_scene* scene, - struct ssol_atmosphere* atm); - +* Miscellaneous functions +******************************************************************************/ extern LOCAL_SYM void score_scene_clear - (struct score_scene* scene); + (struct score_device* dev); extern LOCAL_SYM res_T -score_scene_reset_simulation - (struct score_scene* scene); +score_reset_simulation + (struct score_device* dev, + const double sun_dir[3]); extern LOCAL_SYM res_T -score_scene_update_simulation - (struct score_scene* scene); +score_update_simulation + (struct score_device* dev, + const double sun_dir[3]); -/******************************************************************************* - * Miscellaneous functions - ******************************************************************************/ extern LOCAL_SYM res_T score_solve - (struct score_scene* scene, + (struct score_device* dev, struct ssp_rng* rng, const size_t realisations_count, FILE* output, diff --git a/src/core/solstice_core_device.c b/src/core/solstice_core_device.c @@ -48,6 +48,9 @@ device_release(ref_T* ref) ASSERT(ref); dev = CONTAINER_OF(ref, struct score_device, ref); ASSERT(dev && dev->allocator); + if (dev->solver) SSOL(scene_ref_put(dev->solver)); + darray_nodes_release(&dev->instances); + darray_nodes_release(&dev->pivots); if (dev->ssol) ssol_device_ref_put(dev->ssol); MEM_RM(dev->allocator, dev); } @@ -83,6 +86,12 @@ score_device_create res = ssol_device_create(logger, allocator, nthreads_hint, verbose, &dev->ssol); if (res != RES_OK) goto error; + res = ssol_scene_create(dev->ssol, &dev->solver); + if (res != RES_OK) goto error; + + darray_nodes_init(dev->allocator, &dev->instances); + darray_nodes_init(dev->allocator, &dev->pivots); + exit: if (out_dev) *out_dev = dev; return res; diff --git a/src/core/solstice_core_device.h b/src/core/solstice_core_device.h @@ -16,6 +16,8 @@ #ifndef SOLSTICE_CORE_DEVICE_H #define SOLSTICE_CORE_DEVICE_H +#include "solstice_core_node.h" + #include <rsys/ref_count.h> #include <rsys/mem_allocator.h> @@ -28,6 +30,10 @@ struct score_device { int verbose; struct ssol_device* ssol; + struct darray_nodes instances; + struct darray_nodes pivots; + struct ssol_scene* solver; + ref_T ref; }; diff --git a/src/core/solstice_core_node.c b/src/core/solstice_core_node.c @@ -36,22 +36,11 @@ node_release(ref_T* ref) dev = node->device; ASSERT(dev && dev->allocator); switch (node->type) { - case NODE_TEMPLATE_ROOT: - break; - case NODE_INSTANCE_ROOT: - darray_nodes_release(&node->data.instance_root.pivots); - if (node->data.instance_root.template) - score_node_ref_put(node->data.instance_root.template); - break; case NODE_TRACKING_TARGET: break; - case NODE_TEMPLATE: - if (node->data.template_node.solver_object) - SSOL(object_ref_put(node->data.template_node.solver_object)); - break; - case NODE_INSTANCE: - if (node->data.instance_node.solver_instance) - SSOL(instance_ref_put(node->data.instance_node.solver_instance)); + case NODE_GEOMETRY: + if (node->data.geometry_node.solver_instance) + SSOL(instance_ref_put(node->data.geometry_node.solver_instance)); break; case NODE_PIVOT: break; @@ -68,27 +57,6 @@ struct data { struct ssol_instance* result; }; -static res_T -search(const struct sanim_node* n, void* data_, int* found) -{ - const struct score_node* node; - struct data* data; - ASSERT(n && data_ && found); - - data = data_; - node = CONTAINER_OF(n, struct score_node, anim); - if (node->type == NODE_INSTANCE) { - const struct ssol_object* solver_model; - ASSERT(node->data.instance_node.model->type == NODE_TEMPLATE); - solver_model = node->data.instance_node.model->data.template_node.solver_object; - if (solver_model == data->searched) { - data->result = node->data.instance_node.solver_instance; - *found = 1; - return RES_OK; - } - } - return RES_OK; -} /******************************************************************************* * Local functions @@ -144,139 +112,39 @@ node_ref_put_children(struct sanim_node* node) } } -static res_T -instance_internal_node_create - (struct score_device* dev, struct score_node** node) -{ - struct sanim_node* anim; - res_T res = RES_OK; - res = node_create(dev, node, NODE_INSTANCE); - if (res != RES_OK) goto error; - anim = &(*node)->anim; - res = sanim_node_initialize((*node)->device->allocator, anim); - if (res != RES_OK) goto error; -exit: - return res; -error: - if (node && *node) { - score_node_ref_put(*node); - *node = NULL; - } - goto exit; -} - -res_T -node_instanciate_any - (struct score_node* tp_node, - struct score_node** out_node) -{ - struct score_node* node = NULL; - struct score_device* dev; - double v[3]; - res_T res = RES_OK; - - ASSERT(tp_node && out_node); - - dev = tp_node->device; - ASSERT(dev && dev->allocator); - - switch (tp_node->type) { - case NODE_TEMPLATE_ROOT: - res = score_node_instantiate(tp_node, &node); - if (res != RES_OK) goto error; - break; - case NODE_INSTANCE_ROOT: - ASSERT(0); - goto error; - case NODE_TRACKING_TARGET: - res = score_node_tracking_target_create(dev, &node); - if (res != RES_OK) goto error; - SANIM(node_get_translation(&tp_node->anim, v)); - SANIM(node_set_translation(&node->anim, v)); - /* rotations have no meaning for a target */ - break; - case NODE_TEMPLATE: - res = instance_internal_node_create(dev, &node); - if (res != RES_OK) goto error; - res = ssol_object_instantiate( - tp_node->data.template_node.solver_object, - &node->data.instance_node.solver_instance); - if (res != RES_OK) goto error; - node->data.instance_node.model = tp_node; - node->data.instance_node.receiver_mask - = tp_node->data.template_node.receiver_mask; - node->data.instance_node.sample - = tp_node->data.template_node.sample; - SANIM(node_get_translation(&tp_node->anim, v)); - SANIM(node_set_translation(&node->anim, v)); - SANIM(node_get_rotations(&tp_node->anim, v)); - SANIM(node_set_rotations(&node->anim, v)); - break; - case NODE_INSTANCE: - ASSERT(0); - goto error; - case NODE_PIVOT: -#ifndef NDEBUG - { - int p; - ASSERT(sanim_node_is_pivot(&tp_node->anim, &p) == RES_OK && p); - } -#endif - res = score_node_pivot_create(dev, &node); - if (res != RES_OK) goto error; - res = sanim_node_copy_initialize( - dev->allocator, &tp_node->anim, &node->anim); - /* copy includes translation and rotations */ - if (res != RES_OK) goto error; - break; - default: FATAL("Unreachable code.\n"); break; - } - -exit: - if (out_node) *out_node = node; - return res; -error: - if (node) { - score_node_ref_put(node); - node = NULL; - } - goto exit; -} - /******************************************************************************* * Exported score_node functions ******************************************************************************/ res_T -score_node_template_create +score_node_geometry_create (struct score_device* dev, - struct score_node** node) + struct score_node** geom) { struct sanim_node* anim; res_T res = RES_OK; - res = node_create(dev, node, NODE_TEMPLATE_ROOT); + res = node_create(dev, geom, NODE_GEOMETRY); if (res != RES_OK) goto error; - anim = &(*node)->anim; - res = sanim_node_initialize((*node)->device->allocator, anim); + anim = &(*geom)->anim; + res = sanim_node_initialize((*geom)->device->allocator, anim); if (res != RES_OK) goto error; exit: return res; error: - if (node && *node) { - score_node_ref_put(*node); - *node = NULL; + if (geom && *geom) { + score_node_ref_put(*geom); + *geom = NULL; } goto exit; } res_T -score_node_create_object +score_node_pivot_create (struct score_device* dev, struct score_node** node) { res_T res = RES_OK; - res = node_create(dev, node, NODE_TEMPLATE); + res = node_create(dev, node, NODE_PIVOT); if (res != RES_OK) goto error; - (*node)->data.template_node.sample = 1; exit: return res; error: @@ -288,12 +156,12 @@ error: } res_T -score_node_pivot_create +score_node_empty_create (struct score_device* dev, struct score_node** node) { res_T res = RES_OK; - res = node_create(dev, node, NODE_PIVOT); + res = node_create(dev, node, NODE_EMPTY); if (res != RES_OK) goto error; exit: return res; @@ -326,52 +194,22 @@ error: } res_T -score_node_instantiate - (struct score_node* template, - struct score_node** out_instance) -{ - res_T res = RES_OK; - struct score_device* dev; - struct score_node* instance; - ASSERT(template && out_instance && template->type == NODE_TEMPLATE_ROOT); - dev = template->device; - ASSERT(dev); - res = node_create(dev, &instance, NODE_INSTANCE_ROOT); - if (res != RES_OK) goto error; - res = sanim_node_initialize(instance->device->allocator, &instance->anim); - if (res != RES_OK) goto error; - /* actual instantiation is deferred */ - instance->data.instance_root.template = template; - darray_nodes_init(dev->allocator, &instance->data.instance_root.pivots); - score_node_ref_get(template); -exit: - *out_instance = instance; - return res; -error: - if (instance) { - score_node_ref_put(instance); - instance = NULL; - } - goto exit; -} - -res_T -score_node_object_setup +score_node_geometry_setup (struct score_node* node, - struct ssol_object* object) + struct ssol_instance* instance) { res_T res = RES_OK; - ASSERT(node && object && node->type == NODE_TEMPLATE); + ASSERT(node && instance && node->type == NODE_GEOMETRY); /* TODO: deal with multiple setups */ res = sanim_node_initialize(node->device->allocator, &node->anim); if (res != RES_OK) goto error; - node->data.template_node.solver_object = object; - SSOL(object_ref_get(object)); + node->data.geometry_node.solver_instance = instance; + SSOL(instance_ref_put(instance)); exit: return res; error: - if (node->data.template_node.solver_object) { - SSOL(object_ref_put(node->data.template_node.solver_object)); + if (node->data.geometry_node.solver_instance) { + SSOL(instance_ref_put(node->data.geometry_node.solver_instance)); } if (node->anim.data) { SANIM(node_release(&node->anim)); @@ -416,11 +254,7 @@ score_node_add_child { res_T res = RES_OK; ASSERT(father && child - && father->type != NODE_INSTANCE_ROOT - && father->type != NODE_TRACKING_TARGET - && child->type != NODE_TEMPLATE_ROOT - && child->type != NODE_INSTANCE_ROOT - ); + && father->type != NODE_TRACKING_TARGET); res = sanim_node_add_child(&father->anim, &child->anim); if (res != RES_OK) return res; score_node_ref_get(child); @@ -446,7 +280,7 @@ score_node_set_translation (struct score_node* node, const double translation[3]) { - ASSERT(node && translation && node->type != NODE_TEMPLATE_ROOT); + ASSERT(node && translation); SANIM(node_set_translation(&node->anim, translation)); } @@ -455,7 +289,7 @@ score_node_get_translation (const struct score_node* node, double translation[3]) { - ASSERT(node && translation && node->type != NODE_TEMPLATE_ROOT); + ASSERT(node && translation); SANIM(node_get_translation(&node->anim, translation)); } @@ -465,7 +299,6 @@ score_node_set_rotations const double rotations[3]) { ASSERT(node && rotations - && node->type != NODE_TEMPLATE_ROOT && node->type != NODE_TRACKING_TARGET); SANIM(node_set_rotations(&node->anim, rotations)); } @@ -476,7 +309,6 @@ score_node_get_rotations double rotations[3]) { ASSERT(node && rotations - && node->type != NODE_TEMPLATE_ROOT && node->type != NODE_TRACKING_TARGET); SANIM(node_get_rotations(&node->anim, rotations)); } @@ -486,8 +318,8 @@ score_node_set_receiver (struct score_node* node, const int mask) { - ASSERT(node && node->type == NODE_TEMPLATE); - node->data.template_node.receiver_mask = mask; + ASSERT(node && node->type == NODE_GEOMETRY); + node->data.geometry_node.receiver_mask = mask; } void @@ -495,25 +327,7 @@ score_node_sample (struct score_node* node, const int sample) { - ASSERT(node && node->type == NODE_TEMPLATE); - node->data.template_node.sample = sample; + ASSERT(node && node->type == NODE_GEOMETRY); + node->data.geometry_node.sample = sample; } -void -score_node_get_instance_of - (const struct score_node* instance, - const struct score_node* node, - struct ssol_instance** solver) -{ - struct data data; - int found = 0; - ASSERT(instance && node && solver - && instance->type == NODE_INSTANCE_ROOT - && node->type == NODE_TEMPLATE); - - data.searched = node->data.template_node.solver_object; - data.result = NULL; - SANIM(node_search_tree(&instance->anim, &data, search, &found)); - ASSERT(data.result); - *solver = data.result; -} diff --git a/src/core/solstice_core_node.h b/src/core/solstice_core_node.h @@ -21,11 +21,11 @@ #include <rsys/dynamic_array.h> #include <rsys/ref_count.h> -struct sanim_node; +struct score_node; /* Define the darray_nodes data structure */ #define DARRAY_NAME nodes -#define DARRAY_DATA struct sanim_node* +#define DARRAY_DATA struct score_node* #include <rsys/dynamic_array.h> struct score_device; @@ -35,32 +35,16 @@ struct ssol_object; struct ssol_instance; enum node_type { - NODE_TEMPLATE_ROOT, - NODE_INSTANCE_ROOT, - NODE_TEMPLATE, - NODE_INSTANCE, + NODE_GEOMETRY, NODE_TRACKING_TARGET, NODE_PIVOT, + NODE_EMPTY, NODE_TYPES_COUNT__ }; -struct instance_root_data { - struct score_scene* scene_attachment; - struct score_node* template; - /* keep own pivots */ - struct darray_nodes pivots; -}; - -struct template_node_data { - struct ssol_object* solver_object; - int receiver_mask; - int sample; -}; - -struct instance_node_data { +struct geometry_node_data { struct ssol_instance* solver_instance; - struct score_node* model; int receiver_mask; int sample; }; @@ -70,9 +54,8 @@ struct score_node { struct score_device* device; struct sanim_node anim; union { - struct instance_root_data instance_root; - struct template_node_data template_node; - struct instance_node_data instance_node; + /* only types of nodes with specific data */ + struct geometry_node_data geometry_node; } data; ref_T ref; }; @@ -86,9 +69,4 @@ node_create void node_ref_put_children(struct sanim_node* node); -res_T -node_instanciate_any - (struct score_node* tp_node, - struct score_node** out_node); - #endif /* SOLSTICE_CORE_NODE_H */ diff --git a/src/core/solstice_core_scene.c b/src/core/solstice_core_scene.c @@ -1,450 +0,0 @@ -/* 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 "solstice_core.h" -#include "solstice_core_scene.h" -#include "solstice_core_node.h" -#include "solstice_core_device.h" - -#include <rsys/double3.h> - -#include <solstice/ssol.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static INLINE struct sanim_node** -contains(struct darray_nodes* array, struct sanim_node* elt) -{ - size_t count, i; - struct sanim_node** data; - ASSERT(array && elt); - count = darray_nodes_size_get(array); - data = darray_nodes_data_get(array); - for (i = 0; i < count; i++) { - if (elt == data[i]) return &data[i]; - } - return NULL; -} - -static int -remove_if(struct darray_nodes* array, struct sanim_node* elt) -{ - size_t count; - struct sanim_node** data; - struct sanim_node** ptr; - ASSERT(array && elt); - ptr = contains(array, elt); - if (ptr == NULL) return 0; - count = darray_nodes_size_get(array); - data = darray_nodes_data_get(array); - *ptr = data[count - 1]; - darray_nodes_pop_back(array); - return 1; -} - -static res_T -create_instance_tree_ - (struct darray_nodes* pivots, - const struct score_node* t_node, - struct score_node* i_node) -{ - res_T res = RES_OK; - size_t count, i; - struct score_node* node = NULL; - int p; - ASSERT(pivots && t_node && i_node); - - SANIM(node_get_children_count(&t_node->anim, &count)); - for (i = 0; i < count; i++) { - struct sanim_node* t_child_; - struct score_node *t_child, *i_child; - SANIM(node_get_child(&t_node->anim, i, &t_child_)); - t_child = CONTAINER_OF(t_child_, struct score_node, anim); - res = node_instanciate_any(t_child, &i_child); - if (res != RES_OK) goto error; - res = sanim_node_add_child(&i_node->anim, &i_child->anim); - if (res != RES_OK) goto error; - create_instance_tree_(pivots, t_child, i_child); - } - - SANIM(node_is_pivot(&i_node->anim, &p)); - if (p) { - struct sanim_node* n = &i_node->anim; - res = darray_nodes_push_back(pivots, &n); - if (res != RES_OK) goto error; - } - -exit: - return res; -error: - if (node) { - node = NULL; - } - goto exit; -} - -static res_T -create_instance_tree(struct score_node* instance) -{ - res_T res = RES_OK; - struct score_node* temp; - ASSERT(instance && instance->type == NODE_INSTANCE_ROOT); - node_ref_put_children(&instance->anim); - darray_nodes_clear(&instance->data.instance_root.pivots); - temp = instance->data.instance_root.template; - ASSERT(temp->type == NODE_TEMPLATE_ROOT); - res = create_instance_tree_(&instance->data.instance_root.pivots, temp, instance); - if (res != RES_OK) goto error; -exit: - return res; -error: - node_ref_put_children(&instance->anim); - darray_nodes_clear(&instance->data.instance_root.pivots); - goto exit; -} - -static res_T -node_to_solver(const struct sanim_node* node_, const double transform[12], void* data) -{ - struct score_node* node; - struct ssol_scene* scene = data; - res_T res = RES_OK; - ASSERT(node_ && transform && data); - node = CONTAINER_OF(node_, struct score_node, anim); - switch (node->type) { - case NODE_TEMPLATE_ROOT: - ASSERT(0); - break; - case NODE_INSTANCE_ROOT: - /* the root doesn't include any solver-related item */ - break; - case NODE_TRACKING_TARGET: - /* not a solver-related item */ - break; - case NODE_TEMPLATE: - ASSERT(0); - break; - case NODE_INSTANCE: - SSOL(instance_set_transform( - node->data.instance_node.solver_instance, transform)); - SSOL(instance_set_receiver( - node->data.instance_node.solver_instance, - node->data.instance_node.receiver_mask)); - SSOL(instance_sample( - node->data.instance_node.solver_instance, - node->data.instance_node.sample)); - res = ssol_scene_attach_instance( - scene, node->data.instance_node.solver_instance); - break; - case NODE_PIVOT: - /* not a solver-related item */ - break; - default: FATAL("Unreachable code.\n"); break; - } - return res; -} - -static res_T -node_to_solver_update(const struct sanim_node* node_, const double transform[12], void* data) -{ - struct score_node* node; - res_T res = RES_OK; - (void) data; - ASSERT(node_ && transform); - node = CONTAINER_OF(node_, struct score_node, anim); - switch (node->type) { - case NODE_TEMPLATE_ROOT: - ASSERT(0); - break; - case NODE_INSTANCE_ROOT: - ASSERT(0); /* should only visit post-pivot nodes */ - break; - case NODE_TRACKING_TARGET: - /* not a solver-related item */ - break; - case NODE_TEMPLATE: - ASSERT(0); - break; - case NODE_INSTANCE: - SSOL(instance_set_transform( - node->data.instance_node.solver_instance, transform)); - break; - case NODE_PIVOT: - /* not a solver-related item */ - break; - default: FATAL("Unreachable code.\n"); break; - } - return res; -} - -static INLINE res_T -update_pivots(struct score_scene* scene, const double sun_dir[3]) -{ - size_t i_count, i; - struct sanim_node** instances; - res_T res = RES_OK; - ASSERT(scene && sun_dir); - i_count = darray_nodes_size_get(&scene->instances); - instances = darray_nodes_data_get(&scene->instances); - for (i = 0; i < i_count; i++) { - size_t p_count, p; - struct sanim_node** pivots; - struct score_node* instance = CONTAINER_OF(instances[i], struct score_node, anim); - ASSERT(instance->type == NODE_INSTANCE_ROOT); - p_count = darray_nodes_size_get(&instance->data.instance_root.pivots); - pivots = darray_nodes_data_get(&instance->data.instance_root.pivots); - for (p = 0; p < p_count; p++) { - struct score_node* pivot = CONTAINER_OF(pivots[p], struct score_node, anim); - res = sanim_node_solve_pivot(&pivot->anim, sun_dir); - if (res != RES_OK) return res; - } - } - return RES_OK; -} - -static void -scene_release(ref_T* ref) -{ - struct score_device* dev; - struct score_scene* scene = CONTAINER_OF(ref, struct score_scene, ref); - ASSERT(ref); - dev = scene->device; - ASSERT(dev && dev->allocator); - score_scene_clear(scene); - darray_nodes_release(&scene->instances); - if (scene->solver) SSOL(scene_ref_put(scene->solver)); - if (scene->sun) SSOL(sun_ref_put(scene->sun)); - if (scene->atmosphere) SSOL(atmosphere_ref_put(scene->atmosphere)); - MEM_RM(dev->allocator, scene); - score_device_ref_put(dev); -} - -/******************************************************************************* - * Exported score_scene functions - ******************************************************************************/ -res_T -score_scene_create - (struct score_device* dev, - struct score_scene** out_scene) -{ - struct score_scene* scene; - res_T res = RES_OK; - ASSERT(dev && out_scene); - - scene = MEM_CALLOC(dev->allocator, 1, sizeof(struct score_scene)); - if (!scene) { - res = RES_MEM_ERR; - goto error; - } - - score_device_ref_get(dev); - scene->device = dev; - ref_init(&scene->ref); - darray_nodes_init(dev->allocator, &scene->instances); - - res = ssol_scene_create(dev->ssol, &scene->solver); - if (res != RES_OK) goto error; - -exit: - if (out_scene) *out_scene = scene; - return res; -error: - if (scene) { - score_scene_ref_put(scene); - scene = NULL; - } - goto exit; -} - -void -score_scene_ref_get(struct score_scene* scene) -{ - ASSERT(scene); - ref_get(&scene->ref); -} - -void -score_scene_ref_put(struct score_scene* scene) -{ - ASSERT(scene); - ref_put(&scene->ref, scene_release); -} - -res_T -score_scene_attach_instance - (struct score_scene* scene, - struct score_node* instance) -{ - struct sanim_node* anim; - res_T res = RES_OK; - int ok; - ASSERT(scene && instance - && instance->type == NODE_INSTANCE_ROOT - && !instance->data.instance_root.scene_attachment); - anim = &instance->anim; - SANIM(node_is_initialized(anim, &ok)); - ASSERT(ok); - res = darray_nodes_push_back(&scene->instances, &anim); - if (res != RES_OK) goto error; - instance->data.instance_root.scene_attachment = scene; - score_node_ref_get(instance); -exit: - return res; -error: - remove_if(&scene->instances, anim); - goto exit; -} - -void -score_scene_detach_instance - (struct score_scene* scene, - struct score_node* instance) -{ - struct sanim_node* anim; - int ok; - ASSERT(scene && instance - && instance->type == NODE_INSTANCE_ROOT - && instance->data.instance_root.scene_attachment == scene); - anim = &instance->anim; - SANIM(node_is_initialized(anim, &ok)); - ASSERT(ok); - ok = remove_if(&scene->instances, anim); - ASSERT(ok); - instance->data.instance_root.scene_attachment = NULL; - score_node_ref_put(instance); -} - -void -score_scene_attach_sun - (struct score_scene* scene, - struct ssol_sun* sun) -{ - ASSERT(scene && sun); - SSOL(scene_attach_sun(scene->solver, sun)); - SSOL(sun_ref_get(sun)); - scene->sun = sun; -} - -void -score_scene_detach_sun - (struct score_scene* scene, - struct ssol_sun* sun) -{ - ASSERT(scene && sun); - SSOL(scene_detach_sun(scene->solver, sun)); - SSOL(sun_ref_put(sun)); - scene->sun = NULL; -} - -void -score_scene_attach_atmosphere - (struct score_scene* scene, - struct ssol_atmosphere* atm) -{ - ASSERT(scene && atm); - SSOL(scene_attach_atmosphere(scene->solver, atm)); - SSOL(atmosphere_ref_get(atm)); - scene->atmosphere = atm; -} - -void -score_scene_detach_atmosphere - (struct score_scene* scene, - struct ssol_atmosphere* atm) -{ - ASSERT(scene && atm); - SSOL(scene_detach_atmosphere(scene->solver, atm)); - SSOL(atmosphere_ref_put(atm)); - scene->atmosphere = NULL; -} - -void -score_scene_clear - (struct score_scene* scene) -{ - size_t count, i; - struct sanim_node** data; - ASSERT(scene); - count = darray_nodes_size_get(&scene->instances); - data = darray_nodes_data_get(&scene->instances); - for (i = 0; i < count; i++) { - struct score_node* node = CONTAINER_OF(data[i], struct score_node, anim); - score_node_ref_put(node); - } - darray_nodes_clear(&scene->instances); -} - -res_T -score_scene_reset_simulation(struct score_scene* scene) -{ - res_T res = RES_OK; - size_t count = 0, i; - struct sanim_node** instances; - double sun_dir[3]; - ASSERT(scene && scene->sun); - SSOL(sun_get_direction(scene->sun, sun_dir)); - count = darray_nodes_size_get(&scene->instances); - instances = darray_nodes_data_get(&scene->instances); - SSOL(scene_clear(scene->solver)); - SSOL(scene_attach_sun(scene->solver, scene->sun)); - if (scene->atmosphere) - SSOL(scene_attach_atmosphere(scene->solver, scene->atmosphere)); - for (i = 0; i < count; i++) { - struct score_node* inst = CONTAINER_OF(instances[i], struct score_node, anim); - ASSERT(inst->type == NODE_INSTANCE_ROOT); - res = create_instance_tree(inst); - if (res != RES_OK) goto error; - res = sanim_node_visit_tree( - instances[i], sun_dir, scene->solver, &node_to_solver); - if (res != RES_OK) goto error; - } -exit: - return res; -error: - for (i = 0; i < count; i++) node_ref_put_children(instances[i]); - goto exit; -} - -res_T -score_scene_update_simulation(struct score_scene* scene) -{ - res_T res = RES_OK; - size_t count = 0, i; - size_t p_count = 0, p; - struct sanim_node** instances; - double sun_dir[3]; - ASSERT(scene && scene->sun); - SSOL(sun_get_direction(scene->sun, sun_dir)); - count = darray_nodes_size_get(&scene->instances); - instances = darray_nodes_data_get(&scene->instances); - for (i = 0; i < count; i++) { - struct sanim_node** pivots; - struct score_node* inst = CONTAINER_OF(instances[i], struct score_node, anim); - ASSERT(inst->type == NODE_INSTANCE_ROOT); - p_count = darray_nodes_size_get(&inst->data.instance_root.pivots); - pivots = darray_nodes_data_get(&inst->data.instance_root.pivots); - for (p = 0; p < p_count; p++) { - res = sanim_node_visit_tree( - pivots[p], sun_dir, NULL, &node_to_solver_update); - if (res != RES_OK) goto error; - } - } -exit: - return res; -error: - goto exit; -} - diff --git a/src/core/solstice_core_scene.h b/src/core/solstice_core_scene.h @@ -1,40 +0,0 @@ -/* 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/>. */ - -#ifndef SCORE_SCENE_H -#define SCORE_SCENE_H - -#include "solstice_core.h" -#include "solstice_core_node.h" - -#include <rsys/dynamic_array.h> -#include <rsys/ref_count.h> - -struct ssol_scene; -struct ssol_sun; -struct ssol_atmosphere; - -struct score_device; - -struct score_scene { - struct score_device* device; - struct darray_nodes instances; - struct ssol_scene* solver; - struct ssol_sun* sun; - struct ssol_atmosphere* atmosphere; - ref_T ref; -}; - -#endif /* SCORE_SCENE_H */ diff --git a/src/core/solstice_core_solver.c b/src/core/solstice_core_solver.c @@ -14,18 +14,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "solstice_core.h" -#include "solstice_core_scene.h" +#include "solstice_core_device.h" #include <solstice/ssol.h> res_T score_solve - (struct score_scene* scene, + (struct score_device* dev, struct ssp_rng* rng, const size_t realisations_count, FILE* output, struct ssol_estimator* estimator) { - ASSERT(scene && rng && realisations_count && output && estimator); - return ssol_solve(scene->solver, rng, realisations_count, output, estimator); + ASSERT(dev && rng && realisations_count && output && estimator); + return ssol_solve(dev->solver, rng, realisations_count, output, estimator); } \ No newline at end of file diff --git a/src/solstice.h b/src/solstice.h @@ -25,23 +25,38 @@ struct solparser; struct ssol_device; struct ssol_material; struct ssol_object; +struct sanim_node; +struct score_device; +struct score_node; #define HTABLE_NAME material #define HTABLE_KEY size_t #define HTABLE_DATA struct ssol_material* #include <rsys/hash_table.h> +#include <rsys/dynamic_array.h> #define HTABLE_NAME object #define HTABLE_KEY size_t #define HTABLE_DATA struct ssol_object* #include <rsys/hash_table.h> +#define HTABLE_NAME anchor +#define HTABLE_KEY size_t +#define HTABLE_DATA struct score_node* +#include <rsys/hash_table.h> + +#include "core/solstice_core_node.h" + struct solstice { struct ssol_device* ssol; struct solparser* parser; + struct score_device* score; struct htable_material materials; struct htable_object objects; + struct htable_anchor anchors; + struct darray_nodes roots; + struct darray_nodes pivots; struct mem_allocator* allocator; }; diff --git a/src/solstice_entity.c b/src/solstice_entity.c @@ -15,3 +15,186 @@ #include "solstice.h" #include "solstice_c.h" + +#include <solstice/ssol.h> +#include <solstice/sanim.h> +#include "core/solstice_core.h" + +res_T +solstice_setup_entity + (struct solstice* solstice, + const struct solparser_entity* entity, + const char is_root, + struct score_node** out_node) +{ + struct score_node* root_node = NULL; + struct score_node* atchmnt_node = NULL; + struct ssol_instance* instance = NULL; + const struct solparser_anchor_id* anchors = NULL; + const struct solparser_entity_id* children = NULL; + size_t count, i; + res_T res = RES_OK; + ASSERT(solstice && solstice->parser && solstice->score && entity); + + switch (entity->type) { + case SOLPARSER_ENTITY_EMPTY: + { + struct score_node* empty_node = NULL; + res = score_node_empty_create(solstice->score, &empty_node); + if (res != RES_OK) goto error; + score_node_set_translation(empty_node, entity->translation); + score_node_set_rotations(empty_node, entity->rotation); + atchmnt_node = root_node = empty_node; + break; + } + case SOLPARSER_ENTITY_GEOMETRY: + { + struct score_node* geometry_node = NULL; + res = score_node_geometry_create(solstice->score, &geometry_node); + if (res != RES_OK) goto error; + score_node_set_translation(geometry_node, entity->translation); + score_node_set_rotations(geometry_node, entity->rotation); + res = solstice_instantiate_geometry( + /* TODO: attach instance to solver */ + solstice, entity->data.geometry, &instance); + if (res != RES_OK) goto error; + res = score_node_geometry_setup(geometry_node, instance); + if (res != RES_OK) goto error; + atchmnt_node = root_node = geometry_node; + break; + } + case SOLPARSER_ENTITY_PIVOT: + { + /* Each entity introduces a new coordinate system + * and each object or pivot has some positionning in this system. + * This behaviour is implemented through 2 levels of sanim_node. */ + /* TODO: remove pivot positionning? */ + struct score_node* entity_node = NULL; + struct score_node* pivot_node = NULL; + const struct solparser_pivot* parser_pivot = NULL; + struct sanim_pivot anim_pivot = SANIM_PIVOT_NULL; + struct sanim_tracking anim_tracking = SANIM_TRACKING_NULL; + res = score_node_empty_create(solstice->score, &entity_node); + if (res != RES_OK) goto error; + score_node_set_translation(entity_node, entity->translation); + score_node_set_rotations(entity_node, entity->rotation); + res = score_node_pivot_create(solstice->score, &pivot_node); + if (res != RES_OK) goto error; + parser_pivot = solparser_get_pivot(solstice->parser, entity->data.pivot); + ASSERT(parser_pivot); + score_node_set_translation(pivot_node, parser_pivot->translation); + score_node_set_rotations(pivot_node, parser_pivot->rotation); + /* TODO: 2-axis pivots */ + anim_pivot.type = PIVOT_SINGLE_AXIS; + d3_set(anim_pivot.data.pivot1.ref_normal, parser_pivot->normal); + d3_set(anim_pivot.data.pivot1.ref_point, parser_pivot->point); + switch (parser_pivot->target_type) { + case SOLPARSER_TARGET_ANCHOR: + { + struct score_node** ptgt = NULL; + const struct solparser_anchor_id id = parser_pivot->target.anchor; + anim_tracking.policy = TRACKING_NODE_TARGET; + ptgt = htable_anchor_find(&solstice->anchors, &id.i); + score_node_track_me(*ptgt, &anim_tracking); + break; + } + case SOLPARSER_TARGET_DIRECTION: + anim_tracking.policy = TRACKING_OUT_DIR; + d3_set(anim_tracking.data.out_dir.u, parser_pivot->target.direction); + break; + case SOLPARSER_TARGET_POSITION: + anim_tracking.policy = TRACKING_POINT; + d3_set(anim_tracking.data.point.target, parser_pivot->target.position); + anim_tracking.data.point.target_is_local = 0; /* TODO */ + break; + case SOLPARSER_TARGET_SUN: + anim_tracking.policy = TRACKING_SUN; + break; + default: FATAL("Unreachable code.\n"); break; + } + res = score_node_pivot_setup(pivot_node, &anim_pivot, &anim_tracking); + if (res != RES_OK) goto error; + res = darray_nodes_push_back(&solstice->pivots, &pivot_node); + if (res != RES_OK) goto error; + root_node = entity_node; + atchmnt_node = pivot_node; + break; + } + default: FATAL("Unreachable code.\n"); break; + } + + ASSERT(root_node && atchmnt_node); + if (is_root) darray_nodes_push_back(&solstice->roots, &root_node); + + /* register anchors */ + count = darray_anchor_id_size_get(&entity->anchors); + anchors = darray_anchor_id_cdata_get(&entity->anchors); + for (i = 0; i < count; i++) { + struct score_node* tgt; + const struct solparser_anchor* anchor = NULL; + res = score_node_tracking_target_create(solstice->score, &tgt); + if (res != RES_OK) goto error; + anchor = solparser_get_anchor(solstice->parser, anchors[i]); + ASSERT(anchor); + res = htable_anchor_set(&solstice->anchors, &anchors[i].i, &tgt); + if (res != RES_OK) goto error; + score_node_set_translation(tgt, anchor->position); + res = score_node_add_child(atchmnt_node, tgt); + if (res != RES_OK) goto error; + } + + /* TODO: setup children */ + count = solparser_entity_get_children_count(entity); + children = darray_child_id_cdata_get(&entity->children); + for (i = 0; i < count; i++) { + const struct solparser_entity* child; + struct score_node* child_root = NULL; + child = solparser_get_entity(solstice->parser, children[i]); + ASSERT(child); + res = solstice_setup_entity(solstice, child, 0, &child_root); + if (res != RES_OK) goto error; + ASSERT(child_root); + res = score_node_add_child(atchmnt_node, child_root); + if (res != RES_OK) goto error; + } + +end: + if (out_node) *out_node = root_node; + return res; + +error: + goto end; +} + +res_T +solstice_setup_entities + (struct solstice* solstice) +{ + struct solparser_entity_iterator it, it_end; + res_T res = RES_OK; + ASSERT(solstice && solstice->parser && solstice->score); + + /* release possible previous roots (incomplete, TODO) */ + score_scene_clear(solstice->score); + + /* (re) create the list of roots from entities */ + solparser_entity_iterator_begin(solstice->parser, &it); + solparser_entity_iterator_end(solstice->parser, &it); + while (!solparser_entity_iterator_eq(&it, &it_end)) { + struct solparser_entity_id entity_id; + const struct solparser_entity* entity; + + entity_id = solparser_entity_iterator_get(&it); + entity = solparser_get_entity(solstice->parser, entity_id); + + res = solstice_setup_entity(solstice, entity, 1, NULL); + if (res != RES_OK) goto error; + + solparser_entity_iterator_next(&it); + } + +end: + return res; +error: + goto end; +} +\ No newline at end of file