use std::cmp::Ordering;
use std::fmt;
use godot_ffi as sys;
use sys::{ExtVariantType, GodotFfi, ffi_methods};
use crate::builtin::math::{FloatExt, GlamConv, GlamType};
use crate::builtin::{RVec4, Vector4Axis, Vector4i, inner, real};
#[doc = shared_vector_docs!()]
#[derive(Default, Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector4 {
pub x: real,
pub y: real,
pub z: real,
pub w: real,
}
impl Vector4 {
impl_vector_consts!(real);
impl_float_vector_consts!();
}
impl_vector_fns!(Vector4, RVec4, real, (x, y, z, w));
impl Vector4 {
#[doc(hidden)]
#[inline]
pub fn as_inner(&self) -> inner::InnerVector4<'_> {
inner::InnerVector4::from_outer(self)
}
}
impl_float_vector_fns!(Vector4, Vector4i, (x, y, z, w));
impl_vector4x_fns!(Vector4, real);
impl_vector3_vector4_fns!(Vector4, (x, y, z, w));
impl_vector_operators!(Vector4, real, (x, y, z, w));
impl fmt::Display for Vector4 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {}, {}, {})", self.x, self.y, self.z, self.w)
}
}
unsafe impl GodotFfi for Vector4 {
const VARIANT_TYPE: ExtVariantType = ExtVariantType::Concrete(sys::VariantType::VECTOR4);
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}
crate::meta::impl_godot_as_self!(Vector4: ByValue);
impl GlamType for RVec4 {
type Mapped = Vector4;
fn to_front(&self) -> Self::Mapped {
Vector4::new(self.x, self.y, self.z, self.w)
}
fn from_front(mapped: &Self::Mapped) -> Self {
RVec4::new(mapped.x, mapped.y, mapped.z, mapped.w)
}
}
impl GlamConv for Vector4 {
type Glam = RVec4;
}
#[cfg(test)] #[cfg_attr(published_docs, doc(cfg(test)))]
mod test {
use super::*;
use crate::builtin::math::assert_eq_approx;
#[test]
fn coord_min_max() {
let a = Vector4::new(1.2, 3.4, 5.6, 0.1);
let b = Vector4::new(0.1, 5.6, 2.3, 1.2);
assert_eq_approx!(a.coord_min(b), Vector4::new(0.1, 3.4, 2.3, 0.1),);
assert_eq_approx!(a.coord_max(b), Vector4::new(1.2, 5.6, 5.6, 1.2),);
}
#[test]
fn sign() {
let vector = Vector4::new(0.2, -0.5, 0., 999.0);
assert_eq!(vector.sign(), Vector4::new(1., -1., 0., 1.));
}
#[cfg(feature = "serde")] #[cfg_attr(published_docs, doc(cfg(feature = "serde")))]
#[test]
fn serde_roundtrip() {
let vector = Vector4::default();
let expected_json = "{\"x\":0.0,\"y\":0.0,\"z\":0.0,\"w\":0.0}";
crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}