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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//! Generic but efficient SIMD vector+matrix library for game engines, with focus on intent and the small bits that make you happier as a user.
//!
//! # Disclaimer
//!
//! **DO NOT USE** (yet). This is very much a work-in progress, breaking changes happen all the time on a whim.
//! Also, the API is a bit cluttered by the `repr(C)` vs `repr(simd)` stuff (I'm still not very
//! confident about that),
//! and very few operations have been proven to actually work in 3D scenes (as of today).
//!
//! See the FAQ in the README and the [the roadmap to 1.0](https://github.com/yoanlcq/vek/issues/1) for more info.
//!
//! The efficiency claim is based on the fact that implementations are specialized according
//! to the target hardware, and the generated assembly is checked to ensure it is optimal.
//! As one would expect, SSE-enabled x86 CPUs do benefit from this.
//!
//! # Overview
//!
//! Here is what `vek` has to offer:
//!
//! - General-purpose vectors: `Vec2<T>`, `Vec3<T>`, `Vec4<T>`. They have uses for representing
//! points or direction in euclidian spaces.
//! - "Data crunching" vectors: `Vec8<T>`, `Vec16<T>`, `Vec32<T>`, `Vec64<T>`, useful for
//! performing basic operaton on many elements in the best way allowed by CPU features.
//! - RGB vectors: `Rgb<T>`, `Rgba<T>`. They have extended functionality related to color.
//! - Texture coordinate vectors: `Uv<T>`, `Uvw<T>`;
//! - Spatial extent vectors: `Extent2<T>`, `Extent3<T>`, for representing width, height and depth.
//! - Square matrices: `Mat2<T>`, `Mat3<T>`, `Mat4<T>`.
//!
//! Matrices can be row-major or column-major at your option, because there are use cases for both
//! layouts, even though column-major is often better performance-wise, for most use case in
//! computer graphics.
//!
//! Types share functionality whenever relevant.
//! Also, there are several (concise) ways to convert from one vector type to another:
//!
//! - Vectors implement `AsRef` and `AsMut` on any lower-dimensioned Vector with the same element type.
//! - Vectors implement `From` on any Vector or tuple type with the same element type. When converting to a
//! higher-dimensioned vector, uninitialized elements are set to the default value of their type.
//!
//! Here's a preview of what using this crate looks like :
//!
//! ```
//! # #![cfg(feature="vec3")]
//!
//! # extern crate vek;
//! use vek::{Vec4, Mat4, Lerp};
//! use std::f32::consts::PI;
//!
//! # fn main() {
//! let point = Vec4::new_point(1_f32, 2_f32, 3_f32); // (1, 2, 3, 1)
//! let direction = Vec4::new_direction(1_f32, 2_f32, 3_f32); // (1, 2, 3, 0)
//! let model = Mat4::rotation_3d(PI, direction)
//! .translated_3d(Vec4::unit_x() * 3_f32)
//! .scaled_3d(2_f32);
//! println!("Rotated point: {}", model * point);
//!
//! let four = Vec4::broadcast(2_f32).sqrt().product();
//! let iota = Vec4::iota() * 2_f32;
//! println!("Interpolated: {}", Vec4::lerp(iota, Vec4::from(four), 0.5_f32));
//! # }
//! ```
//!
//! Because tuples can be converted into vectors, you may directly use tuples
//! in operations that are generic over relevant parameters.
//!
//! In the docs and the code, matrix elements are written as `mij`,
//! where i is the row index and j is the column index, independently of storage layout.
//! This convention has been chosen because it is the mathematical standard.
//!
//! # The deal with `repr_c` and `repr_simd` modules
//!
//! *N.B: If you're on Stable or have disabled this crate's "`repr_simd`"
//! feature, you don't need to worry about this.*
//!
//! The need for convenient SIMD-enabled types was a major motivation for creating `vek`.
//! However, since there are a some issues with Nightly Rust's `#[repr(simd)]` features,
//! we would like to be able to also use regular `#[repr(C, packed)]` vectors.
//!
//! Therefore, `vek` splits main modules into two sub-modules, `repr_c` and `repr_simd`,
//! hoping to make everyone happy. This is a trade-off between functionality and
//! implementation complexity that I am willing to make for now.
//!
//! ## `#[repr(simd)]` caveats
//!
//! You can instantiate any `#[repr(simd)]` type with any type as long as
//! it is a "machine type", like `f32` and `i32`, but not `isize` or newtypes.
//!
//! **Be careful:** the size of a `#[repr(simd)]` vector is never guaranteed to be
//! exactly equal to the sum of its elements.
//! For instance, an SIMD `Vec3<f32>` actually contains 4 `f32` elements on x86 instead of 3.
//! **Also, `repr_simd` matrices are affected by this.**
//!
//! Therefore, be extra careful when sending these as raw data, as you may want
//! to do with OpenGL.
//!
//! ## `#[repr(C, packed)]` caveats
//!
//! **Be careful:** Taking a reference to a `#[repr(packed)]` structure's field
//! [may cause undefined behaviour](https://github.com/rust-lang/rust/issues/27060).
//!
//! ## So, which do I pick?
//!
//! Use types of `repr_simd` modules when:
//!
//! - You know how your target hardware handles `#[repr(simd)]`, and therefore
//! know how much memory SIMD vector structures actually take;
//! - You don't mind alignment requirements and extra empty space;
//!
//! Otherwise, or when in doubt, just pick `repr_c`.
//! This crate always re-exports `repr_c` modules, so this would be the default.
//!
//! # Cargo features
//!
//! - `serde` makes vectors and matrices derive `Serialize` and `Deserialize`.
//! - `image` makes color vectors implement the `Pixel` trait from the `image` crate.
//!
//! ***
//!
//! - `vec2`, `vec3`, `vec8`, `vec16`, `vec32`, `vec64`, `rgba`, `rgb`, `extent3`, `extent2`, `uvw`, `uv`, `mat2`, `mat3`, `quaternion`
//! Select which types you want. Restricting your selection drastically decreases compile times.
//! They are all enabled by default so that they appear in the documentation (and that doc-tests work).
//! - `geom`, `bezier`
//! Other commonly useful and lightweight goodies such as rectangles and Bézier curves.
//!
//! ***
//!
//! - `repr_simd` enables Nightly Rust's `repr_simd` and `simd_ffi` features, which
//! help a lot to generate high-quality code.
//! - `repr_align` enables Nightly Rust's `repr_align` features so that `#[repr(c)]`
//! have the same alignment as their SIMD counterpart.
//! Because enabling it may incur some issues, it is not enabled by default (and might become
//! deprecated).
//! - `x86intrin` enables x86 intrinsics through the `x86intrin` crate. `vek` doesn't directly
//! depend on it because it won't compile on Stable and there's no way (as of this writing)
//! to selectively depend on a crate based on the `rustc` version, not even via build scripts.
//!
//! ***
//!
//! - `fix` implements vectors and matrices of fixed-point numbers from the `fix` crate.
//! - `fpa` implements vectors and matrices of fixed-point numbers from the `fpa` crate.
//! - `num-bigint` implements vectors and matrices of big integers from the `num-bigint` crate.
//!
//! # `#![no_std]`
//! This crate is `#![no_std]`.
//#![deny(warnings)]
//#![cfg_attr(feature="repr_simd", allow(improper_ctypes)]
//#![cfg_attr(feature="repr_simd", feature(link_llvm_intrinsics)]
// FIXME: Remove before release
extern crate test;
/*
#[cfg(feature="serde_derive")]
#[macro_use]
extern crate serde_derive;
*/
extern crate serde;
extern crate fix;
extern crate fpa;
extern crate num_bigint;
extern crate x86intrin;
extern crate num_traits;
extern crate num_integer;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;