Skip to content

Commit

Permalink
Version 0.6.1 (#41)
Browse files Browse the repository at this point in the history
* Version 0.6.1

* Fix

* Fix swizzling

* Add from impls for arrays
  • Loading branch information
maplant authored Oct 2, 2024
1 parent 8a47e87 commit c7c1bb7
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 101 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ This project adheres to [Semantic Versioning](http://semver.org/) as of version
## Unreleased Changes
These changes are included in `master` but have not been released in a new crate version yet.

## [v0.6.1]
- Added `look_to_rh`, `look_to_lh`, `look_at_rh` and `look_at_lh` functions for creating view
matrices.
- Added `perspective_rh` and `perspective_lh` functions for creating perspective matrices.
- Added `orthographic_rh` and `orthographic_lh` functions for creating orthographic matrices.
- Added `extend` function to `Vector1`, `Vector2`, and `Vector3`.
- Added `truncate` function to `Vector2`, `Vector3`, and `Vector4`.
- Added swizzle functions to small vectors.
- Added conversion functions from vectors and points into arrays.
- Removed `swizzle` feature and include swizzling always.
- Changed `reflect` method of `InnerSpace` to take a `Unit<Self>` for the `surface_normal`.

## [v0.6.0]
- Added `Vector2`, `Vector3` and `Vector4` structs to improve ergonomics while dealing with smaller
vector types.
Expand Down
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "al-jabr"
version = "0.6.0"
version = "0.6.1"
authors = ["Matthew Plant <[email protected]>", "Øystein Hovind <[email protected]>"]
edition = "2021"
description = "An n-dimensional linear algebra library."
Expand All @@ -17,15 +17,14 @@ keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
name = "al_jabr"

[dependencies]
paste = { version = "0.1" }
mint = { version = "0.5", optional = true }
paste = { version = "0.1", optional = true }
rand = { version = "0.8", optional = true }
serde = { version = "1", features = ["derive"], optional = true }
approx = { version = "0.5", optional = true }

[features]
default = []
swizzle = [ "dep:paste" ]

[[test]]
name = "serde_tests"
Expand All @@ -38,4 +37,4 @@ approx = "0.5"

[package.metadata.docs.rs]
# No need to clutter docs.rs with the mint converters.
features = [ "swizzle", "serde", "rand" ]
features = [ "serde", "rand" ]
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ For more information and a guide on getting started, check out the [documentatio
* The `mint` feature (off by default) adds a dependency to the [mint](https://crates.io/crates/mint) crate and provides support for converting between al-jabr types and mint types.
* The `serde` feature (off by default) adds serialization/deserialization support from the [serde](https://crates.io/crates/serde) crate.
* The `rand` feature (off by default) allows you to create random points, vectors, and matrices by sampling from a random number source.
* The `swizzle` feature (off by default) enables [swizzle](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)) functions for vectors.

## Contributions

Expand Down
147 changes: 70 additions & 77 deletions src/column_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,74 @@ use super::*;
/// ColumnVector::<u32, 4>::from([ 0u32, 1, 2, 3 ])
/// );
/// ```
#[cfg_attr(
feature = "swizzle",
doc = r##"
# Swizzling
[Swizzling](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics))
is supported for up to four elements. Swizzling is a technique for easily
rearranging and accessing elements of a vector, used commonly in graphics
shader programming. Swizzling is available on vectors whose element type
implements `Clone`.
Single-element accessors return the element itself. Multi-element accessors
return vectors of the appropriate size.
## Element names
Only the first four elements of a vector may be swizzled. If you have vectors
larger than length four and want to manipulate their elements, you must do so
manually.
Because swizzling is often used in compute graphics contexts when dealing with
colors, both 'xyzw' and 'rgba' element names are available.
| Element Index | xyzw Name | rgba Name |
|---------------|-----------|-----------|
| 0 | x | r |
| 1 | y | g |
| 2 | z | b |
| 3 | w | a |
## Restrictions
It is a runtime error to attempt to access an element beyond the bounds of a vector.
For example, `vec2(1i32, 2).z()` will panic because `z()` is only available on vectors
of length 3 or greater. Previously, this was a compilation error. However, for newer
versions of rustc this is no longer always the case.
```should_panic
# use al_jabr::*;
let z = column_vector!(1i32, 2).z(); // Will panic.
```
### Mixing
zle methods are not implemented for mixed xyzw/rgba methods.
```
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3, 4);
let xy = v.xy(); // OK, only uses xyzw names.
let ba = v.ba(); // OK, only uses rgba names.
assert_eq!(xy, column_vector!(1i32, 2));
assert_eq!(ba, column_vector!(3i32, 4));
```
```compile_fail
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3, 4);
let bad = v.xyrg(); // Compile error, mixes xyzw and rgba names.
```
## Examples
To get the first two elements of a 4-vector.
```
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3, 4).xy();
```
To get the first and last element of a 4-vector.
```
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3, 4).xw();
```
To reverse the order of a 3-vector.
```
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3).zyx();
```
To select the first and third elements into the second and fourth elements,
respectively.
```
# use al_jabr::*;
let v = column_vector!(1i32, 2, 3, 4).xxzz();
```
"##
)]
/// # Swizzling
/// [Swizzling](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics))
/// is supported for up to four elements. Swizzling is a technique for easily
/// rearranging and accessing elements of a vector, used commonly in graphics
/// shader programming. Swizzling is available on vectors whose element type
/// implements `Clone`.
/// Single-element accessors return the element itself. Multi-element accessors
/// return vectors of the appropriate size.
/// ## Element names
/// Only the first four elements of a vector may be swizzled. If you have vectors
/// larger than length four and want to manipulate their elements, you must do so
/// manually.
/// Because swizzling is often used in compute graphics contexts when dealing with
/// colors, both 'xyzw' and 'rgba' element names are available.
///
/// | Element Index | xyzw Name | rgba Name |
/// |---------------|-----------|-----------|
/// | 0 | x | r |
/// | 1 | y | g |
/// | 2 | z | b |
/// | 3 | w | a |
///
/// ## Restrictions
/// It is a runtime error to attempt to access an element beyond the bounds of a vector.
/// For example, `vec2(1i32, 2).z()` will panic because `z()` is only available on vectors
/// of length 3 or greater. Previously, this was a compilation error. However, for newer
/// versions of rustc this is no longer always the case.
/// ```should_panic
/// # use al_jabr::*;
/// let z = column_vector!(1i32, 2).z(); // Will panic.
/// ```
/// ### Mixing
/// swizzle methods are not implemented for mixed xyzw/rgba methods.
/// ```
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3, 4);
/// let xy = v.xy(); // OK, only uses xyzw names.
/// let ba = v.ba(); // OK, only uses rgba names.
/// assert_eq!(xy, column_vector!(1i32, 2));
/// assert_eq!(ba, column_vector!(3i32, 4));
/// ```
/// ```compile_fail
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3, 4);
/// let bad = v.xyrg(); // Compile error, mixes xyzw and rgba names.
/// ```
/// ## Examples
/// To get the first two elements of a 4-vector.
/// ```
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3, 4).xy();
/// ```
/// To get the first and last element of a 4-vector.
/// ```
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3, 4).xw();
/// ```
/// To reverse the order of a 3-vector.
/// ```
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3).zyx();
/// ```
/// To select the first and third elements into the second and fourth elements,
/// respectively.
/// ```
/// # use al_jabr::*;
/// let v = column_vector!(1i32, 2, 3, 4).xxzz();
/// ```
pub type ColumnVector<T, const N: usize> = Matrix<T, N, 1>;

impl<T> ColumnVector<T, 1>
Expand Down Expand Up @@ -507,7 +502,6 @@ impl<T, const N: usize> ColumnVector<T, N> {
}

// Generates all the 2, 3, and 4-level swizzle functions.
#[cfg(feature = "swizzle")]
macro_rules! swizzle {
// First level. Doesn't generate any functions itself because the one-letter functions
// are manually provided in the Swizzle trait.
Expand Down Expand Up @@ -576,7 +570,6 @@ macro_rules! swizzle {
};
}

#[cfg(feature = "swizzle")]
impl<T, const N: usize> ColumnVector<T, N>
where
T: Clone,
Expand Down Expand Up @@ -859,13 +852,13 @@ mod tests {
// Incident straight on to the surface.
let v = column_vector!(1, 0);
let n = column_vector!(-1, 0);
let r = v.reflect(n);
let r = v.reflect(unsafe { Unit::new_unchecked(n) });
assert_eq!(r, column_vector!(-1, 0));

// Incident at 45 degree angle to the surface.
let v = column_vector!(1, 1);
let n = column_vector!(-1, 0);
let r = v.reflect(n);
let r = v.reflect(unsafe { Unit::new_unchecked(n) });
assert_eq!(r, column_vector!(-1, 1));
}
}
34 changes: 32 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
//! If the scalar type implements [Mul] as well, then the Vector will be an
//! [InnerSpace] and have the [dot](InnerSpace::dot) product defined for it,
//! as well as the ability to find the squared distance between two vectors
//! (implements [MetricSpace]) and the squared magnitude of a vector. If the
//! (implements [MetricSpace]) and the squared magnitude of a vector. If the
//! scalar type is a real number then the distance between two vectors and
//! the magnitude of a vector can be found in addition:
//!
Expand All @@ -83,6 +83,17 @@
//! );
//! ```
//!
//! #### Swizzling
//!
//! ColumnVectors of any size and Vectors of size 2, 3 and 4 support
//! [swizzling](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)).
//! The methods are hidden as to not pollute the docs, but are still available:
//!
//! ```rust
//! # use al_jabr::*;
//! assert_eq!(Vector3::new(1i32, 2, 3).xy(), Vector2::new(1i32, 2));
//! ```
//!
//! ### Points
//!
//! Small (N = 1, 2, 3, 4) points in space are provided.
Expand Down Expand Up @@ -194,6 +205,9 @@
//! c
//! );
//! ```
//!
//! Some matrices have special functions defined for them. Check out [Matrix3]
//! and [Matrix4] for more information.
use core::{
cmp::PartialOrd,
Expand Down Expand Up @@ -350,8 +364,10 @@ where
{
fn sqrt(self) -> Self;

/// Returns twice the value.
fn mul2(self) -> Self;

/// Returns half of the value.
fn div2(self) -> Self;

fn abs(self) -> Self;
Expand Down Expand Up @@ -551,7 +567,8 @@ where
/// surface normal must be of length 1 for the return value to be
/// correct. The current vector is interpreted as pointing toward the
/// surface, and does not need to be normalized.
fn reflect(self, surface_normal: Self) -> Self {
fn reflect(self, surface_normal: Unit<Self>) -> Self {
let surface_normal = surface_normal.into_inner();
let a = surface_normal.clone() * self.clone().dot(surface_normal);
self - (a.clone() + a)
}
Expand Down Expand Up @@ -635,6 +652,19 @@ where
}
}

impl<T> Unit<T> {
/// Construct a new unit object without normalizing
///
/// # Safety
///
/// This method assumes that the object being passed to it is normalized,
/// i.e. has a magnitude of one. If it does not, other methods can break
/// in strange ways.
pub unsafe fn new_unchecked(obj: T) -> Self {
Unit(obj)
}
}

impl<T> Unit<T>
where
T: RealInnerSpace + VectorSpace + Neg<Output = T>,
Expand Down
Loading

0 comments on commit c7c1bb7

Please sign in to comment.