commit 3289952fd733c2de94b1e5735ca15637b7a01254
parent dafd321577b8fd0b578582467c73357c90719f06
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 4 Nov 2015 14:48:38 +0100
Add and test mesh data getters
Implement the s3d_mesh_get_<triangles|vertices>_count and
s3d_mesh_get_<vertex_attrib|triangle_indices> functions.
Diffstat:
3 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -439,6 +439,29 @@ s3d_mesh_copy
(const struct s3d_shape* src,
struct s3d_shape* dst);
+S3D_API res_T
+s3d_mesh_get_vertices_count
+ (const struct s3d_shape* shape,
+ unsigned* nverts);
+
+S3D_API res_T
+s3d_mesh_get_vertex_attrib
+ (const struct s3d_shape* shape,
+ const unsigned ivert,
+ const enum s3d_attrib_usage usage,
+ struct s3d_attrib* attrib);
+
+S3D_API res_T
+s3d_mesh_get_triangles_count
+ (const struct s3d_shape* shape,
+ unsigned* ntris);
+
+S3D_API res_T
+s3d_mesh_get_triangle_indices
+ (const struct s3d_shape* shape,
+ const unsigned itri,
+ unsigned ids[3]);
+
/*******************************************************************************
* Instance API - An instance is a shape that encapsulates a scene and that
* supports a local to world transformation. Since the scene geometry is stored
diff --git a/src/s3d_shape.c b/src/s3d_shape.c
@@ -31,6 +31,7 @@
* knowledge of the CeCILL license and that you accept its terms. */
#include "s3d.h"
+#include "s3d_c.h"
#include "s3d_device_c.h"
#include "s3d_scene_c.h"
#include "s3d_shape_c.h"
@@ -275,3 +276,65 @@ s3d_mesh_copy
return RES_OK;
}
+res_T
+s3d_mesh_get_vertices_count(const struct s3d_shape* shape, unsigned* nverts)
+{
+ if(!shape || !nverts || shape->type != GEOM_MESH) return RES_BAD_ARG;
+ *nverts = (unsigned)mesh_get_nverts(shape->data.mesh);
+ return RES_OK;
+}
+
+res_T
+s3d_mesh_get_vertex_attrib
+ (const struct s3d_shape* shape,
+ const unsigned ivert,
+ const enum s3d_attrib_usage usage,
+ struct s3d_attrib* attrib)
+{
+ const float* data;
+ unsigned i, dim;
+ if(!shape
+ || shape->type != GEOM_MESH
+ || (unsigned)usage >= S3D_ATTRIBS_COUNT__
+ || !shape->data.mesh->attribs[usage]
+ || !attrib
+ || ivert >= (unsigned)mesh_get_nverts(shape->data.mesh))
+ return RES_BAD_ARG;
+
+ attrib->usage = usage;
+ attrib->type = shape->data.mesh->attribs_type[usage];
+
+ dim = s3d_type_get_dimension(attrib->type);
+ data = mesh_get_attr(shape->data.mesh, usage) + ivert * dim;
+ FOR_EACH(i, 0, dim) attrib->value[i] = data[i];
+ return RES_OK;
+}
+
+res_T
+s3d_mesh_get_triangles_count(const struct s3d_shape* shape, unsigned* ntris)
+{
+ if(!shape || !ntris || shape->type != GEOM_MESH) return RES_BAD_ARG;
+ *ntris = (unsigned)mesh_get_ntris(shape->data.mesh);
+ return RES_OK;
+}
+
+res_T
+s3d_mesh_get_triangle_indices
+ (const struct s3d_shape* shape,
+ const unsigned itri,
+ unsigned ids[3])
+{
+ const unsigned* data;
+ if(!shape
+ || shape->type != GEOM_MESH
+ || !ids
+ || itri >= (unsigned)mesh_get_ntris(shape->data.mesh))
+ return RES_BAD_ARG;
+
+ data = mesh_get_ids(shape->data.mesh) + itri * 3;
+ ids[0] = data[0];
+ ids[1] = data[1];
+ ids[2] = data[2];
+ return RES_OK;
+}
+
diff --git a/src/test_s3d_shape.c b/src/test_s3d_shape.c
@@ -34,6 +34,7 @@
#include "test_s3d_cbox.h"
#include "test_s3d_utils.h"
+#include <rsys/float3.h>
#include <rsys/math.h>
int
@@ -46,6 +47,9 @@ main(int argc, char** argv)
struct s3d_shape* inst;
struct s3d_scene* scn;
struct s3d_vertex_data attribs[4];
+ struct s3d_attrib attr;
+ unsigned nverts, ntris;
+ unsigned ids[3];
float pos[3];
const unsigned cbox_ntris = sizeof(cbox_walls_ids) / sizeof(unsigned[3]);
const unsigned cbox_nverts = sizeof(cbox_walls) / sizeof(float[3]);
@@ -189,7 +193,6 @@ main(int argc, char** argv)
attribs[2].type = S3D_FLOAT2;
attribs[2].usage = S3D_ATTRIB_2;
attribs[2].get = cbox_get_uv;
- attribs[3] = S3D_VERTEX_DATA_NULL;
CHECK(s3d_mesh_setup_indexed_vertices
(shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data), RES_OK);
@@ -211,6 +214,65 @@ main(int argc, char** argv)
CHECK(s3d_mesh_setup_indexed_vertices
(shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 2, data), RES_OK);
+ CHECK(s3d_mesh_get_vertices_count(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertices_count(shape, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertices_count(NULL, &nverts), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertices_count(shape, &nverts), RES_OK);
+ CHECK(nverts, cbox_nverts);
+
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_POSITION, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, &attr), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, &attr), RES_BAD_ARG);
+ FOR_EACH(id, 0, nverts) {
+ cbox_get_position(id, pos, data);
+
+ CHECK(s3d_mesh_get_vertex_attrib(shape, id, S3D_POSITION, &attr), RES_OK);
+ CHECK(attr.type, S3D_FLOAT3);
+ CHECK(attr.usage, S3D_POSITION);
+ CHECK(f3_eq_eps(attr.value, pos, 1.e-6f), 1);
+
+ CHECK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_0, &attr), RES_OK);
+ CHECK(attr.type, S3D_FLOAT3);
+ CHECK(attr.usage, S3D_ATTRIB_0);
+ CHECK(f3_eq_eps(attr.value, pos, 1.e-6f), 1);
+ }
+ CHECK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_1, &attr), RES_BAD_ARG);
+
+ CHECK(s3d_mesh_get_triangles_count(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangles_count(shape, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangles_count(NULL, &ntris), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangles_count(shape, &ntris), RES_OK);
+ CHECK(ntris, cbox_ntris);
+
+ CHECK(s3d_mesh_get_triangle_indices(NULL, ntris, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(shape, ntris, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(shape, 0, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(NULL, ntris, ids), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(shape, ntris, ids), RES_BAD_ARG);
+ CHECK(s3d_mesh_get_triangle_indices(NULL, 0, ids), RES_BAD_ARG);
+
+ FOR_EACH(id, 0, ntris) {
+ unsigned indices[3];
+ CHECK(s3d_mesh_get_triangle_indices(shape, id, ids), RES_OK);
+ cbox_get_ids(id, indices, data);
+ CHECK(ids[0], indices[0]);
+ CHECK(ids[1], indices[1]);
+ CHECK(ids[2], indices[2]);
+ }
+
CHECK(s3d_shape_is_enabled(NULL, NULL), RES_BAD_ARG);
CHECK(s3d_shape_is_enabled(shape, NULL), RES_BAD_ARG);
CHECK(s3d_shape_is_enabled(NULL, &c), RES_BAD_ARG);