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 5d9aad93875ea6521a1266ee0314eee7d0d71281
parent 5da228ad7f3903cff904221f7de5949e16b41174
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 18 Mar 2015 18:06:21 +0100

Begin the implementation  of scene instantiation

Diffstat:
Msrc/s3d.h | 33++++++++++++++++++++++-----------
Msrc/s3d_device.c | 2+-
Msrc/s3d_scene.c | 23+++++++++++++++++++++++
Msrc/s3d_shape.c | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/s3d_shape_c.h | 16++++++++--------
5 files changed, 125 insertions(+), 27 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -76,6 +76,11 @@ enum s3d_type { S3D_FLOAT4 }; +enum s3d_transform_space { + S3D_LOCAL_TRANSFORM, + S3D_WORLD_TRANSFORM +}; + struct s3d_attrib { float value[4]; enum s3d_type type; @@ -175,6 +180,11 @@ S3D_API res_T s3d_scene_ref_put (struct s3d_scene* scn); +S3D_API res_T +s3d_scene_instantiate + (struct s3d_scene* scn, + struct s3d_shape* shape); + /* Attach the shape to the scene. If the shape is already attached to the same * or another scene, nothing is performed and a RES_BAD_ARG error is returned. * On success, the scene takes a reference onto the attached shape */ @@ -218,11 +228,6 @@ s3d_shape_create_mesh struct s3d_shape** shape); S3D_API res_T -s3d_shape_create_group - (struct s3d_device* dev, - struct s3d_shape **shape); - -S3D_API res_T s3d_shape_ref_get (struct s3d_shape* shape); @@ -250,11 +255,6 @@ S3D_API res_T s3d_shape_detach (struct s3d_shape* shape); -S3D_API res_T -s3d_shape_set_transform - (struct s3d_shape* shape, - const float transform[12]); /* 3x4 column major matrix */ - /* Retrieve the attribute of the shape prim `iprim' at the barycentric * coordinates `uv' */ S3D_API res_T @@ -293,10 +293,21 @@ s3d_shape_mesh_setup_indexed_vertices * the scene. Can be invoked only on a shape created with the * s3d_shape_create_group function */ S3D_API res_T -s3d_shape_group_setup_scene +s3d_shape_instance_setup_scene (struct s3d_shape* shape, struct s3d_scene* scene); +S3D_API res_T +s3d_shape_instance_set_position + (struct s3d_shape* shape, + const float position[3]); + +S3D_API res_T +s3d_shape_instance_translate + (struct s3d_shape* shape, + const enum s3d_transform_space space, + const float translation[3]); + END_DECLS #endif /* S3D_H */ diff --git a/src/s3d_device.c b/src/s3d_device.c @@ -87,7 +87,7 @@ s3d_device_create dev->logger = logger ? logger : LOGGER_DEFAULT; dev->allocator = allocator; ref_init(&dev->ref); - rtcInit(); + rtcInit("verbose=1"); ATOMIC_SET(&g_EmbreeIsInitialized, 1); exit: diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -71,6 +71,9 @@ scene_setup(struct s3d_scene* scn) mutex_rw_rlock(shape->lock); /* Prevent concurrent shape update */ + if(shape->type != SHAPE_MESH) + FATAL("Unsupported shape type\n"); + /* The Embree geometry is no more valid */ if(shape->data.mesh.resize_mask && shape->rtc_geom != RTC_INVALID_GEOMETRY_ID) { @@ -225,6 +228,26 @@ s3d_scene_ref_put(struct s3d_scene* scn) } res_T +s3d_scene_instantiate(struct s3d_scene* scn, struct s3d_shape** out_shape) +{ + struct s3d_shape* shape; + res_T res = RES_OK; + + if(!scn || !out_shape) + return RES_BAD_ARG; + + res = shape_create(scn->dev, &shape); + if(res != RES_OK) + return res; + + shape->type = SHAPE_INSTANCE; + S3D(scene_ref_get(scn)); + shape->data.scene = scn; + *out_shape = shape; + return RES_OK; +} + +res_T s3d_scene_attach_shape(struct s3d_scene* scn, struct s3d_shape* shape) { if(!scn || !shape) diff --git a/src/s3d_shape.c b/src/s3d_shape.c @@ -35,6 +35,7 @@ #include "s3d_scene_c.h" #include "s3d_shape_c.h" +#include <rsys/float33.h> #include <rsys/mem_allocator.h> /******************************************************************************* @@ -269,11 +270,10 @@ shape_release(ref_T* ref) } /******************************************************************************* - * Exported s3d_shape functions: + * Local functions ******************************************************************************/ res_T -s3d_shape_create_mesh - (struct s3d_device* dev, struct s3d_shape** out_shape) +shape_create(struct s3d_device* dev, struct s3d_shape** out_shape) { struct s3d_shape* shape = NULL; res_T res = RES_OK; @@ -289,14 +289,12 @@ s3d_shape_create_mesh goto error; } list_init(&shape->scene_attachment); - mesh_init(dev->allocator, &shape->data.mesh); - shape->type = SHAPE_MESH; - shape->status = SHAPE_STATUS_READY; shape->rtc_geom = RTC_INVALID_GEOMETRY_ID; shape->scn = NULL; S3D(device_ref_get(dev)); shape->dev = dev; ref_init(&shape->ref); + f33_set_identity(shape->transform); shape->lock = mutex_rw_create(); if(!shape->lock) { res = RES_MEM_ERR; @@ -312,6 +310,30 @@ error: shape = NULL; } goto exit; + +} + +/******************************************************************************* + * Exported s3d_shape functions: + ******************************************************************************/ +res_T +s3d_shape_create_mesh + (struct s3d_device* dev, struct s3d_shape** out_shape) +{ + struct s3d_shape* shape; + res_T res = RES_OK; + + if(!dev || !out_shape) + return RES_BAD_ARG; + + res = shape_create(dev, &shape); + if(res != RES_OK) + return res; + + mesh_init(dev->allocator, &shape->data.mesh); + shape->type = SHAPE_MESH; + *out_shape = shape; + return RES_OK; } res_T @@ -356,6 +378,45 @@ s3d_shape_detach(struct s3d_shape* shape) } res_T +s3d_shape_instance_set_position + (struct s3d_shape* shape, const float position[3]) +{ + float axis[3]; + if(!shape || shape->type != SHAPE_INSTANCE || !position) + return RES_BAD_ARG; + mutex_rw_wlock(shape->lock); + shape->transform[9] = -f3_dot(f33_row(axis, shape->transform, 0), position); + shape->transform[10] = -f3_dot(f33_row(axis, shape->transform, 1), position); + shape->transform[12] = -f3_dot(f33_row(axis, shape->transform, 2), position); + mutex_rw_unlock(shape->lock); + return RES_OK; +} + +res_T +s3d_shape_translate + (struct s3d_shape* shape, + const enum s3d_transform_space space, + const float translation[3]) +{ + if(!shape || shape->type != SHAPE_INSTANCE || !translation) + return RES_BAD_ARG; + if(space == S3D_LOCAL_TRANSFORM) { + float vec[3]; + mutex_rw_wlock(shape->lock); + f33_mulf3(vec, shape->transform, translation); /* Trans in local space */ + f3_add(shape->transform + 9, shape->transform + 9, vec); + mutex_rw_unlock(shape->lock); + } else if(space == S3D_WORLD_TRANSFORM) { + mutex_rw_wlock(shape->lock); + f3_add(shape->transform + 9, shape->transform + 9, translation); + mutex_rw_unlock(shape->lock); + } else { + return RES_BAD_ARG; + } + return RES_BAD_ARG; +} + +res_T s3d_shape_mesh_setup_indexed_vertices (struct s3d_shape* shape, const unsigned ntris, @@ -427,8 +488,11 @@ s3d_shape_mesh_setup_indexed_vertices } } - if(shape->scn) /* Notify the shape update */ + if(shape->scn) {/* Notify the shape update */ + mutex_lock(shape->scn->lock); shape->scn->is_outdated = 1; + mutex_unlock(shape->scn->lock); + } exit: mutex_rw_unlock(shape->lock); diff --git a/src/s3d_shape_c.h b/src/s3d_shape_c.h @@ -48,15 +48,9 @@ enum mesh_buffer { MESH_VERTEX_BUFFER = BIT(1) }; -enum shape_status { - SHAPE_STATUS_COMMIT, /* Shape data are committed */ - SHAPE_STATUS_PULL, /* Shape data are pulled */ - SHAPE_STATUS_READY /* The shape is ready for any operation */ -}; - enum shape_type { SHAPE_MESH, - SHAPE_SCENE, + SHAPE_INSTANCE, SHAPE_TYPES_COUNT__, SHAPE_NONE = SHAPE_TYPES_COUNT__ }; @@ -74,10 +68,10 @@ struct mesh { /* Triangular mesh */ struct s3d_shape { struct list_node scene_attachment; enum shape_type type; - enum shape_status status; unsigned rtc_geom; /* Embree geometry id */ struct s3d_scene* scn; /* The scene on which the shape is attached */ struct mutex_rw* lock; + float transform[12]; /* 3x4 column major transformation */ union { struct s3d_scene* scene; @@ -88,5 +82,11 @@ struct s3d_shape { ref_T ref; }; +/* Create an Untyped shape */ +extern LOCAL_SYM res_T +shape_create + (struct s3d_device* dev, + struct s3d_shape** shape); + #endif /* S3D_SHAPE_C_H */