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 9a9a0c47a132f0c28c6bfce1094684104b0bb97d
parent 46b98bcb8106c08106a3566d978f481170025a53
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 11 Sep 2015 14:43:54 +0200

Add and test the s3d_primitive_compute_area

Compute the area of a given primitive

Diffstat:
Msrc/s3d.h | 7++++++-
Msrc/s3d_primitive.c | 24++++++++++++++++++++++++
Msrc/test_s3d_primitive.c | 11++++++++++-
3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -402,6 +402,11 @@ s3d_primitive_sample const float u, const float v, /* Random numbers in [0, 1) */ float st[2]); /* Sampled parametric coordinates on prim */ +S3D_API res_T +s3d_primitive_compute_area + (const struct s3d_primitive* prim, + float* area); + /******************************************************************************* * Mesh API - Manage a triangular meshes ******************************************************************************/ @@ -424,7 +429,7 @@ s3d_mesh_setup_indexed_vertices * supports a local to world transformation. Since the scene geometry is stored * only a single time even though it is instantiated in several positions, one * can use this feature to create extremely large scene - * ******************************************************************************/ + ******************************************************************************/ S3D_API res_T s3d_instance_set_position (struct s3d_shape* shape, diff --git a/src/s3d_primitive.c b/src/s3d_primitive.c @@ -181,3 +181,27 @@ s3d_primitive_sample return RES_OK;; } +res_T +s3d_primitive_compute_area(const struct s3d_primitive* prim, float* area) +{ + const uint32_t* ids; + const float* pos; + const float* v0, *v1, *v2; + float E0[3], E1[3], N[3]; + struct geometry* geom; + + if(!prim || !area || S3D_PRIMITIVE_EQ(prim, &S3D_PRIMITIVE_NULL)) + return RES_BAD_ARG; + + geom = (struct geometry*)prim->mesh__; + pos = mesh_get_pos(geom->data.mesh); + ids = mesh_get_ids(geom->data.mesh) + prim->prim_id * 3/* #triangle ids */; + v0 = pos + ids[0] * 3/* #coords */; + v1 = pos + ids[1] * 3/* #coords */; + v2 = pos + ids[2] * 3/* #coords */; + f3_sub(E0, v1, v0); + f3_sub(E1, v2, v0); + *area = f3_len(f3_cross(N, E0, E1)) * 0.5f; + return RES_OK; +} + diff --git a/src/test_s3d_primitive.c b/src/test_s3d_primitive.c @@ -34,6 +34,8 @@ #include "test_s3d_cbox.h" #include "test_s3d_utils.h" +#include <rsys/math.h> + static const float plane_verts[] = { 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, @@ -91,8 +93,9 @@ main(int argc, char** argv) struct cbox_desc desc; size_t nprims; size_t i; - unsigned ntris, nverts; float uv[2]; + float area; + unsigned ntris, nverts; unsigned walls_id; (void)argc, (void)argv; @@ -159,6 +162,12 @@ main(int argc, char** argv) CHECK(S3D_PRIMITIVE_EQ(&prim, &S3D_PRIMITIVE_NULL), 0); CHECK(s3d_scene_end_session(scn), RES_OK); + CHECK(s3d_primitive_compute_area(NULL, NULL), RES_BAD_ARG); + CHECK(s3d_primitive_compute_area(&prim, NULL), RES_BAD_ARG); + CHECK(s3d_primitive_compute_area(NULL, &area), RES_BAD_ARG); + CHECK(s3d_primitive_compute_area(&prim, &area), RES_OK); + CHECK(eq_epsf(area, 0.5f, 1.e-6f), 1); + CHECK(s3d_primitive_sample(NULL, 1.f, 1.f, NULL), RES_BAD_ARG); CHECK(s3d_primitive_sample(&prim, 1.f, 1.f, NULL), RES_BAD_ARG); CHECK(s3d_primitive_sample(NULL, 0.f, 1.f, NULL), RES_BAD_ARG);