25 releases (breaking)
0.19.0 | Jun 23, 2024 |
---|---|
0.18.0 | Jan 14, 2023 |
0.17.0 | Apr 30, 2022 |
0.16.0 | Jan 2, 2022 |
0.2.0 | Oct 22, 2018 |
#892 in Math
10,345 downloads per month
Used in 72 crates
(54 directly)
2MB
39K
SLoC
Linear algebra library for the Rust programming language.
lib.rs
:
nalgebra-glm − nalgebra in easy mode
nalgebra-glm is a GLM-like interface for the nalgebra general-purpose linear algebra library. GLM itself is a popular C++ linear algebra library essentially targeting computer graphics. Therefore nalgebra-glm draws inspiration from GLM to define a nice and easy-to-use API for simple graphics application.
All the types of nalgebra-glm are aliases of types from nalgebra. Therefore there is a complete and seamless inter-operability between both.
Getting started
First of all, you should start by taking a look at the official GLM API documentation
since nalgebra-glm implements a large subset of it. To use nalgebra-glm to your project, you
should add it as a dependency to your Crates.toml
:
[dependencies]
nalgebra-glm = "0.3"
Then, you should add an extern crate
statement to your lib.rs
or main.rs
file. It is strongly
recommended to add a crate alias to glm
as well so that you will be able to call functions of
nalgebra-glm using the module prefix glm::
. For example you will write glm::rotate(...)
instead
of the more verbose nalgebra_glm::rotate(...)
:
extern crate nalgebra_glm as glm;
Features overview
nalgebra-glm supports most linear-algebra related features of the C++ GLM library. Mathematically speaking, it supports all the common transformations like rotations, translations, scaling, shearing, and projections but operating in homogeneous coordinates. This means all the 2D transformations are expressed as 3x3 matrices, and all the 3D transformations as 4x4 matrices. This is less computationally-efficient and memory-efficient than nalgebra's transformation types, but this has the benefit of being simpler to use.
Main differences compared to GLM
While nalgebra-glm follows the feature line of the C++ GLM library, quite a few differences remain and they are mostly syntactic. The main ones are:
- All function names use
snake_case
, which is the Rust convention. - All type names use
CamelCase
, which is the Rust convention. - All function arguments, except for scalars, are all passed by-reference.
- The most generic vector and matrix types are
TMat
andTVec
instead ofmat
andvec
. - Some feature are not yet implemented and should be added in the future. In particular, no packing functions are available.
- A few features are not implemented and will never be. This includes functions related to color spaces, and closest points computations. Other crates should be used for those. For example, closest points computation can be handled by the ncollide project.
In addition, because Rust does not allows function overloading, all functions must be given a unique name. Here are a few rules chosen arbitrarily for nalgebra-glm:
- Functions operating in 2d will usually end with the
2d
suffix, e.g.,glm::rotate2d()
is for 2D whileglm::rotate()
is for 3D. - Functions operating on vectors will often end with the
_vec
suffix, possibly followed by the dimension of vector, e.g.,glm::rotate_vec2()
. - Every function related to quaternions start with the
quat_
prefix, e.g.,glm::quat_dot(q1, q2)
. - All the conversion functions have unique names as described below.
Vector and matrix construction
Vectors, matrices, and quaternions can be constructed using several approaches:
- Using functions with the same name as their type in lower-case. For example
glm::vec3(x, y, z)
will create a 3D vector. - Using the
::new
constructor. For exampleVec3::new(x, y, z)
will create a 3D vector. - Using the functions prefixed by
make_
to build a vector a matrix from a slice. For exampleglm::make_vec3(&[x, y, z])
will create a 3D vector. Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice. - Using a geometric construction function. For example
glm::rotation(angle, axis)
will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis. - Using swizzling and conversions as described in the next sections.
Swizzling
Vector swizzling is a native feature of nalgebra itself. Therefore, you can use it with all
the vectors of nalgebra-glm as well. Swizzling is supported as methods and works only up to
dimension 3, i.e., you can only refer to the components x
, y
and z
and can only create a
2D or 3D vector using this technique. Here is some examples, assuming v
is a vector with float
components here:
v.xx()
is equivalent toglm::vec2(v.x, v.x)
and toVec2::new(v.x, v.x)
.v.zx()
is equivalent toglm::vec2(v.z, v.x)
and toVec2::new(v.z, v.x)
.v.yxz()
is equivalent toglm::vec3(v.y, v.x, v.z)
and toVec3::new(v.y, v.x, v.z)
.v.zzy()
is equivalent toglm::vec3(v.z, v.z, v.y)
and toVec3::new(v.z, v.z, v.y)
.
Any combination of two or three components picked among x
, y
, and z
will work.
Conversions
It is often useful to convert one algebraic type to another. There are two main approaches for converting
between types in nalgebra-glm
:
- Using function with the form
type1_to_type2
in order to convert an instance oftype1
into an instance oftype2
. For exampleglm::mat3_to_mat4(m)
will convert the 3x3 matrixm
to a 4x4 matrix by appending one column on the right and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1. - Using one of the
convert
,try_convert
, orconvert_unchecked
functions. These functions are directly re-exported from nalgebra and are extremely versatile:
- The
convert
function can convert any type (especially geometric types from nalgebra likeIsometry3
) into another algebraic type which is equivalent but more general. For example,let sim: Similarity3<_> = na::convert(isometry)
will convert anIsometry3
into aSimilarity3
. In addition,let mat: Mat4 = glm::convert(isometry)
will convert anIsometry3
to a 4x4 matrix. This will also convert the scalar types, therefore:let mat: DMat4 = glm::convert(m)
wherem: Mat4
will work. However, conversion will not work the other way round: you can't convert aMatrix4
to anIsometry3
usingglm::convert
because that could cause unexpected results if the matrix does not complies to the requirements of the isometry. - If you need this kind of conversions anyway, you can use
try_convert
which will test if the object being converted complies with the algebraic requirements of the target type. This will returnNone
if the requirements are not satisfied. - The
convert_unchecked
will ignore those tests and always perform the conversion, even if that breaks the invariants of the target type. This must be used with care! This is actually the recommended method to convert between homogeneous transformations generated bynalgebra-glm
and specific transformation types from nalgebra likeIsometry3
. Just be careful you know your conversions make sense.
Should I use nalgebra or nalgebra-glm?
Well that depends on your tastes and your background. nalgebra is more powerful overall since it allows stronger typing, and goes much further than simple computer graphics math. However, has a bit of a learning curve for those not used to the abstract mathematical concepts for transformations. nalgebra-glm however have more straightforward functions and benefit from the various tutorials existing on the internet for the original C++ GLM library.
Overall, if you are already used to the C++ GLM library, or to working with homogeneous coordinates (like 4D matrices for 3D transformations), then you will have more success with nalgebra-glm. If on the other hand you prefer more rigorous treatments of transformations, with type-level restrictions, then go for nalgebra. If you need dynamically-sized matrices, you should go for nalgebra as well.
Keep in mind that nalgebra-glm is just a different API for nalgebra. So you can very well use both
and benefit from both their advantages: use nalgebra-glm when mathematical rigor is not that important,
and nalgebra itself when you need more expressive types, and more powerful linear algebra operations like
matrix factorizations and slicing. Just remember that all the nalgebra-glm types are just aliases to nalgebra types,
and keep in mind it is possible to convert, e.g., an Isometry3
to a Mat4
and vice-versa (see the conversions section).
Dependencies
~0.8–2MB
~50K SLoC