commit 66b89ab62f3be9cad99277e6d9ac0c5ba70e5326
parent db37af79b18a5256f0c2acfbdd7ca0b132d89e65
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 20 Mar 2015 14:21:11 +0100
Implement the s3d_mesh_get_attrib function
Diffstat:
| M | src/s3d.h | | | 24 | +++++++++++++----------- |
| M | src/s3d_shape.c | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -66,7 +66,9 @@ enum s3d_attrib_usage {
S3D_ATTRIB_2, /* Generic attrib 2 */
S3D_ATTRIB_3, /* Generic attrib 3 */
S3D_ATTRIBS_COUNT__,
- S3D_GEOMETRY_NORMAL /* World space face normal */
+ /* Unormalized world space face normal. Outward orientation defined with
+ * respect to the Counter Clock Wise vertex ordering */
+ S3D_GEOMETRY_NORMAL
};
enum s3d_type {
@@ -256,16 +258,6 @@ S3D_API res_T
s3d_shape_detach
(struct s3d_shape* shape);
-/* Retrieve the attribute of the shape prim `iprim' at the barycentric
- * coordinates `uv' */
-S3D_API res_T
-s3d_shape_get_attrib
- (struct s3d_shape* shape,
- const enum s3d_attrib_usage attr, /* Attribute to retrieve */
- const unsigned iprim, /* Id of the primitive on which `attr' is retrieved */
- const float uv[2], /* Barycentric coordinates of `attr' on `iprim' */
- struct s3d_attrib* attrib); /* Resulting attrib */
-
/* Sample the shape with respect to 3 uniform random variables */
S3D_API res_T
s3d_shape_sample
@@ -275,6 +267,16 @@ s3d_shape_sample
unsigned* iprim, /* Sampled primitive */
float uv[2]); /* Sampled barycentric coordinate onto `iprim' */
+/* Retrieve the attribute of the shape prim `iprim' at the barycentric
+ * coordinates `uv' */
+S3D_API res_T
+s3d_mesh_get_attrib
+ (struct s3d_shape* shape,
+ const enum s3d_attrib_usage attr, /* Attribute to retrieve */
+ const unsigned iprim, /* Id of the primitive on which `attr' is retrieved */
+ const float uv[2], /* Barycentric coordinates of `attr' on `iprim' */
+ struct s3d_attrib* attrib); /* Resulting attrib */
+
/*******************************************************************************
* Mesh API - Define a triangluar meshes
******************************************************************************/
diff --git a/src/s3d_shape.c b/src/s3d_shape.c
@@ -378,6 +378,77 @@ s3d_shape_detach(struct s3d_shape* shape)
}
res_T
+s3d_shape_get_attrib
+ (const struct s3d_shape* shape,
+ const enum s3d_attrib_usage usage,
+ const unsigned iprim,
+ const float uv[2],
+ struct s3d_attrib* attrib)
+{
+ const uint32_t* ids;
+ float w;
+
+ if(!shape || !usage == S3D_ATTRIBS_COUNT__ || !uv || !attrib)
+ return RES_BAD_ARG;
+
+ /* Unsupported mesh type */
+ if(shape->type != SHAPE_MESH)
+ return RES_BAD_ARG;
+ /* The mesh haven't the required mesh attrib */
+ if(usage != S3D_GEOMETRY_NORMAL
+ && !darray_float_size_get(shape->data.mesh.attribs + usage))
+ return RES_BAD_ARG;
+ /* Out of bound primitive index */
+ if(iprim >= darray_u32_size_get(&shape->data.mesh.indices) / 3/*# prim ids*/)
+ return RES_BAD_ARG;
+ /* Unormalized barycentric coordinates */
+ w = 1.f - uv[0] - uv[1];
+ if(uv[0] < 0.f || uv[1] < 0.f || !eq_eps(w, 1.f, 1.e-6f))
+ return RES_BAD_ARG;
+
+ ids = darray_u32_cdata_get(&shape->data.mesh.indices) + iprim * 3;
+ attrib->usage = usage;
+
+ if(usage == S3D_POSITION || usage == S3D_GEOMETRY_NORMAL) {
+ /* TODO take into account the instance transformation */
+ const float* v0, *v1, *v2;
+ const float* pos;
+ attrib->type = S3D_FLOAT3;
+ /* Fetch data */
+ pos = darray_float_cdata_get(shape->data.mesh.attribs + S3D_POSITION);
+ v0 = pos + ids[0] * 3;
+ v1 = pos + ids[1] * 3;
+ v2 = pos + ids[2] * 3;
+ if(usage == S3D_GEOMETRY_NORMAL) { /* Compute the geometry normal */
+ float e0[3], e1[3];
+ f3_cross(attrib->value, f3_sub(e0, v1, v0), f3_sub(e1, v2, v0));
+ } else { /* Interpolate the vertex position */
+ float tmp[3];
+ f3_mulf(attrib->value, v0, uv[0]);
+ f3_add(attrib->value, attrib->value, f3_mulf(tmp, v1, uv[1]));
+ f3_add(attrib->value, attrib->value, f3_mulf(tmp, v2, w));
+ }
+ } else {
+ const float* attr;
+ const float* v0, *v1, *v2;
+ unsigned i, dim;
+ attrib->type = shape->data.mesh.attribs_type[usage];
+ /* Fetch attrib data */
+ dim = get_s3d_type_dimension(attrib->type);
+ attr = darray_float_cdata_get(shape->data.mesh.attribs + usage);
+ v0 = attr + ids[0] * dim;
+ v1 = attr + ids[1] * dim;
+ v2 = attr + ids[2] * dim;
+ /* Interpolate the vertex attribs */
+ ASSERT(dim <= 4);
+ FOR_EACH(i, 0, dim) {
+ attrib->value[i] = v0[i]*uv[0] + v1[i]*uv[1] + v2[i]*w;
+ }
+ }
+ return RES_OK;
+}
+
+res_T
s3d_instance_set_position
(struct s3d_shape* shape, const float position[3])
{