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 e63c9738b791b37c8fb0f82522d6eb04c4ba0b3f
parent 10614f7eeafcb58d2d6a5012bb1488945a31a282
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  5 Jan 2017 14:56:24 +0100

Deep refactoring of the solstice_setup_entities function

The geometries of the entities are now positionned in world space during
the setup of the entities.

Diffstat:
Msrc/core/solstice_core.h | 4++--
Msrc/core/solstice_core_node.c | 14+++++++-------
Msrc/core/solstice_core_node.h | 3++-
Msrc/solstice.c | 14+++++++++++---
Msrc/solstice_entity.c | 321++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
5 files changed, 234 insertions(+), 122 deletions(-)

diff --git a/src/core/solstice_core.h b/src/core/solstice_core.h @@ -139,8 +139,8 @@ score_node_sample const int sample); /******************************************************************************* -* Miscellaneous functions -******************************************************************************/ + * Miscellaneous functions + ******************************************************************************/ extern LOCAL_SYM void score_scene_clear (struct score_device* dev); diff --git a/src/core/solstice_core_node.c b/src/core/solstice_core_node.c @@ -25,7 +25,7 @@ /* * NOTE: There is a weakness in the Solstice-Anim API that forbids the - * initialization of he pivot node on its creation contraty to the common node + * initialization of the pivot node on its creation contraty to the common node. */ /******************************************************************************* @@ -59,7 +59,6 @@ struct data { struct ssol_instance* result; }; - /******************************************************************************* * Local functions ******************************************************************************/ @@ -211,8 +210,7 @@ error: res_T score_node_geometry_setup - (struct score_node* node, - struct ssol_instance* instance) + (struct score_node* node, struct ssol_instance* instance) { int is_init = 0; res_T res = RES_OK; @@ -228,14 +226,17 @@ score_node_geometry_setup if (res != RES_OK) goto error; node->data.geometry_node.solver_instance = instance; SSOL(instance_ref_get(instance)); + exit: return res; error: if (node->data.geometry_node.solver_instance) { SSOL(instance_ref_put(node->data.geometry_node.solver_instance)); + node->data.geometry_node.solver_instance = NULL; } if (node->anim.data) { SANIM(node_release(&node->anim)); + node->anim = SANIM_NODE_NULL; } goto exit; } @@ -265,6 +266,7 @@ exit: error: if (node->anim.data) { SANIM(node_release(&node->anim)); + node->anim = SANIM_NODE_NULL; } goto exit; } @@ -279,9 +281,7 @@ score_node_track_me } res_T -score_node_add_child - (struct score_node* father, - struct score_node* child) +score_node_add_child(struct score_node* father, struct score_node* child) { res_T res = RES_OK; ASSERT(father && child diff --git a/src/core/solstice_core_node.h b/src/core/solstice_core_node.h @@ -54,7 +54,8 @@ struct score_node { struct score_device* device; struct sanim_node anim; union { - /* only types of nodes with specific data */ + /* only types of nodes with specific data. + * TODO remove the useless union (?) */ struct geometry_node_data geometry_node; } data; ref_T ref; diff --git a/src/solstice.c b/src/solstice.c @@ -299,11 +299,19 @@ solstice_release(struct solstice* solstice) res_T solstice_run(struct solstice* solstice) { + res_T res = RES_OK; ASSERT(solstice); + if(solstice->framebuffer) { /* Rendering */ - return solstice_draw(solstice); + res = solstice_draw(solstice); } else { /* Solstice integration */ - /* TODO */ - return RES_OK; + res = RES_BAD_OP; /* TODO */ } + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; } + diff --git a/src/solstice_entity.c b/src/solstice_entity.c @@ -24,74 +24,113 @@ * Helper function ******************************************************************************/ static res_T -solstice_setup_entity - (struct solstice* solstice, - const struct solparser_entity* entity, - const char is_root, - struct score_node** out_node) +update_instance_transform + (const struct sanim_node* n, const double transform[12], void* data) { - 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; + struct score_node* node; + ASSERT(n && transform); + (void)data; + + node = CONTAINER_OF(n, struct score_node, anim); + if(node->type != NODE_GEOMETRY) return RES_OK; + return ssol_instance_set_transform + (node->data.geometry_node.solver_instance, transform); +} + +static struct score_node* +setup_entity_empty + (struct solstice* solstice, const struct solparser_entity* entity) +{ + struct score_node* empty_node = NULL; res_T res = RES_OK; - ASSERT(solstice && solstice->parser && solstice->score && entity); + ASSERT(solstice && entity); + + 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); - /* TODO Split the cases un sub-functions! */ - 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; +exit: + return empty_node; +error: + if(empty_node) { + score_node_ref_put(empty_node); + empty_node = NULL; } - 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; - res = solstice_instantiate_geometry - (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; - score_node_set_translation(geometry_node, entity->translation); - score_node_set_rotations(geometry_node, entity->rotation); - atchmnt_node = root_node = geometry_node; - break; + goto exit; +} + +static struct score_node* +setup_entity_geometry + (struct solstice* solstice, const struct solparser_entity* entity) +{ + struct score_node* geometry_node = NULL; + struct ssol_instance* instance = NULL; + res_T res = RES_OK; + ASSERT(solstice && entity); + + res = score_node_geometry_create(solstice->score, &geometry_node); + if(res != RES_OK) goto error; + + res = solstice_instantiate_geometry + (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; + + score_node_set_translation(geometry_node, entity->translation); + score_node_set_rotations(geometry_node, entity->rotation); + +exit: + if(instance) SSOL(instance_ref_put(instance)); + return geometry_node; +error: + if(geometry_node) { + score_node_ref_put(geometry_node); + geometry_node = NULL; } - 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) { + goto exit; +} + +static struct score_node* +setup_entity_pivot + (struct solstice* solstice, + const struct solparser_entity* entity, + struct score_node** atchmnt_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_T res = RES_OK; + ASSERT(solstice && entity && atchmnt_node); + + /* + * 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. + */ + + 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); + + parser_pivot = solparser_get_pivot(solstice->parser, entity->data.pivot); + res = score_node_pivot_create(solstice->score, &pivot_node); + if(res != RES_OK) goto error; + 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; @@ -114,70 +153,117 @@ solstice_setup_entity 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; + + 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; + +exit: + *atchmnt_node = pivot_node; + return entity_node; +error: + if(pivot_node) { + score_node_ref_put(pivot_node); + pivot_node = NULL; + } + if(entity_node) { + score_node_ref_put(entity_node); + entity_node = NULL; + } + goto exit; +} + +static struct score_node* +setup_entity(struct solstice* solstice, const struct solparser_entity* entity) +{ + struct score_node* root_node = NULL; + struct score_node* atchmnt_node = NULL; + struct score_node* tgt = NULL; + struct score_node* child_root = NULL; + size_t i; + res_T res = RES_OK; + ASSERT(solstice && solstice->parser && solstice->score && entity); + + switch(entity->type) { + case SOLPARSER_ENTITY_EMPTY: + atchmnt_node = root_node = setup_entity_empty(solstice, entity); + break; + case SOLPARSER_ENTITY_GEOMETRY: + atchmnt_node = root_node = setup_entity_geometry(solstice, entity); + break; + case SOLPARSER_ENTITY_PIVOT: + root_node = setup_entity_pivot(solstice, entity, &atchmnt_node); + break; + default: FATAL("Unreachable code.\n"); break; } - ASSERT(root_node && atchmnt_node); - if (is_root) darray_nodes_push_back(&solstice->roots, &root_node); + if(!root_node || !atchmnt_node) { + fprintf(stderr, "Could not setup the entity node.\n"); + goto error; + } - /* 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; + /* Register anchors */ + FOR_EACH(i, 0, solparser_entity_get_anchors_count(entity)) { + struct solparser_anchor_id id; 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; + if(res != RES_OK) goto error; + + id = solparser_entity_get_anchor(entity, i); + anchor = solparser_get_anchor(solstice->parser, id); + + res = htable_anchor_set(&solstice->anchors, &id.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; + if(res != RES_OK) goto error; + + tgt = NULL; } - /* TODO: setup children */ - count = solparser_entity_get_children_count(entity); - children = darray_child_id_cdata_get(&entity->children); - for (i = 0; i < count; i++) { + /* Setup children */ + FOR_EACH(i, 0, solparser_entity_get_children_count(entity)) { + struct solparser_entity_id id; 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); + + id = solparser_entity_get_child(entity, i); + child = solparser_get_entity(solstice->parser, id); + + child_root = setup_entity(solstice, child); + if(!child_root) goto error; + res = score_node_add_child(atchmnt_node, child_root); - if (res != RES_OK) goto error; - } + if(res != RES_OK) goto error; -end: - if (instance) SSOL(instance_ref_put(instance)); - if (out_node) *out_node = root_node; - return res; + child_root = NULL; + } +exit: + return root_node; error: - goto end; + if(tgt) score_node_ref_put(tgt); + if(child_root) score_node_ref_put(child_root); + if(atchmnt_node && atchmnt_node!=root_node) score_node_ref_put(atchmnt_node); + if(root_node) score_node_ref_put(root_node); + atchmnt_node = NULL; + root_node = NULL; + goto exit; } /******************************************************************************* * Local functions ******************************************************************************/ res_T -solstice_setup_entities - (struct solstice* solstice) +solstice_setup_entities(struct solstice* solstice) { struct solparser_entity_iterator it, it_end; + struct score_node* root = NULL; + const double dummy_sun_dir[3] = {0, 0, 1}; /* Use the user defined dir */ res_T res = RES_OK; ASSERT(solstice && solstice->parser && solstice->score); @@ -187,22 +273,39 @@ solstice_setup_entities /* (re) create the list of roots from entities */ solparser_entity_iterator_begin(solstice->parser, &it); solparser_entity_iterator_end(solstice->parser, &it_end); - while (!solparser_entity_iterator_eq(&it, &it_end)) { + 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; + root = setup_entity(solstice, entity); + if(!root) goto error; + + /* Initialialised the world space position of the entity geometry */ + res = sanim_node_visit_tree + (&root->anim, dummy_sun_dir, NULL, update_instance_transform); + if(res != RES_OK) { + fprintf(stderr, + "Could not setup the transformation of the entity geometries.\n"); + goto error; + } + + res = darray_nodes_push_back(&solstice->roots, &root); + if(res != RES_OK) { + fprintf(stderr, "Could not register a root entity.\n"); + goto error; + } solparser_entity_iterator_next(&it); + root = NULL; } -end: +exit: return res; error: - goto end; + if(root) score_node_ref_put(root); + goto exit; }