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 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:
Msrc/s3d.h | 24+++++++++++++-----------
Msrc/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]) {