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