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:
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);