commit d7d535b97f8450c74490d0da9a6ecdcff92302d6
parent e1ca1392af7e762c53ec836d2a34d8f0ac9236de
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 10 Oct 2016 11:09:34 +0200
Merge remote-tracking branch 'origin/multi_shapes'
Diffstat:
27 files changed, 569 insertions(+), 326 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -147,10 +147,16 @@ struct ssol_quadric {
struct ssol_quadric_parabol parabol;
struct ssol_quadric_parabolic_cylinder parabolic_cylinder;
} data;
+
+ /* 3x4 column major transformation of the quadric in object space */
+ double transform[12];
};
-#define SSOL_QUADRIC_DEFAULT__ \
- {SSOL_QUADRIC_PLANE, {SSOL_QUADRIC_PLANE_DEFAULT__}}
+#define SSOL_QUADRIC_DEFAULT__ { \
+ SSOL_QUADRIC_PLANE, \
+ {SSOL_QUADRIC_PLANE_DEFAULT__}, \
+ {1,0,0, 0,1,0, 0,0,1, 0,0,0} \
+}
static const struct ssol_quadric SSOL_QUADRIC_DEFAULT = SSOL_QUADRIC_DEFAULT__;
/* Define the contour of a 2D polygon as well as the clipping operation to
@@ -370,6 +376,12 @@ SSOL_API res_T
ssol_shape_ref_put
(struct ssol_shape* shape);
+/* Retrieve the id of the shape */
+SSOL_API res_T
+ssol_shape_get_id
+ (struct ssol_shape* shape,
+ uint32_t* id);
+
/* Define a punched surface in local space, i.e. no translation & no orientation */
SSOL_API res_T
ssol_punched_surface_setup
@@ -422,9 +434,6 @@ ssol_mirror_set_shader
SSOL_API res_T
ssol_object_create
(struct ssol_device* dev,
- struct ssol_shape* shape,
- 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
@@ -435,6 +444,18 @@ SSOL_API res_T
ssol_object_ref_put
(struct ssol_object* obj);
+SSOL_API res_T
+ssol_object_add_shaded_shape
+ (struct ssol_object* object,
+ struct ssol_shape* shape,
+ struct ssol_material* mtl_front, /* Front face material of the shape */
+ struct ssol_material* mtl_back); /* Back face material of the shape */
+
+/* Remove all the shaded shapes */
+SSOL_API res_T
+ssol_object_clear
+ (struct ssol_object* object);
+
/*******************************************************************************
* Object Instance API - Clone of an object with a set of per instance data as
* world transformation, material parameters, etc. Note that the object
@@ -566,7 +587,7 @@ ssol_sun_set_buie_param
/*******************************************************************************
* Atmosphere API - Describe an atmosphere model.
******************************************************************************/
-/* The atmosphere describes absorbtion along the light paths */
+/* The atmosphere describes absorption along the light paths */
SSOL_API res_T
ssol_atmosphere_create_uniform
(struct ssol_device* dev,
@@ -582,7 +603,7 @@ ssol_atmosphere_ref_put
/* List of per wavelength power of the sun */
SSOL_API res_T
-ssol_atmosphere_set_uniform_absorbtion
+ssol_atmosphere_set_uniform_absorption
(struct ssol_atmosphere* atmosphere,
struct ssol_spectrum* spectrum);
diff --git a/src/ssol_atmosphere.c b/src/ssol_atmosphere.c
@@ -62,7 +62,7 @@ compute_atmosphere_attenuation
switch (atmosphere->type) {
case ATMOS_UNIFORM:
spectrum = atmosphere->data.uniform.spectrum;
- CHECK(spectrum_interpolate(spectrum, wavelength, &ka), RES_OK);
+ ka = spectrum_interpolate(spectrum, wavelength);
break;
default: FATAL("Unreachable code\n"); break;
}
@@ -124,7 +124,7 @@ ssol_atmosphere_ref_put
}
res_T
-ssol_atmosphere_set_uniform_absorbtion
+ssol_atmosphere_set_uniform_absorption
(struct ssol_atmosphere* atmosphere,
struct ssol_spectrum* spectrum)
{
@@ -139,4 +139,4 @@ ssol_atmosphere_set_uniform_absorbtion
SSOL(spectrum_ref_get(spectrum));
uni->spectrum = spectrum;
return RES_OK;
-}
-\ No newline at end of file
+}
diff --git a/src/ssol_object.c b/src/ssol_object.c
@@ -33,9 +33,10 @@ object_release(ref_T* ref)
ASSERT(ref);
dev = object->dev;
ASSERT(dev && dev->allocator);
- SSOL(shape_ref_put(object->shape));
- SSOL(material_ref_put(object->mtl_front));
- SSOL(material_ref_put(object->mtl_back));
+ SSOL(object_clear(object));
+ darray_shaded_shape_release(&object->shaded_shapes);
+ htable_shaded_shape_release(&object->shaded_shapes_rt);
+ htable_shaded_shape_release(&object->shaded_shapes_samp);
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);
@@ -48,15 +49,12 @@ object_release(ref_T* ref)
res_T
ssol_object_create
(struct ssol_device* dev,
- struct ssol_shape* shape,
- 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 || !mtl_front || !mtl_back || !out_object) {
+ if(!dev || !out_object) {
res = RES_BAD_ARG;
goto error;
}
@@ -66,28 +64,19 @@ ssol_object_create
res = RES_MEM_ERR;
goto error;
}
- /* Check if material/shape association is legit: TODO */
- SSOL(shape_ref_get(shape));
- SSOL(material_ref_get(mtl_front));
- SSOL(material_ref_get(mtl_back));
SSOL(device_ref_get(dev));
object->dev = dev;
- object->shape = shape;
- object->mtl_front = mtl_front;
- object->mtl_back = mtl_back;
ref_init(&object->ref);
+ darray_shaded_shape_init(dev->allocator, &object->shaded_shapes);
+ htable_shaded_shape_init(dev->allocator, &object->shaded_shapes_rt);
+ htable_shaded_shape_init(dev->allocator, &object->shaded_shapes_samp);
/* Create the Star-3D RT scene to instantiate through the instance */
res = s3d_scene_create(dev->s3d, &object->scn_rt);
if(res != RES_OK) goto error;
- res = s3d_scene_attach_shape(object->scn_rt, object->shape->shape_rt);
- if(res != RES_OK) goto error;
-
/* Create the Star-3D sampling scene to instantiated through the instance */
res = s3d_scene_create(dev->s3d, &object->scn_samp);
if(res != RES_OK) goto error;
- res = s3d_scene_attach_shape(object->scn_samp, object->shape->shape_samp);
- if(res != RES_OK) goto error;
exit:
if(out_object) *out_object = object;
@@ -99,7 +88,6 @@ error:
}
goto exit;
}
-
res_T
ssol_object_ref_get(struct ssol_object* object)
{
@@ -116,3 +104,113 @@ ssol_object_ref_put(struct ssol_object* object)
return RES_OK;
}
+res_T
+ssol_object_add_shaded_shape
+ (struct ssol_object* object,
+ struct ssol_shape* shape,
+ struct ssol_material* front,
+ struct ssol_material* back)
+{
+ enum {
+ ATTACH_S3D_RT, ATTACH_S3D_SAMP, REGISTER_RT, REGISTER_SAMP, REGISTER_SHAPE
+ };
+ struct shaded_shape* shaded_shape;
+ unsigned id_rt, id_samp;
+ size_t i;
+ int mask = 0;
+ res_T res = RES_OK;
+
+ if(!object || !shape || !front || !back) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ S3D(shape_get_id(shape->shape_rt, &id_rt));
+ S3D(shape_get_id(shape->shape_samp, &id_samp));
+ if(htable_shaded_shape_find(&object->shaded_shapes_rt, &id_rt)) {
+ log_warning
+ (object->dev, "%s: the object already own the shape.\n", FUNC_NAME);
+ goto exit;
+ }
+
+ /* Add the shape RT to the RT scene of the object */
+ res = s3d_scene_attach_shape(object->scn_rt, shape->shape_rt);
+ if(res != RES_OK) goto error;
+ mask |= BIT(ATTACH_S3D_RT);
+
+ /* Add the shape samp to the sampling scene of the object */
+ res = s3d_scene_attach_shape(object->scn_samp, shape->shape_samp);
+ if(res != RES_OK) goto error;
+ mask |= BIT(ATTACH_S3D_SAMP);
+
+ /* Ask for a shaded shape identifier */
+ i = darray_shaded_shape_size_get(&object->shaded_shapes);
+ res = darray_shaded_shape_resize(&object->shaded_shapes, i+1);
+ if(res != RES_OK) goto error;
+ mask |= BIT(REGISTER_SHAPE);
+
+ /* Register the RT shape identifer */
+ res = htable_shaded_shape_set(&object->shaded_shapes_rt, &id_rt, &i);
+ if(res != RES_OK) goto error;
+ mask |= BIT(REGISTER_RT);
+
+ /* Register the samp shape identifier */
+ res = htable_shaded_shape_set(&object->shaded_shapes_samp, &id_samp, &i);
+ if(res != RES_OK) goto error;
+ mask |= BIT(REGISTER_SAMP);
+
+ /* Setup the object shaded shape */
+ SSOL(shape_ref_get(shape));
+ SSOL(material_ref_get(front));
+ SSOL(material_ref_get(back));
+ shaded_shape = darray_shaded_shape_data_get(&object->shaded_shapes)+i;
+ shaded_shape->shape = shape;
+ shaded_shape->mtl_front = front;
+ shaded_shape->mtl_back = back;
+
+exit:
+ return res;
+error:
+ if(mask & BIT(ATTACH_S3D_RT)) {
+ S3D(scene_detach_shape(object->scn_rt, shape->shape_rt));
+ }
+ if(mask & BIT(ATTACH_S3D_SAMP)) {
+ S3D(scene_detach_shape(object->scn_samp, shape->shape_samp));
+ }
+ if(mask & BIT(REGISTER_SHAPE)) {
+ darray_shaded_shape_pop_back(&object->shaded_shapes);
+ }
+ if(mask & BIT(REGISTER_RT)) {
+ i = htable_shaded_shape_erase(&object->shaded_shapes_rt, &id_rt);
+ ASSERT(i == 1);
+ }
+ if(mask & BIT(REGISTER_SAMP)) {
+ i = htable_shaded_shape_erase(&object->shaded_shapes_samp, &id_samp);
+ ASSERT(i == 1);
+ }
+ goto exit;
+}
+
+res_T
+ssol_object_clear(struct ssol_object* obj)
+{
+ size_t i, n;
+ if(!obj) return RES_BAD_ARG;
+
+ n = darray_shaded_shape_size_get(&obj->shaded_shapes);
+ FOR_EACH(i, 0, n) {
+ struct shaded_shape* s = darray_shaded_shape_data_get(&obj->shaded_shapes);
+ SSOL(shape_ref_put(s->shape));
+ SSOL(material_ref_put(s->mtl_front));
+ SSOL(material_ref_put(s->mtl_back));
+ }
+ darray_shaded_shape_clear(&obj->shaded_shapes);
+ htable_shaded_shape_clear(&obj->shaded_shapes_rt);
+ htable_shaded_shape_clear(&obj->shaded_shapes_samp);
+
+ S3D(scene_clear(obj->scn_rt));
+ S3D(scene_clear(obj->scn_samp));
+
+ return RES_OK;
+}
+
diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h
@@ -16,12 +16,34 @@
#ifndef SSOL_OBJECT_C_H
#define SSOL_OBJECT_C_H
+#include <rsys/dynamic_array.h>
+#include <rsys/hash_table.h>
#include <rsys/ref_count.h>
-struct ssol_object {
+struct shaded_shape {
struct ssol_shape* shape;
- struct ssol_material* mtl_front; /* Front faces material */
- struct ssol_material* mtl_back; /* Back faces material */
+ struct ssol_material* mtl_back; /* Material of the front faces */
+ struct ssol_material* mtl_front; /* Material of the back faces */
+};
+
+/* Define the darray_shaded_shape data structure */
+#define DARRAY_NAME shaded_shape
+#define DARRAY_DATA struct shaded_shape
+#include <rsys/dynamic_array.h>
+
+/* Define the htable_shaded_shape data structure */
+#define HTABLE_NAME shaded_shape
+#define HTABLE_KEY unsigned /* S3D object instance identifier */
+#define HTABLE_DATA size_t
+#include <rsys/hash_table.h>
+
+struct ssol_object {
+ /* List of shaded shapes added to the object */
+ struct darray_shaded_shape shaded_shapes;
+
+ /* Map the RT/Samp S3D id to an entry into the shaded_shapes array */
+ struct htable_shaded_shape shaded_shapes_rt;
+ struct htable_shaded_shape shaded_shapes_samp;
struct s3d_scene* scn_rt; /* RT scene to instantiate */
struct s3d_scene* scn_samp; /* Sampling scene to instantiate */
diff --git a/src/ssol_ranst_sun_dir.c b/src/ssol_ranst_sun_dir.c
@@ -257,9 +257,9 @@ ran_pillbox_get
******************************************************************************/
static double*
ran_dirac_get
-(const struct ranst_sun_dir* ran,
- struct ssp_rng* rng,
- double dir[3])
+ (const struct ranst_sun_dir* ran,
+ struct ssp_rng* rng,
+ double dir[3])
{
(void) rng;
ASSERT(d3_is_normalized(ran->state.dirac.dir));
@@ -356,9 +356,9 @@ ranst_sun_dir_dirac_setup
const double dir[3])
{
if (!ran || !dir) return RES_BAD_ARG;
- if (0 == d3_normalize(ran->state.dirac.dir, dir))
- /* zero vector */
- return RES_BAD_ARG;
+ if (0 == d3_normalize(ran->state.dirac.dir, dir)) {
+ return RES_BAD_ARG; /* zero vector */
+ }
ran->get = ran_dirac_get;
return RES_OK;
}
diff --git a/src/ssol_ranst_sun_dir.h b/src/ssol_ranst_sun_dir.h
@@ -16,19 +16,33 @@
#ifndef SSOL_RANST_SUN_DIR_H
#define SSOL_RANST_SUN_DIR_H
-/* Random variate state of a sun direction */
-struct ranst_sun_dir;
-
/* External types */
struct ssp_rng;
struct mem_allocator;
+/* Random variate state of a sun direction */
+struct ranst_sun_dir;
+
extern LOCAL_SYM res_T
ranst_sun_dir_create
(struct mem_allocator* allocator,
struct ranst_sun_dir** ran);
extern LOCAL_SYM res_T
+ranst_sun_dir_ref_get
+ (struct ranst_sun_dir* ran);
+
+extern LOCAL_SYM res_T
+ranst_sun_dir_ref_put
+ (struct ranst_sun_dir* ran);
+
+extern LOCAL_SYM double*
+ranst_sun_dir_get
+ (const struct ranst_sun_dir* ran,
+ struct ssp_rng* rng,
+ double dir[3]);
+
+extern LOCAL_SYM res_T
ranst_sun_dir_buie_setup
(struct ranst_sun_dir* ran,
const double param,
@@ -45,19 +59,5 @@ ranst_sun_dir_dirac_setup
(struct ranst_sun_dir* ran,
const double dir[3]);
-extern LOCAL_SYM res_T
-ranst_sun_dir_ref_get
- (struct ranst_sun_dir* ran);
-
-extern LOCAL_SYM res_T
-ranst_sun_dir_ref_put
- (struct ranst_sun_dir* ran);
-
-extern LOCAL_SYM double*
-ranst_sun_dir_get
- (const struct ranst_sun_dir* ran,
- struct ssp_rng* rng,
- double dir[3]);
-
#endif /* SSOL_RANST_SUN_DIR_H */
diff --git a/src/ssol_ranst_sun_wl.c b/src/ssol_ranst_sun_wl.c
@@ -24,7 +24,7 @@
#include <rsys/rsys.h>
#include <rsys/ref_count.h>
- /*******************************************************************************
+/*******************************************************************************
* Distributions types for wavelengths
******************************************************************************/
struct ran_piecewise_wl_state {
@@ -42,7 +42,7 @@ enum wl_ran_type {
};
/* One single type for all distributions. Only the state type depends on the
-* distribution type */
+ * distribution type */
struct ranst_sun_wl {
double(*get)
(const struct ranst_sun_wl* ran, struct ssp_rng* rng);
@@ -66,13 +66,13 @@ distrib_sun_wl_release(ref_T* ref)
ASSERT(ref);
ran = CONTAINER_OF(ref, struct ranst_sun_wl, ref);
switch (ran->type) {
- case WL_DIRAC:
- break;
- case WL_PIECEWISE:
- SSP(ranst_piecewise_linear_ref_put(ran->state.piecewise.spectrum));
- ran->state.piecewise.spectrum = NULL;
- break;
- default: FATAL("Unreachable code\n"); break;
+ case WL_DIRAC:
+ break;
+ case WL_PIECEWISE:
+ SSP(ranst_piecewise_linear_ref_put(ran->state.piecewise.spectrum));
+ ran->state.piecewise.spectrum = NULL;
+ break;
+ default: FATAL("Unreachable code\n"); break;
}
MEM_RM(ran->allocator, ran);
}
@@ -85,7 +85,8 @@ ran_piecewise_get
(const struct ranst_sun_wl* ran,
struct ssp_rng* rng)
{
- ASSERT(ran && rng && ran->type == WL_PIECEWISE && ran->state.piecewise.spectrum);
+ ASSERT(ran && rng && ran->type == WL_PIECEWISE);
+ ASSERT(ran->state.piecewise.spectrum);
return ssp_ranst_piecewise_linear_get(ran->state.piecewise.spectrum, rng);
}
@@ -94,8 +95,8 @@ ran_piecewise_get
******************************************************************************/
static double
ran_dirac_get
-(const struct ranst_sun_wl* ran,
- struct ssp_rng* rng)
+ (const struct ranst_sun_wl* ran,
+ struct ssp_rng* rng)
{
(void) rng;
ASSERT(ran && rng && ran->type == WL_DIRAC);
@@ -164,24 +165,24 @@ ranst_sun_wl_setup
if (sz > 1) {
ran->type = WL_PIECEWISE;
ran->get = &ran_piecewise_get;
- res = ssp_ranst_piecewise_linear_create(
- ran->allocator, &ran->state.piecewise.spectrum);
+ res = ssp_ranst_piecewise_linear_create
+ (ran->allocator, &ran->state.piecewise.spectrum);
if (res != RES_OK) goto error;
res = ssp_ranst_piecewise_linear_setup
- (ran->state.piecewise.spectrum, wavelengths, intensities, sz);
+ (ran->state.piecewise.spectrum, wavelengths, intensities, sz);
if (res != RES_OK) goto error;
- }
- else {
+ } else {
ran->type = WL_DIRAC;
ran->get = &ran_dirac_get;
ran->state.dirac.wavelength = wavelengths[0];
}
-end:
+exit:
return res;
error:
- if (ran->state.piecewise.spectrum)
+ if(ran->state.piecewise.spectrum) {
SSP(ranst_piecewise_linear_ref_put(ran->state.piecewise.spectrum));
- ran->state.piecewise.spectrum = NULL;
- goto end;
+ ran->state.piecewise.spectrum = NULL;
+ }
+ goto exit;
}
diff --git a/src/ssol_ranst_sun_wl.h b/src/ssol_ranst_sun_wl.h
@@ -16,26 +16,19 @@
#ifndef SSOL_RANST_SUN_WL_H
#define SSOL_RANST_SUN_WL_H
-/* Random variate state of a sun direction */
-struct ranst_sun_wl;
-
/* External types */
struct ssp_rng;
struct mem_allocator;
+/* Random variate state of a sun direction */
+struct ranst_sun_wl;
+
extern LOCAL_SYM res_T
ranst_sun_wl_create
(struct mem_allocator* allocator,
struct ranst_sun_wl** ran);
extern LOCAL_SYM res_T
-ranst_sun_wl_setup
- (struct ranst_sun_wl* ran,
- const double* wavelengths,
- const double* intensities,
- const size_t sz);
-
-extern LOCAL_SYM res_T
ranst_sun_wl_ref_get
(struct ranst_sun_wl* ran);
@@ -48,5 +41,12 @@ ranst_sun_wl_get
(const struct ranst_sun_wl* ran,
struct ssp_rng* rng);
+extern LOCAL_SYM res_T
+ranst_sun_wl_setup
+ (struct ranst_sun_wl* ran,
+ const double* wavelengths,
+ const double* intensities,
+ const size_t sz);
+
#endif /* SSOL_RANST_SUN_WL_H */
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -121,7 +121,7 @@ ssol_scene_attach_instance
res_T res;
if(!scene || !instance) return RES_BAD_ARG;
-
+
/* Attach the instantiated s3d shape to ray-trace to the RT scene */
res = s3d_scene_attach_shape(scene->scn_rt, instance->shape_rt);
if(res != RES_OK) return res;
@@ -291,9 +291,8 @@ scene_setup_s3d_sampling_scene
unsigned id;
htable_instance_iterator_next(&it);
- if (!str_is_empty(&inst->receiver_back)
- || !str_is_empty(&inst->receiver_front))
- {
+ if(!str_is_empty(&inst->receiver_back)
+ || !str_is_empty(&inst->receiver_front)) {
hr = 1;
}
@@ -340,10 +339,12 @@ hit_filter_function
void* filter_data)
{
struct ssol_instance* inst;
+ const struct shaded_shape* shaded_shape;
const struct ssol_shape* shape;
const struct str* receiver_name;
struct realisation* rs = realisation;
struct segment* seg;
+ size_t id;
(void) filter_data, (void) org, (void) dir;
ASSERT(rs);
@@ -357,44 +358,57 @@ hit_filter_function
ASSERT(seg->self_front != NON_BOOL);
inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id);
- shape = inst->object->shape;
+ id = *htable_shaded_shape_find
+ (&inst->object->shaded_shapes_rt, &hit->prim.geom_id);
+ shaded_shape = darray_shaded_shape_cdata_get(&inst->object->shaded_shapes)+id;
+ shape = shaded_shape->shape;
seg->on_punched = (shape->type == SHAPE_PUNCHED);
switch (shape->type) {
- case SHAPE_PUNCHED: {
- /* hits on quadrics must be recomputed more accurately */
- double org_local[3], hit_pos_local[3], dir_local[3];
- const double* transform = inst->transform;
- double tr[9];
- int valid;
- d33_inverse(tr, transform);
-
- /* get org in local coordinate */
- d3_set(org_local, seg->org);
- d3_sub(org_local, org_local, transform + 9);
- d33_muld3(org_local, tr, org_local);
-
- /* get dir in local */
- d33_muld3(dir_local, tr, seg->dir);
- /* recompute hit */
- valid = punched_shape_intersect_local(shape, org_local, dir_local,
- hit->distance, hit_pos_local, seg->hit_normal, &seg->hit_distance);
- if (!valid) return 1;
- /* transform point to world */
- d33_muld3(seg->hit_pos, transform, hit_pos_local);
- d3_add(seg->hit_pos, transform + 9, seg->hit_pos);
- /* transform normal to world */
- d33_invtrans(tr, transform);
- d33_muld3(seg->hit_normal, tr, seg->hit_normal);
- break;
- }
- case SHAPE_MESH: {
- d3_set_f3(seg->hit_normal, hit->normal);
- /* use raytraced distance to fill hit_pos */
- d3_add(seg->hit_pos, seg->org, d3_muld(seg->hit_pos, seg->dir, hit->distance));
- seg->hit_distance = hit->distance;
- break;
- }
- default: FATAL("Unreachable code.\n"); break;
+ case SHAPE_MESH: {
+ d3_set_f3(seg->hit_normal, hit->normal);
+ /* use raytraced distance to fill hit_pos */
+ d3_add(seg->hit_pos, seg->org, d3_muld(seg->hit_pos, seg->dir, hit->distance));
+ seg->hit_distance = hit->distance;
+ break;
+ }
+ case SHAPE_PUNCHED: {
+ /* hits on quadrics must be recomputed more accurately */
+ double org_local[3], hit_pos_local[3], dir_local[3];
+ double R[9]; /* Rotation matrix */
+ double T[3]; /* Translation vector */
+ double R_invtrans[9]; /* Inverse transpose rotation matrix */
+ double T_inv[3]; /* Inverse of the translation vector */
+ int valid;
+
+ if(d33_is_identity(shape->quadric.transform)) {
+ d33_set(R, inst->transform);
+ d3_set (T, inst->transform+9);
+ } else {
+ d33_muld33(R, shape->quadric.transform, inst->transform);
+ d33_muld3 (T, shape->quadric.transform, inst->transform+9);
+ }
+ d33_invtrans(R_invtrans, R);
+ d3_minus(T_inv, T);
+
+ /* get org in local coordinate */
+ d3_set(org_local, seg->org);
+ d3_add(org_local, org_local, T_inv);
+ d3_muld33(org_local, org_local, R_invtrans);
+
+ /* get dir in local */
+ d3_muld33(dir_local, seg->dir, R_invtrans);
+ /* recompute hit */
+ valid = punched_shape_intersect_local(shape, org_local, dir_local,
+ hit->distance, hit_pos_local, seg->hit_normal, &seg->hit_distance);
+ if (!valid) return 1;
+ /* transform point to world */
+ d33_muld3(seg->hit_pos, R, hit_pos_local);
+ d3_add(seg->hit_pos, seg->hit_pos, T);
+ /* transform normal to world */
+ d33_muld3(seg->hit_normal, R_invtrans, seg->hit_normal);
+ break;
+ }
+ default: FATAL("Unreachable code.\n"); break;
}
d3_normalize(seg->hit_normal, seg->hit_normal);
@@ -405,11 +419,11 @@ hit_filter_function
}
if(seg->hit_front) {
- seg->hit_material = inst->object->mtl_front;
+ seg->hit_material = shaded_shape->mtl_front;
receiver_name = &inst->receiver_front;
} else {
d3_muld(seg->hit_normal, seg->hit_normal, -1);
- seg->hit_material = inst->object->mtl_back;
+ seg->hit_material = shaded_shape->mtl_back;
receiver_name = &inst->receiver_back;
}
diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h
@@ -36,12 +36,15 @@ struct ssol_scene;
struct ssol_sun;
struct ssol_scene {
+ /* Map the instantiated RT/Samp S3D shape id to its SSOL intrance */
struct htable_instance instances_rt;
struct htable_instance instances_samp;
- struct s3d_scene* scn_rt;
- struct s3d_scene* scn_samp;
- struct ssol_sun* sun;
- struct ssol_atmosphere* atmosphere;
+
+ struct s3d_scene* scn_rt; /* S3D scene to ray trace */
+ struct s3d_scene* scn_samp; /* S3D scene to sample */
+
+ struct ssol_sun* sun; /* Sun of the scene */
+ struct ssol_atmosphere* atmosphere; /* Atmosphere of the scene */
struct ssol_device* dev;
ref_T ref;
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -18,10 +18,12 @@
#include "ssol_device_c.h"
#include "ssol_shape_c.h"
-#include <rsys/double3.h>
#include <rsys/double2.h>
+#include <rsys/double3.h>
+#include <rsys/double33.h>
#include <rsys/dynamic_array_double.h>
#include <rsys/dynamic_array_size_t.h>
+#include <rsys/float3.h>
#include <rsys/mem_allocator.h>
#include <rsys/ref_count.h>
#include <rsys/rsys.h>
@@ -40,6 +42,7 @@ struct quadric_mesh_context {
const double* coords;
const size_t* ids;
double focal; /* Use by parabol and parabolic cylinder quadrics */
+ const double* transform; /* 3x4 column major matrix */
};
/*******************************************************************************
@@ -171,10 +174,17 @@ quadric_mesh_plane_get_pos(const unsigned ivert, float pos[3], void* ctx)
{
const size_t i = ivert*2/*#coords per vertex*/;
const struct quadric_mesh_context* msh = ctx;
+ double p[3]; /* Temporary quadric space position */
ASSERT(pos && ctx);
- pos[0] = (float)msh->coords[i+0];
- pos[1] = (float)msh->coords[i+1];
- pos[2] = 0.f;
+ p[0] = (float)msh->coords[i+0];
+ p[1] = (float)msh->coords[i+1];
+ p[2] = 0.f;
+
+ /* Transform the position in object space */
+ d33_muld3(p, msh->transform, p);
+ d3_add(p, p, msh->transform+9);
+
+ f3_set_d3(pos, p);
}
static void
@@ -182,13 +192,17 @@ quadric_mesh_parabol_get_pos(const unsigned ivert, float pos[3], void* ctx)
{
const size_t i = ivert*2/*#coords per vertex*/;
const struct quadric_mesh_context* msh = ctx;
- double x, y;
+ double p[3]; /* Temporary quadric space position */
ASSERT(pos && ctx);
- x = msh->coords[i+0];
- y = msh->coords[i+1];
- pos[0] = (float)x;
- pos[1] = (float)y;
- pos[2] = (float)((x*x + y*y) / (4.0*msh->focal));
+ p[0] = msh->coords[i+0];
+ p[1] = msh->coords[i+1];
+ p[2] = (p[0]*p[0] + p[1]*p[1]) / (4.0*msh->focal);
+
+ /* Transform the position in object space */
+ d33_muld3(p, msh->transform, p);
+ d3_add(p, p, msh->transform+9);
+
+ f3_set_d3(pos, p);
}
static void
@@ -197,13 +211,17 @@ quadric_mesh_parabolic_cylinder_get_pos
{
const size_t i = ivert*2/*#coords per vertex*/;
const struct quadric_mesh_context* msh = ctx;
- double x, y;
+ double p[3]; /* Temporary quadric space position */
ASSERT(pos && ctx);
- x = msh->coords[i+0];
- y = msh->coords[i+1];
- pos[0] = (float)x;
- pos[1] = (float)y;
- pos[2] = (float)((y*y) / (4.0*msh->focal));
+ p[0] = msh->coords[i+0];
+ p[1] = msh->coords[i+1];
+ p[2] = ((p[1]*p[1]) / (4.0*msh->focal));
+
+ /* Transform the position in object space */
+ d33_muld3(p, msh->transform, p);
+ d3_add(p, p, msh->transform+9);
+
+ f3_set_d3(pos, p);
}
static FINLINE int
@@ -425,6 +443,7 @@ quadric_setup_s3d_shape_rt
ntris = (unsigned)darray_size_t_size_get(ids) / 3/*#ids per triangle*/;
ctx.coords = darray_double_cdata_get(coords);
ctx.ids = darray_size_t_cdata_get(ids);
+ ctx.transform = quadric->transform;
vdata.usage = S3D_POSITION;
vdata.type = S3D_FLOAT3;
@@ -538,9 +557,9 @@ inject_same_sign(const double x, const double src)
return ucast.d;
}
-/* solve a 2nd degree equation
- hint is used to select among the 2 solutions (if applies)
- the selected solution is then the closest to hint positive value */
+/* Solve a 2nd degree equation
+ * hint is used to select among the 2 solutions (if applies)
+ * the selected solution is then the closest to hint positive value */
static int
quadric_solve_second
(const double a,
@@ -550,38 +569,38 @@ quadric_solve_second
double* dist)
{
ASSERT(dist);
- if (a != 0) {
- /* standard case: 2nd degree */
+ if(a != 0) {
+ /* Standard case: 2nd degree */
const double delta = b * b - 4 * a * c;
- if (delta > 0) {
+ if(delta > 0) {
const double sqrt_delta = sqrt(delta);
- /* precise formula */
+ /* Precise formula */
const double t1 = (-b - inject_same_sign(sqrt_delta, b)) / (2 * b);
const double t2 = c / (a * t1);
- if (t1 < 0 && t2 < 0) return 0; /* no positive solution */
- if (t1 < 0) {
+ if(t1 < 0 && t2 < 0) return 0; /* no positive solution */
+ if(t1 < 0) {
*dist = t2; /* t2 is the only positive solution */
return 1;
}
- if (t2 < 0) {
+ if(t2 < 0) {
*dist = t1; /* t1 is the only positive solution */
return 1;
}
- /* both t1 and t2 are positive: choose the closest value to hint */
+ /* Both t1 and t2 are positive: choose the closest value to hint */
*dist = fabs(t1 - hint) < fabs(t2 - hint) ? t1 : t2;
return 1;
- } else if (delta == 0) {
+ } else if(delta == 0) {
const double t = -b / (2 * a);
- if (t < 0) return 0; /* no positive solution */
+ if(t < 0) return 0; /* no positive solution */
*dist = t;
return 1;
} else {
return 0;
}
- } else if (b != 0) {
+ } else if(b != 0) {
/* degenerated case: 1st degree only */
const double t = -c / b;
- if (t < 0) return 0; /* no positive solution */
+ if(t < 0) return 0; /* no positive solution */
*dist = t;
return 1;
}
@@ -632,7 +651,7 @@ quadric_plane_intersect_local
const double b = dir[2];
const double c = org[2];
int sol = quadric_solve_second(a, b, c, 0, dist);
- if (!sol) return 0;
+ if(!sol) return 0;
d3_add(pt, org, d3_muld(pt, dir, *dist));
quadric_plane_gradient_local(grad);
return 1;
@@ -654,7 +673,7 @@ quadric_parabol_intersect_local
2 * org[0] * dir[0] + 2 * org[1] * dir[1] - 4 * quad->focal * dir[2];
const double c = org[0] * org[0] + org[1] * org[1] - 4 * quad->focal * org[2];
const int sol = quadric_solve_second(a, b, c, hint, dist);
- if (!sol) return 0;
+ if(!sol) return 0;
d3_add(pt, org, d3_muld(pt, dir, *dist));
quadric_parabol_gradient_local(quad, pt, grad);
return 1;
@@ -675,7 +694,7 @@ quadric_parabolic_cylinder_intersect_local
const double b = 2 * org[1] * dir[1] - 4 * quad->focal * dir[2];
const double c = org[1] * org[1] - 4 * quad->focal * org[2];
const int sol = quadric_solve_second(a, b, c, hint, dist);
- if (!sol) return 0;
+ if(!sol) return 0;
d3_add(pt, org, d3_muld(pt, dir, *dist));
quadric_parabolic_cylinder_gradient_local(quad, pt, grad);
return 1;
@@ -821,6 +840,17 @@ ssol_shape_ref_put(struct ssol_shape* shape)
}
res_T
+ssol_shape_get_id(struct ssol_shape* shape, uint32_t* id)
+{
+ unsigned ui;
+ STATIC_ASSERT(sizeof(unsigned) <= sizeof(uint32_t), Unexpected_sizeof_unsigned);
+ if(!shape || !id) return RES_BAD_ARG;
+ S3D(shape_get_id(shape->shape_rt, &ui));
+ *id = (uint32_t)ui;
+ return RES_OK;
+}
+
+res_T
ssol_punched_surface_setup
(struct ssol_shape* shape,
const struct ssol_punched_surface* psurf)
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -67,39 +67,33 @@ cmp_candidates(const void* _c1, const void* _c2)
}
static FINLINE res_T
-check_scene(const struct ssol_scene* scene) {
- ASSERT(scene);
+check_scene(const struct ssol_scene* scene, const char* caller)
+{
+ ASSERT(scene && caller);
+
if (!scene->sun) {
- log_error(scene->dev, "%s: no sun attached.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: no sun attached.\n", caller);
return RES_BAD_ARG;
}
if (!scene->sun->spectrum) {
- log_error(scene->dev, "%s: sun's spectrum undefined.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: sun's spectrum undefined.\n", caller);
return RES_BAD_ARG;
}
if (scene->sun->dni <= 0) {
- log_error(scene->dev, "%s: sun's DNI undefined.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: sun's DNI undefined.\n", caller);
return RES_BAD_ARG;
}
if (scene->atmosphere) {
- switch (scene->atmosphere->type) {
- case ATMOS_UNIFORM: {
- char ok;
- CHECK(spectrum_includes(
- scene->atmosphere->data.uniform.spectrum,
- scene->sun->spectrum,
- &ok),
- RES_OK);
- if (!ok) {
- log_error(scene->dev, "%s: sun/atmosphere spectra mismatch.\n", FUNC_NAME);
- return RES_BAD_ARG;
- }
- break;
- }
- default: FATAL("Unreachable code\n"); break;
+ int i;
+ ASSERT(scene->atmosphere->type == ATMOS_UNIFORM);
+ i = spectrum_includes
+ (scene->atmosphere->data.uniform.spectrum, scene->sun->spectrum);
+ if (!i) {
+ log_error(scene->dev, "%s: sun/atmosphere spectra mismatch.\n", caller);
+ return RES_BAD_ARG;
}
}
return RES_OK;
@@ -471,6 +465,7 @@ sample_starting_point(struct realisation* rs)
struct solver_data* data;
struct s3d_primitive sampl_prim;
struct starting_point* start;
+ size_t id;
ASSERT(rs);
data = &rs->data;
@@ -489,7 +484,11 @@ sample_starting_point(struct realisation* rs)
start->instance = *htable_instance_find
(&data->scene->instances_samp, &sampl_prim.inst_id);
start->sampl_primitive = sampl_prim;
- shape = start->instance->object->shape;
+ id = *htable_shaded_shape_find
+ (&start->instance->object->shaded_shapes_samp, &sampl_prim.geom_id);
+ start->shaded_shape = darray_shaded_shape_cdata_get
+ (&start->instance->object->shaded_shapes)+id;
+ shape = start->shaded_shape->shape;
start->on_punched = (shape->type == SHAPE_PUNCHED);
/* set sampling normal */
S3D(primitive_get_attrib(&sampl_prim, S3D_GEOMETRY_NORMAL, start->uv, &attrib));
@@ -503,21 +502,36 @@ sample_starting_point(struct realisation* rs)
break;
}
case SHAPE_PUNCHED: {
- const double* transform = start->instance->transform;
- double tr[9], pos_local[3];
+ struct ssol_instance* inst = start->instance;
+ double pos_local[3];
+ double R[9]; /* Rotation matrix */
+ double T[3]; /* Translation vector */
+ double R_invtrans[9]; /* Inverse transpose rotation matrix */
+ double T_inv[3]; /* Inverse of the translation vector */
+
+ if(d33_is_identity(shape->quadric.transform)) {
+ d33_set(R, inst->transform);
+ d3_set (T, inst->transform+9);
+ } else {
+ d33_muld33(R, shape->quadric.transform, inst->transform);
+ d33_muld3 (T, shape->quadric.transform, inst->transform+9);
+ }
+ d33_invtrans(R_invtrans, R);
+ d3_minus(T_inv, T);
+
/* project the sampled point on the quadric */
- d33_inverse(tr, transform);
- d3_sub(pos_local, start->pos, transform + 9);
- d33_muld3(pos_local, tr, pos_local);
+ d3_set(pos_local, start->pos);
+ d3_add(pos_local, pos_local, T_inv);
+ d3_muld33(pos_local, pos_local, R_invtrans);
+
punched_shape_set_z_local(shape, pos_local);
/* transform point to world */
- d33_muld3(start->pos, transform, pos_local);
- d3_add(start->pos, transform + 9, start->pos);
+ d33_muld3(start->pos, R, pos_local);
+ d3_add(start->pos, start->pos, T);
/* compute exact normal on the instance */
punched_shape_set_normal_local(shape, pos_local, start->rt_normal);
/* transform normal to world */
- d33_invtrans(tr, transform);
- d33_muld3(start->rt_normal, tr, start->rt_normal);
+ d33_muld3(start->rt_normal, R_invtrans, start->rt_normal);
break;
}
default: FATAL("Unreachable code.\n"); break;
@@ -568,9 +582,9 @@ receive_sunlight(struct realisation* rs)
start->geom_cos = d3_dot(start->rt_normal, start->sundir);
start->front_exposed = start->geom_cos < 0;
if (start->front_exposed) {
- start->material = start->instance->object->mtl_front;
+ start->material = start->shaded_shape->mtl_front;
} else {
- start->material = start->instance->object->mtl_back;
+ start->material = start->shaded_shape->mtl_back;
}
/* normals must face the sun and cos must be positive */
if (start->geom_cos > 0) {
@@ -774,7 +788,7 @@ ssol_solve
if (!scene || !rng || !output || !estimator || !realisations_count)
return RES_BAD_ARG;
- res = check_scene(scene);
+ res = check_scene(scene, FUNC_NAME);
if (res != RES_OK) return res;
/* init realisation */
diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h
@@ -60,6 +60,7 @@ struct segment {
struct starting_point {
struct ssol_instance* instance;
+ const struct shaded_shape* shaded_shape;
const struct ssol_material* material;
struct s3d_primitive sampl_primitive;
double sundir[3];
diff --git a/src/ssol_spectrum.c b/src/ssol_spectrum.c
@@ -40,105 +40,96 @@ spectrum_release(ref_T* ref)
SSOL(device_ref_put(dev));
}
-static char
+static int
spectrum_includes_point
(const struct ssol_spectrum* spectrum,
- const double wavelenght)
+ const double wavelength)
{
const double* data;
size_t sz;
- ASSERT(spectrum && spectrum->wavelengths.data && spectrum->intensities.data);
- sz = spectrum->wavelengths.size;
- ASSERT(sz && sz == spectrum->intensities.size);
- data = spectrum->wavelengths.data;
- return data[0] <= wavelenght && wavelenght <= data[sz - 1];
+ ASSERT(spectrum);
+ sz = darray_double_size_get(&spectrum->wavelengths);
+ ASSERT(sz && sz == darray_double_size_get(&spectrum->intensities));
+ data = darray_double_cdata_get(&spectrum->wavelengths);
+ return data[0] <= wavelength && wavelength <= data[sz - 1];
}
static int
-eq_d(const void* key, const void* base)
+eq_dbl(const void* key, const void* base)
{
- double k = *(double*) key;
- double b = *(double*) base;
- if (k > b) return +1;
- if (k < b) return -1;
+ const double k = *(const double*) key;
+ const double b = *(const double*) base;
+ if(k > b) return +1;
+ if(k < b) return -1;
return 0;
}
/*******************************************************************************
-* Local ssol_spectrum functions
-******************************************************************************/
-res_T
+ * Local ssol_spectrum functions
+ ******************************************************************************/
+int
spectrum_includes
(const struct ssol_spectrum* reference,
- const struct ssol_spectrum* tested,
- char* include)
+ const struct ssol_spectrum* tested)
{
const double* test_data;
size_t test_sz;
- if(!reference || !tested || !include) {
- return RES_BAD_ARG;
- }
-
- test_sz = tested->wavelengths.size;
- test_data = tested->wavelengths.data;
- *include = spectrum_includes_point(reference, test_data[0])
- && spectrum_includes_point(reference, test_data[test_sz - 1]);
+ ASSERT(reference && tested);
- return RES_OK;
+ test_sz = darray_double_size_get(&tested->wavelengths);
+ test_data = darray_double_cdata_get(&tested->wavelengths);
+ return spectrum_includes_point(reference, test_data[0])
+ && spectrum_includes_point(reference, test_data[test_sz - 1]);
}
-res_T
+double
spectrum_interpolate
(const struct ssol_spectrum* spectrum,
- const double wavelenght,
- double* intensity)
+ const double wavelength)
{
- double* next;
- double* wavelengths;
- double* ints;
+ const double* wls;
+ const double* ints;
+ const double* next;
double slope;
- size_t idx_next, sz;
- if (!spectrum
- || !intensity
- || !spectrum_includes_point(spectrum, wavelenght))
- {
- return RES_BAD_ARG;
- }
-
- sz = spectrum->wavelengths.size;
- wavelengths = spectrum->wavelengths.data;
- ints = spectrum->intensities.data;
- next = search_lower_bound(&wavelenght, wavelengths, sz, sizeof(double), &eq_d);
- ASSERT(next); /* cause spectrum_includes_point */
- idx_next = (size_t)(next - wavelengths);
- ASSERT(idx_next); /* cause spectrum_includes_point */
- ASSERT(ints[idx_next] >= ints[idx_next - 1]);
- ASSERT(wavelengths[idx_next] >= wavelengths[idx_next - 1]);
-
- slope = (ints[idx_next] - ints[idx_next - 1])
- / (wavelengths[idx_next] - wavelengths[idx_next - 1]);
- *intensity = ints[idx_next - 1]
- + (wavelenght - wavelengths[idx_next - 1]) * slope;
- ASSERT(*intensity >= 0);
- return RES_OK;
+ double intensity;
+ size_t id_next, sz;
+ ASSERT(spectrum && spectrum_includes_point(spectrum, wavelength));
+
+ sz = darray_double_size_get(&spectrum->wavelengths);
+ wls = darray_double_cdata_get(&spectrum->wavelengths);
+ ints = darray_double_cdata_get(&spectrum->intensities);
+ next = search_lower_bound(&wavelength, wls, sz, sizeof(double), &eq_dbl);
+ ASSERT(next); /* because spectrum_includes_point */
+
+ id_next = (size_t)(next - wls);
+ ASSERT(id_next); /* because spectrum_includes_point */
+ ASSERT(ints[id_next] >= ints[id_next - 1]);
+ ASSERT(wls[id_next] >= wls[id_next - 1]);
+
+ slope = (ints[id_next] - ints[id_next-1]) / (wls[id_next] - wls[id_next-1]);
+ intensity = ints[id_next-1] + (wavelength - wls[id_next - 1]) * slope;
+ ASSERT(intensity >= 0);
+ return intensity;
}
/*******************************************************************************
-* Exported ssol_spectrum functions
-******************************************************************************/
+ * Exported ssol_spectrum functions
+ ******************************************************************************/
res_T
ssol_spectrum_create
(struct ssol_device* dev, struct ssol_spectrum** out_spectrum)
{
struct ssol_spectrum* spectrum = NULL;
res_T res = RES_OK;
- if (!dev || !out_spectrum) {
- return RES_BAD_ARG;
+
+ if(!dev || !out_spectrum) {
+ res = RES_BAD_ARG;
+ goto error;
}
spectrum = (struct ssol_spectrum*)MEM_CALLOC
(dev->allocator, 1, sizeof(struct ssol_spectrum));
- if (!spectrum) {
+ if(!spectrum) {
res = RES_MEM_ERR;
goto error;
}
@@ -150,10 +141,10 @@ ssol_spectrum_create
darray_double_init(dev->allocator, &spectrum->intensities);
exit:
- if (out_spectrum) *out_spectrum = spectrum;
+ if(out_spectrum) *out_spectrum = spectrum;
return res;
error:
- if (spectrum) {
+ if(spectrum) {
SSOL(spectrum_ref_put(spectrum));
spectrum = NULL;
}
@@ -163,8 +154,7 @@ error:
res_T
ssol_spectrum_ref_get(struct ssol_spectrum* spectrum)
{
- if (!spectrum)
- return RES_BAD_ARG;
+ if(!spectrum) return RES_BAD_ARG;
ref_get(&spectrum->ref);
return RES_OK;
}
@@ -172,8 +162,7 @@ ssol_spectrum_ref_get(struct ssol_spectrum* spectrum)
res_T
ssol_spectrum_ref_put(struct ssol_spectrum* spectrum)
{
- if (!spectrum)
- return RES_BAD_ARG;
+ if(!spectrum) return RES_BAD_ARG;
ref_put(&spectrum->ref, spectrum_release);
return RES_OK;
}
@@ -187,25 +176,29 @@ ssol_spectrum_setup
{
res_T res = RES_OK;
size_t i;
- if(!spectrum
- || nwavelength <= 0
- || !wavelengths
- || !data)
- return RES_BAD_ARG;
+ if(!spectrum || !nwavelength || !wavelengths || !data) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
res = darray_double_resize(&spectrum->wavelengths, nwavelength);
- if (res != RES_OK) return res;
+ if(res != RES_OK) goto error;
res = darray_double_resize(&spectrum->intensities, nwavelength);
- if (res != RES_OK) {
- darray_double_clear(&spectrum->wavelengths);
- return res;
- }
+ if(res != RES_OK) goto error;
FOR_EACH(i, 0, nwavelength) {
spectrum->wavelengths.data[i] = wavelengths[i];
spectrum->intensities.data[i] = data[i];
}
+exit:
return res;
+error:
+ if(spectrum) {
+ darray_double_clear(&spectrum->wavelengths);
+ darray_double_clear(&spectrum->intensities);
+ }
+ goto exit;
}
+
diff --git a/src/ssol_spectrum_c.h b/src/ssol_spectrum_c.h
@@ -22,20 +22,22 @@
struct ssol_spectrum {
struct darray_double wavelengths;
struct darray_double intensities;
+
struct ssol_device* dev;
ref_T ref;
};
-extern LOCAL_SYM res_T
+/* Check that the `tested' spectrum is included into `reference' */
+extern LOCAL_SYM int
spectrum_includes
(const struct ssol_spectrum* reference,
- const struct ssol_spectrum* tested,
- char* include);
+ const struct ssol_spectrum* tested);
-extern LOCAL_SYM res_T
+/* Retrieve the linearly interpolated spectrum intensity for the commited
+ * wavelength */
+extern LOCAL_SYM double
spectrum_interpolate
(const struct ssol_spectrum* spectrum,
- const double wavelenght,
- double* intensity);
+ const double wavelength);
#endif /* SSOL_SPECTRUM_C_H */
diff --git a/src/test_ssol_atmosphere.c b/src/test_ssol_atmosphere.c
@@ -52,11 +52,11 @@ main(int argc, char** argv)
CHECK(ssol_atmosphere_ref_put(NULL), RES_BAD_ARG);
CHECK(ssol_atmosphere_ref_put(atm), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(NULL, spectrum), RES_BAD_ARG);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, NULL), RES_BAD_ARG);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, spectrum), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, spectrum2), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, spectrum2), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(NULL, spectrum), RES_BAD_ARG);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, NULL), RES_BAD_ARG);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, spectrum), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, spectrum2), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, spectrum2), RES_OK);
CHECK(ssol_atmosphere_ref_put(atm), RES_OK);
diff --git a/src/test_ssol_instance.c b/src/test_ssol_instance.c
@@ -44,7 +44,8 @@ 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, material, &object), RES_OK);
+ CHECK(ssol_object_create(dev, &object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(object, shape, material, material), RES_OK);
CHECK(ssol_object_instantiate(object, &instance), RES_OK);
diff --git a/src/test_ssol_object.c b/src/test_ssol_object.c
@@ -43,11 +43,27 @@ main(int argc, char** argv)
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, 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_create(NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_create(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_create(NULL, &object), RES_BAD_ARG);
+ CHECK(ssol_object_create(dev, &object), RES_OK);
+
+ CHECK(ssol_object_add_shaded_shape(NULL, NULL, NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, NULL, NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, shape, NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, shape, NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, NULL, mtl, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, NULL, mtl, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, shape, mtl, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, shape, mtl, NULL), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, NULL, NULL, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, NULL, NULL, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, shape, NULL, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, shape, NULL, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, NULL, mtl, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, NULL, mtl, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(NULL, shape, mtl, mtl), RES_BAD_ARG);
+ CHECK(ssol_object_add_shaded_shape(object, shape, mtl, mtl), RES_OK);
CHECK(ssol_object_ref_get(NULL), RES_BAD_ARG);
CHECK(ssol_object_ref_get(object), RES_OK);
@@ -55,7 +71,12 @@ main(int argc, char** argv)
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_create(dev, &object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(object, shape, mtl, mtl2), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(object, shape, mtl2, mtl), RES_OK);
+
+ CHECK(ssol_object_clear(NULL), RES_BAD_ARG);
+ CHECK(ssol_object_clear(object), RES_OK);
CHECK(ssol_object_ref_put(object), RES_OK);
CHECK(ssol_shape_ref_put(shape), RES_OK);
diff --git a/src/test_ssol_scene.c b/src/test_ssol_scene.c
@@ -53,7 +53,8 @@ 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, material, &object), RES_OK);
+ CHECK(ssol_object_create(dev, &object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(object, shape, material, material), RES_OK);
CHECK(ssol_object_instantiate(object, &instance), RES_OK);
CHECK(ssol_instance_set_transform(instance, transform), RES_OK);
CHECK(ssol_sun_create_directional(dev, &sun), RES_OK);
@@ -111,9 +112,9 @@ main(int argc, char** argv)
CHECK(ssol_spectrum_create(dev, &spectrum), RES_OK);
CHECK(ssol_spectrum_setup(spectrum, wavelengths, data, 3), RES_OK);
CHECK(ssol_atmosphere_create_uniform(dev, &atm), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, spectrum), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, spectrum), RES_OK);
CHECK(ssol_atmosphere_create_uniform(dev, &atm2), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm2, spectrum), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm2, spectrum), RES_OK);
CHECK(ssol_scene_attach_atmosphere(NULL, atm), RES_BAD_ARG);
CHECK(ssol_scene_attach_atmosphere(scene, NULL), RES_BAD_ARG);
diff --git a/src/test_ssol_shape.c b/src/test_ssol_shape.c
@@ -37,6 +37,7 @@ main(int argc, char** argv)
struct ssol_punched_surface punched_surface;
struct ssol_carving carving;
struct ssol_quadric quadric;
+ uint32_t id;
double polygon[] = {
-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.f, -2.f
};
@@ -58,6 +59,11 @@ main(int argc, char** argv)
CHECK(ssol_shape_create_mesh(NULL, &shape), RES_BAD_ARG);
CHECK(ssol_shape_create_mesh(dev, &shape), RES_OK);
+ CHECK(ssol_shape_get_id(NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_get_id(shape, NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_get_id(NULL, &id), RES_BAD_ARG);
+ CHECK(ssol_shape_get_id(shape, &id), RES_OK);
+
CHECK(ssol_shape_ref_get(NULL), RES_BAD_ARG);
CHECK(ssol_shape_ref_get(shape), RES_OK);
diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c
@@ -126,7 +126,8 @@ main(int argc, char** argv)
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_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK);
CHECK(ssol_instance_set_receiver(heliostat, "miroir", NULL), RES_OK);
CHECK(ssol_instance_set_target_mask(heliostat, 0x1, 0), RES_OK);
@@ -138,7 +139,8 @@ main(int argc, char** argv)
CHECK(ssol_instance_set_target_mask(secondary, 0x2, 0), RES_OK);
CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK);
- CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform2), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);
@@ -185,7 +187,7 @@ main(int argc, char** argv)
CHECK(ssol_spectrum_create(dev, &abs), RES_OK);
CHECK(ssol_spectrum_setup(abs, mismatch, ka, 2), RES_OK);
CHECK(ssol_atmosphere_create_uniform(dev, &atm), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, abs), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, abs), RES_OK);
CHECK(ssol_scene_attach_atmosphere(scene, atm), RES_OK);
CHECK(ssol_solve(scene, rng, 10, stdout, estimator), RES_BAD_ARG); /* spectra mismatch */
CHECK(ssol_scene_detach_atmosphere(scene, atm), RES_OK);
@@ -237,11 +239,11 @@ main(int argc, char** argv)
logger_print(&logger, LOG_OUTPUT, "Missing = %g +/- %g", status.E, status.SE);
CHECK(eq_eps(status.E, 0, 1e-4), 1);
- /* check atmosphere model; with no absorbtion result is unchanged */
+ /* check atmosphere model; with no absorption result is unchanged */
CHECK(ssol_spectrum_create(dev, &abs), RES_OK);
CHECK(ssol_spectrum_setup(abs, wavelengths, ka, 3), RES_OK);
CHECK(ssol_atmosphere_create_uniform(dev, &atm), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, abs), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, abs), RES_OK);
CHECK(ssol_scene_attach_atmosphere(scene, atm), RES_OK);
NCHECK(tmp = tmpfile(), 0);
@@ -262,12 +264,12 @@ main(int argc, char** argv)
logger_print(&logger, LOG_OUTPUT, "Missing = %g +/- %g", status.E, status.SE);
CHECK(eq_eps(status.E, 0, 1e-4), 1);
- /* check atmosphere model; with absorbtion power decreases */
+ /* check atmosphere model; with absorption power decreases */
ka[0] = ka[1] = ka[2] = 0.1;
CHECK(ssol_spectrum_create(dev, &abs), RES_OK);
CHECK(ssol_spectrum_setup(abs, wavelengths, ka, 3), RES_OK);
CHECK(ssol_atmosphere_create_uniform(dev, &atm), RES_OK);
- CHECK(ssol_atmosphere_set_uniform_absorbtion(atm, abs), RES_OK);
+ CHECK(ssol_atmosphere_set_uniform_absorption(atm, abs), RES_OK);
CHECK(ssol_scene_attach_atmosphere(scene, atm), RES_OK);
NCHECK(tmp = tmpfile(), 0);
diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c
@@ -56,7 +56,7 @@ main(int argc, char** argv)
struct ssol_vertex_data attribs[1];
struct ssol_shape* quad_square;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -150,7 +150,8 @@ main(int argc, char** argv)
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, rect, m_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, rect, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat1), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat2), RES_OK);
CHECK(ssol_instance_set_receiver(heliostat1, "miroir", NULL), RES_OK);
@@ -162,14 +163,16 @@ main(int argc, char** argv)
CHECK(ssol_scene_attach_instance(scene, heliostat1), RES_OK);
CHECK(ssol_scene_attach_instance(scene, heliostat2), RES_OK);
- CHECK(ssol_object_create(dev, quad_square, m_mtl, m_mtl, &s_object), RES_OK);
+ CHECK(ssol_object_create(dev, &s_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(s_object, quad_square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(s_object, &secondary), RES_OK);
CHECK(ssol_instance_set_receiver(secondary, "secondaire", NULL), RES_OK);
CHECK(ssol_instance_set_transform(secondary, transform1), RES_OK);
CHECK(ssol_instance_dont_sample(secondary, 1), RES_OK);
CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK);
- CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform2), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);
diff --git a/src/test_ssol_solver2b.c b/src/test_ssol_solver2b.c
@@ -56,7 +56,7 @@ main(int argc, char** argv)
struct ssol_shape* quad_square;
struct ssol_shape* quad_rect;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -155,7 +155,8 @@ main(int argc, char** argv)
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, quad_rect, m_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, quad_rect, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat1), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat2), RES_OK);
CHECK(ssol_instance_set_receiver(heliostat1, "miroir", NULL), RES_OK);
@@ -167,14 +168,16 @@ main(int argc, char** argv)
CHECK(ssol_scene_attach_instance(scene, heliostat1), RES_OK);
CHECK(ssol_scene_attach_instance(scene, heliostat2), RES_OK);
- CHECK(ssol_object_create(dev, quad_square, m_mtl, m_mtl, &s_object), RES_OK);
+ CHECK(ssol_object_create(dev, &s_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(s_object, quad_square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(s_object, &secondary), RES_OK);
CHECK(ssol_instance_set_receiver(secondary, "secondaire", NULL), RES_OK);
CHECK(ssol_instance_set_transform(secondary, transform1), RES_OK);
CHECK(ssol_instance_dont_sample(secondary, 1), RES_OK);
CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK);
- CHECK(ssol_object_create(dev, rect, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, rect, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform2), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);
diff --git a/src/test_ssol_solver3.c b/src/test_ssol_solver3.c
@@ -50,7 +50,7 @@ main(int argc, char** argv)
struct ssol_vertex_data attribs[1];
struct ssol_shape* quad_square;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -124,12 +124,14 @@ main(int argc, char** argv)
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, quad_square, m_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, quad_square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK);
CHECK(ssol_instance_set_receiver(heliostat, "heliostat", NULL), RES_OK);
CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK);
- CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);
diff --git a/src/test_ssol_solver3N.c b/src/test_ssol_solver3N.c
@@ -94,7 +94,7 @@ main(int argc, char** argv)
struct ssol_vertex_data attribs[1];
struct ssol_shape* quad_square;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -168,7 +168,8 @@ main(int argc, char** argv)
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, quad_square, m_mtl, v_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, quad_square, m_mtl, v_mtl), RES_OK);
common.scene = scene;
d3_set(common.sun_dir, sun_dir);
@@ -194,7 +195,8 @@ main(int argc, char** argv)
d33_rotation_pitch(transform, PI); /* flip faces: invert normal */
d3_set(transform + 9, target_pos);
- CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);
diff --git a/src/test_ssol_solver4.c b/src/test_ssol_solver4.c
@@ -50,7 +50,7 @@ main(int argc, char** argv)
struct ssol_vertex_data attribs[1];
struct ssol_shape* quad_square;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -126,11 +126,13 @@ main(int argc, char** argv)
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, quad_square, m_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, quad_square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK);
CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK);
- CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target1), RES_OK);
CHECK(ssol_instance_set_transform(target1, transform), RES_OK);
CHECK(ssol_instance_set_receiver(target1, "cible1", NULL), RES_OK);
diff --git a/src/test_ssol_solver5.c b/src/test_ssol_solver5.c
@@ -50,7 +50,7 @@ main(int argc, char** argv)
struct ssol_vertex_data attribs[1];
struct ssol_shape* quad_square;
struct ssol_carving carving;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
struct ssol_punched_surface punched;
struct ssol_material* m_mtl;
struct ssol_material* v_mtl;
@@ -125,11 +125,13 @@ main(int argc, char** argv)
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, quad_square, m_mtl, m_mtl, &m_object), RES_OK);
+ CHECK(ssol_object_create(dev, &m_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(m_object, quad_square, m_mtl, m_mtl), RES_OK);
CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK);
CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK);
- CHECK(ssol_object_create(dev, rect, v_mtl, v_mtl, &t_object), RES_OK);
+ CHECK(ssol_object_create(dev, &t_object), RES_OK);
+ CHECK(ssol_object_add_shaded_shape(t_object, rect, v_mtl, v_mtl), RES_OK);
CHECK(ssol_object_instantiate(t_object, &target), RES_OK);
CHECK(ssol_instance_set_transform(target, transform), RES_OK);
CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK);