solstice-solver

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

commit de54c65f9878b2e1c8a3aef6c2d9d33618010cdb
parent 67e48a4f266a890680e9e778af5e660666de6643
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue, 14 Mar 2017 18:30:02 +0100

Add normal to shapes and objects.

Diffstat:
Msrc/ssol.h | 7+++++++
Msrc/ssol_object.c | 14++++++++++++++
Msrc/ssol_object_c.h | 1+
Msrc/ssol_shape.c | 17+++++++++++++----
Msrc/ssol_shape_c.h | 1+
Msrc/test_ssol_object.c | 9+++++++++
6 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -318,6 +318,7 @@ struct ssol_mc_receiver { struct ssol_mc_sampled { struct ssol_mc_result shadowed; + double n[3]; /* normals */ size_t nb_samples; }; @@ -679,6 +680,12 @@ ssol_object_get_area (const struct ssol_object* object, double* area); +/* Retrieve the normal of the object */ +SSOL_API res_T +ssol_object_get_normal + (const struct ssol_object* object, + double normal[3]); + /******************************************************************************* * Object Instance API - Clone of an object with a set of per instance data as * world transformation, material parameters, etc. Note that the object diff --git a/src/ssol_object.c b/src/ssol_object.c @@ -23,6 +23,7 @@ #include <rsys/ref_count.h> #include <rsys/rsys.h> #include <rsys/mem_allocator.h> +#include <rsys/double3.h> /******************************************************************************* * Helper functions @@ -164,6 +165,7 @@ ssol_object_add_shaded_shape /* Setup the object shaded shape */ object->scn_rt_area += shape->shape_rt_area; object->scn_samp_area += shape->shape_samp_area; + d3_add(object->n, object->n, shape->n); SSOL(shape_ref_get(shape)); SSOL(material_ref_get(front)); SSOL(material_ref_get(back)); @@ -214,6 +216,7 @@ ssol_object_clear(struct ssol_object* obj) obj->scn_rt_area = 0; obj->scn_samp_area = 0; + d3_splat(obj->n, 0); S3D(scene_clear(obj->scn_rt)); S3D(scene_clear(obj->scn_samp)); @@ -230,3 +233,13 @@ ssol_object_get_area(const struct ssol_object* object, double* area) return RES_OK; } +res_T +ssol_object_get_normal + (const struct ssol_object* object, + double normal[3]) +{ + if (!object || !normal) return RES_BAD_ARG;; + /* the area of the 3D surface */ + d3_set(normal, object->n); + return RES_OK; +} +\ No newline at end of file diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h @@ -48,6 +48,7 @@ struct ssol_object { struct s3d_scene* scn_rt; /* RT scene to instantiate */ struct s3d_scene* scn_samp; /* Sampling scene to instantiate */ double scn_rt_area, scn_samp_area; + double n[3]; /* sum of normals */ struct ssol_device* dev; ref_T ref; diff --git a/src/ssol_shape.c b/src/ssol_shape.c @@ -474,12 +474,14 @@ mesh_compute_area void (*get_indices)(const unsigned itri, unsigned ids[3], void* data), const unsigned nverts, void (*get_position)(const unsigned ivert, float position[3], void* data), - void* ctx) + void* ctx, + double* normal) { unsigned itri; double area = 0; (void)nverts; + if(normal) d3_splat(normal, 0); FOR_EACH(itri, 0, ntris) { float v0[3], v1[3], v2[3]; double E0[3], E1[3], N[3]; @@ -501,7 +503,9 @@ mesh_compute_area d3_sub(E1, V2, V0); area += d3_len(d3_cross(N, E0, E1)); + if(normal) d3_add(normal, normal, N); } + if (normal) d3_muld(normal, normal, 0.5); return area * 0.5; } @@ -559,7 +563,7 @@ quadric_setup_s3d_shape_rt ASSERT(vdata.get); *rt_area = mesh_compute_area - (ntris, quadric_mesh_get_ids, nverts, vdata.get, &ctx); + (ntris, quadric_mesh_get_ids, nverts, vdata.get, &ctx, NULL); return RES_OK; } @@ -597,7 +601,7 @@ quadric_setup_s3d_shape_samp (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx); if(res != RES_OK) return res; *samp_area = mesh_compute_area - (ntris, quadric_mesh_get_ids, nverts, quadric_mesh_plane_get_pos, &ctx); + (ntris, quadric_mesh_get_ids, nverts, quadric_mesh_plane_get_pos, &ctx, NULL); return RES_OK; } @@ -1144,6 +1148,7 @@ ssol_punched_surface_setup struct darray_double coords; struct darray_size_t ids; size_t nslices; + double n; res_T res = RES_OK; darray_double_init(shape->dev->allocator, &coords); @@ -1232,6 +1237,10 @@ ssol_punched_surface_setup res = quadric_setup_s3d_shape_samp (psurf->quadric, &coords, &ids, shape->shape_samp, &shape->shape_samp_area); if(res != RES_OK) goto error; + /* the normal to the quadric is known */ + n = psurf->quadric->type == SSOL_QUADRIC_HYPERBOL + ? -shape->shape_samp_area : shape->shape_samp_area; + d3(shape->n, 0, 0, n); exit: darray_double_release(&coords); @@ -1298,7 +1307,7 @@ ssol_mesh_setup (shape->shape_rt, ntris, get_indices, nverts, attrs, nattribs, data); if(res != RES_OK) goto error; shape->shape_rt_area = - mesh_compute_area(ntris, get_indices, nverts, get_position, data); + mesh_compute_area(ntris, get_indices, nverts, get_position, data, shape->n); /* The Star-3D shape to sample is the same of the one to ray-traced */ res = s3d_mesh_copy(shape->shape_rt, shape->shape_samp); diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h @@ -60,6 +60,7 @@ struct ssol_shape { struct priv_quadric_data priv_quadric; struct ssol_quadric quadric; double shape_rt_area, shape_samp_area; + double n[3]; /* sum of normals */ struct ssol_device* dev; ref_T ref; diff --git a/src/test_ssol_object.c b/src/test_ssol_object.c @@ -26,6 +26,7 @@ main(int argc, char** argv) struct ssol_material* mtl; struct ssol_material* mtl2; struct ssol_object* object; + double a, n[3]; (void) argc, (void) argv; mem_init_proxy_allocator(&allocator, &mem_default_allocator); @@ -73,6 +74,14 @@ main(int argc, char** argv) CHECK(ssol_object_clear(NULL), RES_BAD_ARG); CHECK(ssol_object_clear(object), RES_OK); + CHECK(ssol_object_get_area(object, NULL), RES_BAD_ARG); + CHECK(ssol_object_get_area(NULL, &a), RES_BAD_ARG); + CHECK(ssol_object_get_area(object, &a), RES_OK); + + CHECK(ssol_object_get_normal(object, NULL), RES_BAD_ARG); + CHECK(ssol_object_get_normal(NULL, n), RES_BAD_ARG); + CHECK(ssol_object_get_normal(object, n), RES_OK); + CHECK(ssol_object_ref_put(object), RES_OK); CHECK(ssol_shape_ref_put(shape), RES_OK); CHECK(ssol_shape_ref_put(shape2), RES_OK);