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 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:
Msrc/s3d.h | 6++++++
Msrc/s3d_mesh.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/s3d_mesh.h | 5+++++
Msrc/s3d_shape.c | 15+++++++++++++++
Msrc/test_s3d_shape.c | 8++++++++
Msrc/test_s3d_trace_ray.c | 10++++++++--
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);