ultraviolet/lib.rs
1//! # `ultraviolet`
2//!
3//! This is a crate to computer-graphics and games-related linear and geometric algebra, but *fast*, both in terms
4//! of productivity and in terms of runtime performance.
5//!
6//! In terms of productivity, ultraviolet uses no generics and is designed to be as straightforward
7//! of an interface as possible, resulting in fast compilation times and clear code. In addition, the
8//! lack of generics and Rust type-system "hacks" result in clear and concise errors that are easy to
9//! parse and fix for the user.
10//!
11//! In terms of runtime performance, ultraviolet was designed from the start with performance in mind.
12//! To do so, we provide two separate kinds of each type, each with nearly identical functionality,
13//! one with usual scalar f32 values, and the other a 'wide' type which uses SIMD f32x4 vectors for
14//! each value. This design is clear and explicit in intent, and it also allows code to
15//! take full advantage of SIMD.
16//!
17//! The 'wide' types use an "SoA" (Structure of Arrays) architecture
18//! such that each wide data structure actually contains the data for 4 or 8 of its associated data type and will do any operation
19//! on all of the simd 'lanes' at the same time. For example, a `Vec3x8` is equivalent to 8 `Vec3`s all bundled together into one
20//! data structure.
21//!
22//! Doing this is potentially *much* (factor of 10) faster than an standard "AoS" (Array of Structs) layout,
23//! though it does depend on your workload and algorithm requirements. Algorithms must be carefully architected to take full advantage
24//! of this, and doing so can be easier said than done, especially if your algorithm involves significant branching.
25//!
26//! `ultraviolet` was the first Rust math library to be designed in this "AoSoA" manner, though
27//! `nalgebra` now supports it for several of their data structures as well.
28//!
29//! ## Benchmarks
30//!
31//! See [`mathbench-rs`](https://github.com/bitshifter/mathbench-rs) for latest benchmarks.
32//!
33//! ## Cargo Features
34//!
35//! To help further improve build times, `ultraviolet` puts various functionality under feature flags. For example, the 2d and 3d projective geometric algebras
36//! as well as f64 and integer types are disabled by default. In order to enable them, enable the corresponding crate feature flags in your `Cargo.toml`. For example:
37//!
38//! ```toml
39//! [dependencies]
40//! ultraviolet = { version = "0.9", features = [ "f64", "int" ] }
41//! ```
42//!
43//! Will enable the `f64` and `int` features. Here's a list of the available features:
44//!
45//! * `f64` – Enable `f64` bit wide floating point support. Naming convention is `D[Type]`, such as `DVec3x4` would be a collection of 4 3d vectors with `f64` precision each.
46//! * `int` – Enable integer vector types.
47//! * `bytemuck` – Enable casting of many types to byte arrays, for use with graphics APIs.
48//! * `mint` – Enable interoperation with other math crates through the `mint` interface.
49//! * `num-traits` – Enable [identity traits](https://docs.rs/num-traits/latest/num_traits/identities/index.html) for interoperation with other math crates.
50//! * `serde` – Enable `Serialize` and `Deserialize` implementations for many scalar types.
51//!
52//! ## Crate Features
53//!
54//! This crate is currently being dogfooded in my ray tracer [`rayn`](https://github.com/termhn/rayn),
55//! and is being used by various independent Rust game developers for various projects.
56//! It does what those users have currently needed it to do.
57//!
58//! There are a couple relatively unique/novel features in this library, the most important being the use of the Geometric Algebra.
59//!
60//! Instead of implementing complex number algebra (for 2d rotations) and Quaternion algebra (for 3d rotations), we use
61//! Rotors, a concept taken from Geometric Algebra, to represent 2d and 3d rotations.
62//!
63//! What this means for the programmer is that you will be using the `Rotor3` type in place of
64//! a Quaternion, though you can expect it to do basically all the same things that a Quaternion does. In fact, Quaternions
65//! are directly isomorphic to Rotors (meaning they are in essense the same thing, just formulated differently). The reason this decision was made was twofold:
66//! first, the derivation of the math is actually quite simple to understand. All the derivations for the code implemented in the Rotor structs in this
67//! library are written out in the `derivations` folder of the GitHub repo; I derived them manually as part of the implementation.
68//!
69//! On the other hand, Quaternions are often basically just seen as black boxes that we programmers use to do rotations because
70//! they have some nice properties, but that we don't really understand. You can use Rotors this same way, but you can also easily
71//! understand them. Second is that in some sense they can be seen as 'more correct' than Quaternions. Specifically, they
72//! facilitate a more proper understanding of rotation as being something that occurs *within a plane* rather than something
73//! that occurs *around an axis*, as it is generally thought. Finally, Rotors also generalize to 4 and even higher dimensions,
74//! and if someone wants to they could implement a Rotor4 which retains all the properties of a Rotor3/Quaternion but does rotation
75//! in 4 dimensions instead, something which simply is not possible to do with Quaternions.
76//!
77//! If it's missing something you need it to do, bug me on the [GitHub issue tracker](https://github.com/termhn/ultraviolet/issues) and/or Rust community discord server
78//! (I'm Fusha there) and I'll try to add it for you, if I believe it fits with the vision of the lib :)
79
80#![deny(
81 rust_2018_compatibility,
82 rust_2018_idioms,
83 future_incompatible,
84 nonstandard_style,
85 unused,
86 clippy::all
87)]
88
89extern crate alloc;
90#[cfg(feature = "serde")]
91extern crate serde;
92
93mod util;
94
95pub(crate) use util::Splat;
96
97pub mod bivec;
98#[cfg(feature = "int")]
99pub mod conversion;
100#[cfg(feature = "int")]
101pub mod int;
102pub mod interp;
103pub mod mat;
104pub mod projection;
105pub mod rotor;
106pub mod transform;
107pub mod vec;
108
109#[cfg(feature = "serde")]
110mod impl_serde;
111
112#[cfg(feature = "mint")]
113mod impl_mint;
114
115#[cfg(feature = "bytemuck")]
116mod impl_bytemuck;
117
118pub use bivec::*;
119#[cfg(feature = "int")]
120pub use conversion::*;
121#[cfg(feature = "int")]
122pub use int::*;
123pub use interp::*;
124pub use mat::*;
125pub use rotor::*;
126pub use transform::*;
127pub use vec::*;
128
129pub use wide::f32x4;
130pub use wide::f32x8;
131pub use wide::f64x2;
132pub use wide::f64x4;
133
134pub use wide::f32x4 as m32x4;
135pub use wide::f32x8 as m32x8;
136pub use wide::f64x2 as m64x2;
137pub use wide::f64x4 as m64x4;
138
139pub(crate) use wide::{CmpGe, CmpLt};