solstice-solver

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

commit 4bc5e9b1d1a985dad33f0f9b2c954d2d929cb64c
parent 165c342ef4bdb23f8c539eb7f84521aec44d5f94
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Sep 2016 16:18:28 +0200

Differentiate the front/back receivers

Diffstat:
Msrc/ssol.h | 3++-
Msrc/ssol_object_instance.c | 43+++++++++++++++++++++++++++++++++----------
Msrc/ssol_object_instance_c.h | 16++++------------
Msrc/ssol_scene.c | 21++++++++++++---------
Msrc/ssol_solver.c | 12++++++++----
Msrc/test_ssol_object_instance.c | 14+++++++++-----
Msrc/test_ssol_solver.c | 6+++---
7 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -422,7 +422,8 @@ ssol_object_instance_set_transform SSOL_API res_T ssol_object_instance_set_receiver (struct ssol_object_instance* instance, - const char* name); /* May be NULL <=> it is no more a receiver */ + const char* name_front, /* May be NULL <=> Front faces are no more receivers */ + const char* name_back); /* May be NULL <=> back faces are no more receivers */ SSOL_API res_T ssol_object_instance_set_target_mask diff --git a/src/ssol_object_instance.c b/src/ssol_object_instance.c @@ -43,7 +43,8 @@ object_instance_release(ref_T* ref) SSOL(object_ref_put(instance->object)); if(instance->shape_rt) S3D(shape_ref_put(instance->shape_rt)); if(instance->shape_samp) S3D(shape_ref_put(instance->shape_samp)); - str_release(&instance->receiver_name); + str_release(&instance->receiver_front); + str_release(&instance->receiver_back); MEM_RM(dev->allocator, instance); SSOL(device_ref_put(dev)); } @@ -79,7 +80,8 @@ ssol_object_instantiate d33_set_identity(instance->transform); d3_splat(instance->transform + 9, 0); instance->target_mask = 0; - str_init(dev->allocator, &instance->receiver_name); + str_init(dev->allocator, &instance->receiver_front); + str_init(dev->allocator, &instance->receiver_back); SSOL(object_ref_get(object)); SSOL(device_ref_get(dev)); ref_init(&instance->ref); @@ -154,17 +156,38 @@ error: res_T ssol_object_instance_set_receiver (struct ssol_object_instance* instance, - const char* name) + const char* name_front, + const char* name_back) { - if(!instance) - return RES_BAD_ARG; + struct str front; + struct str back; + res_T res = RES_OK; + + if(!instance) return RES_BAD_ARG; - if(name) { - return str_set(&instance->receiver_name, name); - } else { - str_clear(&instance->receiver_name); - return RES_OK; + str_init(instance->dev->allocator, &front); + str_init(instance->dev->allocator, &back); + + if(name_front) { + res = str_set(&front, name_front); + if(res != RES_OK) goto error; + } + if(name_back) { + res = str_set(&back, name_back); + if(res != RES_OK) goto error; } + + res = str_copy_and_release(&instance->receiver_front, &front); + ASSERT(res == RES_OK); + res = str_copy_and_release(&instance->receiver_back, &back); + ASSERT(res == RES_OK); + +exit: + return res; +error: + str_release(&front); + str_release(&back); + goto exit; } res_T diff --git a/src/ssol_object_instance_c.h b/src/ssol_object_instance_c.h @@ -20,25 +20,17 @@ #include <rsys/ref_count.h> #include <rsys/str.h> -struct ssol_object_instance -{ +struct ssol_object_instance { struct ssol_object* object; /* Instantiated object */ struct s3d_shape* shape_rt; /* Instantiated Star-3D shape to ray-trace */ struct s3d_shape* shape_samp; /* Instantiated Star-3D shape to sample */ - struct str receiver_name; /* Empty if not a receiver */ - double transform[12]; + struct str receiver_front; /* Empty if front faces are not receivers */ + struct str receiver_back; /* Empty if back faces are not receivers */ + double transform[12]; /* Column major 4x3 affine transformation */ uint32_t target_mask; struct ssol_device* dev; ref_T ref; }; -static INLINE const char* -object_instance_get_receiver_name(const struct ssol_object_instance* instance) -{ - ASSERT(instance); - return str_is_empty(&instance->receiver_name) - ? NULL : str_cget(&instance->receiver_name); -} - #endif /* SSOL_OBJECT_INSTANCE_C_H */ diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -273,7 +273,7 @@ hit_filter_function void* filter_data) { struct ssol_object_instance* inst; - const char* receiver_name; + const struct str* receiver_name; struct realisation* rs = realisation; struct ssol_material* mtl; struct segment* seg; @@ -293,19 +293,24 @@ hit_filter_function inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id); - /* Check if the hit surface is a receiver that registers hit data */ - receiver_name = object_instance_get_receiver_name(inst); + front_face = f3_dot(hit->normal, dir) < 0; - front_face = f3_dot(hit->normal, dir) > 0; - mtl = front_face ? inst->object->mtl_front : inst->object->mtl_back; + if(front_face) { + mtl = inst->object->mtl_front; + receiver_name = &inst->receiver_front; + } else { + mtl = inst->object->mtl_back; + receiver_name = &inst->receiver_back; + } - if(receiver_name && front_face) { + /* Check if the hit surface is a receiver that registers hit data */ + if(str_is_empty(receiver_name)) { float pos[3]; f3_add(pos, org, f3_mulf(pos, dir, hit->distance)); front_face = 1; fprintf(rs->data.out_stream, "Receiver '%s': %u %u %g %g (%g:%g:%g) (%g:%g:%g) (%g:%g)\n", - receiver_name, + str_cget(receiver_name), (unsigned)rs->rs_id, (unsigned)rs->s_idx, rs->freq, @@ -319,8 +324,6 @@ hit_filter_function if(front_face) { rs->success_mask |= inst->target_mask; } - if(front_face) { - } if(mtl->type == MATERIAL_VIRTUAL) { return 1; /* Discard virtual material */ } diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -391,8 +391,8 @@ receive_sunlight(struct realisation* rs) { struct s3d_attrib attrib; struct segment* seg = sun_segment(rs); + const struct str* receiver_name = NULL; int receives; - const char* receiver_name; d3_muld(seg->dir, rs->start.sundir, -1); CHECK(d3_is_normalized(seg->dir), 1); @@ -415,12 +415,16 @@ receive_sunlight(struct realisation* rs) if (!receives) return receives; /* if the sampled instance is a receiver, register the sampled point */ - receiver_name = object_instance_get_receiver_name(rs->start.instance); - if (receiver_name) { + if(rs->start.material == rs->start.instance->object->mtl_front) { + receiver_name = &rs->start.instance->receiver_front; + } else { + receiver_name = &rs->start.instance->receiver_back; + } + if(str_is_empty(receiver_name)) { /* normal orientation has already been checked */ fprintf(rs->data.out_stream, "Receiver '%s': %u %u %g %g (%g:%g:%g) (%g:%g:%g) (%g:%g)\n", - receiver_name, + str_cget(receiver_name), (unsigned) rs->rs_id, (unsigned) rs->s_idx, rs->freq, diff --git a/src/test_ssol_object_instance.c b/src/test_ssol_object_instance.c @@ -58,11 +58,15 @@ main(int argc, char** argv) CHECK(ssol_object_instance_set_transform(instance, NULL), RES_BAD_ARG); CHECK(ssol_object_instance_set_transform(instance, transform), RES_OK); - CHECK(ssol_object_instance_set_receiver(NULL, "receiver 1"), RES_BAD_ARG); - CHECK(ssol_object_instance_set_receiver(instance, NULL), RES_OK); - CHECK(ssol_object_instance_set_receiver(instance, "receiver 1"), RES_OK); - CHECK(ssol_object_instance_set_receiver(instance, "receiver 0"), RES_OK); - CHECK(ssol_object_instance_set_receiver(instance, NULL), RES_OK); + #define SET_RECEIVER ssol_object_instance_set_receiver + CHECK(SET_RECEIVER(NULL, "receiver 1", NULL), RES_BAD_ARG); + CHECK(SET_RECEIVER(instance, NULL, NULL), RES_OK); + CHECK(SET_RECEIVER(instance, "receiver 1", NULL), RES_OK); + CHECK(SET_RECEIVER(instance, "receiver 0", NULL), RES_OK); + CHECK(SET_RECEIVER(instance, NULL, NULL), RES_OK); + CHECK(SET_RECEIVER(instance, "receiver front", "receiver back"), RES_OK); + CHECK(SET_RECEIVER(instance, NULL, "receiver back"), RES_OK); + #undef SET_RECEIVER CHECK(ssol_object_instance_set_target_mask(NULL, 1), RES_BAD_ARG); CHECK(ssol_object_instance_set_target_mask(instance, 1), RES_OK); diff --git a/src/test_ssol_solver.c b/src/test_ssol_solver.c @@ -110,12 +110,12 @@ main(int argc, char** argv) CHECK(ssol_object_create(dev, square, m_mtl, m_mtl, &m_object), RES_OK); CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK); - CHECK(ssol_object_instance_set_receiver(heliostat, "miroir"), RES_OK); + CHECK(ssol_object_instance_set_receiver(heliostat, "miroir", NULL), RES_OK); CHECK(ssol_object_instance_set_target_mask(heliostat, 0x1), RES_OK); CHECK(ssol_scene_attach_object_instance(scene, heliostat), RES_OK); CHECK(ssol_object_instantiate(m_object, &secondary), RES_OK); - CHECK(ssol_object_instance_set_receiver(secondary, "secondaire"), RES_OK); + CHECK(ssol_object_instance_set_receiver(secondary, "secondaire", NULL), RES_OK); CHECK(ssol_object_instance_set_transform(secondary, transform1), RES_OK); CHECK(ssol_object_instance_set_target_mask(secondary, 0x2), RES_OK); CHECK(ssol_scene_attach_object_instance(scene, secondary), RES_OK); @@ -123,7 +123,7 @@ main(int argc, char** argv) CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK); CHECK(ssol_object_instantiate(t_object, &target), RES_OK); CHECK(ssol_object_instance_set_transform(target, transform2), RES_OK); - CHECK(ssol_object_instance_set_receiver(target, "cible"), RES_OK); + CHECK(ssol_object_instance_set_receiver(target, "cible", NULL), RES_OK); CHECK(ssol_object_instance_set_target_mask(target, 0x4), RES_OK); CHECK(ssol_scene_attach_object_instance(scene, target), RES_OK);