Skip to content

Commit

Permalink
Use explicit methods to convert between arrays and matrices.
Browse files Browse the repository at this point in the history
Removed `From` trait implementations converting between 1D and 2D arrays
and matrix types to avoid any potential confusion about data being
loaded and stored in column major order. New function names hopefully
make it clear that column major ordering is being used.

Fixes #21.
  • Loading branch information
bitshifter committed Oct 9, 2019
1 parent 5b69980 commit 4cb4ffe
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 192 deletions.
18 changes: 9 additions & 9 deletions src/f32/glam_mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl From<Quat> for mint::Quaternion<f32> {

impl From<mint::RowMatrix2<f32>> for Mat2 {
fn from(m: mint::RowMatrix2<f32>) -> Self {
Self::new(m.x.into(), m.y.into()).transpose()
Self::from_cols(m.x.into(), m.y.into()).transpose()
}
}

Expand All @@ -100,7 +100,7 @@ impl From<Mat2> for mint::RowMatrix2<f32> {

impl From<mint::ColumnMatrix2<f32>> for Mat2 {
fn from(m: mint::ColumnMatrix2<f32>) -> Self {
Self::new(m.x.into(), m.y.into())
Self::from_cols(m.x.into(), m.y.into())
}
}

Expand All @@ -115,7 +115,7 @@ impl From<Mat2> for mint::ColumnMatrix2<f32> {

impl From<mint::RowMatrix3<f32>> for Mat3 {
fn from(m: mint::RowMatrix3<f32>) -> Self {
Self::new(m.x.into(), m.y.into(), m.z.into()).transpose()
Self::from_cols(m.x.into(), m.y.into(), m.z.into()).transpose()
}
}

Expand All @@ -132,7 +132,7 @@ impl From<Mat3> for mint::RowMatrix3<f32> {

impl From<mint::ColumnMatrix3<f32>> for Mat3 {
fn from(m: mint::ColumnMatrix3<f32>) -> Self {
Self::new(m.x.into(), m.y.into(), m.z.into())
Self::from_cols(m.x.into(), m.y.into(), m.z.into())
}
}

Expand All @@ -148,7 +148,7 @@ impl From<Mat3> for mint::ColumnMatrix3<f32> {

impl From<mint::RowMatrix4<f32>> for Mat4 {
fn from(m: mint::RowMatrix4<f32>) -> Self {
Self::new(m.x.into(), m.y.into(), m.z.into(), m.w.into()).transpose()
Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into()).transpose()
}
}

Expand All @@ -166,7 +166,7 @@ impl From<Mat4> for mint::RowMatrix4<f32> {

impl From<mint::ColumnMatrix4<f32>> for Mat4 {
fn from(m: mint::ColumnMatrix4<f32>) -> Self {
Self::new(m.x.into(), m.y.into(), m.z.into(), m.w.into())
Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into())
}
}

Expand Down Expand Up @@ -261,7 +261,7 @@ mod test {
#[test]
fn test_matrix2() {
use crate::Mat2;
let g = Mat2::from([[1.0, 2.0], [3.0, 4.0]]);
let g = Mat2::from_cols_array_2d(&[[1.0, 2.0], [3.0, 4.0]]);
let m = mint::ColumnMatrix2::from(g);
assert_eq!(g, Mat2::from(m));
let mt = mint::RowMatrix2::from(g);
Expand All @@ -272,7 +272,7 @@ mod test {
#[test]
fn test_matrix3() {
use crate::Mat3;
let g = Mat3::from([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
let g = Mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
let m = mint::ColumnMatrix3::from(g);
assert_eq!(g, Mat3::from(m));
let mt = mint::RowMatrix3::from(g);
Expand All @@ -286,7 +286,7 @@ mod test {
#[test]
fn test_matrix4() {
use crate::Mat4;
let g = Mat4::from([
let g = Mat4::from_cols_array_2d(&[
[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[9.0, 10.0, 11.0, 12.0],
Expand Down
6 changes: 3 additions & 3 deletions src/f32/glam_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl<'de> Deserialize<'de> for Mat2 {
}
let x = Vec2::new(f[0], f[1]);
let y = Vec2::new(f[2], f[3]);
Ok(Mat2::new(x, y))
Ok(Mat2::from_cols(x, y))
}
}

Expand Down Expand Up @@ -340,7 +340,7 @@ impl<'de> Deserialize<'de> for Mat3 {
let x = Vec3::new(f[0], f[1], f[2]);
let y = Vec3::new(f[3], f[4], f[5]);
let z = Vec3::new(f[6], f[7], f[8]);
Ok(Mat3::new(x, y, z))
Ok(Mat3::from_cols(x, y, z))
}
}

Expand Down Expand Up @@ -378,7 +378,7 @@ impl<'de> Deserialize<'de> for Mat4 {
let y = Vec4::new(f[4], f[5], f[6], f[7]);
let z = Vec4::new(f[8], f[9], f[10], f[11]);
let w = Vec4::new(f[12], f[13], f[14], f[15]);
Ok(Mat4::new(x, y, z, w))
Ok(Mat4::from_cols(x, y, z, w))
}
}

Expand Down
73 changes: 39 additions & 34 deletions src/f32/mat2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::ops::{Add, Mul, Sub};

#[inline]
pub fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
Mat2::new(x_axis, y_axis)
Mat2::from_cols(x_axis, y_axis)
}

/// A 2x2 column major matrix.
Expand All @@ -35,11 +35,47 @@ impl Mat2 {
Self(Vec4::new(1.0, 0.0, 0.0, 1.0))
}

#[deprecated(since = "0.7.2", note = "please use `Mat4::from_cols` instead")]
#[inline]
pub fn new(x_axis: Vec2, y_axis: Vec2) -> Self {
Self::from_cols(x_axis, y_axis)
}

/// Creates a new `Mat2` from four column vectors.
#[inline]
pub fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
Self(Vec4::new(x_axis.x(), x_axis.y(), y_axis.x(), y_axis.y()))
}

/// Creates a new `Mat2` from a `[f32; 4]` stored in column major order.
/// If your data is stored in row major you will need to `transpose` the resulting `Mat2`.
#[inline]
pub fn from_cols_array(m: &[f32; 4]) -> Self {
Mat2(Vec4::new(m[0], m[1], m[2], m[3]))
}

/// Creates a new `[f32; 4]` storing data in column major order.
/// If you require data in row major order `transpose` the `Mat2` first.
#[inline]
pub fn to_cols_array(&self) -> [f32; 4] {
self.0.into()
}

/// Creates a new `Mat2` from a `[[f32; 2]; 2]` stored in column major order.
/// If your data is in row major order you will need to `transpose` the resulting `Mat2`.
#[inline]
pub fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
Mat2(Vec4::new(m[0][0], m[0][1], m[1][0], m[1][1]))
}

/// Creates a new `[[f32; 2]; 2]` storing data in column major order.
/// If you require data in row major order `transpose` the `Mat2` first.
#[inline]
pub fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
let (x0, y0, x1, y1) = self.0.into();
[[x0, y0], [x1, y1]]
}

/// Create a 2x2 matrix containing scale and rotation (in radians).
#[inline]
pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
Expand Down Expand Up @@ -128,7 +164,7 @@ impl Mat2 {
pub fn mul_mat2(&self, rhs: &Self) -> Self {
// TODO: SSE2
let (x0, y0, x1, y1) = rhs.0.into();
Mat2::new(
Mat2::from_cols(
self.mul_vec2(Vec2::new(x0, y0)),
self.mul_vec2(Vec2::new(x1, y1)),
)
Expand All @@ -155,7 +191,7 @@ impl Mat2 {
impl Distribution<Mat2> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Mat2 {
rng.gen::<[[f32; 2]; 2]>().into()
Mat2::from_cols_array(&rng.gen())
}
}

Expand Down Expand Up @@ -220,34 +256,3 @@ impl Mul<f32> for Mat2 {
self.mul_scalar(rhs)
}
}

impl From<[[f32; 2]; 2]> for Mat2 {
#[inline]
fn from(m: [[f32; 2]; 2]) -> Self {
Mat2(Vec4::new(m[0][0], m[0][1], m[1][0], m[1][1]))
}
}

impl From<Mat2> for [[f32; 2]; 2] {
#[inline]
fn from(m: Mat2) -> Self {
let (x0, y0, x1, y1) = m.0.into();
[[x0, y0], [x1, y1]]
}
}

impl From<[f32; 4]> for Mat2 {
#[inline]
/// Load from array in column major order.
fn from(m: [f32; 4]) -> Self {
Mat2(m.into())
}
}

impl From<Mat2> for [f32; 4] {
#[inline]
/// Store to array in column major order.
fn from(m: Mat2) -> Self {
m.0.into()
}
}
93 changes: 49 additions & 44 deletions src/f32/mat3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,62 @@ impl Mat3 {
}
}

#[deprecated(since = "0.7.2", note = "please use `Mat3::from_cols` instead")]
#[inline]
pub fn new(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
Self::from_cols(x_axis, y_axis, z_axis)
}

/// Creates a new `Mat3` from three column vectors.
#[inline]
pub fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
Self {
x_axis,
y_axis,
z_axis,
}
}

/// Create a 3x3 matrix that can scale, rotate and translate a 2D vector.
/// Creates a new `Mat3` from a `[f32; 9]` stored in column major order.
/// If your data is stored in row major you will need to `transpose` the resulting `Mat3`.
#[inline]
pub fn from_cols_array(m: &[f32; 9]) -> Self {
Mat3 {
x_axis: Vec3::new(m[0], m[1], m[2]),
y_axis: Vec3::new(m[3], m[4], m[5]),
z_axis: Vec3::new(m[6], m[7], m[8]),
}
}

/// Creates a new `[f32; 9]` storing data in column major order.
/// If you require data in row major order `transpose` the `Mat3` first.
#[inline]
pub fn to_cols_array(&self) -> [f32; 9] {
let (m00, m01, m02) = self.x_axis.into();
let (m10, m11, m12) = self.y_axis.into();
let (m20, m21, m22) = self.z_axis.into();
[m00, m01, m02, m10, m11, m12, m20, m21, m22]
}

/// Creates a new `Mat3` from a `[[f32; 3]; 3]` stored in column major order.
/// If your data is in row major order you will need to `transpose` the resulting `Mat3`.
#[inline]
pub fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
Mat3 {
x_axis: m[0].into(),
y_axis: m[1].into(),
z_axis: m[2].into(),
}
}

/// Creates a new `[[f32; 3]; 3]` storing data in column major order.
/// If you require data in row major order `transpose` the `Mat3` first.
#[inline]
pub fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
[self.x_axis.into(), self.y_axis.into(), self.z_axis.into()]
}

/// Creates a new `Mat3` that can scale, rotate and translate a 2D vector.
/// `angle` is in radians.
#[inline]
pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
Expand Down Expand Up @@ -235,7 +281,7 @@ impl Mat3 {
glam_assert!(det.cmpne(Vec3::zero()).all());
let inv_det = det.reciprocal();
// TODO: Work out if it's possible to get rid of the transpose
Mat3::new(tmp0 * inv_det, tmp1 * inv_det, tmp2 * inv_det).transpose()
Mat3::from_cols(tmp0 * inv_det, tmp1 * inv_det, tmp2 * inv_det).transpose()
}

#[inline]
Expand Down Expand Up @@ -301,7 +347,7 @@ impl Mat3 {
impl Distribution<Mat3> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Mat3 {
rng.gen::<[[f32; 3]; 3]>().into()
Mat3::from_cols_array(&rng.gen())
}
}

Expand Down Expand Up @@ -352,44 +398,3 @@ impl Mul<f32> for Mat3 {
self.mul_scalar(rhs)
}
}

impl From<[[f32; 3]; 3]> for Mat3 {
#[inline]
fn from(m: [[f32; 3]; 3]) -> Self {
Mat3 {
x_axis: m[0].into(),
y_axis: m[1].into(),
z_axis: m[2].into(),
}
}
}

impl From<Mat3> for [[f32; 3]; 3] {
#[inline]
fn from(m: Mat3) -> Self {
[m.x_axis.into(), m.y_axis.into(), m.z_axis.into()]
}
}

impl From<[f32; 9]> for Mat3 {
#[inline]
/// Load from array in column major order.
fn from(m: [f32; 9]) -> Self {
Mat3 {
x_axis: Vec3::new(m[0], m[1], m[2]),
y_axis: Vec3::new(m[3], m[4], m[5]),
z_axis: Vec3::new(m[6], m[7], m[8]),
}
}
}

impl From<Mat3> for [f32; 9] {
#[inline]
/// Store to array in column major order.
fn from(m: Mat3) -> Self {
let (m00, m01, m02) = m.x_axis.into();
let (m10, m11, m12) = m.y_axis.into();
let (m20, m21, m22) = m.z_axis.into();
[m00, m01, m02, m10, m11, m12, m20, m21, m22]
}
}
Loading

0 comments on commit 4cb4ffe

Please sign in to comment.