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:
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);