use crate::math::{Pose, Vector};
pub trait NormalConstraints: 'static {
fn project_local_normal_mut(&self, normal: &mut Vector) -> bool;
fn project_local_normal(&self, mut normal: Vector) -> Option<Vector> {
self.project_local_normal_mut(&mut normal).then_some(normal)
}
fn project_local_normal1(
&self,
pos12: &Pose,
normal1: &mut Vector,
normal2: &mut Vector,
) -> bool {
if !self.project_local_normal_mut(normal1) {
return false;
}
*normal2 = pos12.rotation.inverse() * -*normal1;
true
}
fn project_local_normal2(
&self,
pos12: &Pose,
normal1: &mut Vector,
normal2: &mut Vector,
) -> bool {
if !self.project_local_normal_mut(normal2) {
return false;
}
*normal1 = pos12.rotation * (-*normal2);
true
}
}
impl NormalConstraints for () {
fn project_local_normal_mut(&self, _: &mut Vector) -> bool {
true
}
}
pub trait NormalConstraintsPair {
fn project_local_normals(
&self,
pos12: &Pose,
normal1: &mut Vector,
normal2: &mut Vector,
) -> bool;
}
impl NormalConstraintsPair
for (
Option<&dyn NormalConstraints>,
Option<&dyn NormalConstraints>,
)
{
fn project_local_normals(
&self,
pos12: &Pose,
normal1: &mut Vector,
normal2: &mut Vector,
) -> bool {
if let Some(proj) = self.0 {
if !proj.project_local_normal1(pos12, normal1, normal2) {
return false;
}
}
if let Some(proj) = self.1 {
proj.project_local_normal2(pos12, normal1, normal2)
} else {
true
}
}
}