Hello community, here is the log from the commit of package graphene for openSUSE:Factory checked in at 2019-04-01 12:31:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/graphene (Old) and /work/SRC/openSUSE:Factory/.graphene.new.25356 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "graphene" Mon Apr 1 12:31:20 2019 rev:9 rq:689310 version:1.8.6 Changes: -------- --- /work/SRC/openSUSE:Factory/graphene/graphene.changes 2018-06-22 13:27:00.897209069 +0200 +++ /work/SRC/openSUSE:Factory/.graphene.new.25356/graphene.changes 2019-04-01 12:31:25.633765517 +0200 @@ -1,0 +2,40 @@ +Mon Mar 25 23:24:28 UTC 2019 - Bjørn Lie <bjorn....@gmail.com> + +- Update to version 1.8.6: + + Bug fixes, bug fixes everywhere! Also: documentation changes to + clarify what we do behind the veil of the various matrix + multiplication functions. Hopefully, this should help people + using Graphene especially when it comes to integration with + other libraries. + + Fix matrix multiplication when the result matrix is also one of + the operands. + + Fix check when converting a 4x4 matrix into an affine + transformation matrix. + + Fix interpolation between matrices with a perspective + component. + + Documentation fixes for matrix/matrix and matrix/vector + multiplication operators. +- Changes from version 1.8.4: + + Mostly a bug fixing release, with an especially glaring bug fix + in the point transformation function of graphene_matrix_t that + was found thanks to GTK 4. Now the function is covered by the + test suite, so it should not regress. + + Another major fix is the ensuring that we have a description of + the SIMD types through introspection, which means that language + bindings can finally know how big every other structure using + them is. The SIMD API is still not available through + introspection, as it's a pure C convenience. + + Require Meson ≥ 0.48.0. + + Fix matrix/point transformation. + + Build fixes for MSVC. + + Introspection fixes for bool. + + Fix the InitOnce checks on Windows. + + Correctly parse SIMD types for introspection. + + Build fixes for the pkg-config file. + + Documentation fixes: + - Clarify matrix/vector/point multiplication. + - Clarify plane description. + - Clarify the units for the matrix skew factors. + - Document use of graphene-gobject with Meson. + +------------------------------------------------------------------- Old: ---- graphene-1.8.2.tar.xz New: ---- graphene-1.8.6.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ graphene.spec ++++++ --- /var/tmp/diff_new_pack.VxNpdJ/_old 2019-04-01 12:31:27.357766053 +0200 +++ /var/tmp/diff_new_pack.VxNpdJ/_new 2019-04-01 12:31:27.361766055 +0200 @@ -1,7 +1,7 @@ # # spec file for package graphene # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,12 +12,12 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: graphene -Version: 1.8.2 +Version: 1.8.6 Release: 0 Summary: Thin type layer for graphic libraries License: MIT @@ -29,7 +29,7 @@ BuildRequires: fdupes BuildRequires: gobject-introspection-devel BuildRequires: gtk-doc -BuildRequires: meson >= 0.43.1 +BuildRequires: meson >= 0.48.0 BuildRequires: pkgconfig BuildRequires: python3-base BuildRequires: pkgconfig(gobject-2.0) >= 2.30.0 @@ -78,18 +78,18 @@ This subpackage contains the development files for the Graphene library. %prep -%autosetup +%autosetup -p1 %build %meson \ - -D gtk_doc=true \ - -D gobject_types=true \ - -D introspection=true \ - -D gcc_vector=true \ - -D sse2=true \ - -D arm-neon=true \ - -D tests=true \ - -D benchmarks=true \ + -Dgtk_doc=true \ + -Dgobject_types=true \ + -Dintrospection=true \ + -Dgcc_vector=true \ + -Dsse2=true \ + -Darm-neon=true \ + -Dtests=true \ + -Dbenchmarks=true \ %{nil} %meson_build ++++++ graphene-1.8.2.tar.xz -> graphene-1.8.6.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/.appveyor/msvc.bat new/graphene-1.8.6/.appveyor/msvc.bat --- old/graphene-1.8.2/.appveyor/msvc.bat 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/.appveyor/msvc.bat 2019-03-05 18:32:19.000000000 +0100 @@ -4,12 +4,12 @@ mkdir _build mkdir graphene-shared-%MSVC_PLATFORM% cd _build -curl -LsSO https://github.com/mesonbuild/meson/releases/download/0.44.1/meson-0.44.1.tar.gz -7z x meson-0.44.1.tar.gz -move dist\meson-0.44.1.tar . -7z x meson-0.44.1.tar +curl -LsSO https://github.com/mesonbuild/meson/releases/download/0.49.0/meson-0.49.0.tar.gz +7z x meson-0.49.0.tar.gz +move dist\meson-0.49.0.tar . +7z x meson-0.49.0.tar rmdir dist -del meson-0.44.1.tar meson-0.44.1.tar.gz +del meson-0.49.0.tar meson-0.49.0.tar.gz curl -LsSO https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-win.zip 7z x ninja-win.zip del ninja-win.zip @@ -19,7 +19,7 @@ cd _build call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %MSVC_PLATFORM% @echo on -C:\Python36\python.exe meson-0.44.1\meson.py .. . --backend=ninja --prefix=%APPVEYOR_BUILD_FOLDER%\graphene-shared-%MSVC_PLATFORM% || goto :error +C:\Python36\python.exe meson-0.49.0\meson.py .. . --backend=ninja --prefix=%APPVEYOR_BUILD_FOLDER%\graphene-shared-%MSVC_PLATFORM% || goto :error ninja || goto :error ninja test || goto :error ninja install || goto :error diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/README.md new/graphene-1.8.6/README.md --- old/graphene-1.8.2/README.md 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/README.md 2019-03-05 18:32:19.000000000 +0100 @@ -29,7 +29,7 @@ ### Dependencies -Graphene has little dependencies. +Graphene has minimal dependencies. Graphene contains optimizations for speeding up vector operations; those optimizations are optional, and used only if both Graphene was compiled @@ -37,6 +37,7 @@ Currently, Graphene supports the following platform-specific fast paths: * Streaming SIMD Extensions (SSE) 2 + * Optionally using SSE 4.1 * ARM NEON * GCC vector extensions @@ -53,6 +54,7 @@ In order to build and install Graphene you will need development tools and the headers of the dependencies. You will also need: + * [python3](https://www.python.org) * [meson](http://mesonbuild.com) * [ninja](https://ninja-build.org/) @@ -63,7 +65,7 @@ Then run: - $ meson _build # on Windows, it's "meson.py" + $ meson _build # on Windows, it may be "meson.py" $ cd _build $ ninja test # ninja install @@ -80,39 +82,40 @@ Graphene, use `-Dgobject_types=false`. Disabling GObject types will also automatically disable generating introspection data. -You can also disable building the test suite and the benchmark suite, +You can explicitly disable building the test suite and the benchmark suite, using the `-Dtests=false` and `-Dbenchmarks=false` configuration switches -respectively. +respectively. The test and benchmark suites depend on [GLib][glib]; if it is +not available at configuration time, tests and benchmarks will be disabled +automatically. #### Building on Windows -In order to build on Windows, it's recommended to use the -[MSYS2](http://sourceforge.net/projects/msys2/) environment. +Graphene supports the Microsoft Visual C compiler 2017 and later versions. -First, [install MSYS2](https://msys2.github.io/) and update it fully -as documented. +Graphene also supports the [MSYS2 toolchain](http://sourceforge.net/projects/msys2/). -Then use `pacman` to set up the build environment by installing the -necessary prerequisites for your target. For all build systems, you -will need a standard development environment and the appropriate native -toolchain. You also need a Python interpreter for Meson and introspection -builds, which are the default. +When using MSYS2, it's recommended to have an up to date installation; +in order to build Graphene you will need to use the `pacman` command +to install the necessary build dependencies first: $ pacman -S base-devel $ pacman -S python3 - $ pacman -S mingw-w64-x86_64-meson # only MINGW64 target - $ pacman -S mingw-w64-i686-meson # only MINGW32 target + $ pacman -S mingw-w64-x86_64-meson # only MINGW64 target + $ pacman -S mingw-w64-i686-meson # only MINGW32 target -There are a number of optional dependencies too: +For the optional support for testing, GObject introspection, and +documentation, you will need to install additional dependencies: $ pacman -S gtk-doc # optional $ pacman -S mingw-w64-x86_64-glib2 # optional, MINGW64 target only $ pacman -S mingw-w64-i686-glib2 # optional, MINGW32 target only $ pacman -S glib2 glib2-devel # optional, MSYS target only -Then clone the Graphene repository and build as usual by following the -instructions in the section above. If you're using Meson, please note -that the tool may be installed as "meson.py" on MSYS2. +After installing all dependencies, you can now clone the Graphene +repository locally, and follow the build instructions above. + +Please note that on some MSYS2 installations the Meson binary may be called +`meson.py`. ## Documentation @@ -156,4 +159,5 @@ See the [LICENSE](./LICENSE) file for more details. +[glib]: https://gitlab.gnome.org/GNOME/glib [gobject-api]: https://developer.gnome.org/gobject/stable/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/doc/graphene-sections.txt new/graphene-1.8.6/doc/graphene-sections.txt --- old/graphene-1.8.2/doc/graphene-sections.txt 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/doc/graphene-sections.txt 2019-03-05 18:32:19.000000000 +0100 @@ -1,6 +1,5 @@ <SECTION> <FILE>graphene-box</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_box_t graphene_box_alloc graphene_box_free @@ -37,7 +36,6 @@ <SECTION> <FILE>graphene-euler</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_euler_t graphene_euler_order_t graphene_euler_alloc @@ -60,7 +58,6 @@ <SECTION> <FILE>graphene-frustum</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_frustum_t graphene_frustum_alloc graphene_frustum_free @@ -76,7 +73,6 @@ <SECTION> <FILE>graphene-gobject</FILE> -<INCLUDE>graphene-gobject.h</INCLUDE> <SUBSECTION Standard> GRAPHENE_TYPE_BOX GRAPHENE_TYPE_EULER @@ -116,7 +112,6 @@ <SECTION> <FILE>graphene-matrix</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_matrix_t graphene_matrix_alloc graphene_matrix_free @@ -182,7 +177,6 @@ <SECTION> <FILE>graphene-plane</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_plane_t graphene_plane_alloc graphene_plane_free @@ -201,7 +195,6 @@ <SECTION> <FILE>graphene-point</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_POINT_INIT GRAPHENE_POINT_INIT_ZERO graphene_point_t @@ -220,7 +213,6 @@ <SECTION> <FILE>graphene-size</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_SIZE_INIT GRAPHENE_SIZE_INIT_ZERO graphene_size_t @@ -236,7 +228,6 @@ <SECTION> <FILE>graphene-point3d</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_POINT3D_INIT GRAPHENE_POINT3D_INIT_ZERO graphene_point3d_t @@ -261,7 +252,6 @@ <SECTION> <FILE>graphene-quad</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_quad_t graphene_quad_alloc graphene_quad_free @@ -275,7 +265,6 @@ <SECTION> <FILE>graphene-quaternion</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_quaternion_t graphene_quaternion_alloc graphene_quaternion_free @@ -302,7 +291,6 @@ <SECTION> <FILE>graphene-ray</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_ray_t graphene_ray_alloc graphene_ray_free @@ -320,7 +308,6 @@ <SECTION> <FILE>graphene-rect</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_RECT_INIT graphene_rect_t graphene_rect_alloc @@ -357,7 +344,6 @@ <SECTION> <FILE>graphene-simd4f</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_simd4f_t graphene_simd4f_init graphene_simd4f_init_zero @@ -433,7 +419,6 @@ <SECTION> <FILE>graphene-simd4x4f</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_simd4x4f_t graphene_simd4x4f_init graphene_simd4x4f_init_identity @@ -468,7 +453,6 @@ <SECTION> <FILE>graphene-sphere</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_sphere_t graphene_sphere_alloc graphene_sphere_free @@ -487,7 +471,6 @@ <SECTION> <FILE>graphene-triangle</FILE> -<INCLUDE>graphene.h</INCLUDE> graphene_triangle_t graphene_triangle_alloc graphene_triangle_free @@ -507,7 +490,6 @@ <SECTION> <FILE>graphene-vectors</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_VEC2_LEN graphene_vec2_t graphene_vec2_alloc @@ -611,7 +593,6 @@ <SECTION> <FILE>graphene-version</FILE> -<INCLUDE>graphene.h</INCLUDE> GRAPHENE_MAJOR_VERSION GRAPHENE_MINOR_VERSION GRAPHENE_MICRO_VERSION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/doc/meson.build new/graphene-1.8.6/doc/meson.build --- old/graphene-1.8.2/doc/meson.build 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/doc/meson.build 2019-03-05 18:32:19.000000000 +0100 @@ -38,6 +38,9 @@ '--ignore-decorators=_GRAPHENE_PUBLIC|GRAPHENE_ALIGN16', '--ignore-headers=' + ' '.join(private_headers), ], + mkdb_args: [ + '--default-include=graphene.h', + ], fixxref_args: [ '--html-dir=@0@'.format(docpath), '--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/meson.build new/graphene-1.8.6/meson.build --- old/graphene-1.8.2/meson.build 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/meson.build 2019-03-05 18:32:19.000000000 +0100 @@ -1,7 +1,7 @@ project('graphene', 'c', - version: '1.8.2', + version: '1.8.6', license: 'MIT', - meson_version: '>= 0.43.1', + meson_version: '>= 0.48.0', default_options: [ 'buildtype=debugoptimized', 'c_std=c99', @@ -114,11 +114,7 @@ common_ldflags = [] if host_system == 'linux' ldflags = [ '-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,-z,now', ] - if meson.version().version_compare('>= 0.46.0') - common_ldflags += cc.get_supported_link_arguments(ldflags) - elif cc.get_id() == 'gcc' - common_ldflags += ldflags - endif + common_ldflags += cc.get_supported_link_arguments(ldflags) endif # Maintain compatibility with Autotools on macOS @@ -230,7 +226,7 @@ return 0; } ''' - conf.set10('HAVE_INIT_ONCE', + conf.set('HAVE_INIT_ONCE', cc.compiles(init_once_prog, name: 'InitOnceExecuteOnce'), description: 'Define if InitOnceExecuteOnce is available', ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/bench/graphene-bench-utils.c new/graphene-1.8.6/src/bench/graphene-bench-utils.c --- old/graphene-1.8.2/src/bench/graphene-bench-utils.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/bench/graphene-bench-utils.c 2019-03-05 18:32:19.000000000 +0100 @@ -166,7 +166,7 @@ graphene_bench_run_test (const char *impl, const char *path, GrapheneBenchFunc func, - gint64 num_rounds, + int num_rounds, double *round_min, double *round_max, double *round_avg) @@ -224,7 +224,7 @@ free (round_elapsed); if (bench_verbose) - g_printerr ("# '[%s]:%s': %.6f usecs/round after %" G_GINT64_FORMAT " rounds\n", + g_printerr ("# '[%s]:%s': %.6f usecs/round after %i rounds\n", impl, path, elapsed, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/bench/matrix.c new/graphene-1.8.6/src/bench/matrix.c --- old/graphene-1.8.2/src/bench/matrix.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/bench/matrix.c 2019-03-05 18:32:19.000000000 +0100 @@ -86,16 +86,17 @@ for (i = 0; i < N_ROUNDS; i++) { + float j = (float) i; graphene_simd4f_t p, q; - p = graphene_simd4f_init (i, i, i, i); - q = graphene_simd4f_init (N_ROUNDS - i, N_ROUNDS - i, N_ROUNDS - i, N_ROUNDS - i); + p = graphene_simd4f_init (j, j, j, j); + q = graphene_simd4f_init (N_ROUNDS - j, N_ROUNDS - j, N_ROUNDS - j, N_ROUNDS - j); res->a[i] = graphene_simd4x4f_init (p, p, p, p); res->b[i] = graphene_simd4x4f_init (q, q, q, q); - res->pa[i] = graphene_simd4f_init (i, i, 0.f, 0.f); - res->qa[i] = graphene_simd4f_init (N_ROUNDS - i, N_ROUNDS - 1, 1.f, 0.f); + res->pa[i] = graphene_simd4f_init (j, j, 0.f, 0.f); + res->qa[i] = graphene_simd4f_init (N_ROUNDS - j, N_ROUNDS - 1, 1.f, 0.f); } return res; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/graphene-gobject.c new/graphene-1.8.6/src/graphene-gobject.c --- old/graphene-1.8.2/src/graphene-gobject.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/graphene-gobject.c 2019-03-05 18:32:19.000000000 +0100 @@ -25,6 +25,7 @@ * SECTION:graphene-gobject * @Title: GObject integration * @short_description: Types for GObject properties and signals + * @Include: graphene-gobject.h * * Graphene optionally provides information for using its own types with * GObject properties and signals. @@ -33,8 +34,17 @@ * * In order to discover at compile time if Graphene exposes type information * for the GType type system, you need to check if the `graphene-gobject-1.0` - * pkg-config file exists. In build systems using autotools, you can use - * the `PKG_CHECK_EXISTS` m4 macro, for instance: + * pkg-config file exists. + * + * If you're using Meson to build your project, you can use a typical + * `dependency()` object, for instance: + * + * |[<!-- language="plain" --> + * graphene_dep = dependency('graphene-gobject-1.0') + * ]| + * + * If you're using Autotools to build your project, you can use the + * `PKG_CHECK_EXISTS` m4 macro, for instance: * * |[<!-- language="plain" --> * PKG_CHECK_EXISTS([graphene-gobject-1.0], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/graphene-macros.h new/graphene-1.8.6/src/graphene-macros.h --- old/graphene-1.8.2/src/graphene-macros.h 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/graphene-macros.h 2019-03-05 18:32:19.000000000 +0100 @@ -71,7 +71,6 @@ # define GRAPHENE_END_DECLS #endif -#ifndef __GI_SCANNER__ #if defined(_MSC_VER) && !defined(__bool_true_false_are_defined) && (_MSC_VER < 1800) typedef int bool; # define false 0 @@ -79,7 +78,6 @@ #else # include <stdbool.h> #endif -#endif #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) #define _GRAPHENE_DEPRECATED __attribute__((__deprecated__)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/graphene-matrix.c new/graphene-1.8.6/src/graphene-matrix.c --- old/graphene-1.8.2/src/graphene-matrix.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/graphene-matrix.c 2019-03-05 18:32:19.000000000 +0100 @@ -33,10 +33,10 @@ * w) representing rows, and elements of each vector are a column: * * |[<!-- language="plain" --> - * | x | | x.x x.y x.z x.w | - * | y | -\ | y.x y.y y.z y.w | - * | z | -/ | z.x z.y z.z z.w | - * | w | | w.x w.y w.z w.w | + * ⎡ m.x ⎤ ⎛ x.x x.y x.z x.w ⎞ + * ⎜ m.y ⎟ -\ ⎜ y.x y.y y.z y.w ⎟ + * ⎜ m.z ⎟ -/ ⎜ z.x z.y z.z z.w ⎟ + * ⎣ m.w ⎦ ⎝ w.x w.y w.z w.w ⎠ * ]| * * It is possible to easily convert a #graphene_matrix_t to and from an array @@ -386,8 +386,8 @@ /** * graphene_matrix_init_skew: * @m: a #graphene_matrix_t - * @x_skew: skew factor on the X axis - * @y_skew: skew factor on the Y axis + * @x_skew: skew factor, in radians, on the X axis + * @y_skew: skew factor, in radians, on the Y axis * * Initializes a #graphene_matrix_t with a skew transformation * with the given factors. @@ -560,13 +560,13 @@ * The arguments map to the following matrix layout: * * |[<!-- language="plain" --> - * | xx yx | | a b 0 | - * | xy yy | = | c d 0 | - * | x0 y0 | | tx ty 1 | + * ⎛ xx yx ⎞ ⎛ a b 0 ⎞ + * ⎜ xy yy ⎟ = ⎜ c d 0 ⎟ + * ⎝ x0 y0 ⎠ ⎝ tx ty 1 ⎠ * ]| * - * This function can be used to convert between a matrix type from - * other libraries and a #graphene_matrix_t. + * This function can be used to convert between an affine matrix type + * from other libraries and a #graphene_matrix_t. * * Returns: (transfer none): the initialized matrix * @@ -605,13 +605,13 @@ * The returned values have the following layout: * * |[<!-- language="plain" --> - * | xx yx | | a b 0 | - * | xy yy | = | c d 0 | - * | x0 y0 | | tx ty 1 | + * ⎛ xx yx ⎞ ⎛ a b 0 ⎞ + * ⎜ xy yy ⎟ = ⎜ c d 0 ⎟ + * ⎝ x0 y0 ⎠ ⎝ tx ty 1 ⎠ * ]| * * This function can be used to convert between a #graphene_matrix_t - * and a matrix type from other libraries. + * and an affine matrix type from other libraries. * * Returns: `true` if the matrix is compatible with an affine * transformation matrix @@ -629,38 +629,22 @@ { float res[4]; - graphene_simd4f_dup_4f (m->value.x, res); - if (!graphene_approx_val (res[2], 0.f) && - !graphene_approx_val (res[3], 0.f)) + if (!graphene_simd4x4f_is_2d (&m->value)) return false; + graphene_simd4f_dup_4f (m->value.x, res); if (xx != NULL) *xx = res[0]; if (yx != NULL) *yx = res[1]; graphene_simd4f_dup_4f (m->value.y, res); - if (!graphene_approx_val (res[2], 0.f) && - !graphene_approx_val (res[3], 0.f)) - return false; - if (xy != NULL) *xy = res[0]; if (yy != NULL) *yy = res[1]; - graphene_simd4f_dup_4f (m->value.z, res); - if (!graphene_approx_val (res[0], 0.f) && - !graphene_approx_val (res[1], 0.f) && - !graphene_approx_val (res[2], 1.f) && - !graphene_approx_val (res[3], 0.f)) - return false; - graphene_simd4f_dup_4f (m->value.w, res); - if (!graphene_approx_val (res[2], 0.f) && - !graphene_approx_val (res[3], 1.f)) - return false; - if (x_0 != NULL) *x_0 = res[0]; if (y_0 != NULL) @@ -783,8 +767,8 @@ * * Multiplies two #graphene_matrix_t. * - * Remember: matrix multiplication is not commutative, except for the - * identity matrix; the product of this multiplication is (A * B). + * Matrix multiplication is not commutative in general; the order of the factors matters. + * The product of this multiplication is (@a × @b) * * Since: 1.0 */ @@ -824,6 +808,12 @@ * * Transforms the given #graphene_vec3_t using the matrix @m. * + * This function will multiply the X, Y, and Z row vectors of the matrix @m + * with the corresponding components of the vector @v. The W row vector will + * be ignored. + * + * See also: graphene_simd4x4f_vec3_mul() + * * Since: 1.0 */ void @@ -842,6 +832,8 @@ * * Transforms the given #graphene_vec4_t using the matrix @m. * + * See also: graphene_simd4x4f_vec4_mul() + * * Since: 1.0 */ void @@ -861,6 +853,12 @@ * * Transforms the given #graphene_point_t using the matrix @m. * + * Unlike graphene_matrix_transform_vec3(), this function will take into + * account the fourth row vector of the #graphene_matrix_t when computing + * the dot product of each row vector of the matrix. + * + * See also: graphene_simd4x4f_point3_mul() + * * Since: 1.0 */ void @@ -870,8 +868,8 @@ { graphene_simd4f_t vec3; - vec3 = graphene_simd4f_init (p->x, p->y, 0.0f, 0.0f); - graphene_simd4x4f_vec3_mul (&m->value, &vec3, &vec3); + vec3 = graphene_simd4f_init (p->x, p->y, 0.0f, 1.0f); + graphene_simd4x4f_point3_mul (&m->value, &vec3, &vec3); res->x = graphene_simd4f_get_x (vec3); res->y = graphene_simd4f_get_y (vec3); @@ -886,7 +884,8 @@ * Transforms the given #graphene_point3d_t using the matrix @m. * * Unlike graphene_matrix_transform_vec3(), this function will take into - * account the fourth row vector of the #graphene_matrix_t. + * account the fourth row vector of the #graphene_matrix_t when computing + * the dot product of each row vector of the matrix. * * Since: 1.2 */ @@ -897,7 +896,7 @@ { graphene_simd4f_t vec3; - vec3 = graphene_simd4f_init (p->x, p->y, p->z, 0.f); + vec3 = graphene_simd4f_init (p->x, p->y, p->z, 1.f); graphene_simd4x4f_point3_mul (&m->value, &vec3, &vec3); res->x = graphene_simd4f_get_x (vec3); @@ -912,8 +911,9 @@ * @res: (out caller-allocates): return location for the * transformed quad * - * Transforms a #graphene_rect_t using the given matrix @m. The - * result is a coplanar quad. + * Transforms each corner of a #graphene_rect_t using the given matrix @m. + * + * The result is a coplanar quadrilateral. * * Since: 1.0 */ @@ -950,8 +950,10 @@ * @res: (out caller-allocates): return location for the bounds * of the transformed rectangle * - * Transforms a #graphene_rect_t using the given matrix @m. The - * result is the bounding box containing the coplanar quad. + * Transforms each corner of a #graphene_rect_t using the given matrix @m. + * + * The result is the axis aligned bounding rectangle containing the coplanar + * quadrilateral. * * Since: 1.0 */ @@ -1047,8 +1049,10 @@ * @res: (out caller-allocates): return location for the bounds * of the transformed box * - * Transforms a #graphene_box_t using the given matrix @m. The - * result is the bounding box containing the transformed box. + * Transforms the vertices of a #graphene_box_t using the given matrix @m. + * + * The result is the axis aligned bounding box containing the transformed + * vertices. * * Since: 1.2 */ @@ -1138,8 +1142,8 @@ * * Projects a #graphene_rect_t using the given matrix. * - * The resulting rectangle is the bounding box capable of containing - * fully the projected rectangle. + * The resulting rectangle is the axis aligned bounding rectangle capable + * of containing fully the projected rectangle. * * Since: 1.0 */ @@ -1214,7 +1218,7 @@ * untransformed point * * Undoes the transformation of a #graphene_point_t using the - * given matrix, within the given rectangular @bounds. + * given matrix, within the given axis aligned rectangular @bounds. * * Returns: `true` if the point was successfully untransformed * @@ -1258,8 +1262,8 @@ * @res: (out caller-allocates): return location for the * untransformed rectangle * - * Undoes the transformation on the points of a #graphene_rect_t - * using the given matrix, within the given rectangular @bounds. + * Undoes the transformation on the corners of a #graphene_rect_t using the + * given matrix, within the given axis aligned rectangular @bounds. * * Since: 1.0 */ @@ -1343,6 +1347,9 @@ * Adds a translation transformation to @m using the coordinates * of the given #graphene_point3d_t. * + * This is the equivalent of calling graphene_matrix_init_translate() and + * then multiplying @m with the translation matrix. + * * Since: 1.0 */ void @@ -1363,6 +1370,9 @@ * Adds a rotation transformation to @m, using the given * #graphene_quaternion_t. * + * This is the equivalent of calling graphene_quaternion_to_matrix() and + * then multiplying @m with the rotation matrix. + * * Since: 1.2 */ void @@ -1415,6 +1425,9 @@ * Adds a rotation transformation to @m, using the given @angle * and @axis vector. * + * This is the equivalent of calling graphene_matrix_init_rotate() and + * then multiplying the matrix @m with the rotation matrix. + * * Since: 1.0 */ void @@ -1433,6 +1446,8 @@ * Adds a rotation transformation around the X axis to @m, using * the given @angle. * + * See also: graphene_matrix_rotate() + * * Since: 1.0 */ void @@ -1451,6 +1466,8 @@ * Adds a rotation transformation around the Y axis to @m, using * the given @angle. * + * See also: graphene_matrix_rotate() + * * Since: 1.0 */ void @@ -1469,6 +1486,8 @@ * Adds a rotation transformation around the Z axis to @m, using * the given @angle. * + * See also: graphene_matrix_rotate() + * * Since: 1.0 */ void @@ -1489,6 +1508,9 @@ * Adds a scaling transformation to @m, using the three * given factors. * + * This is the equivalent of calling graphene_matrix_init_scale() and then + * multiplying the matrix @m with the scale matrix. + * * Since: 1.0 */ void @@ -1822,7 +1844,7 @@ graphene_point3d_t *translate_r, graphene_vec4_t *perspective_r) { - graphene_matrix_t local, perspective; + graphene_matrix_t local; float shear_xy, shear_xz, shear_yz; float scale_x, scale_y, scale_z; graphene_simd4f_t perspective_v; @@ -1840,17 +1862,20 @@ * but it also provides an easy way to test for singularity of * the upper 3x3 component */ - perspective = local; - perspective.value.w = graphene_simd4f_init (0.f, 0.f, 0.f, 1.f); - - if (graphene_approx_val (graphene_matrix_determinant (&perspective), 0.f)) - return false; - perspective_v = graphene_simd4f_init (graphene_simd4f_get_w (local.value.x), graphene_simd4f_get_w (local.value.y), graphene_simd4f_get_w (local.value.z), graphene_simd4f_get_w (local.value.w)); + /* Clear the perspective component */ + local.value.x = graphene_simd4f_merge_w (local.value.x, 0.f); + local.value.y = graphene_simd4f_merge_w (local.value.y, 0.f); + local.value.z = graphene_simd4f_merge_w (local.value.z, 0.f); + local.value.w = graphene_simd4f_merge_w (local.value.w, 1.f); + + if (graphene_approx_val (graphene_matrix_determinant (&local), 0.f)) + return false; + /* isolate the perspective */ if (!graphene_simd4f_is_zero3 (perspective_v)) { @@ -1864,14 +1889,8 @@ * check if the matrix is invertible here because we just checked * whether the determinant is not zero. */ - graphene_matrix_inverse (&perspective, &tmp); - graphene_matrix_transpose_transform_vec4 (&tmp, perspective_r, perspective_r); - - /* Clear the perspective component */ - local.value.x = graphene_simd4f_merge_w (local.value.x, 0.f); - local.value.y = graphene_simd4f_merge_w (local.value.y, 0.f); - local.value.z = graphene_simd4f_merge_w (local.value.z, 0.f); - local.value.w = graphene_simd4f_merge_w (local.value.w, 1.f); + graphene_matrix_inverse (&local, &tmp); + graphene_matrix_transform_vec4 (&tmp, perspective_r, perspective_r); } else graphene_vec4_init (perspective_r, 0.f, 0.f, 0.f, 1.f); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/graphene-plane.c new/graphene-1.8.6/src/graphene-plane.c --- old/graphene-1.8.2/src/graphene-plane.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/graphene-plane.c 2019-03-05 18:32:19.000000000 +0100 @@ -26,9 +26,11 @@ * @Title: Plane * @Short_Description: A plane in 3D space * - * #graphene_plane_t is a structure representing a plane in 3D space, using - * a normal vector pointing towards the origin, and a constant distance from - * the origin along the normal vector. + * #graphene_plane_t is a structure representing a plane that extends + * infinitely in 3D space, described using the [Hessian normal + * form](http://mathworld.wolfram.com/HessianNormalForm.html) + * of a unit length normal vector pointing towards the origin, and a + * constant distance from the origin along the normal vector. */ #include "graphene-private.h" @@ -78,9 +80,11 @@ /** * graphene_plane_init: * @p: the #graphene_plane_t to initialize - * @normal: (nullable): a normal vector defining the plane pointing towards the origin - * @constant: the negative distance from the origin to the plane along the - * normal vector + * @normal: (nullable): a unit length normal vector defining the plane + * pointing towards the origin; if unset, we use the X axis by default + * @constant: the distance from the origin to the plane along the + * normal vector; the sign determines the half-space occupied by the + * plane * * Initializes the given #graphene_plane_t using the given @normal vector * and @constant values. @@ -221,7 +225,8 @@ * @p: a #graphene_plane_t * @res: (out caller-allocates): return location for the normalized plane * - * Normalizes the vector and constant of a #graphene_plane_t. + * Normalizes the vector of the given #graphene_plane_t, + * and adjusts the constant accordingly. * * Since: 1.2 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/graphene-simd4x4f.h new/graphene-1.8.6/src/graphene-simd4x4f.h --- old/graphene-1.8.2/src/graphene-simd4x4f.h 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/graphene-simd4x4f.h 2019-03-05 18:32:19.000000000 +0100 @@ -218,8 +218,30 @@ * @b: a #graphene_simd4f_t * @res: (out): return location for a #graphene_simd4f_t * - * Multiplies the given #graphene_simd4x4f_t with the given - * #graphene_simd4f_t using a dot product. + * Left multiplies the given #graphene_simd4x4f_t with the given + * #graphene_simd4f_t row vector using a dot product: + * + * |[<!-- language="plain" --> + * res = b × A + * + * = ⎡x⎤ ⎛ x.x x.y x.z x.w ⎞ + * ⎜y⎟ ⎜ y.x y.y y.z y.w ⎟ + * ⎜z⎟ ⎜ z.x z.y z.z z.w ⎟ + * ⎣w⎦ ⎝ w.x w.y w.z w.w ⎠ + * + * = [ x.x × x x.y × x x.z × x x.w × x ] + * + + + + + * [ y.x × y y.y × y y.z × y y.w × y ] + * + + + + + * [ z.x × z z.y × z z.z × z z.w × z ] + * + + + + + * [ w.x × w w.y × w w.z × w w.w × w ] + * + * = ⎡ x.x × x + y.x × y + z.x × z + w.x × w ⎤ + * ⎜ x.y × x + y.y × y + z.y × z + w.y × w ⎟ + * ⎜ x.z × x + y.z × y + z.z × z + w.z × w ⎟ + * ⎣ x.w × x + y.w × y + z.w × z + w.w × w ⎦ + * ]| * * Since: 1.0 */ @@ -246,9 +268,31 @@ * @v: a #graphene_simd4f_t * @res: (out): return location for a #graphene_simd4f_t * - * Multiplies the given #graphene_simd4x4f_t with the given + * Left multiplies the given #graphene_simd4x4f_t with the given * #graphene_simd4f_t, using only the first three row vectors - * of the matrix, and the first three components of the vector. + * of the matrix, and the first three components of the vector; + * the W components of the matrix and vector are ignored: + * + * |[<!-- language="plain" --> + * res = b × A + * + * = ⎡x⎤ ⎛ x.x x.y x.z ⎞ + * ⎜y⎟ ⎜ y.x y.y y.z ⎟ + * ⎣z⎦ ⎝ z.x z.y z.z ⎠ + * + * = [ x.x × x x.y × x x.z × x ] + * + + + + * [ y.x × y y.y × y y.z × y ] + * + + + + * [ z.x × z z.y × z z.z × z ] + * + * = ⎡ x.x × x + y.x × y + z.x × z ⎤ + * ⎜ x.y × x + y.y × y + z.y × z ⎟ + * ⎜ x.z × x + y.z × y + z.z × z ⎟ + * ⎣ 0 ⎦ + * ]| + * + * See also: graphene_simd4x4f_vec4_mul(), graphene_simd4x4f_point3_mul() * * Since: 1.0 */ @@ -260,10 +304,12 @@ const graphene_simd4f_t v_x = graphene_simd4f_splat_x (*v); const graphene_simd4f_t v_y = graphene_simd4f_splat_y (*v); const graphene_simd4f_t v_z = graphene_simd4f_splat_z (*v); + graphene_simd4f_t r; - *res = graphene_simd4f_add (graphene_simd4f_add (graphene_simd4f_mul (m->x, v_x), - graphene_simd4f_mul (m->y, v_y)), - graphene_simd4f_mul (m->z, v_z)); + r = graphene_simd4f_add (graphene_simd4f_add (graphene_simd4f_mul (m->x, v_x), + graphene_simd4f_mul (m->y, v_y)), + graphene_simd4f_mul (m->z, v_z)); + *res = graphene_simd4f_zero_w (r); } /** @@ -276,7 +322,29 @@ * #graphene_simd4f_t. * * Unlike graphene_simd4x4f_vec3_mul(), this function will - * also use the fourth row vector of the matrix. + * use the W components of the matrix: + * + * |[<!-- language="plain" --> + * res = b × A + * + * = ⎡x⎤ ⎛ x.x x.y x.z x.w ⎞ + * ⎜y⎟ ⎜ y.x y.y y.z y.w ⎟ + * ⎜z⎟ ⎜ z.x z.y z.z z.w ⎟ + * ⎣w⎦ ⎝ w.x w.y w.z w.w ⎠ + * + * = [ x.x × x x.y × x x.z × x x.w × x ] + * + + + + + * [ y.x × y y.y × y y.z × y y.w × y ] + * + + + + + * [ z.x × z z.y × z z.z × z z.w × z ] + * + + + + + * [ w.x w.y w.z w.w ] + * + * = ⎡ x.x × x + y.x × y + z.x × z + w.x ⎤ + * ⎜ x.y × x + y.y × y + z.y × z + w.y ⎟ + * ⎜ x.z × x + y.z × y + z.z × z + w.z ⎟ + * ⎣ x.w × x + y.w × y + z.w × z + w.w ⎦ + * ]| * * Since: 1.0 */ @@ -428,10 +496,14 @@ * the order is correct if we want to multiply A with B; remember * that matrix multiplication is non-commutative. */ - graphene_simd4x4f_vec4_mul (b, &a->x, &res->x); - graphene_simd4x4f_vec4_mul (b, &a->y, &res->y); - graphene_simd4x4f_vec4_mul (b, &a->z, &res->z); - graphene_simd4x4f_vec4_mul (b, &a->w, &res->w); + graphene_simd4f_t x, y, z, w; + + graphene_simd4x4f_vec4_mul (b, &a->x, &x); + graphene_simd4x4f_vec4_mul (b, &a->y, &y); + graphene_simd4x4f_vec4_mul (b, &a->z, &z); + graphene_simd4x4f_vec4_mul (b, &a->w, &w); + + *res = graphene_simd4x4f_init (x, y, z, w); #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/meson.build new/graphene-1.8.6/src/meson.build --- old/graphene-1.8.2/src/meson.build 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/meson.build 2019-03-05 18:32:19.000000000 +0100 @@ -69,7 +69,7 @@ ) # External configuration header -configure_file( +graphene_config_h = configure_file( input: 'graphene-config.h.meson', output: 'graphene-config.h', configuration: graphene_conf, @@ -94,12 +94,19 @@ install_headers(headers + simd_headers + [ 'graphene.h' ], subdir: graphene_api_path) -pkgconfig_files = [ graphene_api_path ] +# pkg name, extra requires +pkgconfig_files = [ + [ graphene_api_path, [], ], +] + platform_deps = [] if build_gobject - pkgconfig_files += [ graphene_gobject_api_path ] - platform_deps += [ gobject ] + pkgconfig_files += [ + [ graphene_gobject_api_path, gobject ], + ] + + platform_deps += gobject endif libgraphene = library( @@ -115,29 +122,33 @@ link_args: common_ldflags, ) -foreach simd: [ 'sse2', 'gcc', 'neon' ] +foreach simd: [ 'sse2', 'gcc', 'neon', 'scalar', ] set_variable('has_' + simd, graphene_simd.contains(simd) ? '1' : '0') endforeach pkgconfig = import('pkgconfig') foreach p: pkgconfig_files + pkg_name = p[0] + pkg_requires = p[1] + pkgconfig.generate( + libgraphene, name: 'Graphene', description: 'Math classes for graphic libraries', url: 'https://ebassi.github.io/graphene', version: meson.project_version(), - filebase: p, + filebase: pkg_name, variables: [ 'graphene_has_sse2=@0@'.format(has_sse2), 'graphene_has_gcc=@0@'.format(has_gcc), 'graphene_has_neon=@0@'.format(has_neon), - 'graphene_has_scalar=1', + 'graphene_has_scalar=@0@'.format(has_scalar), ], subdirs: graphene_api_path, + requires: pkg_requires, extra_cflags: [ '-I${libdir}/@0@/include'.format(graphene_api_path), ] + sse2_cflags + neon_cflags, - libraries: libgraphene, ) endforeach @@ -155,8 +166,9 @@ '--warn-all', '-DGRAPHENE_COMPILATION', ] + graphene_gir = gnome.generate_gir(libgraphene, - sources: headers + sources, + sources: [graphene_config_h] + headers + sources, namespace: 'Graphene', nsversion: graphene_api_version, identifier_prefix: 'Graphene', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/tests/graphene-test-compat.h new/graphene-1.8.6/src/tests/graphene-test-compat.h --- old/graphene-1.8.2/src/tests/graphene-test-compat.h 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/tests/graphene-test-compat.h 2019-03-05 18:32:19.000000000 +0100 @@ -108,6 +108,21 @@ } \ } G_STMT_END +#define graphene_assert_fuzzy_point3d_equal(p1,p2,epsilon) \ + G_STMT_START { \ + graphene_point3d_t *__p1 = (p1); \ + graphene_point3d_t *__p2 = (p2); \ + float __epsilon = (epsilon); \ + if (graphene_point3d_near (__p1, __p2, __epsilon)) ; \ + else { \ + char *s = g_strdup_printf (#p1 " == " #p2 " (+/- " #epsilon "): " \ + "{ x:%.7g, y:%.7g, z:%.7g } == { x:%.7g, y:%.7g, z:%.7g }", \ + __p1->x, __p1->y, __p1->z, __p2->x, __p2->y, __p2->z); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, s); \ + g_free (s); \ + } \ + } G_STMT_END + #define graphene_assert_fuzzy_size_equal(s1,s2,epsilon) \ G_STMT_START { \ if (graphene_fuzzy_equals ((s1)->width, (s2)->width, epsilon) && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/graphene-1.8.2/src/tests/matrix.c new/graphene-1.8.6/src/tests/matrix.c --- old/graphene-1.8.2/src/tests/matrix.c 2018-06-13 18:51:25.000000000 +0200 +++ new/graphene-1.8.6/src/tests/matrix.c 2019-03-05 18:32:19.000000000 +0100 @@ -455,6 +455,78 @@ } GRAPHENE_TEST_UNIT_END +GRAPHENE_TEST_UNIT_BEGIN (matrix_interpolate_perspective) +{ + graphene_matrix_t m1, m2, m3, mr; + + graphene_matrix_init_identity (&m1); + graphene_matrix_perspective (&m1, 200, &m1); + graphene_matrix_init_identity (&m2); + graphene_matrix_perspective (&m2, 800, &m2); + + graphene_matrix_interpolate (&m1, &m2, 0.0, &mr); + graphene_assert_fuzzy_matrix_equal (&mr, &m1, 0.1); + + graphene_matrix_interpolate (&m1, &m2, 1.0, &mr); + graphene_assert_fuzzy_matrix_equal (&mr, &m2, 0.1); + + graphene_matrix_init_identity (&m3); + graphene_matrix_perspective (&m3, 400, &m3); + graphene_matrix_interpolate (&m1, &m2, 0.5, &mr); + graphene_assert_fuzzy_matrix_equal (&mr, &m3, 0.1); +} +GRAPHENE_TEST_UNIT_END + +GRAPHENE_TEST_UNIT_BEGIN (matrix_multiply_self) +{ + graphene_matrix_t a, b, res, test; + float floats[16] = { 0, 0, 0, 2, + 0, 0, 2, 0, + 0, 2, 0, 0, + 2, 0, 0, 0 }; + + graphene_matrix_init_from_float (&a, floats); + graphene_matrix_init_from_float (&b, floats); + graphene_matrix_multiply (&a, &b, &res); + + graphene_matrix_init_from_float (&test, floats); + graphene_matrix_multiply (&test, &b, &test); + graphene_assert_fuzzy_matrix_equal (&test, &res, G_MINDOUBLE); + + graphene_matrix_init_from_float (&test, floats); + graphene_matrix_multiply (&a, &test, &test); + graphene_assert_fuzzy_matrix_equal (&test, &res, G_MINDOUBLE); + + graphene_matrix_init_from_float (&test, floats); + graphene_matrix_multiply (&test, &test, &test); + graphene_assert_fuzzy_matrix_equal (&test, &res, G_MINDOUBLE); +} +GRAPHENE_TEST_UNIT_END + +GRAPHENE_TEST_UNIT_BEGIN (matrix_to_2d) +{ + graphene_matrix_t matrix; + float f[16]; + guint i; + bool valid[16] = { + true, true, false, false, + true, true, false, false, + false, false, false, false, + true, true, false, false }; + + for (i = 0; i < 16; i++) + { + /* Take the identity matrix and change one member to a different value */ + graphene_matrix_init_identity (&matrix); + graphene_matrix_to_float (&matrix, f); + f[i] = 0.5f; + graphene_matrix_init_from_float (&matrix, f); + + g_assert_cmpint (graphene_matrix_to_2d (&matrix, NULL, NULL, NULL, NULL, NULL, NULL), ==, valid[i]); + } +} +GRAPHENE_TEST_UNIT_END + GRAPHENE_TEST_UNIT_BEGIN (matrix_2d_interpolate) { graphene_matrix_t m1, m2, m3, mr; @@ -498,6 +570,32 @@ } GRAPHENE_TEST_UNIT_END +GRAPHENE_TEST_UNIT_BEGIN (matrix_3d_transform_point) +{ + graphene_matrix_t m; + graphene_point_t p; + graphene_point3d_t p3; + graphene_vec3_t v; + + graphene_matrix_init_translate (&m, &GRAPHENE_POINT3D_INIT (50.f, 70.f, 0.f)); + + g_test_message ("mat(translation) * point(zero) = point(translation)"); + graphene_point_init (&p, 0.f, 0.f); + graphene_matrix_transform_point (&m, &p, &p); + graphene_assert_fuzzy_point_equal (&p, &GRAPHENE_POINT_INIT (50.f, 70.f), 0.01f); + + g_test_message ("mat(translation) * point3d(zero) = point3d(translation)"); + graphene_point3d_init (&p3, 0.f, 0.f, 0.f); + graphene_matrix_transform_point3d (&m, &p3, &p3); + graphene_assert_fuzzy_point3d_equal (&p3, &GRAPHENE_POINT3D_INIT (50.f, 70.f, 0.0f), 0.01f); + + g_test_message ("mat(translation) * vec3(zero) = vec3(zero)"); + graphene_vec3_init (&v, 0.f, 0.f, 0.f); + graphene_matrix_transform_vec3 (&m, &v, &v); + graphene_assert_fuzzy_vec3_equal (&v, graphene_vec3_zero (), 0.01f); +} +GRAPHENE_TEST_UNIT_END + GRAPHENE_TEST_SUITE ( GRAPHENE_TEST_UNIT ("/matrix/identity", matrix_identity) GRAPHENE_TEST_UNIT ("/matrix/scale", matrix_scale) @@ -508,9 +606,13 @@ GRAPHENE_TEST_UNIT ("/matrix/look_at", matrix_look_at) GRAPHENE_TEST_UNIT ("/matrix/invert", matrix_invert) GRAPHENE_TEST_UNIT ("/matrix/interpolate", matrix_interpolate) + GRAPHENE_TEST_UNIT ("/matrix/interpolate-perspective", matrix_interpolate_perspective) + GRAPHENE_TEST_UNIT ("/matrix/multiply_self", matrix_multiply_self) + GRAPHENE_TEST_UNIT ("/matrix/to-2d", matrix_to_2d) GRAPHENE_TEST_UNIT ("/matrix/2d/identity", matrix_2d_identity) GRAPHENE_TEST_UNIT ("/matrix/2d/transforms", matrix_2d_transforms) GRAPHENE_TEST_UNIT ("/matrix/2d/round-trip", matrix_2d_round_trip) GRAPHENE_TEST_UNIT ("/matrix/2d/interpolate", matrix_2d_interpolate) GRAPHENE_TEST_UNIT ("/matrix/2d/transform_bound", matrix_2d_transform_bound) + GRAPHENE_TEST_UNIT ("/matrix/3d/transform_point", matrix_3d_transform_point) )