use crate::color;
use crate::geom::{scalar, Point2, Point3};
use crate::math::BaseNum;
use std::ops::{Deref, DerefMut};
pub trait Vertex: Clone + Copy + PartialEq {
type Scalar: BaseNum;
}
pub trait Vertex2d: Vertex {
fn point2(self) -> Point2<Self::Scalar>;
}
pub trait Vertex3d: Vertex2d {
fn point3(self) -> Point3<Self::Scalar>;
}
pub type Default = Point3<scalar::Default>;
#[derive(Clone, Debug)]
pub struct IterFromIndices<'a, I, V: 'a = Default> {
indices: I,
vertices: &'a [V],
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Rgba<V = Default>(pub V, pub color::Rgba);
pub fn iter_from_indices<I, V>(indices: I, vertices: &[V]) -> IterFromIndices<I::IntoIter, V>
where
I: IntoIterator<Item = usize>,
{
let indices = indices.into_iter();
IterFromIndices { indices, vertices }
}
impl<'a, I, V> Iterator for IterFromIndices<'a, I, V>
where
I: Iterator<Item = usize>,
{
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
let IterFromIndices {
ref mut indices,
ref vertices,
} = *self;
indices.next().map(|i| &vertices[i])
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.indices.size_hint()
}
}
impl<'a, I, V> DoubleEndedIterator for IterFromIndices<'a, I, V>
where
I: Iterator<Item = usize> + DoubleEndedIterator,
{
fn next_back(&mut self) -> Option<Self::Item> {
let IterFromIndices {
ref mut indices,
ref vertices,
} = *self;
indices.next_back().map(|i| &vertices[i])
}
}
impl<'a, I, V> ExactSizeIterator for IterFromIndices<'a, I, V>
where
I: Iterator<Item = usize> + ExactSizeIterator,
{
fn len(&self) -> usize {
self.indices.len()
}
}
impl<V> Rgba<V> {
pub fn vertex(&self) -> &V {
&self.0
}
pub fn rgba(&self) -> &color::Rgba {
&self.1
}
}
impl<V> Deref for Rgba<V> {
type Target = V;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<V> DerefMut for Rgba<V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<V> From<(V, color::Rgba)> for Rgba<V> {
fn from((v, rgba): (V, color::Rgba)) -> Self {
Rgba(v, rgba)
}
}
impl<V> Into<(V, color::Rgba)> for Rgba<V> {
fn into(self) -> (V, color::Rgba) {
let Rgba(v, rgba) = self;
(v, rgba)
}
}
impl<S> Vertex for Point2<S>
where
S: BaseNum,
{
type Scalar = S;
}
impl<S> Vertex for Point3<S>
where
S: BaseNum,
{
type Scalar = S;
}
impl<S> Vertex for [S; 2]
where
S: BaseNum,
{
type Scalar = S;
}
impl<S> Vertex for [S; 3]
where
S: BaseNum,
{
type Scalar = S;
}
impl<S> Vertex for (S, S)
where
S: BaseNum,
{
type Scalar = S;
}
impl<S> Vertex for (S, S, S)
where
S: BaseNum,
{
type Scalar = S;
}
impl<V> Vertex for Rgba<V>
where
V: Vertex,
{
type Scalar = V::Scalar;
}
impl<S> Vertex2d for Point2<S>
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
Point2 {
x: self.x,
y: self.y,
}
}
}
impl<S> Vertex2d for Point3<S>
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
Point2 {
x: self.x,
y: self.y,
}
}
}
impl<S> Vertex2d for [S; 2]
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
Point2 {
x: self[0],
y: self[1],
}
}
}
impl<S> Vertex2d for [S; 3]
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
Point2 {
x: self[0],
y: self[1],
}
}
}
impl<S> Vertex2d for (S, S)
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
let (x, y) = self;
Point2 { x, y }
}
}
impl<S> Vertex2d for (S, S, S)
where
S: BaseNum,
{
fn point2(self) -> Point2<S> {
let (x, y, _) = self;
Point2 { x, y }
}
}
impl<V> Vertex2d for Rgba<V>
where
V: Vertex2d,
{
fn point2(self) -> Point2<V::Scalar> {
self.0.point2()
}
}
impl<S> Vertex3d for Point3<S>
where
S: BaseNum,
{
fn point3(self) -> Point3<S> {
Point3 {
x: self.x,
y: self.y,
z: self.z,
}
}
}
impl<S> Vertex3d for [S; 3]
where
S: BaseNum,
{
fn point3(self) -> Point3<S> {
Point3 {
x: self[0],
y: self[1],
z: self[2],
}
}
}
impl<S> Vertex3d for (S, S, S)
where
S: BaseNum,
{
fn point3(self) -> Point3<S> {
let (x, y, z) = self;
Point3 { x, y, z }
}
}
impl<V> Vertex3d for Rgba<V>
where
V: Vertex3d,
{
fn point3(self) -> Point3<V::Scalar> {
self.0.point3()
}
}