commit e14b05b4a5847bfadb33467b98928befa537f7aa
parent 68bb68d306b16badba07149ae513ea205d4f3eca
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 6 Jan 2017 12:05:07 +0100
Handle the sun directions in Solstice
Currently Solstice can only render the provided scene. The sun
directions are used to update the entities priorly to the rendering. If
several directions are submitted, Solstice renders an image per sun
direction. Each output image are then preceded by the header
"# Sun direction: ..." defining the Cartesian coordinates of the sun
direction used to update the position of the Solstice entities.
Diffstat:
7 files changed, 117 insertions(+), 11 deletions(-)
diff --git a/src/solstice.c b/src/solstice.c
@@ -156,6 +156,54 @@ error:
goto exit;
}
+static INLINE void
+spherical_to_cartesian_sun_dir
+ (struct solstice_args_spherical* spherical, double sun_dir[3])
+{
+ double cos_azimuth;
+ double sin_azimuth;
+ double cos_elevation;
+ double sin_elevation;
+ ASSERT(spherical && sun_dir);
+
+ cos_azimuth = cos(spherical->azimuth);
+ sin_azimuth = sin(spherical->azimuth);
+ cos_elevation = cos(spherical->elevation);
+ sin_elevation = sin(spherical->elevation);
+
+ sun_dir[0] = -(cos_elevation * cos_azimuth);
+ sun_dir[1] = -(cos_elevation * sin_azimuth);
+ sun_dir[2] = -(sin_elevation);
+}
+
+static res_T
+setup_sun_dirs(struct solstice* solstice, const struct solstice_args* args)
+{
+ double* sun_dirs = NULL;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(solstice && args);
+
+ res = darray_double_resize(&solstice->sun_dirs, args->nsun_dirs*3/*#dims*/);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Could not reserve the list of %lu sun directions.\n", args->nsun_dirs);
+ goto error;
+
+ }
+
+ sun_dirs = darray_double_data_get(&solstice->sun_dirs);
+ FOR_EACH(i, 0, args->nsun_dirs) {
+ spherical_to_cartesian_sun_dir(args->sun_dirs + i, sun_dirs + i*3/*#dims*/);
+ }
+
+exit:
+ return res;
+error:
+ darray_double_clear(&solstice->sun_dirs);
+ goto exit;
+}
+
static res_T
load_data(struct solstice* solstice, const struct solstice_args* args)
{
@@ -218,6 +266,7 @@ solstice_init
htable_object_init(allocator, &solstice->objects);
darray_nodes_init(allocator, &solstice->roots);
darray_nodes_init(allocator, &solstice->pivots);
+ darray_double_init(allocator, &solstice->sun_dirs);
solstice->allocator = allocator ? allocator : &mem_default_allocator;
@@ -253,6 +302,9 @@ solstice_init
if(res != RES_OK) goto error;
}
+ res = setup_sun_dirs(solstice, args);
+ if(res != RES_OK) goto error;
+
if(!args->output_filename) {
solstice->output = stdout;
} else {
@@ -294,20 +346,40 @@ solstice_release(struct solstice* solstice)
htable_object_release(&solstice->objects);
darray_nodes_release(&solstice->roots);
darray_nodes_release(&solstice->pivots);
+ darray_double_release(&solstice->sun_dirs);
}
res_T
solstice_run(struct solstice* solstice)
{
+ const double* sun_dirs = NULL;
+ size_t nsun_dirs = 0;
+ size_t i;
res_T res = RES_OK;
ASSERT(solstice);
- if(solstice->framebuffer) { /* Rendering */
- res = solstice_draw(solstice);
- } else { /* Solstice integration */
+ sun_dirs = darray_double_cdata_get(&solstice->sun_dirs);
+ nsun_dirs = darray_double_size_get(&solstice->sun_dirs);
+ ASSERT(nsun_dirs%3 == 0);
+ nsun_dirs /= 3/*#dims*/;
+
+ if(!solstice->framebuffer) { /* Solstice integration */
res = RES_BAD_OP; /* TODO */
+ goto error;
+ } else if(!nsun_dirs) {
+ res = solstice_draw(solstice);
+ if(res != RES_OK) goto error;
+ } else {
+ FOR_EACH(i, 0, nsun_dirs) {
+ const double* sun_dir = sun_dirs + i*3/*#dims*/;
+
+ res = solstice_update_entities(solstice, sun_dir);
+ if(res != RES_OK) goto error;
+ fprintf(solstice->output, "# Sun direction: %g %g %g\n", SPLIT3(sun_dir));
+ res = solstice_draw(solstice);
+ if(res != RES_OK) goto error;
+ }
}
- if(res != RES_OK) goto error;
exit:
return res;
diff --git a/src/solstice.h b/src/solstice.h
@@ -18,6 +18,7 @@
#include "parser/solparser_material.h"
+#include <rsys/dynamic_array_double.h>
#include <rsys/hash_table.h>
#include <rsys/mem_allocator.h>
@@ -65,6 +66,8 @@ struct solstice {
struct ssol_camera* camera;
struct ssol_image* framebuffer;
+ struct darray_double sun_dirs; /* List of double3 */
+
FILE* output; /* Output stream */
struct mem_allocator* allocator;
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -110,7 +110,7 @@ parse_sun_dir_list(const char* str, struct solstice_args* args)
tk = strtok_r(buf, ":", &ctx);
while(tk) {
- struct solstice_args_polar polar;
+ struct solstice_args_spherical spherical;
double tmp[2];
res = parse_doubleN(tk, tmp, 2);
@@ -119,9 +119,9 @@ parse_sun_dir_list(const char* str, struct solstice_args* args)
goto error;
}
- polar.azimuth = tmp[0];
- polar.elevation = tmp[1];
- sa_push(args->sun_dirs, polar);
+ spherical.azimuth = tmp[0];
+ spherical.elevation = tmp[1];
+ sa_push(args->sun_dirs, spherical);
tk = strtok_r(NULL, ":", &ctx);
}
diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in
@@ -18,7 +18,7 @@
#include <rsys/math.h>
-struct solstice_args_polar {
+struct solstice_args_spherical {
double azimuth; /* In radians */
double elevation; /* In radians */
};
@@ -29,7 +29,7 @@ struct solstice_args {
const char* input_filename; /* May be NULL <=> read data from stdin */
/* List of sun directions */
- struct solstice_args_polar* sun_dirs;
+ struct solstice_args_spherical* sun_dirs;
size_t nsun_dirs;
struct {
diff --git a/src/solstice_c.h b/src/solstice_c.h
@@ -30,6 +30,11 @@ solstice_setup_entities
(struct solstice* solstice);
extern LOCAL_SYM res_T
+solstice_update_entities
+ (struct solstice* solstice,
+ const double sun_dir[3]);
+
+extern LOCAL_SYM res_T
solstice_create_ssol_material
(struct solstice* solstice,
const struct solparser_material_id mtl_id,
diff --git a/src/solstice_entity.c b/src/solstice_entity.c
@@ -310,3 +310,30 @@ error:
goto exit;
}
+res_T
+solstice_update_entities(struct solstice* solstice, const double sun_dir[3])
+{
+ size_t i, n;
+ res_T res = RES_OK;
+ ASSERT(solstice && sun_dir);
+
+ n = darray_nodes_size_get(&solstice->pivots);
+ FOR_EACH(i, 0, n) {
+ struct score_node* pivot = darray_nodes_data_get(&solstice->pivots)[i];
+
+ /* Initialialised the world space position of the entity geometry */
+ res = sanim_node_visit_tree
+ (&pivot->anim, sun_dir, NULL, update_instance_transform);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Could not update the transformation of the entity geometries.\n");
+ goto error;
+ }
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
diff --git a/src/test_solstice_args.c b/src/test_solstice_args.c
@@ -213,7 +213,6 @@ main(int argc, char** argv)
(void)argc, (void)argv;
test_rendering();
test_sun_dirs();
-
CHECK(mem_allocated_size(), 0);
return 0;
}