use crate::color;
use crate::geom::{self, Point2, Point3, Vector3};
use crate::math::BaseFloat;
use crate::mesh::vertex::{WithColor, WithTexCoords};
use std::marker::PhantomData;
pub type Point<S> = Point3<S>;
pub type Color = color::Rgba;
pub type TexCoords<S> = Point2<S>;
pub type Normal<S> = Vector3<S>;
pub type ColoredPoint<S> = WithColor<Point<S>, Color>;
pub type Vertex<S> = WithTexCoords<WithColor<Point<S>, Color>, TexCoords<S>>;
pub trait IntoVertex<S> {
fn into_vertex(self) -> Vertex<S>;
}
pub trait IntoPoint<S> {
fn into_point(self) -> Point<S>;
}
const DEFAULT_VERTEX_COLOR: Color = color::WHITE;
impl<'a, S, T> IntoVertex<S> for &'a T
where
T: Clone + IntoVertex<S>,
{
fn into_vertex(self) -> Vertex<S> {
self.clone().into_vertex()
}
}
impl<S> IntoVertex<S> for Vertex<S> {
fn into_vertex(self) -> Vertex<S> {
self
}
}
impl<S> IntoVertex<S> for ColoredPoint<S>
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let WithColor { vertex, color } = self;
let tex_coords = default_tex_coords();
new(vertex, color, tex_coords)
}
}
impl<S> IntoVertex<S> for Point<S>
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let colored_point = WithColor {
vertex: self,
color: DEFAULT_VERTEX_COLOR,
};
colored_point.into_vertex()
}
}
impl<S> IntoVertex<S> for Point2<S>
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let pt = Point3::new(self.x, self.y, S::zero());
pt.into_vertex()
}
}
impl<S> IntoVertex<S> for [S; 2]
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let pt = Point2::new(self[0].clone(), self[1].clone());
pt.into_vertex()
}
}
impl<S> IntoVertex<S> for [S; 3]
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let pt = Point3::new(self[0].clone(), self[1].clone(), self[2].clone());
pt.into_vertex()
}
}
impl<S> IntoVertex<S> for (S, S)
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let (x, y) = self;
let pt = Point2::new(x, y);
pt.into_vertex()
}
}
impl<S> IntoVertex<S> for (S, S, S)
where
S: BaseFloat,
{
fn into_vertex(self) -> Vertex<S> {
let (x, y, z) = self;
let pt = Point3::new(x, y, z);
pt.into_vertex()
}
}
impl<S, T> IntoVertex<S> for (T, Color)
where
S: BaseFloat,
T: IntoPoint<S>,
{
fn into_vertex(self) -> Vertex<S> {
let (t, color) = self;
let vertex = t.into_point();
let with_color = WithColor { vertex, color };
with_color.into_vertex()
}
}
impl<S, V> IntoVertex<S> for geom::vertex::Rgba<V>
where
S: BaseFloat,
V: geom::Vertex<Scalar = S>,
(V, Color): IntoVertex<S>,
{
fn into_vertex(self) -> Vertex<S> {
let geom::vertex::Rgba(v, color) = self;
(v, color).into_vertex()
}
}
impl<S> IntoPoint<S> for Point<S> {
fn into_point(self) -> Self {
self
}
}
impl<S> IntoPoint<S> for Point2<S>
where
S: BaseFloat,
{
fn into_point(self) -> Point<S> {
let Point2 { x, y } = self;
let z = S::zero();
Point3 { x, y, z }
}
}
impl<S> IntoPoint<S> for (S, S)
where
S: BaseFloat,
{
fn into_point(self) -> Point<S> {
let (x, y) = self;
let z = S::zero();
Point3 { x, y, z }
}
}
impl<S> IntoPoint<S> for (S, S, S) {
fn into_point(self) -> Point<S> {
let (x, y, z) = self;
Point3 { x, y, z }
}
}
impl<S> IntoPoint<S> for [S; 2]
where
S: BaseFloat,
{
fn into_point(self) -> Point<S> {
let x = self[0];
let y = self[1];
let z = S::zero();
Point3 { x, y, z }
}
}
impl<S> IntoPoint<S> for [S; 3]
where
S: Copy,
{
fn into_point(self) -> Point<S> {
let x = self[0];
let y = self[1];
let z = self[2];
Point3 { x, y, z }
}
}
pub fn new<S>(point: Point<S>, color: Color, tex_coords: TexCoords<S>) -> Vertex<S> {
WithTexCoords {
tex_coords,
vertex: WithColor {
color,
vertex: point,
},
}
}
pub fn default_tex_coords<S>() -> TexCoords<S>
where
S: BaseFloat,
{
Point2 {
x: S::zero(),
y: S::zero(),
}
}
impl<S> Vertex<S> {
pub fn point(&self) -> &Point<S> {
&self.vertex.vertex
}
pub fn point_mut(&mut self) -> &mut Point<S> {
&mut self.vertex.vertex
}
}
#[derive(Clone, Debug)]
pub struct IterFromColoredPoints<I, S = geom::scalar::Default> {
colored_points: I,
_scalar: PhantomData<S>,
}
impl<I, S> IterFromColoredPoints<I, S> {
pub fn new<P>(colored_points: P) -> Self
where
P: IntoIterator<IntoIter = I, Item = WithColor<Point<S>, Color>>,
I: Iterator<Item = WithColor<Point<S>, Color>>,
{
let colored_points = colored_points.into_iter();
let _scalar = PhantomData;
IterFromColoredPoints {
colored_points,
_scalar,
}
}
}
impl<I, S> Iterator for IterFromColoredPoints<I, S>
where
I: Iterator<Item = WithColor<Point<S>, Color>>,
S: BaseFloat,
{
type Item = Vertex<S>;
fn next(&mut self) -> Option<Self::Item> {
self.colored_points.next().map(|vertex| {
let tex_coords = default_tex_coords();
let vertex = WithTexCoords { tex_coords, vertex };
vertex
})
}
}
#[derive(Clone, Debug)]
pub struct IterFromPoints<I, S = geom::scalar::Default> {
points: I,
default_color: Color,
_scalar: PhantomData<S>,
}
#[derive(Clone, Debug)]
pub struct IterFromPoint2s<I, S = geom::scalar::Default> {
points: I,
default_color: Color,
_scalar: PhantomData<S>,
}
impl<I, S> IterFromPoints<I, S> {
pub fn new<P>(points: P, default_color: Color) -> Self
where
P: IntoIterator<IntoIter = I, Item = Point<S>>,
I: Iterator<Item = Point3<S>>,
{
let points = points.into_iter();
let _scalar = PhantomData;
IterFromPoints {
points,
default_color,
_scalar,
}
}
}
impl<I, S> IterFromPoint2s<I, S> {
pub fn new<P>(points: P, default_color: Color) -> Self
where
P: IntoIterator<IntoIter = I, Item = Point2<S>>,
I: Iterator<Item = Point2<S>>,
{
let points = points.into_iter();
let _scalar = PhantomData;
IterFromPoint2s {
points,
default_color,
_scalar,
}
}
}
impl<I, S> Iterator for IterFromPoints<I, S>
where
I: Iterator<Item = Point<S>>,
S: BaseFloat,
{
type Item = Vertex<S>;
fn next(&mut self) -> Option<Self::Item> {
self.points.next().map(|vertex| {
let color = self.default_color;
let vertex = WithColor { vertex, color };
let tex_coords = default_tex_coords();
let vertex = WithTexCoords { vertex, tex_coords };
vertex
})
}
}
impl<I, S> Iterator for IterFromPoint2s<I, S>
where
I: Iterator<Item = Point2<S>>,
S: BaseFloat,
{
type Item = Vertex<S>;
fn next(&mut self) -> Option<Self::Item> {
self.points.next().map(|Point2 { x, y }| {
let vertex = Point3 { x, y, z: S::zero() };
let color = self.default_color;
let vertex = WithColor { vertex, color };
let tex_coords = default_tex_coords();
let vertex = WithTexCoords { vertex, tex_coords };
vertex
})
}
}