pybevy_transform 0.2.1

Transform component for PyBevy
Documentation
use bevy::transform::components::{GlobalTransform, Transform};
use pybevy_core::{ComponentStorage, PyComponent};
use pybevy_macros::component_storage;
use pybevy_math::{PyAffine3A, PyIsometry3d, PyMat4, PyQuat, PyVec3};
use pyo3::prelude::*;

use crate::transform::PyTransform;

#[component_storage(GlobalTransform)]
#[pyclass(name = "GlobalTransform", extends = pybevy_core::PyComponent, eq)]
#[derive(Debug, Clone)]
pub struct PyGlobalTransform {
    pub(crate) storage: ComponentStorage<GlobalTransform>,
}

impl PartialEq for PyGlobalTransform {
    fn eq(&self, other: &Self) -> bool {
        match (self.as_ref(), other.as_ref()) {
            (Ok(a), Ok(b)) => a == b,
            _ => false,
        }
    }
}

#[pymethods]
impl PyGlobalTransform {
    #[new]
    pub fn new() -> (Self, PyComponent) {
        (GlobalTransform::default().into(), PyComponent)
    }

    #[staticmethod]
    #[pyo3(name = "IDENTITY")]
    pub fn identity(py: Python) -> PyResult<Py<Self>> {
        Py::new(py, (GlobalTransform::IDENTITY.into(), PyComponent))
    }

    pub fn translation(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.translation().into())
    }

    pub fn rotation(&self) -> PyResult<PyQuat> {
        Ok(self.as_ref()?.rotation().into())
    }

    pub fn scale(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.scale().into())
    }

    pub fn to_scale_rotation_translation(&self) -> PyResult<(PyVec3, PyQuat, PyVec3)> {
        let (scale, rotation, translation) = self.as_ref()?.to_scale_rotation_translation();
        Ok((scale.into(), rotation.into(), translation.into()))
    }

    pub fn to_matrix(&self) -> PyResult<PyMat4> {
        Ok(self.as_ref()?.to_matrix().into())
    }

    pub fn affine(&self) -> PyResult<PyAffine3A> {
        Ok(self.as_ref()?.affine().into())
    }

    pub fn to_isometry(&self) -> PyResult<PyIsometry3d> {
        Ok(self.as_ref()?.to_isometry().into())
    }

    pub fn compute_transform(&self, py: Python<'_>) -> PyResult<Py<PyTransform>> {
        let transform = self.as_ref()?.compute_transform();
        Py::new(py, PyTransform::from_owned(transform))
    }

    pub fn transform_point(&self, point: PyVec3) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.transform_point(point.into()).into())
    }

    pub fn reparented_to(
        &self,
        py: Python<'_>,
        parent: &PyGlobalTransform,
    ) -> PyResult<Py<PyTransform>> {
        let transform = self.as_ref()?.reparented_to(parent.as_ref()?);
        Py::new(py, PyTransform::from_owned(transform))
    }

    pub fn right(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.right().into())
    }

    pub fn left(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.left().into())
    }

    pub fn up(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.up().into())
    }

    pub fn down(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.down().into())
    }

    pub fn forward(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.forward().into())
    }

    pub fn back(&self) -> PyResult<PyVec3> {
        Ok(self.as_ref()?.back().into())
    }

    pub fn mul_transform(
        &self,
        py: Python<'_>,
        transform: &PyTransform,
    ) -> PyResult<Py<PyGlobalTransform>> {
        let bevy_transform: Transform = transform.clone().try_into()?;
        let result = self.as_ref()?.mul_transform(bevy_transform);
        Py::new(py, PyGlobalTransform::from_owned(result))
    }

    pub fn __repr__(&self) -> PyResult<String> {
        match self.as_ref() {
            Ok(gt) => {
                let t = gt.translation();
                let r = gt.rotation();
                let s = gt.scale();
                Ok(format!(
                    "GlobalTransform(translation={:?}, rotation={:?}, scale={:?})",
                    t, r, s
                ))
            }
            Err(_) => Ok("GlobalTransform(<invalid>)".to_string()),
        }
    }
}