star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

commit 230c96562e070530c6d11f36f24a62463a770047
parent c21b5df24322460a06fae21b68bf8943eb15f901
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 27 Jul 2015 15:11:30 +0200

Add and test the s3d_shape_primitives_count function

This function returns the number of geometric primitives of a shape. If
the shape is an instantiated scene, the returned value is the sum of the
instantiated primitives.

Diffstat:
Msrc/s3d.h | 8+++++++-
Msrc/s3d_instance.c | 18++++++++++++++++++
Msrc/s3d_instance.h | 4++++
Msrc/s3d_mesh.h | 2+-
Msrc/s3d_shape.c | 17+++++++++++++++++
Msrc/test_s3d_shape.c | 10++++++++++
Msrc/test_s3d_trace_ray.c | 23++++++++++++++++++-----
7 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -331,6 +331,12 @@ S3D_API res_T s3d_shape_flip_surface (struct s3d_shape* shape); +/* Get the number of primitives */ +S3D_API res_T +s3d_shape_primitives_count + (struct s3d_shape* shape, + size_t* primitives_count); + /******************************************************************************* * Sampler API ******************************************************************************/ @@ -381,7 +387,7 @@ s3d_primitive_get_attrib struct s3d_attrib* attrib); /* Resulting attrib */ /******************************************************************************* - * Mesh API - Define a triangular meshes + * Mesh API - Manage a triangular meshes ******************************************************************************/ /* Set/update the data of the indexed triangular meshes */ S3D_API res_T diff --git a/src/s3d_instance.c b/src/s3d_instance.c @@ -34,6 +34,7 @@ #include "s3d_backend.h" #include "s3d_device_c.h" #include "s3d_instance.h" +#include "s3d_shape_c.h" #include "s3d_scene_c.h" #include <rsys/float33.h> @@ -104,3 +105,20 @@ instance_ref_put(struct instance* inst) ref_put(&inst->ref, instance_release); } +size_t +instance_get_ntris(struct instance* inst) +{ + size_t ntris = 0; + struct list_node* node; + LIST_FOR_EACH(node, &inst->scene->shapes) { + struct s3d_shape* shape = CONTAINER_OF + (node, struct s3d_shape, scene_attachment); + switch(shape->type) { + case SHAPE_INSTANCE: ntris += instance_get_ntris(shape->data.instance); break; + case SHAPE_MESH: ntris += mesh_get_ntris(shape->data.mesh); break; + default: FATAL("Unreachable code\n"); break; + } + } + return ntris; +} + diff --git a/src/s3d_instance.h b/src/s3d_instance.h @@ -62,5 +62,9 @@ extern LOCAL_SYM void instance_ref_put (struct instance* inst); +extern LOCAL_SYM size_t +instance_get_ntris + (struct instance* inst); + #endif /* S3D_INSTANCE_H */ diff --git a/src/s3d_mesh.h b/src/s3d_mesh.h @@ -66,7 +66,7 @@ struct mesh { /* Triangular mesh */ int update_mask; /* Combination of buffer_type */ struct geometry geom; - char flip_surface; + char flip_surface; unsigned id; /* Unique identifier of a mesh */ diff --git a/src/s3d_shape.c b/src/s3d_shape.c @@ -225,6 +225,23 @@ s3d_shape_flip_surface(struct s3d_shape* shape) } res_T +s3d_shape_primitives_count(struct s3d_shape* shape, size_t* nprims) +{ + if(!shape || !nprims) + return RES_BAD_ARG; + switch(shape->type) { + case SHAPE_MESH: + *nprims = mesh_get_ntris(shape->data.mesh); + break; + case SHAPE_INSTANCE: + *nprims = instance_get_ntris(shape->data.instance); + break; + default: FATAL("Unreachable code\n"); break; + } + return RES_OK; +} + +res_T s3d_instance_set_position (struct s3d_shape* shape, const float position[3]) { diff --git a/src/test_s3d_shape.c b/src/test_s3d_shape.c @@ -43,6 +43,7 @@ main(int argc, char** argv) struct s3d_shape* inst; struct s3d_scene* scn; struct s3d_vertex_data attribs[4]; + size_t nprims; float pos[3]; const unsigned cbox_ntris = sizeof(cbox_walls_ids) / sizeof(unsigned[3]); const unsigned cbox_nverts = sizeof(cbox_walls) / sizeof(float[3]); @@ -73,6 +74,12 @@ main(int argc, char** argv) CHECK(s3d_shape_is_attached(shape, &c), RES_OK); CHECK(c, 0); + CHECK(s3d_shape_primitives_count(NULL, NULL), RES_BAD_ARG); + CHECK(s3d_shape_primitives_count(shape, NULL), RES_BAD_ARG); + CHECK(s3d_shape_primitives_count(NULL, &nprims), RES_BAD_ARG); + CHECK(s3d_shape_primitives_count(shape, &nprims), RES_OK); + CHECK(nprims, 0); + CHECK(s3d_scene_attach_shape(NULL, NULL), RES_BAD_ARG); CHECK(s3d_scene_attach_shape(scn, NULL), RES_BAD_ARG); CHECK(s3d_scene_attach_shape(NULL, shape), RES_BAD_ARG); @@ -156,6 +163,9 @@ main(int argc, char** argv) CHECK(s3d_mesh_setup_indexed_vertices (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, data), RES_OK); + CHECK(s3d_shape_primitives_count(shape, &nprims), RES_OK); + CHECK(nprims, 10); + attribs[0] = S3D_VERTEX_DATA_NULL; CHECK(s3d_mesh_setup_indexed_vertices (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, data), RES_BAD_ARG); diff --git a/src/test_s3d_trace_ray.c b/src/test_s3d_trace_ray.c @@ -98,6 +98,7 @@ main(int argc, char** argv) struct cbox_desc desc; unsigned char* img = NULL; unsigned ntris, nverts; + size_t nprims; size_t ix, iy; float org[3] = { 0.f, 0.f, 0.f }; float dir[3] = { 0.f, 1.f, 0.f }; @@ -172,6 +173,7 @@ main(int argc, char** argv) f3(dir, 0.f, 1.f, 0.f); CHECK(s3d_scene_trace_ray(scn, org, dir, range, &hit), RES_BAD_OP); + CHECK(s3d_scene_clear(scn), RES_OK); /* Update the inst with the CBox tall block mesh */ ntris = sizeof(cbox_block_ids)/sizeof(unsigned[3]); @@ -182,6 +184,8 @@ main(int argc, char** argv) CHECK(s3d_shape_get_id(tall_block, &tall_block_id), RES_OK); CHECK(s3d_mesh_setup_indexed_vertices (tall_block, ntris, cbox_get_ids, nverts, attribs, &desc), RES_OK); + CHECK(s3d_shape_primitives_count(tall_block, &nprims), RES_OK); + CHECK(nprims, 10); CHECK(s3d_scene_attach_shape(scn, tall_block), RES_OK); /* Update the inst vertices */ @@ -195,9 +199,17 @@ main(int argc, char** argv) CHECK(s3d_shape_get_id(short_block, &short_block_id), RES_OK); CHECK(s3d_mesh_setup_indexed_vertices (short_block, ntris, cbox_get_ids, nverts, attribs, &desc), RES_OK); + CHECK(s3d_shape_primitives_count(short_block, &nprims), RES_OK); + CHECK(nprims, 10); CHECK(s3d_scene_attach_shape(scn, short_block), RES_OK); - /* Create the CBox walls inst */ + /* Instantiate the scene */ + CHECK(s3d_scene_instantiate(scn, &inst), RES_OK); + CHECK(s3d_shape_primitives_count(inst, &nprims), RES_OK); + CHECK(nprims, 20); + CHECK(s3d_shape_get_id(inst, &inst_id), RES_OK); + + /* Create the CBox walls */ desc.indices = cbox_walls_ids; desc.vertices = cbox_walls; nverts = sizeof(cbox_walls)/sizeof(float[3]); @@ -206,18 +218,20 @@ main(int argc, char** argv) CHECK(s3d_shape_get_id(walls, &walls_id), RES_OK); CHECK(s3d_mesh_setup_indexed_vertices (walls, ntris, cbox_get_ids, nverts, attribs, &desc), RES_OK); + CHECK(s3d_shape_primitives_count(walls, &nprims), RES_OK); + CHECK(nprims, 10); CHECK(s3d_scene_attach_shape(scn, walls), RES_OK); + CHECK(s3d_shape_primitives_count(inst, &nprims), RES_OK); + CHECK(nprims, 30); /* Check that the ids are all different */ NCHECK(walls_id, short_block_id); NCHECK(walls_id, tall_block_id); NCHECK(short_block_id, tall_block_id); - /* Instantiate the whole CBox */ + /* Attach the CBox instance to a scene */ CHECK(s3d_scene_create(dev, &scn2), RES_OK); f3(org, -100.f, 0.f, -2.f); - CHECK(s3d_scene_instantiate(scn, &inst), RES_OK); - CHECK(s3d_shape_get_id(inst, &inst_id), RES_OK); CHECK(s3d_scene_attach_shape(scn2, inst), RES_OK); CHECK(s3d_instance_set_position(inst, org), RES_OK); @@ -243,7 +257,6 @@ main(int argc, char** argv) CHECK(s3d_scene_attach_shape(scn, short_block), RES_OK); CHECK(s3d_scene_attach_shape(scn, tall_block), RES_OK); - CHECK(s3d_scene_begin_trace(scn2), RES_OK); camera_init(&cam);