Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 93 additions & 7 deletions core/src/math/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ pub const INV_GAMMA: f32 = 1.0 / GAMMA;
// Inherent impls
//

impl<Ch, Sp, const N: usize> Color<[Ch; N], Sp> {
/// Returns a new `Color` with the given channels.
impl<R, Sp> Color<R, Sp> {
/// Returns a new `Color` with the given representation.
#[inline]
pub const fn new(chs: [Ch; N]) -> Self {
Self(chs, PhantomData)
pub const fn new(repr: R) -> Self {
Self(repr, PhantomData)
}
}

impl<Ch, Sp, const N: usize> Color<[Ch; N], Sp> {
/// Returns `self` with each channel mapped with the given function.
#[inline]
pub fn map<C>(&self, f: impl FnMut(Ch) -> C) -> Color<[C; N], Sp>
Expand Down Expand Up @@ -661,10 +663,43 @@ impl<R: PartialEq, Sp> PartialEq for Color<R, Sp> {
}
}

// Color <-> repr conversions
impl<R, Sp> From<R> for Color<R, Sp> {
#[inline]
fn from(els: R) -> Self {
Self(els, PhantomData)
fn from(repr: R) -> Self {
Self::new(repr)
}
}
impl<Sc, Sp, const N: usize> From<Color<[Sc; N], Sp>> for [Sc; N] {
#[inline]
fn from(c: Color<[Sc; N], Sp>) -> Self {
c.0
}
}

// Color <-> tuple conversions
impl<Sc, Sp> From<(Sc, Sc, Sc)> for Color<[Sc; 3], Sp> {
#[inline]
fn from(chs: (Sc, Sc, Sc)) -> Self {
Self::new(chs.into())
}
}
impl<Sc, Sp> From<Color<[Sc; 3], Sp>> for (Sc, Sc, Sc) {
#[inline]
fn from(c: Color<[Sc; 3], Sp>) -> Self {
c.0.into()
}
}
impl<Sc, Sp> From<(Sc, Sc, Sc, Sc)> for Color<[Sc; 4], Sp> {
#[inline]
fn from(chs: (Sc, Sc, Sc, Sc)) -> Self {
Self::new(chs.into())
}
}
impl<Sc, Sp> From<Color<[Sc; 4], Sp>> for (Sc, Sc, Sc, Sc) {
#[inline]
fn from(c: Color<[Sc; 4], Sp>) -> Self {
c.0.into()
}
}

Expand All @@ -676,7 +711,6 @@ impl<R: Index<usize>, Sp> Index<usize> for Color<R, Sp> {
&self.0[i]
}
}

impl<R: IndexMut<usize>, Sp> IndexMut<usize> for Color<R, Sp> {
#[inline]
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
Expand Down Expand Up @@ -798,6 +832,58 @@ impl_op!(Div::div, Color, f32, /=, bound=Linear<Scalar = f32>);
mod tests {
use super::*;

#[test]
fn color3_from() {
let c: Color3 = [1, 2, 3].into();
assert_eq!(c.0, [1, 2, 3]);

let c: Color3 = (1, 2, 3).into();
assert_eq!(c.0, [1, 2, 3]);

let c: Color3f = [1.0, 2.0, 3.0].into();
assert_eq!(c.0, [1.0, 2.0, 3.0]);

let c: Color3f = (1.0, 2.0, 3.0).into();
assert_eq!(c.0, [1.0, 2.0, 3.0]);
}

#[test]
fn color3_into() {
let c = rgb(1, 2, 3);
assert_eq!(<[_; 3]>::from(c), [1, 2, 3]);
assert_eq!(<(_, _, _)>::from(c), (1, 2, 3));

let c = rgb(1.0, 2.0, 3.0);
assert_eq!(<[_; 3]>::from(c), [1.0, 2.0, 3.0]);
assert_eq!(<(_, _, _)>::from(c), (1.0, 2.0, 3.0));
}

#[test]
fn color4_from() {
let c: Color4 = [1, 2, 3, 4].into();
assert_eq!(c.0, [1, 2, 3, 4]);

let c: Color4 = (1, 2, 3, 4).into();
assert_eq!(c.0, [1, 2, 3, 4]);

let c: Color4f = [1.0, 2.0, 3.0, 4.0].into();
assert_eq!(c.0, [1.0, 2.0, 3.0, 4.0]);

let c: Color4f = (1.0, 2.0, 3.0, 4.0).into();
assert_eq!(c.0, [1.0, 2.0, 3.0, 4.0]);
}

#[test]
fn color4_into() {
let c = rgba(1, 2, 3, 4);
assert_eq!(<[_; 4]>::from(c), [1, 2, 3, 4]);
assert_eq!(<(_, _, _, _)>::from(c), (1, 2, 3, 4));

let c = rgba(1.0, 2.0, 3.0, 4.0);
assert_eq!(<[_; 4]>::from(c), [1.0, 2.0, 3.0, 4.0]);
assert_eq!(<(_, _, _, _)>::from(c), (1.0, 2.0, 3.0, 4.0));
}

#[test]
fn rgb_components() {
assert_eq!(rgb(0xFF, 0, 0).r(), 0xFF);
Expand Down
49 changes: 36 additions & 13 deletions core/src/math/point.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use super::{Affine, ApproxEq, Linear, Vector, space::Real, vary::ZDiv};
use crate::math::space::Hom;
use core::{
array,
fmt::{Debug, Formatter},
Expand All @@ -8,6 +6,12 @@ use core::{
ops::{AddAssign, DivAssign, MulAssign, SubAssign},
};

use super::{
Affine, ApproxEq, Linear, Vector,
space::{Hom, Real},
vary::ZDiv,
};

#[repr(transparent)]
pub struct Point<Repr, Space = ()>(pub Repr, Pd<Space>);

Expand Down Expand Up @@ -334,26 +338,45 @@ impl<R: PartialEq, S> PartialEq for Point<R, S> {
}
}

// Point <-> repr conversions
impl<R, Sp> From<R> for Point<R, Sp> {
#[inline]
fn from(repr: R) -> Self {
Self(repr, Pd)
Self::new(repr)
}
}
/*
impl<B> From<Point3<B>> for HomVec3<B> {
fn from(p: Point3<B>) -> Self {
let [x, y, z] = p.0;
[x, y, z, 1.0].into()
impl<Sc, Sp, const N: usize> From<Point<[Sc; N], Sp>> for [Sc; N] {
#[inline]
fn from(v: Point<[Sc; N], Sp>) -> Self {
v.0
}
}

impl<B> From<Point2<B>> for HomVec2<B> {
fn from(p: Point2<B>) -> Self {
let [x, y] = p.0;
[x, y, 1.0].into()
// Point <-> tuple conversions
impl<Sc, Sp> From<(Sc, Sc)> for Point<[Sc; 2], Sp> {
#[inline]
fn from(xy: (Sc, Sc)) -> Self {
Self::new(xy.into())
}
}
impl<Sc, Sp> From<Point<[Sc; 2], Sp>> for (Sc, Sc) {
#[inline]
fn from(v: Point<[Sc; 2], Sp>) -> Self {
v.0.into()
}
}*/
}
impl<Sc, Sp> From<(Sc, Sc, Sc)> for Point<[Sc; 3], Sp> {
#[inline]
fn from(xyz: (Sc, Sc, Sc)) -> Self {
Self::new(xyz.into())
}
}
impl<Sc, Sp> From<Point<[Sc; 3], Sp>> for (Sc, Sc, Sc) {
#[inline]
fn from(v: Point<[Sc; 3], Sp>) -> Self {
v.0.into()
}
}

impl<R: Index<usize>, Sp> Index<usize> for Point<R, Sp> {
type Output = R::Output;
Expand Down
48 changes: 40 additions & 8 deletions core/src/math/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
//!
//! TODO

use super::{
Affine, ApproxEq, Linear, Point,
space::{Proj3, Real},
vary::ZDiv,
};
use crate::math::space::Hom;
use core::{
array,
fmt::{Debug, Formatter},
Expand All @@ -17,6 +11,12 @@ use core::{
ops::{AddAssign, DivAssign, MulAssign, SubAssign},
};

use super::{
Affine, ApproxEq, Linear, Point,
space::{Hom, Proj3, Real},
vary::ZDiv,
};

//
// Types
//
Expand Down Expand Up @@ -722,14 +722,20 @@ impl<R: Debug, Sp: Debug + Default> Debug for Vector<R, Sp> {
}
}

// Vector <-> repr conversions
impl<R, Sp> From<R> for Vector<R, Sp> {
#[inline]
fn from(repr: R) -> Self {
Self::new(repr)
}
}

impl<Sp, Sc: Copy, const DIM: usize> From<Sc> for Vector<[Sc; DIM], Sp> {
impl<Sc, Sp, const N: usize> From<Vector<[Sc; N], Sp>> for [Sc; N] {
#[inline]
fn from(v: Vector<[Sc; N], Sp>) -> Self {
v.0
}
}
impl<Sp, Sc: Copy, const N: usize> From<Sc> for Vector<[Sc; N], Sp> {
/// Returns a vector with all components equal to `scalar`.
///
/// This operation is also called "splat" or "broadcast".
Expand All @@ -739,6 +745,32 @@ impl<Sp, Sc: Copy, const DIM: usize> From<Sc> for Vector<[Sc; DIM], Sp> {
}
}

// Vector <-> tuple conversions
impl<Sc, Sp> From<(Sc, Sc)> for Vector<[Sc; 2], Sp> {
#[inline]
fn from(xy: (Sc, Sc)) -> Self {
Self::new(xy.into())
}
}
impl<Sc, Sp> From<Vector<[Sc; 2], Sp>> for (Sc, Sc) {
#[inline]
fn from(v: Vector<[Sc; 2], Sp>) -> Self {
v.0.into()
}
}
impl<Sc, Sp> From<(Sc, Sc, Sc)> for Vector<[Sc; 3], Sp> {
#[inline]
fn from(xyz: (Sc, Sc, Sc)) -> Self {
Self::new(xyz.into())
}
}
impl<Sc, Sp> From<Vector<[Sc; 3], Sp>> for (Sc, Sc, Sc) {
#[inline]
fn from(v: Vector<[Sc; 3], Sp>) -> Self {
v.0.into()
}
}

impl<R, Sp> Index<usize> for Vector<R, Sp>
where
Self: Affine,
Expand Down