use crate::traits::{IntoSTD140, Pack, Real};
use crate::vector::{TVec2, TVec3, TVec4};
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct TVec2P<T: Real>([T; 2]);
pub const fn vector_2_packed_f32(x: f32, y: f32) -> TVec2P<f32> {
TVec2P::<f32> { 0: [x, y] }
}
pub const fn vector_2_packed_f64(x: f64, y: f64) -> TVec2P<f64> {
TVec2P::<f64> { 0: [x, y] }
}
impl<T: Real> TVec2P<T> {
pub fn new(x: T, y: T) -> Self {
Self([x, y])
}
}
impl<T: Real> From<TVec2<T>> for TVec2P<T> {
fn from(other: TVec2<T>) -> Self {
Self([other[0], other[1]])
}
}
impl<T: Real> From<[T; 2]> for TVec2P<T> {
fn from(other: [T; 2]) -> Self {
Self(other)
}
}
impl<T: Real> From<(T, T)> for TVec2P<T> {
fn from(other: (T, T)) -> Self {
Self([other.0, other.1])
}
}
impl<T: Real> Pack for TVec2P<T> {
type GLSLOutput = [T; 2];
type HLSLOutput = [T; 2];
type GLSLOutputArray = Self::GLSLOutput;
type HLSLOutputArray = Self::HLSLOutput;
type CPUOutput = [T; 2];
#[inline]
fn into_packed_glsl(self) -> Self::GLSLOutput {
self.0
}
#[inline]
fn into_packed_hlsl(self) -> Self::HLSLOutput {
self.0
}
#[inline]
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
self.0
}
#[inline]
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
self.0
}
#[inline]
fn into_packed_cpu(self) -> Self::CPUOutput {
self.0
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct TVec3P<T: Real>([T; 3]);
pub const fn vector_3_packed_f32(x: f32, y: f32, z: f32) -> TVec3P<f32> {
TVec3P::<f32> { 0: [x, y, z] }
}
pub const fn vector_3_packed_f64(x: f64, y: f64, z: f64) -> TVec3P<f64> {
TVec3P::<f64> { 0: [x, y, z] }
}
impl<T: Real> TVec3P<T> {
pub fn new(x: T, y: T, z: T) -> Self {
Self([x, y, z])
}
}
impl<T: Real> From<TVec3<T>> for TVec3P<T> {
fn from(other: TVec3<T>) -> Self {
Self([other[0], other[1], other[2]])
}
}
impl<T: Real> From<[T; 3]> for TVec3P<T> {
fn from(other: [T; 3]) -> Self {
Self(other)
}
}
impl<T: Real> From<(T, T, T)> for TVec3P<T> {
fn from(other: (T, T, T)) -> Self {
Self([other.0, other.1, other.2])
}
}
impl<T: Real> Pack for TVec3P<T> {
type GLSLOutput = [T; 4];
type HLSLOutput = [T; 4];
type GLSLOutputArray = Self::GLSLOutput;
type HLSLOutputArray = Self::HLSLOutput;
type CPUOutput = [T; 3];
#[inline]
fn into_packed_glsl(self) -> Self::GLSLOutput {
[self.0[0], self.0[1], self.0[2], T::zero()]
}
#[inline]
fn into_packed_hlsl(self) -> Self::HLSLOutput {
[self.0[0], self.0[1], self.0[2], T::zero()]
}
#[inline]
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
self.into_packed_glsl()
}
#[inline]
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
self.into_packed_hlsl()
}
#[inline]
fn into_packed_cpu(self) -> Self::CPUOutput {
[self.0[0], self.0[1], self.0[2]]
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct TVec4P<T: Real>([T; 4]);
pub const fn vector_4_packed_f32(x: f32, y: f32, z: f32, w: f32) -> TVec4P<f32> {
TVec4P::<f32> { 0: [x, y, z, w] }
}
pub const fn vector_4_packed_f64(x: f64, y: f64, z: f64, w: f64) -> TVec4P<f64> {
TVec4P::<f64> { 0: [x, y, z, w] }
}
impl<T: Real> TVec4P<T> {
pub fn new(x: T, y: T, z: T, w: T) -> Self {
Self([x, y, z, w])
}
}
impl<T: Real> From<TVec4<T>> for TVec4P<T> {
fn from(other: TVec4<T>) -> Self {
Self([other[0], other[1], other[2], other[3]])
}
}
impl<T: Real> From<[T; 4]> for TVec4P<T> {
fn from(other: [T; 4]) -> Self {
Self(other)
}
}
impl<T: Real> From<(T, T, T, T)> for TVec4P<T> {
fn from(other: (T, T, T, T)) -> Self {
Self([other.0, other.1, other.2, other.3])
}
}
impl<T: Real> Pack for TVec4P<T> {
type GLSLOutput = [T; 4];
type HLSLOutput = [T; 4];
type GLSLOutputArray = Self::GLSLOutput;
type HLSLOutputArray = Self::HLSLOutput;
type CPUOutput = [T; 4];
#[inline]
fn into_packed_glsl(self) -> Self::GLSLOutput {
self.0
}
#[inline]
fn into_packed_hlsl(self) -> Self::HLSLOutput {
self.0
}
#[inline]
fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
self.into_packed_glsl()
}
#[inline]
fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
self.into_packed_hlsl()
}
#[inline]
fn into_packed_cpu(self) -> Self::CPUOutput {
self.0
}
}
impl<T: Real> IntoSTD140 for TVec2<T> {
type Output = TVec2P<T>;
fn into_std140(self) -> Self::Output {
TVec2P::from(self)
}
}
impl<T: Real> IntoSTD140 for TVec3<T> {
type Output = TVec3P<T>;
fn into_std140(self) -> Self::Output {
TVec3P::from(self)
}
}
impl<T: Real> IntoSTD140 for TVec4<T> {
type Output = TVec4P<T>;
fn into_std140(self) -> Self::Output {
TVec4P::from(self)
}
}