commit dafd321577b8fd0b578582467c73357c90719f06
parent 332dff54eed2e32a406010ecbdfbd5983b711733
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 21 Oct 2015 15:46:06 +0200
Add and test the s3d_mesh_copy function
Share the index and vertex buffers between the source an the destination
of the copy. Copy the internal flag of the shape (flip_surface,
is_enabled).
Diffstat:
6 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -433,6 +433,12 @@ s3d_mesh_setup_indexed_vertices
const unsigned nattribs, /* # attributes in the attribs list */
void* data); /* Client data set as the last param of the callbacks */
+/* Copy the mesh data from `src' to `dst' */
+S3D_API res_T
+s3d_mesh_copy
+ (const struct s3d_shape* src,
+ struct s3d_shape* dst);
+
/*******************************************************************************
* 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_mesh.c b/src/s3d_mesh.c
@@ -546,3 +546,60 @@ mesh_compute_aabb(struct mesh* mesh, float lower[3], float upper[3])
}
}
+void
+mesh_copy_indexed_vertices(const struct mesh* src, struct mesh* dst)
+{
+ size_t ntris_src;
+ size_t ntris_dst;
+ size_t nverts_src;
+ size_t nverts_dst;
+ int i;
+ ASSERT(src && dst && src != dst);
+
+ ntris_src = mesh_get_ntris(src);
+ ntris_dst = mesh_get_ntris(dst);
+ nverts_src = mesh_get_nverts(src);
+ nverts_dst = mesh_get_nverts(dst);
+
+ /* Setup the index buffer masks */
+ if(ntris_src == ntris_dst) {
+ dst->update_mask = (INDEX_BUFFER & !dst->resize_mask);
+ } else {
+ dst->resize_mask |= INDEX_BUFFER;
+ dst->update_mask &= !INDEX_BUFFER;
+ }
+
+ /* Release the previous index buffer of dst */
+ if(dst->indices) {
+ index_buffer_ref_put(dst->indices);
+ dst->indices = NULL;
+ }
+ /* Get a reference onto the index buffer of src */
+ if(src->indices) {
+ index_buffer_ref_get(src->indices);
+ dst->indices = src->indices;
+ }
+
+ /* Setup the vertex buffer masks */
+ if(nverts_src == nverts_dst) {
+ dst->update_mask = (VERTEX_BUFFER & ~dst->resize_mask);
+ } else {
+ dst->resize_mask |= VERTEX_BUFFER;
+ dst->update_mask &= !VERTEX_BUFFER;
+ }
+
+ FOR_EACH(i, 0, S3D_ATTRIBS_COUNT__) {
+ /* Release the previous vertex buffers of dst */
+ if(dst->attribs[i]) {
+ vertex_buffer_ref_put(dst->attribs[i]);
+ dst->attribs[i] = NULL;
+ }
+ /* Get a reference onto the vertex buffers of src */
+ if(src->attribs[i]) {
+ vertex_buffer_ref_get(src->attribs[i]);
+ dst->attribs[i] = src->attribs[i];
+ dst->attribs_type[i] = src->attribs_type[i];
+ }
+ }
+}
+
diff --git a/src/s3d_mesh.h b/src/s3d_mesh.h
@@ -137,5 +137,10 @@ mesh_compute_aabb
float lower[3],
float upper[3]);
+extern LOCAL_SYM void
+mesh_copy_indexed_vertices
+ (const struct mesh* src,
+ struct mesh* dst);
+
#endif /* S3D_MESH_H */
diff --git a/src/s3d_shape.c b/src/s3d_shape.c
@@ -260,3 +260,18 @@ s3d_mesh_setup_indexed_vertices
(shape->data.mesh, ntris, get_indices, nverts, attribs, nattribs, data);
}
+res_T
+s3d_mesh_copy
+ (const struct s3d_shape* src,
+ struct s3d_shape* dst)
+{
+ if(!src || !dst || src->type != GEOM_MESH || dst->type != GEOM_MESH)
+ return RES_BAD_ARG;
+ if(src == dst) return RES_OK;
+
+ dst->flip_surface = src->flip_surface;
+ dst->is_enabled = src->is_enabled;
+ mesh_copy_indexed_vertices(src->data.mesh, dst->data.mesh);
+ return RES_OK;
+}
+
diff --git a/src/test_s3d_shape.c b/src/test_s3d_shape.c
@@ -42,6 +42,7 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct s3d_device* dev;
struct s3d_shape* shape;
+ struct s3d_shape* shape_copy;
struct s3d_shape* inst;
struct s3d_scene* scn;
struct s3d_vertex_data attribs[4];
@@ -248,12 +249,19 @@ main(int argc, char** argv)
CHECK(s3d_shape_flip_surface(inst), RES_OK);
+ CHECK(s3d_shape_create_mesh(dev, &shape_copy), RES_OK);
+ CHECK(s3d_mesh_copy(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_copy(shape, NULL), RES_BAD_ARG);
+ CHECK(s3d_mesh_copy(NULL, shape_copy), RES_BAD_ARG);
+ CHECK(s3d_mesh_copy(shape, shape_copy), RES_OK);
+
CHECK(s3d_shape_ref_get(NULL), RES_BAD_ARG);
CHECK(s3d_shape_ref_get(shape), RES_OK);
CHECK(s3d_shape_ref_put(NULL), RES_BAD_ARG);
CHECK(s3d_shape_ref_put(shape), RES_OK);
CHECK(s3d_shape_ref_put(shape), RES_OK);
CHECK(s3d_shape_ref_put(inst), RES_OK);
+ CHECK(s3d_shape_ref_put(shape_copy), RES_OK);
CHECK(s3d_scene_ref_put(scn), RES_OK);
CHECK(s3d_device_ref_put(dev), RES_OK);;
diff --git a/src/test_s3d_trace_ray.c b/src/test_s3d_trace_ray.c
@@ -91,6 +91,7 @@ main(int argc, char** argv)
struct s3d_scene* scn2;
struct s3d_shape* inst;
struct s3d_shape* walls;
+ struct s3d_shape* walls_copy;
struct s3d_shape* tall_block;
struct s3d_shape* short_block;
struct s3d_vertex_data attribs;
@@ -248,8 +249,13 @@ main(int argc, char** argv)
CHECK(s3d_scene_begin_session(scn2, S3D_TRACE), RES_OK);
CHECK(s3d_scene_end_session(scn2), RES_OK);
+ CHECK(s3d_shape_create_mesh(dev, &walls_copy), RES_OK);
+ CHECK(s3d_mesh_copy(walls, walls_copy), RES_OK);
+ CHECK(s3d_shape_ref_put(walls), RES_OK);
+ CHECK(s3d_shape_get_id(walls_copy, &walls_id), RES_OK);
+
CHECK(s3d_scene_clear(scn), RES_OK);
- CHECK(s3d_scene_attach_shape(scn, walls), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, walls_copy), RES_OK);
CHECK(s3d_scene_attach_shape(scn, short_block), RES_OK);
CHECK(s3d_scene_attach_shape(scn, tall_block), RES_OK);
@@ -356,7 +362,7 @@ main(int argc, char** argv)
CHECK(s3d_shape_ref_put(inst), RES_OK);
CHECK(s3d_shape_ref_put(short_block), RES_OK);
CHECK(s3d_shape_ref_put(tall_block), RES_OK);
- CHECK(s3d_shape_ref_put(walls), RES_OK);
+ CHECK(s3d_shape_ref_put(walls_copy), RES_OK);
CHECK(s3d_scene_ref_put(scn), RES_OK);
CHECK(s3d_scene_ref_put(scn2), RES_OK);