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:
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 */