[vlc-devel] [PATCH 17/18] viewpoint: add test for conversion to 4x4 matrix

Alexandre Janniaux ajanni at videolabs.io
Wed Mar 31 09:25:49 UTC 2021


Check that the final transformation is preserved.
---
 test/Makefile.am          |   2 +-
 test/src/misc/viewpoint.c | 113 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 2148dd6505..ccc6dc0512 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -138,7 +138,7 @@ test_src_misc_epg_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_src_misc_keystore_SOURCES = src/misc/keystore.c
 test_src_misc_keystore_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_src_misc_viewpoint_SOURCES = src/misc/viewpoint.c
-test_src_misc_viewpoint_LDADD = $(LIBVLCCORE)
+test_src_misc_viewpoint_LDADD = $(LIBVLCCORE) $(LIBM)
 test_src_interface_dialog_SOURCES = src/interface/dialog.c
 test_src_interface_dialog_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_src_media_source_LDADD = $(LIBVLCCORE) $(LIBVLC)
diff --git a/test/src/misc/viewpoint.c b/test/src/misc/viewpoint.c
index 0a759678f6..6b806796d1 100644
--- a/test/src/misc/viewpoint.c
+++ b/test/src/misc/viewpoint.c
@@ -19,9 +19,54 @@
  *****************************************************************************/
 
 #include <vlc_viewpoint.h>
+#include <math.h>
 #include "../../libvlc/test.h"
 
 
+static void mat4x4_for_angles( float *m, float *angles )
+{
+    const float yaw   = -angles[0] * (float)M_PI / 180.f;
+    const float pitch = -angles[1] * (float)M_PI / 180.f;
+    const float roll  = -angles[2] * (float)M_PI / 180.f;
+
+    float s, c;
+
+    s = sinf(pitch);
+    c = cosf(pitch);
+    const float x_rot[4][4] = {
+        { 1.f,    0.f,    0.f,    0.f },
+        { 0.f,    c,      -s,      0.f },
+        { 0.f,    s,      c,      0.f },
+        { 0.f,    0.f,    0.f,    1.f } };
+
+    s = sinf(yaw);
+    c = cosf(yaw);
+    const float y_rot[4][4] = {
+        { c,      0.f,    s,     0.f },
+        { 0.f,    1.f,    0.f,    0.f },
+        { -s,      0.f,    c,      0.f },
+        { 0.f,    0.f,    0.f,    1.f } };
+
+    s = sinf(roll);
+    c = cosf(roll);
+    const float z_rot[4][4] = {
+        { c,      s,      0.f,    0.f },
+        { -s,     c,      0.f,    0.f },
+        { 0.f,    0.f,    1.f,    0.f },
+        { 0.f,    0.f,    0.f,    1.f } };
+
+    /**
+     * Column-major matrix multiplication mathematically equal to
+     * z_rot * x_rot * y_rot
+     */
+    memset(m, 0, 16 * sizeof(float));
+    for (int i=0; i<4; ++i)
+        for (int j=0; j<4; ++j)
+            for (int k=0; k<4; ++k)
+                for (int l=0; l<4; ++l)
+                    m[4*i+l] += y_rot[i][j] * x_rot[j][k] * z_rot[k][l];
+}
+
 static bool
 compare_angles(float epsilon, const float a1[3], const float a2[3])
 {
@@ -83,11 +128,79 @@ test_conversion_euler_to_euler()
     assert(reciprocal_euler(epsilon, -45.f, -45.f, -45.f));
 }
 
+static int fuzzy_memcmp(const float *a, const float *b,
+                         size_t size, float epsilon)
+{
+    for (size_t i=0; i < size; ++i)
+    {
+        if (fabs(a[i]-b[i]) > epsilon)
+        {
+            fprintf(stderr, "Difference at %zu, a[%zu]=%f, b[%zu]=%f\n",
+                    i, i, a[i], i, b[i]);
+            return a[i] < b[i] ? -1 : 1;
+        }
+    }
+    return 0;
+}
+
+static void
+test_conversion_viewpoint_mat4x4()
+{
+    const float epsilon = 0.1f;
+    vlc_viewpoint_t vp;
+
+#define MATRIX_LINE "[%f %f %f %f]\n"
+#define MATRIX_FORMAT \
+    MATRIX_LINE \
+    MATRIX_LINE \
+    MATRIX_LINE \
+    MATRIX_LINE
+
+#define PRINT_MATRIX(title, mat) \
+    fprintf(stderr, title ":\n" \
+                    MATRIX_FORMAT \
+                    "\n", \
+           mat[0],  mat[1],  mat[2], mat[3], \
+           mat[4],  mat[5],  mat[6], mat[7], \
+           mat[8],  mat[9],  mat[10], mat[11], \
+           mat[12], mat[13], mat[14], mat[15])
+
+    for (float i=0; i<361; i+=10)
+    for (float j=0; j<181; j+=5)
+    for (float k=0; k<361; k+=10)
+    {
+        float angles[] = { i, j, k, };
+        fprintf(stderr, "angles: %f %f %f\n",
+                angles[0], angles[1], angles[2]);
+
+        float computed_matrix[16];
+        vlc_viewpoint_from_euler(&vp, angles[0], angles[1], angles[2]);
+        vlc_viewpoint_to_4x4(&vp, computed_matrix);
+
+        float expected_matrix[16];
+        mat4x4_for_angles(expected_matrix, angles);
+
+        bool is_different = !!fuzzy_memcmp(
+            computed_matrix,
+            expected_matrix,
+            ARRAY_SIZE(computed_matrix), epsilon);
+        if (is_different)
+        {
+            /* Do not print every results, it weights 18Mo otherwise. */
+            PRINT_MATRIX("Expected matrix", expected_matrix);
+            PRINT_MATRIX("vlc_viewpoint_to_4x4", computed_matrix);
+            fflush(stderr);
+            exit(1);
+        }
+    }
+}
+
 int main( void )
 {
     test_init();
 
     test_conversion_euler_to_euler();
+    test_conversion_viewpoint_mat4x4();
 
     return 0;
 }
-- 
2.31.0



More information about the vlc-devel mailing list