commit fff4552e9a86d43f0bb0da8515173ff1a4eb8c2d
parent 4a6590b500b657c3fcd1dad2473cc68988df8d03
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 9 Oct 2018 11:11:09 +0200
Add and test the s2d_segment_get_vertex_attrib function
Diffstat:
3 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/src/s2d.h b/src/s2d.h
@@ -402,6 +402,13 @@ s2d_primitive_compute_length
(const struct s2d_primitive* prim,
float* area);
+S2D_API res_T
+s2d_segment_get_vertex_attrib
+ (const struct s2d_primitive* prim,
+ const size_t ivertex, /* in [0..2[ */
+ const enum s2d_attrib_usage usage,
+ struct s2d_attrib* attrib); /* Resulting attrib */
+
/*******************************************************************************
* Line Segments API - manage a list of segments
******************************************************************************/
diff --git a/src/s2d_primitive.c b/src/s2d_primitive.c
@@ -27,12 +27,25 @@
* knowledge of the CeCILL license and that you accept its terms. */
#include "s2d.h"
+#include "s2d_c.h"
#include "s2d_geometry.h"
#include "s2d_line_segments.h"
#include <rsys/float2.h>
/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static int
+check_primitive(const struct s2d_primitive* prim)
+{
+ return prim
+ && prim->geom_id != S2D_INVALID_ID
+ && prim->prim_id != S2D_INVALID_ID
+ && prim->mesh__ != NULL;
+}
+
+/*******************************************************************************
* Exported functions
******************************************************************************/
res_T
@@ -46,20 +59,13 @@ s2d_primitive_get_attrib
struct geometry* geom = NULL;
res_T res = RES_OK;
- if(!prim
+ if(!check_primitive(prim)
|| !attrib
|| (usage != S2D_GEOMETRY_NORMAL && (unsigned)usage >= S2D_ATTRIBS_COUNT__)) {
res = RES_BAD_ARG;
goto error;
}
- if(prim->geom_id == S2D_INVALID_ID
- || prim->prim_id == S2D_INVALID_ID
- || prim->mesh__ == NULL) {
- res = RES_BAD_ARG;
- goto error;
- }
-
/* Unnormalized barycentric coordinates */
if(s < 0.f || s > 1.f) {
res = RES_BAD_ARG;
@@ -126,7 +132,7 @@ s2d_primitive_sample
const float u,
float* s)
{
- if(!prim || S2D_PRIMITIVE_EQ(prim, &S2D_PRIMITIVE_NULL) || !s)
+ if(!check_primitive(prim) || !s)
return RES_BAD_ARG;
if(u < 0.f || u >= 1.f)
@@ -148,7 +154,7 @@ s2d_primitive_compute_length(const s2d_primitive* prim, float* length)
float tmp[2];
struct geometry* geom;
- if(!prim || !length || S2D_PRIMITIVE_EQ(prim, &S2D_PRIMITIVE_NULL))
+ if(!check_primitive(prim) || !length)
return RES_BAD_ARG;
geom = (struct geometry*)prim->mesh__;
@@ -160,3 +166,52 @@ s2d_primitive_compute_length(const s2d_primitive* prim, float* length)
return RES_OK;
}
+res_T
+s2d_segment_get_vertex_attrib
+ (const struct s2d_primitive* prim,
+ const size_t ivertex, /* in [0..2[ */
+ const enum s2d_attrib_usage usage,
+ struct s2d_attrib* attrib) /* Resulting attrib */
+{
+ struct geometry* geom;
+ const uint32_t* ids;
+
+ if(!check_primitive(prim) || ivertex > 1
+ || (unsigned)usage >= S2D_ATTRIBS_COUNT__ || !attrib) {
+ return RES_BAD_ARG;
+ }
+
+ geom = (struct geometry*)prim->mesh__;
+ ASSERT(prim->geom_id == geom->name);
+
+ /* The segment have not the required attrib */
+ if(!geom->lines->attribs[usage]) {
+ return RES_BAD_ARG;
+ }
+
+ /* Out of bound primitive index */
+ if(prim->prim_id >= line_segments_get_nverts(geom->lines)) {
+ return RES_BAD_ARG;
+ }
+
+ ids = line_segments_get_ids(geom->lines) + prim->prim_id*2/*#segment ids*/;
+ attrib->usage = usage;
+
+ if(usage != S2D_POSITION) {
+ const float* attr;
+ unsigned i, dim;
+ attrib->type = geom->lines->attribs_type[usage];
+ /* Fetch attrib data */
+ dim = s2d_type_get_dimension(attrib->type);
+ attr = line_segments_get_attr(geom->lines, usage) + ids[ivertex]*dim;
+ FOR_EACH(i, 0, dim) attrib->value[i] = attr[i];
+ } else {
+ const float* pos;
+ attrib->type = S2D_FLOAT2;
+ /* Fetch data */
+ pos = line_segments_get_pos(geom->lines) + ids[ivertex]*2;
+ f2_set(attrib->value, pos);
+ }
+ return RES_OK;
+}
+
diff --git a/src/test_s2d_primitive.c b/src/test_s2d_primitive.c
@@ -108,7 +108,6 @@ main(int argc, char** argv)
CHK(s2d_scene_view_create(scn, S2D_GET_PRIMITIVE, &scnview) == RES_OK);
CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK);
CHK(nprims == 4);
- CHK(s2d_scene_view_ref_put(scnview) == RES_OK);
CHK(s2d_primitive_compute_length(NULL, NULL) == RES_BAD_ARG);
CHK(s2d_primitive_compute_length(&prim, NULL) == RES_BAD_ARG);
@@ -124,7 +123,7 @@ main(int argc, char** argv)
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);
+ CHK(eq_epsf(s, 0.5f, 1.e-6f));
FOR_EACH(i, 0, NSAMPS) {
CHK(s2d_primitive_sample(&prim, rand_canonic(), &s) == RES_OK);
@@ -132,8 +131,23 @@ main(int argc, char** argv)
CHK(s <= 1.f);
}
+ CHK(s2d_scene_view_get_primitive(scnview, 0, &prim) == RES_OK);
+
+ #define GET_VERTEX_ATTR s2d_segment_get_vertex_attrib
+ CHK(GET_VERTEX_ATTR(NULL, 0, S2D_POSITION, &attr) == RES_BAD_ARG);
+ CHK(GET_VERTEX_ATTR(&prim, 2, S2D_POSITION, &attr) == RES_BAD_ARG);
+ CHK(GET_VERTEX_ATTR(&prim, 0, S2D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG);
+ CHK(GET_VERTEX_ATTR(&prim, 0, S2D_POSITION, NULL) == RES_BAD_ARG);
+ CHK(GET_VERTEX_ATTR(&prim, 0, S2D_POSITION, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
+ CHK(f2_eq_eps(attr.value, square_verts + square_ids[0]*2, 1.e-6f));
+ CHK(GET_VERTEX_ATTR(&prim, 1, S2D_POSITION, &attr) == RES_OK);
+ CHK(attr.type == S2D_FLOAT2);
+ CHK(f2_eq_eps(attr.value, square_verts + square_ids[1]*2, 1.e-6f));
+
CHK(s2d_device_ref_put(dev) == RES_OK);
CHK(s2d_scene_ref_put(scn) == RES_OK);
+ CHK(s2d_scene_view_ref_put(scnview) == RES_OK);
CHK(s2d_shape_ref_put(shape) == RES_OK);
check_memory_allocator(&allocator);