use core::f64::consts::PI;
use core::fmt::{Debug, Display};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
use num_traits::Float;
pub enum FloatType {
F32,
F64,
}
pub trait Real:
Float
+ Add
+ AddAssign
+ Sub
+ SubAssign
+ Mul
+ MulAssign
+ Div
+ DivAssign
+ Copy
+ Clone
+ Pi
+ IntoDegrees
+ IntoRadians
+ PartialEq
+ PartialOrd
+ Debug
+ Display
{
fn is_f32() -> bool;
fn is_f64() -> bool;
fn float_type() -> FloatType;
fn as_f32(self) -> f32;
fn as_f64(self) -> f64;
}
impl Real for f32 {
#[inline]
fn is_f32() -> bool {
true
}
#[inline]
fn is_f64() -> bool {
false
}
#[inline]
fn float_type() -> FloatType {
FloatType::F32
}
#[inline]
fn as_f32(self) -> f32 {
self
}
#[inline]
fn as_f64(self) -> f64 {
f64::from(self)
}
}
impl Real for f64 {
#[inline]
fn is_f32() -> bool {
false
}
#[inline]
fn is_f64() -> bool {
true
}
#[inline]
fn float_type() -> FloatType {
FloatType::F64
}
#[inline]
fn as_f32(self) -> f32 {
self as f32
}
#[inline]
fn as_f64(self) -> f64 {
self
}
}
pub trait Lerp<F: Real> {
fn lerp(&self, b: &Self, factor: F) -> Self;
}
impl Lerp<f32> for f32 {
fn lerp(&self, b: &Self, factor: f32) -> Self {
*self + ((*self - *b) * factor)
}
}
impl Lerp<f64> for f64 {
fn lerp(&self, b: &Self, factor: f64) -> Self {
*self + ((*self - *b) * factor)
}
}
pub trait Pi {
fn pi() -> Self;
}
impl<T: Real> Pi for T {
fn pi() -> Self {
T::from(PI).unwrap()
}
}
pub trait IntoRadians {
fn into_radians(self) -> Self;
}
impl<T: Real + Pi> IntoRadians for T {
fn into_radians(self) -> Self {
crate::units::radians(self)
}
}
pub trait IntoDegrees {
fn into_degrees(self) -> Self;
}
impl<T: Real + Pi> IntoDegrees for T {
fn into_degrees(self) -> Self {
crate::units::degrees(self)
}
}
pub trait DotProduct<T: Real> {
fn dot(&self, rhs: &Self) -> T;
}
pub trait CrossProduct {
fn cross(&self, rhs: &Self) -> Self;
}
pub trait Transpose {
fn transpose(self) -> Self;
}
pub trait TransposeAssign {
fn transpose_assign(&mut self);
}
pub trait Inverse {
fn inverse(self) -> Self;
}
pub trait InverseAssign {
fn inverse_assign(&mut self);
}
pub trait Pack {
type GLSLOutput;
type HLSLOutput;
type GLSLOutputArray;
type HLSLOutputArray;
type CPUOutput;
fn into_packed_glsl(self) -> Self::GLSLOutput;
fn into_packed_hlsl(self) -> Self::HLSLOutput;
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray;
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray;
fn into_packed_cpu(self) -> Self::CPUOutput;
}
pub trait IntoSTD140 {
type Output: Pack;
fn into_std140(self) -> Self::Output;
}
pub trait Column {
type Output;
fn get_column(&self, col: usize) -> Self::Output;
}
pub trait ColumnRef: Column {
fn get_column_ref(&self, col: usize) -> &Self::Output;
}
pub trait ColumnRefMut: Column {
fn get_column_ref_mut(&mut self, col: usize) -> &mut Self::Output;
}
pub trait Row {
type Output;
fn get_row(&self, row: usize) -> Self::Output;
}
pub trait RowRef: Row {
fn get_row_ref(&self, row: usize) -> &Self::Output;
}
pub trait RowRefMut: Row {
fn get_row_ref_mut(&mut self, row: usize) -> &mut Self::Output;
}
pub trait Length {
type Output;
fn length(&self) -> Self::Output;
}
pub trait LengthSquared {
type Output;
fn length_squared(&self) -> Self::Output;
}
pub trait Normalize {
fn normalize(self) -> Self;
}
pub trait NormalizeAssign {
fn normalize_assign(&mut self);
}
pub mod std140 {
use crate::traits::{IntoSTD140, Pack};
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct F32Pack(f32);
impl IntoSTD140 for f32 {
type Output = F32Pack;
fn into_std140(self) -> Self::Output {
F32Pack(self)
}
}
impl Pack for F32Pack {
type GLSLOutput = f32;
type HLSLOutput = f32;
type GLSLOutputArray = f32;
type HLSLOutputArray = f32;
type CPUOutput = f32;
fn into_packed_glsl(self) -> Self::GLSLOutput {
self.0
}
fn into_packed_hlsl(self) -> Self::HLSLOutput {
self.0
}
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
self.0
}
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
self.0
}
fn into_packed_cpu(self) -> Self::CPUOutput {
self.0
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct F64Pack(f64);
impl IntoSTD140 for f64 {
type Output = F64Pack;
fn into_std140(self) -> Self::Output {
F64Pack(self)
}
}
impl Pack for F64Pack {
type GLSLOutput = f64;
type HLSLOutput = f64;
type GLSLOutputArray = f64;
type HLSLOutputArray = f64;
type CPUOutput = f64;
fn into_packed_glsl(self) -> Self::GLSLOutput {
self.0
}
fn into_packed_hlsl(self) -> Self::HLSLOutput {
self.0
}
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
self.0
}
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
self.0
}
fn into_packed_cpu(self) -> Self::CPUOutput {
self.0
}
}
}