solstice-solver

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

commit f65abc2f15d15716e3a225f63b9c87697ed449be
parent 70ea68b2d4f2f65069d117dee16114aa4064b8a2
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 14 Sep 2016 16:05:56 +0200

BugFix: initial weight was not using the correct cos

Used cos on the actual geometry; correct weigth use the cos on the
sampling plane.

Diffstat:
Msrc/ssol_solver.c | 45+++++++++++++++++++++++++++++----------------
Msrc/ssol_solver_c.h | 6++++--
2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -284,7 +284,8 @@ reset_starting_point(struct starting_point* start) start->front_exposed = 99; start->instance = NULL; start->material = NULL; - d3_splat(start->normal, NAN); + d3_splat(start->rt_normal, NAN); + d3_splat(start->sampl_normal, NAN); start->on_punched = 99; d3_splat(start->pos, NAN); d3_splat(start->pos_local, NAN); @@ -304,7 +305,8 @@ check_starting_point(const struct starting_point* start) NCHECK(start->front_exposed, 99); ASSERT(start->instance); ASSERT(start->material); - ASSERT_NAN(start->normal, 3); + ASSERT_NAN(start->rt_normal, 3); + ASSERT_NAN(start->sampl_normal, 3); NCHECK(start->on_punched, 99); ASSERT_NAN(start->pos, 3); if(start->on_punched) ASSERT_NAN(start->pos_local, 3); @@ -405,13 +407,15 @@ sample_point_on_primary_mirror(struct realisation* rs) start->sampl_primitive = sampl_prim; shape = start->instance->object->shape; start->on_punched = (shape->type == SHAPE_PUNCHED); + /* set sampling normal */ + S3D(primitive_get_attrib(&sampl_prim, S3D_GEOMETRY_NORMAL, start->uv, &attrib)); + CHECK(attrib.type, S3D_FLOAT3); + d3_set_f3(start->sampl_normal, attrib.value); switch (shape->type) { case SHAPE_MESH: { /* no projection needed */ - /* set normal */ - S3D(primitive_get_attrib(&sampl_prim, S3D_GEOMETRY_NORMAL, start->uv, &attrib)); - CHECK(attrib.type, S3D_FLOAT3); - d3_set_f3(start->normal, attrib.value); + /* set geometry normal */ + d3_set(start->rt_normal, start->sampl_normal); break; } case SHAPE_PUNCHED: { @@ -426,18 +430,19 @@ sample_point_on_primary_mirror(struct realisation* rs) /* transform point to world */ d33_muld3(start->pos, transform, start->pos_local); d3_add(start->pos, transform + 9, start->pos); - /* compute exact normal */ - punched_shape_set_normal_local(shape, start->pos_local, start->normal); + /* compute exact normal on the instance */ + punched_shape_set_normal_local(shape, start->pos_local, start->rt_normal); /* transform normal to world */ d33_invtrans(tr, transform); - d33_muld3(start->normal, tr, start->normal); + d33_muld3(start->rt_normal, tr, start->rt_normal); break; } default: FATAL("Unreachable code.\n"); break; } /* TODO: transform everything to world coordinate */ - d3_normalize(start->normal, start->normal); + d3_normalize(start->rt_normal, start->rt_normal); + d3_normalize(start->sampl_normal, start->sampl_normal); /* will be defined later, depending on wich side sees the sun */ start->material = NULL; } @@ -473,19 +478,27 @@ receive_sunlight(struct realisation* rs) sun = rs->data.scene->sun; start = &rs->start; ASSERT(d3_is_normalized(start->sundir)); - ASSERT(d3_is_normalized(start->normal)); + ASSERT(d3_is_normalized(start->rt_normal)); + ASSERT(d3_is_normalized(start->sampl_normal)); /* find which material/face is exposed to sun */ - start->cos_sun = d3_dot(start->normal, start->sundir); - start->front_exposed = start->cos_sun < 0; + start->geom_cos = d3_dot(start->rt_normal, start->sundir); + start->front_exposed = start->geom_cos < 0; if (start->front_exposed) { - start->cos_sun *= -1; start->material = start->instance->object->mtl_front; } else { start->material = start->instance->object->mtl_back; - d3_muld(start->normal, start->normal, -1); + d3_muld(start->sampl_normal, start->sampl_normal, -1); + } + if (start->geom_cos > 0) { + d3_muld(start->rt_normal, start->rt_normal, -1); } + else { + start->geom_cos *= -1; + } + start->cos_sun = fabs(d3_dot(start->sampl_normal, start->sundir)); + /* start must now be complete */ check_starting_point(start); @@ -513,7 +526,7 @@ receive_sunlight(struct realisation* rs) /* hit_front will be set from the next impact (if any) */ /* hit_instance will be set from the next impact (if any) */ seg->hit_material = start->material; - d3_set(seg->hit_normal, start->normal); + d3_set(seg->hit_normal, start->rt_normal); d3_set(seg->hit_pos, start->pos); d3_set(seg->hit_pos_local, start->pos_local); seg->on_punched = start->on_punched; diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -79,8 +79,10 @@ struct starting_point { double sundir[3]; double pos[3]; double pos_local[3]; /* in local coordinate, only set on punched shapes */ - double normal[3]; /* oriented towards the sun*/ - double cos_sun; /* > 0 */ + double rt_normal[3]; /* relative to the actual geometry; towards the sun*/ + double sampl_normal[3]; /* relative to the sampling plane; towards the sun*/ + double cos_sun; /* relative to the sampling plane; > 0 */ + double geom_cos; /* relative to the actual geometry; > 0 */ float uv[2]; char front_exposed; /* if false, normal has been reversed */ char on_punched; /* is the point on a punched shape? */