commit 47e30a4173e993dfb22839f993feda0351795e80
parent 29dd366b10ff06d751c9d24758f83fa7c024bbb5
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 11 Jan 2018 15:04:45 +0100
Major update of the API
Add the the scene_view concept
Diffstat:
19 files changed, 2167 insertions(+), 1812 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -38,11 +38,12 @@ option(NO_TEST "Disable the test" OFF)
################################################################################
find_package(Embree 2.9 REQUIRED)
find_package(RCMake 0.2.2 REQUIRED)
-find_package(RSys 0.4.0 REQUIRED)
+find_package(RSys 0.6.0 REQUIRED)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
include(rcmake)
include(rcmake_runtime)
+message(STATUS ${EMBREE_INCLUDE_DIRS})
include_directories(${EMBREE_INCLUDE_DIRS} ${RSys_INCLUDE_DIR})
rcmake_append_runtime_dirs(_runtime_dirs RSys Embree)
@@ -51,7 +52,7 @@ rcmake_append_runtime_dirs(_runtime_dirs RSys Embree)
# Configure and define targets
################################################################################
set(VERSION_MAJOR 0)
-set(VERSION_MINOR 0)
+set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
@@ -61,6 +62,7 @@ set(S2D_FILES_SRC
s2d_line_segments.c
s2d_primitive.c
s2d_scene.c
+ s2d_scene_view.c
s2d_shape.c)
set(S2D_FILES_INC_API s2d.h)
set(S2D_FILES_INC
@@ -69,6 +71,7 @@ set(S2D_FILES_INC
s2d_geometry.h
s2d_line_segments.h
s2d_scene_c.h
+ s2d_scene_view_c.h
s2d_shape_c.h)
set(S2D_FILES_DOC COPYING.fr COPYING.en README.md)
@@ -127,13 +130,13 @@ if(NOT NO_TEST)
endfunction()
new_test(test_s2d_device)
- new_test(test_s2d_primitive)
- new_test(test_s2d_sample)
- new_test(test_s2d_scene)
- new_test(test_s2d_session_advanced)
- new_test(test_s2d_shape)
- new_test(test_s2d_trace_ray)
- new_test(test_s2d_trace_ray_3d)
+# new_test(test_s2d_primitive)
+# new_test(test_s2d_sample)
+# new_test(test_s2d_scene)
+# new_test(test_s2d_session_advanced)
+# new_test(test_s2d_shape)
+# new_test(test_s2d_trace_ray)
+# new_test(test_s2d_trace_ray_3d)
endif(NOT NO_TEST)
################################################################################
diff --git a/src/s2d.h b/src/s2d.h
@@ -137,6 +137,12 @@ static const struct s2d_hit S2D_HIT_NULL = S2D_HIT_NULL__;
* intersects a shape or not */
#define S2D_HIT_NONE(Hit) ((Hit)->distance >= FLT_MAX)
+enum s2d_scene_view_flag {
+ S2D_TRACE = BIT(0),
+ S2D_SAMPLE = BIT(1),
+ S2D_GET_PRIMITIVE = BIT(2)
+};
+
/* Filter function data type. One can define such function to discard
* intersections along a ray with respect to user defined criteria, e.g.:
* masked/transparent primitive, etc. Return 0 or the intersection is not
@@ -149,15 +155,10 @@ typedef int
void* ray_data, /* User data submitted on trace ray(s) invocation */
void* filter_data); /* Data defined on the setup of the filter function */
-enum s2d_session_flag {
- S2D_TRACE = BIT(0),
- S2D_SAMPLE = BIT(1),
- S2D_GET_PRIMITIVE = BIT(2)
-};
-
/* Forward declaration of s2d opaque data types */
struct s2d_device;
struct s2d_scene;
+struct s2d_scene_view;
struct s2d_shape;
/* Forward declaration of external data types */
@@ -200,9 +201,8 @@ S2D_API res_T
s2d_scene_ref_put
(struct s2d_scene* scn);
-/* Attach the shape to the scene. If the shape is already attached to the same
- * or another scene, nothing is performed and a RES_BAD_ARG error is returned.
- * On success, the scene gets a reference onto the attached shape */
+/* Attach the shape to the scene. On success, the scene gets a reference onto
+ * the attached shape */
S2D_API res_T
s2d_scene_attach_shape
(struct s2d_scene* scn,
@@ -221,34 +221,42 @@ S2D_API res_T
s2d_scene_clear
(struct s2d_scene* scn);
-/* Synchronize the scene geometry with the geometry of its attached shapes. If
- * a s2d_scene_begin_session is already active on `scn' or one of its attached
- * instance a RES_BAD_OP error is returned. On success neither another begin
- * session nor a clear or shape_detach can be invoked on `scn' and its attached
- * instances until s2d_scene_end_session is called. */
+/* Retrieve the device from which the scene was created */
S2D_API res_T
-s2d_scene_begin_session
+s2d_scene_get_device
(struct s2d_scene* scn,
- const int session_mask); /* Combination of s2d_session_flag */
+ struct s2d_device** dev);
-/* End the session on the `scn' */
+/*******************************************************************************
+ * Scene view API - State of the scene geometry
+ ******************************************************************************/
S2D_API res_T
-s2d_scene_end_session
- (struct s2d_scene* scn);
+s2d_scene_view_create
+ (struct s2d_scene* scn,
+ const int mask, /* Combination of s2d_scene_view_flag */
+ struct s2d_scene_view** scnview);
S2D_API res_T
-s2d_scene_get_session_mask
- (struct s2d_scene* scn,
+s2d_scene_view_ref_get
+ (struct s2d_scene_view* scnview);
+
+S2D_API res_T
+s2d_scene_view_ref_put
+ (struct s2d_scene_view* scnview);
+
+S2D_API res_T
+s2d_scene_view_get_mask
+ (struct s2d_scene_view* scnview,
int* mask);
/* Trace a ray into the `scn' and return the closest intersection. The ray is
* defined by `origin' + t*`direction' = 0 with t in [`range[0]', `range[1]').
* Note that if range is degenerated (i.e. `range[0]' >= `range[1]') then the
- * ray is not traced and `hit' is set to S2D_HIT_NULL. Can be called only if an
- * S2D_TRACE session is active on `scn' */
+ * ray is not traced and `hit' is set to S2D_HIT_NULL. Can be called only if
+ * the scnview was created with the S2D_TRACE flag. */
S2D_API res_T
-s2d_scene_trace_ray
- (struct s2d_scene* scn,
+s2d_scene_view_trace_ray
+ (struct s2d_scene_view* scnview,
const float origin[2], /* Ray origin */
const float direction[2], /* Ray direction. Must be normalized */
const float range[2], /* In [0, INF)^2 */
@@ -262,10 +270,10 @@ s2d_scene_trace_ray
* as the potential hit distance are expressed with respect to the 3D
* direction. Note that if range is degenerated (i.e. `range[0]' >=
* `range[1]') then the ray is not traced and `hit' is set to S2D_HIT_NULL. Can
- * be called only if an S2D_TRACE session is active on `scn'. */
+ * be called only if te scnview was created with the S2D_TRACE flag. */
S2D_API res_T
-s2d_scene_trace_ray_3d
- (struct s2d_scene* scn,
+s2d_scene_view_trace_ray_3d
+ (struct s2d_scene_view* scnview,
const float origin[3],
const float dir[3],
const float range[2],
@@ -273,60 +281,52 @@ s2d_scene_trace_ray_3d
struct s2d_hit* hit);
/* Uniformly sample the scene and returned the sampled primitive and its sample
- * position. Can be called only if a S2D_SAMPLE session is active on `scn'*/
+ * position. CCan be called only if the scnview was created with the
+ * S2D_SAMPLE flag */
S2D_API res_T
-s2d_scene_sample
- (struct s2d_scene* scn,
+s2d_scene_view_sample
+ (struct s2d_scene_view* scnview,
const float u, const float v, /* Random numbers in [0, 1) */
struct s2d_primitive* primitive, /* Sampled primitive */
float* s); /* Sampled parametric coordinates on the primitive */
-/* Retrieve a primitive from the scene. Can be called only if a
- * S2D_GET_PRIMITIVE session is active on `scn' */
+/* Retrieve a primitive from the scene. Can be called only if the scnview was
+ * created with the S2D_GET_PRIMITIVE flag */
S2D_API res_T
-s2d_scene_get_primitive
- (struct s2d_scene* scn,
+s2d_scene_view_get_primitive
+ (struct s2d_scene* scnview,
const unsigned iprim, /* in [0, #prims) */
struct s2d_primitive* prim);
-/* Retrieve the number of scene primitives. Can be called only if a sessio is
- * active on `scn' */
+/* Retrieve the number of scene primitives. Can be called only if the scnview
+ * was created with the S2D_GET_PRIMITIVE flag */
S2D_API res_T
-s2d_scene_primitives_count
- (struct s2d_scene* scn,
+s2d_scene_view_primitives_count
+ (struct s2d_scene_view* scnview,
size_t* primitives_count);
-/* Compute the overall length of the shape contours. Return RES_BAD_ARG if no
- * session is active on scn. */
+/* Compute the overall length of the shape contours */
S2D_API res_T
-s2d_scene_compute_contour_length
- (struct s2d_scene* scn,
+s2d_scene_view_compute_contour_length
+ (struct s2d_scene_view* scnview,
float* length);
/* This function assumes that the scene defines a closed polygon and that the
- * normals point into the polygon. Return RES_BAD_ARG if no session is active
- * on scn */
+ * normals point into the polygon. */
S2D_API res_T
-s2d_scene_compute_area
- (struct s2d_scene* scn,
+s2d_scene_view_compute_area
+ (struct s2d_scene_view* scnview,
float* area);
-/* Retrieve the Axis Aligned Bounding Box of the scene. Return RES_BAD_ARG if
- * no session is active on scn */
+/* Retrieve the Axis Aligned Bounding Box of the scene. */
S2D_API res_T
-s2d_scene_get_aabb
- (struct s2d_scene* scn,
- float lower[3], /* AABB lower bound */
- float upper[3]); /* AABB upper bound */
-
-/* Retrieve the device from which the scene was created */
-S2D_API res_T
-s2d_scene_get_device
- (struct s2d_scene* scn,
- struct s2d_device** dev);
+s2d_scene_view_get_aabb
+ (struct s2d_scene_view* scnview,
+ float lower[2], /* AABB lower bound */
+ float upper[2]); /* AABB upper bound */
/*******************************************************************************
- * Shape API - define a 2D contour that can be attached to *one* scene.
+ * Shape API - define a 2D contour that can be attached to a scene.
******************************************************************************/
S2D_API res_T
s2d_shape_create_line_segments
diff --git a/src/s2d_device.c b/src/s2d_device.c
@@ -35,6 +35,21 @@
/*******************************************************************************
* Helper functions
******************************************************************************/
+static INLINE void
+log_msg
+ (struct s2d_device* dev,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(dev && msg);
+ if(dev->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(dev->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
static void
device_release(ref_T* ref)
{
@@ -113,12 +128,20 @@ log_error(struct s2d_device* dev, const char* msg, ...)
{
va_list vargs_list;
ASSERT(dev && msg);
- if(dev->verbose) {
- res_T res; (void)res;
- va_start(vargs_list, msg);
- res = logger_vprint(dev->logger, LOG_ERROR, msg, vargs_list);
- ASSERT(res == RES_OK);
- va_end(vargs_list);
- }
+
+ va_start(vargs_list, msg);
+ log_msg(dev, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warning(struct s2d_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(dev, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
}
diff --git a/src/s2d_device_c.h b/src/s2d_device_c.h
@@ -50,6 +50,8 @@ struct s2d_device {
ref_T ref;
};
+/* Conditionally log a message on the LOG_ERROR stream of the device logger,
+ * with respect to the device verbose flag */
extern LOCAL_SYM void
log_error
(struct s2d_device* dev,
@@ -60,5 +62,17 @@ log_error
#endif
;
+/* Conditionally log a message on the LOG_WARNING stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_warning
+ (struct s2d_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
#endif /* S2D_DEVICE_C_H */
diff --git a/src/s2d_geometry.c b/src/s2d_geometry.c
@@ -69,6 +69,7 @@ geometry_create(struct s2d_device* dev, struct geometry** out_geom)
geom->dev = dev;
geom->name = S2D_INVALID_ID;
geom->irtc = RTC_INVALID_GEOMETRY_ID;
+ geom->embree_outdated_mask = 0;
geom->flip_contour = 0;
geom->is_enabled = 1;
geom->lines = NULL;
diff --git a/src/s2d_geometry.h b/src/s2d_geometry.h
@@ -33,11 +33,21 @@
#include "s2d_backend.h"
#include <rsys/ref_count.h>
+enum embree_attrib {
+ EMBREE_ENABLE = BIT(0),
+ EMBREE_FILTER_FUNCTION = BIT(1),
+ EMBREE_INDICES = BIT(2),
+ EMBREE_VERTICES = BIT(4)
+};
+
/* Backend geometry */
struct geometry {
unsigned name; /* Client side identifier */
unsigned irtc; /* Backend identifier */
unsigned scene_prim_id_offset; /* Offset from local to scene prim_id */
+
+ int embree_outdated_mask; /* Combination of embree_attrib */
+
char flip_contour; /* Is the geometry contour flipped? */
char is_enabled; /* Is the geometry enabled? */
diff --git a/src/s2d_scene.c b/src/s2d_scene.c
@@ -28,542 +28,33 @@
#include "s2d.h"
#include "s2d_device_c.h"
-#include "s2d_line_segments.h"
-#include "s2d_geometry.h"
#include "s2d_scene_c.h"
+#include "s2d_scene_view_c.h"
#include "s2d_shape_c.h"
-#include <rsys/logger.h>
-#include <rsys/float2.h>
-#include <rsys/float3.h>
+#include <rsys/list.h>
#include <rsys/mem_allocator.h>
-#include <algorithm>
-
-struct ray_extended : public RTCRay {
- struct s2d_scene* scene;
- void* data; /* User defined data */
-};
-
/*******************************************************************************
* Helper functions
******************************************************************************/
-static INLINE void
-hit_setup(struct s2d_scene* scn, const RTCRay* ray, struct s2d_hit* hit)
-{
- struct geometry* geom;
-
- if((unsigned)ray->geomID == RTC_INVALID_GEOMETRY_ID) { /* No hit */
- *hit = S2D_HIT_NULL;
- return;
- }
- ASSERT(eq_epsf(ray->Ng[2], 0.f, 1.e-6f));
- ASSERT((unsigned)ray->instID == RTC_INVALID_GEOMETRY_ID);
- ASSERT((unsigned)ray->geomID < darray_geom_size_get(&scn->embree2geoms));
-
- geom = darray_geom_data_get(&scn->embree2geoms)[ray->geomID];
- ASSERT(geom);
-
- hit->prim.mesh__ = geom;
- hit->prim.prim_id = ray->primID;
- hit->prim.geom_id = geom->name;
- hit->prim.scene_prim_id = hit->prim.prim_id + geom->scene_prim_id_offset;
- hit->normal[0] = ray->Ng[0];
- hit->normal[1] = ray->Ng[1];
- hit->distance = ray->tfar;
- /* The Embree "v" parametric coordinate of the extruded quad corresponds to
- * the edge parametric coordinate */
- hit->u = ray->v;
-
- if(geom->flip_contour)
- f2_minus(hit->normal, hit->normal);
-}
-
-static void
-filter_wrapper(void* user_ptr, RTCRay& ray)
-{
- struct s2d_hit hit;
- struct hit_filter* filter = (struct hit_filter*)user_ptr;
- struct ray_extended* ray_ex = static_cast<struct ray_extended*>(&ray);
-
- hit_setup(ray_ex->scene, &ray, &hit);
- if(filter->func(&hit, ray_ex->org, ray_ex->dir, ray_ex->data, filter->data)) {
- /* Discard the intersection */
- ray.geomID = RTC_INVALID_GEOMETRY_ID;
- }
-}
-
-static void
-scene_geometry_flush_enable_state
- (struct s2d_scene* scn,
- struct geometry* geom,
- const struct s2d_shape* shape)
-{
- ASSERT(scn && geom && shape && geom->irtc != RTC_INVALID_GEOMETRY_ID);
- if(geom->is_enabled == shape->is_enabled)
- return;
-
- geom->is_enabled = shape->is_enabled;
- if(geom->is_enabled) {
- rtcEnable(scn->rtc_scn, geom->irtc);
- } else {
- rtcDisable(scn->rtc_scn, geom->irtc);
- }
- scn->is_rtc_scn_outdated = 1;
-}
-
-static void
-scene_geometry_flush_filter_function
- (struct s2d_scene* scn,
- struct geometry* geom,
- const struct s2d_shape* shape)
-{
- ASSERT(scn && geom && shape && geom->irtc != RTC_INVALID_GEOMETRY_ID);
-
- if(geom->lines->filter.func == shape->lines->filter.func
- && geom->lines->filter.data == shape->lines->filter.data)
- return; /* Up to date */
-
- geom->lines->filter = shape->lines->filter;
- if(!geom->lines->filter.func) {
- rtcSetIntersectionFilterFunction(scn->rtc_scn, geom->irtc, NULL);
- } else {
- rtcSetIntersectionFilterFunction(scn->rtc_scn, geom->irtc, filter_wrapper);
- rtcSetUserData(scn->rtc_scn, geom->irtc, &geom->lines->filter);
- }
- scn->is_rtc_scn_outdated = 1;
-}
-
-
-static res_T
-scene_register_geometry(struct s2d_scene* scn, struct geometry* geom)
-{
- ASSERT(scn && geom);
-
- /* Create the embree geometry if it is not valid */
- if(geom->irtc == RTC_INVALID_GEOMETRY_ID) {
- geom->irtc = rtcNewQuadMesh
- (scn->rtc_scn,
- RTC_GEOMETRY_DYNAMIC,
- line_segments_get_nsegments(geom->lines),
- line_segments_get_nverts(geom->lines)*2/*Lines are extruded as quads*/);
- if(geom->irtc == RTC_INVALID_GEOMETRY_ID)
- return RES_UNKNOWN_ERR;
- scn->is_rtc_scn_outdated = 1;
- }
- if(geom->irtc >= darray_geom_size_get(&scn->embree2geoms)) {
- const res_T res = darray_geom_resize(&scn->embree2geoms, geom->irtc + 1);
- if(res != RES_OK) {
- rtcDeleteGeometry(scn->rtc_scn, geom->irtc);
- geom->irtc = RTC_INVALID_GEOMETRY_ID;
- return res;
- }
- }
- geometry_ref_get(geom);
- darray_geom_data_get(&scn->embree2geoms)[geom->irtc] = geom;
- return RES_OK;
-}
-
-static void
-scene_geometry_flush_positions(struct s2d_scene* scn, struct geometry* geom)
-{
- size_t nverts;
- size_t i;
- float* verts;
- float* rtc_verts;
- ASSERT(scn && geom && geom->irtc != RTC_INVALID_GEOMETRY_ID);
-
- /* Extrude segment vertices as quad whose Z is [-1, 1] */
- nverts = line_segments_get_nverts(geom->lines);
- verts = line_segments_get_attr(geom->lines, S2D_POSITION);
- rtc_verts = (float*)rtcMapBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
- FOR_EACH(i, 0, nverts) {
- size_t ivert = i*2/*#coords per vertex*/;
- size_t rtc_ivert = i*4/*#coords + padding*/ * 2/*#rtc vertices per line vertex*/;
-
- rtc_verts[rtc_ivert + 0] = verts[ivert + 0];
- rtc_verts[rtc_ivert + 1] = verts[ivert + 1];
- rtc_verts[rtc_ivert + 2] = 1.f;
- rtc_verts[rtc_ivert + 3] = 0.f; /* Padding */
-
- rtc_verts[rtc_ivert + 4] = verts[ivert + 0];
- rtc_verts[rtc_ivert + 5] = verts[ivert + 1];
- rtc_verts[rtc_ivert + 6] = -1.f;
- rtc_verts[rtc_ivert + 7] = 0.f; /* Padding */
- }
- rtcUnmapBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
-}
-
-static void
-scene_geometry_flush_indices(struct s2d_scene* scn, struct geometry* geom)
-{
- size_t nsegs;
- size_t i;
- uint32_t* ids;
- uint32_t* rtc_ids;
- ASSERT(scn && geom && geom->irtc != RTC_INVALID_GEOMETRY_ID);
-
- /* Define the index of the extruded line segments */
- nsegs = line_segments_get_nsegments(geom->lines);
- ids = line_segments_get_ids(geom->lines);
- rtc_ids = (uint32_t*)rtcMapBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
- FOR_EACH(i, 0, nsegs) {
- size_t id = i*2/*#ids per segment*/;
- size_t rtc_id = i*4/*#ids per quad*/;
-
- rtc_ids[rtc_id + 0] = ids[id + 0] * 2/*#rtc vertices per line vertex*/ + 1;
- rtc_ids[rtc_id + 1] = ids[id + 0] * 2/*#rtc vertices per line vertex*/ + 0;
- rtc_ids[rtc_id + 2] = ids[id + 1] * 2/*#rtc vertices per line vertex*/ + 0;
- rtc_ids[rtc_id + 3] = ids[id + 1] * 2/*#rtc vertices per line vertex*/ + 1;
- }
- rtcUnmapBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
-}
-
-static res_T
-scene_register_line_segments
- (struct s2d_scene* scn,
- struct s2d_shape* shape)
-{
- struct geometry** pgeom = NULL;
- struct geometry* geom = NULL;
- size_t iattr;
- char upd_pos, upd_ids;
-
- res_T res = RES_OK;
- ASSERT(scn && shape);
-
- /* Retrieved the cached geometry */
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- if(pgeom) {
- geom = *pgeom;
- } else {
- res = geometry_create(scn->dev, &geom);
- if(res != RES_OK) goto error;
- res = line_segments_create(scn->dev, &geom->lines);
- if(res != RES_OK) goto error;
- res = htable_geom_set(&scn->cached_geoms, &shape, &geom);
- if(res != RES_OK) goto error;
- geom->name = shape->id.index;
- }
-
- /* Discard the geometries that are not geometrically valid */
- if(!shape->lines->indices || !shape->lines->attribs[S2D_POSITION]) {
- if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
- rtcDeleteGeometry(scn->rtc_scn, geom->irtc);
- geom->irtc = RTC_INVALID_GEOMETRY_ID;
- scn->is_rtc_scn_outdated = 1;
- }
- line_segments_clear(geom->lines);
- goto exit;
- }
-
- /* Define which geometry buffers were updated */
- upd_ids = geom->lines->indices != shape->lines->indices
- || ((shape->lines->update_mask & INDEX_BUFFER) != 0);
- upd_pos = geom->lines->attribs[S2D_POSITION] != shape->lines->attribs[S2D_POSITION]
- || ((shape->lines->update_mask & VERTEX_BUFFER) != 0);
-
- /* Get a reference onto the shape lines segments indices */
- if(geom->lines->indices != shape->lines->indices) {
- if(geom->lines->indices) { /* Release previous indices of the geometry */
- index_buffer_ref_put(geom->lines->indices);
- geom->lines->indices = NULL;
- }
- ASSERT(shape->lines->indices);
- index_buffer_ref_get(shape->lines->indices);
- geom->lines->indices = shape->lines->indices;
- }
-
- /* Get a reference onto the shape line segments attribs */
- FOR_EACH(iattr, 0, S2D_ATTRIBS_COUNT__) {
- if(geom->lines->attribs[iattr] == shape->lines->attribs[iattr])
- continue;
-
- if(geom->lines->attribs[iattr]) { /* Release the previous geometry attribs */
- vertex_buffer_ref_put(geom->lines->attribs[iattr]);
- geom->lines->attribs[iattr] = NULL;
- }
-
- if(!shape->lines->attribs[iattr]) continue;
-
- vertex_buffer_ref_get(shape->lines->attribs[iattr]);
- geom->lines->attribs[iattr] = shape->lines->attribs[iattr];
- geom->lines->attribs_type[iattr] = shape->lines->attribs_type[iattr];
- }
-
- /* The line segments were resize => the Embree geometry is no more valid */
- if(shape->lines->resize_mask && geom->irtc != RTC_INVALID_GEOMETRY_ID) {
- rtcDeleteGeometry(scn->rtc_scn, geom->irtc);
- geom->irtc = RTC_INVALID_GEOMETRY_ID;
- scn->is_rtc_scn_outdated = 1;
- }
-
- res = scene_register_geometry(scn, geom);
- if(res != RES_OK) goto error;
-
- if(upd_pos) { /* Update the Embree vertex buffer if necessary */
- scene_geometry_flush_positions(scn, geom);
- }
- if(upd_ids) { /* Update the Embree index buffer if necessary */
- scene_geometry_flush_indices(scn, geom);
- }
-
- /* Flush the remaining geometry states */
- scene_geometry_flush_enable_state(scn, geom, shape);
- scene_geometry_flush_filter_function(scn, geom, shape);
- geom->flip_contour = shape->flip_contour;
-
- /* Flush the shape line segments states */
- shape->lines->resize_mask = 0;
- shape->lines->update_mask = 0;
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static void
-scene_session_clear(struct s2d_scene* scn)
-{
- struct geometry** pgeoms;
- size_t ngeoms, i;
- ASSERT(scn);
-
- ngeoms = darray_geom_size_get(&scn->embree2geoms);
- pgeoms = darray_geom_data_get(&scn->embree2geoms);
- FOR_EACH(i, 0, ngeoms) {
- if(!pgeoms[i]) continue;
- geometry_ref_put(pgeoms[i]);
- }
- darray_geom_clear(&scn->embree2geoms);
- scn->session_mask = 0;
-}
-
-static res_T
-scene_detach_shape
- (struct s2d_scene* scn, struct s2d_shape* shape, const char* caller_name)
-{
- struct geometry** pgeom;
- ASSERT(scn && shape && !is_list_empty(&shape->scene_attachment));
-
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- if(pgeom) { /* Remove the cached geometry */
- struct geometry* geom = *pgeom;
-
- if(scn->session_mask != 0) {
- log_error(scn->dev,
- "%s: Cannot detach a shape currently in used in a scene session.\n",
- caller_name);
- return RES_BAD_OP;
- }
- if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
- rtcDeleteGeometry(scn->rtc_scn, geom->irtc);
- geom->irtc = RTC_INVALID_GEOMETRY_ID;
- scn->is_rtc_scn_outdated = 1;
- }
- geometry_ref_put(geom);
- htable_geom_erase(&scn->cached_geoms, &shape);
- }
- list_del(&shape->scene_attachment);
-
- S2D(shape_ref_put(shape));
- return RES_OK;
-}
-
-static res_T
-scene_compute_cdf(struct s2d_scene* scn)
-{
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
- size_t len;
- float length = 0.f;
- res_T res = RES_OK;
- ASSERT(scn);
-
- darray_fltui_clear(&scn->cdf);
-
- LIST_FOR_EACH(node, &scn->shapes) {
-
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
-
- if(!geom->is_enabled) continue;
-
- res = line_segments_compute_cdf(geom->lines);
- if(res != RES_OK) goto error;
- len = darray_float_size_get(&geom->lines->cdf);
-
- if(len) { /* The geometry has valid segments */
- struct fltui fltui;
- length += darray_float_cdata_get(&geom->lines->cdf)[len - 1];
- fltui.ui = geom->irtc;
- fltui.flt = length;
- res = darray_fltui_push_back(&scn->cdf, &fltui);
- if(res != RES_OK) goto error;
- }
- }
-
-exit:
- return res;
-error:
- darray_fltui_clear(&scn->cdf);
- goto exit;
-}
-
-static FINLINE bool
-operator < (const struct fltui& it, const float val)
-{
- /* This operator is used by the std::lower_bound algorithm that returns an
- * iterator to the first element that is not less than val while one expect
- * an iterator on the first element that is not less *or equal* than val.
- * That's why we use <= rather than < */
- return it.flt <= val;
-}
-
-static FINLINE bool
-operator < (const struct nprims_cdf& it, const size_t iprim)
-{
- /* This operator is used by the std::lower_bound algorithm that returns an
- * iterator to the first element that is not less than iprim while one expect
- * an iterator on the first element that is not less *or equal* than iprim.
- * That's why we use <= rather than < */
- return it.nprims <= iprim;
-}
-
-static res_T
-scene_compute_nprims_cdf(struct s2d_scene* scn, const char store_cdf)
-{
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
- size_t len;
- unsigned nprims;
- res_T res = RES_OK;
- ASSERT(scn);
-
- darray_nprims_cdf_clear(&scn->nprims_cdf);
-
- nprims = 0;
- LIST_FOR_EACH(node, &scn->shapes) {
- struct nprims_cdf cdf;
-
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
-
- if(!geom->is_enabled) continue;
-
- geom->scene_prim_id_offset = nprims;
- len = line_segments_get_nsegments(geom->lines);
- nprims += (unsigned)len;
-
- if(store_cdf && len) {
- cdf.nprims = nprims;
- cdf.irtc = geom->irtc;
- res = darray_nprims_cdf_push_back(&scn->nprims_cdf, &cdf);
- if(res != RES_OK) goto error;
- }
- }
-
-exit:
- return res;
-error:
- darray_nprims_cdf_clear(&scn->nprims_cdf);
- goto exit;
-}
-
-static void
-scene_compute_aabb(struct s2d_scene* scn)
-{
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
- float lower[2], upper[2];
-
- f2_splat(scn->lower, FLT_MAX);
- f2_splat(scn->upper,-FLT_MAX);
-
- LIST_FOR_EACH(node, &scn->shapes) {
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
-
- if(!geom->is_enabled) continue;
-
- line_segments_compute_aabb(geom->lines, lower, upper);
- f2_min(scn->lower, scn->lower, lower);
- f2_max(scn->upper, scn->upper, upper);
- }
-}
-
-static res_T
-scene_sync
- (struct s2d_scene* scn, const int session_mask, const char* caller_name)
-{
- struct list_node* node;
- struct s2d_shape* shape;
- res_T res = RES_OK;
- ASSERT(scn);
-
- if(scn->session_mask != 0) {
- log_error(scn->dev,
- "%s: Invalid operation. The scene cannot be synced several times.\n",
- caller_name);
- res = RES_BAD_OP;
- goto error;
- }
-
- LIST_FOR_EACH(node, &scn->shapes) {
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- res = scene_register_line_segments(scn, shape);
- if(res != RES_OK) goto error;
- }
-
- if((session_mask & S2D_SAMPLE) != 0) {
- res = scene_compute_cdf(scn);
- if(res != RES_OK) goto error;
- }
-
- res = scene_compute_nprims_cdf(scn, (session_mask & S2D_GET_PRIMITIVE)!=0);
- if(res != RES_OK) goto error;
-
- if((session_mask & S2D_TRACE) != 0 && scn->is_rtc_scn_outdated) {
- rtcCommit(scn->rtc_scn);
- scn->is_rtc_scn_outdated = 0;
- }
- scn->session_mask = session_mask;
- scene_compute_aabb(scn);
-
-exit:
- return res;
-error:
- goto exit;
-}
-
static void
scene_release(ref_T* ref)
{
struct s2d_scene* scn;
struct s2d_device* dev;
+ struct list_node* node;
+ struct list_node* tmp;
+
ASSERT(ref);
scn = CONTAINER_OF(ref, struct s2d_scene, ref);
- S2D(scene_clear(scn));
dev = scn->dev;
- scene_session_clear(scn);
- if(scn->rtc_scn) rtcDeleteScene(scn->rtc_scn);
- htable_geom_release(&scn->cached_geoms);
- darray_geom_release(&scn->embree2geoms);
- darray_fltui_release(&scn->cdf);
- darray_nprims_cdf_release(&scn->nprims_cdf);
+
+ LIST_FOR_EACH_SAFE(node, tmp, &scn->scnviews) {
+ scene_view_destroy(CONTAINER_OF(node, struct s2d_scene_view, node));
+ }
+ S2D(scene_clear(scn));
+ htable_shape_release(&scn->shapes);
MEM_RM(dev->allocator, scn);
S2D(device_ref_put(dev));
}
@@ -575,13 +66,6 @@ res_T
s2d_scene_create(struct s2d_device* dev, struct s2d_scene** out_scn)
{
struct s2d_scene* scn = NULL;
- const RTCSceneFlags rtc_scene_mask =
- RTC_SCENE_DYNAMIC
- | RTC_SCENE_INCOHERENT
- | RTC_SCENE_ROBUST;
- const RTCAlgorithmFlags rtc_intersect_mask =
- RTC_INTERSECT1
- | RTC_INTERSECT4;
res_T res = RES_OK;
if(!dev || !out_scn) {
@@ -595,22 +79,12 @@ s2d_scene_create(struct s2d_device* dev, struct s2d_scene** out_scn)
res = RES_MEM_ERR;
goto error;
}
- list_init(&scn->shapes);
- htable_geom_init(dev->allocator, &scn->cached_geoms);
- darray_geom_init(dev->allocator, &scn->embree2geoms);
- darray_fltui_init(dev->allocator, &scn->cdf);
- darray_nprims_cdf_init(dev->allocator, &scn->nprims_cdf);
+ htable_shape_init(dev->allocator, &scn->shapes);
+ SIG_INIT(&scn->sig_shape_detach);
+ list_init(&scn->scnviews);
ref_init(&scn->ref);
S2D(device_ref_get(dev));
scn->dev = dev;
- scn->session_mask = 0;
- scn->rtc_scn = rtcDeviceNewScene(dev->rtc, rtc_scene_mask, rtc_intersect_mask);
- if(!scn->rtc_scn) {
- res = RES_MEM_ERR;
- goto error;
- }
- f2_splat(scn->lower, FLT_MAX);
- f2_splat(scn->upper,-FLT_MAX);
exit:
if(out_scn) *out_scn = scn;
@@ -642,498 +116,88 @@ s2d_scene_ref_put(struct s2d_scene* scn)
res_T
s2d_scene_attach_shape(struct s2d_scene* scn, struct s2d_shape* shape)
{
- if(!scn || !shape)
- return RES_BAD_ARG;
- if(!is_list_empty(&shape->scene_attachment)) {
- log_error(scn->dev,
- "%s: Cannot attach a shape that is already attached to a scene.\n",
- FUNC_NAME);
- return RES_BAD_ARG;
- }
- list_add_tail(&scn->shapes, &shape->scene_attachment);
- S2D(shape_ref_get(shape));
- return RES_OK;
-}
-
-res_T
-s2d_scene_detach_shape(struct s2d_scene* scn, struct s2d_shape* shape)
-{
+ unsigned shape_id;
res_T res = RES_OK;
- char is_attached;
-
-
- if(!scn || !shape) return RES_BAD_ARG;
- if(!(S2D(shape_is_attached(shape, &is_attached)), is_attached)) {
- log_error(scn->dev,
- "%s: The shape to detach is not attached to any scene.\n",
- FUNC_NAME);
- return RES_BAD_ARG;
- }
-#ifndef NDEBUG
- { /* Check that the shape is attached to `scn' */
- struct list_node* node;
- char is_found = 0;
- LIST_FOR_EACH(node, &scn->shapes) {
- if(node == &shape->scene_attachment) {
- is_found = 1;
- break;
- }
- }
- ASSERT(is_found);
- }
-#endif
- res = scene_detach_shape(scn, shape, FUNC_NAME);
- if(res != RES_OK) return res;
-
- return RES_OK;
-}
-
-res_T
-s2d_scene_clear(struct s2d_scene* scn)
-{
- struct list_node* node, *tmp;
- if(!scn) return RES_BAD_ARG;
- if(scn->session_mask != 0) {
- log_error(scn->dev,
- "%s: Invalid operation. A session is active onto the scene.\n",
- FUNC_NAME);
- return RES_BAD_OP;
- }
- LIST_FOR_EACH_SAFE(node, tmp, &scn->shapes) {
- struct s2d_shape* shape = CONTAINER_OF
- (node, struct s2d_shape, scene_attachment);
- res_T res = scene_detach_shape(scn, shape, FUNC_NAME);
- ASSERT(res == RES_OK); (void)res;
- }
- return RES_OK;
-}
-res_T
-s2d_scene_begin_session(struct s2d_scene* scn, const int session_mask)
-{
- if(!scn) return RES_BAD_ARG;
- if(!(session_mask & S2D_TRACE)
- && !(session_mask & S2D_SAMPLE)
- && !(session_mask & S2D_GET_PRIMITIVE)) {
- log_error(scn->dev,
- "%s: Invalid session mask. No valid session is defined.\n",
- FUNC_NAME);
+ if(!scn || !shape) {
return RES_BAD_ARG;
}
- return scene_sync(scn, session_mask, FUNC_NAME);
-}
-res_T
-s2d_scene_end_session(struct s2d_scene* scn)
-{
- if(!scn)
- return RES_BAD_ARG;
- if(!scn->session_mask) {
- log_error(scn->dev,
- "%s: Cannot end session. No session is currently active onto the scene.\n",
- FUNC_NAME);
- return RES_BAD_ARG;
- }
- scene_session_clear(scn);
- return RES_OK;
-}
-
-res_T
-s2d_scene_get_session_mask(struct s2d_scene* scn, int* session_mask)
-{
- if(!scn || !session_mask)
- return RES_BAD_ARG;
- *session_mask = scn->session_mask;
- return RES_OK;
-}
-
-res_T
-s2d_scene_trace_ray
- (struct s2d_scene* scn,
- const float org[2],
- const float dir[2],
- const float range[2],
- void* ray_data,
- struct s2d_hit* hit)
-{
- struct ray_extended ray_ex;
-
- if(!scn || !org || !dir || !range || !hit)
- return RES_BAD_ARG;
- if(!f2_is_normalized(dir)) {
- log_error(scn->dev,
- "%s: The ray direction should be normalized.\n", FUNC_NAME);
- return RES_BAD_ARG;
- }
- if((scn->session_mask & S2D_TRACE) == 0) {
- log_error(scn->dev,
- "%s: A S2D_TRACE session should be active onto the submitted scene.\n",
- FUNC_NAME);
- return RES_BAD_OP;
- }
- if(range[0] > range[1]) { /* Degenerated range <=> disabled ray */
- *hit = S2D_HIT_NULL;
+ S2D(shape_get_id(shape, &shape_id));
+ if(htable_shape_find(&scn->shapes, &shape_id) != NULL) {
+ log_warning(scn->dev,
+ "%s: the shape is already attached to the scene.\n", FUNC_NAME);
return RES_OK;
}
- f3(ray_ex.org, org[0], org[1], 0.f);
- f3(ray_ex.dir, dir[0], dir[1], 0.f);
- ray_ex.tnear = range[0];
- ray_ex.tfar = range[1];
- ray_ex.geomID = RTC_INVALID_GEOMETRY_ID;
- ray_ex.primID = RTC_INVALID_GEOMETRY_ID;
- ray_ex.instID = RTC_INVALID_GEOMETRY_ID;
- ray_ex.mask = 0xFFFFFFFF;
- ray_ex.time = 0.f;
- ray_ex.scene = scn;
- ray_ex.data = ray_data;
-
- rtcIntersect(scn->rtc_scn, ray_ex);
- hit_setup(scn, &ray_ex, hit);
-
- return RES_OK;
-}
-
-res_T
-s2d_scene_trace_ray_3d
- (struct s2d_scene* scn,
- const float org[3],
- const float dir[3],
- const float range[2],
- void* ray_data,
- struct s2d_hit* hit)
-{
- float range_2d[2];
- float dir_2d[3] = {0.f, 0.f, 0.f};
- float dot;
- res_T res = RES_OK;
-
- if(!dir || !range || !hit) {
- return RES_BAD_ARG;
- }
- if(!f3_is_normalized(dir)) {
+ res = htable_shape_set(&scn->shapes, &shape_id, &shape);
+ if(res != RES_OK) {
log_error(scn->dev,
- "%s: The ray direction should be normalized.\n", FUNC_NAME);
- return RES_BAD_ARG;
- }
- if((dir[0] == 0.f && dir[1] == 0.f) || range[0] > range[1]) {
- *hit = S2D_HIT_NULL;
+ "%s: cannot attach the shape to the scene.\n", FUNC_NAME);
return RES_OK;
}
-
- f2_normalize(dir_2d, dir);
- dot = f3_dot(dir_2d, dir); /* Cosine between dir and dir_2d */
- range_2d[0] = dot*range[0];
- range_2d[1] = dot*range[1];
-
- res = s2d_scene_trace_ray(scn, org, dir_2d, range_2d, ray_data, hit);
- if(res != RES_OK) return res;
-
- if(!S2D_HIT_NONE(hit))
- hit->distance = hit->distance / dot;
+ S2D(shape_ref_get(shape));
return RES_OK;
}
res_T
-s2d_scene_sample
- (struct s2d_scene* scn,
- const float u,
- const float v,
- struct s2d_primitive* primitive,
- float* s)
-{
- struct geometry* geom;
- const struct fltui* fltui_begin, *fltui_end, *fltui_found;
- const float* flt_begin, *flt_end, *flt_found;
- size_t igeom;
- float f;
- res_T res = RES_OK;
-
- if(!scn || !primitive || !s) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(u < 0.f || u >= 1.f || v < 0.f || v >= 1.f) {
- log_error(scn->dev,
- "%s: The submitted numbers are not canonical, i.e. they ar not in [0, 1[.\n",
- FUNC_NAME);
- res = RES_BAD_ARG;
- goto error;
- }
- if((scn->session_mask & S2D_SAMPLE) == 0) {
- log_error(scn->dev,
- "%s: A S2D_SAMPLE session should be active onto the submitted scene.\n",
- FUNC_NAME);
- res = RES_BAD_OP;
- goto error;
- }
-
- /* Find the sampled geometry */
- if(darray_fltui_size_get(&scn->cdf) == 0) { /* No geometry to sample */
- *primitive = S2D_PRIMITIVE_NULL;
- goto exit;
- } else if(darray_fltui_size_get(&scn->cdf) == 1) {
- igeom = darray_fltui_cdata_get(&scn->cdf)[0].ui;
- f = u * darray_fltui_cdata_get(&scn->cdf)[0].flt;/* Map u to the CDF bounds */
- } else {
- fltui_begin = darray_fltui_cdata_get(&scn->cdf);
- fltui_end = fltui_begin + darray_fltui_size_get(&scn->cdf);
- f = u * fltui_end[-1].flt; /* Map u to the CDF bounds */
- fltui_found = std::lower_bound(fltui_begin, fltui_end, f);
- ASSERT(fltui_found != fltui_end);
- igeom = fltui_found->ui;
-
- if(fltui_found != fltui_begin) /* Transform u to the geometry CDF bounds */
- f -= fltui_found[-1].flt;
- }
- geom = darray_geom_data_get(&scn->embree2geoms)[igeom];
- ASSERT(geom);
-
- /* Find the sampled segment */
- flt_begin = darray_float_cdata_get(&geom->lines->cdf);
- flt_end = flt_begin + darray_float_size_get(&geom->lines->cdf);
- flt_found = std::lower_bound(flt_begin, flt_end, f);
- ASSERT(flt_found != flt_end);
-
- primitive->mesh__ = geom;
- primitive->geom_id = geom->name;
- primitive->prim_id = (unsigned)(flt_found - flt_begin);
- primitive->scene_prim_id = primitive->prim_id + geom->scene_prim_id_offset;
- S2D(primitive_sample(primitive, v, s));
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-s2d_scene_get_primitive
- (struct s2d_scene* scn, const unsigned iprim, struct s2d_primitive* prim)
-{
- struct geometry* geom;
- const struct nprims_cdf* begin;
- const struct nprims_cdf* end;
- const struct nprims_cdf* found;
- size_t nprims, igeom, i;
- res_T res = RES_OK;
-
- if(!scn || !prim) {
- res = RES_BAD_ARG;
- goto error;
- }
- if((scn->session_mask & S2D_GET_PRIMITIVE) == 0) {
- log_error(scn->dev,
- "%s: A S2D_GET_PRIMITIVE session should be active onto the submitted scene.\n",
- FUNC_NAME);
- res = RES_BAD_OP;
- goto error;
- }
- S2D(scene_primitives_count(scn, &nprims));
- if(iprim >= nprims) {
- log_error(scn->dev,
- "%s: The primitive index %u exceeds the number of scene primitives %u.\n",
- FUNC_NAME, iprim, (unsigned)nprims);
- res = RES_BAD_ARG;
- goto error;
- }
-
- i = iprim;
- if(darray_nprims_cdf_size_get(&scn->nprims_cdf) == 1) {
- igeom = darray_nprims_cdf_cdata_get(&scn->nprims_cdf)[0].irtc;
- } else {
- begin = darray_nprims_cdf_cdata_get(&scn->nprims_cdf);
- end = begin + darray_nprims_cdf_size_get(&scn->nprims_cdf);
- found = std::lower_bound(begin, end, i);
- ASSERT(found != end);
- igeom = found->irtc;
- if(found != begin) {
- ASSERT(i >= found[-1].nprims);
- i -= found[-1].nprims;
- }
- }
- geom = darray_geom_data_get(&scn->embree2geoms)[igeom];
- ASSERT(geom && i < line_segments_get_nsegments(geom->lines));
- prim->mesh__ = geom;
- prim->geom_id = geom->name;
- prim->prim_id = (unsigned)i;
- prim->scene_prim_id = geom->scene_prim_id_offset + prim->prim_id;
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-s2d_scene_primitives_count(struct s2d_scene* scn, size_t* prims_count)
-{
- size_t nprims = 0;
- res_T res = RES_OK;
-
- if(!scn || !prims_count) {
- res = RES_BAD_ARG;
- goto error;
- }
- if(!scn->session_mask) {
- log_error(scn->dev,
- "%s: A session must be active on the submitted scene.\n", FUNC_NAME);
- res = RES_BAD_OP;
- goto error;
- }
- if((scn->session_mask & S2D_GET_PRIMITIVE) != 0) {
- const size_t len = darray_nprims_cdf_size_get(&scn->nprims_cdf);
- if(!len) {
- nprims = 0;
- } else {
- nprims = darray_nprims_cdf_cdata_get(&scn->nprims_cdf)[len-1].nprims;
- }
- } else {
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
-
- nprims = 0;
- LIST_FOR_EACH(node, &scn->shapes) {
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
-
- if(geom->is_enabled) {
- nprims += line_segments_get_nsegments(geom->lines);
- }
- }
- }
-exit:
- if(prims_count) *prims_count = nprims;
- return res;
-error:
- goto exit;
-}
-
-res_T
-s2d_scene_compute_contour_length(struct s2d_scene* scn, float* out_length)
+s2d_scene_detach_shape(struct s2d_scene* scn, struct s2d_shape* shape)
{
- float length = 0;
- res_T res = RES_OK;
+ size_t n;
+ unsigned shape_id;
- if(!scn || !out_length) {
- res = RES_BAD_ARG;
- goto error;
- }
+ if(!scn || !shape) return RES_BAD_ARG;
- if(!scn->session_mask) {
+ S2D(shape_get_id(shape, &shape_id));
+ if(htable_shape_find(&scn->shapes, &shape_id) == NULL) {
log_error(scn->dev,
- "%s: A session must be active on the submitted scene.\n", FUNC_NAME);
- res = RES_BAD_OP;
- goto error;
+ "%s: the shape is not attached to the scene.\n", FUNC_NAME);
+ return RES_BAD_ARG;
}
- if((scn->session_mask & S2D_SAMPLE) != 0) {
- /* Retrieve the overall scene contour length from the scene cumulative
- * distribution function. Note that the CDF stores the cumulative contour
- * length. The real contour length is thus the CDF upper bound */
- size_t len = darray_fltui_size_get(&scn->cdf);
- if(!len) {
- length = 0.f;
- } else {
- length = darray_fltui_cdata_get(&scn->cdf)[len-1].flt;
- }
- } else {
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
+ n = htable_shape_erase(&scn->shapes, &shape_id);
+ ASSERT(n == 1); (void)n;
- length = 0;
- LIST_FOR_EACH(node, &scn->shapes) {
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
+ SIG_BROADCAST(&scn->sig_shape_detach, scene_shape_cb_T, ARG2(scn, shape));
- if(geom->is_enabled) {
- length += line_segments_compute_length(geom->lines);
- }
- }
- }
-
-exit:
- if(out_length) *out_length = length;
- return res;
-error:
- length = -1.f;
- goto exit;
+ S2D(shape_ref_put(shape));
+ return RES_OK;
}
res_T
-s2d_scene_compute_area(struct s2d_scene* scn, float* out_area)
+s2d_scene_clear(struct s2d_scene* scn)
{
- struct list_node* node;
- struct s2d_shape* shape;
- struct geometry** pgeom;
- struct geometry* geom;
- float area = 0.f;
- res_T res = RES_OK;
+ struct htable_shape_iterator it, end;
- if(!scn || !out_area) {
- res = RES_BAD_ARG;
- goto error;
- }
- if(!scn->session_mask) {
- log_error(scn->dev,
- "%s: A session must be active on the submitted scene.\n", FUNC_NAME);
- res = RES_BAD_OP;
- goto error;
- }
-
- LIST_FOR_EACH(node, &scn->shapes) {
- shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment);
- pgeom = htable_geom_find(&scn->cached_geoms, &shape);
- ASSERT(pgeom != NULL);
- geom = *pgeom;
+ if(!scn) return RES_BAD_ARG;
- if(geom->is_enabled) {
- area += line_segments_compute_area(geom->lines, geom->flip_contour);
- }
- }
- if(area < 0.f) {
- log_error(scn->dev,
- "%s: The area of the scene polygons is negative. The scene shapes might\n"
- " not represent closed manifold polygons, or their contour might not point\n"
- " inward the polygon.\n", FUNC_NAME);
+ htable_shape_begin(&scn->shapes, &it);
+ htable_shape_end(&scn->shapes, &end);
+ while(!htable_shape_iterator_eq(&it, &end)) {
+ struct s2d_shape** pshape = htable_shape_iterator_data_get(&it);
+ struct s2d_shape* shape = *pshape;
+ SIG_BROADCAST(&scn->sig_shape_detach, scene_shape_cb_T, ARG2(scn, shape));
+ S2D(shape_ref_put(shape));
+ htable_shape_iterator_next(&it);
}
+ htable_shape_clear(&scn->shapes);
-exit:
- if(out_area) *out_area = area;
- return res;
-error:
- area = -1.f;
- goto exit;
+ return RES_OK;
}
res_T
-s2d_scene_get_aabb(struct s2d_scene* scn, float lower[2], float upper[2])
+s2d_scene_get_device(struct s2d_scene* scn, struct s2d_device** dev)
{
- if(!scn || !lower || !upper) return RES_BAD_ARG;
- if(!scn->session_mask) {
- log_error(scn->dev,
- "%s: A session must be active on the submitted scene.\n", FUNC_NAME);
- return RES_BAD_OP;
- }
- f2_set(lower, scn->lower);
- f2_set(upper, scn->upper);
+ if(!scn || !dev) return RES_BAD_ARG;
+ *dev = scn->dev;
return RES_OK;
}
res_T
-s2d_scene_get_device(struct s2d_scene* scn, struct s2d_device** dev)
+s2d_scene_get_shapes_count(struct s2d_scene* scn, size_t* nshapes)
{
- if(!scn || !dev) return RES_BAD_ARG;
- *dev = scn->dev;
+ if(!scn || !nshapes) return RES_BAD_ARG;
+ *nshapes = htable_shape_size_get(&scn->shapes);
return RES_OK;
}
diff --git a/src/s2d_scene_c.h b/src/s2d_scene_c.h
@@ -29,63 +29,29 @@
#ifndef S2D_SCENE_C_H
#define S2D_SCENE_C_H
-#include "s2d_backend.h"
-
-#include <rsys/dynamic_array.h>
#include <rsys/hash_table.h>
#include <rsys/list.h>
#include <rsys/ref_count.h>
+#include <rsys/signal.h>
-/*
- * The geometry pointer must be initialized to NULL in order to define which
- * pointers are valid or not.
- */
-static FINLINE void
-geom_ptr_init__(struct mem_allocator* alloc, struct geometry** geom)
-{
- (void)alloc;
- *geom = NULL;
-}
-
-/* Generate the darray_geom data type */
-#define DARRAY_NAME geom
-#define DARRAY_DATA struct geometry*
-#define DARRAY_FUNCTOR_INIT geom_ptr_init__
-#include <rsys/dynamic_array.h>
-
-/* Generate the htable_geom hash table */
-#define HTABLE_NAME geom
-#define HTABLE_DATA struct geometry*
-#define HTABLE_KEY struct s2d_shape*
+/* Generate the htable_shape hash table */
+#define HTABLE_NAME shape
+#define HTABLE_DATA struct s2d_shape*
+#define HTABLE_KEY unsigned /* Id of the shape */
#include <rsys/hash_table.h>
-/* Generate the darray_fltui dynamic array */
-struct fltui { float flt; unsigned ui; };
-#define DARRAY_NAME fltui
-#define DARRAY_DATA struct fltui
-#include <rsys/dynamic_array.h>
-
-/* Generate the darray_geom_nprims array */
-struct nprims_cdf { unsigned nprims, irtc; };
-#define DARRAY_NAME nprims_cdf
-#define DARRAY_DATA struct nprims_cdf
-#include <rsys/dynamic_array.h>
+/* Declare the scene_shape_cb_T callback data type */
+CLBK(scene_shape_cb_T, ARG2
+ (const struct s2d_scene* scn,
+ const struct s2d_shape* shape));
struct s2d_scene {
- struct list_node shapes; /* List of attached shapes */
- struct htable_geom cached_geoms; /* Cached shape geometries */
- struct darray_geom embree2geoms; /* Shape geometries indexed by embree id */
- struct darray_fltui cdf; /* Unormalized CDF */
- struct darray_nprims_cdf nprims_cdf;
-
- float lower[2], upper[2]; /* AABB of the scene */
+ struct htable_shape shapes; /* List of attached shapes */
+ struct list_node scnviews; /* Pool of available s3d_scene_view */
- RTCScene rtc_scn; /* Embree scene */
- char is_rtc_scn_outdated; /* Must the embree scene rebuild */
+ signal_T sig_shape_detach;
- int session_mask; /* Combination of enum s2d_session_flag */
struct s2d_device* dev;
-
ref_T ref;
};
diff --git a/src/s2d_scene_view.c b/src/s2d_scene_view.c
@@ -0,0 +1,1155 @@
+/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms. */
+
+#include "s2d.h"
+#include "s2d_device_c.h"
+#include "s2d_line_segments.h"
+#include "s2d_geometry.h"
+#include "s2d_scene_c.h"
+#include "s2d_scene_view_c.h"
+#include "s2d_shape_c.h"
+
+#include <rsys/float2.h>
+#include <rsys/float3.h>
+
+#include <algorithm>
+
+struct ray_extended : public RTCRay {
+ struct s2d_scene_view* scnview;
+ float ws_org[3]; /* World space ray origin */
+ float ws_dir[3]; /* World space ray direction */
+ void* data; /* User defined data */
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static FINLINE bool
+operator < (const struct fltui& it, const float val)
+{
+ /* This operator is used by the std::lower_bound algorithm that returns an
+ * iterator to the first element that is not less than val while one expect
+ * an iterator on the first element that is not less *or equal* than val.
+ * That's why we use <= rather than < */
+ return it.flt <= val;
+}
+
+static FINLINE bool
+operator < (const struct nprims_cdf& it, const size_t iprim)
+{
+ /* This operator is used by the std::lower_bound algorithm that returns an
+ * iterator to the first element that is not less than iprim while one expect
+ * an iterator on the first element that is not less *or equal* than iprim.
+ * That's why we use <= rather than < */
+ return it.nprims <= iprim;
+}
+
+static INLINE void
+scene_view_destroy_geometry(struct s2d_scene_view* scnview, struct geometry* geom)
+{
+ ASSERT(geom);
+ if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
+ rtcDeleteGeometry(scnview->rtc_scn, geom->irtc);
+ geom->irtc = RTC_INVALID_GEOMETRY_ID;
+ scnview->rtc_scn_update = 1; /* Notify the scene upd */
+ }
+ geometry_ref_put(geom);
+}
+
+static void
+on_shape_detach
+ (const struct s2d_scene* scn,
+ const struct s2d_shape* shape,
+ void* data)
+{
+ struct geometry** pgeom;
+ struct geometry* geom;
+ struct s2d_scene_view* scnview = (struct s2d_scene_view*)data;
+ unsigned shape_id;
+ ASSERT(scn && shape && data);
+ (void)scn;
+
+ S2D(shape_get_id(shape, &shape_id));
+ pgeom = htable_geom_find(&scnview->cached_geoms, &shape_id);
+
+ /* The scnview did not register a geometry for this shape. Ignore the signal */
+ if(!pgeom) return;
+
+ geom = *pgeom;
+ if(scnview->mask == 0) {
+ /* The scnview is NOT in use. Directly rm the cached geometry */
+ size_t n; (void)n;
+ scene_view_destroy_geometry(scnview, geom);
+ n = htable_geom_erase(&scnview->cached_geoms, &shape_id);
+ ASSERT(n == 1);
+ } else {
+ /* The scnview is in use. Delay the deletion of the cached geometry */
+ res_T res = darray_uint_push_back(&scnview->detached_shapes, &shape_id);
+ if(res != RES_OK) FATAL("Insufficient memory.\n");
+ }
+}
+
+static INLINE void
+hit_setup(struct s2d_scene_view* scnview, const RTCRay* ray, struct s2d_hit* hit)
+{
+ struct geometry* geom;
+
+ if((unsigned)ray->geomID == RTC_INVALID_GEOMETRY_ID) { /* No hit */
+ *hit = S2D_HIT_NULL;
+ return;
+ }
+ ASSERT(eq_epsf(ray->Ng[2], 0.f, 1.e-6f));
+ ASSERT((unsigned)ray->instID == RTC_INVALID_GEOMETRY_ID);
+ ASSERT((unsigned)ray->geomID < darray_geom_size_get(&scnview->embree2geoms));
+
+ geom = darray_geom_data_get(&scnview->embree2geoms)[ray->geomID];
+ ASSERT(geom);
+
+ hit->prim.mesh__ = geom;
+ hit->prim.prim_id = ray->primID;
+ hit->prim.geom_id = geom->name;
+ hit->prim.scene_prim_id = hit->prim.prim_id + geom->scene_prim_id_offset;
+ hit->normal[0] = ray->Ng[0];
+ hit->normal[1] = ray->Ng[1];
+ hit->distance = ray->tfar;
+ /* The Embree "v" parametric coordinate of the extruded quad corresponds to
+ * the edge parametric coordinate */
+ hit->u = ray->v;
+
+ if(geom->flip_contour) {
+ f2_minus(hit->normal, hit->normal);
+ }
+}
+
+static void
+filter_wrapper(void* user_ptr, RTCRay& ray)
+{
+ struct s2d_hit hit;
+ struct hit_filter* filter = (struct hit_filter*)user_ptr;
+ struct ray_extended* ray_ex = static_cast<struct ray_extended*>(&ray);
+
+ hit_setup(ray_ex->scnview, &ray, &hit);
+ if(filter->func
+ (&hit, ray_ex->ws_org, ray_ex->ws_dir, ray_ex->data, filter->data)) {
+ /* Discard the intersection */
+ ray.geomID = RTC_INVALID_GEOMETRY_ID;
+ }
+}
+
+static res_T
+embree_geometry_register
+ (struct s2d_scene_view* scnview,
+ struct geometry* geom)
+{
+ ASSERT(scnview);
+
+ /* Create the Embree geometry if it is not valid */
+ if(geom->irtc == RTC_INVALID_GEOMETRY_ID) {
+ rtcNewQuadMesh
+ (scnview->rtc_scn,
+ RTC_GEOMETRY_DYNAMIC,
+ line_segments_get_nsegments(geom->lines),
+ line_segments_get_nverts(geom->lines)*2/*Lines are extruded as quads*/);
+ if(geom->irtc == RTC_INVALID_GEOMETRY_ID)
+ return RES_UNKNOWN_ERR;
+ scnview->rtc_scn_update = 1;
+ }
+
+ /* Register the embree geometry in the embree2geoms associative array */
+ if(geom->irtc >= darray_geom_size_get(&scnview->embree2geoms)) {
+ const res_T res = darray_geom_resize(&scnview->embree2geoms, geom->irtc+1);
+ if(res != RES_OK) {
+ rtcDeleteGeometry(scnview->rtc_scn, geom->irtc);
+ geom->irtc = RTC_INVALID_GEOMETRY_ID;
+ return res;
+ }
+ }
+
+ darray_geom_data_get(&scnview->embree2geoms)[geom->irtc] = geom;
+ return RES_OK;
+}
+
+static void
+embree_geometry_setup_positions
+ (struct s2d_scene_view* scnview, struct geometry* geom)
+{
+ size_t nverts;
+ size_t i;
+ float* verts;
+ float* rtc_verts;
+ ASSERT(scnview && geom && geom->irtc != RTC_INVALID_GEOMETRY_ID);
+
+ /* Extrude segment vertices as quad whose Z is [-1, 1] */
+ nverts = line_segments_get_nverts(geom->lines);
+ verts = line_segments_get_attr(geom->lines, S2D_POSITION);
+ rtc_verts = (float*)rtcMapBuffer(scnview->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
+ FOR_EACH(i, 0, nverts) {
+ size_t ivert = i*2/*#coords per vertex*/;
+ size_t rtc_ivert = i*4/*#coords + padding*/ * 2/*#rtc vertices per line vertex*/;
+
+ rtc_verts[rtc_ivert + 0] = verts[ivert + 0];
+ rtc_verts[rtc_ivert + 1] = verts[ivert + 1];
+ rtc_verts[rtc_ivert + 2] = 1.f;
+ rtc_verts[rtc_ivert + 3] = 0.f; /* Padding */
+
+ rtc_verts[rtc_ivert + 4] = verts[ivert + 0];
+ rtc_verts[rtc_ivert + 5] = verts[ivert + 1];
+ rtc_verts[rtc_ivert + 6] = -1.f;
+ rtc_verts[rtc_ivert + 7] = 0.f; /* Padding */
+ }
+ rtcUnmapBuffer(scnview->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
+ rtcUpdateBuffer(scnview->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
+}
+
+
+static INLINE void
+embree_geometry_setup_indices
+ (struct s2d_scene_view* scnview, struct geometry* geom)
+{
+ size_t nsegs;
+ size_t i;
+ uint32_t* ids;
+ uint32_t* rtc_ids;
+ ASSERT(scnview && geom && geom->irtc != RTC_INVALID_GEOMETRY_ID);
+
+ /* Define the index of the extruded line segments */
+ nsegs = line_segments_get_nsegments(geom->lines);
+ ids = line_segments_get_ids(geom->lines);
+ rtc_ids = (uint32_t*)rtcMapBuffer(scnview->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
+ FOR_EACH(i, 0, nsegs) {
+ size_t id = i*2/*#ids per segment*/;
+ size_t rtc_id = i*4/*#ids per quad*/;
+
+ rtc_ids[rtc_id + 0] = ids[id + 0] * 2/*#rtc vertices per line vertex*/ + 1;
+ rtc_ids[rtc_id + 1] = ids[id + 0] * 2/*#rtc vertices per line vertex*/ + 0;
+ rtc_ids[rtc_id + 2] = ids[id + 1] * 2/*#rtc vertices per line vertex*/ + 0;
+ rtc_ids[rtc_id + 3] = ids[id + 1] * 2/*#rtc vertices per line vertex*/ + 1;
+ }
+ rtcUnmapBuffer(scnview->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
+ rtcUpdateBuffer(scnview->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
+}
+
+static INLINE void
+embree_geometry_setup_enable_state
+ (struct s2d_scene_view* scnview, struct geometry* geom)
+{
+ ASSERT(scnview && geom);
+ if(geom->is_enabled) {
+ rtcEnable(scnview->rtc_scn, geom->irtc);
+ } else {
+ rtcDisable(scnview->rtc_scn, geom->irtc);
+ }
+}
+
+static INLINE void
+embree_geometry_setup_filter_function
+ (struct s2d_scene_view* scnview, struct geometry* geom)
+{
+ ASSERT(scnview && geom && geom->irtc != RTC_INVALID_GEOMETRY_ID);
+
+ if(!geom->lines->filter.func) {
+ rtcSetIntersectionFilterFunction(scnview->rtc_scn, geom->irtc, NULL);
+ } else {
+ rtcSetIntersectionFilterFunction(scnview->rtc_scn, geom->irtc, filter_wrapper);
+ rtcSetUserData(scnview->rtc_scn, geom->irtc, &geom->lines->filter);
+ }
+}
+
+static INLINE res_T
+scene_view_setup_embree(struct s2d_scene_view* scnview)
+{
+ struct htable_geom_iterator it, end;
+ const RTCSceneFlags rtc_scene_mask =
+ RTC_SCENE_DYNAMIC
+ | RTC_SCENE_INCOHERENT
+ | RTC_SCENE_ROBUST;
+ const RTCAlgorithmFlags rtc_algorithm_mask =
+ RTC_INTERSECT1
+ | RTC_INTERSECT4;
+ int rtc_outdated = 0;
+ res_T res = RES_OK;
+ ASSERT(scnview);
+
+ /* The rtc_scn could be already allocated since the scene views are cached */
+ if(!scnview->rtc_scn) {
+ scnview->rtc_scn = rtcDeviceNewScene
+ (scnview->scn->dev->rtc, rtc_scene_mask, rtc_algorithm_mask);
+ if(!scnview->rtc_scn) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ }
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry** pgeom = htable_geom_iterator_data_get(&it);
+ struct geometry* geom = *pgeom;
+
+ htable_geom_iterator_next(&it);
+
+ /* Define whether or not the embree scene is outdated */
+ if(geom->embree_outdated_mask) rtc_outdated = 1;
+
+ /* Register the embree geometry */
+ res = embree_geometry_register(scnview, geom);
+ if(res != RES_OK) goto error;
+
+ /* Flush the embree geometry states */
+ if((geom->embree_outdated_mask & EMBREE_VERTICES) != 0)
+ embree_geometry_setup_positions(scnview, geom);
+ if((geom->embree_outdated_mask & EMBREE_INDICES) != 0)
+ embree_geometry_setup_indices(scnview, geom);
+ if((geom->embree_outdated_mask & EMBREE_ENABLE) != 0)
+ embree_geometry_setup_enable_state(scnview, geom);
+ if((geom->embree_outdated_mask & EMBREE_FILTER_FUNCTION) != 0)
+ embree_geometry_setup_filter_function(scnview, geom);
+
+ geom->embree_outdated_mask = 0;
+ }
+
+ rtc_outdated = rtc_outdated || scnview->rtc_scn_update;
+
+ /* Commit the embree changes */
+ if(rtc_outdated) {
+ rtcCommit(scnview->rtc_scn);
+ scnview->rtc_commit = 1; /* Notify that the scene view was committed */
+ scnview->rtc_scn_update = 0;
+ }
+
+exit:
+ return res;
+error:
+ if(scnview->rtc_scn) {
+ scnview->rtc_scn = NULL;
+ rtcDeleteScene(scnview->rtc_scn);
+ }
+ darray_geom_clear(&scnview->embree2geoms);
+ goto exit;
+}
+
+static res_T
+scene_view_register_line_segments
+ (struct s2d_scene_view* scnview,
+ struct s2d_shape* shape)
+{
+ struct geometry** pgeom = NULL;
+ struct geometry* geom = NULL;
+ size_t iattr;
+ unsigned shape_id;
+ res_T res = RES_OK;
+ ASSERT(scnview && shape);
+
+ /* Retrieved the cached geometry */
+ S2D(shape_get_id(shape, &shape_id));
+ pgeom = htable_geom_find(&scnview->cached_geoms, &shape_id);
+ if(pgeom) {
+ geom = *pgeom;
+ } else {
+ res = geometry_create(scnview->scn->dev, &geom);
+ if(res != RES_OK) goto error;
+ res = line_segments_create(scnview->scn->dev, &geom->lines);
+ if(res != RES_OK) goto error;
+ res = htable_geom_set(&scnview->cached_geoms, &shape_id, &geom);
+ if(res != RES_OK) goto error;
+ geom->name = shape->id.index;
+ }
+
+ /* Discard the geometries that are not geometrically valid */
+ if(!shape->lines->indices || !shape->lines->attribs[S2D_POSITION]) {
+ if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
+ rtcDeleteGeometry(scnview->rtc_scn, geom->irtc);
+ geom->irtc = RTC_INVALID_GEOMETRY_ID;
+ }
+ line_segments_clear(geom->lines);
+ goto exit;
+ }
+
+ /* Get a reference onto the shape lines segments indices */
+ if(geom->lines->indices != shape->lines->indices) {
+ geom->embree_outdated_mask |= EMBREE_INDICES;
+ if(geom->lines->indices) { /* Release previous indices of the geometry */
+ index_buffer_ref_put(geom->lines->indices);
+ geom->lines->indices = NULL;
+ }
+ ASSERT(shape->lines->indices);
+ index_buffer_ref_get(shape->lines->indices);
+ geom->lines->indices = shape->lines->indices;
+ }
+
+ /* Get a reference onto the shape line segments attribs */
+ FOR_EACH(iattr, 0, S2D_ATTRIBS_COUNT__) {
+ geom->embree_outdated_mask |= EMBREE_VERTICES;
+ if(geom->lines->attribs[iattr] == shape->lines->attribs[iattr])
+ continue;
+
+ if(geom->lines->attribs[iattr]) { /* Release the previous geometry attribs */
+ vertex_buffer_ref_put(geom->lines->attribs[iattr]);
+ geom->lines->attribs[iattr] = NULL;
+ }
+
+ if(!shape->lines->attribs[iattr]) continue;
+
+ vertex_buffer_ref_get(shape->lines->attribs[iattr]);
+ geom->lines->attribs[iattr] = shape->lines->attribs[iattr];
+ geom->lines->attribs_type[iattr] = shape->lines->attribs_type[iattr];
+ }
+
+ /* Update the enable flag */
+ if(geom->is_enabled != shape->is_enabled) {
+ geom->is_enabled = shape->is_enabled;
+ geom->embree_outdated_mask |= EMBREE_ENABLE;
+ }
+
+ /* Update the filter function */
+ if(geom->lines->filter.func != shape->lines->filter.func
+ || geom->lines->filter.data != shape->lines->filter.data) {
+ geom->lines->filter = shape->lines->filter;
+ geom->embree_outdated_mask |= EMBREE_FILTER_FUNCTION;
+ }
+
+ if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
+ struct index_buffer* shape_ids = shape->lines->indices;
+ struct index_buffer* geom_ids = geom->lines->indices;
+ struct vertex_buffer* shape_verts = shape->lines->attribs[S2D_POSITION];
+ struct vertex_buffer* geom_verts = geom->lines->attribs[S2D_POSITION];
+ const size_t shape_nids = darray_u32_size_get(&shape_ids->data);
+ const size_t geom_nids = darray_u32_size_get(&geom_ids->data);
+ const size_t shape_nverts = darray_float_size_get(&shape_verts->data);
+ const size_t geom_nverts = darray_float_size_get(&geom_verts->data);
+
+ /* The shape lines was resize => the Embree geometry is no more valid */
+ if(shape_nids != geom_nids || shape_nverts != geom_nverts) {
+ rtcDeleteGeometry(scnview->rtc_scn, geom->irtc);
+ geom->irtc = RTC_INVALID_GEOMETRY_ID;
+ }
+ }
+
+ geom->flip_contour = shape->flip_contour;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+scene_view_compute_nprims_cdf
+ (struct s2d_scene_view* scnview, const char store_cdf)
+{
+ struct htable_geom_iterator it, end;
+ size_t len;
+ unsigned nprims;
+ res_T res = RES_OK;
+ ASSERT(scnview);
+ ASSERT(darray_nprims_cdf_size_get(&scnview->nprims_cdf) == 0);
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+
+ nprims = 0;
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ const unsigned* shape_id = htable_geom_iterator_key_get(&it);
+ struct geometry* geom = *htable_geom_iterator_data_get(&it);
+ struct nprims_cdf cdf;
+
+ htable_geom_iterator_next(&it);
+
+ if(!geom->is_enabled) continue;
+
+ geom->scene_prim_id_offset = nprims;
+ len = line_segments_get_nsegments(geom->lines);
+ nprims += (unsigned)len;
+
+ cdf.nprims = nprims;
+ cdf.ishape = *shape_id;
+ if(store_cdf && len) {
+ res = darray_nprims_cdf_push_back(&scnview->nprims_cdf, &cdf);
+ if(res != RES_OK) goto error;
+ }
+ }
+
+exit:
+ return res;
+error:
+ darray_nprims_cdf_clear(&scnview->nprims_cdf);
+ goto exit;
+}
+
+static void
+scene_view_compute_scene_aabb(struct s2d_scene_view* scnview)
+{
+ struct htable_geom_iterator it, end;
+ float lower[2], upper[2];
+
+ ASSERT(scnview->lower[0] == FLT_MAX && scnview->upper[0] == -FLT_MAX);
+ ASSERT(scnview->lower[1] == FLT_MAX && scnview->upper[1] == -FLT_MAX);
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry* geom = *htable_geom_iterator_data_get(&it);
+
+ htable_geom_iterator_next(&it);
+
+ if(!geom->is_enabled) continue;
+
+ line_segments_compute_aabb(geom->lines, lower, upper);
+ f2_min(scnview->lower, scnview->lower, lower);
+ f2_max(scnview->upper, scnview->upper, upper);
+ }
+}
+
+static res_T
+scene_view_compute_cdf(struct s2d_scene_view* scnview)
+{
+ struct htable_geom_iterator it, end;
+ size_t len;
+ float area = 0.f;
+ res_T res = RES_OK;
+ ASSERT(scnview);
+ ASSERT(darray_fltui_size_get(&scnview->cdf) == 0);
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ const unsigned* shape_id = htable_geom_iterator_key_get(&it);
+ struct geometry* geom = *htable_geom_iterator_data_get(&it);
+ struct fltui fltui;
+
+ htable_geom_iterator_next(&it);
+
+ if(!geom->is_enabled) continue;
+
+ res = line_segments_compute_cdf(geom->lines);
+ if(res != RES_OK) goto error;
+ len = darray_float_size_get(&geom->lines->cdf);
+
+ fltui.ui = *shape_id;
+ fltui.flt = area;
+ if(len) {
+ res = darray_fltui_push_back(&scnview->cdf, &fltui);
+ if(res != RES_OK) goto error;
+ }
+ }
+exit:
+ return res;
+error:
+ darray_fltui_clear(&scnview->cdf);
+ goto exit;
+}
+
+static res_T
+scene_view_sync
+ (struct s2d_scene_view* scnview,
+ const int mask)
+{
+ struct htable_shape_iterator it, end;
+ res_T res = RES_OK;
+
+ ASSERT(scnview);
+ ASSERT((mask & (S2D_TRACE|S2D_SAMPLE|S2D_GET_PRIMITIVE)) != 0);
+
+ /* Commit the scene shape to the scnview */
+ htable_shape_begin(&scnview->scn->shapes, &it);
+ htable_shape_end(&scnview->scn->shapes, &end);
+ while(!htable_shape_iterator_eq(&it, &end)) {
+ struct s2d_shape** pshape = htable_shape_iterator_data_get(&it);
+ struct s2d_shape* shape = *pshape;
+
+ res = scene_view_register_line_segments(scnview, shape);
+ if(res != RES_OK) goto error;
+ htable_shape_iterator_next(&it);
+ }
+
+ scene_view_compute_scene_aabb(scnview);
+
+ /* Setup the scene for the S2D_TRACE scnview */
+ if((mask & S2D_TRACE) != 0) {
+ res = scene_view_setup_embree(scnview);
+ if(res != RES_OK) goto error;
+ }
+ /* Setup the scene for the S2D_SAMPLE scnview */
+ if((mask & S2D_SAMPLE) != 0) {
+ res = scene_view_compute_cdf(scnview);
+ if(res != RES_OK) goto error;
+ }
+ /* Setup the scene for the scene_primitive_id/S3D_GET_PRIMITIVE scnview */
+ res = scene_view_compute_nprims_cdf(scnview, (mask & S2D_GET_PRIMITIVE)!=0);
+ if(res != RES_OK) goto error;
+
+ scnview->mask = mask;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+scene_view_create(struct s2d_scene* scn, struct s2d_scene_view** out_scnview)
+{
+ struct s2d_scene_view* scnview = NULL;
+ res_T res = RES_OK;
+ ASSERT(scn && out_scnview);
+
+ if(!is_list_empty(&scn->scnviews)) {
+ /* Retrieve an already allocated scnview */
+ scnview = CONTAINER_OF(list_head(&scn->scnviews), struct s2d_scene_view, node);
+ list_del(&scnview->node);
+ ref_get(&scnview->ref);
+ } else {
+ scnview = (struct s2d_scene_view*)MEM_CALLOC
+ (scn->dev->allocator, 1, sizeof(struct s2d_scene_view));
+ if(!scnview) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ list_init(&scnview->node);
+ htable_geom_init(scn->dev->allocator, &scnview->cached_geoms);
+ darray_geom_init(scn->dev->allocator, &scnview->embree2geoms);
+ darray_fltui_init(scn->dev->allocator, &scnview->cdf);
+ darray_nprims_cdf_init(scn->dev->allocator, &scnview->nprims_cdf);
+ darray_uint_init(scn->dev->allocator, &scnview->detached_shapes);
+ f2_splat(scnview->lower, FLT_MAX);
+ f2_splat(scnview->upper,-FLT_MAX);
+ ref_init(&scnview->ref);
+
+ CLBK_INIT(&scnview->on_shape_detach_cb);
+ CLBK_SETUP(&scnview->on_shape_detach_cb, on_shape_detach, scnview);
+ SIG_CONNECT_CLBK(&scn->sig_shape_detach, &scnview->on_shape_detach_cb);
+ }
+ S2D(scene_ref_get(scn));
+ scnview->scn = scn;
+exit:
+ *out_scnview = scnview;
+ return res;
+error:
+ if(scnview) {
+ S2D(scene_view_ref_put(scnview));
+ scnview = NULL;
+ }
+ goto exit;
+}
+
+static void
+scene_view_release(ref_T* ref)
+{
+ struct s2d_scene_view* scnview = CONTAINER_OF(ref, struct s2d_scene_view, ref);
+ size_t i, n;
+ ASSERT(ref);
+
+ /* Remove the geometry of the shapes detached while the scnview was active */
+ n = darray_uint_size_get(&scnview->detached_shapes);
+ FOR_EACH(i, 0, n) {
+ const unsigned shape_id = darray_uint_cdata_get(&scnview->detached_shapes)[i];
+ struct geometry** pgeom = htable_geom_find(&scnview->cached_geoms, &shape_id);
+ struct geometry* geom = *pgeom;
+ size_t tmp; (void)tmp;
+ scene_view_destroy_geometry(scnview, geom);
+ tmp = htable_geom_erase(&scnview->cached_geoms, &shape_id);
+ ASSERT(tmp == 1);
+ }
+ darray_uint_clear(&scnview->detached_shapes);
+
+ /* Clear the scnview data structures excepted the cache of geometries that
+ * will be used to speed up the future scnview creation */
+ darray_geom_clear(&scnview->embree2geoms);
+ darray_fltui_clear(&scnview->cdf);
+ darray_nprims_cdf_clear(&scnview->nprims_cdf);
+ f2_splat(scnview->lower, FLT_MAX);
+ f2_splat(scnview->upper,-FLT_MAX);
+ scnview->mask = 0;
+ scnview->rtc_commit = 0;
+
+ /* Do not physically release the memory space of the scnview. Add it to the
+ * available scnviews pool of the scene */
+ list_add(&scnview->scn->scnviews, &scnview->node);
+ S2D(scene_ref_put(scnview->scn));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+s2d_scene_view_create
+ (struct s2d_scene* scn,
+ const int mask,
+ struct s2d_scene_view** out_scnview)
+{
+ struct s2d_scene_view* scnview = NULL;
+ res_T res = RES_OK;
+
+ if(!scn || !out_scnview) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!(mask & S2D_TRACE)
+ && !(mask & S2D_SAMPLE)
+ && !(mask & S2D_GET_PRIMITIVE)) {
+ log_error(scn->dev, "%s: no valid scene view mask is defined.\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = scene_view_create(scn, &scnview);
+ if(res != RES_OK) goto error;
+
+ res = scene_view_sync(scnview, mask);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(out_scnview) *out_scnview = scnview;
+ return res;
+error:
+ if(scnview) {
+ S2D(scene_view_ref_put(scnview));
+ scnview = NULL;
+ }
+ goto exit;
+}
+
+res_T
+s2d_scene_view_ref_get(struct s2d_scene_view* scnview)
+{
+ if(!scnview) return RES_BAD_ARG;
+ ref_get(&scnview->ref);
+ return RES_OK;
+}
+
+res_T
+s2d_scene_view_ref_put(struct s2d_scene_view* scnview)
+{
+ if(!scnview) return RES_BAD_ARG;
+ ref_put(&scnview->ref, scene_view_release);
+ return RES_OK;
+}
+
+res_T
+s2d_scene_view_get_mask(struct s2d_scene_view* scnview, int* mask)
+{
+ if(scnview || !mask) return RES_BAD_ARG;
+ *mask = scnview->mask;
+ return RES_OK;
+}
+
+res_T
+s2d_scene_view_trace_ray
+ (struct s2d_scene_view* scnview,
+ const float org[2],
+ const float dir[2],
+ const float range[2],
+ void* ray_data,
+ struct s2d_hit* hit)
+{
+ struct ray_extended ray_ex;
+
+ if(!scnview || !org || !dir || !range || !hit)
+ return RES_BAD_ARG;
+ if(!f2_is_normalized(dir)) {
+ log_error(scnview->scn->dev,
+ "%s: unnormalized ray direction {%g, %g}.\n", FUNC_NAME, SPLIT2(dir));
+ return RES_BAD_ARG;
+ }
+ if((scnview->mask & S2D_TRACE) == 0) {
+ log_error(scnview->scn->dev,
+ "%s: the S2D_TRACE flag is not active onto the submitted scene view.\n",
+ FUNC_NAME);
+ return RES_BAD_OP;
+ }
+ if(range[0] > range[1]) { /* Degenerated range <=> disabled ray */
+ *hit = S2D_HIT_NULL;
+ return RES_OK;
+ }
+
+ f3_set(ray_ex.org, f3(ray_ex.ws_org, org[0], org[1], 0.f));
+ f3_set(ray_ex.dir, f3(ray_ex.ws_dir, dir[0], dir[1], 0.f));
+ ray_ex.tnear = range[0];
+ ray_ex.tfar = range[1];
+ ray_ex.geomID = RTC_INVALID_GEOMETRY_ID;
+ ray_ex.primID = RTC_INVALID_GEOMETRY_ID;
+ ray_ex.instID = RTC_INVALID_GEOMETRY_ID;
+ ray_ex.mask = 0xFFFFFFFF;
+ ray_ex.time = 0.f;
+ ray_ex.scnview = scnview;
+ ray_ex.data = ray_data;
+
+ rtcIntersect(scnview->rtc_scn, ray_ex);
+ hit_setup(scnview, &ray_ex, hit);
+
+ return RES_OK;
+}
+
+res_T
+s2d_scene_view_trace_ray_3d
+ (struct s2d_scene_view* scnview,
+ const float org[3],
+ const float dir[3],
+ const float range[2],
+ void* ray_data,
+ struct s2d_hit* hit)
+{
+ float range_2d[2];
+ float dir_2d[3] = {0.f, 0.f, 0.f};
+ float dot;
+ res_T res = RES_OK;
+
+ if(!dir || !range || !hit) {
+ return RES_BAD_ARG;
+ }
+ if((dir[0] == 0.f && dir[1] == 0.f) || range[0] > range[1]) {
+ *hit = S2D_HIT_NULL;
+ return RES_OK;
+ }
+
+ f2_normalize(dir_2d, dir);
+ dot = f3_dot(dir_2d, dir); /* Cosine between dir and dir_2d */
+ range_2d[0] = dot*range[0];
+ range_2d[1] = dot*range[1];
+
+ res = s2d_scene_view_trace_ray(scnview, org, dir_2d, range_2d, ray_data, hit);
+ if(res != RES_OK) return res;
+
+ if(!S2D_HIT_NONE(hit))
+ hit->distance = hit->distance / dot;
+ return RES_OK;
+}
+
+res_T
+s2d_scene_view_sample
+ (struct s2d_scene_view* scnview,
+ const float u, const float v,
+ struct s2d_primitive* primitive,
+ float* s)
+{
+ struct geometry* geom;
+ const struct fltui* fltui_begin, *fltui_end, *fltui_found;
+ const float* flt_begin, *flt_end, *flt_found;
+ size_t igeom;
+ float f;
+ res_T res = RES_OK;
+
+ if(!scnview || !primitive || !s) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(u < 0.f || u >= 1.f || v < 0.f || v >= 1.f) {
+ log_error(scnview->scn->dev,
+ "%s: The submitted numbers are not canonical, i.e. they ar not in [0, 1[.\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if((scnview->mask & S2D_SAMPLE) == 0) {
+ log_error(scnview->scn->dev,
+ "%s: the S2D_SAMPLE flag is not active onto the submitted scene view.\n",
+ FUNC_NAME);
+ res = RES_BAD_OP;
+ goto error;
+ }
+
+ /* Find the sampled geometry */
+ if(darray_fltui_size_get(&scnview->cdf) == 0) { /* No geometry to sample */
+ *primitive = S2D_PRIMITIVE_NULL;
+ goto exit;
+ } else if(darray_fltui_size_get(&scnview->cdf) == 1) {
+ igeom = darray_fltui_cdata_get(&scnview->cdf)[0].ui;
+ /* Map u to the CDF bounds */
+ f = u * darray_fltui_cdata_get(&scnview->cdf)[0].flt;
+ } else {
+ fltui_begin = darray_fltui_cdata_get(&scnview->cdf);
+ fltui_end = fltui_begin + darray_fltui_size_get(&scnview->cdf);
+ f = u * fltui_end[-1].flt; /* Map u to the CDF bounds */
+ fltui_found = std::lower_bound(fltui_begin, fltui_end, f);
+ ASSERT(fltui_found != fltui_end);
+ igeom = fltui_found->ui;
+
+ if(fltui_found != fltui_begin) /* Transform u to the geometry CDF bounds */
+ f -= fltui_found[-1].flt;
+ }
+ geom = darray_geom_data_get(&scnview->embree2geoms)[igeom];
+ ASSERT(geom);
+
+ /* Find the sampled segment */
+ flt_begin = darray_float_cdata_get(&geom->lines->cdf);
+ flt_end = flt_begin + darray_float_size_get(&geom->lines->cdf);
+ flt_found = std::lower_bound(flt_begin, flt_end, f);
+ ASSERT(flt_found != flt_end);
+
+ primitive->mesh__ = geom;
+ primitive->geom_id = geom->name;
+ primitive->prim_id = (unsigned)(flt_found - flt_begin);
+ primitive->scene_prim_id = primitive->prim_id + geom->scene_prim_id_offset;
+ S2D(primitive_sample(primitive, v, s));
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+s2d_scene_view_get_primitive
+ (struct s2d_scene_view* scnview,
+ const unsigned iprim,
+ struct s2d_primitive* prim)
+{
+ struct geometry** pgeom;
+ struct geometry* geom;
+ const struct nprims_cdf* begin;
+ const struct nprims_cdf* end;
+ const struct nprims_cdf* found;
+ size_t nprims;
+ unsigned ishape;
+ size_t i;
+ res_T res = RES_OK;
+
+ if(!scnview || !prim) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if((scnview->mask & S2D_GET_PRIMITIVE) == 0) {
+ log_error(scnview->scn->dev,
+ "%s: the S2D_GET_PRIMITIVE flag is not active onto the submitted scene view.\n",
+ FUNC_NAME);
+ res = RES_BAD_OP;
+ goto error;
+ }
+ S2D(scene_view_primitives_count(scnview, &nprims));
+ if(iprim >= nprims) {
+ log_error(scnview->scn->dev,
+ "%s: The primitive index %u exceeds the number of primitives %u.\n",
+ FUNC_NAME, iprim, (unsigned)nprims);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ i = iprim;
+ if(darray_nprims_cdf_size_get(&scnview->nprims_cdf) == 1) {
+ ishape = darray_nprims_cdf_cdata_get(&scnview->nprims_cdf)[0].ishape;
+ } else {
+ begin = darray_nprims_cdf_cdata_get(&scnview->nprims_cdf);
+ end = begin + darray_nprims_cdf_size_get(&scnview->nprims_cdf);
+ found = std::lower_bound(begin, end, i);
+ ASSERT(found != end);
+ ishape = found->ishape;
+ if(found != begin) {
+ ASSERT(i >= found[-1].nprims);
+ i -= found[-1].nprims;
+ }
+ }
+ pgeom = htable_geom_find(&scnview->cached_geoms, &ishape);
+ ASSERT(pgeom);
+ geom = *pgeom;
+ ASSERT(i < line_segments_get_nsegments(geom->lines));
+ prim->mesh__ = geom;
+ prim->geom_id = geom->name;
+ prim->prim_id = (unsigned)i;
+ prim->scene_prim_id = geom->scene_prim_id_offset + prim->prim_id;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+s2d_scene_view_primitives_count
+ (struct s2d_scene_view* scnview, size_t* prims_count)
+{
+ size_t nprims = 0;
+ res_T res = RES_OK;
+
+ if(!scnview || !prims_count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if((scnview->mask & S2D_GET_PRIMITIVE) != 0) {
+ const size_t len = darray_nprims_cdf_size_get(&scnview->nprims_cdf);
+ if(!len) {
+ nprims = 0;
+ } else {
+ nprims = darray_nprims_cdf_cdata_get(&scnview->nprims_cdf)[len-1].nprims;
+ }
+ } else {
+ struct htable_geom_iterator it, end;
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+ nprims = 0;
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry** pgeom = htable_geom_iterator_data_get(&it);
+ struct geometry* geom = *pgeom;
+ htable_geom_iterator_next(&it);
+
+ if(geom->is_enabled) {
+ nprims += line_segments_get_nsegments(geom->lines);
+ }
+ }
+ }
+
+exit:
+ if(prims_count) *prims_count = nprims;
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+s2d_scene_view_compute_contour_length
+ (struct s2d_scene_view* scnview, float* out_length)
+{
+ float length = 0;
+ res_T res = RES_OK;
+
+ if(!scnview || !out_length) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if((scnview->mask & S2D_SAMPLE) != 0) {
+ /* Retrieve the overall scene contour length from the scene cumulative
+ * distribution function. Note that the CDF stores the cumulative contour
+ * length. The real contour length is thus the CDF upper bound */
+ size_t len = darray_fltui_size_get(&scnview->cdf);
+ if(!len) {
+ length = 0.f;
+ } else {
+ length = darray_fltui_cdata_get(&scnview->cdf)[len-1].flt;
+ }
+ } else {
+ struct htable_geom_iterator it, end;
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+ length = 0.f;
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry** pgeom = htable_geom_iterator_data_get(&it);
+ struct geometry* geom = *pgeom;
+ htable_geom_iterator_next(&it);
+
+ if(geom->is_enabled) {
+ length += line_segments_compute_length(geom->lines);
+ }
+ }
+ }
+
+exit:
+ if(out_length) *out_length = length;
+ return res;
+error:
+ length = -1.f;
+ goto exit;
+}
+
+res_T
+s2d_scene_view_compute_area(struct s2d_scene_view* scnview, float* out_area)
+{
+ struct htable_geom_iterator it, end;
+ float area = 0.f;
+ res_T res = RES_OK;
+
+ if(!scnview || !out_area) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+ area = 0.f;
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry** pgeom = htable_geom_iterator_data_get(&it);
+ struct geometry* geom = *pgeom;
+ htable_geom_iterator_next(&it);
+
+ if(geom->is_enabled) {
+ area += line_segments_compute_area(geom->lines, geom->flip_contour);
+ }
+ }
+
+exit:
+ if(out_area) *out_area = area;
+ return res;
+error:
+ area = -1.f;
+ goto exit;
+}
+
+res_T
+s2d_scene_view_get_aabb
+ (struct s2d_scene_view* scnview, float lower[2], float upper[2])
+{
+ if(!scnview || !lower || !upper) return RES_BAD_ARG;
+ f2_set(lower, scnview->lower);
+ f2_set(upper, scnview->upper);
+ return RES_OK;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+scene_view_destroy(struct s2d_scene_view* scnview)
+{
+ htable_geom_iterator it, end;
+ ASSERT(scnview && !is_list_empty(&scnview->node)/*Not in use*/);
+ ASSERT(scnview->mask == 0);
+
+ /* Delete the cached geometries */
+ htable_geom_begin(&scnview->cached_geoms, &it);
+ htable_geom_end(&scnview->cached_geoms, &end);
+ while(!htable_geom_iterator_eq(&it, &end)) {
+ struct geometry** pgeom = htable_geom_iterator_data_get(&it);
+ struct geometry* geom = *pgeom;
+ scene_view_destroy_geometry(scnview, geom);
+ htable_geom_iterator_next(&it);
+ }
+
+ /* Delete the back-end scene */
+ if(scnview->rtc_scn) rtcDeleteScene(scnview->rtc_scn);
+
+ /* Release internal data structure */
+ htable_geom_release(&scnview->cached_geoms);
+ darray_geom_release(&scnview->embree2geoms);
+ darray_fltui_release(&scnview->cdf);
+ darray_nprims_cdf_release(&scnview->nprims_cdf);
+ darray_uint_release(&scnview->detached_shapes);
+
+ /* Remove the scnview from its pool */
+ list_del(&scnview->node);
+ CLBK_DISCONNECT(&scnview->on_shape_detach_cb);
+
+ /* Free the scnview memory space */
+ MEM_RM(scnview->scn->dev->allocator, scnview);
+}
+
diff --git a/src/s2d_scene_view_c.h b/src/s2d_scene_view_c.h
@@ -0,0 +1,119 @@
+/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms. */
+
+#ifndef S2D_SCENE_VIEW_C_H
+#define S2D_SCENE_VIEW_C_H
+
+#include "s2d_backend.h"
+#include "s2d_scene_c.h"
+
+#include <rsys/dynamic_array_uint.h>
+#include <rsys/hash_table.h>
+#include <rsys/list.h>
+#include <rsys/ref_count.h>
+
+/* Forward declarations */
+struct s2d_scene_view;
+
+/*
+ * The geometry pointers must be initialized to NULL in order to define
+ * which pointers are valid or not
+ */
+static FINLINE void
+geom_ptr_init__(struct mem_allocator* alloc, struct geometry** geom)
+{
+ (void)alloc; *geom = NULL;
+}
+
+/* Generate the darray_geom dynamic array */
+#define DARRAY_NAME geom
+#define DARRAY_DATA struct geometry*
+#define DARRAY_FUNCTOR_INIT geom_ptr_init__
+#include <rsys/dynamic_array.h>
+
+/* Generate the htable_geom hash table */
+#define HTABLE_NAME geom
+#define HTABLE_DATA struct geometry*
+#define HTABLE_KEY unsigned /* Id of the shape */
+#include <rsys/hash_table.h>
+
+/* Generate the darray_fltui dynamic array */
+struct fltui { float flt; unsigned ui; };
+#define DARRAY_NAME fltui
+#define DARRAY_DATA struct fltui
+#include <rsys/dynamic_array.h>
+
+/* Generate the darray_geom_nprims array */
+struct nprims_cdf { unsigned nprims, ishape; };
+#define DARRAY_NAME nprims_cdf
+#define DARRAY_DATA struct nprims_cdf
+#include <rsys/dynamic_array.h>
+
+struct s2d_scene_view {
+ struct list_node node; /* Attachment point to the scene scene_views pool */
+
+ struct htable_geom cached_geoms; /* Cached shape geometries */
+ struct darray_geom embree2geoms; /* Embree index to geometry */
+ struct darray_fltui cdf; /* Unormalized CDF */
+ struct darray_nprims_cdf nprims_cdf;
+
+ /* Id of Shapes detached while the scnview is active */
+ struct darray_uint detached_shapes;
+
+ float lower[2], upper[2]; /* AABB of the scene */
+
+ /* Callback attached to the sig_shape_detach signal of scn */
+ scene_shape_cb_T on_shape_detach_cb;
+
+ int mask; /* Combination of enum s3d_scene_view_flag */
+ int rtc_scn_update; /* Define if Embree geometries were deleted/added */
+ int rtc_commit; /* Define whether or not the Embree scene was committed */
+ RTCScene rtc_scn; /* Embree scene */
+
+ ref_T ref;
+ struct s2d_scene* scn;
+};
+
+extern LOCAL_SYM void
+scene_view_destroy
+ (struct s2d_scene_view* scnview);
+
+static FINLINE struct geometry*
+scene_view_geometry_from_embree_id
+ (struct s2d_scene_view* scnview,
+ const unsigned irtc)
+{
+ struct geometry* geom;
+ ASSERT(scnview && irtc != RTC_INVALID_GEOMETRY_ID);
+ ASSERT(irtc < darray_geom_size_get(&scnview->embree2geoms));
+ geom = darray_geom_data_get(&scnview->embree2geoms)[irtc];
+ ASSERT(geom);
+ return geom;
+}
+
+#endif /* S2D_SCENE_VIEW_C_H */
diff --git a/src/test_s2d_device.c b/src/test_s2d_device.c
@@ -46,40 +46,40 @@ main(int argc, char** argv)
struct s2d_device* dev;
(void)argc, (void)argv;
- CHECK(s2d_device_create(NULL, NULL, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_device_create(NULL, NULL, 0, &dev), RES_OK);
+ CHK(s2d_device_create(NULL, NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_device_create(NULL, NULL, 0, &dev) == RES_OK);
- CHECK(s2d_device_ref_get(NULL), RES_BAD_ARG);
- CHECK(s2d_device_ref_get(dev), RES_OK);
- CHECK(s2d_device_ref_put(NULL), RES_BAD_ARG);
- CHECK(s2d_device_ref_put(dev), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_device_ref_get(NULL) == RES_BAD_ARG);
+ CHK(s2d_device_ref_get(dev) == RES_OK);
+ CHK(s2d_device_ref_put(NULL) == RES_BAD_ARG);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
- CHECK(s2d_device_create(NULL, &allocator, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_device_create(NULL, &allocator, 0, &dev), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
+ CHK(s2d_device_create(NULL, &allocator, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- CHECK(logger_init(&allocator, &logger), RES_OK);
+ CHK(logger_init(&allocator, &logger) == RES_OK);
logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
- CHECK(s2d_device_create(&logger, NULL, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_device_create(&logger, NULL, 0, &dev), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_device_create(&logger, NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_device_create(&logger, NULL, 0, &dev) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
- CHECK(s2d_device_create(&logger, &allocator, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_device_create(&logger, &allocator, 0, &dev), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_device_create(&logger, &allocator, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_device_create(&logger, &allocator, 0, &dev) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
logger_release(&logger);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_primitive.c b/src/test_s2d_primitive.c
@@ -53,11 +53,11 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &dev), RES_OK);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
- CHECK(s2d_shape_get_id(shape, &box_id), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
+ CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
+ CHK(s2d_shape_get_id(shape, &box_id) == RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
vdata.usage = S2D_POSITION;
vdata.type = S2D_FLOAT2;
@@ -66,83 +66,83 @@ main(int argc, char** argv)
(shape, box_nsegs, line_segments_get_ids, box_nverts, &vdata, 1,
(void*)&box_desc), RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, &s), RES_OK);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, &s) == RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
#define GET_ATTRIB s2d_primitive_get_attrib
- CHECK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, 2, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, 2, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, s, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, s, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, 2, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, 2, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, s, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, s, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_POSITION, 2, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_POSITION, 2, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_POSITION, s, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_POSITION, s, NULL), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_POSITION, 2, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_POSITION, 2, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(NULL, S2D_POSITION, s, &attr), RES_BAD_ARG);
- CHECK(GET_ATTRIB(&prim, S2D_POSITION, s, &attr), RES_OK);
- CHECK(attr.type, S2D_FLOAT2);
- CHECK(attr.usage, S2D_POSITION);
-
- CHECK(GET_ATTRIB(&prim, S2D_GEOMETRY_NORMAL, s, &attr), RES_OK);
+ CHK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, 2, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, 2, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, s, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, s, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, 2, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, 2, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_ATTRIBS_COUNT__, s, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_ATTRIBS_COUNT__, s, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_POSITION, 2, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_POSITION, 2, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_POSITION, s, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_POSITION, s, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_POSITION, 2, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_POSITION, 2, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(NULL, S2D_POSITION, s, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTRIB(&prim, S2D_POSITION, s, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
+ CHK(attr.usage == S2D_POSITION);
+
+ CHK(GET_ATTRIB(&prim, S2D_GEOMETRY_NORMAL, s, &attr) == RES_OK);
f2_normalize(attr.value, attr.value);
switch(prim.prim_id) {
- case 0: CHECK(f2_eq_eps(attr.value, f2(tmp, 0.f, 1.f), 1.e-6f), 1); break;
- case 1: CHECK(f2_eq_eps(attr.value, f2(tmp, 1.f, 0.f), 1.e-6f), 1); break;
- case 2: CHECK(f2_eq_eps(attr.value, f2(tmp, 0.f,-1.f), 1.e-6f), 1); break;
- case 3: CHECK(f2_eq_eps(attr.value, f2(tmp,-1.f, 0.f), 1.e-6f), 1); break;
- default: CHECK(0, 1); /* Invalid primitive id */
+ case 0: CHK(f2_eq_eps(attr.value, f2(tmp, 0.f, 1.f), 1.e-6f) == 1); break;
+ case 1: CHK(f2_eq_eps(attr.value, f2(tmp, 1.f, 0.f), 1.e-6f) == 1); break;
+ case 2: CHK(f2_eq_eps(attr.value, f2(tmp, 0.f,-1.f), 1.e-6f) == 1); break;
+ case 3: CHK(f2_eq_eps(attr.value, f2(tmp,-1.f, 0.f), 1.e-6f) == 1); break;
+ default: CHK(0 == 1); /* Invalid primitive id */
}
- CHECK(GET_ATTRIB(&S2D_PRIMITIVE_NULL, S2D_GEOMETRY_NORMAL, s, &attr),
+ CHK(GET_ATTRIB(&S2D_PRIMITIVE_NULL, S2D_GEOMETRY_NORMAL, s == &attr),
RES_BAD_ARG);
#undef GET_ATTRIB
- CHECK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE), RES_OK);
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_OK);
- CHECK(nprims, 4);
- CHECK(s2d_scene_end_session(scn), RES_OK);
-
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_OK);
- CHECK(nprims, 4);
- CHECK(s2d_scene_end_session(scn), RES_OK);
-
- CHECK(s2d_primitive_compute_length(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_compute_length(&prim, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_compute_length(NULL, &length), RES_BAD_ARG);
- CHECK(s2d_primitive_compute_length(&prim, &length), RES_OK);
- CHECK(eq_epsf(length, 2, 1.e-6f), 1);
-
- CHECK(s2d_primitive_sample(NULL, 2.f, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(&prim, 2.f, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(NULL, 0.5f, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(&prim, 0.5f, NULL), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(NULL, 2.f, &s), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(&prim, 2.f, &s), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(NULL, 0.5f, &s), RES_BAD_ARG);
- CHECK(s2d_primitive_sample(&prim, 0.5f, &s), RES_OK);
- CHECK(eq_epsf(s, 0.5f, 1.e-6f), 1);
+ CHK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE) == RES_OK);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_OK);
+ CHK(nprims == 4);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_OK);
+ CHK(nprims == 4);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+
+ CHK(s2d_primitive_compute_length(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_compute_length(&prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_compute_length(NULL, &length) == RES_BAD_ARG);
+ CHK(s2d_primitive_compute_length(&prim, &length) == RES_OK);
+ CHK(eq_epsf(length, 2, 1.e-6f) == 1);
+
+ CHK(s2d_primitive_sample(NULL, 2.f, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(&prim, 2.f, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(NULL, 0.5f, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(&prim, 0.5f, NULL) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(NULL, 2.f, &s) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(&prim, 2.f, &s) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(NULL, 0.5f, &s) == RES_BAD_ARG);
+ CHK(s2d_primitive_sample(&prim, 0.5f, &s) == RES_OK);
+ CHK(eq_epsf(s, 0.5f, 1.e-6f) == 1);
FOR_EACH(i, 0, NSAMPS) {
- CHECK(s2d_primitive_sample(&prim, rand_canonic(), &s), RES_OK);
- CHECK(s >= 0.f, 1);
- CHECK(s <= 1.f, 1);
+ CHK(s2d_primitive_sample(&prim, rand_canonic(), &s) == RES_OK);
+ CHK(s >= 0.f == 1);
+ CHK(s <= 1.f == 1);
}
- CHECK(s2d_device_ref_put(dev), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_sample.c b/src/test_s2d_sample.c
@@ -49,47 +49,47 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &dev), RES_OK);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
-
- CHECK(s2d_shape_get_id(shape, &box_id), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
-
- CHECK(s2d_scene_sample(NULL, 1, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 1, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 1, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 1, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 1, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 0, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 0, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 0, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 1, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 1, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 1, NULL,&s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 1, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 0, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 0, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 0, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 0, NULL, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 1, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 1, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 1, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 1, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 1, 0, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 1, 0, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(NULL, 0, 0, &prim, &s), RES_BAD_ARG);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, &s), RES_OK);
- CHECK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL), 1);
+ CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
+
+ CHK(s2d_shape_get_id(shape, &box_id) == RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
+
+ CHK(s2d_scene_sample(NULL, 1, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 0, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 0, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 0, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 0, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 1, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 1, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 1, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 1, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 0, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 0, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 0, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 1, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 1, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 1, NULL,&s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 1, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 0, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 0, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 0, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 0, NULL, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 1, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 1, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 1, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 1, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 1, 0, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 1, 0, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(NULL, 0, 0, &prim, &s) == RES_BAD_ARG);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, &s) == RES_OK);
+ CHK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL) == 1);
vdata.usage = S2D_POSITION;
vdata.type = S2D_FLOAT2;
@@ -98,20 +98,20 @@ main(int argc, char** argv)
(shape, box_nsegs, line_segments_get_ids, box_nverts, &vdata, 1,
(void*)&box_desc), RES_OK);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, &s), RES_OK);
- CHECK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL), 1);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, &s) == RES_OK);
+ CHK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL) == 1);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, &s), RES_OK);
- CHECK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL), 0);
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, &s) == RES_OK);
+ CHK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL) == 0);
- CHECK(prim.prim_id < 4, 1);
- CHECK(prim.geom_id, box_id);
- CHECK(s, 0);
+ CHK(prim.prim_id < 4 == 1);
+ CHK(prim.geom_id == box_id);
+ CHK(s == 0);
/* Should take effect on the next session */
- CHECK(s2d_shape_flip_contour(shape), RES_OK);
+ CHK(s2d_shape_flip_contour(shape) == RES_OK);
FOR_EACH(i, 0, NSAMPS) {
struct s2d_attrib attr_position;
@@ -120,10 +120,10 @@ main(int argc, char** argv)
const float v = rand_canonic();
float N[2], P[2];
- CHECK(s2d_scene_sample(scn, u, v, &prim, &s), RES_OK);
- CHECK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL), 0);
- CHECK(prim.prim_id < 4, 1);
- CHECK(prim.geom_id, box_id);
+ CHK(s2d_scene_sample(scn, u, v, &prim, &s) == RES_OK);
+ CHK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL) == 0);
+ CHK(prim.prim_id < 4 == 1);
+ CHK(prim.geom_id == box_id);
CHECK(s2d_primitive_get_attrib
(&prim, S2D_POSITION, s, &attr_position), RES_OK);
@@ -137,32 +137,32 @@ main(int argc, char** argv)
case 1: f2(P, -1.f, 1.f*s + (1-s)*-1.f); f2(N, 1.f, 0.f); break;
case 2: f2(P, 1.f*s + (1-s)* -1.f, 1.f); f2(N, 0.f,-1.f); break;
case 3: f2(P, 1.f, -1.f*s + (1-s)* 1.f); f2(N,-1.f, 0.f); break;
- default: CHECK(0, 1); break; /* Invalid primitive id */
+ default: CHK(0 == 1); break; /* Invalid primitive id */
}
- CHECK(f2_eq_eps(P, attr_position.value, 1.e-6f), 1);
- CHECK(f2_eq_eps(N, attr_normal.value, 1.e-6f), 1);
+ CHK(f2_eq_eps(P, attr_position.value, 1.e-6f) == 1);
+ CHK(f2_eq_eps(N, attr_normal.value, 1.e-6f) == 1);
}
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
- CHECK(s2d_scene_sample(scn, 0, 0, &prim, &s), RES_BAD_OP);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
+ CHK(s2d_scene_sample(scn, 0, 0, &prim, &s) == RES_BAD_OP);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
FOR_EACH(i, 0, NSAMPS) {
struct s2d_attrib attr;
const float u = rand_canonic();
const float v = rand_canonic();
float N[2];
- CHECK(s2d_scene_sample(scn, u, v, &prim, &s), RES_OK);
- CHECK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL), 0);
- CHECK(prim.prim_id < 4, 1);
- CHECK(prim.geom_id, box_id);
+ CHK(s2d_scene_sample(scn, u, v, &prim, &s) == RES_OK);
+ CHK(S2D_PRIMITIVE_EQ(&prim, &S2D_PRIMITIVE_NULL) == 0);
+ CHK(prim.prim_id < 4 == 1);
+ CHK(prim.geom_id == box_id);
- CHECK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attr), RES_OK);
+ CHK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attr) == RES_OK);
f2_normalize(attr.value, attr.value);
switch(prim.prim_id) {
@@ -170,21 +170,21 @@ main(int argc, char** argv)
case 1: f2(N,-1.f, 0.f); break;
case 2: f2(N, 0.f, 1.f); break;
case 3: f2(N, 1.f, 0.f); break;
- default: CHECK(0, 1); break; /* Invalid primitive id */
+ default: CHK(0 == 1); break; /* Invalid primitive id */
}
- CHECK(f2_eq_eps(N, attr.value, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, attr.value, 1.e-6f) == 1);
}
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_scene.c b/src/test_s2d_scene.c
@@ -52,66 +52,66 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &dev), RES_OK);
-
- CHECK(s2d_scene_create(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_create(dev, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_create(NULL, &scn), RES_BAD_ARG);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
-
- CHECK(s2d_scene_ref_get(NULL), RES_BAD_ARG);
- CHECK(s2d_scene_ref_get(scn), RES_OK);
- CHECK(s2d_scene_ref_put(NULL), RES_BAD_ARG);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
-
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
-
- CHECK(s2d_scene_attach_shape(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_attach_shape(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_attach_shape(NULL, shape), RES_BAD_ARG);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_BAD_ARG);
-
- CHECK(s2d_scene_detach_shape(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_detach_shape(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_detach_shape(NULL, shape), RES_BAD_ARG);
- CHECK(s2d_scene_detach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_detach_shape(scn, shape), RES_BAD_ARG);
-
- CHECK(s2d_scene_clear(NULL), RES_BAD_ARG);
- CHECK(s2d_scene_clear(scn), RES_OK);
- CHECK(s2d_scene_clear(scn), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_clear(scn), RES_OK);
-
- CHECK(s2d_scene_begin_session(NULL, 0), RES_BAD_ARG);
- CHECK(s2d_scene_begin_session(scn, 0), RES_BAD_ARG);
- CHECK(s2d_scene_begin_session(NULL, S2D_TRACE), RES_BAD_ARG);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
-
- CHECK(s2d_scene_get_session_mask(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_session_mask(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_session_mask(NULL, &mask), RES_BAD_ARG);
- CHECK(s2d_scene_get_session_mask(scn, &mask), RES_OK);
- CHECK(mask, S2D_TRACE);
-
- CHECK(s2d_scene_primitives_count(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_primitives_count(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_primitives_count(NULL, &nprims), RES_BAD_ARG);
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_OK);
- CHECK(nprims, 0);
-
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_clear(scn), RES_BAD_OP);
- CHECK(s2d_scene_detach_shape(scn, shape), RES_OK);
-
- CHECK(s2d_scene_end_session(NULL), RES_BAD_ARG);
- CHECK(s2d_scene_end_session(scn), RES_OK);
- CHECK(s2d_scene_end_session(scn), RES_BAD_ARG);
- CHECK(s2d_scene_get_session_mask(scn, &mask), RES_OK);
- CHECK(mask, 0);
+ CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
+
+ CHK(s2d_scene_create(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_create(dev, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_create(NULL, &scn) == RES_BAD_ARG);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
+
+ CHK(s2d_scene_ref_get(NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_ref_get(scn) == RES_OK);
+ CHK(s2d_scene_ref_put(NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
+
+ CHK(s2d_scene_attach_shape(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_attach_shape(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_attach_shape(NULL, shape) == RES_BAD_ARG);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_BAD_ARG);
+
+ CHK(s2d_scene_detach_shape(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_detach_shape(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_detach_shape(NULL, shape) == RES_BAD_ARG);
+ CHK(s2d_scene_detach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_detach_shape(scn, shape) == RES_BAD_ARG);
+
+ CHK(s2d_scene_clear(NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_clear(scn) == RES_OK);
+ CHK(s2d_scene_clear(scn) == RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_clear(scn) == RES_OK);
+
+ CHK(s2d_scene_begin_session(NULL, 0) == RES_BAD_ARG);
+ CHK(s2d_scene_begin_session(scn, 0) == RES_BAD_ARG);
+ CHK(s2d_scene_begin_session(NULL, S2D_TRACE) == RES_BAD_ARG);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
+
+ CHK(s2d_scene_get_session_mask(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_session_mask(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_session_mask(NULL, &mask) == RES_BAD_ARG);
+ CHK(s2d_scene_get_session_mask(scn, &mask) == RES_OK);
+ CHK(mask == S2D_TRACE);
+
+ CHK(s2d_scene_primitives_count(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_primitives_count(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_primitives_count(NULL, &nprims) == RES_BAD_ARG);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_OK);
+ CHK(nprims == 0);
+
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_clear(scn) == RES_BAD_OP);
+ CHK(s2d_scene_detach_shape(scn, shape) == RES_OK);
+
+ CHK(s2d_scene_end_session(NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_BAD_ARG);
+ CHK(s2d_scene_get_session_mask(scn, &mask) == RES_OK);
+ CHK(mask == 0);
attrib.type = S2D_FLOAT2;
attrib.usage = S2D_POSITION;
@@ -120,36 +120,36 @@ main(int argc, char** argv)
(shape, box_nsegs, line_segments_get_ids, box_nverts, &attrib, 1,
(void*)&box_desc), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
- CHECK(s2d_scene_detach_shape(scn, shape), RES_BAD_OP);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
+ CHK(s2d_scene_detach_shape(scn, shape) == RES_BAD_OP);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_BAD_OP);
- CHECK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE), RES_OK);
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_OK);
- CHECK(nprims, 4);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_BAD_OP);
+ CHK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE) == RES_OK);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_OK);
+ CHK(nprims == 4);
- CHECK(s2d_scene_get_primitive(NULL, 5, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(scn, 5, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(NULL, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(scn, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(NULL, 5, &prim), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(scn, 5, &prim), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(NULL, 0, &prim), RES_BAD_ARG);
- CHECK(s2d_scene_get_primitive(scn, 0, &prim), RES_OK);
+ CHK(s2d_scene_get_primitive(NULL, 5, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(scn, 5, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(scn, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(NULL, 5, &prim) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(scn, 5, &prim) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(NULL, 0, &prim) == RES_BAD_ARG);
+ CHK(s2d_scene_get_primitive(scn, 0, &prim) == RES_OK);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_get_primitive(scn, 0, &prim), RES_BAD_OP);
+ CHK(s2d_scene_get_primitive(scn, 0, &prim) == RES_BAD_OP);
- CHECK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_GET_PRIMITIVE) == RES_OK);
FOR_EACH(i, 0, nprims) {
struct s2d_attrib attr;
float tmp[2];
- CHECK(s2d_scene_get_primitive(scn, (unsigned)i, &prim), RES_OK);
- CHECK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, 0, &attr), RES_OK);
+ CHK(s2d_scene_get_primitive(scn, (unsigned)i, &prim) == RES_OK);
+ CHK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, 0, &attr) == RES_OK);
f2_normalize(attr.value, attr.value);
switch(i) {
case 0: f2_eq_eps(attr.value, f2(tmp, 0.f, 1.f), 1.e-6f); break;
@@ -160,71 +160,71 @@ main(int argc, char** argv)
}
}
- CHECK(s2d_scene_compute_contour_length(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_compute_contour_length(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_compute_contour_length(NULL, &length), RES_BAD_ARG);
- CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK);
- CHECK(eq_epsf(length, 8.f, 1.e-6f), 1);
-
- CHECK(s2d_scene_compute_area(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_compute_area(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_compute_area(NULL, &area), RES_BAD_ARG);
- CHECK(s2d_scene_compute_area(scn, &area), RES_OK);
- CHECK(eq_epsf(area, 4.f, 1.e-6f), 1);
-
- CHECK(s2d_scene_get_aabb(NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(scn, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(NULL, lower, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(scn, lower, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(NULL, NULL, upper), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(scn, NULL, upper), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(NULL, lower, upper), RES_BAD_ARG);
- CHECK(s2d_scene_get_aabb(scn, lower, upper), RES_OK);
- CHECK(f2_eq_eps(lower, f2(tmp, -1.f, -1.f), 1.e-6f), 1);
- CHECK(f2_eq_eps(upper, f2(tmp, 1.f, 1.f), 1.e-6f), 1);
-
- CHECK(s2d_scene_end_session(scn), RES_OK);
-
- CHECK(s2d_scene_compute_contour_length(scn, &length), RES_BAD_OP);
- CHECK(s2d_scene_compute_area(scn, &area), RES_BAD_OP);
- CHECK(s2d_scene_get_aabb(scn, lower, upper), RES_BAD_OP);
-
- CHECK(s2d_shape_flip_contour(shape), RES_OK);
-
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
-
- CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK);
- CHECK(eq_epsf(length, 8.f, 1.e-6f), 1);
-
- CHECK(s2d_scene_compute_area(scn, &area), RES_OK);
- CHECK(eq_epsf(area, -4.f, 1.e-6f), 1);
-
- CHECK(s2d_scene_end_session(scn), RES_OK);
-
- CHECK(s2d_scene_clear(scn), RES_OK);
- CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK);
- CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK);
- CHECK(length, 0.f);
- CHECK(s2d_scene_compute_area(scn, &area), RES_OK);
- CHECK(area, 0.f);
- CHECK(s2d_scene_get_aabb(scn, lower, upper), RES_OK);
- CHECK(lower[0] > upper[0], 1);
- CHECK(lower[1] > upper[1], 1);
- CHECK(s2d_scene_end_session(scn), RES_OK);
-
- CHECK(s2d_scene_get_device(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_device(scn, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_get_device(NULL, &dev2), RES_BAD_ARG);
- CHECK(s2d_scene_get_device(scn, &dev2), RES_OK);
- CHECK(dev2, dev);
-
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_scene_compute_contour_length(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_contour_length(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_contour_length(NULL, &length) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_contour_length(scn, &length) == RES_OK);
+ CHK(eq_epsf(length, 8.f, 1.e-6f) == 1);
+
+ CHK(s2d_scene_compute_area(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_area(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_area(NULL, &area) == RES_BAD_ARG);
+ CHK(s2d_scene_compute_area(scn, &area) == RES_OK);
+ CHK(eq_epsf(area, 4.f, 1.e-6f) == 1);
+
+ CHK(s2d_scene_get_aabb(NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(scn, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(NULL, lower, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(scn, lower, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(NULL, NULL, upper) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(scn, NULL, upper) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(NULL, lower, upper) == RES_BAD_ARG);
+ CHK(s2d_scene_get_aabb(scn, lower, upper) == RES_OK);
+ CHK(f2_eq_eps(lower, f2(tmp, -1.f, -1.f), 1.e-6f) == 1);
+ CHK(f2_eq_eps(upper, f2(tmp, 1.f, 1.f), 1.e-6f) == 1);
+
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+
+ CHK(s2d_scene_compute_contour_length(scn, &length) == RES_BAD_OP);
+ CHK(s2d_scene_compute_area(scn, &area) == RES_BAD_OP);
+ CHK(s2d_scene_get_aabb(scn, lower, upper) == RES_BAD_OP);
+
+ CHK(s2d_shape_flip_contour(shape) == RES_OK);
+
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
+
+ CHK(s2d_scene_compute_contour_length(scn, &length) == RES_OK);
+ CHK(eq_epsf(length, 8.f, 1.e-6f) == 1);
+
+ CHK(s2d_scene_compute_area(scn, &area) == RES_OK);
+ CHK(eq_epsf(area, -4.f, 1.e-6f) == 1);
+
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+
+ CHK(s2d_scene_clear(scn) == RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_SAMPLE) == RES_OK);
+ CHK(s2d_scene_compute_contour_length(scn, &length) == RES_OK);
+ CHK(length == 0.f);
+ CHK(s2d_scene_compute_area(scn, &area) == RES_OK);
+ CHK(area == 0.f);
+ CHK(s2d_scene_get_aabb(scn, lower, upper) == RES_OK);
+ CHK(lower[0] > upper[0] == 1);
+ CHK(lower[1] > upper[1] == 1);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
+
+ CHK(s2d_scene_get_device(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_device(scn, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_get_device(NULL, &dev2) == RES_BAD_ARG);
+ CHK(s2d_scene_get_device(scn, &dev2) == RES_OK);
+ CHK(dev2 == dev);
+
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_session_advanced.c b/src/test_s2d_session_advanced.c
@@ -48,11 +48,11 @@ static INLINE float*
ran_semi_disk_cos(const float up[2], float samp[2])
{
float tmp[2], v[2];
- CHECK(f2_is_normalized(samp), 1);
+ CHK(f2_is_normalized(samp) == 1);
ran_semi_disk_cos_local(tmp);
v[0] = -up[1] * tmp[0] + up[0]*tmp[1];
v[1] = up[0] * tmp[0] + up[1]*tmp[1];;
- CHECK(f2_is_normalized(v), 1);
+ CHK(f2_is_normalized(v) == 1);
return f2_set(samp, v);
}
@@ -65,10 +65,10 @@ discard_self_hit
void* filter_data)
{
struct s2d_primitive* prim_from = ray_data;
- NCHECK(hit, NULL);
- NCHECK(org, NULL);
- NCHECK(dir, NULL);
- CHECK((intptr_t)filter_data, (intptr_t)0xDECAFBAD);
+ CHK(hit != NULL);
+ CHK(org != NULL);
+ CHK(dir != NULL);
+ CHK((intptr_t)filter_data == (intptr_t)0xDECAFBAD);
if(!ray_data) return 0;
return S2D_PRIMITIVE_EQ(prim_from, &hit->prim);
}
@@ -88,14 +88,14 @@ create_circle_shape
const double step = 2.0*PI/(double)nsteps;
unsigned i;
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
CHECK(s2d_line_segments_set_hit_filter_function
(shape, discard_self_hit, (void*)0xDECAFBAD), RES_OK);
- CHECK(nsteps > 4, 1);
- NCHECK(center, NULL);
- NCHECK(sa_add(positions, nsteps*2/*#coords per vertex*/), NULL);
- NCHECK(sa_add(indices, nsteps*2/*#ids per segment*/), NULL);
+ CHK(nsteps > 4 == 1);
+ CHK(center != NULL);
+ CHK(sa_add(positions, nsteps*2/*#coords per vertex*/) != NULL);
+ CHK(sa_add(indices, nsteps*2/*#ids per segment*/) != NULL);
FOR_EACH(i, 0, nsteps) {
const double theta = i*step;
@@ -121,7 +121,7 @@ create_circle_shape
(shape, nsteps, line_segments_get_ids, nsteps, &vdata, 1, (void*)&desc),
RES_OK);
- CHECK(s2d_shape_flip_contour(shape), RES_OK);
+ CHK(s2d_shape_flip_contour(shape) == RES_OK);
sa_release(positions);
sa_release(indices);
@@ -151,35 +151,35 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 0, &dev), RES_OK);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
+ CHK(s2d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
- NCHECK(sa_add(shape_prims[0], shape_nsteps[0]), NULL);
- NCHECK(sa_add(shape_prims[1], shape_nsteps[1]), NULL);
- NCHECK(sa_add(shape_prims[2], shape_nsteps[2]), NULL);
+ CHK(sa_add(shape_prims[0], shape_nsteps[0]) != NULL);
+ CHK(sa_add(shape_prims[1], shape_nsteps[1]) != NULL);
+ CHK(sa_add(shape_prims[2], shape_nsteps[2]) != NULL);
NCHECK(sa_add
(scene_prims, shape_nsteps[0]+shape_nsteps[1]+shape_nsteps[2]), NULL);
shape = create_circle_shape(dev, 1.f, f2(tmp, 0.f, 0.f), shape_nsteps[0]);
- CHECK(s2d_shape_get_id(shape, &shape_ids[0]), RES_OK);
- NCHECK(shape_ids[0], S2D_INVALID_ID);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_shape_get_id(shape, &shape_ids[0]) == RES_OK);
+ CHK(shape_ids[0] != S2D_INVALID_ID);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
shape = create_circle_shape(dev, 0.5f, f2(tmp, 2.f, 0.5f), shape_nsteps[1]);
- CHECK(s2d_shape_get_id(shape, &shape_ids[1]), RES_OK);
- NCHECK(shape_ids[1], S2D_INVALID_ID);
- NCHECK(shape_ids[1], shape_ids[0]);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_shape_get_id(shape, &shape_ids[1]) == RES_OK);
+ CHK(shape_ids[1] != S2D_INVALID_ID);
+ CHK(shape_ids[1] != shape_ids[0]);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
shape = create_circle_shape(dev, 0.25f, f2(tmp, 1.5f, -0.25f), shape_nsteps[2]);
- CHECK(s2d_shape_get_id(shape, &shape_ids[2]), RES_OK);
- NCHECK(shape_ids[2], S2D_INVALID_ID);
- NCHECK(shape_ids[2], shape_ids[0]);
- NCHECK(shape_ids[2], shape_ids[1]);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_shape_get_id(shape, &shape_ids[2]) == RES_OK);
+ CHK(shape_ids[2] != S2D_INVALID_ID);
+ CHK(shape_ids[2] != shape_ids[0]);
+ CHK(shape_ids[2] != shape_ids[1]);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
CHECK(s2d_scene_begin_session
(scn, S2D_SAMPLE|S2D_GET_PRIMITIVE|S2D_TRACE), RES_OK);
@@ -192,55 +192,55 @@ main(int argc, char** argv)
FOR_EACH(i, 0, 1024) {
struct s2d_attrib attr;
float s;
- CHECK(s2d_scene_sample(scn, rand_canonic(), rand_canonic(), &prim, &s), RES_OK);
- CHECK(s2d_primitive_get_attrib(&prim, S2D_POSITION, s, &attr), RES_OK);
- CHECK(attr.type, S2D_FLOAT2);
+ CHK(s2d_scene_sample(scn, rand_canonic(), rand_canonic(), &prim, &s) == RES_OK);
+ CHK(s2d_primitive_get_attrib(&prim, S2D_POSITION, s, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
FOR_EACH(ishape, 0, 3) if(prim.geom_id == shape_ids[ishape]) break;
- NCHECK(ishape, 3);
+ CHK(ishape != 3);
/* Mark the shape primitive as sampled */
- CHECK(prim.prim_id < shape_nsteps[ishape], 1);
+ CHK(prim.prim_id < shape_nsteps[ishape] == 1);
shape_prims[ishape][prim.prim_id] = 1;
/* Mark the scene primitive as sampled */
- CHECK(prim.scene_prim_id < sa_size(scene_prims), 1);
+ CHK(prim.scene_prim_id < sa_size(scene_prims) == 1);
scene_prims[prim.scene_prim_id] = 1;
}
/* Check that all primitives were sampled */
- FOR_EACH(i, 0, sa_size(shape_prims[0])) CHECK(shape_prims[0][i], 1);
- FOR_EACH(i, 0, sa_size(shape_prims[1])) CHECK(shape_prims[1][i], 1);
- FOR_EACH(i, 0, sa_size(shape_prims[2])) CHECK(shape_prims[2][i], 1);
- FOR_EACH(i, 0, sa_size(scene_prims)) CHECK(scene_prims[i], 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[0])) CHK(shape_prims[0][i] == 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[1])) CHK(shape_prims[1][i] == 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[2])) CHK(shape_prims[2][i] == 1);
+ FOR_EACH(i, 0, sa_size(scene_prims)) CHK(scene_prims[i] == 1);
/* Check iteration */
memset(shape_prims[0], 0, sa_size(shape_prims[0])*sizeof(shape_prims[0][0]));
memset(shape_prims[1], 0, sa_size(shape_prims[1])*sizeof(shape_prims[1][0]));
memset(shape_prims[2], 0, sa_size(shape_prims[2])*sizeof(shape_prims[2][0]));
memset(scene_prims, 0, sa_size(scene_prims)*sizeof(scene_prims[0]));
- CHECK(s2d_scene_primitives_count(scn, &nprims), RES_OK);
- CHECK(sa_size(scene_prims), nprims);
+ CHK(s2d_scene_primitives_count(scn, &nprims) == RES_OK);
+ CHK(sa_size(scene_prims) == nprims);
FOR_EACH(i, 0, nprims) {
- CHECK(s2d_scene_get_primitive(scn, (unsigned)i, &prim), RES_OK);
+ CHK(s2d_scene_get_primitive(scn, (unsigned)i, &prim) == RES_OK);
FOR_EACH(ishape, 0, 3) if(prim.geom_id == shape_ids[ishape]) break;
- NCHECK(ishape, 3);
+ CHK(ishape != 3);
/* Mark the shape primitive as visited */
- CHECK(prim.prim_id < shape_nsteps[ishape], 1);
+ CHK(prim.prim_id < shape_nsteps[ishape] == 1);
shape_prims[ishape][prim.prim_id] = 1;
/* Mark the scene primitive as visited */
- CHECK(prim.scene_prim_id < sa_size(scene_prims), 1);
+ CHK(prim.scene_prim_id < sa_size(scene_prims) == 1);
scene_prims[prim.scene_prim_id] = 1;
}
/* Check that all primitives were visited */
- FOR_EACH(i, 0, sa_size(shape_prims[0])) CHECK(shape_prims[0][i], 1);
- FOR_EACH(i, 0, sa_size(shape_prims[1])) CHECK(shape_prims[1][i], 1);
- FOR_EACH(i, 0, sa_size(shape_prims[2])) CHECK(shape_prims[2][i], 1);
- FOR_EACH(i, 0, sa_size(scene_prims)) CHECK(scene_prims[i], 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[0])) CHK(shape_prims[0][i] == 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[1])) CHK(shape_prims[1][i] == 1);
+ FOR_EACH(i, 0, sa_size(shape_prims[2])) CHK(shape_prims[2][i] == 1);
+ FOR_EACH(i, 0, sa_size(scene_prims)) CHK(scene_prims[i] == 1);
/* Check the ray tracing by numerically compute PI*S/P aka 4V/S in 2D */
sum = sum_sqr = 0;
@@ -251,39 +251,39 @@ main(int argc, char** argv)
float P[2], N[2];
float s;
- CHECK(s2d_scene_sample(scn, rand_canonic(), rand_canonic(), &prim, &s), RES_OK);
+ CHK(s2d_scene_sample(scn, rand_canonic(), rand_canonic(), &prim, &s) == RES_OK);
- CHECK(s2d_primitive_get_attrib(&prim, S2D_POSITION, s, &attr), RES_OK);
- CHECK(attr.type, S2D_FLOAT2);
+ CHK(s2d_primitive_get_attrib(&prim, S2D_POSITION, s, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
f2_set(P, attr.value);
- CHECK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attr), RES_OK);
- CHECK(attr.type, S2D_FLOAT2);
- NCHECK(f2_normalize(N, attr.value), 0.f);
+ CHK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
+ CHK(f2_normalize(N, attr.value) != 0.f);
f2_normalize(tmp, f2(tmp, 1, 1));
ran_semi_disk_cos(N, tmp);
- CHECK(s2d_scene_trace_ray(scn, P, tmp, range, &prim, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
+ CHK(s2d_scene_trace_ray(scn, P, tmp, range, &prim, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
sum += hit.distance;
sum_sqr += hit.distance*hit.distance;
}
- CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK);
- CHECK(s2d_scene_compute_area(scn, &area), RES_OK);
+ CHK(s2d_scene_compute_contour_length(scn, &length) == RES_OK);
+ CHK(s2d_scene_compute_area(scn, &area) == RES_OK);
E = sum / (float)NSAMPS;
V = sum_sqr / (float)NSAMPS - E*E;
SE = (float)sqrt(V/(float)NSAMPS);
printf("PI*S / P = %g ~ %g +/- %g\n",(float)PI*area / length, E, SE);
- CHECK(eq_epsf((float)PI*area / length, E, SE), 1);
+ CHK(eq_epsf((float)PI*area / length, E, SE) == 1);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
sa_release(scene_prims);
sa_release(shape_prims[0]);
@@ -292,7 +292,7 @@ main(int argc, char** argv)
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_shape.c b/src/test_s2d_shape.c
@@ -63,32 +63,32 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 0, &dev), RES_OK);
+ CHK(s2d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
- CHECK(s2d_shape_create_line_segments(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_create_line_segments(dev, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_create_line_segments(NULL, &shape), RES_BAD_ARG);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
+ CHK(s2d_shape_create_line_segments(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_create_line_segments(dev, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_create_line_segments(NULL, &shape) == RES_BAD_ARG);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
- CHECK(s2d_shape_ref_get(NULL), RES_BAD_ARG);
- CHECK(s2d_shape_ref_get(shape), RES_OK);
- CHECK(s2d_shape_ref_put(NULL), RES_BAD_ARG);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
+ CHK(s2d_shape_ref_get(NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_ref_get(shape) == RES_OK);
+ CHK(s2d_shape_ref_put(NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
- CHECK(s2d_shape_get_id(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_get_id(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_get_id(NULL, &id), RES_BAD_ARG);
- CHECK(s2d_shape_get_id(shape, &id), RES_OK);
- NCHECK(id, S2D_INVALID_ID);
+ CHK(s2d_shape_get_id(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_get_id(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_get_id(NULL, &id) == RES_BAD_ARG);
+ CHK(s2d_shape_get_id(shape, &id) == RES_OK);
+ CHK(id != S2D_INVALID_ID);
- CHECK(s2d_shape_is_attached(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_is_attached(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_is_attached(NULL, &c), RES_BAD_ARG);
- CHECK(s2d_shape_is_attached(shape, &c), RES_OK);
- CHECK(c, 0);
+ CHK(s2d_shape_is_attached(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_is_attached(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_is_attached(NULL, &c) == RES_BAD_ARG);
+ CHK(s2d_shape_is_attached(shape, &c) == RES_OK);
+ CHK(c == 0);
vdata[0].type = S2D_FLOAT2;
vdata[0].usage = S2D_POSITION;
@@ -96,189 +96,189 @@ main(int argc, char** argv)
#define SETUP s2d_line_segments_setup_indexed_vertices
#define box_get_ids line_segments_get_ids
- CHECK(SETUP(NULL, 0, NULL, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, 0, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, NULL, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, 0, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 0, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, 0, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, NULL, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, 0, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, NULL, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, NULL, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, NULL, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, NULL, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, 0, box_get_ids, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, 0, box_get_ids, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(NULL, nsegs, box_get_ids, nverts, vdata, 1, data), RES_BAD_ARG);
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data), RES_OK);
+ CHK(SETUP(NULL, 0, NULL, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, 0, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, NULL, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, 0, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 0, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, NULL, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, 0, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, NULL, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, NULL, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, NULL, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, NULL, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, 0, box_get_ids, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, 0, box_get_ids, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(NULL, nsegs, box_get_ids, nverts, vdata, 1, data) == RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data) == RES_OK);
vdata[0] = S2D_VERTEX_DATA_NULL;
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data), RES_BAD_ARG);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data) == RES_BAD_ARG);
vdata[0].type = S2D_FLOAT2;
vdata[0].usage = S2D_POSITION;
vdata[0].get = S2D_KEEP;
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data), RES_OK);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data) == RES_OK);
vdata[0].get = line_segments_get_position;
- CHECK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data), RES_OK);
+ CHK(SETUP(shape, nsegs, box_get_ids, nverts, vdata, 1, data) == RES_OK);
#undef box_get_ids
#undef SETUP
- CHECK(s2d_line_segments_get_vertices_count(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_vertices_count(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_vertices_count(NULL, &n), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_vertices_count(shape, &n), RES_OK);
- CHECK(n, nverts);
+ CHK(s2d_line_segments_get_vertices_count(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_vertices_count(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_vertices_count(NULL, &n) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_vertices_count(shape, &n) == RES_OK);
+ CHK(n == nverts);
- CHECK(s2d_line_segments_get_segments_count(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segments_count(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segments_count(NULL, &n), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segments_count(shape, &n), RES_OK);
- CHECK(n, nsegs);
+ CHK(s2d_line_segments_get_segments_count(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segments_count(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segments_count(NULL, &n) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segments_count(shape, &n) == RES_OK);
+ CHK(n == nsegs);
#define GET_ATTR s2d_line_segments_get_vertex_attrib
- CHECK(GET_ATTR(NULL, nverts, S2D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, nverts, S2D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, 0, S2D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, 0, S2D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, nverts, S2D_POSITION, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, nverts, S2D_POSITION, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, 0, S2D_POSITION, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, 0, S2D_POSITION, NULL), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, nverts, S2D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, nverts, S2D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, 0, S2D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, 0, S2D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, nverts, S2D_POSITION, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(shape, nverts, S2D_POSITION, &attr), RES_BAD_ARG);
- CHECK(GET_ATTR(NULL, 0, S2D_POSITION, &attr), RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, nverts, S2D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, nverts, S2D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, 0, S2D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, 0, S2D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, nverts, S2D_POSITION, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, nverts, S2D_POSITION, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, 0, S2D_POSITION, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, 0, S2D_POSITION, NULL) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, nverts, S2D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, nverts, S2D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, 0, S2D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, 0, S2D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, nverts, S2D_POSITION, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(shape, nverts, S2D_POSITION, &attr) == RES_BAD_ARG);
+ CHK(GET_ATTR(NULL, 0, S2D_POSITION, &attr) == RES_BAD_ARG);
FOR_EACH(id, 0, nverts) {
float pos[2];
line_segments_get_position(id, pos, data);
- CHECK(GET_ATTR(shape, id, S2D_POSITION, &attr), RES_OK);
- CHECK(attr.type, S2D_FLOAT2);
- CHECK(attr.usage, S2D_POSITION);
- CHECK(f2_eq_eps(attr.value, pos, 1.e-6f), 1);
+ CHK(GET_ATTR(shape, id, S2D_POSITION, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
+ CHK(attr.usage == S2D_POSITION);
+ CHK(f2_eq_eps(attr.value, pos, 1.e-6f) == 1);
}
#undef GET_ATTR
- CHECK(s2d_line_segments_get_segment_indices(NULL, nsegs, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(shape, nsegs, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(NULL, nsegs, ids), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(shape, nsegs, ids), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(NULL, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(shape, 0, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_get_segment_indices(NULL, 0, ids), RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(NULL, nsegs, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(shape, nsegs, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(NULL, nsegs, ids) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(shape, nsegs, ids) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(shape, 0, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_get_segment_indices(NULL, 0, ids) == RES_BAD_ARG);
FOR_EACH(id, 0, nsegs) {
unsigned indices[2];
line_segments_get_ids(id, indices, data);
- CHECK(s2d_line_segments_get_segment_indices(shape, id, ids), RES_OK);
- CHECK(ids[0], indices[0]);
- CHECK(ids[1], indices[1]);
+ CHK(s2d_line_segments_get_segment_indices(shape, id, ids) == RES_OK);
+ CHK(ids[0] == indices[0]);
+ CHK(ids[1] == indices[1]);
}
- CHECK(s2d_shape_is_enabled(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_is_enabled(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_shape_is_enabled(NULL, &c), RES_BAD_ARG);
- CHECK(s2d_shape_is_enabled(shape, &c), RES_OK);
- NCHECK(c, 0);
+ CHK(s2d_shape_is_enabled(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_is_enabled(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_is_enabled(NULL, &c) == RES_BAD_ARG);
+ CHK(s2d_shape_is_enabled(shape, &c) == RES_OK);
+ CHK(c != 0);
- CHECK(s2d_shape_enable(NULL, 0), RES_BAD_ARG);
- CHECK(s2d_shape_enable(shape, 0), RES_OK);
- CHECK(s2d_shape_is_enabled(shape, &c), RES_OK);
- CHECK(c, 0);
+ CHK(s2d_shape_enable(NULL, 0) == RES_BAD_ARG);
+ CHK(s2d_shape_enable(shape, 0) == RES_OK);
+ CHK(s2d_shape_is_enabled(shape, &c) == RES_OK);
+ CHK(c == 0);
- CHECK(s2d_shape_flip_contour(NULL), RES_BAD_ARG);
- CHECK(s2d_shape_flip_contour(shape), RES_OK);
- CHECK(s2d_shape_flip_contour(shape), RES_OK);
+ CHK(s2d_shape_flip_contour(NULL) == RES_BAD_ARG);
+ CHK(s2d_shape_flip_contour(shape) == RES_OK);
+ CHK(s2d_shape_flip_contour(shape) == RES_OK);
#define SET_FILTER_FUNC s2d_line_segments_set_hit_filter_function
#define GET_FILTER_DATA s2d_line_segments_get_hit_filter_data
- CHECK(SET_FILTER_FUNC(NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(SET_FILTER_FUNC(shape, NULL, NULL), RES_OK);
- CHECK(SET_FILTER_FUNC(NULL, filter_none, NULL), RES_BAD_ARG);
- CHECK(SET_FILTER_FUNC(shape, filter_none, NULL), RES_OK);
-
- CHECK(GET_FILTER_DATA(NULL, NULL), RES_BAD_ARG);
- CHECK(GET_FILTER_DATA(shape, NULL), RES_BAD_ARG);
- CHECK(GET_FILTER_DATA(NULL, &data), RES_BAD_ARG);
- CHECK(GET_FILTER_DATA(shape, &data), RES_OK);
- CHECK(data, NULL);
-
- CHECK(SET_FILTER_FUNC(shape, NULL, NULL), RES_OK);
- CHECK(GET_FILTER_DATA(shape, &data), RES_OK);
- CHECK(data, NULL);
- CHECK(SET_FILTER_FUNC(shape, filter_none, (void*)(uintptr_t)0xDEADBEEF), RES_OK);
- CHECK(GET_FILTER_DATA(shape, &data), RES_OK);
- CHECK((uintptr_t)data, 0xDEADBEEF);
+ CHK(SET_FILTER_FUNC(NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(SET_FILTER_FUNC(shape, NULL, NULL) == RES_OK);
+ CHK(SET_FILTER_FUNC(NULL, filter_none, NULL) == RES_BAD_ARG);
+ CHK(SET_FILTER_FUNC(shape, filter_none, NULL) == RES_OK);
+
+ CHK(GET_FILTER_DATA(NULL, NULL) == RES_BAD_ARG);
+ CHK(GET_FILTER_DATA(shape, NULL) == RES_BAD_ARG);
+ CHK(GET_FILTER_DATA(NULL, &data) == RES_BAD_ARG);
+ CHK(GET_FILTER_DATA(shape, &data) == RES_OK);
+ CHK(data == NULL);
+
+ CHK(SET_FILTER_FUNC(shape, NULL, NULL) == RES_OK);
+ CHK(GET_FILTER_DATA(shape, &data) == RES_OK);
+ CHK(data == NULL);
+ CHK(SET_FILTER_FUNC(shape, filter_none, (void*)(uintptr_t)0xDEADBEEF) == RES_OK);
+ CHK(GET_FILTER_DATA(shape, &data) == RES_OK);
+ CHK((uintptr_t)data == 0xDEADBEEF);
#undef SET_FILTER_FUNC
#undef GET_FILTER_DATA
- CHECK(s2d_shape_create_line_segments(dev, &shape_copy), RES_OK);
- CHECK(s2d_line_segments_copy(NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_copy(shape, NULL), RES_BAD_ARG);
- CHECK(s2d_line_segments_copy(NULL, shape_copy), RES_BAD_ARG);
- CHECK(s2d_line_segments_copy(shape, shape_copy), RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape_copy) == RES_OK);
+ CHK(s2d_line_segments_copy(NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_copy(shape, NULL) == RES_BAD_ARG);
+ CHK(s2d_line_segments_copy(NULL, shape_copy) == RES_BAD_ARG);
+ CHK(s2d_line_segments_copy(shape, shape_copy) == RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_shape_ref_put(shape_copy), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
+ CHK(s2d_shape_ref_put(shape_copy) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_trace_ray.c b/src/test_s2d_trace_ray.c
@@ -40,8 +40,8 @@ filter_hit
void* filter_data)
{
(void)dir, (void)org;
- NCHECK(hit, NULL);
- CHECK((intptr_t)filter_data, 0xDEADBEEF);
+ CHK(hit != NULL);
+ CHK((intptr_t)filter_data == 0xDEADBEEF);
if(!ray_data) return 0;
return S2D_PRIMITIVE_EQ((struct s2d_primitive*)ray_data, &hit->prim);
}
@@ -62,9 +62,9 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &dev), RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
+ CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
vdata.type = S2D_FLOAT2;
vdata.usage = S2D_POSITION;
@@ -74,166 +74,166 @@ main(int argc, char** argv)
(void*)&box_desc), RES_OK);
#define SET_FILTER_FUNC s2d_line_segments_set_hit_filter_function
- CHECK(SET_FILTER_FUNC(NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(SET_FILTER_FUNC(shape, NULL, NULL), RES_OK);
- CHECK(SET_FILTER_FUNC(NULL, filter_hit, NULL), RES_BAD_ARG);
- CHECK(SET_FILTER_FUNC(shape, filter_hit, NULL), RES_OK);
- CHECK(SET_FILTER_FUNC(shape, filter_hit, (void*)0xDEADBEEF), RES_OK);
+ CHK(SET_FILTER_FUNC(NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(SET_FILTER_FUNC(shape, NULL, NULL) == RES_OK);
+ CHK(SET_FILTER_FUNC(NULL, filter_hit, NULL) == RES_BAD_ARG);
+ CHK(SET_FILTER_FUNC(shape, filter_hit, NULL) == RES_OK);
+ CHK(SET_FILTER_FUNC(shape, filter_hit, (void*)0xDEADBEEF) == RES_OK);
#undef SET_FILTER_FUNC
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
f2(org, 0.f, 0.f);
f2(dir, 0.f, -1.f);
f2(range, 0, FLT_MAX);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
-
- CHECK(s2d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, org, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, NULL, dir, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(scn, NULL, dir, range, NULL, &hit), RES_BAD_ARG);
- CHECK(s2d_scene_trace_ray(NULL, org, dir, range, NULL, &hit), RES_BAD_ARG);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
+
+ CHK(s2d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(NULL, org, dir, range, NULL, &hit) == RES_BAD_ARG);
f2(dir, 0.f, -1.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(hit.prim.prim_id, 0);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(hit.prim.prim_id == 0);
f2_normalize(N, hit.normal);
- CHECK(f2_eq_eps(N, f2(dir, 0.f, 1.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.0f, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, f2(dir, 0.f, 1.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
prim = hit.prim;
f2(dir, 0.f, -1.f);
range[1] = 0.5f;
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 1);
range[1] = FLT_MAX;
f2(dir, 0.f, -1.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, &prim, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, &prim, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 1);
f2(dir, -1.f, 0.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(hit.prim.prim_id, 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(hit.prim.prim_id == 1);
f2_normalize(N, hit.normal);
- CHECK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.0f, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
f2(dir, 0.f, 1.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(hit.prim.prim_id, 2);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(hit.prim.prim_id == 2);
f2_normalize(N, hit.normal);
- CHECK(f2_eq_eps(N, f2(dir, 0.f, -1.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.0f, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, f2(dir, 0.f, -1.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
prim2 = hit.prim;
f2(org, 0.f, 2.f);
f2(dir, 0.f, -1.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(S2D_PRIMITIVE_EQ(&hit.prim, &prim2), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim2) == 1);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, &prim2, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(S2D_PRIMITIVE_EQ(&hit.prim, &prim), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, &prim2, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim) == 1);
f2_splat(org, 0.f);
f2(dir, 1.f, 0.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(hit.prim.prim_id, 3);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(hit.prim.prim_id == 3);
f2_normalize(N, hit.normal);
- CHECK(f2_eq_eps(N, f2(dir, -1.f, 0.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.0f, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, f2(dir, -1.f, 0.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
f2(range, 1.f, -1.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 1);
f2(dir, 1.f, 1.f);
f2(range, 0.f, FLT_MAX);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_BAD_ARG);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_BAD_ARG);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
f2(dir, 1.f, 0.f);
f2(range, 0.f, FLT_MAX);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_BAD_OP);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_BAD_OP);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
f2_sub(dir, f2(dir, 0.75f, -1.f), org);
f2_normalize(dir, dir);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(eq_epsf(hit.u, 0.125f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.25, 1.E-6f), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(eq_epsf(hit.u, 0.125f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.25, 1.E-6f) == 1);
f2_sub(dir, f2(dir, -1.f, 0.25f), org);
f2_normalize(dir, dir);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(eq_epsf(hit.u, 0.625, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, (float)sqrt(1.0625f), 1e-6f), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(eq_epsf(hit.u, 0.625, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, (float)sqrt(1.0625f), 1e-6f) == 1);
f2(org, -1.25f, 0.f);
f2(dir, -1, 0.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 1);
f2(dir, 1, 0.f);
- CHECK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
- CHECK(hit.prim.prim_id, 1);
+ CHK(s2d_scene_trace_ray(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
+ CHK(hit.prim.prim_id == 1);
f2_normalize(N, hit.normal);
- CHECK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 0.25f, 1.e-6f), 1);
+ CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 0.25f, 1.e-6f) == 1);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_trace_ray_3d.c b/src/test_s2d_trace_ray_3d.c
@@ -50,10 +50,10 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &dev), RES_OK);
- CHECK(s2d_scene_create(dev, &scn), RES_OK);
- CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
+ CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
+ CHK(s2d_scene_create(dev, &scn) == RES_OK);
+ CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
+ CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
vdata.get = line_segments_get_position;
vdata.type = S2D_FLOAT2;
@@ -66,74 +66,74 @@ main(int argc, char** argv)
f3(dir, 1, 0, 0);
f2(range, 0, FLT_MAX);
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE), RES_OK);
+ CHK(s2d_scene_begin_session(scn, S2D_TRACE) == RES_OK);
#define TRACE_3D s2d_scene_trace_ray_3d
- CHECK(TRACE_3D(NULL, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, dir, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, NULL, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, dir, range, NULL, NULL), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, NULL, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, dir, NULL, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, NULL, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, NULL, dir, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, NULL, dir, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(NULL, org, dir, range, NULL, &hit), RES_BAD_ARG);
- CHECK(TRACE_3D(scn, org, dir, range, NULL, &hit), RES_OK);
-
- CHECK(S2D_HIT_NONE(&hit), 0);
+ CHK(TRACE_3D(NULL, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, dir, range, NULL, NULL) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(NULL, org, dir, range, NULL, &hit) == RES_BAD_ARG);
+ CHK(TRACE_3D(scn, org, dir, range, NULL, &hit) == RES_OK);
+
+ CHK(S2D_HIT_NONE(&hit) == 0);
f2_normalize(hit.normal, hit.normal);
- CHECK(f2_eq_eps(hit.normal, f2(tmp, -1.f, 0.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.distance, 1.f, 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
+ CHK(f2_eq_eps(hit.normal, f2(tmp, -1.f, 0.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.distance, 1.f, 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
f3_normalize(dir, f3(dir, 1.f, 0.f, 1.f));
- CHECK(TRACE_3D(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 0);
+ CHK(TRACE_3D(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 0);
f2_normalize(hit.normal, hit.normal);
- CHECK(f2_eq_eps(hit.normal, f2(tmp, -1.f, 0.f), 1.e-6f), 1);
- CHECK(eq_epsf(hit.u, 0.5f, 1.e-6f), 1);
+ CHK(f2_eq_eps(hit.normal, f2(tmp, -1.f, 0.f), 1.e-6f) == 1);
+ CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
dot = dir[0];
- CHECK(eq_epsf(hit.distance, 1.f / dot, 1.e-6f), 1);
+ CHK(eq_epsf(hit.distance, 1.f / dot, 1.e-6f) == 1);
range[1] = 1.2f;
- CHECK(TRACE_3D(scn, org, dir, range, NULL, &hit), RES_OK);
- CHECK(S2D_HIT_NONE(&hit), 1);
+ CHK(TRACE_3D(scn, org, dir, range, NULL, &hit) == RES_OK);
+ CHK(S2D_HIT_NONE(&hit) == 1);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ CHK(s2d_scene_end_session(scn) == RES_OK);
- CHECK(TRACE_3D(scn, org, dir, range, NULL, &hit), RES_BAD_OP);
+ CHK(TRACE_3D(scn, org, dir, range, NULL, &hit) == RES_BAD_OP);
#undef TRACE_3D
- CHECK(s2d_scene_ref_put(scn), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_device_ref_put(dev), RES_OK);
+ CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_shape_ref_put(shape) == RES_OK);
+ CHK(s2d_device_ref_put(dev) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_s2d_utils.h b/src/test_s2d_utils.h
@@ -63,7 +63,7 @@ line_segments_get_ids(const unsigned isegment, unsigned ids[2], void* data)
{
const unsigned id = isegment * 2;
const struct line_segments_desc* desc = data;
- NCHECK(desc, NULL);
+ CHK(desc != NULL);
ids[0] = desc->indices[id + 0];
ids[1] = desc->indices[id + 1];
}
@@ -73,7 +73,7 @@ line_segments_get_position(const unsigned ivert, float position[2], void* data)
{
const unsigned id = ivert * 2;
const struct line_segments_desc* desc = data;
- NCHECK(desc, NULL);
+ CHK(desc != NULL);
position[0] = desc->vertices[id + 0];
position[1] = desc->vertices[id + 1];
}