Code Monkey home page Code Monkey logo

vek's Issues

Update the `approx` dependency

Some traits have changed from 0.1.0 to current 0.3.0, meaning vek is not compatible with the latest approx (which is annoying. Hand-rolling comparisons is possible, but no fun.)

Add conversions for `mint` types?

The mint crate is basically an indirection layer for basic vector math types. Its goal is to make it easier for people to write API's that can accept math types from different libraries. I've used it in the ggez library and it works quite well; instead of a function taking nalgebra::Point2 and forcing the user to use not only nalgebra, but a specific version of nalgebra, I can have a function take Into<mint::Point2>. nalgebra, cgmath and a couple other math libraries all have features that provide Into<mint::Point2> conversions for their Point2 types, so you can use whatever math library you want to make games with ggez now.

Is this functionality interesting to you at all? Would you care for a PR?

uom support

https://crates.io/crates/uom

I think it would be really useful to have uom support for vek. At the moment, this isn't possible because num_traits::Float isn't implemented for uom's quantity types. Presumably this is something that would need to be fixed upstream in the num_traits crate, or supported by uom?

Add better numerical type conversion functions

Writing vec.numcast().unwrap() is really noisy, especially where I don't expect any conversion errors and don't want to handle them. To avoid unnecessary checks and panics I keep writing vec.map(|v| v as f32) which is still not ideal...

So I suggest adding a new function for conversion between different numerical types, using num_traits::cast::AsPrimitive. In most cases, precision loss and overflowing isn't something you should worry about, especially in graphics programming (e.g. converting u32 framebuffer extent to f32).

Perhaps, the old numcast function should be renamed to try_cast and a new panicking cast be introduced to match euclid behaviour. But that's another question...

In the code: Handedness makes no sense for view/model matrices until someone proves me wrong

Could you explain the note in this code?

vek/src/mat.rs

Lines 2245 to 2252 in c81fda5

/// Builds a "look at" view transform for left-handed spaces
/// from an eye position, a target position, and up vector.
/// Commonly used for cameras.
// NOTE: Not public. Handedness makes no sense for view/model matrices until someone proves me wrong.
pub(crate) fn look_at_lh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Sum
{

Specifically,

NOTE: Handedness makes no sense for view/model matrices until someone proves me wrong

I'm new to graphics and still wrapping my head around this, so forgive me if I'm completely wrong. I think I ran into an issue caused by handedness today. I had some code that assumes right-handedness and it just did not work with look_at because it assumes left-handedness. I do believe handedness matters with look_at, but this comment in the code implies differently.

Does handedness actually not matter for look_at? Or was there some other reason behind this comment? Would you accept a PR to make those handedness-specific versions of these functions public?

as_ref and as_mut

I've found myself wanting methods similar to Option's as_ref and as_mut.

Their type signatures would be as follows:

impl<T> VecN<T> {
    fn as_ref(&self) -> VecN<&T>;
    fn as_mut(&mut self) -> VecN<&mut T>;
}

What do you think?

Nested calls makes vek unusable in debug-buils for real-time applications.

Hi, sorry for overly negative tone, but I am profiling some code using vek and I can't believe my eyes:

 - 75.82% basic::sd_terrain                                                                                          ▒
      - 39.16% basic::sd_line                                                                                          ▒
         - 21.87% vek::vec::repr_c::vec2::Vec2<T>::dot                                                                 ▒
            - 19.60% vek::vec::repr_c::vec2::Vec2<T>::sum                                                              ▒
               - 17.80% core::iter::traits::iterator::Iterator::sum                                                    ▒
                  - <f32 as core::iter::traits::accum::Sum>::sum                                                       ▒
                     - core::iter::traits::iterator::Iterator::fold                                                    ▒
                        - 11.89% core::iter::traits::iterator::Iterator::try_fold                                      ▒
                           - 7.72% <vek::vec::repr_c::vec2::IntoIter<T> as core::iter::traits::iterator::Iterator>::nex▒
                              - 2.72% <vek::vec::repr_c::vec2::Vec2<T> as core::ops::deref::Deref>::deref              ▒
                                 - vek::vec::repr_c::vec2::Vec2<T>::as_slice                                           ▒
                                    - 1.25% vek::vec::repr_c::vec2::Vec2<T>::as_ptr_priv                               ▒
                                       - vek::vec::repr_c::vec2::Vec2<T>::is_packed                                    ▒
                                            0.56% core::ptr::const_ptr::<impl *const T>::wrapping_of

Are there really 11 nested calls in a Vec2::dot product, which could be a.x * b.x + a.y * b.y?

Use of deprecated 'mem::uninitialized()'

Building the latest version of vek emits this warning several times

warning: use of deprecated item 'core::mem::uninitialized': use `mem::MaybeUninit` instead
    --> src/vec.rs:1594:46
     |
1594 |                   let mut out: Self = unsafe { mem::uninitialized() };
     |                                                ^^^^^^^^^^^^^^^^^^
...
3266 | /     vec_impl_all_vecs! {
3267 | |         c
3268 | |         #[repr(C)]
3269 | |     }
     | |_____- in this macro invocation
     |
     = note: `#[warn(deprecated)]` on by default

Type annotations required for trivial conversion

This causes E283 :

let v = Vec2::<f32>::zero(); // Or whatever value, the point is to have a Vec2<f32>
let v = Vec3::from(v); // Fails to infer Vec3<f32>

Today, the solution would be...

let v = Vec2::<f32>::zero();
let v = Vec3::<f32>::from(v);

... but it's annoying. There's something that messes with the compiler's ability to properly infer types.
it might be just me though.

Calculate scalar multiple of vector?

Is it possible to add the Mul trait to floating point values? Is there a workaround in the meantime for VecX? There should be a function like:

fn scale<T>(&self, scale: T) -> Self;

Unless I'm missing something from the API, I'd have to do something like:

Vec3::new(old_vec[0] * x, old_vec[1] * x, old_vec[2] * x);

rgb(a) and image features compile error

When I try building vek v0.11.1 with rustc 1.46.0-nightly (0262de554 2020-06-07) with "rgb", "rgba" and "image" features, I get the following errors:

error[E0308]: mismatched types
    --> src/vec.rs:2123:56
     |
2123 |               fn from_slice(slice: &[Self::Subpixel]) -> &Self {
     |                  ----------                              ^^^^^ expected reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2124 |                   assert!(slice.len() >= Self::channel_count() as _);
2125 |                   unsafe { &*(slice.as_ptr() as *const _ as *const Self) };
     |                                                                           - help: consider removing this semicolon
...
3174 | /     vec_impl_all_vecs!{
3175 | |         c
3176 | |         #[repr(C)]
3177 | |     }
     | |_____- in this macro invocation
     |
     = note: expected reference `&vec::repr_c::rgb::Rgb<T>`
                found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2123:56
     |
2123 |               fn from_slice(slice: &[Self::Subpixel]) -> &Self {
     |                  ----------                              ^^^^^ expected reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2124 |                   assert!(slice.len() >= Self::channel_count() as _);
2125 |                   unsafe { &*(slice.as_ptr() as *const _ as *const Self) };
     |                                                                           - help: consider removing this semicolon
...
3185 | /     vec_impl_all_vecs!{
3186 | |         simd
3187 | |         #[repr(simd)]
3188 | |     }
     | |_____- in this macro invocation
     |
     = note: expected reference `&vec::repr_simd::rgb::Rgb<T>`
                found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2127:64
     |
2127 |               fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
     |                  --------------                                  ^^^^^^^^^ expected mutable reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2128 |                   assert!(slice.len() >= Self::channel_count() as _);
2129 |                   unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) };
     |                                                                               - help: consider removing this semicolon
...
3174 | /     vec_impl_all_vecs!{
3175 | |         c
3176 | |         #[repr(C)]
3177 | |     }
     | |_____- in this macro invocation
     |
     = note: expected mutable reference `&mut vec::repr_c::rgb::Rgb<T>`
                        found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2127:64
     |
2127 |               fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
     |                  --------------                                  ^^^^^^^^^ expected mutable reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2128 |                   assert!(slice.len() >= Self::channel_count() as _);
2129 |                   unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) };
     |                                                                               - help: consider removing this semicolon
...
3185 | /     vec_impl_all_vecs!{
3186 | |         simd
3187 | |         #[repr(simd)]
3188 | |     }
     | |_____- in this macro invocation
     |
     = note: expected mutable reference `&mut vec::repr_simd::rgb::Rgb<T>`
                        found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2225:56
     |
2225 |               fn from_slice(slice: &[Self::Subpixel]) -> &Self {
     |                  ----------                              ^^^^^ expected reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2226 |                   assert!(slice.len() >= Self::channel_count() as _);
2227 |                   unsafe { &*(slice.as_ptr() as *const _ as *const Self) };
     |                                                                           - help: consider removing this semicolon
...
3174 | /     vec_impl_all_vecs!{
3175 | |         c
3176 | |         #[repr(C)]
3177 | |     }
     | |_____- in this macro invocation
     |
     = note: expected reference `&vec::repr_c::rgba::Rgba<T>`
                found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2225:56
     |
2225 |               fn from_slice(slice: &[Self::Subpixel]) -> &Self {
     |                  ----------                              ^^^^^ expected reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2226 |                   assert!(slice.len() >= Self::channel_count() as _);
2227 |                   unsafe { &*(slice.as_ptr() as *const _ as *const Self) };
     |                                                                           - help: consider removing this semicolon
...
3185 | /     vec_impl_all_vecs!{
3186 | |         simd
3187 | |         #[repr(simd)]
3188 | |     }
     | |_____- in this macro invocation
     |
     = note: expected reference `&vec::repr_simd::rgba::Rgba<T>`
                found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2229:64
     |
2229 |               fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
     |                  --------------                                  ^^^^^^^^^ expected mutable reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2230 |                   assert!(slice.len() >= Self::channel_count() as _);
2231 |                   unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) };
     |                                                                               - help: consider removing this semicolon
...
3174 | /     vec_impl_all_vecs!{
3175 | |         c
3176 | |         #[repr(C)]
3177 | |     }
     | |_____- in this macro invocation
     |
     = note: expected mutable reference `&mut vec::repr_c::rgba::Rgba<T>`
                        found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
    --> src/vec.rs:2229:64
     |
2229 |               fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
     |                  --------------                                  ^^^^^^^^^ expected mutable reference, found `()`
     |                  |
     |                  implicitly returns `()` as its body has no tail or `return` expression
2230 |                   assert!(slice.len() >= Self::channel_count() as _);
2231 |                   unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) };
     |                                                                               - help: consider removing this semicolon
...
3185 | /     vec_impl_all_vecs!{
3186 | |         simd
3187 | |         #[repr(simd)]
3188 | |     }
     | |_____- in this macro invocation
     |
     = note: expected mutable reference `&mut vec::repr_simd::rgba::Rgba<T>`
                        found unit type `()`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

Following the compiler help messages and removing semicolons on lines: 2125, 2129, 2227 and 2231 in src/vec.rs seems to mitigate the issue.

Some Bézier curve functions should return arrays instead of tuples

Arrays are way more convenient because they can be iterated on.

For instance, today, where we have :

fn split(self, t: T) -> (Self, Self) {...}
fn unit_circle() -> (Self, Self, Self, Self) {...}

I would much rather have :

fn split(self, t: T) -> [Self; 2] {...}
fn unit_circle() -> [Self; 4] {...}

Currently, Bézier curves seem to be the only API in which this issues shows up.

Crate is not actually `no_std`

Despite the assertion in the docs, the vek crate at 0.9.6 does not actually build on targets without std available, because of a transitive dependency on std through the approx crate.

Steps to reproduce:

Ensure that the thumbv7em-none-eabihf target is installed:

$ rustup target add thumbv7em-none-eabihf

Clone and build:

$ git clone https://github.com/yoanlcq/vek.git
$ cd vek
$ cargo build --target thumbv7em-none-eabihf

Expected results

Crate builds.

Actual results

    Updating crates.io index
   Compiling semver-parser v0.7.0
   Compiling num-traits v0.2.6
   Compiling num-integer v0.1.39
   Compiling approx v0.1.1
   Compiling static_assertions v0.2.5
error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv7em-none-eabihf` target may not be installed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: Could not compile `approx`.
warning: build failed, waiting for other jobs to finish...
error: build failed

Likely fix

approx, num-traits, num-integer all need to be set to default-features = false. Unfortunately, the version of num-integer (at least) that's pinned here isn't no_std compatible, so this probably never worked. Upgrading to at least 0.1.36 should fix it.

Also, consider adding a no-std target to your continuous build to catch regressions here. thumbv7em-none-eabihf is a supported target on stable and nightly and would be a reasonable choice, but in general, any target with -none- in the triple instead of e.g. -linux- should do.

Add a .join() method to do element-wise joining of vectors

impl<T> Vec2<T> {
    fn join<U>(self, other: Vec2<U>) -> Vec2<(T, U)> {
        Vec2::new((self.x, other.x), (self.y, other.y))
    }
}

This is extremely useful as a way to do arbitrary-N mapping. For example:

let x = ...; // A vector
let lower = ...; // Another vector
let upper = ...; // Another vector

let bounded_x = x
    .join(lower)
    .join(upper)
    .map(|((x, lower), upper)| x.max(lower).min(upper));

Use for accelerometers and other embedded projects

Hello! This is just a heads up that I mentioned vek in an issue I opened on the Rust Embedded WG about an accelerometer crate:

rust-embedded/wg#340

It looks like vek might potentially be nice for these applications, aside from #20 which I think looks trivially fixable (I could potentially send a PR).

Anyway, if you have any thoughts on this I'd be curious, otherwise feel free to close this issue.

Build broken on nightly

Compiling with latest nightly causes the following errors:

error[E0075]: SIMD vector length must be a power of two
    --> /Users/caelum/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.12.0/src/vec.rs:2803:13
     |
2803 |               pub struct Vec3<T> { pub x:T, pub y:T, pub z:T }
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
3195 | /     vec_impl_all_vecs!{
3196 | |         simd
3197 | |         #[repr(simd)]
3198 | |     }
     | |_____- in this macro invocation
     |
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0075]: SIMD vector length must be a power of two
    --> /Users/caelum/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.12.0/src/vec.rs:3022:13
     |
3022 |               pub struct Extent3<T> { pub w:T, pub h:T, pub d:T }
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
3195 | /     vec_impl_all_vecs!{
3196 | |         simd
3197 | |         #[repr(simd)]
3198 | |     }
     | |_____- in this macro invocation
     |
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0075]: SIMD vector length must be a power of two
    --> /Users/caelum/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.12.0/src/vec.rs:3112:13
     |
3112 |               pub struct Rgb<T> { pub r:T, pub g:T, pub b:T }
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
3195 | /     vec_impl_all_vecs!{
3196 | |         simd
3197 | |         #[repr(simd)]
3198 | |     }
     | |_____- in this macro invocation
     |
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

Remove length 3 repr_simd vectors

In rust-lang/rust#80652 we are removing support for non-power-of-two vector lengths with #[repr(simd)] from nightly Rust, and vek is one of the crates that will be effected. Just wanted to give a heads up before we make the change. If you have any questions feel free to ask!

Add Transform2D struct

Add this kind of data structure :

pub struct Transform2D<P,O,S> {
    pub position: Vec2<P>,
    pub rotation_z: O, // In degrees
    pub scale: Vec2<S>,
}

If a z position element is needed, people should just use Transform instead.
The reason is, we shouldn't enforce the way to set z-order. Some architectures might be "layer-based", for instance.

Add `all`, `any` and `find` methods on vectors

Now that vek has methods such as map2 and apply2, methods such as all, any and find would have many potential uses. For example:

let v1 = Vec3::new(1, 2, 3);
let v2 = Vec3::new(3, 2, 1);

// Returns true if all of the elements satisfy the 'e > 5' predicate
let x = v1.map2(v2, |a, b| a + b * 3).all(|e| e > 5); // true

// Returns true if any of the elements satisfy the 'e == 8' predicate
let y = v1.map2(v2, |a, b| a + b * 3).any(|e| e == 8); // true

// Returns the index of the first element that satisfies the 'e == 8' predicate
let z = v1.map2(v2, |a, b| a + b * 3).find(|e| e == 8); // 1

In addition, it might be useful to add a few utility methods specifically for boolean vectors: .and() and .or(). These would provide a nice shortcut to the above code for Vec3<bool>-like types.

Add `to_normalized_f32()` for `Rgba<u8>`, etc.

This feature is intended for Rgb and Rgba vectors, using the ColorComponent trait.
The idea is to provide convenient concise conversion methods between vectors of different ColorComponent implementors (e.g u8 and f32).

I've often found myself juggling between Rgba<u8> and Rgba<f32> (the former for bitmap colors, displaying, serialization, and saving memory, and the latter for use with OpenGL).

It's obvious how to convert from one to another...

let c = Rgb::new(255u8, 128, 0);
let c = c.map(|c| c as f32 / 255.); // Convert to Rgb<u8>
let c = c.map(|c| (c * 255.) as u8); // Convert back to Rgb<f32>

... But I think this warrants convenience methods. Also, this should be made generic for all ColorComponent types, not only f32 and u8.

Implement some sort of `.and` higher order function to accompany `.map`

There are a lot of use-cases for performing an operation on 2 vectors on an element-by-element basis.

vek already supports this through the built-in arithmetic operator overloads.

This should be extended further in a similar manner to std's Option::and_then to allow things like this:

let va = Vec3::new(3, -24, 32);
let vb = Vec3::new(4, 9, 13);

let vc = v0.and(|a, b| a.div_euc(b));

Outdated/insecure dependencies

I checked https://deps.rs/repo/github/yoanlcq/vek and it appears some deps are outdated, one of them marked as insecure.

Updating approx might be a breaking change for crates which depend on approx explicitly in their Cargo.toml to import some of its traits. E.g.: My project uses vek = "0.12.0" and approx = "0.3.2", I wanted to update to approx = "0.4.0" but can't because I am using Vec2<f64>::default_epsilon() from the approx::AbsDiffEq trait, which means I need to depend on the same version of vek - IIUC when vek updates, projects doing this will need to update too.

Not sure how many changes are needed in vek as part of the update, I can look into it if you want.

Regarding insecure deps: Have you considered running something like cargo audit periodically as part of CI? I see vek is using travis - didn't they drop support for OSS projects? Are you planning to move to something else? I only have experience with GitLab CI but i know GitHub Actions should be able to run periodically (not just on push) using a cron-like schedule.

Image feature compile error

I wanted to enable the "image" feature and got those compile errors:

error[E0308]: mismatched types
    --> /home/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.9.10/src/vec.rs:2044:35
     |
2044 |                   *self = self.map2(other, f);
     |                                     ^^^^^ expected struct `vec::repr_c::rgb::Rgb`, found reference
...
3048 | /     vec_impl_all_vecs!{
3049 | |         c
3050 | |         #[repr(C)]
3051 | |     }
     | |_____- in this macro invocation
     |
     = note: expected type `vec::repr_c::rgb::Rgb<_>`
                found type `&vec::repr_c::rgb::Rgb<T>`

error[E0308]: mismatched types
    --> /home/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.9.10/src/vec.rs:2051:29
     |
2051 |                   self.apply2(other, |a, b| {
     |                               ^^^^^ expected struct `vec::repr_c::rgb::Rgb`, found reference
...
3048 | /     vec_impl_all_vecs!{
3049 | |         c
3050 | |         #[repr(C)]
3051 | |     }
     | |_____- in this macro invocation
     |
     = note: expected type `vec::repr_c::rgb::Rgb<_>`
                found type `&vec::repr_c::rgb::Rgb<T>`

error[E0308]: mismatched types
    --> /home/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.9.10/src/vec.rs:2151:35
     |
2151 |                   *self = self.map2(other, f);
     |                                     ^^^^^ expected struct `vec::repr_c::rgba::Rgba`, found reference
...
3048 | /     vec_impl_all_vecs!{
3049 | |         c
3050 | |         #[repr(C)]
3051 | |     }
     | |_____- in this macro invocation
     |
     = note: expected type `vec::repr_c::rgba::Rgba<_>`
                found type `&vec::repr_c::rgba::Rgba<T>`

error[E0308]: mismatched types
    --> /home/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/vek-0.9.10/src/vec.rs:2158:29
     |
2158 |                   self.apply2(other, |a, b| {
     |                               ^^^^^ expected struct `vec::repr_c::rgba::Rgba`, found reference
...
3048 | /     vec_impl_all_vecs!{
3049 | |         c
3050 | |         #[repr(C)]
3051 | |     }
     | |_____- in this macro invocation
     |
     = note: expected type `vec::repr_c::rgba::Rgba<_>`
                found type `&vec::repr_c::rgba::Rgba<T>`

As you can see it is originating from within the crate

Multiple `cannot borrow as immutable because it's borrowed as mutable` warnings

There's a lot of warnings that variables are borrowed immutably while also being borrowed mutably in the currently released version of vek (0.9.7)

warning[E0502]: cannot borrow `rows` as immutable because it is also borrowed as mutable
    --> C:\Users\appveyor\.cargo\registry\src\github.com-1ecc6299db9ec823\vek-0.9.7\src\mat.rs:1897:31
     |
1897 |                 rows[3][0] += rows[0].dot(t);
     |                 --------------^^^^----------
     |                 |             |
     |                 |             immutable borrow occurs here
     |                 mutable borrow occurs here
     |                 mutable borrow later used here
...
3952 |     mat_declare_modules!{}
     |     ---------------------- in this macro invocation
     |
     = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
     = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

Const constructor

Hi,
i want to have const Vec3, is this possible ?

e.g.

const ENTITY_MIDDLE_OFFSET: Vec3<f32> = Vec3::new(0.0, 0.0, 0.9);

best regards,
xMAC94x

Build fails on 2020-10-04

   Compiling vek v0.12.0 (/home/joshua/Projects/vek)
error: expected `,`
   --> src/bezier.rs:428:30
    |
428 |             pub start: $Point<T>,
    |                              ^
...
834 |     impl_all_beziers!{repr_simd}
    |     ---------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:428:30
    |
428 |             pub start: $Point<T>,
    |                              ^
...
834 |     impl_all_beziers!{repr_simd}
    |     ---------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:612:30
    |
612 |             pub start: $Point<T>,
    |                              ^
...
834 |     impl_all_beziers!{repr_simd}
    |     ---------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:612:30
    |
612 |             pub start: $Point<T>,
    |                              ^
...
834 |     impl_all_beziers!{repr_simd}
    |     ---------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:428:30
    |
428 |             pub start: $Point<T>,
    |                              ^
...
839 |     impl_all_beziers!{repr_c}
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:428:30
    |
428 |             pub start: $Point<T>,
    |                              ^
...
839 |     impl_all_beziers!{repr_c}
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:612:30
    |
612 |             pub start: $Point<T>,
    |                              ^
...
839 |     impl_all_beziers!{repr_c}
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected `,`
   --> src/bezier.rs:612:30
    |
612 |             pub start: $Point<T>,
    |                              ^
...
839 |     impl_all_beziers!{repr_c}
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 8 previous errors

error: could not compile `vek`

To learn more, run the command again with --verbose.

Using `acos` in some methods leads to NaNs if the two vecs are near identical

The two affected methods:

pub fn slerp_unclamped(from: Self, to: Self, factor: T) -> Self
    where T: Sum + Real + Clamp + Lerp<T,Output=T>
{
    // From GLM, gtx/rotate_vector.inl
    let (mag_from, mag_to) = (from.magnitude(), to.magnitude());
    let (from, to) = (from/mag_from, to/mag_to);
    let cos_alpha = from.dot(to);
    let alpha = cos_alpha.acos();
    let sin_alpha = alpha.sin();
    let t1 = ((T::one() - factor) * alpha).sin() / sin_alpha;
    let t2 = (factor * alpha).sin() / sin_alpha;
    (from * t1 + to * t2) * Lerp::lerp_unclamped(mag_from, mag_to, factor)
}
pub fn angle_between(self, v: Self) -> T where T: Sum + Real {
    self.normalized().dot(v.normalized()).acos()
}

Due to floating point error the magnitude of normalized vecs can be slightly over 1.0 so when the two input vecs are near identical it is possible for the dot product to be over 1 (or under -1 if they are opposite).
Unfortunately, acos returns NaN outside the range [-1, 1]

Is it intended for the user to handle this case or should it be handled in these methods?

Another concern with slerp_unclamped is that it doesn't handle the case where the two vectors are not linearly independent.

Go crazy with associated constants (ZERO, ONE, etc).

Add meaningful associated constants along with existing functions that are meant as constants.
Sadly this is currently not possible (num-traits's Zero doesn't have ZERO), but I'd prefer not to forget.

impl<T: Zero> Vec4<T> {
    pub fn zero() -> Self { Self::ZERO }
    pub const ZERO: Self = $Vec { $($get: T::ZERO,)+ };
}

Add `From<(Vec2<T>, T)>` for `Vec3<T>`?

Right now this either has to be done by:

Vec3::new(vec2.x, vec2.y, z)

or

Vec3::from(vec2) + Vec3::unit_z() * z

where it could just be

Vec3::from((vec2, z))

And this would be really convenient in creating APIs that take Into<Vec3<T>> since then just (vec2, z) could be passed in instead of having to convert it.

Roadmap to 1.0

Pre-requisites for 1.0

  • Fix all TODOs and FIXMEs. Fix as many XXXs as possible.
  • All doc is re-read (especially the FAQ) to ensure it reflects the current situation well.
  • Reference material such as "How we do SIMD at insomniac Games", illustrating how it applies to vek;
  • Macros are actually documented (even internally).
  • Enable all possible targets on Travis CI;
  • Assembly-check all the things!
  • Write some benchmarks.
  • Make an annoucement and get feedback from the wider Rust community before going 1.0.

Awaiting triage

  • Make vectors properly implement AsRef and AsMut to all other kinds of vectors;
    • ... as long as the target dimension is greater or equal, and it's not a C -> SIMD conversion (because of alignment requirements).
  • More From conversions from vectors to other kinds of vectors;
  • Re-provide the fix, fpa and num-bigint optional dependencies.
    The point is to make their types implement most of vek::ops traits;

Docs and publicity

  • Make a cool logo! (I'm already on it.)

Features

  • impl FromStr for vectors and matrices!
    • With a special case for Rgb and Rgba;
  • from_html_hex(s: &str) for Rgb and Rgba;
  • Quaternions:
    • look_at() rotation (See Unity ?);
  • Matrices:
    • orthonormalized (for Mat4);
    • Add 3D shearing.
    • Add symmetry transforms.
    • Add decompose() (steal from GLM) (and make it a conversion into Transform!)
    • Add scale_from_point and rotate_about_point (I've seen these somewhere, but can't recall exactly)
    • is_diagonal_matrix()
    • is_symmetric()
    • FromStr
  • Add Euler Angles ?
    • I'm not sure, because they suck, and nobody agrees on the order in which
      rotations are applied. Some say X,Y,Z, others say Z,Y,X.
      I'd rather leave this to users who know better what they want.
      The only use case I can think of is GUIs, and it's as misguided as using degrees IMO.
      Fix the GUI, not the intermediary representation.
  • Free functions.
    This would require pulling new traits out of existing functionality.
    • dot()
    • hadd()
    • cross()
    • distance()
    • normalize()
    • reflect()
    • refract()
    • face_forward()
    • angle_between()
    • transpose()
    • invert() (matrix, not color vector)
      Note that there are no free functions for Lerp, Slerp, etc.
      It's enough to just write Lerp::lerp(..). Less pain for us to maintain, but I might change my mind.
  • Consider turning the ops module into a vek-ops crate (Like num did with num-traits)
  • Consider experimenting with a vek-derive crate for deriving Lerp and stuff;

Soft fixes

  • Make sure to fullfill the SIMD efficiency promise.
    • Use platform-intrinsics for operations on repr(simd) vectors, including shuffles.
    • transposed_sse() for Mat4<f32> (based on _MM_TRANSPOSE4_PS());
    • transposed_sse2() for Mat4<i32>
    • dot_sse4_1() for Vec4<f32>
    • load/store_nontemporal() for Vec4<f32> and Vec4<i32>
      (!! needs fencing! So there should be associated fence functions! !!)
    • Many others ??? (cmpgt, average, etc!!)

Tab and Space Craziness in src/ops.rs

There seem to be random tabs and spaces all over the place in at least src/ops.rs which rustdoc apparently can't deal with:

warning: could not parse code block as Rust code
   --> C:\Users\Christopher Serr\.cargo\registry\src\github.com-1ecc6299db9ec823\vek-0.9.7\src\ops.rs:306:6
    |
306 |       ///    ```
    |  ____________^
307 | |     /// use vek::ops::Lerp;
    | |_
    |
    = note: error from rustc: unknown start of token: `

Display impl should respect formatting parameters just like Debug

Example: Currently formatting with {:.2?} correctly shows only 2 decimal places but using {:.2} prints all the digits.

I took a brief look at the code and I think it's only a matter of slightly modifying the macro:

  • take only e.g "rgba" instead of "rgba({}, {}, {}, {})"
  • iterate through the vector's elements and pass them the Formatter when printing them

If you agree, i should be able to make a PR.

Add `Point` types?

nalgebra and cgmath both separate Point types from Vector types... a Point is a location, and a Vector is an offset from a location. Thus you can add together a Point and a Vector and get a new Point, or you can add two Vector's and get a new Vector, but you can't add together two Point's.

While this starts off weird, the distinction has grown on me a lot. Since the actual representation of a Point and a Vector are identical, as are many of the actual math operations on them, I totally understand if you don't want to do this, but I was wondering if you'd considered it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.