pybevy_math 0.2.1

Math types (Vec2, Vec3, Vec4, Quat, Mat3, Mat4) for PyBevy
Documentation
use bevy::math::{Vec3, Vec3A};
use pybevy_core::{FromBorrowedStorage, ValueStorage};
use pyo3::{basic::CompareOp, exceptions::PyTypeError, prelude::*};

use crate::vec3::PyVec3;

#[pyclass(name = "Vec3A")]
#[derive(Debug, Clone)]
pub struct PyVec3A {
    storage: ValueStorage<Vec3A>,
}

impl From<PyVec3A> for Vec3A {
    #[inline(always)]
    fn from(py_vec: PyVec3A) -> Self {
        py_vec.storage.get().unwrap()
    }
}

impl From<&PyVec3A> for Vec3A {
    #[inline(always)]
    fn from(py_vec: &PyVec3A) -> Self {
        py_vec.storage.get().unwrap()
    }
}

impl From<Vec3A> for PyVec3A {
    #[inline(always)]
    fn from(vec: Vec3A) -> Self {
        PyVec3A::from_vec3a(vec)
    }
}

impl FromBorrowedStorage<ValueStorage<Vec3A>> for PyVec3A {
    fn from_borrowed(storage: ValueStorage<Vec3A>) -> Self {
        PyVec3A { storage }
    }
}

impl PyVec3A {
    #[inline(always)]
    pub fn from_vec3a(vec: Vec3A) -> Self {
        PyVec3A {
            storage: ValueStorage::owned(vec),
        }
    }

    #[inline(always)]
    pub const fn vec3a(vec: Vec3A) -> Self {
        PyVec3A {
            storage: ValueStorage::owned(vec),
        }
    }

    #[inline(always)]
    fn as_ref(&self) -> PyResult<&Vec3A> {
        Ok(self.storage.as_ref()?)
    }

    #[inline(always)]
    fn as_mut(&mut self) -> PyResult<&mut Vec3A> {
        Ok(self.storage.as_mut()?)
    }
}

#[pymethods]
impl PyVec3A {
    #[classattr]
    pub const ZERO: PyVec3A = PyVec3A::vec3a(Vec3A::ZERO);

    #[classattr]
    pub const ONE: PyVec3A = PyVec3A::vec3a(Vec3A::ONE);

    #[classattr]
    pub const NEG_ONE: PyVec3A = PyVec3A::vec3a(Vec3A::NEG_ONE);

    #[classattr]
    pub const MIN: PyVec3A = PyVec3A::vec3a(Vec3A::MIN);

    #[classattr]
    pub const MAX: PyVec3A = PyVec3A::vec3a(Vec3A::MAX);

    #[classattr]
    pub const NAN: PyVec3A = PyVec3A::vec3a(Vec3A::NAN);

    #[classattr]
    pub const INFINITY: PyVec3A = PyVec3A::vec3a(Vec3A::INFINITY);

    #[classattr]
    pub const NEG_INFINITY: PyVec3A = PyVec3A::vec3a(Vec3A::NEG_INFINITY);

    #[classattr]
    pub const X: PyVec3A = PyVec3A::vec3a(Vec3A::X);

    #[classattr]
    pub const Y: PyVec3A = PyVec3A::vec3a(Vec3A::Y);

    #[classattr]
    pub const Z: PyVec3A = PyVec3A::vec3a(Vec3A::Z);

    #[classattr]
    pub const NEG_X: PyVec3A = PyVec3A::vec3a(Vec3A::NEG_X);

    #[classattr]
    pub const NEG_Y: PyVec3A = PyVec3A::vec3a(Vec3A::NEG_Y);

    #[classattr]
    pub const NEG_Z: PyVec3A = PyVec3A::vec3a(Vec3A::NEG_Z);

    #[new]
    pub fn new(x: f32, y: f32, z: f32) -> Self {
        PyVec3A::vec3a(Vec3A::new(x, y, z))
    }

    #[staticmethod]
    pub fn splat(value: f32) -> Self {
        PyVec3A::vec3a(Vec3A::splat(value))
    }

    #[staticmethod]
    pub fn from_vec3(v: &PyVec3) -> Self {
        PyVec3A::from_vec3a(Vec3A::from(v.get()))
    }

    pub fn to_vec3(&self) -> PyResult<PyVec3> {
        Ok(Vec3::from(*self.as_ref()?).into())
    }

    #[getter]
    pub fn x(&self) -> PyResult<f32> {
        Ok(self.as_ref()?.x)
    }

    #[setter]
    pub fn set_x(&mut self, value: f32) -> PyResult<()> {
        self.as_mut()?.x = value;
        Ok(())
    }

    #[getter]
    pub fn y(&self) -> PyResult<f32> {
        Ok(self.as_ref()?.y)
    }

    #[setter]
    pub fn set_y(&mut self, value: f32) -> PyResult<()> {
        self.as_mut()?.y = value;
        Ok(())
    }

    #[getter]
    pub fn z(&self) -> PyResult<f32> {
        Ok(self.as_ref()?.z)
    }

    #[setter]
    pub fn set_z(&mut self, value: f32) -> PyResult<()> {
        self.as_mut()?.z = value;
        Ok(())
    }

    pub fn dot(&self, other: &PyVec3A) -> PyResult<f32> {
        Ok(self.as_ref()?.dot(*other.as_ref()?))
    }

    pub fn cross(&self, other: &PyVec3A) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(self.as_ref()?.cross(*other.as_ref()?)))
    }

    pub fn length(&self) -> PyResult<f32> {
        Ok(self.as_ref()?.length())
    }

    pub fn length_squared(&self) -> PyResult<f32> {
        Ok(self.as_ref()?.length_squared())
    }

    pub fn normalize(&self) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(self.as_ref()?.normalize()))
    }

    pub fn abs(&self) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(self.as_ref()?.abs()))
    }

    pub fn min(&self, other: &PyVec3A) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(self.as_ref()?.min(*other.as_ref()?)))
    }

    pub fn max(&self, other: &PyVec3A) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(self.as_ref()?.max(*other.as_ref()?)))
    }

    pub fn distance(&self, other: &PyVec3A) -> PyResult<f32> {
        Ok(self.as_ref()?.distance(*other.as_ref()?))
    }

    pub fn distance_squared(&self, other: &PyVec3A) -> PyResult<f32> {
        Ok(self.as_ref()?.distance_squared(*other.as_ref()?))
    }

    pub fn lerp(&self, other: &PyVec3A, t: f32) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(
            self.as_ref()?.lerp(*other.as_ref()?, t),
        ))
    }

    pub fn __add__(&self, other: &PyVec3A) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(*self.as_ref()? + *other.as_ref()?))
    }

    pub fn __sub__(&self, other: &PyVec3A) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(*self.as_ref()? - *other.as_ref()?))
    }

    pub fn __mul__(&self, scalar: f32) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(*self.as_ref()? * scalar))
    }

    pub fn __rmul__(&self, scalar: f32) -> PyResult<Self> {
        self.__mul__(scalar)
    }

    pub fn __truediv__(&self, scalar: f32) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(*self.as_ref()? / scalar))
    }

    pub fn __neg__(&self) -> PyResult<Self> {
        Ok(PyVec3A::from_vec3a(-*self.as_ref()?))
    }

    pub fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult<bool> {
        let s = self.as_ref()?;
        let o = other.as_ref()?;
        match op {
            CompareOp::Eq => Ok(*s == *o),
            CompareOp::Ne => Ok(*s != *o),
            _ => Err(PyTypeError::new_err("Vec3A only supports == and !=")),
        }
    }

    pub fn __repr__(&self) -> PyResult<String> {
        let v = self.as_ref()?;
        Ok(format!("Vec3A({}, {}, {})", v.x, v.y, v.z))
    }

    pub fn __str__(&self) -> PyResult<String> {
        self.__repr__()
    }
}