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 6a611f84688294e853355714e5a29972877cffc3
parent aa50add43ae7972d00b1024f171869e783481c5b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 10 Sep 2015 09:23:20 +0200

Fix issues in the s3d_scene instancing

No error occurs if a scene is instantiated several times in another
scene. A scene cannot own an instance of itself.

Diffstat:
Msrc/s3d_scene.c | 19++++++++++++++++++-
Msrc/test_s3d_scene.c | 17+++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -408,7 +408,17 @@ scene_sync(struct s3d_scene* scn, const int session_mask) res_T res = RES_OK; ASSERT(scn); - if(scn->session_mask != 0) { + if((session_mask & S3D_INSTANCE) != 0 + && (scn->session_mask & S3D_INSTANCE) != 0) { + /* The scene was already synced as an instance. Discard sync process */ + return RES_OK; + } else if(scn->session_mask != 0) { + /* The scene cannot be synced several times exepted if it is instantiated */ + res = RES_BAD_OP; + goto error; + } + + if((session_mask & S3D_INSTANCE) == 0 && scn->session_mask != 0) { res = RES_BAD_OP; goto error; } @@ -417,6 +427,11 @@ scene_sync(struct s3d_scene* scn, const int session_mask) shape = CONTAINER_OF(node, struct s3d_shape, scene_attachment); switch(shape->type) { case GEOM_INSTANCE: + /* One instancing level is supported */ + if((session_mask & S3D_INSTANCE) != 0) { + res = RES_BAD_ARG; + goto error; + } res = scene_register_instance(scn, shape, session_mask); break; case GEOM_MESH: @@ -567,6 +582,8 @@ s3d_scene_attach_shape(struct s3d_scene* scn, struct s3d_shape* shape) return RES_BAD_ARG; if(!is_list_empty(&shape->scene_attachment)) return RES_BAD_ARG; + if(shape->type == GEOM_INSTANCE && shape->data.instance->scene == scn) + return RES_BAD_ARG; list_add_tail(&scn->shapes, &shape->scene_attachment); S3D(shape_ref_get(shape)); diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c @@ -39,6 +39,8 @@ main(int argc, char** argv) struct mem_allocator allocator; struct s3d_device* dev; struct s3d_scene* scn; + struct s3d_scene* scn2; + struct s3d_scene* scn3; struct s3d_shape* shapes[4]; const size_t nshapes = sizeof(shapes)/sizeof(struct s3d_shape*); size_t i; @@ -56,6 +58,8 @@ main(int argc, char** argv) CHECK(s3d_scene_create(dev, NULL), RES_BAD_ARG); CHECK(s3d_scene_create(NULL, &scn), RES_BAD_ARG); CHECK(s3d_scene_create(dev, &scn), RES_OK); + CHECK(s3d_scene_create(dev, &scn2), RES_OK); + CHECK(s3d_scene_create(dev, &scn3), RES_OK); CHECK(s3d_scene_attach_shape(NULL, NULL), RES_BAD_ARG); CHECK(s3d_scene_attach_shape(scn, NULL), RES_BAD_ARG); @@ -89,6 +93,7 @@ main(int argc, char** argv) CHECK(s3d_scene_clear(scn), RES_OK); CHECK(s3d_scene_clear(scn), RES_OK); CHECK(s3d_scene_instantiate(scn, shapes + 2), RES_OK); + CHECK(s3d_scene_attach_shape(scn, shapes[2]), RES_BAD_ARG); CHECK(s3d_scene_get_session_mask(NULL, NULL), RES_BAD_ARG); CHECK(s3d_scene_get_session_mask(scn, NULL), RES_BAD_ARG); @@ -116,17 +121,29 @@ main(int argc, char** argv) CHECK(s3d_scene_get_session_mask(scn, &mask), RES_OK); CHECK(mask, 0); + CHECK(s3d_scene_attach_shape(scn2, shapes[1]), RES_OK); + CHECK(s3d_scene_attach_shape(scn2, shapes[2]), RES_OK); + CHECK(s3d_scene_begin_session(scn2, S3D_SAMPLE|S3D_TRACE), RES_OK); + CHECK(s3d_scene_end_session(scn2), RES_OK); + + CHECK(s3d_scene_instantiate(scn2, shapes + 3), RES_OK); + CHECK(s3d_scene_attach_shape(scn3, shapes[3]), RES_OK); + CHECK(s3d_scene_begin_session(scn3, S3D_SAMPLE|S3D_TRACE), RES_BAD_ARG); + CHECK(s3d_scene_detach_shape(scn, shapes[0]), RES_OK); CHECK(s3d_shape_ref_put(shapes[0]), RES_OK); CHECK(s3d_shape_ref_put(shapes[1]), RES_OK); CHECK(s3d_shape_ref_put(shapes[2]), RES_OK); + CHECK(s3d_shape_ref_put(shapes[3]), RES_OK); CHECK(s3d_scene_ref_get(NULL), RES_BAD_ARG); CHECK(s3d_scene_ref_get(scn), RES_OK); CHECK(s3d_scene_ref_put(NULL), RES_BAD_ARG); CHECK(s3d_scene_ref_put(scn), RES_OK); CHECK(s3d_scene_ref_put(scn), RES_OK); + CHECK(s3d_scene_ref_put(scn2), RES_OK); + CHECK(s3d_scene_ref_put(scn3), RES_OK); CHECK(s3d_device_ref_put(dev), RES_OK);;