commit 2bb9edf0c7fbe273d57c69b48af7b4ef39f46ddf
parent a590a61a31834a49abf7424aab8a0338a2dad409
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 13 Jul 2016 15:44:36 +0200
Add and test the s3d_primitive_get_transform function
Return the 3x4 column major transformation matrix of the primitive
Diffstat:
4 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -447,6 +447,11 @@ s3d_primitive_compute_area
(const struct s3d_primitive* prim,
float* area);
+S3D_API res_T
+s3d_primitive_get_transform
+ (const struct s3d_primitive* prim,
+ float transform[12]); /* 3x4 column major matrix */
+
/*******************************************************************************
* Mesh API - Manage a triangular meshes
******************************************************************************/
diff --git a/src/s3d_primitive.c b/src/s3d_primitive.c
@@ -226,3 +226,26 @@ s3d_primitive_compute_area(const struct s3d_primitive* prim, float* area)
return RES_OK;
}
+res_T
+s3d_primitive_get_transform
+ (const struct s3d_primitive* prim, float transform[12])
+{
+ if(!prim || !transform)
+ return RES_BAD_ARG;
+
+ if(!prim->inst__) {
+ f3(transform + 0, 1.f, 0.f, 0.f);
+ f3(transform + 3, 0.f, 1.f, 0.f);
+ f3(transform + 6, 0.f, 0.f, 1.f);
+ f3(transform + 9, 0.f, 0.f, 0.f);
+ } else {
+ struct geometry* geom_inst = (struct geometry*)prim->inst__;
+ ASSERT(geom_inst->type == GEOM_INSTANCE);
+ f3_set(transform + 0, geom_inst->data.instance->transform + 0);
+ f3_set(transform + 3, geom_inst->data.instance->transform + 3);
+ f3_set(transform + 6, geom_inst->data.instance->transform + 6);
+ f3_set(transform + 9, geom_inst->data.instance->transform + 9);
+ }
+ return RES_OK;
+}
+
diff --git a/src/test_s3d_primitive.c b/src/test_s3d_primitive.c
@@ -34,6 +34,7 @@
#include "test_s3d_cbox.h"
#include "test_s3d_utils.h"
+#include <rsys/float3.h>
#include <rsys/math.h>
static const float plane_verts[] = {
@@ -93,6 +94,8 @@ main(int argc, char** argv)
struct cbox_desc desc;
size_t nprims;
size_t i;
+ float transform[12];
+ float vec[3];
float uv[2];
float area;
unsigned ntris, nverts;
@@ -167,6 +170,15 @@ main(int argc, char** argv)
CHECK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_0, &b), RES_OK);
CHECK(b, 0);
+ CHECK(s3d_primitive_get_transform(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_primitive_get_transform(&prim, NULL), RES_BAD_ARG);
+ CHECK(s3d_primitive_get_transform(NULL, transform), RES_BAD_ARG);
+ CHECK(s3d_primitive_get_transform(&prim, transform), RES_OK);
+ CHECK(f3_eq(transform + 0, f3(vec, 1.f, 0.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 3, f3(vec, 0.f, 1.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 6, f3(vec, 0.f, 0.f, 1.f)), 1);
+ CHECK(f3_eq(transform + 9, f3(vec, 0.f, 0.f, 0.f)), 1);
+
CHECK(s3d_scene_clear(scn), RES_OK);
CHECK(s3d_scene_attach_shape(scn, plane), RES_OK);
CHECK(s3d_scene_begin_session(scn, S3D_GET_PRIMITIVE), RES_OK);
diff --git a/src/test_s3d_trace_ray.c b/src/test_s3d_trace_ray.c
@@ -121,6 +121,8 @@ main(int argc, char** argv)
unsigned ntris, nverts;
size_t nprims;
size_t ix, iy;
+ float transform[12];
+ float vec[3];
float lower[3], upper[3];
float org[3] = { 0.f, 0.f, 0.f };
float dir[3] = { 0.f, 1.f, 0.f };
@@ -313,6 +315,12 @@ main(int argc, char** argv)
FOR_EACH(j, 0, i) {
CHECK(S3D_PRIMITIVE_EQ(prims + i, prims + j), 0);
}
+
+ CHECK(s3d_primitive_get_transform(prims + i, transform), RES_OK);
+ CHECK(f3_eq(transform + 0, f3(vec, 1.f, 0.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 3, f3(vec, 0.f, 1.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 6, f3(vec, 0.f, 0.f, 1.f)), 1);
+ CHECK(f3_eq(transform + 9, f3(vec, -100.f, 0.f, -2.f)), 1);
}
camera_init(&cam);
@@ -343,6 +351,12 @@ main(int argc, char** argv)
|| hit.prim.geom_id == short_block_id, 1);
CHECK(hit.prim.geom_id < 10, 1);
+ CHECK(s3d_primitive_get_transform(&hit.prim, transform), RES_OK);
+ CHECK(f3_eq(transform + 0, f3(vec, 1.f, 0.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 3, f3(vec, 0.f, 1.f, 0.f)), 1);
+ CHECK(f3_eq(transform + 6, f3(vec, 0.f, 0.f, 1.f)), 1);
+ CHECK(f3_eq(transform + 9, f3(vec, -100.f, 0.f, -2.f)), 1);
+
CHECK(s3d_primitive_get_attrib
(&hit.prim, S3D_POSITION, hit.uv, &attr), RES_OK);
CHECK(attr.type, S3D_FLOAT3);