use std::marker::PhantomData;
use cgmath::BaseFloat;
use super::{TreeValue, Visitor};
use crate::{Frustum, PlaneBound, Relation};
use crate::prelude::*;
#[derive(Debug)]
pub struct ContinuousVisitor<'a, B: 'a, T> {
bound: &'a B,
marker: PhantomData<T>,
}
impl<'a, B: 'a, T> ContinuousVisitor<'a, B, T>
where
T: TreeValue,
T::Bound: Continuous<B> + Discrete<B>,
{
pub fn new(bound: &'a B) -> Self {
Self {
bound,
marker: PhantomData,
}
}
}
impl<'a, B: 'a, T> Visitor for ContinuousVisitor<'a, B, T>
where
T: TreeValue,
T::Bound: Continuous<B> + Discrete<B>,
{
type Bound = T::Bound;
type Result = <T::Bound as Continuous<B>>::Result;
fn accept(&mut self, bound: &Self::Bound, _: bool) -> Option<Self::Result> {
bound.intersection(self.bound)
}
}
#[derive(Debug)]
pub struct DiscreteVisitor<'a, B: 'a, T> {
bound: &'a B,
marker: PhantomData<T>,
}
impl<'a, B: 'a, T> DiscreteVisitor<'a, B, T>
where
T: TreeValue,
T::Bound: Discrete<B>,
{
pub fn new(bound: &'a B) -> Self {
Self {
bound,
marker: PhantomData,
}
}
}
impl<'a, B: 'a, T> Visitor for DiscreteVisitor<'a, B, T>
where
T: TreeValue,
T::Bound: Discrete<B>,
{
type Bound = T::Bound;
type Result = ();
fn accept(&mut self, bound: &Self::Bound, _: bool) -> Option<()> {
if bound.intersects(self.bound) {
Some(())
} else {
None
}
}
}
#[derive(Debug)]
pub struct FrustumVisitor<'a, S: 'a, T>
where
S: BaseFloat,
{
frustum: &'a Frustum<S>,
marker: PhantomData<T>,
}
impl<'a, S, T> FrustumVisitor<'a, S, T>
where
S: BaseFloat,
T: TreeValue,
T::Bound: PlaneBound<S>,
{
pub fn new(frustum: &'a Frustum<S>) -> Self {
Self {
frustum,
marker: PhantomData,
}
}
}
impl<'a, S, T> Visitor for FrustumVisitor<'a, S, T>
where
S: BaseFloat,
T: TreeValue,
T::Bound: PlaneBound<S>,
{
type Bound = T::Bound;
type Result = Relation;
fn accept(&mut self, bound: &Self::Bound, _: bool) -> Option<Relation> {
let r = self.frustum.contains(bound);
if r == Relation::Out {
None
} else {
Some(r)
}
}
}