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