commit 385e7b8ece4d1cd4cbb095a7c7826419fcc12c60
parent a89292751726df9f2e0d27d99ec733f2745d5bc8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 20 Jul 2016 14:54:20 +0200
Add the internal hit filter function
The hit filter function is attached to *all* Star-3D shape. It discards
self intersections as well as the hits on a virtual material.
Diffstat:
7 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/src/ssol_c.h b/src/ssol_c.h
@@ -23,6 +23,11 @@
#define SSOL_TO_S3D_NORMAL S3D_ATTRIB_0
#define SSOL_TO_S3D_TEXCOORD S3D_ATTRIB_1
+struct ray_data {
+ struct ssol_scene* scene; /* Scene in which the ray is traced */
+ struct s3d_primitive prim_from; /* Primitive from which the scene start */
+};
+
static FINLINE enum s3d_attrib_usage
ssol_to_s3d_attrib_usage(const enum ssol_attrib_usage usage)
{
@@ -34,5 +39,13 @@ ssol_to_s3d_attrib_usage(const enum ssol_attrib_usage usage)
}
}
+extern LOCAL_SYM int
+hit_filter_function
+ (const struct s3d_hit* hit,
+ const float org[3],
+ const float dir[3],
+ void* ray_data,
+ void* filter_data);
+
#endif /* SSOL_C_H */
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -40,6 +40,13 @@ 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 res_T
material_shade
(const struct ssol_material* mtl,
diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h
@@ -28,4 +28,12 @@ struct ssol_object {
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
@@ -153,4 +153,3 @@ ssol_object_instance_is_attached
return RES_OK;
}
-
diff --git a/src/ssol_object_instance_c.h b/src/ssol_object_instance_c.h
@@ -39,4 +39,19 @@ object_instance_get_s3d_shape(const struct ssol_object_instance* 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)
+{
+ ASSERT(instance);
+ return str_is_empty(&instance->receiver_name)
+ ? NULL : str_cget(&instance->receiver_name);
+}
+
#endif /* SSOL_OBJECT_INSTANCE_C_H */
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -14,9 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "ssol.h"
+#include "ssol_c.h"
#include "ssol_scene_c.h"
#include "ssol_sun_c.h"
#include "ssol_device_c.h"
+#include "ssol_material_c.h"
+#include "ssol_object_c.h"
#include "ssol_object_instance_c.h"
#include <rsys/hash_table.h>
@@ -242,3 +245,35 @@ scene_get_object_instance_from_s3d_hit
return *pinst;
}
+/*******************************************************************************
+ * Local miscellaneous functions
+ ******************************************************************************/
+int
+hit_filter_function
+ (const struct s3d_hit* hit,
+ const float org[3],
+ const float dir[3],
+ void* ray_data,
+ void* filter_data)
+{
+ struct ray_data* rdata;
+ struct ssol_object_instance* instance;
+ struct ssol_material* material;
+ (void)org, (void)dir, (void)filter_data;
+ ASSERT(rdata);
+
+ if(!ray_data) return 0;
+
+ rdata = ray_data;
+ if(S3D_PRIMITIVE_EQ(&hit->prim, &rdata->prim_from))
+ return 1; /* Discard self intersection */
+
+ instance = scene_get_object_instance_from_s3d_hit(rdata->scene, hit);
+ material = object_get_material(object_instance_get_object(instance));
+
+ if(material_get_type(material) == MATERIAL_VIRTUAL)
+ return 1; /* Discard virtual material */
+
+ return 0;
+}
+
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -186,7 +186,10 @@ shape_create
/* create a s3d_scene to hold a mesh */
res = s3d_shape_create_mesh(dev->s3d, &shape->s3d_shape);
if(res != RES_OK) goto error;
-
+ res = s3d_mesh_set_hit_filter_function
+ (shape->s3d_shape, hit_filter_function, NULL);
+ if(res != RES_OK) goto error;
+
SSOL(device_ref_get(dev));
shape->dev = dev;
ref_init(&shape->ref);