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:
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