commit e533c1aa7cbfe3e83462f023bc04569de7b00605
parent d74054cf855ab88d073e21386b0126c2d9f64d9c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 6 Sep 2016 11:58:22 +0200
Add a Star-3D sampling shape to the ssol_shape.
Use the Star-3D sampling shape to create a Star-3D sampling scene in the
ssol_object. Instantiate it as a sampling instance in the
ssol_object_instance. On solve invocation, conditionally attach the
Star-3D sampling instance to the Star-3D sampling scene of the
ssol_scene whether its associated material is a mirror or not. Fill an
associative container that maps the Star-3D instance identifier to its
associated ssol_object_instance and use it to retrieve the sampled
solstice instance at the beginning of each realisation.
Clean up the code by removing useless getters.
Diffstat:
11 files changed, 270 insertions(+), 321 deletions(-)
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -53,13 +53,6 @@ struct ssol_material {
ref_T ref;
};
-static INLINE enum material_type
-material_get_type(const struct ssol_material* mtl)
-{
- ASSERT(mtl);
- return mtl->type;
-}
-
extern LOCAL_SYM void
surface_fragment_setup
(struct surface_fragment* fragment,
diff --git a/src/ssol_object.c b/src/ssol_object.c
@@ -25,6 +25,16 @@
/*******************************************************************************
* 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)
{
@@ -35,21 +45,12 @@ object_release(ref_T* ref)
ASSERT(dev && dev->allocator);
SSOL(shape_ref_put(object->shape));
SSOL(material_ref_put(object->material));
- if(object->s3d_scn) S3D(scene_ref_put(object->s3d_scn));
+ 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);
SSOL(device_ref_put(dev));
}
-static INLINE res_T
-object_ok(const struct ssol_object* object)
-{
- if(!object
- || !object->shape
- || !object->material)
- return RES_BAD_ARG;
- return RES_OK;
-}
-
/*******************************************************************************
* Exported ssol_object functions
******************************************************************************/
@@ -81,11 +82,16 @@ ssol_object_create
object->material = material;
ref_init(&object->ref);
- /* Create the Star-3D scene to instantiate through the object instance */
- res = s3d_scene_create(dev->s3d, &object->s3d_scn);
+ /* 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->s3d_scn, shape_get_s3d_shape(object->shape));
+ res = s3d_scene_attach_shape(object->scn_samp, object->shape->shape_samp);
if(res != RES_OK) goto error;
exit:
diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h
@@ -22,18 +22,11 @@ struct ssol_object {
struct ssol_shape* shape;
struct ssol_material* material;
- struct s3d_scene* s3d_scn; /* Scene to instantiate */
+ struct s3d_scene* scn_rt; /* RT scene to instantiate */
+ struct s3d_scene* scn_samp; /* Sampling scene to instantiate */
struct ssol_device* dev;
ref_T ref;
};
-static FINLINE struct ssol_material*
-object_get_material(const struct ssol_object* object)
-{
- ASSERT(object);
- return object->material;
-}
-
-
#endif /* SSOL_OBJECT_C_H */
diff --git a/src/ssol_object_instance.c b/src/ssol_object_instance.c
@@ -40,7 +40,8 @@ object_instance_release(ref_T* ref)
ASSERT(dev && dev->allocator);
SSOL(object_ref_put(instance->object));
- if(instance->s3d_shape) S3D(shape_ref_put(instance->s3d_shape));
+ 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);
MEM_RM(dev->allocator, instance);
SSOL(device_ref_put(dev));
@@ -80,8 +81,12 @@ ssol_object_instantiate
SSOL(device_ref_get(dev));
ref_init(&instance->ref);
- /* Create the Star-3D instance */
- res = s3d_scene_instantiate(object->s3d_scn, &instance->s3d_shape);
+ /* Create the Star-3D instance to ray-trace */
+ res = s3d_scene_instantiate(object->scn_rt, &instance->shape_rt);
+ if(res != RES_OK) goto error;
+
+ /* Create the Star-3D instance to sample */
+ res = s3d_scene_instantiate(object->scn_samp, &instance->shape_samp);
if(res != RES_OK) goto error;
exit:
@@ -98,7 +103,7 @@ error:
res_T
ssol_object_instance_ref_get(struct ssol_object_instance* instance)
{
- if (!instance)
+ if(!instance)
return RES_BAD_ARG;
ref_get(&instance->ref);
return RES_OK;
@@ -120,13 +125,27 @@ ssol_object_instance_set_transform
{
float t[12];
int i;
- if (!instance || !transform)
- return RES_BAD_ARG;
+ res_T res = RES_OK;
- for (i = 0; i < 12; i++) t[i] = (float) transform[i];
- s3d_instance_set_transform(instance->s3d_shape, t);
+ if(!instance || !transform) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
- return RES_OK;
+ FOR_EACH(i, 0, 12) t[i] = (float)transform[i];
+
+ res = s3d_instance_set_transform(instance->shape_rt, t);
+ if(res != RES_OK) goto error;
+
+ if(instance->shape_rt != instance->shape_samp) {
+ res = s3d_instance_set_transform(instance->shape_samp, t);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
}
res_T
diff --git a/src/ssol_object_instance_c.h b/src/ssol_object_instance_c.h
@@ -23,7 +23,8 @@
struct ssol_object_instance
{
struct ssol_object* object; /* Instantiated object */
- struct s3d_shape* s3d_shape; /* Instantiated Star-3D shape */
+ 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 */
uint32_t target_mask;
@@ -31,21 +32,6 @@ struct ssol_object_instance
ref_T ref;
};
-/* Return the Star-3D shape of the object instance */
-static INLINE struct s3d_shape*
-object_instance_get_s3d_shape(const struct ssol_object_instance* instance)
-{
- ASSERT(instance);
- return instance->s3d_shape;
-}
-
-static INLINE struct ssol_object*
-object_instance_get_object(const struct ssol_object_instance* instance)
-{
- ASSERT(instance);
- return instance->object;
-}
-
static INLINE const char*
object_instance_get_receiver_name(const struct ssol_object_instance* instance)
{
@@ -54,11 +40,4 @@ object_instance_get_receiver_name(const struct ssol_object_instance* instance)
? NULL : str_cget(&instance->receiver_name);
}
-static INLINE uint32_t
-object_instance_get_target_mask(const struct ssol_object_instance* instance)
-{
- ASSERT(instance);
- return instance->target_mask;
-}
-
#endif /* SSOL_OBJECT_INSTANCE_C_H */
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -40,10 +40,11 @@ scene_release(ref_T* ref)
dev = scene->dev;
ASSERT(dev && dev->allocator);
SSOL(scene_clear(scene));
- if (scene->s3d_raytracing_scn) S3D(scene_ref_put(scene->s3d_raytracing_scn));
- if (scene->s3d_sampling_scn) S3D(scene_ref_put(scene->s3d_sampling_scn));
+ if(scene->scn_rt) S3D(scene_ref_put(scene->scn_rt));
+ if(scene->scn_samp) S3D(scene_ref_put(scene->scn_samp));
if(scene->sun) SSOL(sun_ref_put(scene->sun));
- htable_instance_release(&scene->instances);
+ htable_instance_release(&scene->instances_rt);
+ htable_instance_release(&scene->instances_samp);
MEM_RM(dev->allocator, scene);
SSOL(device_ref_put(dev));
}
@@ -58,32 +59,32 @@ ssol_scene_create
{
struct ssol_scene* scene = NULL;
res_T res = RES_OK;
- if (!dev || !out_scene) {
+ if(!dev || !out_scene) {
return RES_BAD_ARG;
}
scene = (struct ssol_scene*)MEM_CALLOC
(dev->allocator, 1, sizeof(struct ssol_scene));
- if (!scene) {
+ if(!scene) {
res = RES_MEM_ERR;
goto error;
}
- htable_instance_init(dev->allocator, &scene->instances);
+ htable_instance_init(dev->allocator, &scene->instances_rt);
+ htable_instance_init(dev->allocator, &scene->instances_samp);
SSOL(device_ref_get(dev));
scene->dev = dev;
ref_init(&scene->ref);
- res = s3d_scene_create(dev->s3d, &scene->s3d_raytracing_scn);
- if (res != RES_OK) goto error;
-
- res = s3d_scene_create(dev->s3d, &scene->s3d_sampling_scn);
- if (res != RES_OK) goto error;
+ res = s3d_scene_create(dev->s3d, &scene->scn_rt);
+ if(res != RES_OK) goto error;
+ res = s3d_scene_create(dev->s3d, &scene->scn_samp);
+ if(res != RES_OK) goto error;
exit:
- if (out_scene) *out_scene = scene;
+ if(out_scene) *out_scene = scene;
return res;
error:
- if (scene) {
+ if(scene) {
SSOL(scene_ref_put(scene));
scene = NULL;
}
@@ -110,23 +111,21 @@ res_T
ssol_scene_attach_object_instance
(struct ssol_scene* scene, struct ssol_object_instance* instance)
{
- struct s3d_shape* shape;
unsigned id;
res_T res;
if(!scene || !instance) return RES_BAD_ARG;
- shape = object_instance_get_s3d_shape(instance);
- /* attach the instantiated s3d shape to s3d scene */
- res = s3d_scene_attach_shape(scene->s3d_raytracing_scn, shape);
+ /* 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;
/* Register the instance against the scene */
- S3D(shape_get_id(shape, &id));
- ASSERT(!htable_instance_find(&scene->instances, &id));
- res = htable_instance_set(&scene->instances, &id, &instance);
+ S3D(shape_get_id(instance->shape_rt, &id));
+ ASSERT(!htable_instance_find(&scene->instances_rt, &id));
+ res = htable_instance_set(&scene->instances_rt, &id, &instance);
if(res != RES_OK) {
- S3D(scene_detach_shape(scene->s3d_raytracing_scn, shape));
+ S3D(scene_detach_shape(scene->scn_rt, instance->shape_rt));
return res;
}
SSOL(object_instance_ref_get(instance));
@@ -140,7 +139,6 @@ ssol_scene_detach_object_instance
{
struct ssol_object_instance** pinst;
struct ssol_object_instance* inst;
- struct s3d_shape* shape;
unsigned id;
size_t n;
(void)n, (void)inst;
@@ -148,19 +146,18 @@ ssol_scene_detach_object_instance
if(!scene || !instance) return RES_BAD_ARG;
/* Retrieve the object instance identifier */
- shape = object_instance_get_s3d_shape(instance);
- S3D(shape_get_id(shape, &id));
+ S3D(shape_get_id(instance->shape_rt, &id));
/* Check that the instance is effectively registered into the scene */
- pinst = htable_instance_find(&scene->instances, &id);
+ pinst = htable_instance_find(&scene->instances_rt, &id);
if(!pinst) return RES_BAD_ARG;
inst = *pinst;
ASSERT(inst == instance);
/* Detach the object instance */
- n = htable_instance_erase(&scene->instances, &id);
+ n = htable_instance_erase(&scene->instances_rt, &id);
ASSERT(n == 1);
- S3D(scene_detach_shape(scene->s3d_raytracing_scn, shape));
+ S3D(scene_detach_shape(scene->scn_rt, instance->shape_rt));
SSOL(object_instance_ref_put(instance));
return RES_OK;
@@ -172,28 +169,29 @@ ssol_scene_clear(struct ssol_scene* scene)
struct htable_instance_iterator it, it_end;
if(!scene) return RES_BAD_ARG;
- htable_instance_begin(&scene->instances, &it);
- htable_instance_end(&scene->instances, &it_end);
+ htable_instance_begin(&scene->instances_rt, &it);
+ htable_instance_end(&scene->instances_rt, &it_end);
while(!htable_instance_iterator_eq(&it, &it_end)) {
struct ssol_object_instance* inst;
inst = *htable_instance_iterator_data_get(&it);
- S3D(scene_detach_shape(scene->s3d_raytracing_scn, object_instance_get_s3d_shape(inst)));
+ S3D(scene_detach_shape(scene->scn_rt, inst->shape_rt));
SSOL(object_instance_ref_put(inst));
htable_instance_iterator_next(&it);
}
- htable_instance_clear(&scene->instances);
- S3D(scene_clear(scene->s3d_raytracing_scn));
- if(scene->sun)
- ssol_scene_detach_sun(scene, scene->sun);
+ htable_instance_clear(&scene->instances_rt);
+ htable_instance_clear(&scene->instances_samp);
+ S3D(scene_clear(scene->scn_rt));
+ S3D(scene_clear(scene->scn_samp));
+ if(scene->sun) ssol_scene_detach_sun(scene, scene->sun);
return RES_OK;
}
res_T
ssol_scene_attach_sun(struct ssol_scene* scene, struct ssol_sun* sun)
{
- if (!scene || ! sun
- || sun->scene_attachment /* should detach this sun first from its own scene */
- || scene->sun) /* should detach previous sun first */
+ if(!scene || ! sun
+ || sun->scene_attachment /* Should detach this sun first from its own scene */
+ || scene->sun) /* Should detach previous sun first */
return RES_BAD_ARG;
SSOL(sun_ref_get(sun));
@@ -205,7 +203,7 @@ ssol_scene_attach_sun(struct ssol_scene* scene, struct ssol_sun* sun)
res_T
ssol_scene_detach_sun(struct ssol_scene* scene, struct ssol_sun* sun)
{
- if (!scene || !sun || !scene->sun || sun->scene_attachment != scene)
+ if(!scene || !sun || !scene->sun || sun->scene_attachment != scene)
return RES_BAD_ARG;
ASSERT(sun == scene->sun);
@@ -218,30 +216,48 @@ ssol_scene_detach_sun(struct ssol_scene* scene, struct ssol_sun* sun)
/*******************************************************************************
* Local functions
******************************************************************************/
-struct s3d_scene*
-scene_get_s3d_raytracing_scn(const struct ssol_scene* scn)
+res_T
+scene_setup_s3d_sampling_scene(struct ssol_scene* scn)
{
+ struct htable_instance_iterator it, end;
+ res_T res = RES_OK;
ASSERT(scn);
- return scn->s3d_raytracing_scn;
-}
-struct s3d_scene*
-scene_get_s3d_sampling_scn(const struct ssol_scene* scn)
-{
- ASSERT(scn);
- return scn->s3d_sampling_scn;
-}
+ S3D(scene_clear(scn->scn_samp));
+ htable_instance_clear(&scn->instances_samp);
-struct ssol_object_instance*
-scene_get_object_instance_from_s3d_hit
- (struct ssol_scene* scn,
- const struct s3d_hit* hit)
-{
- struct ssol_object_instance** pinst;
- ASSERT(scn && hit);
- pinst = htable_instance_find(&scn->instances, &hit->prim.inst_id);
- ASSERT(pinst);
- return *pinst;
+ htable_instance_begin(&scn->instances_rt, &it);
+ htable_instance_end(&scn->instances_rt, &end);
+
+ while(!htable_instance_iterator_eq(&it, &end)) {
+ struct ssol_object_instance* inst = *htable_instance_iterator_data_get(&it);
+ unsigned id;
+ htable_instance_iterator_next(&it);
+
+ /* TODO: keep only primary mirrors */
+ if(inst->object->material->type != MATERIAL_MIRROR)
+ continue;
+
+ /* Attach the instantiated s3d sampling shape to the s3d sampling scene */
+ res = s3d_scene_attach_shape(scn->scn_samp, inst->shape_samp);
+ if(res != RES_OK) goto error;
+
+ /* Register the instantiated s3d sampling shape */
+ S3D(shape_get_id(inst->shape_samp, &id));
+ ASSERT(!htable_instance_find(&scn->instances_samp, &id));
+ res = htable_instance_set(&scn->instances_samp, &id, &inst);
+ if(res != RES_OK) goto error;
+
+ /* Do not get a reference onto the instance since it was already referenced
+ * by the scene on its attachment */
+ }
+
+exit:
+ return res;
+error:
+ S3D(scene_clear(scn->scn_samp));
+ htable_instance_clear(&scn->instances_samp);
+ goto exit;
}
/*******************************************************************************
@@ -255,8 +271,7 @@ hit_filter_function
void* realisation,
void* filter_data)
{
- struct ssol_object_instance* instance;
- struct ssol_material* material;
+ struct ssol_object_instance* inst;
const char* receiver_name;
struct realisation* rs = realisation;
struct segment* seg;
@@ -274,10 +289,10 @@ hit_filter_function
if(prev && S3D_PRIMITIVE_EQ(&hit->prim, &prev->hit.prim))
return 1; /* Discard self intersection */
- instance = scene_get_object_instance_from_s3d_hit(rs->data.scene, hit);
+ 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(instance);
+ receiver_name = object_instance_get_receiver_name(inst);
if(receiver_name) {
float cos_in;
/* check normal orientation */
@@ -301,40 +316,15 @@ hit_filter_function
}
/* register success mask */
- if (front_face)
- rs->success_mask |= object_instance_get_target_mask(instance);
-
- material = object_get_material(object_instance_get_object(instance));
+ if(front_face) {
+ rs->success_mask |= inst->target_mask;
+ }
- if(material_get_type(material) == MATERIAL_VIRTUAL) {
+ if(inst->object->material->type == MATERIAL_VIRTUAL) {
return 1; /* Discard virtual material */
}
- rs->data.instance = instance;
-
+ rs->data.instance = inst;
return 0;
}
-struct ssol_sun*
-scene_get_sun
- (struct ssol_scene* scn)
-{
- ASSERT(scn);
- return scn->sun;
-}
-
-struct ssol_device*
- scene_get_device
- (struct ssol_scene* scn)
-{
- ASSERT(scn);
- return scn->dev;
-}
-
-struct htable_instance*
- scene_get_instances
- (struct ssol_scene* scn)
-{
- ASSERT(scn);
- return &scn->instances;
-}
diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h
@@ -16,9 +16,11 @@
#ifndef SSOL_SCENE_C_H
#define SSOL_SCENE_C_H
-#include <rsys/rsys.h>
-#include <rsys/ref_count.h>
#include <rsys/hash_table.h>
+#include <rsys/ref_count.h>
+#include <rsys/rsys.h>
+
+struct ssol_object_instance;
/* Define the htable_instance data structure */
#define HTABLE_NAME instance
@@ -26,47 +28,27 @@
#define HTABLE_DATA struct ssol_object_instance*
#include <rsys/hash_table.h>
-struct ssol_scene
-{
- struct htable_instance instances;
- struct s3d_scene* s3d_raytracing_scn;
- struct s3d_scene* s3d_sampling_scn;
- struct ssol_sun* sun;
-
- struct ssol_device* dev;
- ref_T ref;
-};
-
+/* Forward declarations */
struct s3d_hit;
struct s3d_scene;
-struct ssol_object_instance;
+struct ssol_device;
struct ssol_scene;
struct ssol_sun;
-struct ssol_device;
-
-extern LOCAL_SYM struct s3d_scene*
-scene_get_s3d_raytracing_scn
- (const struct ssol_scene* scn);
-
-extern LOCAL_SYM struct s3d_scene*
-scene_get_s3d_sampling_scn
-(const struct ssol_scene* scn);
-
-extern LOCAL_SYM struct ssol_object_instance*
-scene_get_object_instance_from_s3d_hit
- (struct ssol_scene* scn,
- const struct s3d_hit* hit);
-extern LOCAL_SYM struct ssol_sun*
-scene_get_sun
- (struct ssol_scene* scn);
+struct ssol_scene {
+ struct htable_instance instances_rt;
+ struct htable_instance instances_samp;
+ struct s3d_scene* scn_rt;
+ struct s3d_scene* scn_samp;
+ struct ssol_sun* sun;
-extern LOCAL_SYM struct ssol_device*
-scene_get_device
- (struct ssol_scene* scn);
+ struct ssol_device* dev;
+ ref_T ref;
+};
-extern LOCAL_SYM struct htable_instance*
-scene_get_instances
+/* Fill the Star-3D sampling scene with the Star-3D shape of the mirrors */
+extern LOCAL_SYM res_T
+scene_setup_s3d_sampling_scene
(struct ssol_scene* scn);
#endif /* SSOL_SCENE_C_H */
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -399,8 +399,11 @@ error:
goto exit;
}
+/* Setup the Star-3D shape of the quadric to ray-trace, i.e. the clipped 2D
+ * profile of the quadric whose vertices are displaced with respect to the
+ * quadric equation */
static res_T
-quadric_setup_s3d_shape
+quadric_setup_s3d_shape_rt
(const struct ssol_quadric* quadric,
const struct darray_double* coords,
const struct darray_size_t* ids,
@@ -442,6 +445,36 @@ quadric_setup_s3d_shape
(shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx);
}
+/* Setup the Star-3D shape of the quadric to sample, i.e. the clipped 2D
+ * profile of the quadric */
+static res_T
+quadric_setup_s3d_shape_samp
+ (const struct darray_double* coords,
+ const struct darray_size_t* ids,
+ struct s3d_shape* shape)
+{
+ struct quadric_mesh_context ctx;
+ struct s3d_vertex_data vdata;
+ unsigned nverts;
+ unsigned ntris;
+ ASSERT(coords && ids && shape);
+ ASSERT(darray_double_size_get(coords)%2 == 0);
+ ASSERT(darray_size_t_size_get(ids)%3 == 0);
+ ASSERT(darray_double_size_get(coords)/2 <= UINT_MAX);
+ ASSERT(darray_size_t_size_get(ids)/3 <= UINT_MAX);
+
+ nverts = (unsigned)darray_double_size_get(coords) / 2/*#coords per vertex*/;
+ 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);
+
+ vdata.usage = S3D_POSITION;
+ vdata.type = S3D_FLOAT3;
+ vdata.get = quadric_mesh_plane_get_pos;
+ return s3d_mesh_setup_indexed_vertices
+ (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx);
+}
+
static res_T
shape_create
(struct ssol_device* dev,
@@ -462,11 +495,15 @@ shape_create
goto error;
}
- /* create a s3d_shape to hold a mesh */
- res = s3d_shape_create_mesh(dev->s3d, &shape->s3d_shape);
+ /* Create the s3d_shape to ray-trace */
+ res = s3d_shape_create_mesh(dev->s3d, &shape->shape_rt);
if(res != RES_OK) goto error;
res = s3d_mesh_set_hit_filter_function
- (shape->s3d_shape, hit_filter_function, NULL);
+ (shape->shape_rt, hit_filter_function, NULL);
+ if(res != RES_OK) goto error;
+
+ /* Create the s3d_shape to sample */
+ res = s3d_shape_create_mesh(dev->s3d, &shape->shape_samp);
if(res != RES_OK) goto error;
SSOL(device_ref_get(dev));
@@ -493,7 +530,8 @@ shape_release(ref_T* ref)
ASSERT(ref);
dev = shape->dev;
ASSERT(dev && dev->allocator);
- if(shape->s3d_shape) S3D(shape_ref_put(shape->s3d_shape));
+ if(shape->shape_rt) S3D(shape_ref_put(shape->shape_rt));
+ if(shape->shape_samp) S3D(shape_ref_put(shape->shape_samp));
MEM_RM(dev->allocator, shape);
SSOL(device_ref_put(dev));
}
@@ -576,8 +614,13 @@ ssol_punched_surface_setup
(&coords, &ids, shape->dev->scpr_mesh, psurf->carvings, psurf->nb_carvings);
if(res != RES_OK) goto error;
- res = quadric_setup_s3d_shape
- (psurf->quadric, &coords, &ids, shape->s3d_shape);
+ /* Setup the Star-3D shape to ray-trace */
+ res = quadric_setup_s3d_shape_rt
+ (psurf->quadric, &coords, &ids, shape->shape_rt);
+ if(res != RES_OK) goto error;
+
+ /* Setup the Star-3D shape to sample */
+ res = quadric_setup_s3d_shape_samp(&coords, &ids, shape->shape_samp);
if(res != RES_OK) goto error;
exit:
@@ -639,7 +682,11 @@ ssol_mesh_setup
}
}
res = s3d_mesh_setup_indexed_vertices
- (shape->s3d_shape, ntris, get_indices, nverts, attrs, nattribs, data);
+ (shape->shape_rt, ntris, get_indices, nverts, attrs, nattribs, data);
+ if(res != RES_OK) goto error;
+
+ /* 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);
if(res != RES_OK) goto error;
exit:
diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h
@@ -27,18 +27,12 @@ enum shape_type {
struct ssol_shape {
enum shape_type type;
- struct s3d_shape* s3d_shape; /* 3D shape for the mesh */
+ struct s3d_shape* shape_rt; /* Star-3D shape to ray-trace */
+ struct s3d_shape* shape_samp; /* Star-3D shape to sample */
struct ssol_quadric quadric;
struct ssol_device* dev;
ref_T ref;
};
-static FINLINE struct s3d_shape*
-shape_get_s3d_shape(struct ssol_shape* shape)
-{
- ASSERT(shape);
- return shape->s3d_shape;
-}
-
#endif /* SSOL_SHAPE_C_H */
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -54,18 +54,12 @@ get_quadric(const struct ssol_object_instance* instance)
return &instance->object->shape->quadric;
}
-static INLINE struct s3d_scene*
-get_3dscene(const struct ssol_object_instance* instance)
-{
- ASSERT(instance);
- return instance->object->s3d_scn;
-}
-
/*******************************************************************************
* Local functions
******************************************************************************/
res_T
-set_sun_distributions(struct solver_data* data) {
+set_sun_distributions(struct solver_data* data)
+{
struct ssol_spectrum* spectrum;
struct ssol_device* dev;
const struct ssol_sun* sun;
@@ -76,9 +70,9 @@ set_sun_distributions(struct solver_data* data) {
if (!data) return RES_BAD_ARG;
ASSERT(data->scene);
- sun = scene_get_sun(data->scene);
+ sun = data->scene->sun;
ASSERT(sun);
- dev = scene_get_device(data->scene);
+ dev = data->scene->dev;
ASSERT(dev && dev->allocator);
/* first set the spectrum distribution */
res = ssp_ranst_piecewise_linear_create
@@ -126,10 +120,11 @@ error:
}
static void
-release_solver_data(struct solver_data* data) {
+release_solver_data(struct solver_data* data)
+{
ASSERT(data);
- if (data->trace_view) s3d_scene_view_ref_put(data->trace_view);
- if (data->sample_view) s3d_scene_view_ref_put(data->sample_view);
+ if (data->view_rt) s3d_scene_view_ref_put(data->view_rt);
+ if (data->view_samp) s3d_scene_view_ref_put(data->view_samp);
if (data->sun_dir_ran) ranst_sun_dir_ref_put(data->sun_dir_ran);
if (data->sun_spectrum_ran) ssp_ranst_piecewise_linear_ref_put(data->sun_spectrum_ran);
if (data->brdfs) brdf_composite_ref_put(data->brdfs);
@@ -137,64 +132,27 @@ release_solver_data(struct solver_data* data) {
}
res_T
-set_views(struct solver_data* data) {
+set_views(struct solver_data* data)
+{
res_T res = RES_OK;
- struct ssol_scene* scene;
- struct s3d_scene* raytracing_scene;
- struct s3d_scene* sampling_scene;
- struct htable_instance_iterator it, it_end;
- int mirror_found = 0;
+ size_t nshapes_samp = 0;
if (!data) return RES_BAD_ARG;
- scene = data->scene;
- ASSERT(scene);
- raytracing_scene = scene_get_s3d_raytracing_scn(scene);
- ASSERT(raytracing_scene);
- sampling_scene = scene_get_s3d_sampling_scn(scene);
- ASSERT(sampling_scene);
- /* feed sampling s3d_scene */
- S3D(scene_clear(sampling_scene));
- htable_instance_end(&scene->instances, &it_end);
- for (
- htable_instance_begin(&scene->instances, &it);
- !htable_instance_iterator_eq(&it, &it_end);
- htable_instance_iterator_next(&it))
- {
- struct ssol_object_instance* inst;
- struct ssol_material* mat;
- struct ssol_object* object;
- inst = *htable_instance_iterator_data_get(&it);
-
- /* TODO: keep only primary mirrors */
- mat = inst->object->material;
- if (material_get_type(mat) != MATERIAL_MIRROR)
- continue;
- mirror_found = 1;
-
- object = object_instance_get_object(inst);
- switch (object->shape->type) {
- case SHAPE_MESH:
- /* the same mesh is used for sampling and raytracing */
- res = s3d_scene_attach_shape(sampling_scene, inst->s3d_shape);
- break;
- case SHAPE_PUNCHED:
- /* use the carving's mesh for sampling */
- FATAL("TODO\n");
- break;
- default: FATAL("Unreachable code\n"); break;
- }
- if (res != RES_OK) goto error;
- }
- if (!mirror_found) {
+ res = scene_setup_s3d_sampling_scene(data->scene);
+ if(res != RES_OK) goto error;
+
+ S3D(scene_get_shapes_count(data->scene->scn_samp, &nshapes_samp));
+ if(!nshapes_samp) {
+ log_error(data->scene->dev, "%s: no mirror geometry defined.\n", FUNC_NAME);
res = RES_BAD_ARG;
- log_error(scene->dev, "%s: no mirror geometry defined.\n", FUNC_NAME);
goto error;
}
- /* create views from scenes */
- res = s3d_scene_view_create(raytracing_scene, S3D_TRACE, &data->trace_view);
+
+ /* Create views from scenes */
+ res = s3d_scene_view_create(data->scene->scn_rt, S3D_TRACE, &data->view_rt);
if (res != RES_OK) goto error;
- res = s3d_scene_view_create(sampling_scene, S3D_SAMPLE, &data->sample_view);
+ res = s3d_scene_view_create(data->scene->scn_samp, S3D_SAMPLE, &data->view_samp);
if (res != RES_OK) goto error;
exit:
@@ -296,14 +254,10 @@ init_realisation
struct realisation* rs)
{
res_T res = RES_OK;
- struct ssol_device* device;
if (!scene || !rng || !rs) return RES_BAD_ARG;
- device = scene_get_device(scene);
- ASSERT(device && device->allocator);
-
- darray_segment_init(device->allocator, &rs->segments);
+ darray_segment_init(scene->dev->allocator, &rs->segments);
/* set a first size; will grow up with time if needed */
res = darray_segment_resize(&rs->segments, 16);
if (res != RES_OK) goto error;
@@ -318,7 +272,7 @@ init_realisation
/* create sun distributions */
res = set_sun_distributions(&rs->data);
if (res != RES_OK) goto error;
- res = brdf_composite_create(device, &rs->data.brdfs);
+ res = brdf_composite_create(scene->dev, &rs->data.brdfs);
if (res != RES_OK) goto error;
exit:
@@ -336,19 +290,13 @@ release_realisation(struct realisation* rs)
darray_segment_release(&rs->segments);
}
-static struct ssol_material*
-get_material_from_hit(struct ssol_scene* scene, struct s3d_hit* hit) {
- struct ssol_object_instance* instance;
- struct ssol_object* object;
- struct ssol_material* material;
+static INLINE struct ssol_material*
+get_material_from_hit(struct ssol_scene* scene, struct s3d_hit* hit)
+{
+ struct ssol_object_instance* inst;
ASSERT(scene && hit);
- instance = scene_get_object_instance_from_s3d_hit(scene, hit);
- ASSERT(instance);
- object = object_instance_get_object(instance);
- ASSERT(object);
- material = object_get_material(object);
- ASSERT(material);
- return material;
+ inst = *htable_instance_find(&scene->instances_rt, &hit->prim.inst_id);
+ return inst->object->material;
}
static void
@@ -362,36 +310,34 @@ sample_point_on_primary_mirror(struct realisation* rs)
struct s3d_primitive tmp_prim;
data = &rs->data;
- ASSERT(data->rng && data->sample_view && data->scene);
+ ASSERT(data->rng && data->view_samp && data->scene);
/* sample a point on a primary mirror's carving */
r1 = ssp_rng_canonical_float(data->rng);
r2 = ssp_rng_canonical_float(data->rng);
r3 = ssp_rng_canonical_float(data->rng);
- S3D(scene_view_sample(data->sample_view, r1, r2, r3, &tmp_prim, rs->start.uv));
+ S3D(scene_view_sample(data->view_samp, r1, r2, r3, &tmp_prim, rs->start.uv));
S3D(primitive_get_attrib(&tmp_prim, S3D_POSITION, rs->start.uv, &attrib));
CHECK(attrib.type, S3D_FLOAT3);
/* find the solstice shape and project the sampled point on the mirror */
- rs->start.instance =
- *htable_instance_find(&data->scene->instances, &tmp_prim.inst_id);
- ASSERT(rs->start.instance);
- object = object_instance_get_object(rs->start.instance);
- ASSERT(object && object->shape);
- rs->start.material = object_get_material(object);
+ rs->start.instance = *htable_instance_find
+ (&data->scene->instances_samp, &tmp_prim.inst_id);
+ object = rs->start.instance->object;
+ rs->start.material = object->material;
ASSERT(rs->start.material);
switch (object->shape->type) {
- case SHAPE_MESH:
- /* no projection needed */
- f3_set(seg->org, attrib.value);
- /* to avoid self intersect */
- rs->start.primitive = tmp_prim;
- break;
- case SHAPE_PUNCHED:
- /* project the sampled point on the quadric */
- FATAL("TODO\n");
- /* cannot self intersect as the sampled mesh is not raytraced */
- rs->start.primitive = S3D_PRIMITIVE_NULL;
- break;
- default: FATAL("Unreachable code\n"); break;
+ case SHAPE_MESH:
+ /* no projection needed */
+ f3_set(seg->org, attrib.value);
+ /* to avoid self intersect */
+ rs->start.primitive = tmp_prim;
+ break;
+ case SHAPE_PUNCHED:
+ /* project the sampled point on the quadric */
+ FATAL("TODO\n");
+ /* cannot self intersect as the sampled mesh is not raytraced */
+ rs->start.primitive = S3D_PRIMITIVE_NULL;
+ break;
+ default: FATAL("Unreachable code\n"); break;
}
}
@@ -436,7 +382,7 @@ receive_sunlight(struct realisation* rs)
seg->hit.prim = rs->start.primitive;
/* TODO (in s3d): need an occlusion test */
S3D(scene_view_trace_ray
- (rs->data.trace_view, seg->org, seg->dir, seg->range, rs, &seg->hit));
+ (rs->data.view_rt, seg->org, seg->dir, seg->range, rs, &seg->hit));
receives = S3D_HIT_NONE(&seg->hit);
if (!receives) return receives;
@@ -457,7 +403,7 @@ receive_sunlight(struct realisation* rs)
}
/* register success mask (normal orientation has already been checked) */
- rs->success_mask |= object_instance_get_target_mask(rs->start.instance);
+ rs->success_mask |= rs->start.instance->target_mask;
/* restore self intersect information for further visibility test
* (previous call to trace_ray overwrote prim) */
@@ -488,7 +434,7 @@ set_output_pos_and_dir(struct realisation* rs) {
f3_set(seg->org, prev->hit_pos);
material = get_material_from_hit(scene, &prev->hit);
}
- CHECK(material_get_type(material), MATERIAL_MIRROR);
+ CHECK(material->type, MATERIAL_MIRROR);
res = material_shade(material, &rs->data.fragment, rs->freq, rs->data.brdfs);
if (res != RES_OK) {
rs->end = TERM_ERR;
@@ -498,7 +444,7 @@ set_output_pos_and_dir(struct realisation* rs) {
if (fst_segment) {
float sundir_f[3];
- const struct ssol_sun* sun = scene_get_sun(rs->data.scene);
+ const struct ssol_sun* sun = rs->data.scene->sun;
ASSERT(-1 <= rs->start.cos_sun && rs->start.cos_sun <= 0);
f3_set_d3(sundir_f, rs->start.sundir);
seg->weight = sun_get_dni(sun)
@@ -518,13 +464,13 @@ propagate(struct realisation* rs)
/* check if the ray hits something */
S3D(scene_view_trace_ray
- (rs->data.trace_view, seg->org, seg->dir, seg->range, rs, &seg->hit));
+ (rs->data.view_rt, seg->org, seg->dir, seg->range, rs, &seg->hit));
if (S3D_HIT_NONE(&seg->hit)) {
rs->end = TERM_MISSING;
return;
}
/* should not stop on a virtual surface */
- ASSERT(material_get_type(get_material_from_hit(rs->data.scene, &seg->hit))
+ ASSERT(get_material_from_hit(rs->data.scene, &seg->hit)->type
!= MATERIAL_VIRTUAL);
/* offset the impact point and recompute normal if needed */
diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h
@@ -83,14 +83,14 @@ struct solver_data {
struct ssol_scene* scene;
struct ssp_rng* rng;
FILE* out_stream;
- /* the s3d_scene_view used for raytracing */
- struct s3d_scene_view* trace_view;
- /* the s3d_scene_view used for sampling */
- struct s3d_scene_view* sample_view;
- /* the random distributions for sun sampling */
+ /* The s3d_scene_view used for raytracing */
+ struct s3d_scene_view* view_rt;
+ /* The s3d_scene_view used for sampling */
+ struct s3d_scene_view* view_samp;
+ /* The random distributions for sun sampling */
struct ranst_sun_dir* sun_dir_ran;
struct ssp_ranst_piecewise_linear* sun_spectrum_ran;
- /* tmp data used for propagation */
+ /* Tmp data used for propagation */
struct brdf_composite* brdfs;
struct ssol_object_instance* instance;
struct surface_fragment fragment;