use glam::{Vec2, Vec3};
pub trait NavVec: Copy + PartialEq + core::fmt::Debug + Send + Sync + 'static {
const ZERO: Self;
fn add(self, other: Self) -> Self;
fn sub(self, other: Self) -> Self;
fn mul(self, scale: f32) -> Self;
fn dot(self, other: Self) -> f32;
fn cross_up(self, other: Self) -> f32;
fn length(self) -> f32;
fn nav2(self) -> [f32; 2];
fn height(self) -> f32;
fn from_nav2(plane: [f32; 2], height: f32) -> Self;
fn distance(self, other: Self) -> f32 {
self.sub(other).length()
}
fn cross_apex(apex: Self, a: Self, b: Self) -> f32 {
a.sub(apex).cross_up(b.sub(apex))
}
fn normalized(self) -> Self {
let len = self.length();
if len > 1e-20 { self.mul(1.0 / len) } else { Self::ZERO }
}
}
impl NavVec for Vec2 {
const ZERO: Self = Vec2::ZERO;
fn add(self, other: Self) -> Self {
self + other
}
fn sub(self, other: Self) -> Self {
self - other
}
fn mul(self, scale: f32) -> Self {
self * scale
}
fn dot(self, other: Self) -> f32 {
Vec2::dot(self, other)
}
fn cross_up(self, other: Self) -> f32 {
self.x * other.y - self.y * other.x
}
fn length(self) -> f32 {
Vec2::length(self)
}
fn nav2(self) -> [f32; 2] {
[self.x, self.y]
}
fn height(self) -> f32 {
0.0
}
fn from_nav2(plane: [f32; 2], _height: f32) -> Self {
Vec2::new(plane[0], plane[1])
}
}
impl NavVec for Vec3 {
const ZERO: Self = Vec3::ZERO;
fn add(self, other: Self) -> Self {
self + other
}
fn sub(self, other: Self) -> Self {
self - other
}
fn mul(self, scale: f32) -> Self {
self * scale
}
fn dot(self, other: Self) -> f32 {
Vec3::dot(self, other)
}
fn cross_up(self, other: Self) -> f32 {
self.z * other.x - self.x * other.z
}
fn length(self) -> f32 {
Vec3::length(self)
}
fn nav2(self) -> [f32; 2] {
[self.x, self.z]
}
fn height(self) -> f32 {
self.y
}
fn from_nav2(plane: [f32; 2], height: f32) -> Self {
Vec3::new(plane[0], height, plane[1])
}
}