Name Mode Size
..
shaders 040000
README.md
# `gliso` A [GLSL][]/[OpenGL][] [\>=2.1][] [isometry][] matrix library. If a `mat4` matrix represents an [isometry][], which in this case means that it encodes only rotations and translations (no scaling or shearing, and a projective `w` entry equal to `1`), it is easy and performant to extract those rotations and translations, and to compute the [inverse][]. This library provides functions to do so. [`gliso`]: https://git.rcrnstn.net/rcrnstn/gliso [GLSL]: https://en.wikipedia.org/wiki/OpenGL_Shading_Language [OpenGL]: https://en.wikipedia.org/wiki/OpenGL [\>=2.1]: https://en.wikipedia.org/wiki/OpenGL#Version_history [isometry]: https://en.wikipedia.org/wiki/Isometry [inverse]: https://en.wikipedia.org/wiki/Invertible_matrix ## Requirements Support for `#include` directives is required. This can be provided by e.g. the standardized [`ARB_shading_language_include`][] extension or some third party library. [`ARB_shading_language_include`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt ## Usage Link shader programs with the provided `iso.glsl`. Include the provided `iso.h` from shaders. It declares the following functions: - `mat{3,4} isorot{inv}{3,4}(mat4 iso)` Extract (inverse) rotation. - `vec{3,4} isotrans{inv}{3,4}(mat4 iso)` Extract (inverse) translation. The `z` components of the `4` versions are set to `0`. - `mat4 isoinv(mat4 iso)` Compute inverse. ## Theory For simplicity, we use the same name for both the [projective][] and [Euclidean][] versions of vectors and transformations below. Assume $M$ is an isometry, $$ M v = \begin{pmatrix} r_{xx} & r_{yx} & r_{zx} & t_x \\ r_{xx} & r_{yx} & r_{zx} & t_y \\ r_{xx} & r_{yx} & r_{zx} & t_z \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} v_x \\ v_y \\ v_z \\ 1 \\ \end{pmatrix} = R v + t $$ It is trivial to extract the rotation $R$ and translation $t$ directly from the components of $M$. Since the rotation part $R$ is [orthonormal][], its inverse is its own transpose. The inverse of the translation is its own negation. $$ \begin{aligned} R^{-1} &= R^T \\ t^{-1} &= -t \\ \end{aligned} $$ Assuming the $3 \mathsf{x} 3$ sub-matrix of $M^{-1}$ is $R^{-1}$, finding the full inverse is simply a matter of finding $M^{-1}$'s fourth column $m^{-1}$: $$ \begin{aligned} v &= M^{-1} M v \\ &= R^{-1} (R v + t) + m^{-1} \\ &= v + R^{-1} t + m^{-1} \\ &\iff \\ m^{-1} &= -R^{-1} t = R^{-1} t^{-1} \\ \end{aligned} $$ Computing this is much faster than the built-in, general, [`inverse`][]. [projective]: https://en.wikipedia.org/wiki/Homogeneous_coordinates [Euclidean]: https://en.wikipedia.org/wiki/Cartesian_coordinates [orthonormal]: https://en.wikipedia.org/wiki/Orthogonal_matrix [`inverse`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/inverse.xhtml ## Build system This project has support for [CMake][], and uses [`cmake-cxx`][]. There are several ways to use this project in another CMake-based project: - Use [`FetchContent`][] to download it and import the targets automatically as part of the configure step: ```cmake include(FetchContent) FetchContent_Declare(project-name GIT_REPOSITORY https://example.com/user/project-name ) FetchContent_MakeAvailable( project-name ) ``` - Bundle it and import the targets with [`add_subdirectory`][]. - Use [`find_package`][] (requires that the project is [packaged](#packaging) or [installed](#installing)). As usual, use [`add_dependencies`][]/[`target_link_libraries`][] to declare the dependency. [CMake]: https://cmake.org [`cmake-cxx`]: https://git.rcrnstn.net/rcrnstn/cmake-cxx [`FetchContent`]: https://cmake.org/cmake/help/v3.14/module/FetchContent.html [`add_subdirectory`]: https://cmake.org/cmake/help/v3.14/command/add_subdirectory.html [`find_package`]: https://cmake.org/cmake/help/v3.14/command/find_package.html [`add_dependencies`]: https://cmake.org/cmake/help/v3.14/command/add_dependencies.html [`target_link_libraries`]: https://cmake.org/cmake/help/v3.14/command/target_link_libraries.html ### Configure and generate To configure and generate a build tree, use `cmake`: ```sh cmake -B build ``` To set the [`CMAKE_BUILD_TYPE`][], pass e.g. `-DCMAKE_BUILD_TYPE=Release`. [`cmake`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#generate-a-project-buildsystem [`CMAKE_BUILD_TYPE`]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_BUILD_TYPE.html ### Build To build, use [`cmake --build`][]: ```sh cmake --build build ``` [`cmake --build`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#build-a-project ### Test To run tests, use [`ctest`][]: ```sh (cd build && ctest --output-on-failure) ``` [`ctest`]: https://cmake.org/cmake/help/v3.14/manual/ctest.1.html ### Package To package, use [`cpack`][]: ```sh (cd build && cpack) ``` [`cpack`]: https://cmake.org/cmake/help/v3.14/manual/cpack.1.html ### Install To install onto the current system, use [`cmake --install`][]: ```sh cmake --install build ``` [`cmake --install`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#install-a-project ## License Licensed under the [ISC License][] unless otherwise noted, see the [`LICENSE`](LICENSE) file. [ISC License]: https://choosealicense.com/licenses/isc/