solstice-solver

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

commit 165c342ef4bdb23f8c539eb7f84521aec44d5f94
parent 1856771104e7eedf6c62237a2a535683e9f865cb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Sep 2016 15:43:53 +0200

Differentiate the front/back-facing materials

Diffstat:
Msrc/ssol.h | 3++-
Msrc/ssol_object.c | 45+++++++++++++++++++--------------------------
Msrc/ssol_object_c.h | 3++-
Msrc/ssol_scene.c | 48++++++++++++++++++++++++------------------------
Msrc/ssol_solver.c | 42++++++++++++++++++++++++++++++++++--------
Msrc/test_ssol_object.c | 25++++++++++++++-----------
Msrc/test_ssol_object_instance.c | 2+-
Msrc/test_ssol_scene.c | 2+-
Msrc/test_ssol_solver.c | 18+++++++++---------
9 files changed, 106 insertions(+), 82 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -383,7 +383,8 @@ SSOL_API res_T ssol_object_create (struct ssol_device* dev, struct ssol_shape* shape, - struct ssol_material* mtl, + struct ssol_material* mtl_front, /* Material to apply to front faces */ + struct ssol_material* mtl_back, /* Material to apply to back faces */ struct ssol_object** obj); SSOL_API res_T diff --git a/src/ssol_object.c b/src/ssol_object.c @@ -18,23 +18,13 @@ #include "ssol_object_c.h" #include "ssol_shape_c.h" +#include <rsys/ref_count.h> #include <rsys/rsys.h> #include <rsys/mem_allocator.h> -#include <rsys/ref_count.h> /******************************************************************************* * Helper functions ******************************************************************************/ -static INLINE res_T -object_ok(const struct ssol_object* object) -{ - if(!object - || !object->shape - || !object->material) - return RES_BAD_ARG; - return RES_OK; -} - static void object_release(ref_T* ref) { @@ -44,7 +34,8 @@ object_release(ref_T* ref) dev = object->dev; ASSERT(dev && dev->allocator); SSOL(shape_ref_put(object->shape)); - SSOL(material_ref_put(object->material)); + SSOL(material_ref_put(object->mtl_front)); + SSOL(material_ref_put(object->mtl_back)); if(object->scn_rt) S3D(scene_ref_put(object->scn_rt)); if(object->scn_samp) S3D(scene_ref_put(object->scn_samp)); MEM_RM(dev->allocator, object); @@ -58,28 +49,32 @@ res_T ssol_object_create (struct ssol_device* dev, struct ssol_shape* shape, - struct ssol_material* material, + struct ssol_material* mtl_front, + struct ssol_material* mtl_back, struct ssol_object** out_object) { struct ssol_object* object = NULL; res_T res = RES_OK; - if (!dev || !shape || !material || !out_object) { - return RES_BAD_ARG; + + if(!dev || !shape || !mtl_front || !mtl_back || !out_object) { + res = RES_BAD_ARG; + goto error; } - object = (struct ssol_object*)MEM_CALLOC - (dev->allocator, 1, sizeof(struct ssol_object)); - if (!object) { + object = MEM_CALLOC(dev->allocator, 1, sizeof(struct ssol_object)); + if(!object) { res = RES_MEM_ERR; goto error; } /* Check if material/shape association is legit: TODO */ SSOL(shape_ref_get(shape)); - SSOL(material_ref_get(material)); + SSOL(material_ref_get(mtl_front)); + SSOL(material_ref_get(mtl_back)); SSOL(device_ref_get(dev)); object->dev = dev; object->shape = shape; - object->material = material; + object->mtl_front = mtl_front; + object->mtl_back = mtl_back; ref_init(&object->ref); /* Create the Star-3D RT scene to instantiate through the instance */ @@ -95,10 +90,10 @@ ssol_object_create if(res != RES_OK) goto error; exit: - if (out_object) *out_object = object; + if(out_object) *out_object = object; return res; error: - if (object) { + if(object) { SSOL(object_ref_put(object)); object = NULL; } @@ -108,8 +103,7 @@ error: res_T ssol_object_ref_get(struct ssol_object* object) { - if (!object) - return RES_BAD_ARG; + if(!object) return RES_BAD_ARG; ref_get(&object->ref); return RES_OK; } @@ -117,8 +111,7 @@ ssol_object_ref_get(struct ssol_object* object) res_T ssol_object_ref_put(struct ssol_object* object) { - if (!object) - return RES_BAD_ARG; + if(!object) return RES_BAD_ARG; ref_put(&object->ref, object_release); return RES_OK; } diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h @@ -20,7 +20,8 @@ struct ssol_object { struct ssol_shape* shape; - struct ssol_material* material; + struct ssol_material* mtl_front; /* Front faces material */ + struct ssol_material* mtl_back; /* Back faces material */ struct s3d_scene* scn_rt; /* RT scene to instantiate */ struct s3d_scene* scn_samp; /* Sampling scene to instantiate */ diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -235,7 +235,8 @@ scene_setup_s3d_sampling_scene(struct ssol_scene* scn) htable_instance_iterator_next(&it); /* TODO: keep only primary mirrors */ - if(inst->object->material->type != MATERIAL_MIRROR) + if(inst->object->mtl_front->type != MATERIAL_MIRROR + && inst->object->mtl_back->type != MATERIAL_MIRROR) continue; /* Attach the instantiated s3d sampling shape to the s3d sampling scene */ @@ -274,6 +275,7 @@ hit_filter_function struct ssol_object_instance* inst; const char* receiver_name; struct realisation* rs = realisation; + struct ssol_material* mtl; struct segment* seg; struct segment* prev; int front_face = 0; @@ -293,37 +295,35 @@ hit_filter_function /* Check if the hit surface is a receiver that registers hit data */ receiver_name = object_instance_get_receiver_name(inst); - if(receiver_name) { - float cos_in; - /* check normal orientation */ - cos_in = f3_dot(hit->normal, dir); - if (cos_in < 0) { - float pos[3]; - - f3_set(pos, 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, - (unsigned)rs->rs_id, - (unsigned)rs->s_idx, - rs->freq, - seg->weight, - SPLIT3(pos), - SPLIT3(dir), - SPLIT2(hit->uv)); - } + + front_face = f3_dot(hit->normal, dir) > 0; + mtl = front_face ? inst->object->mtl_front : inst->object->mtl_back; + + if(receiver_name && front_face) { + 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, + (unsigned)rs->rs_id, + (unsigned)rs->s_idx, + rs->freq, + seg->weight, + SPLIT3(pos), + SPLIT3(dir), + SPLIT2(hit->uv)); } /* register success mask */ if(front_face) { rs->success_mask |= inst->target_mask; } - - if(inst->object->material->type == MATERIAL_VIRTUAL) { + if(front_face) { + } + if(mtl->type == MATERIAL_VIRTUAL) { return 1; /* Discard virtual material */ } - rs->data.instance = inst; return 0; } diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -55,7 +55,7 @@ get_quadric(const struct ssol_object_instance* instance) } static FINLINE void -solstice_trace_ray(struct realisation* rs) +solstice_trace_ray(struct realisation* rs) { float org[3], dir[3]; struct segment* seg = current_segment(rs); @@ -296,12 +296,19 @@ release_realisation(struct realisation* rs) } static INLINE struct ssol_material* -get_material_from_hit(struct ssol_scene* scene, struct s3d_hit* hit) +get_material_from_hit + (struct ssol_scene* scene, + const double dir[3], + const struct s3d_hit* hit) { struct ssol_object_instance* inst; + float dirf[3]; + int front_face; ASSERT(scene && hit); inst = *htable_instance_find(&scene->instances_rt, &hit->prim.inst_id); - return inst->object->material; + f3_set_d3(dirf, dir); + front_face = f3_dot(dirf, hit->normal) < 0.f; + return front_face ? inst->object->mtl_front : inst->object->mtl_back; } static void @@ -327,8 +334,26 @@ sample_point_on_primary_mirror(struct realisation* rs) rs->start.instance = *htable_instance_find (&data->scene->instances_samp, &tmp_prim.inst_id); object = rs->start.instance->object; - rs->start.material = object->material; + + /* Define which side of the primitive is actually sampled */ + if(object->mtl_front->type == MATERIAL_MIRROR) { + /* If both sides are mirrors, uniformly sample between them */ + if(object->mtl_back->type == MATERIAL_MIRROR) { + if(ssp_rng_canonical_float(data->rng) > 0.5) { + rs->start.material = object->mtl_front; + } else { + rs->start.material = object->mtl_back; + } + } else { + rs->start.material = object->mtl_front; + } + } else if(object->mtl_back->type == MATERIAL_MIRROR) { + rs->start.material = object->mtl_back; + } else { + FATAL("Unreachable code.\n"); + } ASSERT(rs->start.material); + switch (object->shape->type) { case SHAPE_MESH: /* no projection needed */ @@ -342,7 +367,7 @@ sample_point_on_primary_mirror(struct realisation* rs) /* cannot self intersect as the sampled mesh is not raytraced */ rs->start.primitive = S3D_PRIMITIVE_NULL; break; - default: FATAL("Unreachable code\n"); break; + default: FATAL("Unreachable code.\n"); break; } } @@ -416,7 +441,8 @@ receive_sunlight(struct realisation* rs) } static res_T -set_output_pos_and_dir(struct realisation* rs) { +set_output_pos_and_dir(struct realisation* rs) +{ struct ssol_material* material; struct segment* seg = current_segment(rs); struct segment* prev = previous_segment(rs); @@ -434,7 +460,7 @@ set_output_pos_and_dir(struct realisation* rs) { material = rs->start.material; } else { d3_set(seg->org, prev->hit_pos); - material = get_material_from_hit(scene, &prev->hit); + material = get_material_from_hit(scene, prev->dir, &prev->hit); } CHECK(material->type, MATERIAL_MIRROR); res = material_shade(material, &rs->data.fragment, rs->freq, rs->data.brdfs); @@ -470,7 +496,7 @@ propagate(struct realisation* rs) return; } /* should not stop on a virtual surface */ - ASSERT(get_material_from_hit(rs->data.scene, &seg->hit)->type + ASSERT(get_material_from_hit(rs->data.scene, seg->dir, &seg->hit)->type != MATERIAL_VIRTUAL); /* offset the impact point and recompute normal if needed */ diff --git a/src/test_ssol_object.c b/src/test_ssol_object.c @@ -25,7 +25,8 @@ main(int argc, char** argv) struct mem_allocator allocator; struct ssol_device* dev; struct ssol_shape* shape; - struct ssol_material* material; + struct ssol_material* mtl; + struct ssol_material* mtl2; struct ssol_object* object; (void) argc, (void) argv; @@ -38,29 +39,31 @@ main(int argc, char** argv) CHECK(ssol_device_create (&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK); - CHECK(ssol_material_create_virtual(dev, &material), RES_OK); + CHECK(ssol_material_create_virtual(dev, &mtl), RES_OK); + CHECK(ssol_material_create_virtual(dev, &mtl2), RES_OK); CHECK(ssol_shape_create_punched_surface(dev, &shape), RES_OK); - CHECK(ssol_object_create(NULL, shape, material, &object), RES_BAD_ARG); - CHECK(ssol_object_create(dev, NULL, material, &object), RES_BAD_ARG); - CHECK(ssol_object_create(dev, shape, NULL, &object), RES_BAD_ARG); - CHECK(ssol_object_create(dev, shape, material, NULL), RES_BAD_ARG); - CHECK(ssol_object_create(dev, shape, material, &object), RES_OK); + CHECK(ssol_object_create(NULL, shape, mtl, NULL, &object), RES_BAD_ARG); + CHECK(ssol_object_create(dev, NULL, mtl, NULL, &object), RES_BAD_ARG); + CHECK(ssol_object_create(dev, shape, NULL, mtl, &object), RES_BAD_ARG); + CHECK(ssol_object_create(dev, shape, mtl, mtl, NULL), RES_BAD_ARG); + CHECK(ssol_object_create(dev, shape, mtl, mtl, &object), RES_OK); CHECK(ssol_object_ref_get(NULL), RES_BAD_ARG); CHECK(ssol_object_ref_get(object), RES_OK); - CHECK(ssol_object_ref_put(NULL), RES_BAD_ARG); CHECK(ssol_object_ref_put(object), RES_OK); + CHECK(ssol_object_ref_put(object), RES_OK); + + CHECK(ssol_object_create(dev, shape, mtl, mtl2, &object), RES_OK); CHECK(ssol_object_ref_put(object), RES_OK); CHECK(ssol_shape_ref_put(shape), RES_OK); - CHECK(ssol_material_ref_put(material), RES_OK); - + CHECK(ssol_material_ref_put(mtl), RES_OK); + CHECK(ssol_material_ref_put(mtl2), RES_OK); CHECK(ssol_device_ref_put(dev), RES_OK); logger_release(&logger); - check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator); CHECK(mem_allocated_size(), 0); diff --git a/src/test_ssol_object_instance.c b/src/test_ssol_object_instance.c @@ -44,7 +44,7 @@ main(int argc, char** argv) CHECK(ssol_material_create_virtual(dev, &material), RES_OK); CHECK(ssol_shape_create_punched_surface(dev, &shape), RES_OK); - CHECK(ssol_object_create(dev, shape, material, &object), RES_OK); + CHECK(ssol_object_create(dev, shape, material, material, &object), RES_OK); CHECK(ssol_object_instantiate(object, &instance), RES_OK); diff --git a/src/test_ssol_scene.c b/src/test_ssol_scene.c @@ -47,7 +47,7 @@ main(int argc, char** argv) CHECK(ssol_material_create_virtual(dev, &material), RES_OK); CHECK(ssol_shape_create_punched_surface(dev, &shape), RES_OK); - CHECK(ssol_object_create(dev, shape, material, &object), RES_OK); + CHECK(ssol_object_create(dev, shape, material, material, &object), RES_OK); CHECK(ssol_object_instantiate(object, &instance), RES_OK); CHECK(ssol_object_instance_set_transform(instance, transform), RES_OK); CHECK(ssol_sun_create_directional(dev, &sun), RES_OK); diff --git a/src/test_ssol_solver.c b/src/test_ssol_solver.c @@ -39,8 +39,8 @@ main(int argc, char** argv) struct ssol_scene* scene; struct ssol_shape* square; struct ssol_vertex_data attribs[1]; - struct ssol_material* m_material; - struct ssol_material* v_material; + struct ssol_material* m_mtl; + struct ssol_material* v_mtl; struct ssol_mirror_shader shader; struct ssol_object* m_object; struct ssol_object* t_object; @@ -101,14 +101,14 @@ main(int argc, char** argv) CHECK(ssol_mesh_setup(square, square_walls_ntris, get_ids, square_walls_nverts, attribs, 1, (void*)&square_walls_desc), RES_OK); - CHECK(ssol_material_create_mirror(dev, &m_material), RES_OK); + CHECK(ssol_material_create_mirror(dev, &m_mtl), RES_OK); shader.normal = get_shader_normal; shader.reflectivity = get_shader_reflectivity; shader.roughness = get_shader_roughness; - CHECK(ssol_mirror_set_shader(m_material, &shader), RES_OK); - CHECK(ssol_material_create_virtual(dev, &v_material), RES_OK); + CHECK(ssol_mirror_set_shader(m_mtl, &shader), RES_OK); + CHECK(ssol_material_create_virtual(dev, &v_mtl), RES_OK); - CHECK(ssol_object_create(dev, square, m_material, &m_object), RES_OK); + 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_target_mask(heliostat, 0x1), RES_OK); @@ -120,7 +120,7 @@ main(int argc, char** argv) CHECK(ssol_object_instance_set_target_mask(secondary, 0x2), RES_OK); CHECK(ssol_scene_attach_object_instance(scene, secondary), RES_OK); - CHECK(ssol_object_create(dev, square, v_material, &t_object), RES_OK); + 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); @@ -137,8 +137,8 @@ main(int argc, char** argv) CHECK(ssol_object_ref_put(m_object), RES_OK); CHECK(ssol_object_ref_put(t_object), RES_OK); CHECK(ssol_shape_ref_put(square), RES_OK); - CHECK(ssol_material_ref_put(m_material), RES_OK); - CHECK(ssol_material_ref_put(v_material), RES_OK); + CHECK(ssol_material_ref_put(m_mtl), RES_OK); + CHECK(ssol_material_ref_put(v_mtl), RES_OK); CHECK(ssol_device_ref_put(dev), RES_OK); CHECK(ssol_scene_ref_put(scene), RES_OK); CHECK(ssp_rng_ref_put(rng), RES_OK);